現在、テストプログラムで以下のような問題を抱えています。
・VC2008でSDI標準のプロジェクトを作成し、リソースエディタ上で
ID_APP_ABOUTのアクセラレータにVK_UPを割り当て、ビルドして実行。
・上キーを押すとバージョン情報ダイアログが表示される。
・ところがこの状態だと、クラスビューのツリー上で上キーを押しても、
ツリー内の移動ではなくバージョン情報ダイアログが表示されてしまう。
・そこで、CMainFrame::PreTranslateMessageを追加し、以下のようにした。
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) {
if (m_wndClassView.IsDialogMessage(pMsg)) {
return TRUE;
}
}
return CFrameWndEx::PreTranslateMessage(pMsg);
}
・ツリー上では上キーでもツリー内の移動をしてくれるようになった。
・しかし、他のアクセラレータキー(Ctrl+OやCtrl+Pなど)も
ツリー上では無視されてしまう。
Ctrl+OやCtrl+Pなど、ダイアログ自身が処理していないはずのメッセージも、
IsDialogMessageで処理されてしまうものなのでしょうか?
> Ctrl+OやCtrl+Pなど、ダイアログ自身が処理していないはずのメッセージも、
> IsDialogMessageで処理されてしまうものなのでしょうか?
http://msdn.microsoft.com/en-us/library/ms645498.aspx
「IsDialogMessage sends WM_GETDLGCODE messages to the dialog box procedure to determine which keys should be processed.」
http://msdn.microsoft.com/en-us/library/ms645425.aspx
「By default, the system handles all keyboard input to the control.」
とある。
> ・ところがこの状態だと、クラスビューのツリー上で上キーを押しても、
> ツリー内の移動ではなくバージョン情報ダイアログが表示されてしまう。
MFC使ってるなら GetDefaultAccelerator() をオーバーライドしてやれば良い。
CDocument 単位で切り替えたいなら CDocument::GetDefaultAccelerator() で対応する HACCEL 返せば良いし、
そうで無いなら↓な感じで切り替えてやっても良い。
HACCEL m_wndClassView::GetAccelerator() {
return ::LoadAccelerators(, m_wndClassView専用のアクセラレータ);
}
HACCEL CMainFrame::GetDefaultAccelerator() {
HWND wnd = ::GetFocus();
if (wnd == m_wndClassView || ::IsChild(m_wndClassView, wnd)) {
return m_wndClassView.GetAccelerator();
}
return CFrameWndEx::GetDefaultAccelerator();
}
> MFC使ってるなら GetDefaultAccelerator() をオーバーライドしてやれば良い。
ありがとうございます。
CFrameWndにこんな隠れ仮想関数があったのですね。
実際にはコントロールを持つペインは複数あるので、
CMainFrameのメンバとしてペイン用のアクセラレータ(上下キーのみ削除)を用意し、
HACCEL CMainFrame::GetDefaultAccelerator()
{
if (ペイン1.IsChild(GetFocus()) || ペイン2.IsChild(GetFocus())) {
return m_hAccelPane; // ペイン用のアクセラレータ
}
return CFrameWndEx::GetDefaultAccelerator();
}
とすることで、上下キー以外のアクセラレータを残したまま
ペイン内のキーボード移動を有効にすることができました。
ありがとうございました。
ツイート | ![]() |