窗口特效基础篇

来源:互联网 发布:matlab 矩阵元素运算 编辑:程序博客网 时间:2024/05/29 13:34

特效1:制作圆角矩形窗口

只需要响应窗口的ONSIZE消息就可以了,在该响应函数中输入以下代码:

CRgn m_rgn;CRect  rc;GetWindowRect(&rc); rc-=rc.TopLeft();

M_rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,100.100);

SetWindowRgn(m_rgn,TRUE);

心得:从上面的代码,我看出了,首先获得窗口的大小,然后按照窗口的尺寸创建一个区域(region),借助CreateRoundRectRgn函数就可以创建圆角的窗口,然后调用函数将区域设置成为窗口就可以了!其中函数中最后面的参数就是设置远角的大小!

特效2:静态切分窗口

首先我们要在框架类的头文件中加入一个成员变量CSplitterWnd m_Splitter;

然后我们需要重载OnCreateClient函数,并且修改它的代码如下:

CRect rect;GetClientRect(&rect);

CSize paneSize(rect.Width()/3,rect.Height()/3);

m_Splitter.CreateStatic(this,3,1);

m_Splitter.CreateView(0,0,RUNTIME_CLASS(CExampleView,paneSize,pContext)

……重复三次就可以了!只不过要该第一个参数。

心得:程序首先通过GetWindowRect函数得到窗口的尺寸,然后通过函数CreateStatic函数建立静态切分窗口,它的参数的意义是:第一个参数是需要创建多少行,第二个就是需要创建多少列。在函数CreateView中,第一个参数是基于索引值为零的行标,第二个参数是基于

零的列的行标,第三个参数是需要创建的窗口是什么类型的(用类名表示,因为在MFC中一个类往往关联着一中资源),例如本例中的CExampleView就是一个视图类,那么创建的就是一个试图窗口!

特效3:动态切分窗口

雷同上面的静态,我们需要添加CSplitterWnd类型的变量m_Splitter

跟着重载OnCreateClient函数,代码变为:

return  m_Splitter.Create(this,2,2,CSize(10,10),pContext);

心得:在该函数中,第二个参数和第三个参数都不能大于2。第三个参数标识着各个部分显示出来的尺寸(不太准确),注意每个窗口的大小都可以在它创建之后动态的改变大小。只需用鼠标拖动即可!

特效4:设计字符形状的窗口

需要在对话框的OninitDialog函数中添加如下代码:

HRGN m_wndRgn;CClientDC dc(this);CFont mfont;

mfont.CreateFont(200,50,0,0,FW_HEAVY,FALSE,FALSE,0,ANSI_CHARSET,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SEISS,"华文行楷");

dc.BeginPath();dc.SetBkMode(TRANSPARENT);CFont*oldfont=dc.SelectObject(&mfont);

dc.TextOut(0,0,"想让窗口呈现出来的字符");  dc.EndPath();

m_wndRgn=::PathToRgn(&dc);

this->SetWindowRect(m_wndRgn,TRUE); return TRUE;

此时如果运行,可以得到正确的窗口,但是无法用鼠标来移动,为使窗口能够移动就必须响应WM_NCHITTEST消息,添加代码:

UINT nHit=CDialog::OnNcHitTest(point); 

Return (nHit==HTCLIENT)?HTCAPTION:Nhit;

这样就可以用鼠标拖动窗口了,但是如果此时想让窗口响应其他的消息,没有可能了,此时就要去掉这个函数,从新设计:响应鼠标左键单击是的WM_LBUTTONDOWN消息,代码添加:PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));

心得:发现创建一些比较花哨的窗口都要用到区域这个概念,也就是region,本例中在路径程中输出字符,其实也就是在路径程中画出字符串或者字符,然后将这个路径程映射到区域中,显示这个区域就可以了。

但是这样得到的窗口有弊端,就是窗口不是真正意义上的字符,很容易出现原本的对话框,而且很不容易改变输入的字符串的颜色(到目前为止,我只能用一种方法改变它的颜色,就是在theapp中的InitInstance函数中调用函数SetDialogBkColor)。

到目前为止,我觉得可行的方法是用位图来创建窗口,这样可靠,而且得到的才是真正意义上的花哨的窗口。但是这种方法也有弊端:首先位图中要显示的字符串的颜色不能和背景的颜色相同,同时背景色最好单调,可以说不是最好就要单调(因为这种方法就是依赖这两者的不同来设计的,具体见下面),再者就是速度太慢,很浪费时间。

具体方法是:先获得该位图的大小,这就要调用CBrush类中的GetObject()函数了,根据位图的大小来MoveWindow,同时根据窗口大小创建一个区域,首先获得背景色的COLORREF的值,然后两参循环依次访问位图中的每一个像素点,对比该像素点的颜色和背景色,相同就创建另外一个区域,然后通过CRgn中的CombineRgn函数就可以将该区域从大的区域中去掉,否则不进行操作。

最后剩下将该区域设置成为当前的窗口了,这样得到的窗口就是一个真正上的花哨窗口了。

为防止窗口重画的时候,位图被擦除,就要响应WM_ERASEBKGND消息,在该响应函数中重新贴上位图就可以了,切记:一定不要直接返回CDialog::OnEraseBkgnd(pDC);函数(这个函数会擦除窗口),否则前面的工作等于白做了,直接返回TRUE;就可以了。

应对上面采用刪像素点的方法的两个弊端的对策:我们可以借助别的软件现将背景都去掉,这样就解决了我们在程序中的复杂的运算了。

特效5:窗口的动画效果

为实现此功能,我们需要一个API函数:AnimateWindow

但是注意:为了能在我们的程序中使用该函数需要在StdAfx.h文件开头添加语句:

#undef WINVER   #define WINVER  0X500.

心得:该函数的第一个参数是窗口的句柄,也就是需要产生动画效果的窗口的句柄(一般通过GetSafeHwnd()获得)。第二个参数就是动画进行的时间,第三个参数就是动画的形式了,具体可见MSDN上。就我所用的效果来看这个函数似乎很费时间,运行的时候程序很容易出现未响应的提示。

特效6:显示半透明的对话框窗口

我们需要用到SetLayeredWindowAttributes函数,该函数的声明是:

BOOL SetLayeredWindowAttributes(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags);

其中dwFlags参数可以被设置为LWA_ALPHA或者LWA_COLORREF。如果设置为LWA_ALPHA,那么通过bAlpha参数来设置窗口的透明度;如果设置为LWA_COLORREF,那么指定crKey参数代表的颜色为窗口的透明色,其他颜色则正常显示。

待续……

 

原创粉丝点击