对于基本的windows程序,其架构都有十分相似的地方,所以才会有wizard来自动生成框架,下面的两个框架第一个采用的是基本的方式:WinMain()函数和WndProc()结合;另一种是采用类的方式,利用继承的特性。总的来说一个windows API程序建立的大致过程:程序信息的初始化(如:窗口标题,显示的内容等)——》定义窗口类(WNDCLASS)——》注册窗口类(RegisterClass())——》建立窗口对象(CreateWindow())——》显示窗口(ShowWindow())——》更新窗口(UpdateWindow())——》消息循环——》结束程序。
1、
#ifndef UNICODE
#define UNICODE
#endif
#include
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE ,PWSTR pCmdLine,int nCmdShow)
{
//register the window class
const wchar_t CLASS_NAME[]=L"Sample Window Class";
WNDCLASS wc={ };
wc.lpfnWndProc=WindowProc;
wc.hInstance=hInstance;
wc.lpszClassName=CLASS_NAME;
RegisterClass(&wc);
//create the window
HWND hwnd=CreateWindowEx(
0, //optional window style
CLASS_NAME, //window class
L"Learn to Program Windows", //window class
WS_OVERLAPPEDWINDOW, //window style
//size and position
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL, //parent window
NULL , //menu
hInstance, //instance handle
NULL //additional application data
);
if(hwnd==NULL)
{return 0;}
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//run the message loop
MSG msg={ };
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps);
FillRect(hdc,&ps.rcPaint,(HBRUSH)(COLOR_WINDOW+1));
EndPaint(hwnd,&ps);
}
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
//另一种采用面向对象方法的实现方式
#ifndef UNICODE
#define UNICODE
#endif
#include
// defien the BaseWindow class
template
class BaseWindow
{
public:
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DERIVED_TYPE *pThis = NULL;
if (uMsg == WM_NCCREATE) //WM_NCCREATE 是应用程序状态标识符
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
pThis->m_hwnd = hwnd;
}
else
{
pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (pThis)
{
return pThis->HandleMessage(uMsg, wParam, lParam); //调用类的成员函数HandleMessage()
}
else
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
BaseWindow() : m_hwnd(NULL) { }
BOOL Create(
PCWSTR lpWindowName,
DWORD dwStyle,
DWORD dwExStyle = 0,
int x = CW_USEDEFAULT,
int y = CW_USEDEFAULT,
int nWidth = CW_USEDEFAULT,
int nHeight = CW_USEDEFAULT,
HWND hWndParent = 0,
HMENU hMenu = 0
)
{
WNDCLASS wc = {0};
wc.lpfnWndProc = DERIVED_TYPE::WindowProc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = ClassName();
RegisterClass(&wc);
m_hwnd = CreateWindowEx(
dwExStyle, ClassName(), lpWindowName, dwStyle, x, y,
nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this
);
return (m_hwnd ? TRUE : FALSE);
}
HWND Window() const { return m_hwnd; }
protected:
virtual PCWSTR ClassName() const = 0; //纯虚函数
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0; //纯虚函数
HWND m_hwnd;
};
//define the MainWindow class
class MainWindow : public BaseWindow
{
public:
PCWSTR ClassName() const { return L"Sample Window Class"; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
};
//define the message processed function
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(m_hwnd, &ps);
}
return 0;
default:
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
return TRUE;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
MainWindow win;
if (!win.Create(L"Learn to Program Windows", WS_OVERLAPPEDWINDOW))
{
return 0;
}
ShowWindow(win.Window(), nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}