最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

實(shí)例分析一個(gè)簡(jiǎn)單的Win32程序

 更新時(shí)間:2014年09月04日 16:53:16   投稿:shichen2014  
這篇文章主要介紹了實(shí)例分析一個(gè)簡(jiǎn)單的Win32程序,對(duì)于Win32應(yīng)用程序的原理、執(zhí)行流程、實(shí)現(xiàn)方法主要環(huán)節(jié)都做了較為詳細(xì)的分析,有助于讀者深入理解Windows應(yīng)用程序設(shè)計(jì),需要的朋友可以參考下

本文較為詳細(xì)的分析了一個(gè)Win32程序的組成、結(jié)構(gòu)、實(shí)現(xiàn)方法及運(yùn)行原理,對(duì)于進(jìn)行Windows程序設(shè)計(jì)有很好的借鑒參考價(jià)值。分享給大家供大家參考之用。具體分析如下:

一、Windows程序與普通C或C++程序的不同

學(xué)過(guò)C或C++等語(yǔ)言的人都知道,我們寫(xiě)的程序都一個(gè)入口,main函數(shù),但是在Win32程序里,我們的入口函數(shù)又是什么呢?它是怎么樣運(yùn)行的,跟我們用C或C++寫(xiě)的控制臺(tái)程序又有什么不同呢?

我們先說(shuō)Win32程序跟我們控制臺(tái)的程序的一個(gè)很重要的不同點(diǎn),就是Win32程序是一個(gè)消息響應(yīng)程序,例如點(diǎn)擊了一個(gè)按鈕,就會(huì)產(chǎn)生一個(gè)消息onButoon,然后會(huì)這個(gè)消息會(huì)進(jìn)入我們程序所維護(hù)的一個(gè)消息隊(duì)列,程序運(yùn)行過(guò)程中不斷地取出隊(duì)列中的消息,并作出相應(yīng)的處理。直到取出的是結(jié)束程序的消息。

二、了解MSG的結(jié)構(gòu)和組成

首先,既然Windows的程序是基于消息觸發(fā)的,那么Windows是如何定義一個(gè)消息的呢?下面是在MSDN上說(shuō)明文檔上的定義:

typedef struct tagMSG {   // msg 
  HWND hwnd;
  UINT message;
  WPARAM wParam;
  LPARAM lParam;
  DWORD time;
  POINT pt;
} MSG;

下面我們來(lái)分析一下這個(gè)結(jié)構(gòu)體:

HWND hwnd:hwnd是一個(gè)窗口的句柄,用來(lái)唯一標(biāo)識(shí)一個(gè)窗口資源;至于什么是一個(gè)句柄,它有點(diǎn)類(lèi)似對(duì)C或C++中的指針,句柄是資源的標(biāo)識(shí),根據(jù)資源的類(lèi)型,又可將句柄細(xì)分成圖標(biāo)句柄(HICON),光標(biāo)句柄(HCURSOR),窗口句柄(HWND),應(yīng)用程序?qū)嵗浔℉INSTANCE)等等各種類(lèi)型的句柄。操作系統(tǒng)給每一個(gè)窗口指定的一個(gè)唯一的標(biāo)識(shí)號(hào)即窗口句柄。
 
UINT message:message是一個(gè)UINT(即C或C++中的unsign int)類(lèi)型的變量,它用來(lái)標(biāo)識(shí)一個(gè)具體的消息,如按鍵盤(pán)的消息。message用一個(gè)整數(shù)來(lái)表示,但是一個(gè)整數(shù)通常不好記憶,所以在VC++中就用微軟給我們定義的一些宏來(lái)表示,如WM_KEYDOWN。

WPARAM wParam:整型參數(shù),用來(lái)指示message的附加信息。

LPARAM lParam:跟wParam一樣,是一個(gè)整型參數(shù),用來(lái)指示message的附加信息。與wParam一樣,多用來(lái)區(qū)分同一個(gè)消息的不同情況。

DWORD time:DWORD其實(shí)是C或C++中的unsigned long類(lèi)型,time標(biāo)識(shí)了一個(gè)消息產(chǎn)生時(shí)的時(shí)間。

POINT pt:POINT是一個(gè)結(jié)構(gòu)體,表示現(xiàn)實(shí)世界里的一個(gè)點(diǎn),里面有兩個(gè)LONG類(lèi)型的成員x和y,用來(lái)表示產(chǎn)生這個(gè)消息產(chǎn)時(shí)光標(biāo)或鼠標(biāo)的坐標(biāo)。

