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