win32程式之視窗程序,以及訊息機制

來源:互聯網
上載者:User
        win32程式值視窗程序,以及訊息機制一丶簡介

  通過上一講.我們瞭解了視窗其實是繪製出來的.而且是不斷繪製的過程. 所以視窗的本質是繪製. 但是我們現在看到的視窗程序.都可以點擊關閉按鈕. 使用滑鼠點擊會有反應.

而我們要怎麼實現那. 

  其實滑鼠點擊是產生了一個訊息.  window把這個訊息封裝成了訊息結構體. 發送給了我們的視窗程序.  那麼windows怎麼知道你點擊的那個視窗那?

是這樣的. 當我們點擊的時候. 會記錄點擊座標.訊息.等等. windows系統會接受到. 然後遍曆核心中的WINOBJ結構. 而這個結構中儲存著視窗對象. 視窗對象對應著訊息線程.

所以windows一層一層的遍曆.則找到了對應的視窗以及視窗對應的線程.然後發送給我們的應用程式. 

上面說的我們需要瞭解. 要知道訊息怎麼產生的. 怎麼傳遞的.那麼下面編程就明白了.

例如:

 

每個應用程式都有一個線程對象. 而這個線程對象如果建立視窗.那麼核心中就有這個視窗對象.

如果我們有滑鼠點擊的訊息.鍵盤訊息等等.作業系統都會遍曆視窗對象. 而視窗對象也會儲存著建立這個視窗對象對應的線程對象. 而這個線程對象中則有訊息佇列.

這樣的話作業系統則會封裝訊息發送給我們視窗對象.

二丶Wind視窗類別結構.建立視窗程序.1.進行視窗編程需要注意的問題

  在Windows中進行視窗編程.進入點已經改成WinMain了. 有四個參數.

如以下代碼所示

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,               //視窗的執行個體控制代碼 hinstance代表模組意思 HWND代表視窗意思. HANDLE代表核心對象. HDC 裝置上下文.                     _In_opt_ HINSTANCE hPrevInstance,        //父視窗控制代碼.不需要.                     _In_ LPWSTR    lpCmdLine,                //命令列參數                     _In_ int       nCmdShow)                 //命令. 最大化命令.還是最小化命令.{      return 0;}
wWinMain  因為有UNICODE跟ASCII區別. 所以我是UNICODE使用wWinMain. A版本就是用WinMain
2.進行Windows編程的調試手法

  在Windows中我們偵錯工具不能簡單的使用printf進行調試.或者列印輸出了. 我們可以使用兩個API進行操作.

1.Sprintf() 格式化字串. 

2.OutPutDebugString() 輸出調試字串.

具體兩個API. 不再累贅.百度搜尋即可.

