久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

windows窗口的創(chuàng)建

 昵稱1088221 2010-07-15
一,、WINDOWS的消息和窗口簡介:
1,、什么是windows在這里我就不介紹了,但是作為一個程序員我們要知道WINDOWS最重要的一個也是我們程序員常用的一個東西就是消息,。窗口是以消息的形式輸入的,,窗口也用消息與其它窗口通訊。
2,、我們常會說windows給程序發(fā)送了一個消息,,其實這是指windows調(diào)用程序中的一個函數(shù),該函數(shù)的參數(shù)描述了這個特定消息,。這種位于windows程序中的函數(shù)稱為“窗體消息處理程序”,。程序建立的每一個窗體都有相關(guān)的窗口消息處理程序,。這個窗口消息處理程序是一個函數(shù),既可以在程序中,,也可以在動態(tài)鏈接庫中,。Windows通過調(diào)用窗口消息處理程序來給窗體發(fā)送消息。窗口消息處理程序根據(jù)此消息進行處理,,然后將控制傳回給windows,。
3、在對象導(dǎo)向的程序設(shè)計中,,對象是程序與數(shù)據(jù)的組合,。窗口是一種對象,其程序是窗口消息處理程序,。數(shù)據(jù)是窗口消息處理程序保存的信息和windows為每個窗口以及系統(tǒng)中那個窗口類別保存的信息,。
4、windows程序開始執(zhí)行后,,windows為該程序建立一個“消息隊列”,。這個消息隊列用來存放該程序可能建立的各種不同窗口的消息。程序中有一小段程序代碼,,叫做“消息循環(huán)”,,用來從隊列中取出消息,并且將它們發(fā)送給相應(yīng)的窗口消息處理程序,。有些消息直接發(fā)送給窗口消息處理程序,,不用放入消息隊列中。
二,、一個真正的windows程序:
1,、代碼如下:
#include <windows.h>
LRESULT CALLBACK WndPro(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) ;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
   static TCHAR szAppName[]=TEXT("helloWin");//一個靜態(tài)的不確定是不是16位還是8位的UNICODE字符串
   HWND hwnd;                                           //窗口句柄
   MSG msg;                                                       //消息結(jié)構(gòu)
   WNDCLASS wndclass ;                                   //窗口類別結(jié)構(gòu)
   wndclass.style =CS_HREDRAW|CS_VREDRAW;//當(dāng)長高改變成重繪區(qū)域型
   wndclass.lpfnWndProc=WndPro;//一個指向消息循環(huán)的函數(shù)指針
   wndclass.cbClsExtra=0;                     //在窗口類別結(jié)構(gòu)和windows內(nèi)部保存的窗
   wndclass.cbWndExtra=0;                   //口結(jié)構(gòu)中預(yù)留一些額外空間
   wndclass.hInstance=hInstance;                //這個程序是hinstance的一個子集
   wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//使用什么圖標(biāo)
   wndclass.hCursor=LoadCursor (NULL,IDC_ARROW);//使用什么鼠標(biāo)樣式
   wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//用白色的背景(在這里是取得繪制窗口背景的畫刷對象)
   wndclass.lpszMenuName=NULL;//不用菜單項
   wndclass.lpszClassName=szAppName;//窗口類別的名字
   if (!RegisterClass(&wndclass))//注冊窗口類
   {
    MessageBox(NULL,TEXT("This program requires Windows NT"),szAppName,MB_ICONERROR);
    return 0;//不成功退出
   }
 
   hwnd=CreateWindow(szAppName,TEXT("The Hello Program"),
    WS_OVERLAPPEDWINDOW,//這是一個多樣式組合
    CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT,//都是windows的內(nèi)定尺寸
    NULL,NULL,hInstance,NULL);//建立窗口類型大小等
   ShowWindow(hwnd,nShowCmd);//顯示窗口以nShowCmd來顯示
   while (GetMessage(&msg,NULL,0,0))//這是從消息隊列中取出一條消息
   {//消息的發(fā)送和分派最上層窗口用NULL
    TranslateMessage(&msg);
    DispatchMessage(&msg);//在這里會調(diào)用到wndPro
   }
   return msg.wParam;
 
}
 
LRESULT CALLBACK WndPro(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
   HDC hdc;
   PAINTSTRUCT ps;                                                 //繪圖結(jié)構(gòu)
   RECT rect;                                                             //矩形結(jié)構(gòu)
   switch(message)
   {
   case WM_CREATE:
// PlaySound(TEXT("hellowin.wav"),NULL,SND_FILENAME|SND_ASYNC);
    break;
   case WM_PAINT:
    hdc=BeginPaint(hwnd,&ps);                           //開始畫圖
    GetClientRect(hwnd,&rect);   
;   // 得到用戶區(qū)
    DrawText(hdc,TEXT("HELLO WINDOWSXP"),-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);// 線型輸出到中間
    EndPaint(hwnd,&ps);
    break;
   case WM_DESTROY:
    PostQuitMessage(0);// 發(fā)出一個退出消息
    break;
   }
   return DefWindowProc(hwnd,message,wParam,lParam);
}
2、代碼分析:
(1),、在這里你除了winMain你還可以看到一個WndPro的函數(shù)這個函數(shù)就是傳說中的消息處理函數(shù),,即消息循環(huán)就在這里運行的也是一個程序的心臟,有了他程序才可以得到正常的運行,,他在窗口注冊類的類里就被移植入窗口類中wndclass.lpfnWndProc=WndPro;要先申明后使用,。
(2)、在這里我還要說一下下CreateWindow和WNDCLASS也就是建立窗口和注冊窗口的聯(lián)系,,他們之間就好比造車廠和設(shè)計車的關(guān)系,,RegisterClass函數(shù)注冊了一個WNDCLASS的對象,然后CreateWindow通過其中的lpClassName這個參數(shù)也就是WNDCLASS對象的lpszClassName與窗口類聯(lián)系起來,,lpszClassName都是字符串的類型,。
(3),、windows函數(shù)的調(diào)用:這個基本的框架里我們調(diào)用了18個windows 函數(shù)如下
LoadIcon                           加載圖標(biāo)代程序使用
LoadCursor                加載鼠標(biāo)光標(biāo)供程序使用
GetStockObject           取得一個圖形對象
RegisterClass                     為程序窗口注冊窗口類別
MessageBox               顯示消息框
CreateWindow            根據(jù)窗口類別建立一個窗口
ShowWindow                     在屏幕上顯示窗口
UpdateWindow            指示窗口自我更新
GetMessage                從消息隊列中取得消息
TranslateMessage        轉(zhuǎn)譯某些鍵盤消息
DispatchMessage        將消息發(fā)送給窗口消息處理程序
PlaySound                  播放一個聲音文件
BeginPaint                  開始繪制窗口
GetClientRect                     取得窗口顯示區(qū)域的大小
DrawText                          顯示字符串
EndPaint                            結(jié)束繪制窗口
PostQuitMessage         在消息隊列中插入一個退出消息
DefWindowProc:         執(zhí)行內(nèi)定消息處理
(4),、在這個函數(shù)里面有很多大小寫字母宏定義:這些解釋一下下
在上面的函數(shù)中出現(xiàn)了如下幾個大寫字母宏定義:
CS_HREDRAW           DT_VCENTER             SND_FILENAME
CS_VREDRAW        IDC_ARROW            WM_CREATE
CW_USEDEFAULT     IDI_APPLICATION      WM_DESTROY
DT_CENTER                 MB_ICONERROR         WM_PAINT
DT_SINGLELINE              SND_ASYNC           WS_OVERLAPPEDWINDOW
           前綴:    類別                                                 使用
           CS          窗口類別樣式    WNDCLASS.style=CS_HREDRAW|CS_VREDRAW;
           CW         建立窗口              CreateWindow---(CW)
           DT         繪制文字              DrawText----(DT)
           IDI         圖示ID                 LoadIcon(….)
           IDC        鼠標(biāo)ID                 LoadCursor()
           MB         消息框
BACKGROUND: #d9d9d9">                  MessageBox------MB
           SND       聲音                      PlaySound ( …… )
           WM        窗口消息               WindowsMessage-------(WM)
           WS         窗口樣式               WindowStyle-----(WS)
 (5),、我們常會問WPARAM和LPARAM有什么區(qū)別干什么用:
其實這兩個參數(shù)是win16和win32并存時留下的產(chǎn)物現(xiàn)在都是32位了,原來wParam(WORD)是一個16位的lParam(LONG)是32位的,現(xiàn)在的WPARAM和LPARAM都是MS重新定義的,,他們通常是與一個消息有關(guān)的常量值如下:
wParam   通常是一個與消息有關(guān)的常量值,,也可能是窗口或控件的句柄。 
lParam   通常是一個指向內(nèi)存中數(shù)據(jù)的指針,。由于wParam,lParam和指針都是32位的,,需要時可以強制類型轉(zhuǎn)換。具體表示什么,,與message相關(guān),,他們是事先定義好的。
(6),、WndPro函數(shù)傳回一個形態(tài)為LRESULT的值,,議該值簡單地被定義為一個LONG,在這里WndPro函數(shù)被指定成一個CALLBACK形態(tài),,其實也是一個和WINAPI一樣的宏定義他是一個_stdcall一個從右到左的壓棧方式,,也就是傳說中的回調(diào)函數(shù)(紙老虎不用怕)。
3,、句柄簡介:
句柄是一個(通常為32位的)整數(shù),,它代表一個對象。Windows中的夠本類似傳統(tǒng)C或MS-Dos程序設(shè)計中使用的文件句柄,。程序幾乎總是通過呼叫window函數(shù)取得句柄,。程序在函數(shù)中使用夠本,用以代表對象,。句柄值對程序來說是無關(guān)緊要的,,但是windows對于這個代號來說他就可以利用這個代號(句柄)使用相對應(yīng)的對象。
一句話句柄是什么,,比如你是一個對象那么句柄就是你的名字,,如果windows要叫你去買醬油那么他會給你說:“XX句柄去買醬油”,和叫對象去買醬油的效果是一樣,,但是用了句柄會更好管理,。(我不知道這樣理解是否會好一點!)
三個大寫標(biāo)識符,,用于不同形態(tài)的句柄
     標(biāo)識符                         含義
     HINSTANCE                執(zhí)行實體(程序自身)句柄
     HWND                         窗口句柄
     HDC                            設(shè)備內(nèi)容句柄
句柄用的很頻繁比如:HICON(圖標(biāo)句柄),、HCURSOR(鼠標(biāo)光標(biāo)句柄) 、
HBRUSH(畫刷句柄),、windows中的每個窗口都有一個夠本,,程序用夠本來使用窗口窗體句柄是windows程序所處理最重要的句柄之一。
4、我順便也說一下instance吧,,其實這就相當(dāng)于是你運行QQ整個QQ就是一個instance!
三,、注冊窗口類別:
窗口依照某一窗口類別建立,窗口類別用以標(biāo)識處理窗口消息的消息處理程序,。
窗口類別定義了窗口消息處理程序和依據(jù)引類別建立的窗口的其它特征,。在建立窗口時,要定義一些該窗口所獨有的特征,。
在為程序建立窗口之前,,必須首先調(diào)用RegisterClass注冊一個窗口類別。該函數(shù)只需要一個參數(shù),,即一個指向形態(tài)為WNDCLASS的結(jié)構(gòu)指針,。些結(jié)構(gòu)包括兩個指向字符串的字段(LPCTSTR lpszMenuName; LPCTSTR lpszClassName;--ASCII。 LPCWSTR lpszMenuName ;LPCWSTR lpszClassName;--UNICODE)因此結(jié)構(gòu)在WINUSER.H表文件中定義了兩種不同的方式(ASCII,UNICODE)在編程過程我們不必去理會,!因為在預(yù)定義時已經(jīng)處理過了(WNDCLASSA,WNDCLASSW---都用WNDCLASS就行),!
       在窗體類定義中最重要的是lpfnWndProc和最后一個字段lpszClassName。
