class CMyWnd
{
public:
CMyWnd(void);
virtual ~CMyWnd(void);
public:
void OnPaint1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
public :
    HWND m_hWnd; // The control's window handle
HWND m_hWndParent;
};typedef void (CMyWnd:: *lpMsgFunc)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
typedef struct MsgInfo
{
UINT Msg;
lpMsgFunc lpMsgfunc;

}MSG_INFO,*PMSG_INFO;typedef struct MsgMap
{
const MsgMap *pMapParrent;
const MSG_INFO* pMsgInfo;
}MSG_MAP,*PMSG_MAP;
#define MYDECLARE_MESSAGE_MAP()\
private:\
static const MSG_INFO messageInfo[];\
protected:\
static const MSG_MAP messageMap;\
static const MSG_MAP* GetThisMessageMap(); \
virtual const MSG_MAP* GetMsgMap() const;#define MYBEGIN_MESSAGE_MAP(thisClass,parrentClass)\
const MSG_MAP thisClass::messageMap = \
{ &parrentClass::messageMap,thisClass::messageInfo };\
const PMSG_MAP thisClass::GetMsgMap()\
{\
return  &thisClass::messageMap;\
}\
const MSG_INFO thisClass::messageInfo[] = \
{\#define MYEND_MESSAGE_MAP()\
};#define MYBEGIN_MESSAGE_MAP1(thisClass)\
const MSG_MAP* thisClass::GetMsgMap() const\
{\
return GetThisMessageMap();\
} \
const MSG_MAP* thisClass::GetThisMessageMap() \
{ \
typedef thisClass theClass;\
static const MSG_INFO messageInfo[] = \
{\#define MYEND_MESSAGE_MAP1()\
};\
static const MSG_MAP messageMap = \
{ NULL, &messageInfo[0] };\
return  &messageMap;\
}\
#define  ON_WM_PAINT1()\
{ WM_PAINT,(lpMsgFunc)(static_cast<void(CMyWnd:: *)(HWND, UINT, WPARAM,LPARAM)>(&theClass::OnPaint1)) },//窗口类头文件
class CMyStatic : public CMyWnd
{
MYDECLARE_MESSAGE_MAP()
public:
CMyStatic(HWND hWnd = NULL);
virtual ~CMyStatic(); enum
{
__SS_TEXT__=0,
__SS_ICON__,
__SS_BITMAP__,
}; //注册该窗口
    static void RegisterWnd();
//窗口函数
static LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    
virtual BOOL Create(LPCTSTR lpszWindowName,
DWORD dwStyle,
long cx,
long cy,
long lWidth,
long lHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam = NULL); inline BOOL ShowWindow(int nCmdShow) { return ::ShowWindow(m_hWnd, nCmdShow); }
inline BOOL UpdateWindow() { return ::UpdateWindow(m_hWnd); }
inline void SetBkColor(COLORREF clr) { m_clrBK = clr; }
inline void SetTextColor(COLORREF clr) { m_clrText = clr; }
inline void SetBitMap(HBITMAP hBitMap) { m_hBitMap = hBitMap; }
inline void SetIcon(HICON hIcon) { m_hIcon = hIcon; }
inline void SetTitle(LPCTSTR lpTitle) { m_lnTitle = lstrlen(lstrcpyn(m_szTitle,lpTitle,254)); }
protected:
LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
void OnPaint1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);private:
    static TCHAR szClassName[32];
