チュートリアル: Win32 での WPF コンテンツのホストWalkthrough: Hosting WPF Content in Win32

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) は、アプリケーションの作成に適した環境を提供します。provides a rich environment for creating applications. ただし、Win32Win32 コードにかなりの投資がある場合は、元のコードを書き換えるより、アプリケーションに WPFWPF の機能を追加するほうがより効果的であることがあります。However, when you have a substantial investment in Win32Win32 code, it might be more effective to add WPFWPF functionality to your application rather than rewriting your original code. WPFWPF ホストするための簡単なメカニズムを提供します。WPFWPFでコンテンツをWin32Win32ウィンドウ。provides a straightforward mechanism for hosting WPFWPF content in a Win32Win32 window.

このチュートリアルは、サンプル アプリケーションを記述する方法を説明しますWin32 ウィンドウのサンプルで WPF コンテンツをホストしている、そのホストWPFWPFでコンテンツをWin32Win32ウィンドウ。This tutorial describes how to write a sample application, Hosting WPF Content in a Win32 Window Sample, that hosts WPFWPF content in a Win32Win32 window. このサンプルを拡張すると、いずれの Win32Win32 ウィンドウでもホストできます。You can extend this sample to host any Win32Win32 window. マネージド コードとアンマネージド コードの混在が関係しているため、このアプリケーションは C++/CLIC++/CLI で記述されます。Because it involves mixing managed and unmanaged code, the application is written in C++/CLIC++/CLI.

必要条件Requirements

このチュートリアルは、WPFWPFWin32Win32 プログラミングの基礎知識があることを前提としています。This tutorial assumes a basic familiarity with both WPFWPF and Win32Win32 programming. 基本的な事柄WPFWPFプログラミングを参照してくださいGetting Startedします。For a basic introduction to WPFWPF programming, see Getting Started. 概要についてはWin32Win32プログラミングでは、参照すること、この主題に関する数多くの書籍の特にプログラミング Windows Charles Petzold 著。For an introduction to Win32Win32 programming, you should reference any of the numerous books on the subject, in particular Programming Windows by Charles Petzold.

このチュートリアルに付属するサンプルがで実装されているためC++/CLIC++/CLI、このチュートリアルの使用に関する知識を前提としていますC++C++プログラムに、 Win32Win32 APIAPIマネージ コード プログラミングの理解。Because the sample that accompanies this tutorial is implemented in C++/CLIC++/CLI, this tutorial assumes familiarity with the use of C++C++ to program the Win32Win32APIAPI plus an understanding of managed code programming. C++/CLIC++/CLI の知識があることは、役立ちますが、必須ではありません。Familiarity with C++/CLIC++/CLI is helpful but not essential.

注意

このチュートリアルには、関連するサンプルからのコード例が多数含まれています。This tutorial includes a number of code examples from the associated sample. しかし、読みやすくするため、完全なサンプル コードは含まれていません。However, for readability, it does not include the complete sample code. 完全なサンプル コードで、次を参照してください。 Win32 ウィンドウのサンプルで WPF のコンテンツをホストしているします。For the complete sample code, see Hosting WPF Content in a Win32 Window Sample.

基本手順The Basic Procedure

このセクションで説明を使用する基本手順ホストWPFWPFでコンテンツをWin32Win32ウィンドウ。This section outlines the basic procedure you use to host WPFWPF content in a Win32Win32 window. 残りのセクションでは、各手順の詳細について説明します。The remaining sections explain the details of each step.

