新建 WinCE7.0 下的 Silverlight 工程
扫描二维码
随时随地手机看文章
这也是我写此文章时一步一步建立的 Silverlight 工程。
1 使用 Microsoft Expression Blend 3 创建一个 Silverlight for Windows Embedded Application 工程,放一个按键控件在窗体上,命名按键然后保存。由于 Microsoft Expression Blend 3 现在只支持生成 C# 的代码,对我们没有什么用,所以我们只用其中的 XAML 文件。
2 VS2008 新建:智能设备->Win32 智能设备项目,选拔一个支持 Silverlight 的SDK。
3 文件 SilverlightHelloWorld.cpp 中,只保留如下代码,其它删除:
// SilverlightHelloWorld.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "SilverlightHelloWorld.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { return 0; }
4 新增加 4 个空文件,内容后面补,分别是:
App.cpp App.h MainPage.cpp MainPage.h
5 增加文件 XRPack.rules,文件的内容如下:
6 将 XRPack.rules 增加到工程文件 SilverlightHelloWorld.vcproj 中,修改了两个地方,修改后的内容如下:
......
7 新增文件 SilverlightHelloWorld.xrpack,其内容如下:
# This file is used to generate the rc2 file and baml resources # Uncomment /C to force xrpack to perform a clean build every time # /C # Verbosity can be a value between 1 and 10 /Verbosity=3 /NoResourceCompile "/TargetRC=WinEmbeddedHelloWorldGenerated.rc2" "/TargetHeader=WinEmbeddedHelloWorldGenerated.h" "/Project=..WinEmbeddedHelloWorldWinEmbeddedHelloWorld.csproj"
8 修改 stdafx.h ,增加以下内容:
// Xaml Runtime Header Files #include#include#include#include// IUnknown extern "C" const GUID __declspec(selectany)IID_IUnknown = __uuidof(IUnknown); // Resource type for XAML files #define RT_XAML L"XAML" // Application headers #include "App.h" #include "resource.h"
9 将 SilverlightHelloWorld.xrpack 文件增加到工程中
这样才能自动生成 WinEmbeddedHelloWorldGenerated.rc2 和 WinEmbeddedHelloWorldGenerated.h 文件
10 WinMain() 函数的实现代码如下
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { App AppInstance; HRESULT hr = AppInstance.Initialize(hInstance); if(SUCCEEDED(hr)) { hr = AppInstance.Run(); } return AppInstance.GetWinMainResultCode(); }
11 编译,是可以成功的,但还需要根据 XAML 文件的内容来修改 MailPage.cpp 和 MailPage.h。
MailPage.h
#pragma once //class __declspec(uuid("{1756acb7-63be-4a4b-97cf-edc048541e75}")) MainPage : public XRCustomUserControlImpl{ QI_IDENTITY_MAPPING(MainPage, XRCustomUserControlImpl) public: static HRESULT GetXamlSource(__in XRXamlSource* pXamlSource) { HRESULT hr = E_INVALIDARG; if (pXamlSource) { pXamlSource->SetResource (App::GetHInstance(), IDR_SILVERLIGHTCLOCK_MAINPAGE); hr = S_OK; } return hr; } static HRESULT Register() { return XRCustomUserControlImpl::Register (__uuidof(MainPage), L"MainPage", L"clr-namespace:SilverlightClock"); } #pragma region GeneratedCode // ============================================================================ // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE // ============================================================================ HRESULT OnLoaded(__in IXRDependencyObject* pRoot); HRESULT InitializeComponent(); IXRGridPtr m_pLayoutRoot; // Grid x:Name="LayoutRoot" ... IXRButtonBasePtr m_MyBtn; IXRDelegate*m_clickDelegate; // ============================================================================ // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE // ============================================================================ #pragma endregion GeneratedCode };
MailPage.cpp
#include "stdafx.h" #include "SilverlightHelloGenerated.h" #include "MainPage.h" #include "App.h" #include "resource.h" #define TEST_BTN_CLICK_PROCESS 1 #if TEST_BTN_CLICK_PROCESS class BtnEventHandler { public: HRESULT OnClick(IXRDependencyObject* source,XRMouseButtonEventArgs* args) { MessageBox(NULL,TEXT("Click!"),TEXT("Silverlight for Hello World!!!"),MB_OK); return S_OK; } }; #endif // ============================================================================ // OnLoaded // // Description: Calls InitializeComponent to bind member variables to named // elements, and attach event handlers specified in XAML // // Parameters: pRoot - The root dependency object. // ============================================================================ HRESULT MainPage::OnLoaded(__in IXRDependencyObject* pRoot) { UNREFERENCED_PARAMETER(pRoot); HRESULT hr = InitializeComponent(); return hr; } // OnLoaded #pragma region GeneratedCode // ============================================================================ // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE // ============================================================================ HRESULT MainPage::InitializeComponent() { HRESULT hr = E_FAIL; m_clickDelegate = NULL; FindName(L"LayoutRoot", &m_pLayoutRoot); #if TEST_BTN_CLICK_PROCESS { HRESULT retCode = 0; BtnEventHandler handler; if(FAILED(retCode = FindName(TEXT("HelloWorldBtn"), &m_MyBtn))) return -1; /* 指向委托对象的指针并不是一个智能指针(smart pointer),我们需要显式释放它:clickDelegate->Release(); 现在未释放!!!可以仿 OnLoaded 中 AddLoadedEventHandler 的实现方式。 */ if(FAILED(retCode = CreateDelegate(&handler,&BtnEventHandler::OnClick,&m_clickDelegate))) return -1; if(FAILED(retCode = m_MyBtn->AddClickEventHandler(m_clickDelegate))) return -1; } #endif if (m_pLayoutRoot && m_MyBtn) { hr = S_OK; } return hr; } // ============================================================================ // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED CODE // ============================================================================ #pragma endregion GeneratedCode
12 App.cpp 和 App.h 的代码如下:
App.h
#pragma once #include// // This function pointer type is used to declare a table of // registration functions in App.cpp // typedef HRESULT (*PFN_XRCUC_REGISTER)(); // // This is the main application class. // class App { public: // // Intialize member variables that cannot fail initialization in the constructor. // App(): m_bInitialized(FALSE), m_nResult(0) { } // // Destructor // ~App() {} // Intialize the XamlRuntime API, a VisualHost, and initialize the application HRESULT Initialize(HINSTANCE hInstance); // Create the VisualHost. HRESULT CreateHost(XRWindowCreateParams* pCreateParams); // Run the application until the message pump exits. HRESULT Run(); // Register the UserControls implemented in this module HRESULT RegisterUserControls(); // Get the host window creation parameters HRESULT GetWindowParameters(XRWindowCreateParams* pWindowParameters); // Get the result code to be returned from WinMain int GetWinMainResultCode(); // Set the result code to be returned from WinMain void SetWinMainResultCode(int nResult); // Get the application HINSTANCE static HINSTANCE GetHInstance(); // Exit the application HRESULT Exit(); // OnStartup is called after the visual host is created // and before the message loop is entered HRESULT OnStartup(); // OnExit is called after the message pump is exited // and before the visual host, and IXRApplication are destroyed. HRESULT OnExit(); // Register the resource dictionary for this application HRESULT InitializeComponent(); // Gets the visual host for this application static HRESULT GetVisualHost(IXRVisualHost** ppHost); // Gets IXRApplication for this class static HRESULT GetApplication(IXRApplication ** ppApp); private: // Sets the visual host for this application static void SetVisualHost(IXRVisualHost* pHost); // Sets IXRApplication for this class static void SetApplication(IXRVisualHost* pApp); protected: // member variables BOOL m_bInitialized; // Initialization succeeded int m_nResult; // WinMain result code // static member variables static HINSTANCE m_hInstance; // The HINSTANCE of this process // 为指向运行 SilverLight 应用程序的单体对象,此对象用来加载管理分析 XAML 文件。 static IXRApplicationPtr m_pApplication; // IXRApplication for this process // 指向 Windows(HWND) 容器对象对象树,以便在运行时用 C++ 或 XAML 创建的对象处理相应事件消息,并显示或隐藏其 XAML 或 C++ 类创建的窗口。 static IXRVisualHostPtr m_pVisualHost; // IXRVisualHost for this process }; // ============================================================================ // Initialize // // Description: Intialize the XamlRuntime API, and the XRApplication and then // create a visual host. // // Parameters: hInstance - The HINSTANCE from WinMain // ============================================================================ inline HRESULT App::Initialize(HINSTANCE hInstance) { HRESULT hr = E_FAIL; // 创建主窗口并让 SE 管理它的内容 XRWindowCreateParams WindowParameters = {0}; m_hInstance = hInstance; // Public API exported from XamlRumtime.dll. Initialize the system. BOOL m_bInitialized = XamlRuntimeInitialize(); // Create IXRApplication instance if (m_bInitialized) { // Public API exported from XR.dll. Obtain a reference to the XRApplication object singleton. hr = GetXRApplicationInstance(&m_pApplication); } if (SUCCEEDED(hr)) { // Add this module for the XamlRuntime to use when automatically resolving Image Source URIs as presented in XAML. hr = m_pApplication->AddResourceModule(m_hInstance); } if (SUCCEEDED(hr)) { hr = RegisterUserControls(); } if (SUCCEEDED(hr)) { hr = InitializeComponent(); } if (SUCCEEDED(hr)) { hr = GetWindowParameters(&WindowParameters); } if (SUCCEEDED(hr)) { hr = CreateHost(&WindowParameters); } if (SUCCEEDED(hr)) { hr = OnStartup(); } return hr; } // Initialize // ============================================================================ // Run // // Description: Run the application until the message pump exits. // ============================================================================ inline HRESULT App::Run() { HRESULT hr = E_FAIL; UINT uiExitCode = 0; if (m_pVisualHost != NULL) { // save the exit code for WinMain hr = m_pVisualHost->StartDialog(&uiExitCode); SetWinMainResultCode(uiExitCode); } // Allow user to cleanup resources. OnExit(); // // XamlRuntime interfaces must be released in the // following order: IXRVisualHost, IXRApplication. // After these interfaces are released the runtime // can be uninitialized. // // First release IXRVisualHost m_pVisualHost = NULL; // Second release IXRApplication m_pApplication = NULL; // If XamlRuntime was initialized, uninitialize it if (m_bInitialized) { m_bInitialized = FALSE; XamlRuntimeUninitialize(); } m_hInstance=NULL; return hr; } // Run // ============================================================================ // GetWinMainResultCode // // Description: Get the result code to be returned from WinMain // ============================================================================ inline int App::GetWinMainResultCode() { return m_nResult; } // GetWinMainResultCode // ============================================================================ // SetWinMainResultCode // // Description: Set the result code to be returned from WinMain // // Parameters: nResult - The result code to be returned from WinMain // ============================================================================ inline void App::SetWinMainResultCode(int nResult) { m_nResult = nResult; } // SetWinMainResultCode // ============================================================================ // GetHInstance // // Description: Get the application HINSTANCE // ============================================================================ inline HINSTANCE App::GetHInstance() { return m_hInstance; } // GetHInstance // ============================================================================ // Exit // // Description: Exit the application // ============================================================================ inline HRESULT App::Exit() { HRESULT hr = E_FAIL; if (NULL != m_pVisualHost) { hr = m_pVisualHost->EndDialog(0); } return hr; } // Exit // ============================================================================ // GetVisualHost // // Gets the visual host for this application // ============================================================================ inline HRESULT App::GetVisualHost(IXRVisualHost ** ppHost) { if (!ppHost) return E_INVALIDARG; if (m_pVisualHost) { *ppHost = m_pVisualHost; (*ppHost)->AddRef(); return S_OK; } return E_FAIL; } // ============================================================================ // SetVisualHost // // Sets the visual host for this application // ============================================================================ inline void App::SetVisualHost(IXRVisualHost* pHost) { // Smart pointer automatically calls AddRef m_pVisualHost = pHost; } // ============================================================================ // GetApplication // // Gets IXRApplication for this class // ============================================================================ inline HRESULT App::GetApplication(IXRApplication ** ppApp) { HRESULT hr = E_FAIL; if (!ppApp) return E_INVALIDARG; if (m_pApplication) { *ppApp = m_pApplication; (*ppApp)->AddRef(); hr = S_OK; } return hr; } // ============================================================================ // SetApplication // // Sets IXRApplication for this class // ============================================================================ inline void App::SetApplication(IXRVisualHost* pApp) { // Smart pointer automatically calls AddRef m_pApplication = pApp; }
App.cpp
#include "stdafx.h" #include "SilverlightHelloGenerated.h" #include "App.h" #include "MainPage.h" // The MAX_LOADSTRING constant needs to be equal to or greater // than the length of the string referenced by IDS_APP_TITLE #define MAX_LOADSTRING 100 // ============================================================================ // Static class member instantiation. // ============================================================================ HINSTANCE App::m_hInstance; // HINSTANCE of this process IXRApplicationPtr App::m_pApplication; // IXRApplication for this process IXRVisualHostPtr App::m_pVisualHost; // IXRVisualHost for this process // ============================================================================ // InitializeComponent // // Description: Load the Application resource dictionary if one exists. // ============================================================================ HRESULT App::InitializeComponent() { XRXamlSource appXaml(GetHInstance(), IDR_SILVERLIGHTCLOCK_APP); HRESULT hr = m_pApplication->LoadResourceDictionary(&appXaml,NULL); return hr; } // InitializeComponent // ============================================================================ // GetWindowParameters // // Description: Set the window creation parameters for this application. // // Parameters: pWindowParameters - Window creation parameters. // ============================================================================ HRESULT App::GetWindowParameters(XRWindowCreateParams* pWindowParameters) { static WCHAR szTitle[MAX_LOADSTRING]; // title bar text HRESULT hr = E_INVALIDARG; if (pWindowParameters) { pWindowParameters->Style = WS_VISIBLE; pWindowParameters->ExStyle = WS_EX_TOPMOST; // Set the title bar text LoadString(m_hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); pWindowParameters->pTitle = szTitle; // Set window position pWindowParameters->Left = 0; pWindowParameters->Top = 0; // TODO: To specify a window size for the visual host set Width and Height // If Width and Height are zero the Width and Height specified in the // XAML are used //pWindowParameters->Width = GetSystemMetrics(SM_CXSCREEN); //pWindowParameters->Height = GetSystemMetrics(SM_CYSCREEN); hr = S_OK; } return hr; } // GetWindowParameters // ============================================================================ // OnStartup // // Description: OnStartup is called after the visual host is created. // and before the message loop is entered. // ============================================================================ HRESULT App::OnStartup() { HRESULT hr = S_OK; IXRFrameworkElementPtr pRoot; hr = m_pVisualHost->GetRootElement(&pRoot); if (SUCCEEDED(hr)) { // TODO: Add one time initialization code here. } return hr; } // OnStartup // ============================================================================ // OnExit // // Description: OnExit is called after the message pump is exited // and before the visual host, and IXRApplication are destroyed. // ============================================================================ HRESULT App::OnExit() { // TODO: Add one-time cleanup code here. return S_OK; } // OnExit // ============================================================================ // CreateHost // // Description: Create the visual host. // // Parameters: pCreateParams - The parameters used for creating the // visual host's window // ============================================================================ HRESULT App::CreateHost(XRWindowCreateParams* pCreateParams) { XRPtrpControl; HRESULT hr = E_FAIL; hr = m_pApplication->CreateObject(__uuidof(MainPage),&pControl); if (SUCCEEDED(hr)) { hr = m_pApplication->CreateHostFromElementTree(pControl, pCreateParams, &m_pVisualHost); } return hr; } #pragma region RegisterUserControls Generated Code // ============================================================================ // RegisterUserControls // // Description: Register all XRCustomUserControl implemenations here. // // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED FUNCTION // ============================================================================ HRESULT App::RegisterUserControls() { HRESULT hr = S_OK; static PFN_XRCUC_REGISTER pfn[] = { &MainPage::Register, }; for (int i=0; i<_countof(pfn) && SUCCEEDED(hr); i++) { hr = pfn[i](); if (FAILED(hr)) { RETAILMSG(1,(L"RegisterUserControls failed.")); } } return hr; } // RegisterUserControls // ============================================================================ // WARNING: DO NOT EDIT THIS ALWAYS-GENERATED FUNCTION // ============================================================================ #pragma endregion RegisterUserControls Generated Code
13 编译、运行,失败了!程序没有加载起来。一般来说,没有加载成功是因为 XMAL 解析失败,或资源没有加载成功。需要进一步分析是什么具体的原因?
调试代码发现,如下函数在加载资源时报错: hr = -2147023082 {找不到映像文件中指定的资源名。}
HRESULT App::InitializeComponent() { XRXamlSource appXaml(GetHInstance(), IDR_SILVERLIGHTCLOCK_APP); HRESULT hr = m_pApplication->LoadResourceDictionary(&appXaml,NULL); return hr; } // InitializeComponent
解决方法:
将资源文件 SilverlightHelloWorld.rc 中的 SilverlightHelloWorld.rc2 替换成 SilverlightHelloGenerated.rc2,共两处。
14 编译、运行,可以看到想要的界面。点击按键,会弹出一个对话框。
OK,到此新建 WinCE 下 Silverlight 工程的整个过程算是结束了,是不是有些复杂?
呵呵...,个人的感觉也是,挺复杂的。