Какие есть способы кроме хуков и замены оконных функций через SetWindowlong? Сейчас использую комбинацию этих двух методов. Задача в изменении поведения окон в проекте на Deiphi(VCL) при минимизации. Отслеживать очередь сообщений потока бесполезно так как сообщение о минимизации видимо отправляется в оконную процедуру напрямую её (процедуры) вызовом. Хочется не пустить сообщение к окну , для этого я подменяю оконную функцию после срабатыванию хука на вызов любой оконной функции в контексте потока.
GetMessage извлекает сообщение из очереди сообщений. Судя по моим экспериментам сообщение о минимизации окна не проходит через очередь сообщений приложения.
И как я с помощью Spy++ изменю поведение Vcl окна? Мне его грузить как dll? Или предлагать юзеру запустить и самостоятельно рулить дальше? GetMessage извлекает сообщение из очереди. Сообщение которое мне нужно не пустить к окну - WM_SYSCOMMAND c wParam = SC_MINIMIZE не ставится в очередь. Я могу его перехватить хуком но не могу его хуком изменить.
Я знаю что ставится в момент минимизации. Меня не устраивают методы перехваты в виде хуков или подмены оконной процедуры. Да не все сообщения проходят через очередь. Внезапно да. В MSDN описаны Nonqueued Messages.
CrazyFun Вряд ли для минимизации используется Nonqueued Messages. Был какой-то кошерный монитор виндовых сообщений. Spy++ - это так, поделка. Надо отмониторить все, что шлется окну во время минимизации.
Результаты в студию. Или будет беспредметный разговор ни о чем. А про Дельфи вообще лучше спрашивать и смотреть на профильных форумах. Там все очень по-другому.
Дельфийского кода и IDE дома нет, повторил на VS2010. Создал шаблонный оконный проект Win32, установил хук типа Код (Text): Hook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 0, GetCurrentThreadId() ); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } UnhookWindowsHookEx(Hook); Вот код процедуры хука. MessageBox появляется только по ветке SC_RESTORE, в отладчике тоже встает только туда. Код (Text): LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam) { PMSG pMsg = (PMSG)lParam; if (code == HC_ACTION) { if (pMsg->message == WM_SYSCOMMAND) switch(pMsg->wParam) { case SC_MINIMIZE: MessageBox(NULL, (LPCWSTR)L"SC_MINIMIZE", (LPCWSTR)L"WM_SYSCOMMAND", MB_OK); break; case SC_RESTORE: MessageBox(NULL, (LPCWSTR)L"SC_RESTORE", (LPCWSTR)L"WM_SYSCOMMAND", MB_OK); break; } } return CallNextHookEx(Hook, code, wParam, lParam); } Хук типа WH_CALLWNDPROC позволяет отловить сообщение, но не позволяет его модифицировать (чтобы это обойти я подменяю оконную функцию, после обработки сообщения возвращаю). Отрывок из лога Spy++. Если я правильно понимаю то S - значит Send а не Post, тоесть какраз сообщение идущее в обход очереди <00048> 00201582 S WM_SYSCOMMAND uCmdType:SC_MINIMIZE xPos:1149 yPos:151 <00049> 00201582 S WM_KILLFOCUS hwndGetFocusnull) <00050> 00201582 R WM_KILLFOCUS <00051> 00201582 S WM_IME_SETCONTEXT fSet:0 iShow:C000000F <00052> 00201582 S WM_IME_NOTIFY dwCommand:IMN_CLOSESTATUSWINDOW dwCommand:00000001 dwData:00000000 <00053> 00201582 R WM_IME_NOTIFY <00054> 00201582 R WM_IME_SETCONTEXT <00055> 00201582 S WM_WINDOWPOSCHANGING lpwp:003EF3E4 <00056> 00201582 S WM_GETMINMAXINFO lpmmi:003EF008 <00057> 00201582 R WM_GETMINMAXINFO lpmmi:003EF008 <00058> 00201582 R WM_WINDOWPOSCHANGING <00059> 00201582 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:003EF3BC <00060> 00201582 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:003EF3BC <00061> 00201582 S WM_WINDOWPOSCHANGED lpwp:003EF3E4 <00062> 00201582 S WM_MOVE xPos:33536 yPos:33536 <00063> 00201582 R WM_MOVE <00064> 00201582 S WM_SIZE fwSizeType:SIZE_MINIMIZED nWidth:0 nHeight:0 <00065> 00201582 R WM_SIZE <00066> 00201582 R WM_WINDOWPOSCHANGED <00067> 00201582 S WM_NCACTIVATE fActive:False <00068> 00201582 R WM_NCACTIVATE fDeactivateOK:True <00069> 00201582 S WM_ACTIVATE fActive:WA_INACTIVE fMinimized:True hwndPreviousnull) <00070> 00201582 R WM_ACTIVATE <00071> 00201582 S WM_ACTIVATEAPP fActive:False dwThreadID:0000113C <00072> 00201582 R WM_ACTIVATEAPP <00073> 00201582 R WM_SYSCOMMAND <00074> 00201582 P WM_NCMOUSELEAVE
Да Send идет напрямую в процедуру окна. (Минуя очередь)-чушь) - оно синхронное. Шлется SendMessage. Думаю S - это оно самое