关于纯win32程序(only use win32api, not use mfc, atl, wtl and other framework), 有很多这样的demo.
vsIDE提供的向导可以生成win32程序(带主窗体的那种), 如果我们要从头搭一个Dialog程序。一般也就是找个demo, 从头来一次。
以前也有过这样的想法,怎么搭一个简单实用的纯win32 Dialg程序,做为测试用呢?
现在找到了一篇关于这个专题的好文章A dialog based Win32 C program, step by step, 讲的非常棒~
#include <windows.h> /** * include tchar.h for LNK2019 * MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol * _WinMain@16 referenced in function ___tmainCRTStartup */ #include <tchar.h> #include "resource.h" #include <commctrl.h> /**< for InitCommonControls */ #pragma comment(lib, "ComCtl32.lib") #define G_NAME_PROG _T("PureWin32Frame") /**< 程序名称 */ //typedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM); INT_PTR WINAPI DialogFunc(HWND hWnd, UINT uMsg, WPARAM wparam, LPARAM lparam); INT_PTR WINAPI MsgProcess_WmCommand(HWND hWnd, UINT uMsg, WPARAM wparam, LPARAM lparam); BOOL WINAPI MyCenterWindow(HWND hWnd); BOOL WINAPI ShowMsgByYesNo(HWND hWnd, TCHAR *pcInfo, TCHAR *pcTitle); /** _tWinMain 的定义, 从 C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\ * src\mfc\appmodul.cpp 中抄出来的, 由 Visual Assist X 提示找到的 */ INT WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, __in TCHAR * lpCmdLine, INT nCmdShow) { HWND hWnd = NULL; DLGPROC lpDlgProc = DialogFunc; BOOL bRc = TRUE; INT iRc = 0; MSG msg; __try { InitCommonControls(); hWnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, lpDlgProc, NULL); if (!MyCenterWindow(hWnd)) { __leave; } ShowWindow(hWnd, SW_SHOW); while ((bRc = GetMessage(&msg, 0, 0, 0)) != 0) { if (!bRc) __leave; if (!IsDialogMessage(hWnd, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } __finally { iRc = bRc ? 0 : - 1; } return iRc; } INT_PTR WINAPI DialogFunc(HWND hWnd, UINT uMsg, WPARAM wparam, LPARAM lparam) { INT_PTR iRc = TRUE; switch (uMsg) { case WM_COMMAND: { iRc = MsgProcess_WmCommand(hWnd, uMsg, wparam, lparam); } break; case WM_CLOSE: { if (ShowMsgByYesNo(hWnd, _T("确定退出程序么?"), G_NAME_PROG)) { DestroyWindow(hWnd); } } break; case WM_DESTROY: { PostQuitMessage(0); } break; /** * 其他消息处理, 参照有向导的工程往工程里加, * 按照实际需要补齐代码后, 作为测试还是很方便 */ default: { iRc = FALSE; /**< let windows process it */ } break; } return iRc; } INT_PTR WINAPI MsgProcess_WmCommand(HWND hWnd, UINT uMsg, WPARAM wparam, LPARAM lparam) { INT_PTR iRc = TRUE; switch (wparam) { case IDOK: { ::PostMessage(hWnd, WM_CLOSE, 0, 0); } default: { iRc = FALSE; /**< let windows process it */ } break; } return iRc; } BOOL WINAPI ShowMsgByYesNo(HWND hWnd, TCHAR *pcInfo, TCHAR *pcTitle) { INT iRc = IDYES; iRc = ::MessageBox(hWnd, pcInfo, pcTitle, MB_YESNO | MB_ICONINFORMATION); return (IDYES == iRc) ? TRUE : FALSE; } BOOL WINAPI MyCenterWindow(HWND hWnd) { BOOL bRc = TRUE; HWND hWndParent = NULL; RECT rcParent; RECT rcMe; __try { hWndParent = ::GetDesktopWindow(); if(!::GetWindowRect(hWndParent, &rcParent)) { bRc = FALSE; __leave; } if(!::GetWindowRect(hWnd, &rcMe)) { bRc = FALSE; __leave; } ::MoveWindow( hWnd, ((rcParent.right - rcParent.left) - (rcMe.right - rcMe.left)) / 2, ((rcParent.bottom - rcParent.top) - (rcMe.bottom - rcMe.top)) / 2, rcMe.right - rcMe.left, rcMe.bottom - rcMe.top, TRUE); } __finally { } return bRc; }