由此可知一個(gè)MSG的變量所包含的信息是相當(dāng)多和詳細(xì)的。

三、了解WinMain函數(shù)

然后,像C或C++控制臺(tái)程序的入口是main函數(shù)一樣,Win32程序的入口也是main函數(shù),不過(guò)它叫WinMain函數(shù),它的定義如下:

int WINAPI WinMain(
 HINSTANCE hInstance,   // handle to current instance
 HINSTANCE hPrevInstance, // handle to previous instance
 LPSTR lpCmdLine,     // command line
 int nCmdShow       // show state
);

下面我們來(lái)分析一下這個(gè)函數(shù):

HINSTANCE hInstance:hInstance是一個(gè)指向當(dāng)前應(yīng)用程序?qū)嵗囊粋€(gè)句柄。實(shí)例就是一個(gè)運(yùn)行中的程序。

HINSTANCE hPrevInstance:hPrevInstance是一個(gè)指向之前應(yīng)用程序?qū)嵗囊粋€(gè)句柄。

LPSTR lpCmdLine:lpCmdLine是一個(gè)指向字符串的指針,表示一個(gè)命令行參數(shù),什么是命令行參數(shù)呢?就是我們C或C++中的main函數(shù)中的參數(shù)char *argv[]。

int nCmdShow:用來(lái)表示一個(gè)窗口的顯示,表示它是要最大化顯示,最小化顯示,正常大小顯示還是隱藏顯示。

WinMain與main函數(shù)一樣,是由操作系統(tǒng)進(jìn)行調(diào)用的,所以這些參數(shù)也是由操作系統(tǒng)來(lái)賦值。

WINAPI是什么呢?其實(shí)它是一個(gè)宏,它代表的是__stdcall,表示的是參數(shù)傳遞的順序,但是在VC中,參數(shù)的默認(rèn)傳遞順序?yàn)開(kāi)_cdecl。

四、創(chuàng)建一個(gè)窗口

那我們應(yīng)該怎樣設(shè)計(jì)一個(gè)窗口呢?要設(shè)計(jì)一個(gè)窗口,實(shí)際上是要設(shè)計(jì)一個(gè)窗口類(lèi),用來(lái)標(biāo)記一個(gè)窗口的各種屬性,在VC中已經(jīng)有這樣類(lèi)(更正確地說(shuō)是一個(gè)結(jié)構(gòu)體)WNDCLASS。它的定義如下,后面的注釋說(shuō)明了它們的用處:

typedef struct _WNDCLASS { 
 UINT style;       //用于指定類(lèi)的類(lèi)型,即窗口類(lèi)的類(lèi)型
 WNDPROC lpfnWndProc;  //指定一個(gè)窗口回調(diào)函數(shù),是一個(gè)函數(shù)的指針 
 int cbClsExtra;     //類(lèi)的附加內(nèi)存,通常數(shù)情況下為0
 int cbWndExtra;     //窗口附加內(nèi)存,通常情況下為0
 HANDLE hInstance;  //當(dāng)前實(shí)例句柄,用WinMain中的形參給它賦值
 HICON hIcon;     //圖標(biāo)句柄,用于指示應(yīng)用程序所用的是什么圖標(biāo),用函數(shù)LoadIcon進(jìn)行賦值
 HCURSOR hCursor; //光標(biāo)句柄,用于指示鼠標(biāo)進(jìn)入應(yīng)用程序窗口區(qū)域時(shí)的顯示,用函數(shù)LoadCursor進(jìn)行賦值
 HBRUSH hbrBackground;   //用于指示程序的背景顏色,用函數(shù)(HBRUSH)GetStockObject賦值。
 LPCTSTR lpszMenuName;   //指定菜單的名字
 LPCTSTR lpszClassName;   //指定類(lèi)的名字
 } WNDCLASS;

注:類(lèi)型窗口的過(guò)程函數(shù),也稱(chēng)回調(diào)函數(shù),原理是,當(dāng)應(yīng)用程序收到給某一窗口的消息時(shí),就應(yīng)該調(diào)用某一函數(shù)來(lái)處理這條消息。這一調(diào)用過(guò)程不用應(yīng)用程序自己來(lái)實(shí)施,而由操作系統(tǒng)來(lái)完成,但是,回調(diào)函數(shù)本身的代碼必須由應(yīng)用程序自己完成。對(duì)于一條消息,操作系統(tǒng)調(diào)用的是接受消息的窗口所屬的類(lèi)型中的lpfnWndProc成員指定的函數(shù)。每一種不同類(lèi)型的窗口都有自己專(zhuān)用的回調(diào)函數(shù),該函數(shù)就是通過(guò)lpfnWndProc成員指定的。

