windows异性窗体.docx

上传人:b****3 文档编号:27018546 上传时间:2023-06-25 格式:DOCX 页数:9 大小:17.68KB
下载 相关 举报
windows异性窗体.docx_第1页
第1页 / 共9页
windows异性窗体.docx_第2页
第2页 / 共9页
windows异性窗体.docx_第3页
第3页 / 共9页
windows异性窗体.docx_第4页
第4页 / 共9页
windows异性窗体.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

windows异性窗体.docx

《windows异性窗体.docx》由会员分享,可在线阅读,更多相关《windows异性窗体.docx(9页珍藏版)》请在冰豆网上搜索。

windows异性窗体.docx

windows异性窗体

windows异性窗体

  WINDOWS图形界面应用程序都是基于窗口的。

在Windows操作系统中,窗口是应用程序与用户之间的界

面。

微软对窗口的定义是:

窗口是屏幕上的一块方形部分,用来显示输出和接受用户的输入。

编写基于

Windows的GUI程序首先要做的事情之一便是创建一个或多个窗口。

我们通常使用CreateWindow和

CreateWindowEx这两个API函数创建窗口,此外通过DialogBox,CreateDialog和MessageBox等函数还可以

创建特殊用途的窗口(如对话框、消息框等)。

  不管是以上哪个函数,都将无一例外的得到矩形窗口。

但是,有时为了实现特殊效果,有时希望使用不

规则形状的窗口。

而本文就将探讨怎样实现这些异形窗口,如圆形、椭圆形、星形等窗口。

 

  为了实现不规则形状的窗口,需要用到“区域”(Region)这一概念。

在微软Windows操作系统中,区域

是指能对其进行填充、绘制、加边框、颜色翻转等操作的长方形、(椭)圆形、多边形,或者这些形状的叠

加。

  区域的创建

  通过以下API函数,我们可以创建区域,它们是:

CreateRectRgn(长方形),CreateRoundRectRgn

(圆角长方形),CreateEllipticRgn(圆形和椭圆形),以及CreatePolygonRgn和

CreatePolyPolygonRgn。

如果调用成功的话,它们都会返回一个指向新建区域的句柄。

下面先简单地介绍

CreatePolygonRgn和CreateEllipticRgn的用法:

  HRGNCreatePolygonRgn(//创建多边形区域

  CONSTPOINT*lppt,//指向一个POINT类型的数组

  intcPoints,//数组中元数的个数

  intfnPolyFillMode//多边形填充模式

  );

  HRGNCreateEllipticRgn(//创建圆形或者椭圆形区域

  intnLeftRect,//(椭)圆外切长方形左上角的X坐标

  intnTopRect,//(椭)圆外切长方形左上角的Y坐标

  intnRightRect,//(椭)圆外切长方形右下角的X坐标

  intnBottomRect//(椭)圆外切长方形右下角的Y坐标

  );

  区域的一个非常重要的性质是:

任意两个区域可以进行合成操作,进而生成一个新的区域。

  区域的合成

  利用已有的区域可以合成新的区域,这便是函数CombineRgn的作用。

该函数的C语言原型声明如下:

  intCombineRgn(

  HRGNhrgnDest,//指向目的区域

  HRGNhrgnSrc1,//指向源区域

  HRGNhrgnSrc2,//指向源区域

  intfnCombineMode//区域结合模式

  );

  在上述函数中,第二、三个参数为源区域;第一个参数hrgnDest指向的是目的区域,这块区域将用来盛

放由hrgnSrc1和hrgnSrc2合成的新区域,所以必须保证hrgnDest所指向的区域在调用函数CombineRgn之前

已经存在。

  第四个参数,即fnCombineMode,指明了合成方式,它的取值及含义如表1所示:

  表1

  合成方式 含义

  RNG_AND新区域为两块源区域的相交部分。

  RNG_COPY新区域为第一块源区域的拷贝。

  RNG_DIFF新区域为第一块源区域减去与第二块源区域共有的部分。

  RNG_OR新区域为两块源区域的并集。

  RNG_XOR新区域为两块源区域的非公共部分的并集。

  区域的使用

  创建或者合成了一定形状的区域之后,并不能看到任何东西。

区域要与具体的窗口结合才能起作用。

区域同窗口挂起钩来,要用到名为SetWindowRgn的API函数。

它的原型如下:

  intSetWindowRgn(

  HWNDhWnd,//指向窗口区域已被设定好的窗口

  HRGNhRgn,//指向区域

  BOOLbRedraw//窗口重画标志

  );

  当成功地调用了此函数后,操作系统将拥有hRgn所指定的那块区域。

区域的坐标是相对于窗口的左上角

(包括标题区在内)。

窗口中只有在区域内的那部分是可见的,对位于区域之外的窗口部分,系统将不予显

示。

也就是说,窗口表现出来的形状与区域的形状是一样的(当然这还有个条件,那就是窗口不得比区域

小)。

为了调整窗口的大小,可先用API函数GetRgnBox获取区域的大小(即长与宽),再根据获得的数据

(在p2中)来相应地调整窗口的长和宽:

  functionGetRgnBox(RGN:

HRGN;varp2:

TRect):

Integer;stdcall;

  有了上面介绍的这些关于区域的知识,就足以实现这些异形窗口了。

 异形窗口示例程序

  笔者用Delphi编写了一个示例程序,它实现了5种形状的窗口(图1中列出了其中四种)。

