Метод PreTranslateMessage не получает вызванный порядок для реализации Ctrl+A в C++
Я пытаюсь реализовать Ctrl+A в элементе управления редактирования заметки:m_editNoteTypeView", который является экземпляром cEdit внутри класса NoteDialog. Редактирование моей заметки создается, как показано ниже.
NoteDialog::initDialog()
{
m_editNoteTypeView.CreateEx(::GetWindowLong(m_editSubject.m_hWnd, GWL_EXSTYLE), "edit", "", dwStyle | ES_READONLY, CRect(0, 0, 0, 0), this, 0);
m_editNoteTypeView.SetSel(0,-1,TRUE);
}
Класс NoteDialog является производным от другого класса с именем Sdialog, который в конечном итоге является производным от CDialog
,
Я определил PreTranslateMessage(MSG* pMsg)
в SDialog, но управление не идет к PreTranslateMessage, поэтому я не могу проверить, какую клавишу я нажимаю на keboard, когда я печатаю при редактировании заметки.
bool Sdialog::PreTranslateMessage(MSG* pMsg)
{
if (GetFocus() == this)
{
if (pMsg->message == WM_CHAR)
{
if ((LOWORD(pMsg->wParam) & VK_CONTROL) == VK_CONTROL)
{
//SetSel(0, -1);
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
1 ответ
return
тип для PreTranslateMessage
должно быть BOOL
иначе вы получите ошибку компиляции в MFC.
if (pMsg->message == WM_CHAR)
if ((LOWORD(pMsg->wParam) & VK_CONTROL) == VK_CONTROL)
{...}
WM_CHAR
сообщение не несет VK_CONTROL
в wParam
,
Чтобы перехватить Ctrl + A:
- Ждать
WM_KEYDOWN
сообщение - Проверьте ключ
- Проверьте, нажата ли клавиша Ctrl
Таким образом:
BOOL Sdialog::PreTranslateMessage(MSG* pMsg)
{
static int i = 0;
CString s;
if(pMsg->message == WM_KEYDOWN)
{
if(GetKeyState(VK_CONTROL) & 0x8000)
{
if(pMsg->wParam == 'A')
{
...
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
Кроме того, вы можете добавить эти вспомогательные макросы:
// Handy functions
#define IsCTRLpressed() ( GetKeyState(VK_CONTROL) & 0x8000 )
#define IsSHIFTpressed() ( GetKeyState(VK_SHIFT) & 0x8000 )
//15 = sizeof(SHORT) * 8 - 1
//0000 0000 0000 0001 = 1
//1000 0000 0000 0000 = 15 << 1
Тогда это может быть так просто, как:
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('A')))
{
// Do whatever
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
Имейте в виду, что вам нужно решить, хотите ли вы по-прежнему запускать базовую реализацию. Если вы на самом деле обрабатываете сообщение и разбираетесь с ним, вам следует вернуться TRUE
, В противном случае, пусть базовый класс справится с этим.
Пример:
BOOL Sdialog::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch, bDealtWith;
bDealtWith = FALSE;
if (IsCTRLpressed() &&
pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('A')))
{
// Deal with it
// Eat it.
bNoDispatch = TRUE;
bDealtWith = TRUE;
}
if (!bDealtWith)
bNoDispatch = CDialogEx::PreTranslateMessage(pMsg);
return bNoDispatch;
}