Windows 程序设计

一、Win32 API

  1 /********************************************************************
  2 created:    2014/04/14 15:30
  3 filename:    WinMain.c
  4 author:        Justme0 (http://blog.csdn.net/justme0)
  5 
  6 purpose:    Win32 API
  7 *********************************************************************/
  8 
  9 #include <windows.h>
 10 #include <string.h>
 11 
 12 WCHAR *strText = L"请单击本窗口用户区";
 13 
 14 /*
 15 ** 某事件发生时,处理该事件对应的消息
 16 */
 17 LRESULT CALLBACK WndProc(
 18     HWND hWindow,
 19     UINT message,
 20     WPARAM wParam,
 21     LPARAM IParam)
 22 {
 23     PAINTSTRUCT ps;
 24     HDC hdc;
 25 
 26     switch (message) {
 27     case WM_LBUTTONDOWN:
 28         strText = L"Hello, world!";
 29         InvalidateRect(hWindow, NULL, 1);
 30         break;
 31 
 32     case WM_PAINT:
 33         hdc = BeginPaint(hWindow, &ps);
 34 
 35         TextOut(hdc, 0, 0, strText, wcslen(strText));
 36         EndPaint(hWindow, &ps);
 37         break;
 38 
 39     case WM_DESTROY:
 40         PostQuitMessage(0);
 41         break;
 42 
 43     default:
 44         return DefWindowProc(hWindow, message, wParam, IParam);
 45     }
 46 
 47     return 0;
 48 }
 49 
 50 /*
 51 ** 注册窗口,该窗口的名字是 wndName
 52 */
 53 ATOM Register(HINSTANCE hInstance, WCHAR *wndName) {
 54     WNDCLASS wnd;
 55     wnd.cbClsExtra = 0;
 56     wnd.cbWndExtra = 0;
 57     wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
 58     wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
 59     wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 60     wnd.hInstance = hInstance;
 61     wnd.lpfnWndProc = WndProc;
 62     wnd.lpszClassName = wndName;
 63     wnd.lpszMenuName = NULL;
 64     wnd.style = 0;
 65 
 66     return RegisterClass(&wnd);
 67 }
 68 
 69 /*
 70 ** 创建窗口,返回窗口句柄
 71 */
 72 HWND Create(HINSTANCE hInstance, WCHAR *lpszClassName) {
 73     return CreateWindow(
 74         lpszClassName,
 75         L"My Window",
 76         WS_OVERLAPPEDWINDOW,
 77         120, 50, 400, 300,
 78         NULL,
 79         NULL,
 80         hInstance,
 81         NULL);
 82 }
 83 
 84 /*
 85 ** 消息循环
 86 */
 87 int Run() {
 88     MSG msg;
 89     while (GetMessage(&msg, NULL, 0, 0)) {
 90         TranslateMessage(&msg);
 91         DispatchMessage(&msg);
 92     }
 93 
 94     return msg.wParam;
 95 }
 96 
 97 int WINAPI WinMain(
 98     HINSTANCE hInstance,
 99     HINSTANCE hPrevInstance,
100     LPSTR lpCmdLine,
101     int nCmdShow)
102 {
103     HWND hWnd = NULL;                        // 窗口句柄
104     WCHAR wndName[] = L"Window_ClassName";    // 窗口名
105 
106     Register(hInstance, wndName);
107     hWnd = Create(hInstance, wndName);
108     ShowWindow(hWnd, nCmdShow);
109     UpdateWindow(hWnd);
110 
111     return Run();
112 }
View Code

