⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 异形窗口1.htm

📁 对于学习很有帮助
💻 HTM
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Delphi</title>
</head>

<body>
<!--webbot bot="Include" U-Include="../top.htm" TAG="BODY" startspan --><strong>[top.htm]</strong><!--webbot bot="Include" endspan i-checksum="11293" -->


<table border="0" width="80%" height="2211">
  <tr>
    <td width="100%" align="center" height="33" bgcolor="#99E3EA"><big><font color="#FF0000" face="幼圆"><big><big><strong>DELPHI 学 习 园 地</strong></big></big></font></big></td> 
  </tr> 
  <tr> 
    <td width="100%" height="33" bgcolor="#D6ED7A"><p align="center"><big><strong><font color="#0000FF" face="幼圆"><big><big>在Delphi中实现Windows异形窗口 </big></big></font></strong></big></td> 
  </tr> 
  <tr> 
    <td width="100%" height="2084" bgcolor="#FFFFFF" bordercolor="#FFFFFF"><p align="left">  WINDOWS图形界面应用程序都是基于窗口的。在Windows操作系统中,窗口是应用程序与用户之间的界面。微软对窗口的定义是:窗口是屏幕上的一块方形部分,用来显示输出和接受用户的输入。编写基于Windows  
    的GUI程序首先要做的事情之一便是创建一个或多个窗口。我们通常使用CreateWindow和CreateWindowEx这两个API函数创建窗口,此外通过DialogBox,CreateDialog和MessageBox等函数还可以创建特殊用途的窗口(如对话框、消息框等)。  
    <br> 
        不管是以上哪个函数,都将无一例外的得到矩形窗口。但是,有时为了实现特殊效果,有时希望使用不规则形状的窗口。而本文就将探讨怎样实现这些异形窗<br>
    口,如圆形、椭圆形、星形等窗口。 <br>
        为了实现不规则形状的窗口,需要用到“区域”(Region)这一概念。在微软<br>
    Windows操作系统中,区域是指能对其进行填充、绘制、加边框、颜色翻转等操作<br>
    的长方形、(椭)圆形、多边形,或者这些形状的叠加。 <br>
       <font color="#0000FF"> <font face="隶书">区域的创建</font> </font><br>
        通过以下API函数,我们可以创建区域,它们是:CreateRectRgn(长方形<br>
    ),CreateRoundRectRgn(圆角长方形),CreateEllipticRgn(圆形和椭圆<br>
    形),以及CreatePolygonRgn和CreatePolyPolygonRgn。如果调用成功的话,<br>
    它们都会返回一个指向新建区域的句柄。下面先简单地介绍CreatePolygonRgn和<br>
    CreateEllipticRgn的用法: <br>
        HRGN CreatePolygonRgn( //创建多边形区域 <br> 
         CONST POINT *lppt, //指向一个POINT类型的数组 <br> 
         int cPoints, //数组中元数的个数 <br> 
         int fnPolyFillMode //多边形填充模式 ); <br> 
        HRGN CreateEllipticRgn( //创建圆形或者椭圆形区域 <br> 
        int nLeftRect, //(椭)圆外切长方形左上角的X坐标 <br> 
        int nTopRect, //(椭)圆外切长方形左上角的Y坐标 <br> 
         int nRightRect, //(椭)圆外切长方形右下角的X坐标 <br> 
         int nBottomRect //(椭)圆外切长方形右下角的Y坐标 ); <br> 
        区域的一个非常重要的性质是:任意两个区域可以进行合成操作,进而生成一<br>
    个新的区域。 <br>
        <big><font face="隶书" color="#0000FF">区域的合成</font></big> <br>
        利用已有的区域可以合成新的区域,这便是函数CombineRgn的作用。该函数<br>
    的C语言原型声明如下: <br>
        int CombineRgn( <br> 
         HRGN hrgnDest, // 指向目的区域 <br> 
         HRGN hrgnSrc1, // 指向源区域 <br> 
         HRGN hrgnSrc2, // 指向源区域 <br> 
         int fnCombineMode // 区域结合模式    ); <br> 
        在上述函数中,第二、三个参数为源区域;第一个参数hrgnDest指向的是目的<br>
    区域,这块区域将用来盛放由hrgnSrc1和hrgnSrc2合成的新区域,所以必须保证<br>
    hrgnDest所指向的区域在调用函数CombineRgn之前已经存在。 <br>
        第四个参数,即fnCombineMode,指明了合成方式,它的取值及含义如下所<br>
    示: </p>
    <table border="1" width="100%">
      <tr>
        <td width="22%"><font face="幼圆" color="#FF0000"><strong>合成方式</strong></font> </td>
        <td width="78%"><font face="幼圆" color="#FF0000"><strong>含 义</strong></font></td>
      </tr>
      <tr>
        <td width="22%">RNG_AND</td>
        <td width="78%">新区域为两块源区域的相交部分</td>
      </tr>
      <tr>
        <td width="22%">RNG_COPY </td>
        <td width="78%">新区域为第一块源区域的拷贝</td>
      </tr>
      <tr>
        <td width="22%">RNG_DIFF</td>
        <td width="78%">新区域为第一块源区域减去与第二块源区域共有的部分</td>
      </tr>
      <tr>
        <td width="22%">RNG_OR</td>
        <td width="78%">新区域为两块源区域的并集</td>
      </tr>
      <tr>
        <td width="22%">RNG_XOR </td>
        <td width="78%">新区域为两块源区域的非公共部分的并集</td>
      </tr>
    </table>
    <p align="left">  <big><font face="隶书" color="#0000FF">区域的使用</font></big> 
    <br>
      创建或者合成了一定形状的区域之后,并不能看到任何东西。区域要与具体的<br>
    窗口结合才能起作用。把区域同窗口挂起钩来,要用到名为SetWindowRgn的API函<br>
    数。它的原型如下: <br>
      int SetWindowRgn( <br> 
       HWND hWnd, // 指向窗口区域已被设定好的窗口 <br> 
       HRGN hRgn, // 指向区域 <br> 
       BOOL bRedraw // 窗口重画标志    ); <br> 
      当成功地调用了此函数后,操作系统将拥有hRgn所指定的那块区域。区域的坐<br>
    标是相对于窗口的左上角(包括标题区在内)。窗口中只有在区域内的那部分是可<br>
    见的,对位于区域之外的窗口部分,系统将不予显示。也就是说,窗口表现出来的<br>
    形状与区域的形状是一样的(当然这还有个条件,那就是窗口不得比区域小)。为<br>
    了调整窗口的大小,可先用API函数GetRgnBox获取区域的大小(即长与宽),再<br>
    根据获得的数据(在p2中)来相应地调整窗口的长和宽: <br>
      function GetRgnBox(RGN: HRGN; var p2: TRect): Integer; stdcall;<br> 
      有了上面介绍的这些关于区域的知识,就足以实现这些异形窗口了。 
    <br>
      异形窗口示例程序 <br>
      笔者用Delphi编写了一个示例程序,它实现了5种形状的窗口(图1中列出了其<br>
    中四种)。希望该示例程序能有助于读者加深对区域的理解和运用。 
    <br>
      以下是程序的主单元代码: <br>
      //Create windows in special shapes. <br> 
      //Press CTRL+S to exit this program. <br> 
      unit Shapes; <br> 
      interface <br>
      uses <br>
       Windows, Messages, SysUtils, Classes, Graphics, <br> 
       Controls, Forms, Dialogs, ExtCtrls, StdCtrls; <br> 
      const HOTKEYID=1; <br> 
      type <br>
       TShape = class(TForm) <br> 
       Timer1: TTimer; <br> 
       procedure FormCreate(Sender: TObject); <br> 
       procedure FormDestroy(Sender: TObject); <br> 
       procedure Timer1Timer(Sender: TObject); <br> 
       private <br> 
       procedure WMHOTKEY(var Msg:TWMHotKey);message WM_HOTKEY; <br> 
       end; <br> 
    <br> 
      var <br>
       Tick:Integer; <br> 
       Shape: TShape; <br> 
       Rgn, Rgn1:THandle; <br> 
       XX,YY:Integer; <br> 
       Triangle:array[0..2] of TPoint <br> 
       =((x:30;y:0),(x:0;y:60),(x:60;y:60)); <br> 
      Diamond:array[0..3] of TPoint <br> 
       =((x:30;y:0),(x:60;y:50),(x:30;y:100),(x:0;y:50)); <br> 
       Star:array[0..4]of TPoint=((x:34;y:0), (x:0;y:73), <br> 
       (x:75;y:28),(x:3;y:28),(x:64;y:73)); <br> 
      implementation <br>
      {$R *.DFM} <br> 
      procedure TShape.FormCreate(Sender: TObject); <br> 
      begin <br>
       Timer1.Interval:=99; <br> 
       BorderStyle:=bsNone; <br> 
      { <br>
      下条语句将Application窗口的扩展风格重新设 <br>
      为WS_EX_TOOLWINDOW,这样程序运行时就不会在 <br>
      任务栏上出现一个小图标。 <br>
      } <br>
       Timer1Timer(self); <br> 
      SetWindowLong(Application.Handle,GWL_ExStyle,WS_EX_ToolWindow); <br> 
      //为窗口注册Ctr+S 热键 <br> 
       RegisterHotKey(Handle,HOTKEYID,MOD_CONTROL,ord('S')); <br> 
      end; <br>
      procedure TShape.FormDestroy(Sender: TObject); <br> 
      begin <br>
      DeleteObject(Rgn); <br>
      UnregisterHotKey(Handle,HOTKEYID); <br>
      end; <br>
       <br>
      procedure TShape.WMHOTKEY(var Msg:TWMHotKey); <br> 
      begin <br>
      //检测到Ctrl+S 热键时退出程序 <br> 
      if (Msg.HotKey=HOTKEYID) then Close <br> 
      else inherited; <br> 
      end; </td>
  </tr>
  <tr>
    <td width="100%" height="37" bgcolor="#7CBDDC"><p align="right"><a href="Delphi2-2.htm"><img src="../images/goto.gif" alt="下一页" WIDTH="49" HEIGHT="23"><strong><big>下一页</big></strong></a></td>
  </tr>
</table>
<!--webbot bot="Include" U-Include="../wei1.htm" TAG="BODY" startspan --><strong>[wei1.htm]</strong><!--webbot bot="Include" endspan i-checksum="9818" -->

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -