ATL布幔之下的秘密(5)
2006-07-22 22:54:48 来源:WEB开发网程序69. #include <windows.h>
那么,我们终于有了这个可以工作的程序。现在,让我们来利用面向对象程序设计。如果我们对于每个消息都调用函数,并且使这些函数都成为虚函数的话,那么我们就可以在继承ZWindow类之后调用这些函数了。所以,我们可以自定义ZWindow的默认行为。现在,WndProc是类似这个样子:
class ZWindow;
ZWindow* g_pWnd = NULL;
class ZWindow
{
public:
HWND m_hWnd;
ZWindow(HWND hWnd = 0) : m_hWnd(hWnd) { }
inline void Attach(HWND hWnd)
{ m_hWnd = hWnd; }
inline BOOL ShowWindow(int nCmdShow)
{ return ::ShowWindow(m_hWnd, nCmdShow); }
inline BOOL UpdateWindow()
{ return ::UpdateWindow(m_hWnd); }
inline HDC BeginPaint(LPPAINTSTRUCT ps)
{ return ::BeginPaint(m_hWnd, ps); }
inline BOOL EndPaint(LPPAINTSTRUCT ps)
{ return ::EndPaint(m_hWnd, ps); }
inline BOOL GetClientRect(LPRECT rect)
{ return ::GetClientRect(m_hWnd, rect); }
BOOL Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance,
HWND hWndParent = 0, DWORD dwStyle = WS_OVERLAPPEDWINDOW,
DWORD dwExStyle = 0, HMENU hMenu = 0)
{
m_hWnd = ::CreateWindowEx(dwExStyle, szClassName, szTitle, dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, hWndParent, hMenu, hInstance, NULL);
return m_hWnd != NULL;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ZWindow* pThis = g_pWnd;
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)
{
case WM_PAINT:
hDC = pThis->BeginPaint(&ps);
pThis->GetClientRect(&rect);
::DrawText(hDC, "Hello world", -1, &rect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
pThis->EndPaint(&ps);
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
char szAppName[] = "Hello world";
MSG msg;
WNDCLASS wnd;
ZWindow zwnd;
wnd.cbClsExtra = NULL;
wnd.cbWndExtra = NULL;
wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd.hInstance = hInstance;
wnd.lpfnWndProc = zwnd.WndProc;
wnd.lpszClassName = szAppName;
wnd.lpszMenuName = NULL;
wnd.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&wnd))
{
MessageBox(NULL, "Can not register window class", "Error",
MB_OK | MB_ICONINFORMATION);
return -1;
}
g_pWnd = &zwnd;
zwnd.Create(szAppName, "Hell world", hInstance);
zwnd.ShowWindow(nCmdShow);
zwnd.UpdateWindow();
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}
return msg.wParam;
}static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
在这里,OnCreate和OnPaint是虚函数。并且,当我们从ZWindow继承一个类的时候,我们就可以重写所有我们想自定义的这些函数。下面是一个完整的程序,它示范了在派生类中WM_PAINT消息的使用。
LPARAM lParam)
{
ZWindow* pThis = g_pWnd;
switch (uMsg)
{
case WM_CREATE:
pThis->OnCreate(wParam, lParam);
break;
case WM_PAINT:
pThis->OnPaint(wParam, lParam);
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
更多精彩
赞助商链接