二、OO模拟MFC

  1 /********************************************************************
  2     created:    2014/04/14 20:37
  3     filename:    WinMain.cpp
  4     author:        Justme0 (http://blog.csdn.net/justme0)
  5 
  6     purpose:    Windows程序设计,用 OO 模拟 MFC
  7 *********************************************************************/
  8 
  9 #include <Windows.h>
 10 
 11 WCHAR *strText = L"请单击本窗口用户区";
 12 
 13 /*
 14 ** 某事件发生时,处理该事件对应的消息
 15 */
 16 LRESULT CALLBACK WndProc(
 17     HWND hWindow,
 18     UINT message,
 19     WPARAM wParam,
 20     LPARAM IParam)
 21 {
 22     PAINTSTRUCT ps;
 23     HDC hdc;
 24 
 25     switch (message) {
 26     case WM_LBUTTONDOWN:
 27         strText = L"Hello, world!";
 28         InvalidateRect(hWindow, NULL, 1);
 29         break;
 30 
 31     case WM_PAINT:
 32         hdc = BeginPaint(hWindow, &ps);
 33 
 34         TextOut(hdc, 0, 0, strText, wcslen(strText));
 35         EndPaint(hWindow, &ps);
 36         break;
 37 
 38     case WM_DESTROY:
 39         PostQuitMessage(0);
 40         break;
 41 
 42     default:
 43         return DefWindowProc(hWindow, message, wParam, IParam);
 44     }
 45 
 46     return 0;
 47 }
 48 
 49 /*
 50 ** 窗体类
 51 */
 52 class CFrameWnd {
 53 protected:
 54     HWND hWnd;
 55 
 56 public:
 57     CFrameWnd() : hWnd(NULL) {}
 58 
 59     /*
 60     ** 注册窗口,该窗口的名字是 className
 61     */
 62     ATOM Register(HINSTANCE hInstance, WCHAR *className) {
 63         WNDCLASS wnd;
 64         wnd.cbClsExtra = 0;
 65         wnd.cbWndExtra = 0;
 66         wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
 67         wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
 68         wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 69         wnd.hInstance = hInstance;
 70         wnd.lpfnWndProc = WndProc;
 71         wnd.lpszClassName = className;
 72         wnd.lpszMenuName = NULL;
 73         wnd.style = 0;
 74 
 75         return RegisterClass(&wnd);
 76     }
 77 
 78     /*
 79     ** 创建窗口,返回窗口句柄
 80     */
 81     void Create(HINSTANCE hInstance, WCHAR *className, WCHAR *wndName) {
 82         this->hWnd = CreateWindow(
 83             className,
 84             wndName,
 85             WS_OVERLAPPEDWINDOW,
 86             120, 50, 400, 300,
 87             NULL,
 88             NULL,
 89             hInstance,
 90             NULL);
 91     }
 92 
 93     void ShowWindow(int nCmdShow) {
 94         ::ShowWindow(this->hWnd, nCmdShow);
 95     }
 96 
 97     void UpdateWindow() {
 98         ::UpdateWindow(this->hWnd);
 99     }
100 };
101 
102 /*
103 ** `应用程序类
104 */
105 class CWinApp {
106 protected:
107     CFrameWnd * m_pMainWnd;
108 
109 public:
110     CWinApp() : m_pMainWnd(NULL) {}
111 
112     virtual void InitInstance(HINSTANCE hInstance, int nCmdShow) {
113         m_pMainWnd = new CFrameWnd;
114 
115         WCHAR className[] = L"Window_ClassName";    // 窗口类名
116         WCHAR wndName[] = L"我的窗口";                // 窗口名
117         m_pMainWnd->Register(hInstance, className);
118         m_pMainWnd->Create(hInstance, className, wndName);
119         m_pMainWnd->ShowWindow(nCmdShow);
120         m_pMainWnd->UpdateWindow();
121     }
122 
123     /*
124     ** 消息循环
125     */
126     int Run() {
127         MSG msg;
128         while (GetMessage(&msg, NULL, 0, 0)) {
129             TranslateMessage(&msg);
130             DispatchMessage(&msg);
131         }
132 
133         return msg.wParam;
134     }
135 
136     virtual ~CWinApp() {
137         delete m_pMainWnd;
138     }
139 
140 };
141 
142 class CWinAppDerived : public CWinApp {
143 public:
144     void InitInstance(HINSTANCE hInstance, int nCmdShow) {
145         m_pMainWnd = new CFrameWnd;
146 
147         WCHAR className[] = L"Window_ClassName";    // 窗口类名
148         WCHAR wndName[] = L"用新的 InitInstance 函数的程序";    // 窗口名
149         m_pMainWnd->Register(hInstance, className);
150         m_pMainWnd->Create(hInstance, className, wndName);
151         m_pMainWnd->ShowWindow(nCmdShow);
152         m_pMainWnd->UpdateWindow();
153     }
154 };
155 
156 int APIENTRY WinMain(
157     __in HINSTANCE hInstance,
158     __in_opt HINSTANCE hPrevInstance,
159     __in LPSTR lpCmdLine,
160     __in int nShowCmd)
161 {
162     CWinApp myApp;    // 或 CWinAppDerived myApp;
163     myApp.InitInstance(hInstance, nShowCmd);
164 
165     return myApp.Run();
166 }
View Code

