在 CComboBox 的编辑控件中检测键盘热键
Detect keyboard hotkey inside edit control of CComboBox
我有这个代码:
BOOL CChristianLifeMinistryStudentMaterialDlg::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch, bDealtWith;
bDealtWith = FALSE;
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
{
if (EncodeText(pMsg->hwnd, _T("i")))
{
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
}
else if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
{
if (EncodeText(pMsg->hwnd, _T("b")))
{
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
}
if (!bDealtWith)
bNoDispatch = CDialogEx::PreTranslateMessage(pMsg);
return bNoDispatch;
}
最初,我的对话框上有 3 个 CEdit
控件。当您使用此键时,它会在编辑控件中对 selection 执行上述操作。
我将控件从 CEdit
更改为 CComboBox
。它们是可编辑类型。我将 EncodeText
调整为使用 GetEditSel
和 SetEditSel
.
现在唯一的问题是当我在组合框中编辑文本时。我 select 一些文本并按 CTRL + I 没有任何反应。我的对话的 PTM 没有被拦截。
视觉示例
在这个CEdit
控件中我可以select文本:
然后我使用其中一个热键,例如:CTRL + B,它仍然有效:
但是,当我 select 可编辑 CComboBox
中的一些文本并使用相同的热键时:
在这种情况下它不起作用。
我假设这是因为从技术上讲我在组合的嵌入式“编辑”控件中。既然我在组合中使用 selected 文本,我如何仍然检测热键?
我最终创建了一个新的 class CEncodedCombBox
,派生自 CComboBox
,如下所示:
// EncodedComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "Meeting Schedule Assistant.h"
#include "EncodedComboBox.h"
// CEncodedComboBox
IMPLEMENT_DYNAMIC(CEncodedComboBox, CComboBox)
CEncodedComboBox::CEncodedComboBox()
{
}
CEncodedComboBox::~CEncodedComboBox()
{
}
BEGIN_MESSAGE_MAP(CEncodedComboBox, CComboBox)
END_MESSAGE_MAP()
// CEncodedComboBox message handlers
BOOL CEncodedComboBox::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch, bDealtWith;
DWORD dwSel = GetEditSel();
CString strCode = _T(""), strText;
GetWindowText(strText);
bDealtWith = FALSE;
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
{
strCode = _T("i");
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
else if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
{
strCode = _T("b");
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
if (bDealtWith)
{
CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
SetWindowText(strText);
SetEditSel(HIWORD(dwSel) + 7, HIWORD(dwSel) + 7);
}
if (!bDealtWith)
bNoDispatch = CComboBox::PreTranslateMessage(pMsg);
return bNoDispatch;
}
如您所见,它包含一个 PreTranslateMessage
并且有效:
如果有更好的方法欢迎大家评论或回答
更新
我必须针对编辑控件句柄进行测试,而不是组合框句柄才能让我自己的 CDialog
工作:
if (::GetParent(hWnd) == m_cbMaterialAssignment1.GetSafeHwnd())
不再需要派生组合 class。
不确定我是否喜欢 WM_KEYDOWN
hack。如果你有真正的热键,我建议你正确处理它们:
BEGIN_MESSAGE_MAP(CEncodedCombBox, CCombBox)
ON_WM_HOTKEY()
END_MESSAGE_MAP()
void CEncodedCombBox::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
if (nHotKeyId == idForHotKey_I)
HandleCode(_T("i"));
else if (nHotKeyId == idForHotKey_B)
HandleCode(_T("b"));
}
void CEncodedCombBox::HandleCode(CString strCode)
{
DWORD dwSel = GetEditSel();
CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
SetWindowText(strText);
SetEditSel(LOWORD(dwSel), HIWORD(dwSel) + 7);
}
我有这个代码:
BOOL CChristianLifeMinistryStudentMaterialDlg::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch, bDealtWith;
bDealtWith = FALSE;
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
{
if (EncodeText(pMsg->hwnd, _T("i")))
{
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
}
else if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
{
if (EncodeText(pMsg->hwnd, _T("b")))
{
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
}
if (!bDealtWith)
bNoDispatch = CDialogEx::PreTranslateMessage(pMsg);
return bNoDispatch;
}
最初,我的对话框上有 3 个 CEdit
控件。当您使用此键时,它会在编辑控件中对 selection 执行上述操作。
我将控件从 CEdit
更改为 CComboBox
。它们是可编辑类型。我将 EncodeText
调整为使用 GetEditSel
和 SetEditSel
.
现在唯一的问题是当我在组合框中编辑文本时。我 select 一些文本并按 CTRL + I 没有任何反应。我的对话的 PTM 没有被拦截。
视觉示例
在这个CEdit
控件中我可以select文本:
然后我使用其中一个热键,例如:CTRL + B,它仍然有效:
但是,当我 select 可编辑 CComboBox
中的一些文本并使用相同的热键时:
在这种情况下它不起作用。
我假设这是因为从技术上讲我在组合的嵌入式“编辑”控件中。既然我在组合中使用 selected 文本,我如何仍然检测热键?
我最终创建了一个新的 class CEncodedCombBox
,派生自 CComboBox
,如下所示:
// EncodedComboBox.cpp : implementation file
//
#include "stdafx.h"
#include "Meeting Schedule Assistant.h"
#include "EncodedComboBox.h"
// CEncodedComboBox
IMPLEMENT_DYNAMIC(CEncodedComboBox, CComboBox)
CEncodedComboBox::CEncodedComboBox()
{
}
CEncodedComboBox::~CEncodedComboBox()
{
}
BEGIN_MESSAGE_MAP(CEncodedComboBox, CComboBox)
END_MESSAGE_MAP()
// CEncodedComboBox message handlers
BOOL CEncodedComboBox::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch, bDealtWith;
DWORD dwSel = GetEditSel();
CString strCode = _T(""), strText;
GetWindowText(strText);
bDealtWith = FALSE;
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
{
strCode = _T("i");
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
else if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
{
strCode = _T("b");
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
if (bDealtWith)
{
CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
SetWindowText(strText);
SetEditSel(HIWORD(dwSel) + 7, HIWORD(dwSel) + 7);
}
if (!bDealtWith)
bNoDispatch = CComboBox::PreTranslateMessage(pMsg);
return bNoDispatch;
}
如您所见,它包含一个 PreTranslateMessage
并且有效:
如果有更好的方法欢迎大家评论或回答
更新
我必须针对编辑控件句柄进行测试,而不是组合框句柄才能让我自己的 CDialog
工作:
if (::GetParent(hWnd) == m_cbMaterialAssignment1.GetSafeHwnd())
不再需要派生组合 class。
不确定我是否喜欢 WM_KEYDOWN
hack。如果你有真正的热键,我建议你正确处理它们:
BEGIN_MESSAGE_MAP(CEncodedCombBox, CCombBox)
ON_WM_HOTKEY()
END_MESSAGE_MAP()
void CEncodedCombBox::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
if (nHotKeyId == idForHotKey_I)
HandleCode(_T("i"));
else if (nHotKeyId == idForHotKey_B)
HandleCode(_T("b"));
}
void CEncodedCombBox::HandleCode(CString strCode)
{
DWORD dwSel = GetEditSel();
CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
SetWindowText(strText);
SetEditSel(LOWORD(dwSel), HIWORD(dwSel) + 7);
}