2

Windows をラップする (アンマネージ) C++ クラスを作成していますPropertySheet。基本的に、次のようなものです:

class PropSheet {
    PROPSHEETHEADER d_header;
    public:
        PropSheet(/* parameters */);
        INT_PTR show();
    private:
        static int CALLBACK *propSheetProc(HWND hwnd, UINT msg, LPARAM lParam);
};

コンストラクターはd_headerメンバーを初期化するだけです。

PropSheet::PropSheet(/* parameters */) {
    d_header.dwSize = sizeof(PROPSHEETHEADER);
    d_header.dwFlags = PSH_USECALLBACK;
    // ...
    d_header.pfnCallback = &propSheetProc;
    // ...
}

その後、次の方法でモーダルに表示できます。

INT_PTR PropSheet::show() {
    return PropertySheet(&d_header);
}

問題は、コールバックが静的であるため、ラッパー クラスにアクセスできないことです。これが通常のウィンドウで、 のWindowProc代わりに を使用している場合、 in を使用しPropSheetProcてウィンドウに追加データを追加できます。この記事のように、ポインターをラッパーに戻すことができます。ただし、プロパティ シートにはこの機能はありません。cbWndExtraWNDCLASS

さらに、プロパティ シートはモーダルに表示されるため、コールバックまたはシートのウィンドウ プロシージャの 1 つを介してコードが実行される場合を除いて、実際のウィンドウの作成と破棄の間にコードを実行することはできません。

これまでに思いついた最善の解決策は、プロパティ シートを表示する直前に、ラッパー クラスへのポインターをグローバル変数内に格納することです。しかし、これは、一度に 1 つのプロパティ シートしか表示しないことを前提としており、いずれにしても非常に見苦しいものです。

これを回避する方法を知っている人はいますか?

4

5 に答える 5

1

プロパティシートをモーダルで表示しているので、のパラメータを使用::GetParent()して、プロパティシートの親ウィンドウ(つまり、そのハンドル)を使用してインスタンスにマップできるはずです。hwndDlgPropSheetProc()

于 2009-12-14T21:10:26.323 に答える
0

別のオプションを見つけましSetPropた。ラッパーへのポインターを格納するプロパティを追加するために使用します。SetPropプロパティシートのコールバックから呼び出すことができるようにするには、グローバル変数を1回だけ必要とします。

于 2009-12-22T19:09:13.020 に答える
0

すばらしい、ユーザー定義のコンテキスト パラメータなしでコールバックを使用するもう 1 つの Win32 API です。残念ながら、それだけではありません。たとえば、CreateWindow は良くありません (ユーザー定義のコンテキストを提供しますが、そのコンテキストは最初のいくつかのウィンドウ メッセージでは使用できません)。SetWindowsHookEx はさらに悪いです (コンテキストがまったくありません)。

汎用で効果的な唯一の「解決策」は、ハードコードされた「this」ポインターを使用して実行可能コードの小さな断片を発行することです。このようなもの: http://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/848000817831?r=848000817831#848000817831

恐ろしいです。

于 2009-12-14T21:54:39.593 に答える
0

PROPSHEETPAGE 構造体には、コールバックに使用できる lParam フィールドがあります。PROPSHEETHEADER に PSH_PROPSHEETPAGE フラグを含めて、ページを説明する PROPSHEETPAGE アイテムの配列を渡すか、フラグを省略して、事前に割り当てられた HPROPSHEETPAGE ハンドルの配列を代わりに渡すことができます (つまり、CreatePropertySheetPage() を使用し、とにかく PROPSHEETPAGE を使用します)。

于 2009-12-15T02:10:23.737 に答える