希望该示例程

序能有助于读者加深对区域的理解和运用。

  以下是程序的主单元代码:

  //Createwindowsinspecialshapes.

  //PressCTRL+Stoexitthisprogram.

  unitShapes;

  interface

  uses

  Windows,Messages,SysUtils,Classes,Graphics,

  Controls,Forms,Dialogs,ExtCtrls,StdCtrls;

  

  constHOTKEYID=1;

  

  type

  TShape=class(TForm)

  Timer1:

TTimer;

  procedureFormCreate(Sender:

TObject);

  procedureFormDestroy(Sender:

TObject);

  procedureTimer1Timer(Sender:

TObject);

  private

  procedureWMHOTKEY(varMsg:

TWMHotKey);messageWM_HOTKEY;

  end;

  

  var

  Tick:

Integer;

  Shape:

TShape;

  Rgn,Rgn1:

THandle;

  XX,YY:

Integer;

  

  Triangle:

array[0..2]ofTPoint

  =((x:

30;y:

0),(x:

0;y:

60),(x:

60;y:

60));

  

  Diamond:

array[0..3]ofTPoint

  =((x:

30;y:

0),(x:

60;y:

50),(x:

30;y:

100),(x:

0;y:

50));

  

  Star:

array[0..4]ofTPoint=((x:

34;y:

0),(x:

0;y:

73),

  (x:

75;y:

28),(x:

3;y:

28),(x:

64;y:

73));

  

  implementation

  {$R*.DFM}

  procedureTShape.FormCreate(Sender:

TObject);

  begin

  Timer1.Interval:

=99;

  BorderStyle:

=bsNone;

  {

  下条语句将Application窗口的扩展风格重新设

  为WS_EX_TOOLWINDOW,这样程序运行时就不会在

  任务栏上出现一个小图标。

  }

  Timer1Timer(self);

  SetWindowLong(Application.Handle,GWL_ExStyle,WS_EX_ToolWindow);

  //为窗口注册Ctr+S热键

  RegisterHotKey(Handle,HOTKEYID,MOD_CONTROL,ord('S'));

  end;

  

  procedureTShape.FormDestroy(Sender:

TObject);

  begin

  DeleteObject(Rgn);

  UnregisterHotKey(Handle,HOTKEYID);

  end;

  

  procedureTShape.WMHOTKEY(varMsg:

TWMHotKey);

  begin

  //检测到Ctrl+S热键时退出程序

  if(Msg.HotKey=HOTKEYID)thenClose

  elseinherited;

  end;

  

  procedureTShape.Timer1Timer(Sender:

TObject);

  varRect:

TRect;

  cl:

Integer;

  begin

  Randomize;

  cl:

=Random($2FFFFFFF);

  

  Tick:

=Tickmod300;

  //每隔一定时间变换一次形状

  caseTickof

  0:

//五星形

  begin

  Rgn:

=CreatePolygonRgn(Star,5,0);

  SetWindowRgn(Handle,Rgn,TRUE);

  GetRgnBox(Rgn,Rect);

  Width:

=Rect.Right-Rect.Left;

  Height:

=Rect.Bottom-Rect.Top;

  Color:

=cl;

  end;

  60:

//圆形

  begin

  Rgn:

=CreateEllipticRgn(0,0,60,60);

  SetWindowRgn(Handle,Rgn,TRUE);

  GetRgnBox(Rgn,Rect);

  Width:

=Rect.Right-Rect.Left;

  Height:

=Rect.Bottom-Rect.Top;

  Color:

=cl;

  end;

  120:

//圆环形

  begin

  Rgn:

=CreateEllipticRgn(0,0,60,60);

  Rgn1:

=CreateEllipticRgn(15,15,45,45);

  CombineRgn(Rgn,Rgn,Rgn1,RGN_XOR);

  DeleteObject(Rgn1);

  SetWindowRgn(Handle,Rgn,TRUE);

  GetRgnBox(Rgn,Rect);

  Width:

=Rect.Right-Rect.Left;

  Height:

=Rect.Bottom-Rect.Top;

  Color:

=cl;

  end;

  180:

//棱形

  begin

  Rgn:

=CreatePolygonRgn(Diamond,4,0);

  SetWindowRgn(Handle,Rgn,TRUE);

  GetRgnBox(Rgn,Rect);

  Width:

=Rect.Right-Rect.Left;

  Height:

=Rect.Bottom-Rect.Top;

  Color:

=cl;

  end;

  240:

//三角形

  begin

  Rgn:

=CreatePolygonRgn(Triangle,3,0);

  SetWindowRgn(Handle,Rgn,TRUE);

  GetRgnBox(Rgn,Rect);

  Width:

=Rect.Right-Rect.Left;

  Height:

=Rect.Bottom-Rect.Top;

  Color:

=cl;

  end;

  end;//case

  

  inc(Tick);

  

  ifLeft>Screen.Width-WidththenXX:

=-Random(20)

  elseifLeft  ifTop>Screen.Height-HeightthenYY:

=-Random(20)

  elseifTop  if(XX>-3)and(XX  if(YY>-3)and(YY  //移动窗口

  SetWindowPos(Handle,HWND_TOPMOST,Left+XX,Top+YY,Width,Height,SWP_NOACTIVATE);

  end;

  

  end.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1