2018年4月6日

Windows 中不规则窗体的编程实现

  一、序文

  在压倒的多数Windows敷用中,它的花样是正态矩的矩形花样。,比如,我们家常常运用它。,“便条簿”,“全胜”,附加物。矩形窗体,有复杂的设计变卖,未完成的风骨的优点,故此,它可以用于普通的文档敷用和复杂的游玩。。只有些文娱游玩怎么不无赖。,这时若用不规则窗体废除模型的矩形窗体,这会使这类表现更风趣。。任一类型的要求是Windows 自代的Media Player,新媒介物版本 玩家有任一把持面板的选择,选择这些板,传播器显示在使牢固面板的时装中。,此刻玩家比先前版本的媒介物还要多。 玩家的矩形交流更风趣,更风趣。。 要变卖不规则窗体指责太难,意识基频的继后,你也可以引起杂多的风趣的不规则窗体。

  二、变卖规律

  所相当 Windows 窗体坐落在区域中。,整队的一定尺寸的极好的了区域的余地。,windows 在区域余地内自动地修剪的窗口。,使它看不见的东西。因而,要引起不规则窗体有两个方法:第一步执意引起不规则”region”.次货步执意将窗体放到引起的“region”中。

  次货步是换乘声明极复杂。。在SDK换乘API职务SetWindowRgn,职务原类型如次所示:

int SetWindowRgn( HWND hWnd, HRGN hRgn, BOOL bRedraw );

  在窗口的句柄是一种处置设,HRgn是区域的处置已引起,bRedraw代表条件重绘窗体。在

MFC

该窗口类CWnd围攻职务int CWnd::SetWindowRgn(HRGN hRgn, BOOL bRedraw 即将到来的职务的决定因素的意义是平稳的的确定功用平稳的。

  对立和次货步,引起不规则窗体的第一步要复杂很多地,而且不规则窗体越复杂,引起区域的诉讼顺序越复杂。以后,我们家将绍介杂多的方法来引起区域。。

  mfc切中要害区域宾语,CRgn类的变卖。近乎每个CRgn围攻职务同义词的SDK API职务的对应相干。

  三、引起复杂的区域

  任一复杂的方法引起任一新的区域经过CRgn类的围攻: BOOL CRgn::CreateRectRgn( int x1, int y1, int x2, int y2 ); 引起矩形的区域。

BOOL CRgn::CreateEllipticRgn( int x1, int y1, int x2, int y2 ); 引起圆形或长方形的区域。
BOOL CRgn::CreateRoundRectRgn( int x1, int y1, int x2, int y2, int x3, int y3 ); 引起圆角矩形区域。
BOOL CRgn::CreatePolygonRgn( LPPOINT lpPoints, int nCount, int nMode ); 引起龟裂状区域。

  上面是引起长圆窗体的示例,长圆造型方法简介。在引起长圆“region”的CreateEllipticRgn职务中,x1,Y1是指左上角坐标的矩形中,x2,Y2是矩形的右下角。

  上面的行为准则添加到MFC对话框的OnInitDialog职务P,对话框可以替换成长方形的。:

BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

CRgn rgn;
RGN。 CreateEllipticRgn(0,0,200,100);
SetWindowRgn(rgn,真的)
}

图一 长方形的效应图

四、引起区域的熭手段方法

  运用这种方法引起区域的诉讼顺序如次:

  第一步是绘制您要引起的窗体的时装。。
在CDC类的许多的围攻职务中运用该方法如次:BOOL CDC::换乘 );

  在目前装备周围的事物(DC)中随后测绘的诉讼顺序。。

int CDC::SetBkMode( int nBkMode );

  在测绘中设置放绘制,在这种申请表格中,一定注重nbkmode透明性 。也执意说,当设置了测绘时,放不见得转变。。

  在目前装备周围的事物的装底随后测绘的诉讼顺序。

  在图,优先换乘换乘,以后工具给setbkmode。接下来,您可以换乘CDC的另一个测绘功用来计算。,比如,弧,AngleArc,LineTo,MoveTo,RoundRect,,TextOut等。在听筒完毕手段绘制

  次货步将成果增大区域。

  在这一步中运用SDK API职务

