2010-11-24 18 views
1

Windowsでは、同じウィンドウクラスの複数のウィンドウ(HWND)が開いているとします。ユーザーがウィンドウ2に入力しようとしたときにウィンドウ1が変更されないように、ウィンドウプロシージャ内のコンテキストデータをどのように追跡しますか?C/C++ - Windows - HWNDコンテキストデータの追跡方法

WndProc()が複数回呼び出された後でないと、CreateWindow()が返されないため、結果のHWNDをコンテキストデータに設定してWndProc()で検索することはできません。あなたはWndProc()でそれを設定する必要があります。

WndProc()は、ウィンドウ作成メッセージ以外でコンテキスト情報を直接渡すことはありませんが、残念ながらウィンドウ作成メッセージはWndProc()に渡される最初のメッセージではありません。いいえ、私はWM_SIZE、WM_NCSIZEなどのものを見つけ、WM_CREATEを見る前にいくつかのものが渡されます。

リンクリストタイプのストレージメカニズムにHWNDを格納すると、大量のウィンドウで効率が悪くなります。ウィンドウ内の各コントロールは単に別のタイプのウィンドウなので、追跡する必要がある別のHWNDです。数百のコントロールの後、数十のメッセージが短時間でプログラムに渡された後、HWNDのリンクリストを検索することはプログラムの主要なボトルネックになります!

私が聞いたことから、SetWindowLong()を使用する人もいますが、ライブラリとは別のライブラリでプログラムとは別のコンテキスト情報を保存することがあり、ウィンドウのデータ衝突が発生することがあります。どのように避けることができますか?

+0

は、あなただけのHWNDのリストを並べ替えることができませんでしたか? – James

+0

私はこれに従っていません..あなたのウィンドウを区別したいですか? window2に入力するときにwindow1が変更されるのはなぜですか? – Default

+2

'SetWindowLongPtr(GWL_USERDATA)'は行く方法です。ライブラリは、ウィンドウを作成している場合を除いては使用しないでください。ウィンドウのユーザーデータは、ウィンドウを作成したユーザーに属します。ライブラリで独自のユーザーデータを添付する場合は、アクセス許可を求める必要があります(たとえば、ウィンドウクラスラッパーのメンバーとして格納するなど)。 –

答えて

4

あなたが正しくあなたを理解しているならば、あるウィンドウが別のウィンドウからメッセージをキャッチするのを避けたいです。これを回避する1つの方法は、thisスレッドで提案されたソリューションを使用することです。このスレッドは、作成されたウィンドウを追跡し、正しいウィンドウに、呼び出し元のポインタをGWL_USERDATAMoo-Juiceによって提案されたよう

// ... 
m_hWnd = CreateWindowEx(0,"Classname","Title",WS_OVERLAPPEDWINDOW, 
         CW_USEDEFAULT,CW_USEDEFAULT, 
         320,200,NULL,NULL,hInstance, /*the magic pointer*/ this); 

// ... 

if(uMsg == WM_CREATE) 
{ 
    // collected here.. 
    pParent = (CWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams; 
    // .. and then stored for later lookup 
    SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent); 
} 
// ... 

また、WM_NCCREATEメッセージをキャッチすることができます。
そして、メッセージがあらかじめWM_CREATEであることを心配する必要はないと思います。ウィンドウがその時点で完全に初期化されていないからです。テキストを設定する必要がある場合は、CreateWindow(Ex)への呼び出し後に、それをユーザー入力またはSendMessage呼び出しにします。

+3

+1、しかし実際には 'WM_NCCREATE'を使ってこれを行うでしょう –

+0

@ Moo-Juice:これはちょうど本質的でしたが、リンクされたフォーラムにはすべてがうまくいくために必要な完全な例があります:) – Default

+0

はいこれは、Windows APIで、コンテキストデータを新しく作成されたウィンドウに関連付ける古い方法です。 – valdo

0

WNDCLASS.cbWndExtraを使用して、クラスに必要なすべてのプライベートストレージを宣言することはできません。その後、そのクラスのウィンドウを作成するたびにWindowsによって割り当てられます。

2

誰でもウィンドウを100%所有するウィンドウを作成します。 CreateWindow()を呼び出す場合は、GetWindowLongを使用して自分のものであることを知ることができます。

ライブラリがウィンドウを作成する場合、それはあなたのものではないのでできません。

(脇の下:他の誰かのつま先を踏み止めることは誰も止めていませんが、コンベンションはかなり標準的です)。

これを行うライブラリを使用している場合、通常、自分のデータをウィンドウに関連付けるためのメカニズムがあります。もちろん、そのドキュメントを参照する必要があります。

関連する問題