Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[44.201.199.251] |
|
Сообщ.
#1
,
|
|
|
Как проще всего найти и закрыть мною же вызванный MessageBox (в другом потоке, например)?
p.s. Надо сделать таймаут для него – суть в этом... |
Сообщ.
#2
,
|
|
|
Я такое ловлю по таймеру через ::FindWindow()... Подробности - только послезавтра, щяс на даче сижу...
|
Сообщ.
#3
,
|
|
|
Сообщ.
#4
,
|
|
|
Цитата Shaggy @ Ооо! ++MessageBoxTimeout Но вопрос всё равно актуален, мне интересен процесс поиска окна MessageBox'а! Добавлено Причём, надо учесть, что окно может быть не Foreground, без заголовка, hWnd=0, и что может быть открыт ещё какой-то другой MessageBox. Т.е. FindWindow('#32770', Title) звучит не надёжно... |
Сообщ.
#5
,
|
|
|
Цитата Jin X @ Причём, надо учесть, что окно может быть не Foreground, без заголовка Если не секрет, а почему бы изначально в заголовок не вставлять метку то? |
Сообщ.
#6
,
|
|
|
Потому что я заранее не знаю какой там будет заголовок.
Добавлено Как вариант можно, конечно, вставить в заголовок штук 200 пробелов и 20 random'ных символа, но меня смущают "..." в заголовке Можно, найдя это окно, сразу убрать эти 220 символов – тоже вариант, конечно, тогда эти "..." не так заметны будут. А ещё можно в добавок ко всему вместо этих 220 символов сделать random'ный набор из 10 пробелов и 255-х символов (2^10 = 1024 вариантов вполне достаточно для гарантии, что такого окна больше нигде нет) – это лучше, т.к. есть большая вероятность, что заголовок+10 пробелов не выйдут за границу заголовка. Добавлено Но мне всё равно почему-то кажется, что это не самый красивый вариант.... Добавлено А ещё прикол в том, что часть заголовка, содержащая текст, подсвечивается... и когда пробелы пропадут, эта подсветка пропадёт. Конечно, может, это и не будет заметно. Но не факт И ещё можно Hook поставить на создание окна, кстати |
Сообщ.
#7
,
|
|
|
Цитата Jin X @ мне интересен процесс поиска окна MessageBox'а! Причём, надо учесть, что окно может быть не Foreground, без заголовка, hWnd=0, и что может быть открыт ещё какой-то другой MessageBox Тогда остается единственный критерий того, что это твое окно - id процесса и\или потока окна. Отсюда варианты - GetGuiThreadInfo, EnumThreadWindows или EnumWindows с проверкой принадлежности окна по GetWindowThreadProcessID |
Сообщ.
#8
,
|
|
|
Цитата leo @ А при вызове MessageBox'а его окно будет принадлежать моего процессу? Тогда остается единственный критерий того, что это твое окно - id процесса и\или потока окна. |
Сообщ.
#9
,
|
|
|
Позор, такой большой, а маны не читаешь:
Цитата int WINAPI MessageBox( _In_opt_ HWND hWnd, _In_opt_ LPCTSTR lpText, _In_opt_ LPCTSTR lpCaption, _In_ UINT uType ); Parameters hWnd [in, optional] Type: HWND A handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window. |
Сообщ.
#10
,
|
|
|
Цитата Gonarh @ If this parameter is NULL, the message box has no owner window MessageBox(0, pMsgBuf, 'Error', 0); |
Сообщ.
#11
,
|
|
|
Ну и ССЗБ, передавай хендл и будет тебе счастье.
|
Сообщ.
#12
,
|
|
|
Руслан, в точку!
Gonarh, в том-то и дело, что MessageBox может вызываться без хэндла окна. А знаешь почему, например? Потому что приложение может не иметь окон в принципе! Например, оно консольное... ну или просто без окон... |
Сообщ.
#13
,
|
|
|
Цитата Jin X @ А при вызове MessageBox'а его окно будет принадлежать моего процессу? Конечно, и тому потоку, из которого вызвана функция MessageBox |
Сообщ.
#14
,
|
|
|
Ну тогда EnumThreadWindows – это вообще самый простой способ!
|
Сообщ.
#15
,
|
|
|
Если MessageBox - твой собственный, то можно создавать списки окон, принадлежащих текущему потоку, до и после создания мессаги, и таким образом находить хендл.
Что-то вроде такого: Любой поток func MyMsgBox(...) создать event отправить потоку-контролеру сообщение-сигнал, что будем создавать окно (WParam = hEvent, LParam = CurrentThreadID) ждать hEvent WinApi.MsgBox() закрыть hEvent Поток-контролер proc Execute крутить цикл выборки сообщений на сообщение-сигнал: получить список всех окон, принадлежащих потоку Msg.LParam взвести событие Msg.WParam повторить в течение N мсек: получить список всех окон, принадлежащих потоку Msg.LParam сравнить со старым списком появившийся хэндл = хэндлу мессаги Слабость данного метода в цикле "повторить в течение N мсек". Вызов WinApi.MsgBox может закончиться неудачей, и за это время поток может создать другое окно. Для избежания можно проверять результат WinApi.MsgBox и, например, ждать некоторое время в случае ошибки. |
Сообщ.
#16
,
|
|
|
Можно просто повесить хук на создание окна и не париться. Из хука вызывать EnumThreadWindows, чтобы получить хэндл (там будет только 1 окно, собственно).
|
Сообщ.
#17
,
|
|
|
Цитата Jin X @ там будет только 1 окно, собственно С чего бы? |
Сообщ.
#18
,
|
|
|
С того, что тред создаётся специально для вызова MessageBox'а.
|
Сообщ.
#19
,
|
|
|
А, если это ты контролируешь, то да.
|