一、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 }
二、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 }
三、消息处理函数的简单封装
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 }
运行结果
四、用 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; // 实在费解,程序中哪里引用到了这个全局变量?怎么检测到这个全局变量的?