三、消息处理函数的简单封装

  1 /********************************************************************
  2 created:    2014/04/14 20:37
  3 filename:    WinMain.cpp
  4 author:        Justme0 (http://blog.csdn.net/justme0)
  5 
  6 purpose:    Windows程序设计,用 OO 模拟 MFC
  7 *********************************************************************/
  8 
  9 #include <Windows.h>
 10 
 11 class CWinApp;
 12 class CWinAppDerived;
 13 CWinApp * AfxGetApp();
 14 LRESULT CALLBACK WndProc(
 15     HWND hWindow,
 16     UINT message,
 17     WPARAM wParam,
 18     LPARAM IParam);
 19 
 20 WCHAR *gText = L"请单击本窗口用户区";
 21 
 22 /*
 23 ** 具有处理消息的类
 24 */
 25 class CCmdTarget {
 26 protected:
 27     HWND hWnd;
 28 
 29 public:
 30     CCmdTarget() : hWnd(NULL) {}
 31 
 32     /*
 33     ** 某事件发生时,处理该事件对应的消息
 34     */
 35     LRESULT CALLBACK AfxWndProc(
 36         HWND hWindow,
 37         UINT message,
 38         WPARAM wParam,
 39         LPARAM IParam)
 40     {
 41         switch (message) {
 42         case WM_LBUTTONDOWN:
 43             this->OnLButtonDown();
 44             break;
 45 
 46         case WM_PAINT: {
 47             PAINTSTRUCT ps;
 48             HDC hdc = BeginPaint(hWindow, &ps);
 49             this->OnDraw(hdc);
 50             EndPaint(hWindow, &ps);
 51             break; }
 52 
 53         case WM_DESTROY:
 54             this->OnDestroy();
 55             break;
 56 
 57         default:
 58             return DefWindowProc(hWindow, message, wParam, IParam);
 59         }
 60 
 61         return 0;
 62     }
 63 
 64     virtual void OnLButtonDown() {}
 65 
 66     virtual void OnDestroy() {
 67         ::PostQuitMessage(0);
 68     }
 69 
 70     void OnDraw(HDC hdc) {
 71         TextOut(hdc, 0, 0, gText, wcslen(gText));
 72     }
 73 };
 74 
 75 /*
 76 ** 窗体类
 77 */
 78 class CFrameWnd : public CCmdTarget {
 79 public:
 80     /*
 81     ** 注册窗口,该窗口的名字是 className
 82     */
 83     ATOM Register(HINSTANCE hInstance, WCHAR *className) {
 84         WNDCLASS wnd;
 85         wnd.cbClsExtra = 0;
 86         wnd.cbWndExtra = 0;
 87         wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
 88         wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
 89         wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 90         wnd.hInstance = hInstance;
 91         wnd.lpfnWndProc = WndProc;
 92         wnd.lpszClassName = className;
 93         wnd.lpszMenuName = NULL;
 94         wnd.style = 0;
 95 
 96         return RegisterClass(&wnd);
 97     }
 98 
 99     /*
100     ** 创建窗口,返回窗口句柄
101     */
102     void Create(HINSTANCE hInstance, WCHAR *className, WCHAR *wndName) {
103         this->hWnd = CreateWindow(
104             className,
105             wndName,
106             WS_OVERLAPPEDWINDOW,
107             120, 50, 400, 300,
108             NULL,
109             NULL,
110             hInstance,
111             NULL);
112     }
113 
114     void ShowWindow(int nCmdShow) {
115         ::ShowWindow(this->hWnd, nCmdShow);
116     }
117 
118     void UpdateWindow() {
119         ::UpdateWindow(this->hWnd);
120     }
121 };
122 
123 class CFrameWndDerived : public CFrameWnd {
124     void OnLButtonDown() {
125         gText = L"重新定义的消息处理";
126         InvalidateRect(this->hWnd, NULL, 1);
127     }
128 };
129 
130 /*
131 ** `应用程序类
132 */
133 class CWinApp {
134 public:
135     CFrameWnd *m_pMainWnd;
136     CWinApp *m_pSelfApp;
137 
138 public:
139     CWinApp() : m_pMainWnd(NULL) {
140         m_pSelfApp = this;    // 不能直接初始化
141     }
142 
143     virtual void InitInstance(HINSTANCE hInstance, int nCmdShow) {
144         m_pMainWnd = new CFrameWnd;
145 
146         WCHAR className[] = L"Window_ClassName";    // 窗口类名
147         WCHAR wndName[] = L"CWinApp窗口";                // 窗口名
148         m_pMainWnd->Register(hInstance, className);
149         m_pMainWnd->Create(hInstance, className, wndName);
150         m_pMainWnd->ShowWindow(nCmdShow);
151         m_pMainWnd->UpdateWindow();
152     }
153 
154     /*
155     ** 消息循环
156     */
157     int Run() {
158         MSG msg;
159         while (GetMessage(&msg, NULL, 0, 0)) {
160             TranslateMessage(&msg);
161             DispatchMessage(&msg);
162         }
163 
164         return msg.wParam;
165     }
166 
167     virtual ~CWinApp() {
168         delete m_pMainWnd;
169     }
170 
171     friend CWinApp * AfxGetApp();
172 };
173 
174 /*
175 ** 派生的窗体类
176 */
177 class CWinAppDerived : public CWinApp {
178 public:
179     void InitInstance(HINSTANCE hInstance, int nCmdShow) {
180         m_pMainWnd = new CFrameWndDerived;
181 
182         WCHAR className[] = L"Window_ClassName";    // 窗口类名
183         WCHAR wndName[] = L"CWinAppDerived窗口";    // 窗口名
184         m_pMainWnd->Register(hInstance, className);
185         m_pMainWnd->Create(hInstance, className, wndName);
186         m_pMainWnd->ShowWindow(nCmdShow);
187         m_pMainWnd->UpdateWindow();
188     }
189 };
190 
191 LRESULT CALLBACK WndProc(
192     HWND hWindow,
193     UINT message,
194     WPARAM wParam,
195     LPARAM IParam)
196 {
197     CWinApp * pApp = AfxGetApp();
198     return pApp->m_pMainWnd->AfxWndProc(hWindow, message, wParam, IParam);
199 }
200 
201 CWinAppDerived g_myAppDerived;
202 
203 CWinApp * AfxGetApp() {
204     return g_myAppDerived.m_pSelfApp;
205 }
206 
207 int APIENTRY WinMain(
208     __in HINSTANCE hInstance,
209     __in_opt HINSTANCE hPrevInstance,
210     __in LPSTR lpCmdLine,
211     __in int nShowCmd)
212 {
213     CWinApp *pCWinApp = AfxGetApp();
214     pCWinApp->InitInstance(hInstance, nShowCmd);
215 
216     return pCWinApp->Run();
217 }
View Code

