Windos程式設計,獲取視窗的尺寸
阿新 • • 發佈:2020-04-13
前言
學習小甲魚的畫\(sin\)函式的例子,發現最開始建立視窗時cxClient和cyClient不能很好的賦值
WM_SIZE和WM_PAINT
經過我的實踐發現:在剛剛建立視窗時WM_SIZE和WM_PAINT訊息的呼叫順序是隨機的,而且大部分時候先是WM_PAINT
如果cxClient和cyClient需要經過WM_SIZE來初始化,並且WM_PAINT訊息處理中需要使用這兩個變數,那麼第一次的WM_PAINT可能會不正常
這個時候可以選擇手動調整一下視窗的大小,但是使用者體驗肯定是很差的
一種解決方案
由於WM_CREATE訊息肯定優先於WM_PAINT處理,那麼我們可以在處理WM_CREAT時初始化cxClient和cyClient
利用GetClientRect獲取當前的矩形結構
case WM_CREATE:
GetClientRect(hwnd,&rect);
cxClient = rect.right-rect.left ;
cyClient = rect.bottom- rect.top ;
return 0;
畫\(sin\)函式程式碼
/* ------------------------------------------------------------------- MyWindows.c -- 基本視窗模型 《Windows 程式設計(SDK)》視訊教程 --------------------------------------------------------------------*/ #include <Windows.h> #include <tchar.h> #include <math.h> LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { static TCHAR szAppName[] = TEXT("MyWindows"); HWND hwnd;//視窗控制代碼 MSG msg;//訊息結構 WNDCLASS wndclass;//視窗類結構 wndclass.style = CS_HREDRAW | CS_VREDRAW;//視窗型別 wndclass.lpfnWndProc = WndProc;//指定視窗過程 wndclass.cbClsExtra = 0;//預留的額外空間 wndclass.cbWndExtra = 0;//預留的額外空間 wndclass.hInstance = hInstance;//應用程式的例項控制代碼 wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);//為所有基於該視窗類的視窗設定一個圖示 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);//為所有基於該視窗類的視窗設定一個滑鼠指標 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);// 指定視窗背景色 wndclass.lpszMenuName = NULL;// 指定視窗選單 wndclass.lpszClassName = szAppName;//指定視窗類名 if (!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("這個程式需要在 Windows NT 才能執行!"),szAppName,MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName,//類名 TEXT("魚C工作室"),//標題 WS_OVERLAPPEDWINDOW,//風格 CW_USEDEFAULT,//初始x座標 CW_USEDEFAULT,//初始y座標 CW_USEDEFAULT,//初始寬度 CW_USEDEFAULT,//初始高度 NULL,//父視窗控制代碼 NULL,//視窗選單控制代碼 hInstance,//程式例項控制代碼 NULL);//建立引數 ShowWindow(hwnd,iCmdShow);//顯示視窗 UpdateWindow(hwnd); while (GetMessage(&msg,NULL,0))//訊息迴圈 { TranslateMessage(&msg);//翻譯一些鍵盤訊息 DispatchMessage(&msg);//將訊息傳送給視窗過程 } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static int cxClient,cyClient; HDC hdc;//裝置環境控制代碼 PAINTSTRUCT ps;//繪製結構 RECT rect;//矩形結構 //int stx = 0,sty =0; POINT apt[1000]; int num = 1000; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0; case WM_CREATE: GetClientRect(hwnd,&rect); cxClient = rect.right-rect.left ; cyClient = rect.bottom- rect.top ; return 0; case WM_PAINT: hdc = BeginPaint(hwnd,&ps);//獲得裝置控制代碼 LineTo(hdc,cxClient,cyClient); for (int i = 0; i < num; i++) { apt[i].x = i * cxClient / num; apt[i].y = (long)(cyClient / 2 * sin(i * 3.1415926 * 2.0 / num)) + cyClient / 2; } Polyline(hdc,apt,num); EndPaint(hwnd,&ps);// 函式標記指定視窗的繪畫過程結束 return 0; case WM_DESTROY://視窗關閉 PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam);//交給windows去處理 }