文章目录
1.CWindowWnd类
- 1.CWindowWnd类
- 2.作者答疑
在duilib中,绘制对象的目标载体是窗口,那就必然有窗口部分的内容需要处理,在WindowImplBase中,封装在父类CWindowWnd中,如下所示:
class UILIB_API CWindowWnd
{
public:
CWindowWnd();
HWND GetHWND() const;
operator HWND() const;//类型转换函数
//注册窗口类
bool RegisterWindowClass();
bool RegisterSuperclass(); // 超类化,hinst—定义窗口类XXXXXX的模块的句柄,如为系统定义的窗口类(如:EDIT、BUTTON)则hinst=NULL.。
//创建窗口
HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
HWND CreateDuiWindow(HWND hwndParent, LPCTSTR pstrWindowName,DWORD dwStyle =0, DWORD dwExStyle =0);
//保存窗口与对象的映射、修改窗口过程函数和解绑
HWND Subclass(HWND hWnd);
void Unsubclass();
//显示窗口
void ShowWindow(bool bShow = true, bool bTakeFocus = true);
UINT ShowModal();
void Close(UINT nRet = IDOK);
void CenterWindow(); // 居中,支持扩展屏幕
void SetIcon(UINT nRes);// 修改窗口图标
//系统函数的封装
LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
void ResizeClient(int cx = -1, int cy = -1);//修改客户端区域大小
protected:
virtual LPCTSTR GetWindowClassName() const = 0;
virtual LPCTSTR GetSuperClassName() const;
virtual UINT GetClassStyle() const;
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual void OnFinalMessage(HWND hWnd);
static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
HWND m_hWnd;
WNDPROC m_OldWndProc;
bool m_bSubclassed;
};
部分内容写在注释里,耐心的读者,请在以上源代码中阅读,可以学习下,在Subclass函数中,如何修改窗口函数、建立窗口和窗口对象指针联系的方法。但这个函数,在duilib中,并没有调用。窗口函数的指定,还是在RegisterWindowClass或者RegisterSuperclass中完成的。 在窗口的创建过程中,提供了两种方法注册窗口程序,一种是独立窗口,另外一种是子控件的方法,对应着两个注册函数 bool RegisterWindowClass(),bool RegisterSuperclass(); 其次查看窗口中最重要的窗口消息函数,如下所示:
LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindowWnd* pThis = NULL;
if( uMsg == WM_NCCREATE ) {//创建窗口消息
LPCREATESTRUCT lpcs = reinterpret_cast(lParam);//获取创建窗口时的创建参数
pThis = static_cast(lpcs->lpCreateParams);
pThis->m_hWnd = hWnd;
::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pThis));
}
else {
pThis = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA));//获取保存的窗口对象
if( uMsg == WM_NCDESTROY && pThis != NULL ) {
LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
if( pThis->m_bSubclassed ) pThis->Unsubclass();
pThis->m_hWnd = NULL;
pThis->OnFinalMessage(hWnd);
return lRes;
}
}
if( pThis != NULL ) {
return pThis->HandleMessage(uMsg, wParam, lParam);//窗口自定义的消息处理
}
else {
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
从上述函数中可以得出,HandleMessage是窗口的消息处理函数。同时它是一个虚函数,子类可以通过虚函数的特征来修改这个窗口消息函数。
2.作者答疑如有疑问,请留言。