WinUI - 起動時のウィンドウサイズを指定する
C++ で WinUI 3 ライブラリを使う
アプリを起動したときのウィンドウサイズは、MainWindow のコンストラクタでAppWindow::Resize を使って指定できます。
#include <winrt/Microsoft.UI.Interop.h> #include <winrt/Microsoft.UI.Windowing.h> MainWindow::MainWindow() { InitializeComponent(); auto hWnd = stuff::getHwnd(this); auto wndId = Microsoft::UI::GetWindowIdFromWindow(hWnd); auto appWnd = Microsoft::UI::Windowing::AppWindow::GetFromWindowId(wndId); appWnd.Resize(Windows::Graphics::SizeInt32{ 1000, 600 }); }
MainWindow から HWND → WindowId → AppWindow と変換します。
MainWindow から HWND に変換する getHwnd 関数は、ウインドウハンドル (HWND) を取得する で説明しています。
参考
WinUI 3 with C++ 入門 - ビリヤードが好きなプログラマー
GetWindowIdFromWindow - Windows App SDK | Microsoft Learn
AppWindow Class (Microsoft.UI.Windowing) - Windows App SDK | Microsoft Learn
WinUI - XAML で日本語を使ったときの文字化けを直す
C++ で WinUI 3 ライブラリを使う
XAML ファイルのメニュー名やボタン名などに日本語を使うとアプリを実行したときに文字化けします。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button x:Name="myButton" Click="myButton_Click">ボタン押してね</Button> </StackPanel>
このような時は XAML ファイルを UTF-8 の文字コードで保存しましょう。
XAMファイルを開いた状態でファイルメニューから名前を付けて保存を選びます。
上書き保存ボタンのエンコード付きで保存を選択します。
UTF-8 を選びます。
ビルドしてアプリを起動すれば、文字化けが解消されているはずです。
参考
WinUI - ウインドウハンドル (HWND) を取得する
C++ で WinUI 3 ライブラリを使う
ウィンドウハンドルを取得する方法を紹介します。
ウィンドウハンドルは IWindowNative::get_WindowHandle で取得できるので、関数にしてみました。
また IWindowNative クラスは microsoft.ui.xaml.window.h で定義されているのでインクルードします。 winrt フォルダ下の winrt/Microsoft.UI.Xaml.~ ではないので間違えないようにしましょう。
#include <microsoft.ui.xaml.window.h> /// IWindowNative を実装するオブジェクトによって表されるウィンドウのウィンドウハンドル (HWND) を取得します。 template<typename T> auto getHwnd(T pWnd) -> HWND { HWND hWnd = 0; if (auto p = pWnd->try_as<::IWindowNative>(); p) { p->get_WindowHandle(&hWnd); } return hWnd; }
このように使います。
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&) { auto hWnd = getHwnd(this); }
参考
WinUI 3 with C++ 入門 - ビリヤードが好きなプログラマー
IWindowNative::get_WindowHandle - Windows App SDK | Microsoft Learn
WinUI - XAML要素のインスタンスにコードからアクセスする
C++ で WinUI 3 ライブラリを使う
XAMLで定義した要素のインスタンスに C++ のコードからアクセスするには、XAML要素に Name 属性をつけます。そうすると XAMLのコンパイル時に Generated Files下にSetter/Getter 実装したファイルが作られ、C++ のコードからアクセスできるようになります。
例えば、Button に Name属性 myButton を設定すると
<Window> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button x:Name="myButton" Click="myButton_Click">Click Me</Button> </StackPanel> </Window>
Setter/Getter を実装した Generated Files/MainWindow.xaml.g.h が作成され
namespace winrt::NavigationView1::implementation { template <typename D, typename ... I> struct MainWindowT : public ::winrt::NavigationView1::implementation::MainWindow_base<D, ::winrt::Microsoft::UI::Xaml::Markup::IComponentConnector, I...> { ::winrt::Microsoft::UI::Xaml::Controls::Button myButton() { return _myButton; } void myButton(::winrt::Microsoft::UI::Xaml::Controls::Button value) { _myButton = value; } private: ::winrt::Microsoft::UI::Xaml::Controls::Button _myButton{nullptr}; }; }
MainWindow.cpp で myButton() を使って Button のインスタンスを取得できるようになります。
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&) { myButton().Content(box_value(L"Clicked")); }
参考
WinUI - イベントハンドラを追加する
C++ で WinUI 3 ライブラリを使う
Button などのコントロールにイベントハンドラを追加したかったのですが、その方法がわからず苦労したので紹介します。
Visual Studio で XAMLファイルを開き、XAML要素にイベントの属性名と = を入力すると <新しいイベントハンドラー> が選択できるようになります。
<新しいイベントハンドラー> を選択するとイベントハンドラーを自動で追加してくれます。
クラスにもイベントハンドラが追加されています。イベントに対応する引数も定義してくれるため、いちいち調べなくても良いのがとても助かります。
void Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
また、Name属性を設定していると「Name属性値_イベント名」が関数名になるようです。
コードの保守を考えるとイベントハンドラーの追加は、 Visual Studio の機能に任せるほうが賢い気がします。
参考
WinUI - ナビゲーションの位置を指定する
C++ で WinUI 3 ライブラリを使う
NavigationView の表示位置は、PaneDisplayMode プロパティを使います。
図のようにナビゲーションメニューを上側に配置するには、Top を指定します。
PaneDisplayMode に指定できる値には、Auto, Left, LeftCompact, LeftMinimal, Top があります。
XAMLで指定する
<NavigationView PaneDisplayMode="Top">
コードで指定する
NavigationView オブジェクトにコードからアクセスできるように名前をつけます。
<NavigationView x:Name="navi" >
navi オブジェクトを取得して PaneDisplayMode を指定します。
MainWindow::MainWindow() { InitializeComponent(); navi().PaneDisplayMode(Microsoft::UI::Xaml::Controls::NavigationViewPaneDisplayMode::Top); }
参考
WinUI 3 with C++ 入門 - ビリヤードが好きなプログラマー
NavigationViewPaneDisplayMode 列挙型 (Microsoft.UI.Xaml.Controls) - Windows App SDK | Microsoft Learn
WinUI - NavigationView を使う
C++ で WinUI 3 ライブラリを使う
図のようなナビゲーションメニューを持つアプリを作るには、NavigationView を使います。
MainWindow.xaml の Window 要素に NavigationView を配置します。
<Window x:Class="NavigationView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:NavigationView1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <NavigationView IsSettingsVisible="False"> <NavigationView.MenuItems> <NavigationViewItem Content="Page A" Tag="PageA" /> <NavigationViewItem Content="Page B" Tag="PageB" > <NavigationViewItem.MenuItems> <NavigationViewItem Icon="Home" Content="Page B1" Tag="PageB1" /> <NavigationViewItem Icon="World" Content="Page B2" Tag="PageB2" /> </NavigationViewItem.MenuItems> </NavigationViewItem> </NavigationView.MenuItems> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <Button x:Name="myButton" Click="myButton_Click">Click Me</Button> </StackPanel> </NavigationView> </Window>
NavigationView については、NavigationView - Windows apps | Microsoft Learn でとても丁寧に説明してあります。ここを読めば NavigationView の機能を把握できると思います。
参考
WinUI 3 with C++ 入門 - ビリヤードが好きなプログラマー
NavigationView クラス (Microsoft.UI.Xaml.Controls) - Windows App SDK | Microsoft Learn