Page 3 of 4

Re: Message Box

Posted: Tue Sep 29, 2009 1:43 pm
by CleverMouse
Я обнаружила, что в примере use_mb.asm комментарий задел одну лишнюю строчку:

Code: Select all

but_2:
  push thread
  push msgbox_2
  call [mb_create]
    ;mov eax,5
    ;mov ebx,50
    ;int 0x40  push msgbox_2_funct
  call [mb_setfunctions]
  jmp still
Из-за этого в примере поток окна сообщения вылетает при нажатии любой кнопки во втором диалоге.

Re: Message Box

Posted: Tue Sep 29, 2009 2:42 pm
by IgorA
Наверное потому diamond не включал последнюю версию use_mb в дистрибутив. Странно то, что в эмуляторе этот пример работал без вылета.

На всякий случай даю архив с этим исправлением в файле use_mb.asm и дополненным about.txt.
При использовании msgbox-ов, нужно стараться избегать ситуаций, когда несколько сообщений открыто одновременно. Потому что все окна msgbox используют одни и те же указатели, и возможен конфликт. Об этом ограничении я только что написал в файле about.txt. Сама библиотека не изменялась.

Re: Message Box

Posted: Tue Sep 29, 2009 4:43 pm
by diamond
IgorA wrote:Наверное потому diamond не включал последнюю версию use_mb в дистрибутив.
Вообще-то use_mb в ночных сборках уже давно присутствует. Папка demos, если что.

Re: Message Box

Posted: Thu Dec 03, 2009 10:24 pm
by Albom
Подскажите пожалуйста, где я облажался. KlbrInWin вываливается в exception...

Re: Message Box

Posted: Thu Dec 03, 2009 10:52 pm
by diamond
Бинарник не соответствует исходникам, в бинарнике сразу после вызова mb_create стоит вызов функции выхода (а уже потом вечный цикл).

Re: Message Box

Posted: Thu Dec 03, 2009 11:02 pm
by IgorA
Albom wrote:KlbrInWin вываливается в exception...
думаю что дело еще и в том, что KlbrInWin считает что папка /rd/1/ это та папка с откуда был запущен исходник kex :

Code: Select all

imp = kol_cofflib_load("/rd/1/lib/Msgbox.obj");
т. е. еще надо создать папку lib рядом с kex, тогда будет запускатся

Re: Message Box

Posted: Thu Dec 03, 2009 11:55 pm
by diamond
А основная ошибка состоит в том, что в приведённом коде перекрываются стеки двух потоков (точнее, два потока параллельно используют один и тот же участок памяти в качестве стека). В зависимости от фазы луны такое может работать нормально, приводить к случайной порче данных или приводить к возврату из процедуры в совершенно неожиданное место (типа невыделенной области памяти - эмулятор очень обижается, когда не может даже прочесть память по eip, с результатом "exception in debuggee").

Re: Message Box

Posted: Fri Dec 04, 2009 7:45 am
by Albom
Спасибо за ответы! Разобрался в чём проблема. Стек-то в другую сторону растёт! Лечится заменой

Code: Select all

mb_create(msg, thread);
на

Code: Select all

mb_create(msg, thread+1024);

Re: Message Box

Posted: Fri Dec 04, 2009 12:10 pm
by Albom
Ещё небольшой вопрос. Как функция mb_create возвращает значение нажатой кнопки? Через eax? Почему-то не получается получить результат. И почему номер кнопки считается с 1?

Re: Message Box

Posted: Fri Dec 04, 2009 7:20 pm
by IgorA
Возврат делается в 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 возвращается в случае, если нажали на крестик закрытия верху окна.

Re: Message Box

Posted: Fri Dec 04, 2009 8:11 pm
by Albom
IgorA wrote:Возврат делается в 1-й байт структуры
байт или слово?
не очень хороший способ. :( не могу придумать, как бы реализовать получение этого параметра (связано с проблемами области видимости локальных переменных и утечки памяти при динамическом создании массивов).
к тому же лучше было бы, если функция возвращала значение только после закрытия бокса (крестиком или кнопкой). т.е. в цикле (в библиотеке) проверялось бы, завершился поток или нет. когда же поток завершился, то только тогда ф-ция возвращает управление вызывающей программе.

Re: Message Box

Posted: Fri Dec 04, 2009 8:28 pm
by IgorA
Возвращает в 1- байт, а 2-й байт используется для других целей.
IgorA wrote:к тому же лучше было бы, если функция возвращала значение только после закрытия бокса (крестиком или кнопкой). т.е. в цикле (в библиотеке) проверялось бы, завершился поток или нет. когда же поток завершился, то только тогда ф-ция возвращает управление вызывающей программе.
Сама функция mb_create ничего не возвращает. Возврат происходит при нажатии на кнопку или при закрытии окна крестиком.
IgorA wrote:не очень хороший способ. :( не могу придумать, как бы реализовать получение этого параметра (связано с проблемами области видимости локальных переменных и утечки памяти при динамическом создании массивов)
Не очень хорошо то, что библиотека не может одновременно использовать несколько сообщений. Надо как-нибудь переписать ее, но у меня не получилось, т. к. каждый поток с сообщением должен иметь именно свои данные.

Re: Message Box

Posted: Tue Dec 15, 2009 2:15 pm
by Albom
почти дописал обёртку для создания окна сообщений. проблемы с возвратом результата.
задумка такая, чтобы ф-ция возвращала результат только после закрытия окна сообщения (кнопкой или крестиком). но почему-то не работает. разбираться нет времени. может кто-нибудь подсобит? (формат обёртки почти такой, как в ф-ции MessageBox из WinAPI; кстати, можно добавить и первый параметр)

Re: Message Box

Posted: Wed Dec 16, 2009 11:22 pm
by IgorA
в файле #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 я не знаю, может даже прийдеться библиотеку подправлять.

Re: Message Box

Posted: Thu Dec 17, 2009 1:40 pm
by CleverMouse
Я в airc воспользовалась функцией mb_setfunctions, и мой обработчик, вызываемый в потоке библиотеки, сообщает главному потоку, который всё время висит в главном цикле обработки сообщений, по IPC, что от окна сообщений пришёл результат.