かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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#のほうが楽!(当然だけど・・・)