回复 36楼 有容就大
不建议你在不了解C++的情况,就去看MFC的源代码,要想知道手工封装Win32窗口,我们完全可以自己干。
这是一个最简单的窗口封装类:
win.h
#pragma once
class KWindow
{
private:
virtual void OnDraw(HDC hdc){}
virtual void OnKeyDown(WPARAM wParam, LPARAM lParam){}
virtual LRESULT WndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
virtual void GetwndClassEx(WNDCLASSEX &wc);
public:
HWND m_hwnd;
KWindow(void)
{
m_hwnd = NULL;
}
virtual ~KWindow(void){}
virtual bool CreateEx(DWORD dwExStyle, LPCTSTR lpszClass, LPCTSTR lpszName,
DWORD dwStyle, int x, int y , int nWidth, int hHeigth, HWND hParent,
HMENU hMenu, HINSTANCE hInst);
bool RegisterClass(LPCTSTR lpszclas, HINSTANCE hInst);
virtual WPARAM MessageLoop(void);
BOOL ShowWindow(int nCmdShow) const
{
return ::ShowWindow(m_hwnd, nCmdShow);
}
BOOL UpdateWindow(void) const
{
return ::UpdateWindow(m_hwnd);
}
};
win.cpp 实现文件
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include "win.h"
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYDOWN:
OnKeyDown(wParam, lParam);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, &ps);
OnDraw(ps.hdc);
EndPaint(hWnd, &ps);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
KWindow * pWindow;
if(uMsg == WM_NCCREATE)
{
assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
MDICREATESTRUCT *pMDIC = (MDICREATESTRUCT *)
((LPCREATESTRUCT) lParam)->lpCreateParams;
pWindow = (KWindow *) (pMDIC->lParam);
assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
}
else
pWindow = (KWindow *) GetWindowLong(hWnd, GWL_USERDATA);
if ( pWindow )
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
else
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
bool KWindow::RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst)
{
WNDCLASSEX wc;
if( !GetClassInfoEx(hInst, lpszClass, &wc) )
{
GetwndClassEx(wc);
wc.hInstance = hInst;
wc.lpszClassName = lpszClass;
if( !RegisterClassEx(&wc) )
return false;
}
return true;
}
bool KWindow::CreateEx(DWORD dwExStyle, LPCTSTR lpszClass,
LPCTSTR lpszName, DWORD dwStyle,
int x, int y, int nWidth, int hHeight,
HWND hParent, HMENU hMenu, HINSTANCE hInst)
{
if(! RegisterClass(lpszClass, hInst) )
return false;
// use MDICREATESTRUCT to pass this pointer, support MDI child window
MDICREATESTRUCT mdic;
memset(&mdic, 0, sizeof(mdic));
mdic.lParam = (LPARAM) this;
m_hwnd = CreateWindowEx(dwExStyle, lpszClass, lpszName, dwStyle,
x, y, nWidth, hHeight, hParent, hMenu, hInst, &mdic);
return m_hwnd != NULL;
}
void KWindow::GetwndClassEx(WNDCLASSEX & wc)
{
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszMenuName = NULL;
wc.hIconSm = NULL;
}
WPARAM KWindow::MessageLoop(void)
{
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
-----------------------------------------------------------------------
主程序:
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include "win.h"
const TCHAR szMessage[] = _T("Hello, world!");
const TCHAR szFace[] = _T("Times New Roman");
const TCHAR szHint[] = _T("Press ESC to Quit");
const TCHAR szProgram[] = _T("HelloWorld3");
//copy centerText from Hello2.cpp
void CenterText(HDC hdc, int x, int y, LPCTSTR szFace,
LPCTSTR szMessage, int point)
{
HFONT hFont = CreateFont(
-point * GetDeviceCaps(hdc, LOGPIXELSY) /72,
0, 0, 0, FW_BOLD, TRUE, FALSE, FALSE,
ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH, szFace);
assert(hFont);
HGDIOBJ hOld = SelectObject(hdc, hFont);
SetTextAlign(hdc, TA_CENTER | TA_BASELINE );
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, x, y, szMessage, _tcslen(szMessage));
SelectObject(hdc, hOld);
DeleteObject(hFont);
}
class KHelloWindow : public KWindow
{
private:
void OnKeyDown(WPARAM wParam, LPARAM lParam)
{
if( wParam == VK_ESCAPE )
{
PostMessage(m_hwnd, WM_CLOSE, 0, 0);
}
}
void OnDraw(HDC hdc)
{
TextOut(hdc, 0, 0, szHint, lstrlen(szHint));
CenterText(hdc, GetDeviceCaps(hdc, HORZRES) / 2,
GetDeviceCaps(hdc, VERTRES) / 2,
szFace, szMessage, 72);
}
public:
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmd, int nShow)
{
KHelloWindow win;
win.CreateEx(0, szProgram, szProgram, WS_POPUP, 0, 0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL, NULL, hInst);
win.ShowWindow(nShow);
win.UpdateWindow();
return win.MessageLoop();
}