窗口类、窗口类对象与窗口三者之间关系
来源:互联网 发布:恒大金服app网络不给力 编辑:程序博客网 时间:2024/05/01 01:46
很多开发人员都将窗口类、窗口类的对象和窗口之间的关系弄混淆了。为了使读者能更好地理解它们之间的关系,下面我们将模拟CWnd类的封装过程。首先新建一个Win32 Application类型的工程,取名为“WinMain”。在随后的向导窗口中选择创建一个空工程(即选择an empty project选项)。接着为该工程新建一个源文件WinMain.cpp。在该文件中,首先新建一个类CWnd,然后为其定义创建窗口函数(CreateEx)、显示窗口函数(ShowWindow)和更新窗口函数(UpdateWindow)三个函数,并定义一个成员变量(m_hWnd)。具体代码如例3-18所示。
例3-18
class CWnd
{
public:
BOOL CreateEx(DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // registered class name
LPCTSTR lpWindowName, // window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam); // window-creation data
BOOL ShowWindow(int nCmdShow);
BOOL UpdateWindow();
public:
HWND m_hWnd;
};
小技巧:这些函数的参数可以参照MSDN中相应MFC函数的定义,然后直接复制这些参数即可。
提示:因为SDK函数数量很多,程序员
接下来完成这三个函数的定义,代码如例3-19所示。
例3-19
BOOL CWnd::CreateEx(DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // registered class name
LPCTSTR lpWindowName, // window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam) // window-creation data
{
m_hWnd=::CreateWindowEx(dwExStyle,lpClassName,dwStyle,x,y,
nWidth,nHeight,hWndParent,hMenu,hInstance,
lpParam);
if(m_hWnd!=NULL)
return TRUE;
else
return FALSE;
}
BOOL CWnd::ShowWindow(int nCmdShow)
{
return ::ShowWindow(m_hWnd,nCmdShow);
}
BOOL CWnd::UpdateWindow()
{
return ::UpdateWindow(m_hWnd);
}
读者应注意的是,在实际开发时,应该初始化m_hWnd变量,这可以在构造函数中实现,给它赋一个初值NULL。这里我们只是为了演示CWnd类是如何与窗口关联起来的,因此就不进行初始化工作了。
接下来定义ShowWindow函数的实现。同样,需要调用Platform SDK函数,即ShowWindow来完成窗口的显示。为了区分这两个同名函数,在调用这个Platform SDK函数时,前面加上作用域标识符(即::)。这种以“::”开始的表示方法表明该函数是一个全局函数,这里表示调用的ShowWindow函数是Platform SDK函数。因为CreateEx函数已经获取了窗口句柄并保存到m_hWnd成员变量中,所以,ShowWindow函数可以直接把这个句柄变量作为参数来使用。
我们自己定义的UpdateWindow函数的实现比较简单,直接调用SDK函数:UpdateWindow完成更新窗口的工作。
从例3-19所示代码可知,我们定义的CWnd类的后两个函数(ShowWindow和UpdateWindow)内部都需要一个窗口句柄,即需要知道对哪个窗口进行操作。
现在我们就实现了一个窗口类:CWnd。但我们知道如果要以类的方式来完成窗口的创建、显示和更新操作,那么首先还需要编写一个WinMain函数。读者并不需要记忆这个函数的写法,只要机器上有MSDN就可以了,在MSDN中找到该函数的帮助文档,直接复制其定义即可。这里,我们只是想讲解在这个函数内部所做的工作,并不是真正的实现,因此只是写出其主要的代码,如例3-20所示。
例3-20
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
//首先是设计窗口类,即定义一个WNDCLASS,并为相应字段赋值。
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
......
//注册窗口类
RegisterClass(&wndcls);
//创建窗口
CWnd wnd;
wnd.CreateEx(...);
//显示窗口
wnd.ShowWindow(SW_SHOWNORMAL);
//更新窗口
wnd.UpdateWindow();
//接下来就是消息循环,此处省略
......
return 0;
}
例3-21
HWND hwnd;
hwnd=CreateWindowEx();
::ShowWindow(hwnd,SW_SHOWNORMAL);
::UpdateWindow(hwnd);
我们可以发现,SDK程序中多了一个HWND类型的变量hwnd。该变量用来保存由CreateWindowEx函数创建的窗口句柄,并将其作为参数传递给随后的显示窗口操作(ShowWindow函数)和更新窗口操作(UpdateWindow函数)。而我们自定义的实现代码中,CWnd类定义了一个HWND类型的成员变量:m_hWnd,用于保存这个窗口句柄。首先CWnd类的CreateEx函数创建窗口,并将该窗口句柄保存到这个成员变量,接着调用CWnd类的ShowWindow函数显示窗口时,就不需要再传递这个句柄了,因为它已经是成员变量,该函数可以直接使用它。CWnd类的UpdateWindow函数也是一样的道理。
许多程序员在进行MFC程序开发时,容易混淆一点:认为这里的CWnd类型的wnd这个C++
C++窗口类对象的生命周期和窗口的生命周期不是一致的。当一个窗口销毁时,与C++窗口类对象没有关系,它们之间的纽带仅仅在于这个C++窗口类内部的成员变量:m_hWnd,该变量保存了与这个C++窗口类对象相关的那个窗口的句柄。
另一方面,当我们设计的这个C++窗口类对象销毁的时候,与之相关的窗口是应该销毁的,因为它们之间的纽带(m_hWnd)已经断了。另外,窗口也是一种资源,它也占据内存。这样,在C++窗口类对象析构时,也需要回收相关的窗口资源,即销毁这个窗口。
这是我们自已定义的CWnd类,那么MFC提供的CWnd类是不是这样实现的呢?读者在MSDN中查看MFC提供的CWnd类,将会发现该类确实定义了一个数据成员:m_hwnd,用来保存与之相关的窗口的句柄。因为MFC中所有的窗口类都是由CWnd类派生的,于是,所有的窗口类(包括子类)内部都有这样的一个成员用来保存与之相关的窗口句柄。所以,读者不能认为我们前面创建的MFC程序Test中的CMainFrame类和CTestView类的对象就是一个窗口。
- 窗口类、窗口类对象与窗口三者之间关系
- 窗口类、窗口类对象与窗口 三者之间关系
- 窗口类、窗口类对象与窗口 三者之间关系
- 窗口类、窗口类对象与窗口 三者之间关系
- “窗口类、窗口类的对象和窗口”三者的关系
- 窗口类、窗口类对象与窗口
- 窗口类,窗口类对象与窗口
- CWnd类的对象和Windows窗口之间的关系
- 窗口类和窗口对象
- Qt中父窗口与子窗口之间的关系
- Qt中父窗口与子窗口之间的关系
- 窗口类--字体关系
- flex弹出窗口与父窗口之间
- 子窗口与父窗口之间消息
- 窗口风格 与 窗口类风格
- 窗口类指针与窗口句柄
- VC++深入详解 笔记 第三章(3) 窗口类对象和窗口的关系
- 三、窗口与消息
- 你真的理解了继承和多态吗?
- Java多态初体验
- hibernate小问题:setString的定义
- MD5加密
- Hibernate 复习笔记一
- 窗口类、窗口类对象与窗口三者之间关系
- 每天进步一点点——记学struts+spring+hibernate的感想,献给所有正在学习软件开发的朋友们
- 探索Win32系统之窗口类(Window Classes in Win32)
- Groovy Tip 24 魔幻数组 四
- 查找同色围棋子的广度和深度遍历方法
- 郁闷的老程序员,不知道前途何在
- 正则只替换URL字符串里面的汉字部分
- DLL详解
- 求catia钣金设计及相关问题