ホストする鍵WPFWPFでコンテンツをWin32Win32ウィンドウは、HwndSourceクラス。The key to hosting WPFWPF content on a Win32Win32 window is the HwndSource class. このクラスは、ラップ、WPFWPFでコンテンツをWin32Win32に組み込むことができるように、ウィンドウ、ユーザー インターフェイス (UI)user interface (UI)子ウィンドウとして。This class wraps the WPFWPF content in a Win32Win32 window, allowing it to be incorporated into your ユーザー インターフェイス (UI)user interface (UI) as a child window. 次の方法では、Win32Win32 および WPFWPF を単一のアプリケーションに統合します。The following approach combines the Win32Win32 and WPFWPF in a single application.

  1. 実装、WPFWPFマネージ クラスとしてコンテンツ。Implement your WPFWPF content as a managed class.

  2. Win32Win32 アプリケーションを C++/CLIC++/CLI で実装します。Implement a Win32Win32 application with C++/CLIC++/CLI. 既存のアプリケーションとアンマネージドの C++C++ コードで使用を開始する場合、通常は、プロジェクトの設定を /clr コンパイラ フラグを含めるように変更して、マネージド コードを呼び出せるようにします。If you are starting with an existing application and unmanaged C++C++ code, you can usually enable it to call managed code by changing your project settings to include the /clr compiler flag.

  3. スレッド処理モデルをシングル スレッド アパートメント (STA: Single Threaded Apartment) に設定します。Set the threading model to single-threaded apartment (STA).

  4. 処理、 WM_CREATEウィンドウ プロシージャと次の操作で通知します。Handle the WM_CREATEnotification in your window procedure and do the following:

    1. 新しい HwndSource オブジェクトを、親ウィンドウがその parent パラメーターとなるように指定して作成します。Create a new HwndSource object with the parent window as its parent parameter.

    2. WPFWPF コンテンツ クラスのインスタンスを作成します。Create an instance of your WPFWPF content class.

    3. 参照を割り当てる、WPFWPFコンテンツ オブジェクト、RootVisualのプロパティ、HwndSourceします。Assign a reference to the WPFWPF content object to the RootVisual property of the HwndSource.

    4. コンテンツの HWND を取得します。Get the HWND for the content. Handle オブジェクトの HwndSource プロパティにウィンドウ ハンドル (HWND) が格納されます。The Handle property of the HwndSource object contains the window handle (HWND). アプリケーションのアンマネージ部分で使用できる HWND を取得するには、Handle.ToPointer() を HWND にキャストします。To get an HWND that you can use in the unmanaged part of your application, cast Handle.ToPointer() to an HWND.

  5. WPFWPF コンテンツへの参照を保持する静的フィールドを含むマネージド クラスを実装します。Implement a managed class that contains a static field to hold a reference to your WPFWPF content. このクラスを使用すると、WPFWPF コードから Win32Win32 コンテンツへの参照を取得できるようになります。This class allows you to get a reference to the WPFWPF content from your Win32Win32 code.

  6. WPFWPF コンテンツを静的フィールドに割り当てます。Assign the WPFWPF content to the static field.

  7. 通知を受信、WPFWPFコンテンツを 1 つまたは複数のハンドラーをアタッチすることにより、WPFWPFイベント。Receive notifications from the WPFWPF content by attaching a handler to one or more of the WPFWPF events.

  8. 静的フィールドに格納した参照を使用して WPFWPF コンテンツと通信し、プロパティの設定などを行います。Communicate with the WPFWPF content by using the reference that you stored in the static field to set properties, and so on.

注意

使用することもExtensible Application Markup Language (XAML)Extensible Application Markup Language (XAML)実装するために、WPFWPFコンテンツ。You can also use Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) to implement your WPFWPF content. ただし、このコンテンツは ダイナミック リンク ライブラリ (DLL)dynamic-link library (DLL) として別にコンパイルしてから、その [DLL]DLLWin32Win32 アプリケーションから参照する必要があります。However, you will have to compile it separately as a ダイナミック リンク ライブラリ (DLL)dynamic-link library (DLL) and reference that [DLL]DLL from your Win32Win32 application. 手順の残りの部分は、前述の手順と同様です。The remainder of the procedure is similar to that outlined above.

ホスト アプリケーションの実装Implementing the Host Application

このセクションの説明をホストする方法WPFWPFで基本的なコンテンツWin32Win32アプリケーション。This section describes how to host WPFWPF content in a basic Win32Win32 application. コンテンツ自体は、マネージド クラスとして C++/CLIC++/CLI に実装されます。The content itself is implemented in C++/CLIC++/CLI as a managed class. ほとんどの部分が、簡単な WPFWPF のプログラミングです。For the most part, it is straightforward WPFWPF programming. コンテンツの実装の重要な側面は、後ほどWPF コンテンツを実装するします。The key aspects of the content implementation are discussed in Implementing the WPF Content.

基本的なアプリケーションThe Basic Application

ホスト アプリケーションの開始点は、Visual Studio 2005 テンプレートを作成しました。The starting point for the host application was to create a Visual Studio 2005 template.

  1. Visual Studio 2005 を開き、選択新しいプロジェクトから、ファイルメニュー。Open Visual Studio 2005, and select New Project from the File menu.

  2. 選択Win32の一覧からVisual C++Visual C++プロジェクトの種類。Select Win32 from the list of Visual C++Visual C++ project types. 既定の言語がない場合C++C++、これらのプロジェクト タイプの下に表示されます他の言語します。If your default language is not C++C++, you will find these project types under Other Languages.

  3. 選択、 Win32 プロジェクトテンプレート、プロジェクトに名前を割り当てるし、をクリックしてOKを起動する、 Win32 アプリケーション ウィザードSelect a Win32 Project template, assign a name to the project and click OK to launch the Win32 Application Wizard.

  4. ウィザードの既定の設定をそのまま使用し、をクリックして完了プロジェクトを開始します。Accept the wizard's default settings and click Finish to start the project.

このテンプレートは、次のような基本的な Win32Win32 アプリケーションを作成します。The template creates a basic Win32Win32 application, including:

  • アプリケーションのエントリ ポイント。An entry point for the application.

  • 関連するウィンドウ プロシージャ (WndProc) を含むウィンドウ。A window, with an associated window procedure (WndProc).

  • 持つメニューファイルヘルプ見出し。A menu with File and Help headings. ファイルメニューがあります、終了項目をアプリケーションを閉じます。The File menu has an Exit item that closes the application. ヘルプメニューがあります、について簡単なダイアログ ボックスを起動する項目。The Help menu has an About item that launches a simple dialog box.

