Элемент редактирования не может получить фокус или установить текст после создания подкласса

Я создал поле для редактирования, и оно работало очень хорошо, но после того, как я добавил для него собственный 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;
}

Нужно ли вручную обрабатывать какое-то событие или менять флаги моего стиля конструирования?

1

Решение

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

Вы этого не делаете — вы передаете все, с чем не справляетесь 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 получено.

4

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector