Windows底层窗口的实现———学习笔记
基本概念
SDK
軟件開發(fā)工具包(Software?Development?Kit),一般都是一些被軟件工程師用于為特定的軟件包、軟件框架、硬件平臺(tái)、操作系統(tǒng)等建立應(yīng)用軟件的開發(fā)工具的集合。?
API
Windows操作系統(tǒng)提供給應(yīng)用程序編程的接口(Application Programming Interface)。
Windows應(yīng)用程序API函數(shù)是通過(guò)C語(yǔ)言實(shí)現(xiàn)的,所有主要的 Windows 函數(shù)都在 Windows.h 頭文件中進(jìn)行了聲明。Windows 操作系統(tǒng)提供了 1000 多種 API函數(shù)。
窗口和句柄
窗口是屏幕上的一塊矩形區(qū)域,是 Windows 應(yīng)用程序與用戶進(jìn)行交互的接口。利用窗口可以接收用戶的輸入、以及顯示輸出。
在 Windows 應(yīng)用程序中, 窗口是通過(guò)窗口句柄( HWND) 來(lái)標(biāo)識(shí)的。
句柄( HANDLE) 是 Windows 程序中一個(gè)重要的概念, 在 Windows 程序中, 有各種各樣的資源( 窗口、 圖標(biāo)、光標(biāo),畫刷等), 系統(tǒng)在創(chuàng)建這些資源時(shí)會(huì)為它們分配內(nèi)存, 并返回標(biāo)識(shí)這些資源的標(biāo)識(shí)號(hào), 即句柄。?
消息和消息隊(duì)列
Windows 程序設(shè)計(jì)是一種完全不同于傳統(tǒng)的 DOS 方式的程序設(shè)計(jì)方法。它是一種事件驅(qū)動(dòng)方式的程序設(shè)計(jì)模式,主要是基于消息的。
每一個(gè) Windows 應(yīng)用程序開始執(zhí)行后, 系統(tǒng)都會(huì)為該程序創(chuàng)建一個(gè)消息隊(duì)列, 這個(gè)消息隊(duì)列用來(lái)存放該程序創(chuàng)建的窗口的消息。
例如,當(dāng)用戶在窗口中畫圖的時(shí)候,按下鼠標(biāo)左鍵,此時(shí),操作系統(tǒng)會(huì)感知到這一事件,于是將這個(gè)事件包裝成一個(gè)消息,投遞到應(yīng)用程序的消息隊(duì)列中,等待應(yīng)用程序的處理。
然后應(yīng)用程序通過(guò)一個(gè)消息循環(huán)不斷地從消息隊(duì)列中取出消息,并進(jìn)行響應(yīng)。
在這個(gè)處理過(guò)程中,操作系統(tǒng)也會(huì)給應(yīng)用程序“ 發(fā)送消息”。所謂“ 發(fā)送消息”,實(shí)際上是操作系統(tǒng)調(diào)用程序中一個(gè)專門負(fù)責(zé)處理消息的函數(shù),這個(gè)函數(shù)稱為窗口過(guò)程。
?
?WinMain函數(shù)
當(dāng)Windows操作系統(tǒng)啟動(dòng)一個(gè)程序時(shí),它調(diào)用的就是該程序的WinMain函數(shù)( 實(shí)際是由插入到可執(zhí)行文件中的啟動(dòng)代碼調(diào)用的)。
WinMain是Windows程序的入口點(diǎn)函數(shù),與DOS程序的入口點(diǎn)函數(shù)main的作用相同,當(dāng)WinMain 函數(shù)結(jié)束或返回時(shí),Windows應(yīng)用程序結(jié)束。
Windows 編程模型
一個(gè)完整的Win32程序(#include <windows.h>),該程序?qū)崿F(xiàn)的功能是創(chuàng)建一個(gè)窗口,并在該窗口中響應(yīng)鍵盤及鼠標(biāo)消息,程序的實(shí)現(xiàn)步驟為:
?
項(xiàng)目的創(chuàng)建
?
?
?
#include <windows.h>//6.處理窗口過(guò)程 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//消息所屬窗口句柄,具體消息名稱,鍵盤附件消息,鼠標(biāo)附加消息 {switch (uMsg){case WM_CLOSE://所有xxxWindow為結(jié)尾的方法 ,都不會(huì)進(jìn)入到消息隊(duì)列中,而是直接執(zhí)行DestroyWindow(hwnd); //DestroyWindow 發(fā)送另一個(gè)消息 WM_DESTROYbreak;case WM_DESTROY:PostQuitMessage(0);break;case WM_LBUTTONDOWN: //鼠標(biāo)左鍵按下{int xPos = LOWORD(lParam);int yPos = HIWORD(lParam);char buf[1024];wsprintf(buf, TEXT("x = %d,y = %d"), xPos, yPos);MessageBox(hwnd, buf, TEXT("鼠標(biāo)左鍵按下"), MB_OK);break;}case WM_KEYDOWN: //鍵盤MessageBox(hwnd, TEXT("鍵盤按下"), TEXT("鍵盤按下"), MB_OK);break;case WM_PAINT: //繪圖{PAINTSTRUCT ps; //繪圖結(jié)構(gòu)體HDC hdc = BeginPaint(hwnd, &ps);TextOut(hdc, 100, 100, TEXT("Hello world"), strlen("Hello world"));EndPaint(hwnd, &ps);}break;}return DefWindowProc(hwnd,uMsg,wParam,lParam); }//WINAPI代表__stdcall 參數(shù)傳遞順序:從右到左,由此入棧,并且在函數(shù)返回前 清空堆棧 int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)//應(yīng)用程序?qū)嵗浔?#xff1b;上一個(gè)應(yīng)用程序句柄,在Win32情況下,參數(shù)一般為NULL,不起作用;vhar * argv[];顯示命令,最大化,最小化,正常 {//1.設(shè)計(jì)窗口//2.注冊(cè)窗口//3.創(chuàng)建窗口//4.顯示和更新//5.通過(guò)循環(huán)取消息//6.窗口過(guò)程//1.設(shè)計(jì)窗口WNDCLASS wc;wc.cbClsExtra = 0;//不要額外內(nèi)存wc.cbWndExtra = 0;//不要窗口額外內(nèi)春wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.hCursor = LoadCursor(NULL,IDC_HAND);//如果第一個(gè)為NULL,使用默認(rèn)的wc.hIcon = LoadIcon(NULL, IDI_ERROR);wc.hInstance = hInstance;//應(yīng)用程序?qū)嵗浔?#xff0c;傳入WinMain中的形參即可wc.lpfnWndProc=WindowProc; //回調(diào)函數(shù),窗口過(guò)程wc.lpszClassName = TEXT("Win");wc.lpszMenuName = NULL;wc.style = 0;//2.注冊(cè)窗口RegisterClass(&wc);//3.創(chuàng)建窗口/*lpClassName,類名lpWindowName,標(biāo)題名dwStyle,WS_OVERLAPPEDWINDOWx, y,顯示坐標(biāo)CW_USEDEFAULTnWidth, nHeight, 寬高h(yuǎn)WndParent, 父窗口 NULLhMenu, 菜單,nullhInstance, 實(shí)例句柄lpParam附加值,鼠標(biāo)附加值 NULL*/HWND hwnd=CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);//4.顯示和更新ShowWindow(hwnd, SW_SHOWNORMAL);//5.通過(guò)循環(huán)區(qū)消息MSG msg;/*HWND hwnd;主窗口UINT message;具體消息名稱WPARAM wParam;附加消息,鍵盤消息LPARAM lParam;附件消息,鼠標(biāo)消息DWORD time;消息產(chǎn)生時(shí)間POINT pt;附加消息,鼠標(biāo)消息,x, y*/while (1){/*_Out_ LPMSG lpMsg,消息_In_opt_ HWND hWnd,捕獲窗口,NULL代表所有窗口_In_ UINT wMsgFilterMin,最小和最大過(guò)濾消息 一般填零_In_ UINT wMsgFilterMax);*/if (GetMessage(&msg, NULL, 0, 0) == FALSE){break;}TranslateMessage(&msg);DispatchMessage(&msg);}return 0; }?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Windows底层窗口的实现———学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux 分隔大文件,linux系统下
- 下一篇: react native loading