Winapi 检测CTRL+;箱子里的一只猫

Winapi 检测CTRL+;箱子里的一只猫,winapi,textbox,keyboard-events,Winapi,Textbox,Keyboard Events,我有一个主窗口和一个多行编辑文本框: hwndEdit = CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 300, 200, hwndMain, 0, (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL); 我用它来检测文本框中的CTRL+A(因为奇怪的是,它不是现成的):

我有一个主窗口和一个多行编辑文本框:

hwndEdit = CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 300, 200, hwndMain, 0, (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);
我用它来检测文本框中的CTRL+A(因为奇怪的是,它不是现成的):

不幸的是,当我按CTRL+A或CTRL+B或CTRL+anything时,什么都不会发生

怎么了?


注意:好的,检测A的代码仍然缺失(我仍然不知道如何做),但是这里的代码应该适用于任何CTRL+键…

只需检查WM\U KEYDOWN的A,然后使用GetKeyState

case WM_KEYDOWN:
  {
    if (wParam=='A' && (::GetKeyState(VK_CONTROL) & 0x8000)!=0)
    {
      SendMessage(hwndEdit, EM_SETSEL, 0, -1);    // select all
    }

请记住,WM_KEYDOWN仅发送到具有焦点的窗口,而不发送到父窗口。

创建所有窗口后:

hwndEdit = CreateWindowEx(.....)
...

//Subbclassing
SetWindowSubclass(hwndEdit, (SUBCLASSPROC)EditWndProc, 0, 1);


LRESULT CALLBACK EditWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwrefData){

    switch(message){ //handle the messages   
        case WM_KEYDOWN:
            //your code

           break;
        default:   //for messages that we don't deal with
            return DefSubclassProc(hwnd, message, wParam, lParam);
    }

    return DefSubclassProc(hwnd, message, wParam, lParam);
}

标准编辑控件将已经处理Ctrl+A。不要破坏它,您将不必重新实现它。WM_KEYDOWN消息将发送到编辑控件,而不是您的窗口。强制阅读:,以防您要覆盖默认实现(无论如何,在某些地区选择整个内容)。@IInspectable我不想覆盖CTRL+A,我想允许使用CTRL+A进行“全选”,因为,我不知道为什么,但CTRL+A在我的编辑中默认不起作用。。。(它适用于所有其他软件)。默认情况下,CTRL+A对您有效吗?当您有一些消息处理功能,如加速器,并且此加速器也使用CTRL+A时,您的编辑控件将不会收到任何键。它不起作用。顺便说一句,我甚至尝试了
case WM_KEYWDOWN:{MessageBox(…)}
但是什么都没有发生:当我在
编辑
文本框中写入时,似乎根本没有触发主窗口的
WM_KEYWDOWN
。。。为什么?@Basj:“记住WM_KEYDOWN只发送到有焦点的窗口,而不发送到父窗口。”那么我应该有两个函数LRESULT CALLBACK WindowProc(HWND-HWND,UINT-uMsg,WPARAM-WPARAM,LPARAM-LPARAM)吗?一个用于主窗口,另一个用于编辑窗口?有没有办法只用一个@IInspectable就可以做到这一点?@Basj:是的,子类控件需要一个窗口过程。但是,我建议您实际修复这个bug,而不是解决它。您打破了标准功能,现在修复它。@xMRi和γηράσκωδαεπλλδδδδσκμε:两个答案的结合解决了问题。我应该接受哪一个?进退两难@Basj你的问题由xMRi回答,所以他应该得到答案。我刚刚帮你做了子类化。再次非常感谢!
hwndEdit = CreateWindowEx(.....)
...

//Subbclassing
SetWindowSubclass(hwndEdit, (SUBCLASSPROC)EditWndProc, 0, 1);


LRESULT CALLBACK EditWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwrefData){

    switch(message){ //handle the messages   
        case WM_KEYDOWN:
            //your code

           break;
        default:   //for messages that we don't deal with
            return DefSubclassProc(hwnd, message, wParam, lParam);
    }

    return DefSubclassProc(hwnd, message, wParam, lParam);
}