Указание процедуры окна для дочерних окон

Я хотел бы знать, возможно ли указать WndProc для дочернего окна, созданного CreateWindowEx,

Я уже создал класс окна, главное окно, процедуру окна и цикл сообщений. Код работает, и я решил оставить его для ясности моего вопроса.

Это мой Window Proc, пока:

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
// Creation of the Win32 Window
case WM_CREATE:
// Add an Edit Field
CreateWindowEx(
WS_EX_CLIENTEDGE,
"EDIT",
"",
WS_CHILD | WS_VISIBLE,
5, 5, 200, 24,
hwnd,
(HMENU)100,
g_Instance, // Comming from WinMain
NULL
);
return DefWindowProc(hwnd, uMsg, lParam, wParam);
case WM_KEYDOWN:
// Track key presses on the edit field
std::cout << "The key with the code " << wParam << " was pressed." << std::endl;
return 0;
case WM_PAINT:
// Some painting code...
return DefWindowProc(hwnd, uMsg, lParam, wParam);
default:
return DefWindowProc(hwnd, uMsg, lParam, wParam);
}
}

Я ожидал нажатия клавиш на дочернем поле редактирования, которое я создал, чтобы выдать сообщение WM_KEYDOWN, но они этого не делают! Ключи просто добавляются в поле редактирования в моем окне, но не вызывают сообщение WM_KEYDOWN.

Кажется, что созданное окно редактирования не использует мой WndProc. Как я могу это изменить?

5

Решение

Ваш WndProc не получить WM_KEYDOWN сообщения, потому что, если пользователь печатает внутри элемента управления редактирования, это означает, что он имеет фокус (не ваше окно), поэтому они отправляются в редактировать контроль оконный процесс, а не ваш. Тем не менее, Proc окна редактирования редактирования будет отправлять уведомления на ваш WndProc (его родительское окно прок).

Так что, если вы хотите только реагировать на пользователя изменения содержание вашего дочернего элемента управления редактированием, вам не нужна другая оконная процедура. Ваш текущий WndProc получит EN_CHANGE код уведомления через WM_COMMAND сообщение.

Увидеть https://msdn.microsoft.com/en-us/library/windows/desktop/bb761676(v=vs.85).aspx


Если вы действительно хотите поймать WM_KEYDOWN сообщения, вы должны создать подкласс управления редактирования, как это:

OldWndProc = (WNDPROC)SetWindowLongPtr (hButton, GWLP_WNDPROC, (LONG_PTR)NewWndProc);

Вам также необходимо определить новую процедуру Windows ( NewWndProc), что должно обрабатывать WM_KEYDOWN сообщение (и любое другое сообщение, которое вы хотите обработать). Вам также нужно позвонить OldWndProc как бы вы назвали DefWndProc в стандарте WndProc, если вы не хотите, чтобы элемент управления редактирования выполнял свою обычную обработку.

Для получения дополнительной информации о создании подклассов см. https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183(v=vs.85).aspx

редактировать

Отвечая на комментарий OP здесь.

Если ваше окно является диалоговым окном, вы должны быть уведомлены о вводе ключа, в вашем WndProc:

 case WM_COMMAND:

if(wParam=IDOFDEFBUTTON || IDOK) ...

Увидеть https://support2.microsoft.com/Default.aspx?scid=kb;en-us;Q102589

Если честно, я так и не удосужился понять, что такое диалоговое окно действительно является. Но если я правильно помню, вы можете получить свое окно для получения специальных уведомлений, вызвав IsDialogMessage в своем насосе сообщений:

if(!IsDialogMessage(hWnd,&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

За интересную информацию о IsDialogMessage, увидеть http://blogs.msdn.com/b/oldnewthing/archive/2012/04/16/10293933.aspx

Если это не дает достаточного контроля, вам, вероятно, придется разделить элемент управления на подклассы.

7

Другие решения

Ваш вызов CreateWindowsEx создает новое окно с классом «EDIT» wnd, имеющим собственную процедуру Window. Вам нужен новый WndProc и установить его во вновь созданное окно (чей дескриптор возвращается CreateWindowEx) через функцию SetClassLong

2

По вопросам рекламы [email protected]