mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
582 lines
22 KiB
ObjectPascal
582 lines
22 KiB
ObjectPascal
unit VirtualTrees.BaseAncestorVCL;
|
|
|
|
{$SCOPEDENUMS ON}
|
|
|
|
{****************************************************************************************************************}
|
|
{ Project : VirtualTrees }
|
|
{ }
|
|
{ author : Karol Bieniaszewski, look at VirtualTrees.pas as some code moved from there }
|
|
{ year : 2022 }
|
|
{ contibutors : }
|
|
{****************************************************************************************************************}
|
|
|
|
interface
|
|
uses
|
|
Winapi.Windows,
|
|
Winapi.oleacc,
|
|
Winapi.ActiveX,
|
|
Winapi.Messages,
|
|
System.Classes,
|
|
Vcl.Controls,
|
|
Vcl.Graphics,
|
|
Vcl.StdCtrls,
|
|
VirtualTrees.Types;
|
|
|
|
type
|
|
TVTBaseAncestorVcl = class abstract(TCustomControl)
|
|
private
|
|
// MSAA support
|
|
FAccessible: IAccessible; // The IAccessible interface to the window itself.
|
|
FAccessibleItem: IAccessible; // The IAccessible to the item that currently has focus.
|
|
FAccessibleName: string; // The name the window is given for screen readers.
|
|
FDottedBrushTreeLines: TBrush; // used to paint dotted lines without special pens
|
|
|
|
procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT;
|
|
protected // methods
|
|
function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; virtual; abstract;
|
|
function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual;
|
|
procedure NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE);
|
|
function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual;
|
|
function CreateSystemImageSet(): TImageList;
|
|
procedure SetWindowTheme(const Theme: string); virtual;
|
|
//// Abtract method that are implemented in TBaseVirtualTree, keep in sync with TVTBaseAncestorFMX
|
|
function GetSelectedCount(): Integer; virtual; abstract;
|
|
procedure MarkCutCopyNodes; virtual; abstract;
|
|
procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual; abstract;
|
|
function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract;
|
|
function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract;
|
|
procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract;
|
|
procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; abstract;
|
|
procedure DoMouseEnter(); virtual; abstract;
|
|
procedure DoMouseLeave(); virtual; abstract;
|
|
protected //properties
|
|
property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines;
|
|
public // methods
|
|
destructor Destroy; override;
|
|
procedure CopyToClipboard(); virtual;
|
|
procedure CutToClipboard(); virtual;
|
|
function PasteFromClipboard: Boolean; virtual; abstract;
|
|
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.InvalidateRect
|
|
/// </summary>
|
|
function InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; inline;
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.UpdateWindow
|
|
/// </summary>
|
|
function UpdateWindow(): BOOL; inline;
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.RedrawWindow
|
|
/// </summary>
|
|
function RedrawWindow(lprcUpdate: PRect; hrgnUpdate: HRGN; flags: UINT): BOOL; overload; inline;
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.RedrawWindow
|
|
/// </summary>
|
|
function RedrawWindow(const lprcUpdate: TRect; hrgnUpdate: HRGN; flags: UINT): BOOL; overload; inline;
|
|
|
|
/// <summary>
|
|
/// Handle less and with limited parameters version
|
|
/// </summary>
|
|
function SendWM_SETREDRAW(Updating: Boolean): LRESULT; inline;
|
|
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.ShowScrollBar
|
|
/// </summary>
|
|
procedure ShowScrollBar(Bar: Integer; AShow: Boolean);
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.SetScrollInfo
|
|
/// </summary>
|
|
function SetScrollInfo(Bar: Integer; const ScrollInfo: TScrollInfo; Redraw: Boolean): TDimension;
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.GetScrollInfo
|
|
/// </summary>
|
|
function GetScrollInfo(Bar: Integer; var ScrollInfo: TScrollInfo): Boolean;
|
|
/// <summary>
|
|
/// Handle less alias for WinApi.Windows.GetScrollPos
|
|
/// </summary>
|
|
function GetScrollPos(Bar: Integer): TDimension;
|
|
/// <summary>
|
|
/// Canvas based without HDC alias for WinApi.Windows.GetTextMetrics
|
|
/// </summary>
|
|
function GetTextMetrics(Canvas: TCanvas; var TM: TTextMetric): BOOL; overload; inline;
|
|
public //properties
|
|
property Accessible: IAccessible read FAccessible write FAccessible;
|
|
property AccessibleItem: IAccessible read FAccessibleItem write FAccessibleItem;
|
|
property AccessibleName: string read FAccessibleName write FAccessibleName;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.SyncObjs,
|
|
System.SysUtils,
|
|
Vcl.AxCtrls,
|
|
Vcl.Forms,
|
|
Vcl.Themes,
|
|
Winapi.CommCtrl,
|
|
Winapi.ShlObj,
|
|
Winapi.UxTheme,
|
|
VirtualTrees.DataObject,
|
|
VirtualTrees.Clipboard,
|
|
VirtualTrees.AccessibilityFactory,
|
|
VirtualTrees.StyleHooks;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
const
|
|
Grays: array[0..3] of TColor = (clWhite, clSilver, clGray, clBlack);
|
|
SysGrays: array[0..3] of TColor = (clWindow, clBtnFace, clBtnShadow, clBtnText);
|
|
|
|
//not used curently anywhere, moved to VCL, to remove ifdef (gWatcher is declared in VirtualTrees.BaseTree)
|
|
procedure ConvertImageList(gWatcher: TCriticalSection; BaseVirtualTreeClass: TClass; IL: TImageList; const ImageName: string; ColorRemapping: Boolean = True);
|
|
|
|
// Loads a bunch of images given by ImageName into IL. If ColorRemapping = True then a mapping of gray values to
|
|
// system colors is performed.
|
|
|
|
var
|
|
lImages,
|
|
lOneImage: TBitmap;
|
|
I: Integer;
|
|
MaskColor: TColor;
|
|
Source,
|
|
Dest: TRect;
|
|
|
|
begin
|
|
gWatcher.Enter();
|
|
try
|
|
// Since we want the image list appearing in the correct system colors, we have to remap its colors.
|
|
lImages := TBitmap.Create;
|
|
lOneImage := TBitmap.Create;
|
|
if ColorRemapping then
|
|
lImages.Handle := CreateMappedRes(FindClassHInstance(BaseVirtualTreeClass), PChar(ImageName), Grays, SysGrays)
|
|
else
|
|
lImages.Handle := LoadBitmap(FindClassHInstance(BaseVirtualTreeClass), PChar(ImageName));
|
|
|
|
try
|
|
Assert(lImages.Height > 0, 'Internal image "' + ImageName + '" is missing or corrupt.');
|
|
if lImages.Height = 0 then
|
|
Exit;// This should never happen, it prevents a division by zero exception below in the for loop, which we have seen in a few cases
|
|
// It is assumed that the image height determines also the width of one entry in the image list.
|
|
IL.Clear;
|
|
IL.Height := lImages.Height;
|
|
IL.Width := lImages.Height;
|
|
lOneImage.Width := IL.Width;
|
|
lOneImage.Height := IL.Height;
|
|
MaskColor := lImages.Canvas.Pixels[0, 0]; // this is usually clFuchsia
|
|
Dest := Rect(0, 0, IL.Width, IL.Height);
|
|
for I := 0 to (lImages.Width div lImages.Height) - 1 do
|
|
begin
|
|
Source := Rect(I * IL.Width, 0, (I + 1) * IL.Width, IL.Height);
|
|
lOneImage.Canvas.CopyRect(Dest, lImages.Canvas, Source);
|
|
IL.AddMasked(lOneImage, MaskColor);
|
|
end;
|
|
finally
|
|
lImages.Free;
|
|
lOneImage.Free;
|
|
end;
|
|
finally
|
|
gWatcher.Leave();
|
|
end;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult;
|
|
|
|
// Returns a memory expression of all currently selected nodes in the Medium structure.
|
|
// Note: The memory requirement of this method might be very high. This depends however on the requested storage format.
|
|
// For HGlobal (a global memory block) we need to render first all nodes to local memory and copy this then to
|
|
// the global memory in Medium. This is necessary because we have first to determine how much
|
|
// memory is needed before we can allocate it. Hence for a short moment we need twice the space as used by the
|
|
// nodes alone (plus the amount the nodes need in the tree anyway)!
|
|
// With IStream this does not happen. We directly stream out the nodes and pass the constructed stream along.
|
|
|
|
//--------------- local function --------------------------------------------
|
|
|
|
procedure WriteNodes(Stream: TStream);
|
|
|
|
var
|
|
Selection: TNodeArray;
|
|
I: Integer;
|
|
|
|
begin
|
|
if ForClipboard then
|
|
Selection := GetSortedCutCopySet(True)
|
|
else
|
|
Selection := GetSortedSelection(True);
|
|
for I := 0 to High(Selection) do
|
|
WriteNode(Stream, Selection[I]);
|
|
end;
|
|
|
|
//--------------- end local function ----------------------------------------
|
|
|
|
var
|
|
Data: PCardinal;
|
|
ResPointer: Pointer;
|
|
ResSize: Integer;
|
|
OLEStream: IStream;
|
|
VCLStream: TStream;
|
|
|
|
begin
|
|
ZeroMemory (@Medium, SizeOf(Medium));
|
|
|
|
// We can render the native clipboard format in two different storage media.
|
|
if (FormatEtcIn.cfFormat = CF_VIRTUALTREE) and (FormatEtcIn.tymed and (TYMED_HGLOBAL or TYMED_ISTREAM) <> 0) then
|
|
begin
|
|
VCLStream := nil;
|
|
try
|
|
Medium.unkForRelease := nil;
|
|
// Return data in one of the supported storage formats, prefer IStream.
|
|
if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then
|
|
begin
|
|
// Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle).
|
|
// Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal
|
|
// back which is not supported by TStreamAdapater).
|
|
CreateStreamOnHGlobal(0, True, OLEStream);
|
|
VCLStream := TOLEStream.Create(OLEStream);
|
|
WriteNodes(VCLStream);
|
|
// Rewind stream.
|
|
VCLStream.Position := 0;
|
|
Medium.tymed := TYMED_ISTREAM;
|
|
IUnknown(Medium.stm) := OLEStream;
|
|
Result := S_OK;
|
|
end
|
|
else
|
|
begin
|
|
VCLStream := TMemoryStream.Create;
|
|
WriteNodes(VCLStream);
|
|
ResPointer := TMemoryStream(VCLStream).Memory;
|
|
ResSize := VCLStream.Position;
|
|
|
|
// Allocate memory to hold the string.
|
|
if ResSize > 0 then
|
|
begin
|
|
Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal));
|
|
Data := GlobalLock(Medium.hGlobal);
|
|
// Store the size of the data too, for easy retrival.
|
|
Data^ := ResSize;
|
|
Inc(Data);
|
|
Move(ResPointer^, Data^, ResSize);
|
|
GlobalUnlock(Medium.hGlobal);
|
|
Medium.tymed := TYMED_HGLOBAL;
|
|
|
|
Result := S_OK;
|
|
end
|
|
else
|
|
Result := E_FAIL;
|
|
end;
|
|
finally
|
|
// We can free the VCL stream here since it was either a pure memory stream or only a wrapper around
|
|
// the OLEStream which exists independently.
|
|
VCLStream.Free;
|
|
end;
|
|
end
|
|
else // Ask application descendants to render self defined formats.
|
|
Result := DoRenderOLEData(FormatEtcIn, Medium, ForClipboard);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TVTBaseAncestorVcl.CopyToClipboard;
|
|
|
|
var
|
|
lDataObject: IDataObject;
|
|
|
|
begin
|
|
if GetSelectedCount > 0 then
|
|
begin
|
|
lDataObject := TVTDataObject.Create(Self, True);
|
|
if OleSetClipboard(lDataObject) = S_OK then
|
|
begin
|
|
MarkCutCopyNodes;
|
|
DoStateChange([tsCopyPending]);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.CreateSystemImageSet: TImageList;
|
|
|
|
// Creates a system check image set.
|
|
// Note: the DarkCheckImages and FlatImages image lists must already be filled, as some images from them are copied here.
|
|
|
|
const
|
|
MaskColor: TColor = clRed;
|
|
cFlags = ILC_COLOR32 or ILC_MASK;
|
|
|
|
var
|
|
BM: TBitmap;
|
|
Theme: HTHEME;
|
|
Details: TThemedElementDetails;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style)
|
|
function StyleServices: TCustomStyleServices;
|
|
begin
|
|
Result := VTStyleServices(Self);
|
|
end;
|
|
|
|
procedure AddSystemImage(IL: TImageList; Index: Integer);
|
|
const
|
|
States: array [0..19] of Integer = (
|
|
RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDDISABLED,
|
|
RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED,
|
|
CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED,
|
|
CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED,
|
|
CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED);
|
|
var
|
|
ButtonState: Cardinal;
|
|
ButtonType: Cardinal;
|
|
|
|
begin
|
|
BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height));
|
|
if StyleServices.Enabled and StyleServices.IsSystemStyle then
|
|
begin
|
|
if Index < 8 then
|
|
Details.Part := BP_RADIOBUTTON
|
|
else
|
|
Details.Part := BP_CHECKBOX;
|
|
Details.State := States[Index];
|
|
DrawThemeBackground(Theme, BM.Canvas.Handle, Details.Part, Details.State, Rect(0, 0, BM.Width, BM.Height), nil);
|
|
end
|
|
else
|
|
begin
|
|
if Index < 8 then
|
|
ButtonType := DFCS_BUTTONRADIO
|
|
else
|
|
ButtonType := DFCS_BUTTONCHECK;
|
|
if Index >= 16 then
|
|
ButtonType := ButtonType or DFCS_BUTTON3STATE;
|
|
|
|
case Index mod 4 of
|
|
0:
|
|
ButtonState := 0;
|
|
1:
|
|
ButtonState := DFCS_HOT;
|
|
2:
|
|
ButtonState := DFCS_PUSHED;
|
|
else
|
|
ButtonState := DFCS_INACTIVE;
|
|
end;
|
|
if Index in [4..7, 12..19] then
|
|
ButtonState := ButtonState or DFCS_CHECKED;
|
|
// if Flat then
|
|
// ButtonState := ButtonState or DFCS_FLAT;
|
|
DrawFrameControl(BM.Canvas.Handle, Rect(0, 0, BM.Width, BM.Height), DFC_BUTTON, ButtonType or ButtonState);
|
|
end;
|
|
IL.AddMasked(BM, MaskColor);
|
|
end;
|
|
|
|
//--------------- end local functions ---------------------------------------
|
|
|
|
const
|
|
cDefaultCheckboxSize = 13;// Used when no other value is available
|
|
var
|
|
I: Integer;
|
|
lSize: TSize;
|
|
Res: Boolean;
|
|
begin
|
|
BM := TBitmap.Create; // Create a temporary bitmap, which holds the intermediate images.
|
|
try
|
|
Res := False;
|
|
// Retrieve the checkbox image size, prefer theme if available, fall back to GetSystemMetrics() otherwise, but this returns odd results on Windows 8 and higher in high-dpi scenarios.
|
|
if StyleServices.Enabled then
|
|
if StyleServices.IsSystemStyle then
|
|
begin
|
|
{$if CompilerVersion >= 33}
|
|
if TOSVersion.Check(10) and (TOSVersion.Build >= 15063) then
|
|
Theme := OpenThemeDataForDPI(Handle, 'BUTTON', CurrentPPI)
|
|
else
|
|
{$ifend}
|
|
Theme := OpenThemeData(Self.Handle, 'BUTTON');
|
|
Details := StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal);
|
|
Res := GetThemePartSize(Theme, BM.Canvas.Handle, Details.Part, Details.State, nil, TS_TRUE, lSize) = S_OK;
|
|
end
|
|
else
|
|
Res := StyleServices.GetElementSize(BM.Canvas.Handle, StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal), TElementSize.esActual, lSize {$IF CompilerVersion >= 34}, Self.CurrentPPI{$IFEND});
|
|
if not Res then begin
|
|
lSize := TSize.Create(GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK));
|
|
if lSize.cx = 0 then begin // error? (Should happen rarely only)
|
|
lSize.cx := MulDiv(cDefaultCheckboxSize, Screen.PixelsPerInch, USER_DEFAULT_SCREEN_DPI);
|
|
lSize.cy := lSize.cx;
|
|
end;// if
|
|
end;//if
|
|
|
|
Result := TImageList.CreateSize(lSize.cx, lSize.cy);
|
|
Result.Handle := ImageList_Create(Result.Width, Result.Height, cFlags, 0, Result.AllocBy);
|
|
Result.Masked := True;
|
|
Result.BkColor := clWhite;
|
|
|
|
// Make the bitmap the same size as the image list is to avoid problems when adding.
|
|
BM.SetSize(Result.Width, Result.Height);
|
|
BM.Canvas.Brush.Color := MaskColor;
|
|
BM.Canvas.Brush.Style := bsSolid;
|
|
BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height));
|
|
Result.AddMasked(BM, MaskColor);
|
|
|
|
// Add the 20 system checkbox and radiobutton images.
|
|
for I := 0 to 19 do
|
|
AddSystemImage(Result, I);
|
|
if StyleServices.Enabled and StyleServices.IsSystemStyle then
|
|
CloseThemeData(Theme);
|
|
|
|
finally
|
|
BM.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TVTBaseAncestorVcl.CutToClipboard;
|
|
var
|
|
lDataObject: IDataObject;
|
|
begin
|
|
if (GetSelectedCount > 0) then
|
|
begin
|
|
lDataObject := TVTDataObject.Create(Self, True);
|
|
if OleSetClipboard(lDataObject) = S_OK then
|
|
begin
|
|
MarkCutCopyNodes;
|
|
DoStateChange([tsCutPending], [tsCopyPending]);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
destructor TVTBaseAncestorVcl.Destroy;
|
|
begin
|
|
// Disconnect all remote MSAA connections
|
|
if Assigned(AccessibleItem) then begin
|
|
CoDisconnectObject(AccessibleItem, 0);
|
|
AccessibleItem := nil;
|
|
end;
|
|
if Assigned(Accessible) then begin
|
|
CoDisconnectObject(Accessible, 0);
|
|
Accessible := nil;
|
|
end;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush;
|
|
begin
|
|
if Assigned(CurrentDottedBrush) then
|
|
begin
|
|
Result := CurrentDottedBrush;
|
|
end else
|
|
begin
|
|
Result := TBrush.Create;
|
|
Result.Bitmap := TBitmap.Create;
|
|
end;
|
|
|
|
Result.Bitmap.Handle := CreateBitmap(8, 8, 1, 1, Bits);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.RedrawWindow(const lprcUpdate: TRect; hrgnUpdate: HRGN; flags: UINT): BOOL;
|
|
begin
|
|
Result:= Winapi.Windows.RedrawWindow(Handle, lprcUpdate, hrgnUpdate, flags);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.RedrawWindow(lprcUpdate: PRect; hrgnUpdate: HRGN; flags: UINT): BOOL;
|
|
begin
|
|
Result:= Winapi.Windows.RedrawWindow(Handle, lprcUpdate, hrgnUpdate, flags);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL;
|
|
begin
|
|
Result:= WinApi.Windows.InvalidateRect(Handle, lpRect, bErase);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TVTBaseAncestorVcl.NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE);
|
|
begin
|
|
if Assigned(AccessibleItem) then
|
|
NotifyWinEvent(pEvent, Handle, OBJID_CLIENT, CHILDID_SELF);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.UpdateWindow(): BOOL;
|
|
begin
|
|
Result:= WinApi.Windows.UpdateWindow(Handle);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TVTBaseAncestorVcl.WMGetObject(var Message: TMessage);
|
|
|
|
begin
|
|
if TVTAccessibilityFactory.GetAccessibilityFactory <> nil then
|
|
begin
|
|
// Create the IAccessibles for the tree view and tree view items, if necessary.
|
|
if Accessible = nil then
|
|
Accessible := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self);
|
|
if AccessibleItem = nil then
|
|
AccessibleItem := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self);
|
|
if Cardinal(Message.LParam) = OBJID_CLIENT then
|
|
if Assigned(Accessible) then
|
|
Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, Accessible)
|
|
else
|
|
Message.Result := 0;
|
|
end;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TVTBaseAncestorVcl.ShowScrollBar(Bar: Integer; AShow: Boolean);
|
|
begin
|
|
WinApi.Windows.ShowScrollBar(Handle, Bar, AShow);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.SendWM_SETREDRAW(Updating: Boolean): LRESULT;
|
|
begin
|
|
Result:= SendMessage(Handle, WM_SETREDRAW, Ord(not Updating), 0);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.SetScrollInfo(Bar: Integer; const ScrollInfo: TScrollInfo; Redraw: Boolean): TDimension;
|
|
begin
|
|
Result:= WinApi.Windows.SetScrollInfo(Handle, Bar, ScrollInfo, Redraw);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TVTBaseAncestorVcl.SetWindowTheme(const Theme: string);
|
|
begin
|
|
Winapi.UxTheme.SetWindowTheme(Handle, PWideChar(Theme), nil);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.GetScrollInfo(Bar: Integer; var ScrollInfo: TScrollInfo): Boolean;
|
|
begin
|
|
Result:= WinApi.Windows.GetScrollInfo(Handle, Bar, ScrollInfo);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TVTBaseAncestorVcl.GetScrollPos(Bar: Integer): TDimension;
|
|
begin
|
|
Result:= WinApi.Windows.GetScrollPos(Handle, Bar);
|
|
end;
|
|
|
|
function TVTBaseAncestorVcl.GetTextMetrics(Canvas: TCanvas; var TM: TTextMetric): BOOL;
|
|
begin
|
|
Result:= WinApi.Windows.GetTextMetrics(Canvas.Handle, TM);
|
|
end;
|
|
|
|
end.
|