ホストにコードを記述する前に、WPFWPFコンテンツ、する必要がある 2 つの基本的なテンプレートを変更します。Before you start writing code to host the WPFWPF content, you need to make two modifications to the basic template.

1 つ目は、プロジェクトをマネージド コードとしてコンパイルすることです。The first is to compile the project as managed code. 既定では、プロジェクトはアンマネージ コードとしてコンパイルされます。By default, the project compiles as unmanaged code. ただし、WPFWPF はマネージド コードで実装されているため、プロジェクトは状況に応じてコンパイルする必要があります。However, because WPFWPF is implemented in managed code, the project must be compiled accordingly.

  1. プロジェクト名を右クリックしてソリューション エクスプ ローラー選択プロパティを起動するコンテキスト メニューから、プロパティ ページ ダイアログ ボックス。Right-click the project name in Solution Explorer and select Properties from the context menu to launch the Property Pages dialog box.

  2. 選択構成プロパティ左側のウィンドウで、ツリー ビューから。Select Configuration Properties from the tree view in the left pane.

  3. 選択共通言語ランタイムからサポート、プロジェクトの既定値右側のウィンドウの一覧。Select Common Language Runtime support from the Project Defaults list in the right pane.

  4. 選択共通言語ランタイム サポート (/clr) ドロップダウン リスト ボックスから。Select Common Language Runtime Support (/clr) from the drop-down list box.

注意

このコンパイラ フラグを使用すると、アプリケーションでマネージド コードを使用できますが、アンマネージド コードは以前と同様にコンパイルされます。This compiler flag allows you to use managed code in your application, but your unmanaged code will still compile as before.

WPFWPF は、シングル スレッド アパートメント (STA) スレッド処理モデルを使用します。uses the single-threaded apartment (STA) threading model. 正しく動作するために、WPFWPFコンテンツ コードは、する必要があります設定するアプリケーションのスレッド モデルを STA にエントリ ポイントに属性を適用しています。In order to work properly with the WPFWPF content code, you must set the application's threading model to STA by applying an attribute to the entry point.

