3

プロジェクトで ATL と WTL を組み合わせて使用​​し、 から独自のクラスを派生させましたCWindowImpl。これは次のようになります。

class CMyControl : public CWindowImpl<CMyControl>
{
public:
    DECLARE_WND_CLASS(_T("MyClassName"))
    ...
    BEGIN_MSG_MAP(CMyControl)
        ...
    END_MSG_MAP()
};

これで問題ありませんCMyControl::Create。コントロールのインスタンスを作成するために使用すると、内部的には正常に機能し、CWindowImpl::Create関数は Win32 クラス (この場合は と呼ばれますMyClassName) を登録します。

ただし、この動作 (インスタンスの作成時に Win32 クラスが登録される) が頭痛の種です。Win32 呼び出しを使用してウィンドウを作成する別のサードパーティ ライブラリでクラス名を使用できるように、事前にクラスを登録できるようにしたいのですが、CreateWindowExこれを行う簡単な方法が見つかりません。現在、クラス名staticとして使用してこれを回避し、クラスをそれにアタッチするために使用しますが、これは面倒です。CreateWindowExCMyWindow::SubclassWindow

CWindowImpl実際にウィンドウを作成せずに派生クラスを登録する方法を知っている人はいますか?クラス名をCreateWindowEx正常に渡すことができますか? この問題に最初に遭遇することはできないため、ATL ウィンドウでこれを行う標準的な方法があると思います。

4

3 に答える 3

2

あなたがやろうとしていることはうまくいきません。これは、ATL/WTL ウィンドウの作成が ATL クラスを通過する必要があるためです。クラスは、そのthis ptr を window thunkに登録します。このサンクは WNDPROC になり、WNDPROC の HWND パラメータをオブジェクト インスタンスのthis ptr に置き換えます。

つまり、ATL ウィンドウが内部でどのように機能するかを知っていれば、これを試してみようとは思わないでしょう。ウィンドウ クラスを登録できた場合、CreateWindowEx 呼び出しはウィンドウの作成に成功します。ただし、WNDPROC サンクは作成されず、ウィンドウを関連付けるオブジェクト インスタンスも存在せず、メッセージ ハンドラも呼び出されません。代わりに、CWindowImpl::Create を使用してウィンドウを作成できるかどうかを確認し、サード パーティのライブラリが作成されたら、ATL コントロールの hwnd を渡します。

于 2009-02-24T06:03:58.900 に答える
0

次を使用できます。

WNDPROC pUnusedWndSuperProc; 
pUnusedWndSuperProc = NULL;
CMyControl::GetWndClassInfo().Register(&pUnusedWndSuperProc);

ただし...ウィンドウのインスタンスを作成して非表示にしておく理由がわかりません。少しオーバーヘッドがありますが、ウィンドウロジックの根性をいじくりまわすことはありません(これはかなり複雑なことです...最後に必要なのは、「サンク」に関する予期しないまたは異常な問題です)。

于 2009-02-22T21:38:45.707 に答える
0

Win32 API RegisterClassEx関数を直接呼び出すことができます。

于 2009-02-22T19:52:20.377 に答える