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
Спасибо за ответы! Разобрался в чём проблема. Стек-то в другую сторону растёт! Лечится заменой
на
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" есть массив:
Номер нажатой кнопки будет записыватся в 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, что от окна сообщений пришёл результат.