程式碼解說:Visual C++ 裝置專案中精靈產生的程式碼
更新:2007 年 11 月
Visual C++ 的功能和精靈可以簡化產生多平台裝置應用程式、組態檔和專案檔的大部分例行工作。此逐步解說將描述 Windows 32 裝置應用程式精靈為您自動產生的程式碼,如此一來,您就能夠擴充及修改 Windows 應用程式,以符合自己的需要。
Windows 32 裝置應用程式的精靈產生之程式碼
如果您熟悉 Windows (win32) 桌面程式設計,即可輕易找到由精靈為您產生的主要常式。
在一般的 Windows 裝置應用程式中,主要項目都位於 <yourprojectname>.cpp 檔案之中;以下列出這個檔案的範例清單。
快速檢閱一番,此應用程式具有下列主要功能:
WinMain 函式
MyRegisterClass 函式
InitInstance 函式
About Dialog 函式
在下列範例中會說明這些函式。
WinMain 函式:int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)。如需詳細資訊,請參閱 WinMain 函式。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; // Perform application initialization: if (!InitInstance(hInstance, nCmdShow)) { return FALSE; }
Win32 平台。如需詳細資訊,請參閱Windows Platforms (CRT)。
#ifndef WIN32_PLATFORM_WFSP HACCEL hAccelTable; hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32SMARTDEVICE); #endif // !WIN32_PLATFORM_WFSP
訊息迴圈。如需詳細資訊,請參閱Message Handling and Command Targets。
// Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { #ifndef WIN32_PLATFORM_WFSP if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) #endif // !WIN32_PLATFORM_WFSP { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; }
MyRegisterClass 函式會登錄視窗應用程式。
// FUNCTION: MyRegisterClass() ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32SMARTDEVICE)); wc.hCursor = 0; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = szWindowClass; return RegisterClass(&wc); }
InitInstance:FUNCTION InitInstance(HANDLE, int) 如需詳細資訊,請參閱 InitInstance Member Function。
WIN32_PLATFORM_WFSP 用來當做 Smartphone 的條件和 Pocket PC 的 WIN32_PLATFORM_PSPC。如果想要更進一步區別,您隨時都能定義自己的條件式。
// FUNCTION: InitInstance(HANDLE, int) // PURPOSE: Saves instance handle and creates main window. // COMMENTS: // In this function, we save the instance handle in a global // variable and create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; TCHAR szTitle[MAX_LOADSTRING]; // title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // main window class name g_hInst = hInstance; // Store instance handle in your global variable. #ifdef WIN32_PLATFORM_PSPC // SHInitExtraControls should be called once during your application's initialization to initialize any // of the Pocket PC special controls such as CAPEDIT and SIPPREF. SHInitExtraControls(); #endif // WIN32_PLATFORM_PSPC LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WIN32SMARTDEVICE, szWindowClass, MAX_LOADSTRING); #if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP) //If it is already running, then focus on the window, and exit. hWnd = FindWindow(szWindowClass, szTitle); if (hWnd) { // Set the focus to the foremost child window. // The "| 0x00000001" is used to bring any owned windows //to the foreground and activate them. SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001)); return 0; } #endif // WIN32_PLATFORM_PSPC || WIN32_PLATFORM_WFSP if (!MyRegisterClass(hInstance, szWindowClass)) { return FALSE; } hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } #ifdef WIN32_PLATFORM_PSPC // When the main window is created using CW_USEDEFAULT, // the height of the menubar is not taken into account. // So the generated code resizes the window after creating it. if (g_hWndMenuBar) { RECT rc; RECT rcMenuBar; GetWindowRect(hWnd, &rc); GetWindowRect(g_hWndMenuBar, &rcMenuBar); rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top); MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE); } #endif // WIN32_PLATFORM_PSPC ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }
也會為您的應用程式產生 [關於] 對話方塊,做為建置其他您所需之對話方塊的方法範例:LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
// win32smartdevice.cpp : Defines the entry point for the application. #include "stdafx.h" #include "win32smartdevice.h" #include <windows.h> #include <commctrl.h> #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE g_hInst; // Current instance: HWND g_hWndMenuBar; // Menu bar handle // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE, LPTSTR); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); #ifndef WIN32_PLATFORM_WFSP LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); #endif // !WIN32_PLATFORM_WFSP // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // PURPOSE: Processes messages for the main window. // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return
一些主訊息 (例如 WM_COMMAND) 也已經為了擴充功能而包含在程式碼中,並且包括針對處理系統和使用者輸入訊息的 WinProc:LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam. 。如需 WinProc 的詳細資訊,請參閱 Windows 概觀。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; HGDIOBJ hbrWhite, hbrGray; POINT aptStar[6] = {50,2, 2,98, 98,33, 2,33, 98,98, 50,2}; #if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP) static SHACTIVATEINFO s_sai; #endif // SHELL_AYGSHELL && !WIN32_PLATFORM_WFSP switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { #ifndef WIN32_PLATFORM_WFSP case IDM_HELP_ABOUT: DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; #endif // !WIN32_PLATFORM_WFSP #ifdef WIN32_PLATFORM_WFSP case IDM_OK: DestroyWindow(hWnd); break; #endif // WIN32_PLATFORM_WFSP #ifndef WIN32_PLATFORM_WFSP case IDM_OK: SendMessage (hWnd, WM_CLOSE, 0, 0); break; #endif // !WIN32_PLATFORM_WFSP default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: #ifdef SHELL_AYGSHELL SHMENUBARINFO mbi; memset(&mbi, 0, sizeof(SHMENUBARINFO)); mbi.cbSize = sizeof(SHMENUBARINFO); mbi.hwndParent = hWnd; mbi.nToolBarId = IDR_MENU; mbi.hInstRes = g_hInst; if (!SHCreateMenuBar(&mbi)) { g_hWndMenuBar = NULL; } else { g_hWndMenuBar = mbi.hwndMB; } #ifndef WIN32_PLATFORM_WFSP // Initialize the shell activate info structure memset(&s_sai, 0, sizeof (s_sai)); s_sai.cbSize = sizeof (s_sai); #endif // !WIN32_PLATFORM_WFSP #endif // SHELL_AYGSHELL hbrWhite = GetStockObject(WHITE_BRUSH); hbrGray = GetStockObject(GRAY_BRUSH); return 0L; break; case WM_PAINT: RECT rc; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rc); Polyline(hdc, aptStar, 6); EndPaint(hWnd, &ps); return 0L; break; case WM_DESTROY: #ifdef SHELL_AYGSHELL CommandBar_Destroy(g_hWndMenuBar); #endif // SHELL_AYGSHELL PostQuitMessage(0); break; #if defined(SHELL_AYGSHELL) && !defined(WIN32_PLATFORM_WFSP) case WM_ACTIVATE: // Notify shell of your activate message. SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE); break; case WM_SETTINGCHANGE: SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); break; #endif // SHELL_AYGSHELL && !WIN32_PLATFORM_WFSP default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } #ifndef WIN32_PLATFORM_WFSP // Message handler for about box. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: #ifdef SHELL_AYGSHELL { // Create a Done button and size it. SHINITDLGINFO shidi; shidi.dwMask = SHIDIM_FLAGS; shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU; shidi.hDlg = hDlg; SHInitDialog(&shidi); } #endif // SHELL_AYGSHELL return TRUE; case WM_COMMAND: #ifdef SHELL_AYGSHELL if (LOWORD(wParam) == IDOK) #endif { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; case WM_CLOSE: EndDialog(hDlg, message); return TRUE; #ifdef _DEVICE_RESOLUTION_AWARE case WM_SIZE: { DRA::RelayoutDialog( g_hInst, hDlg, DRA::GetDisplayMode() != DRA::Portrait ? MAKEINTRESOURCE(IDD_ABOUTBOX_WIDE) : MAKEINTRESOURCE(IDD_ABOUTBOX)); } break; #endif } return FALSE; } #endif // !WIN32_PLATFORM_WFSP