ウィンドウを左右に分割し、左にツリー、右に通常ウィンドウを置いたアプリを作成し
ています。
Ctrl+XなどのショートカットをAcceleratorに割り当てているのですが、
ツリー項目のラベル編集中、標準的なEdit系のコマンド、Ctrl+Xなどが効かなくなって
しまいました。
TranslateAccelerator()でキーが処理されてしまっているようなので、
ラベル編集用Editにフォーカスがある場合はTranslateAccelerator()を実行しないよう
にしてみると、なぜかラベル編集開始で一切操作ができなくなってしまいました。
代わりにIsDialogMessageを実行してみたのですが、ラベル編集終了のためのEnter, ESC
キーの処理は親であるTreeViewが処理しているようで、編集が終了できなくなってしま
いました。
Ctrl+XなどのAcceleratorを有効にしたまま、ラベル編集用Editに標準的なEditの動作を
させたいのですが、良い方法はないでしょうか?
VC2008
Window XP SP3
参考になるか分かりませんが、私の場合は以下のようにしました。
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) {
if (gAccelerator == FALSE)
return CWnd::PreTranslateMessage(pMsg);
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
gAcceleratorはグローバルなフラグで、ツリーやリストの編集開始時/終了時にON/OFFし
ます。
又、別にフラグを使わなくても例えば
ツリービュー->GetTreeCtrl().GetEditControl()->IsWindowVisible()
でインプレースエディットが表示中か調べても良い気がします。
> if(pMsg->message == WM_KEYDOWN)
> nChar = (UINT) pMsg->wParam;
僕も、Windows2000以降からAcceleratorが効かなくなり
それからPreTranslateMessageで直接処理しています。
処理したくない場合は、FUKUさんの例の通りにフラグ
で処理すればいいと思います。
FUKUさん、ITOさん、ご回答ありがとうございます。
> PreTranslateMessageで直接処理しています。
PreTranslateMessageでキーを一つ一つ処理しているのでしょうか。
できればそれは避けたいところです。
結局、FUKUさんと同じような方法で対抗できました。
Treeの子にフォーカスがある場合はPreTranslateMessage()でTRUEを返してしまい、
TranslateAccelerator()を呼び出さないようにしました。
(前回はFALSEを返したせいで動作がおかしくなっていたようです)
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (m_tree.IsChild(::GetFocus()))
{
return TRUE;
}
return CMDIFrameWindowImpl<CMDIWindow>::PreTranslateMessage(pMsg);
}
TRUEじゃなくてFALSEでした。。。
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (m_tree.IsChild(::GetFocus()))
{
return FALSE; // TRUEだとDispatchされない
}
return CMDIFrameWindowImpl<CMDIWindow>::PreTranslateMessage(pMsg);
}