Создание пользовательского MessageBox с помощью SoftModalMessageBox
Ранее я уже рассказывал, каким образом можно кастомизировать стандартный MessageBox при помощи хуков, в частности, менять надписи на кнопках. Сегодня разберем создание MessageBox с помощью недокументированной функции SoftModalMessageBox. В качестве единственного параметра она принимает указатель на структуру MSGBOXDATA, которая тоже относится к недокументированным:Code (Assembler) : Убрать нумерацию
- struct MSGBOXDATA
- params MSGBOXPARAMS
- pwndOwner dd ? ; Хэндл окна-владельца
- wLanguageId dd ? ; Идентификатор языка
- pidButton dd ? ; Массив с идентификаторами кнопок
- ppszButtonText dd ? ; Массив с указателями на строки текста
- cButtons dd ? ; Количество кнопок в окне
- DefButton dd ? ; Кнопка по умолчанию
- CancelId dd ? ; Идентификатор кнопки отмены
- Timeout dd ? ; Таймаут окна
- Unknown rd 5 ; Зарезервировано
- ends
Еще одно важное замечание. Для того, чтобы функция SoftModalMessageBox возвращала идентификатор нажатой кнопки, хотя бы один из четырех младших бит в поле dwStyle структуры params (MSGBOXPARAMS) должен быть взведен. То есть стиль должен включать любой из флагов MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO или MB_YESNOCANCEL. Они игнорируются при отрисовке окна, но должны присутствовать при описании, иначе в качестве результата SoftModalMessageBox будет всегда возвращаться 1.
Теперь, когда мы знаем все поля структуры, можно переходить к программированию. Вот простейший пример использования SoftModalMessageBox:
Code (Assembler) : Убрать нумерацию
- ; Массив идентификаторов кнопок
- butIDs dd IDOK,IDYES,IDNO,IDCANCEL
- ; Массив указателей на названия кнопок
- butTxt dd str1,str2,str3,str4
- str1 du 'Natalie',0
- str2 du 'Dylan',0
- str3 du 'Alex',0
- str4 du 'NONE',0
Code (Assembler) : Убрать нумерацию
- ; Размер структуры MSGBOXPARAMS, обязательное поле
- mov [mbdata.params.cbSize],sizeof.MSGBOXPARAMS
- ; Хэндл окна-владельца
- mov [mbdata.params.hwndOwner],HWND_DESKTOP
- ; Хэндл приложения, из ресурсов которого будет браться иконка
- invoke GetModuleHandle,0
- mov [mbdata.params.hInstance],eax
- ; Текст сообщения
- mov [mbdata.params.lpszText],szMess
- ; Текст заголовка
- mov [mbdata.params.lpszCaption],szTitle
- ; Пользовательская иконка + возврат идентификатора
- mov [mbdata.params.dwStyle],MB_USERICON or MB_OKCANCEL
- ; Идентификатор иконки из ресурсов
- mov [mbdata.params.lpszIcon],1
- ; Хэндл окна-владельца
- mov [mbdata.pwndOwner],HWND_DESKTOP
- ; Язык текста
- mov [mbdata.wLanguageId],LANG_NEUTRAL
- ; Указатель на массив идентификаторов кнопок
- mov [mbdata.pidButton],butIDs
- ; Указатель на массив указателей на названия кнопок
- mov [mbdata.ppszButtonText],butTxt
- ; Количество кнопок
- mov [mbdata.cButtons],4
- ; Вторая по счету кнопка используется по умолчанию
- mov [mbdata.DefButton],1
- ; Крестик закрытия окна активен
- mov [mbdata.CancelId],1
- ; Бесконечное отображение
- mov [mbdata.Timeout],-1
- invoke SoftModalMessageBox,mbdata
В приложении пример программы с исходным текстом, которая использует функцию SoftModalMessageBox для создания окна сообщения.
Просмотров: 1093 | Комментариев: 12
Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Mikl___
(21.03.2022 в 13:42):
Спасибо за подсказку! Жаль, что в комментарии нельзя картинки в тэгах [img] и [/img] вставлять
ManHunter
(21.03.2022 в 13:30):
Можно и без dll: https://www.manhunter.ru/assem...sagebox.html
Хук WH_CBT на текущий тред. Тоже постоянно пользуюсь в своих программах, делаю перетаскиваемое окно "About".
Хук WH_CBT на текущий тред. Тоже постоянно пользуюсь в своих программах, делаю перетаскиваемое окно "About".
Mikl___
(21.03.2022 в 13:03):
ManHunter а это SoftModalMessageBox, который при помощи хуков превратился в окно диалога https://wasm.in/threads/skazki...#post-383977 :) на странице исходники, капелька пояснений и экзешник
https://wasm.in/attachments/01-png.5617/
https://wasm.in/attachments/01-png.5617/
ManHunter
(21.03.2022 в 12:21):
Mikl___, ну вот, все написано до нас :) Но там x64 и без описания. Я где-то в камментах тоже собирал варианты вывода MessageBox, сейчас не вспомню.
А от себя в копилку к Дядюшке могу добавить SHMessageBoxCheck:
https://www.manhunter.ru/assem...kazivat.html
А от себя в копилку к Дядюшке могу добавить SHMessageBoxCheck:
https://www.manhunter.ru/assem...kazivat.html
Mikl___
(21.03.2022 в 12:16):
Здравствуйте, ManHunter!
wasm.in --> WASM.ARTICLES --> Сказки дядюшки Римуса о x64 --> Глава шестая. Братец Кролик выводит MessageBox всеми возможными способами
https://wasm.in/threads/skazki...#post-408016
wasm.in --> WASM.ARTICLES --> Сказки дядюшки Римуса о x64 --> Глава шестая. Братец Кролик выводит MessageBox всеми возможными способами
https://wasm.in/threads/skazki...#post-408016
ManHunter
(16.03.2022 в 14:04):
Теги и так есть, но там, где я считаю нужным.
qqq
(16.03.2022 в 12:37):
афтар по брацки, расставь в статьях тематические метки аля winapi, шифрование, архивы и т.д.
ManHunter
(14.03.2022 в 15:56):
Я в своих программах пользуюсь MessageBoxIndirect
DRON
(14.03.2022 в 09:30):
Нет, всё не так: основная проблема в том, что на 64-битных виндах pwndOwner имеет размер 8, а не 4 байта, потому что объявлен он как
PWND hwndOwner; // Converted hwndOwner
Вообще с этой функцией одна морока: она чисто внутренняя и MS меняет её как хочет от версии к версии, что там в Win11 я боюсь представить.
Проще использовать документированный TaskDialogIndirect.
PWND hwndOwner; // Converted hwndOwner
Вообще с этой функцией одна морока: она чисто внутренняя и MS меняет её как хочет от версии к версии, что там в Win11 я боюсь представить.
Проще использовать документированный TaskDialogIndirect.
ManHunter
(14.03.2022 в 07:57):
Дополнил, спасибо!
DRON
(14.03.2022 в 06:36):
>Размер кнопок под длину надписей не подгоняется, так что без фанатизма.
Он кстати подгоняется, но только под самую большую стандартную надпись. Так что у разных языков будут разные длины кнопок.
Исходник функции: https://pastebin.com/LyY3SCSr
Он кстати подгоняется, но только под самую большую стандартную надпись. Так что у разных языков будут разные длины кнопок.
Исходник функции: https://pastebin.com/LyY3SCSr
DRON
(14.03.2022 в 05:38):
На 64-битной семёрке вылетает, потому что там структура больше:
struct MSGBOXDATA
params MSGBOXPARAMS
pwndOwner dd ? ; Хэндл окна-владельца
dwPadding dd ?
wLanguageId dd ? ; Идентификатор языка
pidButton dd ? ; Массив с идентификаторами кнопок
ppszButtonText dd ? ; Массив с указателями на строки текста
cButtons dd ? ; Количество кнопок в окне
DefButton dd ? ; Кнопка по умолчанию
CancelId dd ? ; Идентификатор кнопки отмены
Timeout dd ? ; Таймаут окна
Unknown dd 5 dup ? ; Зарезервировано
ends
struct MSGBOXDATA
params MSGBOXPARAMS
pwndOwner dd ? ; Хэндл окна-владельца
dwPadding dd ?
wLanguageId dd ? ; Идентификатор языка
pidButton dd ? ; Массив с идентификаторами кнопок
ppszButtonText dd ? ; Массив с указателями на строки текста
cButtons dd ? ; Количество кнопок в окне
DefButton dd ? ; Кнопка по умолчанию
CancelId dd ? ; Идентификатор кнопки отмены
Timeout dd ? ; Таймаут окна
Unknown dd 5 dup ? ; Зарезервировано
ends
Добавить комментарий
Заполните форму для добавления комментария