因為OutPutDebugString() 只能列印固定字串.所以使用sprintf進行格式化字串.如下面代碼.

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,                     _In_opt_ HINSTANCE hPrevInstance,                     _In_ LPWSTR    lpCmdLine,                     _In_ int       nCmdShow){      TCHAR str[30] = { NULL };    wsprintf(str,TEXT( "%s"),TEXT("HelloWin32"));      //因為是Unicode所以使用W版本.    OutputDebugStringW(str);    return 0;}

我們編譯出程式之後.可以使用DebugView這款工具查看.

 

3.視窗編程的步驟

1.建立視窗類別. windows提供的視窗樣式.我們需要給定.

2.註冊視窗類別.建立了視窗我們需要註冊到windows系統中.

3.建立視窗.如果註冊視窗成功.那麼我們需要建立出來這個視窗.並且顯示跟更新.

4.訊息處理

4.視窗編程需要的主要結構

  視窗的建立Windows已經為我們提供了. 這個結構就是WNDCLASSEXW 結構

看下這個結構中的內容吧

typedef struct _WNDCLASSEX {     UINT       cbSize;                   擴充的大小. 自己WndClass本身大小.    UINT       style;                    風格    WNDPROC    lpfnWndProc;              視窗回調.訊息都要進入這個回調    int        cbClsExtra;                  int        cbWndExtra;      HINSTANCE  hInstance;                執行個體控制代碼    HICON      hIcon;                    表徵圖    HCURSOR    hCursor;                  游標    HBRUSH     hbrBackground;            背景    LPCTSTR    lpszMenuName;             菜單名稱    LPCTSTR    lpszClassName;            類名稱    HICON      hIconSm;                  最小化表徵圖} WNDCLASSEX, *PWNDCLASSEX; 

這個結構就是說.你的視窗是什麼樣式. 大小.是否有表徵圖. 訊息處理函數在哪裡等等.需要我們給指定.

 5.完整代碼.
// WindoS.cpp : 定義應用程式的進入點。//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include "WindoS.h"#define MAX_LOADSTRING 100// 全域變數: HINSTANCE hInst;                                // 當前執行個體WCHAR szTitle[MAX_LOADSTRING]  = TEXT("第一個我的視窗");                  // 標題列文本WCHAR szWindowClass[MAX_LOADSTRING] = TEXT("MyWindow");            // 主視窗類名// 此代碼模組中包含的函數的前向聲明: LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance,                     _In_opt_ HINSTANCE hPrevInstance,                     _In_ LPWSTR    lpCmdLine,                     _In_ int       nCmdShow){    //1.自訂視窗樣式    WNDCLASS wcex;    wcex.style = CS_HREDRAW | CS_VREDRAW;    wcex.lpfnWndProc = WndProc;                          //設定回調    wcex.cbClsExtra = 0;    wcex.cbWndExtra = 0;    wcex.hInstance = hInstance;                         //設定模組執行個體控制代碼    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOS));    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);    //設定背景顏色    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOS);    wcex.lpszClassName = szWindowClass;                //設定類名    
  //上面主要就是4個參數有用. 回呼函數 背景顏色 模組控制代碼. 類名 //2.註冊視窗類別 BOOL bRet = RegisterClass(&wcex); //A RegisterClass U RegisterClassW 擴充 RegisterClassExA /ExW if (bRet == FALSE) { return 0; } //3.建立視窗 並且顯示跟更新視窗 HWND hWnd = CreateWindowW( szWindowClass, //我們的類名 szTitle, //我們自訂的視窗名稱 WS_OVERLAPPEDWINDOW, //視窗的建立樣式 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, //執行個體控制代碼 nullptr); //上面重要的也就是4個參數.其餘參數查詢下MSDN. if (!hWnd) { return FALSE; } ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); //4.訊息迴圈. MSG msg; /* 1參數是訊息結構體.作業系統會往裡面填寫訊息. 2 參數視窗控制代碼 因為每個線程可以有多個視窗.表示我要取那個視窗的訊息 3.4 參數表示我要取這個視窗的那個訊息. 後面三個參數屬於過濾條件 */ while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); //鍵盤訊息轉換為小寫. DispatchMessage(&msg); //分發訊息.將我們的訊息傳遞給我們的回呼函數處理. 重要函數.此訊息會將Windows的訊息.發送給我們 定義視窗類別的時候給的回呼函數.這樣我們就可以根據訊息執行我們代碼了. } } return 0;}//// 函數: WndProc(HWND, UINT, WPARAM, LPARAM)//// 目的: 處理主視窗的訊息。//// WM_COMMAND - 處理應用程式菜單// WM_PAINT - 繪製主視窗// WM_DESTROY - 發送退出訊息並返回//// 我們的視窗回調.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_COMMAND: //菜單訊息類型 { int wmId = LOWORD(wParam); //取低兩位為菜單ID.根據菜單ID可以進行操作我們的視窗 // 分析菜單選擇: switch (wmId) { case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); //如果不處理.則必須調用這個函數教給預設的視窗回調處理 } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此處添加使用 hdc 的任何繪圖代碼... LineTo(hdc, 0, 100); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}

建立完畢的結果

三丶訊息類型

我們回調中有我們的訊息類型.我們可以判斷訊息類型進行我們不同的操作.

比如菜單訊息.

WM_COMMAND.  如果是這個訊息.那麼回呼函數的 wparam等附加資訊就是WM_COMMAND的附加訊息了. 我們可以取低位得出操作的菜單ID.進而進行訊息處理.

 

WM_PAINT  這個訊息是繪製的訊息.我們知道.視窗是不斷繪製的.所以繪製訊息會一直來.

WM_DESTROY  視窗關閉訊息. 如果接受到這個訊息.則調用API往訊息佇列中(MSG)中傳遞退出訊息. 此時外層主線程就會結束.

具體API:

  postQuitMessage(0);

當前具體的訊息還要查詢MSDN. 因為訊息種類很多.

windows訊息都是WM開頭的.

比如查詢WM_COMMAND訊息

可以清楚的看到.她會告訴你如果是WM_COMMAND訊息來了.那麼回呼函數的參數.分別代表的是什麼意思.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.