MFC CEdit 控件在添加到加速器后不处理按键
MFC CEdit Control does not handle Key Pressed after added to Accelerator
我的 MFC 应用程序中的 del
键有问题。
我在 CTreeView.
中定义了一个加速器条目以使用 del
键
我的应用程序使用拆分视图。 CTreeView
在左侧面板上,CEdit
控件在 CFormView
.
内的右侧面板上
条目定义如下:
VK_DELETE, ID_EDIT_DELETE, VIRTKEY, NOINVERT
ID_EDIT_DELETE
事件在 CTreeView
内部处理。
添加后,del
键在 CEdit
控件内停止工作。
我需要做什么才能恢复 CEdit 控件中的功能?
我是否必须添加类似的内容:
ON_COMMAND(ID_EDIT_DELETE, &StationView::OnDelete)
到包含 CEdit Control
的每个面板?然后手动实现删除字符功能?
或者是否有更简单的方法将 del
键事件传递给 CEdit
控件?
更新:
我覆盖了 CFormView
Class 中的 PreTranslateMessage
方法,Del 键按下被捕获。但是我该如何继续呢?
更新 V2:
如这里所问,创建拆分器的代码:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) {
// create splitter window
if (!m_wndSplitter.CreateStatic(this, 1, 2)) {
return FALSE;
}
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(250, 1000), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CLineSyncView), CSize(500, 1000), pContext)) {
m_wndSplitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
MFC has default implementation for menu handlers and accelerator keys
that AppWizard adds to your application to handle these functions.
These menu handlers get the accelerator keystrokes instead of your
edit control.
解决方案是加载加速器 table 并在需要时将消息发送到您的编辑控件。
代码如下:
- 在您的
CFormView
派生 class 中,添加 HACCEL m_hAccelTable
成员。
加载加速器覆盖 OnInitialUpdate
:
void CFormRight::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
}
覆盖 CFormView
派生的 class 中的 PreTranslateMessage
函数。
我们需要在那里检查这是否是关键消息,焦点 window 是否是编辑控件以及是否有加速器。
BOOL CFormRight::PreTranslateMessage(MSG* pMsg)
{
if (m_hAccelTable)
{
// cheaper to check the message range then TranslateAccelerator
if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
{
CWnd* pWnd = GetFocus();
if (IsEdit(pWnd) && ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
{
pWnd->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
return FALSE;
}
}
}
return CFormView::PreTranslateMessage(pMsg);
}
BOOL CFormRight::IsEdit(CWnd* pWnd)
{
ASSERT(pWnd != NULL);
HWND hWnd = pWnd->GetSafeHwnd();
if (hWnd == NULL)
return FALSE;
TCHAR szClassName[6];
return ::GetClassName(hWnd, szClassName, 6) &&
_tcsicmp(szClassName, _T("Edit")) == 0;
}
最后,摧毁加速器
void CFormRight::OnDestroy()
{
CFormView::OnDestroy();
::DestroyAcceleratorTable(m_hAccelTable);
}
另一种方法是处理ON_UPDATE_COMMAND_UI:
ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, &StationView::OnDelete)
和
void StationView::OnDelete(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(! IsEdit(GetFocus())); // see previous post for IsEdit method
}
但是,我没有尝试过这个。你试试:)
P.S。如何实现 IsEdit(取自之前的 post):
BOOL CFormRight::IsEdit(CWnd* pWnd)
{
ASSERT(pWnd != NULL);
HWND hWnd = pWnd->GetSafeHwnd();
if (hWnd == NULL)
return FALSE;
TCHAR szClassName[6];
return ::GetClassName(hWnd, szClassName, 6) &&
_tcsicmp(szClassName, _T("Edit")) == 0;
}
我的 MFC 应用程序中的 del
键有问题。
我在 CTreeView.
del
键
我的应用程序使用拆分视图。 CTreeView
在左侧面板上,CEdit
控件在 CFormView
.
条目定义如下:
VK_DELETE, ID_EDIT_DELETE, VIRTKEY, NOINVERT
ID_EDIT_DELETE
事件在 CTreeView
内部处理。
添加后,del
键在 CEdit
控件内停止工作。
我需要做什么才能恢复 CEdit 控件中的功能? 我是否必须添加类似的内容:
ON_COMMAND(ID_EDIT_DELETE, &StationView::OnDelete)
到包含 CEdit Control
的每个面板?然后手动实现删除字符功能?
或者是否有更简单的方法将 del
键事件传递给 CEdit
控件?
更新:
我覆盖了 CFormView
Class 中的 PreTranslateMessage
方法,Del 键按下被捕获。但是我该如何继续呢?
更新 V2:
如这里所问,创建拆分器的代码:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) {
// create splitter window
if (!m_wndSplitter.CreateStatic(this, 1, 2)) {
return FALSE;
}
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(250, 1000), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CLineSyncView), CSize(500, 1000), pContext)) {
m_wndSplitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
MFC has default implementation for menu handlers and accelerator keys that AppWizard adds to your application to handle these functions. These menu handlers get the accelerator keystrokes instead of your edit control.
解决方案是加载加速器 table 并在需要时将消息发送到您的编辑控件。
代码如下:
- 在您的
CFormView
派生 class 中,添加HACCEL m_hAccelTable
成员。 加载加速器覆盖
OnInitialUpdate
:void CFormRight::OnInitialUpdate() { CFormView::OnInitialUpdate(); m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); }
覆盖
CFormView
派生的 class 中的PreTranslateMessage
函数。 我们需要在那里检查这是否是关键消息,焦点 window 是否是编辑控件以及是否有加速器。BOOL CFormRight::PreTranslateMessage(MSG* pMsg) { if (m_hAccelTable) { // cheaper to check the message range then TranslateAccelerator if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST) { CWnd* pWnd = GetFocus(); if (IsEdit(pWnd) && ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg)) { pWnd->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam); return FALSE; } } } return CFormView::PreTranslateMessage(pMsg); } BOOL CFormRight::IsEdit(CWnd* pWnd) { ASSERT(pWnd != NULL); HWND hWnd = pWnd->GetSafeHwnd(); if (hWnd == NULL) return FALSE; TCHAR szClassName[6]; return ::GetClassName(hWnd, szClassName, 6) && _tcsicmp(szClassName, _T("Edit")) == 0; }
最后,摧毁加速器
void CFormRight::OnDestroy() { CFormView::OnDestroy(); ::DestroyAcceleratorTable(m_hAccelTable); }
另一种方法是处理ON_UPDATE_COMMAND_UI:
ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, &StationView::OnDelete)
和
void StationView::OnDelete(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(! IsEdit(GetFocus())); // see previous post for IsEdit method
}
但是,我没有尝试过这个。你试试:)
P.S。如何实现 IsEdit(取自之前的 post):
BOOL CFormRight::IsEdit(CWnd* pWnd)
{
ASSERT(pWnd != NULL);
HWND hWnd = pWnd->GetSafeHwnd();
if (hWnd == NULL)
return FALSE;
TCHAR szClassName[6];
return ::GetClassName(hWnd, szClassName, 6) &&
_tcsicmp(szClassName, _T("Edit")) == 0;
}