简单!!! 这样做: (我以前写的)
procedure loadmask(Filename : string);
var
   maskfile : tfilestream;
   rgnsize : integer;
   rgndata : prgndata;
   winregion : hrgn;
begin
      maskfile := tfilestream.Create('xxx.msk'),fmopenread);
      maskfile.Read(rgnsize,4);
      if rgnsize<>0 then
      begin
         getmem(rgndata,rgnsize);
         maskfile.Read(rgndata^,rgnsize);
         winregion := extcreateregion(nil,rgnsize,rgndata^);
         setwindowrgn(form1.Handle,winregion,true);
      end;
      maskfile.Free;
   config.Free;
end;生成区域文件unit Unit3;
////ok ok ok ok  !!!!!!!!!!!!!
interfaceuses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtDlgs, ExtCtrls, StdCtrls, ComCtrls;type
  TForm3 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    OpenDialog: TOpenPictureDialog;
    SaveDialog: TSaveDialog;
    Image2: TImage;
    Button3: TButton;
    Label1: TLabel;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Image2MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;  TCreateThread = class(TThread)
  public
     Bitmap : TBitmap;
     TransColor : TColor;
     Filename : String;
     Value : integer;
     Total: integer;
     Finished : boolean;
  private
     procedure process;
  protected
     procedure execute;override;
  end;
var
  Form3: TForm3;
  cv_color : tcolor;
  Rgnx : integer;
  Rgny : integer;
  selected : boolean;
  createthread : Tcreatethread;
implementation{$R *.DFM}procedure TCreateThread.process;
begin
//   bitmap.Canvas.Pixels[rgnx,rgny] := clblue;
   form3.Label1.Caption := inttostr(rgny);
   if finished then
   begin
      form3.Cursor := crdefault;
      beep;
      form3.UpdateWindowState;
      form3.Caption :='Generate Skin Mask';
      form3.button1.Enabled := true;
      form3.button2.Enabled := true;
      form3.button3.Enabled := true;
   end;end;procedure TCreateThread.execute;
var
   x,y : integer;
   RgnSize : integer;
   RgnData : pRgnData;
   OutFile : TFileStream;
   Rgn1, Rgn2 : hrgn;
   StartPos ,EndPos : integer;
begin
   finished := false;
   rgn1 :=0;
   rgn2 :=0;
   total := bitmap.Height -1;
   for y:= 0 to bitmap.Height -1 do
   begin
      value := y;
      x := 0;
      endpos := 0;
         repeat
            startpos := x;
            inc(x);
            while(bitmap.Canvas.Pixels[x,y]<>transcolor) and (x<=bitmap.Width ) do
            begin
               rgnx := x;
               rgny := y;
               synchronize(process);
               inc(x);
            end;
            endpos := x;
            if startpos <> bitmap.Width then
            begin
               if endpos = bitmap.Width then dec(endpos);
               if rgn1 = 0 then
               begin
                  rgn1 := createrectrgn(startpos+1,y,endpos,y+1);
               end
               else
               begin
                  rgn2 := createrectrgn(startpos+1,y,endpos,y+1);
                  if rgn2 <>0 then combinergn(rgn1,rgn1,rgn2,rgn_or);
                  deleteobject(rgn2);
               end;
            end;
         until x>= bitmap.Width -1;
        synchronize(process);
   end;
   if (rgn1<>0) then
   begin
      outfile := TfileStream.Create(filename,fmcreate or fmsharedenywrite);
      rgnsize := getregiondata(rgn1,0,nil);
      getmem(rgndata,rgnsize);
      getregiondata(rgn1,rgnsize,rgndata);
      outfile.Write(rgnsize,sizeof(rgnsize));  //need?
      outfile.Write(rgndata^,rgnsize);
      freemem(rgndata,rgnsize);
      outfile.Free;
   end;
   finished := true;
   synchronize(process);
end;procedure TForm3.Button2Click(Sender: TObject);
begin
   if not selected then
   begin
      application.MessageBox('Please select a color.','Message', mb_ok);
      exit;
   end;
   with savedialog do
   begin
      if not execute then exit;
      form3.Caption := 'Generate Skin Mask -- Working...Please Wait.';
      form3.Refresh;
      form3.Cursor := crhourglass;
      form3.button1.Enabled := false;
      form3.button2.Enabled := false;
      form3.button3.Enabled := false;
      createthread:= Tcreatethread.Create(true);
      createthread.Bitmap := image2.picture.bitmap;
      createthread.TransColor := cv_color;
      createthread.Filename := ChangeFileExt(fileName, '.msk');
      createthread.FreeOnTerminate := true;
      createthread.Resume;
   end;
end;procedure TForm3.Button1Click(Sender: TObject);
begin
   with opendialog do
   begin
      if not execute then exit;
      image2.Picture.LoadFromFile(filename);
   end;
   selected := false;
   with image2 do
   begin
      top := 8;
      left:=72;
      if left+width+10<=276  then
         form3.Width := 276
      else
         form3.Width := left+width+10;
      if top+height+30<= 194 then
         form3.Height := 194
      else
         form3.Height := top+height+30;
  end;