运行结果

 四、用 MFC 设计的含有消息映射的 Windows 应用程序

 1 /********************************************************************
 2 created:    2014/04/16 22:08
 3 filename:    WinMain.cpp
 4 author:        Justme0 (http://blog.csdn.net/justme0)
 5 
 6 purpose:    用 MFC 设计的含有消息映射的 Windows 应用程序
 7 
 8 注:在“项目设置”中选择使用 MFC 类库(动态、静态皆可)
 9 *********************************************************************/
10 
11 #define _WIN32_WINNT 0x0502
12 
13 #include <afxwin.h>
14 
15 class CFrameWndDerived : public CFrameWnd {
16 private:
17     WCHAR *showText;
18 
19 public:
20     CFrameWndDerived() : showText(L"初始化的字符串") {}
21 
22     afx_msg void OnPaint() {
23         CPaintDC dc(this);
24         dc.TextOut(20, 20, showText);
25     }
26 
27     afx_msg void OnLButtonDown(UINT, CPoint) {    // 这个参数表针对 VS 编译器
28         showText = L"有消息映射表的程序";
29         InvalidateRect(NULL, TRUE);
30     }
31 
32     DECLARE_MESSAGE_MAP();
33 };
34 
35 BEGIN_MESSAGE_MAP(CFrameWndDerived, CFrameWnd)
36     ON_WM_PAINT()
37     ON_WM_LBUTTONDOWN()
38 END_MESSAGE_MAP()
39 
40 /*
41 ** 派生的窗体类
42 */
43 class CWinAppDerived : public CWinApp {
44 public:
45     BOOL InitInstance() {
46         CFrameWndDerived *pMainWndDerived = new CFrameWndDerived;
47         pMainWndDerived->Create(NULL, L"MFC");
48         pMainWndDerived->ShowWindow(m_nCmdShow);
49         pMainWndDerived->UpdateWindow();
50         m_pMainWnd = pMainWndDerived;
51 
52         return TRUE;
53     }
54 };
55 
56 CWinAppDerived MyApp;    // 实在费解,程序中哪里引用到了这个全局变量?怎么检测到这个全局变量的?
View Code

原文地址:https://www.cnblogs.com/jjtx/p/3664256.html