在VC里或?qū)慦indows程序時(shí),我們會(huì)經(jīng)常用到一類(lèi)變量,這個(gè)變量里的每一位(bit)都對(duì)應(yīng)某一種特性。當(dāng)該變量的某位為1時(shí),表示有該位對(duì)應(yīng)的那種特性,當(dāng)該位為0時(shí),即沒(méi)有該位所對(duì)應(yīng)的特性。當(dāng)變量中的某幾位同時(shí)為1時(shí),就表示同時(shí)具有幾種特性的組合。一個(gè)變量中的哪一位代表哪種意義,不容易記憶,所以我們經(jīng)常根據(jù)特征的英文拼寫(xiě)的大寫(xiě)去定義一些宏,該宏所對(duì)應(yīng)的數(shù)值中僅有與該特征相對(duì)應(yīng)的那一位(bit)為1,其余的bit都為0。其實(shí)這些宏是一個(gè)UINT類(lèi)型的一個(gè)數(shù)值,所以我們可以用|運(yùn)算符來(lái)把多個(gè)特性結(jié)合在一起,用&~來(lái)去掉一個(gè)特性。

所以要?jiǎng)?chuàng)建一個(gè)窗口,首先我們?cè)赪inMain函數(shù)中創(chuàng)建一個(gè)WNDCLASS變量,并對(duì)WNDCLASS變量中的成員賦值之后,就可以注冊(cè)這個(gè)窗口,可調(diào)用函數(shù)RegisterClass(&wndcls)來(lái)注冊(cè)一個(gè)窗口,它需要一個(gè)WNDCLASS類(lèi)型變量的地址。然后定義一個(gè)窗口的句柄HWND hwnd;然后調(diào)用函數(shù)CreateWindow,把返回值賦給hwnd。最后調(diào)用函數(shù)ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);來(lái)顯示窗口。

五、建立消息循環(huán)

現(xiàn)在窗口是創(chuàng)建出來(lái)了,但是之前我們就說(shuō)過(guò),Windows程序是基于消息觸發(fā)和處理的程序,那么我們?nèi)绾巫尦绦蜃屜到y(tǒng)知道我們的操作呢?例如點(diǎn)擊了一下鼠標(biāo),按了一下鍵盤(pán),那就要建立我們的消息循環(huán)了,建立方法如下。
首先,我們定義一個(gè)MSG類(lèi)型的變量,如MSG msg;
然后執(zhí)行如下的循環(huán):

while(GetMessage(&msg,NULL,0,0)) { 
 TranslateMessage(&msg); 
 DispatchMessage(&msg); 
 }

解釋?zhuān)?/strong>

GetMessage函數(shù)從我們的消息隊(duì)列中取出消息,第一個(gè)參數(shù)為MSG變量,它出會(huì)自動(dòng)幫我們填充msg中的成員變量;第二個(gè)參數(shù)是一個(gè)窗口句柄,NULL表示接受屬于調(diào)用線程的所有消息;第三個(gè)參數(shù)指定消息的最小值;第四個(gè)參數(shù)指定消息的最大值。這兩個(gè)參數(shù)若設(shè)為0,則獲取所有在消息隊(duì)列中的消息。它的返回值為BOOL型,只有在取出的消息為WM_QUIT時(shí),返回FALSE;即除非關(guān)閉程序,否則將是一個(gè)死循環(huán),一直對(duì)我們的操作進(jìn)行處理。

TranslateMessage函數(shù),用于翻譯、處理和轉(zhuǎn)換消息并把新消息投放到消息隊(duì)列中,并且此過(guò)程不會(huì)影響原來(lái)的消息隊(duì)列。

DispatechMessage函數(shù),用于把收到的消息傳到窗口回調(diào)函數(shù)進(jìn)行分析和處理。即將消息傳遞給操作系統(tǒng),讓操作系統(tǒng)調(diào)用窗口回調(diào)函數(shù),來(lái)對(duì)信息進(jìn)行處理。

六、回調(diào)函數(shù)(窗口過(guò)程函數(shù))

首先來(lái)看看它的定義:

LRESULT CALLBACK WinSunProc( 
 HWND hwnd, // 窗口句柄 
 UINT uMsg, // 消息標(biāo)志符
 WPARAM wParam, // MSG第一附加參數(shù) 
 LPARAM lParam // MSG第二附加參數(shù)
 );

