I have a Problem with the del
Key in my MFC Application.
I have defined an Accelerator entry to use the del
key in my CTreeView.
My Application uses a split view. The CTreeView
is on the left panel and the CEdit
Control is on the right Panel inside a CFormView
.
The Entry is defined like this:
VK_DELETE, ID_EDIT_DELETE, VIRTKEY, NOINVERT
The ID_EDIT_DELETE
event is handled inside the CTreeView
.
After i added it, the del
Key stopped working inside the CEdit
Controls.
What do I have to do to restore the functionality in CEdit Control? Do i have to add something like:
ON_COMMAND(ID_EDIT_DELETE, &StationView::OnDelete)
to every Panel which contains an CEdit Control
? And then manually implement the delete Character Functionality?
Or is there an easier way to pass the del
Key event to the CEdit
Control?
UPDATE:
I overwrote the PreTranslateMessage
Method inside the CFormView
Class and the Del Key Press gets catched. But how do i proceed further?
UPDATE V2:
As asked here the Code for the Splitter Creation:
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.
The solution is to load the accelerator table and send the message to your edit control in case it's needed.
Here is the code:
CFormView
derived class, add HACCEL m_hAccelTable
member.Load the accelerator in overridden OnInitialUpdate
:
void CFormRight::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
}
Override the PreTranslateMessage
function in your CFormView
derived class.
We need to check there if this is a key message, if the focused window is edit control and if the has an accelerator.
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;
}
Finally, destroy the accelerator.
void CFormRight::OnDestroy()
{
CFormView::OnDestroy();
::DestroyAcceleratorTable(m_hAccelTable);
}