Build your first GacUI Application!
This is a walkthrough of building a Hello World application in GacUI.
It based on one of the demo project released with GacUI.
You need to prepare the following first:
- Download GacUI from github.
-
For Windows,
Install Visual Studio 2022 Community or newer version
-
For macOS,
(article to be completed)
-
For Linux,
(article to be completed)
1. Prepare your folder structure
- GacUI.xml
- UI folder
- Source folder: empty, storing generated C++ files from Resource.xml
- Resource.xml
- Lib folder: copy files to this folder from here. Choose all files in "Files you need for a typical GacUI application" from the Download page.
- Main.cpp
- WinMain.cpp
1.1. GacUI.xml
GacUI allow resource files to have dependency to other resource files.
GacUI.xml is placed in the root folder.
Run GacBuild.ps1 on GacUI.xml and it will search all resource files recursively.
In this tutorial, we only have one resource file,
that is UI\Resource.xml.
In this case, concent of GacUI.xml is very simple:
<GacUI/>
1.2. UI\Resource.xml
In this file, we specify the following informations:
- Where to store generated C++ files
- Where to store the generated binary resource file
- Include "GacUI.h" because we don't need runtime reflection
- The name is HelloWorld
- Describe the HelloWorld window
<?xml version="1.0" encoding="utf-8"?>
<Resource>
<Folder name="GacGenConfig">
<Folder name="Cpp">
<Text name="SourceFolder">Source</Text>
<Text name="Resource">..\HelloWorld.bin</Text>
<Text name="NormalInclude">GacUI.h</Text>
<Text name="Name">HelloWorld</Text>
</Folder>
</Folder>
<Folder name="MainWindow">
<Instance name="MainWindowResource">
<Instance ref.CodeBehind="false" ref.Class="helloworld::MainWindow">
<Window Text="Hello, world!" ClientSize="x:480 y:320">
<att.BoundsComposition-set PreferredMinSize="x:480 y:320"/>
<Label Text="Welcome to GacUI Library!">
<att.Font>fontFamily:"Segoe UI" size:32 antialias:true</att.Font>
</Label>
</Window>
</Instance>
</Instance>
</Folder>
</Resource>
2. Build GacUI Resource File
In the root folder, run GacBuild.ps1, with parameter "GacUI.xml".
GacBuild.ps1 performs incremental build,
when you have multiple GacUI resource files.
GacClear.ps1 deletes all log files created by GacBuild.ps1,
to cause GacBuild.ps1 perform a full build in the next time.
If it build successfully,
you will see HelloWorld.bin on the root folder,
and also some files in UI\Source folder.
We only need:
- HelloWorld.h
- HelloWorldPartialClasses.h
- HelloWorldPartialClasses.cpp
There is also a Resource.xml.log folder created.
This folder contains build results for GacBuild.ps1 for incremental build.
It is safe to be deleted.
3. Main.cpp
To build this file,
you need to include necessary files to your VC++ project:
- UI\Source\HelloWorld.h
- UI\Source\HelloWorldPartialClasses.h
- UI\Source\HelloWorldPartialClasses.cpp
- Selected files in Lib folder.
We don't need runtime reflection in this project,
so you have to define a empty VCZH_DEBUG_NO_REFLECTION macro using preprocessor definitions.
You can either to this by updating your project properties,
or use the /D compiler option if you are using Visual Studio Code.
You need to add Lib to your include folder list.
You can either to this by updating your project properties,
or use the /I compiler option if you are using Visual Studio Code.
#define GAC_HEADER_USE_NAMESPACE
#include "UI/Source/HelloWorld.h"
using namespace vl::collections;
using namespace vl::stream;
void GuiMain()
{
{
FileStream fileStream(L"HelloWorld.bin", FileStream::ReadOnly);
GetResourceManager()->LoadResourceOrPending(fileStream);
}
helloworld::MainWindow window;
window.MoveToScreenCenter();
GetApplication()->Run(&window);
}
Please note that, you need to carefully place HelloWorld.bin,
and search for this file at runtime.
"HelloWorld.bin" is a relative path,
it will try to find the file in your working directory.
When you press F5 in Visual Studio, the working directory is the folder containing the ".vcxproj" file.
When you double click the executable file, the working directory is where the executable file is in.
You are recommended to Calculate a absolute path based on the full path of the executable file.
GetApplication()->GetExecutableFolder() is useful here.
4. WinMain.cpp
WinMain function is the entry of a Windows GUI program.
#define GAC_HEADER_USE_NAMESPACE
#include <GacUI.h>
#include <Skins\DarkSkin\DarkSkin.h>
#include <Windows.h>
class DefaultSkinPlugin : public Object, public IGuiPlugin
{
public:
GUI_PLUGIN_NAME(Custom_DefaultSkinPlugin)
{
GUI_PLUGIN_DEPEND(GacGen_DarkSkinResourceLoader);
}
void Load(bool, bool)override
{
RegisterTheme(Ptr(new darkskin::Theme));
}
void Unload(bool, bool)override
{
}
};
GUI_REGISTER_PLUGIN(DefaultSkinPlugin)
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
{
return SetupWindowsDirect2DRenderer();
}
The DefaultSkinPlugin class uses the predefined DarkSkin as the default control template.
You can write your own control template to override default ones for some controls.
You can also write control template for all controls and get rid of the DarkSkin.
Every control needs a default control template assigned in order to launch a GacUI program.
5. Build and run your program!
