簡單windows應用程式的實現

理解windows應用程式的組成結構,WinMain()和窗口函數

掌握windows應用程式的運行機制

工具/原料

visual studio開發平台

方法/步驟

1、新建—項目,選擇「Win32項目

選擇「Windows應用程式」和「空項目」

【添加C++源文件】

// Win32.cpp : 定義應用程式的入口點。//#include "stdafx.h"#include "Win32.h"#define MAX_LOADSTRING 100// 全局變量:HINSTANCE hInst;                                                    // 當前實例TCHAR szTitle[MAX_LOADSTRING];                        // 標題欄文本TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口類名/* 此代碼模塊中包含的函數的【前向聲明】:    (Forward Declaration)是指聲明標識符(表示編程的實體,如數據類型、變量、函數)時還沒有給出完整的定義。typedef unsigned short      WORD;typedef WORD                ATOM;About對話框的對話框處理函數 處理About對話框的各種消息窗口函數說明*///函數聲明ATOM            MyRegisterClass(HINSTANCE hInstance);BOOL            InitInstance(HINSTANCE, int);LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);/**************************************************************************************************************///一、WinMain函數/*實際就是__stdcall#define APIENTRY    WINAPI#define WINAPI      __stdcall_tWinMainWinMain函數結構1)註冊窗口類,並註冊【消息處理函數WindowProc】2)創建並顯示窗口3)循環獲取消息*///1.函數說明int APIENTRY _tWinMain(HINSTANCE hInstance,                          HINSTANCE hPrevInstance,                          LPTSTR    lpCmdLine,                       int       nCmdShow){    /*    Nothing at all    #define UNREFERENCED_PARAMETER(P)          (P)*///2.初始化    //目前無用    UNREFERENCED_PARAMETER(hPrevInstance);    UNREFERENCED_PARAMETER(lpCmdLine);     // TODO: 在此放置代碼。    MSG msg;    HACCEL hAccelTable;    // 初始化【全局字符串】?????????????????    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);    LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING);    MyRegisterClass(hInstance);    // 執行【應用程式初始化】:    if (!InitInstance (hInstance, nCmdShow))    {        return FALSE;    }    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32));    //3.【主消息】循環:    while (GetMessage(&msg, NULL, 0, 0))    //消息隊列獲取消息,放入MSG,GetMessage返回值為 0 ,結束循環        {        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))        {            TranslateMessage(&msg);                        //虛擬鍵轉換為字符信息            DispatchMessage(&msg);                        //參數&msg == lpMSG指向的消息傳送到指定的窗口函數        }    }    return (int) msg.wParam;}///*//  函數: MyRegisterClass()////  目的: 註冊窗口類。////  注釋:////    僅當希望//    此代碼與添加到 Windows 95 中的「RegisterClassEx」//    函數之前的 Win32 系統兼容時,才需要此函數及其用法。調用此函數十分重要,//    這樣應用程式就可以獲得關聯的//    「格式正確的」小圖標。*///2.(2)註冊窗口類ATOM MyRegisterClass(HINSTANCE hInstance){    WNDCLASSEX wcex;    wcex.cbSize = sizeof(WNDCLASSEX);    wcex.style            = CS_HREDRAW | CS_VREDRAW;    wcex.lpfnWndProc    = WndProc;    wcex.cbClsExtra        = 0;    wcex.cbWndExtra        = 0;    wcex.hInstance        = hInstance;    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32));    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_WIN32);    wcex.lpszClassName    = szWindowClass;    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));    return RegisterClassEx(&wcex);}/*//   函數: InitInstance(HINSTANCE, int)////   目的: 保存實例句柄並創建主窗口////   注釋:////        在此函數中,我們在全局變量中保存實例句柄並//        創建和顯示主程序窗口。*///2.(3)保存實例句柄並創建主窗口BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){   HWND hWnd;   hInst = hInstance; // 將實例句柄存儲在全局變量中   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)   {      return FALSE;   }   ShowWindow(hWnd, nCmdShow);   UpdateWindow(hWnd);   return TRUE;}/************************************************************************************************************///二、窗口函數/*//  函數: WndProc(HWND, UINT, WPARAM, LPARAM)2015/3/15 21:15:45////  目的: 【處理【主窗口】的消息】////  WM_COMMAND    - 處理應用程式菜單//  WM_PAINT    - 繪製主窗口//  WM_DESTROY    - 發送退出消息並返回//*///【處理【主窗口】的消息】LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    int wmId, wmEvent;    PAINTSTRUCT ps;    HDC hdc;    switch (message)    {    /*處理各種消息*/        case WM_COMMAND:        wmId    = LOWORD(wParam);        wmEvent = HIWORD(wParam);        // 分析菜單選擇:        switch (wmId)        {        case IDM_ABOUT:            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);            break;        case IDM_EXIT:            DestroyWindow(hWnd);            break;        default:            return DefWindowProc(hWnd, message, wParam, lParam);        }        break;    case WM_PAINT:        hdc = BeginPaint(hWnd, &ps);        // TODO: 在此添加任意繪圖代碼...                EndPaint(hWnd, &ps);        break;    case WM_DESTROY:        PostQuitMessage(0);        break;    default:        return DefWindowProc(hWnd, message, wParam, lParam);    }    return 0;}// 【處理【關於】的消息】。INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){    UNREFERENCED_PARAMETER(lParam);    switch (message)    {        /*處理各種消息*/            case WM_INITDIALOG:            //WM_INITDIALOG 消息是對話框才能收到的消息,表明對話框及其所有子控制項都創建完畢了。        return (INT_PTR)TRUE;    case WM_COMMAND:             //窗口通過WindowProc函數收到此消息        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)        {            EndDialog(hDlg, LOWORD(wParam));            return (INT_PTR)TRUE;        }        break;    }    return (INT_PTR)FALSE;}

Windows程序窗口的創建過程和消息循環如何實現?

(1)得到應用程式的句柄(GetModuleHandle)。

(2)註冊窗口類(RegisterClassEx)。

在註冊前,填寫RegisterClassEx的參數WNDCLASSEX結構。

(3)建立窗口(CreateWindowEx)。

(4)顯示窗口(ShowWindows)。

(5)刷新窗口客戶區(UpdateWindow)。

(6)進入無限的消息獲取和處理的循環。

首先獲取消息(GetMessage):

如果有消息到達,則將消息分派到回調函數處理(DispatchMessage)

如果消息是WM_QUIT,則退出循環。

注意事項

注意:添加 #include

本文內容整理自網絡, 文中所有觀點看法不代表淘大白的立場