使非標準 Win32 控制項或自畫控制項也具有 Windows XP 的介面風格

來源:互聯網
上載者:User

這裡先說說兩個概念:Theme(主題)和 Visual Style 。Theme 最早出現在 Microsoft Plus! for Windows 95 中,是 Windows 中 Wallpaper、Cursors、Fonts、Sounds 、Icons 等的設定值集合。Visual Style 在 Windows XP 中才被引入,Visual Style 規定了 Contorls 的外觀,另外還包括使用這些外觀的一套 API 。使用 Visual Style 必須要 ComCtl32.dll 6,而 ComCtl32.dll 6 是不能被分發到以前版本的 Windows 中的,所以只能在 Windows XP 下使用 Visual Style。

    Delphi 7 (後面簡稱 7 吧)對 Visual Style 提供了較好的支援。首先 7 將那個 Menifest 封裝成了 VCL - TXPMenifest,另外增加了 UxTheme.pas 單元,裡面是對 Visual Style 的一套 API 及其結構、常數等的引用聲明(大概有 47 個API 函數),更重要的是 7 還增加一個 Themes.pas 單元,裡面是對這套 API 的更進一步的簡化和封裝,7 下的 Win32 控制項對 Visual Style 的支援較 Delphi 6有了很大改觀,就是這個單元的功勞。

    一般來說要使 7 下編譯的程式在 Windows XP 具有 Visual Style ,只需在主表單上放入 VCL - TXPMenifest 即可,但對於一些非標準或是自畫的控制項,還是經典的介面。這裡就說一下如何用 Themes.pas 中提供的方法使這些控制項具有 Visual Style 。

    Themes.pas 中只有一個類:TThemeServices 。這個類有一個重要的屬性: ThemesEnabled (Boolean 類型),就是判斷在當前程式能不能使用 Visual Style ,這個屬性只有在程式使用了 TXPMenifest 並且在 Windows XP 下運行並且使用了 Windows XP 的主題(即桌面主題不是 Windows 經典)才為 True ,由於程式要運行在以前版本的 Windows 下,所以你的程式也得提供這個屬性為 False 時的處理過程(一般就是原有的處理過程)。還要提一下這個類封裝的幾個重要函數:DrawEdge 用來畫控制項邊界的,DrawElement 用來畫整個介面的,DrawText 用來寫字的。這個類還處理了 WM_THEMECHANGED 訊息,這樣當我們在改變桌面主題後,程式會自動調整外觀。再說一下我們最常用到的一個函數(多態函數):GetElementDetails ,這個函數的傳回值在上面的幾個 DrawXXX 函數中要用到,這個函數的輸入值是 24 個枚舉類型中的元素,這 24 個枚舉類型在 Themes.pas 單元開頭定義(從第二個 TThemedButton 開始直到 TThemedWindow)。最後,我們不去直接使用這個類,在 Themes.pas 單元中有一函數:

function ThemeServices: TThemeServices;
傳回值就是這個類,所以我們直接使用這個方法,7 的 VCL 裡都是這樣做。

    好,下面就來個簡單的例子。Delphi 的 TPanel 控制項不是標準控制項,我們就來在它上面實現一下 Visual Style 。在 Delphi 7 中建立一工程,在主表單上放入 TXPMenifest ,在 Unit1 單元引用 Themes 單元,在

TForm1 = class(TForm)
前面加入下代碼(主要是重載 TCustomPanel 的 Paint 方法):

TVSPanel = class(TCustomPanel)
private
  //
protected
  procedure Paint; override;
public
  //
end;
重載的 Paint 方法實現如下:

procedure TVSPanel.Paint;
var
  Details: TThemedElementDetails;
begin
  inherited;
  if ThemeServices.ThemesEnabled then
  begin
    Details := ThemeServices.GetElementDetails(tbPushButtonHot);   {這裡畫個按鈕處於 Hot 狀態下的樣子}
    PerformEraseBackground(Self, Canvas.Handle);      {擦除畫按鈕時的背景}
    ThemeServices.DrawElement(Canvas.Handle, Details, ClientRect);
    ThemeServices.DrawText(Canvas.Handle, Details, Caption, ClientRect,
      DT_EXPANDTABS or DT_VCENTER or DT_CENTER or DT_SINGLELINE, 0);
  end;
end;
TCustomPanel 的改動完成,再就是在主表單的 Create 事件中執行個體化 TVSPanel ,代碼如下:

procedure TForm1.FormCreate(Sender: TObject);
var
  APanel: TVSPanel;
begin
  APanel := TVSPanel.Create(Application);
  APanel.Left := 100;
  APanel.Top := 100;
  APanel.Width := 200;
  APanel.Height := 30;
  APanel.Caption := '具有 Button 風格的 Panel';
  APanel.Parent := Self;
end;
    好了,運行看看 Visual Style 效果是不是出來了。我的程式裡用 THintWindow 做了個浮動視窗並且加上了 Visual Style ,效果還不錯,如果再細緻點的話,就做出和 Windows XP 下微軟拼音IME那個浮動條完全相同的介面了。

    另外,還有幾個重要的東西沒有提及,比如 Part 和 State ,大家可以查 MSDN ,在 User Interface Design and Development \ Windows Shell \ Shell Refrence \ Visual Styles Refrence 裡

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.