EditBoxのサブクラス化について質問

このQ&Aのポイント
  • EditBoxのサブクラス化について詰まってしまいました。
  • ENTERとESCAPE以外のキーが受け付けられなくなってしまいました。
  • どのようにすれば実現できるかアドバイスお願いします。
回答を見る
  • ベストアンサー

EditBoxのサブクラス化

いつもお世話になっております。 現在、EditBoxのサブクラス化についてやっておりまして、詰まってしまったのでお聞きしたいです。 EditBoxにおいてENTERとESCAPEを押下されたときにある処理をしようとしてサブクラス化をしたのですが、その結果その他のキーが受け付けられなくなってしまいました。 defaultで何かすればいいかと思いいろいろやってみましたがよくわからなかったのでアドバイスお願いします。 現在のソースは以下のとおりです。 LRESULT CALLBACK EditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {  switch (uMsg)  {   case WM_KEYUP:   {    if (wParam == VK_RETURN)    {     // 処理    }    else if (wParam == VK_ESCAPE)    {     // 処理    }   }  break;  }  return false; } ここでENTERとESC以外は普通に入力したいのですがどのようにすれば実現できるかアドバイスお願いします。 環境は WindowsXP SP3 Visual Studio6.0 です。よろしくお願いします。

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

  • ベストアンサー
回答No.1

 こんばんは。  ↓此れを呼び出す筈だったと思います。  ::CallWindowProc(/*以前のエディットボックスが使っていたプロシージャ*/, hEdit, uMsg, wParam, lParam);  以前のプロシージャは  WNDPROC wndOldEditProc = (WNDPROC)::SetWindowLong(hEdit, GWL_WNDPROC...);  の戻り値から取れます。

iec1128
質問者

お礼

ご回答ありがとうございました。 実現できました。

関連するQ&A

  • デスクトップをサブクラス

    デスクトップ以外のサブクラスなら何度もやったことがあります。 DLLを使わずにデスクトップをサブクラスにできますか? DLLを使わずにデスクトップをサブクラス化しようとしたけど、 サブクラスの対象がデスクトップだと特殊なのか、 サブクラスにできていないみたいでした。 MessageBeep(0xFFFFFFFF); が実行されなかったからそう思いました。 FARPROC Org_Proc; LRESULT CALLBACK DeskProc(HWND, UINT, WPARAM, LPARAM); OrgProc = (FARPROC)GetWindowLong(HWND_DESKTOP, GWL_WNDPROC); SetWindowLong(HWND_DESKTOP, GWL_WNDPROC, (LONG)DeskProc); LRESULT CALLBACK DeskProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {  if(msg == WM_LBUTTONDOWN)MessageBeep(0xFFFFFFFF);  return CallWindowProc((WNDPROC)Org_Proc, hWnd, msg, wp, lp); }

  • CALLBACK 内の DefWindowProc の場所

    こんにちは、最近 無料版Borland C++Compiler 5.5 を使って WIN32 API の勉強をしています 気にしなければ別に問題ないのですが、どうしても気になって気持ち悪いので、質問させて下さい 参考書や Web でコード例を見ていると、CALLBACK 内の DefWindowProc関数 を switch の default にする例 と switch の default を書かずに CALLBACK の return にする例があります 好みの問題なのでしょうか? switch は、 default を入れた方が正式と思いますが、default に DefWindowProc を記述すると コードが長くなるにつれ DefWindowProc が switch 内でちょこちょこ必要になってきます 私は、switch の default があった方が良いかなと思い DefWindowProc を default に記述していますが、コードが短くなるなら CALLBACK の return に DefWindowProc を記述しようと思っています どちらが良いのでしょうか? 暇な時でかまいませんので、ご教授下さい 宜しくお願い致します ※DefWindowProc の 記述場所を CALLBACK の return にする LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {   switch(uMsg){     case WM_DESTROY:     PostQuitMessage(0);     break;   }   /*基本的なメッセージの処理*/   return DefWindowProc(hWnd, uMsg, wParam, lParam); } ※DefWindowProc の 記述場所を switch の default にする LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {   switch(uMsg){     case WM_DESTROY:     PostQuitMessage(0);     break;   default:     /*基本的なメッセージの処理*/     return DefWindowProc(hWnd, uMsg, wParam, lParam);   }   return 0; }

  • ソースを見てください。お願いします

    始めまして、Missing0001と申します。 ウィンドウズプログラムをしていて、 他のところは正常に動いているのにMoveWindow関数の場所だけ思うように動きません。 どなたかソースの間違っているところを指摘していただけないでしょうか? したいことはButtonのマウスでの移動です。 BtProc・・・サブクラス(Button)のプロシージャ DrawRect・・・Buttonのサイズの四角形を描いたり消したりするもの LRESULT CALLBACK BtProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { static BOOL Btn_Flag = false; static POINTS end,old_end; char Str[512]; switch(uMsg) { case WM_LBUTTONDOWN: Btn_Flag = true; old_end = MAKEPOINTS(lParam); DrawRect(hWnd,old_end); break; case WM_MOUSEMOVE: if(Btn_Flag) { end = MAKEPOINTS(lParam); DrawRect(hWnd,old_end); DrawRect(hWnd,end); old_end = end; } else { return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); } break; case WM_LBUTTONUP: if(Btn_Flag) { DrawRect(hWnd,end); MoveWindow(hWnd,end.x,end.y,50,30,true); ←ここがうまくいかない Btn_Flag = false; } else { return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); } } return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); }

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

    パソコンを現在人間が実際に操作中であるか否かを判定しながら進めるアプリを作っています 簡易的にキィーボードを操作していれば操作中と判断します(マウス操作も含めますが話を簡単にするため今はキィーだけとします) グローバルフックで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などのキィーボード系のメッセージだとフックしません なぜでしょうか??? 多分きわめて初歩的な知識の欠如によるものでしょうが分かりません 宜しくご指導願います

  • 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 にした場合、何が違うのか、 どういうソースなら違いを確かめられるのか教えてください。

  • グローバルで宣言

    HWND g_wnd; のようにグローバルで宣言して1つのウインドウを作った場合、 それに対応するWndProcで LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg ,WPARAM wp, LPARAM lp) { ここでは、hwndとg_wndはどっちを使っても同じですか? }

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  • C++ WIN32 ウィドウの表示

    プログラミング初心者です。 WIN32APIの勉強を始めたばかりの状態です。 本を見ながら、ウィンドウを表示させるだけのプログラムを書いてみたのですが、エラーになってしまいます。 #include <windows.h> //ウィンドウ・クラス名 #define MYWNDCLSNAME "MyWindowClass" LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wndcls; HWND hWnd; MSG msg; //ウィンドウ・クラスを登録 ZeroMemory(&wndcls, sizeof(wndcls)); wndcls.lpfnWndProc = WndProc; wndcls.hInstance = hInst; wndcls.hIcon = LoadIcon(0, IDI_APPLICATION); wndcls.hCursor = LoadCursor(0, IDC_ARROW); wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND; wndcls.lpszClassName = MYWNDCLSNAME; if(RegisterClass(&wndcls) == 0) return -1; //メイン・ウィンドウを作成 hWnd = CreateWindow(MYWNDCLSNAME, "My Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, NULL); if(hWnd == 0) return -2; //ウィンドウの表示状態を指定する ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); //メッセージループ while(GetMessage(&msg, 0, 0, 0)){ DispatchMessage(&msg); } //WM_QUITメッセージのwParamを終了コードにする return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); return 0; } //自分で処理しないメッセージはWindowsに任せる return DefWindowProc(hWnd, uMsg, wParam, lParam); } 本を読み直しても原因がよくわかりません。 どこがいけないのかご指摘いただけるとうれしいです。お願いします。 エラーの内容は error C2440: '=' : 'const char [14]' から 'LPCWSTR' に変換できません。 error C2664: 'CreateWindowExW' : 2 番目の引数を 'const char [14]' から 'LPCWSTR' に変換できません。 です。

  • プロトタイプが必要な場合

    WndProc関数の前にFunc関数を書いているから、WndProc関数の ソースがコンパイルされる時はFunc関数は既に読み込み済みで Func関数のプロトタイプは必要無いと思ったんだけど、必要なんですか? #include <windows.h> int Func(HWND); ←これは必要ですか? LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPInst, LPSTR lpstr, int n) {  … } int Func(HWND hWnd) {  … } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {  static int i;  switch(uMsg){  case WM_CREATE:   i = Func(hWnd);   break;  … }

  •    ダイアログのクラス化で仮想関数を用いて派生クラスにしているんです

       ダイアログのクラス化で仮想関数を用いて派生クラスにしているんですが・・・ ダイアログを基本クラスで静的プロシージャと派生クラスでオーバーライドしてプロシージャを使いたい のですが、どうしても自身のポインタが取得できません。 以下にソースを載せておきます。  class CBaseWnd  {  public:    // ポインタの設定    void SetPointer( HWND hWnd );    // ウィンドウプロシージャの呼び出し    static LRESULT CALLBACK CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );    // ウィンドウプロシージャの実装    virtual LRESULT MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );  }; [クラスの実装]  //===== ポインタの設定 =====//  void CBaseWnd::SetPointer( HWND hWnd )  {    SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );  }  //===== ウィンドウプロシージャの呼び出し =====//  LRESULT CALLBACK CBaseWnd::CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )  {    //_プロパティリストからthisポインタを取得 //ここでポインタを取得することができないでいます。値が0です。 //先にSetWindowlongをやっても値が0のままです。    CBaseWnd* thisPtr = (CBaseWnd*)GetWindowLong( hWnd, GWL_USERDATA );    //_thisポインタが取得できなかった場合...    if( ! thisPtr )    {      //_ウィンドウの作成時の場合... //ここでアクセス違反というエラーが起きる      if( message == WM_INITDIALOG )        thisPtr = (CBaseWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;      //_thisポインタが取得できた場合...      if( thisPtr )      {        //_プロパティリストにオブジェクトハンドル(thisポインタ)を設定する        thisPtr->SetPointer( hWnd );      }    }    //_thisポインタが取得できた場合...    if( thisPtr )    {      LRESULT lResult = thisPtr->MainProc( hWnd, message, wParam, lParam );      return lResult;    }    return DefWindowProc( hWnd, message, wParam, lParam );  }  //===== ウィンドウプロシージャの実装(継承可能) =====//  // ここでの記述はデフォルトの処理  //  LRESULT CBaseWnd::MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )  {    switch( message )    {      //_ウィンドウが破棄された場合      case WM_DESTROY:        PostQuitMessage(0);        return 0;        //_デフォルトの場合      default:        return DefWindowProc( hWnd, message, wParam, lParam );    }  } WM_INITDIALOGでダイアログの初期化中にポインタを取得しようとしますが、アクセス違反が起こり失敗します。 どなたか分かる方がいらっしゃったらご指摘お願いします。

専門家に質問してみよう