Avalon without XAML

Introduction

I'm learning Avalon. I would like to access Avalon controls directly from C++/CLI code without separate XAML files. It's not straightforward, so I document steps to create such app here.

I used physical XP SP2 system (works under VMWare 5.0 too), Visual Studio 2005 Pro, WinFX November CTP Runtime Components (to run following Avalon apps on client computer it's enough to install only Runtime Components. Entire Runtime Components package (43 MB) is available at the bottom of the link).

Screenshots were made under Windows Classic (aka gray) theme.

Message box

screenshot

1. Create new empty C++ CLR project in VS.

Visual C++ - CLR - CLR Empty Project.

2. Set Windows SubSystem and main Entry Point.

To remove console window, for all configurations in Properties - Configuration Properties - Linker:

3. Add reference to PresentationFramework.dll.

Project - Properties - References - Add new reference - Browse - c:\WINDOWS\assembly\GAC_MSIL\PresentationFramework\6.0.5070.0__31bf3856ad364e35\PresentationFramework.dll

4. Add main.cpp source code.

[System::STAThreadAttribute]
int main()
{
	System::Windows::MessageBox::Show("Hello, Avalon");
}
Download solution.

Rendering

screenshot

4. Repeat steps 1-3 for Message box and add references to PresentationCore.dll and WindowsBase.dll.

c:\WINDOWS\assembly\GAC_32\PresentationCore\6.0.5070.0__31bf3856ad364e35\PresentationCore.dll c:\WINDOWS\assembly\GAC_MSIL\WindowsBase\6.0.5070.0__31bf3856ad364e35\WindowsBase.dll

5. Add main.cpp source code.

namespace WinMedia = System::Windows::Media;

ref class MyCanvas : public System::Windows::Controls::Canvas{
protected:
	virtual void OnRender(WinMedia::DrawingContext^ drawingContext) override 
	{ 
		WinMedia::Brush^ brushForPen = gcnew WinMedia::SolidColorBrush(WinMedia::Colors::Blue);
		WinMedia::Pen^ pen = gcnew WinMedia::Pen(brushForPen, 3);
			
		System::Windows::Point p1(0, 0), p2(200, 200), p3(0, 200), p4(200, 0);
		drawingContext->DrawLine(pen, p1, p2);
		drawingContext->DrawLine(pen, p3, p4);
	} 
};

ref class MyWindow : public System::Windows::Window{

	void SetBackgroundOrOnlyBlackWindowOnMyMachine(){
		WinMedia::Imaging::RenderTargetBitmap^ bmp = 
			gcnew WinMedia::Imaging::RenderTargetBitmap(1, 1, 1, 1, WinMedia::PixelFormats::Default);
		Background = gcnew WinMedia::ImageBrush(bmp);
	}

public:
	MyWindow(){
		SetBackgroundOrOnlyBlackWindowOnMyMachine();

		AddChild(gcnew MyCanvas());
		Title = "Avalon Render";
	}
};

[System::STAThreadAttribute]
int main()
{
	System::Windows::Application^ app = gcnew System::Windows::Application();
	app->Run(gcnew MyWindow());
}
Download solution.

Without SetBackground... workaround I have only black empty window. I read about it from Greg Kerr posting to microsoft.public.windows.developer.winfx.avalon newsgroup.

Button

screenshot

4. Repeat steps 1-4 for Rednering.

5. Add main.cpp source code.

namespace WinMedia = System::Windows::Media;

ref class MyWindow : public System::Windows::Window{

	void SetBackgroundOrOnlyBlackWindowOnMyMachine(){
		WinMedia::Imaging::RenderTargetBitmap^ bmp = 
			gcnew WinMedia::Imaging::RenderTargetBitmap(1, 1, 1, 1, WinMedia::PixelFormats::Default);
		Background = gcnew WinMedia::ImageBrush(bmp);
	}

public:
	MyWindow(){
		SetBackgroundOrOnlyBlackWindowOnMyMachine();

		AddChild(gcnew System::Windows::Controls::Button());
		Title = "Avalon Button";
	}
};

[System::STAThreadAttribute]
int main()
{
	System::Windows::Application^ app = gcnew System::Windows::Application();
	app->Run(gcnew MyWindow());
}
Download solution.

Conclusion

Simplest examples work. I hope I will be able to follow this approach for more complex tasks without additional obstacles.

Copyright (C) 2005 Sergey Vlasov