SDK Hello world(直接使用SDK封装)
前言
将代码拆分了一下, 如果处理更多的消息也不怕看的眼花
SDK编程就是对各种Windows消息的处理
实验工程
- /// @file exam_1.cpp
- /// @brief 查阅本地MSDN, 手工写SDK程序
- #include "common.h"
- #include "ErrorProc.h"
- #include "WindowProc.h"
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow) {
- if (!fnRegisterClass(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) {
- ShowErrMsg();
- goto WINMAIN_END;
- }
- if (!fnCreateWindow(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) {
- ShowErrMsg();
- goto WINMAIN_END;
- }
- MsgLoop();
- WINMAIN_END:
- return 0;
- }
- /// @file common.h
- /// @brief 公用头文件
- #ifndef COMMON_H_2016_0128
- #define COMMON_H_2016_0128
- #define _WIN32_WINDOWS 0x500
- #include <windows.h>
- #include <tchar.h>
- #include <stdlib.h>
- #include <stdio.h>
- #endif // #ifndef COMMON_H_2016_0128
- /// @file ErrorProc.h
- /// @brief 错误处理
- #ifndef ERRORPROC_H_2016_0128
- #define ERRORPROC_H_2016_0128
- const TCHAR* StringFormatV(TCHAR* szFormat, ...);
- void ShowMsg(const TCHAR* pcMsg);
- void ShowErrMsg();
- BOOL isQuitProg(HWND hWnd);
- #endif // #ifndef ERRORPROC_H_2016_0128
- /// @file WindowProc.h
- /// @brief 消息处理
- /// 消息处理函数命名规范
- /// OnX On说明是Windows消息处理函数
- /// X是消息 WM_X 去掉 WM_ 之后,按照将X按照匈牙利写法拼在On后面
- /// e.g. WM_CLOSE消息处理函数为OnClose
- #ifndef WINDOWPROC_H_2016_0128
- #define WINDOWPROC_H_2016_0128
- #include "common.h"
- BOOL fnRegisterClass(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
- BOOL fnCreateWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
- void MsgLoop();
- HWND getMainWnd();
- HINSTANCE getInstance();
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- LONG fnDispatchMessage(CONST MSG* lpMsg);
- BOOL OnKeyDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnSysDeadChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnSysChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnSysKeyDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnSysKeyUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouse(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseMove(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseWheel(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseLButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseLButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseLButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseRButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseRButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseRButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseMButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseMButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnMouseMButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnClose(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- BOOL OnDestory(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- #endif // #ifndef WINDOWPROC_H_2016_0128
- /// @file common.cpp
- /// @brief 公用头文件对应的实现
- #include "common.h"
- /// @file ErrorProc.cpp
- /// @brief 错误处理实现
- #include "common.h"
- #include "ErrorProc.h"
- #include "WindowProc.h"
- BOOL isQuitProg(HWND hWnd) {
- BOOL bRc = FALSE;
- if (IDYES == MessageBox(hWnd, _T("是否退出?"), _T("提示"), MB_YESNO)) {
- bRc = TRUE;
- }
- return bRc; ///< true is quit prog
- }
- 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(getMainWnd(), (LPCTSTR)lpMsgBuf, _T("Error"), MB_OK | MB_ICONINFORMATION);
- LocalFree(lpMsgBuf);
- }
- const TCHAR* StringFormatV(TCHAR* szFormat, ...)
- {
- /// 在栈空间上拼字符串, 如果new的话, 容易引起内存碎片
- /// 运行的次数多了,有可能分配不出内存来
- static TCHAR s_cBuf[4096] = {'\0'}; ///< _vsntprintf做了处理, 最多就是打印不全
- int iStringLen = 0;
- va_list args;
- va_start(args, szFormat);
- iStringLen = _vsntprintf(s_cBuf, (sizeof(s_cBuf) / sizeof(TCHAR)) - 1, szFormat, args);
- va_end(args);
- return s_cBuf;
- }
- void ShowMsg(const TCHAR* pcMsg) {
- if (NULL != pcMsg) {
- OutputDebugString(pcMsg);
- }
- }
- /// @file WindowProc.cpp
- /// @brief Windows消息处理的实现
- #include "WindowProc.h"
- #include "ErrorProc.h"
- static HWND g_hWnd = NULL;
- static HINSTANCE g_hInstance = NULL;
- HWND getMainWnd() {
- return g_hWnd;
- }
- HINSTANCE getInstance() {
- return g_hInstance;
- }
- BOOL fnRegisterClass(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- /// 设计,注册窗口类
- BOOL bRc = TRUE;
- ATOM _atom;
- WNDCLASS WndClass = {0};
- // 拥有了经典样式 CS_DBLCLKS, 才会响应双击操作
- WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
- 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) {
- bRc = FALSE;
- }
- g_hInstance = hInstance;
- return bRc;
- }
- BOOL fnCreateWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- /// 创建, 显示窗口
- BOOL bRc = TRUE;
- g_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 == g_hWnd) {
- bRc = FALSE;
- goto FNCREATEWINDOW_END;
- }
- ShowMsg(StringFormatV(_T("g_hWnd = 0x%X\n"), g_hWnd));
- ShowWindow(g_hWnd, SW_SHOWNORMAL);
- UpdateWindow(g_hWnd);
- FNCREATEWINDOW_END:
- return bRc;
- }
- void MsgLoop() {
- /// 消息循环
- MSG msg;
- // GetMessage参数2必须是NULL, 如果是g_hWnd, 会在WM_NCDESTROY后,
- // msg子项内容都全变成0, 变成一个死循环
- // 如果第2个参数为NULL, 会接收本进程所有窗口(线程)的消息
- ShowMsg(_T(">> MsgLoop()\n"));
- while (GetMessage(
- &msg, // address of structure with message
- NULL, // handle of window
- 0, // first message
- 0 // last message
- )) {
- TranslateMessage(&msg); ///< 键盘消息到字符消息(多投递一个WM_CHAR消息)
- fnDispatchMessage(&msg); ///< DispatchMessage不是必须的,我们也可以自己实现
- }
- ShowMsg(_T("<< MsgLoop()\n"));
- }
- LONG fnDispatchMessage(CONST MSG* lpMsg) {
- long lRc = 0;
- int iLen = 0;
- TCHAR cBuf[MAXBYTE] = {_T('\0')};
- WNDCLASS WndClass = {0};
- if (NULL == lpMsg)
- goto FNDISPATCHMESSAGE_END;
- iLen = GetClassName(lpMsg->hwnd, cBuf, sizeof(cBuf)/sizeof(TCHAR));
- if (iLen <= 0)
- goto FNDISPATCHMESSAGE_END;
- if (!GetClassInfo(getInstance(), cBuf, &WndClass))
- goto FNDISPATCHMESSAGE_END;
- if (NULL == WndClass.lpfnWndProc)
- goto FNDISPATCHMESSAGE_END;
- lRc = WndClass.lpfnWndProc(lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
- FNDISPATCHMESSAGE_END:
- return lRc;
- }
- /**
- WM_XXX
- 键盘,鼠标,绘制消息
- WM_COMMAND
- 菜单,快捷键消息
- 快捷键消息和键盘消息不同。
- 键盘消息是一个一个的按键
- 快捷键消息是组合键.
- WM_NOTIFY
- 子窗口的消息
- */
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- BOOL bCallDefWindowProc = TRUE;
- LRESULT lRc = 0;
- ShowMsg(StringFormatV(_T("uMsg = 0x%X\n"), uMsg));
- /// 编码规范, 必须单独封装处理消息的函数OnMsg,
- /// 不允许在WindowProc中写具体的消息处理实现
- switch (uMsg) {
- case WM_KEYDOWN:
- bCallDefWindowProc = OnKeyDown(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_CHAR:
- bCallDefWindowProc = OnChar(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_SYSDEADCHAR:
- bCallDefWindowProc = OnSysDeadChar(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_SYSCHAR:
- bCallDefWindowProc = OnSysChar(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_SYSKEYDOWN:
- bCallDefWindowProc = OnSysKeyDown(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_SYSKEYUP:
- bCallDefWindowProc = OnSysKeyUp(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_MOUSEMOVE:
- case WM_MOUSEWHEEL:
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_LBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- case WM_MBUTTONDBLCLK:
- bCallDefWindowProc = OnMouse(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_CLOSE:
- bCallDefWindowProc = OnClose(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_DESTROY:
- bCallDefWindowProc = OnDestory(lRc, hwnd, uMsg, wParam, lParam);
- break;
- default:
- break;
- }
- /// The DefWindowProc function calls the default window procedure
- /// to provide default processing for any window messages
- /// that an application does not process.
- return bCallDefWindowProc ? DefWindowProc(hwnd, uMsg, wParam, lParam) : lRc;
- }
- BOOL OnKeyDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- /// 如果不调用 TranslateMessage, 可以自己取按键值
- /// 如果调用了 TranslateMessage, 在OnChar中直接取键值
- ShowMsg(_T("OnKeyDown\n"));
- int nVirtKey = (int) wParam; // virtual-key code
- ULONG ulKeyData = lParam; // key data
- BYTE ucKeyState[256] = {0};
- WORD wChar = 0;
- int iRc = 0;
- /**
- lKeyData
- Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table. Value Description
- 0–15 Specifies the repeat count for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
- 16–23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
- 24 Specifies whether the key is an extended key, such as the right-hand alt and ctrl keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
- 25–28 Reserved; do not use.
- 29 Specifies the context code. The value is always 0 for a WM_KEYDOWN message.
- 30 Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
- 31 Specifies the transition state. The value is always 0 for a WM_KEYDOWN message.
- */
- if (!GetKeyboardState(&ucKeyState[0])) {
- goto ONKEYDOWN_END;
- }
- if (ToAscii(nVirtKey, (ulKeyData >> 16) & 0xff, ucKeyState, &wChar, 0) <= 0) {
- goto ONKEYDOWN_END;
- }
- ShowMsg(StringFormatV(_T("%c "), (TCHAR)wChar));
- ONKEYDOWN_END:
- lRc = 0;
- return TRUE;
- }
- BOOL OnChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- ShowMsg(StringFormatV(_T("%c "), (TCHAR)wParam));
- lRc = 0;
- return TRUE;
- }
- BOOL OnSysDeadChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnSysChar(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnSysKeyDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- /// F10 press down
- lRc = 0;
- return TRUE;
- }
- BOOL OnSysKeyUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- /// F10 press up
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouse(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- BOOL bRc = FALSE;
- // POINTS pt;
- // UINT uMK = 0; // key flags
- // WORD xPos = 0; // horizontal position of cursor
- // WORD yPos = 0; // vertical position of cursor
- if ((uMsg < WM_MOUSEFIRST) || (uMsg > WM_MOUSELAST))
- goto ONMOUSE_END;
- /**
- * Key State Masks for Mouse Messages
- #define MK_LBUTTON 0x0001
- #define MK_RBUTTON 0x0002
- #define MK_SHIFT 0x0004
- #define MK_CONTROL 0x0008
- #define MK_MBUTTON 0x0010
- */
- // uMK = wParam;
- // xPos = LOWORD(lParam);
- // yPos = HIWORD(lParam);
- // pt = MAKEPOINTS(lParam);
- switch (uMsg) {
- // 移动
- case WM_MOUSEMOVE:
- bRc = OnMouseMove(lRc, hwnd, uMsg, wParam, lParam);
- break;
- // 滑过
- case WM_MOUSEWHEEL:
- bRc = OnMouseWheel(lRc, hwnd, uMsg, wParam, lParam);
- break;
- // 左键
- case WM_LBUTTONDOWN:
- bRc = OnMouseLButtonDown(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_LBUTTONUP:
- bRc = OnMouseLButtonUp(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_LBUTTONDBLCLK:
- bRc = OnMouseLButtonDblClk(lRc, hwnd, uMsg, wParam, lParam);
- break;
- // 右键
- case WM_RBUTTONDOWN:
- bRc = OnMouseRButtonDown(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_RBUTTONUP:
- bRc = OnMouseRButtonUp(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_RBUTTONDBLCLK:
- bRc = OnMouseRButtonDblClk(lRc, hwnd, uMsg, wParam, lParam);
- break;
- // 中键
- case WM_MBUTTONDOWN:
- bRc = OnMouseMButtonDown(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_MBUTTONUP:
- bRc = OnMouseMButtonUp(lRc, hwnd, uMsg, wParam, lParam);
- break;
- case WM_MBUTTONDBLCLK:
- bRc = OnMouseMButtonDblClk(lRc, hwnd, uMsg, wParam, lParam);
- break;
- default:
- break;
- }
- ONMOUSE_END:
- lRc = 0;
- return bRc; ///< bCallDefWindowProc
- }
- BOOL OnMouseMove(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseWheel(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseLButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- ShowMsg(StringFormatV(_T("OnMouseLButtonDown, hwnd = 0x%X\n"), hwnd));
- // MessageBox(hwnd, _T("OnMouseLButtonDown"), _T("SDK Frame"), MB_OK);
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseLButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- ShowMsg(StringFormatV(_T("OnMouseLButtonUp, hwnd = 0x%X\n"), hwnd));
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseLButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- ShowMsg(_T("OnMouseLButtonDblClk\n"));
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseRButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseRButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseRButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseMButtonDown(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseMButtonUp(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnMouseMButtonDblClk(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return TRUE;
- }
- BOOL OnClose(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- return isQuitProg(hwnd); ///< bCallDefWindowProc
- }
- BOOL OnDestory(OUT LRESULT& lRc, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- lRc = 0;
- // WM_QUIT使GetMessage为FALSE, 跳出消息循环的处理
- // PostMessage(hwnd, WM_QUIT, 0, 0); ///< ok
- PostQuitMessage(0); ///< 也会发送WM_QUIT消息
- return TRUE; ///< bCallDefWindowProc
- }
http://blog.csdn.net/lostspeed/article/details/50606215
http://blog.csdn.net/lostspeed/article/details/50614423