私はコントロールをサブクラス化していますが、この時点でいくつかのキーボードショートカットを追加したいと思います。リソース内で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);
}
感謝。いいえ、トップレベルのウィンドウではありません。サブクラス化しているウィンドウは子ウィンドウです。ダイアログウィンドウの一部。だから、それ自身のメニューはありません。私が尋ねる理由は、 'TranslateAccelerator'がメッセージループ自体の中から呼び出されたことがないからです。 – c00000fd
メッセージループの外で見たことはありませんか?私はそれがあなたのトップレベルのウィンドウではないことを知っていますが、あなたのトップレベルのウィンドウがすべてのアクセラレータを扱うことができれば良いでしょう。 – Anders
うん。私は 'WndProc'の中で言うつもりだった。 – c00000fd