2012-03-14 17 views
0

ウィンドウプロシージャをウィンドウに添付する際に問題があります。子クラスからWNDPROC関数を呼び出す

BaseWindowと呼ばれるベースクラスがあり、GWPL_USERDATAを使用して、子クラスのHandleMessage()という仮想関数を呼び出します。

しかし、カスタムウィンドウクラスを作成せずにウィンドウプロシージャを変更しようとすると、子プロセスから長い型エラーが発生します。

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    BaseWindow *pThis = NULL; 

    if (uMsg == WM_NCCREATE) 
    { 
     CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; 
     pThis = (BaseWindow*)pCreate->lpCreateParams; 
     SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); 

     pThis->m_hwnd = hwnd; 
    } 
    else 
    { 
     pThis = (BaseWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); 
    } 
    if (pThis) 
    { 
     return pThis->HandleMessage(uMsg, wParam, lParam); 
    } 
    else 
    { 
     return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
} 

virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 
    {return 0;}; 


PlayList Class : BaseWindow 

SetWindowLong(m_hwnd, GWL_WNDPROC,(long) HandleMessage); //Error 

LRESULT PlayList::HandleMessage(UINT message,WPARAM wParam,LPARAM lParam) //Need to  attach this window procedure 
{} 

子手続きが静的である場合、それは動作しますが、しかし、私はその手順で非静的メンバを使用します。

は、ここでは、コードです。

共通のコントロールをサブクラス化したいのですが、この基本クラスを使用しています(多くのコードが冗長であるため)可能ですか? MSDNからhttp://pastebin.com/ME8ks7XK

答えて

0

コンパイラはHandleMessageの宣言が嫌いですが、静的ではありません。 CALLBACKもありません。うまくいきません。

あなたがこれをやろうとしている理由がわからない場合、WindowProc()関数の全体的なポイントは、メッセージを仮想HandleMessage()メソッドに転送することです。最高でHandleMesssageの代わりにSetWindowLong()呼び出しでWindowProcを使用します。または、CreateWindowEx()呼び出しで直接指定するだけです。

+0

私がウィンドウクラスを作成して登録すると、handlemessage()がうまく動作しますが(この特定のウィンドウはシステムクラス[listbox]をサブクラス化しています)、なぜ私はそれを使いたくないのですか? CreateWindowEx()でBeacauseをベースクラスの子として欲しいので、全体のコードを繰り返す必要はありません(例えば、pos、size、currはベースクラスに存在するハンドルなど) –

+0

これは不可能ですが、 WindowsのAPIはCで、仮想C++メソッドの呼び出し方法はわかりません。あなたは巨大な車輪を再発明していることを知っていますか? APIをラップするC++クラスライブラリは豊富です。 –

+0

または私はこの1つのウィンドウ(または他のサブクラスのシステムクラス)に例外を作らなければならないでしょう、他の解決策がありますか? –

0

アプリケーションでのSetWindowLong関数を使用して、ウィンドウのインスタンスをサブクラス

ここ基底クラスの全コードです。アプリケーションはGWL_WNDPROCフラグ、サブクラスへのウィンドウへのハンドル、およびサブクラスのアドレスをSetWindowLongに渡します。サブクラス・プロシージャは、アプリケーションの実行可能ファイルまたはDLLのいずれかに置くことができます。
SetWindowLong(m_hwnd, GWL_WNDPROC,(long) & HandleMessage);

をしかし、これは再コンパイルされません:

だから、あなたはこれを書く必要があります!理由:すべての非静的メンバ関数は、thisパラメータ(所有者クラスへのポインタ)を隠しています。したがって、HandleMessageWindowProc宣言に適合しません。

関連する問題