かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

C++でWPF

C++といっても普通のC++じゃなくてC++/CLIです。
まず、WPFアプリケーションのテンプレートはないので、空のCLRプロジェクトを作成します。ここでは、プロジェクトの名前を「WPFCppEdu」にしました。

プロジェクトのプロパティを設定していきます。

共通プロパティの設定

参照設定を、追加していきます。

  • System:必須だよね。
  • PresentationCore:WPFには必須
  • PresentationFramework:WPFには必須
  • WindowsBase:WPFには必須

上記4つを、追加しました。

構成プロパティの設定

構成プロパティも続いて設定します。とりあえずWindowsアプリケーションなので、リンカのシステムのサブシステムを「Windows(/SUBSYSTEM:WINDOWS)」にします。次に、リンカの詳細のエントリポイントを「main」にします。

main関数の作成

App.cppという名前のC++ファイルを作成して、ここにmain関数を作っていきます。

int main(array<System::String ^> ^args)
{
	return 0;
}

これで、やっと実行できる形になりました。(といっても実行しても何もおきませんが)

Window1クラスの作成

さて、XAMLを書いたりしたいのですが、ちょっとC++のプロジェクトでXAML使って画面作る方法が、ぱっと見わからなかったのでコードで書いていきます。C++クラスウィザードで、Window1クラス(もちろんマネージでね)をプロジェクトに追加します。

// Window1.h
#pragma once

ref class Window1 : System::Windows::Window
{
public:
	Window1(void);
};
// Window1.cpp
#include "Window1.h"

Window1::Window1(void)
{
}

とりあえず、ボタンがあって、ボタンをクリックするとHello worldと表示されるものを作ってみようと思います。なので、ボタンクリック用のメソッドと、Window1のコンストラクタでUIを組み立てます。

// Window1.h
#pragma once
using namespace System;
using namespace System::Windows;

ref class Window1 : System::Windows::Window
{
public:
	Window1(void);
private:
	// ボタンクリックのイベントハンドラ
	void Button_Click(Object ^sender, RoutedEventArgs ^e);
};
// Window1.cpp
#include "Window1.h"
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;

Window1::Window1(void)
{
	Button ^btn1 = gcnew Button();
	btn1->Content = L"押してね";
	btn1->Click += gcnew RoutedEventHandler(this, &Window1::Button_Click);

	this->Content = btn1;
}

void Window1::Button_Click(Object ^sender, RoutedEventArgs ^e)
{
	MessageBox::Show(L"こんにちは世界");
}

これで、OKなはず。仕上げにmain関数に、ApplicationクラスのRunにWindow1を渡すようにします。

// App.cpp
#include "Window1.h" // Window1
using namespace System::Windows;

[STAThread]
int main(array<System::String ^> ^args)
{
	Application ^app = gcnew Application();
	app->Run(gcnew Window1());
	return 0;
}

実行

以上で完成!実行してみると以下のような感じでちゃんと動いています。正直C#のほうが楽!(当然だけど・・・)