HRGN PathToRegion( HDC hdc );

  是HDC测绘DC控制, 在m_hdc CDC类的围攻变量可以经过即将到来的决定因素。示例,在用纽扣装饰点击事情中添加以下行为准则,目前窗体的时装可以替换成字母行hello。

void CTestDlg::OnTest()
{
HRGN wndRgn;
CClientDC DC(即将到来的)
CFont mFont;

 if (!null)
{
达到最低点(200), 50, 0, 0, FW_HEAVY, TRUE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, 歌体

  开端记载整队的配置文件手段。
();

  将放设置为透明性类型,这句话是电话联络的。。
(透明性)

  CFont * pOldFont;
pOldFont = ( &mFont );
(0, 0, 嘿

  完毕记载整队的手段
( pOldFont );
();

  将记载手段替换为窗体的窗体句柄。
wndRgn = ::PathToRegion();

  为窗体使具有特性的配置文件
this->SetWindowRgn(wndRgn, 真的)
}
}

  CClientDC是派生类CDC,因而即将到来的类有围攻变量和买到CDC类的围攻职务。。

图二 形形效果图

五、由于图像引起区域

  此法引起不规则窗体相对地复杂。率先,预备一张具有目的时装的图片。,设置透明性色,不在意的中心的表格的偏袒的,迹象平稳的的色,比如,蓝色RGB(0),0,255)。顺序运转后,率先装货图片。。以后一个接一个扫描图片的每任一像素。,以防此像素不属于透明性色,则在确切的位引起任一只含任一像素的“region”以后将这些小”region ”合起来结合任一恣意时装的”region”.在这里将运用到CRgn的任一围攻职务 :int CRgn::CombineRgn( CRgn* pRgn1, CRgn* pRgn2, int nCombineMode );

  进入,prgn1,prgn2是两区域合,NCombineMode是合的方法,在这种申请表格中,rgn_or,也执意说,两个区域都合了零件反复部门。。行为准则变卖如次:

void SetupRegion(
CDC *pDC, 整队的DC拨弄
CBitmap &cBitmap, 具有窗体花样的位图宾语
COLORREF TransColor //透明性色
)
{
CDC memDC;
引起任一与输出dc能共处的的暂时DC。
memDC.CreateCompatibleDC(pDC);

 CBitmap *pOldMemBmp=NULL;
将位图选择为暂时DC。
pOldMemBmp=(&cBitmap);

 CRgn wndRgn;
引起总窗体区域,初始区域是0。
wndRgn.CreateRectRgn(0,0,0,0);

 BITMAP bit;
位);/获取位图决定因素,在这里运用位图的上涂料和宽度。

 int y;
为(y=0;y)<=bit.bmHeight ;y++)
{
CRgn rgnTemp; 保养暂时区

  int iX = 0;
do
{
齐足跳行透明性色并找到下任一非透明性点。
while (九 <= bit.bmWidth && memDC.GetPixel(九, y) == TransColor)
iX++;
纪念即将到来的开航点
int iLeftX = iX;

    找寻下任一透明性的色点
while (九 <= bit.bmWidth && memDC.GetPixel(九, y) != TransColor)
++iX;

    在摄取点当中引起任一具有1像素高等的的暂时区域
(iLeftX, y, iX, y+1);

    合到主区域。
(&wndRgn, &rgnTemp, RGN_OR);

   取代暂时区域,要不然下任一金属钱币和过失
();
}while(九 GetWindow();
pWnd->SetWindowRgn(wndRgn,真的)
pWnd->SetForegroundWindow();
}

  上述的行为准则引起的不规则窗体中,在OnEraseBkgnd事情绘制位图,您可以利润与位图时装近似的窗体。。

图三 由于位图和位图中透明性色的整队效果图

六、小结

  引起区域的三种方法,第任一是最复杂的。,以防整队所需的花样是任一复杂的几何图形。,这种方法最适宜的。;次货个轻微地复杂些许。,但所金属钱币的花样更为成形。;第三种方法可以引起少许在图片中排好队伍的窗体时装,只变卖的不同类亦难以完成的的。。

作者:上海卫宫交通 roc责任编辑:方舟)

请关注天极网

最酷的新媒介物信息技术。

经过扫码腰槽证明书

评论

* 互联网网络用户不在意的车站说话。,本站不在意的评论栏中使清洁少许網上商店。、配电盘,警上当!

发表评论

电子邮件地址不会被公开。 必填项已用*标注