Пользовательские элементы управления и сообщения Windows - PullRequest
0 голосов
/ 19 августа 2011

Я сделал пользовательский элемент управления Splitter в чистом Windows API. Он состоит из 4 элементов управления: основной контейнер, сплиттер и 2 панели.

Теперь мне нужно было подключиться к процедуре Windows, чтобы узнать, когда один из его дочерних элементов управления перемещался или изменял размеры, поэтому я использовал SetWindowsHookEx . Я получаю сообщения WM_SIZE в моей процедуре подключения просто отлично, но никакие сообщения WM_MOVE никогда не перехватываются из дочерних окон моего Splitter.

Я попытался добавить дочернее окно в Groupbox (я знаю, что это не тот способ, которым они должны использоваться), просто чтобы посмотреть, были ли сообщения WM_MOVE перехвачены процедурой подключения, они были.

Так чего мне здесь не хватает? Что мне нужно добавить в процедуру окна Splitter, чтобы эти WM_MOVE s были отправлены? Или моя ошибка была где-то еще?

PS: SetWindowPos работает на этих дочерних окнах, просто не перехватывает WM_MOVE .

РЕДАКТИРОВАТЬ: По запросу, вот полный код класса окна Splitter: http://pastebin.com/Lgvb0Vfv

Вот часть кода, которая имеет значение:

LRESULT WINAPI AnchorProc(int nCode, WPARAM wParam, LPARAM lParam) {
    CWPRETSTRUCT* theMessage = (CWPRETSTRUCT*)lParam;

    if (theMessage->message == WM_MOVE) printf ("!");
}    

Через некоторое время после главного окна WM_CREATE :

SetWindowsHookEx(WH_CALLWNDPROCRET,AnchorProc,NULL,GetCurrentThreadId());

// groupbox

HWND gb = CreateWindowEx(0,"button",NULL,BS_GROUPBOX|WS_CHILD,0,0,200,200,hwndMain,0,hInst,NULL);
HWND but = CreateWindowEx(0,"button",NULL,BS_PUSHBUTTON|WS_CHILD,0,0,40,40,gb,0,hInst,NULL);

// custom control

HWND split = CreateWindowEx(0,"FSplitterClass",NULL,WS_CHILD,200,0,200,200,hwndMain,0,hInst,NULL);
HWND pane1 = (HWND)SendMessage(split,WM_SPGETPANE,0,0);
HWND but1 = CreateWindowEx(0,"button",NULL,BS_PUSHBUTTON|WS_CHILD,0,0,40,40,pane1,0,hInst,NULL);

SetWindowPos(but, NULL, 1,1,0,0,SWP_NOSIZE|SWP_NOZORDER); // triggers WM_MOVE
SetWindowPos(but1, NULL, 1,1,0,0,SWP_NOSIZE|SWP_NOZORDER); // doesn't

1 Ответ

5 голосов
/ 20 августа 2011
  1. Крюк для окон здесь лишний.Подклассы намного эффективнее.
  2. WM_MOVE генерируется только , если оконная процедура передает сообщение WM_WINDOWPOSCHANGED в DefWindowProc .Если вы не можете гарантировать это, то вам не гарантировано сообщение WM_MOVE.Прослушайте WM_WINDOWPOSCHANGED.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...