[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{

WPF コンテンツのホスティングHosting the WPF Content

WPFWPFコンテンツは、単純なアドレス入力アプリケーションです。The WPFWPF content is a simple address entry application. それは、ユーザー名やアドレスなどを取得する複数の TextBox コントロールで構成されています。It consists of several TextBox controls to take user name, address, and so on. 2 つありますButtonコントロール、 OKキャンセルします。There are also two Button controls, OK and Cancel. ユーザーがクリックすると [ok]、ボタンのClickからデータを収集するイベント ハンドラー、TextBoxを制御に対応するプロパティは、代入、およびカスタム イベントを発生させますOnButtonClickedします。When the user clicks OK, the button's Click event handler collects the data from the TextBox controls, assigns it to corresponding properties, and raises a custom event, OnButtonClicked. ユーザーがクリックするとキャンセル、ハンドラーが発生させるだけですOnButtonClickedします。When the user clicks Cancel, the handler simply raises OnButtonClicked. OnButtonClicked のイベント引数オブジェクトには、どのボタンをクリックしたかを示すブール型フィールドが含まれています。The event argument object for OnButtonClicked contains a Boolean field that indicates which button was clicked.

ホストするコード、WPFWPFのハンドラーでコンテンツが実装されている、 WM_CREATEホスト ウィンドウに通知します。The code to host the WPFWPF content is implemented in a handler for the WM_CREATE notification on the host window.

case WM_CREATE :
  GetClientRect(hWnd, &rect);
  wpfHwnd = GetHwnd(hWnd, rect.right-375, 0, 375, 250);
  CreateDataDisplay(hWnd, 275, rect.right-375, 375);
  CreateRadioButtons(hWnd);
break;

GetHwndメソッドのサイズと位置情報および親ウィンドウ ハンドルを受け取るし、ホスト型のウィンドウ ハンドルを返しますWPFWPFコンテンツ。The GetHwnd method takes size and position information plus the parent window handle and returns the window handle of the hosted WPFWPF content.

注意

#using 名前空間に System::Windows::Interop ディレクティブを使用することはできません。You cannot use a #using directive for the System::Windows::Interop namespace. 使用すると、その名前空間の MSG 構造体と winuser.h で宣言した MSG 構造体の間で名前の競合が発生します。Doing so creates a name collision between the MSG structure in that namespace and the MSG structure declared in winuser.h. 代わりに、その名前空間のコンテンツにアクセスするための完全修飾名を使用する必要があります。You must instead use fully-qualified names to access the contents of that namespace.

HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
    System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters(
    "hi" // NAME
    );
    sourceParams->PositionX = x;
    sourceParams->PositionY = y;
    sourceParams->Height = height;
    sourceParams->Width = width;
    sourceParams->ParentWindow = IntPtr(parent);
    sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; // style
    System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
    WPFPage ^myPage = gcnew WPFPage(width, height);
    //Assign a reference to the WPF page and a set of UI properties to a set of static properties in a class
    //that is designed for that purpose.
    WPFPageHost::hostedPage = myPage;
    WPFPageHost::initBackBrush = myPage->Background;
    WPFPageHost::initFontFamily = myPage->DefaultFontFamily;
    WPFPageHost::initFontSize = myPage->DefaultFontSize;
    WPFPageHost::initFontStyle = myPage->DefaultFontStyle;
    WPFPageHost::initFontWeight = myPage->DefaultFontWeight;
    WPFPageHost::initForeBrush = myPage->DefaultForeBrush;
    myPage->OnButtonClicked += gcnew WPFPage::ButtonClickHandler(WPFButtonClicked);
    source->RootVisual = myPage;
    return (HWND) source->Handle.ToPointer();
}

ホストすることはできません、WPFWPFコンテンツを直接アプリケーション ウィンドウ。You cannot host the WPFWPF content directly in your application window. 代わりに、まず HwndSource コンテンツをラップするための WPFWPF オブジェクトを作成します。Instead, you first create an HwndSource object to wrap the WPFWPF content. このオブジェクトをホストするように設計されたウィンドウで、基本的に、WPFWPFコンテンツ。This object is basically a window that is designed to host a WPFWPF content. ホストする、HwndSource親ウィンドウの子として作成することでオブジェクトをWin32Win32ウィンドウは、アプリケーションの一部であります。You host the HwndSource object in the parent window by creating it as a child of a Win32Win32 window that is part of your application. HwndSource コンストラクターのパラメーターには、Win32Win32 の子ウィンドウの作成時に CreateWindow に渡される情報とほとんど同じ情報が含まれています。The HwndSource constructor parameters contain much the same information that you would pass to CreateWindow when you create a Win32Win32 child window.

次のインスタンスを作成、WPFWPFコンテンツ オブジェクト。You next create an instance of the WPFWPF content object. この場合は、WPFWPF コンテンツは、WPFPage を使用して、別のクラス C++/CLIC++/CLI として実装されます。In this case, the WPFWPF content is implemented as a separate class, WPFPage, using C++/CLIC++/CLI. さらに、WPFWPF コンテンツを XAMLXAML で実装することもできます。You could also implement the WPFWPF content with XAMLXAML. ただし、これを行うにする必要がある別のプロジェクトを設定して、ビルド、WPFWPFコンテンツとして、[DLL]DLLします。However, to do so you need to set up a separate project and build the WPFWPF content as a [DLL]DLL. プロジェクトにその [DLL]DLL への参照を追加し、その参照を使用して WPFWPF コンテンツのインスタンスを作成します。You can add a reference to that [DLL]DLL to your project, and use that reference to create an instance of the WPFWPF content.

表示する、WPFWPFコンテンツへの参照を割り当てることで、子ウィンドウに、WPFWPFコンテンツをRootVisualのプロパティ、HwndSourceします。You display the WPFWPF content in your child window by assigning a reference to the WPFWPF content to the RootVisual property of the HwndSource.

次のコード行は、イベント ハンドラー WPFButtonClickedWPFWPF コンテンツの OnButtonClicked イベントにアタッチしています。The next line of code attaches an event handler, WPFButtonClicked, to the WPFWPF content OnButtonClicked event. ユーザーがクリックしたときに、このハンドラーが呼び出されます、 OKまたはキャンセルボタン。This handler is called when the user clicks the OK or Cancel button. 参照してくださいcommunicating_with_the_WPF コンテンツこのイベント ハンドラーの詳細についてはします。See communicating_with_the_WPF content for further discussion of this event handler.

示されているコードの最後の行は、HwndSource オブジェクトに関連付けられているウィンドウ ハンドル (HWND) を返します。The final line of code shown returns the window handle (HWND) that is associated with the HwndSource object. このハンドルは、Win32Win32 コードから使用してホストされたウィンドウにメッセージを送信することができます。ただし、サンプルではこれはできません。You can use this handle from your Win32Win32 code to send messages to the hosted window, although the sample does not do so. HwndSource オブジェクトは、メッセージを受信するたびにイベントを発生させます。The HwndSource object raises an event every time it receives a message. メッセージを処理するには、AddHook メソッドを呼び出してメッセージ ハンドラーをアタッチしてから、そのハンドラーでメッセージを処理します。To process the messages, call the AddHook method to attach a message handler and then process the messages in that handler.

WPF コンテンツへの参照の保持Holding a Reference to the WPF Content

多くのアプリケーションでは、後で WPFWPF コンテンツと通信することができます。For many applications, you will want to communicate with the WPFWPF content later. たとえば、WPFWPF コンテンツのプロパティを変更したり、場合によっては HwndSource オブジェクトが異なる WPFWPF コンテンツをホストするようにしたりできます。For example, you might want to modify the WPFWPF content properties, or perhaps have the HwndSource object host different WPFWPF content. そのためには、HwndSource オブジェクトまたは WPFWPF コンテンツへの参照が必要です。To do this, you need a reference to the HwndSource object or the WPFWPF content. HwndSource オブジェクトと関連する WPFWPF コンテンツは、ウィンドウ ハンドルを破棄するまでメモリに残ります。The HwndSource object and its associated WPFWPF content remain in memory until you destroy the window handle. ただし、HwndSource オブジェクトに割り当てる変数は、ウィンドウ プロシージャから戻ると同時にスコープの外に出ます。However, the variable you assign to the HwndSource object will go out of scope as soon as you return from the window procedure. Win32Win32 アプリケーションでこの問題を処理するためによく使用される方法は、静的変数またはグローバル変数を使用することです。The customary way to handle this issue with Win32Win32 applications is to use a static or global variable. 残念ながら、このような変数の種類に対してマネージド オブジェクトを割り当てることはできません。Unfortunately, you cannot assign a managed object to those types of variables. HwndSource オブジェクトに関連付けられているウィンドウ ハンドルを、グローバル変数または静的変数に割り当てることができますが、オブジェクト自体にアクセスすることはできません。You can assign the window handle associated with HwndSource object to a global or static variable, but that doe not provide access to the object itself.

この問題の最も簡単な解決法は、静的フィールドのセットを含むマネージド クラスを実装して、アクセスが必要なすべてのマネージド オブジェクトへの参照を保持することです。The simplest solution to this issue is to implement a managed class that contains a set of static fields to hold references to any managed objects that you need access to. サンプルでは、WPFPageHost クラスを使用して、WPFWPF コンテンツへの参照、および後でユーザーが変更する可能性があるプロパティの数の初期値を保持します。The sample uses the WPFPageHost class to hold a reference to the WPFWPF content, plus the initial values of a number of its properties that might be changed later by the user. これは、ヘッダーで定義します。This is defined in the header.

public ref class WPFPageHost
{
public:
  WPFPageHost();
  static WPFPage^ hostedPage;
  //initial property settings
  static System::Windows::Media::Brush^ initBackBrush;
  static System::Windows::Media::Brush^ initForeBrush;
  static System::Windows::Media::FontFamily^ initFontFamily;
  static System::Windows::FontStyle initFontStyle;
  static System::Windows::FontWeight initFontWeight;
  static double initFontSize;
};

GetHwnd 関数の後半部分では、後に、myPage がスコープ内にある間に使用するため、対象のフィールドに値を割り当てます。The latter part of the GetHwnd function assigns values to those fields for later use while myPage is still in scope.

WPF コンテンツとの通信Communicating with the WPF Content

WPFWPF コンテンツとの通信には次の 2 種類があります。There are two types of communication with the WPFWPF content. アプリケーションから情報を受信する、WPFWPFコンテンツ、ユーザーがクリックしたときに、 OKまたはキャンセルボタン。The application receives information from the WPFWPF content when the user clicks the OK or Cancel buttons. アプリケーションには、背景色や既定のフォント サイズなどのさまざまな UIUI コンテンツのプロパティをユーザーが変更できるようにする WPFWPF があります。The application also has a UIUI that allows the user to change various WPFWPF content properties, such as the background color or default font size.

前述のように、ユーザーがいずれかのボタンをクリックすると、WPFWPF コンテンツは OnButtonClicked イベントを発生させます。As mentioned above, when the user clicks either button the WPFWPF content raises an OnButtonClicked event. アプリケーションは、これらの通知を受信するため、このイベントにハンドラーをアタッチします。The application attaches a handler to this event to receive these notifications. 場合、 OKボタンがクリックされた、ハンドラーからのユーザー情報を取得する、WPFWPFコンテンツし、一連の静的コントロールで表示されます。If the OK button was clicked, the handler gets the user information from the WPFWPF content and displays it in a set of static controls.

void WPFButtonClicked(Object ^sender, MyPageEventArgs ^args)
{
    if(args->IsOK) //display data if OK button was clicked
    {
        WPFPage ^myPage = WPFPageHost::hostedPage;
        LPCWSTR userName = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Name: " + myPage->EnteredName).ToPointer();
        SetWindowText(nameLabel, userName);
        LPCWSTR userAddress = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Address: " + myPage->EnteredAddress).ToPointer();
        SetWindowText(addressLabel, userAddress);
        LPCWSTR userCity = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("City: " + myPage->EnteredCity).ToPointer();
        SetWindowText(cityLabel, userCity);
        LPCWSTR userState = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("State: " + myPage->EnteredState).ToPointer();
        SetWindowText(stateLabel, userState);
        LPCWSTR userZip = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Zip: " + myPage->EnteredZip).ToPointer();
        SetWindowText(zipLabel, userZip);
    }
    else
    {
        SetWindowText(nameLabel, L"Name: ");
        SetWindowText(addressLabel, L"Address: ");
        SetWindowText(cityLabel, L"City: ");
        SetWindowText(stateLabel, L"State: ");
        SetWindowText(zipLabel, L"Zip: ");
    }
}

ハンドラーは、カスタム イベント引数オブジェクトを WPFWPF のコンテンツ、MyPageEventArgs から受信します。The handler receives a custom event argument object from the WPFWPF content, MyPageEventArgs. オブジェクトのIsOKプロパティに設定されてtrue場合、 OKボタンがクリックされたとfalse場合、キャンセルボタンがクリックされました。The object's IsOK property is set to true if the OK button was clicked, and false if the Cancel button was clicked.

場合、 OKボタンがクリックされた、ハンドラーへの参照を取得する、WPFWPFコンテナー クラスからのコンテンツ。If the OK button was clicked, the handler gets a reference to the WPFWPF content from the container class. その後、関連する WPFWPF コンテンツ プロパティが保持するユーザー情報を収集し、静的コントロールを使用して親ウィンドウに情報を表示します。It then collects the user information that is held by the associated WPFWPF content properties and uses the static controls to display the information on the parent window. WPFWPF コンテンツ データは、マネージド文字列の形式であるため、Win32Win32 コントロールによってマーシャリングする必要があります。Because the WPFWPF content data is in the form of a managed string, it has to be marshaled for use by a Win32Win32 control. 場合、キャンセルボタンがクリックされ、ハンドラーは、スタティック コントロールからデータをクリアします。If the Cancel button was clicked, the handler clears the data from the static controls.

アプリケーション UIUI には、ユーザーが WPFWPF コンテンツの背景色を変更できるようにするラジオ ボタンのセット、および複数のフォント関連のプロパティが用意されています。The application UIUI provides a set of radio buttons that allow the user to modify the background color of the WPFWPF content, and several font-related properties. 次の例は、アプリケーションのウィンドウ プロシージャ (WndProc)、および背景色など、各種のメッセージに対してさまざまなプロパティを設定するそのプロシージャのメッセージ処理からの抜粋です。The following example is an excerpt from the application's window procedure (WndProc) and its message handling that sets various properties on different messages, including the background color. その他は類似しているため、示していません。The others are similar, and are not shown. 詳細とコンテキストについては、完全なサンプルを参照してください。See the complete sample for details and context.

case WM_COMMAND:
  wmId    = LOWORD(wParam);
  wmEvent = HIWORD(wParam);

  switch (wmId)
  {
  //Menu selections
    case IDM_ABOUT:
      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    break;
    case IDM_EXIT:
      DestroyWindow(hWnd);
    break;
    //RadioButtons
    case IDC_ORIGINALBACKGROUND :
      WPFPageHost::hostedPage->Background = WPFPageHost::initBackBrush;
    break;
    case IDC_LIGHTGREENBACKGROUND :
      WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightGreen);
    break;
    case IDC_LIGHTSALMONBACKGROUND :
      WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightSalmon);
    break;

