2013-06-01 10 views
7

मैं TActionMainMenuBar डिस्प्ले स्टाइल वाले एमडीआई बटन जैसे टीएमएएनमेनू करता हूं।TActionMainMenuBar, वीसीएल-स्टाइल और एमडीआई बटन (न्यूनतम, बंद आदि) स्टाइल नहीं किया जा रहा है।

VCL Styles problem

कोई सुझाव? मैं इस परियोजना के लिए एमडीआई का उपयोग बंद नहीं कर सकता।

+0

तुम हमेशा VCL शैलियों का उपयोग बंद ....... –

+0

एमडीआई एक एकल अभिभावक खिड़की कई उदाहरण होस्टिंग के विचार के साथ पैदा किया गया था सकता है "दस्तावेज़" की एक ही कक्षा के, फ्रेम्स आपको डेवलपर और उपयोगकर्ता के लिए अनावश्यक परेशानी के बिना ऐसा करने की अनुमति देता है। – Peter

+0

क्या आप इस मुद्दे को पुन: पेश करने के लिए नमूना कोड शामिल कर सकते हैं? – RRUZ

उत्तर

11

ठीक है, पहले यह वीसीएल स्टाइल बग नहीं है, यह एक वीसीएल बग है। यह समस्या तब भी प्रकट होती है जब Vcl स्टाइल अक्षम हैं।

enter image description here

enter image description here

मुद्दा TCustomMDIMenuButton.Paint विधि है जो कैप्शन बटन आकर्षित करने के लिए वर्ष DrawFrameControl WINAPI विधि का उपयोग करता में स्थित है।

procedure TCustomMDIMenuButton.Paint; 
begin 
    DrawFrameControl(Canvas.Handle, ClientRect, DFC_CAPTION, 
    MouseStyles[MouseInControl] or ButtonStyles[ButtonStyle] or 
    PushStyles[FState = bsDown]); 
end; 

के रूप में वैकल्पिक हल आप एक चक्कर का उपयोग कर और फिर StylesServices उपयोग कर एक नया रंग विधि को लागू करने के लिए इस विधि पैच कर सकते हैं।

बस इस इकाई को अपनी परियोजना में जोड़ें।

unit PatchMDIButtons; 

interface 

implementation 

uses 
    System.SysUtils, 
    Winapi.Windows, 
    Vcl.Themes, 
    Vcl.Styles, 
    Vcl.ActnMenus; 

type 
    TCustomMDIMenuButtonClass= class(TCustomMDIMenuButton); 

    TJumpOfs = Integer; 
    PPointer = ^Pointer; 

    PXRedirCode = ^TXRedirCode; 
    TXRedirCode = packed record 
    Jump: Byte; 
    Offset: TJumpOfs; 
    end; 

    PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp; 
    TAbsoluteIndirectJmp = packed record 
    OpCode: Word; 
    Addr: PPointer; 
    end; 

var 
    PaintMethodBackup : TXRedirCode; 

function GetActualAddr(Proc: Pointer): Pointer; 
begin 
    if Proc <> nil then 
    begin 
    if (Win32Platform = VER_PLATFORM_WIN32_NT) and (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then 
     Result := PAbsoluteIndirectJmp(Proc).Addr^ 
    else 
     Result := Proc; 
    end 
    else 
    Result := nil; 
end; 

procedure HookProc(Proc, Dest: Pointer; var BackupCode: TXRedirCode); 
var 
    n: NativeUInt; 
    Code: TXRedirCode; 
begin 
    Proc := GetActualAddr(Proc); 
    Assert(Proc <> nil); 
    if ReadProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n) then 
    begin 
    Code.Jump := $E9; 
    Code.Offset := PAnsiChar(Dest) - PAnsiChar(Proc) - SizeOf(Code); 
    WriteProcessMemory(GetCurrentProcess, Proc, @Code, SizeOf(Code), n); 
    end; 
end; 

procedure UnhookProc(Proc: Pointer; var BackupCode: TXRedirCode); 
var 
    n: NativeUInt; 
begin 
    if (BackupCode.Jump <> 0) and (Proc <> nil) then 
    begin 
    Proc := GetActualAddr(Proc); 
    Assert(Proc <> nil); 
    WriteProcessMemory(GetCurrentProcess, Proc, @BackupCode, SizeOf(BackupCode), n); 
    BackupCode.Jump := 0; 
    end; 
end; 


procedure PaintPatch(Self: TObject); 
const 
    ButtonStyles: array[TMDIButtonStyle] of TThemedWindow = (twMDIMinButtonNormal, twMDIRestoreButtonNormal, twMDICloseButtonNormal); 
var 
    LButton : TCustomMDIMenuButtonClass; 
    LDetails: TThemedElementDetails; 
begin 
    LButton:=TCustomMDIMenuButtonClass(Self); 
    LDetails := StyleServices.GetElementDetails(ButtonStyles[LButton.ButtonStyle]); 
    StyleServices.DrawElement(LButton.Canvas.Handle, LDetails, LButton.ClientRect); 
end; 

procedure HookPaint; 
begin 
    HookProc(@TCustomMDIMenuButtonClass.Paint, @PaintPatch, PaintMethodBackup); 
end; 

procedure UnHookPaint; 
begin 
    UnhookProc(@TCustomMDIMenuButtonClass.Paint, PaintMethodBackup); 
end; 


initialization 
HookPaint; 
finalization 
UnHookPaint; 
end. 

परिणाम होगा

enter image description here enter image description here

+0

बढ़िया! Rodrigo बहुत बहुत धन्यवाद। –

+0

आपका स्वागत है, डॉन 'भूल QC साइट http://qc.embarcadero.com/wc/qcmain.aspx – RRUZ

+0

तुम बहुत बहुत बहुत धन्यवाद करने के लिए इस मामले की रिपोर्ट! – gabr

संबंधित मुद्दे