コントロールでのフォーカスの取得方法について質問

このQ&Aのポイント
  • VC++Expressを使用してウィンドウのフォーカスの取得方法について質問します。
  • エディットコントロールと自作コントロールを使い、フォーカスを取得したいです。
  • 自作コントロールをクリックした場合にフォーカスを取得し、キーイベントなどを受け取れる方法を知りたいです。
回答を見る
  • ベストアンサー

コントロールでのフォーカスの取得

WNDOWSXP + VC++2010Express + SDKです。VC++ExpressなのでMFCなどは使えません。 ウィンドウのフォーカスの取得方法について質問します。 メインウィンドウにコントロールを3つ貼り付けます。 エディットコントロール2つと、自分で作成したコントロールが1つです。 自分で作成したコントロールのウィンドウプロシージャは仮に↓こんなものだとします。 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if(message==WM_KEYDOWN) { if(wParam=='A'){ MessageBox(NULL,_T("A"),_T("KEYDOWN"),NULL); } return 0; } return DefWindowProc(hWnd, message, wParam, lParam); } プログラムを起動し、エディットコントロールAをクリックすると エディットコントロールAにフォーカスが移動します。 キーボードのAボタンを押下すると、エディットコントロールAに「a」と入力されます。 エディットコントロールB、自分で作成したコントロールは無反応です。 エディットコントロールBをクリックすると、エディットコントロールBにフォーカスが移動します。 キーボードのAボタンを押下すると、エディットコントロールBに「a」と入力されます。 エディットコントロールA、自分で作成したコントロールは無反応です。 次に、自分で作成したコントロールをクリックした場合、 フォーカスはエディットコントロールBにあります。キーイベントなども エディットコントロールBのみが反応します。 ここで、自分で作成したコントロールをクリックした場合に 自分で作成したコントロールがフォーカスを取得し、 キーイベントなどを独占的に受け取れるようにしたいのですが、方法がわかりません。 どなたか方法をご存知の方がいらっしゃいましたら、ご教授いただけないでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • dalycity
  • ベストアンサー率100% (1/1)
回答No.2

CreateWindow 時に、 WS_CHILD と WS_TABSTOP 属性はついていますか?

button_denchi
質問者

お礼

すみません。WM_LBUTTONDOWN で SetFocus したら普通にできました。 私はバカでした。事故解決してしまったので回答を締め切ります。

button_denchi
質問者

補足

WS_CHILDはつけています。WS_TABSTOPはつけてもはずしても変化はありませんでした。

その他の回答 (2)

noname#137556
noname#137556
回答No.3

あ,DefWindowProc なのですね。 失礼いたしました。#1

button_denchi
質問者

お礼

すみません。WM_LBUTTONDOWN で SetFocus したら普通にできました。 私はバカでした。事故解決してしまったので回答を締め切ります。

button_denchi
質問者

補足

はい。コモンコントロールのサブクラス化ではなく1からつくってみたいなと思いまして。

noname#137556
noname#137556
回答No.1

自分で作成したコントロールとはどのようなものでしょうか? 例えば,static control をサブクラス化したものであれば, もとの性質を受け継いでいるので,フォーカスを受け取れないはず。

