|
以前、こういったアプリを作った時ダイアログ好きな私が、何故か普通にMDIアプリにしたのを覚えている。 なぜだろう・・・。と、ふと、思い出してしまったのだよ。 そう、ダイアログではKeyDownとか取れないという事実に。 ワーオ。マジかよ。 さーてどうすっぺ。複数選択させる手段を考えて居たのになぁ。 で、しょうがないので、せめてキーボードからのショートカットを幾つか受け入れる事で妥協する事に。 |
|
|
|
さて、ショートカットと言えば、アクセラレータキーでしょって事で、リソースエディタ開く。 で、アクセラレータを作る、もしくは追加する。
このアクセラレータキーの名前を仮に IDR_MAINDIALOG とした。 この中にキーを作って行くのだが、取り合えず 今回の場合は IDR_MAINFRAME とバッティングしない Ctrl + F とかを作ってみたりする。 作ったら、そのCtrl+FのショートカットのIDを ID_MAINDLG_CTRL_F と付けてみる。 実験実験。 アクセラレータを追加したら、今度は使いたいダイアログのヘッダーファイルを開き、 HACCEL m_hAccKey; をメンバに加える。このハンドルは IDR 1個と対になるので、通常は1個で良いはず。 1つのアクセラレータファイルに複数登録出来るから。 これを複数持つケースとして考えられるのは、内部の状態遷移に拠って同じショートカットの飛び先の関数を変えたり、そういう事をしたい時は二つ以上宣言することも有るには有るが、普通は無いかなぁ。 更にヘッダーファイルにイベント発生時の関数を宣言しておく。 afx_msg void OnShortCutCtrlF(); さて、次はCPPファイルを開き、OnInitDialog内で、 m_hAccKey = ::LoadAccelerators( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_MAINDIALOG ) ); を追加する。 更に、PreTranslateMessages をオーバライドする。オーバライドして出来た関数内で、
BOOL EDialog::PreTranslateMessage(MSG* pMsg)
{
if ( m_hAccKey != NULL ){
if ( ::TranslateAccelerator( this->m_hWnd, m_hAccKey, pMsg ) )
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
という感じに書く。
更に、実際にイベントをフックする部分を同CPPファイルに追加する BEGIN_MESSAGE_MAP(EDialog, CDialog) ON_COMMAND(ID_MAINDLG_CTRL_F, OnShortCutCtrlF) END_MESSAGE_MAP()ここで書いた ID_MAINDLG_CTRL_F とは、アクセラレータキーの登録時に Ctrl+F のショートカットのIDです。 で、右側が先にヘッダーファイルに書いたイベント発生時に呼ばれるべき関数名です。 これを実装します。
void EDialog::OnShortCutCtrlF()
{
}
こんな感じで、OKなはず。これでダイアログ上で Ctrl+Fを押すとこの関数に飛んでくるですよ。 今回のサンプルはここからダウンロードしてください。 |