赞美男子的古诗词:freeform设计是什么东东啊?

来源:百度文库 编辑:中科新闻网 时间:2024/04/28 01:51:16
我有个朋友叫我帮他找个Freeform设计的工作,可是我连Freeform都不知道是什么意思,我又不好意思问他,只好在这里来向大家求助了!谢谢各位,帮帮忙啊!

在Windows系统中窗口的默认形状是矩形,在实际应用中绝大多数窗口都是标准矩形窗口。如果一个窗口有着与众不同的形状,则会非常引人注目,如何创建非标准窗口呢?

在Windows,可以通过调用SetWindowRgn(在MFC类库中对应的函数为CWnd::SetWindowRgn)来设置窗口的形状,函数的定义如下:

intSetWindowRgn(HWNDhWnd,HRGNhRgn,BOOLbRedrawflag);

窗口的形状由参数hRgn所标志的的区域(region)决定。通过创建不同的区域就可以创建不同形状的窗口。下面的代码,可以产生圆角矩形的窗口。

CRgntrgn;
trgn.CreateRoundRectRgn(0,0,200,200,30,30);
SetWindowRgn(trgn,TRUE);
效果如下图所示:

Windows还支持由路径(Path)创建区域(Region),通过这个途径我们还可以创建文字形状的窗口。
下面的代码可以创建形状为“计算机世界"五个字的窗口。

+CDC*pDC=GetDC();
CFontrfont,*pOldFont;
CRgnm_rgn;

rfont.CreatePointFont(1000,“隶书");
pOldFont=pDC->SelectObject(&rfont);

pDC->BeginPath();
pDC->SetBkMode(TRANSPARENT);
CStringstxt=“计算机世界";
pDC->TextOut(0,0,stxt);
pDC->EndPath();

m_rgn.CreateFromPath(pDC);

pDC->SelectObject(pOldFont);
ReleaseDC(pDC);
SetWindowRgn(m_rgn,TRUE);

效果如下图所示:

那么我们能不能创建任意形状的窗口呢?也就是创建任意形状的区域呢?答案是肯定的。大家请看下面这个圆号形状的窗口。

创建这样的一个区域是调用SDK的ExtCreateRegion来实现(MFC中的对应函数为CRgn::CreateFromData)。这个函数是通过提供一个矩形数组,来创建一个由这些矩形组成的区域。而创建圆号区域的过程就是由一个圆号的位图生成矩形数组,再由这个矩形数组生成区域的过程。
下面是由圆号位图创建区域的函数代码。

CDibm_dib;
CRgnm_rgn;
COLORREFm_dwColorKey=0x0000ff;//透明色,纯蓝

BOOLCAswDlg::CreateRegionFromBmp(LPCSTRlpsFName)
{
//读入位图
if(!m_dib.Open(lpsFName))
returnFALSE;

SIZEdibsize;

//获取位图尺寸
dibsize=m_dib.GetSize();

inti,j;
BOOLbkey;
intiCount=0;

//统计需要的矩形个数
for(i=0;i<dibsize.cy;i++)>br> {
bkey=TRUE;
for(j=0;j<dibsize.cx;j++)>br> {
if(m_dib.GetPixel(j,i)==m_dwColorKey)
{
bkey=TRUE;
}
else
{
if(bkey)
{
iCount++;
}
bkey=FALSE;
}
}
}
BYTE*pData;
RGNDATA*pRgnData;
RECT*pRect;
intiIndex=0;

pData=newBYTE[sizeof
(RGNDATAHEADER)+sizeof(RECT)*iCount];
pRgnData=(RGNDATA*)pData;
pRect=(RECT*)(pData+sizeof(RGNDATAHEADER));
pRgnData->rdh.dwSize=sizeo(RGNDATAHEADER);
pRgnData->rdh.iType=RDH_RECTANGLES;
pRgnData->rdh.nCount=iCount;
pRgnData->rdh.nRgnSize=sizeof(RECT)*iCount;
pRgnData->rdh.rcBound.left=0;
pRgnData->rdh.rcBound.top=0;
pRgnData->rdh.rcBound.right=dibsize.cx;
pRgnData->rdh.rcBound.bottom=dibsize.cy;

intiLeft=0;
for(i=dibsize.cy-1;i>=0;i--)
//因为Bitmap位图在Y方向是颠倒
的所以要从底部开始
{
bkey=TRUE;
iLeft=-1;
for(j=0;j<dibsize.cx;j++)>br> {
if(m_dib.GetPixel(j,i)==m_dwColorKey)
{
if(!bkey)
{
pRect[iIndex].left=iLeft;
pRect[iIndex].right=j;
pRect[iIndex].top=dibsize.cy-i-1;
pRect[iIndex].bottom=dibsize.cy-i;
bkey=TRUE;
iIndex++;
iLeft=-1;
}
}
else
{
if(bkey)
{
iLeft=j;
bkey=FALSE;
}
}
}

if(iLeft>=0)
{
pRect[iIndex].left=iLeft;
pRect[iIndex].right=dibsize.cx;
pRect[iIndex].top=i;
pRect[iIndex].bottom=i;
iIndex++;
}
}
BOOLbr=m_rgn.CreateFromData
(NULL,sizeof(RGNDATAHEADER)+sizeof
(RECT)*iCount,pRgnData);
returnbr;
}

有了这个方法,任意形状的窗口都可以被创建,只要先画出想要的形状位图即可。
这里还要谈到一个问题,任意形状的窗口没有标题栏,那么用户如何拖动窗口呢?其实只要在响应左键点击消息时调用SendMessage(WM_SYSCOMMAND,SC_MOVE|HTCLIENT,0)即可。