16,548
社区成员




#ifndef __BASE_WND__H__
#define __BASE_WND__H__
#ifndef ASSERT
#include <crtdbg.h>
#define ASSERT(X) _ASSERT(X);
#endif
class CBaseWnd
{
private:
bool IsDeleteInDestructor;
public:
HWND m_hWnd;
virtual LRESULT HandleMessage(UINT message, WPARAM wParam, LPARAM lParam) { return 0;}
// static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// HWND Create(DWORD ,LPCTSTR , LPCTSTR , DWORD , int ,int , int ,int ,HWND ,HMENU ,HINSTANCE );
// BOOL RegisterWindowClass();
CBaseWnd() : m_hWnd(NULL) , IsDeleteInDestructor(false) {}
virtual ~CBaseWnd()
{
if (m_hWnd)
{
IsDeleteInDestructor=true;
::DestroyWindow(m_hWnd);
m_hWnd=NULL; // 这样比较安全
}
}
inline HWND GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
//慎用,除非你确定hWnd 就是 CBaseWnd
static CBaseWnd* FromHandle(HWND hWnd)
{
ASSERT ( ::GetCurrentThreadId() == ::GetWindowThreadProcessId(hWnd,NULL) ) ;
return reinterpret_cast<CBaseWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
static LRESULT CALLBACK CBaseWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CBaseWnd* pThis = reinterpret_cast<CBaseWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
if(pThis != NULL)
{
if(uMsg==WM_NCDESTROY )
{
//LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
LRESULT lRes = ::DefWindowProc(hWnd, uMsg, wParam, lParam);
::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
pThis->m_hWnd = NULL;
//当窗口结束时,删除掉对象本身
if (!pThis->IsDeleteInDestructor)
delete pThis;
return lRes;
}
else
{
return pThis->HandleMessage(uMsg, wParam, lParam);
}
}
else
{
if(uMsg == WM_NCCREATE)
{
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
pThis = static_cast<CBaseWnd*>(lpcs->lpCreateParams);
ASSERT(pThis != NULL);
pThis->m_hWnd = hWnd;
::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis));
return pThis->HandleMessage(uMsg, wParam, lParam);
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
BOOL CBaseWnd::RegisterWindowClass(LPCTSTR lpClassName)
{
WNDCLASS wc={0};
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszMenuName = NULL;
wc.hInstance = NULL;
wc.style = NULL; /*CS_HREDRAW|CS_VREDRAW*/
wc.hbrBackground = NULL; /*(HBRUSH)GetStockObject(WHITE_BRUSH)*/
wc.hIcon = NULL; /*LoadIcon(::GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON))*/
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.lpszClassName = lpClassName;
wc.lpfnWndProc = CBaseWnd::WndProc;
ATOM ret = ::RegisterClass(&wc);
ASSERT (ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
return (ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
}
HWND CBaseWnd::Create(DWORD dwExStyle,LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,
int x,int y, int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance )
{
if(!RegisterWindowClass(lpClassName))
return NULL;
m_hWnd = CreateWindowEx(dwExStyle,lpClassName,lpWindowName,dwStyle,
x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,
this) ; //!!!!!注意这里的this,把这个对象的指针传递进去
ASSERT(m_hWnd);
return m_hWnd;
}
};
#endif #define __BASE_WND__H__
#include "BaseWnd.h"
class CMyButton : public CBaseWnd
{
public:
virtual LRESULT HandleMessage(UINT message, WPARAM wParam, LPARAM lParam);
};
LRESULT CMyButton::HandleMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
POINT point;
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
trace(point);
}
break;
case WM_RBUTTONDOWN:
{
}
break;
case WM_MOUSEMOVE:
{
}
break;
case WM_CLOSE:
{
// DestroyWindow(m_hWnd);
}
break;
}
return DefWindowProc(m_hWnd,message,wParam,lParam);
}
CMyButton* pWnd;
void CDemoDlg::OnButton1()
{
pWnd=new CMyButton();
pWnd->Create(
WS_EX_TOPMOST
// | WS_EX_TOOLWINDOW|WS_EX_TOPMOST&~WS_EX_APPWINDOW, //取消任务栏标题
,
"Button",
_T("Demo"),
WS_OVERLAPPEDWINDOW
| WS_VISIBLE
// | WS_OVERLAPPEDWINDOW
// | WS_CHILD
// | WS_POPUP | WS_BORDER
// | WS_VSCROLL
,225,160,400,400,NULL,NULL,NULL);
}
void CDemoDlg::OnButton2()
{
// delete pWnd;
::PostMessage(pWnd->m_hWnd,WM_CLOSE,NULL,NULL);
}