如何在子类化控件中使用快捷键表?

How to use accelerator table in a subclassed control?

本文关键字:快捷键 控件 子类      更新时间:2023-10-16

我正在对控件进行子类化,此时我想为其添加一些键盘快捷键。在资源的加速器表中定义了大约十几个。

我知道我可以从主应用程序中利用这些加速器,方法是调用TranslateAccelerator然后从其主循环中TranslateMessageDispatchMessage

但是,我可以检查快捷键序列是否从WndProc本身的子类化控件中按下吗?

编辑:换句话说,做这样的事情会不好吗?

LRESULT CSubclassedWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if(message == WM_KEYDOWN ||
message == WM_CHAR ||
message == WM_SYSKEYDOWN ||
message == WM_SYSCHAR)
{
if(hAccel)
{
CRect rcThis;
this->GetWindowRect(&rcThis);
this->ScreenToClient(&rcThis);
POINT pnt = {(rcThis.right + rcThis.left) / 2, (rcThis.bottom + rcThis.top) / 2};
MSG msg = {this->GetSafeHwnd(), message, wParam, lParam, ::GetTickCount(), pnt};
if(::TranslateAccelerator(this->GetSafeHwnd(), hAccel, &msg))
{
//Accelerator was recognized and sent as WM_COMMAND message to the same window
return 0;
}
}
}
switch(message)
{
case WM_COMMAND:
{
//Special accelerator commands
if(HIWORD(wParam) == 1 &&
lParam == 0)
{
//See which command was it
switch(LOWORD(wParam))
{
case ID_MY_ACCELERATOR_ID1:
{
//Do work...
}
return 0;
case ID_MY_ACCELERATOR_ID2:
{
//Do work...
}
return 0;
}
}
}
break;
case WM_ERASEBKGND:
//process it
return TRUE;
case WM_PAINT:
//process it
return TRUE;
case WM_KEYDOWN:
//process it
break;
//etc.
}
return CWnd::WindowProc(message, wParam, lParam);
}

我相信标准的Windows控件只使用WM_KEYDOWN/CHAR和GetKeyState但我不明白为什么你不能使用TranslateAccelerator

TranslateAccelerator在某些方面更好,因为它知道如何处理Alt.Gr但如果捕获鼠标(IIRC(,它也会忽略该键,因此这取决于您的需求。

GetMessage之后在顶级窗口调用TranslateAccelerator当然是最好的选择,因为它会检查窗口菜单以查看该命令是否被禁用......