CALLBACK是一個(gè)宏表示前面所說(shuō)的_stdcall,LRESULT是一個(gè)long型參數(shù)。
調(diào)用時(shí),把窗口類(lèi)WNDCLASS的參數(shù)傳遞過(guò)來(lái),里面有一個(gè)switch語(yǔ)句,用來(lái)判斷要處理的消息類(lèi)型,并作出相應(yīng)的處理,注意switch語(yǔ)句里一定有一個(gè)default:return DefWindowProc(hwnd,uMsg,wParam,lParam);表示沒(méi)有在case中出現(xiàn)的消息將按默認(rèn)處理方式來(lái)處理,不然窗口運(yùn)行會(huì)出錯(cuò),連窗口都不能創(chuàng)建和顯示出來(lái)。

通過(guò)上述分析還原了一個(gè)Win32應(yīng)用程序的完整執(zhí)行流程,相信本文所述對(duì)大家的Windows應(yīng)用程序設(shè)計(jì)有一定的借鑒價(jià)值。

相關(guān)文章

  • Flutter應(yīng)用Windows平臺(tái)接入實(shí)踐詳解

    Flutter應(yīng)用Windows平臺(tái)接入實(shí)踐詳解

    這篇文章主要為大家介紹了Flutter應(yīng)用Windows平臺(tái)接入實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 詳解C++中的析構(gòu)函數(shù)

    詳解C++中的析構(gòu)函數(shù)

    這篇文章主要介紹了C++中的析構(gòu)函數(shù)的相關(guān)知識(shí),文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 如何解決C語(yǔ)言,函數(shù)名與宏沖突

    如何解決C語(yǔ)言,函數(shù)名與宏沖突

    本文介紹了“如何解決C語(yǔ)言,函數(shù)名與宏沖突”,需要的朋友可以參考一下
    2013-03-03
  • C語(yǔ)言代碼實(shí)現(xiàn)三子棋小游戲

    C語(yǔ)言代碼實(shí)現(xiàn)三子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析

    C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟

    C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟

    C++標(biāo)準(zhǔn)模板庫(kù)(STL)提供了多種容器類(lèi)型,包括順序容器、關(guān)聯(lián)容器、無(wú)序關(guān)聯(lián)容器和容器適配器,每種容器都有其特定的用途和特性,這篇文章主要介紹了C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟,需要的朋友可以參考下
    2025-01-01
  • 利用C++實(shí)現(xiàn)獲取文件夾下所有文件名

    利用C++實(shí)現(xiàn)獲取文件夾下所有文件名

    這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)獲取文件夾下所有文件名,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-09-09
  • 詳解為什么指針被譽(yù)為C語(yǔ)言靈魂

    詳解為什么指針被譽(yù)為C語(yǔ)言靈魂

    說(shuō)到指針,就不可能脫離開(kāi)內(nèi)存,學(xué)會(huì)指針的人分為兩種,一種是不了解內(nèi)存模型,另外一種則是了解。不了解的對(duì)指針的理解就停留在“指針就是變量的地址”這句話,會(huì)比較害怕使用指針,特別是各種高級(jí)操作。本文將帶你詳細(xì)了解C語(yǔ)言指針
    2021-06-06
  • C++順序表實(shí)現(xiàn)圖書(shū)管理系統(tǒng)

    C++順序表實(shí)現(xiàn)圖書(shū)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++順序表實(shí)現(xiàn)圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 關(guān)于C++中引用和指針的區(qū)別詳解

    關(guān)于C++中引用和指針的區(qū)別詳解

    這篇文章主要介紹了關(guān)于C++中引用和指針的區(qū)別詳解,
    2023-07-07

最新評(píng)論

南通市| 卢龙县| 灵川县| 泾川县| 孝感市| 宽城| 临夏县| 当涂县| 新余市| 枣庄市| 乡城县| 纳雍县| 高陵县| 仁怀市| 衡南县| 富平县| 阳曲县| 阿拉尔市| 彰武县| 彩票| 繁昌县| 进贤县| 阿坝| 浑源县| 金塔县| 铜鼓县| 东乌珠穆沁旗| 偃师市| 兴仁县| 嘉荫县| 阿城市| 赤城县| 镇雄县| 峡江县| 澜沧| 澎湖县| 山阴县| 龙里县| 神池县| 寻乌县| 察雅县|