纯C:对话默认处理Ctrl + C消息

时间:2017-08-26 12:20:28

标签: c winapi

标准Windows消息框具有按Ctrl + C复制其内容到剪贴板的功能。 好的,我决定自己尝试这样做。

这是我的对话资源:

IDD_MAIN DIALOGEX 0,0,500,250 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Information"
FONT 8, "MS Shell Dlg",0,0,0x1
    {   LTEXT   "I strongly recommend you to move all your user folders to disk D\:",ID_INFOTEXT,10,10,100,100
        CHECKBOX    "&Do not show this dialogue again",ID_SHOWSTATE,10,120,100,15
        DEFPUSHBUTTON   "&Ok",IDOK,273, 148, 100, 15
    }

对话创建得很好,一切都很好。 按预期选中/取消选中复选框,然后关闭对话框。

现在当你按下Ctrl + C时,你会听到一声丑陋的哔哔声。 我已经尝试在对话过程中处理Ctrl + C,但键击根本不会去那里。 现在我在子类控制窗口proc中使用了WM_GETDLGCODE,但也没有结果 - 无法摆脱那个丑陋的嘟嘟声而且Ctrl + C也没有去那里。

好的,我已经更换了一个windowProc来进行对话,但仍然没有结果 - 发出丑陋的哔哔声并且没有Ctrl + C..

所以最后的问题是那个丑陋的哔哔声来自哪里? DefWindowProc中的某个特殊消息处理? 我在哪里可以最终处理它并替换处理程序?

P上。 S.没有MFC,没有启动代码,没有.net,只有纯C和WinAPI。

2 个答案:

答案 0 :(得分:2)

对话管理器以特殊方式处理基于MessageBox的对话框,并向它们发送WM_COPY消息,以便它可以填充剪贴板。

蜂鸣声来自IsDialogMessage,因为使用键盘焦点的子控件不需要键盘输入。

要捕捉Ctrl + C按键并避免发出哔哔声,您必须在调用IsDialogMessage之前处理键盘消息。您可以致电TranslateAccelerator或进行自己的自定义处理:

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT Msg, WPARAM Wp, LPARAM Lp)
{
    switch(Msg)
    {
    case WM_CLOSE:
        DestroyWindow(hDlg);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_COPY:
        MessageBoxA(hDlg, "TODO: Set clipboard content here", 0, 0);
        break;
    }
    return FALSE;
}

BOOL IsKbdCopyMessage(HWND hDlg, MSG*pMsg)
{
    if (pMsg->message == WM_CHAR && pMsg->wParam == VK_CANCEL)
    {
        LRESULT dlgcod = SendMessage(pMsg->hwnd, WM_GETDLGCODE, pMsg->wParam, 0);
        if (!(dlgcod & (DLGC_WANTMESSAGE|DLGC_WANTCHARS)))
        {
            SendMessage(hDlg, WM_COPY, 0, 0);
            return TRUE;
        }
    }
    return FALSE;
}

...WinMain(...) 
{
    MSG msg;
    HWND hDlg = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
    while(GetMessage(&msg, 0, 0, 0))
    {
        if (IsKbdCopyMessage(hDlg, &msg)) continue;
        if (IsDialogMessage(hDlg, &msg)) continue;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

答案 1 :(得分:-1)

检测Ctrl-C的一种方法可能是在收到WM_KEYDOWN 0x43virtual key-code C键)时wParam调用{{3}并测试其设置VK_CONTROL的结果。

您可以通过监控WM_KEYUP消息以及相关的“虚拟密钥代码”来自行跟踪Ctrl键的状态来避免呼叫GetAsyncKeyState()