Я создал поле для редактирования, и оно работало очень хорошо, но после того, как я добавил для него собственный WndProc, текст «мое редактирование» не отображается и не будет фокусироваться при нажатии.
HWND handle=CreateWindowExW(0,L"Edit",L"my edit",WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_CENTER | ES_MULTILINE | ES_AUTOVSCROLL,
0,0,200,200,window.handle,0,GetModuleHandle(NULL),0);
Пока здесь все работало просто отлично
После того, как я установил эту оконную процедуру, элемент управления редактированием больше не работает должным образом
SetWindowLongPtr(handle,GWLP_WNDPROC,(LRESULT)staticWndProc);
LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam){
switch (uMsg){
case WM_LBUTTONDOWN:
std::wcout << handle << L" click\n"; //click event works
break;
default:
return DefWindowProcW(handle,uMsg,wParam,lParam);
}
return 0;
}
Нужно ли вручную обрабатывать какое-то событие или менять флаги моего стиля конструирования?
Подклассы включают в себя перехват сообщений для окна, возможно обработку некоторых из них и передачу тех, которые вы не обрабатываете, оригинальная процедура окна.
Вы этого не делаете — вы передаете все, с чем не справляетесь DefWindowProc
, DefWindowProc
не имеет какого-либо специального поведения для элемента управления редактирования (или даже для любого типа элемента управления). Таким образом, вы фактически превратили элемент управления для редактирования в обычное окно.
С помощью SetWindowLongPtr
подклассу окно не рекомендуется в эти дни, но если вы используете этот метод, возвращаемое значение от вызова к SetWindowLongPtr
дает вам старую оконную процедуру, и вы должны использовать CallWndProc
функция вместо DefWindowProc
называть это.
Однако современный способ создания подкласса окна — это использование SetWindowSubclass
функция, которая обрабатывает вызов оригинального процесса для вас — все, что вам нужно сделать, это вызвать DefSubclassProc
функция, как показано здесь:
LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR){
switch (uMsg){
case WM_LBUTTONDOWN:
std::wcout << handle << L" click\n"; //click event works
break;
case WM_NCDESTROY:
RemoveWindowSubclass(handle, staticWndProc, 0);
// fall through
default:
return DefSubclassProc(handle,uMsg,wParam,lParam);
}
return 0;
}
SetWindowSubclass(handle, staticWndProc, 0, 0);
Обратите внимание, что функция подкласса, показанная выше, удаляет себя, когда WM_NCDESTROY
получено.