2012-02-03 4 views
4

내 양식의 컨트롤에서 색상을 사용하지 않도록 설정하는 예제를 따르려고합니다.Delphi XE2 : 구성 요소에서 vcl 스타일 사용 안 함

TStyleManager.Engine.RegisterStyleHook (ClrMeans.TwwDBComboDLG, TEditStyleHook);

하지만 타사 컨트롤 (infowower TwwDBComboDlg) 또는 표준 VCL TEdit 중 하나를 등록하거나 등록을 취소 할 때 예외가 발생합니다. 누구나이 문제 또는 제안 사항에 문제가있는 경우

+0

예외는 무엇입니까? – RRUZ

+0

위의 호출에 대한 액세스 위반입니다. 그것의 구성 요소를 비활성화하려고 양식의 초기화 부분에. – mike

+0

TStyleManager.Engine.RegisterStyleHook을 시도해보십시오 (ClrMeans.TwwDBComboDLG, TStyleHook); – RRUZ

답변

3

여기에서 link에 대해 알아야 할 사항이 설명되어 있습니다.

기본적으로 이미 알고있는 "null 후크"를 넣거나 누락 된 부분의 절반 인 "VCL 색상"후크를 넣어야합니다. 나머지 절반은 포인터없는 문제입니다.

이 (당신처럼)은 TEdit 유도체를 만들기 위해 VCL 표준 색상처럼 당신이 당신의 컨트롤을 사용하여 작업 할 수 있도록하는 데 필요한 코드를 보는 것은 이것이다 :

uses 
    Winapi.Messages, 
    Vcl.Controls, 
    Vcl.StdCtrls, 
    Vcl.Forms, 
    Vcl.Themes, 
    Vcl.Styles; 

type 

TEditStyleHookColor = class(TEditStyleHook) 
    private 
    procedure UpdateColors; 
    protected 
    procedure WndProc(var Message: TMessage); override; 
    constructor Create(AControl: TWinControl); override; 
    end; 

implementation 


type 
TWinControlH= class(TWinControl); 


constructor TEditStyleHookColor.Create(AControl: TWinControl); 
begin 
    inherited; 
    //call the UpdateColors method to use the custom colors 
    UpdateColors; 
end; 

//Here you set the colors of the style hook 
procedure TEditStyleHookColor.UpdateColors; 
var 
    LStyle: TCustomStyleServices; 
begin 
if Control.Enabled then 
begin 
    Brush.Color := TWinControlH(Control).Color; //use the Control color 
    FontColor := TWinControlH(Control).Font.Color;//use the Control font color 
end 
else 
begin 
    //if the control is disabled use the colors of the style 
    LStyle := StyleServices; 
    Brush.Color := LStyle.GetStyleColor(scEditDisabled); 
    FontColor := LStyle.GetStyleFontColor(sfEditBoxTextDisabled); 
end; 
end; 

//Handle the messages of the control 
procedure TEditStyleHookColor.WndProc(var Message: TMessage); 
begin 
    case Message.Msg of 
    CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC: 
     begin 
     //Get the colors 
     UpdateColors; 
     SetTextColor(Message.WParam, ColorToRGB(FontColor)); 
     SetBkColor(Message.WParam, ColorToRGB(Brush.Color)); 
     Message.Result := LRESULT(Brush.Handle); 
     Handled := True; 
     end; 
    CM_ENABLEDCHANGED: 
     begin 
     //Get the colors 
     UpdateColors; 
     Handled := False; 
     end 
    else 
    inherited WndProc(Message); 
    end; 
end; 

Procedure ApplyVCLColorsStyleHook(ControlClass :TClass); 
begin 
    if Assigned(TStyleManager.Engine) then 
     TStyleManager.Engine.RegisterStyleHook(ControlClass, TEditStyleHookColor); 
end; 

initialization 
    ApplyVCLColorsStyleHook(TwwDBComboDlg); 

NIL에 귀하의 문제는 당신이없는 경우에 그 VCL 테마가 켜져 있으면 Engine은 nil이므로 호출중인 함수를 호출하지 않고 해당 코드를 확인하고 반환해야합니다. 당신이 테마를 켤 경우 여기에 당신이 그것을 놓친 경우이다 :

enter image description here

흥미로운 측면 물건 : the VCL Styles utils 라이브러리를 가져옵니다.

TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleColor(scEdit, clWindow); 
TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleFontColor(sfEditBoxTextNormal 
        ,clWindowText); 

당신은 스타일을 만들고, 특정 컨트롤에 그 스타일을 적용, 심지어 테마 엔진을 확장 할 수 있습니다, VCL 스타일의 Utils 도구를 사용 할 수 있습니다 여기 물건의 색상을 변경하는 데 사용의 예 원하는 결과를 얻지 만 사소한 것은 아닙니다.

+0

DB 편집이지만 내부에는 더 많은 컨트롤이있는 자체 드롭 다운 WS_POPUP 창이있다. –

+0

난 그냥 TEdit 컨트롤로 시도하고 동일한 문제가있어. TStyleManager.engine은 디버거에서 보았을 때 nil입니다. 그 소리가 맞습니까. 그게 내 문제일지도 모른다. 그것을 고칠 수있는 방법에 대한 아이디어. – mike

+0

프로젝트에 참여하지 않고 VCL 스타일을 활성화하지 않으면 항상 0이됩니다. 프로젝트 설정으로 이동하여 스타일을 켜십시오. –