CMyStatic *pwndApp;private:
TCHAR m_szTitle[256];
long m_lnTitle;
long m_rnMask; //换行符标识
COLORREF m_clrText;
COLORREF m_clrBK;
HBITMAP m_hBitMap;
HICON m_hIcon; DWORD m_dwShowStyle;
DWORD m_AlignText; //DT_LEFT,DT_CENTER,SS_RIGHT
DWORD m_wndStyle,m_wndStyleEx;};
//窗口类源文件TCHAR CMyStatic::szClassName[32] = _T("CMyStatic");CMyStatic::CMyStatic(HWND hWnd):pwndApp(NULL)
//,m_hWnd(hWnd),m_hWndParent(NULL)
,m_clrText(RGB(1,0,0)),m_clrBK(RGB(245,0,0))
,m_hBitMap(NULL),m_hIcon(NULL)
,m_wndStyle(0),m_wndStyleEx(0),m_dwShowStyle(0),m_AlignText(DT_LEFT)
,m_rnMask(0),m_lnTitle(0)
{
memset(m_szTitle,0,sizeof(m_szTitle));
}CMyStatic::~CMyStatic()
{}MYBEGIN_MESSAGE_MAP1(CMyStatic)
//{WM_PAINT,static_cast<void(CMyWnd:: *)(HWND, UINT, WPARAM,LPARAM)>(&CMyWnd::OnPaint1)}
ON_WM_PAINT1()
MYEND_MESSAGE_MAP1()void CMyStatic::RegisterWnd()
{
WNDCLASSEX wc; wc.cbSize = sizeof(wc);
wc.lpszClassName = CMyStatic::szClassName;
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = CMyStatic::WndProc;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = 0;
wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
wc.style = 0;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CMyStatic *);
wc.hIconSm = 0; RegisterClassEx(&wc);
}LRESULT CALLBACK CMyStatic::WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
//取得与窗口绑定的类实例
CMyStatic *wndApp = (CMyStatic *)GetWindowLong(hWnd,GWL_USERDATA);
for(int i = 0;i<1;++i)
{
if(Msg==messageInfo[i].Msg)
{
messageInfo[i].lpMsgfunc(hWnd,Msg,wParam,lParam);
return 0;
}
}
//if(!wndApp) return 0;
switch(Msg)
{
case WM_NCCREATE:
//在Windows创建窗口之前实例化一个CMyStatic实例,并与窗口句柄hWnd绑定
if(!wndApp)
{
wndApp = new CMyStatic(hWnd);
SetWindowLong(hWnd,GWL_USERDATA,(LONG)wndApp);
return (wndApp != NULL);
} //case WM_PAINT:
// return wndApp->OnPaint(wParam, lParam); // Clean up when the window is destroyed.
case WM_NCDESTROY:
DELETE_PTR(wndApp); break;
break;
case WM_ERASEBKGND:
return 1;
//case WM_LBUTTONDOWN:
// return wndApp->OnLButtonDown(wParam, lParam);
case WM_MOUSEACTIVATE:
SetFocus(hWnd); return MA_ACTIVATE;
default:
break;
} return DefWindowProc(hWnd, Msg, wParam, lParam);
}BOOL CMyStatic::Create(LPCTSTR lpszWindowName,
DWORD dwStyle,
long cx,
long cy,
long lWidth,
long lHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam)
{
RegisterWnd();
m_hWnd = CreateWindow(CMyStatic::szClassName, lpszWindowName, dwStyle , cx, cy, 
lWidth, lHeight, hWndParent, hMenu, hInstance, lpParam);
m_hWndParent = hWndParent;
m_lnTitle = lstrlen(lstrcpyn(m_szTitle,lpszWindowName,254));
m_wndStyle = GetWindowLong(m_hWnd,GWL_STYLE) | m_AlignText;
m_wndStyleEx = GetWindowLong(m_hWnd,GWL_EXSTYLE);
SetWindowLong(m_hWnd,GWL_USERDATA,(LONG)this);
return m_hWnd != NULL;
}LRESULT CMyStatic::OnPaint(WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect; hDC = ::BeginPaint(m_hWnd,&ps);
::GetClientRect(m_hWnd,&rect);
HBRUSH hBrush=CreateSolidBrush(m_clrBK);
HGDIOBJ oldBrush = SelectObject(hDC,hBrush);
FillRect(hDC,&rect,hBrush);
::SetBkMode(hDC, TRANSPARENT);
switch(m_dwShowStyle)
{
case 0:
::SetTextColor(hDC,m_clrText);
DrawText(hDC,m_szTitle,m_lnTitle,&rect,
DT_VCENTER|((m_wndStyle&SS_CENTER)?DT_CENTER:((m_wndStyle&SS_RIGHT)?DT_RIGHT:DT_LEFT))|
(m_rnMask?0:(DT_SINGLELINE|DT_END_ELLIPSIS)));
}

//::DrawText(hDC, _T("MyStatic"), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SelectObject(hDC,oldBrush);
__SAFE_DELETE_GDIOBJ__(hBrush);
::EndPaint(m_hWnd,&ps); return 0;
}void CMyStatic::OnPaint1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
OnPaint(wParam,lParam);
}
窗口过程处理函数中的这几句测试for(int i = 0;i<1;++i)
{
if(Msg==messageInfo[i].Msg)
{
messageInfo[i].lpMsgfunc(hWnd,Msg,wParam,lParam);
return 0;
}
}根本就不行,求指导

解决方案 »

  1.   

    messageInfo[i].lpMsgfunc(hWnd,Msg,wParam,lParam);
    这句出现错误,error C2064: 项不会计算为接受 4 个参数的函数
      

  2.   

    你基类实现一个defaultwndprocess不就行了,干吗搞个基类的回调
      

  3.   

    这个帮不了楼主,不过可以向楼主请教一个问题:
    既然你LZ 都能写出来,能不能简明几句说说MFC消息机制原理呢?
      

  4.   

    你看MFC他重载消息循环会把
    CMyStatic *wndApp = (CMyStatic *)GetWindowLong(hWnd,GWL_USERDATA);
        for(int i = 0;i<1;++i)
        {
            if(Msg==messageInfo[i].Msg)
            {
                messageInfo[i].lpMsgfunc(hWnd,Msg,wParam,lParam);
                return 0;
            }
        }这么一段代码加进来么,这明显不合理。如果某些消息你要处理,完全可以在基类pretranslatemessage里操作。