背景色を設定するには、WPFWPF から hostedPage コンテンツ (WPFPageHost) への参照を取得して、背景色のプロパティを適切な色に設定します。To set the background color, get a reference to the WPFWPF content (hostedPage) from WPFPageHost and set the background color property to the appropriate color. サンプルでは、元の色、明るい緑、または明るいサーモン色の 3 つの色のオプションを使用します。The sample uses three color options: the original color, light green, or light salmon. 元の背景色は静的フィールドとして WPFPageHost クラスに格納されます。The original background color is stored as a static field in the WPFPageHost class. 他の 2 つの色を設定するには、新しい SolidColorBrush オブジェクトを作成して、Colors オブジェクトからコンストラクターに静的な色の値を渡します。To set the other two, you create a new SolidColorBrush object and pass the constructor a static colors value from the Colors object.

WPF ページの実装Implementing the WPF Page

ホストして、使用することができます、WPFWPF実際の実装の知識がなくてもコンテンツ。You can host and use the WPFWPF content without any knowledge of the actual implementation. 場合、WPFWPF別でコンテンツをパッケージ化されていた[DLL]DLL、いずれかで構築されたでした共通言語ランタイム (CLR)common language runtime (CLR)言語。If the WPFWPF content had been packaged in a separate [DLL]DLL, it could have been built in any 共通言語ランタイム (CLR)common language runtime (CLR) language. 以下は、このサンプルで使用する C++/CLIC++/CLI の実装の簡単なチュートリアルです。Following is a brief walkthrough of the C++/CLIC++/CLI implementation that is used in the sample. このセクションには、次のサブセクションが含まれています。This section contains the following subsections.

