如何禁用 CComboBox mfc 键盘导航?

发布于 2024-10-11 08:14:30 字数 65 浏览 3 评论 0原文

我如何禁用 CComboBox mfc 键盘导航,当我在打开的下拉列表中按下键盘上的键时,我需要不得选择项目。谢谢!

How i can disable CComboBox mfc keyboard navigation, i need when i press key on keyboard with open dropdown list, item must not selecting. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一人独醉 2024-10-18 08:14:30

如果您真的只是想:“如何禁用控件被更改?”,那么只需调用 CComboBox 上的 EnableWindow 方法即可。

但是,如果您真的只想阻止键盘消息击中控件,请使用 窗口子类化以吞咽键盘消息。 (不要将术语“窗口子类化”与 C++ 类混淆 - 不是同一件事)。基本上,我们将拦截与组合框关联的所有 WM_CHAR 和 WM_KEYDOWN 消息,并让所有其他消息通过。

执行此操作:

WNDPROC g_prevFunc = NULL;

LRESULT MyWindowHook(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if ((uMsg == WM_CHAR) || (uMsg == WM_KEYDOWN) || (uMsg == WM_KEYUP))
    {
        return 0; // swallow message
    }

    return ::CallWindowProcW(g_prevFunc, hWnd, uMsg, wParam, lParam);
}


void MySubclassWindow(HWND hwnd)
{
    g_prevFunc = (WNDPROC)::SetWindowLongW(hwnd, GWL_WNDPROC, (LONG_PTR)MyWindowHook);
}

// wherever your code gets initialized
CYourWindow::OnInit()
{
   // whatever other initialization you got going on...

  // I'm assuming your CComboBox is named something like m_combobox.

  ::MySubclassWindow(m_combobox.m_hWnd);

}

仔细检查以确保这不会破坏 Tab 键导航。我刚刚尝试过,看起来效果很好。您可能不需要吞咽 WM_CHAR,只可能需要吞咽 WM_KEYUP 和 WM_KEYDOWN。您可能需要进行一些实验。

CWnd 类上还有一个名为 SubclassWindow 的 MFC 方法。所以如果你想使用纯MFC,你也可以研究一下。

If you really just mean: "how do I disable the control from being changed?", then just call the EnableWindow method on the CComboBox.

But if you really mean you just want to block keyboard messages from hitting the control, then use window subclassing to swallow keyboard messages. (Don't confuse the term "window subclassing" with C++ classes - not the same thing). Basically, we're just going to intercept all WM_CHAR and WM_KEYDOWN messages associated with the combo box and let all the other messages pass.

Do this:

WNDPROC g_prevFunc = NULL;

LRESULT MyWindowHook(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if ((uMsg == WM_CHAR) || (uMsg == WM_KEYDOWN) || (uMsg == WM_KEYUP))
    {
        return 0; // swallow message
    }

    return ::CallWindowProcW(g_prevFunc, hWnd, uMsg, wParam, lParam);
}


void MySubclassWindow(HWND hwnd)
{
    g_prevFunc = (WNDPROC)::SetWindowLongW(hwnd, GWL_WNDPROC, (LONG_PTR)MyWindowHook);
}

// wherever your code gets initialized
CYourWindow::OnInit()
{
   // whatever other initialization you got going on...

  // I'm assuming your CComboBox is named something like m_combobox.

  ::MySubclassWindow(m_combobox.m_hWnd);

}

Double check to make sure this doesn't break tab key navigation. I just tried and it seems to work fine. You may not need to swallow WM_CHAR, just might need to swallow WM_KEYUP and WM_KEYDOWN. Some experimentation on your part is likely needed.

There's also an MFC method on the CWnd class called SubclassWindow. So if you want to go pure MFC, you can look into this as well.

数理化全能战士 2024-10-18 08:14:30

无需子类化组合框的一个简单解决方案是将其第一个子窗口(即 CEdit 框)设置为只读,如下所示:

GetDlgItem(IDC_MY_COMBO)->GetWindow(GW_CHILD)->SendMessage(EM_SETREADONLY, 1, 0);

A simple solution without subclassing the combobox is to set its first child window (which is the CEdit box) to readonly, like this :

GetDlgItem(IDC_MY_COMBO)->GetWindow(GW_CHILD)->SendMessage(EM_SETREADONLY, 1, 0);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文