関連するQ&A

  • Tabでのフォーカス(win32)

    edit = CreateWindow( TEXT("EDIT") , NULL , WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER | ES_LEFT , 0 , 0 , 35 , 18 , hWnd , (HMENU)1 , ((LPCREATESTRUCT)(lParam))->hInstance , NULL ); でエディットコントロールを作成しました。 フォーカスがエディットコントロールにある時、TABキーで フォーカスをなくしたいのですが、どうしたらよいでしょうか? デバッガーで追ってみると、WM_KEYDOWNがウィンドウに送られていませんでした。

  • ダイアログボックスのボタンコントロールのフォーカスについて

    ダイアログボックスのボタンコントロールのフォーカスについて 教えて下さい。  モーダルダイアログにボタン「OK」を一つ貼り付けて それを「標準のボタン」(BS_DEFPUSHBUTTON)として作成したのですが ダイアログ表示直後は下画像(1)のようになってエンターキーを押しても 反応しません。何度かカーソルキーを押すとようやく(2)のように ボタンに枠線がついてエンターで押せるようになるのですが ダイアログ表示直後に(2)のようにするにはどうするべきでしょうか? ダイアログのコールバック・プロシージャ(WM_INITDIALOG部分でボタン作成) LRESULT CALLBACK SettingWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ switch (msg){ case WM_INITDIALOG: CreateWindowEx(0x00000000,"BUTTON","OK", WS_CHILD |WS_VISIBLE| WS_TABSTOP | BS_DEFPUSHBUTTON, 16,16,80,21,hWnd,(HMENU)IDOK,GetModuleHandle(0),0); return TRUE; } return FALSE; }

  • 別プロセスのコントロールにフォーカスをあてたい

    VC++5.0 または VC++6.0 の環境で、MFC を使ってダイアログベースの EXEを造っています。 (OS は NT4.0 または 2000 です) 以下のことをしたいと思っています。 ・プロセスA、Bがあります。 ・プロセスAがプロセスBをフォアグランドにします。 →SetForegroundWindow() します。 ・プロセスAがプロセスBのボタンやエディットボックスなどのコントロールに フォーカスをあてる。 で、この最後のフォーカスをあてる処理は実現可能でしょうか? 自分のプロセス内のコントロールに対しては、SetFocus() で フォーカスをあてられたのですが、別プロセスではフォーカスを あてることができませんでした。 識者の方、ご教授願います。

  • テキストボックスからフォーカス外す

     editBox = CreateWindow(   "EDIT",   "あああ",   SS_CENTER | WS_CHILD | WS_VISIBLE,   0,0,100,20,   hWnd,   NULL,   hInstance,   NULL); テキストボックスのフォーカスを外すにはどうしたら いいんですか? ESCキーでフォーカスを外そうと思ったら、 テキストボックスにフォーカスがあるせいで case WM_KEYDOWN が動作しません。 フォーカスを外すというソース自体も分かっていません。  case WM_KEYDOWN:   if( wParam == VK_ESCAPE )    ?  break;

  • キィーボードをフックしません、何故ですか???

    パソコンを現在人間が実際に操作中であるか否かを判定しながら進めるアプリを作っています 簡易的にキィーボードを操作していれば操作中と判断します(マウス操作も含めますが話を簡単にするため今はキィーだけとします) グローバルフックでKEY_DOWNをフックする為に以下のDLL(主要部分のみ)を作りました キィーが押されるとMW_KEYDOWN_DLLというメッセージをアプリに送ります EXPORT LRESULT CALLBACK HookProc( int nCode, WPARAM wParam, LPARAM lParam) { if(nCode == HC_ACTION) { CWPSTRUCT *pcwp = (CWPSTRUCT *)lParam; if(pcwp->message == WM_KEYDOWN) { SendMessage(g_hWnd, WM_KEYDOWN_DLL, pcwp->wParam, pcwp->lParam); ←(1) } } return (CallNextHookEx(g_hHook, nCode, wParam, lParam)); } MW_KEYDOWN_DLLメッセージを受けたアプリは操作中フラグを立てます(主要部分のみ) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_KEYDOWN_DLL: ここで操作中フラグを立てます ←(2)  このフラグは一定時間後にタイマーが倒します break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return (0L); } 実行してみると(1)に来ません、当然(2)のフラグは立ちません WM_KEYDOWNの代わりにWM_CREATE、WM_CLOSEだときちんとフックします WM_CHAR、MW_KEYUPなどのキィーボード系のメッセージだとフックしません なぜでしょうか??? 多分きわめて初歩的な知識の欠如によるものでしょうが分かりません 宜しくご指導願います

  • エディットコントロール入力時の背景色変更について

    Win32 APIについて質問です。(前回質問させてもらった続きです) Microsoft Visual Studio .NET 2002、XP、API 2つのエディットコントロール(hEdit_DatDelay、hEdit_DatDelay2) のことなんですが、2つのエディットコントロールは、「0」を入力し フォーカスを外すと、メッセージを表示し、背景色を赤色表示する。 その後「0」以外の値を入力しフォーカスを外すと、背景色が元の 白色に戻る仕様を予定しています。 次のコードのように作成すると、両方のエディットコントロールで、 「0」を入力しフォーカスを外すとメッセージは表示しますが、 背景色は白色のままとなります。 (3)、(4)の行をコメントアウトすると「hEdit_DatDelay」のみ赤色と なります。 (1)~(4)のあたりが何か問題があるのではと思っているのですが、 お手上げ状態です。 ご存じの方すいませんがご教授の程よろしくお願いします。 //・・・ switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { //・・・ case IDC_DAT_DELAY: //一つ目のエディットコントロール switch (wmEvent) { case EN_KILLFOCUS: GetWindowText(hEdit_DatDelay , DatDelay , 4); DatDelay_int = atoi(DatDelay); if(DatDelay_int == 0) { Bck_Red = 1; MessageBox(hWnd, (PCTSTR)Text, _T("ftp"), MB_OK); SetFocus(hEdit_DatDelay); break; }else{ Bck_Red = 3; //(1) InvalidateRect(hEdit_DatDelay, NULL, TRUE); //(2) break; } break ; } break; case IDC_DAT_DELAY2://二つ目のエディットコントロール switch (wmEvent) { case EN_KILLFOCUS: GetWindowText(hEdit_DatDelay2 , DatDelay2 , 4); DatDelay_int2 = atoi(DatDelay2); if(DatDelay_int2 == 0) { Bck_Red = 2; MessageBox(hWnd, (PCTSTR)Text, _T("ftp"), MB_OK); SetFocus(hEdit_DatDelay2); break; }else{ Bck_Red = 4; //(3) InvalidateRect(hEdit_DatDelay2, NULL, TRUE); //(4) break; } break ; } break; //・・・ case WM_INITDIALOG: //ブラシの作成 RedBrush = CreateSolidBrush(RGB(255,0,0));// 赤ブラシ ClearBrush = (HBRUSH)GetStockObject( NULL_BRUSH );//透明 break; case WM_CTLCOLOREDIT: { switch(Bck_Red) { case 1: if ((HWND)lParam == GetDlgItem(hWnd, IDC_DAT_DELAY)) { SetBkColor((HDC)wParam, RGB(255,0,0)); //背景を赤色 return (LRESULT)RedBrush; } break; case 2: if ((HWND)lParam == GetDlgItem(hWnd, IDC_DAT_DELAY2)) { SetBkColor((HDC)wParam, RGB(255,0,0)); //背景を赤色 return (LRESULT)RedBrush; } break; case 3: SetBkColor( (HDC)wParam, GetSysColor( COLOR_WINDOW ) ); return (LRESULT)ClearBrush; break; case 4: SetBkColor( (HDC)wParam, GetSysColor( COLOR_WINDOW ) ); return (LRESULT)ClearBrush; break; default: break; } } break;

  • エディットボックス内でキー押されたときのメッセージ

    VC++6.0です。 メインウインドウ内のエディットボックス(一行)で、特定のキー入力を検知したいのですが、どのようにすればよいでしょうか。 mfcは使ってません。 //ウインドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {  switch( message )  {   case WM_CREATE:    //エディットボックスを作成    CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT","",          WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,          0,0,2000, 20, hWnd, (HMENU)IDC_EDIT, g_hInst, NULL );    break;   case WM_COMMAND:    //エディットボックス内の変更はEN_CHANGEで受け取れるが、    //キーコードは送られてこない    break;  } }

  • CallNextHookEx( ) == FALSE

    1つのアプリの中で、メインプロージャとフックプロージャを作りました。 フックはキーボードフックです。 HHOOK hHook; LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam){  if(nCode < 0)return CallNextHookEx(hHook, nCode, wParam, lParam);  if(wParam == 0x31)return FALSE;  return TRUE; } フックしていても 「ぬ」 のキーは使えるようにしました。  if(wParam == 0x31)return FALSE; は  if(wParam == 0x31)return CallNextHookEx(hHook, nCode, wParam, lParam); にしても違いが分かりませんでした。 return FALSE では、メッセージをキューから削除らしいけど、メインの プロージャで LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){  switch(msg){  case WM_KEYDOWN:   if(wParam == 0x31)MessageBox(hWnd, "メインプロージャから", "", MB_OK);  break; にしても、フックプロージヤの戻り値は CallNextHookEx( ) でも FALSE でも MessageBox() は表示されました。 CallNextHookEx( ) にした場合と FALSE にした場合、何が違うのか、 どういうソースなら違いを確かめられるのか教えてください。

  • VC++&グローバルフックについて質問です

    vc++2008,Windows Vistaの環境でプログラムを作成しています。 以下、aが押されたら、設定したhWndにWM_KEYDOWN,VK_LEFTのメッセージを送るプログラムのつもりで書きました。 http://www.shos.info/develop/cwin/tipswin.html#windows008 を参考にしています。 しかし、dllにしてWinMainで呼び出したのですが動作しません。 エラーも出ないのでなぜ動かないのかがわかりません。 このプログラムをちゃんと動かすにはどうしたらいいでしょうか。 どうかご指摘ください。よろしくお願いします。 //hook.h #ifdef HOOKAPI #else #define HOOKAPI extern "C" __declspec(dllimport) #endif HOOKAPI HINSTANCE _hInstance; HOOKAPI HHOOK _hHook; HOOKAPI HWND _hWnd; HOOKAPI BOOL Set(HWND hWnd); HOOKAPI void Reset(); //hook.cpp #include <windows.h> #define HOOKAPI extern "C" __declspec(dllexport) #include "hook.h" #pragma data_seg(".share") HHOOK _hHook = NULL; HWND _hWnd = NULL; HINSTANCE _hInstance; #pragma data_seg() #pragma comment(linker, "/section:.share,rws") LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) { /* ここでは 'A' が押されたら予め設定済みの _hWnd にメッセージを送る */ if (nCode >= 0 && nCode != HC_NOREMOVE && wParam == 'A') { PostMessage(_hWnd, WM_KEYDOWN, VK_LEFT, 0); CallNextHookEx(_hHook, nCode, wParam, lParam); return 1; } return CallNextHookEx(_hHook, nCode, wParam, lParam); } BOOL Set(HWND hWnd) { /* キーのフック */ _hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookProc, _hInstance, 0); /* ここで hInstance は DLL のインスタンス ハンドル */ _hWnd = hWnd; return (_hHook != NULL); } void Reset() { if (_hHook != NULL) { UnhookWindowsHookEx(_hHook); _hHook = NULL; } }

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

専門家に質問してみよう