1 //
2 // Fully native C++ WinRT application example
3 // Programmed by fincs
4 //
5
6 #include <windows.h>
7 #include <roapi.h>
8 #include <wchar.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <wrl.h>
13
14 #include <Windows.UI.Xaml.h>
15 #include <Windows.UI.Xaml.Markup.h>
16 #include <Windows.ApplicationModel.Activation.h>
17
18 using namespace Microsoft::WRL;
19 using namespace Microsoft::WRL::Wrappers;
20 using namespace Windows::Foundation;
21 using namespace ABI::Windows::UI::Xaml;
22 using namespace ABI::Windows::UI::Xaml::Markup;
23 using namespace ABI::Windows::ApplicationModel::Activation;
24
25 //---------------------------------------------------------------------------
26 // Error handling
27 //---------------------------------------------------------------------------
28
29 // Even though this is officially unsupported and the corresponding declaration in
30 // the header files is left out for WinRT apps, it is actually possible to use these
31 // "forbidden" functions via manually including the declaration like as follows:
32 extern "C" int WINAPI MessageBoxW(HWND parent, LPCWSTR aText, LPCWSTR aTitle, int opt);
33
34 // Error checking helper
35 void CheckHRESULT(HRESULT hr, LPCWSTR message)
36 {
37 if (FAILED(hr))
38 {
39 WCHAR aBuf[1024];
40 swprintf_s(aBuf, L"Error 0x%08X during: %s", hr, message);
41 MessageBoxW(NULL, aBuf, L"BareMetalMetroApp", MB_ICONERROR);
42 exit(1);
43 }
44 }
45
46 //---------------------------------------------------------------------------
47 // Application class
48 //---------------------------------------------------------------------------
49
50 class MyApp: public RuntimeClass<IApplicationOverrides>
51 {
52 InspectableClass(L"BareMetalMetroApp.MyApp", BaseTrust);
53
54 protected:
55 ComPtr<IApplicationOverrides> pBaseImpl;
56
57 public:
58 void SetBase(IApplicationOverrides* _pBaseImpl)
59 {
60 pBaseImpl = _pBaseImpl;
61 }
62
63 STDMETHOD(OnActivated)(IActivatedEventArgs* args) { return pBaseImpl->OnActivated(args); }
64 STDMETHOD(OnLaunched)(ILaunchActivatedEventArgs* args);
65 STDMETHOD(OnFileActivated)(IFileActivatedEventArgs* args) { return pBaseImpl->OnFileActivated(args); }
66 STDMETHOD(OnSearchActivated)(ISearchActivatedEventArgs* args) { return pBaseImpl->OnSearchActivated(args); }
67 STDMETHOD(OnShareTargetActivated)(IShareTargetActivatedEventArgs* args) { return pBaseImpl->OnShareTargetActivated(args); }
68 STDMETHOD(OnFileOpenPickerActivated)(IFileOpenPickerActivatedEventArgs* args) { return pBaseImpl->OnFileOpenPickerActivated(args); }
69 STDMETHOD(OnFileSavePickerActivated)(IFileSavePickerActivatedEventArgs* args) { return pBaseImpl->OnFileSavePickerActivated(args); }
70 STDMETHOD(OnCachedFileUpdaterActivated)(ICachedFileUpdaterActivatedEventArgs* args) { return pBaseImpl->OnCachedFileUpdaterActivated(args); }
71 };
72
73 //---------------------------------------------------------------------------
74 // OnLaunched event
75 //---------------------------------------------------------------------------
76
77 #define MARKUP_TO_LOAD \
78 L"<Grid xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" \
79 L" <TextBlock Text=\"Hello, fully native world!\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" FontSize=\"48\" />" \
80 L"</Grid>"
81
82 // TODO: find out how to listen to events coming from e.g. buttons
83 // L" <Button Content=\"Click me\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" />"
84
85 /*
86 // This is what this function looks like under C++/CX:
87
88 void MyApp::OnLaunched(ILaunchActivatedEventArgs^ args)
89 {
90 Window::Current->Content = XamlReader::Load(MARKUP_TO_LOAD);
91 }
92 */
93
94 STDMETHODIMP MyApp::OnLaunched(ILaunchActivatedEventArgs* args)
95 {
96 // Prepare HSTRING versions of class names
97 HStringReference WindowClsName(RuntimeClass_Windows_UI_Xaml_Window);
98 HStringReference XamlReaderClsName(RuntimeClass_Windows_UI_Xaml_Markup_XamlReader);
99 HStringReference MarkupData(MARKUP_TO_LOAD);
100
101 // pCurWin = Window::Current
102 ComPtr<IWindow> pCurWin;
103 {
104 ComPtr<IWindowStatics> pWinStatics;
105 CheckHRESULT(GetActivationFactory(WindowClsName.Get(), &pWinStatics), L"IWinStatics");
106 CheckHRESULT(pWinStatics->get_Current(&pCurWin), L"get_Current");
107 }
108
109 ComPtr<IUIElement> pContent;
110 {
111 ComPtr<IXamlReaderStatics> pXamlReaderStatics;
112 ComPtr<IInspectable> pObj;
113
114 // pContent = XamlReader::Load(MarkupData)
115 CheckHRESULT(GetActivationFactory(XamlReaderClsName.Get(), &pXamlReaderStatics), L"IXamlReaderStatics");
116 CheckHRESULT(pXamlReaderStatics->Load(MarkupData.Get(), &pObj), L"Markup loading failure");
117 CheckHRESULT(pObj.As(&pContent), L"IUIElement");
118 }
119
120 // pCurWin->Content = pContent
121 pCurWin->put_Content(pContent.Get());
122 pCurWin->Activate();
123
124 return S_OK;
125 }
126
127 //---------------------------------------------------------------------------
128 // Application initialization function
129 //---------------------------------------------------------------------------
130
131 /*
132 // This is what this function looks like under C++/CX:
133
134 static void InitApplication(IApplicationInitializationCallbackParams^ args)
135 {
136 auto app = ref new MyApp();
137 }
138 */
139
140 static STDMETHODIMP InitApplication(IApplicationInitializationCallbackParams* args)
141 {
142 // Prepare HSTRING versions of class names
143 HStringReference ApplicationClsName(RuntimeClass_Windows_UI_Xaml_Application);
144
145 ComPtr<IApplicationFactory> pAppFactory;
146 CheckHRESULT(GetActivationFactory(ApplicationClsName.Get(), &pAppFactory), L"IApplicationFactory");
147
148 ComPtr<MyApp> pMyApp = Make<MyApp>();
149 ComPtr<IApplication> pApp;
150 {
151 // This is done like this because pInner is set to a reference to the same object as the
152 // return value (albeit with a different VTable (offset)), and the Microsoft guys *FORGOT*
153 // to AddRef(). Therefore we need to throw out the pInner pointer.
154 IInspectable* pInner;
155 CheckHRESULT(pAppFactory->CreateInstance(pMyApp.Get(), &pInner, &pApp), L"CreateInstance");
156 }
157
158 // Set the inherited Application object
159 ComPtr<IApplicationOverrides> pBaseImpl;
160 CheckHRESULT(pApp.As(&pBaseImpl), L"IApplicationOverrides");
161 pMyApp->SetBase(pBaseImpl.Get());
162
163 return S_OK;
164 }
165
166 //---------------------------------------------------------------------------
167 // Application entrypoint
168 //---------------------------------------------------------------------------
169
170 /*
171 // This is what this function looks like under C++/CX:
172
173 int main()
174 {
175 Application::Start(ref new ApplicationInitializationCallback(InitApplication));
176 return 0;
177 }
178 */
179
180 int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
181 {
182 // Initialize WinRT
183 RoInitializeWrapper init(RO_INIT_MULTITHREADED);
184 CheckHRESULT(init, L"RoInitialize");
185
186 ComPtr<IApplicationStatics> pAppStatics;
187 HStringReference ApplicationClsName(RuntimeClass_Windows_UI_Xaml_Application);
188 CheckHRESULT(GetActivationFactory(ApplicationClsName.Get(), &pAppStatics), L"IApplicationStatics");
189
190 // Application::Start(AppMain)
191 ComPtr<IApplicationInitializationCallback> pCallback = Callback<IApplicationInitializationCallback>(InitApplication);
192 pAppStatics->Start(pCallback.Get());
193
194 return 0;
195 }