レイアウトLayout

UIUI内の要素、WPFWPFコンテンツから成る 5TextBox制御は、関連付けられているLabelコントロール。名前、アドレス、市区町村、状態、および Zip です。The UIUI elements in the WPFWPF content consist of five TextBox controls, with associated Label controls: Name, Address, City, State, and Zip. 2 つあるButtonコントロール、 OKキャンセルThere are also two Button controls, OK and Cancel

WPFWPF コンテンツは WPFPage クラスに実装されています。The WPFWPF content is implemented in the WPFPage class. レイアウトは、Grid レイアウト要素で処理されます。Layout is handled with a Grid layout element. クラスは Grid から継承されます。これにより、クラスは効果的に WPFWPF コンテンツのルート要素になります。The class inherits from Grid, which effectively makes it the WPFWPF content root element.

WPFWPFコンテンツのコンス トラクターは、必要な幅と高さ、およびサイズ、Gridそれに応じて。The WPFWPF content constructor takes the required width and height, and sizes the Grid accordingly. セットを作成して基本的なレイアウトを定義しColumnDefinitionRowDefinitionオブジェクトと追加すること、Gridオブジェクトの基本ColumnDefinitionsRowDefinitionsコレクション、それぞれします。It then defines the basic layout by creating a set of ColumnDefinition and RowDefinition objects and adding them to the Grid object base ColumnDefinitions and RowDefinitions collections, respectively. これにより、5 つの行と、7 つの列のグリッドが定義され、セルの内容によって大きさが決定します。This defines a grid of five rows and seven columns, with the dimensions determined by the contents of the cells.

