Message Box

...
  • Наверное потому diamond не включал последнюю версию use_mb в дистрибутив. Странно то, что в эмуляторе этот пример работал без вылета.

    На всякий случай даю архив с этим исправлением в файле use_mb.asm и дополненным about.txt.
    При использовании msgbox-ов, нужно стараться избегать ситуаций, когда несколько сообщений открыто одновременно. Потому что все окна msgbox используют одни и те же указатели, и возможен конфликт. Об этом ограничении я только что написал в файле about.txt. Сама библиотека не изменялась.
    Attachments
    msgbox4.7z (10.64 KiB)
    Downloaded 404 times
  • IgorA wrote:Наверное потому diamond не включал последнюю версию use_mb в дистрибутив.
    Вообще-то use_mb в ночных сборках уже давно присутствует. Папка demos, если что.
    Ушёл к умным, знающим и культурным людям.
  • Подскажите пожалуйста, где я облажался. KlbrInWin вываливается в exception...
    Attachments
    msgbox.zip (6.1 KiB)
    Downloaded 382 times
  • Бинарник не соответствует исходникам, в бинарнике сразу после вызова mb_create стоит вызов функции выхода (а уже потом вечный цикл).
    Ушёл к умным, знающим и культурным людям.
  • Albom wrote:KlbrInWin вываливается в exception...
    думаю что дело еще и в том, что KlbrInWin считает что папка /rd/1/ это та папка с откуда был запущен исходник kex :

    Code: Select all

    imp = kol_cofflib_load("/rd/1/lib/Msgbox.obj");
    т. е. еще надо создать папку lib рядом с kex, тогда будет запускатся
    Attachments
    вот что у меня вышло
    lib_msg_err.PNG (13.98 KiB)
    вот что у меня вышло Viewed 9597 times
  • А основная ошибка состоит в том, что в приведённом коде перекрываются стеки двух потоков (точнее, два потока параллельно используют один и тот же участок памяти в качестве стека). В зависимости от фазы луны такое может работать нормально, приводить к случайной порче данных или приводить к возврату из процедуры в совершенно неожиданное место (типа невыделенной области памяти - эмулятор очень обижается, когда не может даже прочесть память по eip, с результатом "exception in debuggee").
    Ушёл к умным, знающим и культурным людям.
  • Спасибо за ответы! Разобрался в чём проблема. Стек-то в другую сторону растёт! Лечится заменой

    Code: Select all

    mb_create(msg, thread);
    на

    Code: Select all

    mb_create(msg, thread+1024);
  • Ещё небольшой вопрос. Как функция mb_create возвращает значение нажатой кнопки? Через eax? Почему-то не получается получить результат. И почему номер кнопки считается с 1?
  • Возврат делается в 1-й байт структуры:

    Code: Select all

    msgbox_1:
      dw 0
      db 'caption',0
      db 'text',0
      db 'button1',0
      db 0
    Из кода библиотеки:

    Code: Select all

    ...
    close:
      sub ah,MB_FIRST_BUT_ID
      inc ah
      mov ebx,[mb_text]
      mov byte[ebx],ah
    ...
    Albom wrote:И почему номер кнопки считается с 1?
    Потому что 0 возвращается в случае, если нажали на крестик закрытия верху окна.
  • IgorA wrote:Возврат делается в 1-й байт структуры
    байт или слово?
    не очень хороший способ. :( не могу придумать, как бы реализовать получение этого параметра (связано с проблемами области видимости локальных переменных и утечки памяти при динамическом создании массивов).
    к тому же лучше было бы, если функция возвращала значение только после закрытия бокса (крестиком или кнопкой). т.е. в цикле (в библиотеке) проверялось бы, завершился поток или нет. когда же поток завершился, то только тогда ф-ция возвращает управление вызывающей программе.
  • Возвращает в 1- байт, а 2-й байт используется для других целей.
    IgorA wrote:к тому же лучше было бы, если функция возвращала значение только после закрытия бокса (крестиком или кнопкой). т.е. в цикле (в библиотеке) проверялось бы, завершился поток или нет. когда же поток завершился, то только тогда ф-ция возвращает управление вызывающей программе.
    Сама функция mb_create ничего не возвращает. Возврат происходит при нажатии на кнопку или при закрытии окна крестиком.
    IgorA wrote:не очень хороший способ. :( не могу придумать, как бы реализовать получение этого параметра (связано с проблемами области видимости локальных переменных и утечки памяти при динамическом создании массивов)
    Не очень хорошо то, что библиотека не может одновременно использовать несколько сообщений. Надо как-нибудь переписать ее, но у меня не получилось, т. к. каждый поток с сообщением должен иметь именно свои данные.
  • почти дописал обёртку для создания окна сообщений. проблемы с возвратом результата.
    задумка такая, чтобы ф-ция возвращала результат только после закрытия окна сообщения (кнопкой или крестиком). но почему-то не работает. разбираться нет времени. может кто-нибудь подсобит? (формат обёртки почти такой, как в ф-ции MessageBox из WinAPI; кстати, можно добавить и первый параметр)
    Attachments
    msgbox.zip (7.87 KiB)
    Downloaded 374 times
  • в файле #include "msgbox.c" есть массив:

    Code: Select all

    char msg[1024];
    Номер нажатой кнопки будет записыватся в 1-й байт при закрытии окна или нажатии на кнопку, т. е. ответ будет в msg[0]
    Albom wrote:чтобы ф-ция возвращала результат только после закрытия окна сообщения
    Хочешь сделать модальный msgbox ? Тогда нужно в цикле следить за процессом окна сообщения (как это сделать нужно посоветоваться с ядерными программистами). И если поток сообщения окажется закрытым, то делать выход из функции (short MessageBox(char *caption, char *text, int type)) возвращая результат: msg[0].

    Код функции создающей msgbox (из библиотеки):

    Code: Select all

    ;input:
    ; [esp+8] = pointer to msgbox text
    align 4
    MsgBoxCreate:
      push ebp
      mov ebp,esp
        m2m dword[mb_text],dword[ebp+8]
        push eax ebx ecx edx
    
        mov eax,51
        mov ebx,1
        mov ecx,start
        mov edx,dword[ebp+12];thread
        int 0x40
    
        mov dword[mb_funct],0
        pop edx ecx ebx eax
      pop ebp
      ret 8
    Как вцепится за этот поток ф. 51.1 я не знаю, может даже прийдеться библиотеку подправлять.
  • Я в airc воспользовалась функцией mb_setfunctions, и мой обработчик, вызываемый в потоке библиотеки, сообщает главному потоку, который всё время висит в главном цикле обработки сообщений, по IPC, что от окна сообщений пришёл результат.
    Сделаем мир лучше!
  • Who is online

    Users browsing this forum: No registered users and 5 guests