程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 創建透明窗體

創建透明窗體

編輯:Delphi

 

 

  也許你曾經看見過這樣的一些窗體,它的一部分是透明的。那麼我們在Delphi中應該怎麼實現這種效果呢?下面的將說到如何實現這種效果:

  一種方法是為你的窗體添加 WS_EX_TRANSPARENT 樣式。雖然它可以動作起來,但是它還不能完全實現我們想要的效果,而且,微軟也建議只為那些運行期比較短的樣式窗體使用 WS_EX_TRANSPARENT 樣式。

  第二種方法就是應用WIN2000所支持的層次化窗體特性。不過這將使你的應用程序只局限在WIN2000下使用。

  本文所采用的是第三種方法。你可以使用 SetWindowRgn API函數精確的指定你所需要窗體顯示的部分。這其中最困難的就是要創建你所要顯示的那部分窗體的區域。解決問題的辦法就是遍歷窗體上所有可視的控件,然後創建包含所有這些小區域的一個巨大的區域。下面是具體的實現:

procedure TForm1.SetRegions;
var
  I: Integer;
  RgnAll, RgnCtrl: HRGN;
begin
  RgnAll := 0;
  for I := 0 to ControlCount - 1 do
  begin
    with Controls[I] do
    begin
      if Visible then
      begin
        // 為所有的可視控件創建一個區域
        RgnCtrl := CreateRectRgn(Left, Top, Left + Width, Top + Height);
        // 組合上面創建的所有區域
        if (RgnCtrl <> 0) and (RgnAll <> 0) then
        begin
          CombineRgn(RgnAll, RgnAll, RgnCtrl, RGN_OR);
          DeleteObject(RgnCtrl);
        end
        else
          RgnAll := RgnCtrl; // 這是第一個創建的區域
      end;
    end;
  end;
  // Now, set the RgnAll as what we see for the Window
  if RgnAll <> 0 then
  begin
    (*
      下面是SetWindowRgn在幫助文件中的注釋:
     ”當調用SetWindowRgn成功後,操作系統將擁有區域句柄hRgn所指定的區域。並且操作系統沒有為這個區域考貝副本。因此,你不應再用這個區域句柄調用其它的函數。特別是不要關閉這個句柄。”
   因此不要在使用SetWindowRgn後對RgnAll調用DeleteObject(感謝Richard Albury指出這點)該文的以前版本就范了以上錯誤。     
    *)
    SetWindowRgn(Handle, RgnAll, True);
  end;
end;

  注意,我在使用完這個區域後應該怎樣調用DeleteObject呢。如果不調用,將導致Windows資源的洩漏。我使用API CreateRectRgn,如果你有不同的形狀也可以使用CreatePolygonRgn。

  你會碰到的一個問題是如何處理窗體中移動的控件。如果你作用程序移動控件(比如:在OnMouseMove事件當中),那麼控件後面的區域將會露出來。同樣,控件在移動後也許不能正確的重畫。這有一個簡單的方法就是重新調用etRegions函數更新窗體中可見的區域,並且調用控件的Repaint方法使控強制性的重畫。如下:
procedure TForm1.GenericMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  // 如果控件沒有移動,則立刻退出。
  if (X - LastX = 0) and (Y - LastY = 0) then Exit;
  // 移動控件
  with (Sender as TControl) do
  begin
    Left := Left + (X - LastX);
    Top := Top + (Y - LastY);
  end;
  SetRegions;
  (Sender as TControl).Repaint;
end;

  現在你將能為你的窗體添加透明的效果了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved