day03

type
DC - 設備上下文
CS - class Style
一、窗口類風格 (sTyle)
CS_GLOBALCLASS 應用程序全局窗口類
CS_BYTEALIGNCLIENT 窗口客戶區水平位置按照8像素對齊
CS_BYTEALIGNWINDOW 窗口水平位置按照8像素對齊
CS_HREDRAW 窗口水平變化時重繪窗口內容
CS_VREDRAW 窗口垂直變化時重繪窗口內容
CS_CLASSDC 同類窗口共享一個設備上下文
CS_PARENTDC 子窗口使用父窗口的設備上下文
CS_OWNDC 使用自己設備上下文(默認這種方式)
CS_SAVEBITS 以位圖的形式保存窗口的客戶區(提高效率,但是費內存)
CS_DBLCLKS 接受窗口接受鼠標雙擊消息
CS_NOCLOSE 沒有關閉按鈕

SetWindowLong
設置
GetWindowLong
獲取
Window每次顯示窗口都需要重繪


使用自己的窗口過程函數截獲消息(對於系統定義的函數)
g_OldBtnProc = SetWindowLong (hWnd, GWL_WNDPROC, (LONG)MyBtnProc);
可以讓你修改窗口數據區,第二個參數就是改變的哪個部分,第三個參數你想改成什麼。
當你用第三個參數進行替換的時候,這個函數會把替換部分原來的值返回出來。
CallWindowProc (g_OldBtnProc, hWnd, wParam,lParam);
在系統調用的窗口中,自己定義的過程函數替換了系統自己的獲證函數,但是我只想是改變一些消息的處理方式,其他的方式不想改變,就使用這個函數,他可以幫助你處理。
窗口子類化








二、註冊窗口類與創建窗口
typedef struct
{
....
HINSTANCE hInstance; //應用程序實例句柄
....
LPCTSTR  lpszClassName; //類名
}WNDCLASSEX,*PWNDCLASS;
------------------------------
WNDCLASSEX wcex = {0};
wcex.hInstance = hInstance;
wcex.lpszClassName = "MainWnd";
...
RegisterClassEx (&wcex);
-------------------------------
局部窗口類列表(沒有CS_GLOBALCLASS)
局部窗口類1 -> 局部窗口類2 -> ....
hInstance 
lpszClassName
全局窗口類列表(定義了CS_GLOBALCLASS)
全局窗口類1 -> 全局窗口類2 -> ....
lpszClassName
系統窗口類列表
系統窗口類1 -> 系統窗口類2 -> ....
"BUTTON" "EDIT"
-------------------------------------
HWND  hWnd = CreateWindow ("MainWnd", ...., hInstance, ....);
-------------------------------------
HWND CreateWindow (LPCTSTR lpClassName, ...., HINSTANCE hInstance, ....)
{
if (局部窗口類列表中存在lpszClassName和hInstance成員與lpclassName和hInstance參數相匹配的元素) 
{
根據該元素去創建一個窗口並返回其句柄.
}
else 
if (全局列表中存在lpszClassName和lpClassName參數相匹配額元素)
{
根據該元素去創建一個窗口並返回其句柄
}
else 
if (系統列表中存在lpszClassName和lpClassName參數相匹配額元素) 
{
根據該元素去創建一個窗口並返回其句柄
}
else
return NULL;
}




創建自己的Icon的步驟:
在工程中添加資源腳本 - 在腳本中添加位圖 - 保存
LoadIcon (hInstance, MAKEINTRESOURCE (IDI_WINREG_BIG));
爲什麼會出現MAKEINTRESOURCE呢?
這個是LoadIcon中參數的問題,他要的是一個實例句柄和字符串指針
但是IDI_WINREG_BIG是一個宏所以他不能成爲LoadIcon的參數


WS_EX_CLIENTEDGE
多了一個3D效果的邊框
在CreateWindowEx 中使用的。而且是第一個參數






三、創建窗口API
CreateWindow
CreateWindowEx相對於CreateWindow,增加了一個參數 - dwExStyle - 擴展風格
WS_EX_CLIENTEDGE - 3D效果的邊框
WS_EX_MDICHILD - MDI子窗口


四、常用窗口風格
WS_BURDER - 邊框
WS_CAPTION - 標題
WS_CHILD - 子窗口
WS_CHILDWINDOW - 同WS_CHILD
WS_CLIPCHILDREN - 恢復父窗口先前被子窗口覆蓋時部分時,不繪製被子窗口覆蓋的部分。應用於父窗口。
(繪製父窗口時不繪製被子窗口覆蓋的部分)
WS_CLIPSIBLINGS - 繪製子窗口的同時也繪製其兄弟窗口。應用於子窗口。 
WS_DISABLE - 禁用
WS_DLGFRAME - 對話框邊框(大小固定,不能縮放)
WS_GROUP - 控件組的首控件
WS_HSCROLL - 水平滾動條
WS_VSCROLL - 垂直滾動條


WS_ICONIC - 初始最小化
WS_MAXIMIZE - 初始最大化
WS_MAXIMIZEBOX - 最大化按鈕
WS_OVERLAPPED - 交疊 帶有標題欄和邊框
WS_OVERLAPPEDWINDOW - 交疊、系統菜單、帶尺寸框、最小最大化按鈕
WS_POPUP - 彈出式
WS_POPUPWINDOW - 彈出式、邊框(改變大小)、系統菜單
WS_SIZEBOX - 尺寸框
WS_SYSMENU - 系統菜單
WS_TABSTOP - 可用Tab切換
WS_THICKFRAME - 同WS_SIZEBOX
WS_TILED - 同WS_OVERAPPLED
WS_TILEDWINDOW - 同WS_OVERAPPLEDWINDOW
WS_VISIBLE - 初始可見


窗口風格 只管着一個風格
窗口類風格 管着一類風格


case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint (hWnd, &ps);
RECT rcClient;
GetClientRect (hWnd, &rcClient);
Ellipse (hDC, rcClient.left, rcClient.top,
rcClient.right, rcClient.bottom);
EndPaint (hWnd, &ps);
return 0;
}


五、子窗口的創建
1.WS_CHILD | WS_VISIBLE
2.有父窗口
3.與子窗口有關的風格


SetWindowPos
設置窗口位置
GetSystemMetrics
獲取某些東西的信息
六、窗口類附加數據和窗口附加數據
WNDCLASSEX wcex;
...
wcex.cbClsExtra = 4;
wcex.cbWndExtra = 4;
/*這個表示使用4個字節存儲數據*/






SetClassLong/GetClassLong
SetWindowLong/GetWindowLong




DWORD SetClassLong(
  HWND hWnd,       // handle of window
  int nIndex,      // index of value to change
/*這個就是一個索引號,例如你定義了8個字節,如果你給0,就使用前4個字節,如果你給1,就使用後4個字節,類似一個數組下標*/
 
  LONG dwNewLong   // new value
/* Set value it you need*/
);


在setclasslong中的規定宏都是小於0的。
 


窗口附加數據獨立的存在,每一個窗口都有一個窗口附加數據
窗口類附加數據不是獨立的,他是整個窗口含有一個,他就像一個父類一樣,有很多的基類
但是窗口附加數據就相當於子類。
七、顯示/刷新窗口
BOOL ShowWindow (HWND hWnd, int nCmdShow) 
{
根據hWnd窗口位置大小顏色等信息。
根據所獲得的窗口外觀信息和nCmdShow參數在屏幕上繪製窗口;

}
BOOL UpdateWindow (hWnd) {
if (hWnd參數所標識的窗口存在無效區域)
以WM_PAINT消息爲參數調用相應窗口過程函數
}
無效區域就是 兩個文件的遮蓋部分


InvalidateRect ()
重畫函數


八、消息隊列/消息循環/消息處理
1.程序的執行機制
1)過程驅動: 程序按照預定的順序執行。
2)事件驅動: 根據用戶觸發的事件來執行相應的動作
3)Win32窗口程序採用事件驅動方式執行, 消息機制
2.消息
typedef struct tagMSG {
HWND hWnd; //窗口句柄
UINT message; //消息標示
WPARAM wParam;
LPARAM lParam; //消息參數
DWORD time; //消息產生的時間
POINT pt; //消息產生時鼠標的位置
} MSG;
消息結構前四個成員與窗口過程函數的參數一致
3.消息隊列
GetMessage () <-WM_CREATE WM_SIZE WM_PAINT ... -< 消息源
每一個線程有一個消息隊列.
4.消息循環
MSG msg = {0};
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
1) GetMessage 函數負責從消息隊列中獲取消息,並將其內容填入Msg結構體。
BOOL GetMessage (
LPMSG lpMsg, //消息結構
HWND hWnd, //窗口句柄,若非NULL則,只獲取特定窗口的消息。
UINT uMsgFilterMin, //消息過濾器的下限
UINT uMsgFilterMax, //消息過濾器的上限
);
收到WM_QUIT消息返回FALSE,收到其他消息返回TRUE
case WM_DESTROY:
PostQuitMessage (0);
return 0;


PostQuitMessage 函數在消息隊列中放入一個WM_QUIT消息


2)TranslateMessage 函數負責對部分消息(與可見字符相關、鍵盤消息,進行翻譯);
BOOL TranslateMessage (
const MSG* lpMsg //消息結構
);
如果消息被翻譯了,返回TRUE,否則返回FALSE
根據CapsLock鍵的狀態判斷大小寫。
3)DispatchMessage 派發消息
LONG DispatchMessage (const MSG* lpmsg)
{
根據 lpmsg->hWnd獲取相應的窗口類
從窗口類的lpfnWndProc成員確定窗口過程函數的地址;
窗口過程函數 (lpmsg->hWnd, lpMsg->message, lpmsg->wParam, lpmsg->lParam);

}
4)一旦GetMessage函數從消息隊列中取到WM_QUIT消息,即返回FALSE,消息循環結束,線程終止。
如果線程爲進程的主線程,進而線程終止。




------------------------------------------------------------
三、消息處理







































































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章