我是一个控件的子类,此时我想为它添加一些键盘快捷键。在资源的accelerator table中定义了大约十几个。
我知道我可以从主应用中使用这些加速器,方法是从主循环中调用TranslateAccelerator
然后TranslateMessage
和DispatchMessage
。
但我可以检查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);
}
答案 0 :(得分:2)
我相信标准Windows控件只使用WM_KEYDOWN / CHAR和GetKeyState
,但我不明白为什么你不能使用TranslateAccelerator
。
TranslateAccelerator
在某些方面更好,因为它知道如何处理 Alt.Gr 但如果捕获了鼠标(IIRC)它也会忽略该键,因此它取决于您的需求
在TranslateAccelerator
之后调用顶级窗口上的GetMessage
当然是最佳选择,因为它会检查窗口菜单以查看该命令是否已被禁用...