end;procedure TForm3.Image2MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
   cv_fill : trect;
begin
   cv_color := image2.Picture.Bitmap.Canvas.Pixels[x,y];
   selected := true;
   with cv_fill do
   begin
      left:= 0;
      top:= 0;
      right := 57;
      bottom := 57;
   end;
   with image1 do
   begin
      Canvas.Brush.Color := cv_color;
      Canvas.FillRect(cv_fill);
   end;
end;procedure TForm3.Button3Click(Sender: TObject);
begin
   close;
end;end.

解决方案 »

  1.   

    iriscat:谢谢,我试一下,如果行的话,我明天给你加分!
      

  2.   

    其实没这么复杂的。你可以使用Window API函数很方便的实现。本来我可以告诉你怎么做的,我的机子里就有这方面的资料,但我是在网吧上机,实在是不好意思。有空再回来跟你说。我现在尽量想吧。Windows程序下的每个窗体都有一个消息返回该窗体的形状,......我实在是记不清了,总之使用一个Windows API函数就能完成你所要的(包括三角形、圆形、圆角矩形......等等)。
      我这里建议你到书店去买一本新书《特效视窗__Delphi高级开发实例》RMB39.00元,里面有一个例子就是关于做不规则窗体的,一个不规则小天使外形加一个说话框。
      

  3.   

    还可以做像Winamp类似的“磁性”窗。可我.......现在暂时是没办法告诉你了。因为我不能常到外面来上网的。我是军人。与我联第吧!
      

  4.   

    试试
    var H: THandle;H:=CreateEllipticRgn(0,0,width, hight);
    SetWindowRgn(Handle, H, TRUE);
    会把窗口改为椭圆形
      

  5.   

    很多DELPHI网站都有,搜索一下吧
      

  6.   

    其实用SetWindowRgn这个API函数就可以,大不了查MSDN或DELPHI的帮助文件,不要太
      

  7.   

    unit shaps;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ExtCtrls;
    const HOTKEYID      = 1;
    type
      Tshape = class(TForm)
        Timer1: TTimer;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
        procedure WMHOTKEY(var Msg: TWMHotKey); message WM_HOTKEY;
      public
        { Public declarations }
      end;var Shape           : TShape;
      Tick              : Integer;
      Rgn, Rgn1         : THandle;
      XX, YY            : Integer;
      Triangle          : array[0..2] of TPoint
                        = ((x: 30; y: 0), (x: 0; y: 60), (x: 60; y: 60));
      Diamond           : array[0..3] of TPoint
                        = ((x: 30; y: 0), (x: 60; y: 50), (x: 30; y: 100), (x: 0; y:
        50));
      Star              : array[0..4] of TPoint = ((x: 34; y: 0), (x: 0; y: 73),
        (x: 75; y: 28), (x: 3; y: 28), (x: 64; y: 73));implementation{$R *.DFM}procedure Tshape.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;procedure Tshape.FormDestroy(Sender: TObject);
    begin
      DeleteObject(Rgn);
      UnregisterHotKey(Handle, HOTKEYID);
    end;procedure Tshape.Timer1Timer(Sender: TObject);
    var Rect            : TRect;
        cl              : Integer;
    begin
      Randomize;
      cl := Random($2FFFFFFF);
      Tick := Tick mod 300;
    //每隔一定时间变换一次形状
      case Tick of
        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);
      if Left > Screen.Width - Width then XX := -Random(20)
      else if Top > Screen.Height - Height then YY := -Random(20)
      else if (XX > -3) and (YY > -3) then  //移动窗口
        SetWindowPos(Handle, HWND_TOPMOST, Left + XX, Top + YY, Width,
          Height, SWP_NOACTIVATE);
    end;procedure TShape.WMHOTKEY(var Msg: TWMHotKey);
    begin                                   //检测到Ctrl+S 热键时退出程序
      if (Msg.HotKey = HOTKEYID) then Close
      else inherited;
    end;end.
    这是我从一本书上看到的。
      

  8.   

    procedure TForm1.DrawRndRectRegion;
    var Rgn: HRgn;
        Rect: TRect;
    begin
      Rect := Self.Canvas.ClipRect;
      Rgn := CreateRoundRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom, 30, 30);//圆角矩形
      SetWindowRgn(Self.Handle, Rgn, TRUE);
    end;
    另外:
    CreateEllipticRgn(椭圆),CreatePolygonRgn(多边形)
      

  9.   

    根据位图的透明色生成任意的RGN,效果惊人,DELPHI BCB 均可直接编译,可生成异型的FORM,
    BUTTON,LABEL....改动HANDLE即可!
    MAIL:[email protected]
      

  10.   

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

  11.   

    多谢大家这么多天来的支持与厚爱,对此表示感谢!
    Thanks: iriscat、dzogchen、zgb、wfmwg(排名不分先后)
    其实很多东西在DELPHI的SDK帮助里面就可以找到,只不过有时太懒而已。
    谢谢大家!