Fully native C++ WinRT application example

  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 }

 

posted @ 2014-10-20 21:34  BinSys  阅读(961)  评论(0编辑  收藏  举报