2010-03-01 100 views
7

是的,這又是一個問題:如何更改啓用主題的控件的字體顏色?

如何在啓用主題的應用程序上使用Delphi7-> Delphi2007更改TCheckBox(或任何處理控件)的字體顏色?

在互聯網上,並在此網站上閱讀了很多之後,我找到4種回答:

  1. 和大多數populare(甚至從QC):你不能,它的設計像微軟。
  2. 創建,讓像你想你畫它的組件。
  3. 購買昂貴的組件集,吸引了像你想要的。
  4. 不要使用主題。

OK,但我仍然不滿這一點。

給予一個屬性/數據他有一個表格上的狀態的用戶反饋有色,似乎合法的給我。

然後我剛安裝的MSVC#2008 Express版本,那叫一個驚喜,他們可以改變(複選框的財產前景色)的字體顏色然後呢?

它似乎並沒有成爲一個「它的設計那樣,由微軟。」那麼現在問題又來了:

我怎樣才能改變一個TCheckBox的字體顏色(或任何處理的對照)與德爾福7至2007年德爾福在啓用主題的應用程序?

+0

什麼讓你覺得Visual Studio的開發人員不是簡單地使用選項2? – 2010-03-01 15:06:07

+0

好吧,我並不需要,而試圖重現「它的設計就是這樣,由微軟。」。在C#上。 我已將ForeColor設置爲紅色,併爲我的複選框獲取紅色標題。 – 2010-03-01 17:50:49

回答

0

選項5.使用T優等作爲基材的選擇,並覆蓋在控制了所有的繪畫消息(是的,你可以把它叫做一個組成部分,但控制是可見的部件名稱,以便您更應使用)的控制。簡單地捕捉WM_PAINT,可能是WM_NCPAINT,您可以用自己的風格繪製控件。至少您可以重複使用控件的全部功能。只要你不改變佈局,只有顏色你不需要改變hitousts mousedown。移動等等

注:我有重寫TCustomEdit的經驗,允許所有種類的顏色,背景文本,額外的按鈕等。它花了相當一段時間纔得到它的權利,並閱讀MSDn的所有文件和KB以確保控制能夠做到我想要的功能。

+0

我明白,不是作爲選項5,而是作爲選項2a和我的選項2作爲選項2b; ^)! 但是爲什麼C#不需要重寫wm_paint方法來更改複選框組件的字體顏色的顏色? – 2010-03-01 15:42:38

+0

@愛德華。名稱中包含的內容不需要它:c#擁有自己的控制層(Microsoft每年爲.NET環境提供一個新的控件),Delphi使用自Windows 95以來存在的相同控件。因此,更穩定,但有時你付出的代價是簡單的事情變得更加困難; GDI已經很老了,但我認爲在十年內,GDi仍然存在,你應該如何處理你的WinForms應用程序?考慮一下! – 2010-03-01 16:52:23

+0

我知道GDI已經很老了,我開始使用它,當我在Borland Object pascal上做了第一步,就像1988年的「windows 2」。你說的是:C#可以做到這一點,因爲他們正在使用除了啓用主題的delphi使用的控件之外,還有一組不同的控件?由於主題是負責繪製新的東西,我會假設delphi使用相同的組件(至少是庫)比C#使用。 – 2010-03-01 18:04:34

2

哦,不過你可以!

只需將您的窗體的這之前聲明:

TCheckBox = class(StdCtrls.TCheckBox) 
public 
    procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC; 
end; 

TCheckBox的這種重新聲明是現在使用在運行時的類型從窗體的DFM流。現在,實現這樣的消息:

procedure TCheckBox.CNCtlColorStatic(var Message: TWMCtlColorStatic); 
begin 
    SetTextColor(Message.ChildDC, ColorToRGB(clRed)); // or RGB(255,0,0)); 
    SetBkMode(Message.ChildDC, TRANSPARENT); 
    Message.Result := GetStockObject(NULL_BRUSH); 
end; 

這個陷阱的WM_CTLCOLORSTATIC消息,改變文字顏色爲紅色。這對我來說是非主題模式(使用WinXP classic) - 但不適用於主題模式。

你應該知道,爲了讓主題的控制給你這個消息時,控制應該提供DTPB_USECTLCOLORSTATIC標誌的主題繪圖API的。可悲的是,這不是默認行爲,我也不知道如何去做。看看this的問題。

1

以下是我在我的應用程序解決了這個:

  1. 解除複選框中的標題,使之更小 - 只是大足以顯示沒有字幕的實際複選框。
  2. 將一個TLabel放在複選框旁邊以充當標題。
  3. 在Label的OnClick事件中,切換複選框的狀態。
  4. 如果標籤具有Alt +字母鍵盤加速器,請使窗體處理CM_DIALOGCHAR消息。複製TLabel源代碼中的消息處理程序,並添加一行以切換複選框的狀態。

這不是一個真正的複選框,它比我想要的工作多一點,但它在我的應用程序(它只有一個複選框需要這種處理)時效果不錯。

4

這需要一定的調整是完美的解決方案,但爲我工作:

添加2的方法來你的CheckBox組件

FOriginalCaption: string; 
    _MySetCap: Boolean; 
    procedure WMPaint(var msg: TWMPaint); message WM_PAINT; 
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; 

和實施這樣:

procedure TMyCheckbox.CMTextChanged(var Message: TMessage); 
begin 
    inherited; 
    if _MySetCap then Exit; 
    FOriginalCaption := Caption; 
end; 

procedure TMyCheckbox.WMPaint(var msg: TWMPaint); 
var 
    BtnWidth: Integer; 
    canv: TControlCanvas; 
begin 
    BtnWidth := GetSystemMetrics(SM_CXMENUCHECK); 

    _MySetCap := True; 
    if not (csDesigning in ComponentState) then 
    Caption := ''; 
    _MySetCap := False; 
    inherited; 
    canv := TControlCanvas.Create; 
    try 
    canv.Control := Self; 
    canv.Font := Font; 
    SetBkMode(canv.Handle, Ord(TRANSPARENT)); 
    canv.TextOut(BtnWidth + 1, 2, FOriginalCaption); 
    finally 
    canv.Free; 
    end; 
end; 
+0

我相信這應該被標記爲答案,很好的工作! – 2018-03-08 17:11:13