四,、窗口類別
他定義了窗口的一般特征,,因此可以使用同一窗口類別建立許多不同的窗口
R: blue">CreateWindow 建立窗口時,可能指定有關(guān)窗口的更詳細的信息,。傳遞給RegisterClass函數(shù)的信息會在一個數(shù)據(jù)結(jié)構(gòu)中設(shè)定好,,而傳遞給CreateWindow函數(shù)的信息會在函數(shù)單獨的參數(shù)中設(shè)定好。
五,、消息循環(huán):
Windows為當(dāng)前執(zhí)行的每個windows程序維護一個“消息隊列”,。在發(fā)生輸入事件后,windows將事件轉(zhuǎn)換為一個消息并將消息放入程序消息隊列中,。程序通過執(zhí)行一塊稱之為消息循環(huán)的程序代碼從消息隊列中取出消息,。
在這里我們了解一下下MSG結(jié)構(gòu):
Typedef struct tagMSG{
       HWND hwnd;               //接收消息的窗口句柄
       UNIT message;             //消息標(biāo)識符WM_XXXX
       WPARAM wparam;       //32位其含義和數(shù)值根據(jù)消息的不同而不同
       LPARAM lparam;         
       DWORD time;              //消息放入消息隊列中的時間
       POINT pt;                    //消息放入消息隊列時的鼠標(biāo)坐標(biāo)
}MSG,*PMSG;
BOOL GetMessage(
 LPMSG lpMsg,         // address of structure with message
 HWND hWnd,           // handle of window
 UINT wMsgFilterMin, // first message
 UINT wMsgFilterMax   // last message
);
這個調(diào)用付給windows一個指標(biāo),指向名這msg的MSG結(jié)構(gòu),。lpMsg是一個消息地址,,hWnd如果為NULL表示程序接收它自己建立的所有窗口的所有消息,Windows用從消息隊列中取出的下一個消息來填充消息結(jié)構(gòu)的各個字段,。只要從消息隊列中取出消息的message字段不為WM_QUIT,,GetMessage就傳回一個非零值。
BOOL TranslateMessage(
 CONST MSG *lpMsg   // address of structure with message
);
將msge結(jié)構(gòu)傳給windows,進行一些鍵盤轉(zhuǎn)換
LONG DispatchMessage(
 CONST MSG *lpmsg   // pointer to structure with message
);
又將msg結(jié)構(gòu)回傳給windows,。然后,,windows將該消息發(fā)送給適當(dāng)?shù)拇翱谙⑻幚沓绦颍屗M行處理,。這里就是windows將會調(diào)用消息處理程序,,也就是這個窗口的wndPro函數(shù)。處理完消息之后,WndProc傳回到windows,此時window還停留在despatchMessage調(diào)用中,,在結(jié)束dispatchMessage調(diào)用的處理之后,,windows回到GetMessage調(diào)用開始消息循環(huán)。
六,、窗口消息處理程序:
在上面我們介紹了一個窗口的產(chǎn)生過程和動作過程:注冊窗口類別,建立窗口,,然后在屏幕上顯示窗口,,程序進入消息循環(huán),然后不斷從消息隊列中取出消息來處理,。實際的動作發(fā)生在窗口消息處理程序中,。窗口消息處理程序確定了在窗口的顯示區(qū)域中顯示以及窗品怎樣響應(yīng)使用者輸入。窗口消息處理程序可任意命名,,一個windows程序中可以包含多個窗口消息處理程序,。一個窗口消息處理程序總與調(diào)用 的registerClass注冊的特定窗口類別相關(guān)聯(lián)。createWindow函數(shù)根據(jù)特定窗口類別建立一個窗口,。但依據(jù)一個窗口類別,,可以建立多個窗口。
窗口消息處理程序總是定義為如下形式:
LRESULT CALLBACK WndProc(HWND hwnd,UNIT message,
WPARAM wparam,LPARAM lparam)這四個參數(shù)和Msg結(jié)構(gòu)的前四個字段是相同的,。
程序通常不直接呼叫窗口消息處理程序,,中消息處理程序通常由windows本身調(diào)用。窗口消息處理程序在處理消息時,,必須傳回窗口消息處理程序不處理的所有消息應(yīng)傳給名為DefWindowProc的Window函數(shù),。Wndproc只先擇處理三種消息:WM_CREATE,WM_PAINT,WM_DESTROY。
WM_CREATE:處理進行一次窗口初始化,。
WM_PAINT:當(dāng)窗口顯示區(qū)域的一部分或者全部內(nèi)容必要更新顯示或無效時,,將由這個消息通知程序。什么叫無效,,無效就是說如果窗口調(diào)用updateWindows時例如在窗口類中我們寫的style=CS_HREDRAW|CS_VREDRAW這表示在窗口大小改變后就把整個窗口顯示內(nèi)容變?yōu)闊o效調(diào)用updateWindows進行重繪,。在對WM_PAINT的處理幾乎總是從一個BeginPaint(hwnd,&ps)調(diào)用開始,以EndPaint(hwnd,&ps)結(jié)束,ps包含一些窗口消息處理程序可以用來更新顯示區(qū)域的內(nèi)容。在BeginPaint調(diào)用中,,如果顯示區(qū)域的前景還沒被刪除則由windows來刪除,,它使用窗口類別的WNDCLASS的結(jié)構(gòu)中的hbrBackground字段中指定的畫刷來刪除前景。BeginPain返回一個只能在當(dāng)前區(qū)域繪圖的設(shè)備內(nèi)容句柄,。EndPain釋放設(shè)備內(nèi)容句柄,。GetClientRect(hwnd,&rect)rect是返回一個窗口顯示區(qū)域的尺寸。
WM_DESTROY:該消息是使用者單擊Close按鈕或者程序的系統(tǒng)菜單上選擇Close時發(fā)生的,。在這里用的是PostQuitMessage(0)來生效的,。該函數(shù)在程序的消息隊列中插入一個WM_QUIT消息使GetMessage得到一個WM_QUIT的消息,它傳回0,終止程序然后執(zhí)行return msg.wparam;
七、隊列化消息與非隊列化消息:
       Windows給窗口發(fā)送消息,,這意味著windows調(diào)用窗口消息處理程序,。但是,windows程序也有一個消息循環(huán),,它調(diào)用GetMessage從消息隊列中取出消息,,并且調(diào)用dispatchMessage將消息發(fā)送給窗口消息處理程序。
       消息被分為“隊列化的”和“非隊列化的”,。
1,、 隊列化的消息:是由windows放入程序消息隊列中的。在程序的消息循環(huán)中,,重新傳回并分配給窗口消息處理程序,。如鍵盤消息,WM_PAINT windows消息等,。
2,、 非隊列化的消息在windows調(diào)用窗口時直接送給窗口消息處理程序。非隊列化消息多來自己于調(diào)用windows函數(shù)如CreateWindows,,鍵盤或鼠標(biāo)輸入時發(fā)出的隊列化消息信號,,也能在非隊列化消息中出現(xiàn)。
3,、 隊列化的消息被發(fā)送給消息隊列,,而非隊列的消息則發(fā)送給窗口消息處理程序。
任何發(fā)問下,,窗口消息處理程序都將獲得窗口所有的消息――包括隊列和非隊列化的消息,。窗口消息處理程序是窗口的消息中心。
4,、在許多情況下,,窗口消息處理程序必須保存它從消息中取得的信息,并在處理另一個消息時使用這些信息,。這些信息可以儲存在窗口的靜態(tài)變量或整體變量中,。
 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多