WPFPage::WPFPage(int allottedWidth, int allotedHeight)
{
  array<ColumnDefinition ^> ^ columnDef = gcnew array<ColumnDefinition ^> (4);
  array<RowDefinition ^> ^ rowDef = gcnew array<RowDefinition ^> (6);

  this->Height = allotedHeight;
  this->Width = allottedWidth;
  this->Background = gcnew SolidColorBrush(Colors::LightGray);
  
  //Set up the Grid's row and column definitions
  for(int i=0; i<4; i++)
  {
    columnDef[i] = gcnew ColumnDefinition();
    columnDef[i]->Width = GridLength(1, GridUnitType::Auto);
    this->ColumnDefinitions->Add(columnDef[i]);
  }
  for(int i=0; i<6; i++)
  {
    rowDef[i] = gcnew RowDefinition();
    rowDef[i]->Height = GridLength(1, GridUnitType::Auto);
    this->RowDefinitions->Add(rowDef[i]);
  }

次に、コンストラクターは UIUI 要素を Grid に追加します。Next, the constructor adds the UIUI elements to the Grid. 最初の要素はタイトルのテキストです。これは、グリッドの 1 行目の中央に表示される Label コントロールです。The first element is the title text, which is a Label control that is centered in the first row of the grid.

//Add the title
titleText = gcnew Label();
titleText->Content = "Simple WPF Control";
titleText->HorizontalAlignment = System::Windows::HorizontalAlignment::Center;
titleText->Margin = Thickness(10, 5, 10, 0);
titleText->FontWeight = FontWeights::Bold;
titleText->FontSize = 14;
Grid::SetColumn(titleText, 0);
Grid::SetRow(titleText, 0);
Grid::SetColumnSpan(titleText, 4);
this->Children->Add(titleText);

次の行には、名前の Label コントロールと関連する TextBox コントロールが格納されます。The next row contains the Name Label control and its associated TextBox control. ラベルとテキスト ボックスの各ペアに同じコードが使用されるため、コードはプライベート メソッドのペアに配置され、5 つのラベルとテキスト ボックスのペアすべてに使用されます。Because the same code is used for each label/textbox pair, it is placed in a pair of private methods and used for all five label/textbox pairs. メソッドは適切な制御を作成し、Grid クラスの静的な SetColumn および SetRow メソッドを呼び出して、適切なセルにコントロールを配置します。The methods create the appropriate control, and call the Grid class static SetColumn and SetRow methods to place the controls in the appropriate cell. コントロールが作成されると、サンプルは AddChildren プロパティの Grid メソッドを呼び出して、グリッドにコントロールを追加します。After the control is created, the sample calls the Add method on the Children property of the Grid to add the control to the grid. 残りのラベルとテキスト ボックスのペアを追加するコードは似ています。The code to add the remaining label/textbox pairs is similar. 詳細については、サンプル コードを参照してください。See the sample code for details.

//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);

2 つのメソッドの実装は、次のとおりです。The implementation of the two methods is as follows:

Label ^WPFPage::CreateLabel(int column, int row, String ^ text)
{
  Label ^ newLabel = gcnew Label();
  newLabel->Content = text;
  newLabel->Margin = Thickness(10, 5, 10, 0);
  newLabel->FontWeight = FontWeights::Normal;
  newLabel->FontSize = 12;
  Grid::SetColumn(newLabel, column);
  Grid::SetRow(newLabel, row);
  return newLabel;
}
TextBox ^WPFPage::CreateTextBox(int column, int row, int span)
{
  TextBox ^newTextBox = gcnew TextBox();
  newTextBox->Margin = Thickness(10, 5, 10, 0);
  Grid::SetColumn(newTextBox, column);
  Grid::SetRow(newTextBox, row);
  Grid::SetColumnSpan(newTextBox, span);
  return newTextBox;
}

最後に、サンプルは、追加、 [ok]キャンセル] ボタンし、[イベント ハンドラーをアタッチします、Clickイベント。Finally, the sample adds the OK and Cancel buttons and attaches an event handler to their Click events.

//Add the Buttons and atttach event handlers
okButton = CreateButton(0, 5, "OK");
cancelButton = CreateButton(1, 5, "Cancel");
this->Children->Add(okButton);
this->Children->Add(cancelButton);
okButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);
cancelButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);

