プロが教えるわが家の防犯対策術!

おせわになります。
開発環境はWindowsXP、VisualC++.NET、SDK開発です。

ダイアログ上のテキストボックスでエンターキーが入力されたら、
値を取り込むというプログラムを考えています。
ただ、WM_KEYDOWNではENTERが検出できないで困っています。
WM_SYSKEYでもENTERを押してもOKボタンが押されてしまいます。

過去のログを見ますとTranslateMessageでフックするというような
記述がありますが、具体的なコードは無いでしょうか?

メイン関数内のループでMSGを処理するのではと思っていますが
思うような動作が出来ません。

A 回答 (2件)

複数行のエディットフィールドであれば



BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
static LONG preProc;

switch (GetDlgCtrlID(hDlg)==IDC_EDIT1?WM_USER+1:msg)
{
case WM_USER+1:
switch (msg)
{
case WM_CHAR:
if (wParam==13) MessageBeep(0);
}
return CallWindowProcA((WNDPROC)preProc,hDlg,msg,wParam,lParam);
case WM_INITDIALOG:
preProc=SetWindowLong(GetDlgItem(hDlg,IDC_EDIT1),GWL_WNDPROC,(LONG)DlgProc);
return 1;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hDlg,0);
return 1;
}
}
return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR nCmdLine,
int lCmdShow)
{
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),0,DlgProc,0);
return 0;
}

と言う感じ(重複サブクラスプロシージャ)でシンプルにできます。

ただし、1行専用フィールドと場合はスレッドフックが必要です。

<セット>
hHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,0,GetCurrentThreadId());

<プロシージャ>
LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
{
if (nCode===HC_ACTION) if (wParam==0xD)
{
ここでエンターキー入力の処理
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}

と言った感じでできると思いますよ。
スレッドフックは参考URLを参照してください。

参考URL:http://www.kumei.ne.jp/c_lang/sdk2/sdk_160.htm

この回答への補足

VTClientさんありがとうございます。

上記のコードを使ってエンターキーの検出ができました。
ありがとうございました。

補足日時:2007/07/02 21:57
    • good
    • 0

ご希望の方法とは違うかもしれませんが、テキストボックス等のコントロールを含む


ウィンドウのウィンドウプロシージャの変更を行うサブクラス化というものがあります。


HWND hwTx;    //テキストボックスのウィンドウハンドル
WNDPROC wpDef;  //テキストボックスのデフォルトのウィンドウプロシージャのアドレス


//ウィンドウプロシージャのアドレスを取得
wpDef = (WNDPROC)GetWindowLong( hwTx, GWL_WNDPROC );

//新たにウィンドウプロシージャを設定する
SetWindowLong( hwTx, GWL_WNDPROC, (LONG)WinProcCnt );



//新しいウィンドウプロシージャ
LRESULT CALLBACK WinProcCnt( HWND hw, UINT msg, WPARAM wp, LPARAM lp )
{
  switch( msg ){
    case WM_CHAR:
      switch( LOWORD(wp) ){
        case VK_RETURN:
          //ENTER入力時の処理
          break;
      }
  }

  //デフォルトのウィンドウプロシージャへ
  return CallWindowProc( wpDef, hw, msg, wp, lp );
}

参考URL:http://wisdom.sakura.ne.jp/system/winapi/win32/w …

この回答への補足

回答ありがとうございます。
サブクラス化をしたのですが思ったような動作が出来ません。
状況としては、ダイアログのある場所をクリックすると
CreateWindowでエディットボックス(改行無し)を作成し、数値を入れてEnterキーを押すと数値が反映されるようにしたいと思っています。
具体的には以下のコードを書いています。

//クリックした所にエディットボックスを貼り付ける
g_hEdit=CreateWindow("EDIT",szText
,WS_CHILD | WS_VISIBLE | ES_RIGHT,//ウィンドウスタイル
rcAll.left,rcAll.top,//X.Y
rcAll.right-rcAll.left,rcAll.bottom-rcAll.top,//幅、高さ
GetDlgItem(hWnd,IDC_LIST1),//親ウィンドウのハンドル
(HMENU)IDC_LISTEDIT,//コントロールID
g_Inst,//インスタンスハンドル
NULL);

//サブクラス化
g_orgListEditProc=(WNDPROC)SetWindowLong(g_hEdit,GWL_WNDPROC,(LONG)ListEditProc);

SendMessage(g_hEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(FALSE, 0));
SetFocus(g_hEdit);

新しいエディットボックスに数値を入れてエンターキーを押すと、
IDOKに飛んでしまうのです。
エディットボックス内に普通の数字を入れるとKEYDOWNで検知できているのですが、Enterキーは検知できません。WM_SYSKEYでも検知できません。
動作としては、エディットボックスではなくIDOKボタンにフォーカスが行っている状態のようにみえます。
状況を説明してみたのですがいかがでしょうか?

補足日時:2007/07/02 17:15
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!