摘 要:本文主要介绍了WINDOWS下的不规则窗口的实现,并给出了一种实现在窗口拖
动时,同时显示窗口内容的方法。
关键词:不规则窗口,拖动
一、引言
贵刊前几期有文章介绍了有关WINDOWS不规则窗口的实现,但我认为还有一些可以补充的地方,现将我的一些实践介绍出来,以供大家参考和共同讨论。
二、主要的函数介绍
1. BOOL CWnd::CreateEx( DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, HWND hwndParent, HMENU nIDorHMenu, LPVOID lpParam = NULL );
主要参数含义:
dwExStyle:指向字符串的指针,此字符串是窗口的类名。可以使用MFC的全局函数AfxRegisterWndClass注册得到指向窗口类名的指针。
LpszWindowName:指向包涵窗口名字符串的指针。
dwStyle:窗口的风格。
rect::相对于父窗口,说明窗口的位置和大小。
2. int CWnd::SetWindowRgn( HRGN hRgn, BOOL bRedraw );
主要参数含义:
hRgn:区域的句柄。
bRedraw:布尔量,表明在设置窗口区域之后,系统是否重绘窗口。
3. BOOL CWnd::SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int
cx,int cy,UINT nFlags);
主要参数含义:
pWndInsertAfter:标识窗口的Z序列。
x,y:在父窗口的客户区中,窗口左上角的坐标。
cx,cy:窗口的宽度和高度。
nFlags:窗口的位置和大小选项,设为SWP_NOSIZE时,保持当前大小,忽略cx,cy。
二、不规则窗口的创建与拖动
首先,提出我对不规则窗口的一些看法。以前的介绍中,有提出基于CDialog来做不规则窗口,我的看法是一定不要用基于CDidlog的不规则窗口,因为这样的不规则窗口,要将Dialog的Title Bar属性去掉,这样一来,在Windows的任务栏上的程序按钮上点鼠标右键时,就不能出现系统菜单,使用户使用不够方便。所以要做不规则窗口,就要自己写一个基于CWnd的窗口类,然后自己在写一个此窗口类的创建函数,假设此创建函数的名字叫CreateMyWindow..在CreateMyWindow中调用CWnd::CreateEx来创建窗口,将dwStyle设为WS_POPUP |WS_SYSMENU|WS_MINIMIZEBOX.这样一来,生成的窗口不会有Title Bar,并且在任务栏上的程序按钮点鼠标右键时,出现程序的系统菜单, 系统菜单中的”最小化” 菜单项是可用的.然后利用CWnd:: SetWindowRgn可以设置不同形状的窗口.以上的方法在很多的杂志、BBS上都有介绍。这里不在详细说明,具体做法可见所带的程序代码。
对于不规则窗口的拖动,一般做法都是当按下鼠标左键时,发出消息WM_NCLBUTTONDOWN,伪装在窗口的Title Bar内点击,实现窗口的拖动。但是这样的拖动处理使得在拖动过程中,窗口显示为一个虚的矩型框。如何在窗口的拖动过程中,一直显示窗口的内容?就象Winamp软件一样。
可采用如下几步:
1. 为自己写的窗口类建立WM_LBUTTONDOWN和WM_MOUSEMOVE的响应函数OnLButtonDown(UINT nFlags, CPoint point)、OnMouseMove(UINT nFlags, CPoint point)。
2. 分别在OnLButtonDown、OnMouseMove加入如下代码。
void CMyWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_TempPoint=point; //保存鼠标左键按下是初始的位置,以后用来计算窗口
//位置。
CWnd::OnLButtonDown(nFlags, point);
}
void CMyWnd::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (nFlags&MK_LBUTTON) //如果鼠标移动时左键是按下的。
{
CPoint ipoint;
::GetCursorPos(&ipoint); //得到当前光标位置。
SetWindowPos(NULL, ipoint.x - m_TempPoint.x, ipoint.y-m_TempPoint.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);//设置窗口新位置。
}
CWnd::OnMouseMove(nFlags, point);
}
注意在上面的语句::GetCursorPos(&ipoint)中,坐标系是屏幕坐标,而m_TempPoint是窗口客户区的坐标,正是这样的表示才刚好计算出窗口新位置的准确值,所以不许要坐标转换。这样,就可以实现不规则的窗口和很有特色的拖动效果。以上只是主要的几个函数,还有其他效果的代码可见所附的MFC工程,此工程在WIN98和Visual C++下,调试通过参考资料
1. Visual C++ 4 开发人员指南,机械工业出版社。
2. 一些VC 编程网站。
|