/// @file exam_1.cpp
/// @brief 查阅本地MSDN, 手工写SDK程序
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
void ShowErrMsg();
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
) {
/// 设计,注册窗口类
ATOM _atom;
WNDCLASS WndClass = {0};
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = &WindowProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = NULL;
WndClass.hCursor = NULL /*LoadCursor(NULL, IDC_ARROW)*/;
WndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _T("test class");///< 不能为空
_atom = RegisterClass(&WndClass);
if (0 == _atom) {
ShowErrMsg();
goto WINMAIN_END;
}
/// 创建, 显示窗口
HWND hWnd;
hWnd = CreateWindow(
_T("test class"), // pointer to registered class name
_T("test class window"), // pointer to window name
WS_OVERLAPPEDWINDOW, // window style
100, // horizontal position of window
100, // vertical position of window
800, // window width
600, // window height
NULL, // handle to parent or owner window
NULL, // handle to menu or child-window identifier
hInstance, // handle to application instance
NULL // pointer to window-creation data
);
if (NULL == hWnd) {
ShowErrMsg();
goto WINMAIN_END;
}
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
/// 消息循环
MSG msg;
while (GetMessage(
&msg, // address of structure with message
hWnd, // handle of window
0, // first message
0 // last message
)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
WINMAIN_END:
return 0;
}
/**
WM_XXX
键盘,鼠标,绘制消息
WM_COMMAND
菜单,快捷键消息
快捷键消息和键盘消息不同。
键盘消息是一个一个的按键
快捷键消息是组合键.
WM_NOTIFY
子窗口的消息
*/
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
) {
switch (uMsg) {
case WM_CLOSE:
if (IDYES == MessageBox(hwnd, _T("是否退出?"), _T("提示"), MB_YESNO)) {
// WM_QUIT使GetMessage为FALSE, 跳出消息循环的处理
PostMessage(hwnd, WM_QUIT, 0, 0);
}
break;
default:
/// The DefWindowProc function calls the default window procedure
/// to provide default processing for any window messages
/// that an application does not process.
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
/// 除了 DefWindowProc的处理, 其它都应该返回 FALSE
/// 否则UI上点击按钮无反应, 鼠标拖动时, UI也移动不了
return FALSE;
}
void ShowErrMsg() {
LPVOID lpMsgBuf = NULL;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL);
MessageBox(NULL, (LPCTSTR)lpMsgBuf, _T("Error"), MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
}
<p>
</p>
WM_QUIT执行的时机
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
) {
BOOL bCallDefault = FALSE;
switch (uMsg) {
case WM_CLOSE:
/// 只能在WM_CLOSE处发WM_QUIT消息
/// WM_DESTROY处发WM_QUIT消息晚了
/// 发出了WM_QUIT后, 不能再调用DefWindowProc
PostMessage(hwnd, WM_QUIT, 0, 0);
break;
default:
bCallDefault = TRUE;
break;
};
return bCallDefault ? DefWindowProc(hwnd, uMsg, wParam, lParam) : 0;
}