データをホスト ウィンドウに返すReturning the Data to the Host Window

いずれかのボタンをクリックすると、その Click イベントが発生します。When either button is clicked, its Click event is raised. ホスト ウィンドウはこれらのイベントにハンドラーをアタッチして、TextBox コントロールから直接データを取得します。The host window could simply attach handlers to these events and get the data directly from the TextBox controls. サンプルは、いくぶん直接的ではない方法を使用します。The sample uses a somewhat less direct approach. 処理、Click内、WPFWPFコンテンツ、およびカスタム イベントが発生し、OnButtonClickedに通知する、WPFWPFコンテンツ。It handles the Click within the WPFWPF content, and then raises a custom event OnButtonClicked, to notify the WPFWPF content. これにより、WPFWPFコンテンツをホストに通知する前にパラメーターの検証を実行します。This allows the WPFWPF content to do some parameter validation before notifying the host. ハンドラーは、TextBox コントロールからテキストを取得し、パブリック プロパティに割り当てます。ここからホストは情報を取得します。The handler gets the text from the TextBox controls and assigns it to public properties, from which the host can retrieve the information.

WPFPage.h でのイベント宣言:The event declaration, in WPFPage.h:

public:
  delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
  WPFPage();
  WPFPage(int height, int width);
  event ButtonClickHandler ^OnButtonClicked;

WPFPage.cpp での Click イベント ハンドラー:The Click event handler, in WPFPage.cpp:

void WPFPage::ButtonClicked(Object ^sender, RoutedEventArgs ^args)
{

  //TODO: validate input data
  bool okClicked = true;
  if(sender == cancelButton)
    okClicked = false;
  EnteredName = nameTextBox->Text;
  EnteredAddress = addressTextBox->Text;
  EnteredCity = cityTextBox->Text;
  EnteredState = stateTextBox->Text;
  EnteredZip = zipTextBox->Text;
  OnButtonClicked(this, gcnew MyPageEventArgs(okClicked));
}

WPF のプロパティを設定するSetting the WPF Properties

Win32Win32ホストにより、ユーザーがいくつか変更WPFWPFコンテンツのプロパティ。The Win32Win32 host allows the user to change several WPFWPF content properties. Win32Win32 側では、これはプロパティの変更の問題にすぎません。From the Win32Win32 side, it is simply a matter of changing the properties. WPFWPF のコンテンツ クラスの実装はいくらか複雑になります。これは、全コントロールのフォントを制御する 1 つのグローバル プロパティがないためです。The implementation in the WPFWPF content class is somewhat more complicated, because there is no single global property that controls the fonts for all controls. 代わりに、各コントロールの適切なプロパティは、プロパティの set アクセサーで変更されます。Instead, the appropriate property for each control is changed in the properties' set accessors. 次の例のコードを示しています、DefaultFontFamilyプロパティ。The following example shows the code for the DefaultFontFamily property. プロパティを設定すると、プライベート メソッドが呼び出され、さまざまなコントロールに FontFamily プロパティが設定されます。Setting the property calls a private method that in turn sets the FontFamily properties for the various controls.

WPFPage.h から:From WPFPage.h:

property FontFamily^ DefaultFontFamily
{
  FontFamily^ get() {return _defaultFontFamily;}
  void set(FontFamily^ value) {SetFontFamily(value);}
};

WPFPage.cpp から:From WPFPage.cpp:

void WPFPage::SetFontFamily(FontFamily^ newFontFamily)
{
  _defaultFontFamily = newFontFamily;
  titleText->FontFamily = newFontFamily;
  nameLabel->FontFamily = newFontFamily;
  addressLabel->FontFamily = newFontFamily;
  cityLabel->FontFamily = newFontFamily;
  stateLabel->FontFamily = newFontFamily;
  zipLabel->FontFamily = newFontFamily;
}

関連項目See also