孙鑫VC++深入详解第一章学习笔记
第一章 Windows程序內部運行機制
1.1 API和SDK
API:Windows操作系統提供給應用程序編程的接口。
SDK(軟件開發包):用于開發的所有資源的集合。
1.2 窗口和句柄
窗口
句柄:系統在創建資源時會為他們分配內存,并返回這些資源的標識號,即句柄。(類似于指針)
窗口句柄(HWND)、圖標(HICON)、光標(HCURSOR)、畫刷(HBRUSH)
1.3 消息和隊列
消息(先進先出)
typedef struct tagMSG {HWND hwnd; //HWND:窗口變量,hwnd:消息所屬的窗口UINT message; //message消息標識符,數值定義為WM_XXX (P4)WPARAM wParam; LPARAM lParam; //指定消息的附加信息,ASCII等DWORD time; //消息投遞到消息隊列中的時間POINT pt; //當前鼠標的位置 } MSG, *PMSG;1.4 WinMain
Win32實現的步驟:
1.4.1 WinMain函數的定義
winmain函數是程序入口函數,由系統調用。
int WINAPI WinMain(HINSTANCE hInstance, // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instance,always NULL in Win32LPSTR lpCmdLine, // 空終止的字符串,指定傳遞給應用程序的命令行參數int nCmdShow // 指定窗口應該如何顯示);1.4.2 窗口的創建
步驟:
1.4.2.1 設計窗口類
typedef struct _WNDCLASS //窗口類 { UINT style; /*(P7知識點方框)窗口樣式;CS_XXX(都只有一位是1,且1位各不相同:位標志);多種特點組合用(|)號;去掉style中的樣式用(&~)*/WNDPROC lpfnWndProc; //指向回調函數的指針;在特定的事件發生時,用于對該事件的響應int cbClsExtra; int cbWndExtra; //cbClsExtra和cbWndExtra兩個附加內存,一般都為0HINSTANCE hInstance; //實例句柄HICON hIcon; //圖標句柄;HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);HCURSOR hCursor; //光標句柄;HCURSOR LoadCursor(HINSTANCE hInstance,LPCTSTR lpCursorName);HBRUSH hbrBackground; //畫刷句柄,背景顏色;wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);LPCTSTR lpszMenuName; //菜單名字,NULLLPCTSTR lpszClassName; //類名,和創建窗口CreateWindow函數中的lpClassName一致 } WNDCLASS, *PWNDCLASS;1.4.2.2 注冊窗口
ATOM RegisterClass( CONST WNDCLASS *lpWndClass ); // 注冊窗口1.4.2.3 創建窗口
HWND CreateWindow( LPCTSTR lpClassName, // registered class name,與窗口類WNDCLASS中的lpszClassName一致LPCTSTR lpWindowName, // window name,DWORD dwStyle, /*window style;和WNDCLASS中的style不同,style是指定具體窗口的樣式,dwstyle是窗口都具有的樣式常用WS_OVERLAPPEDWINDOW*/int x, // horizontal position of windowint y, // vertical position of windowint nWidth, // window widthint nHeight, // window height;/*如果x設為CW_USEDEFAULT,系統為窗口選擇左上角并忽略y;nWidth設為CW_USEDEFAULT,系統為默認大小并忽略nHeight。窗口之間的父子關系,子窗口必須有WS_CHILD*/HWND hWndParent, // handle to parent or owner window(父窗口句柄);NULLHMENU hMenu, // menu handle or child identifier;NULLHINSTANCE hInstance, // handle to application instance;hInstanceLPVOID lpParam // window-creation data;NULL );注意:創建窗口成功,函數返回系統為該窗口分配的句柄,否則返回NULL。創建窗口之前應先定義一個窗口句柄變量來接收創建窗口之后返回的句柄值。
1.4.2.4 顯示及更新窗口
顯示窗口
BOOL ShowWindow(HWND hWnd, // 哪一個窗口?int nCmdShow // 如何顯示?;常用SW_SHOWNORMAL );更新窗口
BOOL UpdateWindow(HWND hWnd // handle to window );1.4.3 消息循環
BOOL GetMessage(LPMSG lpMsg, // 指向一個消息結構體MSG,GetMessage取出的消息放入該結構體對象中HWND hWnd, // handle to window,設為NULL接收所用窗口UINT wMsgFilterMin, // first messageUINT wMsgFilterMax // last message;范圍過濾,獲得所有消息則設為0 );注意:GetMessage函數除了接收到WM_QUIT(退出消息)外都返回非零值,出錯返回-1。
通常編寫的消息循環代碼如下:
MSG msg;//聲明消息結構體變量 while(GetMessage(&msg,NULL,0,0))//沒接收到WM_QUIT時一致循環 {TranslateMessage(&msg);//將WM_KEYDOWN和WM_KEYUP轉化為WM_CHAR,不修改原消息DispatchMessage(&msg);//將消息發送至操作系統,后者用窗口過程函數對消息響應; Dispatch:派遣 }圖1.1 Windows應用程序的消息處理機制
1.4.2窗口創建和1.4.3消息循環都包含在WinMain函數體內
1.4.4 窗口過程函數
即回調函數
LRESULT CALLBACK WindowProc(HWND hwnd, // 窗口句柄UINT uMsg, // 消息代碼WPARAM wParam, // first message parameterLPARAM lParam // second message parameter );如下方例子中的過程函數所示。
例子1.1
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> #include <stdexcept>/*******************函數聲明****************************/ LRESULT CALLBACK WinSunProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter );/*******************WinMain函數*************************/ int WINAPI WinMain(HINSTANCE hInstance, // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state ) {/*設計一個窗口類*/WNDCLASS wndcls;wndcls.cbClsExtra = 0;wndcls.cbWndExtra = 0;wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);wndcls.hInstance = hInstance;wndcls.lpfnWndProc = WinSunProc;wndcls.lpszClassName="sunxin2021";wndcls.lpszMenuName = NULL;wndcls.style = CS_HREDRAW | CS_VREDRAW;RegisterClass(&wndcls);/*創建窗口*/HWND hwnd;hwnd = CreateWindow("sunxin2021", "sx's home.", WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);/*顯示及刷新窗口*/ShowWindow(hwnd, SW_SHOWNORMAL);UpdateWindow(hwnd);/*消息循環*/MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);//將WM_KEYDOWN和WM_KEYUP轉化為WM_CHAR,不修改原消息DispatchMessage(&msg);//將消息發送至操作系統,后者用窗口過程函數對消息響應}return msg.wParam;}/*******************窗口過程函數*************************/ LRESULT CALLBACK WinSunProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter ) {switch (uMsg){case WM_CHAR:char szChar[20];sprintf(szChar, "char code is %d", wParam);MessageBox(hwnd, szChar, "char", 0);break;case WM_LBUTTONDOWN:MessageBox(hwnd, "mouse clicked", "message", 0);HDC hdc; //要在窗口中輸出文字或顯示圖形,要用到設備描述表(DC)。DC是一個包含設備信息的結構體,所有的圖形操作都是利用DC來完成。//定義類型為HDC的變量hdchdc = GetDC(hwnd); //GetDC返回與特定窗口相關聯的DC句柄TextOut(hdc, 0, 50, "sx's home",strlen("sx's home"));ReleaseDC(hwnd, hdc); //在使用完GetDC后一定要注意釋放break;case WM_PAINT://窗口重繪HDC hDC;PAINTSTRUCT ps;hDC = BeginPaint(hwnd, &ps);TextOut(hDC, 0, 0, "http://www.sunxin.org", strlen("http://www.sunxin.org"));EndPaint(hwnd, &ps);//WM_PAINT、BeginPaint、EndPaint一起用,而不能用GetDCbreak;case WM_CLOSE://關閉消息if (IDYES == MessageBox(hwnd, "是否真的結束了?", "message", MB_YESNO)){DestroyWindow(hwnd);//銷毀窗口}break;//此時窗口銷毀,但程序還在后臺運行case WM_DESTROY:PostQuitMessage(0);//在響應消息后,投遞一個退出的消息使用程序安全退出break;default:return DefWindowProc(hwnd, uMsg, wParam, lParam);//調用缺省的消息處理過程函數,對沒有處理的其他消息以默認處理}return 0; }問題反思
1、創建新的項目:vs2019>>Windows桌面應用程序
2、vs2019中如遇到類似cannot convert from ‘const char [7]’ to 'LPCWSTR’的錯誤,請對工程進行字符設置菜單欄-<項目-<xxx 屬性-<配置屬性-<高級-<字符集,改成“not set”或改成“Use Multi-Byte Character Set”。
參考文獻
[1] VC++深入詳解 孫鑫 第一章 Windows程序內部運行機制 - focusahaha - 博客園 (cnblogs.com).https://www.cnblogs.com/focusahaha/p/12601081.html
[2]孫鑫.VC++深度詳解修訂版[M]. 北京:電子工業出版社, 2012. 1-26.
總結
以上是生活随笔為你收集整理的孙鑫VC++深入详解第一章学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mfc编程 孙鑫_孙鑫MFC学习笔记7:
- 下一篇: 直流单臂桥的使用注意事项: