diff --git a/components/jvcllaz/devtools/JvExVCL/Readme.txt b/components/jvcllaz/devtools/JvExVCL/Readme.txt
new file mode 100644
index 000000000..133c51400
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/Readme.txt
@@ -0,0 +1,16 @@
+Directory structure
+-------------------
+.\ preprocessed files
+source\ source files that must be preprocessed
+
+
+Files
+-----
+.\jpp.exe JCL pascal preprocessor
+.\preprocess.bat preprocess the source\JvExXxx files
+.\Readme.txt this file
+source\dpp.exe Delphi language preprocessor (http://www.sf.net/projects/dpp32)
+source\build.pas used for preprocessing
+source\JvExControls.pas base system and interfaces
+source\JvExXxx extended VCL classes for the VCL controls
+source\JvExControls.macros macros used by the preprocessor
diff --git a/components/jvcllaz/devtools/JvExVCL/preprocess.bat b/components/jvcllaz/devtools/JvExVCL/preprocess.bat
new file mode 100644
index 000000000..28b9d975f
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/preprocess.bat
@@ -0,0 +1,37 @@
+@echo off
+
+SET OUTDIR=..\..\..\run
+
+cd src
+
+
+SET FILE=.\build
+if NOT "-%1" == "-" SET FILE=%1
+echo Preprocessing template: %FILE%.pas
+dpp.exe .\%FILE%.pas -I..\..\..\common >NUL
+
+if "%FILE%" == ".\build" GOTO ALL
+
+move %FILE%.i.pas %OUTDIR%\%FILE%.pas
+
+
+goto LEAVE
+:ALL
+
+move JvExButtons.i.pas %OUTDIR%\JvExButtons.pas
+move JvExCheckLst.i.pas %OUTDIR%\JvExCheckLst.pas
+move JvExComCtrls.i.pas %OUTDIR%\JvExComCtrls.pas
+move JvExControls.i.pas %OUTDIR%\JvExControls.pas
+REM move JvExDBCtrls.i.pas %OUTDIR%\JvExDBCtrls.pas
+move JvExDBGrids.i.pas %OUTDIR%\JvExDBGrids.pas
+move JvExExtCtrls.i.pas %OUTDIR%\JvExExtCtrls.pas
+move JvExForms.i.pas %OUTDIR%\JvExForms.pas
+move JvExGrids.i.pas %OUTDIR%\JvExGrids.pas
+move JvExMask.i.pas %OUTDIR%\JvExMask.pas
+move JvExStdCtrls.i.pas %OUTDIR%\JvExStdCtrls.pas
+
+cd ..
+
+:LEAVE
+SET FILE=
+SET OUTDIR=
diff --git a/components/jvcllaz/devtools/JvExVCL/src/JvExControls.macros b/components/jvcllaz/devtools/JvExVCL/src/JvExControls.macros
new file mode 100644
index 000000000..b338ab4ce
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/src/JvExControls.macros
@@ -0,0 +1,594 @@
+
+// This comment is inserted into every JvExXxx.pas file
+(*$DEFINE WARNINGHEADER
+{*****************************************************************************
+ * WARNING: Do not edit this file.
+ * This file is autogenerated from the source in devtools/JvExVCL/src.
+ * If you do it despite this warning your changes will be discarded by the next
+ * update of this file. Do your changes in the template files.
+ ****************************************************************************}
+{$D-} // do not step into this unit
+*)
+
+// *************************************************************************
+// *************************** INTERFACE MACROS ****************************
+// *************************************************************************
+
+(*$DEFINE COMMON_PUBLISHED
+ published
+ property BiDiMode;
+ property DragCursor;
+ property DragKind;
+ property DragMode;
+ property ParentBiDiMode;
+ property OnEndDock;
+ property OnStartDock;
+*)
+
+// ****************** Control ************************
+(*$DEFINE CONTROL_DECL
+ private
+ // TODO:
+ // FAboutJVCL: TJVCLAboutInfo;
+ FHintColor: TColor;
+ FMouseOver: Boolean;
+ FHintWindowClass: THintWindowClass;
+ FOnMouseEnter: TNotifyEvent;
+ FOnMouseLeave: TNotifyEvent;
+ FOnParentColorChanged: TNotifyEvent;
+ function BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer; overload;
+ function BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer; overload;
+ function BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+ protected
+ procedure WndProc(var Msg: TLMessage); override;
+ procedure FocusChanged(AControl: TWinControl); dynamic;
+ procedure VisibleChanged; reintroduce; dynamic;
+ procedure EnabledChanged; reintroduce; dynamic;
+ procedure TextChanged; reintroduce; virtual;
+ procedure ColorChanged; reintroduce; dynamic;
+ procedure FontChanged; reintroduce; dynamic;
+ procedure ParentFontChanged; reintroduce; dynamic;
+ procedure ParentColorChanged; reintroduce; dynamic;
+ procedure ParentShowHintChanged; reintroduce; dynamic;
+ function WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean; reintroduce; virtual;
+ function HintShow(var HintInfo: THintInfo): Boolean; reintroduce; dynamic;
+ function HitTest(X, Y: Integer): Boolean; reintroduce; virtual;
+ procedure MouseEnter(AControl: TControl); reintroduce; dynamic;
+ procedure MouseLeave(AControl: TControl); reintroduce; dynamic;
+ property MouseOver: Boolean read FMouseOver write FMouseOver;
+ property HintColor: TColor read FHintColor write FHintColor default clDefault;
+ property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
+ property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
+ property OnParentColorChange: TNotifyEvent read FOnParentColorChanged write FOnParentColorChanged;
+ function GetCaption: TCaption; virtual;
+ procedure SetCaption(Value: TCaption); virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Caption: TCaption read GetCaption write SetCaption;
+ property HintWindowClass: THintWindowClass read FHintWindowClass write FHintWindowClass;
+ published
+ // TODO:
+ // property AboutJVCL: TJVCLAboutInfo read FAboutJVCL write FAboutJVCL stored False;
+*)
+
+// ****************** WinControl *********************
+((*$DEFINE WINCONTROL_DECL
+ CONTROL_DECL
+ private
+ FDotNetHighlighting: Boolean;
+ protected
+ procedure BoundsChanged; reintroduce; virtual;
+ procedure CursorChanged; reintroduce; dynamic;
+ procedure ShowingChanged; reintroduce; dynamic;
+ procedure ShowHintChanged; reintroduce; dynamic;
+ procedure ControlsListChanging(Control: TControl; Inserting: Boolean); reintroduce; dynamic;
+ procedure ControlsListChanged(Control: TControl; Inserting: Boolean); reintroduce; dynamic;
+ procedure GetDlgCode(var Code: TDlgCodes); virtual;
+ procedure FocusSet(PrevWnd: THandle); virtual;
+ procedure FocusKilled(NextWnd: THandle); virtual;
+ function DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean; virtual;
+ published
+ property DotNetHighlighting: Boolean read FDotNetHighlighting write FDotNetHighlighting default False;
+*)
+
+// ****************** EditControl ********************
+(*$DEFINE EDITCONTROL_DECL
+ WINCONTROL_DECL
+ private
+ FClipboardCommands: TJvClipboardCommands;
+ protected
+ procedure SetClipboardCommands(const Value: TJvClipboardCommands); virtual;
+ property ClipboardCommands: TJvClipboardCommands read FClipboardCommands write SetClipboardCommands default [caCopy..caUndo];
+*)
+
+// *************************************************************************
+// *************************************************************************
+
+// ****************** Default-Helpers ********************
+
+// TJvEx##ClassName = class(T##ClassName, IJvExControl)
+(*$DEFINE CONTROL_DECL_DEFAULT(ClassName)
+ TJvEx##ClassName = class(T##ClassName)
+ CONTROL_DECL
+ end;
+*)
+
+// TJvEx##ClassName = class(T##ClassName, IJvExControl)
+(*$DEFINE WINCONTROL_DECL_DEFAULT(ClassName)
+ TJvEx##ClassName = class(T##ClassName)
+ WINCONTROL_DECL
+ end;
+*)
+
+// TJvEx##ClassName = class(T##ClassName, IJvExControl)
+(*$DEFINE EDITCONTROL_DECL_DEFAULT(ClassName)
+ TJvEx##ClassName = class(T##ClassName)
+ EDITCONTROL_DECL
+ end;
+*)
+
+// *************************************************************************
+// ************************ IMPLEMENTATION MACROS **************************
+// *************************************************************************
+
+// ****************** Constructors *******************
+(*$DEFINE BEGIN_CONTROL_CONSTRUCTOR(ClassName)
+constructor TJvEx##ClassName.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHintColor := clDefault;
+*)
+
+(*$DEFINE BEGIN_WINCONTROL_CONSTRUCTOR(ClassName)
+BEGIN_CONTROL_CONSTRUCTOR(ClassName)
+*)
+
+(*$DEFINE BEGIN_EDITCONTROL_CONSTRUCTOR(ClassName)
+BEGIN_WINCONTROL_CONSTRUCTOR(ClassName)
+ FClipboardCommands := [caCopy..caUndo];
+*)
+
+(*$DEFINE END_CONSTRUCTOR
+end;
+*)
+
+// ****************** Control implementation *******************
+(*$DEFINE CONTROL_IMPL(ClassName)
+function TJvEx##ClassName.BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvEx##ClassName.BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvEx##ClassName.BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+var
+ Mesg: TStructPtrMessage;
+begin
+ Mesg := TStructPtrMessage.Create(Msg, WParam, LParam);
+ try
+ inherited WndProc(Mesg.Msg);
+ finally
+ Result := Mesg.Msg.Result;
+ Mesg.Free;
+ end;
+end;
+
+procedure TJvEx##ClassName.VisibleChanged;
+begin
+ BaseWndProc(CM_VISIBLECHANGED);
+end;
+
+procedure TJvEx##ClassName.EnabledChanged;
+begin
+ BaseWndProc(CM_ENABLEDCHANGED);
+end;
+
+procedure TJvEx##ClassName.TextChanged;
+begin
+ BaseWndProc(CM_TEXTCHANGED);
+end;
+
+procedure TJvEx##ClassName.FontChanged;
+begin
+ BaseWndProc(CM_FONTCHANGED);
+end;
+
+procedure TJvEx##ClassName.ColorChanged;
+begin
+ BaseWndProc(CM_COLORCHANGED);
+end;
+
+procedure TJvEx##ClassName.ParentFontChanged;
+begin
+ // LCL doesn't send this message but left it in case
+ //BaseWndProc(CM_PARENTFONTCHANGED);
+end;
+
+procedure TJvEx##ClassName.ParentColorChanged;
+begin
+ BaseWndProc(CM_PARENTCOLORCHANGED);
+ if Assigned(OnParentColorChange) then
+ OnParentColorChange(Self);
+end;
+
+procedure TJvEx##ClassName.ParentShowHintChanged;
+begin
+ BaseWndProc(CM_PARENTSHOWHINTCHANGED);
+end;
+
+function TJvEx##ClassName.WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean;
+begin
+ Result := BaseWndProc(CM_DIALOGCHAR, Word(Key), ShiftStateToKeyData(Shift)) <> 0;
+end;
+
+function TJvEx##ClassName.HitTest(X, Y: Integer): Boolean;
+begin
+ Result := BaseWndProc(CM_HITTEST, 0, SmallPointToLong(PointToSmallPoint(Point(X, Y)))) <> 0;
+end;
+
+function TJvEx##ClassName.HintShow(var HintInfo: THintInfo): Boolean;
+begin
+ GetHintColor(HintInfo, Self, FHintColor);
+ if FHintWindowClass <> nil then
+ HintInfo.HintWindowClass := FHintWindowClass;
+ Result := BaseWndProcEx(CM_HINTSHOW, 0, HintInfo) <> 0;
+end;
+
+procedure TJvEx##ClassName.MouseEnter(AControl: TControl);
+begin
+ FMouseOver := True;
+ if Assigned(FOnMouseEnter) then
+ FOnMouseEnter(Self);
+ BaseWndProc(CM_MOUSEENTER, 0, AControl);
+end;
+
+procedure TJvEx##ClassName.MouseLeave(AControl: TControl);
+begin
+ FMouseOver := False;
+ BaseWndProc(CM_MOUSELEAVE, 0, AControl);
+ if Assigned(FOnMouseLeave) then
+ FOnMouseLeave(Self);
+end;
+
+procedure TJvEx##ClassName.FocusChanged(AControl: TWinControl);
+begin
+ BaseWndProc(CM_FOCUSCHANGED, 0, AControl);
+end;
+
+function TJvEx##ClassName.GetCaption: TCaption;
+begin
+ Result := inherited Caption;
+end;
+
+// 25.09.2007 - SESS:
+// I have done this because TextChanged wasn't fired as expected.
+// I still don't shure if this problem is only for this reintroduced
+// method because the way LCL treats Caption or will have the same
+// problem with other reintroduced methods. So far, I tested some
+// other events and seems not.
+procedure TJvEx##ClassName.SetCaption(Value: TCaption);
+begin
+ inherited Caption := Value;
+ TextChanged;
+end;
+*)
+
+// ****************** WinControl implementation *******************
+((*$DEFINE WINCONTROL_IMPL(ClassName)
+CONTROL_IMPL(ClassName)
+
+procedure TJvEx##ClassName.BoundsChanged;
+begin
+end;
+
+procedure TJvEx##ClassName.CursorChanged;
+begin
+ BaseWndProc(CM_CURSORCHANGED);
+end;
+
+procedure TJvEx##ClassName.ShowingChanged;
+begin
+ BaseWndProc(CM_SHOWINGCHANGED);
+end;
+
+procedure TJvEx##ClassName.ShowHintChanged;
+begin
+ BaseWndProc(CM_SHOWHINTCHANGED);
+end;
+
+{ VCL sends CM_CONTROLLISTCHANGE and CM_CONTROLCHANGE in a different order than
+ the CLX methods are used. So we must correct it by evaluating "Inserting". }
+procedure TJvEx##ClassName.ControlsListChanging(Control: TControl; Inserting: Boolean);
+begin
+ if Inserting then
+ BaseWndProc(CM_CONTROLLISTCHANGE, Integer(Control), Integer(Inserting))
+ else
+ BaseWndProc(CM_CONTROLCHANGE, Integer(Control), Integer(Inserting));
+end;
+
+procedure TJvEx##ClassName.ControlsListChanged(Control: TControl; Inserting: Boolean);
+begin
+ if not Inserting then
+ BaseWndProc(CM_CONTROLLISTCHANGE, Integer(Control), Integer(Inserting))
+ else
+ BaseWndProc(CM_CONTROLCHANGE, Integer(Control), Integer(Inserting));
+end;
+
+procedure TJvEx##ClassName.GetDlgCode(var Code: TDlgCodes);
+begin
+end;
+
+procedure TJvEx##ClassName.FocusSet(PrevWnd: THandle);
+begin
+ BaseWndProc(LM_SETFOCUS, Integer(PrevWnd), 0);
+end;
+
+procedure TJvEx##ClassName.FocusKilled(NextWnd: THandle);
+begin
+ BaseWndProc(LM_KILLFOCUS, Integer(NextWnd), 0);
+end;
+
+function TJvEx##ClassName.DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean;
+begin
+ Result := BaseWndProc(LM_ERASEBKGND, ACanvas.Handle, Param) <> 0;
+end;
+*)
+
+
+// ****************** EditControl implementation *******************
+(*$DEFINE EDITCONTROL_IMPL(ClassName)
+WINCONTROL_IMPL(ClassName)
+
+procedure TJvEx##ClassName.SetClipboardCommands(const Value: TJvClipboardCommands);
+begin
+ FClipboardCommands := Value;
+end;
+*)
+
+// *********************************************************************
+// *********************************************************************
+
+// ****************** Control WndProc implementation *******************
+(*$DEFINE CONTROL_WNDPROC_CASES
+ {
+ // TODO: do we need this? I think not...
+ CM_DENYSUBCLASSING:
+ Msg.Result := Ord(GetInterfaceEntry(IJvDenySubClassing) <> nil);
+ }
+ CM_DIALOGCHAR:
+ with TCMDialogChar(Msg) do
+ Result := Ord(WantKey(CharCode, KeyDataToShiftState(KeyData), WideChar(CharCode)));
+ CM_HINTSHOW:
+ with TCMHintShow(Msg) do
+ Result := Integer(HintShow(HintInfo^));
+ CM_HITTEST:
+ with TCMHitTest(Msg) do
+ Result := Integer(HitTest(XPos, YPos));
+ CM_MOUSEENTER:
+ MouseEnter(TControl(Msg.LParam));
+ CM_MOUSELEAVE:
+ MouseLeave(TControl(Msg.LParam));
+ CM_VISIBLECHANGED:
+ VisibleChanged;
+ CM_ENABLEDCHANGED:
+ EnabledChanged;
+ // LCL doesn't send this message but left it in case
+ CM_TEXTCHANGED:
+ TextChanged;
+ CM_FONTCHANGED:
+ FontChanged;
+ CM_COLORCHANGED:
+ ColorChanged;
+ CM_FOCUSCHANGED:
+ FocusChanged(TWinControl(Msg.LParam));
+ // LCL doesn't send this message but left it in case
+ //CM_PARENTFONTCHANGED:
+ // ParentFontChanged;
+ CM_PARENTCOLORCHANGED:
+ ParentColorChanged;
+ CM_PARENTSHOWHINTCHANGED:
+ ParentShowHintChanged;
+*)
+
+(*$DEFINE CONTROL_WNDPROC(ClassName)
+procedure TJvEx##ClassName.WndProc(var Msg: TLMessage);
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ case Msg.Msg of
+ CONTROL_WNDPROC_CASES
+ else
+ inherited WndProc(Msg);
+ end;
+end;
+*)
+
+// ****************** WinControl WndProc implementation *******************
+(*$DEFINE WINCONTROL_WNDPROC_CASES
+ CONTROL_WNDPROC_CASES
+ CM_CURSORCHANGED:
+ CursorChanged;
+ CM_SHOWINGCHANGED:
+ ShowingChanged;
+ CM_SHOWHINTCHANGED:
+ ShowHintChanged;
+ CM_CONTROLLISTCHANGE:
+ if Msg.LParam <> 0 then
+ ControlsListChanging(TControl(Msg.WParam), True)
+ else
+ ControlsListChanged(TControl(Msg.WParam), False);
+ CM_CONTROLCHANGE:
+ if Msg.LParam = 0 then
+ ControlsListChanging(TControl(Msg.WParam), False)
+ else
+ ControlsListChanged(TControl(Msg.WParam), True);
+ LM_SETFOCUS:
+ FocusSet(THandle(Msg.WParam));
+ LM_KILLFOCUS:
+ FocusKilled(THandle(Msg.WParam));
+ LM_SIZE:
+ begin
+ inherited WndProc(Msg);
+ BoundsChanged;
+ end;
+ LM_ERASEBKGND:
+ if Msg.WParam <> 0 then
+ begin
+ IdSaveDC := SaveDC(HDC(Msg.WParam)); // protect DC against Stock-Objects from Canvas
+ WCanvas := TCanvas.Create;
+ try
+ WCanvas.Handle := HDC(Msg.WParam);
+ Msg.Result := Ord(DoEraseBackground(WCanvas, Msg.LParam));
+ finally
+ WCanvas.Handle := 0;
+ WCanvas.Free;
+ RestoreDC(HDC(Msg.WParam), IdSaveDC);
+ end;
+ end
+ else
+ inherited WndProc(Msg);
+ LM_GETDLGCODE:
+ begin
+ inherited WndProc(Msg);
+ DlgCodes := [dcNative] + DlgcToDlgCodes(Msg.Result);
+ GetDlgCode(DlgCodes);
+ if not (dcNative in DlgCodes) then
+ Msg.Result := DlgCodesToDlgc(DlgCodes);
+ end;
+*)
+
+(*$DEFINE WINCONTROL_WNDPROC(ClassName)
+procedure TJvEx##ClassName.WndProc(var Msg: TLMessage);
+var
+ IdSaveDC: Integer;
+ DlgCodes: TDlgCodes;
+ WCanvas: TCanvas;
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ begin
+ case Msg.Msg of
+ WINCONTROL_WNDPROC_CASES
+ else
+ inherited WndProc(Msg);
+ end;
+ // TODO:
+ // LM_NCPAINT isn't send by LCL, may be .Net highlighting can't be implemented.
+ case Msg.Msg of // precheck message to prevent access violations on released controls
+ CM_MOUSEENTER, CM_MOUSELEAVE, LM_KILLFOCUS, LM_SETFOCUS, LM_NCPAINT:
+ if DotNetHighlighting then
+ HandleDotNetHighlighting(Self, Msg, MouseOver, Color);
+ end;
+ end;
+end;
+*)
+
+// ****************** EditControl WndProc implementation *******************
+(*$DEFINE EDITCONTROL_WNDPROC_CASES
+ WINCONTROL_WNDPROC_CASES
+ {
+ // TODO: convert to LCL messages
+ WM_CLEAR:
+ if caClear in ClipboardCommands then
+ inherited WndProc(Msg)
+ else
+ Msg.Result := 1;
+ WM_UNDO, EM_UNDO:
+ if caUndo in ClipboardCommands then
+ inherited WndProc(Msg)
+ else
+ Msg.Result := 1;
+ WM_COPY:
+ if caCopy in ClipboardCommands then
+ inherited WndProc(Msg)
+ else
+ Msg.Result := 1;
+ WM_CUT:
+ if caCut in ClipboardCommands then
+ inherited WndProc(Msg)
+ else
+ Msg.Result := 1;
+ WM_PASTE:
+ if caPaste in ClipboardCommands then
+ inherited WndProc(Msg)
+ else
+ Msg.Result := 1;
+ }
+*)
+
+(*$DEFINE EDITCONTROL_WNDPROC(ClassName)
+procedure TJvEx##ClassName.WndProc(var Msg: TLMessage);
+var
+ IdSaveDC: Integer;
+ DlgCodes: TDlgCodes;
+ WCanvas: TCanvas;
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ begin
+ case Msg.Msg of
+ EDITCONTROL_WNDPROC_CASES
+ else
+ inherited WndProc(Msg);
+ end;
+ // TODO:
+ // LM_NCPAINT isn't send by LCL, may be .Net highlighting can't be implemented.
+ case Msg.Msg of // precheck message to prevent access violations on released controls
+ CM_MOUSEENTER, CM_MOUSELEAVE, LM_KILLFOCUS, LM_SETFOCUS, LM_NCPAINT:
+ if DotNetHighlighting then
+ HandleDotNetHighlighting(Self, Msg, MouseOver, Color);
+ end;
+ end;
+end;
+*)
+
+// *************************************************************************
+// *************************************************************************
+
+// ****************** Default-Helpers ********************
+
+(*$DEFINE CONTROL_IMPL_DEFAULT(ClassName)
+BEGIN_CONTROL_CONSTRUCTOR(ClassName)
+END_CONSTRUCTOR
+
+CONTROL_IMPL(ClassName)
+
+CONTROL_WNDPROC(ClassName)
+
+//============================================================================
+
+*)
+
+(*$DEFINE WINCONTROL_IMPL_DEFAULT(ClassName)
+BEGIN_WINCONTROL_CONSTRUCTOR(ClassName)
+END_CONSTRUCTOR
+
+WINCONTROL_IMPL(ClassName)
+
+WINCONTROL_WNDPROC(ClassName)
+
+//============================================================================
+
+*)
+
+(*$DEFINE EDITCONTROL_IMPL_DEFAULT(ClassName)
+BEGIN_EDITCONTROL_CONSTRUCTOR(ClassName)
+END_CONSTRUCTOR
+
+EDITCONTROL_IMPL(ClassName)
+
+EDITCONTROL_WNDPROC(ClassName)
+
+//============================================================================
+
+*)
+
diff --git a/components/jvcllaz/devtools/JvExVCL/src/JvExControls.pas b/components/jvcllaz/devtools/JvExVCL/src/JvExControls.pas
new file mode 100644
index 000000000..602b0c46b
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/src/JvExControls.pas
@@ -0,0 +1,479 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvExControls.pas, released on 2004-01-04
+
+The Initial Developer of the Original Code is Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
+Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
+All Rights Reserved.
+
+Contributor(s): -
+ dejoy.
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvExControls.pas 11400 2007-06-28 21:24:06Z ahuser $
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+// TODO: Make this unit generated by template as JVCL's.
+
+{$mode objfpc}{$H+}
+
+unit JvExControls;
+{MACROINCLUDE JvExControls.macros}
+
+{*****************************************************************************
+ * WARNING: Do not edit this file.
+ * This file is autogenerated from the source in devtools/JvExVCL/src.
+ * If you do it despite this warning your changes will be discarded by the next
+ * update of this file. Do your changes in the template files.
+ ****************************************************************************}
+{$D-} // do not step into this unit
+
+interface
+
+uses
+ Classes, Controls, Graphics, LCLIntf, LCLType, LMessages, Forms;
+
+type
+ TDlgCode =
+ (dcWantAllKeys, dcWantArrows, dcWantChars, dcButton, dcHasSetSel, dcWantTab,
+ dcNative); // if dcNative is in the set the native allowed keys are used and GetDlgCode is ignored
+ TDlgCodes = set of TDlgCode;
+
+(******************** NOT CONVERTED
+const
+ dcWantMessage = dcWantAllKeys;
+
+const
+ CM_DENYSUBCLASSING = JvThemes.CM_DENYSUBCLASSING;
+ CM_PERFORM = CM_BASE + $500 + 0; // LParam: "Msg: ^TMessage"
+ CM_SETAUTOSIZE = CM_BASE + $500 + 1; // WParam: "Value: Boolean"
+
+type
+ TJvHotTrackOptions = class;
+
+ { IJvExControl is used for the identification of an JvExXxx control. }
+ IJvExControl = interface
+ ['{8E6579C3-D683-4562-AFAB-D23C8526E386}']
+ end;
+
+ { Add IJvDenySubClassing to the base class list if the control should not
+ be themed by the ThemeManager (http://www.soft-gems.net Mike Lischke).
+ This only works with JvExVCL derived classes. }
+ IJvDenySubClassing = interface
+ ['{76942BC0-2A6E-4DC4-BFC9-8E110DB7F601}']
+ end;
+
+
+ { IJvHotTrack is Specifies whether Control are highlighted when the mouse passes over them}
+ IJvHotTrack = interface
+ ['{8F1B40FB-D8E3-46FE-A7A3-21CE4B199A8F}']
+
+ function GetHotTrack:Boolean;
+ function GetHotTrackFont:TFont;
+ function GetHotTrackFontOptions:TJvTrackFontOptions;
+ function GetHotTrackOptions:TJvHotTrackOptions;
+
+ procedure SetHotTrack(Value: Boolean);
+ procedure SetHotTrackFont(Value: TFont);
+ procedure SetHotTrackFontOptions(Value: TJvTrackFontOptions);
+ procedure SetHotTrackOptions(Value: TJvHotTrackOptions);
+
+ property HotTrack: Boolean read GetHotTrack write SetHotTrack;
+ property HotTrackFont: TFont read GetHotTrackFont write SetHotTrackFont;
+ property HotTrackFontOptions: TJvTrackFontOptions read GetHotTrackFontOptions write SetHotTrackFontOptions;
+ property HotTrackOptions: TJvHotTrackOptions read GetHotTrackOptions write SetHotTrackOptions;
+ end;
+
+ TJvHotTrackOptions = class(TJvPersistentProperty)
+ private
+ FEnabled: Boolean;
+ FFrameVisible: Boolean;
+ FColor: TColor;
+ FFrameColor: TColor;
+ procedure SetColor(Value: TColor);
+ procedure SetEnabled(Value: Boolean);
+ procedure SetFrameColor(Value: TColor);
+ procedure SetFrameVisible(Value: Boolean);
+ public
+ constructor Create; virtual;
+ procedure Assign(Source: TPersistent); override;
+ published
+ property Enabled: Boolean read FEnabled write SetEnabled default False;
+ property Color: TColor read FColor write SetColor default $00D2BDB6;
+ property FrameVisible: Boolean read FFrameVisible write SetFrameVisible default False;
+ property FrameColor: TColor read FFrameColor write SetFrameColor default $006A240A;
+ end;
+******************** NOT CONVERTED *)
+
+type
+ TStructPtrMessage = class(TObject)
+ private
+ public
+ Msg: TLMessage;
+ constructor Create(AMsg: Integer; WParam: Integer; var LParam);
+ end;
+
+//******************** NOT CONVERTED
+//procedure SetDotNetFrameColors(FocusedColor, UnfocusedColor: TColor);
+
+procedure DrawDotNetControl(Control: TWinControl; AColor: TColor; InControl: Boolean);
+procedure HandleDotNetHighlighting(Control: TWinControl; const Msg: TLMessage;
+ MouseOver: Boolean; Color: TColor);
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: Longint): TLMessage; overload; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: TControl): TLMessage; overload; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function SmallPointToLong(const Pt: TSmallPoint): Longint; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function ShiftStateToKeyData(Shift: TShiftState): Longint;
+
+//******************** NOT CONVERTED
+//function GetFocusedControl(AControl: TControl): TWinControl;
+
+function DlgcToDlgCodes(Value: Longint): TDlgCodes;
+function DlgCodesToDlgc(Value: TDlgCodes): Longint;
+procedure GetHintColor(var HintInfo: THintInfo; AControl: TControl; HintColor: TColor);
+function DispatchIsDesignMsg(Control: TControl; var Msg: TLMessage): Boolean;
+
+type
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Control)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(WinControl)
+
+ WINCONTROL_DECL_DEFAULT(CustomControl)
+
+ CONTROL_DECL_DEFAULT(GraphicControl)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(HintWindow)
+
+(******************** NOT CONVERTED
+ TJvExPubGraphicControl = class(TJvExGraphicControl)
+ COMMON_PUBLISHED
+ end;
+******************** NOT CONVERTED *)
+
+implementation
+
+(******************** NOT CONVERTED
+uses
+ TypInfo;
+
+var
+ InternalFocusedColor: TColor = TColor($00733800);
+ InternalUnfocusedColor: TColor = clGray;
+
+procedure SetDotNetFrameColors(FocusedColor, UnfocusedColor: TColor);
+begin
+ InternalFocusedColor := FocusedColor;
+ InternalUnfocusedColor := UnfocusedColor;
+end;
+******************** NOT CONVERTED *)
+
+procedure DrawDotNetControl(Control: TWinControl; AColor: TColor; InControl: Boolean);
+(******************** NOT CONVERTED
+var
+ DC: HDC;
+ R: TRect;
+ Canvas: TCanvas;
+begin
+ DC := GetWindowDC(Control.Handle);
+ try
+ GetWindowRect(Control.Handle, R);
+ OffsetRect(R, -R.Left, -R.Top);
+ Canvas := TCanvas.Create;
+ with Canvas do
+ try
+ Handle := DC;
+ Brush.Color := InternalUnfocusedColor;
+ if Control.Focused or InControl then
+ Brush.Color := InternalFocusedColor;
+ FrameRect(R);
+ InflateRect(R, -1, -1);
+ if not (Control.Focused or InControl) then
+ Brush.Color := AColor;
+ FrameRect(R);
+ finally
+ Free;
+ end;
+ finally
+ ReleaseDC(Control.Handle, DC);
+ end;
+end;
+******************** NOT CONVERTED *)
+begin
+end;
+
+procedure HandleDotNetHighlighting(Control: TWinControl; const Msg: TLMessage;
+ MouseOver: Boolean; Color: TColor);
+(******************** NOT CONVERTED
+var
+ Rgn, SubRgn: HRGN;
+begin
+ if not (csDesigning in Control.ComponentState) then
+ case Msg.Msg of
+ CM_MOUSEENTER, CM_MOUSELEAVE, WM_KILLFOCUS, WM_SETFOCUS, WM_NCPAINT:
+ begin
+ DrawDotNetControl(Control, Color, MouseOver);
+ if Msg.Msg = CM_MOUSELEAVE then
+ begin
+ Rgn := CreateRectRgn(0, 0, Control.Width - 1, Control.Height - 1);
+ SubRgn := CreateRectRgn(2, 2, Control.Width - 3, Control.Height - 3);
+ try
+ CombineRgn(Rgn, Rgn, SubRgn, RGN_DIFF);
+ InvalidateRgn(Control.Handle, Rgn, False); // redraw 3D border
+ finally
+ DeleteObject(SubRgn);
+ DeleteObject(Rgn);
+ end;
+ end;
+ end;
+ end;
+end;
+******************** NOT CONVERTED *)
+begin
+end;
+
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: Longint): TLMessage;
+begin
+ Result.Msg := Msg;
+ Result.WParam := WParam;
+ Result.LParam := LParam;
+ Result.Result := 0;
+end;
+
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: TControl): TLMessage;
+begin
+ Result := CreateWMMessage(Msg, WParam, Integer(LParam));
+end;
+
+{ TStructPtrMessage }
+constructor TStructPtrMessage.Create(AMsg: Integer; WParam: Integer; var LParam);
+begin
+ inherited Create;
+ Self.Msg.Msg := AMsg;
+ Self.Msg.WParam := WParam;
+ Self.Msg.LParam := Longint(@LParam);
+ Self.Msg.Result := 0;
+end;
+
+function SmallPointToLong(const Pt: TSmallPoint): Longint;
+begin
+ Result := Longint(Pt);
+end;
+
+function ShiftStateToKeyData(Shift: TShiftState): Longint;
+const
+ AltMask = $20000000;
+ CtrlMask = $10000000;
+ ShiftMask = $08000000;
+begin
+ Result := 0;
+ if ssAlt in Shift then
+ Result := Result or AltMask;
+ if ssCtrl in Shift then
+ Result := Result or CtrlMask;
+ if ssShift in Shift then
+ Result := Result or ShiftMask;
+end;
+
+(******************** NOT CONVERTED
+function GetFocusedControl(AControl: TControl): TWinControl;
+var
+ Form: TCustomForm;
+begin
+ Result := nil;
+ Form := GetParentForm(AControl);
+ if Assigned(Form) then
+ Result := Form.ActiveControl;
+end;
+******************** NOT CONVERTED *)
+
+function DlgcToDlgCodes(Value: Longint): TDlgCodes;
+begin
+ Result := [];
+(******************** NOT CONVERTED
+ if (Value and DLGC_WANTARROWS) <> 0 then
+ Include(Result, dcWantArrows);
+ if (Value and DLGC_WANTTAB) <> 0 then
+ Include(Result, dcWantTab);
+ if (Value and DLGC_WANTALLKEYS) <> 0 then
+ Include(Result, dcWantAllKeys);
+ if (Value and DLGC_WANTCHARS) <> 0 then
+ Include(Result, dcWantChars);
+ if (Value and DLGC_BUTTON) <> 0 then
+ Include(Result, dcButton);
+ if (Value and DLGC_HASSETSEL) <> 0 then
+ Include(Result, dcHasSetSel);
+******************** NOT CONVERTED *)
+end;
+
+function DlgCodesToDlgc(Value: TDlgCodes): Longint;
+begin
+ Result := 0;
+(******************** NOT CONVERTED
+ if dcWantAllKeys in Value then
+ Result := Result or DLGC_WANTALLKEYS;
+ if dcWantArrows in Value then
+ Result := Result or DLGC_WANTARROWS;
+ if dcWantTab in Value then
+ Result := Result or DLGC_WANTTAB;
+ if dcWantChars in Value then
+ Result := Result or DLGC_WANTCHARS;
+ if dcButton in Value then
+ Result := Result or DLGC_BUTTON;
+ if dcHasSetSel in Value then
+ Result := Result or DLGC_HASSETSEL;
+******************** NOT CONVERTED *)
+end;
+
+procedure GetHintColor(var HintInfo: THintInfo; AControl: TControl; HintColor: TColor);
+var
+ AHintInfo: THintInfo;
+begin
+ case HintColor of
+ clNone:
+ HintInfo.HintColor := Application.HintColor;
+ clDefault:
+ begin
+ if Assigned(AControl) and Assigned(AControl.Parent) then
+ begin
+ AHintInfo := HintInfo;
+ AControl.Parent.Perform(CM_HINTSHOW, 0, Integer(@AHintInfo));
+ HintInfo.HintColor := AHintInfo.HintColor;
+ end;
+ end;
+ else
+ HintInfo.HintColor := HintColor;
+ end;
+end;
+
+function DispatchIsDesignMsg(Control: TControl; var Msg: TLMessage): Boolean;
+var
+ Form: TCustomForm;
+begin
+ Result := False;
+ case Msg.Msg of
+ LM_SETFOCUS, LM_KILLFOCUS, LM_NCHITTEST,
+ LM_MOUSEFIRST..LM_MOUSELAST,
+ LM_KEYFIRST..LM_KEYLAST,
+ LM_CANCELMODE:
+ Exit; // These messages are handled in TWinControl.WndProc before IsDesignMsg() is called
+ end;
+ if (Control <> nil) and (csDesigning in Control.ComponentState) then
+ begin
+ Form := GetParentForm(Control);
+ if (Form <> nil) and (Form.Designer <> nil) and
+ Form.Designer.IsDesignMsg(Control, Msg) then
+ Result := True;
+ end;
+end;
+
+(******************** NOT CONVERTED
+//=== { TJvHotTrackOptions } ======================================
+
+constructor TJvHotTrackOptions.Create;
+begin
+ inherited Create;
+ FEnabled := False;
+ FFrameVisible := False;
+ FColor := $00D2BDB6;
+ FFrameColor := $006A240A;
+end;
+
+procedure TJvHotTrackOptions.Assign(Source: TPersistent);
+begin
+ if Source is TJvHotTrackOptions then
+ begin
+ BeginUpdate;
+ try
+ Enabled := TJvHotTrackOptions(Source).Enabled;
+ Color := TJvHotTrackOptions(Source).Color;
+ FrameVisible := TJvHotTrackOptions(Source).FrameVisible;
+ FrameColor := TJvHotTrackOptions(Source).FrameColor;
+ finally
+ EndUpdate;
+ end;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvHotTrackOptions.SetColor(Value: TColor);
+begin
+ if FColor <> Value then
+ begin
+ Changing;
+ ChangingProperty('Color');
+ FColor := Value;
+ ChangedProperty('Color');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetEnabled(Value: Boolean);
+begin
+ if FEnabled <> Value then
+ begin
+ Changing;
+ ChangingProperty('Enabled');
+ FEnabled := Value;
+ ChangedProperty('Enabled');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetFrameVisible(Value: Boolean);
+begin
+ if FFrameVisible <> Value then
+ begin
+ Changing;
+ ChangingProperty('FrameVisible');
+ FFrameVisible := Value;
+ ChangedProperty('FrameVisible');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetFrameColor(Value: TColor);
+begin
+ if FFrameColor <> Value then
+ begin
+ Changing;
+ ChangingProperty('FrameColor');
+ FFrameColor := Value;
+ ChangedProperty('FrameColor');
+ Changed;
+ end;
+end;
+******************** NOT CONVERTED *)
+
+//============================================================================
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Control)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(WinControl)
+
+CONTROL_IMPL_DEFAULT(GraphicControl)
+
+WINCONTROL_IMPL_DEFAULT(CustomControl)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(HintWindow)
+
+end.
+
diff --git a/components/jvcllaz/devtools/JvExVCL/src/JvExExtCtrls.pas b/components/jvcllaz/devtools/JvExVCL/src/JvExExtCtrls.pas
new file mode 100644
index 000000000..e93ca879d
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/src/JvExExtCtrls.pas
@@ -0,0 +1,163 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvExExtCtrls.pas, released on 2004-01-04
+
+The Initial Developer of the Original Code is Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
+Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
+All Rights Reserved.
+
+Contributor(s): -
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvExExtCtrls.pas 10613 2006-05-19 19:21:43Z jfudickar $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+unit JvExExtCtrls;
+
+{MACROINCLUDE JvExControls.macros}
+
+WARNINGHEADER
+
+interface
+
+uses
+ Classes, Controls, ExtCtrls, Forms, Graphics, JvExControls, LCLIntf, LMessages;
+
+type
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Shape)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(PaintBox)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Image)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Bevel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomPanel)
+
+ (******************** NOT CONVERTED
+ TJvExPubCustomPanel = class(TJvExCustomPanel)
+ COMMON_PUBLISHED
+ end;
+ ******************** NOT CONVERTED *)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomRadioGroup)
+
+ CONTROL_DECL_DEFAULT(Splitter)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomControlBar)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(ControlBar)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Panel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(RadioGroup)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Page)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Notebook)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Header)
+
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(BoundLabel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomLabeledEdit)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(LabeledEdit)
+
+ //******************** NOT CONVERTED - Exists in LCL?
+ //WINCONTROL_DECL_DEFAULT(CustomColorBox)
+
+ //******************** NOT CONVERTED - Exists in LCL?
+ //WINCONTROL_DECL_DEFAULT(ColorBox)
+
+implementation
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Shape)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(PaintBox)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Image)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Bevel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomPanel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomRadioGroup)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomControlBar)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(ControlBar)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Panel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(RadioGroup)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Page)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Notebook)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Header)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(BoundLabel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomLabeledEdit)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(LabeledEdit)
+
+//******************** NOT CONVERTED - Exists in LCL?
+//WINCONTROL_IMPL_DEFAULT(CustomColorBox)
+
+//******************** NOT CONVERTED - Exists in LCL?
+//WINCONTROL_IMPL_DEFAULT(ColorBox)
+
+CONTROL_IMPL_DEFAULT(Splitter)
+
+end.
diff --git a/components/jvcllaz/devtools/JvExVCL/src/build.pas b/components/jvcllaz/devtools/JvExVCL/src/build.pas
new file mode 100644
index 000000000..5eea37346
--- /dev/null
+++ b/components/jvcllaz/devtools/JvExVCL/src/build.pas
@@ -0,0 +1,19 @@
+unit build;
+interface
+uses
+ JvExControls
+ // ,JvExButtons
+ // ,JvExCheckLst
+ // ,JvExComCtrls
+ // ,JvExExtCtrls
+ // ,JvExForms
+ // ,JvExGrids,
+ // ,JvExMask,
+ // {,JvExDBCtrls}
+ // ,JvExDBGrids,
+ // ,JvExStdCtrls
+ ;
+
+implementation
+
+end.
diff --git a/components/jvcllaz/dist/readme.txt b/components/jvcllaz/dist/readme.txt
new file mode 100644
index 000000000..7db7ca556
--- /dev/null
+++ b/components/jvcllaz/dist/readme.txt
@@ -0,0 +1 @@
+Output directory for distribution packaging.
\ No newline at end of file
diff --git a/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpi b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpi
new file mode 100644
index 000000000..ce959d9ed
--- /dev/null
+++ b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpi
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpr b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpr
new file mode 100644
index 000000000..d3ff7b73e
--- /dev/null
+++ b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemo.lpr
@@ -0,0 +1,18 @@
+program JvNavPaneDemo;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Interfaces, // this includes the LCL widgetset
+ Forms
+ { add your units here }, JvNavPaneDemoMainForm;
+
+begin
+ Application.Initialize;
+ Application.CreateForm(TJvNavPaneDemoMainFrm, JvNavPaneDemoMainFrm);
+ Application.Run;
+end.
+
diff --git a/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lfm b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lfm
new file mode 100644
index 000000000..2f935786b
--- /dev/null
+++ b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lfm
@@ -0,0 +1,776 @@
+object JvNavPaneDemoMainFrm: TJvNavPaneDemoMainFrm
+ Left = 105
+ Height = 468
+ Top = 109
+ Width = 518
+ HorzScrollBar.Page = 517
+ VertScrollBar.Page = 467
+ Caption = 'JvNavigationPane Demo'
+ DockSite = True
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ OnCreate = FormCreate
+ object PopupMenu1: TPopupMenu
+ OnPopup = PopupMenu1Popup
+ left = 92
+ top = 64
+ object HideAll1: TMenuItem
+ Caption = 'Hide All'
+ OnClick = HideAll1Click
+ end
+ object ShowAll1: TMenuItem
+ Caption = 'Show All'
+ OnClick = ShowAll1Click
+ end
+ object N1: TMenuItem
+ Caption = '-'
+ end
+ object ChangeFont1: TMenuItem
+ Caption = 'Font...'
+ OnClick = ChangeFont1Click
+ end
+ object Colors1: TMenuItem
+ Caption = 'Colors'
+ object Standard1: TMenuItem
+ Caption = 'Standard'
+ Checked = True
+ GroupIndex = 1
+ RadioItem = True
+ OnClick = SchemaClick
+ end
+ object Blue1: TMenuItem
+ Tag = 1
+ Caption = 'Blue'
+ GroupIndex = 1
+ RadioItem = True
+ OnClick = SchemaClick
+ end
+ object Silver1: TMenuItem
+ Tag = 2
+ Caption = 'Silver'
+ GroupIndex = 1
+ RadioItem = True
+ OnClick = SchemaClick
+ end
+ object Olive1: TMenuItem
+ Tag = 3
+ Caption = 'Olive'
+ GroupIndex = 1
+ RadioItem = True
+ OnClick = SchemaClick
+ end
+ end
+ object BackgroundImage1: TMenuItem
+ Caption = 'Background Image...'
+ OnClick = BackgroundImage1Click
+ end
+ object N2: TMenuItem
+ Caption = '-'
+ end
+ object Dontallowresize1: TMenuItem
+ Caption = 'Don''t allow resize'
+ OnClick = Dontallowresize1Click
+ end
+ object N3: TMenuItem
+ Caption = '-'
+ end
+ object ShowToolPanel1: TMenuItem
+ Caption = 'Show Tool Panel'
+ OnClick = ShowToolPanel1Click
+ end
+ object ShowCloseButton1: TMenuItem
+ Caption = 'Show Close Button'
+ OnClick = ShowCloseButton1Click
+ end
+ end
+ object LargeImages: TImageList
+ Height = 20
+ Width = 24
+ left = 92
+ top = 16
+ Bitmap = {
+ 4C69060000001800000014000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000CEB59CFFC6AD9CFFCEAD
+ 9CFFCEAD9CFF0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000BDBDBDFFE7C6B5FFC6F7FFFFC6F7FFFFADE7
+ F7FFC6AD9CFFCEAD9CFF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000CEAD9CFFDED6CEFFC6EFFFFFC6EFFFFFC6F7FFFFADE7
+ F7FF7BD6F7FF8CC6D6FFAD9484FF000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000BDBDBDFFCEBDB5FFC6F7FFFFC6EFFFFFC6F7FFFFC6F7FFFFC6EFFFFF8CE7
+ FFFF7BDEF7FF6BC6F7FF6BCEF7FFAD9484FF0000000000000000000000000000
+ 000000000000000000000000000000000000000000000000000000000000CEAD
+ 9CFFDED6CEFFC6EFFFFFC6F7FFFFC6EFFFFFC6F7FFFFC6EFFFFFADE7F7FF8CE7
+ F7FF84D6F7FF63CEF7FF6BC6F7FF4ABDF7FFBDBDBDFF849CA5FF000000000000
+ 0000000000000000000000000000000000000000000000000000CEAD9CFFC6F7
+ FFFFC6F7FFFFC6EFFFFFC6F7FFFFA5E7F7FF94E7FFFF7BD6F7FF7BD6F7FF84D6
+ F7FF7BD6F7FF6BC6F7FF6BCEF7FF4AB5EFFF52B5F7FF4ABDF7FFAD9484FF0000
+ 00000000000000000000000000000000000000000000C6AD9CFFC6F7FFFFADE7
+ F7FFA5E7F7FF94E7F7FF7BD6F7FF6BC6F7FF63CEF7FF52B5EFFF4ABDF7FF4AB5
+ F7FF52BDF7FF31B5DEFF39ADF7FF31A5EFFF21A5EFFF39A5EFFF39ADF7FFA57B
+ 6BFF0000000000000000000000000000000000000000CEAD9CFF63C6F7FFF7EF
+ EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7
+ E7FFF7EFEFFFF7F7EFFFF7EFEFFFADE7F7FFADE7EFFF94C6D6FF31ADEFFF9C7B
+ 6BFF0000000000000000000000000000000000000000D6AD84FF7BD6F7FFF7F7
+ EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7EF
+ EFFFEFEFEFFFF7EFE7FFEFEFEFFFF7F7EFFFF7EFEFFFDEC6ADFF31A5F7FF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000CEADA5FFC6AD9CFFFFDE
+ C6FFFFFFFFFFF7DECEFFFFDEC6FFF7F7EFFFFFDECEFFFFDEC6FFFFDECEFFF7DE
+ C6FFF7F7EFFFF7EFEFFFEFF7EFFFF7EFEFFFEFEFEFFFD6BDADFFA57B6BFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000D6AD84FFFFDECEFFC6AD
+ 9CFFFFFFFFFFF7F7EFFFD6CECEFFDED6CEFFD6D6CEFFD6D6CEFFDED6CEFFD6D6
+ CEFFDEBDADFFDEC6ADFFE7C6ADFFD6CECEFFF7F7EFFF9C7B6BFFE7AD8CFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000D6A58CFFFFFFFFFFFFE7
+ CEFFC6AD9CFFFFFFFFFFFFFFFFFFCEA584FFD6A58CFFD6A584FFAD948CFFAD94
+ 8CFFAD948CFFAD948CFFF7EFEFFFF7F7EFFF9C736BFFE7BD94FFFFCEA5FF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000CE9C7BFFFFFFFFFFEFEF
+ EFFFF7F7EFFFC6AD9CFFD6A58CFFFFE7CEFFEFEFEFFFF7F7EFFFF7EFEFFFF7F7
+ EFFFEFEFEFFFF7D6B5FF9C7B6BFFAD948CFFEFB594FFF7D6BDFFFFCE9CFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000AD9484FFF7EFEFFFEFF7
+ EFFFF7EFEFFFD6A584FFEFF7EFFFF7EFEFFFEFEFEFFFF7EFEFFFEFEFEFFFEFEF
+ EFFFFFE7C6FFFFDECEFFFFCEA5FF9C7B6BFFFFCE9CFFFFCE9CFFF7C68CFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000AD948CFFF7F7EFFFF7EF
+ EFFFCEA584FFF7F7EFFFF7EFEFFFEFEFEFFFF7F7E7FFEFEFEFFFF7F7EFFFFFDE
+ C6FFF7D6C6FFF7DEBDFFF7D6B5FFF7C68CFF9C7B6BFFF7B58CFFF7A573FF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000AD9484FFF7EFEFFFC6AD
+ 9CFFEFEFEFFFF7EFEFFFEFEFEFFFF7F7EFFFF7DEC6FFFFDECEFFF7DEC6FFF7D6
+ C6FFF7D6B5FFF7D6BDFFFFCE9CFFF7C68CFFFFAD8CFF9C7B6BFFE7946BFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000AD9484FFC6B59CFFF7F7
+ EFFFF7EFEFFFEFF7EFFFFFDEC6FFF7D6BDFFF7D6BDFFF7D6B5FFF7D6BDFFF7CE
+ ADFFFFCE9CFFFFCEA5FFF7BD8CFFE7B594FFF7A573FFE7946BFF9C7B6BFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000C69C7BFFFFDEC6FFEFEF
+ EFFFFFDEC6FFF7D6BDFFFFCE9CFFF7C68CFFE7B594FFF7AD8CFFF7B58CFFF7A5
+ 73FFEFA57BFFF7A573FFE79C63FFE79463FFE79C6BFFE79463FFCE7B4AFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000CE9C7BFF9C7B6BFF9C7B
+ 6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B
+ 6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B
+ 6BFF4A4231FF00000000000000000000000000000000000000004A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF0000000000000000000000004A3931FF000000004A3929FF0000
+ 00004A3931FF000000004A3931FF000000004A3931FF000000004A3929FF0000
+ 00004A3931FF000000004A3931FF000000004A3931FF000000004A3931FF0000
+ 00004A3931FF0000000000000000AD948CFF00000000AD948CFF00000000AD94
+ 8CFF00000000AD948CFF00000000A57B6BFF000000009C7B6BFF00000000A57B
+ 6BFF00000000A57B6BFF000000006B6352FF00000000735A52FF000000006B5A
+ 52FF000000000000000000000000E7AD8CFFE7B58CFFE7B58CFFF7A573FFDEA5
+ 7BFFDEAD84FFDEA57BFFE79C63FFE7946BFFE79463FFEF9C6BFFE79463FFD684
+ 5AFFD68452FFD6845AFFDE7B4AFFE77B4AFFDE7B4AFFDE7B4AFFE77B4AFFDE7B
+ 4AFF4A4231FF0000000000000000E7B58CFFFFDECEFFF7DECEFFFFDECEFFF7DE
+ C6FFFFD6BDFFF7D6BDFFF7CEB5FFF7CEB5FFF7CEB5FFF7BD9CFFF7BDA5FFF7BD
+ 9CFFF7B58CFFF7B58CFFF7B58CFFF7A57BFFF7A573FFF7A57BFFF7A573FFE794
+ 6BFF4A4231FF0000000000000000E7AD8CFFF7DEC6FFFFDEBDFFF7DEC6FFF7CE
+ ADFFEFCEB5FFF7CEADFFFFCE9CFFF7BD9CFFEFBD9CFFF7B58CFFF7B58CFFF7B5
+ 8CFFF7A573FFF7A573FFF7A573FFEFA573FFF7A57BFFE79C63FFE7946BFFE79C
+ 63FF4A4231FF0000000000000000F7A573FFF7A573FFF7A57BFFDEA57BFFDEA5
+ 7BFFDEA57BFFE79463FFE7946BFFE79463FFE79C6BFFE79463FFD68452FFCE84
+ 52FFD68452FFDE7B4AFFDE7B4AFFDE7B4AFFDE7B4AFFDE7B4AFF4A4231FF4A42
+ 31FF4A4231FF0000000000000000CEBDB5FFFFFFFFFFFFFFFFFFFFFFFFFFEFBD
+ 9CFFFFFFFFFFFFFFFFFFFFFFFFFFEFC69CFFFFFFFFFFF7EFEFFFF7F7F7FFEFBD
+ 9CFFFFFFFFFFEFEFF7FFF7F7EFFFEFBD9CFFF7EFEFFFF7F7EFFFFFDECEFFE7BD
+ 9CFF4A4231FF0000000000000000CEBDADFFFFFFFFFFEFF7EFFFF7EFEFFFE7BD
+ 9CFFFFFFFFFFF7EFEFFFF7F7EFFFCEA58CFFF7EFEFFFEFF7EFFFF7DECEFFD6A5
+ 84FFEFEFEFFFF7EFEFFFF7DEC6FFD6A584FFEFEFEFFFF7DECEFFF7CEB5FFCE9C
+ 7BFF4A4231FF0000000000000000CEBDADFFFFFFFFFFF7EFEFFFEFEFEFFFD6A5
+ 84FFFFFFFFFFEFF7EFFFFFDECEFFC69C7BFFF7EFEFFFFFDEC6FFF7DECEFFC69C
+ 7BFFF7F7EFFFF7D6BDFFF7CEADFFC69C7BFFFFDECEFFF7CEADFFFFCE9CFFC69C
+ 7BFF4A4231FF0000000000000000CEAD9CFFE7BD9CFFEFBD94FFCEA584FFD6AD
+ 8CFFE7B594FFE7AD8CFFCE9C7BFFC69C7BFFE7BD94FFD6A584FFCE9C7BFF398C
+ D6FF428CD6FF398CD6FF1842CEFF1842CEFFE7BD94FFD6A58CFFC69C7BFFA57B
+ 73FF4A4231FF0000000000000000C6B59CFFFFFFFFFFFFFFFFFFF7EFEFFFE7B5
+ 94FFFFFFFFFFF7F7EFFFEFEFEFFFEFB594FFEFEFEFFFF7F7EFFFEFEFEFFF428C
+ D6FFF7F7EFFFF7EFEFFFFFE7CEFF1839CEFFFFE7CEFFF7DEC6FFFFE7CEFFE7B5
+ 94FF4A4231FF0000000000000000C6ADA5FFFFFFFFFFF7EFEFFFEFF7EFFFD6A5
+ 8CFFFFFFFFFFF7EFEFFFF7E7CEFFD6A58CFFEFEFEFFFF7EFEFFFFFE7C6FF398C
+ D6FFFFDECEFFF7D6BDFFFFDEBDFF1042CEFFFFDECEFFF7D6BDFFF7CEB5FFCE9C
+ 7BFF4A4231FF0000000000000000C6AD9CFFFFFFFFFFF7F7EFFFF7DECEFFCE9C
+ 7BFFEFF7EFFFFFDEC6FFF7D6BDFFCE9C7BFFEFF7EFFFFFDECEFFF7D6B5FF1839
+ CEFFFFDEBDFFF7D6BDFFF7CEADFF1842CEFFFFDEBDFFEFC6A5FFEFBD9CFFC69C
+ 7BFF4A3931FF0000000000000000CEB59CFFE7B594FFD6A584FFC69C7BFFCE9C
+ 7BFFE7B594FFCEA58CFFCE9C7BFFC69C7BFFEFB594FFCEA58CFFCE9C7BFF1842
+ CEFF1042CEFF1842CEFF1842CEFF1042D6FFE7AD8CFFC69C7BFFAD948CFFA57B
+ 6BFF4A4231FF0000000000000000C6ADA5FFFFFFFFFFF7F7EFFFF7EFEFFFE7B5
+ 94FFF7F7EFFFF7F7EFFFEFEFEFFFE7BD94FFF7EFEFFFFFE7CEFFF7DECEFFEFBD
+ 94FFFFDECEFFFFE7CEFFFFDEBDFFEFB594FFF7DEC6FFFFDEC6FFF7CEADFFE7B5
+ 9CFF4A4231FF0000000000000000C6B59CFFF7EFEFFFEFEFEFFFF7F7EFFFCEA5
+ 8CFFF7EFEFFFF7DEC6FFFFDECEFFD6A584FFF7DECEFFF7D6BDFFFFDEBDFFC69C
+ 7BFFFFDECEFFF7D6BDFFF7CEB5FFC69C7BFFFFD6BDFFEFCEB5FFFFCE9CFFCE9C
+ 7BFF4A3931FF0000000000000000D6A58CFFF7F7EFFFEFEFEFFFF7DEBDFFCE9C
+ 7BFFEFF7EFFFF7D6C6FFF7CEADFFC69C7BFFFFE7CEFFF7D6BDFFFFCEA5FFC69C
+ 7BFFF7DEBDFFF7CEB5FFF7BD9CFFC69C7BFFF7CEB5FFF7BD9CFFE7BD94FFCE9C
+ 7BFF4A4231FF0000000000000000CEA58CFFF7D6B5FFE7B594FFD6A58CFFC69C
+ 7BFFE7AD8CFFCE9C7BFFAD948CFF9C7B6BFFE7AD8CFFCE9C7BFFAD948CFF9C7B
+ 6BFFE7AD8CFFC69C7BFFAD948CFF9C7B6BFFE7B58CFFC69C7BFFAD948CFFA57B
+ 73FF4A3931FF0000000000000000D6A58CFF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000CEBDADFFCEBDB5FFD6BD
+ ADFFCEBDADFFCEBDADFFCEBDADFFD6BDB5FFCEBDADFFCEAD9CFFC6B5A5FFCEAD
+ 9CFFC6B59CFFC6AD9CFFC6B59CFFCEAD9CFFC6B59CFFD6A58CFFCEA584FFD6A5
+ 8CFFAD948CFFAD9484FFAD948CFF0000000000000000D6BDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFEFEFEFFFF7F7EFFF4A4231FF0000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFF7EFEFFFB5BDBDFFAD948CFF6B7B8CFF6B848CFFBDBDBDFFF7EFEFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7EFFFF7EF
+ EFFFEFF7EFFFFFD6C6FF4A4231FF0000000000000000CEBDB5FFFFFFFFFFFFFF
+ FFFFBDBDBDFF6B848CFF6B7B8CFF8C9CA5FFAD948CFF6B5A52FFB5BDBDFFFFFF
+ FFFFFFFFFFFFF7AD8CFFF7B58CFFF7B58CFFF7A573FFF7A57BFFEFA573FFF7A5
+ 73FFEFEFEFFFFFDEC6FF4A4231FF0000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFF6B7B8CFF6B5A52FF736352FF6B848CFF6B5A52FFBDBDBDFF6B7B8CFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFF7F7EFFFEFEFEFFFF7F7
+ EFFFEFEFEFFFF7D6B5FF4A4231FF0000000000000000D6BDADFFFFFFFFFFFFFF
+ FFFF736352FF4A3931FFBDBDBDFFDED6D6FFBDBDBDFF8C9CA5FF6B848CFFFFFF
+ FFFFFFFFFFFFFFB58CFFF7AD8CFFF7B58CFFF7A573FFEFA573FFF7A573FFF7A5
+ 73FFF7EFEFFFF7CEADFF4A4231FF0000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFF4A3931FF4A4231FFDED6D6FFB5B5BDFF849CA5FF6B7B8CFF6B6352FFFFFF
+ FFFFFFFFFFFFEFF7EFFFF7EFEFFFF7F7EFFFEFEFEFFFF7EFEFFFEFEFEFFFF7F7
+ EFFFEFEFEFFFF7BD9CFF4A4231FF0000000000000000CEADA5FFFFFFFFFFFFFF
+ FFFFBDBDBDFF000000FFBDBDBDFF8C9CA5FF6B848CFF735A52FF849CA5FFF7EF
+ EFFFF7F7EFFFF7EFEFFFF7EFEFFFEFEFEFFFF7EFEFFFEFF7EFFFF7EFEFFFEFEF
+ EFFFFFE7CEFFF7BDA5FF4A4231FF0000000000000000C6AD9CFFFFFFFFFFFFFF
+ FFFFF7F7EFFFDECECEFF6B5A52FF6B6352FF735A52FF1842D6FFBDBDBDFFF7F7
+ EFFFEFEFEFFFEFEFE7FFF7F7EFFFEFEFEFFFF7F7EFFFF7EFEFFFF7DEC6FFFFDE
+ C6FFF7DECEFFEFB594FF4A4231FF0000000000000000CEAD9CFFFFFFFFFFFFFF
+ FFFFB5CEDEFF1842CEFF1842CEFFDED6D6FFF7F7EFFF1842CEFF1839CEFFD6D6
+ CEFFF7EFEFFFC69C7BFFCE9C7BFF9C7B6BFF9C736BFF9C7B6BFF9C7B6BFF9C7B
+ 6BFFF7E7C6FFFFB58CFF4A4231FF0000000000000000C6AD9CFFFFFFFFFFFFFF
+ FFFF1842CEFF84ADC6FF398CD6FF1842CEFF1884BDFF1842CEFF188CC6FF1842
+ CEFFF7F7EFFFF7EFEFFFEFEFEFFFF7F7EFFFFFDEC6FFFFE7CEFFFFDECEFFFFD6
+ C6FFF7DEC6FFF7A573FF4A4231FF0000000000000000CEB5A5FFFFFFFFFFFFFF
+ FFFF1842CEFF39ADEFFF428CD6FF428CD6FF1842CEFF188CBDFF1842CEFF315A
+ 73FFF7EFEFFFC69C7BFFA57B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C7B6BFF9C73
+ 6BFFF7DEC6FFF7A573FF4A4231FF0000000000000000C6AD9CFFFFFFFFFFFFFF
+ FFFF1842CEFF188CBDFF428CD6FF428CD6FF1842CEFF188CC6FF2142CEFF3963
+ 7BFFF7F7EFFFFFDECEFFF7DEC6FFFFDECEFFFFDECEFFFFDEC6FFF7DEBDFFFFDE
+ C6FFF7D6B5FFF7A57BFF4A4231FF0000000000000000C6AD9CFFFFFFFFFFF7F7
+ EFFFDED6CEFF1842CEFF1842CEFF1842CEFF1842CEFF396373FF39637BFFCEBD
+ ADFFFFDECEFF9C7B6BFFA57B6BFF9C7B6BFF9C7B6BFF9C736BFF9C7B6BFF9C73
+ 6BFFF7CEB5FFE79463FF4A4231FF0000000000000000D6A58CFFF7F7EFFFF7EF
+ EFFFF7EFEFFFF7F7EFFFF7F7EFFFF7F7EFFFF7F7EFFFF7EFEFFFFFDECEFFFFE7
+ C6FFF7DECEFFFFDECEFFF7DEBDFFFFDEC6FFF7DEC6FFFFD6BDFFF7CEADFFF7CE
+ B5FFF7CEADFFE79463FF4A4231FF0000000000000000CEA584FFF7EFEFFFF7DE
+ C6FFF7D6C6FFF7DEC6FFF7CEBDFFF7D6B5FFF7C6ADFFEFC6ADFFF7BD9CFFEFBD
+ 9CFFE7B594FFE7B58CFFF7AD8CFFF7A573FFF7A573FFEFA573FFF7A57BFFE794
+ 63FFE79463FFEF9C6BFF4A4231FF0000000000000000D6A58CFF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A4231FF4A42
+ 31FF4A4231FF4A4231FF4A4231FF000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000849CA5FF849CA5FF849CA5FF8C9C
+ A5FF6B7B8CFF0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000DEC6B5FFCEBD
+ ADFFD6BDADFFCEBDB5FFCEBDADFF8C9CA5FF8CC6D6FFC6EFFFFFC6F7FFFFADE7
+ F7FF8CC6D6FF6B7B8CFFCEAD9CFFC6B5A5FFCEAD9CFFC6AD9CFFC6ADA5FF0000
+ 00000000000000000000000000000000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF7EFEFFF849CA5FFC6F7FFFF6B7B8CFF6B7B8CFF8C9C
+ A5FF8CC6CEFF31637BFFCEAD9CFFF7F7EFFFEFEFEFFFF7F7EFFFF7EFEFFF849C
+ A5FF0000000000000000000000000000000000000000D6BDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF8C9CA5FF8CBDD6FFADF7FFFF6B848CFF84ADC6FF8CC6
+ D6FF6BCEF7FF6B7B8CFF31637BFFFFDEC6FFEFEFEFFFF7F7EFFFB5CED6FF395A
+ 7BFF0000000000000000000000000000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF849CA5FFADE7F7FFADE7EFFF8CBDD6FF8CC6CEFF8CC6
+ CEFF84ADC6FF84ADC6FF6B848CFFFFDEC6FFEFEFEFFFB5CED6FF1842CEFF428C
+ D6FF0000000000000000000000000000000000000000D6BDB5FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF6B848CFF6B7B8CFF6B7B8CFF396373FF39637BFF395A
+ 7BFF396373FF6B7B8CFFAD948CFFFFDEBDFFA5ADF7FF1842CEFF428CD6FFCEA5
+ 8CFF0000000000000000000000000000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7EFFFF7F7EFFFFFDECEFFF7DEC6FFFFD6
+ B5FFEFC6ADFFF7D6BDFFFFDEC6FFA5ADF7FF398CD6FF428CD6FFFFE7C6FF9C7B
+ 6BFF0000000000000000000000000000000000000000CEBDB5FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEF
+ EFFFF7F7EFFFF7EFEFFFB5CED6FF1842CEFF1842CEFFB5CED6FFFFDECEFF9C7B
+ 6BFF0000000000000000000000000000000000000000D6BDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7EFEFFFF7EF
+ EFFFEFEFEFFFA5ADF7FF398CD6FF1842CEFFBDBDBDFFFFDECEFFF7D6BDFF6B5A
+ 52FF0000000000000000000000000000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7EFEFFFEFEFEFFFF7F7
+ EFFFA5B5F7FF428CD6FF1842CEFF84ADBDFFFFDECEFFFFE7C6FFF7C6ADFF6B63
+ 52FF0000000000000000000000000000000000000000CEBDADFFFFFFFFFFFFFF
+ FFFFA5ADFFFFB5CED6FFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFF7F7E7FFA5AD
+ F7FF398CD6FF1842CEFF8C9CA5FFDED6CEFFF7DECEFFF7DEBDFFF7BD9CFF6B5A
+ 52FF0000000000000000000000000000000000000000CEBDB5FFF7F7EFFFA5AD
+ F7FF428CD6FF398CD6FFA5ADF7FFFFFFFFFFF7EFEFFFF7F7EFFFA5ADF7FF428C
+ D6FF1842CEFF398CD6FFFFDEC6FFF7E7CEFFFFD6BDFFF7DEC6FFEFBD9CFF6B63
+ 52FF0000000000000000000000000000000000000000E7BDADFFA5E7F7FF1842
+ CEFF1842CEFF1842CEFFADB5F7FFA5ADF7FFEFF7EFFFA5ADF7FF398CD6FF1842
+ CEFF1842CEFFE7D6CEFFFFDECEFFF7D6BDFFF7DEC6FFF7CEADFFE7AD8CFF6B5A
+ 52FF0000000000000000000000000000000000000000CEAD9CFFFFFFFFFFADB5
+ F7FF1842CEFF1842CEFF1842CEFFA5ADF7FFA5ADF7FF428CD6FF1842CEFF1842
+ CEFFBDBDBDFFFFE7C6FFF7D6C6FFF7DEBDFFF7D6C6FFF7C6ADFFE7B58CFF4A42
+ 31FF0000000000000000000000000000000000000000C6B59CFFFFFFFFFFFFFF
+ FFFFBDCED6FF1842CEFF1842CEFF1842CEFF428CD6FF1842CEFF1842CEFF428C
+ D6FFFFDECEFFF7DECEFFF7DEBDFFFFD6C6FFF7D6B5FFEFC6ADFFF7B58CFF4A39
+ 31FF0000000000000000000000000000000000000000CEAD9CFFFFFFFFFFFFFF
+ FFFFF7EFEFFFBDD6DEFF1842CEFF2142CEFF1842CEFF1842CEFF1842CEFFDED6
+ CEFFF7DEC6FFFFDEBDFFF7D6C6FFF7D6B5FFF7CEB5FFEFC6A5FFF7A573FF4A39
+ 31FF0000000000000000000000000000000000000000C6AD9CFFFFFFFFFFF7F7
+ EFFFEFEFEFFFF7EFEFFFB5CED6FF1842CEFF1842CEFF2142CEFFD6C6ADFFF7D6
+ BDFFF7D6BDFFF7CEADFFEFC6ADFFF7C6ADFFF7BD9CFFE7BD94FFF7A57BFF4A42
+ 31FF0000000000000000000000000000000000000000CEAD9CFFEFF7EFFFFFD6
+ C6FFF7D6BDFFEFC6A5FFF7CEADFF8C9CA5FF1842CEFFAD9C8CFFE7B594FFE7AD
+ 8CFFE7AD8CFFE7AD8CFFF7B58CFFF7B58CFFEFA573FFF7A57BFFEF9463FF4A42
+ 31FF0000000000000000000000000000000000000000CEAD8CFF9C736BFF6B5A
+ 52FF6B6352FF735A52FF6B5A52FF6B6352FFA57B6BFF6B5A52FF736352FF6B5A
+ 52FF4A4231FF4A4231FF4A3931FF4A4231FF4A3931FF4A4231FF4A4231FF0000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000000000008CC6D6FF8CBD
+ D6FF8CC6D6FF8CC6CEFF8CBDD6FF8CC6CEFF8CC6D6FF8CBDD6FF8CC6CEFF94BD
+ D6FF7BADC6FF84ADC6FF7BADC6FF84ADC6FF7BADBDFF84ADC6FF7BADC6FF84AD
+ BDFF7BADC6FF00000000000000000000000000000000000000008CC6CEFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFF395A7BFF000000000000000000000000000000000000000094BDD6FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFF39637BFF00000000000000000000000000000000000000008CC6D6FFFFFF
+ FFFFCEF7FFFFC6EFFFFFC6F7FFFFCEF7FFFFC6EFFFFFC6F7FFFFC6F7FFFFC6F7
+ FFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7
+ FFFF395A7BFF00000000000000000000000000000000000000008CC6CEFFC6EF
+ FFFFA5F7FFFFA5F7FFFFADEFFFFFA5F7FFFFA5F7FFFFADF7FFFFA5EFFFFFADF7
+ FFFFA5EFFFFFADF7FFFFA5EFFFFFADF7FFFFA5EFFFFFADF7FFFFA5EFFFFFADF7
+ FFFF396373FF00000000000000000000000000000000000000008CC6D6FFC6F7
+ FFFFADF7FFFFA5F7F7FFADF7FFFFA5F7F7FFADEFFFFFA5F7F7FFADF7FFFFA5F7
+ F7FFADF7FFFFA5F7F7FFADF7FFFFA5F7F7FFADF7FFFFA5F7FFFFADF7FFFFA5F7
+ FFFF315A73FF00000000000000000000000000000000000000008CC6CEFFC6EF
+ FFFFA5EFFFFFADF7FFFFA5EFFFFFADF7FFFFA5F7FFFFA5F7FFFFADF7FFFFA5EF
+ FFFFA5F7FFFFADF7FFFFA5EFFFFFA5F7FFFFADF7FFFFA5EFFFFFA5F7F7FFADF7
+ FFFF39637BFF00000000000000000000000000000000000000007BADBDFF94E7
+ FFFF8CE7F7FFA5F7FFFFADF7F7FFA5F7FFFFADEFF7FFA5F7FFFFADF7F7FFA5F7
+ FFFFADF7F7FFA5EFFFFFADF7F7FFA5F7FFFFADF7F7FFA5F7FFFFADF7FFFFA5F7
+ FFFF395A73FF000000000000000000000000000000000000000084ADBDFF8CE7
+ FFFF94E7F7FFA5F7FFFFADEFFFFFA5F7FFFFA5F7FFFFADF7FFFFA5F7FFFFA5EF
+ FFFFADF7FFFFA5F7FFFFA5F7FFFFADF7FFFFA5EFFFFFADF7F7FFA5EFFFFFADF7
+ FFFF31637BFF00000000000000000000000000000000000000007BADC6FF84D6
+ F7FF8CE7FFFF8CE7F7FF8CE7F7FF94E7F7FF8CDEFFFF8CE7F7FF94E7F7FF8CE7
+ F7FF8CE7FFFF94DEF7FF8CE7F7FF8CE7FFFF8CE7F7FF8CE7FFFF94E7F7FF8CE7
+ FFFF395A73FF000000000000000000000000000000000000000084ADBDFF63C6
+ F7FF94E7F7FF8CE7FFFF94E7FFFF8CE7F7FF8CE7FFFF94E7F7FF8CDEFFFF94E7
+ FFFF8CE7F7FF94E7FFFF8CE7F7FF94DEFFFF8CE7F7FF94E7FFFF8CE7F7FF94E7
+ FFFF31637BFF00000000000000000000000000000000000000007BADC6FF52BD
+ F7FF7BD6F7FF94E7F7FF8CDEFFFF94E7F7FF8CE7FFFF8CE7F7FF94E7FFFF8CE7
+ F7FF8CE7FFFF8CE7F7FF94E7FFFF8CE7F7FF94E7FFFF8CDEF7FF8CE7FFFF94E7
+ F7FF395A73FF000000000000000000000000000000000000000084ADBDFF319C
+ CEFF39B5E7FF4ABDEFFF4AB5F7FF39B5DEFF39B5E7FF84D6F7FF8CE7F7FF8CDE
+ FFFF94E7F7FF8CE7FFFF94DEF7FF8CE7FFFF8CE7F7FF94E7FFFF8CE7F7FF94E7
+ FFFF31637BFF000000000000000000000000000000000000000084ADC6FF39B5
+ E7FF39B5DEFF39B5E7FF39B5E7FF39B5DEFF00A5DEFF6BCEF7FF7BD6F7FF84D6
+ F7FF7BD6F7FF84D6F7FF7BD6F7FF7BD6F7FF84D6F7FF7BD6F7FF7BD6F7FF84D6
+ F7FF315A7BFF000000000000000000000000000000000000000084ADBDFF6BCE
+ F7FF00A5DEFF39B5E7FF39B5DEFF39B5E7FF00A5DEFF39B5E7FF84D6F7FF7BD6
+ FFFF84DEF7FF7BD6F7FF84DEF7FF7BD6FFFF84DEF7FF7BD6F7FF84D6FFFF7BDE
+ F7FF39637BFF00000000000000000000000000000000000000007BADC6FF6BCE
+ F7FF39B5DEFF1884BDFF39B5E7FF39B5DEFF39ADEFFF00A5DEFF6BCEF7FF7BD6
+ F7FF7BD6F7FF84D6F7FF7BD6F7FF84D6F7FF7BD6F7FF84DEF7FF7BD6F7FF84D6
+ F7FF31637BFF000000000000000000000000000000000000000084ADBDFF63C6
+ F7FF6BCEF7FF52BDF7FF00A5DEFF1884BDFF08A5DEFF00A5DEFF219CEFFF6BCE
+ F7FF63C6F7FF84DEF7FF7BD6FFFF7BDEF7FF84D6F7FF7BD6FFFF7BD6F7FF84D6
+ F7FF39637BFF00000000000000000000000000000000000000007BADC6FF6BCE
+ F7FF63C6F7FF6BCEF7FF6BCEF7FF4ABDF7FF299CEFFF319CCEFF08A5DEFF319C
+ CEFF39ADEFFF39B5E7FF4AB5EFFF52BDF7FF63C6F7FF6BCEF7FF6BCEF7FF63CE
+ F7FF395A73FF000000000000000000000000000000000000000084ADC6FF3963
+ 73FF395A7BFF396373FF395A7BFF395A73FF39637BFF396373FF39637BFF3963
+ 73FF39637BFF39637BFF395A73FF39637BFF396373FF395A7BFF396373FF395A
+ 7BFF39637BFF0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000000000008494A5FF849C
+ A5FF849CA5FF8C9CA5FF849CADFF849CA5FF8C9CA5FF00000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000008C9CA5FFB5CEDEFFCEF7
+ FFFFC6F7FFFFC6EFFFFFADF7FFFFADE7F7FFB5CED6FF849CA5FF000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000008494A5FF84ADC6FFB5CED6FFB5CE
+ D6FFB5CEDEFFB5CED6FF8CBDCEFF8CC6D6FF8CBDCEFF84ADC6FF849CA5FF0000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000008C9CA5FF849CA5FF8C9CADFF849C
+ A5FF8C9CA5FF849CA5FF8C9CA5FF8C9CA5FF6B848CFF6B7B8CFF6B848CFF6B7B
+ 8CFF6B848CFF6B7B8CFF6B7B8CFF6B7B8CFF6B7B8CFF6B7B8CFF6B7B8CFF6B7B
+ 8CFF6B7B8CFF000000000000000000000000849CADFFCEF7FFFFC6EFFFFFC6F7
+ FFFFC6EFFFFFC6F7FFFFC6F7FFFFADE7F7FFADE7F7FFADE7F7FFADE7F7FF7BD6
+ F7FF84DEF7FF7BD6F7FF84DEF7FF7BDEF7FF6BCEF7FF6BCEF7FF63CEF7FF6BCE
+ F7FF84ADC6FF6B7B8CFF0000000000000000849CA5FFC6EFFFFFC6F7FFFFC6EF
+ FFFFADE7F7FFADE7F7FFADDEF7FFADE7F7FF8CE7F7FF7BD6F7FF7BDEF7FF6BC6
+ F7FF63CEF7FF6BC6F7FF63CEF7FF52B5F7FF4AB5F7FF4AB5F7FF39B5DEFF39B5
+ E7FF319CCEFF39637BFF0000000000000000849CA5FFC6F7FFFFC6EFFFFFADF7
+ FFFFA5E7EFFFADE7F7FFA5E7EFFF8CE7F7FF84D6F7FF7BD6F7FF6BC6F7FF6BCE
+ F7FF6BC6F7FF6BCEF7FF4AB5EFFF52BDF7FF4ABDEFFF39B5DEFF39B5E7FF319C
+ CEFF31A5CEFF735A52FF00000000000000008C9CA5FFC6EFFFFFA5F7FFFFADE7
+ EFFFADE7F7FFA5E7EFFF94E7FFFF7BD6F7FF84D6FFFF7BD6F7FF6BCEF7FF63C6
+ F7FF6BCEF7FF4AB5EFFF52BDF7FF4AB5EFFF39B5E7FF39B5E7FF39B5E7FF399C
+ CEFF319CCEFF39637BFF0000000000000000849CA5FFC6F7FFFFADE7F7FFADDE
+ F7FFA5E7EFFFADE7F7FF8CE7F7FF84D6F7FF7BDEF7FF6BC6F7FF6BCEF7FF63CE
+ F7FF6BC6F7FF4ABDF7FF52B5EFFF4ABDF7FF39B5DEFF39B5E7FF39ADEFFF319C
+ CEFF188CC6FF523931FF00000000000000008C9CA5FFC6EFFFFFADE7EFFFA5E7
+ F7FFADE7EFFF94E7FFFF7BD6F7FF84D6F7FF63C6F7FF6BCEF7FF63C6F7FF6BCE
+ F7FF4AB5EFFF52BDF7FF4AB5EFFF39B5E7FF39B5DEFF39B5E7FF31ADEFFF399C
+ CEFF188CC6FF4A4231FF0000000000000000849CA5FFC6F7FFFFADE7F7FFADDE
+ EFFF8CE7FFFF7BD6F7FF7BD6F7FF84DEF7FF63C6F7FF6BCEF7FF6BC6F7FF4ABD
+ EFFF52B5F7FF4ABDEFFF39B5E7FF39B5E7FF39B5DEFF39A5F7FF39ADEFFF319C
+ CEFF1884BDFF524231FF00000000000000008C9CA5FFC6EFFFFFADE7F7FFA5E7
+ EFFF94E7FFFF7BD6F7FF84D6F7FF63C6F7FF6BCEF7FF6BCEF7FF4AB5EFFF52BD
+ F7FF4AB5F7FF39B5DEFF39B5E7FF39B5DEFF31ADF7FF39ADEFFF319CCEFF399C
+ CEFF188CC6FF4A4231FF0000000000000000849CA5FFADE7F7FFA5E7EFFF94E7
+ FFFF7BD6F7FF84D6F7FF63CEF7FF6BCEF7FF6BC6F7FF63CEF7FF52B5F7FF4ABD
+ EFFF39B5E7FF39B5DEFF39B5E7FF39A5EFFF39ADEFFF319CCEFF39A5CEFF1884
+ C6FF188CBDFF4A3931FF00000000000000008494A5FFADE7F7FF8CE7FFFF7BD6
+ F7FF84D6F7FF63CEF7FF6BC6F7FF6BCEF7FF63C6F7FF52BDF7FF4AB5EFFF39B5
+ E7FF39B5DEFF39B5E7FF31ADEFFF39ADF7FF319CCEFF399CD6FF319CCEFF188C
+ BDFF1884C6FF4A4231FF0000000000000000849CA5FFADE7F7FF7BD6F7FF84D6
+ F7FF7BDEF7FF6BC6F7FF63CEF7FF6BC6F7FF4ABDEFFF52B5EFFF4ABDF7FF39B5
+ DEFF39B5E7FF39A5EFFF39ADEFFF319CCEFF39A5CEFF319CCEFF39A5CEFF1884
+ C6FF188CBDFF000000FF0000000000000000849CA5FFADE7F7FF84D6F7FF7BDE
+ F7FF6BC6F7FF6BCEF7FF63C6F7FF6BCEF7FF52BDF7FF4AB5F7FF39B5DEFF39B5
+ E7FF39B5E7FF39ADEFFF31ADF7FF399CCEFF319CCEFF399CCEFF31A5CEFF1884
+ BDFF188CC6FF000000FF0000000000000000849CADFFADE7EFFF7BD6F7FF6BC6
+ F7FF4ABDF7FF4AB5EFFF52BDEFFF4AB5F7FF39B5DEFF39ADEFFF319CCEFF399C
+ CEFF319CCEFF319CCEFF399CCEFF31A5CEFF1884C6FF188CC6FF1884BDFF188C
+ C6FF1884BDFF000000FF00000000000000008C9CA5FFADE7F7FF4AB5F7FF4ABD
+ F7FF84ADBDFF39B5E7FF319CCEFF399CCEFF319CCEFF319CCEFF1884BDFF188C
+ C6FF1884BDFF188CC6FF188CBDFF1884C6FF188CBDFF1884BDFF188CC6FF1884
+ BDFF188CC6FF000000FF00000000000000006B7B8CFF396373FF39637BFF5239
+ 29FF4A4231FF524231FF4A4231FF524231FF4A4231FF524231FF000000FF0000
+ 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000
+ 00FF000000FF000000FF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000
+ }
+ end
+ object SmallImages: TImageList
+ left = 40
+ top = 16
+ Bitmap = {
+ 4C69060000001000000010000000000000000000000000000000000000000000
+ 000000000000CEBDADFFC6ADA5FFC6AD9CFFC6ADA5FF00000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000008CBD
+ CEFFC6ADA5FFEFE7DEFFC6F7FFFFC6F7FFFFBDC6CEFFCEBDADFF000000000000
+ 0000000000000000000000000000000000000000000000000000CEBDB5FFCEBD
+ ADFFC6EFFFFFC6F7FFFFC6EFFFFFADE7EFFF8CE7FFFF63CEF7FFC6AD9CFF8C9C
+ A5FF0000000000000000000000000000000000000000CEBDADFFC6D6DEFFC6F7
+ FFFFC6F7FFFFC6EFFFFFADEFFFFFA5E7EFFF7BD6F7FF6BC6F7FF63CEF7FF8CBD
+ D6FFC6AD9CFF84ADC6FF00000000C6AD9CFFCEB5ADFFC6F7FFFFC6EFFFFFC6EF
+ FFFFC6F7FFFFA5EFFFFFADE7EFFF7BD6F7FF63C6F7FF6BCEF7FF6BC6EFFF6BCE
+ F7FF4AB5EFFF8CADC6FF8C9CA5FFC6AD9CFFADF7FFFFA5E7F7FFADE7EFFFADE7
+ EFFF7BD6F7FF6BC6F7FF63CEF7FF6BCEF7FF6BCEEFFF4AADEFFF42B5EFFF4AAD
+ E7FF42B5EFFF29BDEFFFBD9C8CFFC6ADA5FFADE7EFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7EFE7FFFFF7EFFFFFEFE7FFFFF7
+ EFFFEFDEDEFF42B5EFFF94847BFFC6AD9CFFCEBDB5FFF7EFEFFFFFEFE7FFE7E7
+ DEFFFFEFEFFFFFEFE7FFF7F7EFFFFFEFE7FFF7EFEFFFFFEFE7FFF7DECEFFF7F7
+ E7FFFFD6C6FF94847BFF94847BFFC6ADA5FFF7CEB5FFDEC6ADFFF7EFEFFFFFEF
+ EFFFE7BD94FFE7B594FFC6ADA5FFC6AD9CFFC6ADA5FFC6AD9CFFE7E7DEFFFFDE
+ C6FFB59C8CFFE7AD84FF94847BFFC6A58CFFFFFFFFFFFFDEC6FFDEC6ADFFDEC6
+ ADFFDEBDADFFDECEC6FFDEC6ADFFDEC6B5FFDEC6ADFFC6ADA5FFC6AD9CFFB59C
+ 8CFFE7AD8CFFFFD69CFF8C8484FFBDA594FFFFFFFFFFFFFFFFFFBDA58CFFDECE
+ C6FFFFF7EFFFF7EFEFFFFFF7EFFFF7EFEFFFFFDECEFFFFDEC6FFDEA57BFFB58C
+ 73FFFFD69CFFFFCE94FF94847BFFC6A58CFFFFFFFFFFC6ADA5FFDECEC6FFF7EF
+ EFFFF7EFE7FFFFEFEFFFF7EFE7FFFFF7E7FFF7DEC6FFF7DEC6FFFFD6ADFFE7AD
+ 84FFB58473FFFFB57BFFCE734AFFB59C8CFFC6ADA5FFDECEC6FFFFFFFFFFF7F7
+ E7FFFFDECEFFF7E7C6FFFFDECEFFF7DEC6FFFFD6ADFFFFDEB5FFFFD69CFFFFCE
+ 94FFE79463FFC67B4AFFCE7342FFBD9C84FFF7D6BDFFFFFFFFFFFFDECEFFFFDE
+ ADFFFFD69CFFFFC68CFFFFC68CFFFFC694FFFFB57BFFFFB57BFFF7A57BFFEFA5
+ 7BFFE79463FFD6845AFFB56331FFB59C8CFFB59C8CFFB58C73FFB58473FFB58C
+ 73FF8C8484FFCE734AFFC6734AFFC67B42FFC6734AFFC6734AFFC6734AFFB563
+ 31FFBD6331FFB56331FFBD6331FF000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF4A3931FFFF00FFFF4A4231FFFF00
+ FFFF4A4231FFFF00FFFF4A4231FFFF00FFFF523931FFFF00FFFF4A4231FFFF00
+ FFFF524231FFFF00FFFF524231FFB59C8CFFFFFFFFFF94847BFFFFFFFFFF9484
+ 84FFFFFFFFFF94847BFFFFFFFFFF948484FFFFFFFFFF52636BFFFFFFFFFF525A
+ 6BFFFFFFFFFF52636BFFFF00FFFFF7A58CFFF7AD94FFF7A57BFFDEA57BFFDEA5
+ 7BFFE7946BFFE79463FFE7946BFFD68452FFDE7B4AFFD68452FFCE7B4AFFCE73
+ 4AFFC67B42FFCE734AFF524231FFEFAD94FFF7EFEFFFFFF7EFFFF7EFEFFFFFF7
+ EFFFF7F7EFFFF7EFEFFFF7AD8CFFF7A57BFFF7A57BFFF7A57BFFEFA57BFFF7A5
+ 7BFFF7A57BFFF7A57BFF524231FFF7AD8CFFF7A58CFFEFA573FFF7A57BFFEFA5
+ 73FFF7A57BFFE79463FFE79463FFDE946BFFD68452FFDE7B4AFFDE7B4AFFDE7B
+ 4AFFDE7B4AFFDE7B4AFF524231FFBDADA5FFFFFFFFFFFFFFFFFFDEA57BFFFFFF
+ FFFFFFFFFFFFDEA57BFFFFFFFFFFFFFFFFFFDEA57BFFFFFFFFFFFFFFFFFFDEA5
+ 7BFFFFF7EFFFF7EFEFFF4A4231FFC6ADA5FFFFFFFFFFFFFFFFFFB59C8CFFFFFF
+ FFFFFFFFFFFFB59C8CFFFFFFFFFFFFFFFFFFB59C8CFFFFFFFFFFFFF7EFFFB594
+ 8CFFFFF7EFFFDECEC6FF4A4239FFC6AD9CFFD6AD94FFB59C8CFFBD8473FFDEA5
+ 7BFFB59C8CFFB58C73FFDEA57BFFB59C8CFF42B5EFFF2994DEFF1842CEFF184A
+ CEFFDEA57BFF00000000524239FFC6ADA5FFFFFFFFFFFFFFFFFFDEA57BFFFFFF
+ FFFFFFFFFFFFDEA57BFFFFFFFFFFFFFFFFFF299CDEFFFFFFFFFFFFF7EFFF1842
+ C6FFFFF7EFFFDECECEFF4A4231FFC6AD9CFFFFFFFFFFFFFFFFFFB59C8CFFFFFF
+ FFFFFFFFFFFFB59C8CFFFFFFFFFFFFEFEFFF1842CEFFFFF7EFFFFFEFE7FF1842
+ CEFFFFF7EFFFCEBDADFF4A4231FFC6ADA5FFD6AD94FF00000000BD8C73FFDEA5
+ 7BFFB59C8CFFBD8473FFDEA57BFF00000000214AC6FF1842CEFF184ACEFF1842
+ CEFFDEA57BFFBD9C8CFF4A4231FFC6B5A5FFFFFFFFFFFFFFFFFFCEAD94FFFFFF
+ FFFFFFFFFFFFDEA57BFFFFF7EFFFFFEFEFFFDEA57BFFFFF7EFFFFFEFE7FFDEA5
+ 7BFFFFE7CEFFC6B5ADFF524239FFC6AD9CFFFFFFFFFFFFFFFFFFB59484FFFFFF
+ FFFFFFF7EFFF00000000F7EFEFFFF7EFEFFF00000000F7EFEFFFF7F7EFFF0000
+ 0000FFDECEFFCEBDB5FF4A4231FFC6ADA5FFC6ADA5FF00000000BD8C73FFE7B5
+ 94FFD6AD94FFB58473FFEFBD94FF00000000BD8473FFC6AD9CFFB59C8CFFBD84
+ 73FFCEAD8CFFB59C8CFF524231FF000000004A4239FF524231FF4A4239FF5242
+ 39FF4A4231FF524239FF4A4231FF4A4239FF524231FF4A4239FF524231FF4A42
+ 39FF524231FF524239FF4A4231FF000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000CEBDADFFCEBDB5FFCEBDADFFCEBDB5FFCEBD
+ ADFFCEBDB5FFC6ADA5FFC6AD9CFFC6ADA5FFC6AD9CFFC6ADA5FFC6A58CFFB59C
+ 8CFFB59C84FFB5948CFFB59C8CFFCEBDB5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF526363FFC6BDADFFFFFFFFFFEFDEDEFF5A7B8CFF9484
+ 7BFF5A7B8CFFBDC6CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+ EFFFFFEFEFFFDED6CEFF4A3931FFCEBDB5FFFFFFFFFF4A6363FF637B8CFF8C9C
+ ADFF849CA5FF94847BFFEFE7DEFFFFFFFFFFF7F7EFFFFFFFFFFFF7EFEFFFF7EF
+ E7FFFFEFE7FFDECEC6FF4A4231FFCEBDADFFFFFFFFFF524239FF4A3931FFEFE7
+ DEFFBDC6CEFF94847BFFE7DEDEFFF7F7EFFFF7BDA5FFF7BD9CFFFFB57BFFF7A5
+ 7BFFF7A57BFFCEBDB5FF4A4231FFC6ADA5FFFFFFFFFF52636BFF524239FFCEBD
+ B5FF94847BFF52636BFFFFFFFFFFFFEFEFFFF7F7E7FFF7EFEFFFFFF7EFFFF7EF
+ EFFFF7E7C6FFCEBDB5FF524231FFC6ADA5FFFFFFFFFFEFE7DEFF52636BFFB59C
+ 84FF8C9CADFF525A63FFC6D6DEFFF7F7E7FFF7CEBDFFC6A58CFFB59C84FFB59C
+ 84FFB58473FFCEBDB5FF4A4231FFBDAD9CFFFFF7EFFF107BBDFF8CADC6FF1842
+ CEFF1884BDFF184ACEFF1842CEFFFFF7EFFFFFDEC6FFF7DECEFFFFDECEFFF7D6
+ BDFFFFD6BDFFE7BD94FF4A3939FFC6AD9CFFEFE7DEFF1842C6FF4AB5EFFF299C
+ DEFF214ACEFF1884BDFF1842C6FFFFEFEFFFDEC6ADFFC6A594FFB59C84FFB59C
+ 8CFFB58473FFEFBD9CFF4A4231FFC6A594FFF7F7EFFFBDC6CEFF1842CEFF214A
+ C6FF1842CEFF214ACEFFC6A58CFFFFE7CEFFF7DEC6FFF7D6BDFFF7D6C6FFFFDE
+ BDFFF7D6BDFFE7B58CFF4A4239FFB59C8CFFFFDEC6FFFFDEC6FFDECEC6FFE7C6
+ ADFFDEC6ADFFE7C6B5FFDEC6ADFFEFC6A5FFE7B59CFFE7BD94FFE7B594FFE7AD
+ 8CFFE7B58CFFE7AD8CFF524231FFB59C84FF52636BFF4A4231FF4A4231FF5242
+ 39FF4A4231FF4A4231FF524239FF4A4231FF524231FF4A4239FF524239FF4A42
+ 31FF4A4239FF524239FF4A4239FF000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000084ADC6FF8C9CA5FF849CADFF0000000000000000000000000000
+ 000000000000000000000000000000000000DEC6ADFFCEBDB5FFCEBDADFFCEBD
+ B5FF8C9CA5FFADE7EFFFADE7F7FF8CC6D6FF526363FFC6ADA5FFC6AD9CFFC6A5
+ 94FF00000000000000000000000000000000CEBDADFFFFFFFFFFFFFFFFFFFFFF
+ FFFF849CA5FF849CADFF94847BFF8CBDD6FF637B8CFFFFF7EFFFE7DEDEFFEFE7
+ DEFF525A63FF000000000000000000000000CEBDB5FFFFFFFFFFFFFFFFFF8C9C
+ ADFF7BD6F7FF8CE7FFFF7BD6F7FF63CEF7FF8C9CA5FF5A738CFFE7E7DEFFDECE
+ C6FFB59C84FF000000000000000000000000CEBDB5FFFFFFFFFFFFFFFFFF849C
+ A5FF637B8CFF637B8CFF637B8CFF637B8CFF5A7B8CFF8C9CADFF84ADBDFF1842
+ CEFFB59C8CFF000000000000000000000000CEBDADFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF7EFEFFFFFEFEFFFF7F7EFFFEFDEDEFFEFE7DEFF8CADC6FF1842CEFF8C9C
+ A5FF948484FF000000000000000000000000C6AD9CFFFFFFFFFFFFFFFFFFFFEF
+ EFFFF7F7E7FFFFEFEFFFF7EFE7FFE7E7DEFF2994DEFF184ACEFF8C9CA5FFDED6
+ C6FF525A6BFF000000000000000000000000C6ADA5FFFFFFFFFFC6F7FFFFC6D6
+ D6FFFFEFE7FFF7EFEFFFEFE7DEFF8CADBDFF1842CEFF5A7B8CFFFFDECEFFE7C6
+ B5FF4A4231FF000000000000000000000000C6AD9CFFF7EFEFFF42ADEFFF4AB5
+ EFFF84ADC6FFC6D6D6FF84ADC6FF1842CEFF214ACEFFFFDEC6FFF7DEBDFFC6AD
+ A5FF4A4231FF000000000000000000000000C6AD9CFFFFF7EFFF2142C6FF1842
+ CEFF299CDEFF2994DEFF184AC6FF1842CEFFCEBDADFFFFDEC6FFDECEC6FFC6AD
+ A5FF4A4239FF000000000000000000000000C6ADA5FFF7F7EFFFC6D6D6FF1842
+ CEFF214ACEFF2142CEFF184ACEFF8C9CA5FFF7D6B5FFF7CEBDFFDEC6ADFFD6AD
+ 8CFF524231FF000000000000000000000000C6AD9CFFFFEFE7FFFFF7EFFFEFE7
+ DEFF2142CEFF184ACEFF637B8CFFDECEC6FFF7CEB5FFDECEC6FFDEC6B5FFD6AD
+ 94FF4A4239FF000000000000000000000000C6ADA5FFF7F7EFFFDECEC6FFDECE
+ C6FFDECEC6FF8C9CA5FFCEBDB5FFE7BD94FFC6ADA5FFC6AD9CFFD6AD8CFFBDA5
+ 94FF524231FF000000000000000000000000D6AD94FF523931FF4A4231FF4A42
+ 31FF4A4231FF52636BFF524231FF4A4239FF524231FF4A4239FF524231FF4A42
+ 39FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000008CBDD6FF8CC6CEFF94C6D6FF8CBD
+ D6FF8CC6D6FF94C6D6FF8CBDD6FF8CC6CEFF94BDD6FF8CC6D6FF84ADBDFF84AD
+ C6FF84ADC6FF84ADC6FF000000000000000094BDCEFFC6F7FFFFC6EFFFFFC6F7
+ FFFFC6F7FFFFC6EFFFFFC6F7FFFFC6F7FFFFC6F7FFFFC6F7FFFFCEEFFFFFC6F7
+ FFFFCEF7FFFF5A7B8CFF00000000000000008CC6D6FFC6F7FFFFADEFFFFFADEF
+ F7FFADEFFFFFADEFF7FFADEFFFFFADEFFFFFADEFFFFFA5EFFFFFADEFFFFFA5EF
+ F7FFADEFFFFF5A7B8CFF000000000000000084ADBDFFADEFFFFFADEFFFFFA5EF
+ FFFFADEFFFFFA5EFFFFFADEFFFFFA5EFF7FFADEFFFFFA5EFF7FFADEFFFFFADEF
+ FFFFADF7FFFF525A6BFF000000000000000084ADC6FFADE7EFFFA5EFFFFFADF7
+ F7FFADEFFFFFADF7FFFFA5EFFFFFADEFFFFFADF7FFFFADEFFFFFA5EFF7FFADEF
+ FFFFA5EFFFFF526363FF000000000000000084ADC6FF8CE7F7FF8CE7FFFF8CE7
+ FFFF8CE7F7FF8CE7FFFF8CE7F7FF8CE7F7FF8CE7FFFF8CE7F7FF8CE7FFFF8CE7
+ FFFF8CE7FFFF526363FF000000000000000084ADC6FF6BC6F7FF8CE7F7FF8CE7
+ FFFF8CDEFFFF8CE7F7FF8CE7FFFF8CE7FFFF8CDEF7FF8CE7FFFF8CE7F7FF8CE7
+ FFFF8CE7F7FF525A6BFF00000000000000008CADBDFF42B5EFFF7BD6F7FF8CE7
+ FFFF8CE7F7FF8CE7FFFF8CDEFFFF8CE7F7FF8CE7FFFF8CE7FFFF8CE7FFFF8CE7
+ FFFF8CE7FFFF526363FF000000000000000084ADC6FF4AADEFFF29BDEFFF4AB5
+ EFFF42ADEFFF299CDEFF6BCEEFFF8CE7FFFF8CE7F7FF8CDEFFFF8CE7F7FF8CE7
+ FFFF8CE7FFFF525A63FF000000000000000084ADBDFF6BCEF7FF299CDEFF29BD
+ EFFF29BDEFFF299CDEFF29BDEFFF8CDEFFFF8CE7FFFF8CE7F7FF8CE7FFFF8CE7
+ F7FF8CE7FFFF52636BFF000000000000000084ADC6FF6BCEF7FF4AADEFFF299C
+ DEFF31BDF7FF29BDEFFF299CDEFF7BD6F7FF7BD6F7FF7BD6FFFF7BD6F7FF7BD6
+ F7FF7BD6F7FF526363FF00000000000000008CADC6FF7BD6F7FF6BCEEFFF4AB5
+ EFFF299CDEFF319CE7FF299CDEFF4AB5EFFF7BD6F7FF6BCEF7FF7BD6F7FF7BD6
+ F7FF7BDEFFFF52636BFF000000000000000084ADBDFF6BCEF7FF7BD6F7FF6BC6
+ F7FF4AB5E7FF2994DEFF299CDEFF1884BDFF299CDEFF4AADEFFF4AB5EFFF4AB5
+ EFFF4AADEFFF526363FF00000000000000008CADC6FF5A738CFF637B8CFF5A7B
+ 8CFF637B8CFF637B8CFF5A636BFF525A63FF5A636BFF526363FF525A6BFF5263
+ 63FF526363FF52636BFF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000008C9CA5FF849CA5FF8C9CADFF849C
+ A5FF8C9CA5FF0000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000849CADFFADE7F7FFADEFFFFFADEFFFFFADF7
+ FFFF8CE7FFFF849CADFF00000000000000000000000000000000000000000000
+ 00000000000000000000000000008C9CA5FF849CA5FF8C9CA5FF849CA5FF849C
+ A5FF8C9CA5FF8C9CA5FF849CA5FF8C9CA5FF849CADFF849CA5FF8C9CADFF849C
+ A5FF849CA5FF0000000000000000849CADFFCEF7FFFFC6F7FFFFC6EFFFFFC6F7
+ FFFFADEFFFFFADEFFFFFADEFFFFF8CE7FFFF8CE7FFFF7BD6F7FF6BCEF7FF63C6
+ F7FF6BCEF7FF5A738CFF00000000849CA5FFC6EFFFFFADEFFFFFADEFFFFFADEF
+ FFFFA5EFFFFF8CE7FFFF8CE7FFFF8CE7FFFF63C6EFFF6BCEF7FF4AADEFFF4AB5
+ EFFF299CDEFF5A7B8CFF00000000849CADFFC6F7FFFFADEFFFFFA5EFFFFFADEF
+ FFFF8CE7F7FF8CE7FFFF8CE7F7FF7BD6F7FF6BCEF7FF63C6F7FF4AB5E7FF2994
+ DEFF1884BDFF5A636BFF000000008C9CA5FFC6F7FFFFA5EFF7FFADF7FFFFADEF
+ F7FF8CE7FFFF8CE7FFFF7BD6F7FF63CEF7FF6BC6EFFF4AB5EFFF4AB5EFFF319C
+ DEFF1884BDFF526363FF00000000849CA5FFADEFFFFFADEFFFFFA5EFFFFF8CE7
+ FFFF8CE7F7FF7BD6F7FF6BC6F7FF6BCEF7FF4AADEFFF4AB5E7FF4AADEFFF299C
+ DEFF1884BDFF524231FF000000008C9CADFFA5E7EFFFADEFFFFF8CE7F7FF8CE7
+ FFFF7BD6F7FF63CEF7FF6BCEF7FF42ADE7FF4AB5EFFF4AB5EFFF2994DEFF299C
+ DEFF1884BDFF4A4239FF0000000094847BFFADE7F7FF8CE7FFFF8CE7FFFF7BD6
+ F7FF6BC6F7FF6BCEEFFF4AADEFFF4AB5EFFF4AB5E7FF2994DEFF299CE7FF2184
+ BDFF1884BDFF524231FF000000005A7B8CFFADE7EFFF63CEF7FF4AADE7FF4AB5
+ EFFF299CDEFF2994E7FF1884B5FF1884BDFF1884BDFF1884BDFF1884B5FF1884
+ BDFF1884BDFF000000FF000000005A7B8CFF63738CFF526363FF52636BFF5242
+ 31FF524231FF524231FF000000FF000000FF000000FF000000FF000000FF0000
+ 00FF000000FF000000FF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000
+ }
+ end
+ object ToolImages: TImageList
+ Height = 12
+ Width = 12
+ left = 144
+ top = 16
+ Bitmap = {
+ 4C69060000000C0000000C000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000008484
+ 84FF848484FF848484FF848484FF848484FF848484FF848484FF848484FF8484
+ 84FF848484FF848484FF000000FF848484FF000000FF00FFFFFFFFFFFFFF00FF
+ FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FF000000FF8484
+ 84FFC6C6C6FF000000FF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF
+ FFFF000000FF008484FF000000FF848484FF00FFFFFFC6C6C6FF000000FF00FF
+ FFFFFFFFFFFF00FFFFFFFFFFFFFF000000FF008484FFC6C6C6FF000000FF8484
+ 84FFFFFFFFFFFFFFFFFF008484FF000000FF00FFFFFFFFFFFFFF000000FF0084
+ 84FFC6C6C6FFC6C6C6FF000000FF848484FF00FFFFFF008484FFC6C6C6FF0084
+ 84FF000000FF000000FF008484FFC6C6C6FF008484FFC6C6C6FF000000FF8484
+ 84FF008484FFC6C6C6FFC6C6C6FFC6C6C6FF008484FF008484FFC6C6C6FFC6C6
+ C6FFC6C6C6FF008484FF000000FF848484FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6
+ C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FF000000FF8484
+ 84FF848484FF848484FF848484FF848484FF848484FF848484FF848484FF8484
+ 84FF848484FF848484FF000000FF000000FF000000FF000000FF000000FF0000
+ 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000008484
+ 84FF848484FF848484FF848484FF848484FF848484FF848484FF848484FF8484
+ 84FF848484FF848484FF000000FF848484FF000000FF00FFFFFFFFFFFFFF00FF
+ FFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF000000FF000000FF8484
+ 84FFC6C6C6FF000000FF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFF
+ FFFF000000FF000084FF000000FF848484FF00FFFFFFC6C6C6FF000000FF00FF
+ FFFFFFFFFFFF00FFFFFFFFFFFFFF000000FF000084FFC6C6C6FF000000FF8484
+ 84FFFFFFFFFFFFFFFFFF000084FF000000FF0000FFFF0000FFFF000000FF0000
+ 84FFC6C6C6FF0000FFFF0000FFFF848484FF00FFFFFF000084FFC6C6C6FF0000
+ 84FF0000FFFF0000FFFF0000FFFFC6C6C6FF0000FFFF0000FFFF0000FFFF8484
+ 84FF000084FFC6C6C6FFC6C6C6FFC6C6C6FF000084FF0000FFFF0000FFFF0000
+ FFFF0000FFFF0000FFFF000000FF848484FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6
+ C6FFC6C6C6FFC6C6C6FF0000FFFF0000FFFF0000FFFFC6C6C6FF000000FF8484
+ 84FF848484FF848484FF848484FF848484FF848484FF0000FFFF0000FFFF0000
+ FFFF0000FFFF0000FFFF000000FF000000FF000000FF000000FF000000FF0000
+ 00FF0000FFFF0000FFFF0000FFFF000000FF0000FFFF0000FFFF0000FFFF0000
+ 0000000000000000000000000000000000000000FFFF0000FFFF000000000000
+ 0000000000000000FFFF0000FFFF000000000000000000000000000000000000
+ 0000848484FFC6C6C6FF848484FF848484FF848484FF00000000000000000000
+ 0000000000000000000000000000848484FFFFFFFFFF848484FFC6C6C6FFFFFF
+ FFFFFFFFFFFF848484FF00000000000000000000000000000000848484FFFFFF
+ FFFFFFFFFFFFFFFFFFFF000000FFC6C6C6FF848484FFFFFFFFFF848484FF0000
+ 00000000000000000000848484FFFFFFFFFFFFFFFFFF848484FF848400FF0000
+ 00FF848400FFC6C6C6FF848484FF000000000000000000000000848484FFFFFF
+ FFFFFFFFFFFF848484FF000000FFFFFF00FF848484FF848484FF848484FF0000
+ 0000C6C6C6FFC6C6C6FF848484FFFFFFFFFFFFFFFFFF848484FF000000FFFFFF
+ FFFF848484FFC6C6C6FF848484FFC6C6C6FF000000FF000000FF848484FFFFFF
+ FFFFFFFFFFFF848484FF848400FF000000FF848400FF848484FF848484FF0000
+ 00FF848484FF0000000000000000000000FFFFFFFFFFFFFFFFFF848484FF8484
+ 84FF848484FF000000FF00000000848484FF0000000000000000000000000000
+ 0000000000FF000000FF000000FF000000FF000000FF00000000000000000000
+ 000000000000000000000000000000000000848484FFC6C6C6FF848484FFC6C6
+ C6FF000000FF0000000000000000000000000000000000000000000000008484
+ 84FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6FF848484FF000000000000
+ 00000000000000000000848484FFC6C6C6FF848484FFC6C6C6FF848484FFC6C6
+ C6FF848484FF848484FF000000FF000000000000000000000000000000000000
+ 0000848484FFC6C6C6FF848484FF848484FF848484FF00000000000000000000
+ 0000000000000000000000000000848484FFFFFFFFFF848484FFC6C6C6FFFFFF
+ FFFFFFFFFFFF848484FF00000000000000000000000000000000848484FFFFFF
+ FFFFFFFFFFFFFFFFFFFF000000FFC6C6C6FF848484FFFFFFFFFF848484FF0000
+ 00000000000000000000848484FFFFFFFFFFFFFFFFFF848484FF848400FF0000
+ 00FF848400FFC6C6C6FF848484FF000000000000000000000000848484FFFFFF
+ FFFFFFFFFFFF848484FF000000FFFFFF00FF848484FF848484FF848484FF0000
+ 0000C6C6C6FFC6C6C6FF848484FFFFFFFFFFFFFFFFFF848484FF0000FFFF0000
+ FFFF0000FFFF0000FFFF848484FFC6C6C6FF000000FF000000FF848484FFFFFF
+ FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFF0000
+ 00FF848484FF0000000000000000000000FFFFFFFFFF0000FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF0000FFFF848484FF0000000000000000000000000000
+ 0000000000FF0000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFF0000
+ 000000000000000000000000000000000000848484FF0000FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF0000FFFF000000000000000000000000000000008484
+ 84FFFFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFF0000
+ 00000000000000000000848484FFC6C6C6FF848484FFC6C6C6FF0000FFFF0000
+ FFFF0000FFFF0000FFFF000000FF000000000000000000000000000000000084
+ 84FF848484FF848484FF848484FF000000000000000000000000000000000000
+ 00000000000000000000008484FFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6FF8484
+ 84FF000000000000000000000000000000000000000000000000000000FF0000
+ 00FF848484FFC6C6C6FF008484FF000000FF0000000000000000000000000000
+ 00000000000000000000848484FFC6C6C6FFFFFFFFFFFFFFFFFF008484FF0000
+ 00FF00000000000000000000000000000000000000FF00000000000000FF0000
+ 00FF848484FFC6C6C6FF000000FF000000FF00000000000000FF00000000C6C6
+ C6FF000000FF000000FF848484FFC6C6C6FFFFFFFFFFFFFFFFFF848484FF0000
+ 00FF000000FF000000FFC6C6C6FF00000000000000FFFFFFFFFF000000FF0000
+ 00FF848484FFC6C6C6FF000000FF000000FFFFFFFFFF000000FF000000000000
+ 0000000000FFFFFFFFFF848484FFC6C6C6FFC6C6C6FF848484FF848484FF0000
+ 00FFFFFFFFFF000000FF000000000000000000000000000000FFFFFFFFFF0000
+ 00FF000000FF000000FF000000FFFFFFFFFF000000FF00000000000000000000
+ 00000000000000000000848484FF848484FF848484FF848484FF848484FF0000
+ 00FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000FF000000FF00000000000000000000000000000000000000000000
+ 000000000000C6C6C6FF848484FF000000FF000000FF000000FF000000FF0000
+ 00FF848484FF0000000000000000000000000000000000000000000000000084
+ 84FF848484FF848484FF848484FF000000000000000000000000000000000000
+ 00000000000000000000008484FFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6FF8484
+ 84FF000000000000000000000000000000000000000000000000000000FF0000
+ 00FF848484FFC6C6C6FF008484FF000000FF0000000000000000000000000000
+ 00000000000000000000848484FFC6C6C6FFFFFFFFFFFFFFFFFF008484FF0000
+ 00FF00000000000000000000000000000000000000FF00000000000000FF0000
+ 00FF848484FFC6C6C6FF000000FF000000FF00000000000000FF00000000C6C6
+ C6FF000000FF000000FF848484FFC6C6C6FFFFFFFFFFFFFFFFFF0000FFFF0000
+ FFFF0000FFFF0000FFFFC6C6C6FF00000000000000FFFFFFFFFF000000FF0000
+ 00FF848484FF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFF0000
+ 0000000000FFFFFFFFFF848484FFC6C6C6FFC6C6C6FF0000FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF0000FFFF0000000000000000000000FFFFFFFFFF0000
+ 00FF000000FF0000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFF0000
+ 00000000000000000000848484FF848484FF848484FF0000FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFF0000FFFF000000000000000000000000000000000000
+ 0000000000FF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFF0000
+ 000000000000C6C6C6FF848484FF000000FF000000FF000000FF0000FFFF0000
+ FFFF0000FFFF0000FFFF00000000
+ }
+ end
+ object OpenPictureDialog1: TOpenPictureDialog
+ Title = 'Open existing file'
+ left = 136
+ top = 64
+ end
+end
diff --git a/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lrs b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lrs
new file mode 100644
index 000000000..584222def
--- /dev/null
+++ b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.lrs
@@ -0,0 +1,941 @@
+LazarusResources.Add('TJvNavPaneDemoMainFrm','FORMDATA',[
+ 'TPF0'#21'TJvNavPaneDemoMainFrm'#20'JvNavPaneDemoMainFrm'#4'Left'#2'i'#6'Heig'
+ +'ht'#3#212#1#3'Top'#2'm'#5'Width'#3#6#2#18'HorzScrollBar.Page'#3#5#2#18'Vert'
+ +'ScrollBar.Page'#3#211#1#7'Caption'#6#21'JvNavigationPane Demo'#8'DockSite'#9
+ +#11'Font.Height'#2#245#9'Font.Name'#6#6'Tahoma'#8'OnCreate'#7#10'FormCreate'
+ +#0#10'TPopupMenu'#10'PopupMenu1'#7'OnPopup'#7#15'PopupMenu1Popup'#4'left'#2
+ +'\'#3'top'#2'@'#0#9'TMenuItem'#8'HideAll1'#7'Caption'#6#8'Hide All'#7'OnClic'
+ +'k'#7#13'HideAll1Click'#0#0#9'TMenuItem'#8'ShowAll1'#7'Caption'#6#8'Show All'
+ +#7'OnClick'#7#13'ShowAll1Click'#0#0#9'TMenuItem'#2'N1'#7'Caption'#6#1'-'#0#0
+ +#9'TMenuItem'#11'ChangeFont1'#7'Caption'#6#7'Font...'#7'OnClick'#7#16'Change'
+ +'Font1Click'#0#0#9'TMenuItem'#7'Colors1'#7'Caption'#6#6'Colors'#0#9'TMenuIte'
+ +'m'#9'Standard1'#7'Caption'#6#8'Standard'#7'Checked'#9#10'GroupIndex'#2#1#9
+ +'RadioItem'#9#7'OnClick'#7#11'SchemaClick'#0#0#9'TMenuItem'#5'Blue1'#3'Tag'#2
+ +#1#7'Caption'#6#4'Blue'#10'GroupIndex'#2#1#9'RadioItem'#9#7'OnClick'#7#11'Sc'
+ +'hemaClick'#0#0#9'TMenuItem'#7'Silver1'#3'Tag'#2#2#7'Caption'#6#6'Silver'#10
+ +'GroupIndex'#2#1#9'RadioItem'#9#7'OnClick'#7#11'SchemaClick'#0#0#9'TMenuItem'
+ +#6'Olive1'#3'Tag'#2#3#7'Caption'#6#5'Olive'#10'GroupIndex'#2#1#9'RadioItem'#9
+ +#7'OnClick'#7#11'SchemaClick'#0#0#0#9'TMenuItem'#16'BackgroundImage1'#7'Capt'
+ +'ion'#6#19'Background Image...'#7'OnClick'#7#21'BackgroundImage1Click'#0#0#9
+ +'TMenuItem'#2'N2'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#16'Dontallowresize1'#7
+ +'Caption'#6#18'Don''t allow resize'#7'OnClick'#7#21'Dontallowresize1Click'#0
+ +#0#9'TMenuItem'#2'N3'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#14'ShowToolPanel1'#7
+ +'Caption'#6#15'Show Tool Panel'#7'OnClick'#7#19'ShowToolPanel1Click'#0#0#9'T'
+ +'MenuItem'#16'ShowCloseButton1'#7'Caption'#6#17'Show Close Button'#7'OnClick'
+ +#7#21'ShowCloseButton1Click'#0#0#0#10'TImageList'#11'LargeImages'#6'Height'#2
+ +#20#5'Width'#2#24#4'left'#2'\'#3'top'#2#16#6'Bitmap'#10#14'-'#0#0'Li'#6#0#0#0
+ +#24#0#0#0#20#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#206#181#156#255#198#173#156#255#206#173#156#255#206
+ +#173#156#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#189#189#189#255#231#198#181#255#198#247#255#255#198#247#255#255#173#231
+ +#247#255#198#173#156#255#206#173#156#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#206#173#156#255#222#214#206#255#198#239#255#255#198#239#255
+ +#255#198#247#255#255#173#231#247#255'{'#214#247#255#140#198#214#255#173#148
+ +#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#189#189#189#255#206#189#181#255#198#247
+ +#255#255#198#239#255#255#198#247#255#255#198#247#255#255#198#239#255#255#140
+ +#231#255#255'{'#222#247#255'k'#198#247#255'k'#206#247#255#173#148#132#255#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#206#173#156#255#222#214#206#255#198#239#255#255#198#247#255#255#198
+ +#239#255#255#198#247#255#255#198#239#255#255#173#231#247#255#140#231#247#255
+ +#132#214#247#255'c'#206#247#255'k'#198#247#255'J'#189#247#255#189#189#189#255
+ +#132#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#206#173#156#255#198#247#255#255#198#247#255#255#198#239#255#255#198#247
+ +#255#255#165#231#247#255#148#231#255#255'{'#214#247#255'{'#214#247#255#132
+ +#214#247#255'{'#214#247#255'k'#198#247#255'k'#206#247#255'J'#181#239#255'R'
+ +#181#247#255'J'#189#247#255#173#148#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#198#173#156#255#198#247#255#255#173#231#247#255#165#231#247
+ +#255#148#231#247#255'{'#214#247#255'k'#198#247#255'c'#206#247#255'R'#181#239
+ +#255'J'#189#247#255'J'#181#247#255'R'#189#247#255'1'#181#222#255'9'#173#247
+ +#255'1'#165#239#255'!'#165#239#255'9'#165#239#255'9'#173#247#255#165'{k'#255
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#173#156#255'c'#198#247#255#247
+ +#239#239#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#247#247#231#255#247#239#239
+ +#255#247#247#239#255#247#239#239#255#173#231#247#255#173#231#239#255#148#198
+ +#214#255'1'#173#239#255#156'{k'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#214#173#132#255'{'#214#247#255#247#247#239#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#247#239#239#255#239#239#239#255#247#239#231#255#239#239#239#255#247
+ +#247#239#255#247#239#239#255#222#198#173#255'1'#165#247#255#156'{k'#255'JB1'
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#173#165#255#198#173#156#255#255#222
+ +#198#255#255#255#255#255#247#222#206#255#255#222#198#255#247#247#239#255#255
+ +#222#206#255#255#222#198#255#255#222#206#255#247#222#198#255#247#247#239#255
+ +#247#239#239#255#239#247#239#255#247#239#239#255#239#239#239#255#214#189#173
+ ,#255#165'{k'#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#214#173
+ +#132#255#255#222#206#255#198#173#156#255#255#255#255#255#247#247#239#255#214
+ +#206#206#255#222#214#206#255#214#214#206#255#214#214#206#255#222#214#206#255
+ +#214#214#206#255#222#189#173#255#222#198#173#255#231#198#173#255#214#206#206
+ +#255#247#247#239#255#156'{k'#255#231#173#140#255#156'{k'#255'JB1'#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#214#165#140#255#255#255#255#255#255#231#206#255#198
+ +#173#156#255#255#255#255#255#255#255#255#255#206#165#132#255#214#165#140#255
+ +#214#165#132#255#173#148#140#255#173#148#140#255#173#148#140#255#173#148#140
+ +#255#247#239#239#255#247#247#239#255#156'sk'#255#231#189#148#255#255#206#165
+ +#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#156'{'#255#255
+ +#255#255#255#239#239#239#255#247#247#239#255#198#173#156#255#214#165#140#255
+ +#255#231#206#255#239#239#239#255#247#247#239#255#247#239#239#255#247#247#239
+ +#255#239#239#239#255#247#214#181#255#156'{k'#255#173#148#140#255#239#181#148
+ +#255#247#214#189#255#255#206#156#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#173#148#132#255#247#239#239#255#239#247#239#255#247#239#239#255
+ +#214#165#132#255#239#247#239#255#247#239#239#255#239#239#239#255#247#239#239
+ +#255#239#239#239#255#239#239#239#255#255#231#198#255#255#222#206#255#255#206
+ +#165#255#156'{k'#255#255#206#156#255#255#206#156#255#247#198#140#255#156'{k'
+ +#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#173#148#140#255#247#247#239#255
+ +#247#239#239#255#206#165#132#255#247#247#239#255#247#239#239#255#239#239#239
+ +#255#247#247#231#255#239#239#239#255#247#247#239#255#255#222#198#255#247#214
+ +#198#255#247#222#189#255#247#214#181#255#247#198#140#255#156'{k'#255#247#181
+ +#140#255#247#165's'#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#173#148#132#255#247#239#239#255#198#173#156#255#239#239#239#255#247#239#239
+ +#255#239#239#239#255#247#247#239#255#247#222#198#255#255#222#206#255#247#222
+ +#198#255#247#214#198#255#247#214#181#255#247#214#189#255#255#206#156#255#247
+ +#198#140#255#255#173#140#255#156'{k'#255#231#148'k'#255#156'{k'#255'JB1'#255
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#173#148#132#255#198#181#156#255#247#247#239
+ +#255#247#239#239#255#239#247#239#255#255#222#198#255#247#214#189#255#247#214
+ +#189#255#247#214#181#255#247#214#189#255#247#206#173#255#255#206#156#255#255
+ +#206#165#255#247#189#140#255#231#181#148#255#247#165's'#255#231#148'k'#255
+ +#156'{k'#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#198#156'{'
+ +#255#255#222#198#255#239#239#239#255#255#222#198#255#247#214#189#255#255#206
+ +#156#255#247#198#140#255#231#181#148#255#247#173#140#255#247#181#140#255#247
+ +#165's'#255#239#165'{'#255#247#165's'#255#231#156'c'#255#231#148'c'#255#231
+ +#156'k'#255#231#148'c'#255#206'{J'#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#206#156'{'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255
+ +#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156
+ +'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'
+ +#255#156'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'JB1'#255'J'
+ +'B1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'
+ +#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255
+ +'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0'J91'#255#0#0#0#0'J9)'#255#0#0#0#0'J91'#255
+ +#0#0#0#0'J91'#255#0#0#0#0'J91'#255#0#0#0#0'J9)'#255#0#0#0#0'J91'#255#0#0#0#0
+ +'J91'#255#0#0#0#0'J91'#255#0#0#0#0'J91'#255#0#0#0#0'J91'#255#0#0#0#0#0#0#0#0
+ +#173#148#140#255#0#0#0#0#173#148#140#255#0#0#0#0#173#148#140#255#0#0#0#0#173
+ +#148#140#255#0#0#0#0#165'{k'#255#0#0#0#0#156'{k'#255#0#0#0#0#165'{k'#255#0#0
+ +#0#0#165'{k'#255#0#0#0#0'kcR'#255#0#0#0#0'sZR'#255#0#0#0#0'kZR'#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#231#173#140#255#231#181#140#255#231#181#140#255#247#165's'#255
+ +#222#165'{'#255#222#173#132#255#222#165'{'#255#231#156'c'#255#231#148'k'#255
+ +#231#148'c'#255#239#156'k'#255#231#148'c'#255#214#132'Z'#255#214#132'R'#255
+ +#214#132'Z'#255#222'{J'#255#231'{J'#255#222'{J'#255#222'{J'#255#231'{J'#255
+ +#222'{J'#255'JB1'#255#0#0#0#0#0#0#0#0#231#181#140#255#255#222#206#255#247#222
+ +#206#255#255#222#206#255#247#222#198#255#255#214#189#255#247#214#189#255#247
+ +#206#181#255#247#206#181#255#247#206#181#255#247#189#156#255#247#189#165#255
+ +#247#189#156#255#247#181#140#255#247#181#140#255#247#181#140#255#247#165'{'
+ +#255#247#165's'#255#247#165'{'#255#247#165's'#255#231#148'k'#255'JB1'#255#0#0
+ +#0#0#0#0#0#0#231#173#140#255#247#222#198#255#255#222#189#255#247#222#198#255
+ +#247#206#173#255#239#206#181#255#247#206#173#255#255#206#156#255#247#189#156
+ +#255#239#189#156#255#247#181#140#255#247#181#140#255#247#181#140#255#247#165
+ +'s'#255#247#165's'#255#247#165's'#255#239#165's'#255#247#165'{'#255#231#156
+ +'c'#255#231#148'k'#255#231#156'c'#255'JB1'#255#0#0#0#0#0#0#0#0#247#165's'#255
+ +#247#165's'#255#247#165'{'#255#222#165'{'#255#222#165'{'#255#222#165'{'#255
+ +#231#148'c'#255#231#148'k'#255#231#148'c'#255#231#156'k'#255#231#148'c'#255
+ ,#214#132'R'#255#206#132'R'#255#214#132'R'#255#222'{J'#255#222'{J'#255#222'{J'
+ +#255#222'{J'#255#222'{J'#255'JB1'#255'JB1'#255'JB1'#255#0#0#0#0#0#0#0#0#206
+ +#189#181#255#255#255#255#255#255#255#255#255#255#255#255#255#239#189#156#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#239#198#156#255#255#255#255
+ +#255#247#239#239#255#247#247#247#255#239#189#156#255#255#255#255#255#239#239
+ +#247#255#247#247#239#255#239#189#156#255#247#239#239#255#247#247#239#255#255
+ +#222#206#255#231#189#156#255'JB1'#255#0#0#0#0#0#0#0#0#206#189#173#255#255#255
+ +#255#255#239#247#239#255#247#239#239#255#231#189#156#255#255#255#255#255#247
+ +#239#239#255#247#247#239#255#206#165#140#255#247#239#239#255#239#247#239#255
+ +#247#222#206#255#214#165#132#255#239#239#239#255#247#239#239#255#247#222#198
+ +#255#214#165#132#255#239#239#239#255#247#222#206#255#247#206#181#255#206#156
+ +'{'#255'JB1'#255#0#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255#247#239#239
+ +#255#239#239#239#255#214#165#132#255#255#255#255#255#239#247#239#255#255#222
+ +#206#255#198#156'{'#255#247#239#239#255#255#222#198#255#247#222#206#255#198
+ +#156'{'#255#247#247#239#255#247#214#189#255#247#206#173#255#198#156'{'#255
+ +#255#222#206#255#247#206#173#255#255#206#156#255#198#156'{'#255'JB1'#255#0#0
+ +#0#0#0#0#0#0#206#173#156#255#231#189#156#255#239#189#148#255#206#165#132#255
+ +#214#173#140#255#231#181#148#255#231#173#140#255#206#156'{'#255#198#156'{'
+ +#255#231#189#148#255#214#165#132#255#206#156'{'#255'9'#140#214#255'B'#140#214
+ +#255'9'#140#214#255#24'B'#206#255#24'B'#206#255#231#189#148#255#214#165#140
+ +#255#198#156'{'#255#165'{s'#255'JB1'#255#0#0#0#0#0#0#0#0#198#181#156#255#255
+ +#255#255#255#255#255#255#255#247#239#239#255#231#181#148#255#255#255#255#255
+ +#247#247#239#255#239#239#239#255#239#181#148#255#239#239#239#255#247#247#239
+ +#255#239#239#239#255'B'#140#214#255#247#247#239#255#247#239#239#255#255#231
+ +#206#255#24'9'#206#255#255#231#206#255#247#222#198#255#255#231#206#255#231
+ +#181#148#255'JB1'#255#0#0#0#0#0#0#0#0#198#173#165#255#255#255#255#255#247#239
+ +#239#255#239#247#239#255#214#165#140#255#255#255#255#255#247#239#239#255#247
+ +#231#206#255#214#165#140#255#239#239#239#255#247#239#239#255#255#231#198#255
+ +'9'#140#214#255#255#222#206#255#247#214#189#255#255#222#189#255#16'B'#206#255
+ +#255#222#206#255#247#214#189#255#247#206#181#255#206#156'{'#255'JB1'#255#0#0
+ +#0#0#0#0#0#0#198#173#156#255#255#255#255#255#247#247#239#255#247#222#206#255
+ +#206#156'{'#255#239#247#239#255#255#222#198#255#247#214#189#255#206#156'{'
+ +#255#239#247#239#255#255#222#206#255#247#214#181#255#24'9'#206#255#255#222
+ +#189#255#247#214#189#255#247#206#173#255#24'B'#206#255#255#222#189#255#239
+ +#198#165#255#239#189#156#255#198#156'{'#255'J91'#255#0#0#0#0#0#0#0#0#206#181
+ +#156#255#231#181#148#255#214#165#132#255#198#156'{'#255#206#156'{'#255#231
+ +#181#148#255#206#165#140#255#206#156'{'#255#198#156'{'#255#239#181#148#255
+ +#206#165#140#255#206#156'{'#255#24'B'#206#255#16'B'#206#255#24'B'#206#255#24
+ +'B'#206#255#16'B'#214#255#231#173#140#255#198#156'{'#255#173#148#140#255#165
+ +'{k'#255'JB1'#255#0#0#0#0#0#0#0#0#198#173#165#255#255#255#255#255#247#247#239
+ +#255#247#239#239#255#231#181#148#255#247#247#239#255#247#247#239#255#239#239
+ +#239#255#231#189#148#255#247#239#239#255#255#231#206#255#247#222#206#255#239
+ +#189#148#255#255#222#206#255#255#231#206#255#255#222#189#255#239#181#148#255
+ +#247#222#198#255#255#222#198#255#247#206#173#255#231#181#156#255'JB1'#255#0#0
+ +#0#0#0#0#0#0#198#181#156#255#247#239#239#255#239#239#239#255#247#247#239#255
+ +#206#165#140#255#247#239#239#255#247#222#198#255#255#222#206#255#214#165#132
+ +#255#247#222#206#255#247#214#189#255#255#222#189#255#198#156'{'#255#255#222
+ +#206#255#247#214#189#255#247#206#181#255#198#156'{'#255#255#214#189#255#239
+ +#206#181#255#255#206#156#255#206#156'{'#255'J91'#255#0#0#0#0#0#0#0#0#214#165
+ +#140#255#247#247#239#255#239#239#239#255#247#222#189#255#206#156'{'#255#239
+ +#247#239#255#247#214#198#255#247#206#173#255#198#156'{'#255#255#231#206#255
+ +#247#214#189#255#255#206#165#255#198#156'{'#255#247#222#189#255#247#206#181
+ +#255#247#189#156#255#198#156'{'#255#247#206#181#255#247#189#156#255#231#189
+ +#148#255#206#156'{'#255'JB1'#255#0#0#0#0#0#0#0#0#206#165#140#255#247#214#181
+ +#255#231#181#148#255#214#165#140#255#198#156'{'#255#231#173#140#255#206#156
+ +'{'#255#173#148#140#255#156'{k'#255#231#173#140#255#206#156'{'#255#173#148
+ +#140#255#156'{k'#255#231#173#140#255#198#156'{'#255#173#148#140#255#156'{k'
+ +#255#231#181#140#255#198#156'{'#255#173#148#140#255#165'{s'#255'J91'#255#0#0
+ +#0#0#0#0#0#0#214#165#140#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB'
+ +'1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'
+ +#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173#255#206#189#181#255#214#189#173#255
+ +#206#189#173#255#206#189#173#255#206#189#173#255#214#189#181#255#206#189#173
+ +#255#206#173#156#255#198#181#165#255#206#173#156#255#198#181#156#255#198#173
+ +#156#255#198#181#156#255#206#173#156#255#198#181#156#255#214#165#140#255#206
+ +#165#132#255#214#165#140#255#173#148#140#255#173#148#132#255#173#148#140#255
+ +#0#0#0#0#0#0#0#0#214#189#173#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#239#239#239#255#247#247#239#255'JB1'#255#0#0#0#0#0#0#0#0#206
+ +#189#173#255#255#255#255#255#255#255#255#255#247#239#239#255#181#189#189#255
+ +#173#148#140#255'k{'#140#255'k'#132#140#255#189#189#189#255#247#239#239#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#247#247#239#255#247#239#239#255#239#247
+ +#239#255#255#214#198#255'JB1'#255#0#0#0#0#0#0#0#0#206#189#181#255#255#255#255
+ +#255#255#255#255#255#189#189#189#255'k'#132#140#255'k{'#140#255#140#156#165
+ +#255#173#148#140#255'kZR'#255#181#189#189#255#255#255#255#255#255#255#255#255
+ +#247#173#140#255#247#181#140#255#247#181#140#255#247#165's'#255#247#165'{'
+ +#255#239#165's'#255#247#165's'#255#239#239#239#255#255#222#198#255'JB1'#255#0
+ +#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255#255#255#255#255'k{'#140#255'k'
+ +'ZR'#255'scR'#255'k'#132#140#255'kZR'#255#189#189#189#255'k{'#140#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#239
+ +#239#239#255#247#247#239#255#239#239#239#255#247#247#239#255#239#239#239#255
+ +#247#214#181#255'JB1'#255#0#0#0#0#0#0#0#0#214#189#173#255#255#255#255#255#255
+ +#255#255#255'scR'#255'J91'#255#189#189#189#255#222#214#214#255#189#189#189
+ +#255#140#156#165#255'k'#132#140#255#255#255#255#255#255#255#255#255#255#181
+ +#140#255#247#173#140#255#247#181#140#255#247#165's'#255#239#165's'#255#247
+ +#165's'#255#247#165's'#255#247#239#239#255#247#206#173#255'JB1'#255#0#0#0#0#0
+ +#0#0#0#206#189#173#255#255#255#255#255#255#255#255#255'J91'#255'JB1'#255#222
+ +#214#214#255#181#181#189#255#132#156#165#255'k{'#140#255'kcR'#255#255#255#255
+ +#255#255#255#255#255#239#247#239#255#247#239#239#255#247#247#239#255#239#239
+ +#239#255#247#239#239#255#239#239#239#255#247#247#239#255#239#239#239#255#247
+ +#189#156#255'JB1'#255#0#0#0#0#0#0#0#0#206#173#165#255#255#255#255#255#255#255
+ +#255#255#189#189#189#255#0#0#0#255#189#189#189#255#140#156#165#255'k'#132#140
+ +#255'sZR'#255#132#156#165#255#247#239#239#255#247#247#239#255#247#239#239#255
+ +#247#239#239#255#239#239#239#255#247#239#239#255#239#247#239#255#247#239#239
+ +#255#239#239#239#255#255#231#206#255#247#189#165#255'JB1'#255#0#0#0#0#0#0#0#0
+ +#198#173#156#255#255#255#255#255#255#255#255#255#247#247#239#255#222#206#206
+ +#255'kZR'#255'kcR'#255'sZR'#255#24'B'#214#255#189#189#189#255#247#247#239#255
+ +#239#239#239#255#239#239#231#255#247#247#239#255#239#239#239#255#247#247#239
+ +#255#247#239#239#255#247#222#198#255#255#222#198#255#247#222#206#255#239#181
+ +#148#255'JB1'#255#0#0#0#0#0#0#0#0#206#173#156#255#255#255#255#255#255#255#255
+ +#255#181#206#222#255#24'B'#206#255#24'B'#206#255#222#214#214#255#247#247#239
+ +#255#24'B'#206#255#24'9'#206#255#214#214#206#255#247#239#239#255#198#156'{'
+ +#255#206#156'{'#255#156'{k'#255#156'sk'#255#156'{k'#255#156'{k'#255#156'{k'
+ +#255#247#231#198#255#255#181#140#255'JB1'#255#0#0#0#0#0#0#0#0#198#173#156#255
+ +#255#255#255#255#255#255#255#255#24'B'#206#255#132#173#198#255'9'#140#214#255
+ +#24'B'#206#255#24#132#189#255#24'B'#206#255#24#140#198#255#24'B'#206#255#247
+ +#247#239#255#247#239#239#255#239#239#239#255#247#247#239#255#255#222#198#255
+ +#255#231#206#255#255#222#206#255#255#214#198#255#247#222#198#255#247#165's'
+ +#255'JB1'#255#0#0#0#0#0#0#0#0#206#181#165#255#255#255#255#255#255#255#255#255
+ +#24'B'#206#255'9'#173#239#255'B'#140#214#255'B'#140#214#255#24'B'#206#255#24
+ +#140#189#255#24'B'#206#255'1Zs'#255#247#239#239#255#198#156'{'#255#165'{k'
+ +#255#156'{k'#255#156'{k'#255#156'{k'#255#156'{k'#255#156'sk'#255#247#222#198
+ +#255#247#165's'#255'JB1'#255#0#0#0#0#0#0#0#0#198#173#156#255#255#255#255#255
+ +#255#255#255#255#24'B'#206#255#24#140#189#255'B'#140#214#255'B'#140#214#255
+ +#24'B'#206#255#24#140#198#255'!B'#206#255'9c{'#255#247#247#239#255#255#222
+ +#206#255#247#222#198#255#255#222#206#255#255#222#206#255#255#222#198#255#247
+ +#222#189#255#255#222#198#255#247#214#181#255#247#165'{'#255'JB1'#255#0#0#0#0
+ +#0#0#0#0#198#173#156#255#255#255#255#255#247#247#239#255#222#214#206#255#24
+ +'B'#206#255#24'B'#206#255#24'B'#206#255#24'B'#206#255'9cs'#255'9c{'#255#206
+ +#189#173#255#255#222#206#255#156'{k'#255#165'{k'#255#156'{k'#255#156'{k'#255
+ ,#156'sk'#255#156'{k'#255#156'sk'#255#247#206#181#255#231#148'c'#255'JB1'#255
+ +#0#0#0#0#0#0#0#0#214#165#140#255#247#247#239#255#247#239#239#255#247#239#239
+ +#255#247#247#239#255#247#247#239#255#247#247#239#255#247#247#239#255#247#239
+ +#239#255#255#222#206#255#255#231#198#255#247#222#206#255#255#222#206#255#247
+ +#222#189#255#255#222#198#255#247#222#198#255#255#214#189#255#247#206#173#255
+ +#247#206#181#255#247#206#173#255#231#148'c'#255'JB1'#255#0#0#0#0#0#0#0#0#206
+ +#165#132#255#247#239#239#255#247#222#198#255#247#214#198#255#247#222#198#255
+ +#247#206#189#255#247#214#181#255#247#198#173#255#239#198#173#255#247#189#156
+ +#255#239#189#156#255#231#181#148#255#231#181#140#255#247#173#140#255#247#165
+ +'s'#255#247#165's'#255#239#165's'#255#247#165'{'#255#231#148'c'#255#231#148
+ +'c'#255#239#156'k'#255'JB1'#255#0#0#0#0#0#0#0#0#214#165#140#255'JB1'#255'JB1'
+ +#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255
+ +'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'#255'JB1'
+ +#255'JB1'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#132#156#165#255#132#156#165#255#132#156#165#255#140
+ +#156#165#255'k{'#140#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#222#198#181#255#206#189
+ +#173#255#214#189#173#255#206#189#181#255#206#189#173#255#140#156#165#255#140
+ +#198#214#255#198#239#255#255#198#247#255#255#173#231#247#255#140#198#214#255
+ +'k{'#140#255#206#173#156#255#198#181#165#255#206#173#156#255#198#173#156#255
+ +#198#173#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#247#239
+ +#239#255#132#156#165#255#198#247#255#255'k{'#140#255'k{'#140#255#140#156#165
+ +#255#140#198#206#255'1c{'#255#206#173#156#255#247#247#239#255#239#239#239#255
+ +#247#247#239#255#247#239#239#255#132#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#214#189#173#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#140#156#165#255#140#189#214#255#173#247#255#255'k'#132#140
+ +#255#132#173#198#255#140#198#214#255'k'#206#247#255'k{'#140#255'1c{'#255#255
+ +#222#198#255#239#239#239#255#247#247#239#255#181#206#214#255'9Z{'#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#132#156#165#255#173#231#247#255#173#231
+ +#239#255#140#189#214#255#140#198#206#255#140#198#206#255#132#173#198#255#132
+ +#173#198#255'k'#132#140#255#255#222#198#255#239#239#239#255#181#206#214#255
+ +#24'B'#206#255'B'#140#214#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#214#189
+ +#181#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255'k'
+ +#132#140#255'k{'#140#255'k{'#140#255'9cs'#255'9c{'#255'9Z{'#255'9cs'#255'k{'
+ +#140#255#173#148#140#255#255#222#189#255#165#173#247#255#24'B'#206#255'B'#140
+ +#214#255#206#165#140#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#247#247#239#255#247#247#239#255#255#222#206#255#247#222#198#255#255
+ +#214#181#255#239#198#173#255#247#214#189#255#255#222#198#255#165#173#247#255
+ +'9'#140#214#255'B'#140#214#255#255#231#198#255#156'{k'#255#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#206#189#181#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#239#239#239#255#247#247#239#255#247#239#239
+ +#255#181#206#214#255#24'B'#206#255#24'B'#206#255#181#206#214#255#255#222#206
+ +#255#156'{k'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#214#189#173#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#247#239#239#255#247#239#239
+ +#255#239#239#239#255#165#173#247#255'9'#140#214#255#24'B'#206#255#189#189#189
+ +#255#255#222#206#255#247#214#189#255'kZR'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#206#189#173#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#247#239#239#255
+ +#239#239#239#255#247#247#239#255#165#181#247#255'B'#140#214#255#24'B'#206#255
+ +#132#173#189#255#255#222#206#255#255#231#198#255#247#198#173#255'kcR'#255#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255#255#255
+ +#255#255#165#173#255#255#181#206#214#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#239#239#239#255#247#247#231#255#165#173#247#255'9'#140#214#255
+ +#24'B'#206#255#140#156#165#255#222#214#206#255#247#222#206#255#247#222#189
+ ,#255#247#189#156#255'kZR'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189
+ +#181#255#247#247#239#255#165#173#247#255'B'#140#214#255'9'#140#214#255#165
+ +#173#247#255#255#255#255#255#247#239#239#255#247#247#239#255#165#173#247#255
+ +'B'#140#214#255#24'B'#206#255'9'#140#214#255#255#222#198#255#247#231#206#255
+ +#255#214#189#255#247#222#198#255#239#189#156#255'kcR'#255#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#231#189#173#255#165#231#247#255#24'B'#206#255#24'B'#206
+ +#255#24'B'#206#255#173#181#247#255#165#173#247#255#239#247#239#255#165#173
+ +#247#255'9'#140#214#255#24'B'#206#255#24'B'#206#255#231#214#206#255#255#222
+ +#206#255#247#214#189#255#247#222#198#255#247#206#173#255#231#173#140#255'kZR'
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#173#156#255#255#255#255#255
+ +#173#181#247#255#24'B'#206#255#24'B'#206#255#24'B'#206#255#165#173#247#255
+ +#165#173#247#255'B'#140#214#255#24'B'#206#255#24'B'#206#255#189#189#189#255
+ +#255#231#198#255#247#214#198#255#247#222#189#255#247#214#198#255#247#198#173
+ +#255#231#181#140#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#198#181
+ +#156#255#255#255#255#255#255#255#255#255#189#206#214#255#24'B'#206#255#24'B'
+ +#206#255#24'B'#206#255'B'#140#214#255#24'B'#206#255#24'B'#206#255'B'#140#214
+ +#255#255#222#206#255#247#222#206#255#247#222#189#255#255#214#198#255#247#214
+ +#181#255#239#198#173#255#247#181#140#255'J91'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#206#173#156#255#255#255#255#255#255#255#255#255#247#239#239#255
+ +#189#214#222#255#24'B'#206#255'!B'#206#255#24'B'#206#255#24'B'#206#255#24'B'
+ +#206#255#222#214#206#255#247#222#198#255#255#222#189#255#247#214#198#255#247
+ +#214#181#255#247#206#181#255#239#198#165#255#247#165's'#255'J91'#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#198#173#156#255#255#255#255#255#247#247#239
+ +#255#239#239#239#255#247#239#239#255#181#206#214#255#24'B'#206#255#24'B'#206
+ +#255'!B'#206#255#214#198#173#255#247#214#189#255#247#214#189#255#247#206#173
+ +#255#239#198#173#255#247#198#173#255#247#189#156#255#231#189#148#255#247#165
+ +'{'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#173#156#255#239
+ +#247#239#255#255#214#198#255#247#214#189#255#239#198#165#255#247#206#173#255
+ +#140#156#165#255#24'B'#206#255#173#156#140#255#231#181#148#255#231#173#140
+ +#255#231#173#140#255#231#173#140#255#247#181#140#255#247#181#140#255#239#165
+ +'s'#255#247#165'{'#255#239#148'c'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#206#173#140#255#156'sk'#255'kZR'#255'kcR'#255'sZR'#255'kZR'#255'k'
+ +'cR'#255#165'{k'#255'kZR'#255'scR'#255'kZR'#255'JB1'#255'JB1'#255'J91'#255'J'
+ +'B1'#255'J91'#255'JB1'#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140#198#214#255#140
+ +#189#214#255#140#198#214#255#140#198#206#255#140#189#214#255#140#198#206#255
+ +#140#198#214#255#140#189#214#255#140#198#206#255#148#189#214#255'{'#173#198
+ +#255#132#173#198#255'{'#173#198#255#132#173#198#255'{'#173#189#255#132#173
+ +#198#255'{'#173#198#255#132#173#189#255'{'#173#198#255#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#140#198#206#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255'9Z{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#148#189#214#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255'9c{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#140#198#214#255#255#255#255#255#206#247#255#255#198#239#255#255#198
+ +#247#255#255#206#247#255#255#198#239#255#255#198#247#255#255#198#247#255#255
+ +#198#247#255#255#198#247#255#255#198#247#255#255#198#247#255#255#198#247#255
+ +#255#198#247#255#255#198#247#255#255#198#247#255#255#198#247#255#255'9Z{'#255
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140#198#206#255#198#239#255#255#165
+ +#247#255#255#165#247#255#255#173#239#255#255#165#247#255#255#165#247#255#255
+ +#173#247#255#255#165#239#255#255#173#247#255#255#165#239#255#255#173#247#255
+ +#255#165#239#255#255#173#247#255#255#165#239#255#255#173#247#255#255#165#239
+ +#255#255#173#247#255#255'9cs'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140
+ +#198#214#255#198#247#255#255#173#247#255#255#165#247#247#255#173#247#255#255
+ +#165#247#247#255#173#239#255#255#165#247#247#255#173#247#255#255#165#247#247
+ +#255#173#247#255#255#165#247#247#255#173#247#255#255#165#247#247#255#173#247
+ +#255#255#165#247#255#255#173#247#255#255#165#247#255#255'1Zs'#255#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140#198#206#255#198#239#255#255#165#239#255#255
+ ,#173#247#255#255#165#239#255#255#173#247#255#255#165#247#255#255#165#247#255
+ +#255#173#247#255#255#165#239#255#255#165#247#255#255#173#247#255#255#165#239
+ +#255#255#165#247#255#255#173#247#255#255#165#239#255#255#165#247#247#255#173
+ +#247#255#255'9c{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'{'#173#189#255
+ +#148#231#255#255#140#231#247#255#165#247#255#255#173#247#247#255#165#247#255
+ +#255#173#239#247#255#165#247#255#255#173#247#247#255#165#247#255#255#173#247
+ +#247#255#165#239#255#255#173#247#247#255#165#247#255#255#173#247#247#255#165
+ +#247#255#255#173#247#255#255#165#247#255#255'9Zs'#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#132#173#189#255#140#231#255#255#148#231#247#255#165#247#255
+ +#255#173#239#255#255#165#247#255#255#165#247#255#255#173#247#255#255#165#247
+ +#255#255#165#239#255#255#173#247#255#255#165#247#255#255#165#247#255#255#173
+ +#247#255#255#165#239#255#255#173#247#247#255#165#239#255#255#173#247#255#255
+ +'1c{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'{'#173#198#255#132#214#247
+ +#255#140#231#255#255#140#231#247#255#140#231#247#255#148#231#247#255#140#222
+ +#255#255#140#231#247#255#148#231#247#255#140#231#247#255#140#231#255#255#148
+ +#222#247#255#140#231#247#255#140#231#255#255#140#231#247#255#140#231#255#255
+ +#148#231#247#255#140#231#255#255'9Zs'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#132#173#189#255'c'#198#247#255#148#231#247#255#140#231#255#255#148#231
+ +#255#255#140#231#247#255#140#231#255#255#148#231#247#255#140#222#255#255#148
+ +#231#255#255#140#231#247#255#148#231#255#255#140#231#247#255#148#222#255#255
+ +#140#231#247#255#148#231#255#255#140#231#247#255#148#231#255#255'1c{'#255#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'{'#173#198#255'R'#189#247#255'{'#214#247
+ +#255#148#231#247#255#140#222#255#255#148#231#247#255#140#231#255#255#140#231
+ +#247#255#148#231#255#255#140#231#247#255#140#231#255#255#140#231#247#255#148
+ +#231#255#255#140#231#247#255#148#231#255#255#140#222#247#255#140#231#255#255
+ +#148#231#247#255'9Zs'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#173#189
+ +#255'1'#156#206#255'9'#181#231#255'J'#189#239#255'J'#181#247#255'9'#181#222
+ +#255'9'#181#231#255#132#214#247#255#140#231#247#255#140#222#255#255#148#231
+ +#247#255#140#231#255#255#148#222#247#255#140#231#255#255#140#231#247#255#148
+ +#231#255#255#140#231#247#255#148#231#255#255'1c{'#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#132#173#198#255'9'#181#231#255'9'#181#222#255'9'#181#231#255
+ +'9'#181#231#255'9'#181#222#255#0#165#222#255'k'#206#247#255'{'#214#247#255
+ +#132#214#247#255'{'#214#247#255#132#214#247#255'{'#214#247#255'{'#214#247#255
+ +#132#214#247#255'{'#214#247#255'{'#214#247#255#132#214#247#255'1Z{'#255#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#173#189#255'k'#206#247#255#0#165#222
+ +#255'9'#181#231#255'9'#181#222#255'9'#181#231#255#0#165#222#255'9'#181#231
+ +#255#132#214#247#255'{'#214#255#255#132#222#247#255'{'#214#247#255#132#222
+ +#247#255'{'#214#255#255#132#222#247#255'{'#214#247#255#132#214#255#255'{'#222
+ +#247#255'9c{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'{'#173#198#255'k'
+ +#206#247#255'9'#181#222#255#24#132#189#255'9'#181#231#255'9'#181#222#255'9'
+ +#173#239#255#0#165#222#255'k'#206#247#255'{'#214#247#255'{'#214#247#255#132
+ +#214#247#255'{'#214#247#255#132#214#247#255'{'#214#247#255#132#222#247#255'{'
+ +#214#247#255#132#214#247#255'1c{'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#132#173#189#255'c'#198#247#255'k'#206#247#255'R'#189#247#255#0#165#222#255
+ +#24#132#189#255#8#165#222#255#0#165#222#255'!'#156#239#255'k'#206#247#255'c'
+ +#198#247#255#132#222#247#255'{'#214#255#255'{'#222#247#255#132#214#247#255'{'
+ +#214#255#255'{'#214#247#255#132#214#247#255'9c{'#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0'{'#173#198#255'k'#206#247#255'c'#198#247#255'k'#206#247#255
+ +'k'#206#247#255'J'#189#247#255')'#156#239#255'1'#156#206#255#8#165#222#255'1'
+ +#156#206#255'9'#173#239#255'9'#181#231#255'J'#181#239#255'R'#189#247#255'c'
+ +#198#247#255'k'#206#247#255'k'#206#247#255'c'#206#247#255'9Zs'#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#173#198#255'9cs'#255'9Z{'#255'9cs'#255'9Z'
+ +'{'#255'9Zs'#255'9c{'#255'9cs'#255'9c{'#255'9cs'#255'9c{'#255'9c{'#255'9Zs'
+ +#255'9c{'#255'9cs'#255'9Z{'#255'9cs'#255'9Z{'#255'9c{'#255#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#148#165
+ +#255#132#156#165#255#132#156#165#255#140#156#165#255#132#156#173#255#132#156
+ +#165#255#140#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#140#156#165#255#181#206#222#255#206#247#255#255#198#247#255#255#198#239#255
+ +#255#173#247#255#255#173#231#247#255#181#206#214#255#132#156#165#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#148#165#255#132#173#198#255#181#206#214#255
+ ,#181#206#214#255#181#206#222#255#181#206#214#255#140#189#206#255#140#198#214
+ +#255#140#189#206#255#132#173#198#255#132#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#140#156#165#255#132#156#165#255#140#156#173#255#132#156#165#255#140#156
+ +#165#255#132#156#165#255#140#156#165#255#140#156#165#255'k'#132#140#255'k{'
+ +#140#255'k'#132#140#255'k{'#140#255'k'#132#140#255'k{'#140#255'k{'#140#255'k'
+ +'{'#140#255'k{'#140#255'k{'#140#255'k{'#140#255'k{'#140#255'k{'#140#255#0#0#0
+ +#0#0#0#0#0#0#0#0#0#132#156#173#255#206#247#255#255#198#239#255#255#198#247
+ +#255#255#198#239#255#255#198#247#255#255#198#247#255#255#173#231#247#255#173
+ +#231#247#255#173#231#247#255#173#231#247#255'{'#214#247#255#132#222#247#255
+ +'{'#214#247#255#132#222#247#255'{'#222#247#255'k'#206#247#255'k'#206#247#255
+ +'c'#206#247#255'k'#206#247#255#132#173#198#255'k{'#140#255#0#0#0#0#0#0#0#0
+ +#132#156#165#255#198#239#255#255#198#247#255#255#198#239#255#255#173#231#247
+ +#255#173#231#247#255#173#222#247#255#173#231#247#255#140#231#247#255'{'#214
+ +#247#255'{'#222#247#255'k'#198#247#255'c'#206#247#255'k'#198#247#255'c'#206
+ +#247#255'R'#181#247#255'J'#181#247#255'J'#181#247#255'9'#181#222#255'9'#181
+ +#231#255'1'#156#206#255'9c{'#255#0#0#0#0#0#0#0#0#132#156#165#255#198#247#255
+ +#255#198#239#255#255#173#247#255#255#165#231#239#255#173#231#247#255#165#231
+ +#239#255#140#231#247#255#132#214#247#255'{'#214#247#255'k'#198#247#255'k'#206
+ +#247#255'k'#198#247#255'k'#206#247#255'J'#181#239#255'R'#189#247#255'J'#189
+ +#239#255'9'#181#222#255'9'#181#231#255'1'#156#206#255'1'#165#206#255'sZR'#255
+ +#0#0#0#0#0#0#0#0#140#156#165#255#198#239#255#255#165#247#255#255#173#231#239
+ +#255#173#231#247#255#165#231#239#255#148#231#255#255'{'#214#247#255#132#214
+ +#255#255'{'#214#247#255'k'#206#247#255'c'#198#247#255'k'#206#247#255'J'#181
+ +#239#255'R'#189#247#255'J'#181#239#255'9'#181#231#255'9'#181#231#255'9'#181
+ +#231#255'9'#156#206#255'1'#156#206#255'9c{'#255#0#0#0#0#0#0#0#0#132#156#165
+ +#255#198#247#255#255#173#231#247#255#173#222#247#255#165#231#239#255#173#231
+ +#247#255#140#231#247#255#132#214#247#255'{'#222#247#255'k'#198#247#255'k'#206
+ +#247#255'c'#206#247#255'k'#198#247#255'J'#189#247#255'R'#181#239#255'J'#189
+ +#247#255'9'#181#222#255'9'#181#231#255'9'#173#239#255'1'#156#206#255#24#140
+ +#198#255'R91'#255#0#0#0#0#0#0#0#0#140#156#165#255#198#239#255#255#173#231#239
+ +#255#165#231#247#255#173#231#239#255#148#231#255#255'{'#214#247#255#132#214
+ +#247#255'c'#198#247#255'k'#206#247#255'c'#198#247#255'k'#206#247#255'J'#181
+ +#239#255'R'#189#247#255'J'#181#239#255'9'#181#231#255'9'#181#222#255'9'#181
+ +#231#255'1'#173#239#255'9'#156#206#255#24#140#198#255'JB1'#255#0#0#0#0#0#0#0
+ +#0#132#156#165#255#198#247#255#255#173#231#247#255#173#222#239#255#140#231
+ +#255#255'{'#214#247#255'{'#214#247#255#132#222#247#255'c'#198#247#255'k'#206
+ +#247#255'k'#198#247#255'J'#189#239#255'R'#181#247#255'J'#189#239#255'9'#181
+ +#231#255'9'#181#231#255'9'#181#222#255'9'#165#247#255'9'#173#239#255'1'#156
+ +#206#255#24#132#189#255'RB1'#255#0#0#0#0#0#0#0#0#140#156#165#255#198#239#255
+ +#255#173#231#247#255#165#231#239#255#148#231#255#255'{'#214#247#255#132#214
+ +#247#255'c'#198#247#255'k'#206#247#255'k'#206#247#255'J'#181#239#255'R'#189
+ +#247#255'J'#181#247#255'9'#181#222#255'9'#181#231#255'9'#181#222#255'1'#173
+ +#247#255'9'#173#239#255'1'#156#206#255'9'#156#206#255#24#140#198#255'JB1'#255
+ +#0#0#0#0#0#0#0#0#132#156#165#255#173#231#247#255#165#231#239#255#148#231#255
+ +#255'{'#214#247#255#132#214#247#255'c'#206#247#255'k'#206#247#255'k'#198#247
+ +#255'c'#206#247#255'R'#181#247#255'J'#189#239#255'9'#181#231#255'9'#181#222
+ +#255'9'#181#231#255'9'#165#239#255'9'#173#239#255'1'#156#206#255'9'#165#206
+ +#255#24#132#198#255#24#140#189#255'J91'#255#0#0#0#0#0#0#0#0#132#148#165#255
+ +#173#231#247#255#140#231#255#255'{'#214#247#255#132#214#247#255'c'#206#247
+ +#255'k'#198#247#255'k'#206#247#255'c'#198#247#255'R'#189#247#255'J'#181#239
+ +#255'9'#181#231#255'9'#181#222#255'9'#181#231#255'1'#173#239#255'9'#173#247
+ +#255'1'#156#206#255'9'#156#214#255'1'#156#206#255#24#140#189#255#24#132#198
+ +#255'JB1'#255#0#0#0#0#0#0#0#0#132#156#165#255#173#231#247#255'{'#214#247#255
+ +#132#214#247#255'{'#222#247#255'k'#198#247#255'c'#206#247#255'k'#198#247#255
+ +'J'#189#239#255'R'#181#239#255'J'#189#247#255'9'#181#222#255'9'#181#231#255
+ +'9'#165#239#255'9'#173#239#255'1'#156#206#255'9'#165#206#255'1'#156#206#255
+ +'9'#165#206#255#24#132#198#255#24#140#189#255#0#0#0#255#0#0#0#0#0#0#0#0#132
+ +#156#165#255#173#231#247#255#132#214#247#255'{'#222#247#255'k'#198#247#255'k'
+ +#206#247#255'c'#198#247#255'k'#206#247#255'R'#189#247#255'J'#181#247#255'9'
+ +#181#222#255'9'#181#231#255'9'#181#231#255'9'#173#239#255'1'#173#247#255'9'
+ +#156#206#255'1'#156#206#255'9'#156#206#255'1'#165#206#255#24#132#189#255#24
+ +#140#198#255#0#0#0#255#0#0#0#0#0#0#0#0#132#156#173#255#173#231#239#255'{'#214
+ +#247#255'k'#198#247#255'J'#189#247#255'J'#181#239#255'R'#189#239#255'J'#181
+ ,#247#255'9'#181#222#255'9'#173#239#255'1'#156#206#255'9'#156#206#255'1'#156
+ +#206#255'1'#156#206#255'9'#156#206#255'1'#165#206#255#24#132#198#255#24#140
+ +#198#255#24#132#189#255#24#140#198#255#24#132#189#255#0#0#0#255#0#0#0#0#0#0#0
+ +#0#140#156#165#255#173#231#247#255'J'#181#247#255'J'#189#247#255#132#173#189
+ +#255'9'#181#231#255'1'#156#206#255'9'#156#206#255'1'#156#206#255'1'#156#206
+ +#255#24#132#189#255#24#140#198#255#24#132#189#255#24#140#198#255#24#140#189
+ +#255#24#132#198#255#24#140#189#255#24#132#189#255#24#140#198#255#24#132#189
+ +#255#24#140#198#255#0#0#0#255#0#0#0#0#0#0#0#0'k{'#140#255'9cs'#255'9c{'#255
+ +'R9)'#255'JB1'#255'RB1'#255'JB1'#255'RB1'#255'JB1'#255'RB1'#255#0#0#0#255#0#0
+ +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
+ +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#10'TImageList'#11'SmallImages'#4'left'#2'('#3'top'#2#16#6'Bitmap'#10
+ +#14#24#0#0'Li'#6#0#0#0#16#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#206#189#173#255#198#173#165#255#198#173#156#255#198#173#165#255
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#140#189#206#255#198#173#165#255#239#231#222#255#198#247#255#255#198#247
+ +#255#255#189#198#206#255#206#189#173#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#181#255#206#189#173#255#198#239#255#255
+ +#198#247#255#255#198#239#255#255#173#231#239#255#140#231#255#255'c'#206#247
+ +#255#198#173#156#255#140#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#206#189#173#255#198#214#222#255#198#247#255#255#198#247#255#255#198#239#255
+ +#255#173#239#255#255#165#231#239#255'{'#214#247#255'k'#198#247#255'c'#206#247
+ +#255#140#189#214#255#198#173#156#255#132#173#198#255#0#0#0#0#198#173#156#255
+ +#206#181#173#255#198#247#255#255#198#239#255#255#198#239#255#255#198#247#255
+ +#255#165#239#255#255#173#231#239#255'{'#214#247#255'c'#198#247#255'k'#206#247
+ +#255'k'#198#239#255'k'#206#247#255'J'#181#239#255#140#173#198#255#140#156#165
+ +#255#198#173#156#255#173#247#255#255#165#231#247#255#173#231#239#255#173#231
+ +#239#255'{'#214#247#255'k'#198#247#255'c'#206#247#255'k'#206#247#255'k'#206
+ +#239#255'J'#173#239#255'B'#181#239#255'J'#173#231#255'B'#181#239#255')'#189
+ +#239#255#189#156#140#255#198#173#165#255#173#231#239#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#247#239#231#255#255#247#239#255#255#239#231#255#255#247#239
+ +#255#239#222#222#255'B'#181#239#255#148#132'{'#255#198#173#156#255#206#189
+ +#181#255#247#239#239#255#255#239#231#255#231#231#222#255#255#239#239#255#255
+ +#239#231#255#247#247#239#255#255#239#231#255#247#239#239#255#255#239#231#255
+ +#247#222#206#255#247#247#231#255#255#214#198#255#148#132'{'#255#148#132'{'
+ +#255#198#173#165#255#247#206#181#255#222#198#173#255#247#239#239#255#255#239
+ +#239#255#231#189#148#255#231#181#148#255#198#173#165#255#198#173#156#255#198
+ +#173#165#255#198#173#156#255#231#231#222#255#255#222#198#255#181#156#140#255
+ +#231#173#132#255#148#132'{'#255#198#165#140#255#255#255#255#255#255#222#198
+ +#255#222#198#173#255#222#198#173#255#222#189#173#255#222#206#198#255#222#198
+ +#173#255#222#198#181#255#222#198#173#255#198#173#165#255#198#173#156#255#181
+ +#156#140#255#231#173#140#255#255#214#156#255#140#132#132#255#189#165#148#255
+ +#255#255#255#255#255#255#255#255#189#165#140#255#222#206#198#255#255#247#239
+ +#255#247#239#239#255#255#247#239#255#247#239#239#255#255#222#206#255#255#222
+ +#198#255#222#165'{'#255#181#140's'#255#255#214#156#255#255#206#148#255#148
+ +#132'{'#255#198#165#140#255#255#255#255#255#198#173#165#255#222#206#198#255
+ +#247#239#239#255#247#239#231#255#255#239#239#255#247#239#231#255#255#247#231
+ +#255#247#222#198#255#247#222#198#255#255#214#173#255#231#173#132#255#181#132
+ +'s'#255#255#181'{'#255#206'sJ'#255#181#156#140#255#198#173#165#255#222#206
+ +#198#255#255#255#255#255#247#247#231#255#255#222#206#255#247#231#198#255#255
+ +#222#206#255#247#222#198#255#255#214#173#255#255#222#181#255#255#214#156#255
+ +#255#206#148#255#231#148'c'#255#198'{J'#255#206'sB'#255#189#156#132#255#247
+ +#214#189#255#255#255#255#255#255#222#206#255#255#222#173#255#255#214#156#255
+ +#255#198#140#255#255#198#140#255#255#198#148#255#255#181'{'#255#255#181'{'
+ +#255#247#165'{'#255#239#165'{'#255#231#148'c'#255#214#132'Z'#255#181'c1'#255
+ +#181#156#140#255#181#156#140#255#181#140's'#255#181#132's'#255#181#140's'#255
+ +#140#132#132#255#206'sJ'#255#198'sJ'#255#198'{B'#255#198'sJ'#255#198'sJ'#255
+ +#198'sJ'#255#181'c1'#255#189'c1'#255#181'c1'#255#189'c1'#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#255#255#255#0#255#255#255#0#255
+ +#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255
+ ,#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0
+ +#255#255#255#0#255#255#255#0#255#255#255#0#255#255'J91'#255#255#0#255#255'JB'
+ +'1'#255#255#0#255#255'JB1'#255#255#0#255#255'JB1'#255#255#0#255#255'R91'#255
+ +#255#0#255#255'JB1'#255#255#0#255#255'RB1'#255#255#0#255#255'RB1'#255#181#156
+ +#140#255#255#255#255#255#148#132'{'#255#255#255#255#255#148#132#132#255#255
+ +#255#255#255#148#132'{'#255#255#255#255#255#148#132#132#255#255#255#255#255
+ +'Rck'#255#255#255#255#255'RZk'#255#255#255#255#255'Rck'#255#255#0#255#255#247
+ +#165#140#255#247#173#148#255#247#165'{'#255#222#165'{'#255#222#165'{'#255#231
+ +#148'k'#255#231#148'c'#255#231#148'k'#255#214#132'R'#255#222'{J'#255#214#132
+ +'R'#255#206'{J'#255#206'sJ'#255#198'{B'#255#206'sJ'#255'RB1'#255#239#173#148
+ +#255#247#239#239#255#255#247#239#255#247#239#239#255#255#247#239#255#247#247
+ +#239#255#247#239#239#255#247#173#140#255#247#165'{'#255#247#165'{'#255#247
+ +#165'{'#255#239#165'{'#255#247#165'{'#255#247#165'{'#255#247#165'{'#255'RB1'
+ +#255#247#173#140#255#247#165#140#255#239#165's'#255#247#165'{'#255#239#165's'
+ +#255#247#165'{'#255#231#148'c'#255#231#148'c'#255#222#148'k'#255#214#132'R'
+ +#255#222'{J'#255#222'{J'#255#222'{J'#255#222'{J'#255#222'{J'#255'RB1'#255#189
+ +#173#165#255#255#255#255#255#255#255#255#255#222#165'{'#255#255#255#255#255
+ +#255#255#255#255#222#165'{'#255#255#255#255#255#255#255#255#255#222#165'{'
+ +#255#255#255#255#255#255#255#255#255#222#165'{'#255#255#247#239#255#247#239
+ +#239#255'JB1'#255#198#173#165#255#255#255#255#255#255#255#255#255#181#156#140
+ +#255#255#255#255#255#255#255#255#255#181#156#140#255#255#255#255#255#255#255
+ +#255#255#181#156#140#255#255#255#255#255#255#247#239#255#181#148#140#255#255
+ +#247#239#255#222#206#198#255'JB9'#255#198#173#156#255#214#173#148#255#181#156
+ +#140#255#189#132's'#255#222#165'{'#255#181#156#140#255#181#140's'#255#222#165
+ +'{'#255#181#156#140#255'B'#181#239#255')'#148#222#255#24'B'#206#255#24'J'#206
+ +#255#222#165'{'#255#0#0#0#0'RB9'#255#198#173#165#255#255#255#255#255#255#255
+ +#255#255#222#165'{'#255#255#255#255#255#255#255#255#255#222#165'{'#255#255
+ +#255#255#255#255#255#255#255')'#156#222#255#255#255#255#255#255#247#239#255
+ +#24'B'#198#255#255#247#239#255#222#206#206#255'JB1'#255#198#173#156#255#255
+ +#255#255#255#255#255#255#255#181#156#140#255#255#255#255#255#255#255#255#255
+ +#181#156#140#255#255#255#255#255#255#239#239#255#24'B'#206#255#255#247#239
+ +#255#255#239#231#255#24'B'#206#255#255#247#239#255#206#189#173#255'JB1'#255
+ +#198#173#165#255#214#173#148#255#0#0#0#0#189#140's'#255#222#165'{'#255#181
+ +#156#140#255#189#132's'#255#222#165'{'#255#0#0#0#0'!J'#198#255#24'B'#206#255
+ +#24'J'#206#255#24'B'#206#255#222#165'{'#255#189#156#140#255'JB1'#255#198#181
+ +#165#255#255#255#255#255#255#255#255#255#206#173#148#255#255#255#255#255#255
+ +#255#255#255#222#165'{'#255#255#247#239#255#255#239#239#255#222#165'{'#255
+ +#255#247#239#255#255#239#231#255#222#165'{'#255#255#231#206#255#198#181#173
+ +#255'RB9'#255#198#173#156#255#255#255#255#255#255#255#255#255#181#148#132#255
+ +#255#255#255#255#255#247#239#255#0#0#0#0#247#239#239#255#247#239#239#255#0#0
+ +#0#0#247#239#239#255#247#247#239#255#0#0#0#0#255#222#206#255#206#189#181#255
+ +'JB1'#255#198#173#165#255#198#173#165#255#0#0#0#0#189#140's'#255#231#181#148
+ +#255#214#173#148#255#181#132's'#255#239#189#148#255#0#0#0#0#189#132's'#255
+ +#198#173#156#255#181#156#140#255#189#132's'#255#206#173#140#255#181#156#140
+ +#255'RB1'#255#0#0#0#0'JB9'#255'RB1'#255'JB9'#255'RB9'#255'JB1'#255'RB9'#255
+ +'JB1'#255'JB9'#255'RB1'#255'JB9'#255'RB1'#255'JB9'#255'RB1'#255'RB9'#255'JB1'
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173#255#206#189#181#255#206#189#173
+ +#255#206#189#181#255#206#189#173#255#206#189#181#255#198#173#165#255#198#173
+ +#156#255#198#173#165#255#198#173#156#255#198#173#165#255#198#165#140#255#181
+ +#156#140#255#181#156#132#255#181#148#140#255#181#156#140#255#206#189#181#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255'Rcc'
+ +#255#198#189#173#255#255#255#255#255#239#222#222#255'Z{'#140#255#148#132'{'
+ +#255'Z{'#140#255#189#198#206#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#247#239#255#255#239#239#255#222#214
+ +#206#255'J91'#255#206#189#181#255#255#255#255#255'Jcc'#255'c{'#140#255#140
+ +#156#173#255#132#156#165#255#148#132'{'#255#239#231#222#255#255#255#255#255
+ +#247#247#239#255#255#255#255#255#247#239#239#255#247#239#231#255#255#239#231
+ +#255#222#206#198#255'JB1'#255#206#189#173#255#255#255#255#255'RB9'#255'J91'
+ +#255#239#231#222#255#189#198#206#255#148#132'{'#255#231#222#222#255#247#247
+ ,#239#255#247#189#165#255#247#189#156#255#255#181'{'#255#247#165'{'#255#247
+ +#165'{'#255#206#189#181#255'JB1'#255#198#173#165#255#255#255#255#255'Rck'#255
+ +'RB9'#255#206#189#181#255#148#132'{'#255'Rck'#255#255#255#255#255#255#239#239
+ +#255#247#247#231#255#247#239#239#255#255#247#239#255#247#239#239#255#247#231
+ +#198#255#206#189#181#255'RB1'#255#198#173#165#255#255#255#255#255#239#231#222
+ +#255'Rck'#255#181#156#132#255#140#156#173#255'RZc'#255#198#214#222#255#247
+ +#247#231#255#247#206#189#255#198#165#140#255#181#156#132#255#181#156#132#255
+ +#181#132's'#255#206#189#181#255'JB1'#255#189#173#156#255#255#247#239#255#16
+ +'{'#189#255#140#173#198#255#24'B'#206#255#24#132#189#255#24'J'#206#255#24'B'
+ +#206#255#255#247#239#255#255#222#198#255#247#222#206#255#255#222#206#255#247
+ +#214#189#255#255#214#189#255#231#189#148#255'J99'#255#198#173#156#255#239#231
+ +#222#255#24'B'#198#255'J'#181#239#255')'#156#222#255'!J'#206#255#24#132#189
+ +#255#24'B'#198#255#255#239#239#255#222#198#173#255#198#165#148#255#181#156
+ +#132#255#181#156#140#255#181#132's'#255#239#189#156#255'JB1'#255#198#165#148
+ +#255#247#247#239#255#189#198#206#255#24'B'#206#255'!J'#198#255#24'B'#206#255
+ +'!J'#206#255#198#165#140#255#255#231#206#255#247#222#198#255#247#214#189#255
+ +#247#214#198#255#255#222#189#255#247#214#189#255#231#181#140#255'JB9'#255#181
+ +#156#140#255#255#222#198#255#255#222#198#255#222#206#198#255#231#198#173#255
+ +#222#198#173#255#231#198#181#255#222#198#173#255#239#198#165#255#231#181#156
+ +#255#231#189#148#255#231#181#148#255#231#173#140#255#231#181#140#255#231#173
+ +#140#255'RB1'#255#181#156#132#255'Rck'#255'JB1'#255'JB1'#255'RB9'#255'JB1'
+ +#255'JB1'#255'RB9'#255'JB1'#255'RB1'#255'JB9'#255'RB9'#255'JB1'#255'JB9'#255
+ +'RB9'#255'JB9'#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#132#173#198#255#140#156#165#255#132#156#173#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#222#198#173#255#206
+ +#189#181#255#206#189#173#255#206#189#181#255#140#156#165#255#173#231#239#255
+ +#173#231#247#255#140#198#214#255'Rcc'#255#198#173#165#255#198#173#156#255#198
+ +#165#148#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#132#156#165#255#132#156#173#255#148#132'{'
+ +#255#140#189#214#255'c{'#140#255#255#247#239#255#231#222#222#255#239#231#222
+ +#255'RZc'#255#0#0#0#0#0#0#0#0#0#0#0#0#206#189#181#255#255#255#255#255#255#255
+ +#255#255#140#156#173#255'{'#214#247#255#140#231#255#255'{'#214#247#255'c'#206
+ +#247#255#140#156#165#255'Zs'#140#255#231#231#222#255#222#206#198#255#181#156
+ +#132#255#0#0#0#0#0#0#0#0#0#0#0#0#206#189#181#255#255#255#255#255#255#255#255
+ +#255#132#156#165#255'c{'#140#255'c{'#140#255'c{'#140#255'c{'#140#255'Z{'#140
+ +#255#140#156#173#255#132#173#189#255#24'B'#206#255#181#156#140#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#206#189#173#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#247#239#239#255#255#239#239#255#247#247#239#255#239#222#222#255#239#231
+ +#222#255#140#173#198#255#24'B'#206#255#140#156#165#255#148#132#132#255#0#0#0
+ +#0#0#0#0#0#0#0#0#0#198#173#156#255#255#255#255#255#255#255#255#255#255#239
+ +#239#255#247#247#231#255#255#239#239#255#247#239#231#255#231#231#222#255')'
+ +#148#222#255#24'J'#206#255#140#156#165#255#222#214#198#255'RZk'#255#0#0#0#0#0
+ +#0#0#0#0#0#0#0#198#173#165#255#255#255#255#255#198#247#255#255#198#214#214
+ +#255#255#239#231#255#247#239#239#255#239#231#222#255#140#173#189#255#24'B'
+ +#206#255'Z{'#140#255#255#222#206#255#231#198#181#255'JB1'#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#198#173#156#255#247#239#239#255'B'#173#239#255'J'#181#239#255#132
+ +#173#198#255#198#214#214#255#132#173#198#255#24'B'#206#255'!J'#206#255#255
+ +#222#198#255#247#222#189#255#198#173#165#255'JB1'#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#198#173#156#255#255#247#239#255'!B'#198#255#24'B'#206#255')'#156#222#255')'
+ +#148#222#255#24'J'#198#255#24'B'#206#255#206#189#173#255#255#222#198#255#222
+ +#206#198#255#198#173#165#255'JB9'#255#0#0#0#0#0#0#0#0#0#0#0#0#198#173#165#255
+ +#247#247#239#255#198#214#214#255#24'B'#206#255'!J'#206#255'!B'#206#255#24'J'
+ +#206#255#140#156#165#255#247#214#181#255#247#206#189#255#222#198#173#255#214
+ +#173#140#255'RB1'#255#0#0#0#0#0#0#0#0#0#0#0#0#198#173#156#255#255#239#231#255
+ +#255#247#239#255#239#231#222#255'!B'#206#255#24'J'#206#255'c{'#140#255#222
+ +#206#198#255#247#206#181#255#222#206#198#255#222#198#181#255#214#173#148#255
+ +'JB9'#255#0#0#0#0#0#0#0#0#0#0#0#0#198#173#165#255#247#247#239#255#222#206#198
+ +#255#222#206#198#255#222#206#198#255#140#156#165#255#206#189#181#255#231#189
+ +#148#255#198#173#165#255#198#173#156#255#214#173#140#255#189#165#148#255'RB1'
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#214#173#148#255'R91'#255'JB1'#255'JB1'#255'JB1'
+ +#255'Rck'#255'RB1'#255'JB9'#255'RB1'#255'JB9'#255'RB1'#255'JB9'#255#0#0#0#0#0
+ ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#140#189#214#255#140#198#206#255#148#198#214#255
+ +#140#189#214#255#140#198#214#255#148#198#214#255#140#189#214#255#140#198#206
+ +#255#148#189#214#255#140#198#214#255#132#173#189#255#132#173#198#255#132#173
+ +#198#255#132#173#198#255#0#0#0#0#0#0#0#0#148#189#206#255#198#247#255#255#198
+ +#239#255#255#198#247#255#255#198#247#255#255#198#239#255#255#198#247#255#255
+ +#198#247#255#255#198#247#255#255#198#247#255#255#206#239#255#255#198#247#255
+ +#255#206#247#255#255'Z{'#140#255#0#0#0#0#0#0#0#0#140#198#214#255#198#247#255
+ +#255#173#239#255#255#173#239#247#255#173#239#255#255#173#239#247#255#173#239
+ +#255#255#173#239#255#255#173#239#255#255#165#239#255#255#173#239#255#255#165
+ +#239#247#255#173#239#255#255'Z{'#140#255#0#0#0#0#0#0#0#0#132#173#189#255#173
+ +#239#255#255#173#239#255#255#165#239#255#255#173#239#255#255#165#239#255#255
+ +#173#239#255#255#165#239#247#255#173#239#255#255#165#239#247#255#173#239#255
+ +#255#173#239#255#255#173#247#255#255'RZk'#255#0#0#0#0#0#0#0#0#132#173#198#255
+ +#173#231#239#255#165#239#255#255#173#247#247#255#173#239#255#255#173#247#255
+ +#255#165#239#255#255#173#239#255#255#173#247#255#255#173#239#255#255#165#239
+ +#247#255#173#239#255#255#165#239#255#255'Rcc'#255#0#0#0#0#0#0#0#0#132#173#198
+ +#255#140#231#247#255#140#231#255#255#140#231#255#255#140#231#247#255#140#231
+ +#255#255#140#231#247#255#140#231#247#255#140#231#255#255#140#231#247#255#140
+ +#231#255#255#140#231#255#255#140#231#255#255'Rcc'#255#0#0#0#0#0#0#0#0#132#173
+ +#198#255'k'#198#247#255#140#231#247#255#140#231#255#255#140#222#255#255#140
+ +#231#247#255#140#231#255#255#140#231#255#255#140#222#247#255#140#231#255#255
+ +#140#231#247#255#140#231#255#255#140#231#247#255'RZk'#255#0#0#0#0#0#0#0#0#140
+ +#173#189#255'B'#181#239#255'{'#214#247#255#140#231#255#255#140#231#247#255
+ +#140#231#255#255#140#222#255#255#140#231#247#255#140#231#255#255#140#231#255
+ +#255#140#231#255#255#140#231#255#255#140#231#255#255'Rcc'#255#0#0#0#0#0#0#0#0
+ +#132#173#198#255'J'#173#239#255')'#189#239#255'J'#181#239#255'B'#173#239#255
+ +')'#156#222#255'k'#206#239#255#140#231#255#255#140#231#247#255#140#222#255
+ +#255#140#231#247#255#140#231#255#255#140#231#255#255'RZc'#255#0#0#0#0#0#0#0#0
+ +#132#173#189#255'k'#206#247#255')'#156#222#255')'#189#239#255')'#189#239#255
+ +')'#156#222#255')'#189#239#255#140#222#255#255#140#231#255#255#140#231#247
+ +#255#140#231#255#255#140#231#247#255#140#231#255#255'Rck'#255#0#0#0#0#0#0#0#0
+ +#132#173#198#255'k'#206#247#255'J'#173#239#255')'#156#222#255'1'#189#247#255
+ +')'#189#239#255')'#156#222#255'{'#214#247#255'{'#214#247#255'{'#214#255#255
+ +'{'#214#247#255'{'#214#247#255'{'#214#247#255'Rcc'#255#0#0#0#0#0#0#0#0#140
+ +#173#198#255'{'#214#247#255'k'#206#239#255'J'#181#239#255')'#156#222#255'1'
+ +#156#231#255')'#156#222#255'J'#181#239#255'{'#214#247#255'k'#206#247#255'{'
+ +#214#247#255'{'#214#247#255'{'#222#255#255'Rck'#255#0#0#0#0#0#0#0#0#132#173
+ +#189#255'k'#206#247#255'{'#214#247#255'k'#198#247#255'J'#181#231#255')'#148
+ +#222#255')'#156#222#255#24#132#189#255')'#156#222#255'J'#173#239#255'J'#181
+ +#239#255'J'#181#239#255'J'#173#239#255'Rcc'#255#0#0#0#0#0#0#0#0#140#173#198
+ +#255'Zs'#140#255'c{'#140#255'Z{'#140#255'c{'#140#255'c{'#140#255'Zck'#255'RZ'
+ +'c'#255'Zck'#255'Rcc'#255'RZk'#255'Rcc'#255'Rcc'#255'Rck'#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140#156#165#255#132#156#165#255#140#156#173#255
+ +#132#156#165#255#140#156#165#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#156#173#255#173#231#247#255#173#239
+ +#255#255#173#239#255#255#173#247#255#255#140#231#255#255#132#156#173#255#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#140#156
+ +#165#255#132#156#165#255#140#156#165#255#132#156#165#255#132#156#165#255#140
+ +#156#165#255#140#156#165#255#132#156#165#255#140#156#165#255#132#156#173#255
+ +#132#156#165#255#140#156#173#255#132#156#165#255#132#156#165#255#0#0#0#0#0#0
+ +#0#0#132#156#173#255#206#247#255#255#198#247#255#255#198#239#255#255#198#247
+ +#255#255#173#239#255#255#173#239#255#255#173#239#255#255#140#231#255#255#140
+ +#231#255#255'{'#214#247#255'k'#206#247#255'c'#198#247#255'k'#206#247#255'Zs'
+ +#140#255#0#0#0#0#132#156#165#255#198#239#255#255#173#239#255#255#173#239#255
+ +#255#173#239#255#255#165#239#255#255#140#231#255#255#140#231#255#255#140#231
+ +#255#255'c'#198#239#255'k'#206#247#255'J'#173#239#255'J'#181#239#255')'#156
+ ,#222#255'Z{'#140#255#0#0#0#0#132#156#173#255#198#247#255#255#173#239#255#255
+ +#165#239#255#255#173#239#255#255#140#231#247#255#140#231#255#255#140#231#247
+ +#255'{'#214#247#255'k'#206#247#255'c'#198#247#255'J'#181#231#255')'#148#222
+ +#255#24#132#189#255'Zck'#255#0#0#0#0#140#156#165#255#198#247#255#255#165#239
+ +#247#255#173#247#255#255#173#239#247#255#140#231#255#255#140#231#255#255'{'
+ +#214#247#255'c'#206#247#255'k'#198#239#255'J'#181#239#255'J'#181#239#255'1'
+ +#156#222#255#24#132#189#255'Rcc'#255#0#0#0#0#132#156#165#255#173#239#255#255
+ +#173#239#255#255#165#239#255#255#140#231#255#255#140#231#247#255'{'#214#247
+ +#255'k'#198#247#255'k'#206#247#255'J'#173#239#255'J'#181#231#255'J'#173#239
+ +#255')'#156#222#255#24#132#189#255'RB1'#255#0#0#0#0#140#156#173#255#165#231
+ +#239#255#173#239#255#255#140#231#247#255#140#231#255#255'{'#214#247#255'c'
+ +#206#247#255'k'#206#247#255'B'#173#231#255'J'#181#239#255'J'#181#239#255')'
+ +#148#222#255')'#156#222#255#24#132#189#255'JB9'#255#0#0#0#0#148#132'{'#255
+ +#173#231#247#255#140#231#255#255#140#231#255#255'{'#214#247#255'k'#198#247
+ +#255'k'#206#239#255'J'#173#239#255'J'#181#239#255'J'#181#231#255')'#148#222
+ +#255')'#156#231#255'!'#132#189#255#24#132#189#255'RB1'#255#0#0#0#0'Z{'#140
+ +#255#173#231#239#255'c'#206#247#255'J'#173#231#255'J'#181#239#255')'#156#222
+ +#255')'#148#231#255#24#132#181#255#24#132#189#255#24#132#189#255#24#132#189
+ +#255#24#132#181#255#24#132#189#255#24#132#189#255#0#0#0#255#0#0#0#0'Z{'#140
+ +#255'cs'#140#255'Rcc'#255'Rck'#255'RB1'#255'RB1'#255'RB1'#255#0#0#0#255#0#0#0
+ +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#10'TImageList'#10'ToolImages'#6'Height'#2#12#5'Width'#2#12#4'left'#3#144
+ +#0#3'top'#2#16#6'Bitmap'#10#142#13#0#0'Li'#6#0#0#0#12#0#0#0#12#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255
+ +#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132
+ +#255#132#132#132#255#132#132#132#255#0#0#0#255#132#132#132#255#0#0#0#255#0
+ +#255#255#255#255#255#255#255#0#255#255#255#255#255#255#255#0#255#255#255#255
+ +#255#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#0#0#255#132#132#132
+ +#255#198#198#198#255#0#0#0#255#0#255#255#255#255#255#255#255#0#255#255#255
+ +#255#255#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#132#132#255#0#0#0
+ +#255#132#132#132#255#0#255#255#255#198#198#198#255#0#0#0#255#0#255#255#255
+ +#255#255#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#132#132#255#198
+ +#198#198#255#0#0#0#255#132#132#132#255#255#255#255#255#255#255#255#255#0#132
+ +#132#255#0#0#0#255#0#255#255#255#255#255#255#255#0#0#0#255#0#132#132#255#198
+ +#198#198#255#198#198#198#255#0#0#0#255#132#132#132#255#0#255#255#255#0#132
+ +#132#255#198#198#198#255#0#132#132#255#0#0#0#255#0#0#0#255#0#132#132#255#198
+ +#198#198#255#0#132#132#255#198#198#198#255#0#0#0#255#132#132#132#255#0#132
+ +#132#255#198#198#198#255#198#198#198#255#198#198#198#255#0#132#132#255#0#132
+ +#132#255#198#198#198#255#198#198#198#255#198#198#198#255#0#132#132#255#0#0#0
+ +#255#132#132#132#255#198#198#198#255#198#198#198#255#198#198#198#255#198#198
+ +#198#255#198#198#198#255#198#198#198#255#198#198#198#255#198#198#198#255#198
+ +#198#198#255#198#198#198#255#0#0#0#255#132#132#132#255#132#132#132#255#132
+ +#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255
+ +#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#0#0#0#255#0
+ +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
+ +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#132
+ +#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255
+ +#132#132#132#255#132#132#132#255#0#0#0#255#132#132#132#255#0#0#0#255#0#255
+ +#255#255#255#255#255#255#0#255#255#255#255#255#255#255#0#255#255#255#255#255
+ +#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#0#0#255#132#132#132#255
+ +#198#198#198#255#0#0#0#255#0#255#255#255#255#255#255#255#0#255#255#255#255
+ +#255#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#0#132#255#0#0#0#255
+ +#132#132#132#255#0#255#255#255#198#198#198#255#0#0#0#255#0#255#255#255#255
+ +#255#255#255#0#255#255#255#255#255#255#255#0#0#0#255#0#0#132#255#198#198#198
+ +#255#0#0#0#255#132#132#132#255#255#255#255#255#255#255#255#255#0#0#132#255#0
+ ,#0#0#255#0#0#255#255#0#0#255#255#0#0#0#255#0#0#132#255#198#198#198#255#0#0
+ +#255#255#0#0#255#255#132#132#132#255#0#255#255#255#0#0#132#255#198#198#198
+ +#255#0#0#132#255#0#0#255#255#0#0#255#255#0#0#255#255#198#198#198#255#0#0#255
+ +#255#0#0#255#255#0#0#255#255#132#132#132#255#0#0#132#255#198#198#198#255#198
+ +#198#198#255#198#198#198#255#0#0#132#255#0#0#255#255#0#0#255#255#0#0#255#255
+ +#0#0#255#255#0#0#255#255#0#0#0#255#132#132#132#255#198#198#198#255#198#198
+ +#198#255#198#198#198#255#198#198#198#255#198#198#198#255#198#198#198#255#0#0
+ +#255#255#0#0#255#255#0#0#255#255#198#198#198#255#0#0#0#255#132#132#132#255
+ +#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#132#132#132
+ +#255#0#0#255#255#0#0#255#255#0#0#255#255#0#0#255#255#0#0#255#255#0#0#0#255#0
+ +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#255#255#0#0#255#255#0#0
+ +#255#255#0#0#0#255#0#0#255#255#0#0#255#255#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#255#255#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255
+ +#255#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#198
+ +#198#198#255#132#132#132#255#132#132#132#255#132#132#132#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255#255#132#132#132
+ +#255#198#198#198#255#255#255#255#255#255#255#255#255#132#132#132#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#0#0#0#255#198#198#198#255#132#132#132#255#255#255#255#255#132
+ +#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255#255#255#255
+ +#255#255#132#132#132#255#132#132#0#255#0#0#0#255#132#132#0#255#198#198#198
+ +#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255#255
+ +#255#255#255#255#132#132#132#255#0#0#0#255#255#255#0#255#132#132#132#255#132
+ +#132#132#255#132#132#132#255#0#0#0#0#198#198#198#255#198#198#198#255#132#132
+ +#132#255#255#255#255#255#255#255#255#255#132#132#132#255#0#0#0#255#255#255
+ +#255#255#132#132#132#255#198#198#198#255#132#132#132#255#198#198#198#255#0#0
+ +#0#255#0#0#0#255#132#132#132#255#255#255#255#255#255#255#255#255#132#132#132
+ +#255#132#132#0#255#0#0#0#255#132#132#0#255#132#132#132#255#132#132#132#255#0
+ +#0#0#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255
+ +#255#255#132#132#132#255#132#132#132#255#132#132#132#255#0#0#0#255#0#0#0#0
+ +#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0
+ +#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#132#132#132#255#198#198#198#255#132#132#132#255#198#198#198#255#0#0#0
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#198#198#198#255#132
+ +#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#198#198#198#255
+ +#132#132#132#255#198#198#198#255#132#132#132#255#198#198#198#255#132#132#132
+ +#255#132#132#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132
+ +#132#132#255#198#198#198#255#132#132#132#255#132#132#132#255#132#132#132#255
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255
+ +#255#132#132#132#255#198#198#198#255#255#255#255#255#255#255#255#255#132#132
+ +#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#0#0#0#255#198#198#198#255#132#132#132#255#255
+ +#255#255#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#255#255
+ +#255#255#255#255#255#255#132#132#132#255#132#132#0#255#0#0#0#255#132#132#0
+ +#255#198#198#198#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255
+ +#255#255#255#255#255#255#255#255#132#132#132#255#0#0#0#255#255#255#0#255#132
+ +#132#132#255#132#132#132#255#132#132#132#255#0#0#0#0#198#198#198#255#198#198
+ +#198#255#132#132#132#255#255#255#255#255#255#255#255#255#132#132#132#255#0#0
+ +#255#255#0#0#255#255#0#0#255#255#0#0#255#255#132#132#132#255#198#198#198#255
+ +#0#0#0#255#0#0#0#255#132#132#132#255#255#255#255#255#255#255#255#255#0#0#255
+ +#255#255#255#255#255#0#0#255#255#0#0#255#255#255#255#255#255#0#0#255#255#0#0
+ +#0#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#0#0#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#255#255
+ +#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#255#255#0#0
+ +#255#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0#255#255#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#0#0#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#132#132#132#255#255#255#255#255#0#0#255#255#255#255#255#255#0#0
+ +#255#255#0#0#255#255#255#255#255#255#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#132
+ +#132#132#255#198#198#198#255#132#132#132#255#198#198#198#255#0#0#255#255#0#0
+ +#255#255#0#0#255#255#0#0#255#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#132#132#255#132#132#132#255#132#132#132#255#132#132#132#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#255#255#255#255#255#255
+ ,#255#255#255#255#255#255#255#198#198#198#255#132#132#132#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#132#132#132#255#198#198
+ +#198#255#0#132#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#132#132#132#255#198#198#198#255#255#255#255#255#255#255#255#255#0#132
+ +#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#0#0#0#0
+ +#255#0#0#0#255#132#132#132#255#198#198#198#255#0#0#0#255#0#0#0#255#0#0#0#0#0
+ +#0#0#255#0#0#0#0#198#198#198#255#0#0#0#255#0#0#0#255#132#132#132#255#198#198
+ +#198#255#255#255#255#255#255#255#255#255#132#132#132#255#0#0#0#255#0#0#0#255
+ +#0#0#0#255#198#198#198#255#0#0#0#0#0#0#0#255#255#255#255#255#0#0#0#255#0#0#0
+ +#255#132#132#132#255#198#198#198#255#0#0#0#255#0#0#0#255#255#255#255#255#0#0
+ +#0#255#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#132#132#132#255#198#198#198
+ +#255#198#198#198#255#132#132#132#255#132#132#132#255#0#0#0#255#255#255#255
+ +#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#0#0#0#255#0
+ +#0#0#255#0#0#0#255#0#0#0#255#255#255#255#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#132#132#132#255#132#132#132#255#132#132#132#255#132#132
+ +#132#255#132#132#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#198#198#198#255#132#132#132#255#0#0#0#255#0#0#0#255#0
+ +#0#0#255#0#0#0#255#0#0#0#255#132#132#132#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#132#132#255#132#132#132#255#132#132#132#255#132#132#132
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#132#132#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#198#198#198#255#132#132#132
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#132
+ +#132#132#255#198#198#198#255#0#132#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#132#132#132#255#198#198#198#255#255#255#255#255#255
+ +#255#255#255#0#132#132#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#255#0#0#0#0#0#0#0#255#0#0#0#255#132#132#132#255#198#198#198#255#0#0#0#255#0
+ +#0#0#255#0#0#0#0#0#0#0#255#0#0#0#0#198#198#198#255#0#0#0#255#0#0#0#255#132
+ +#132#132#255#198#198#198#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0
+ +#255#255#0#0#255#255#0#0#255#255#198#198#198#255#0#0#0#0#0#0#0#255#255#255
+ +#255#255#0#0#0#255#0#0#0#255#132#132#132#255#0#0#255#255#255#255#255#255#0#0
+ +#255#255#0#0#255#255#255#255#255#255#0#0#255#255#0#0#0#0#0#0#0#255#255#255
+ +#255#255#132#132#132#255#198#198#198#255#198#198#198#255#0#0#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0#0#0
+ +#0#0#0#0#0#0#0#255#255#255#255#255#0#0#0#255#0#0#0#255#0#0#255#255#0#0#255
+ +#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0#255#255#0#0#0#0#0#0#0#0
+ +#0#0#0#0#132#132#132#255#132#132#132#255#132#132#132#255#0#0#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#255#255#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#255#255#255#255#255#255#0#0
+ +#255#255#0#0#255#255#255#255#255#255#0#0#255#255#0#0#0#0#0#0#0#0#198#198#198
+ +#255#132#132#132#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#255#255#0#0#255#255#0
+ +#0#255#255#0#0#255#255#0#0#0#0#0#0#18'TOpenPictureDialog'#18'OpenPictureDial'
+ +'og1'#5'Title'#6#18'Open existing file'#4'left'#3#136#0#3'top'#2'@'#0#0#0
+]);
diff --git a/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.pas b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.pas
new file mode 100644
index 000000000..3d8b0da5f
--- /dev/null
+++ b/components/jvcllaz/examples/JvNavigationPane/JvNavPaneDemoMainForm.pas
@@ -0,0 +1,482 @@
+// $Id: JvNavPaneDemoMainForm.pas 10610 2006-05-19 13:35:08Z elahn $
+unit JvNavPaneDemoMainForm;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ LCLIntf, LMessages, SysUtils, Classes, Graphics, Controls, Forms,
+ Dialogs, StdCtrls, {JvOutlookBar,} ComCtrls, CheckLst, //JvComponent,
+ JvNavigationPane, ImgList, Menus, {JvPageList, JclWin32, JvExControls,} ExtCtrls,
+ {JvExExtCtrls,} ExtDlgs, LResources;
+
+type
+ TJvNavPaneDemoMainFrm = class(TForm)
+ PopupMenu1: TPopupMenu;
+ LargeImages: TImageList;
+ HideAll1: TMenuItem;
+ ShowAll1: TMenuItem;
+ N1: TMenuItem;
+ Dontallowresize1: TMenuItem;
+ ChangeFont1: TMenuItem;
+ SmallImages: TImageList;
+ Colors1: TMenuItem;
+ Standard1: TMenuItem;
+ Blue1: TMenuItem;
+ Silver1: TMenuItem;
+ Olive1: TMenuItem;
+ N2: TMenuItem;
+ ShowToolPanel1: TMenuItem;
+ ToolImages: TImageList;
+ ShowCloseButton1: TMenuItem;
+ N3: TMenuItem;
+ BackgroundImage1: TMenuItem;
+ OpenPictureDialog1: TOpenPictureDialog;
+ procedure FormCreate(Sender: TObject);
+ procedure Dontallowresize1Click(Sender: TObject);
+ procedure HideAll1Click(Sender: TObject);
+ procedure ShowAll1Click(Sender: TObject);
+ procedure ChangeFont1Click(Sender: TObject);
+ procedure SchemaClick(Sender: TObject);
+ procedure PopupMenu1Popup(Sender: TObject);
+ procedure ShowToolPanel1Click(Sender: TObject);
+ procedure ShowCloseButton1Click(Sender: TObject);
+ procedure BackgroundImage1Click(Sender: TObject);
+ private
+ JvNavPaneStyleManager1: TJvNavPaneStyleManager;
+ JvOutlookSplitter1: TJvOutlookSplitter;
+ { Private declarations }
+ procedure DoToolMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
+ procedure DoToolMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
+ procedure DoToolPanelClose(Sender: TObject);
+ procedure DoToolButtonClick(Sender: TObject; Index: integer);
+ procedure DoToolEndDock(Sender, Target: TObject; X, Y: Integer);
+ public
+ { Public declarations }
+ NP: TJvNavigationPane;
+ NT: TJvNavPaneToolPanel;
+ end;
+
+var
+ JvNavPaneDemoMainFrm: TJvNavPaneDemoMainFrm;
+
+implementation
+uses
+ CommCtrl;
+
+procedure TJvNavPaneDemoMainFrm.FormCreate(Sender: TObject);
+var
+ Page: TJvNavPanelPage;
+ N: TTreeNode;
+ R: TRect;
+ i: integer;
+
+ tv: TTreeView;
+
+ dummy: integer;
+begin
+ //Self.Height := 600;
+ //Self.Width := 800;
+ (*
+ object JvNavPaneStyleManager1: TJvNavPaneStyleManager
+ Theme = nptXPOlive
+ Left = 32
+ Top = 50
+ end
+ object JvOutlookSplitter1: TJvOutlookSplitter
+ Left = 0
+ Top = 0
+ Width = 7
+ Height = 434
+ Cursor = crSizeWE
+ Align = alLeft
+ ColorFrom = 7703937
+ ColorTo = 3823693
+ StyleManager = JvNavPaneStyleManager1
+ ParentStyleManager = False
+ end
+ *)
+ JvNavPaneStyleManager1 := TJvNavPaneStyleManager.Create(Self);
+ JvNavPaneStyleManager1.Theme := nptXPOlive;
+
+ JvOutlookSplitter1 := TJvOutlookSplitter.Create(Self);
+ JvOutlookSplitter1.Parent := Self;
+ JvOutlookSplitter1.Align := alLeft;
+ JvOutlookSplitter1.ColorFrom := TColor(7703937);
+ JvOutlookSplitter1.ColorTo := TColor(3823693);
+ JvOutlookSplitter1.StyleManager := JvNavPaneStyleManager1;
+ JvOutlookSplitter1.ParentStyleManager := False;
+
+ JvNavPaneStyleManager1.Theme := nptCustom;
+ // this is how to create a NavPane at run-time
+ // also shows how to create and insert pages as well as controls on pages
+ NP := TJvNavigationPane.Create(Self);
+
+ NP.Parent := Self;
+ NP.Cursor := crHandPoint;
+ NP.Width := 220;
+ // NP.BorderWidth := 2;
+ NP.Align := alLeft;
+ JvOutlookSplitter1.Left := 225;
+ JvOutlookSplitter1.MinSize := 220;
+ NP.DropDownMenu := PopupMenu1;
+ NP.SmallImages := SmallImages;
+ NP.LargeImages := LargeImages;
+ NP.AutoHeaders := True;
+ NP.StyleManager := JvNavPaneStyleManager1;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := '&Mail';
+ Page.ImageIndex := 0;
+ Page.PageList := NP;
+
+ with TJvNavPanelDivider.Create(Self) do
+ begin
+ Caption := 'Favorite Folders';
+ Parent := Page;
+ Top := 100;
+ Align := alTop;
+ Enabled := false;
+ Cursor := crDefault;
+ StyleManager := JvNavPaneStyleManager1;
+ end;
+
+ tv := TTreeView.Create(Self);
+ with tv do
+ begin
+ Parent := Page;
+ Top := 200;
+ Align := alTop;
+ Font.Style := [];
+ BorderStyle := bsNone;
+ Items.Add(nil, 'Inbox');
+ Items.Add(nil, 'Unread Mail');
+ Items.Add(nil, 'For Follow Up [4]');
+ Items.Add(nil, 'Sent Items');
+ Height := 100;
+ end;
+
+ with TJvNavPanelDivider.Create(Self) do
+ begin
+ Caption := 'All Mail Folders';
+ Parent := Page;
+ Top := tv.Top + tv.Height; // 201; // old = 100
+ Align := alTop;
+ Cursor := crSizeNS;
+ StyleManager := JvNavPaneStyleManager1;
+ end;
+
+ with TTreeView.Create(Self) do
+ begin
+ Parent := Page;
+ Align := alClient;
+ BorderStyle := bsNone;
+ Font.Style := [];
+ N := Items.Add(nil, 'Mailbox - Chris Gray');
+ Items.AddChild(N, 'Deleted Items');
+ Items.AddChild(N, 'Drafts');
+ Items.AddChild(N, 'Inbox');
+ Items.AddChild(N, 'Junk E-mail');
+ Items.AddChild(N, 'Outbox');
+ Items.AddChild(N, 'Sent Items');
+ N := Items.AddChild(N, 'Search Folders');
+ Items.AddChild(N, 'For Follow Up [4]');
+ Items.AddChild(N, 'Large Mail');
+ Items.AddChild(N, 'Unread Mail');
+ FullExpand;
+ end;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := '&Calendar';
+ Page.ImageIndex := 1;
+ Page.PageList := NP;
+ //TODO: replace
+ (*
+ // NB! TMonthCalendar messes up the form when you size the form smaller than one calendar width
+ with TMonthCalendar.Create(Self) do
+ begin
+ Parent := Page;
+ Align := alTop;
+ AutoSize := true;
+ AutoSize := false;
+ Date := SysUtils.Date;
+ MonthCal_GetMinReqRect(Handle, R);
+ end;
+ Constraints.MinHeight := R.Bottom - R.Top + 12;
+ Constraints.MinWidth := R.Right - R.Left + 12;
+ *)
+
+ with TJvNavPanelDivider.Create(Self) do
+ begin
+ Caption := 'My Calendars';
+ Parent := Page;
+ Top := 1500;
+ Align := alTop;
+ Cursor := crDefault;
+ Enabled := false;
+ StyleManager := JvNavPaneStyleManager1;
+ end;
+ with TCheckListBox.Create(Self) do
+ begin
+ Parent := Page;
+ Checked[Items.Add('Calendar')] := true;
+ Items.Add('Project Schedule');
+ Top := 1500;
+ Height := 32;
+ Align := alTop;
+ end;
+ with TJvNavPanelDivider.Create(Self) do
+ begin
+ Caption := 'Other Calendars';
+ Parent := Page;
+ Top := 1500;
+ Align := alTop;
+ Cursor := crSizeNS;
+ StyleManager := JvNavPaneStyleManager1;
+ end;
+ with TCheckListBox.Create(Self) do
+ begin
+ Parent := Page;
+ Checked[Items.Add('Alan Chong')] := Random(4) = 1;
+ Checked[Items.Add('Andreas Hausladen')] := Random(4) = 1;
+ Checked[Items.Add('André Snepvangers')] := Random(4) = 1;
+ Checked[Items.Add('Michael Beck')] := Random(4) = 1;
+ Checked[Items.Add('Leroy Casterline')] := Random(4) = 1;
+ Checked[Items.Add('Chris Latta')] := Random(4) = 1;
+ Checked[Items.Add('Erwin Molendijk')] := Random(4) = 1;
+ Checked[Items.Add('James Lan')] := Random(4) = 1;
+ Checked[Items.Add('Ignacio Vazquez')] := Random(4) = 1;
+ Checked[Items.Add('Marcel Bestebroer')] := Random(4) = 1;
+ Checked[Items.Add('Jens Fudickar')] := Random(4) = 1;
+ Checked[Items.Add('Jose Perez')] := Random(4) = 1;
+ Checked[Items.Add('Marc Hoffmann')] := Random(4) = 1;
+ Checked[Items.Add('Fernando Silva')] := Random(4) = 1;
+ Checked[Items.Add('Robert Marquardt')] := Random(4) = 1;
+ Checked[Items.Add('Matthias Thoma')] := Random(4) = 1;
+ Checked[Items.Add('Olivier Sannier')] := Random(4) = 1;
+ Checked[Items.Add('Oliver Giesen')] := Random(4) = 1;
+ Checked[Items.Add('Dmitry Osinovsky')] := Random(4) = 1;
+ Checked[Items.Add('Peter Thornqvist')] := Random(4) = 1;
+ Checked[Items.Add('henri gourvest')] := Random(4) = 1;
+ Checked[Items.Add('Rob den Braasem')] := Random(4) = 1;
+ Checked[Items.Add('Remko Bonte')] := Random(4) = 1;
+ Checked[Items.Add('Christian Vogt')] := Random(4) = 1;
+ Checked[Items.Add('Warren Postma')] := Random(4) = 1;
+ Top := 1500;
+ Align := alClient;
+ end;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := 'C&ontacts';
+ Page.ImageIndex := 2;
+ Page.PageList := NP;
+
+ with TListBox.Create(Self) do
+ begin
+ Parent := Page;
+ Align := alClient;
+ Items.Add('Alan Chong');
+ Items.Add('Andreas Hausladen');
+ Items.Add('André Snepvangers');
+ Items.Add('Michael Beck');
+ Items.Add('Leroy Casterline');
+ Items.Add('Chris Latta');
+ Items.Add('Erwin Molendijk');
+ Items.Add('James Lan');
+ Items.Add('Ignacio Vazquez');
+ Items.Add('Marcel Bestebroer');
+ Items.Add('Jens Fudickar');
+ Items.Add('Jose Perez');
+ Items.Add('Marc Hoffmann');
+ Items.Add('Fernando Silva');
+ Items.Add('Robert Marquardt');
+ Items.Add('Matthias Thoma');
+ Items.Add('Olivier Sannier');
+ Items.Add('Oliver Giesen');
+ Items.Add('Dmitry Osinovsky');
+ Items.Add('Peter Thornqvist');
+ Items.Add('henri gourvest');
+ Items.Add('Rob den Braasem');
+ Items.Add('Remko Bonte');
+ Items.Add('Christian Vogt');
+ Items.Add('Warren Postma');
+ end;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := '&Tasks';
+ Page.ImageIndex := 3;
+ Page.PageList := NP;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := '&Notes';
+ Page.ImageIndex := 4;
+ Page.PageList := NP;
+
+ Page := TJvNavPanelPage.Create(Self);
+ Page.Caption := '&Folder List';
+ Page.ImageIndex := 5;
+ Page.PageList := NP;
+
+ { with TJvOutlookSplitter.Create(Self) do
+ begin
+ Align := alNone;
+ Parent := Self;
+ Left := NP.Width + 100;
+ Align := alLeft;
+ Width := 7;
+ Cursor := crSizeWE;
+ end;
+ }
+ NP.ActivePageIndex := 0;
+
+ NT := TJvNavPaneToolPanel.Create(Self);
+ NT.DragKind := dkDock;
+ // NT.DragMode := dmAutomatic;
+ NT.Parent := Self;
+ NT.Align := alClient;
+ NT.Caption := 'Sample Tool Panel';
+ NT.StyleManager := JvNavPaneStyleManager1;
+ NT.Images := ToolImages;
+ NT.DropDownMenu := PopupMenu1;
+ for i := 0 to ToolImages.Count - 1 do
+ NT.Buttons.Add.ImageIndex := i;
+ NT.OnButtonClick := @DoToolButtonClick;
+ NT.OnMouseDown := @DoToolMouseDown;
+ NT.OnMouseMove := @DoToolMouseMove;
+ NT.OnEndDock := @DoToolEndDock;
+
+ NT.CloseButton := false;
+ NT.OnClose := @DoToolPanelClose;
+ // now, set the real start theme:
+ JvNavPaneStyleManager1.Theme := nptStandard;
+
+ // SESS
+ NT.ShowHint := true;
+ NT.Hint := 'Hello world !!';
+
+end;
+
+procedure TJvNavPaneDemoMainFrm.Dontallowresize1Click(Sender: TObject);
+begin
+ Dontallowresize1.Checked := not Dontallowresize1.Checked;
+ NP.Resizable := not Dontallowresize1.Checked;
+end;
+
+procedure TJvNavPaneDemoMainFrm.HideAll1Click(Sender: TObject);
+begin
+ NP.MaximizedCount := 0;
+end;
+
+procedure TJvNavPaneDemoMainFrm.ShowAll1Click(Sender: TObject);
+begin
+ NP.MaximizedCount := NP.PageCount;
+end;
+
+procedure TJvNavPaneDemoMainFrm.ChangeFont1Click(Sender: TObject);
+var
+ FD: TFontDialog;
+begin
+ FD := TFontDialog.Create(nil);
+ try
+ FD.Font := NP.NavPanelFont;
+ if FD.Execute then
+ NP.NavPanelFont := FD.Font;
+ finally
+ FD.Free;
+ end;
+end;
+
+procedure TJvNavPaneDemoMainFrm.SchemaClick(Sender: TObject);
+begin
+ JvNavPaneStyleManager1.Theme := TJvNavPanelTheme((Sender as TMenuItem).Tag);
+ (Sender as TMenuItem).Checked := true;
+end;
+
+procedure TJvNavPaneDemoMainFrm.DoToolPanelClose(Sender: TObject);
+begin
+ if MessageDlg('Close this window?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
+ begin
+ JvOutlookSplitter1.Visible := False;
+ NT.Visible := False;
+ NP.Align := alClient;
+ end;
+end;
+
+procedure TJvNavPaneDemoMainFrm.PopupMenu1Popup(Sender: TObject);
+begin
+ ShowToolPanel1.Enabled := not NT.Visible;
+ ShowCloseButton1.Checked := NT.CloseButton;
+end;
+
+procedure TJvNavPaneDemoMainFrm.ShowToolPanel1Click(Sender: TObject);
+begin
+ NP.Align := alLeft;
+ NP.Width := 220;
+ JvOutlookSplitter1.Visible := True;
+ JvOutlookSplitter1.Left := 225;
+ NT.Visible := True;
+end;
+
+procedure TJvNavPaneDemoMainFrm.DoToolButtonClick(Sender: TObject; Index: integer);
+begin
+ ShowMessageFmt('You clicked button %d ', [Index]);
+end;
+
+procedure TJvNavPaneDemoMainFrm.ShowCloseButton1Click(Sender: TObject);
+begin
+ ShowCloseButton1.Checked := not ShowCloseButton1.Checked;
+ NT.CloseButton := ShowCloseButton1.Checked;
+end;
+
+type
+ THackForm = class(TCustomForm);
+
+procedure TJvNavPaneDemoMainFrm.DoToolEndDock(Sender, Target: TObject; X, Y: Integer);
+begin
+ if (Target is TCustomForm) and (Target <> Self) then
+ begin
+ TCustomForm(Target).BorderStyle := bsSizeable;
+ //TODO:
+ //SetWindowLong(TCustomForm(Target).Handle, GWL_STYLE, GetWindowLong(TCustomForm(Target).Handle, GWL_STYLE) and not WS_CAPTION);
+ TCustomForm(Target).Width := TCustomForm(Target).Width + 1;
+ TCustomForm(Target).Width := TCustomForm(Target).Width - 1;
+ end
+ else
+ NT.Align := alClient;
+end;
+
+procedure TJvNavPaneDemoMainFrm.DoToolMouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: integer);
+begin
+ if phtGrabber in NT.GetHitTestInfoAt(X, Y) then
+ NT.BeginDrag(false);
+end;
+
+procedure TJvNavPaneDemoMainFrm.DoToolMouseMove(Sender: TObject; Shift: TShiftState; X,
+ Y: integer);
+begin
+ if phtGrabber in NT.GetHitTestInfoAt(X, Y) then
+ NT.Cursor := crSize
+ else
+ NT.Cursor := crDefault;
+end;
+
+procedure TJvNavPaneDemoMainFrm.BackgroundImage1Click(Sender: TObject);
+begin
+ if OpenPictureDialog1.Execute then
+ begin
+ NP.Background.Picture.LoadFromFile(OpenPictureDialog1.Filename);
+ NP.Background.Tile := True;
+ NT.Background.Picture.LoadFromFile(OpenPictureDialog1.Filename);
+ NT.Background.Tile := True;
+ end;
+end;
+
+initialization
+ {$i JvNavPaneDemoMainForm.lrs}
+ {$i JvNavPaneDemoMainForm.lrs}
+ {$i JvNavPaneDemoMainForm.lrs}
+
+end.
+
diff --git a/components/jvcllaz/examples/JvNavigationPane/LargeImages.bmp b/components/jvcllaz/examples/JvNavigationPane/LargeImages.bmp
new file mode 100644
index 000000000..986df990d
Binary files /dev/null and b/components/jvcllaz/examples/JvNavigationPane/LargeImages.bmp differ
diff --git a/components/jvcllaz/examples/JvNavigationPane/SmallImages.bmp b/components/jvcllaz/examples/JvNavigationPane/SmallImages.bmp
new file mode 100644
index 000000000..9eef73e37
Binary files /dev/null and b/components/jvcllaz/examples/JvNavigationPane/SmallImages.bmp differ
diff --git a/components/jvcllaz/packages/JvCoreLaz.lpk b/components/jvcllaz/packages/JvCoreLaz.lpk
new file mode 100644
index 000000000..bf0c366fd
--- /dev/null
+++ b/components/jvcllaz/packages/JvCoreLaz.lpk
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/packages/JvCoreLaz.pas b/components/jvcllaz/packages/JvCoreLaz.pas
new file mode 100644
index 000000000..09b63fc3f
--- /dev/null
+++ b/components/jvcllaz/packages/JvCoreLaz.pas
@@ -0,0 +1,15 @@
+{ This file was automatically created by Lazarus. Do not edit!
+This source is only used to compile and install the package.
+ }
+
+unit JvCoreLaz;
+
+interface
+
+uses
+ JvTypes, JvComponent, JvConsts, JvExControls, JvExExtCtrls, JvJCLUtils,
+ JvJVCLUtils;
+
+implementation
+
+end.
diff --git a/components/jvcllaz/packages/JvXPBarLaz.lpk b/components/jvcllaz/packages/JvXPBarLaz.lpk
new file mode 100644
index 000000000..ef80e5236
--- /dev/null
+++ b/components/jvcllaz/packages/JvXPBarLaz.lpk
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jvcllaz/packages/JvXPBarLaz.lrs b/components/jvcllaz/packages/JvXPBarLaz.lrs
new file mode 100644
index 000000000..5bb5082e8
--- /dev/null
+++ b/components/jvcllaz/packages/JvXPBarLaz.lrs
@@ -0,0 +1,79 @@
+LazarusResources.Add('TJVXPBAR','BMP',[
+ 'BM'#246#6#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#24#0#0#0#0#0
+ +#192#6#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#192#0#224#0#224#192#0#224#192
+ +#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224
+ +#192#0#224#192#0#224#192#0#224#160#0#224#160#0#224#160#255#255#0#255#0#0#255
+ +#0#0#255#0#0#255#0#0#255#0#0#255#0#0#255#0#0#0#224#192#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#224#192#0#0#0#0#0#0#0#0#0#0#224#192#0#224#160#0
+ +#0#0#255#255#0#255#0#0#255#0#0#0#255#255#0#255#255#255#0#0#255#0#0#255#0#0#0
+ +#224#192#192#192#192#192#192#192#192#192#192#192#192#192#192#192#192#192#192
+ +#192#192#192#192#192#192#192#0#224#192#0#0#0#0#224#192#0#224#192#0#0#0#0#224
+ +#192#0#224#160#255#255#0#255#0#0#0#255#255#255#0#0#255#0#0#0#255#255#255#0#0
+ +#255#0#0#0#224#224#128#128#128#128#128#128#128#128#128#128#128#128#128#128
+ +#128#128#128#128#128#128#128#128#128#128#0#224#192#0#0#0#0#224#192#0#224#192
+ +#0#0#0#0#224#192#0#224#192#255#255#0#255#0#0#0#255#255#255#0#0#255#0#0#0#255
+ +#255#255#0#0#255#0#0#0#224#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#224#192#0#0#0#0#0#0#0#0#0#0#224#192#0#224#192#0#0#0#255#255#0#255#0#0
+ +#255#0#0#255#0#0#255#0#0#0#255#255#255#0#0#255#0#0#0#224#224#0#224#224#0#224
+ +#224#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0
+ +#224#192#0#224#192#0#224#192#0#224#192#0#224#192#0#224#192#255#255#0#255#0#0
+ +#255#0#0#255#0#0#255#0#0#0#255#255#255#0#0#255#0#0#0#224#224#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#255#255#0#255#0#0#255#0#0#255#0#0#255#0#0#0#255#255#255#0#0#255#0#0#0#224
+ +#224#0#0#0#255#255#255#128#128#128#128#128#128#128#128#128#128#128#128#128
+ +#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128
+ +#128#128#128#128#128#128#128#255#255#0#255#0#0#255#0#0#255#0#0#255#0#0#255#0
+ +#0#255#0#0#255#0#0#0#224#224#0#0#0#255#255#255#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#0#224#224#0#0#0#255
+ +#255#255#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#128
+ +#128#128#0#0#0#0#224#160#0#224#224#0#0#0#255#255#255#247#223#214#247#223#214
+ +#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#128#128#128#0#0#0#0#224#160#0#224
+ +#224#0#0#0#255#255#255#247#223#214#247#223#214#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#128#128#128#0#0#0#0#224#160#0#224#224#0#0#0#255#255#255#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#128#128#128#0#0#0#0
+ +#224#192#0#224#224#0#0#0#255#255#255#247#223#214#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#247#223#214#128#128#128#0#0#0#0#224#192#0#224#224#0#0#0#255#255
+ +#255#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#128#128
+ +#128#0#0#0#0#224#192#0#224#224#0#0#0#255#255#255#247#223#214#247#223#214#247
+ +#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223
+ +#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214#247#223#214
+ +#247#223#214#247#223#214#247#223#214#128#128#128#0#0#0#0#224#192#0#224#224#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#224#192#0#224#224#0
+ +#0#0#255#255#255#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228
+ +#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228
+ +#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#128#128#128#0
+ +#0#0#0#224#192#0#224#224#0#0#0#255#255#255#228#167'~'#228#167'~'#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#0#0#0#228#167'~'#228
+ +#167'~'#128#128#128#0#0#0#0#224#192#0#224#224#0#0#0#255#255#255#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#0#0#0#0#0
+ ,#0#0#0#0#228#167'~'#128#128#128#0#0#0#0#224#192#0#224#224#0#0#0#255#255#255
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'#228#167'~'
+ +#228#167'~'#228#167'~'#228#167'~'#228#167'~'#128#128#128#0#0#0#0#224#192#0
+ +#192#224#0#224#224#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+ +#255#255#255#0#0#0#0#224#192#0#224#192#0#192#224#0#192#224#0#224#224#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#224#192#0#224#192#0#224#192#0#192#224#0#192#224#0
+ +#192#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224
+ +#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224#224#0#224#224#0
+ +#224#224#0#224#224#0#224#224#0#224#224#0#224#192#0#224#192#0#224#192
+]);
diff --git a/components/jvcllaz/packages/JvXPBarLaz.pas b/components/jvcllaz/packages/JvXPBarLaz.pas
new file mode 100644
index 000000000..9fb9e07bb
--- /dev/null
+++ b/components/jvcllaz/packages/JvXPBarLaz.pas
@@ -0,0 +1,21 @@
+{ This file was automatically created by Lazarus. Do not edit!
+This source is only used to compile and install the package.
+ }
+
+unit JvXPBarLaz;
+
+interface
+
+uses
+ JvXPCoreUtils, JvXPBar, JvXPCore, JvXPBarReg, LazarusPackageIntf;
+
+implementation
+
+procedure Register;
+begin
+ RegisterUnit('JvXPBarReg', @JvXPBarReg.Register);
+end;
+
+initialization
+ RegisterPackage('JvXPBarLaz', @Register);
+end.
diff --git a/components/jvcllaz/packages/JvXPBarReg.pp b/components/jvcllaz/packages/JvXPBarReg.pp
new file mode 100644
index 000000000..6b9df86b0
--- /dev/null
+++ b/components/jvcllaz/packages/JvXPBarReg.pp
@@ -0,0 +1,24 @@
+unit JvXPBarReg;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, LResources, SysUtils;
+
+procedure Register;
+
+implementation
+uses JvXPBar;
+
+procedure Register;
+begin
+ RegisterComponents('JvXP',[TJvXPBar]);
+end;
+
+initialization
+ {$I JvXPBarLaz.lrs}
+
+end.
+
diff --git a/components/jvcllaz/resource/JvXPBar.lrs b/components/jvcllaz/resource/JvXPBar.lrs
new file mode 100644
index 000000000..99599805c
--- /dev/null
+++ b/components/jvcllaz/resource/JvXPBar.lrs
@@ -0,0 +1,254 @@
+LazarusResources.Add('JVXPCUSTOMWINXPBARCOLLAPSE0','BMP',[
+ 'BM&'#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#24#0#0#0#0#0#240#3
+ +#0#0#195#14#0#0#195#14#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0
+ +#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#165'8'#0#165'8'#0#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0
+ +#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0
+]);
+LazarusResources.Add('JVXPCUSTOMWINXPBARCOLLAPSE1','BMP',[
+ 'BM&'#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#24#0#0#0#0#0#240#3
+ +#0#0#195#14#0#0#195#14#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0
+ +#255#255#0#255#165'8'#0#165'8'#1#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#165'8'#0#165'8'#0#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0
+ +#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0
+]);
+LazarusResources.Add('JVXPCUSTOMWINXPBARCOLLAPSE2','BMP',[
+ 'BM&'#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#24#0#0#0#0#0#240#3
+ +#0#0#195#14#0#0#195#14#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#165'8'#0#165
+ +'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255
+ +#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165
+ +'8'#0#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0#255#165'8'#0#165'8'#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165
+ +'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#165'8'#0#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0
+]);
+LazarusResources.Add('JVXPCUSTOMWINXPBAREXPAND0','BMP',[
+ 'BM&'#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#24#0#0#0#0#0#240#3
+ +#0#0#195#14#0#0#195#14#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#168'6'#8#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#165'8'#0#165
+ +'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#165'8'#0#165'8'#0#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#173'3'#24#166'8'#2#255#0#255#255#0#255#255#0#255#165'8'
+ +#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#166'7'#3#165'8'#0#255#0#255#165
+ +'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#0#182
+ +'./'#255#0#255#255#0#255#255#0#255#169'6'#11#169'5'#12#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#0#0
+]);
+LazarusResources.Add('JVXPCUSTOMWINXPBAREXPAND1','BMP',[
+ 'BM&'#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#24#0#0#0#0#0#240#3
+ +#0#0#195#14#0#0#195#14#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#167'6'#7#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#166'8'#2#165'8'#0#165
+ +'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#165'8'#0#165'8'#0#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#165'8'#0
+ +#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#165'8'#0#165'8'#0#165'8'#0#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#1#165'8'#1#255#0#255#165
+ +'8'#0#165'8'#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#165'8'#1#171
+ +'4'#18#255#0#255#255#0#255#255#0#255#166'7'#4#165'8'#1#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0
+ +#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
+ +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#0#0#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0#255#0#255
+ +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
+ +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
+ +#255#0#255#255#0#255#0#0
+]);
+LazarusResources.Add('JVXPCUSTOMWINXPBAREXPAND2','BMP',[
+ 'BM'#174#1#0#0#0#0#0#0'F'#0#0#0'('#0#0#0#18#0#0#0#18#0#0#0#1#0#8#0#0#0#0#0'h'
+ +#1#0#0#195#14#0#0#195#14#0#0#4#0#0#0#4#0#0#0#255#0#255#0#165'8'#0#0#255#255
+ +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#1#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#1#1#0#1#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#1#0#0#0#1#1#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#1#1#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#1#1#0#1#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#1#0#0#0#1#1#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+]);
diff --git a/components/jvcllaz/run/JvButton.pas b/components/jvcllaz/run/JvButton.pas
new file mode 100644
index 000000000..7f14b12ec
--- /dev/null
+++ b/components/jvcllaz/run/JvButton.pas
@@ -0,0 +1,923 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvButton.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvButton.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvButton;
+
+interface
+
+uses
+ Classes, Controls, Graphics, JvComponent, JvConsts, JvTypes, LMessages, Menus;
+
+type
+ TJvButtonMouseState = (bsMouseInside, bsMouseDown);
+ TJvButtonMouseStates = set of TJvButtonMouseState;
+
+ TJvCustomGraphicButton = class(TJvGraphicControl)
+ private
+ FStates: TJvButtonMouseStates;
+ FBuffer: TBitmap;
+ FFlat: Boolean;
+ FDropDownMenu: TPopupMenu;
+ FDown: Boolean;
+ FForceSameSize: Boolean;
+ FAllowAllUp: Boolean;
+ FGroupIndex: Integer;
+ FHotTrack: Boolean;
+ FHotFont: TFont;
+ FHotTrackFontOptions: TJvTrackFontOptions;
+ FOnDropDownMenu: TContextPopupEvent;
+ FDropArrow: Boolean;
+ FOnDropDownClose: TNotifyEvent;
+ function GetPattern: TBitmap;
+ procedure SetFlat(const Value: Boolean);
+ procedure SetDown(Value: Boolean);
+ procedure CMButtonPressed(var Msg: TCMButtonPressed); message CM_JVBUTTONPRESSED;
+ procedure CMForceSize(var Msg: TCMForceSize); message CM_FORCESIZE;
+ procedure CMSysColorChange(var Msg: TLMessage); message CM_SYSCOLORCHANGE;
+ procedure SetForceSameSize(const Value: Boolean);
+ procedure SetAllowAllUp(const Value: Boolean);
+ procedure SetGroupIndex(const Value: Integer);
+ procedure SetHotFont(const Value: TFont);
+ procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
+ procedure SetDropArrow(const Value: Boolean);
+ procedure SetDropDownMenu(const Value: TPopupMenu);
+ protected
+ procedure ButtonPressed(Sender: TJvCustomGraphicButton; AGroupIndex: Integer); virtual;
+ procedure ForceSize(Sender: TControl; AWidth, AHeight: Integer);
+ function DoDropDownMenu(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
+ procedure DropDownClose;
+ procedure UpdateExclusive;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+ procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
+ procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+ procedure MouseEnter(Control: TControl); override;
+ procedure MouseLeave(Control: TControl); override;
+ procedure Paint; override;
+ procedure PaintButton(ACanvas: TCanvas); virtual;
+ procedure PaintFrame(ACanvas: TCanvas); virtual;
+ function InsideBtn(X, Y: Integer): Boolean; virtual;
+ function WantKey(Key: Integer; Shift: TShiftState;
+ const KeyText: WideString): Boolean; override;
+ procedure EnabledChanged; override;
+ procedure FontChanged; override;
+ procedure RepaintBackground; virtual;
+ procedure TextChanged; override;
+ property AllowAllUp: Boolean read FAllowAllUp write SetAllowAllUp default False;
+ property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
+ property MouseStates: TJvButtonMouseStates read FStates write FStates default [];
+ property ForceSameSize: Boolean read FForceSameSize write SetForceSameSize default False;
+ property Pattern: TBitmap read GetPattern;
+ property Flat: Boolean read FFlat write SetFlat default False;
+ property HotTrack: Boolean read FHotTrack write FHotTrack default False;
+ property HotTrackFont: TFont read FHotFont write SetHotFont;
+ property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions default
+ DefaultTrackFontOptions;
+ property Down: Boolean read FDown write SetDown default False;
+ property DropDownMenu: TPopupMenu read FDropDownMenu write SetDropDownMenu;
+ property DropArrow: Boolean read FDropArrow write SetDropArrow default False;
+ property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
+ property OnDropDownClose: TNotifyEvent read FOnDropDownClose write FOnDropDownClose;
+ public
+ procedure Click; override;
+ procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure DrawDropArrow(ACanvas: TCanvas; ArrowRect: TRect); virtual;
+ end;
+
+(******************** NOT CONVERTED
+ TJvCustomButton = class(TJvExButton)
+ private
+ FDropDownMenu: TPopupMenu;
+ FHotTrack: Boolean;
+ FHotFont: TFont;
+ FFontSave: TFont;
+ FWordWrap: Boolean;
+ FForceSameSize: Boolean;
+ FHotTrackFontOptions: TJvTrackFontOptions;
+ FOnDropDownMenu: TContextPopupEvent;
+ FDropArrow: Boolean;
+ procedure SetHotFont(const Value: TFont);
+ procedure SetWordWrap(const Value: Boolean);
+ procedure SetForceSameSize(const Value: Boolean);
+ procedure CMForceSize(var Msg: TCMForceSize); message CM_FORCESIZE;
+ procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
+ procedure SetDropArrow(const Value: Boolean);
+ procedure SetDropDownMenu(const Value: TPopupMenu);
+ protected
+ function DoDropDownMenu(X, Y: Integer): Boolean; virtual;
+ procedure ForceSize(Sender: TControl; AWidth, AHeight: Integer);
+ procedure MouseEnter(Control: TControl); override;
+ procedure MouseLeave(Control: TControl); override;
+ procedure FontChanged; override;
+ procedure CreateParams(var Params: TCreateParams); override;
+ function GetRealCaption: string; dynamic;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ property WordWrap: Boolean read FWordWrap write SetWordWrap default True;
+ property ForceSameSize: Boolean read FForceSameSize write SetForceSameSize default False;
+ property DropArrow: Boolean read FDropArrow write SetDropArrow default False;
+ property DropDownMenu: TPopupMenu read FDropDownMenu write SetDropDownMenu;
+ property HotTrack: Boolean read FHotTrack write FHotTrack default False;
+ property HotTrackFont: TFont read FHotFont write SetHotFont;
+ property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions default
+ DefaultTrackFontOptions;
+ property HintColor;
+ property OnParentColorChange;
+ property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure Click;override;
+ procedure DrawDropArrow(Canvas: TCanvas; ArrowRect: TRect); virtual;
+ procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
+ end;
+
+ // TJvDropDownButton draws a DropDown button with the DropDown glyph
+ // (also themed). It ignores the properties Glyph and Flat
+ TJvDropDownButton = class(TSpeedButton)
+ protected
+ procedure Paint; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ end;
+******************** NOT CONVERTED *)
+
+implementation
+
+uses
+ Forms, JvJVCLUtils, LCLIntf, LCLType, SysUtils;
+
+(******************** NOT CONVERTED
+const
+ JvBtnLineSeparator = '|';
+******************** NOT CONVERTED *)
+
+var
+ GlobalPattern: TBitmap = nil;
+
+function CreateBrushPattern: TBitmap;
+var
+ X, Y: Integer;
+begin
+ if GlobalPattern = nil then
+ begin
+ GlobalPattern := TBitmap.Create;
+ try
+ GlobalPattern.Width := 8; { must have this size }
+ GlobalPattern.Height := 8;
+ with GlobalPattern.Canvas do
+ begin
+ Brush.Style := bsSolid;
+ Brush.Color := clBtnFace;
+ FillRect(Rect(0, 0, GlobalPattern.Width, GlobalPattern.Height));
+ for Y := 0 to 7 do
+ for X := 0 to 7 do
+ if (Y mod 2) = (X mod 2) then { toggles between even/odd pixels }
+ Pixels[X, Y] := clWhite; { on even/odd rows }
+ end;
+ except
+ FreeAndNil(GlobalPattern);
+ end;
+ end;
+ Result := GlobalPattern;
+end;
+
+//=== { TJvCustomGraphicButton } =============================================
+
+constructor TJvCustomGraphicButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ ControlStyle := ControlStyle -
+ [csOpaque, csDoubleClicks ];
+ FStates := [];
+ SetBounds(0, 0, 40, 40);
+ FBuffer := TBitmap.Create;
+ FFlat := False;
+ FDropArrow := False;
+ FForceSameSize := False;
+ FHotFont := TFont.Create;
+ FHotTrackFontOptions := DefaultTrackFontOptions;
+end;
+
+destructor TJvCustomGraphicButton.Destroy;
+begin
+ FBuffer.Free;
+ FHotFont.Free;
+ inherited Destroy;
+end;
+
+procedure TJvCustomGraphicButton.DrawDropArrow(ACanvas: TCanvas; ArrowRect: TRect);
+var
+ I: Integer;
+begin
+ if not Enabled then
+ ACanvas.Pen.Color := clInactiveCaption
+ else
+ ACanvas.Pen.Color := clWindowText;
+ for I := 0 to 3 do
+ begin
+ if ArrowRect.Left + I <= ArrowRect.Right - I then
+ begin
+ ACanvas.MoveTo(ArrowRect.Left + I, ArrowRect.Top + I);
+ ACanvas.LineTo(ArrowRect.Right - I, ArrowRect.Top + I);
+ end;
+ end;
+end;
+
+{ Handle speedkeys (Alt + key) }
+
+function TJvCustomGraphicButton.WantKey(Key: Integer; Shift: TShiftState;
+ const KeyText: WideString): Boolean;
+begin
+ Result := IsAccel(Key, Caption) and Enabled and (Shift * KeyboardShiftStates = [ssAlt]);
+ if Result then
+ Click
+ else
+ Result := inherited WantKey(Key, Shift, KeyText);
+end;
+
+procedure TJvCustomGraphicButton.EnabledChanged;
+begin
+ inherited EnabledChanged;
+ if not Enabled then
+ FStates := [];
+ RepaintBackground;
+end;
+
+procedure TJvCustomGraphicButton.MouseEnter(Control: TControl);
+begin
+ if csDesigning in ComponentState then
+ Exit;
+ if Enabled and not MouseOver then
+ begin
+ Include(FStates, bsMouseInside);
+ inherited MouseEnter(Control);
+ if Flat then
+ RepaintBackground;
+ if HotTrack then
+ Repaint;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.MouseLeave(Control: TControl);
+begin
+ if Enabled and MouseOver then
+ begin
+ Exclude(FStates, bsMouseInside);
+ inherited MouseLeave(Control);
+ if Flat then
+ RepaintBackground;
+ if HotTrack then
+ Repaint;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.Paint;
+var
+ ArrowRect: TRect;
+begin
+// FBuffer.Width := Width;
+// FBuffer.Height := Height;
+ PaintFrame(Canvas);
+ PaintButton(Canvas);
+ if DropArrow and Assigned(DropDownMenu) then
+ begin
+ ArrowRect := Rect(Width - 16, Height div 2, Width - 9, Height div 2 + 9);
+ if bsMouseDown in FStates then
+ OffsetRect(ArrowRect, 1, 1);
+ DrawDropArrow(Canvas, ArrowRect);
+ end;
+// BitBlt(Canvas.Handle, 0, 0, Width,Height, FBuffer.Canvas.Handle, 0, 0, SRCCOPY);
+end;
+
+procedure TJvCustomGraphicButton.PaintFrame(ACanvas: TCanvas);
+begin
+ // do nothing
+end;
+
+procedure TJvCustomGraphicButton.PaintButton(ACanvas: TCanvas);
+begin
+ if (bsMouseInside in FStates) and HotTrack then
+ ACanvas.Font := FHotFont
+ else
+ ACanvas.Font := Font;
+end;
+
+function TJvCustomGraphicButton.InsideBtn(X, Y: Integer): Boolean;
+begin
+ Result := PtInRect(Rect(0, 0, Width, Height), Point(X, Y));
+end;
+
+procedure TJvCustomGraphicButton.MouseDown(Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+var
+ Tmp: TPoint;
+begin
+ if not Enabled then
+ Exit;
+
+ inherited MouseDown(Button, Shift, X, Y);
+
+ if InsideBtn(X, Y) then
+ begin
+ FStates := [bsMouseDown, bsMouseInside];
+ RepaintBackground;
+ end;
+ SetCaptureControl(Self);
+ Tmp := ClientToScreen(Point(0, Height));
+ DoDropDownMenu(Button, Shift, Tmp.X, Tmp.Y);
+end;
+
+procedure TJvCustomGraphicButton.MouseMove(Shift: TShiftState;
+ X, Y: Integer);
+begin
+ inherited MouseMove(Shift, X, Y);
+ if MouseCapture then
+ begin
+ if not InsideBtn(X, Y) then
+ begin
+ if bsMouseInside in FStates then
+ begin
+ Exclude(FStates, bsMouseInside);
+ RepaintBackground;
+ end;
+ end
+ else
+ begin
+ if not (bsMouseInside in FStates) then
+ begin
+ Include(FStates, bsMouseInside);
+ RepaintBackground;
+ end;
+ end;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.MouseUp(Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+begin
+ if GetCaptureControl = Self then
+ ReleaseCapture;
+ if not Enabled then
+ Exit;
+ inherited MouseUp(Button, Shift, X, Y);
+ Exclude(FStates, bsMouseDown);
+
+ // 26.09.2007 - SESS:
+ // Update bsMouseInside flag also.
+ if not InsideBtn(X, Y) and (bsMouseInside in FStates) then
+ Exclude(FStates, bsMouseInside);
+
+ RepaintBackground;
+end;
+
+function TJvCustomGraphicButton.DoDropDownMenu(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean;
+var
+ Msg: TMsg;
+ Handled: Boolean;
+begin
+ Result := (Button = mbLeft) and (DropDownMenu <> nil);
+ if Result then
+ begin
+ DropDownMenu.PopupComponent := Self;
+ Handled := False;
+ if Assigned(FOnDropDownMenu) then
+ FOnDropDownMenu(Self, Point(X, Y), Handled);
+ if not Handled then
+ DropDownMenu.Popup(X, Y)
+ else
+ Exit;
+ { wait 'til menu is done }
+ while PeekMessage(Msg, 0, LM_MOUSEFIRST, LM_MOUSELAST, PM_REMOVE) do
+ {nothing};
+ { release button }
+ MouseUp(Button, Shift, X, Y);
+ DropDownClose;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetFlat(const Value: Boolean);
+begin
+ if FFlat <> Value then
+ begin
+ FFlat := Value;
+ if FFlat then
+ ControlStyle := ControlStyle - [csOpaque]
+ else
+ ControlStyle := ControlStyle + [csOpaque];
+ RepaintBackground;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if (Operation = opRemove) and (AComponent = DropDownMenu) then
+ DropDownMenu := nil;
+end;
+
+procedure TJvCustomGraphicButton.SetDown(Value: Boolean);
+begin
+ if GroupIndex = 0 then
+ Value := False;
+ if FDown <> Value then
+ begin
+ if FDown and not AllowAllUp then
+ Exit;
+ FDown := Value;
+ UpdateExclusive;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetForceSameSize(const Value: Boolean);
+begin
+ if FForceSameSize <> Value then
+ begin
+ FForceSameSize := Value;
+ if FForceSameSize then
+ SetBounds(Left, Top, Width, Height);
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
+var
+ Form: TCustomForm;
+ Msg: TCMForceSize;
+begin
+ inherited SetBounds(ALeft, ATop, AWidth, AHeight);
+ if ForceSameSize then
+ begin
+ Form := GetParentForm(Self);
+ if Assigned(Form) then
+ begin
+ Msg.Msg := CM_FORCESIZE;
+ Msg.Sender := Self;
+ Msg.NewSize.X := AWidth;
+ Msg.NewSize.Y := AHeight;
+ Form.Broadcast(Msg);
+ end;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.CMForceSize(var Msg: TCMForceSize);
+begin
+ with Msg do
+ ForceSize(Sender, NewSize.x, NewSize.y);
+end;
+
+function TJvCustomGraphicButton.GetPattern: TBitmap;
+begin
+ Result := CreateBrushPattern;
+end;
+
+procedure TJvCustomGraphicButton.SetAllowAllUp(const Value: Boolean);
+begin
+ if FAllowAllUp <> Value then
+ begin
+ FAllowAllUp := Value;
+ UpdateExclusive;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetGroupIndex(const Value: Integer);
+begin
+ if FGroupIndex <> Value then
+ begin
+ FGroupIndex := Value;
+ UpdateExclusive;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.UpdateExclusive;
+var
+ Msg: TCMButtonPressed;
+begin
+ if (GroupIndex <> 0) and (Parent <> nil) then
+ begin
+ Msg.Msg := CM_JVBUTTONPRESSED;
+ Msg.Index := GroupIndex;
+ Msg.Control := Self;
+ Msg.Result := 0;
+ Parent.Broadcast(Msg);
+ end;
+end;
+
+procedure TJvCustomGraphicButton.CMButtonPressed(var Msg: TCMButtonPressed);
+begin
+ ButtonPressed(TJvCustomGraphicButton(Msg.Control), Msg.Index);
+end;
+
+procedure TJvCustomGraphicButton.SetHotFont(const Value: TFont);
+begin
+ FHotFont.Assign(Value);
+end;
+
+procedure TJvCustomGraphicButton.SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
+begin
+ if FHotTrackFontOptions <> Value then
+ begin
+ FHotTrackFontOptions := Value;
+ UpdateTrackFont(HotTrackFont, Font, HotTrackFontOptions);
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetDropArrow(const Value: Boolean);
+begin
+ if FDropArrow <> Value then
+ begin
+ FDropArrow := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.SetDropDownMenu(const Value: TPopupMenu);
+begin
+ if FDropDownMenu <> Value then
+ begin
+ FDropDownMenu := Value;
+ if DropArrow then
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.CMSysColorChange(var Msg: TLMessage);
+begin
+ inherited;
+ RepaintBackground;
+end;
+
+procedure TJvCustomGraphicButton.FontChanged;
+begin
+ inherited FontChanged;
+ UpdateTrackFont(HotTrackFont, Font, HotTrackFontOptions);
+end;
+
+procedure TJvCustomGraphicButton.TextChanged;
+begin
+ inherited TextChanged;
+ RepaintBackground;
+end;
+
+procedure TJvCustomGraphicButton.Click;
+begin
+ if GroupIndex <> 0 then
+ begin
+ if AllowAllUp then
+ Down := not Down
+ else
+ Down := True;
+ end;
+ try
+ inherited Click;
+ except
+ // Mantis 3097: In case there is an exception, we ensure here that the
+ // button is not left "down", and we reraise the exception as we can't
+ // handle it and don't want to ignore it.
+ Exclude(FStates, bsMouseDown);
+ RepaintBackground;
+ raise;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.ButtonPressed(Sender: TJvCustomGraphicButton;
+ AGroupIndex: Integer);
+begin
+ if AGroupIndex = GroupIndex then
+ if Sender <> Self then
+ begin
+ if Sender.Down and Down then
+ begin
+ FDown := False;
+ Exclude(FStates, bsMouseDown);
+ RepaintBackground;
+ end;
+ FAllowAllUp := Sender.AllowAllUp;
+ end;
+end;
+
+procedure TJvCustomGraphicButton.ForceSize(Sender: TControl; AWidth, AHeight: Integer);
+begin
+ if Sender <> Self then
+ inherited SetBounds(Left, Top, AWidth, AHeight);
+end;
+
+(******************** NOT CONVERTED
+//=== { TJvCustomButton } ====================================================
+
+constructor TJvCustomButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FDropArrow := False;
+ FHotTrack := False;
+ FHotFont := TFont.Create;
+ FFontSave := TFont.Create;
+ // ControlStyle := ControlStyle + [csAcceptsControls];
+ FWordWrap := True;
+ FForceSameSize := False;
+ FHotTrackFontOptions := DefaultTrackFontOptions;
+end;
+
+destructor TJvCustomButton.Destroy;
+begin
+ FHotFont.Free;
+ FFontSave.Free;
+ inherited Destroy;
+end;
+
+procedure TJvCustomButton.Click;
+var
+ Tmp: TPoint;
+begin
+ // Call ClientToScreen before the inherited Click as the OnClick handler might
+ // reset the parent, which is needed by ClientToScreen.
+ Tmp := ClientToScreen(Point(0, Height));
+ inherited Click;
+ DoDropDownMenu(Tmp.X, Tmp.Y);
+end;
+
+procedure TJvCustomButton.DrawDropArrow(Canvas: TCanvas; ArrowRect: TRect);
+var
+ I: Integer;
+begin
+ if not Enabled then
+ Canvas.Pen.Color := clInactiveCaption
+ else
+ Canvas.Pen.Color := clWindowText;
+ for I := 0 to (ArrowRect.Bottom - ArrowRect.Top) do
+ begin
+ if ArrowRect.Left + I <= ArrowRect.Right - I then
+ begin
+ Canvas.MoveTo(ArrowRect.Left + I, ArrowRect.Top + I);
+ Canvas.LineTo(ArrowRect.Right - I, ArrowRect.Top + I);
+ end;
+ end;
+end;
+
+procedure TJvCustomButton.CreateParams(var Params: TCreateParams);
+begin
+ inherited CreateParams(Params);
+ Params.Style := Params.Style or BS_MULTILINE;
+end;
+
+procedure TJvCustomButton.SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
+begin
+ if FHotTrackFontOptions <> Value then
+ begin
+ FHotTrackFontOptions := Value;
+ UpdateTrackFont(HotTrackFont, Font, HotTrackFontOptions);
+ end;
+end;
+
+procedure TJvCustomButton.SetDropArrow(const Value: Boolean);
+begin
+ if FDropArrow <> Value then
+ begin
+ FDropArrow := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomButton.SetHotFont(const Value: TFont);
+begin
+ FHotFont.Assign(Value);
+end;
+
+procedure TJvCustomButton.SetDropDownMenu(const Value: TPopupMenu);
+begin
+ if FDropDownMenu <> Value then
+ begin
+ FDropDownMenu := Value;
+ if DropArrow then
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomButton.MouseEnter(Control: TControl);
+begin
+ if not MouseOver then
+ begin
+ if FHotTrack then
+ begin
+ FFontSave.Assign(Font);
+ Font.Assign(FHotFont);
+ end;
+ inherited MouseEnter(Control);
+ end;
+end;
+
+procedure TJvCustomButton.MouseLeave(Control: TControl);
+begin
+ if MouseOver then
+ begin
+ if FHotTrack then
+ Font.Assign(FFontSave);
+ inherited MouseLeave(Control);
+ end;
+end;
+
+procedure TJvCustomButton.FontChanged;
+begin
+ inherited FontChanged;
+ UpdateTrackFont(HotTrackFont, Font, HotTrackFontOptions);
+end;
+
+function TJvCustomButton.GetRealCaption: string;
+begin
+ if WordWrap then
+ Result := StringReplace(Caption, JvBtnLineSeparator, Lf, [rfReplaceAll])
+ else
+ Result := Caption;
+end;
+
+procedure TJvCustomButton.SetWordWrap(const Value: Boolean);
+begin
+ if FWordWrap <> Value then
+ begin
+ FWordWrap := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomButton.SetForceSameSize(const Value: Boolean);
+begin
+ if FForceSameSize <> Value then
+ begin
+ FForceSameSize := Value;
+ if FForceSameSize then
+ SetBounds(Left, Top, Width, Height);
+ end;
+end;
+
+procedure TJvCustomButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
+var
+ Form: TCustomForm;
+ Msg: TCMForceSize;
+begin
+ inherited SetBounds(ALeft, ATop, AWidth, AHeight);
+ if ForceSameSize then
+ begin
+ Form := GetParentForm(Self);
+ if Assigned(Form) then
+ begin
+ Msg.Msg := CM_FORCESIZE;
+ Msg.Sender := Self;
+ Msg.NewSize.X := AWidth;
+ Msg.NewSize.Y := AHeight;
+ Form.Broadcast(Msg);
+ end;
+ end;
+end;
+
+procedure TJvCustomButton.CMForceSize(var Msg: TCMForceSize);
+begin
+ with Msg do
+ ForceSize(Sender, NewSize.x, NewSize.y);
+end;
+
+procedure TJvCustomButton.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if (Operation = opRemove) and (AComponent = FDropDownMenu) then
+ DropDownMenu := nil;
+end;
+******************** NOT CONVERTED *)
+
+procedure TJvCustomGraphicButton.RepaintBackground;
+var
+ R: TRect;
+begin
+ if (Parent <> nil) and Parent.HandleAllocated then
+ begin
+ R := BoundsRect;
+ InvalidateRect(Parent.Handle, @R, True);
+ end;
+ Repaint;
+end;
+
+(******************** NOT CONVERTED
+procedure TJvCustomButton.ForceSize(Sender: TControl; AWidth, AHeight: Integer);
+begin
+ if Sender <> Self then
+ inherited SetBounds(Left, Top, AWidth, AHeight);
+end;
+
+function TJvCustomButton.DoDropDownMenu(X, Y: Integer): Boolean;
+var
+ Msg: TMsg;
+ Handled: Boolean;
+begin
+ Result := (DropDownMenu <> nil);
+ if Result then
+ begin
+ DropDownMenu.PopupComponent := Self;
+ case DropDownMenu.Alignment of
+ paRight:
+ Inc(X, Width);
+ paCenter:
+ Inc(X, Width div 2);
+ end;
+ Handled := False;
+ if Assigned(FOnDropDownMenu) then
+ FOnDropDownMenu(Self, Point(X, Y), Handled);
+ if not Handled then
+ DropDownMenu.Popup(X, Y)
+ else
+ Exit;
+ { wait 'til menu is done }
+ while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do
+ {nothing};
+ end;
+end;
+
+//=== { TJvDropDownButton } ==================================================
+
+constructor TJvDropDownButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ Width := 16;
+ Height := 16;
+end;
+
+procedure TJvDropDownButton.Paint;
+var
+ PaintRect: TRect;
+ DrawFlags: Integer;
+ DC: HDC;
+ Bmp: TBitmap;
+begin
+ // adjust FState and FDragging
+ DC := Canvas.Handle;
+ Bmp := TBitmap.Create;
+ try
+ Bmp.Width := 1;
+ Bmp.Height := 1;
+ Canvas.Handle := Bmp.Canvas.Handle;
+ try
+ inherited Paint;
+ finally
+ Canvas.Handle := DC;
+ end;
+ finally
+ Bmp.Free;
+ end;
+
+ PaintRect := Rect(0, 0, Width, Height);
+ DrawFlags := DFCS_SCROLLCOMBOBOX or DFCS_ADJUSTRECT;
+ if FState in [bsDown, bsExclusive] then
+ DrawFlags := DrawFlags or DFCS_PUSHED;
+
+ {$IFDEF JVCLThemesEnabled}
+ if ThemeServices.ThemesEnabled then
+ DrawThemedFrameControl(Self, Canvas.Handle, PaintRect, DFC_SCROLL, DrawFlags)
+ else
+ {$ENDIF JVCLThemesEnabled}
+ begin
+ DrawFrameControl(Canvas.Handle, PaintRect, DFC_SCROLL, DrawFlags);
+
+ end;
+end;
+******************** NOT CONVERTED *)
+
+procedure TJvCustomGraphicButton.DropDownClose;
+begin
+ if Assigned(FOnDropDownClose) then
+ FOnDropDownClose(Self);
+end;
+
+finalization
+ FreeAndNil(GlobalPattern);
+
+end.
+
diff --git a/components/jvcllaz/run/JvComponent.pas b/components/jvcllaz/run/JvComponent.pas
new file mode 100644
index 000000000..0bd2eddc4
--- /dev/null
+++ b/components/jvcllaz/run/JvComponent.pas
@@ -0,0 +1,267 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvComponent.PAS, released on 2000-09-22.
+
+The Initial Developer of the Original Code is Joe Doe .
+Portions created by Joe Doe are Copyright (C) 1999 Joe Doe.
+Portions created by XXXX Corp. are Copyright (C) 1998, 1999 XXXX Corp.
+All Rights Reserved.
+
+Contributor(s): -
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvComponent.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvComponent;
+
+interface
+
+uses
+ Classes, Controls, Forms, LMessages, JvExControls;
+
+type
+ TJvGraphicControl = TJvExGraphicControl;
+
+ //******************** NOT CONVERTED
+ //TJvPubGraphicControl = TJvExPubGraphicControl;
+
+ TJvCustomControl = TJvExCustomControl;
+
+ //******************** NOT CONVERTED
+ //TJvWinControl = TJvExWinControl;
+
+(******************** NOT CONVERTED
+ TJvForm = class(TJvExForm)
+ private
+ FIsFocusable: Boolean;
+ procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
+ procedure WMMouseActivate(var Msg: TMessage); message WM_MOUSEACTIVATE;
+ protected
+ public
+ constructor Create(AOwner: TComponent); override;
+ constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
+ {$IFDEF USE_DXGETTEXT}
+ procedure RefreshTranslation; virtual;
+ {$ENDIF USE_DXGETTEXT}
+
+ function ShowModal: Integer; override;
+ { ShowNoActivate() shows the form but does not activate it. }
+ procedure ShowNoActivate(CallActivate: Boolean = False);
+ published
+ property IsFocusable: Boolean read FIsFocusable write FIsFocusable default True;
+ end;
+
+//=== { TJvPopupListBox } ====================================================
+
+type
+ TJvPopupListBox = class(TJvExCustomListBox)
+ private
+ FSearchText: string;
+ FSearchTickCount: Longint;
+ protected
+ procedure CreateParams(var Params: TCreateParams); override;
+ procedure CreateWnd; override;
+ procedure KeyPress(var Key: Char); override;
+ end;
+******************** NOT CONVERTED *)
+
+implementation
+
+(******************** NOT CONVERTED
+{$IFDEF COMPILER6_UP}
+uses
+ RTLConsts;
+{$ELSE}
+uses
+ Consts;
+{$ENDIF COMPILER6_UP}
+
+//=== { TJvForm } ============================================================
+
+constructor TJvForm.Create(AOwner: TComponent);
+begin
+// inherited Create(AOwner);
+ {$IFDEF CLR}
+ GlobalNameSpace.AcquireWriterLock(MaxInt);
+ {$ELSE}
+ GlobalNameSpace.BeginWrite;
+ {$ENDIF CLR}
+ try
+ CreateNew(AOwner, 0);
+ if (ClassType <> TJvForm) and not (csDesigning in ComponentState) then
+ begin
+ Include(FFormState, fsCreating);
+ try
+ if not InitInheritedComponent(Self, TJvForm) then
+ {$IFDEF CLR}
+ raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
+ {$ELSE}
+ raise EResNotFound.CreateResFmt(@SResNotFound, [ClassName]);
+ {$ENDIF CLR}
+
+ {$IFDEF USE_DXGETTEXT}
+ TranslateComponent(Self, cDomainName);
+ {$ENDIF USE_DXGETTEXT}
+ finally
+ Exclude(FFormState, fsCreating);
+ end;
+ {$IFNDEF CLR}
+ if OldCreateOrder then
+ {$ENDIF !CLR}
+ DoCreate;
+ end;
+ finally
+ {$IFDEF CLR}
+ GlobalNameSpace.ReleaseWriterLock;
+ {$ELSE}
+ GlobalNameSpace.EndWrite;
+ {$ENDIF CLR}
+ end;
+end;
+
+constructor TJvForm.CreateNew(AOwner: TComponent; Dummy: Integer);
+begin
+ inherited CreateNew(AOwner, Dummy);
+ FIsFocusable := True;
+end;
+
+{$IFDEF USE_DXGETTEXT}
+
+procedure TJvForm.RefreshTranslation;
+begin
+ ReTranslateComponent(Self, cDomainName);
+end;
+
+{$ENDIF USE_DXGETTEXT}
+
+procedure TJvForm.CMShowingChanged(var Message: TMessage);
+var
+ NewParent: HWND;
+begin
+ if Showing and (FormStyle <> fsMDIChild) then
+ begin
+ if FormStyle = fsStayOnTop then
+ begin
+ // restore StayOnTop
+ NewParent := Application.Handle;
+ if GetWindowLong(Handle, GWL_HWNDPARENT) <> Longint(NewParent) then
+ SetWindowLong(Handle, GWL_HWNDPARENT, Longint(NewParent));
+ SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOACTIVATE);
+ end
+ else
+ begin
+ // Fixing the Window Ghosting "bug", only for forms that don't have a parent assigned (Mantis 4032)
+ if not Assigned(Parent) then
+ begin
+ NewParent := 0;
+ if Assigned(Screen.ActiveForm) and (Screen.ActiveForm <> Self) then
+ begin
+ if fsModal in Screen.ActiveForm.FormState then
+ NewParent := Screen.ActiveForm.Handle;
+ end;
+ if (NewParent = 0) and Assigned(Application.MainForm) and (Application.MainForm <> Self) then
+ NewParent := Application.MainForm.Handle;
+ if NewParent = 0 then
+ NewParent := Application.Handle;
+ if GetWindowLong(Handle, GWL_HWNDPARENT) <> Longint(NewParent) then
+ SetWindowLong(Handle, GWL_HWNDPARENT, Longint(NewParent));
+ end;
+ end;
+ end;
+ inherited;
+end;
+
+function TJvForm.ShowModal: Integer;
+var
+ Msg: TMsg;
+begin
+ while PeekMessage(Msg, 0, WM_ENABLE, WM_ENABLE, PM_REMOVE) do
+ DispatchMessage(Msg);
+ Result := inherited ShowModal;
+end;
+
+procedure TJvForm.WMMouseActivate(var Msg: TMessage);
+begin
+ if IsFocusable then
+ inherited
+ else
+ Msg.Result := MA_NOACTIVATE;
+end;
+
+procedure TJvForm.ShowNoActivate(CallActivate: Boolean);
+begin
+ if CallActivate then
+ Activate;
+ SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW or SWP_NOACTIVATE);
+ Visible := True;
+end;
+
+//=== { TJvPopupListBox } ====================================================
+
+procedure TJvPopupListBox.CreateParams(var Params: TCreateParams);
+begin
+ inherited CreateParams(Params);
+ with Params do
+ begin
+ Style := Style or WS_BORDER;
+ ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
+ AddBiDiModeExStyle(ExStyle);
+ WindowClass.Style := CS_SAVEBITS;
+ end;
+end;
+
+procedure TJvPopupListBox.CreateWnd;
+begin
+ inherited CreateWnd;
+ Windows.SetParent(Handle, 0);
+ CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
+end;
+
+procedure TJvPopupListBox.KeyPress(var Key: Char);
+var
+ TickCount: Int64;
+begin
+ case Key of
+ BackSpace, Esc:
+ FSearchText := '';
+ #32..#255:
+ begin
+ TickCount := GetTickCount;
+ if TickCount < FSearchTickCount then
+ Inc(TickCount, $100000000); // (ahuser) reduces the overflow
+ if TickCount - FSearchTickCount >= 4000 then
+ FSearchText := '';
+ FSearchTickCount := TickCount;
+ if Length(FSearchText) < 32 then
+ FSearchText := FSearchText + Key;
+ {$IFNDEF CLR}
+ SendMessage(Handle, LB_SELECTSTRING, WPARAM(-1), LPARAM(PChar(FSearchText)));
+ {$ELSE}
+ SendTextMessage(Handle, LB_SELECTSTRING, WPARAM(-1), FSearchText);
+ {$ENDIF !CLR}
+ Key := #0;
+ end;
+ end;
+ inherited KeyPress(Key);
+end;
+******************** NOT CONVERTED *)
+
+end.
diff --git a/components/jvcllaz/run/JvConsts.pas b/components/jvcllaz/run/JvConsts.pas
new file mode 100644
index 000000000..fece89303
--- /dev/null
+++ b/components/jvcllaz/run/JvConsts.pas
@@ -0,0 +1,215 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvConst.PAS, released on 2002-07-04.
+
+The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
+Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
+Copyright (c) 2001,2002 SGB Software
+All Rights Reserved.
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvConsts.pas 11414 2007-07-11 21:15:58Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvConsts;
+
+interface
+
+uses
+ Controls, Classes, LMessages, SysUtils;
+ //, Forms, Graphics, Windows,
+
+const
+ { JvEditor }
+ JvEditorCompletionChars = #8'0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm';
+
+ { Various units }
+ DigitSymbols = ['0'..'9'];
+ SignSymbols = ['+', '-'];
+ IdentifierUppercaseLetters = ['A'..'Z'];
+ IdentifierLowercaseLetters = ['a'..'z'];
+ HexadecimalUppercaseLetters = ['A'..'F'];
+ HexadecimalLowercaseLetters = ['a'..'f'];
+ IdentifierLetters = IdentifierUppercaseLetters + IdentifierLowercaseLetters;
+ IdentifierFirstSymbols = ['_'] + IdentifierLetters;
+ IdentifierSymbols = IdentifierFirstSymbols + DigitSymbols;
+ HexadecimalSymbols = DigitSymbols + HexadecimalUppercaseLetters + HexadecimalLowercaseLetters;
+
+ {$IFDEF DELPHI5}
+ SDelphiKey = 'Software\Borland\Delphi\5.0';
+ {$ENDIF DELPHI5}
+ {$IFDEF BCB5}
+ SDelphiKey = 'Software\Borland\C++Builder\5.0';
+ {$ENDIF BCB5}
+ {$IFDEF DELPHI6}
+ SDelphiKey = 'Software\Borland\Delphi\6.0';
+ {$ENDIF DELPHI6}
+ {$IFDEF BCB6}
+ SDelphiKey = 'Software\Borland\C++Builder\6.0';
+ {$ENDIF BCB6}
+ {$IFDEF DELPHI7}
+ SDelphiKey = 'Software\Borland\Delphi\7.0';
+ {$ENDIF DELPHI7}
+ {$IFDEF DELPHI8}
+ SDelphiKey = 'Software\Borland\BDS\2.0';
+ {$ENDIF DELPHI8}
+ {$IFDEF DELPHI9}
+ SDelphiKey = 'Software\Borland\BDS\3.0';
+ {$ENDIF DELPHI9}
+ {$IFDEF DELPHI10}
+ SDelphiKey = 'Software\Borland\BDS\4.0';
+ {$ENDIF DELPHI10}
+ {$IFDEF DELPHI11}
+ SDelphiKey = 'Software\Borland\BDS\5.0';
+ {$ENDIF DELPHI11}
+ { JvDataProvider constants }
+ { Consumer attributes }
+ DPA_RenderDisabledAsGrayed = 1;
+ DPA_RendersSingleItem = 2;
+ DPA_ConsumerDisplaysList = 3;
+
+ CM_JVBASE = CM_BASE + 80; // warning VCL improves and comes nearer
+ { Command message for JvSpeedbar editor }
+ CM_SPEEDBARCHANGED = CM_JVBASE + 0;
+ { Command message for TJvSpeedButton }
+ CM_JVBUTTONPRESSED = CM_JVBASE + 1;
+ // (rom) disabled unused
+ { Command messages for TJvWindowHook }
+ //CM_RECREATEWINDOW = CM_JVBASE + 2;
+ //CM_DESTROYHOOK = CM_JVBASE + 3;
+ { Notify message for TJvxTrayIcon }
+ //CM_TRAYICON = CM_JVBASE + 4;
+ CM_FORCESIZE = CM_JVBASE + 5; // used in JvButton
+
+ { Values for WParam for CM_SPEEDBARCHANGED message }
+ SBR_CHANGED = 0; { change buttons properties }
+ SBR_DESTROYED = 1; { destroy SpeedBar }
+ SBR_BTNSELECT = 2; { select button in SpeedBar }
+ SBR_BTNSIZECHANGED = 3; { button size changed }
+
+ { TBitmap.GetTransparentColor from GRAPHICS.PAS use this value }
+ PaletteMask = $02000000;
+
+ // (outchy) now used
+ {$IFDEF COMPILER7_UP}
+ // (outchy) it was defined as $000000FF
+ DEFAULT_SYSCOLOR_MASK = clSystemColor; // $FF000000
+ {$ELSE}
+ DEFAULT_SYSCOLOR_MASK = $80000000;
+ {$ENDIF COMPILER7_UP}
+
+ {$IFDEF COMPILER5}
+ // Delphi colors not defined in Delphi 5
+ clMoneyGreen = TColor($C0DCC0);
+ clSkyBlue = TColor($F0CAA6);
+ clCream = TColor($F0FBFF);
+ clMedGray = TColor($A4A0A0);
+ // (outchy) = TColor(COLOR_XXXXXXXXXXX or $80000000);
+ clGradientActiveCaption = TColor(COLOR_GRADIENTACTIVECAPTION or DEFAULT_SYSCOLOR_MASK);
+ clGradientInactiveCaption = TColor(COLOR_GRADIENTINACTIVECAPTION or DEFAULT_SYSCOLOR_MASK);
+ clHotLight = TColor(COLOR_HOTLIGHT or DEFAULT_SYSCOLOR_MASK);
+ clMenuHighlight = TColor(COLOR_MENUHILIGHT or DEFAULT_SYSCOLOR_MASK);
+ clMenuBar = TColor(COLOR_MENUBAR or DEFAULT_SYSCOLOR_MASK);
+ {$ENDIF COMPILER5}
+
+ {$IFDEF COMPILER5}
+ {$IFDEF MSWINDOWS}
+ sLineBreak = #13#10;
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ sLineBreak = #10;
+ {$ENDIF UNIX}
+ {$ENDIF COMPILER5}
+ sLineBreakLen = Length(sLineBreak);
+
+ CrLf = #13#10;
+ Cr = #13;
+ Lf = #10;
+ Backspace = #8;
+ Tab = #9;
+ Esc = #27;
+ Del = #127;
+ CtrlC = ^C;
+ CtrlH = ^H;
+ CtrlI = ^I;
+ CtrlJ = ^J;
+ CtrlM = ^M;
+ CtrlV = ^V;
+ CtrlX = ^X;
+ {$IFDEF MSWINDOWS}
+ RegPathDelim = '\';
+ PathDelim = '\';
+ DriveDelim = ':';
+ PathSep = ';';
+ AllFilePattern = '*.*';
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ RegPathDelim = '_';
+ PathDelim = '/';
+ AllFilePattern = '*';
+ {$ENDIF UNIX}
+
+ (******************** NOT CONVERTED
+ //TODO: SESS - 25.09.2007 This doesnt compile in fpc
+ {const Separators is used in GetWordOnPos, JvUtils.ReplaceStrings and SubWord}
+ Separators: TSysCharSet = [#00, ' ', '-', #13, #10, '.', ',', '/', '\', '#', '"', '''',
+ ':', '+', '%', '*', '(', ')', ';', '=', '{', '}', '[', ']', '{', '}', '<', '>'];
+ ******************** NOT CONVERTED *)
+
+ DigitChars = ['0'..'9'];
+
+var
+ crJVCLFirst: TCursor = 100;
+ crMultiDragLink: TCursor = 100;
+ crDragAlt: TCursor = 101;
+ crMultiDragAlt: TCursor = 102;
+ crMultiDragLinkAlt: TCursor = 103;
+ crHand: TCursor = 104;
+ crDragHand: TCursor = 105;
+ // this should be incremented to always contain the last default JVCL cursor index
+ crJVCLLast: TCursor = 105;
+
+const
+ ROP_DSPDxax = $00E20746;
+
+const
+ FOURCC_ACON = 'ACON';
+ FOURCC_IART = 'IART';
+ FOURCC_INAM = 'INAM';
+ FOURCC_INFO = 'INFO';
+ FOURCC_LIST = 'LIST';
+ FOURCC_RIFF = 'RIFF';
+ FOURCC_anih = 'anih';
+ FOURCC_fram = 'fram';
+ FOURCC_icon = 'icon';
+ FOURCC_rate = 'rate';
+ FOURCC_seq = 'seq ';
+
+ AF_ICON = $00000001;
+ AF_SEQUENCE = $00000002;
+
+const
+ KeyboardShiftStates = [ssShift, ssAlt, ssCtrl];
+ MouseShiftStates = [ssLeft, ssRight, ssMiddle, ssDouble];
+
+implementation
+
+end.
+
diff --git a/components/jvcllaz/run/JvExControls.pas b/components/jvcllaz/run/JvExControls.pas
new file mode 100644
index 000000000..2264df838
--- /dev/null
+++ b/components/jvcllaz/run/JvExControls.pas
@@ -0,0 +1,1064 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvExControls.pas, released on 2004-01-04
+
+The Initial Developer of the Original Code is Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
+Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
+All Rights Reserved.
+
+Contributor(s): -
+ dejoy.
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvExControls.pas 11400 2007-06-28 21:24:06Z ahuser $
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+// TODO: Make this unit generated by template as JVCL's.
+
+{$mode objfpc}{$H+}
+
+unit JvExControls;
+{MACROINCLUDE JvExControls.macros}
+
+{*****************************************************************************
+ * WARNING: Do not edit this file.
+ * This file is autogenerated from the source in devtools/JvExVCL/src.
+ * If you do it despite this warning your changes will be discarded by the next
+ * update of this file. Do your changes in the template files.
+ ****************************************************************************}
+{$D-} // do not step into this unit
+
+interface
+
+uses
+ Classes, Controls, Graphics, LCLIntf, LCLType, LMessages, Forms;
+
+type
+ TDlgCode =
+ (dcWantAllKeys, dcWantArrows, dcWantChars, dcButton, dcHasSetSel, dcWantTab,
+ dcNative); // if dcNative is in the set the native allowed keys are used and GetDlgCode is ignored
+ TDlgCodes = set of TDlgCode;
+
+(******************** NOT CONVERTED
+const
+ dcWantMessage = dcWantAllKeys;
+
+const
+ CM_DENYSUBCLASSING = JvThemes.CM_DENYSUBCLASSING;
+ CM_PERFORM = CM_BASE + $500 + 0; // LParam: "Msg: ^TMessage"
+ CM_SETAUTOSIZE = CM_BASE + $500 + 1; // WParam: "Value: Boolean"
+
+type
+ TJvHotTrackOptions = class;
+
+ { IJvExControl is used for the identification of an JvExXxx control. }
+ IJvExControl = interface
+ ['{8E6579C3-D683-4562-AFAB-D23C8526E386}']
+ end;
+
+ { Add IJvDenySubClassing to the base class list if the control should not
+ be themed by the ThemeManager (http://www.soft-gems.net Mike Lischke).
+ This only works with JvExVCL derived classes. }
+ IJvDenySubClassing = interface
+ ['{76942BC0-2A6E-4DC4-BFC9-8E110DB7F601}']
+ end;
+
+
+ { IJvHotTrack is Specifies whether Control are highlighted when the mouse passes over them}
+ IJvHotTrack = interface
+ ['{8F1B40FB-D8E3-46FE-A7A3-21CE4B199A8F}']
+
+ function GetHotTrack:Boolean;
+ function GetHotTrackFont:TFont;
+ function GetHotTrackFontOptions:TJvTrackFontOptions;
+ function GetHotTrackOptions:TJvHotTrackOptions;
+
+ procedure SetHotTrack(Value: Boolean);
+ procedure SetHotTrackFont(Value: TFont);
+ procedure SetHotTrackFontOptions(Value: TJvTrackFontOptions);
+ procedure SetHotTrackOptions(Value: TJvHotTrackOptions);
+
+ property HotTrack: Boolean read GetHotTrack write SetHotTrack;
+ property HotTrackFont: TFont read GetHotTrackFont write SetHotTrackFont;
+ property HotTrackFontOptions: TJvTrackFontOptions read GetHotTrackFontOptions write SetHotTrackFontOptions;
+ property HotTrackOptions: TJvHotTrackOptions read GetHotTrackOptions write SetHotTrackOptions;
+ end;
+
+ TJvHotTrackOptions = class(TJvPersistentProperty)
+ private
+ FEnabled: Boolean;
+ FFrameVisible: Boolean;
+ FColor: TColor;
+ FFrameColor: TColor;
+ procedure SetColor(Value: TColor);
+ procedure SetEnabled(Value: Boolean);
+ procedure SetFrameColor(Value: TColor);
+ procedure SetFrameVisible(Value: Boolean);
+ public
+ constructor Create; virtual;
+ procedure Assign(Source: TPersistent); override;
+ published
+ property Enabled: Boolean read FEnabled write SetEnabled default False;
+ property Color: TColor read FColor write SetColor default $00D2BDB6;
+ property FrameVisible: Boolean read FFrameVisible write SetFrameVisible default False;
+ property FrameColor: TColor read FFrameColor write SetFrameColor default $006A240A;
+ end;
+******************** NOT CONVERTED *)
+
+type
+ TStructPtrMessage = class(TObject)
+ private
+ public
+ Msg: TLMessage;
+ constructor Create(AMsg: Integer; WParam: Integer; var LParam);
+ end;
+
+//******************** NOT CONVERTED
+//procedure SetDotNetFrameColors(FocusedColor, UnfocusedColor: TColor);
+
+procedure DrawDotNetControl(Control: TWinControl; AColor: TColor; InControl: Boolean);
+procedure HandleDotNetHighlighting(Control: TWinControl; const Msg: TLMessage;
+ MouseOver: Boolean; Color: TColor);
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: Longint): TLMessage; overload; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: TControl): TLMessage; overload; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function SmallPointToLong(const Pt: TSmallPoint): Longint; {$IFDEF SUPPORTS_INLINE} inline {$ENDIF}
+function ShiftStateToKeyData(Shift: TShiftState): Longint;
+
+//******************** NOT CONVERTED
+//function GetFocusedControl(AControl: TControl): TWinControl;
+
+function DlgcToDlgCodes(Value: Longint): TDlgCodes;
+function DlgCodesToDlgc(Value: TDlgCodes): Longint;
+procedure GetHintColor(var HintInfo: THintInfo; AControl: TControl; HintColor: TColor);
+function DispatchIsDesignMsg(Control: TControl; var Msg: TLMessage): Boolean;
+
+type
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Control)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(WinControl)
+
+ TJvExCustomControl = class(TCustomControl)
+ private
+ // TODO:
+ // FAboutJVCL: TJVCLAboutInfo;
+ FHintColor: TColor;
+ FMouseOver: Boolean;
+ FHintWindowClass: THintWindowClass;
+ FOnMouseEnter: TNotifyEvent;
+ FOnMouseLeave: TNotifyEvent;
+ FOnParentColorChanged: TNotifyEvent;
+ function BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer; overload;
+ function BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer; overload;
+ function BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+ protected
+ procedure WndProc(var Msg: TLMessage); override;
+ procedure FocusChanged(AControl: TWinControl); dynamic;
+ procedure VisibleChanged; reintroduce; dynamic;
+ procedure EnabledChanged; reintroduce; dynamic;
+ procedure TextChanged; reintroduce; virtual;
+ procedure ColorChanged; reintroduce; dynamic;
+ procedure FontChanged; reintroduce; dynamic;
+ procedure ParentFontChanged; reintroduce; dynamic;
+ procedure ParentColorChanged; reintroduce; dynamic;
+ procedure ParentShowHintChanged; reintroduce; dynamic;
+ function WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean; reintroduce; virtual;
+ function HintShow(var HintInfo: THintInfo): Boolean; reintroduce; dynamic;
+ function HitTest(X, Y: Integer): Boolean; reintroduce; virtual;
+ procedure MouseEnter(AControl: TControl); reintroduce; dynamic;
+ procedure MouseLeave(AControl: TControl); reintroduce; dynamic;
+ property MouseOver: Boolean read FMouseOver write FMouseOver;
+ property HintColor: TColor read FHintColor write FHintColor default clDefault;
+ property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
+ property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
+ property OnParentColorChange: TNotifyEvent read FOnParentColorChanged write FOnParentColorChanged;
+ function GetCaption: TCaption; virtual;
+ procedure SetCaption(Value: TCaption); virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Caption: TCaption read GetCaption write SetCaption;
+ property HintWindowClass: THintWindowClass read FHintWindowClass write FHintWindowClass;
+ published
+ // TODO:
+ // property AboutJVCL: TJVCLAboutInfo read FAboutJVCL write FAboutJVCL stored False;
+ private
+ FDotNetHighlighting: Boolean;
+ protected
+ procedure BoundsChanged; reintroduce; virtual;
+ procedure CursorChanged; reintroduce; dynamic;
+ procedure ShowingChanged; reintroduce; dynamic;
+ procedure ShowHintChanged; reintroduce; dynamic;
+ procedure ControlsListChanging(Control: TControl; Inserting: Boolean); reintroduce; dynamic;
+ procedure ControlsListChanged(Control: TControl; Inserting: Boolean); reintroduce; dynamic;
+ procedure GetDlgCode(var Code: TDlgCodes); virtual;
+ procedure FocusSet(PrevWnd: THandle); virtual;
+ procedure FocusKilled(NextWnd: THandle); virtual;
+ function DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean; virtual;
+ published
+ property DotNetHighlighting: Boolean read FDotNetHighlighting write FDotNetHighlighting default False;
+ end;
+
+ TJvExGraphicControl = class(TGraphicControl)
+ private
+ // TODO:
+ // FAboutJVCL: TJVCLAboutInfo;
+ FHintColor: TColor;
+ FMouseOver: Boolean;
+ FHintWindowClass: THintWindowClass;
+ FOnMouseEnter: TNotifyEvent;
+ FOnMouseLeave: TNotifyEvent;
+ FOnParentColorChanged: TNotifyEvent;
+ function BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer; overload;
+ function BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer; overload;
+ function BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+ protected
+ procedure WndProc(var Msg: TLMessage); override;
+ procedure FocusChanged(AControl: TWinControl); dynamic;
+ procedure VisibleChanged; reintroduce; dynamic;
+ procedure EnabledChanged; reintroduce; dynamic;
+ procedure TextChanged; reintroduce; virtual;
+ procedure ColorChanged; reintroduce; dynamic;
+ procedure FontChanged; reintroduce; dynamic;
+ procedure ParentFontChanged; reintroduce; dynamic;
+ procedure ParentColorChanged; reintroduce; dynamic;
+ procedure ParentShowHintChanged; reintroduce; dynamic;
+ function WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean; reintroduce; virtual;
+ function HintShow(var HintInfo: THintInfo): Boolean; reintroduce; dynamic;
+ function HitTest(X, Y: Integer): Boolean; reintroduce; virtual;
+ procedure MouseEnter(AControl: TControl); reintroduce; dynamic;
+ procedure MouseLeave(AControl: TControl); reintroduce; dynamic;
+ property MouseOver: Boolean read FMouseOver write FMouseOver;
+ property HintColor: TColor read FHintColor write FHintColor default clDefault;
+ property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
+ property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
+ property OnParentColorChange: TNotifyEvent read FOnParentColorChanged write FOnParentColorChanged;
+ function GetCaption: TCaption; virtual;
+ procedure SetCaption(Value: TCaption); virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Caption: TCaption read GetCaption write SetCaption;
+ property HintWindowClass: THintWindowClass read FHintWindowClass write FHintWindowClass;
+ published
+ // TODO:
+ // property AboutJVCL: TJVCLAboutInfo read FAboutJVCL write FAboutJVCL stored False;
+ end;
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(HintWindow)
+
+(******************** NOT CONVERTED
+ TJvExPubGraphicControl = class(TJvExGraphicControl)
+ COMMON_PUBLISHED
+ end;
+******************** NOT CONVERTED *)
+
+implementation
+
+(******************** NOT CONVERTED
+uses
+ TypInfo;
+
+var
+ InternalFocusedColor: TColor = TColor($00733800);
+ InternalUnfocusedColor: TColor = clGray;
+
+procedure SetDotNetFrameColors(FocusedColor, UnfocusedColor: TColor);
+begin
+ InternalFocusedColor := FocusedColor;
+ InternalUnfocusedColor := UnfocusedColor;
+end;
+******************** NOT CONVERTED *)
+
+procedure DrawDotNetControl(Control: TWinControl; AColor: TColor; InControl: Boolean);
+(******************** NOT CONVERTED
+var
+ DC: HDC;
+ R: TRect;
+ Canvas: TCanvas;
+begin
+ DC := GetWindowDC(Control.Handle);
+ try
+ GetWindowRect(Control.Handle, R);
+ OffsetRect(R, -R.Left, -R.Top);
+ Canvas := TCanvas.Create;
+ with Canvas do
+ try
+ Handle := DC;
+ Brush.Color := InternalUnfocusedColor;
+ if Control.Focused or InControl then
+ Brush.Color := InternalFocusedColor;
+ FrameRect(R);
+ InflateRect(R, -1, -1);
+ if not (Control.Focused or InControl) then
+ Brush.Color := AColor;
+ FrameRect(R);
+ finally
+ Free;
+ end;
+ finally
+ ReleaseDC(Control.Handle, DC);
+ end;
+end;
+******************** NOT CONVERTED *)
+begin
+end;
+
+procedure HandleDotNetHighlighting(Control: TWinControl; const Msg: TLMessage;
+ MouseOver: Boolean; Color: TColor);
+(******************** NOT CONVERTED
+var
+ Rgn, SubRgn: HRGN;
+begin
+ if not (csDesigning in Control.ComponentState) then
+ case Msg.Msg of
+ CM_MOUSEENTER, CM_MOUSELEAVE, WM_KILLFOCUS, WM_SETFOCUS, WM_NCPAINT:
+ begin
+ DrawDotNetControl(Control, Color, MouseOver);
+ if Msg.Msg = CM_MOUSELEAVE then
+ begin
+ Rgn := CreateRectRgn(0, 0, Control.Width - 1, Control.Height - 1);
+ SubRgn := CreateRectRgn(2, 2, Control.Width - 3, Control.Height - 3);
+ try
+ CombineRgn(Rgn, Rgn, SubRgn, RGN_DIFF);
+ InvalidateRgn(Control.Handle, Rgn, False); // redraw 3D border
+ finally
+ DeleteObject(SubRgn);
+ DeleteObject(Rgn);
+ end;
+ end;
+ end;
+ end;
+end;
+******************** NOT CONVERTED *)
+begin
+end;
+
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: Longint): TLMessage;
+begin
+ Result.Msg := Msg;
+ Result.WParam := WParam;
+ Result.LParam := LParam;
+ Result.Result := 0;
+end;
+
+function CreateWMMessage(Msg: Integer; WParam: Integer; LParam: TControl): TLMessage;
+begin
+ Result := CreateWMMessage(Msg, WParam, Integer(LParam));
+end;
+
+{ TStructPtrMessage }
+constructor TStructPtrMessage.Create(AMsg: Integer; WParam: Integer; var LParam);
+begin
+ inherited Create;
+ Self.Msg.Msg := AMsg;
+ Self.Msg.WParam := WParam;
+ Self.Msg.LParam := Longint(@LParam);
+ Self.Msg.Result := 0;
+end;
+
+function SmallPointToLong(const Pt: TSmallPoint): Longint;
+begin
+ Result := Longint(Pt);
+end;
+
+function ShiftStateToKeyData(Shift: TShiftState): Longint;
+const
+ AltMask = $20000000;
+ CtrlMask = $10000000;
+ ShiftMask = $08000000;
+begin
+ Result := 0;
+ if ssAlt in Shift then
+ Result := Result or AltMask;
+ if ssCtrl in Shift then
+ Result := Result or CtrlMask;
+ if ssShift in Shift then
+ Result := Result or ShiftMask;
+end;
+
+(******************** NOT CONVERTED
+function GetFocusedControl(AControl: TControl): TWinControl;
+var
+ Form: TCustomForm;
+begin
+ Result := nil;
+ Form := GetParentForm(AControl);
+ if Assigned(Form) then
+ Result := Form.ActiveControl;
+end;
+******************** NOT CONVERTED *)
+
+function DlgcToDlgCodes(Value: Longint): TDlgCodes;
+begin
+ Result := [];
+(******************** NOT CONVERTED
+ if (Value and DLGC_WANTARROWS) <> 0 then
+ Include(Result, dcWantArrows);
+ if (Value and DLGC_WANTTAB) <> 0 then
+ Include(Result, dcWantTab);
+ if (Value and DLGC_WANTALLKEYS) <> 0 then
+ Include(Result, dcWantAllKeys);
+ if (Value and DLGC_WANTCHARS) <> 0 then
+ Include(Result, dcWantChars);
+ if (Value and DLGC_BUTTON) <> 0 then
+ Include(Result, dcButton);
+ if (Value and DLGC_HASSETSEL) <> 0 then
+ Include(Result, dcHasSetSel);
+******************** NOT CONVERTED *)
+end;
+
+function DlgCodesToDlgc(Value: TDlgCodes): Longint;
+begin
+ Result := 0;
+(******************** NOT CONVERTED
+ if dcWantAllKeys in Value then
+ Result := Result or DLGC_WANTALLKEYS;
+ if dcWantArrows in Value then
+ Result := Result or DLGC_WANTARROWS;
+ if dcWantTab in Value then
+ Result := Result or DLGC_WANTTAB;
+ if dcWantChars in Value then
+ Result := Result or DLGC_WANTCHARS;
+ if dcButton in Value then
+ Result := Result or DLGC_BUTTON;
+ if dcHasSetSel in Value then
+ Result := Result or DLGC_HASSETSEL;
+******************** NOT CONVERTED *)
+end;
+
+procedure GetHintColor(var HintInfo: THintInfo; AControl: TControl; HintColor: TColor);
+var
+ AHintInfo: THintInfo;
+begin
+ case HintColor of
+ clNone:
+ HintInfo.HintColor := Application.HintColor;
+ clDefault:
+ begin
+ if Assigned(AControl) and Assigned(AControl.Parent) then
+ begin
+ AHintInfo := HintInfo;
+ AControl.Parent.Perform(CM_HINTSHOW, 0, Integer(@AHintInfo));
+ HintInfo.HintColor := AHintInfo.HintColor;
+ end;
+ end;
+ else
+ HintInfo.HintColor := HintColor;
+ end;
+end;
+
+function DispatchIsDesignMsg(Control: TControl; var Msg: TLMessage): Boolean;
+var
+ Form: TCustomForm;
+begin
+ Result := False;
+ case Msg.Msg of
+ LM_SETFOCUS, LM_KILLFOCUS, LM_NCHITTEST,
+ LM_MOUSEFIRST..LM_MOUSELAST,
+ LM_KEYFIRST..LM_KEYLAST,
+ LM_CANCELMODE:
+ Exit; // These messages are handled in TWinControl.WndProc before IsDesignMsg() is called
+ end;
+ if (Control <> nil) and (csDesigning in Control.ComponentState) then
+ begin
+ Form := GetParentForm(Control);
+ if (Form <> nil) and (Form.Designer <> nil) and
+ Form.Designer.IsDesignMsg(Control, Msg) then
+ Result := True;
+ end;
+end;
+
+(******************** NOT CONVERTED
+//=== { TJvHotTrackOptions } ======================================
+
+constructor TJvHotTrackOptions.Create;
+begin
+ inherited Create;
+ FEnabled := False;
+ FFrameVisible := False;
+ FColor := $00D2BDB6;
+ FFrameColor := $006A240A;
+end;
+
+procedure TJvHotTrackOptions.Assign(Source: TPersistent);
+begin
+ if Source is TJvHotTrackOptions then
+ begin
+ BeginUpdate;
+ try
+ Enabled := TJvHotTrackOptions(Source).Enabled;
+ Color := TJvHotTrackOptions(Source).Color;
+ FrameVisible := TJvHotTrackOptions(Source).FrameVisible;
+ FrameColor := TJvHotTrackOptions(Source).FrameColor;
+ finally
+ EndUpdate;
+ end;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvHotTrackOptions.SetColor(Value: TColor);
+begin
+ if FColor <> Value then
+ begin
+ Changing;
+ ChangingProperty('Color');
+ FColor := Value;
+ ChangedProperty('Color');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetEnabled(Value: Boolean);
+begin
+ if FEnabled <> Value then
+ begin
+ Changing;
+ ChangingProperty('Enabled');
+ FEnabled := Value;
+ ChangedProperty('Enabled');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetFrameVisible(Value: Boolean);
+begin
+ if FFrameVisible <> Value then
+ begin
+ Changing;
+ ChangingProperty('FrameVisible');
+ FFrameVisible := Value;
+ ChangedProperty('FrameVisible');
+ Changed;
+ end;
+end;
+
+procedure TJvHotTrackOptions.SetFrameColor(Value: TColor);
+begin
+ if FFrameColor <> Value then
+ begin
+ Changing;
+ ChangingProperty('FrameColor');
+ FFrameColor := Value;
+ ChangedProperty('FrameColor');
+ Changed;
+ end;
+end;
+******************** NOT CONVERTED *)
+
+//============================================================================
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Control)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(WinControl)
+
+constructor TJvExGraphicControl.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHintColor := clDefault;
+end;
+
+function TJvExGraphicControl.BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExGraphicControl.BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExGraphicControl.BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+var
+ Mesg: TStructPtrMessage;
+begin
+ Mesg := TStructPtrMessage.Create(Msg, WParam, LParam);
+ try
+ inherited WndProc(Mesg.Msg);
+ finally
+ Result := Mesg.Msg.Result;
+ Mesg.Free;
+ end;
+end;
+
+procedure TJvExGraphicControl.VisibleChanged;
+begin
+ BaseWndProc(CM_VISIBLECHANGED);
+end;
+
+procedure TJvExGraphicControl.EnabledChanged;
+begin
+ BaseWndProc(CM_ENABLEDCHANGED);
+end;
+
+procedure TJvExGraphicControl.TextChanged;
+begin
+ BaseWndProc(CM_TEXTCHANGED);
+end;
+
+procedure TJvExGraphicControl.FontChanged;
+begin
+ BaseWndProc(CM_FONTCHANGED);
+end;
+
+procedure TJvExGraphicControl.ColorChanged;
+begin
+ BaseWndProc(CM_COLORCHANGED);
+end;
+
+procedure TJvExGraphicControl.ParentFontChanged;
+begin
+ // LCL doesn't send this message but left it in case
+ //BaseWndProc(CM_PARENTFONTCHANGED);
+end;
+
+procedure TJvExGraphicControl.ParentColorChanged;
+begin
+ BaseWndProc(CM_PARENTCOLORCHANGED);
+ if Assigned(OnParentColorChange) then
+ OnParentColorChange(Self);
+end;
+
+procedure TJvExGraphicControl.ParentShowHintChanged;
+begin
+ BaseWndProc(CM_PARENTSHOWHINTCHANGED);
+end;
+
+function TJvExGraphicControl.WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean;
+begin
+ Result := BaseWndProc(CM_DIALOGCHAR, Word(Key), ShiftStateToKeyData(Shift)) <> 0;
+end;
+
+function TJvExGraphicControl.HitTest(X, Y: Integer): Boolean;
+begin
+ Result := BaseWndProc(CM_HITTEST, 0, SmallPointToLong(PointToSmallPoint(Point(X, Y)))) <> 0;
+end;
+
+function TJvExGraphicControl.HintShow(var HintInfo: THintInfo): Boolean;
+begin
+ GetHintColor(HintInfo, Self, FHintColor);
+ if FHintWindowClass <> nil then
+ HintInfo.HintWindowClass := FHintWindowClass;
+ Result := BaseWndProcEx(CM_HINTSHOW, 0, HintInfo) <> 0;
+end;
+
+procedure TJvExGraphicControl.MouseEnter(AControl: TControl);
+begin
+ FMouseOver := True;
+ if Assigned(FOnMouseEnter) then
+ FOnMouseEnter(Self);
+ BaseWndProc(CM_MOUSEENTER, 0, AControl);
+end;
+
+procedure TJvExGraphicControl.MouseLeave(AControl: TControl);
+begin
+ FMouseOver := False;
+ BaseWndProc(CM_MOUSELEAVE, 0, AControl);
+ if Assigned(FOnMouseLeave) then
+ FOnMouseLeave(Self);
+end;
+
+procedure TJvExGraphicControl.FocusChanged(AControl: TWinControl);
+begin
+ BaseWndProc(CM_FOCUSCHANGED, 0, AControl);
+end;
+
+function TJvExGraphicControl.GetCaption: TCaption;
+begin
+ Result := inherited Caption;
+end;
+
+// 25.09.2007 - SESS:
+// I have done this because TextChanged wasn't fired as expected.
+// I still don't shure if this problem is only for this reintroduced
+// method because the way LCL treats Caption or will have the same
+// problem with other reintroduced methods. So far, I tested some
+// other events and seems not.
+procedure TJvExGraphicControl.SetCaption(Value: TCaption);
+begin
+ inherited Caption := Value;
+ TextChanged;
+end;
+
+procedure TJvExGraphicControl.WndProc(var Msg: TLMessage);
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ case Msg.Msg of
+ {
+ // TODO: do we need this? I think not...
+ CM_DENYSUBCLASSING:
+ Msg.Result := Ord(GetInterfaceEntry(IJvDenySubClassing) <> nil);
+ }
+ CM_DIALOGCHAR:
+ with TCMDialogChar(Msg) do
+ Result := Ord(WantKey(CharCode, KeyDataToShiftState(KeyData), WideChar(CharCode)));
+ CM_HINTSHOW:
+ with TCMHintShow(Msg) do
+ Result := Integer(HintShow(HintInfo^));
+ CM_HITTEST:
+ with TCMHitTest(Msg) do
+ Result := Integer(HitTest(XPos, YPos));
+ CM_MOUSEENTER:
+ MouseEnter(TControl(Msg.LParam));
+ CM_MOUSELEAVE:
+ MouseLeave(TControl(Msg.LParam));
+ CM_VISIBLECHANGED:
+ VisibleChanged;
+ CM_ENABLEDCHANGED:
+ EnabledChanged;
+ // LCL doesn't send this message but left it in case
+ CM_TEXTCHANGED:
+ TextChanged;
+ CM_FONTCHANGED:
+ FontChanged;
+ CM_COLORCHANGED:
+ ColorChanged;
+ CM_FOCUSCHANGED:
+ FocusChanged(TWinControl(Msg.LParam));
+ // LCL doesn't send this message but left it in case
+ //CM_PARENTFONTCHANGED:
+ // ParentFontChanged;
+ CM_PARENTCOLORCHANGED:
+ ParentColorChanged;
+ CM_PARENTSHOWHINTCHANGED:
+ ParentShowHintChanged;
+ else
+ inherited WndProc(Msg);
+ end;
+end;
+
+//============================================================================
+
+constructor TJvExCustomControl.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHintColor := clDefault;
+end;
+
+function TJvExCustomControl.BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExCustomControl.BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExCustomControl.BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+var
+ Mesg: TStructPtrMessage;
+begin
+ Mesg := TStructPtrMessage.Create(Msg, WParam, LParam);
+ try
+ inherited WndProc(Mesg.Msg);
+ finally
+ Result := Mesg.Msg.Result;
+ Mesg.Free;
+ end;
+end;
+
+procedure TJvExCustomControl.VisibleChanged;
+begin
+ BaseWndProc(CM_VISIBLECHANGED);
+end;
+
+procedure TJvExCustomControl.EnabledChanged;
+begin
+ BaseWndProc(CM_ENABLEDCHANGED);
+end;
+
+procedure TJvExCustomControl.TextChanged;
+begin
+ BaseWndProc(CM_TEXTCHANGED);
+end;
+
+procedure TJvExCustomControl.FontChanged;
+begin
+ BaseWndProc(CM_FONTCHANGED);
+end;
+
+procedure TJvExCustomControl.ColorChanged;
+begin
+ BaseWndProc(CM_COLORCHANGED);
+end;
+
+procedure TJvExCustomControl.ParentFontChanged;
+begin
+ // LCL doesn't send this message but left it in case
+ //BaseWndProc(CM_PARENTFONTCHANGED);
+end;
+
+procedure TJvExCustomControl.ParentColorChanged;
+begin
+ BaseWndProc(CM_PARENTCOLORCHANGED);
+ if Assigned(OnParentColorChange) then
+ OnParentColorChange(Self);
+end;
+
+procedure TJvExCustomControl.ParentShowHintChanged;
+begin
+ BaseWndProc(CM_PARENTSHOWHINTCHANGED);
+end;
+
+function TJvExCustomControl.WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean;
+begin
+ Result := BaseWndProc(CM_DIALOGCHAR, Word(Key), ShiftStateToKeyData(Shift)) <> 0;
+end;
+
+function TJvExCustomControl.HitTest(X, Y: Integer): Boolean;
+begin
+ Result := BaseWndProc(CM_HITTEST, 0, SmallPointToLong(PointToSmallPoint(Point(X, Y)))) <> 0;
+end;
+
+function TJvExCustomControl.HintShow(var HintInfo: THintInfo): Boolean;
+begin
+ GetHintColor(HintInfo, Self, FHintColor);
+ if FHintWindowClass <> nil then
+ HintInfo.HintWindowClass := FHintWindowClass;
+ Result := BaseWndProcEx(CM_HINTSHOW, 0, HintInfo) <> 0;
+end;
+
+procedure TJvExCustomControl.MouseEnter(AControl: TControl);
+begin
+ FMouseOver := True;
+ if Assigned(FOnMouseEnter) then
+ FOnMouseEnter(Self);
+ BaseWndProc(CM_MOUSEENTER, 0, AControl);
+end;
+
+procedure TJvExCustomControl.MouseLeave(AControl: TControl);
+begin
+ FMouseOver := False;
+ BaseWndProc(CM_MOUSELEAVE, 0, AControl);
+ if Assigned(FOnMouseLeave) then
+ FOnMouseLeave(Self);
+end;
+
+procedure TJvExCustomControl.FocusChanged(AControl: TWinControl);
+begin
+ BaseWndProc(CM_FOCUSCHANGED, 0, AControl);
+end;
+
+function TJvExCustomControl.GetCaption: TCaption;
+begin
+ Result := inherited Caption;
+end;
+
+// 25.09.2007 - SESS:
+// I have done this because TextChanged wasn't fired as expected.
+// I still don't shure if this problem is only for this reintroduced
+// method because the way LCL treats Caption or will have the same
+// problem with other reintroduced methods. So far, I tested some
+// other events and seems not.
+procedure TJvExCustomControl.SetCaption(Value: TCaption);
+begin
+ inherited Caption := Value;
+ TextChanged;
+end;
+
+procedure TJvExCustomControl.BoundsChanged;
+begin
+end;
+
+procedure TJvExCustomControl.CursorChanged;
+begin
+ BaseWndProc(CM_CURSORCHANGED);
+end;
+
+procedure TJvExCustomControl.ShowingChanged;
+begin
+ BaseWndProc(CM_SHOWINGCHANGED);
+end;
+
+procedure TJvExCustomControl.ShowHintChanged;
+begin
+ BaseWndProc(CM_SHOWHINTCHANGED);
+end;
+
+{ VCL sends CM_CONTROLLISTCHANGE and CM_CONTROLCHANGE in a different order than
+ the CLX methods are used. So we must correct it by evaluating "Inserting". }
+procedure TJvExCustomControl.ControlsListChanging(Control: TControl; Inserting: Boolean);
+begin
+ if Inserting then
+ BaseWndProc(CM_CONTROLLISTCHANGE, Integer(Control), Integer(Inserting))
+ else
+ BaseWndProc(CM_CONTROLCHANGE, Integer(Control), Integer(Inserting));
+end;
+
+procedure TJvExCustomControl.ControlsListChanged(Control: TControl; Inserting: Boolean);
+begin
+ if not Inserting then
+ BaseWndProc(CM_CONTROLLISTCHANGE, Integer(Control), Integer(Inserting))
+ else
+ BaseWndProc(CM_CONTROLCHANGE, Integer(Control), Integer(Inserting));
+end;
+
+procedure TJvExCustomControl.GetDlgCode(var Code: TDlgCodes);
+begin
+end;
+
+procedure TJvExCustomControl.FocusSet(PrevWnd: THandle);
+begin
+ BaseWndProc(LM_SETFOCUS, Integer(PrevWnd), 0);
+end;
+
+procedure TJvExCustomControl.FocusKilled(NextWnd: THandle);
+begin
+ BaseWndProc(LM_KILLFOCUS, Integer(NextWnd), 0);
+end;
+
+function TJvExCustomControl.DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean;
+begin
+ Result := BaseWndProc(LM_ERASEBKGND, ACanvas.Handle, Param) <> 0;
+end;
+
+procedure TJvExCustomControl.WndProc(var Msg: TLMessage);
+var
+ IdSaveDC: Integer;
+ DlgCodes: TDlgCodes;
+ WCanvas: TCanvas;
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ begin
+ case Msg.Msg of
+ {
+ // TODO: do we need this? I think not...
+ CM_DENYSUBCLASSING:
+ Msg.Result := Ord(GetInterfaceEntry(IJvDenySubClassing) <> nil);
+ }
+ CM_DIALOGCHAR:
+ with TCMDialogChar(Msg) do
+ Result := Ord(WantKey(CharCode, KeyDataToShiftState(KeyData), WideChar(CharCode)));
+ CM_HINTSHOW:
+ with TCMHintShow(Msg) do
+ Result := Integer(HintShow(HintInfo^));
+ CM_HITTEST:
+ with TCMHitTest(Msg) do
+ Result := Integer(HitTest(XPos, YPos));
+ CM_MOUSEENTER:
+ MouseEnter(TControl(Msg.LParam));
+ CM_MOUSELEAVE:
+ MouseLeave(TControl(Msg.LParam));
+ CM_VISIBLECHANGED:
+ VisibleChanged;
+ CM_ENABLEDCHANGED:
+ EnabledChanged;
+ // LCL doesn't send this message but left it in case
+ CM_TEXTCHANGED:
+ TextChanged;
+ CM_FONTCHANGED:
+ FontChanged;
+ CM_COLORCHANGED:
+ ColorChanged;
+ CM_FOCUSCHANGED:
+ FocusChanged(TWinControl(Msg.LParam));
+ // LCL doesn't send this message but left it in case
+ //CM_PARENTFONTCHANGED:
+ // ParentFontChanged;
+ CM_PARENTCOLORCHANGED:
+ ParentColorChanged;
+ CM_PARENTSHOWHINTCHANGED:
+ ParentShowHintChanged;
+ CM_CURSORCHANGED:
+ CursorChanged;
+ CM_SHOWINGCHANGED:
+ ShowingChanged;
+ CM_SHOWHINTCHANGED:
+ ShowHintChanged;
+ CM_CONTROLLISTCHANGE:
+ if Msg.LParam <> 0 then
+ ControlsListChanging(TControl(Msg.WParam), True)
+ else
+ ControlsListChanged(TControl(Msg.WParam), False);
+ CM_CONTROLCHANGE:
+ if Msg.LParam = 0 then
+ ControlsListChanging(TControl(Msg.WParam), False)
+ else
+ ControlsListChanged(TControl(Msg.WParam), True);
+ LM_SETFOCUS:
+ FocusSet(THandle(Msg.WParam));
+ LM_KILLFOCUS:
+ FocusKilled(THandle(Msg.WParam));
+ LM_SIZE:
+ begin
+ inherited WndProc(Msg);
+ BoundsChanged;
+ end;
+ LM_ERASEBKGND:
+ if Msg.WParam <> 0 then
+ begin
+ IdSaveDC := SaveDC(HDC(Msg.WParam)); // protect DC against Stock-Objects from Canvas
+ WCanvas := TCanvas.Create;
+ try
+ WCanvas.Handle := HDC(Msg.WParam);
+ Msg.Result := Ord(DoEraseBackground(WCanvas, Msg.LParam));
+ finally
+ WCanvas.Handle := 0;
+ WCanvas.Free;
+ RestoreDC(HDC(Msg.WParam), IdSaveDC);
+ end;
+ end
+ else
+ inherited WndProc(Msg);
+ LM_GETDLGCODE:
+ begin
+ inherited WndProc(Msg);
+ DlgCodes := [dcNative] + DlgcToDlgCodes(Msg.Result);
+ GetDlgCode(DlgCodes);
+ if not (dcNative in DlgCodes) then
+ Msg.Result := DlgCodesToDlgc(DlgCodes);
+ end;
+ else
+ inherited WndProc(Msg);
+ end;
+ // TODO:
+ // LM_NCPAINT isn't send by LCL, may be .Net highlighting can't be implemented.
+ case Msg.Msg of // precheck message to prevent access violations on released controls
+ CM_MOUSEENTER, CM_MOUSELEAVE, LM_KILLFOCUS, LM_SETFOCUS, LM_NCPAINT:
+ if DotNetHighlighting then
+ HandleDotNetHighlighting(Self, Msg, MouseOver, Color);
+ end;
+ end;
+end;
+
+//============================================================================
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(HintWindow)
+
+end.
+
diff --git a/components/jvcllaz/run/JvExExtCtrls.pas b/components/jvcllaz/run/JvExExtCtrls.pas
new file mode 100644
index 000000000..b70f641f0
--- /dev/null
+++ b/components/jvcllaz/run/JvExExtCtrls.pas
@@ -0,0 +1,395 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvExExtCtrls.pas, released on 2004-01-04
+
+The Initial Developer of the Original Code is Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
+Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
+All Rights Reserved.
+
+Contributor(s): -
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvExExtCtrls.pas 10613 2006-05-19 19:21:43Z jfudickar $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+unit JvExExtCtrls;
+
+{MACROINCLUDE JvExControls.macros}
+
+{*****************************************************************************
+ * WARNING: Do not edit this file.
+ * This file is autogenerated from the source in devtools/JvExVCL/src.
+ * If you do it despite this warning your changes will be discarded by the next
+ * update of this file. Do your changes in the template files.
+ ****************************************************************************}
+{$D-} // do not step into this unit
+
+interface
+
+uses
+ Classes, Controls, ExtCtrls, Forms, Graphics, JvExControls, LCLIntf, LMessages;
+
+type
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Shape)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(PaintBox)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Image)
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(Bevel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomPanel)
+
+ (******************** NOT CONVERTED
+ TJvExPubCustomPanel = class(TJvExCustomPanel)
+ COMMON_PUBLISHED
+ end;
+ ******************** NOT CONVERTED *)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomRadioGroup)
+
+ TJvExSplitter = class(TSplitter)
+ private
+ // TODO:
+ // FAboutJVCL: TJVCLAboutInfo;
+ FHintColor: TColor;
+ FMouseOver: Boolean;
+ FHintWindowClass: THintWindowClass;
+ FOnMouseEnter: TNotifyEvent;
+ FOnMouseLeave: TNotifyEvent;
+ FOnParentColorChanged: TNotifyEvent;
+ function BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer; overload;
+ function BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer; overload;
+ function BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+ protected
+ procedure WndProc(var Msg: TLMessage); override;
+ procedure FocusChanged(AControl: TWinControl); dynamic;
+ procedure VisibleChanged; reintroduce; dynamic;
+ procedure EnabledChanged; reintroduce; dynamic;
+ procedure TextChanged; reintroduce; virtual;
+ procedure ColorChanged; reintroduce; dynamic;
+ procedure FontChanged; reintroduce; dynamic;
+ procedure ParentFontChanged; reintroduce; dynamic;
+ procedure ParentColorChanged; reintroduce; dynamic;
+ procedure ParentShowHintChanged; reintroduce; dynamic;
+ function WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean; reintroduce; virtual;
+ function HintShow(var HintInfo: THintInfo): Boolean; reintroduce; dynamic;
+ function HitTest(X, Y: Integer): Boolean; reintroduce; virtual;
+ procedure MouseEnter(AControl: TControl); reintroduce; dynamic;
+ procedure MouseLeave(AControl: TControl); reintroduce; dynamic;
+ property MouseOver: Boolean read FMouseOver write FMouseOver;
+ property HintColor: TColor read FHintColor write FHintColor default clDefault;
+ property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
+ property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
+ property OnParentColorChange: TNotifyEvent read FOnParentColorChanged write FOnParentColorChanged;
+ function GetCaption: TCaption; virtual;
+ procedure SetCaption(Value: TCaption); virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Caption: TCaption read GetCaption write SetCaption;
+ property HintWindowClass: THintWindowClass read FHintWindowClass write FHintWindowClass;
+ published
+ // TODO:
+ // property AboutJVCL: TJVCLAboutInfo read FAboutJVCL write FAboutJVCL stored False;
+ end;
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomControlBar)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(ControlBar)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Panel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(RadioGroup)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Page)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Notebook)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(Header)
+
+
+ //******************** NOT CONVERTED
+ //CONTROL_DECL_DEFAULT(BoundLabel)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(CustomLabeledEdit)
+
+ //******************** NOT CONVERTED
+ //WINCONTROL_DECL_DEFAULT(LabeledEdit)
+
+ //******************** NOT CONVERTED - Exists in LCL?
+ //WINCONTROL_DECL_DEFAULT(CustomColorBox)
+
+ //******************** NOT CONVERTED - Exists in LCL?
+ //WINCONTROL_DECL_DEFAULT(ColorBox)
+
+implementation
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Shape)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(PaintBox)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Image)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(Bevel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomPanel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomRadioGroup)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomControlBar)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(ControlBar)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Panel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(RadioGroup)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Page)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Notebook)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(Header)
+
+//******************** NOT CONVERTED
+//CONTROL_IMPL_DEFAULT(BoundLabel)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(CustomLabeledEdit)
+
+//******************** NOT CONVERTED
+//WINCONTROL_IMPL_DEFAULT(LabeledEdit)
+
+//******************** NOT CONVERTED - Exists in LCL?
+//WINCONTROL_IMPL_DEFAULT(CustomColorBox)
+
+//******************** NOT CONVERTED - Exists in LCL?
+//WINCONTROL_IMPL_DEFAULT(ColorBox)
+
+constructor TJvExSplitter.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHintColor := clDefault;
+end;
+
+function TJvExSplitter.BaseWndProc(Msg: Integer; WParam: Integer = 0; LParam: Longint = 0): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExSplitter.BaseWndProc(Msg: Integer; WParam: Integer; LParam: TControl): Integer;
+var
+ Mesg: TLMessage;
+begin
+ Mesg := CreateWMMessage(Msg, WParam, LParam);
+ inherited WndProc(Mesg);
+ Result := Mesg.Result;
+end;
+
+function TJvExSplitter.BaseWndProcEx(Msg: Integer; WParam: Integer; var LParam): Integer;
+var
+ Mesg: TStructPtrMessage;
+begin
+ Mesg := TStructPtrMessage.Create(Msg, WParam, LParam);
+ try
+ inherited WndProc(Mesg.Msg);
+ finally
+ Result := Mesg.Msg.Result;
+ Mesg.Free;
+ end;
+end;
+
+procedure TJvExSplitter.VisibleChanged;
+begin
+ BaseWndProc(CM_VISIBLECHANGED);
+end;
+
+procedure TJvExSplitter.EnabledChanged;
+begin
+ BaseWndProc(CM_ENABLEDCHANGED);
+end;
+
+procedure TJvExSplitter.TextChanged;
+begin
+ BaseWndProc(CM_TEXTCHANGED);
+end;
+
+procedure TJvExSplitter.FontChanged;
+begin
+ BaseWndProc(CM_FONTCHANGED);
+end;
+
+procedure TJvExSplitter.ColorChanged;
+begin
+ BaseWndProc(CM_COLORCHANGED);
+end;
+
+procedure TJvExSplitter.ParentFontChanged;
+begin
+ // LCL doesn't send this message but left it in case
+ //BaseWndProc(CM_PARENTFONTCHANGED);
+end;
+
+procedure TJvExSplitter.ParentColorChanged;
+begin
+ BaseWndProc(CM_PARENTCOLORCHANGED);
+ if Assigned(OnParentColorChange) then
+ OnParentColorChange(Self);
+end;
+
+procedure TJvExSplitter.ParentShowHintChanged;
+begin
+ BaseWndProc(CM_PARENTSHOWHINTCHANGED);
+end;
+
+function TJvExSplitter.WantKey(Key: Integer; Shift: TShiftState; const KeyText: WideString): Boolean;
+begin
+ Result := BaseWndProc(CM_DIALOGCHAR, Word(Key), ShiftStateToKeyData(Shift)) <> 0;
+end;
+
+function TJvExSplitter.HitTest(X, Y: Integer): Boolean;
+begin
+ Result := BaseWndProc(CM_HITTEST, 0, SmallPointToLong(PointToSmallPoint(Point(X, Y)))) <> 0;
+end;
+
+function TJvExSplitter.HintShow(var HintInfo: THintInfo): Boolean;
+begin
+ GetHintColor(HintInfo, Self, FHintColor);
+ if FHintWindowClass <> nil then
+ HintInfo.HintWindowClass := FHintWindowClass;
+ Result := BaseWndProcEx(CM_HINTSHOW, 0, HintInfo) <> 0;
+end;
+
+procedure TJvExSplitter.MouseEnter(AControl: TControl);
+begin
+ FMouseOver := True;
+ if Assigned(FOnMouseEnter) then
+ FOnMouseEnter(Self);
+ BaseWndProc(CM_MOUSEENTER, 0, AControl);
+end;
+
+procedure TJvExSplitter.MouseLeave(AControl: TControl);
+begin
+ FMouseOver := False;
+ BaseWndProc(CM_MOUSELEAVE, 0, AControl);
+ if Assigned(FOnMouseLeave) then
+ FOnMouseLeave(Self);
+end;
+
+procedure TJvExSplitter.FocusChanged(AControl: TWinControl);
+begin
+ BaseWndProc(CM_FOCUSCHANGED, 0, AControl);
+end;
+
+function TJvExSplitter.GetCaption: TCaption;
+begin
+ Result := inherited Caption;
+end;
+
+// 25.09.2007 - SESS:
+// I have done this because TextChanged wasn't fired as expected.
+// I still don't shure if this problem is only for this reintroduced
+// method because the way LCL treats Caption or will have the same
+// problem with other reintroduced methods. So far, I tested some
+// other events and seems not.
+procedure TJvExSplitter.SetCaption(Value: TCaption);
+begin
+ inherited Caption := Value;
+ TextChanged;
+end;
+
+procedure TJvExSplitter.WndProc(var Msg: TLMessage);
+begin
+ if not DispatchIsDesignMsg(Self, Msg) then
+ case Msg.Msg of
+ {
+ // TODO: do we need this? I think not...
+ CM_DENYSUBCLASSING:
+ Msg.Result := Ord(GetInterfaceEntry(IJvDenySubClassing) <> nil);
+ }
+ CM_DIALOGCHAR:
+ with TCMDialogChar(Msg) do
+ Result := Ord(WantKey(CharCode, KeyDataToShiftState(KeyData), WideChar(CharCode)));
+ CM_HINTSHOW:
+ with TCMHintShow(Msg) do
+ Result := Integer(HintShow(HintInfo^));
+ CM_HITTEST:
+ with TCMHitTest(Msg) do
+ Result := Integer(HitTest(XPos, YPos));
+ CM_MOUSEENTER:
+ MouseEnter(TControl(Msg.LParam));
+ CM_MOUSELEAVE:
+ MouseLeave(TControl(Msg.LParam));
+ CM_VISIBLECHANGED:
+ VisibleChanged;
+ CM_ENABLEDCHANGED:
+ EnabledChanged;
+ // LCL doesn't send this message but left it in case
+ CM_TEXTCHANGED:
+ TextChanged;
+ CM_FONTCHANGED:
+ FontChanged;
+ CM_COLORCHANGED:
+ ColorChanged;
+ CM_FOCUSCHANGED:
+ FocusChanged(TWinControl(Msg.LParam));
+ // LCL doesn't send this message but left it in case
+ //CM_PARENTFONTCHANGED:
+ // ParentFontChanged;
+ CM_PARENTCOLORCHANGED:
+ ParentColorChanged;
+ CM_PARENTSHOWHINTCHANGED:
+ ParentShowHintChanged;
+ else
+ inherited WndProc(Msg);
+ end;
+end;
+
+//============================================================================
+
+end.
diff --git a/components/jvcllaz/run/JvJCLUtils.pas b/components/jvcllaz/run/JvJCLUtils.pas
new file mode 100644
index 000000000..60344317f
--- /dev/null
+++ b/components/jvcllaz/run/JvJCLUtils.pas
@@ -0,0 +1,9764 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvJCLUtils.pas, released on 2002-07-04.
+
+The Initial Developers of the Original Code are: Andrei Prygounkov
+Copyright (c) 1999, 2002 Andrei Prygounkov
+All Rights Reserved.
+
+Contributor(s):
+ Andreas Hausladen
+ Ralf Kaiser
+ Vladimir Gaitanoff
+ Dejoy den
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+
+-----------------------------------------------------------------------------}
+// $Id: JvJCLUtils.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// (ahuser) No dependency on JCL units. Required functions are emulated.
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvJCLUtils;
+
+interface
+
+// (p3) note: this unit should only contain JCL compatible routines (no Forms etc)
+// and no JVCL units!
+// (ahuser) Unfortunately the QGraphics unit imports the QForms unit. Because
+// the JCL has the same problem with CLX it should not make any difference.
+
+uses
+ Classes, Graphics, LCLIntf, LCLType;
+
+(******************** NOT CONVERTED
+const
+ {$IFDEF MSWINDOWS}
+ PathDelim = '\';
+ DriveDelim = ':';
+ PathSep = ';';
+ AllFilesMask = '*.*';
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ PathDelim = '/';
+ AllFilesMask = '*';
+ {$ENDIF UNIX}
+ // Note: the else is on purpose, VCL is not defined for a console application
+ NullHandle = 0;
+
+{$IFDEF UNIX}
+type
+ TFileTime = Integer;
+{$ENDIF UNIX}
+
+function SendRectMessage(Handle: THandle; Msg: Integer; wParam: WPARAM; var R: TRect): Integer;
+function SendStructMessage(Handle: THandle; Msg: Integer; wParam: WPARAM; var Data): Integer;
+
+function ReadCharsFromStream(Stream: TStream; var Buf: array of Char; BufSize: Integer): Integer; // ANSI-Stream
+function WriteStringToStream(Stream: TStream; const Buf: string; BufSize: Integer): Integer; // ANSI-Stream
+
+const
+ DefaultDateOrder = doDMY;
+ CenturyOffset: Byte = 60;
+ NullDate: TDateTime = {-693594} 0;
+
+function USToLocalFloatStr(const Text: string): string;
+function StrToFloatUS(const Text: string): Extended;
+// StrToFloatUS uses US '.' as decimal seperator and ',' as thousand separator
+function StrToFloatUSDef(const Text: string; Default: Extended): Extended;
+
+function VarIsInt(Value: Variant): Boolean;
+ // VarIsInt returns VarIsOrdinal-[varBoolean]
+
+{ PosIdx returns the index of the first appearance of SubStr in Str. The search
+ starts at index "Index". }
+function PosIdx(const SubStr, S: string; Index: Integer = 0): Integer;
+{$IFNDEF CLR}
+function PosIdxW(const SubStr, S: WideString; Index: Integer = 0): Integer;
+{$ENDIF !CLR}
+function PosLastCharIdx(Ch: Char; const S: string; Index: Integer = 0): Integer;
+
+{ GetWordOnPos returns Word from string, S, on the cursor position, P}
+function GetWordOnPos(const S: string; const P: Integer): string;
+function GetWordOnPosW(const S: WideString; const P: Integer): WideString;
+function GetWordOnPos2(const S: string; P: Integer; var iBeg, iEnd: Integer): string;
+function GetWordOnPos2W(const S: WideString; P: Integer; var iBeg, iEnd: Integer): WideString;
+{ GetWordOnPosEx working like GetWordOnPos function, but
+ also returns Word position in iBeg, iEnd variables }
+function GetWordOnPosEx(const S: string; const P: Integer; var iBeg, iEnd: Integer): string;
+function GetWordOnPosExW(const S: WideString; const P: Integer; var iBeg, iEnd: Integer): WideString;
+function GetNextWordPosEx(const Text: string; StartIndex: Integer;
+ var iBeg, iEnd: Integer): string;
+function GetNextWordPosExW(const Text: WideString; StartIndex: Integer;
+ var iBeg, iEnd: Integer): WideString;
+procedure GetEndPosCaret(const Text: string; CaretX, CaretY: Integer;
+ var X, Y: Integer);
+{ GetEndPosCaret returns the caret position of the last char. For the position
+ after the last char of Text you must add 1 to the returned X value. }
+procedure GetEndPosCaretW(const Text: WideString; CaretX, CaretY: Integer;
+ var X, Y: Integer);
+{ GetEndPosCaret returns the caret position of the last char. For the position
+ after the last char of Text you must add 1 to the returned X value. }
+
+{ SubStrBySeparator returns substring from string, S, separated with Separator string}
+function SubStrBySeparator(const S: string; const Index: Integer; const Separator: string; StartIndex: Integer = 1): string;
+{$IFNDEF CLR}
+function SubStrBySeparatorW(const S: WideString; const Index: Integer; const Separator: WideString; StartIndex: Integer = 1): WideString;
+{$ENDIF !CLR}
+{ SubStrEnd same to previous function but Index numerated from the end of string }
+//function SubStrEnd(const S: string; const Index: Integer; const Separator: string): string;
+{ SubWord returns next Word from string, P, and offsets Pointer to the end of Word, P2 }
+{$IFDEF CLR}
+function SubWord(P: string; var P2: string): string;
+{$ELSE}
+function SubWord(P: PChar; var P2: PChar): string;
+{$ENDIF CLR}
+// function CurrencyByWord(Value: Currency): string;
+{ GetLineByPos returns the Line number, there
+ the symbol Pos is pointed. Lines separated with #13 symbol }
+function GetLineByPos(const S: string; const Pos: Integer): Integer;
+{ GetXYByPos is same as GetLineByPos, but returns X position in line as well}
+procedure GetXYByPos(const S: string; const Pos: Integer; var X, Y: Integer);
+procedure GetXYByPosW(const S: WideString; const Pos: Integer; var X, Y: Integer);
+{ ReplaceString searches for all substrings, OldPattern,
+ in a string, S, and replaces them with NewPattern }
+function ReplaceString(S: string; const OldPattern, NewPattern: string; StartIndex: Integer = 1): string;
+{$IFNDEF CLR}
+function ReplaceStringW(S: WideString; const OldPattern, NewPattern: WideString; StartIndex: Integer = 1): WideString;
+{$ENDIF !CLR}
+{ ConcatSep concatenate S1 and S2 strings with Separator.
+ if S = '' then separator not included }
+function ConcatSep(const S1, S2, Separator: string): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ ConcatLeftSep is same to previous function, but
+ strings concatenate right to left }
+function ConcatLeftSep(const S1, S2, Separator: string): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+
+{ Next 4 function for russian chars transliterating.
+ This functions are needed because Oem2Ansi and Ansi2Oem functions
+ sometimes suck }
+procedure Dos2Win(var S: string);
+procedure Win2Dos(var S: string);
+function Dos2WinRes(const S: string): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function Win2DosRes(const S: string): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function Win2Koi(const S: string): string;
+
+{ FillString fills the string Buffer with Count Chars }
+procedure FillString(var Buffer: string; Count: Integer; const Value: Char); overload;
+procedure FillString(var Buffer: string; StartIndex, Count: Integer; const Value: Char); overload;
+{ MoveString copies Count Chars from Source to Dest }
+procedure MoveString(const Source: string; var Dest: string; Count: Integer); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} overload;
+procedure MoveString(const Source: string; SrcStartIdx: Integer; var Dest: string;
+ DstStartIdx: Integer; Count: Integer); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} overload;
+{$IFNDEF CLR}
+{ FillWideChar fills Buffer with Count WideChars (2 Bytes) }
+procedure FillWideChar(var Buffer; Count: Integer; const Value: WideChar);
+{ MoveWideChar copies Count WideChars from Source to Dest }
+procedure MoveWideChar(const Source; var Dest; Count: Integer); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{$ENDIF !CLR}
+{ IsSubString() compares the sub string to the string. Indices are 1th based. }
+function IsSubString(const S: string; StartIndex: Integer; const SubStr: string): Boolean;
+
+{ Spaces returns string consists on N space chars }
+function Spaces(const N: Integer): string;
+{ AddSpaces adds spaces to string S, if its Length is smaller than N }
+function AddSpaces(const S: string; const N: Integer): string;
+{$IFNDEF CLR}
+function SpacesW(const N: Integer): WideString;
+function AddSpacesW(const S: WideString; const N: Integer): WideString;
+{$ENDIF !CLR}
+{ function LastDateRUS for russian users only }
+{ returns date relative to current date: 'äâà äíÿ íàçàä' }
+function LastDateRUS(const Dat: TDateTime): string;
+{ CurrencyToStr format Currency, Cur, using ffCurrency float format}
+function CurrencyToStr(const Cur: Currency): string;
+{ HasChar returns True, if Char, Ch, contains in string, S }
+function HasChar(const Ch: Char; const S: string): Boolean;
+function HasCharW(const Ch: WideChar; const S: WideString): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function HasAnyChar(const Chars: string; const S: string): Boolean;
+function CharInSet(const Ch: Char; const SetOfChar: TSysCharSet): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function CharInSetW(const Ch: WideChar; const SetOfChar: TSysCharSet): Boolean; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function CountOfChar(const Ch: Char; const S: string): Integer;
+function DefStr(const S: string; Default: string): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+
+{$IFNDEF CLR}
+{ StrLICompW2 is a faster replacement for JclUnicode.StrLICompW }
+function StrLICompW2(S1, S2: PWideChar; MaxLen: Integer): Integer;
+function StrPosW(S, SubStr: PWideChar): PWideChar;
+function StrLenW(S: PWideChar): Integer;
+{$ENDIF !CLR}
+function TrimW(const S: WideString): WideString; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function TrimLeftW(const S: WideString): WideString; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function TrimRightW(const S: WideString): WideString; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{**** files routines}
+procedure SetDelimitedText(List: TStrings; const Text: string; Delimiter: Char);
+
+const
+ {$IFDEF MSWINDOWS}
+ DefaultCaseSensitivity = False;
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ DefaultCaseSensitivity = True;
+ {$ENDIF UNIX}
+
+{ GetTempDir returns Windows temporary folder name }
+function GetTempDir: string;
+{ GenTempFileName returns temporary file name on
+ drive, there FileName is placed }
+function GenTempFileName(FileName: string): string;
+{ GenTempFileNameExt same to previous function, but
+ returning filename has given extension, FileExt }
+function GenTempFileNameExt(FileName: string; const FileExt: string): string;
+{ ClearDir clears folder Dir }
+function ClearDir(const Dir: string): Boolean;
+{ DeleteDir clears and than delete folder Dir }
+function DeleteDir(const Dir: string): Boolean;
+{ FileEquMask returns True if file, FileName,
+ is compatible with given dos file mask, Mask }
+function FileEquMask(FileName, Mask: TFileName;
+ CaseSensitive: Boolean = DefaultCaseSensitivity): Boolean;
+{ FileEquMasks returns True if file, FileName,
+ is compatible with given Masks.
+ Masks must be separated with SepPath (MSW: ';' / UNIX: ':') }
+function FileEquMasks(FileName, Masks: TFileName;
+ CaseSensitive: Boolean = DefaultCaseSensitivity): Boolean;
+function DeleteFiles(const Folder: TFileName; const Masks: string): Boolean;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+{ LZFileExpand expand file, FileSource,
+ into FileDest. Given file must be compressed, using MS Compress program }
+function LZFileExpand(const FileSource, FileDest: string): Boolean;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+{ FileGetInfo fills SearchRec record for specified file attributes}
+function FileGetInfo(FileName: TFileName; var SearchRec: TSearchRec): Boolean;
+{ HasSubFolder returns True, if folder APath contains other folders }
+function HasSubFolder(APath: TFileName): Boolean;
+{ IsEmptyFolder returns True, if there are no files or
+ folders in given folder, APath}
+function IsEmptyFolder(APath: TFileName): Boolean;
+{ AddSlash returns string with added slash Char to Dir parameter, if needed }
+function AddSlash(const Dir: TFileName): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ AddPath returns FileName with Path, if FileName not contain any path }
+function AddPath(const FileName, Path: TFileName): TFileName;
+function AddPaths(const PathList, Path: string): string;
+function ParentPath(const Path: TFileName): TFileName;
+function FindInPath(const FileName, PathList: string): TFileName;
+{ DeleteReadOnlyFile clears R/O file attribute and delete file }
+function DeleteReadOnlyFile(const FileName: TFileName): Boolean;
+{ HasParam returns True, if program running with specified parameter, Param }
+function HasParam(const Param: string): Boolean;
+function HasSwitch(const Param: string): Boolean;
+function Switch(const Param: string): string;
+{ ExePath returns ExtractFilePath(ParamStr(0)) }
+function ExePath: TFileName; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function CopyDir(const SourceDir, DestDir: TFileName): Boolean;
+//function FileTimeToDateTime(const FT: TFileTime): TDateTime;
+procedure FileTimeToDosDateTimeDWord(const FT: TFileTime; out Dft: DWORD);
+function MakeValidFileName(const FileName: TFileName; ReplaceBadChar: Char): TFileName;
+
+{**** Graphic routines }
+
+{ IsTTFontSelected returns True, if True Type font
+ is selected in specified device context }
+function IsTTFontSelected(const DC: HDC): Boolean;
+function KeyPressed(VK: Integer): Boolean;
+
+{ TrueInflateRect inflates rect in other method, than InflateRect API function }
+function TrueInflateRect(const R: TRect; const I: Integer): TRect;
+
+{**** Color routines }
+procedure RGBToHSV(R, G, B: Integer; var H, S, V: Integer);
+function RGBToBGR(Value: Cardinal): Cardinal;
+function ColorToPrettyName(Value: TColor): string;
+function PrettyNameToColor(const Value: string): TColor;
+
+{**** other routines }
+procedure SwapInt(var Int1, Int2: Integer); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function IntPower(Base, Exponent: Integer): Integer;
+{$IFNDEF CLR}
+function ChangeTopException(E: TObject): TObject; // Linux version writes error message to ErrOutput
+{$ENDIF !CLR}
+function StrToBool(const S: string): Boolean;
+
+function Var2Type(V: Variant; const DestVarType: Integer): Variant;
+function VarToInt(V: Variant): Integer;
+function VarToFloat(V: Variant): Double;
+
+{ following functions are not documented
+ because they do not work properly sometimes, so do not use them }
+// (rom) ReplaceStrings1, GetSubStr removed
+
+function GetLongFileName(const FileName: string): string;
+function FileNewExt(const FileName, NewExt: TFileName): TFileName;
+{$IFNDEF CLR}
+function GetParameter: string;
+function GetComputerID: string;
+{$ENDIF !CLR}
+function GetComputerName: string;
+
+{**** string routines }
+
+{ ReplaceAllStrings searches for all substrings, Words,
+ in a string, S, and replaces them with Frases with the same Index. }
+function ReplaceAllStrings(const S: string; Words, Frases: TStrings): string;
+{ ReplaceStrings searches the Word in a string, S, on PosBeg position,
+ in the list, Words, and if founds, replaces this Word
+ with string from another list, Frases, with the same Index,
+ and then update NewSelStart variable }
+function ReplaceStrings(const S: string; PosBeg, Len: Integer; Words, Frases: TStrings; var NewSelStart: Integer): string;
+{ CountOfLines calculates the lines count in a string, S,
+ each line must be separated from another with CrLf sequence }
+function CountOfLines(const S: string): Integer;
+{ DeleteLines deletes all lines from strings which in the words, words.
+ The word of will be deleted from strings. }
+procedure DeleteOfLines(Ss: TStrings; const Words: array of string);
+{ DeleteEmptyLines deletes all empty lines from strings, Ss.
+ Lines contained only spaces also deletes. }
+procedure DeleteEmptyLines(Ss: TStrings);
+{ SQLAddWhere addes or modifies existing where-statement, where,
+ to the strings, SQL.
+ Note: If strings SQL allready contains where-statement,
+ it must be started on the begining of any line }
+procedure SQLAddWhere(SQL: TStrings; const Where: string);
+
+{**** files routines - }
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+{ ResSaveToFile save resource named as Name with Typ type into file FileName.
+ Resource can be compressed using MS Compress program}
+function ResSaveToFile(const Typ, Name: string; const Compressed: Boolean; const FileName: string): Boolean;
+function ResSaveToFileEx(Instance: HINST; Typ, Name: PChar;
+ const Compressed: Boolean; const FileName: string): Boolean;
+function ResSaveToString(Instance: HINST; const Typ, Name: string;
+ var S: string): Boolean;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+{ IniReadSection read section, Section, from ini-file,
+ IniFileName, into strings, Ss.
+ This function reads ALL strings from specified section.
+ Note: TIninFile.ReadSection function reads only strings with '=' symbol.}
+function IniReadSection(const IniFileName: TFileName; const Section: string; Ss: TStrings): Boolean;
+{ LoadTextFile load text file, FileName, into string }
+function LoadTextFile(const FileName: TFileName): string;
+procedure SaveTextFile(const FileName: TFileName; const Source: string);
+{ ReadFolder reads files list from disk folder, Folder,
+ that are equal to mask, Mask, into strings, FileList}
+function ReadFolder(const Folder, Mask: TFileName; FileList: TStrings): Integer;
+function ReadFolders(const Folder: TFileName; FolderList: TStrings): Integer;
+
+{ RATextOut same with TCanvas.TextOut procedure, but
+ can clipping drawing with rectangle, RClip. }
+procedure RATextOut(Canvas: TCanvas; const R, RClip: TRect; const S: string);
+{ RATextOutEx same with RATextOut function, but
+ can calculate needed height for correct output }
+function RATextOutEx(Canvas: TCanvas; const R, RClip: TRect; const S: string; const CalcHeight: Boolean): Integer;
+{ RATextCalcHeight calculate needed height for
+ correct output, using RATextOut or RATextOutEx functions }
+function RATextCalcHeight(Canvas: TCanvas; const R: TRect; const S: string): Integer;
+{ Cinema draws some visual effect }
+procedure Cinema(Canvas: TCanvas; rS {Source}, rD {Dest}: TRect);
+{ Roughed fills rect with special 3D pattern }
+procedure Roughed(ACanvas: TCanvas; const ARect: TRect; const AVert: Boolean);
+{ BitmapFromBitmap creates new small bitmap from part
+ of source bitmap, SrcBitmap, with specified width and height,
+ AWidth, AHeight and placed on a specified Index, Index in the
+ source bitmap }
+function BitmapFromBitmap(SrcBitmap: TBitmap; const AWidth, AHeight, Index: Integer): TBitmap;
+{ TextWidth calculate text with for writing using standard desktop font }
+function TextWidth(const AStr: string): Integer;
+{ TextHeight calculate text height for writing using standard desktop font }
+function TextHeight(const AStr: string): Integer;
+
+procedure SetChildPropOrd(Owner: TComponent; const PropName: string; Value: Longint);
+procedure Error(const Msg: string);
+procedure ItemHtDrawEx(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean; var PlainItem: string;
+ var Width: Integer; CalcWidth: Boolean);
+{ example for Text parameter :
+ 'Item 1 bold italic ITALIC red green blue ' }
+function ItemHtDraw(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean): string;
+function ItemHtWidth(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean): Integer;
+function ItemHtPlain(const Text: string): string;
+{ ClearList - clears list of TObject }
+procedure ClearList(List: TList);
+
+{$IFNDEF CLR}
+procedure MemStreamToClipBoard(MemStream: TMemoryStream; const Format: Word);
+procedure ClipBoardToMemStream(MemStream: TMemoryStream; const Format: Word);
+{$ENDIF !CLR}
+
+{ RTTI support }
+function GetPropType(Obj: TObject; const PropName: string): TTypeKind;
+function GetPropStr(Obj: TObject; const PropName: string): string;
+function GetPropOrd(Obj: TObject; const PropName: string): Integer;
+function GetPropMethod(Obj: TObject; const PropName: string): TMethod;
+
+procedure PrepareIniSection(Ss: TStrings);
+{ following functions are not documented because
+ they are don't work properly, so don't use them }
+
+// (rom) from JvBandWindows to make it obsolete
+function PointL(const X, Y: Longint): TPointL; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+// (rom) from JvBandUtils to make it obsolete
+function iif(const Test: Boolean; const ATrue, AFalse: Variant): Variant; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+
+{$IFNDEF CLR}
+procedure CopyIconToClipboard(Icon: TIcon; BackColor: TColor);
+function CreateIconFromClipboard: TIcon;
+{$ENDIF !CLR}
+{ begin JvIconClipboardUtils }
+{ Icon clipboard routines }
+function CF_ICON: Word;
+{$IFNDEF CLR}
+procedure AssignClipboardIcon(Icon: TIcon);
+
+{ Real-size icons support routines (32-bit only) }
+procedure GetIconSize(Icon: HICON; var W, H: Integer);
+function CreateRealSizeIcon(Icon: TIcon): HICON;
+procedure DrawRealSizeIcon(Canvas: TCanvas; Icon: TIcon; X, Y: Integer);
+{end JvIconClipboardUtils }
+
+function CreateScreenCompatibleDC: HDC;
+{$ENDIF !CLR}
+
+{ begin JvRLE }
+
+// (rom) changed API for inclusion in JCL
+
+procedure RleCompressTo(InStream, OutStream: TStream);
+procedure RleDecompressTo(InStream, OutStream: TStream);
+procedure RleCompress(Stream: TStream);
+procedure RleDecompress(Stream: TStream);
+{ end JvRLE }
+
+{ begin JvDateUtil }
+function CurrentYear: Word; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function IsLeapYear(AYear: Integer): Boolean;
+function DaysInAMonth(const AYear, AMonth: Word): Word;
+function DaysPerMonth(AYear, AMonth: Integer): Integer;
+function FirstDayOfPrevMonth: TDateTime;
+function LastDayOfPrevMonth: TDateTime;
+function FirstDayOfNextMonth: TDateTime;
+function ExtractDay(ADate: TDateTime): Word;
+function ExtractMonth(ADate: TDateTime): Word;
+function ExtractYear(ADate: TDateTime): Word;
+function IncDate(ADate: TDateTime; Days, Months, Years: Integer): TDateTime;
+function IncDay(ADate: TDateTime; Delta: Integer): TDateTime; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+function IncMonth(ADate: TDateTime; Delta: Integer): TDateTime;
+function IncYear(ADate: TDateTime; Delta: Integer): TDateTime;
+function ValidDate(ADate: TDateTime): Boolean;
+procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word);
+function MonthsBetween(Date1, Date2: TDateTime): Double;
+function DaysInPeriod(Date1, Date2: TDateTime): Longint;
+{ Count days between Date1 and Date2 + 1, so if Date1 = Date2 result = 1 }
+function DaysBetween(Date1, Date2: TDateTime): Longint;
+{ The same as previous but if Date2 < Date1 result = 0 }
+function IncTime(ATime: TDateTime; Hours, Minutes, Seconds, MSecs: Integer): TDateTime;
+function IncHour(ATime: TDateTime; Delta: Integer): TDateTime;
+function IncMinute(ATime: TDateTime; Delta: Integer): TDateTime;
+function IncSecond(ATime: TDateTime; Delta: Integer): TDateTime;
+function IncMSec(ATime: TDateTime; Delta: Integer): TDateTime;
+function CutTime(ADate: TDateTime): TDateTime; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE} { Set time to 00:00:00:00 }
+
+{ String to date conversions }
+function GetDateOrder(const DateFormat: string): TDateOrder;
+function MonthFromName(const S: string; MaxLen: Byte): Byte;
+function StrToDateDef(const S: string; Default: TDateTime): TDateTime;
+function StrToDateFmt(const DateFormat, S: string): TDateTime;
+function StrToDateFmtDef(const DateFormat, S: string; Default: TDateTime): TDateTime;
+function DefDateFormat(AFourDigitYear: Boolean): string;
+function DefDateMask(BlanksChar: Char; AFourDigitYear: Boolean): string;
+
+function FormatLongDate(Value: TDateTime): string;
+function FormatLongDateTime(Value: TDateTime): string;
+{ end JvDateUtil }
+{$IFDEF CLR}
+function BufToBinStr(const Buf: TBytes; BufSize: Integer): string;
+function BinStrToBuf(Value: string; Buf: TBytes; BufSize: Integer): Integer;
+{$ELSE}
+function BufToBinStr(Buf: Pointer; BufSize: Integer): string;
+function BinStrToBuf(Value: string; Buf: Pointer; BufSize: Integer): Integer;
+{$ENDIF CLR}
+
+
+{ begin JvStrUtils }
+
+ { ** Common string handling routines ** }
+
+{$IFDEF UNIX}
+function iconversion(InP: PChar; OutP: Pointer; InBytes, OutBytes: Cardinal;
+ const ToCode, FromCode: string): Boolean;
+function iconvString(const S, ToCode, FromCode: string): string;
+function iconvWideString(const S: WideString; const ToCode, FromCode: string): WideString;
+function OemStrToAnsi(const S: string): string;
+function AnsiStrToOem(const S: string): string;
+{$ENDIF UNIX}
+
+function StrToOem(const AnsiStr: string): string;
+{ StrToOem translates a string from the Windows character set into the
+ OEM character set. }
+function OemToAnsiStr(const OemStr: string): string;
+{ OemToAnsiStr translates a string from the OEM character set into the
+ Windows character set. }
+function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
+{ EmptyStr returns True if the given string contains only character
+ from the EmptyChars. }
+function ReplaceStr(const S, Srch, Replace: string): string;
+{ Returns string with every occurrence of Srch string replaced with
+ Replace string. }
+function DelSpace(const S: string): string;
+{ DelSpace return a string with all white spaces removed. }
+function DelChars(const S: string; Chr: Char): string;
+{ DelChars return a string with all Chr characters removed. }
+function DelBSpace(const S: string): string;
+{ DelBSpace trims leading spaces from the given string. }
+function DelESpace(const S: string): string;
+{ DelESpace trims trailing spaces from the given string. }
+function DelRSpace(const S: string): string;
+{ DelRSpace trims leading and trailing spaces from the given string. }
+function DelSpace1(const S: string): string;
+{ DelSpace1 return a string with all non-single white spaces removed. }
+function Tab2Space(const S: string; Numb: Byte): string;
+{ Tab2Space converts any tabulation character in the given string to the
+ Numb spaces characters. }
+function NPos(const C: string; S: string; N: Integer): Integer;
+{ NPos searches for a N-th position of substring C in a given string. }
+function MakeStr(C: Char; N: Integer): string; overload;
+{$IFNDEF CLR}
+function MakeStr(C: WideChar; N: Integer): WideString; overload;
+{$ENDIF !CLR}
+function MS(C: Char; N: Integer): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ MakeStr return a string of length N filled with character C. }
+function AddChar(C: Char; const S: string; N: Integer): string;
+{ AddChar return a string left-padded to length N with characters C. }
+function AddCharR(C: Char; const S: string; N: Integer): string;
+{ AddCharR return a string right-padded to length N with characters C. }
+function LeftStr(const S: string; N: Integer): string;
+{ LeftStr return a string right-padded to length N with blanks. }
+function RightStr(const S: string; N: Integer): string;
+{ RightStr return a string left-padded to length N with blanks. }
+function CenterStr(const S: string; Len: Integer): string;
+{ CenterStr centers the characters in the string based upon the
+ Len specified. }
+function CompStr(const S1, S2: string): Integer; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ CompStr compares S1 to S2, with case-sensitivity. The return value is
+ -1 if S1 < S2, 0 if S1 = S2, or 1 if S1 > S2. }
+function CompText(const S1, S2: string): Integer; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ CompText compares S1 to S2, without case-sensitivity. The return value
+ is the same as for CompStr. }
+function Copy2Symb(const S: string; Symb: Char): string;
+{ Copy2Symb returns a substring of a string S from begining to first
+ character Symb. }
+function Copy2SymbDel(var S: string; Symb: Char): string;
+{ Copy2SymbDel returns a substring of a string S from begining to first
+ character Symb and removes this substring from S. }
+function Copy2Space(const S: string): string;
+{ Copy2Symb returns a substring of a string S from begining to first
+ white space. }
+function Copy2SpaceDel(var S: string): string;
+{ Copy2SpaceDel returns a substring of a string S from begining to first
+ white space and removes this substring from S. }
+function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
+{ Returns string, with the first letter of each word in uppercase,
+ all other letters in lowercase. Words are delimited by WordDelims. }
+function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
+{ WordCount given a set of word delimiters, returns number of words in S. }
+function WordPosition(const N: Integer; const S: string;
+ const WordDelims: TSysCharSet): Integer;
+{ Given a set of word delimiters, returns start position of N'th word in S. }
+function ExtractWord(N: Integer; const S: string;
+ const WordDelims: TSysCharSet): string;
+function ExtractWordPos(N: Integer; const S: string;
+ const WordDelims: TSysCharSet; var Pos: Integer): string;
+function ExtractDelimited(N: Integer; const S: string;
+ const Delims: TSysCharSet): string;
+{ ExtractWord, ExtractWordPos and ExtractDelimited given a set of word
+ delimiters, return the N'th word in S. }
+function ExtractSubstr(const S: string; var Pos: Integer;
+ const Delims: TSysCharSet): string;
+{ ExtractSubstr given a set of word delimiters, returns the substring from S,
+ that started from position Pos. }
+function IsWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
+{ IsWordPresent given a set of word delimiters, returns True if word W is
+ present in string S. }
+function QuotedString(const S: string; Quote: Char): string;
+{ QuotedString returns the given string as a quoted string, using the
+ provided Quote character. }
+function ExtractQuotedString(const S: string; Quote: Char): string;
+{ ExtractQuotedString removes the Quote characters from the beginning and
+ end of a quoted string, and reduces pairs of Quote characters within
+ the quoted string to a single character. }
+function FindPart(const HelpWilds, InputStr: string): Integer;
+{ FindPart compares a string with '?' and another, returns the position of
+ HelpWilds in InputStr. }
+function IsWild(InputStr, Wilds: string; IgnoreCase: Boolean): Boolean;
+{ IsWild compares InputString with WildCard string and returns True
+ if corresponds. }
+function XorString(const Key, Src: ShortString): ShortString;
+function XorEncode(const Key, Source: string): string;
+function XorDecode(const Key, Source: string): string;
+
+{ ** Command line routines ** }
+
+function GetCmdLineArg(const Switch: string; ASwitchChars: TSysCharSet): string;
+
+{ ** Numeric string handling routines ** }
+
+function Numb2USA(const S: string): string;
+{ Numb2USA converts numeric string S to USA-format. }
+function Dec2Hex(N: Longint; A: Byte): string; {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF SUPPORTS_INLINE}
+{ Dec2Hex converts the given value to a hexadecimal string representation
+ with the minimum number of digits (A) specified. }
+function Hex2Dec(const S: string): Longint;
+{ Hex2Dec converts the given hexadecimal string to the corresponding integer
+ value. }
+function Dec2Numb(N: Int64; A, B: Byte): string;
+{ Dec2Numb converts the given value to a string representation with the
+ base equal to B and with the minimum number of digits (A) specified. }
+function Numb2Dec(S: string; B: Byte): Int64;
+{ Numb2Dec converts the given B-based numeric string to the corresponding
+ integer value. }
+function IntToBin(Value: Longint; Digits, Spaces: Integer): string;
+{ IntToBin converts the given value to a binary string representation
+ with the minimum number of digits specified. }
+function IntToRoman(Value: Longint): string;
+{ IntToRoman converts the given value to a roman numeric string
+ representation. }
+function RomanToInt(const S: string): Longint;
+{ RomanToInt converts the given string to an integer value. If the string
+ doesn't contain a valid roman numeric value, the 0 value is returned. }
+
+function FindNotBlankCharPos(const S: string): Integer;
+function FindNotBlankCharPosW(const S: WideString): Integer;
+function AnsiChangeCase(const S: string): string;
+function WideChangeCase(const S: string): string;
+
+{$IFNDEF CLR}
+function StartsText(const SubStr, S: string): Boolean;
+function EndsText(const SubStr, S: string): Boolean;
+
+function DequotedStr(const S: string; QuoteChar: Char = ''''): string;
+function AnsiDequotedStr(const S: AnsiString; AQuote: AnsiChar): AnsiString;
+{$ENDIF !CLR}
+
+{end JvStrUtils}
+
+{$IFDEF UNIX}
+function GetTempFileName(const Prefix: string): string;
+{$ENDIF UNIX}
+
+{ begin JvFileUtil }
+function FileDateTime(const FileName: string): TDateTime;
+function HasAttr(const FileName: string; Attr: Integer): Boolean;
+function DeleteFilesEx(const FileMasks: array of string): Boolean;
+function NormalDir(const DirName: string): string;
+function RemoveBackSlash(const DirName: string): string; // only for Windows/DOS Paths
+function ValidFileName(const FileName: string): Boolean;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+function FileLock(Handle: Integer; Offset, LockSize: Longint): Integer; overload;
+function FileLock(Handle: Integer; Offset, LockSize: Int64): Integer; overload;
+function FileUnlock(Handle: Integer; Offset, LockSize: Longint): Integer; overload;
+function FileUnlock(Handle: Integer; Offset, LockSize: Int64): Integer; overload;
+{$ENDIF MSWINDOWS}
+function GetWindowsDir: string;
+{$ENDIF !CLR}
+function GetSystemDir: string;
+
+function ShortToLongFileName(const ShortName: string): string;
+function LongToShortFileName(const LongName: string): string;
+function ShortToLongPath(const ShortName: string): string;
+function LongToShortPath(const LongName: string): string;
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+procedure CreateFileLink(const FileName, DisplayName: string; Folder: Integer);
+procedure DeleteFileLink(const DisplayName: string; Folder: Integer);
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+{ end JvFileUtil }
+
+// Works like PtInRect but includes all edges in comparision
+function PtInRectInclusive(R: TRect; Pt: TPoint): Boolean;
+// Works like PtInRect but excludes all edges from comparision
+function PtInRectExclusive(R: TRect; Pt: TPoint): Boolean;
+
+function FourDigitYear: Boolean; {$IFDEF SUPPORTS_DEPRECATED} deprecated; {$ENDIF}
+function IsFourDigitYear: Boolean;
+
+{ moved from JvJVCLUTils }
+
+//Open an object with the shell (url or something like that)
+function OpenObject(const Value: string): Boolean; overload;
+{$IFNDEF CLR}
+function OpenObject(Value: PChar): Boolean; overload;
+{$ENDIF !CLR}
+
+{$IFDEF MSWINDOWS}
+//Raise the last Exception
+procedure RaiseLastWin32; overload;
+procedure RaiseLastWin32(const Text: string); overload;
+//Raise the last Exception with a small comment from your part
+
+{ GetFileVersion returns the most significant 32 bits of a file's binary
+ version number. Typically, this includes the major and minor version placed
+ together in one 32-bit Integer. It generally does not include the release
+ or build numbers. It returns 0 if it failed. }
+function GetFileVersion(const AFileName: string): Cardinal;
+{$EXTERNALSYM GetFileVersion}
+
+//Get version of Shell.dll
+function GetShellVersion: Cardinal;
+{$EXTERNALSYM GetShellVersion}
+
+{$IFNDEF CLR}
+// CD functions
+procedure OpenCdDrive;
+procedure CloseCdDrive;
+
+// returns True if Drive is accessible
+function DiskInDrive(Drive: Char): Boolean;
+{$ENDIF !CLR}
+{$ENDIF MSWINDOWS}
+
+//Same as linux function ;)
+procedure PError(const Text: string);
+
+// execute a program without waiting
+procedure Exec(const FileName, Parameters, Directory: string);
+// execute a program and wait for it to finish
+function ExecuteAndWait(const CommandLine, WorkingDirectory: string; Visibility: Integer = SW_SHOW): Integer;
+
+
+// returns True if this is the first instance of the program that is running
+function FirstInstance(const ATitle: string): Boolean;
+// restores a window based on it's classname and Caption. Either can be left empty
+// to widen the search
+procedure RestoreOtherInstance(const MainFormClassName, MainFormCaption: string);
+
+// manipulate the traybar and start button
+procedure HideTraybar;
+procedure ShowTraybar;
+{$IFNDEF CLR}
+procedure ShowStartButton(Visible: Boolean = True);
+{$ENDIF !CLR}
+
+// (rom) SC_MONITORPOWER is documented as Windows 95 only
+// (rom) better do some testing
+// set monitor functions
+procedure MonitorOn;
+procedure MonitorOff;
+procedure LowPower;
+
+// send a key to the window named AppName
+function SendKey(const AppName: string; Key: Char): Boolean;
+
+{$IFDEF MSWINDOWS}
+
+{$IFNDEF CLR}
+// returns a list of all windows currently visible, the Objects property is filled with their window handle
+procedure GetVisibleWindows(List: TStrings);
+// associates an extension to a specific program
+procedure AssociateExtension(const IconPath, ProgramName, Path, Extension: string);
+
+procedure AddToRecentDocs(const FileName: string);
+{$ENDIF !CLR}
+function GetRecentDocs: TStringList;
+{$ENDIF MSWINDOWS}
+
+// JvComponentFunctions
+{-----------------------------------------------------------------------------
+Comments:
+ Functions pulled out of MemoEx, used in MemoEx.pas and TypedEdit.pas
+
+ This unit has low internal cohesion (ie it contains routines that do all kinds of stuff)
+ Some are very good candidates for wider reuse
+ some are quite specific to the controls
+ and in a larger library this unit would be broken up
+
+ I have tried to group related functions together
+}
+
+function CharIsMoney(const Ch: AnsiChar): Boolean;
+
+{ there is a STrToIntDef provided by Delphi, but no "safe" versions of
+ StrToFloat or StrToCurr }
+// Note: before using StrToFloatDef, please be aware that it will ignore
+// any character that is not a valid character for a float, which is different
+// from what the one in Delphi 6 up is doing. This has been documented in Mantis
+// issue# 2935: http://homepages.borland.com/jedi/issuetracker/view.php?id=2935
+function StrToFloatDef(const Str: string; Def: Extended): Extended;
+function StrToCurrDef(const Str: string; Def: Currency): Currency;
+function IntToExtended(I: Integer): Extended;
+
+{ GetChangedText works out the new text given the current cursor pos & the key pressed
+ It is not very useful in other contexts,
+ but it is in this unit as it is needed in both MemoEx and TypedEdit }
+function GetChangedText(const Text: string; SelStart, SelLength: Integer; Key: Char): string;
+
+function MakeYear4Digit(Year, Pivot: Integer): Integer;
+
+function StrIsInteger(const S: string): Boolean;
+function StrIsFloatMoney(const Ps: string): Boolean;
+function StrIsDateTime(const Ps: string): Boolean;
+
+function PreformatDateString(Ps: string): string;
+
+function BooleanToInteger(const B: Boolean): Integer;
+function StringToBoolean(const Ps: string): Boolean;
+
+function SafeStrToDateTime(const Ps: string): TDateTime;
+function SafeStrToDate(const Ps: string): TDateTime;
+function SafeStrToTime(const Ps: string): TDateTime;
+
+function StrDelete(const psSub, psMain: string): string;
+
+ { returns the fractional value of pcValue}
+function TimeOnly(pcValue: TDateTime): TTime;
+{ returns the integral value of pcValue }
+function DateOnly(pcValue: TDateTime): TDate;
+
+type
+ TdtKind = (dtkDateOnly, dtkTimeOnly, dtkDateTime);
+
+const
+ { TDateTime value used to signify Null value}
+ NullEquivalentDate: TDateTime = 0.0;
+
+function DateIsNull(const pdtValue: TDateTime; const pdtKind: TdtKind): Boolean;
+// Replacement for Win32Check to avoid platform specific warnings in D6
+function OSCheck(RetVal: Boolean): Boolean;
+
+{ Shortens a fully qualified Path name so that it can be drawn with a specified length limit.
+ Same as FileCtrl.MinimizeName in functionality (but not implementation). Included here to
+ not be forced to use FileCtrl unnecessarily }
+function MinimizeFileName(const FileName: string; Canvas: TCanvas; MaxLen: Integer): string;
+function MinimizeText(const Text: string; Canvas: TCanvas; MaxWidth: Integer): string;
+{ MinimizeString trunactes long string, S, and appends
+ '...' symbols, if Length of S is more than MaxLen }
+function MinimizeString(const S: string; const MaxLen: Integer): string;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+{ RunDLL32 runs a function in a DLL using the utility rundll32.exe (on NT) or rundll.exe (on Win95/98)
+ ModuleName is the name of the DLL to load, FuncName is the function to call and CmdLine is
+ the command-line parameters (if any) to send to the function. Set WaitForCompletion to False to
+ return immediately after the call.
+ CmdShow should be one of the SW_SHOWXXXX constants and defaults SW_SHOWDEFAULT
+ Return value:
+ if WaitForCompletion is True, returns True if the wait didn't return WAIT_FAILED
+ if WaitForCompletion is False, returns True if the process could be created
+ To get information on why RunDLL32 might have failed, call GetLastError
+ To get more info on what can actually be called using rundll32.exe, take a look at
+ http://www.dx21.com/SCRIPTING/RUNDLL32/REFGUIDE.ASP?NTI=4&SI=6
+}
+type
+ // the signature of procedures in DLL's that can be called using rundll32.exe
+ TRunDLL32Proc = procedure(Handle: THandle; HInstance: HMODULE; CmdLine: PChar; CmdShow: Integer); stdcall;
+
+function RunDLL32(const ModuleName, FuncName, CmdLine: string; WaitForCompletion: Boolean; CmdShow: Integer =
+ SW_SHOWDEFAULT): Boolean;
+{ RunDll32Internal does the same as RunDLL32 but does not use the RunDLL32.exe application to do it.
+ Rather it loads the DLL, gets a pointer to the function in FuncName and calls it with the given parameters.
+ Because of this behaviour, RunDll32Internal works slightly different from RunDLL32:
+ * It doesn't return any value indicating success/failure
+ * There is no WaitForCompletion parameter (but see comment below on how to circumvent this)
+ * You must pass in a valid windows handle in Wnd. Note that if you pass 0, the call might fail, with no indication of why.
+ * To simulate WaitForCompletion = False, pass the return value of GetDesktopWindow as the Wnd parameter,
+ * To simulate WaitForCompletion = True, pass the handle of the calling window (f ex the form you are calling the procedure from)
+ * If you try to call a function in a DLL that doesn't use the TRunDLL32Proc signature, your program
+ might crash. Using the RunDLL32 function protects you from any problems with calling the wrong functions
+ (a dialog is displayed if do something wrong)
+ * RunDll32Internal is slightly faster but RunDLL32 is safer
+}
+procedure RunDll32Internal(Wnd: THandle; const DLLName, FuncName, CmdLine: string; CmdShow: Integer = SW_SHOWDEFAULT);
+{ GetDLLVersion loads DLLName, gets a pointer to the DLLVersion function and calls it, returning the major and minor version values
+from the function. Returns False if the DLL couldn't be loaded or if GetDLLVersion couldn't be found. }
+function GetDLLVersion(const DLLName: string; var pdwMajor, pdwMinor: Integer): Boolean;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+{$IFNDEF CLR}
+procedure ResourceNotFound(ResID: PChar);
+{$ENDIF !CLR}
+
+******************** NOT CONVERTED *)
+
+function RectWidth(R: TRect): Integer;
+function RectHeight(R: TRect): Integer;
+function CompareRect(const R1, R2: TRect): Boolean;
+
+(******************** NOT CONVERTED
+{$IFDEF MSWINDOWS}
+{$IFNDEF CLR}
+procedure FreeUnusedOle;
+function GetWindowsVersion: string;
+function LoadDLL(const LibName: string): THandle;
+function RegisterServer(const ModuleName: string): Boolean;
+function UnregisterServer(const ModuleName: string): Boolean;
+{$ENDIF !CLR}
+{$ENDIF MSWINDOWS}
+
+{ String routines }
+function GetEnvVar(const VarName: string): string;
+function AnsiUpperFirstChar(const S: AnsiString): AnsiString;
+{$IFNDEF CLR}
+function StringToPChar(var S: string): PChar;
+function StrPAlloc(const S: string): PChar;
+{$ENDIF !CLR}
+procedure SplitCommandLine(const CmdLine: string; var ExeName, Params: string);
+function DropT(const S: string): string;
+
+{ Memory routines }
+
+{$IFNDEF CLR}
+function AllocMemo(Size: Longint): Pointer;
+function ReallocMemo(fpBlock: Pointer; Size: Longint): Pointer;
+procedure FreeMemo(var fpBlock: Pointer);
+function GetMemoSize(fpBlock: Pointer): Longint;
+function CompareMem(fpBlock1, fpBlock2: Pointer; Size: Cardinal): Boolean;
+{$ENDIF !CLR}
+
+{ Manipulate huge pointers routines }
+
+{$IFNDEF CLR}
+procedure HugeInc(var HugePtr: Pointer; Amount: Longint);
+procedure HugeDec(var HugePtr: Pointer; Amount: Longint);
+function HugeOffset(HugePtr: Pointer; Amount: Longint): Pointer;
+procedure HugeMove(Base: Pointer; Dst, Src, Size: Longint);
+procedure HMemCpy(DstPtr, SrcPtr: Pointer; Amount: Longint);
+{$ENDIF !CLR}
+
+{$IFNDEF CLR}
+function WindowClassName(Wnd: THandle): string;
+{$ENDIF !CLR}
+
+procedure SwitchToWindow(Wnd: THandle; Restore: Boolean);
+procedure ActivateWindow(Wnd: THandle);
+procedure ShowWinNoAnimate(Handle: THandle; CmdShow: Integer);
+procedure KillMessage(Wnd: THandle; Msg: Cardinal);
+
+{ SetWindowTop put window to top without recreating window }
+procedure SetWindowTop(const Handle: THandle; const Top: Boolean);
+procedure CenterWindow(Wnd: THandle);
+function MakeVariant(const Values: array of Variant): Variant;
+
+{ Convert dialog units to pixels and backwards }
+
+{$IFDEF MSWINDOWS}
+function DialogUnitsToPixelsX(DlgUnits: Word): Word;
+function DialogUnitsToPixelsY(DlgUnits: Word): Word;
+function PixelsToDialogUnitsX(PixUnits: Word): Word;
+function PixelsToDialogUnitsY(PixUnits: Word): Word;
+{$ENDIF MSWINDOWS}
+
+function GetUniqueFileNameInDir(const Path, FileNameMask: string): string;
+
+{$IFNDEF CLR}
+
+{$IFDEF BCB}
+function FindPrevInstance(const MainFormClass: ShortString;
+ const ATitle: string): THandle;
+function ActivatePrevInstance(const MainFormClass: ShortString;
+ const ATitle: string): Boolean;
+{$ELSE}
+function FindPrevInstance(const MainFormClass, ATitle: string): THandle;
+function ActivatePrevInstance(const MainFormClass, ATitle: string): Boolean;
+{$ENDIF BCB}
+
+
+{$IFDEF MSWINDOWS}
+{ BrowseForFolderNative displays Browse For Folder dialog }
+function BrowseForFolderNative(const Handle: THandle; const Title: string; var Folder: string): Boolean;
+{$ENDIF MSWINDOWS}
+
+
+procedure AntiAlias(Clip: TBitmap);
+procedure AntiAliasRect(Clip: TBitmap; XOrigin, YOrigin,
+ XFinal, YFinal: Integer);
+
+{$ENDIF !CLR}
+
+
+{$IFNDEF CLR}
+procedure CopyRectDIBits(ACanvas: TCanvas; const DestRect: TRect;
+ ABitmap: TBitmap; const SourceRect: TRect);
+{$ENDIF !CLR}
+function IsTrueType(const FontName: string): Boolean;
+
+
+// Removes all non-numeric characters from AValue and returns
+// the resulting string
+function TextToValText(const AValue: string): string;
+
+// VisualCLX compatibility functions
+function DrawText(DC: HDC; const Text: TCaption; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+******************** NOT CONVERTED *)
+
+function DrawText(Canvas: TCanvas; const Text: string; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+function DrawText(Canvas: TCanvas; Text: PAnsiChar; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+
+(******************** NOT CONVERTED
+function DrawTextEx(Canvas: TCanvas; lpchText: PChar; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+function DrawTextEx(Canvas: TCanvas; const Text: string; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+{$IFDEF COMPILER6_UP}
+function DrawText(Canvas: TCanvas; const Text: WideString; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+function DrawTextEx(Canvas: TCanvas; const Text: WideString; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+{$ENDIF COMPILER6_UP}
+{$ENDIF !CLR}
+
+{$IFNDEF CLR}
+function DrawTextW(Canvas: TCanvas; const Text: WideString; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+function DrawTextW(Canvas: TCanvas; Text: PWideChar; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+function DrawTextExW(Canvas: TCanvas; lpchText: PWideChar; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+function DrawTextExW(Canvas: TCanvas; const Text: WideString; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+{$ENDIF !CLR}
+
+type
+ {$IFDEF COMPILER6_UP}
+ RasterOp = (
+ RasterOp_CopyROP,
+ RasterOp_OrROP,
+ RasterOp_XorROP,
+ RasterOp_NotAndROP,
+ RasterOp_EraseROP = 3,
+ RasterOp_NotCopyROP,
+ RasterOp_NotOrROP,
+ RasterOp_NotXorROP,
+ RasterOp_AndROP,
+ RasterOp_NotEraseROP = 7,
+ RasterOp_NotROP,
+ RasterOp_ClearROP,
+ RasterOp_SetROP,
+ RasterOp_NopROP,
+ RasterOp_AndNotROP,
+ RasterOp_OrNotROP,
+ RasterOp_NandROP,
+ RasterOp_NorROP,
+ RasterOp_LastROP = 15);
+ {$ELSE}
+ // Delphi 5 and below doesn't support values in enums
+ RasterOp = Integer;
+const
+ RasterOp_CopyROP = 0;
+ RasterOp_OrROP = 1;
+ RasterOp_XorROP = 2;
+ RasterOp_NotAndROP = 3;
+ RasterOp_EraseROP = 3;
+ RasterOp_NotCopyROP = 4;
+ RasterOp_NotOrROP = 5;
+ RasterOp_NotXorROP = 6;
+ RasterOp_AndROP = 7;
+ RasterOp_NotEraseROP = 7;
+ RasterOp_NotROP = 8;
+ RasterOp_ClearROP = 9;
+ RasterOp_SetROP = 10;
+ RasterOp_NopROP = 11;
+ RasterOp_AndNotROP = 12;
+ RasterOp_OrNotROP = 13;
+ RasterOp_NandROP = 14;
+ RasterOp_NorROP = 15;
+ RasterOp_LastROP = 15;
+ {$ENDIF COMPILER6_UP}
+
+function BitBlt(DestCanvas: TCanvas; X, Y, Width, Height: Integer; SrcCanvas: TCanvas;
+ XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean = True): LongBool;overload;
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
+ XSrc, YSrc: Integer; Rop: RasterOp; IgnoreMask: Boolean): LongBool; overload;
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
+ XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean): LongBool; overload;
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
+ XSrc, YSrc: Integer; WinRop: Cardinal): LongBool; overload;
+
+
+
+function IsEqualGUID(const IID1, IID2: TGUID): Boolean;
+{$EXTERNALSYM IsEqualGUID}
+
+
+{$IFNDEF BCB}
+{$IFDEF COMPILER5}
+{ These functions simply call their JvVCL5Utils equivalents }
+
+function TryStrToInt(const S: string; out Value: Integer): Boolean;
+function TryStrToDateTime(const S: string; out Date: TDateTime): Boolean;
+function StrToDateTimeDef(const S: string; Default: TDateTime): TDateTime;
+// function StrToFloatDef(const Str: string; Default: Extended): Extended;
+procedure RaiseLastOSError;
+function IncludeTrailingPathDelimiter(const APath: string): string;
+function ExcludeTrailingPathDelimiter(const APath: string): string;
+function DirectoryExists(const Name: string): Boolean;
+function ForceDirectories(Dir: string): Boolean;
+function SameFileName(const FN1, FN2: string): Boolean;
+
+function WideCompareText(const S1, S2: WideString): Integer;
+function WideUpperCase(const S: WideString): WideString;
+function WideLowerCase(const S: WideString): WideString;
+function CompareDateTime(const A, B: TDateTime): Integer;
+
+// StrUtils
+function AnsiStartsText(const SubText, Text: string): Boolean;
+function AnsiEndsText(const SubText, Text: string): Boolean;
+function AnsiStartsStr(const SubStr, Str: string): Boolean;
+function AnsiEndsStr(const SubStr, Str: string): Boolean;
+
+// Math
+type
+ TValueSign = JvVCL5Utils.TValueSign;
+
+const
+ NegativeValue = Low(TValueSign);
+ ZeroValue = 0;
+ PositiveValue = High(TValueSign);
+
+// Variants
+function VarIsStr(const V: Variant): Boolean;
+{$ENDIF COMPILER5}
+{$ENDIF !BCB}
+
+// Containers
+type
+ TIntegerListChange = procedure(Sender: TObject; Item: Integer; Action: TListNotification) of object;
+
+ TIntegerList = class(TList)
+ private
+ FOnChange: TIntegerListChange;
+ FLoading: Boolean;
+
+ function GetItem(Index: Integer): Integer;
+ procedure SetItem(Index: Integer; const Value: Integer);
+ protected
+ procedure Notify(Ptr: Pointer; Action: TListNotification); override;
+ procedure DoChange(Item: Integer; Action: TListNotification);
+ public
+ {$IFDEF COMPILER5}
+ procedure Assign(Source: TList);
+ {$ENDIF COMPILER5}
+
+ // To be used with DefineProperties in client classes.
+ procedure ReadData(Reader: TReader);
+ procedure WriteData(Writer: TWriter);
+ property Loading: Boolean read FLoading;
+
+ // Overloaded to accept/return Integer instead of Pointer.
+ function Add(Value: Integer): Integer;
+ function Extract(Item: Integer): Integer;
+ function First: Integer;
+ function IndexOf(Item: Integer): Integer;
+ procedure Insert(Index: Integer; Item: Integer);
+ function Last: Integer;
+ function Remove(Item: Integer): Integer;
+ property Items[Index: Integer]: Integer read GetItem write SetItem; default;
+
+ property OnChange: TIntegerListChange read FOnChange write FOnChange;
+ end;
+
+type
+ TCollectionSortProc = function(Item1, Item2: TCollectionItem): Integer;
+
+procedure CollectionSort(Collection: Classes.TCollection; SortProc: TCollectionSortProc);
+
+{$IFDEF COMPILER5}
+function SecondsBetween(const Now: TDateTime; const FTime: TDateTime): Integer;
+{$ENDIF COMPILER5}
+
+******************** NOT CONVERTED *)
+
+implementation
+
+(******************** NOT CONVERTED
+uses
+ {$IFDEF HAS_UNIT_RTLCONSTS}
+ RTLConsts,
+ {$ENDIF HAS_UNIT_RTLCONSTS}
+ SysConst,
+ {$IFDEF MSWINDOWS}
+ ComObj, ShellAPI, MMSystem, Registry,
+ {$ENDIF MSWINDOWS}
+ Consts,
+ {$IFNDEF NO_JCL}
+ JclStrings, JclSysInfo,
+ {$ENDIF !NO_JCL}
+ Math;
+
+{$IFDEF CLR}
+type
+ PPropInfo = TPropInfo;
+{$ENDIF CLR}
+
+const
+ Separators: TSysCharSet = [#00, ' ', '-', #13, #10, '.', ',', '/', '\', '#', '"', '''',
+ ':', '+', '%', '*', '(', ')', ';', '=', '{', '}', '[', ']', '{', '}', '<', '>'];
+ {$IFDEF MSWINDOWS}
+ RC_OpenCDDrive = 'set cdaudio door open wait';
+ RC_CloseCDDrive = 'set cdaudio door closed wait';
+ RC_ShellName = 'Shell_TrayWnd';
+ RC_DefaultIcon = 'DefaultIcon';
+ {$ENDIF MSWINDOWS}
+
+resourcestring
+ // (p3) duplicated from JvConsts since this unit should not rely on JVCL at all
+ RsEPropertyNotExists = 'Property "%s" does not exist';
+ RsEInvalidPropertyType = 'Property "%s" has invalid type';
+ RsEPivotLessThanZero = 'JvJCLUtils.MakeYear4Digit: Pivot < 0';
+
+{$IFDEF NO_JCL}
+
+ // These are the replacement functions for the JCL.
+
+const
+ AnsiSpace = AnsiChar(#32);
+ AnsiForwardSlash = AnsiChar('/');
+
+function StrIPos(const SubStr, S: string): Integer;
+begin
+ {$IFDEF CLR}
+ Result := S.ToLower().IndexOf(SubStr.ToLower());
+ {$ELSE}
+ Result := Pos(AnsiLowerCase(SubStr), AnsiLowerCase(S));
+ {$ENDIF CLR}
+end;
+
+function CharIsDigit(Ch: AnsiChar): Boolean;
+begin
+ Result := Ch in ['0'..'9'];
+end;
+
+function CharIsNumber(Ch: AnsiChar): Boolean;
+begin
+ Result := Ch in ['0'..'9'];
+end;
+
+function CharIsAlpha(Ch: AnsiChar): Boolean;
+begin
+ Result := Windows.IsCharAlpha(Char(Ch));
+end;
+
+{$IFDEF MSWINDOWS}
+function GetRecentFolder: string;
+{$IFDEF CLR}
+begin
+ Result := System.Environment.GetFolderPath(Environment.SpecialFolder.Recent);
+end;
+{$ELSE}
+var
+ ItemIDList: PItemIDList;
+begin
+ OleCheck(SHGetSpecialFolderLocation(0, CSIDL_RECENT, ItemIDList));
+ SetLength(Result, MAX_PATH);
+ SHGetPathFromIDList(ItemIDList, PChar(Result));
+ SetLength(Result, Length(PChar(Result)));
+end;
+{$ENDIF CLR}
+{$ENDIF MSWINDOWS}
+
+{$ENDIF NO_JCL}
+
+function SendRectMessage(Handle: THandle; Msg: Integer; wParam: WPARAM; var R: TRect): Integer;
+{$IFDEF CLR}
+var
+ Mem: IntPtr;
+begin
+ { R is a System.ValueType }
+ Mem := Marshal.AllocHGlobal(Marshal.SizeOf(R));
+ try
+ Marshal.StructureToPtr(R, Mem, False);
+ Result := SendMessage(Handle, Msg, wParam, Longint(Mem));
+ R := TRect(Marshal.PtrToStructure(Mem, R.GetType));
+ finally
+ Marshal.DestroyStructure(Mem, R.GetType);
+ end;
+end;
+{$ELSE}
+begin
+ Result := SendMessage(Handle, Msg, wParam, Longint(@R));
+end;
+{$ENDIF CLR}
+
+function SendStructMessage(Handle: THandle; Msg: Integer; wParam: WPARAM; var Data): Integer;
+{$IFDEF CLR}
+var
+ Mem: IntPtr;
+begin
+ { Data is System.Object }
+ Mem := Marshal.AllocHGlobal(Marshal.SizeOf(TObject(Data)));
+ try
+ Marshal.StructureToPtr(TObject(Data), Mem, False);
+ Result := SendMessage(Handle, Msg, wParam, Longint(Mem));
+ Data := Marshal.PtrToStructure(Mem, TObject(Data).GetType);
+ finally
+ Marshal.DestroyStructure(Mem, TObject(Data).GetType);
+ end;
+end;
+{$ELSE}
+begin
+ Result := SendMessage(Handle, Msg, wParam, Longint(@Data));
+end;
+{$ENDIF CLR}
+
+
+{$IFDEF CLR}
+function VarFromDateTime(const Value: TDateTime): Variant;
+begin
+ Result := Value;
+end;
+
+function VarToDateTime(const Value: Variant): TDateTime;
+begin
+ Result := Value;
+end;
+
+function SucceededCom(out Intf; Value: TObject): Boolean;
+begin
+ Intf := Value;
+ Result := Value <> nil;
+end;
+
+function GetPrivateField(Instance: TObject; const FieldName: string): TObject;
+var
+ Info: FieldInfo;
+begin
+ Result := nil;
+ if Instance <> nil then
+ begin
+ Info := Instance.GetType.GetField(FieldName, BindingFlags.NonPublic or BindingFlags.Instance);
+ if Info <> nil then
+ Result := Info.GetValue(Instance);
+ end;
+end;
+
+procedure SetPrivateField(Instance: TObject; const FieldName: string; Value: TObject);
+var
+ Info: FieldInfo;
+begin
+ if Instance <> nil then
+ begin
+ Info := Instance.GetType.GetField(FieldName, BindingFlags.NonPublic or BindingFlags.Instance);
+ if Info <> nil then
+ Info.SetValue(Instance, Value);
+ end;
+end;
+
+procedure SetProtectedObjectEvent(Instance: TObject; const EventName: string; Ev: Delegate);
+var
+ Info: EventInfo;
+begin
+ if Instance <> nil then
+ begin
+ Info := Instance.GetType.GetEvent(EventName, BindingFlags.NonPublic or BindingFlags.Instance);
+ if Info <> nil then
+ { TODO : Implement }
+ //Info.RemoveEventHandler();
+ end;
+end;
+
+function GetProtectedObjectEvent(Instance: TObject; const EventName: string): Delegate;
+var
+ Info: EventInfo;
+begin
+ Result := nil;
+ if Instance <> nil then
+ begin
+ Info := Instance.GetType.GetEvent(EventName, BindingFlags.NonPublic or BindingFlags.Instance);
+ if Info <> nil then
+ { TODO : Implement }
+ //Info.RemoveEventHandler();
+ end;
+end;
+
+function AnsiLastChar(const S: string): Char;
+begin
+ if (S <> nil) and (S <> '') then
+ Result := S[Length(S)]
+ else
+ Result := #0;
+end;
+{$ENDIF CLR}
+
+function ReadCharsFromStream(Stream: TStream; var Buf: array of Char; BufSize: Integer): Integer;
+{$IFDEF CLR}
+var
+ Bytes: TBytes;
+{$ENDIF CLR}
+begin
+ {$IFDEF CLR}
+ SetLength(Bytes, BufSize);
+ Result := Stream.Read(Bytes, 0, BufSize);
+ System.Array.Copy(AnsiEncoding.GetChars(Bytes), 0, Buf, 0, BufSize);
+ {$ELSE}
+ Result := Stream.Read(Buf, BufSize);
+ {$ENDIF CLR}
+end;
+
+function WriteStringToStream(Stream: TStream; const Buf: string; BufSize: Integer): Integer;
+begin
+ {$IFDEF CLR}
+ Result := Stream.Write(BytesOf(Buf), BufSize);
+ {$ELSE}
+ Result := Stream.Write(Buf[1], BufSize);
+ {$ENDIF CLR}
+end;
+
+
+// StrToFloatUS uses US '.' as decimal separator and ',' as thousand separator
+
+function USToLocalFloatStr(const Text: string): string;
+var
+ I: Integer;
+begin
+ Result := Text;
+ if (DecimalSeparator <> '.') or (ThousandSeparator <> ',') then
+ begin
+ for I := 0 to Length(Result) do
+ {$IFNDEF CLR}
+ case Result[I] of
+ '.':
+ Result[I] := DecimalSeparator;
+ ',':
+ Result[I] := ThousandSeparator;
+ end;
+ {$ELSE}
+ case Result[I] of
+ '.':
+ Result[I] := DecimalSeparator[1];
+ ',':
+ Result[I] := ThousandSeparator[1];
+ end;
+ {$ENDIF !CLR}
+ end;
+end;
+
+function StrToFloatUS(const Text: string): Extended;
+begin
+ try
+ Result := StrToFloat(USToLocalFloatStr(Text));
+ except
+ Result := StrToFloat(Text); // try it with local settings
+ end;
+end;
+
+function StrToFloatUSDef(const Text: string; Default: Extended): Extended;
+begin
+ Result := StrToFloatDef(USToLocalFloatStr(Text), Default);
+end;
+
+function VarIsInt(Value: Variant): Boolean;
+begin
+ Result := VarType(Value) in [varByte,
+ {$IFDEF COMPILER6_UP}
+ varShortInt, varWord, varLongWord, {varInt64,}
+ {$ENDIF COMPILER6_UP}
+ varSmallint, varInteger];
+end;
+
+function PosIdx(const SubStr, S: string; Index: Integer = 0): Integer;
+{$IFDEF CLR}
+begin
+ Result := S.IndexOf(SubStr, Index - 1) + 1;
+end;
+{$ELSE}
+ // use best register allocation
+ function Find(Index, EndPos: Integer; StartChar: Char; const S: string): Integer;
+ begin
+ for Result := Index to EndPos do
+ if S[Result] = StartChar then
+ Exit;
+ Result := 0;
+ end;
+
+ // use best register allocation
+ function FindNext(Index, EndPos: Integer; const S, SubStr: string): Integer;
+ begin
+ for Result := Index + 1 to EndPos do
+ if S[Result] <> SubStr[Result - Index + 1] then
+ Exit;
+ Result := 0;
+ end;
+
+var
+ StartChar: Char;
+ LenSubStr, LenStr: Integer;
+ EndPos: Cardinal;
+begin
+ if Index <= 0 then
+ Index := 1;
+ Result := 0;
+ LenSubStr := Length(SubStr);
+ LenStr := Length(S);
+ if (LenSubStr = 0) or (S = '') or (LenSubStr > LenStr - (Index - 1)) then
+ Exit;
+
+ StartChar := SubStr[1];
+ EndPos := LenStr - LenSubStr + 1;
+ if LenSubStr = 1 then
+ Result := Find(Index, EndPos, StartChar, S)
+ else
+ begin
+ repeat
+ Result := Find(Index, EndPos, StartChar, S);
+ if Result = 0 then
+ Break;
+ Index := Result;
+ Result := FindNext(Result, Index + LenSubStr - 1, S, SubStr);
+ if Result = 0 then
+ begin
+ Result := Index;
+ Exit;
+ end
+ else
+ Inc(Index);
+ until False;
+ end;
+end;
+
+function PosIdxW(const SubStr, S: WideString; Index: Integer = 0): Integer;
+
+ // use best register allocation
+ function Find(Index, EndPos: Integer; StartChar: WideChar; const S: WideString): Integer;
+ begin
+ for Result := Index to EndPos do
+ if S[Result] = StartChar then
+ Exit;
+ Result := 0;
+ end;
+
+ // use best register allocation
+ function FindNext(Index, EndPos: Integer; const S, SubStr: WideString): Integer;
+ begin
+ for Result := Index + 1 to EndPos do
+ if S[Result] <> SubStr[Result - Index + 1] then
+ Exit;
+ Result := 0;
+ end;
+
+var
+ StartChar: WideChar;
+ LenSubStr, LenStr: Integer;
+ EndPos: Cardinal;
+begin
+ if Index <= 0 then
+ Index := 1;
+ Result := 0;
+ LenSubStr := Length(SubStr);
+ LenStr := Length(S);
+ if (LenSubStr = 0) or (S = '') or (LenSubStr > LenStr - (Index - 1)) then
+ Exit;
+
+ StartChar := SubStr[1];
+ EndPos := LenStr - LenSubStr + 1;
+ if LenSubStr = 1 then
+ Result := Find(Index, EndPos, StartChar, S)
+ else
+ begin
+ repeat
+ Result := Find(Index, EndPos, StartChar, S);
+ if Result = 0 then
+ Break;
+ Index := Result;
+ Result := FindNext(Result, Index + LenSubStr - 1, S, SubStr);
+ if Result = 0 then
+ begin
+ Result := Index;
+ Exit;
+ end
+ else
+ Inc(Index);
+ until False;
+ end;
+end;
+{$ENDIF CLR}
+
+function PosLastCharIdx(Ch: Char; const S: string; Index: Integer = 0): Integer;
+begin
+ if (Index = 0) or (Index > Length(S)) then
+ Index := Length(S);
+ for Result := Index downto 1 do
+ if S[Result] = Ch then
+ Exit;
+ Result := 0;
+end;
+
+
+function GetLineByPos(const S: string; const Pos: Integer): Integer;
+var
+ I: Integer;
+begin
+ if Length(S) < Pos then
+ Result := -1
+ else
+ begin
+ I := 1;
+ Result := 0;
+ while I <= Pos do
+ begin
+ if S[I] = #13 then
+ Inc(Result);
+ Inc(I);
+ end;
+ end;
+end;
+
+procedure GetXYByPos(const S: string; const Pos: Integer; var X, Y: Integer);
+var
+ I, iB: Integer;
+begin
+ X := -1;
+ Y := -1;
+ iB := 0;
+ if (Length(S) >= Pos) and (Pos >= 0) then
+ begin
+ I := 1;
+ Y := 0;
+ while I <= Pos do
+ begin
+ if S[I] = #10 then
+ begin
+ Inc(Y);
+ iB := I + 1;
+ end;
+ Inc(I);
+ end;
+ X := Pos - iB;
+ end;
+end;
+
+procedure GetXYByPosW(const S: WideString; const Pos: Integer; var X, Y: Integer);
+var
+ I, iB: Integer;
+begin
+ X := -1;
+ Y := -1;
+ iB := 0;
+ if (Length(S) >= Pos) and (Pos >= 0) then
+ begin
+ I := 1;
+ Y := 0;
+ while I <= Pos do
+ begin
+ if S[I] = #10 then
+ begin
+ Inc(Y);
+ iB := I + 1;
+ end;
+ Inc(I);
+ end;
+ X := Pos - iB;
+ end;
+end;
+
+function GetWordOnPos(const S: string; const P: Integer): string;
+var
+ I, Beg: Integer;
+begin
+ Result := '';
+ if (P > Length(S)) or (P < 1) then
+ Exit;
+ for I := P downto 1 do
+ if S[I] in Separators then
+ Break;
+ Beg := I + 1;
+ for I := P to Length(S) do
+ if S[I] in Separators then
+ Break;
+ if I > Beg then
+ Result := Copy(S, Beg, I - Beg)
+ else
+ Result := S[P];
+end;
+
+function GetWordOnPosW(const S: WideString; const P: Integer): WideString;
+var
+ I, Beg: Integer;
+begin
+ Result := '';
+ if (P > Length(S)) or (P < 1) then
+ Exit;
+ for I := P downto 1 do
+ if CharInSetW(S[I], Separators) then
+ Break;
+ Beg := I + 1;
+ for I := P to Length(S) do
+ if CharInSetW(S[I], Separators) then
+ Break;
+ if I > Beg then
+ Result := Copy(S, Beg, I - Beg)
+ else
+ Result := S[P];
+end;
+
+function GetWordOnPos2(const S: string; P: Integer; var iBeg, iEnd: Integer): string;
+begin
+ Result := '';
+ if P < 1 then
+ Exit;
+ if (S[P] in Separators) and ((P < 1) or (S[P - 1] in Separators)) then
+ Inc(P);
+ iBeg := P;
+ while iBeg >= 1 do
+ if S[iBeg] in Separators then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := P;
+ while iEnd <= Length(S) do
+ if S[iEnd] in Separators then
+ Break
+ else
+ Inc(iEnd);
+ if iEnd > iBeg then
+ Result := Copy(S, iBeg, iEnd - iBeg)
+ else
+ Result := S[P];
+end;
+
+function GetWordOnPos2W(const S: WideString; P: Integer; var iBeg, iEnd: Integer): WideString;
+begin
+ Result := '';
+ if P < 1 then
+ Exit;
+ if (CharInSetW(S[P], Separators)) and
+ ((P < 1) or (CharInSetW(S[P - 1], Separators))) then
+ Inc(P);
+ iBeg := P;
+ while iBeg >= 1 do
+ if CharInSetW(S[iBeg], Separators) then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := P;
+ while iEnd <= Length(S) do
+ if CharInSetW(S[iEnd], Separators) then
+ Break
+ else
+ Inc(iEnd);
+ if iEnd > iBeg then
+ Result := Copy(S, iBeg, iEnd - iBeg)
+ else
+ Result := S[P];
+end;
+
+function GetWordOnPosEx(const S: string; const P: Integer; var iBeg, iEnd: Integer): string;
+begin
+ Result := '';
+ if (P > Length(S)) or (P < 1) then
+ Exit;
+ iBeg := P;
+ if P > 1 then
+ if S[P] in Separators then
+ if (P < 1) or ((P - 1 > 0) and (S[P - 1] in Separators)) then
+ Inc(iBeg)
+ else
+ if not ((P - 1 > 0) and (S[P - 1] in Separators)) then
+ Dec(iBeg);
+ while iBeg >= 1 do
+ if S[iBeg] in Separators then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := P;
+ while iEnd <= Length(S) do
+ if S[iEnd] in Separators then
+ Break
+ else
+ Inc(iEnd);
+ if iEnd > iBeg then
+ Result := Copy(S, iBeg, iEnd - iBeg)
+ else
+ Result := S[P];
+end;
+
+function GetWordOnPosExW(const S: WideString; const P: Integer; var iBeg, iEnd: Integer): WideString;
+begin
+ Result := '';
+ if (P > Length(S)) or (P < 1) then
+ Exit;
+ iBeg := P;
+ if P > 1 then
+ if CharInSetW(S[P], Separators) then
+ if (P < 1) or ((P - 1 > 0) and CharInSetW(S[P - 1], Separators)) then
+ Inc(iBeg)
+ else
+ if not ((P - 1 > 0) and CharInSetW(S[P - 1], Separators)) then
+ Dec(iBeg);
+ while iBeg >= 1 do
+ if CharInSetW(S[iBeg], Separators) then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := P;
+ while iEnd <= Length(S) do
+ if CharInSetW(S[iEnd], Separators) then
+ Break
+ else
+ Inc(iEnd);
+ if iEnd > iBeg then
+ Result := Copy(S, iBeg, iEnd - iBeg)
+ else
+ Result := S[P];
+end;
+
+function GetNextWordPosEx(const Text: string; StartIndex: Integer;
+ var iBeg, iEnd: Integer): string;
+var
+ Len: Integer;
+begin
+ Len := Length(Text);
+ Result := '';
+ if (StartIndex < 1) or (StartIndex > Len) then
+ Exit;
+ if (Text[StartIndex] in Separators) and
+ ((StartIndex < 1) or (Text[StartIndex - 1] in Separators)) then
+ Inc(StartIndex);
+ iBeg := StartIndex;
+ while iBeg >= 1 do
+ if Text[iBeg] in Separators then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := StartIndex;
+ while iEnd <= Len do
+ if Text[iEnd] in Separators then
+ Break
+ else
+ Inc(iEnd);
+ Dec(iEnd);
+ if iEnd >= iBeg then
+ Result := Copy(Text, iBeg, iEnd - iBeg)
+ else
+ Result := Text[StartIndex];
+
+ // go right
+ iEnd := iBeg;
+ while (iEnd <= Len) and (not (Text[iEnd] in Separators)) do
+ Inc(iEnd);
+ if iEnd > Len then
+ iEnd := Len
+ else
+ Dec(iEnd);
+ Result := Copy(Text, iBeg, iEnd - iBeg + 1);
+end;
+
+function GetNextWordPosExW(const Text: WideString; StartIndex: Integer;
+ var iBeg, iEnd: Integer): WideString;
+var
+ Len: Integer;
+begin
+ Len := Length(Text);
+ Result := '';
+ if (StartIndex < 1) or (StartIndex > Len) then
+ Exit;
+ if CharInSetW(Text[StartIndex], Separators) and
+ ((StartIndex < 1) or CharInSetW(Text[StartIndex - 1], Separators)) then
+ Inc(StartIndex);
+ iBeg := StartIndex;
+ while iBeg >= 1 do
+ if CharInSetW(Text[iBeg], Separators) then
+ Break
+ else
+ Dec(iBeg);
+ Inc(iBeg);
+ iEnd := StartIndex;
+ while iEnd <= Len do
+ if CharInSetW(Text[iEnd], Separators) then
+ Break
+ else
+ Inc(iEnd);
+ Dec(iEnd);
+ if iEnd >= iBeg then
+ Result := Copy(Text, iBeg, iEnd - iBeg)
+ else
+ Result := Text[StartIndex];
+
+ // go right
+ iEnd := iBeg;
+ while (iEnd <= Len) and (not CharInSetW(Text[iEnd], Separators)) do
+ Inc(iEnd);
+ if iEnd > Len then
+ iEnd := Len
+ else
+ Dec(iEnd);
+ Result := Copy(Text, iBeg, iEnd - iBeg + 1);
+end;
+
+procedure GetEndPosCaret(const Text: string; CaretX, CaretY: Integer;
+ var X, Y: Integer);
+begin
+ GetXYByPos(Text, Length(Text), X, Y);
+ if Y = 0 then
+ Inc(X, CaretX)
+ else
+ Inc(X);
+ Dec(X);
+ Inc(Y, CaretY);
+end;
+
+procedure GetEndPosCaretW(const Text: WideString; CaretX, CaretY: Integer;
+ var X, Y: Integer);
+begin
+ GetXYByPosW(Text, Length(Text), X, Y);
+ if Y = 0 then
+ Inc(X, CaretX)
+ else
+ Inc(X);
+ Dec(X);
+ Inc(Y, CaretY);
+end;
+
+function SubStrBySeparator(const S: string; const Index: Integer; const Separator: string; StartIndex: Integer): string;
+{ Returns a substring. Substrings are divided by a separator character }
+var
+ I, LenS, LenSeparator: Integer;
+begin
+ Result := '';
+ LenSeparator := Length(Separator);
+ LenS := Length(S);
+
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ if (LenS = 0) or (LenSeparator = 0) or (StartIndex > LenS) or
+ ((Index < 0) or ((Index = 0) and (LenS > 0) and (S[StartIndex] = Separator[1]))) then
+ Exit;
+
+ for I := 1 to Index do
+ begin
+ StartIndex := PosIdx(Separator, S, StartIndex);
+ if StartIndex = 0 then
+ Exit;
+ Inc(StartIndex, LenSeparator);
+ if StartIndex > LenS then
+ Exit;
+ end;
+ I := PosIdx(Separator, S, StartIndex + 1);
+ if I = 0 then
+ I := LenS + 1;
+ Result := Copy(S, StartIndex, I - StartIndex);
+ if CompareText(Result, Separator) = 0 then
+ Result := '';
+end;
+
+{$IFNDEF CLR}
+function SubStrBySeparatorW(const S: WideString; const Index: Integer; const Separator: WideString; StartIndex: Integer): WideString;
+{ Returns a substring. Substrings are divided by a separator character }
+var
+ I, LenS, LenSeparator: Integer;
+begin
+ Result := '';
+ LenSeparator := Length(Separator);
+ LenS := Length(S);
+
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ if (LenS = 0) or (LenSeparator = 0) or (StartIndex > LenS) or
+ ((Index < 0) or ((Index = 0) and (LenS > 0) and (S[StartIndex] = Separator[1]))) then
+ Exit;
+
+ for I := 1 to Index do
+ begin
+ StartIndex := PosIdx(Separator, S, StartIndex);
+ if StartIndex = 0 then
+ Exit;
+ Inc(StartIndex, LenSeparator);
+ if StartIndex > LenS then
+ Exit;
+ end;
+ I := PosIdx(Separator, S, StartIndex + 1);
+ if I = 0 then
+ I := LenS + 1;
+ Result := Copy(S, StartIndex, I - StartIndex);
+ if WideCompareText(Result, Separator) = 0 then
+ Result := '';
+end;
+{$ENDIF !CLR}
+
+{$IFDEF CLR}
+function SubWord(P: string; var P2: string): string;
+var
+ I: Integer;
+begin
+ for I := 1 to Length(P) do
+ if P[I] in Separators then
+ Break;
+ Result := Copy(P, 1, I);
+ P2 := Copy(Result, I + 1, MaxInt);
+end;
+{$ELSE}
+function SubWord(P: PChar; var P2: PChar): string;
+var
+ I: Integer;
+begin
+ I := 0;
+ while not (P[I] in Separators) do
+ Inc(I);
+ SetString(Result, P, I);
+ P2 := P + I;
+end;
+{$ENDIF CLR}
+
+function ReplaceString(S: string; const OldPattern, NewPattern: string; StartIndex: Integer): string;
+var
+ I, LenOldPattern: Integer;
+begin
+ if OldPattern <> '' then
+ begin
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ LenOldPattern := Length(OldPattern);
+ I := PosIdx(OldPattern, S, StartIndex);
+ while I > 0 do
+ begin
+ StartIndex := I + LenOldPattern;
+ S := Copy(S, 1, I - 1) + NewPattern + Copy(S, StartIndex, MaxInt);
+ I := PosIdx(OldPattern, S, StartIndex);
+ end;
+ end;
+ Result := S;
+end;
+
+{$IFNDEF CLR}
+function ReplaceStringW(S: WideString; const OldPattern, NewPattern: WideString; StartIndex: Integer): WideString;
+var
+ I, LenOldPattern: Integer;
+begin
+ if OldPattern <> '' then
+ begin
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ LenOldPattern := Length(OldPattern);
+ I := PosIdxW(OldPattern, S, StartIndex);
+ while I > 0 do
+ begin
+ StartIndex := I + LenOldPattern;
+ S := Copy(S, 1, I - 1) + NewPattern + Copy(S, StartIndex, MaxInt);
+ I := PosIdxW(OldPattern, S, StartIndex);
+ end;
+ end;
+ Result := S;
+end;
+{$ENDIF !CLR}
+
+function ConcatSep(const S1, S2, Separator: string): string;
+begin
+ Result := S1;
+ if Result <> '' then
+ Result := Result + Separator;
+ Result := Result + S2;
+end;
+
+function ConcatLeftSep(const S1, S2, Separator: string): string;
+begin
+ Result := S1;
+ if Result <> '' then
+ Result := Separator + Result;
+ Result := S2 + Result;
+end;
+
+function MinimizeString(const S: string; const MaxLen: Integer): string;
+begin
+ if Length(S) > MaxLen then
+ if MaxLen < 3 then
+ Result := Copy(S, 1, MaxLen)
+ else
+ Result := Copy(S, 1, MaxLen - 3) + '...'
+ else
+ Result := S;
+end;
+
+function TrueInflateRect(const R: TRect; const I: Integer): TRect;
+begin
+ with R do
+ SetRect(Result, Left - I, Top - I, Right + I, Bottom + I);
+end;
+
+function FileGetInfo(FileName: TFileName; var SearchRec: TSearchRec): Boolean;
+var
+ DosError: Integer;
+ Path: TFileName;
+begin
+ Result := False;
+ Path := ExtractFilePath(ExpandFileName(FileName)) + AllFilesMask;
+ {$IFDEF MSWINDOWS}
+ {$IFDEF CLR}
+ FileName := ExtractFileName(FileName).ToUpper();
+ {$ELSE}
+ FileName := AnsiUpperCase(ExtractFileName(FileName));
+ {$ENDIF CLR}
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ FileName := ExtractFileName(FileName);
+ {$ENDIF UNIX}
+ DosError := FindFirst(Path, faAnyFile, SearchRec);
+ while DosError = 0 do
+ begin
+ {$IFDEF MSWINDOWS}
+ if SameFileName(SearchRec.FindData.cFileName, FileName) or
+ SameFileName(SearchRec.FindData.cAlternateFileName, FileName) then
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ if AnsiSameStr(SearchRec.Name, FileName) then
+ {$ENDIF UNIX}
+ begin
+ Result := True;
+ Break;
+ end;
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+end;
+
+function HasSubFolder(APath: TFileName): Boolean;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+begin
+ Result := False;
+ APath := Concat(AddSlash(APath), AllFilesMask);
+ DosError := FindFirst(APath, faDirectory, SearchRec);
+ while DosError = 0 do
+ begin
+ if (SearchRec.Attr and faDirectory = faDirectory) and
+ (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
+ begin
+ Result := True;
+ Break;
+ end;
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+end;
+
+function IsEmptyFolder(APath: TFileName): Boolean;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+begin
+ Result := True;
+ APath := Concat(AddSlash(APath), AllFilesMask);
+ DosError := FindFirst(APath, faDirectory, SearchRec);
+ while DosError = 0 do
+ begin
+ if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
+ begin
+ Result := False;
+ Break;
+ end;
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+function LZFileExpand(const FileSource, FileDest: string): Boolean;
+type
+ TLZCopy = function(Source, Dest: Integer): Longint; stdcall;
+ TLZOpenFile = function(FileName: PChar; var ReOpenBuff: TOFStruct; Style: Word): Integer; stdcall;
+ TLZClose = procedure(hFile: Integer); stdcall;
+var
+ Source, Dest: Integer;
+ OSSource, OSDest: TOFStruct;
+ Res: Integer;
+ Inst: THandle;
+ LZCopy: TLZCopy;
+ LZOpenFile: TLZOpenFile;
+ LZClose: TLZClose;
+begin
+ Result := False;
+ Inst := SafeLoadLibrary('LZ32.dll');
+ try
+ if Inst = 0 then
+ RaiseLastOSError;
+ LZCopy := GetProcAddress(Inst, 'LZCopy');
+ LZOpenFile := GetProcAddress(Inst, 'LZOpenFileA');
+ LZClose := GetProcAddress(Inst, 'LZClose');
+ if not Assigned(LZCopy) or not Assigned(LZOpenFile) or not Assigned(LZClose) then
+ begin
+ SetLastError(ERROR_NOT_SUPPORTED);
+ RaiseLastOSError;
+ end;
+ OSSource.cBytes := SizeOf(TOFStruct);
+ OSDest.cBytes := SizeOf(TOFStruct);
+ Source := LZOpenFile(
+ PChar(FileSource), // address of name of file to be opened
+ OSSource, // address of open file structure
+ OF_READ or OF_SHARE_DENY_NONE); // action to take
+ if Source < 0 then
+ begin
+ DeleteFile(FileDest);
+ Dest := LZOpenFile(
+ PChar(FileDest), // address of name of file to be opened
+ OSDest, // address of open file structure
+ OF_CREATE or OF_WRITE or OF_SHARE_EXCLUSIVE); // action to take
+ if Dest >= 0 then
+ begin
+ Res := LZCopy(Source, Dest);
+ if Res >= 0 then
+ Result := True;
+ end;
+ LZClose(Source);
+ LZClose(Dest);
+ end;
+ finally
+ FreeLibrary(Inst);
+ end;
+end;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+procedure Dos2Win(var S: string);
+var
+ I: Integer;
+begin
+ for I := 1 to Length(S) do
+ case S[I] of
+ #$80..#$AF:
+ S[I] := Char(Byte(S[I]) + (192 - $80));
+ #$E0..#$EF:
+ S[I] := Char(Byte(S[I]) + (240 - $E0));
+ end;
+end;
+
+procedure Win2Dos(var S: string);
+var
+ I: Integer;
+begin
+ for I := 1 to Length(S) do
+ case S[I] of
+ #$C0..#$EF:
+ S[I] := Char(Byte(S[I]) - (192 - $80));
+ #$F0..#$FF:
+ S[I] := Char(Byte(S[I]) - (240 - $E0));
+ end;
+end;
+
+function Dos2WinRes(const S: string): string;
+begin
+ Result := S;
+ Dos2Win(Result);
+end;
+
+function Win2DosRes(const S: string): string;
+begin
+ Result := S;
+ Win2Dos(Result);
+end;
+
+function Win2Koi(const S: string): string;
+const
+ W = 'àáâãä叿çèéêëìíîïðñ=óôõ÷öøùüûúýÝÿ+--+-+¨ÆÇ++--Ý-+ÏÐÑÒÓÔi×ÖØ+_Ý+ÝÞî';
+ K = '--×Ç-+£Ö++--Ý-+ÏÐÒÓÔiÆ+Þ+ÝÝØ+î_+Ñáâ÷çäåÝöúéêëìíîïð=óôõæèÝãûýøùÿüàñ';
+var
+ I, J: Integer;
+begin
+ Result := S;
+ for I := 1 to Length(Result) do
+ begin
+ J := Pos(Result[I], W);
+ if J > 0 then
+ Result[I] := K[J];
+ end;
+end;
+
+{$IFNDEF CLR}
+procedure FillString(var Buffer: string; Count: Integer; const Value: Char);
+begin
+ FillChar(Buffer[1], Count, Value);
+end;
+
+procedure FillString(var Buffer: string; StartIndex, Count: Integer; const Value: Char);
+begin
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ FillChar(Buffer[StartIndex], Count, Value);
+end;
+
+procedure MoveString(const Source: string; var Dest: string; Count: Integer);
+begin
+ Move(Source[1], Dest[1], Count);
+end;
+
+procedure MoveString(const Source: string; SrcStartIdx: Integer; var Dest: string;
+ DstStartIdx: Integer; Count: Integer);
+begin
+ if DstStartIdx <= 0 then
+ DstStartIdx := 1;
+ if SrcStartIdx <= 0 then
+ SrcStartIdx := 1;
+
+ Move(Source[SrcStartIdx], Dest[DstStartIdx], Count);
+end;
+
+procedure FillWideChar(var Buffer; Count: Integer; const Value: WideChar);
+var
+ P: PLongint;
+ Value2: Cardinal;
+ CopyWord: Boolean;
+begin
+ Value2 := (Cardinal(Value) shl 16) or Cardinal(Value);
+ CopyWord := Count and $1 <> 0;
+ Count := Count div 2;
+ P := @Buffer;
+ while Count > 0 do
+ begin
+ P^ := Value2;
+ Inc(P);
+ Dec(Count);
+ end;
+ if CopyWord then
+ PWideChar(P)^ := Value;
+end;
+
+procedure MoveWideChar(const Source; var Dest; Count: Integer);
+begin
+ Move(Source, Dest, Count * SizeOf(WideChar));
+end;
+{$ELSE}
+procedure FillString(var Buffer: string; Count: Integer; const Value: Char);
+var
+ sb: StringBuilder;
+ I: Integer;
+begin
+ sb := StringBuilder.Create(Count);
+ for I := 1 to Count do
+ sb.Append(Value);
+ Buffer := sb.ToString() + Buffer.Substring(Count);
+end;
+
+procedure FillString(var Buffer: string; StartIndex, Count: Integer; const Value: Char); overload;
+var
+ sb: StringBuilder;
+ I: Integer;
+begin
+ if StartIndex <= 0 then
+ StartIndex := 1;
+ sb := StringBuilder.Create(Count);
+ for I := 1 to Count do
+ sb.Append(Value);
+ Buffer := Buffer.Substring(0, StartIndex - 1) + sb.ToString() + Buffer.Substring(StartIndex - 1 + Count);
+end;
+
+procedure MoveString(const Source: string; var Dest: string; Count: Integer);
+begin
+ Dest.Remove(0, Count);
+ Dest.Insert(0, Source.Substring(0, Count));
+end;
+
+procedure MoveString(const Source: string; SrcStartIdx: Integer; var Dest: string;
+ DstStartIdx: Integer; Count: Integer);
+begin
+ if DstStartIdx <= 0 then
+ DstStartIdx := 1;
+ if SrcStartIdx <= 0 then
+ SrcStartIdx := 1;
+
+ Dest.Remove(DstStartIdx - 1, Count);
+ Dest.Insert(DstStartIdx - 1, Source.Substring(SrcStartIdx - 1, Count));
+end;
+{$ENDIF !CLR}
+
+function IsSubString(const S: string; StartIndex: Integer; const SubStr: string): Boolean;
+begin
+ {$IFDEF CLR}
+ Result := Copy(S, StartIndex, Length(SubStr)) = SubStr;
+ {$ELSE}
+ if StartIndex < 1 then
+ StartIndex := 1;
+ if StartIndex > Length(S) then
+ StartIndex := Length(S);
+ Result := StrLComp(PChar(S) + StartIndex - 1, PChar(SubStr), Length(SubStr)) = 0;
+ {$ENDIF CLR}
+end;
+
+function Spaces(const N: Integer): string;
+begin
+ if N > 0 then
+ begin
+ SetLength(Result, N);
+ FillString(Result, N, ' ');
+ end
+ else
+ Result := '';
+end;
+
+function AddSpaces(const S: string; const N: Integer): string;
+var
+ Len: Integer;
+begin
+ Len := Length(S);
+ if (Len < N) and (N > 0) then
+ begin
+ SetLength(Result, N);
+ MoveString(S, Result, Len);
+ FillString(Result, Len + 1, N - Len, ' ');
+ end
+ else
+ Result := S;
+end;
+
+{$IFNDEF CLR}
+function SpacesW(const N: Integer): WideString;
+begin
+ if N > 0 then
+ begin
+ SetLength(Result, N);
+ FillWideChar(Result[1], N, ' ');
+ end
+ else
+ Result := '';
+end;
+
+function AddSpacesW(const S: WideString; const N: Integer): WideString;
+var
+ Len: Integer;
+begin
+ Len := Length(S);
+ if (Len < N) and (N > 0) then
+ begin
+ SetLength(Result, N);
+ MoveWideChar(S[1], Result[1], Len);
+ FillWideChar(Result[Len + 1], N - Len, ' ');
+ end
+ else
+ Result := S;
+end;
+{$ENDIF !CLR}
+
+{ (rb) maybe construct an english variant? }
+
+function LastDateRUS(const Dat: TDateTime): string;
+const
+ D2D: array [0..9] of Byte =
+ (3, 1, 2, 2, 2, 3, 3, 3, 3, 3);
+ Day: array [1..3] of string =
+ ('äåíü', 'äíÿ', 'äíåé'); // Day, Days, Days
+ Month: array [1..3] of string =
+ ('ìåñÿö', 'ìåñÿöà', 'ìåñÿöåâ'); // Month, Months, Months
+ Year: array [1..3] of string =
+ ('ãîä', 'ãîäà', 'ëå='); // Year, Years, Years
+ Week: array [1..4] of string =
+ ('íåäåëÝ', '2 íåäåëè', '3 íåäåëè', 'ìåñÿö'); // Week, 2 Weeks, 3 Weeks, Month
+var
+ Y, M, D: Integer;
+begin
+ if Date = Dat then
+ Result := 'ñåãîäíÿ' // Today
+ else
+ if Dat = Date - 1 then
+ Result := 'â÷åðà' // Yesterday
+ else
+ if Dat = Date - 2 then
+ Result := 'ïîçàâ÷åðà' // Day before yesterday
+ else
+ if Dat > Date then
+ Result := 'â áóäóùåì' // In the future
+ else
+ begin
+ D := Trunc(Date - Dat);
+ Y := Round(D / 365);
+ M := Round(D / 30);
+ if Y > 0 then
+ Result := IntToStr(Y) + ' ' + Year[D2D[StrToInt(IntToStr(Y)[Length(IntToStr(Y))])]] + ' íàçàä' // ago
+ else
+ if M > 0 then
+ Result := IntToStr(M) + ' ' + Month[D2D[StrToInt(IntToStr(M)[Length(IntToStr(M))])]] + ' íàçàä' // ago
+ else
+ if D > 6 then
+ Result := Week[D div 7] + ' íàçàä' // ago
+ else
+ if D > 0 then
+ Result := IntToStr(D) + ' ' + Day[D2D[StrToInt(IntToStr(D)[Length(IntToStr(D))])]] + ' íàçàä' // ago
+ end;
+end;
+
+function AddSlash(const Dir: TFileName): string;
+begin
+ Result := Dir;
+ if (Length(Dir) > 0) and (Dir[Length(Dir)] <> PathDelim) then
+ Result := Dir + PathDelim;
+end;
+
+function AddPath(const FileName, Path: TFileName): TFileName;
+begin
+ if ExtractFileDrive(FileName) = '' then
+ Result := AddSlash(Path) + FileName
+ else
+ Result := FileName;
+end;
+
+function AddPaths(const PathList, Path: string): string;
+var
+ I: Integer;
+ S: string;
+begin
+ Result := '';
+ I := 0;
+ S := SubStrBySeparator(PathList, I, PathSep);
+ while S <> '' do
+ begin
+ Result := ConcatSep(Result, AddPath(S, Path), PathSep);
+ Inc(I);
+ S := SubStrBySeparator(PathList, I, PathSep);
+ end;
+end;
+
+function ParentPath(const Path: TFileName): TFileName;
+begin
+ Result := Path;
+ if (Length(Result) > 0) and (Result[Length(Result)] = PathDelim) then
+ Delete(Result, Length(Result), 1);
+ Result := ExtractFilePath(Result);
+end;
+
+function FindInPath(const FileName, PathList: string): TFileName;
+var
+ I: Integer;
+ S: string;
+begin
+ I := 0;
+ S := SubStrBySeparator(PathList, I, PathSep);
+ while S <> '' do
+ begin
+ Result := AddSlash(S) + FileName;
+ if FileExists(Result) then
+ Exit;
+ Inc(I);
+ S := SubStrBySeparator(PathList, I, PathSep);
+ end;
+ Result := '';
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+function GetComputerID: string;
+var
+ SN: DWORD;
+ Nul: DWORD;
+ WinDir: array [0..MAX_PATH] of Char;
+begin
+ GetWindowsDirectory(WinDir, MAX_PATH);
+ WinDir[3] := #0;
+ if GetVolumeInformation(
+ WinDir, // address of root directory of the file system
+ nil, // address of name of the volume
+ 0, // Length of lpVolumeNameBuffer
+ @SN, // address of volume serial number
+ Nul, // address of system's maximum filename Length
+ Nul, // address of file system flags
+ nil, // address of name of file system
+ 0) {// Length of lpFileSystemNameBuffer} then
+ Result := IntToHex(SN, 8)
+ else
+ Result := 'None';
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+function GetComputerID: string;
+begin
+ Result := 'None';
+end;
+{$ENDIF UNIX}
+
+{$ENDIF !CLR}
+
+function GetComputerName: string;
+{$IFDEF CLR}
+begin
+ Result := System.Environment.MachineName;
+end;
+{$ELSE}
+var
+ nSize: Cardinal;
+begin
+ nSize := MAX_COMPUTERNAME_LENGTH + 1;
+ SetLength(Result, nSize);
+ if Windows.GetComputerName(PChar(Result), nSize) then
+ SetLength(Result, nSize)
+ else
+ Result := '';
+end;
+{$ENDIF CLR}
+
+function CurrencyToStr(const Cur: Currency): string;
+begin
+ Result := CurrToStrF(Cur, ffCurrency, CurrencyDecimals)
+end;
+
+function HasChar(const Ch: Char; const S: string): Boolean;
+var
+ I: Integer;
+begin
+ Result := True;
+ for I := 1 to Length(S) do
+ if S[I] = Ch then
+ Exit;
+ Result := False;
+end;
+
+function HasCharW(const Ch: WideChar; const S: WideString): Boolean;
+begin
+ Result := Pos(Ch, S) > 0;
+end;
+
+function HasAnyChar(const Chars: string; const S: string): Boolean;
+var
+ I: Integer;
+begin
+ for I := 1 to Length(Chars) do
+ if HasChar(Chars[I], S) then
+ begin
+ Result := True;
+ Exit;
+ end;
+ Result := False;
+end;
+
+function CountOfChar(const Ch: Char; const S: string): Integer;
+var
+ I: Integer;
+begin
+ Result := 0;
+ for I := 1 to Length(S) do
+ if S[I] = Ch then
+ Inc(Result);
+end;
+
+procedure SwapInt(var Int1, Int2: Integer);
+var
+ Tmp: Integer;
+begin
+ Tmp := Int1;
+ Int1 := Int2;
+ Int2 := Tmp;
+end;
+
+function DeleteReadOnlyFile(const FileName: TFileName): Boolean;
+begin
+ {$IFDEF MSWINDOWS}
+ FileSetAttr(FileName, 0); {clear Read Only Flag}
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ FileSetReadOnly(FileName, False);
+ {$ENDIF UNIX}
+ Result := DeleteFile(FileName);
+end;
+
+function HasParam(const Param: string): Boolean;
+var
+ I: Integer;
+begin
+ Result := False;
+ for I := 1 to ParamCount do
+ begin
+ Result := SameText(ParamStr(I), Param);
+ if Result then
+ Exit;
+ end;
+end;
+
+function HasSwitch(const Param: string): Boolean;
+var
+ I: Integer;
+begin
+ Result := False;
+ for I := 1 to ParamCount do
+ if HasChar(ParamStr(I)[1], '-/') then
+ begin
+ Result := SameText(Copy(ParamStr(I), 2, Length(Param)), Param);
+ if Result then
+ Exit;
+ end;
+end;
+
+function Switch(const Param: string): string;
+var
+ I: Integer;
+begin
+ Result := '';
+ for I := 1 to ParamCount do
+ if HasChar(ParamStr(I)[1], '-/\') and
+ SameText(Copy(ParamStr(I), 2, Length(Param)), Param) then
+ begin
+ Result := Copy(ParamStr(I), 2 + Length(Param), 260);
+ Exit;
+ end;
+end;
+
+function ExePath: TFileName;
+begin
+ Result := ExtractFilePath(ParamStr(0));
+end;
+
+function FileNewExt(const FileName, NewExt: TFileName): TFileName;
+begin
+ Result := Copy(FileName, 1, Length(FileName) - Length(ExtractFileExt(FileName))) + NewExt;
+end;
+
+function CharInSet(const Ch: Char; const SetOfChar: TSysCharSet): Boolean;
+begin
+ Result := Ch in SetOfChar;
+end;
+
+function CharInSetW(const Ch: WideChar; const SetOfChar: TSysCharSet): Boolean;
+begin
+ if Word(Ch) > 255 then
+ Result := False
+ else
+ Result := Char(Ch) in SetOfChar;
+end;
+
+function IntPower(Base, Exponent: Integer): Integer;
+begin
+ if Exponent > 0 then
+ begin
+ Result := Base;
+ Dec(Exponent);
+ while Exponent > 0 do
+ begin
+ Result := Result * Base;
+ Dec(Exponent);
+ end;
+ end
+ else
+ if Exponent < 0 then
+ Result := 0
+ else
+ Result := 1;
+end;
+
+{$IFNDEF CLR}
+function ChangeTopException(E: TObject): TObject;
+type
+ PRaiseFrame = ^TRaiseFrame;
+ TRaiseFrame = record
+ NextRaise: PRaiseFrame;
+ ExceptAddr: Pointer;
+ ExceptObject: TObject;
+ //ExceptionRecord: PExceptionRecord;
+ end;
+begin
+ { C++ Builder 3 Warning !}
+ { if linker error occured with message "unresolved external 'System::RaiseList'" try
+ comment this function implementation, compile,
+ then uncomment and compile again. }
+ {$IFDEF MSWINDOWS}
+ {$IFDEF SUPPORTS_DEPRECATED}
+ {$WARN SYMBOL_DEPRECATED OFF}
+ {$ENDIF SUPPORTS_DEPRECATED}
+ if RaiseList <> nil then
+ begin
+ Result := PRaiseFrame(RaiseList)^.ExceptObject;
+ PRaiseFrame(RaiseList)^.ExceptObject := E
+ end
+ else
+ Result := nil;
+ {$IFDEF SUPPORTS_DEPRECATED}
+ {$WARN SYMBOL_DEPRECATED ON}
+ {$ENDIF SUPPORTS_DEPRECATED}
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ // XXX: changing exception in stack frame is not supported on Kylix
+ Writeln(ErrOutput, 'ChangeTopException');
+ Result := E;
+ {$ENDIF UNIX}
+end;
+{$ENDIF !CLR}
+
+
+function KeyPressed(VK: Integer): Boolean;
+begin
+ Result := Windows.GetKeyState(VK) and $8000 = $8000;
+end;
+
+
+function Var2Type(V: Variant; const DestVarType: Integer): Variant;
+var
+ VType: TVarType;
+begin
+ {$IFDEF CLR}
+ VType := VarType(V);
+ {$ELSE}
+ VType := TVarData(V).VType;
+ {$ENDIF CLR}
+ if VType in [varEmpty, varNull] then
+ begin
+ case DestVarType of
+ {$IFNDEF CLR}
+ varOleStr,
+ {$ENDIF !CLR}
+ varString:
+ Result := '';
+ varInteger, varSmallint, varByte:
+ Result := 0;
+ varBoolean:
+ Result := False;
+ varSingle, varDouble, varCurrency, varDate:
+ Result := 0.0;
+ {$IFDEF CLR}
+ varObject:
+ {$ELSE}
+ varVariant:
+ {$ENDIF CLR}
+ Result := Null;
+ else
+ Result := VarAsType(V, DestVarType);
+ end;
+ end
+ else
+ Result := VarAsType(V, DestVarType);
+ if (DestVarType = varInteger) and (VType = varBoolean) then
+ Result := Integer(V = True);
+end;
+
+function VarToInt(V: Variant): Integer;
+begin
+ Result := Var2Type(V, varInteger);
+end;
+
+function VarToFloat(V: Variant): Double;
+begin
+ Result := Var2Type(V, varDouble);
+end;
+
+function CopyDir(const SourceDir, DestDir: TFileName): Boolean;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+ Path, DestPath: TFileName;
+begin
+ Result := False;
+ if not CreateDir(DestDir) then
+ Exit;
+ Path := SourceDir;
+ DestPath := AddSlash(DestDir);
+ Path := AddSlash(Path);
+ DosError := FindFirst(Path + AllFilesMask, faAnyFile, SearchRec);
+ while DosError = 0 do
+ begin
+ if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
+ begin
+ if (SearchRec.Attr and faDirectory) = faDirectory then
+ Result := CopyDir(Path + SearchRec.Name, AddSlash(DestDir) + SearchRec.Name)
+ else
+ {$IFDEF CLR}
+ Result := CopyFile(Path + SearchRec.Name, DestPath + SearchRec.Name, True);
+ {$ELSE}
+ Result := CopyFile(PChar(Path + SearchRec.Name), PChar(DestPath + SearchRec.Name), True);
+ {$ENDIF CLR}
+ if not Result then
+ Exit;
+ end;
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+ Result := True;
+end;
+
+//////////////////////////////////////////////////////////////////////////////
+{ Note: FileTimeToDateTime has been commented out, it is not used anywhere
+ in the JVCL code. Further, the old version is not to be returned
+ as it does not behave like the JCL version it is supposed to mimick.
+ See Mantis 2452 for details.
+}
+{const
+ FileTimeBase = -109205.0;
+ FileTimeStep: Extended = 24.0 * 60.0 * 60.0 * 1000.0 * 1000.0 * 10.0; // 100 nSek per Day
+function FileTimeToDateTime(const FT: TFileTime): TDateTime;
+begin
+ Result := Int64(FileTime) / FileTimeStep;
+ Result := Result + FileTimeBase;
+end;}
+// ---------------------------- old version ---------------------------
+//{$IFDEF MSWINDOWS}
+{var
+ LocalFileTime: TFileTime;
+ FileDate: Integer;
+begin
+ FileTimeToLocalFileTime(FT, LocalFileTime);
+ FileTimeToDosDateTime(LocalFileTime, LongRec(FileDate).Hi, LongRec(FileDate).Lo);
+ Result := FileDateToDateTime(FileDate);
+end;}
+//{$ENDIF MSWINDOWS}
+//{$IFDEF UNIX}
+{begin
+ Result := FileDateToDateTime(FT);
+end;}
+//{$ENDIF UNIX}
+// ------------------------- old version --------------------------------
+
+procedure FileTimeToDosDateTimeDWord(const FT: TFileTime; out Dft: DWORD);
+{$IFDEF CLR}
+var
+ wHi, wLo: Word;
+{$ENDIF CLR}
+begin
+ {$IFDEF CLR}
+ FileTimeToDosDateTime(FT, wHi, wLo);
+ Dft := (wHi shl 16) or wLo;
+ {$ELSE}
+ FileTimeToDosDateTime(FT, LongRec(Dft).Hi, LongRec(Dft).Lo);
+ {$ENDIF CLR}
+end;
+
+function MakeValidFileName(const FileName: TFileName;
+ ReplaceBadChar: Char): TFileName;
+var
+ I: Integer;
+begin
+ Result := FileName;
+ for I := 1 to Length(Result) do
+ if HasChar(Result[I], '''":?*\/') then
+ Result[I] := ReplaceBadChar;
+end;
+
+function DefStr(const S: string; Default: string): string;
+begin
+ if S <> '' then
+ Result := S
+ else
+ Result := Default;
+end;
+
+{$IFNDEF CLR}
+function StrLICompW2(S1, S2: PWideChar; MaxLen: Integer): Integer;
+// faster than the JclUnicode.StrLICompW function
+var
+ P1, P2: WideString;
+begin
+ SetString(P1, S1, Min(MaxLen, StrLenW(S1)));
+ SetString(P2, S2, Min(MaxLen, StrLenW(S2)));
+ {$IFDEF COMPILER6_UP}
+ Result := SysUtils.WideCompareText(P1, P2);
+ {$ELSE}
+ Result := WideCompareText(P1, P2);
+ {$ENDIF COMPILER6_UP}
+end;
+
+function StrPosW(S, SubStr: PWideChar): PWideChar;
+var
+ P: PWideChar;
+ I: Integer;
+begin
+ Result := nil;
+ if (S = nil) or (SubStr = nil) or
+ (S[0] = #0) or (SubStr[0] = #0) then
+ Exit;
+ Result := S;
+ while Result[0] <> #0 do
+ begin
+ if Result[0] <> SubStr[0] then
+ Inc(Result)
+ else
+ begin
+ P := Result + 1;
+ I := 0;
+ while (P[0] <> #0) and (P[0] = SubStr[I]) do
+ begin
+ Inc(I);
+ Inc(P);
+ end;
+ if SubStr[I] = #0 then
+ Exit
+ else
+ Inc(Result);
+ end;
+ end;
+ Result := nil;
+end;
+
+function StrLenW(S: PWideChar): Integer;
+begin
+ Result := 0;
+ if S <> nil then
+ while S[Result] <> #0 do
+ Inc(Result);
+end;
+{$ENDIF !CLR}
+
+function TrimW(const S: WideString): WideString;
+{$IFDEF COMPILER6_UP}
+begin
+ Result := Trim(S);
+end;
+{$ELSE}
+var
+ I, L: Integer;
+begin
+ L := Length(S);
+ I := 1;
+ while (I <= L) and (S[I] <= ' ') do
+ Inc(I);
+ if I > L then
+ Result := ''
+ else
+ begin
+ while S[L] <= ' ' do
+ Dec(L);
+ Result := Copy(S, I, L - I + 1);
+ end;
+end;
+{$ENDIF COMPILER6_UP}
+
+function TrimLeftW(const S: WideString): WideString;
+{$IFDEF COMPILER6_UP}
+begin
+ Result := TrimLeft(S);
+end;
+{$ELSE}
+var
+ I, L: Integer;
+begin
+ L := Length(S);
+ I := 1;
+ while (I <= L) and (S[I] <= ' ') do
+ Inc(I);
+ Result := Copy(S, I, MaxInt);
+end;
+{$ENDIF COMPILER6_UP}
+
+function TrimRightW(const S: WideString): WideString;
+{$IFDEF COMPILER6_UP}
+begin
+ Result := TrimRight(S);
+end;
+{$ELSE}
+var
+ I: Integer;
+begin
+ I := Length(S);
+ while (I > 0) and (S[I] <= ' ') do
+ Dec(I);
+ Result := Copy(S, 1, I);
+end;
+{$ENDIF COMPILER6_UP}
+
+procedure SetDelimitedText(List: TStrings; const Text: string; Delimiter: Char);
+var
+ {$IFDEF COMPILER6_UP}
+ Ch: Char;
+ {$ELSE}
+ S: string;
+ F, P: PChar;
+ {$ENDIF COMPILER6_UP}
+begin
+ {$IFDEF COMPILER6_UP}
+ Ch := List.Delimiter;
+ try
+ List.Delimiter := Delimiter;
+ List.DelimitedText := Text;
+ finally
+ List.Delimiter := Ch;
+ end;
+ {$ELSE}
+ List.BeginUpdate;
+ try
+ List.Clear;
+ P := PChar(Text);
+ while P^ in [#1..#32] do
+ Inc(P);
+ while P^ <> #0 do
+ begin
+ if P^ = '"' then
+ begin
+ F := P;
+ while (P[0] <> #0) and (P[0] <> '"') do
+ Inc(P);
+ SetString(S, F, P - F);
+ end
+ else
+ begin
+ F := P;
+ while not (P[0] < #32) and (P[0] <> Delimiter) do
+ Inc(P);
+ SetString(S, F, P - F);
+ end;
+ List.Add(S);
+ while P[0] in [#1..#32] do
+ Inc(P);
+ if P[0] = Delimiter then
+ begin
+ F := P;
+ Inc(F);
+ if F[0] = #0 then
+ List.Add('');
+ repeat
+ Inc(P);
+ until not (P[0] in [#1..#32]);
+ end;
+ end;
+ finally
+ List.EndUpdate;
+ end;
+ {$ENDIF COMPILER6_UP}
+end;
+
+function StrToBool(const S: string): Boolean;
+begin
+ Result := (S = '1') or SameText(S, 'True') or SameText(S, 'yes');
+end;
+
+function RATextOutEx(Canvas: TCanvas; const R, RClip: TRect; const S: string;
+ const CalcHeight: Boolean): Integer;
+var
+ Ss: TStrings;
+ I: Integer;
+ H: Integer;
+begin
+ Ss := TStringList.Create;
+ try
+ Ss.Text := S;
+ H := Canvas.TextHeight('A');
+ Result := H * Ss.Count;
+ if not CalcHeight then
+ for I := 0 to Ss.Count - 1 do
+ ExtTextOut(
+ Canvas.Handle, // handle of device context
+ R.Left, // X-coordinate of reference point
+ R.Top + H * I, // Y-coordinate of reference point
+ ETO_CLIPPED, // text-output options
+ {$IFDEF CLR}
+ RClip,
+ Ss[I],
+ Length(Ss[I]),
+ {$ELSE}
+ @RClip, // optional clipping and/or opaquing rectangle
+ PChar(Ss[I]),
+ Length(Ss[I]), // number of characters in string
+ {$ENDIF CLR}
+ nil); // address of array of intercharacter spacing values
+ finally
+ Ss.Free;
+ end;
+end;
+
+procedure RATextOut(Canvas: TCanvas; const R, RClip: TRect; const S: string);
+begin
+ RATextOutEx(Canvas, R, RClip, S, False);
+end;
+
+function RATextCalcHeight(Canvas: TCanvas; const R: TRect; const S: string): Integer;
+begin
+ Result := RATextOutEx(Canvas, R, R, S, True);
+end;
+
+procedure Cinema(Canvas: TCanvas; rS, rD: TRect);
+const
+ Pause = 30; {milliseconds}
+ Steps = 7;
+ Width = 1;
+var
+ R: TRect;
+ I: Integer;
+ PenOld: TPen;
+
+ procedure FrameR(R: TRect);
+ begin
+ with Canvas do
+ begin
+ MoveTo(R.Left, R.Top);
+ LineTo(R.Left, R.Bottom);
+ LineTo(R.Right, R.Bottom);
+ LineTo(R.Right, R.Top);
+ LineTo(R.Left, R.Top);
+ end;
+ end;
+
+ procedure Frame;
+ begin
+ FrameR(R);
+ with Canvas do
+ begin
+ MoveTo(rS.Left, rS.Top);
+ LineTo(R.Left, R.Top);
+ if R.Top <> rS.Top then
+ begin
+ MoveTo(rS.Right, rS.Top);
+ LineTo(R.Right, R.Top);
+ end;
+ if R.Left <> rS.Left then
+ begin
+ MoveTo(rS.Left, rS.Bottom);
+ LineTo(R.Left, R.Bottom);
+ end;
+ if (R.Bottom <> rS.Bottom) and (R.Right <> rS.Right) then
+ begin
+ MoveTo(rS.Right, rS.Bottom);
+ LineTo(R.Right, R.Bottom);
+ end;
+ end;
+ end;
+
+begin
+ PenOld := TPen.Create;
+ PenOld.Assign(Canvas.Pen);
+ Canvas.Pen.Mode := pmNot;
+ Canvas.Pen.Width := Width;
+ Canvas.Pen.Style := psDot;
+ FrameR(rS);
+ R := rS;
+ for I := 1 to Steps do
+ begin
+ R.Left := rS.Left + (rD.Left - rS.Left) div Steps * I;
+ R.Top := rS.Top + (rD.Top - rS.Top) div Steps * I;
+ R.Bottom := rS.Bottom + (rD.Bottom - rS.Bottom) div Steps * I;
+ R.Right := rS.Right + (rD.Right - rS.Right) div Steps * I;
+ Frame;
+ Sleep(Pause);
+ Frame;
+ end;
+ FrameR(rS);
+ Canvas.Pen.Assign(PenOld);
+end;
+
+function IniReadSection(const IniFileName: TFileName; const Section: string; Ss: TStrings): Boolean;
+var
+ F: Integer;
+ S: string;
+begin
+ with TStringList.Create do
+ try
+ LoadFromFile(IniFileName);
+ F := IndexOf('[' + Section + ']');
+ Result := F > -1;
+ if Result then
+ begin
+ Ss.BeginUpdate;
+ try
+ Ss.Clear;
+ Inc(F);
+ while F < Count do
+ begin
+ S := Strings[F];
+ if (Length(S) > 0) and (Trim(S[1]) = '[') then
+ Break;
+ Ss.Add(S);
+ Inc(F);
+ end;
+ finally
+ Ss.EndUpdate;
+ end;
+ end;
+ finally
+ Free;
+ end;
+end;
+
+procedure SaveTextFile(const FileName: TFileName; const Source: string);
+begin
+ with TStringList.Create do
+ try
+ Text := Source;
+ SaveToFile(FileName);
+ finally
+ Free;
+ end;
+end;
+
+function LoadTextFile(const FileName: TFileName): string;
+begin
+ with TStringList.Create do
+ try
+ LoadFromFile(FileName);
+ Result := Text;
+ finally
+ Free;
+ end;
+end;
+
+function ReadFolder(const Folder, Mask: TFileName; FileList: TStrings): Integer;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+begin
+ FileList.BeginUpdate;
+ try
+ FileList.Clear;
+ Result := FindFirst(AddSlash(Folder) + Mask, faAnyFile, SearchRec);
+ DosError := Result;
+ while DosError = 0 do
+ begin
+ if not ((SearchRec.Attr and faDirectory) = faDirectory) then
+ FileList.Add(SearchRec.Name);
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+ finally
+ FileList.EndUpdate;
+ end;
+end;
+
+function ReadFolders(const Folder: TFileName; FolderList: TStrings): Integer;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+begin
+ FolderList.BeginUpdate;
+ try
+ FolderList.Clear;
+ Result := FindFirst(AddSlash(Folder) + AllFilesMask, faAnyFile, SearchRec);
+ DosError := Result;
+ while DosError = 0 do
+ begin
+ if ((SearchRec.Attr and faDirectory) = faDirectory) and
+ (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
+ FolderList.Add(SearchRec.Name);
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+ finally
+ FolderList.EndUpdate;
+ end;
+end;
+
+{ example for ReplaceStrings:
+ with memEdit do
+ begin
+ Text := ReplaceStrings(Text, SelStart+1, SelLength, memWords.Lines, memFrases.Lines, NewSelStart);
+ SelStart := NewSelStart-1;
+ end; }
+
+function ReplaceStrings(const S: string; PosBeg, Len: Integer; Words, Frases: TStrings;
+ var NewSelStart: Integer): string;
+var
+ I, Beg, Ent, LS, F: Integer;
+ Word: string;
+begin
+ NewSelStart := PosBeg;
+ Result := S;
+ LS := Length(S);
+ if Len = 0 then
+ begin
+ if PosBeg < 1 then
+ Exit;
+ if PosBeg = 1 then
+ PosBeg := 2;
+ for I := PosBeg - 1 downto 1 do
+ if S[I] in Separators then
+ Break;
+ Beg := I + 1;
+ for Ent := PosBeg to LS do
+ if S[Ent] in Separators then
+ Break;
+ if Ent > Beg then
+ Word := Copy(S, Beg, Ent - Beg)
+ else
+ Word := S[PosBeg];
+ end
+ else
+ begin
+ Word := Copy(S, PosBeg, Len);
+ Beg := PosBeg;
+ Ent := PosBeg + Len;
+ end;
+ if Word = '' then
+ Exit;
+ F := Words.IndexOf(Word);
+ if (F > -1) and (F < Frases.Count) then
+ begin
+ Result := Copy(S, 1, Beg - 1) + Frases[F] + Copy(S, Ent, LS);
+ NewSelStart := Beg + Length(Frases[F]);
+ end;
+end;
+
+{ example for ReplaceAllStrings:
+
+ with memEdit do
+ Text := ReplaceAllStrings(Text, memWords.Lines, memFrases.Lines);
+}
+
+function ReplaceAllStrings(const S: string; Words, Frases: TStrings): string;
+var
+ I: Integer;
+begin
+ Result := S;
+ for I := 0 to Words.Count - 1 do
+ Result := ReplaceString(Result, Words[I], Frases[I]);
+end;
+
+function CountOfLines(const S: string): Integer;
+begin
+ with TStringList.Create do
+ try
+ Text := S;
+ Result := Count;
+ finally
+ Free;
+ end;
+end;
+
+procedure DeleteOfLines(Ss: TStrings; const Words: array of string);
+var
+ I, J: Integer;
+begin
+ Ss.BeginUpdate;
+ try
+ for J:= Low(Words) to High(Words) do
+ for I := Ss.Count - 1 downto 0 do
+ if Trim(Ss[I]) = Trim(Words[J]) then
+ Ss.Delete(I);
+ finally
+ Ss.EndUpdate;
+ end;
+end;
+
+procedure DeleteEmptyLines(Ss: TStrings);
+begin
+ DeleteOfLines(Ss,['']);
+end;
+
+procedure SQLAddWhere(SQL: TStrings; const Where: string);
+var
+ I, J: Integer;
+begin
+ J := SQL.Count - 1;
+ for I := 0 to SQL.Count - 1 do
+ // (rom) does this always work? Think of a fieldname "grouporder"
+ {$IFDEF CLR}
+ if StartsText('where ', SQL[I]) then
+ begin
+ J := I + 1;
+ while J < SQL.Count do
+ begin
+ if StartsText('order ', SQL[J]) or StartsText('group ', SQL[J]) then
+ Break;
+ Inc(J);
+ end;
+ end;
+ {$ELSE}
+ if StrLIComp(PChar(SQL[I]), 'where ', 6) = 0 then
+ begin
+ J := I + 1;
+ while J < SQL.Count do
+ begin
+ if (StrLIComp(PChar(SQL[J]), 'order ', 6) = 0) or
+ (StrLIComp(PChar(SQL[J]), 'group ', 6) = 0) then
+ Break;
+ Inc(J);
+ end;
+ end;
+ {$ENDIF CLR}
+ SQL.Insert(J, 'and ' + Where);
+end;
+
+procedure InternalFrame3D(Canvas: TCanvas; var Rect: TRect; TopColor, BottomColor: TColor;
+ Width: Integer);
+
+ procedure DoRect;
+ var
+ TopRight, BottomLeft: TPoint;
+ begin
+ with Canvas, Rect do
+ begin
+ TopRight.X := Right;
+ TopRight.Y := Top;
+ BottomLeft.X := Left;
+ BottomLeft.Y := Bottom;
+ Pen.Color := TopColor;
+ PolyLine([BottomLeft, TopLeft, TopRight]);
+ Pen.Color := BottomColor;
+ Dec(BottomLeft.X);
+ PolyLine([TopRight, BottomRight, BottomLeft]);
+ end;
+ end;
+
+begin
+ Canvas.Pen.Width := 1;
+ Dec(Rect.Bottom);
+ Dec(Rect.Right);
+ while Width > 0 do
+ begin
+ Dec(Width);
+ DoRect;
+ InflateRect(Rect, -1, -1);
+ end;
+ Inc(Rect.Bottom);
+ Inc(Rect.Right);
+end;
+
+procedure Roughed(ACanvas: TCanvas; const ARect: TRect; const AVert: Boolean);
+var
+ I: Integer;
+ J: Integer;
+ R: TRect;
+ V: Boolean;
+ H: Boolean;
+begin
+ H := True;
+ V := True;
+ for I := 0 to (ARect.Right - ARect.Left) div 4 do
+ begin
+ for J := 0 to (ARect.Bottom - ARect.Top) div 4 do
+ begin
+ if AVert then
+ begin
+ if V then
+ R := Bounds(ARect.Left + I * 4 + 2, ARect.Top + J * 4, 2, 2)
+ else
+ R := Bounds(ARect.Left + I * 4, ARect.Top + J * 4, 2, 2);
+ end
+ else
+ begin
+ if H then
+ R := Bounds(ARect.Left + I * 4, ARect.Top + J * 4 + 2, 2, 2)
+ else
+ R := Bounds(ARect.Left + I * 4, ARect.Top + J * 4, 2, 2);
+ end;
+
+ InternalFrame3D(ACanvas, R, clBtnHighlight, clBtnShadow, 1);
+ V := not V;
+ end;
+ H := not H;
+ end;
+end;
+
+function BitmapFromBitmap(SrcBitmap: TBitmap; const AWidth, AHeight, Index: Integer): TBitmap;
+begin
+ Result := TBitmap.Create;
+ Result.Width := AWidth;
+ Result.Height := AHeight;
+ Result.Canvas.CopyRect(Rect(0, 0, AWidth, AHeight), SrcBitmap.Canvas, Bounds(AWidth * Index, 0, AWidth, AHeight));
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+
+function ResSaveToFileEx(Instance: HINST; Typ, Name: PChar;
+ const Compressed: Boolean; const FileName: string): Boolean;
+var
+ RhRsrc: HRSRC;
+ RhGlobal: HGLOBAL;
+ RAddr: Pointer;
+ RLen: DWORD;
+ Stream: TFileStream;
+ FileDest: string;
+begin
+ Result := False;
+ RhRsrc := FindResource(
+ Instance, // resource-module handle
+ Name, // address of resource name
+ Typ); // address of resource type
+ if RhRsrc = 0 then
+ Exit;
+ RhGlobal := LoadResource(
+ Instance, // resource-module handle
+ RhRsrc); // resource handle
+ if RhGlobal = 0 then
+ Exit;
+ RAddr := LockResource(
+ RhGlobal); // handle to resource to lock
+ FreeResource(RhGlobal);
+ if RAddr = nil then
+ Exit;
+ RLen := SizeofResource(
+ Instance, // resource-module handle
+ RhRsrc); // resource handle
+ if RLen = 0 then
+ Exit;
+ { And now it is possible to duplicate [translated] }
+ Stream := nil; { for Free [translated] }
+ if Compressed then
+ FileDest := GenTempFileName(FileName)
+ else
+ FileDest := FileName;
+ try
+ try
+ Stream := TFileStream.Create(FileDest, fmCreate or fmOpenWrite or fmShareExclusive);
+ Stream.WriteBuffer(RAddr^, RLen);
+ finally
+ Stream.Free;
+ end;
+ if Compressed then
+ begin
+ Result := LZFileExpand(FileDest, FileName);
+ DeleteFile(FileDest);
+ end
+ else
+ Result := True;
+ except
+ end;
+end;
+
+function ResSaveToFile(const Typ, Name: string; const Compressed: Boolean;
+ const FileName: string): Boolean;
+begin
+ Result := ResSaveToFileEx(HInstance, PChar(Typ), PChar(Name), Compressed, FileName);
+end;
+
+function ResSaveToString(Instance: HINST; const Typ, Name: string;
+ var S: string): Boolean;
+var
+ RhRsrc: HRSRC;
+ RhGlobal: HGLOBAL;
+ RAddr: Pointer;
+ RLen: DWORD;
+begin
+ Result := False;
+ RhRsrc := FindResource(
+ Instance, // resource-module handle
+ PChar(Name), // address of resource name
+ PChar(Typ)); // address of resource type
+ if RhRsrc = 0 then
+ Exit;
+ RhGlobal := LoadResource(
+ Instance, // resource-module handle
+ RhRsrc); // resource handle
+ if RhGlobal = 0 then
+ Exit;
+ RAddr := LockResource(RhGlobal); // handle to resource to lock
+ FreeResource(RhGlobal);
+ if RAddr = nil then
+ Exit;
+ RLen := SizeofResource(
+ Instance, // resource-module handle
+ RhRsrc); // resource handle
+ if RLen = 0 then
+ Exit;
+ { And now it is possible to duplicate [translated] }
+ SetString(S, PChar(RAddr), RLen);
+end;
+
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+function TextHeight(const AStr: string): Integer;
+var
+ Canvas: TCanvas;
+ DC: HDC;
+begin
+ DC := GetDC(HWND_DESKTOP);
+ Canvas := TCanvas.Create;
+ try
+ Canvas.Handle := DC;
+ Result := Canvas.TextHeight(AStr);
+ Canvas.Handle := NullHandle;
+ finally
+ ReleaseDC(HWND_DESKTOP, DC);
+ Canvas.Free;
+ end;
+end;
+
+function TextWidth(const AStr: string): Integer;
+var
+ Canvas: TCanvas;
+ DC: HDC;
+begin
+ DC := GetDC(HWND_DESKTOP);
+ Canvas := TCanvas.Create;
+ try
+ Canvas.Handle := DC;
+ Result := Canvas.TextWidth(AStr);
+ Canvas.Handle := NullHandle;
+ finally
+ ReleaseDC(HWND_DESKTOP, DC);
+ Canvas.Free;
+ end;
+end;
+
+procedure SetChildPropOrd(Owner: TComponent; const PropName: string; Value: Longint);
+var
+ I: Integer;
+ PropInfo: PPropInfo;
+begin
+ for I := 0 to Owner.ComponentCount - 1 do
+ begin
+ PropInfo := GetPropInfo(Owner.Components[I].ClassInfo, PropName);
+ if PropInfo <> nil then
+ SetOrdProp(Owner.Components[I], PropInfo, Value);
+ end;
+end;
+
+procedure Error(const Msg: string);
+begin
+ raise Exception.Create(Msg);
+end;
+
+procedure ItemHtDrawEx(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean; var PlainItem: string;
+ var Width: Integer; CalcWidth: Boolean);
+var
+ CL: string;
+ I: Integer;
+ M1: string;
+ OriRect: TRect; // it's added
+ LastFontStyle: TFontStyles;
+ LastFontColor: TColor;
+
+ function Cmp(const M1: string): Boolean;
+ begin
+ {$IFDEF CLR}
+ Result := System.String.Compare(Text, I, M1, 0, M1.Length, True) = 0;
+ {$ELSE}
+ Result := AnsiStrLIComp(PChar(Text) + I, PChar(M1), Length(M1)) = 0;
+ {$ENDIF CLR}
+ end;
+
+ function Cmp1(const M1: string): Boolean;
+ begin
+ Result := Cmp(M1);
+ if Result then
+ Inc(I, Length(M1));
+ end;
+
+ function CmpL(const M1: string): Boolean;
+ begin
+ Result := Cmp(M1 + '>');
+ end;
+
+ function CmpL1(const M1: string): Boolean;
+ begin
+ Result := Cmp1(M1 + '>');
+ end;
+
+ procedure Draw(const M: string);
+ begin
+ if not Assigned(Canvas) then
+ Exit;
+ if not CalcWidth then
+ Canvas.TextOut(Rect.Left, Rect.Top, M);
+ Rect.Left := Rect.Left + Canvas.TextWidth(M);
+ end;
+
+ procedure Style(const Style: TFontStyle; const Include: Boolean);
+ begin
+ if not Assigned(Canvas) then
+ Exit;
+ if Include then
+ Canvas.Font.Style := Canvas.Font.Style + [Style]
+ else
+ Canvas.Font.Style := Canvas.Font.Style - [Style];
+ end;
+
+begin
+ PlainItem := '';
+ LastFontColor := 0; { satisfy compiler }
+ if Canvas <> nil then
+ begin
+ LastFontStyle := Canvas.Font.Style;
+ LastFontColor := Canvas.Font.Color;
+ end;
+ try
+ if HideSelColor and Assigned(Canvas) then
+ begin
+ Canvas.Brush.Color := clWindow;
+ Canvas.Font.Color := clWindowText;
+ end;
+ if Assigned(Canvas) then
+ Canvas.FillRect(Rect);
+
+ Width := Rect.Left;
+ Rect.Left := Rect.Left + 2;
+
+ OriRect := Rect; //save origin rectangle
+
+ M1 := '';
+ I := 1;
+ while I <= Length(Text) do
+ begin
+ if (Text[I] = '<') and
+ (CmpL('b') or CmpL('/b') or
+ CmpL('i') or CmpL('/i') or
+ CmpL('u') or CmpL('/u') or
+ Cmp('c:')) then
+ begin
+ Draw(M1);
+ PlainItem := PlainItem + M1;
+
+ if CmpL1('b') then
+ Style(fsBold, True)
+ else
+ if CmpL1('/b') then
+ Style(fsBold, False)
+ else
+ if CmpL1('i') then
+ Style(fsItalic, True)
+ else
+ if CmpL1('/i') then
+ Style(fsItalic, False)
+ else
+ if CmpL1('u') then
+ Style(fsUnderline, True)
+ else
+ if CmpL1('/u') then
+ Style(fsUnderline, False)
+ else
+ if Cmp1('c:') then
+ begin
+ CL := SubStrBySeparator(Text, 0, '>', I);
+ if (HideSelColor or not (odSelected in State)) and Assigned(Canvas) then
+ try
+ if (Length(CL) > 0) and (CL[1] <> '$') then
+ Canvas.Font.Color := StringToColor('cl' + CL)
+ else
+ Canvas.Font.Color := StringToColor(CL);
+ except
+ end;
+ Inc(I, Length(CL) + 1 {'>'});
+ end;
+ Inc(I);
+ if (Text[I] = Chr(13)) and Cmp1(string(Chr(10))) then
+ begin
+ Rect.Left := OriRect.Left;
+ Rect.Top := Rect.Top + Canvas.TextHeight(M1 + 'W');
+ Inc(I);
+ end;
+ Dec(I);
+ M1 := '';
+ end
+ else
+ if (Text[I] = Chr(13)) and Cmp1(string(Chr(10))) then
+ begin
+ // new line
+ Draw(M1);
+ PlainItem := PlainItem + M1;
+ Rect.Left := OriRect.Left;
+ Rect.Top := Rect.Top + Canvas.TextHeight(M1 + 'W');
+ M1 := '';
+ end
+ else
+ M1 := M1 + Text[I]; // add text
+ Inc(I);
+ end; { for }
+ Draw(M1);
+ PlainItem := PlainItem + M1;
+ finally
+ if Canvas <> nil then
+ begin
+ Canvas.Font.Style := LastFontStyle;
+ Canvas.Font.Color := LastFontColor;
+ end;
+ end;
+ Width := Rect.Left - Width + 2;
+end;
+
+function ItemHtDraw(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean): string;
+var
+ S: string;
+ W: Integer;
+begin
+ ItemHtDrawEx(Canvas, Rect, State, Text, HideSelColor, S, W, False);
+end;
+
+function ItemHtPlain(const Text: string): string;
+var
+ S: string;
+ W: Integer;
+begin
+ ItemHtDrawEx(nil, Rect(0, 0, -1, -1), [], Text, False, S, W, False);
+ Result := S;
+end;
+
+function ItemHtWidth(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string;
+ const HideSelColor: Boolean): Integer;
+var
+ S: string;
+ W: Integer;
+begin
+ ItemHtDrawEx(Canvas, Rect, State, Text, HideSelColor, S, W, True);
+ Result := W;
+end;
+
+procedure ClearList(List: TList);
+var
+ I: Integer;
+begin
+ if Assigned(List) then
+ begin
+ if not (List is TObjectList) then
+ for I := 0 to List.Count - 1 do
+ TObject(List[I]).Free;
+ List.Clear;
+ end;
+end;
+
+{$IFNDEF CLR}
+procedure MemStreamToClipBoard(MemStream: TMemoryStream; const Format: Word);
+
+var
+ Data: THandle;
+ DataPtr: Pointer;
+
+
+begin
+ Clipboard.Open;
+ try
+ Data := GlobalAlloc(GMEM_MOVEABLE, MemStream.Size);
+ try
+ DataPtr := GlobalLock(Data);
+ try
+ Move(MemStream.Memory^, DataPtr^, MemStream.Size);
+ Clipboard.Clear;
+ SetClipboardData(Format, Data);
+ finally
+ GlobalUnlock(Data);
+ end;
+ except
+ GlobalFree(Data);
+ raise;
+ end;
+ finally
+ Clipboard.Close;
+ end;
+end;
+
+procedure ClipBoardToMemStream(MemStream: TMemoryStream; const Format: Word);
+
+var
+ Data: THandle;
+ DataPtr: Pointer;
+
+begin
+ Clipboard.Open;
+ try
+ Data := GetClipboardData(Format);
+ if Data = 0 then
+ Exit;
+ DataPtr := GlobalLock(Data);
+ if DataPtr = nil then
+ Exit;
+ try
+ MemStream.WriteBuffer(DataPtr^, GlobalSize(Data));
+ MemStream.Position := 0;
+ finally
+ GlobalUnlock(Data);
+ end;
+ finally
+ Clipboard.Close;
+ end;
+end;
+{$ENDIF !CLR}
+
+function GetPropTypeKind(PropInf: PPropInfo): TTypeKind;
+begin
+ {$IFDEF CLR}
+ Result := PropInf.TypeKind;
+ {$ELSE}
+ Result := PropInf.PropType^.Kind;
+ {$ENDIF CLR}
+end;
+
+function GetPropType(Obj: TObject; const PropName: string): TTypeKind;
+var
+ PropInf: PPropInfo;
+begin
+ PropInf := GetPropInfo(Obj.ClassInfo, PropName);
+ if PropInf = nil then
+ Result := tkUnknown
+ else
+ Result := GetPropTypeKind(PropInf);
+end;
+
+function GetPropStr(Obj: TObject; const PropName: string): string;
+var
+ PropInf: PPropInfo;
+begin
+ PropInf := GetPropInfo(Obj.ClassInfo, PropName);
+ if PropInf = nil then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEPropertyNotExists, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEPropertyNotExists, [PropName]);
+ {$ENDIF CLR}
+ if not (GetPropTypeKind(PropInf) in [tkString, tkLString, tkWString]) then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEInvalidPropertyType, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEInvalidPropertyType, [PropName]);
+ {$ENDIF CLR}
+ Result := GetStrProp(Obj, PropInf);
+end;
+
+function GetPropOrd(Obj: TObject; const PropName: string): Integer;
+var
+ PropInf: PPropInfo;
+begin
+ PropInf := GetPropInfo(Obj.ClassInfo, PropName);
+ if PropInf = nil then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEPropertyNotExists, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEPropertyNotExists, [PropName]);
+ {$ENDIF CLR}
+ if not (GetPropTypeKind(PropInf) in [tkInteger, tkChar, tkWChar, tkEnumeration, tkClass]) then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEInvalidPropertyType, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEInvalidPropertyType, [PropName]);
+ {$ENDIF CLR}
+ Result := GetOrdProp(Obj, PropInf);
+end;
+
+function GetPropMethod(Obj: TObject; const PropName: string): TMethod;
+var
+ PropInf: PPropInfo;
+begin
+ PropInf := GetPropInfo(Obj.ClassInfo, PropName);
+ if PropInf = nil then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEPropertyNotExists, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEPropertyNotExists, [PropName]);
+ {$ENDIF CLR}
+ if not (GetPropTypeKind(PropInf) = tkMethod) then
+ {$IFDEF CLR}
+ raise Exception.CreateFmt(RsEInvalidPropertyType, [PropName]);
+ {$ELSE}
+ raise Exception.CreateResFmt(@RsEInvalidPropertyType, [PropName]);
+ {$ENDIF CLR}
+ Result := GetMethodProp(Obj, PropInf);
+end;
+
+procedure PrepareIniSection(Ss: TStrings);
+var
+ I: Integer;
+ S: string;
+begin
+ Ss.BeginUpdate;
+ try
+ for I := Ss.Count - 1 downto 0 do
+ begin
+ S := Trim(Ss[I]);
+ if (S = '') or (S[1] in [';', '#']) then
+ Ss.Delete(I);
+ end;
+ finally
+ Ss.EndUpdate;
+ end;
+end;
+
+{:Creates a TPointL structure from a pair of coordinates.
+Call PointL to create a TPointL structure that represents the specified
+coordinates. Use PointL to construct parameters for functions
+that require a TPointL, rather than setting up local variables
+for each parameter.
+@param X The X coordinate.
+@param Y The Y coordinate.
+@return A TPointL structure for coordinates X and Y.
+@example
+var
+ p: TPointL;
+begin
+ p := PointL(100, 100);
+end;
+
+}
+
+function PointL(const X, Y: Longint): TPointL;
+begin
+ Result.X := X;
+ Result.Y := Y;
+end;
+
+{:Conditional assignment.
+Returns the value in True or False depending on the condition Test.
+@param Test The test condition.
+@param True Returns this value if Test is True.
+@param False Returns this value if Test is False.
+@return Value in True or False depending on Test.
+@example
+bar := iif(foo, 1, 0);
+
+
has the same effects as:
+
+if foo then
+ bar := 1
+else
+ bar := 0;
+
+}
+
+function iif(const Test: Boolean; const ATrue, AFalse: Variant): Variant;
+begin
+ if Test then
+ Result := ATrue
+ else
+ Result := AFalse;
+end;
+
+
+{ begin JvIconClipboardUtils}
+{ Icon clipboard routines }
+
+var
+ Private_CF_ICON: Word;
+
+function CF_ICON: Word;
+begin
+ if Private_CF_ICON = 0 then
+ begin
+ { The following string should not be localized }
+ Private_CF_ICON := RegisterClipboardFormat('Delphi Icon');
+ TPicture.RegisterClipboardFormat(Private_CF_ICON, TIcon);
+ end;
+ Result := Private_CF_ICON;
+end;
+
+{$IFNDEF CLR}
+function CreateBitmapFromIcon(Icon: TIcon; BackColor: TColor): TBitmap;
+var
+ Ico: HICON;
+ W, H: Integer;
+begin
+ Ico := CreateRealSizeIcon(Icon);
+ try
+ GetIconSize(Ico, W, H);
+ Result := TBitmap.Create;
+ try
+ Result.Width := W;
+ Result.Height := H;
+ with Result.Canvas do
+ begin
+ Brush.Color := BackColor;
+ FillRect(Rect(0, 0, W, H));
+ DrawIconEx(Handle, 0, 0, Ico, W, H, 0, 0, DI_NORMAL);
+ end;
+ except
+ Result.Free;
+ raise;
+ end;
+ finally
+ DestroyIcon(Ico);
+ end;
+end;
+
+procedure CopyIconToClipboard(Icon: TIcon; BackColor: TColor);
+var
+ Bmp: TBitmap;
+ Stream: TStream;
+ Data: THandle;
+ Format: Word;
+ Palette: HPalette;
+ Buffer: Pointer;
+begin
+ Bmp := CreateBitmapFromIcon(Icon, BackColor);
+ try
+ Stream := TMemoryStream.Create;
+ try
+ Icon.SaveToStream(Stream);
+ Palette := 0;
+ with Clipboard do
+ begin
+ Open;
+ try
+ Clear;
+ Bmp.SaveToClipboardFormat(Format, Data, Palette);
+ SetClipboardData(Format, Data);
+ if Palette <> 0 then
+ SetClipboardData(CF_PALETTE, Palette);
+ Data := GlobalAlloc(HeapAllocFlags, Stream.Size);
+ try
+ if Data <> 0 then
+ begin
+ Buffer := GlobalLock(Data);
+ try
+ Stream.Seek(0, 0);
+ Stream.Read(Buffer^, Stream.Size);
+ SetClipboardData(CF_ICON, Data);
+ finally
+ GlobalUnlock(Data);
+ end;
+ end;
+ except
+ GlobalFree(Data);
+ raise;
+ end;
+ finally
+ Close;
+ end;
+ end;
+ finally
+ Stream.Free;
+ end;
+ finally
+ Bmp.Free;
+ end;
+end;
+
+procedure AssignClipboardIcon(Icon: TIcon);
+var
+ Stream: TStream;
+ Data: THandle;
+ Buffer: Pointer;
+begin
+ if not Clipboard.HasFormat(CF_ICON) then
+ Exit;
+ with Clipboard do
+ begin
+ Open;
+ try
+ Data := GetClipboardData(CF_ICON);
+ Buffer := GlobalLock(Data);
+ try
+ Stream := TMemoryStream.Create;
+ try
+ Stream.Write(Buffer^, GlobalSize(Data));
+ Stream.Seek(0, 0);
+ Icon.LoadFromStream(Stream);
+ finally
+ Stream.Free;
+ end;
+ finally
+ GlobalUnlock(Data);
+ end;
+ finally
+ Close;
+ end;
+ end;
+end;
+
+function CreateIconFromClipboard: TIcon;
+begin
+ Result := nil;
+ if not Clipboard.HasFormat(CF_ICON) then
+ Exit;
+ Result := TIcon.Create;
+ try
+ AssignClipboardIcon(Result);
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+{$ENDIF !CLR}
+
+
+
+
+
+{ Real-size icons support routines }
+const
+ RC3_STOCKICON = 0;
+ RC3_ICON = 1;
+ RC3_CURSOR = 2;
+
+type
+ PCursorOrIcon = ^TCursorOrIcon;
+ TCursorOrIcon = packed record
+ Reserved: Word;
+ wType: Word;
+ Count: Word;
+ end;
+
+ PIconRec = ^TIconRec;
+ TIconRec = packed record
+ Width: Byte;
+ Height: Byte;
+ Colors: Word;
+ Reserved1: Word;
+ Reserved2: Word;
+ DIBSize: Longint;
+ DIBOffset: Longint;
+ end;
+
+function WidthBytes(I: Longint): Longint;
+begin
+ Result := ((I + 31) div 32) * 4;
+end;
+
+function GetDInColors(BitCount: Word): Integer;
+begin
+ case BitCount of
+ 1, 4, 8:
+ Result := 1 shl BitCount;
+ else
+ Result := 0;
+ end;
+end;
+
+{$IFNDEF CLR}
+procedure OutOfResources;
+begin
+ raise EOutOfResources.Create(SOutOfResources);
+end;
+
+function DupBits(Src: HBITMAP; Size: TPoint; Mono: Boolean): HBITMAP;
+var
+ DC, Mem1, Mem2: HDC;
+ Old1, Old2: HBITMAP;
+ Bitmap: tagBITMAP;
+begin
+ Mem1 := CreateCompatibleDC(NullHandle);
+ Mem2 := CreateCompatibleDC(NullHandle);
+ GetObject(Src, SizeOf(Bitmap), @Bitmap);
+ if Mono then
+ Result := CreateBitmap(Size.X, Size.Y, 1, 1, nil)
+ else
+ begin
+ DC := GetDC(HWND_DESKTOP);
+ if DC = NullHandle then
+ OutOfResources;
+ try
+ Result := CreateCompatibleBitmap(DC, Size.X, Size.Y);
+ if Result = NullHandle then
+ OutOfResources;
+ finally
+ ReleaseDC(HWND_DESKTOP, DC);
+ end;
+ end;
+ if Result <> NullHandle then
+ begin
+ Old1 := SelectObject(Mem1, Src);
+ Old2 := SelectObject(Mem2, Result);
+ StretchBlt(Mem2, 0, 0, Size.X, Size.Y, Mem1, 0, 0, Bitmap.bmWidth,
+ Bitmap.bmHeight, SRCCOPY);
+ if Old1 <> NullHandle then
+ SelectObject(Mem1, Old1);
+ if Old2 <> NullHandle then
+ SelectObject(Mem2, Old2);
+ end;
+ DeleteDC(Mem1);
+ DeleteDC(Mem2);
+end;
+
+{$IFDEF MSWINDOWS}
+procedure TwoBitsFromDIB(var BI: TBitmapInfoHeader; var XorBits, AndBits: HBITMAP);
+type
+ PLongArray = ^TLongArray;
+ TLongArray = array [0..1] of Longint;
+var
+ Temp: HBITMAP;
+ NumColors: Integer;
+ DC: HDC;
+ Bits: Pointer;
+ Colors: PLongArray;
+ IconSize: TPoint;
+ BM: tagBITMAP;
+begin
+ IconSize.X := GetSystemMetrics(SM_CXICON);
+ IconSize.Y := GetSystemMetrics(SM_CYICON);
+ with BI do
+ begin
+ biHeight := biHeight shr 1; { Size in record is doubled }
+ biSizeImage := WidthBytes(Longint(biWidth) * biBitCount) * biHeight;
+ NumColors := GetDInColors(biBitCount);
+ end;
+ DC := GetDC(HWND_DESKTOP);
+ if DC = NullHandle then
+ OutOfResources;
+ try
+ Bits := Pointer(Longint(@BI) + SizeOf(BI) + NumColors * SizeOf(TRGBQuad));
+ Temp := CreateDIBitmap(DC, BI, CBM_INIT, Bits, PBitmapInfo(@BI)^, DIB_RGB_COLORS);
+ if Temp = NullHandle then
+ OutOfResources;
+ try
+ GetObject(Temp, SizeOf(BM), @BM);
+ IconSize.X := BM.bmWidth;
+ IconSize.Y := BM.bmHeight;
+ XorBits := DupBits(Temp, IconSize, False);
+ finally
+ DeleteObject(Temp);
+ end;
+ with BI do
+ begin
+ Inc(Longint(Bits), biSizeImage);
+ biBitCount := 1;
+ biSizeImage := WidthBytes(Longint(biWidth) * biBitCount) * biHeight;
+ biClrUsed := 2;
+ biClrImportant := 2;
+ end;
+ Colors := Pointer(Longint(@BI) + SizeOf(BI));
+ Colors^[0] := 0;
+ Colors^[1] := $FFFFFF;
+ Temp := CreateDIBitmap(DC, BI, CBM_INIT, Bits, PBitmapInfo(@BI)^, DIB_RGB_COLORS);
+ if Temp = NullHandle then
+ OutOfResources;
+ try
+ AndBits := DupBits(Temp, IconSize, True);
+ finally
+ DeleteObject(Temp);
+ end;
+ finally
+ ReleaseDC(HWND_DESKTOP, DC);
+ end;
+end;
+
+procedure ReadIcon(Stream: TStream; var Icon: HICON; ImageCount: Integer;
+ StartOffset: Integer);
+type
+ PIconRecArray = ^TIconRecArray;
+ TIconRecArray = array [0..300] of TIconRec;
+var
+ List: PIconRecArray;
+ HeaderLen, Length: Integer;
+ Colors, BitsPerPixel: Word;
+ C1, C2, N, Index: Integer;
+ IconSize: TPoint;
+ DC: HDC;
+ BI: PBitmapInfoHeader;
+ ResData: Pointer;
+ XorBits, AndBits: HBITMAP;
+ XorInfo, AndInfo: Windows.TBitmap;
+ XorMem, AndMem: Pointer;
+ XorLen, AndLen: Integer;
+begin
+ HeaderLen := SizeOf(TIconRec) * ImageCount;
+ List := AllocMem(HeaderLen);
+ try
+ Stream.Read(List^, HeaderLen);
+ IconSize.X := GetSystemMetrics(SM_CXICON);
+ IconSize.Y := GetSystemMetrics(SM_CYICON);
+ DC := GetDC(HWND_DESKTOP);
+ if DC = NullHandle then
+ OutOfResources;
+ try
+ BitsPerPixel := GetDeviceCaps(DC, PLANES) * GetDeviceCaps(DC, BITSPIXEL);
+ if BitsPerPixel = 24 then
+ Colors := 0
+ else
+ Colors := 1 shl BitsPerPixel;
+ finally
+ ReleaseDC(HWND_DESKTOP, DC);
+ end;
+ Index := -1;
+ { the following code determines which image most closely matches the
+ current device. It is not meant to absolutely match Windows
+ (known broken) algorithm }
+ C2 := 0;
+ for N := 0 to ImageCount - 1 do
+ begin
+ C1 := List^[N].Colors;
+ if C1 = Colors then
+ begin
+ Index := N;
+ Break;
+ end
+ else
+ if Index = -1 then
+ begin
+ if C1 <= Colors then
+ begin
+ Index := N;
+ C2 := List^[N].Colors;
+ end;
+ end
+ else
+ if C1 > C2 then
+ Index := N;
+ end;
+ if Index = -1 then
+ Index := 0;
+ with List^[Index] do
+ begin
+ BI := AllocMem(DIBSize);
+ try
+ Stream.Seek(DIBOffset - (HeaderLen + StartOffset), 1);
+ Stream.Read(BI^, DIBSize);
+ TwoBitsFromDIB(BI^, XorBits, AndBits);
+ GetObject(AndBits, SizeOf(Windows.TBitmap), @AndInfo);
+ GetObject(XorBits, SizeOf(Windows.TBitmap), @XorInfo);
+ IconSize.X := AndInfo.bmWidth;
+ IconSize.Y := AndInfo.bmHeight;
+ with AndInfo do
+ AndLen := bmWidthBytes * bmHeight * bmPlanes;
+ with XorInfo do
+ XorLen := bmWidthBytes * bmHeight * bmPlanes;
+ Length := AndLen + XorLen;
+ ResData := AllocMem(Length);
+ try
+ AndMem := ResData;
+ with AndInfo do
+ XorMem := Pointer(Longint(ResData) + AndLen);
+ GetBitmapBits(AndBits, AndLen, AndMem);
+ GetBitmapBits(XorBits, XorLen, XorMem);
+ DeleteObject(XorBits);
+ DeleteObject(AndBits);
+ Icon := CreateIcon(HInstance, IconSize.X, IconSize.Y,
+ XorInfo.bmPlanes, XorInfo.bmBitsPixel, AndMem, XorMem);
+ if Icon = 0 then
+ OutOfResources;
+ finally
+ FreeMem(ResData, Length);
+ end;
+ finally
+ FreeMem(BI, DIBSize);
+ end;
+ end;
+ finally
+ FreeMem(List, HeaderLen);
+ end;
+end;
+{$ENDIF MSWINDOWS}
+
+
+
+procedure GetIconSize(Icon: HICON; var W, H: Integer);
+var
+ IconInfo: TIconInfo;
+ BM: Windows.TBitmap;
+begin
+ if GetIconInfo(Icon, IconInfo) then
+ begin
+ try
+ if IconInfo.hbmColor <> 0 then
+ begin
+ GetObject(IconInfo.hbmColor, SizeOf(BM), @BM);
+ W := BM.bmWidth;
+ H := BM.bmHeight;
+ end
+ else
+ if IconInfo.hbmMask <> 0 then
+ begin { Monochrome icon }
+ GetObject(IconInfo.hbmMask, SizeOf(BM), @BM);
+ W := BM.bmWidth;
+ H := BM.bmHeight shr 1; { Size in record is doubled }
+ end
+ else
+ begin
+ W := GetSystemMetrics(SM_CXICON);
+ H := GetSystemMetrics(SM_CYICON);
+ end;
+ finally
+ if IconInfo.hbmColor <> 0 then
+ DeleteObject(IconInfo.hbmColor);
+ if IconInfo.hbmMask <> 0 then
+ DeleteObject(IconInfo.hbmMask);
+ end;
+ end
+ else
+ begin
+ W := GetSystemMetrics(SM_CXICON);
+ H := GetSystemMetrics(SM_CYICON);
+ end;
+end;
+
+function CreateRealSizeIcon(Icon: TIcon): HICON;
+var
+ Mem: TMemoryStream;
+ CI: TCursorOrIcon;
+begin
+ Result := 0;
+ Mem := TMemoryStream.Create;
+ try
+ Icon.SaveToStream(Mem);
+ Mem.Position := 0;
+ Mem.ReadBuffer(CI, SizeOf(CI));
+ case CI.wType of
+ RC3_STOCKICON:
+ Result := LoadIcon(0, IDI_APPLICATION);
+ RC3_ICON:
+ ReadIcon(Mem, Result, CI.Count, SizeOf(CI));
+ else
+ Result := CopyIcon(Icon.Handle);
+ end;
+ finally
+ Mem.Free;
+ end;
+end;
+
+procedure DrawRealSizeIcon(Canvas: TCanvas; Icon: TIcon; X, Y: Integer);
+var
+ Ico: HICON;
+ W, H: Integer;
+begin
+ Ico := CreateRealSizeIcon(Icon);
+ try
+ GetIconSize(Ico, W, H);
+ DrawIconEx(Canvas.Handle, X, Y, Ico, W, H, 0, 0, DI_NORMAL);
+ finally
+ DestroyIcon(Ico);
+ end;
+end;
+
+function CreateScreenCompatibleDC: HDC;
+const
+ HDC_DESKTOP = HDC(0);
+begin
+ Result := CreateCompatibleDC(HDC_DESKTOP);
+end;
+
+
+{$ENDIF !CLR}
+
+{ end JvIconClipboardUtils }
+
+{ begin JvRLE }
+
+procedure RleCompressTo(InStream, OutStream: TStream);
+var
+ Count, Count2, Count3, I: Integer;
+ Buf1: array [0..1024] of Byte;
+ Buf2: array [0..60000] of Byte;
+ B: Byte;
+begin
+ InStream.Position := 0;
+ Count := 1024;
+ while Count = 1024 do
+ begin
+ Count := InStream.Read(Buf1, 1024);
+ Count2 := 0;
+ I := 0;
+ while I < Count do
+ begin
+ B := Buf1[I];
+ Count3 := 0;
+ while (Buf1[I] = B) and (I < Count) and (Count3 < $30) do
+ begin
+ Inc(I);
+ Inc(Count3);
+ end;
+ if (I = Count) and (Count3 in [2..$2F]) and (Count = 1024) then
+ InStream.Position := InStream.Position - Count3
+ else
+ begin
+ if Count3 = 1 then
+ begin
+ if (B and $C0) = $C0 then
+ begin
+ Buf2[Count2] := $C1;
+ Buf2[Count2 + 1] := B;
+ Inc(Count2, 2);
+ end
+ else
+ begin
+ Buf2[Count2] := B;
+ Inc(Count2);
+ end;
+ end
+ else
+ begin
+ Buf2[Count2] := Count3 or $C0;
+ Buf2[Count2 + 1] := B;
+ Inc(Count2, 2);
+ end;
+ end;
+ end;
+ OutStream.Write(Buf2, Count2);
+ end;
+end;
+
+procedure RleDecompressTo(InStream, OutStream: TStream);
+var
+ Count, Count2, Count3, I: Integer;
+ Buf1: array [0..1024] of Byte;
+ Buf2: array [0..60000] of Byte;
+ B: Byte;
+begin
+ InStream.Position := 0;
+ Count := 1024;
+ while Count = 1024 do
+ begin
+ Count := InStream.Read(Buf1, 1024);
+ Count2 := 0;
+ I := 0;
+ while I < Count do
+ begin
+ if (Buf1[I] and $C0) = $C0 then
+ begin
+ if I = Count - 1 then
+ InStream.Position := InStream.Position - 1
+ else
+ begin
+ B := Buf1[I] and $3F;
+ Inc(I);
+ for Count3 := Count2 to Count2 + B - 1 do
+ Buf2[Count3] := Buf1[I];
+ Count2 := Count2 + B;
+ end;
+ end
+ else
+ begin
+ Buf2[Count2] := Buf1[I];
+ Inc(Count2);
+ end;
+ Inc(I);
+ end;
+ OutStream.Write(Buf2, Count2);
+ end;
+end;
+
+procedure RleCompress(Stream: TStream);
+var
+ Tmp: TMemoryStream;
+begin
+ Tmp := TMemoryStream.Create;
+ try
+ RleCompressTo(Stream, Tmp);
+ Tmp.Position := 0;
+ Stream.Size := 0;
+ Stream.CopyFrom(Tmp, 0);
+ finally
+ Tmp.Free;
+ end;
+end;
+
+procedure RleDecompress(Stream: TStream);
+var
+ Tmp: TMemoryStream;
+begin
+ Tmp := TMemoryStream.Create;
+ try
+ RleDecompressTo(Stream, Tmp);
+ Tmp.Position := 0;
+ Stream.Size := 0;
+ Stream.CopyFrom(Tmp, 0);
+ finally
+ Tmp.Free;
+ end;
+end;
+{ end JvRLE }
+
+{ begin JvDateUtil }
+
+function IsLeapYear(AYear: Integer): Boolean;
+begin
+ Result := (AYear mod 4 = 0) and ((AYear mod 100 <> 0) or (AYear mod 400 = 0));
+end;
+
+function DaysInAMonth(const AYear, AMonth: Word): Word;
+begin
+ Result := MonthDays[(AMonth = 2) and IsLeapYear(AYear), AMonth];
+end;
+
+function DaysPerMonth(AYear, AMonth: Integer): Integer;
+begin
+ Result := DaysInAMonth(AYear, AMonth);
+end;
+
+function FirstDayOfNextMonth: TDateTime;
+var
+ Year, Month, Day: Word;
+begin
+ DecodeDate(Date, Year, Month, Day);
+ Day := 1;
+ if Month < 12 then
+ Inc(Month)
+ else
+ begin
+ Inc(Year);
+ Month := 1;
+ end;
+ Result := EncodeDate(Year, Month, Day);
+end;
+
+function FirstDayOfPrevMonth: TDateTime;
+var
+ Year, Month, Day: Word;
+begin
+ DecodeDate(Date, Year, Month, Day);
+ Day := 1;
+ if Month > 1 then
+ Dec(Month)
+ else
+ begin
+ Dec(Year);
+ Month := 12;
+ end;
+ Result := EncodeDate(Year, Month, Day);
+end;
+
+function LastDayOfPrevMonth: TDateTime;
+var
+ D: TDateTime;
+ Year, Month, Day: Word;
+begin
+ D := FirstDayOfPrevMonth;
+ DecodeDate(D, Year, Month, Day);
+ Day := DaysPerMonth(Year, Month);
+ Result := EncodeDate(Year, Month, Day);
+end;
+
+function ExtractDay(ADate: TDateTime): Word;
+var
+ M, Y: Word;
+begin
+ DecodeDate(ADate, Y, M, Result);
+end;
+
+function ExtractMonth(ADate: TDateTime): Word;
+var
+ D, Y: Word;
+begin
+ DecodeDate(ADate, Y, Result, D);
+end;
+
+function ExtractYear(ADate: TDateTime): Word;
+var
+ D, M: Word;
+begin
+ DecodeDate(ADate, Result, M, D);
+end;
+
+function IncDate(ADate: TDateTime; Days, Months, Years: Integer): TDateTime;
+var
+ D, M, Y: Word;
+ Day, Month, Year: Longint;
+begin
+ DecodeDate(ADate, Y, M, D);
+ Year := Y;
+ Month := M;
+ Day := D;
+ Inc(Year, Years);
+ Inc(Year, Months div 12);
+ Inc(Month, Months mod 12);
+ if Month < 1 then
+ begin
+ Inc(Month, 12);
+ Dec(Year);
+ end
+ else
+ if Month > 12 then
+ begin
+ Dec(Month, 12);
+ Inc(Year);
+ end;
+ if Day > DaysPerMonth(Year, Month) then
+ Day := DaysPerMonth(Year, Month);
+ Result := EncodeDate(Year, Month, Day) + Days + Frac(ADate);
+end;
+
+procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word);
+{ Corrected by Anatoly A. Sanko (2:450/73) }
+var
+ DtSwap: TDateTime;
+ Day1, Day2, Month1, Month2, Year1, Year2: Word;
+begin
+ if Date1 > Date2 then
+ begin
+ DtSwap := Date1;
+ Date1 := Date2;
+ Date2 := DtSwap;
+ end;
+ DecodeDate(Date1, Year1, Month1, Day1);
+ DecodeDate(Date2, Year2, Month2, Day2);
+ Years := Year2 - Year1;
+ Months := 0;
+ Days := 0;
+ if Month2 < Month1 then
+ begin
+ Inc(Months, 12);
+ Dec(Years);
+ end;
+ Inc(Months, Month2 - Month1);
+ if Day2 < Day1 then
+ begin
+ Inc(Days, DaysPerMonth(Year1, Month1));
+ if Months = 0 then
+ begin
+ Dec(Years);
+ Months := 11;
+ end
+ else
+ Dec(Months);
+ end;
+ Inc(Days, Day2 - Day1);
+end;
+
+function IncDay(ADate: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := ADate + Delta;
+end;
+
+function IncMonth(ADate: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncDate(ADate, 0, Delta, 0);
+end;
+
+function IncYear(ADate: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncDate(ADate, 0, 0, Delta);
+end;
+
+function MonthsBetween(Date1, Date2: TDateTime): Double;
+var
+ D, M, Y: Word;
+begin
+ DateDiff(Date1, Date2, D, M, Y);
+ Result := 12 * Y + M;
+ if (D > 1) and (D < 7) then
+ Result := Result + 0.25
+ else
+ if (D >= 7) and (D < 15) then
+ Result := Result + 0.5
+ else
+ if (D >= 15) and (D < 21) then
+ Result := Result + 0.75
+ else
+ if D >= 21 then
+ Result := Result + 1;
+end;
+
+function IsValidDate(Y, M, D: Word): Boolean;
+begin
+ Result := (Y >= 1) and (Y <= 9999) and (M >= 1) and (M <= 12) and
+ (D >= 1) and (D <= DaysPerMonth(Y, M));
+end;
+
+function ValidDate(ADate: TDateTime): Boolean;
+var
+ Year, Month, Day: Word;
+begin
+ try
+ DecodeDate(ADate, Year, Month, Day);
+ Result := IsValidDate(Year, Month, Day);
+ except
+ Result := False;
+ end;
+end;
+
+function DaysInPeriod(Date1, Date2: TDateTime): Longint;
+begin
+ if ValidDate(Date1) and ValidDate(Date2) then
+ Result := Abs(Trunc(Date2) - Trunc(Date1)) + 1
+ else
+ Result := 0;
+end;
+
+{ // (ahuser) wrong implementation
+function DaysBetween(Date1, Date2: TDateTime): Longint;
+begin
+ Result := Trunc(Date2) - Trunc(Date1) + 1;
+ if Result < 0 then
+ Result := 0;
+end;}
+
+function DaysBetween(Date1, Date2: TDateTime): Longint;
+begin
+ if Date1 < Date2 then
+ Result := Trunc(Date2 - Date1)
+ else
+ Result := Trunc(Date1 - Date2);
+end;
+
+function IncTime(ATime: TDateTime; Hours, Minutes, Seconds,
+ MSecs: Integer): TDateTime;
+begin
+ Result := ATime + (Hours div 24) + (((Hours mod 24) * 3600000 +
+ Minutes * 60000 + Seconds * 1000 + MSecs) / MSecsPerDay);
+ if Result < 0 then
+ Result := Result + 1;
+end;
+
+function IncHour(ATime: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncTime(ATime, Delta, 0, 0, 0);
+end;
+
+function IncMinute(ATime: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncTime(ATime, 0, Delta, 0, 0);
+end;
+
+function IncSecond(ATime: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncTime(ATime, 0, 0, Delta, 0);
+end;
+
+function IncMSec(ATime: TDateTime; Delta: Integer): TDateTime;
+begin
+ Result := IncTime(ATime, 0, 0, 0, Delta);
+end;
+
+function CutTime(ADate: TDateTime): TDateTime;
+begin
+ Result := Trunc(ADate);
+end;
+
+function CurrentYear: Word;
+begin
+ Result := ExtractYear(Date);
+end;
+
+{ String to date conversions. Copied from SYSUTILS.PAS unit. }
+
+procedure ScanBlanks(const S: string; var Pos: Integer);
+var
+ I: Integer;
+begin
+ I := Pos;
+ while (I <= Length(S)) and (S[I] = ' ') do
+ Inc(I);
+ Pos := I;
+end;
+
+function ScanNumber(const S: string; MaxLength: Integer; var Pos: Integer;
+ var Number: Longint): Boolean;
+var
+ I: Integer;
+ N: Word;
+begin
+ Result := False;
+ ScanBlanks(S, Pos);
+ I := Pos;
+ N := 0;
+ while (I <= Length(S)) and (Longint(I - Pos) < MaxLength) and
+ (S[I] in ['0'..'9']) and (N < 1000) do
+ begin
+ N := N * 10 + (Ord(S[I]) - Ord('0'));
+ Inc(I);
+ end;
+ if I > Pos then
+ begin
+ Pos := I;
+ Number := N;
+ Result := True;
+ end;
+end;
+
+function ScanChar(const S: string; var Pos: Integer; Ch: Char): Boolean;
+begin
+ Result := False;
+ ScanBlanks(S, Pos);
+ if (Pos <= Length(S)) and (S[Pos] = Ch) then
+ begin
+ Inc(Pos);
+ Result := True;
+ end;
+end;
+
+procedure ScanToNumber(const S: string; var Pos: Integer);
+begin
+ while (Pos <= Length(S)) and not (S[Pos] in ['0'..'9']) do
+ begin
+ if S[Pos] in LeadBytes then
+ Inc(Pos);
+ Inc(Pos);
+ end;
+end;
+
+function GetDateOrder(const DateFormat: string): TDateOrder;
+var
+ I: Integer;
+begin
+ Result := DefaultDateOrder;
+ I := 1;
+ while I <= Length(DateFormat) do
+ begin
+ case Chr(Ord(DateFormat[I]) and $DF) of
+ 'E':
+ Result := doYMD;
+ 'Y':
+ Result := doYMD;
+ 'M':
+ Result := doMDY;
+ 'D':
+ Result := doDMY;
+ else
+ Inc(I);
+ Continue;
+ end;
+ Exit;
+ end;
+ Result := DefaultDateOrder; { default }
+end;
+
+function CurrentMonth: Word;
+begin
+ Result := ExtractMonth(Date);
+end;
+
+{Modified}
+
+function ExpandYear(Year: Integer): Integer;
+var
+ N: Longint;
+begin
+ if Year = -1 then
+ Result := CurrentYear
+ else
+ begin
+ Result := Year;
+ if Result < 100 then
+ begin
+ N := CurrentYear - CenturyOffset;
+ Inc(Result, N div 100 * 100);
+ if (CenturyOffset > 0) and (Result < N) then
+ Inc(Result, 100);
+ end;
+ end;
+end;
+
+function ScanDate(const S, DateFormat: string; var Position: Integer;
+ var Y, M, D: Integer): Boolean;
+var
+ DateOrder: TDateOrder;
+ N1, N2, N3: Longint;
+begin
+ Result := False;
+ Y := 0;
+ M := 0;
+ D := 0;
+ DateOrder := GetDateOrder(DateFormat);
+ if ShortDateFormat[1] = 'g' then { skip over prefix text }
+ ScanToNumber(S, Position);
+ if not (ScanNumber(S, MaxInt, Position, N1) and ScanChar(S, Position, DateSeparator{$IFDEF CLR}[1]{$ENDIF}) and
+ ScanNumber(S, MaxInt, Position, N2)) then
+ Exit;
+ if ScanChar(S, Position, DateSeparator{$IFDEF CLR}[1]{$ENDIF}) then
+ begin
+ if not ScanNumber(S, MaxInt, Position, N3) then
+ Exit;
+ case DateOrder of
+ doMDY:
+ begin
+ Y := N3;
+ M := N1;
+ D := N2;
+ end;
+ doDMY:
+ begin
+ Y := N3;
+ M := N2;
+ D := N1;
+ end;
+ doYMD:
+ begin
+ Y := N1;
+ M := N2;
+ D := N3;
+ end;
+ end;
+ Y := ExpandYear(Y);
+ end
+ else
+ begin
+ Y := CurrentYear;
+ if DateOrder = doDMY then
+ begin
+ D := N1;
+ M := N2;
+ end
+ else
+ begin
+ M := N1;
+ D := N2;
+ end;
+ end;
+ ScanChar(S, Position, DateSeparator{$IFDEF CLR}[1]{$ENDIF});
+ ScanBlanks(S, Position);
+ if SysLocale.FarEast and (Pos('ddd', ShortDateFormat) <> 0) then
+ begin { ignore trailing text }
+ if ShortTimeFormat[1] in ['0'..'9'] then { stop at time digit }
+ ScanToNumber(S, Position)
+ else { stop at time prefix }
+ repeat
+ while (Position <= Length(S)) and (S[Position] <> ' ') do
+ Inc(Position);
+ ScanBlanks(S, Position);
+ until (Position > Length(S)) or
+ {$IFDEF CLR}
+ SameText(TimeAMString, Copy(S, Position, Length(TimeAMString))) or
+ SameText(TimePMString, Copy(S, Position, Length(TimePMString)));
+ {$ELSE}
+ AnsiSameText(TimeAMString, Copy(S, Position, Length(TimeAMString))) or
+ AnsiSameText(TimePMString, Copy(S, Position, Length(TimePMString)));
+ {$ENDIF CLR}
+ end;
+ Result := IsValidDate(Y, M, D) and (Position > Length(S));
+end;
+
+function MonthFromName(const S: string; MaxLen: Byte): Byte;
+begin
+ if Length(S) > 0 then
+ for Result := 1 to 12 do
+ begin
+ if (Length(LongMonthNames[Result]) > 0) and
+ {$IFDEF CLR}
+ SameText(Copy(S, 1, MaxLen), Copy(LongMonthNames[Result], 1, MaxLen)) then
+ {$ELSE}
+ AnsiSameText(Copy(S, 1, MaxLen), Copy(LongMonthNames[Result], 1, MaxLen)) then
+ {$ENDIF CLR}
+ Exit;
+ end;
+ Result := 0;
+end;
+
+procedure ExtractMask(const Format, S: string; Ch: Char; Cnt: Integer;
+ var I: Integer; Blank, Default: Integer);
+var
+ Tmp: string[20];
+ J, L: Integer;
+begin
+ I := Default;
+ Ch := UpCase(Ch);
+ L := Length(Format);
+ if Length(S) < L then
+ L := Length(S)
+ else
+ if Length(S) > L then
+ Exit;
+ {$IFDEF CLR}
+ J := Pos(MakeStr(Ch, Cnt), Format.ToUpper());
+ {$ELSE}
+ J := Pos(MakeStr(Ch, Cnt), AnsiUpperCase(Format));
+ {$ENDIF CLR}
+ if J <= 0 then
+ Exit;
+ Tmp := '';
+ while (UpCase(Format[J]) = Ch) and (J <= L) do
+ begin
+ if S[J] <> ' ' then
+ Tmp := Tmp + S[J];
+ Inc(J);
+ end;
+ if Tmp = '' then
+ I := Blank
+ else
+ if Cnt > 1 then
+ begin
+ I := MonthFromName(Tmp, Length(Tmp));
+ if I = 0 then
+ I := -1;
+ end
+ else
+ I := StrToIntDef(Tmp, -1);
+end;
+
+function ScanDateStr(const Format, S: string; var D, M, Y: Integer): Boolean;
+var
+ Pos: Integer;
+begin
+ ExtractMask(Format, S, 'm', 3, M, -1, 0); { short month name? }
+ if M = 0 then
+ ExtractMask(Format, S, 'm', 1, M, -1, 0);
+ ExtractMask(Format, S, 'd', 1, D, -1, 1);
+ ExtractMask(Format, S, 'y', 1, Y, -1, CurrentYear);
+ if M = -1 then
+ M := CurrentMonth;
+ Y := ExpandYear(Y);
+ Result := IsValidDate(Y, M, D);
+ if not Result then
+ begin
+ Pos := 1;
+ Result := ScanDate(S, Format, Pos, Y, M, D);
+ end;
+end;
+
+function InternalStrToDate(const DateFormat, S: string;
+ var Date: TDateTime): Boolean;
+var
+ D, M, Y: Integer;
+begin
+ if S = '' then
+ begin
+ Date := NullDate;
+ Result := True;
+ end
+ else
+ begin
+ Result := ScanDateStr(DateFormat, S, D, M, Y);
+ if Result then
+ try
+ Date := EncodeDate(Y, M, D);
+ except
+ Result := False;
+ end;
+ end;
+end;
+
+function StrToDateFmt(const DateFormat, S: string): TDateTime;
+begin
+ if not InternalStrToDate(DateFormat, S, Result) then
+ {$IFDEF CLR}
+ raise EConvertError.CreateFmt(SInvalidDate, [S]);
+ {$ELSE}
+ raise EConvertError.CreateResFmt(@SInvalidDate, [S]);
+ {$ENDIF CLR}
+end;
+
+function StrToDateDef(const S: string; Default: TDateTime): TDateTime;
+begin
+ if not InternalStrToDate(ShortDateFormat, S, Result) then
+ Result := Trunc(Default);
+end;
+
+function StrToDateFmtDef(const DateFormat, S: string; Default: TDateTime): TDateTime;
+begin
+ if not InternalStrToDate(DateFormat, S, Result) then
+ Result := Trunc(Default);
+end;
+
+function DefDateFormat(AFourDigitYear: Boolean): string;
+begin
+ if AFourDigitYear then
+ begin
+ case GetDateOrder(ShortDateFormat) of
+ doMDY:
+ Result := 'MM/DD/YYYY';
+ doDMY:
+ Result := 'DD/MM/YYYY';
+ doYMD:
+ Result := 'YYYY/MM/DD';
+ end;
+ end
+ else
+ begin
+ case GetDateOrder(ShortDateFormat) of
+ doMDY:
+ Result := 'MM/DD/YY';
+ doDMY:
+ Result := 'DD/MM/YY';
+ doYMD:
+ Result := 'YY/MM/DD';
+ end;
+ end;
+end;
+
+function DefDateMask(BlanksChar: Char; AFourDigitYear: Boolean): string;
+begin
+ if AFourDigitYear then
+ begin
+ case GetDateOrder(ShortDateFormat) of
+ doMDY, doDMY:
+ Result := '!99/99/9999;1;';
+ doYMD:
+ Result := '!9999/99/99;1;';
+ end;
+ end
+ else
+ begin
+ case GetDateOrder(ShortDateFormat) of
+ doMDY, doDMY:
+ Result := '!99/99/99;1;';
+ doYMD:
+ Result := '!99/99/99;1;';
+ end;
+ end;
+ if Result <> '' then
+ Result := Result + BlanksChar;
+end;
+
+function FormatLongDate(Value: TDateTime): string;
+{$IFDEF CLR}
+begin
+ Result := TrimRight(FormatDateTime(LongDateFormat, Value));
+end;
+{$ELSE}
+{$IFDEF MSWINDOWS}
+var
+ Buffer: array [0..1023] of Char;
+ SystemTime: TSystemTime;
+begin
+ DateTimeToSystemTime(Value, SystemTime);
+ SetString(Result, Buffer, GetDateFormat(GetThreadLocale, DATE_LONGDATE,
+ @SystemTime, nil, Buffer, SizeOf(Buffer) - 1));
+ Result := TrimRight(Result);
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+begin
+ Result := TrimRight(FormatDateTime(LongDateFormat, Value));
+end;
+{$ENDIF UNIX}
+{$ENDIF CLR}
+
+function FormatLongDateTime(Value: TDateTime): string;
+begin
+ if Value <> NullDate then
+ Result := FormatLongDate(Value) + FormatDateTime(' tt', Value)
+ else
+ Result := '';
+end;
+
+function FourDigitYear: Boolean; // deprecated
+begin
+ Result := IsFourDigitYear;
+end;
+
+function IsFourDigitYear: Boolean;
+begin
+ {$IFDEF CLR}
+ Result := Pos('YYYY', ShortDateFormat.ToUpper()) > 0;
+ {$ELSE}
+ Result := Pos('YYYY', AnsiUpperCase(ShortDateFormat)) > 0;
+ {$ENDIF CLR}
+end;
+{ end JvDateUtil }
+
+{$IFDEF CLR}
+
+function BufToBinStr(const Buf: TBytes; BufSize: Integer): string;
+var
+ I: Integer;
+ P: TBytes;
+begin
+ P := Buf;
+ for I := 0 to Pred(BufSize) do
+ Result := Result + IntToHex(P[I] , 2);
+end;
+
+function BinStrToBuf(Value: string; Buf: TBytes; BufSize: Integer): Integer;
+var
+ I: Integer;
+ P: TBytes;
+begin
+ if Odd(Length(Value)) then
+ Value := '0' + Value; // should not occur, might indicate corrupted Value
+ if (Length(Value) div 2) < BufSize then
+ BufSize := Length(Value) div 2;
+ P := Buf;
+ for I := 0 to Pred(BufSize) do
+ P[I] := StrToInt('$' + Value[2 * I + 1] + Value[2 * I + 2]);
+ Result := BufSize;
+end;
+
+{$ELSE}
+
+function BufToBinStr(Buf: Pointer; BufSize: Integer): string;
+var
+ I: Integer;
+ P: PByteArray;
+begin
+ P := Buf;
+ for I := 0 to Pred(BufSize) do
+ Result := Result + IntToHex(P[I] , 2);
+end;
+
+function BinStrToBuf(Value: string; Buf: Pointer; BufSize: Integer): Integer;
+var
+ I: Integer;
+ P: PByteArray;
+begin
+ if Odd(Length(Value)) then
+ Value := '0' + Value; // should not occur, might indicate corrupted Value
+ if (Length(Value) div 2) < BufSize then
+ BufSize := Length(Value) div 2;
+ P := Buf;
+ for I := 0 to Pred(BufSize) do
+ P[I] := StrToInt('$' + Value[2 * I + 1] + Value[2 * I + 2]);
+ Result := BufSize;
+end;
+
+{$ENDIF CLR}
+
+{ begin JvStrUtils }
+{$IFDEF UNIX}
+
+function iconversion(InP: PChar; OutP: Pointer; InBytes, OutBytes: Cardinal;
+ const ToCode, FromCode: string): Boolean;
+var
+ conv: iconv_t;
+begin
+ Result := False;
+ if (InBytes > 0) and (OutBytes > 0) and (InP <> nil) and (OutP <> nil) then
+ begin
+ conv := iconv_open(PChar(ToCode), PChar(FromCode));
+ if Integer(conv) <> -1 then
+ begin
+ if Integer(iconv(conv, InP, InBytes, OutP, OutBytes)) <> -1 then
+ Result := True;
+ iconv_close(conv);
+ end;
+ end;
+end;
+
+function iconvString(const S, ToCode, FromCode: string): string;
+begin
+ SetLength(Result, Length(S));
+ if not iconversion(PChar(S), Pointer(Result),
+ Length(S), Length(Result),
+ ToCode, FromCode) then
+ Result := S;
+end;
+
+function iconvWideString(const S: WideString; const ToCode, FromCode: string): WideString;
+begin
+ SetLength(Result, Length(S));
+ if not iconversion(Pointer(S), Pointer(Result),
+ Length(S) * SizeOf(WideChar), Length(Result) * SizeOf(WideChar),
+ ToCode, FromCode) then
+ Result := S;
+end;
+
+function OemStrToAnsi(const S: string): string;
+begin
+ Result := iconvString(S, 'WINDOWS-1252', 'CP850');
+end;
+
+function AnsiStrToOem(const S: string): string;
+begin
+ Result := iconvString(S, 'CP850', 'WINDOWS-1250');
+end;
+
+{$ENDIF UNIX}
+
+function StrToOem(const AnsiStr: string): string;
+{$IFDEF CLR}
+var
+ sb: StringBuilder;
+begin
+ if AnsiStr <> '' then
+ begin
+ sb := StringBuilder.Create(AnsiStr.Length);
+ CharToOemBuff(AnsiStr, sb, sb.Capacity);
+ Result := sb.ToString();
+ end
+ else
+ Result := '';
+end;
+{$ELSE}
+begin
+ {$IFDEF MSWINDOWS}
+ SetLength(Result, Length(AnsiStr));
+ if Result <> '' then
+ CharToOemBuff(PChar(AnsiStr), PChar(Result), Length(Result));
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ Result := AnsiStrToOem(AnsiStr);
+ {$ENDIF UNIX}
+end;
+{$ENDIF CLR}
+
+function OemToAnsiStr(const OemStr: string): string;
+{$IFDEF CLR}
+var
+ sb: StringBuilder;
+begin
+ if OemStr <> '' then
+ begin
+ sb := StringBuilder.Create(OemStr.Length);
+ OemToCharBuff(OemStr, sb, sb.Capacity);
+ Result := sb.ToString();
+ end
+ else
+ Result := '';
+end;
+{$ELSE}
+begin
+ {$IFDEF MSWINDOWS}
+ SetLength(Result, Length(OemStr));
+ if Length(Result) > 0 then
+ OemToCharBuff(PChar(OemStr), PChar(Result), Length(Result));
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ Result := OemStrToAnsi(OemStr);
+ {$ENDIF UNIX}
+end;
+{$ENDIF CLR}
+
+function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
+var
+ I, SLen: Integer;
+begin
+ SLen := Length(S);
+ I := 1;
+ while I <= SLen do
+ begin
+ if not (S[I] in EmptyChars) then
+ begin
+ Result := False;
+ Exit;
+ end
+ else
+ Inc(I);
+ end;
+ Result := True;
+end;
+
+function ReplaceStr(const S, Srch, Replace: string): string;
+var
+ I: Integer;
+ Source: string;
+begin
+ Source := S;
+ Result := '';
+ repeat
+ I := Pos(Srch, Source);
+ if I > 0 then
+ begin
+ Result := Result + Copy(Source, 1, I - 1) + Replace;
+ Source := Copy(Source, I + Length(Srch), MaxInt);
+ end
+ else
+ Result := Result + Source;
+ until I <= 0;
+end;
+
+function DelSpace(const S: string): string;
+begin
+ Result := DelChars(S, ' ');
+end;
+
+function DelChars(const S: string; Chr: Char): string;
+var
+ I: Integer;
+begin
+ Result := S;
+ for I := Length(Result) downto 1 do
+ begin
+ if Result[I] = Chr then
+ Delete(Result, I, 1);
+ end;
+end;
+
+function DelBSpace(const S: string): string;
+var
+ I, L: Integer;
+begin
+ L := Length(S);
+ I := 1;
+ while (I <= L) and (S[I] = ' ') do
+ Inc(I);
+ Result := Copy(S, I, MaxInt);
+end;
+
+function DelESpace(const S: string): string;
+var
+ I: Integer;
+begin
+ I := Length(S);
+ while (I > 0) and (S[I] = ' ') do
+ Dec(I);
+ Result := Copy(S, 1, I);
+end;
+
+function DelRSpace(const S: string): string;
+begin
+ Result := DelBSpace(DelESpace(S));
+end;
+
+function DelSpace1(const S: string): string;
+var
+ I: Integer;
+begin
+ Result := S;
+ for I := Length(Result) downto 2 do
+ begin
+ if (Result[I] = ' ') and (Result[I - 1] = ' ') then
+ Delete(Result, I, 1);
+ end;
+end;
+
+function Tab2Space(const S: string; Numb: Byte): string;
+var
+ I: Integer;
+begin
+ I := 1;
+ Result := S;
+ while I <= Length(Result) do
+ begin
+ if Result[I] = Chr(9) then
+ begin
+ Delete(Result, I, 1);
+ Insert(MakeStr(' ', Numb), Result, I);
+ Inc(I, Numb);
+ end
+ else
+ Inc(I);
+ end;
+end;
+
+function MakeStr(C: Char; N: Integer): string; overload;
+begin
+ if N < 1 then
+ Result := ''
+ else
+ begin
+ SetLength(Result, N);
+ FillString(Result, Length(Result), C);
+ end;
+end;
+
+{$IFNDEF CLR}
+function MakeStr(C: WideChar; N: Integer): WideString; overload;
+begin
+ if N < 1 then
+ Result := ''
+ else
+ begin
+ SetLength(Result, N);
+ FillWideChar(Result[1], Length(Result), C);
+ end;
+end;
+{$ENDIF !CLR}
+
+function MS(C: Char; N: Integer): string;
+begin
+ Result := MakeStr(C, N);
+end;
+
+function NPos(const C: string; S: string; N: Integer): Integer;
+var
+ I, P, K: Integer;
+begin
+ Result := 0;
+ K := 0;
+ for I := 1 to N do
+ begin
+ P := Pos(C, S);
+ Inc(K, P);
+ if (I = N) and (P > 0) then
+ begin
+ Result := K;
+ Exit;
+ end;
+ if P > 0 then
+ Delete(S, 1, P)
+ else
+ Exit;
+ end;
+end;
+
+function AddChar(C: Char; const S: string; N: Integer): string;
+begin
+ if Length(S) < N then
+ Result := MakeStr(C, N - Length(S)) + S
+ else
+ Result := S;
+end;
+
+function AddCharR(C: Char; const S: string; N: Integer): string;
+begin
+ if Length(S) < N then
+ Result := S + MakeStr(C, N - Length(S))
+ else
+ Result := S;
+end;
+
+function LeftStr(const S: string; N: Integer): string;
+begin
+ Result := AddCharR(' ', S, N);
+end;
+
+function RightStr(const S: string; N: Integer): string;
+begin
+ Result := AddChar(' ', S, N);
+end;
+
+{$IFDEF MSWINDOWS}
+
+function CompStr(const S1, S2: string): Integer;
+begin
+ {$IFDEF CLR}
+ Result := System.String.Compare(S1, S2, False);
+ {$ELSE}
+ Result := CompareString(GetThreadLocale, SORT_STRINGSORT, PChar(S1),
+ Length(S1), PChar(S2), Length(S2)) - 2;
+ {$ENDIF CLR}
+end;
+
+function CompText(const S1, S2: string): Integer;
+begin
+ {$IFDEF CLR}
+ Result := System.String.Compare(S1, S2, True);
+ {$ELSE}
+ Result := CompareString(GetThreadLocale, SORT_STRINGSORT or NORM_IGNORECASE,
+ PChar(S1), Length(S1), PChar(S2), Length(S2)) - 2;
+ {$ENDIF CLR}
+end;
+
+{$ENDIF MSWINDOWS}
+
+{$IFDEF UNIX}
+
+function CompStr(const S1, S2: string): Integer;
+begin
+ Result := AnsiCompareStr(S1, S2);
+end;
+
+function CompText(const S1, S2: string): Integer;
+begin
+ Result := AnsiCompareText(S1, S2);
+end;
+
+{$ENDIF UNIX}
+
+function Copy2Symb(const S: string; Symb: Char): string;
+var
+ P: Integer;
+begin
+ P := Pos(Symb, S);
+ if P = 0 then
+ P := Length(S) + 1;
+ Result := Copy(S, 1, P - 1);
+end;
+
+function Copy2SymbDel(var S: string; Symb: Char): string;
+begin
+ Result := Copy2Symb(S, Symb);
+ S := DelBSpace(Copy(S, Length(Result) + 1, Length(S)));
+end;
+
+function Copy2Space(const S: string): string;
+begin
+ Result := Copy2Symb(S, ' ');
+end;
+
+function Copy2SpaceDel(var S: string): string;
+begin
+ Result := Copy2SymbDel(S, ' ');
+end;
+
+function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
+var
+ SLen, I: Cardinal;
+begin
+ {$IFDEF CLR}
+ Result := LowerCase(S);
+ {$ELSE}
+ Result := AnsiLowerCase(S);
+ {$ENDIF CLR}
+ I := 1;
+ SLen := Length(Result);
+ while I <= SLen do
+ begin
+ while (I <= SLen) and (Result[I] in WordDelims) do
+ Inc(I);
+ if I <= SLen then
+ {$IFDEF CLR}
+ Result[I] := UpperCase(Result[I])[1];
+ {$ELSE}
+ Result[I] := AnsiUpperCase(Result[I])[1];
+ {$ENDIF CLR}
+ while (I <= SLen) and not (Result[I] in WordDelims) do
+ Inc(I);
+ end;
+end;
+
+function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
+var
+ SLen, I: Cardinal;
+begin
+ Result := 0;
+ I := 1;
+ SLen := Length(S);
+ while I <= SLen do
+ begin
+ while (I <= SLen) and (S[I] in WordDelims) do
+ Inc(I);
+ if I <= SLen then
+ Inc(Result);
+ while (I <= SLen) and not (S[I] in WordDelims) do
+ Inc(I);
+ end;
+end;
+
+function WordPosition(const N: Integer; const S: string;
+ const WordDelims: TSysCharSet): Integer;
+var
+ Count, I: Integer;
+begin
+ Count := 0;
+ I := 1;
+ Result := 0;
+ while (I <= Length(S)) and (Count <> N) do
+ begin
+ { skip over delimiters }
+ while (I <= Length(S)) and (S[I] in WordDelims) do
+ Inc(I);
+ { if we're not beyond end of S, we're at the start of a word }
+ if I <= Length(S) then
+ Inc(Count);
+ { if not finished, find the end of the current word }
+ if Count <> N then
+ while (I <= Length(S)) and not (S[I] in WordDelims) do
+ Inc(I)
+ else
+ Result := I;
+ end;
+end;
+
+function ExtractWord(N: Integer; const S: string;
+ const WordDelims: TSysCharSet): string;
+var
+ I: Integer;
+ Len: Integer;
+begin
+ Len := 0;
+ I := WordPosition(N, S, WordDelims);
+ if I <> 0 then
+ { find the end of the current word }
+ while (I <= Length(S)) and not (S[I] in WordDelims) do
+ begin
+ { add the I'th character to result }
+ Inc(Len);
+ SetLength(Result, Len);
+ Result[Len] := S[I];
+ Inc(I);
+ end;
+ SetLength(Result, Len);
+end;
+
+function ExtractWordPos(N: Integer; const S: string;
+ const WordDelims: TSysCharSet; var Pos: Integer): string;
+var
+ I, Len: Integer;
+begin
+ Len := 0;
+ I := WordPosition(N, S, WordDelims);
+ Pos := I;
+ if I <> 0 then
+ { find the end of the current word }
+ while (I <= Length(S)) and not (S[I] in WordDelims) do
+ begin
+ { add the I'th character to result }
+ Inc(Len);
+ SetLength(Result, Len);
+ Result[Len] := S[I];
+ Inc(I);
+ end;
+ SetLength(Result, Len);
+end;
+
+function ExtractDelimited(N: Integer; const S: string;
+ const Delims: TSysCharSet): string;
+var
+ CurWord: Integer;
+ I, Len, SLen: Integer;
+begin
+ CurWord := 0;
+ I := 1;
+ Len := 0;
+ SLen := Length(S);
+ SetLength(Result, 0);
+ while (I <= SLen) and (CurWord <> N) do
+ begin
+ if S[I] in Delims then
+ Inc(CurWord)
+ else
+ begin
+ if CurWord = N - 1 then
+ begin
+ Inc(Len);
+ SetLength(Result, Len);
+ Result[Len] := S[I];
+ end;
+ end;
+ Inc(I);
+ end;
+end;
+
+function ExtractSubstr(const S: string; var Pos: Integer;
+ const Delims: TSysCharSet): string;
+var
+ I: Integer;
+begin
+ I := Pos;
+ while (I <= Length(S)) and not (S[I] in Delims) do
+ Inc(I);
+ Result := Copy(S, Pos, I - Pos);
+ if (I <= Length(S)) and (S[I] in Delims) then
+ Inc(I);
+ Pos := I;
+end;
+
+function IsWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
+var
+ Count, I: Integer;
+begin
+ Result := False;
+ Count := WordCount(S, WordDelims);
+ for I := 1 to Count do
+ if ExtractWord(I, S, WordDelims) = W then
+ begin
+ Result := True;
+ Exit;
+ end;
+end;
+
+function QuotedString(const S: string; Quote: Char): string;
+begin
+ {$IFDEF CLR}
+ Result := QuotedStr(S, Quote);
+ {$ELSE}
+ Result := AnsiQuotedStr(S, Quote);
+ {$ENDIF CLR}
+end;
+
+function ExtractQuotedString(const S: string; Quote: Char): string;
+begin
+ Result := DequotedStr(S, Quote);
+end;
+
+function Numb2USA(const S: string): string;
+var
+ I, NA: Integer;
+begin
+ I := Length(S);
+ Result := S;
+ NA := 0;
+ while (I > 0) do
+ begin
+ if ((Length(Result) - I + 1 - NA) mod 3 = 0) and (I <> 1) then
+ begin
+ Insert(',', Result, I);
+ Inc(NA);
+ end;
+ Dec(I);
+ end;
+end;
+
+function CenterStr(const S: string; Len: Integer): string;
+begin
+ if Length(S) < Len then
+ begin
+ Result := MakeStr(' ', (Len div 2) - (Length(S) div 2)) + S;
+ Result := Result + MakeStr(' ', Len - Length(Result));
+ end
+ else
+ Result := S;
+end;
+
+function Dec2Hex(N: Longint; A: Byte): string;
+begin
+ Result := IntToHex(N, A);
+end;
+
+function Hex2Dec(const S: string): Longint;
+var
+ HexStr: string;
+begin
+ if Pos('$', S) = 0 then
+ HexStr := '$' + S
+ else
+ HexStr := S;
+ Result := StrToIntDef(HexStr, 0);
+end;
+
+function Dec2Numb(N: Int64; A, B: Byte): string;
+var
+ C: Integer;
+ Number: Cardinal;
+begin
+ if N = 0 then
+ Result := '0'
+ else
+ begin
+ Number := Cardinal(N);
+ Result := '';
+ while Number > 0 do
+ begin
+ C := Number mod B;
+ if C > 9 then
+ C := C + 55
+ else
+ C := C + 48;
+ Result := Chr(C) + Result;
+ Number := Number div B;
+ end;
+ end;
+ if Result <> '' then
+ Result := AddChar('0', Result, A);
+end;
+
+function Numb2Dec(S: string; B: Byte): Int64;
+var
+ I, P: Int64;
+begin
+ I := Length(S);
+ Result := 0;
+ S := UpperCase(S);
+ P := 1;
+ while (I >= 1) do
+ begin
+ if S[I] > '@' then
+ Result := Result + (Ord(S[I]) - 55) * P
+ else
+ Result := Result + (Ord(S[I]) - 48) * P;
+ Dec(I);
+ P := P * B;
+ end;
+end;
+
+function RomanToInt(const S: string): Longint;
+const
+ RomanChars = ['C', 'D', 'I', 'L', 'M', 'V', 'X'];
+ RomanValues: array ['C'..'X'] of Word =
+ (100, 500, 0, 0, 0, 0, 1, 0, 0, 50, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10);
+var
+ Index, Next: Char;
+ I: Integer;
+ Negative: Boolean;
+begin
+ Result := 0;
+ I := 0;
+ Negative := (Length(S) > 0) and (S[1] = '-');
+ if Negative then
+ Inc(I);
+ while (I < Length(S)) do
+ begin
+ Inc(I);
+ Index := UpCase(S[I]);
+ if Index in RomanChars then
+ begin
+ if Succ(I) <= Length(S) then
+ Next := UpCase(S[I + 1])
+ else
+ Next := #0;
+ if (Next in RomanChars) and (RomanValues[Index] < RomanValues[Next]) then
+ begin
+ Inc(Result, RomanValues[Next]);
+ Dec(Result, RomanValues[Index]);
+ Inc(I);
+ end
+ else
+ Inc(Result, RomanValues[Index]);
+ end
+ else
+ begin
+ Result := 0;
+ Exit;
+ end;
+ end;
+ if Negative then
+ Result := -Result;
+end;
+
+function IntToRoman(Value: Longint): string;
+label
+ A500, A400, A100, A90, A50, A40, A10, A9, A5, A4, A1;
+begin
+ Result := '';
+ while Value >= 1000 do
+ begin
+ Dec(Value, 1000);
+ Result := Result + 'M';
+ end;
+ if Value < 900 then
+ goto A500
+ else
+ begin
+ Dec(Value, 900);
+ Result := Result + 'CM';
+ end;
+ goto A90;
+ A400:
+ if Value < 400 then
+ goto A100
+ else
+ begin
+ Dec(Value, 400);
+ Result := Result + 'CD';
+ end;
+ goto A90;
+ A500:
+ if Value < 500 then
+ goto A400
+ else
+ begin
+ Dec(Value, 500);
+ Result := Result + 'D';
+ end;
+ A100:
+ while Value >= 100 do
+ begin
+ Dec(Value, 100);
+ Result := Result + 'C';
+ end;
+ A90:
+ if Value < 90 then
+ goto A50
+ else
+ begin
+ Dec(Value, 90);
+ Result := Result + 'XC';
+ end;
+ goto A9;
+ A40:
+ if Value < 40 then
+ goto A10
+ else
+ begin
+ Dec(Value, 40);
+ Result := Result + 'XL';
+ end;
+ goto A9;
+ A50:
+ if Value < 50 then
+ goto A40
+ else
+ begin
+ Dec(Value, 50);
+ Result := Result + 'L';
+ end;
+ A10:
+ while Value >= 10 do
+ begin
+ Dec(Value, 10);
+ Result := Result + 'X';
+ end;
+ A9:
+ if Value < 9 then
+ goto A5
+ else
+ Result := Result + 'IX';
+ Exit;
+ A4:
+ if Value < 4 then
+ goto A1
+ else
+ Result := Result + 'IV';
+ Exit;
+ A5:
+ if Value < 5 then
+ goto A4
+ else
+ begin
+ Dec(Value, 5);
+ Result := Result + 'V';
+ end;
+ goto A1;
+ A1:
+ while Value >= 1 do
+ begin
+ Dec(Value);
+ Result := Result + 'I';
+ end;
+end;
+
+function IntToBin(Value: Longint; Digits, Spaces: Integer): string;
+begin
+ Result := '';
+ if Digits > 32 then
+ Digits := 32;
+ while Digits > 0 do
+ begin
+ if (Digits mod Spaces) = 0 then
+ Result := Result + ' ';
+ Dec(Digits);
+ Result := Result + IntToStr((Value shr Digits) and 1);
+ end;
+end;
+
+function FindPart(const HelpWilds, InputStr: string): Integer;
+var
+ I, J: Integer;
+ Diff: Integer;
+begin
+ I := Pos('?', HelpWilds);
+ if I = 0 then
+ begin
+ { if no '?' in HelpWilds }
+ Result := Pos(HelpWilds, InputStr);
+ Exit;
+ end;
+ { '?' in HelpWilds }
+ Diff := Length(InputStr) - Length(HelpWilds);
+ if Diff < 0 then
+ begin
+ Result := 0;
+ Exit;
+ end;
+ { now move HelpWilds over InputStr }
+ for I := 0 to Diff do
+ begin
+ for J := 1 to Length(HelpWilds) do
+ begin
+ if (InputStr[I + J] = HelpWilds[J]) or (HelpWilds[J] = '?') then
+ begin
+ if J = Length(HelpWilds) then
+ begin
+ Result := I + 1;
+ Exit;
+ end;
+ end
+ else
+ Break;
+ end;
+ end;
+ Result := 0;
+end;
+
+function IsWild(InputStr, Wilds: string; IgnoreCase: Boolean): Boolean;
+
+ function SearchNext(var Wilds: string): Integer;
+ { looking for next *, returns position and string until position }
+ begin
+ Result := Pos('*', Wilds);
+ if Result > 0 then
+ Wilds := Copy(Wilds, 1, Result - 1);
+ end;
+
+var
+ CWild, CInputWord: Integer; { counter for positions }
+ I, LenHelpWilds: Integer;
+ MaxInputWord, MaxWilds: Integer; { Length of InputStr and Wilds }
+ HelpWilds: string;
+begin
+ if Wilds = InputStr then
+ begin
+ Result := True;
+ Exit;
+ end;
+ repeat { delete '**', because '**' = '*' }
+ I := Pos('**', Wilds);
+ if I > 0 then
+ Wilds := Copy(Wilds, 1, I - 1) + '*' + Copy(Wilds, I + 2, MaxInt);
+ until I = 0;
+ if Wilds = '*' then
+ begin { for fast end, if Wilds only '*' }
+ Result := True;
+ Exit;
+ end;
+ MaxInputWord := Length(InputStr);
+ MaxWilds := Length(Wilds);
+ if IgnoreCase then
+ begin { upcase all letters }
+ {$IFDEF CLR}
+ InputStr := InputStr.ToUpper();
+ Wilds := Wilds.ToUpper();
+ {$ELSE}
+ InputStr := AnsiUpperCase(InputStr);
+ Wilds := AnsiUpperCase(Wilds);
+ {$ENDIF CLR}
+ end;
+ if (MaxWilds = 0) or (MaxInputWord = 0) then
+ begin
+ Result := False;
+ Exit;
+ end;
+ CInputWord := 1;
+ CWild := 1;
+ Result := True;
+ repeat
+ if InputStr[CInputWord] = Wilds[CWild] then
+ begin { equal letters }
+ { goto next letter }
+ Inc(CWild);
+ Inc(CInputWord);
+ Continue;
+ end;
+ if Wilds[CWild] = '?' then
+ begin { equal to '?' }
+ { goto next letter }
+ Inc(CWild);
+ Inc(CInputWord);
+ Continue;
+ end;
+ if Wilds[CWild] = '*' then
+ begin { handling of '*' }
+ HelpWilds := Copy(Wilds, CWild + 1, MaxWilds);
+ I := SearchNext(HelpWilds);
+ LenHelpWilds := Length(HelpWilds);
+ if I = 0 then
+ begin
+ { no '*' in the rest, compare the ends }
+ if HelpWilds = '' then
+ Exit; { '*' is the last letter }
+ { check the rest for equal Length and no '?' }
+ for I := 0 to LenHelpWilds - 1 do
+ begin
+ if (HelpWilds[LenHelpWilds - I] <> InputStr[MaxInputWord - I]) and
+ (HelpWilds[LenHelpWilds - I] <> '?') then
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+ Exit;
+ end;
+ { handle all to the next '*' }
+ Inc(CWild, 1 + LenHelpWilds);
+ I := FindPart(HelpWilds, Copy(InputStr, CInputWord, MaxInt));
+ if I = 0 then
+ begin
+ Result := False;
+ Exit;
+ end;
+ CInputWord := I + LenHelpWilds;
+ Continue;
+ end;
+ Result := False;
+ Exit;
+ until (CInputWord > MaxInputWord) or (CWild > MaxWilds);
+ { no completed evaluation }
+ if CInputWord <= MaxInputWord then
+ Result := False;
+ if (CWild <= MaxWilds) and (Wilds[MaxWilds] <> '*') then
+ Result := False;
+end;
+
+function XorString(const Key, Src: ShortString): ShortString;
+var
+ I: Integer;
+begin
+ Result := Src;
+ if Length(Key) > 0 then
+ for I := 1 to Length(Src) do
+ Result[I] := AnsiChar(Chr(Byte(Key[1 + ((I - 1) mod Length(Key))]) xor Ord(Src[I])));
+end;
+
+function XorEncode(const Key, Source: string): string;
+var
+ I: Integer;
+ C: Byte;
+begin
+ Result := '';
+ for I := 1 to Length(Source) do
+ begin
+ if Length(Key) > 0 then
+ C := Byte(Key[1 + ((I - 1) mod Length(Key))]) xor Byte(Source[I])
+ else
+ C := Byte(Source[I]);
+ {$IFDEF CLR}
+ Result := Result + IntToHex(C, 2).ToLower();
+ {$ELSE}
+ Result := Result + AnsiLowerCase(IntToHex(C, 2));
+ {$ENDIF CLR}
+ end;
+end;
+
+function XorDecode(const Key, Source: string): string;
+var
+ I: Integer;
+ C: Char;
+begin
+ Result := '';
+ for I := 0 to Length(Source) div 2 - 1 do
+ begin
+ C := Chr(StrToIntDef('$' + Copy(Source, (I * 2) + 1, 2), Ord(' ')));
+ if Length(Key) > 0 then
+ C := Chr(Byte(Key[1 + (I mod Length(Key))]) xor Byte(C));
+ Result := Result + C;
+ end;
+end;
+
+function GetCmdLineArg(const Switch: string; ASwitchChars: TSysCharSet): string;
+var
+ I: Integer;
+ S: string;
+begin
+ I := 1;
+ while I <= ParamCount do
+ begin
+ S := ParamStr(I);
+ if (ASwitchChars = []) or ((S[1] in ASwitchChars) and (Length(S) > 1)) then
+ begin
+ {$IFDEF CLR}
+ if SameText(Copy(S, 2, MaxInt), Switch) then
+ {$ELSE}
+ if AnsiSameText(Copy(S, 2, MaxInt), Switch) then
+ {$ENDIF CLR}
+ begin
+ Inc(I);
+ if I <= ParamCount then
+ begin
+ Result := ParamStr(I);
+ Exit;
+ end;
+ end;
+ end;
+ Inc(I);
+ end;
+ Result := '';
+end;
+
+{ begin JvStrUtil }
+
+function FindNotBlankCharPos(const S: string): Integer;
+begin
+ for Result := 1 to Length(S) do
+ if S[Result] <> ' ' then
+ Exit;
+ Result := Length(S) + 1;
+end;
+
+function FindNotBlankCharPosW(const S: WideString): Integer;
+begin
+ for Result := 1 to Length(S) do
+ if S[Result] <> ' ' then
+ Exit;
+ Result := Length(S) + 1;
+end;
+
+// (rom) reimplemented
+
+function AnsiChangeCase(const S: string): string;
+var
+ I: Integer;
+ Up: string;
+ Down: string;
+begin
+ Result := S;
+ {$IFDEF CLR}
+ Up := S.ToUpper();
+ Down := S.ToLower();
+ {$ELSE}
+ Up := AnsiUpperCase(S);
+ Down := AnsiLowerCase(S);
+ {$ENDIF CLR}
+ for I := 1 to Length(Result) do
+ if Result[I] = Up[I] then
+ Result[I] := Down[I]
+ else
+ Result[I] := Up[I];
+end;
+
+function WideChangeCase(const S: string): string;
+var
+ I: Integer;
+ Up: string;
+ Down: string;
+begin
+ Result := S;
+ Up := WideUpperCase(S);
+ Down := WideLowerCase(S);
+ for I := 1 to Length(Result) do
+ if Result[I] = Up[I] then
+ Result[I] := Down[I]
+ else
+ Result[I] := Up[I];
+end;
+
+{ end JvStrUtil }
+{ end JvStrUtils }
+
+{ begin JvFileUtil }
+
+function NormalDir(const DirName: string): string;
+begin
+ Result := DirName;
+ {$IFDEF MSWINDOWS}
+ if (Result <> '') and
+ {$IFDEF CLR}
+ not (Result[Length(Result)] in [':', '\'])
+ {$ELSE}
+ not (AnsiLastChar(Result)^ in [':', '\'])
+ {$ENDIF CLR}
+ then
+ if (Length(Result) = 1) and (UpCase(Result[1]) in ['A'..'Z']) then
+ Result := Result + ':\'
+ else
+ Result := Result + '\';
+ {$ENDIF MSWINDOWS}
+end;
+
+function RemoveBackSlash(const DirName: string): string;
+begin
+ Result := DirName;
+ if (Length(Result) > 1) and
+ {$IFDEF CLR}
+ (Result[Length(Result)] = '\')
+ {$ELSE}
+ (AnsiLastChar(Result)^ = '\')
+ {$ENDIF CLR}
+ then
+ if not ((Length(Result) = 3) and (UpCase(Result[1]) in ['A'..'Z']) and
+ (Result[2] = ':')) then
+ Delete(Result, Length(Result), 1);
+end;
+
+function FileDateTime(const FileName: string): TDateTime;
+{$IFNDEF COMPILER10_UP}
+var
+ Age: Longint;
+{$ENDIF !COMPILER10_UP}
+begin
+ {$IFDEF COMPILER10_UP}
+ if not FileAge(Filename, Result) then
+ Result := NullDate;
+ {$ELSE}
+ Age := FileAge(FileName);
+ {$IFDEF MSWINDOWS}
+ // [roko] -1 is valid FileAge value on Linux
+ if Age = -1 then
+ Result := NullDate
+ else
+ {$ENDIF MSWINDOWS}
+ Result := FileDateToDateTime(Age);
+ {$ENDIF COMPILER10_UP}
+end;
+
+function HasAttr(const FileName: string; Attr: Integer): Boolean;
+var
+ FileAttr: Integer;
+begin
+ FileAttr := FileGetAttr(FileName);
+ Result := (FileAttr >= 0) and (FileAttr and Attr = Attr);
+end;
+
+function DeleteFilesEx(const FileMasks: array of string): Boolean;
+var
+ I: Integer;
+begin
+ Result := True;
+ for I := Low(FileMasks) to High(FileMasks) do
+ Result := Result and DeleteFiles(ExtractFilePath(FileMasks[I]), ExtractFileName(FileMasks[I]));
+end;
+
+{$IFDEF MSWINDOWS}
+
+{$IFNDEF CLR}
+function GetWindowsDir: string;
+var
+ Buffer: array [0..MAX_PATH] of Char;
+begin
+ SetString(Result, Buffer, GetWindowsDirectory(Buffer, SizeOf(Buffer)));
+end;
+{$ENDIF !CLR}
+
+function GetSystemDir: string;
+{$IFDEF CLR}
+begin
+ Result := System.Environment.SystemDirectory;
+end;
+{$ELSE}
+var
+ Buffer: array [0..MAX_PATH] of Char;
+begin
+ SetString(Result, Buffer, GetSystemDirectory(Buffer, SizeOf(Buffer)));
+end;
+{$ENDIF CLR}
+
+{$ENDIF MSWINDOWS}
+
+{$IFDEF UNIX}
+function GetTempFileName(const Prefix: string): string;
+var
+ P: PChar;
+begin
+ P := tempnam(nil, Pointer(Prefix));
+ Result := P;
+ if P <> nil then
+ Libc.free(P);
+end;
+{$ENDIF UNIX}
+
+function GenTempFileName(FileName: string): string;
+var
+ TempDir: string;
+ {$IFDEF CLR}
+ TempFile: StringBuilder;
+ {$ELSE}
+ {$IFDEF MSWINDOWS}
+ TempFile: array [0..MAX_PATH] of Char;
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ TempFile: string;
+ {$ENDIF UNIX}
+ {$ENDIF CLR}
+ STempDir: TFileName;
+ Res: Integer;
+begin
+ TempDir := GetTempDir;
+ if FileName <> '' then
+ begin
+ if Length(FileName) < 4 then
+ FileName := ExpandFileName(FileName);
+ if (Length(FileName) > 4) and (FileName[2] = ':') and
+ (Length(TempDir) > 4) and
+ (AnsiCompareFileName(TempDir, FileName) <> 0) then
+ begin
+ STempDir := ExtractFilePath(FileName);
+ MoveString(STempDir, TempDir, Length(STempDir) + 1);
+ end;
+ end;
+ {$IFDEF CLR}
+ TempFile := StringBuilder.Create(MAX_PATH);
+ {$ENDIF CLR}
+ {$IFDEF MSWINDOWS}
+ Res := GetTempFileName(
+ {$IFDEF CLR}
+ TempDir, { address of directory name for temporary file}
+ {$ELSE}
+ PChar(TempDir), { address of directory name for temporary file}
+ {$ENDIF CLR}
+ '~JV', { address of filename prefix}
+ 0, { number used to create temporary filename}
+ TempFile); { address of buffer that receives the new filename}
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ TempFile := GetTempFileName('~JV');
+ Res := 1;
+ {$ENDIF UNIX}
+ if Res <> 0 then
+ Result := TempFile{$IFDEF CLR}.ToString(){$ENDIF}
+ else
+ Result := '~JVCLTemp.tmp';
+ DeleteFile(Result);
+end;
+
+function GenTempFileNameExt(FileName: string; const FileExt: string): string;
+begin
+ Result := ChangeFileExt(GenTempFileName(FileName), FileExt);
+end;
+
+function GetTempDir: string;
+{$IFDEF CLR}
+begin
+ Result := Path.GetTempPath;
+end;
+{$ELSE}
+{$IFDEF MSWINDOWS}
+var
+ TempDir: array [0..MAX_PATH] of Char;
+begin
+ TempDir[GetTempPath(260, TempDir)] := #0;
+ Result := TempDir;
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+begin
+ Result := ExtractFileDir(GetTempFileName(''));
+ if Result = '' then
+ Result := '/tmp'; // hard coded
+end;
+{$ENDIF UNIX}
+{$ENDIF CLR}
+
+function ClearDir(const Dir: string): Boolean;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+ Path: TFileName;
+begin
+ Result := True;
+ Path := AddSlash(Dir);
+ DosError := FindFirst(Path + AllFilesMask, faAnyFile, SearchRec);
+ while DosError = 0 do
+ begin
+ if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
+ begin
+ if (SearchRec.Attr and faDirectory) = faDirectory then
+ Result := Result and DeleteDir(Path + SearchRec.Name)
+ else
+ Result := Result and DeleteFile(Path + SearchRec.Name);
+ // if not Result then Exit;
+ end;
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+end;
+
+function DeleteDir(const Dir: string): Boolean;
+begin
+ ClearDir(Dir);
+ Result := RemoveDir(Dir);
+end;
+
+function DeleteFiles(const Folder: TFileName; const Masks: string): Boolean;
+var
+ SearchRec: TSearchRec;
+ DosError: Integer;
+ Path: TFileName;
+begin
+ Result := False;
+ Path := AddSlash(Folder);
+ DosError := FindFirst(Path + AllFilesMask, faAnyFile and not faDirectory, SearchRec);
+ while DosError = 0 do
+ begin
+ if FileEquMasks(Path + SearchRec.Name, Masks) then
+ Result := DeleteFile(Path + SearchRec.Name);
+ DosError := FindNext(SearchRec);
+ end;
+ FindClose(SearchRec);
+end;
+
+{$IFNDEF CLR}
+function GetParameter: string;
+var
+ FN, FN1: PChar;
+begin
+ if ParamCount = 0 then
+ begin
+ Result := '';
+ Exit
+ end;
+ FN := CmdLine;
+ if FN[0] = '"' then
+ begin
+ FN := StrScan(FN + 1, '"');
+ if (FN[0] = #0) or (FN[1] = #0) then
+ Result := ''
+ else
+ begin
+ Inc(FN, 2);
+ if FN[0] = '"' then
+ begin
+ Inc(FN, 1);
+ FN1 := StrScan(FN + 1, '"');
+ if FN1[0] <> #0 then
+ FN1[0] := #0;
+ end;
+ Result := FN;
+ end;
+ end
+ else
+ Result := Copy(CmdLine, Length(ParamStr(0)) + 1, 260);
+ while (Length(Result) > 0) and (Result[1] = ' ') do
+ Delete(Result, 1, 1);
+ Result := ReplaceString(Result, '"', '');
+ if FileExists(Result) then
+ Result := GetLongFileName(Result);
+end;
+{$ENDIF !CLR}
+
+function GetLongFileName(const FileName: string): string;
+{$IFDEF MSWINDOWS}
+var
+ SearchRec: TSearchRec;
+{$ENDIF MSWINDOWS}
+begin
+ {$IFDEF MSWINDOWS}
+ if FileGetInfo(FileName, SearchRec) then
+ Result := ExtractFilePath(ExpandFileName(FileName)) + SearchRec.FindData.cFileName
+ else
+ Result := FileName;
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ Result := ExpandFileName(FileName);
+ {$ENDIF UNIX}
+end;
+
+function FileEquMask(FileName, Mask: TFileName; CaseSensitive: Boolean): Boolean;
+var
+ I: Integer;
+ C: Char;
+ Index: Integer;
+ LenFileName: Integer;
+begin
+ if not CaseSensitive then
+ begin
+ FileName := AnsiUpperCase(ExtractFileName(FileName));
+ Mask := AnsiUpperCase(Mask);
+ end;
+ Result := False;
+ {$IFDEF MSWINDOWS}
+ if Pos('.', FileName) = 0 then
+ FileName := FileName + '.';
+ {$ENDIF MSWINDOWS}
+ LenFileName := Length(FileName);
+ I := 1;
+ Index := 1;
+ while I <= Length(Mask) do
+ begin
+ C := Mask[I];
+ if (Index > LenFileName) and (C <> '*') then
+ Exit;
+ case C of
+ '*':
+ if I = Length(Mask) then
+ begin
+ Result := True;
+ Exit;
+ end
+ else
+ begin
+ Index := PosIdx(Mask[I + 1], FileName, Index);
+ if Index = 0 then
+ Exit;
+ end;
+ '?':
+ Inc(Index);
+ else
+ if C = FileName[Index] then
+ Inc(Index)
+ else
+ Exit;
+ end;
+ Inc(I);
+ end;
+ if Index > LenFileName then
+ Result := True;
+end;
+
+function FileEquMasks(FileName, Masks: TFileName; CaseSensitive: Boolean): Boolean;
+var
+ I: Integer;
+ Mask: string;
+begin
+ Result := False;
+ I := 0;
+ Mask := Trim(SubStrBySeparator(Masks, I, PathSep));
+ while Length(Mask) <> 0 do
+ if FileEquMask(FileName, Mask, CaseSensitive) then
+ begin
+ Result := True;
+ Break;
+ end
+ else
+ begin
+ Inc(I);
+ Mask := Trim(SubStrBySeparator(Masks, I, PathSep));
+ end;
+end;
+
+function ValidFileName(const FileName: string): Boolean;
+
+ function HasAny(const Str, SubStr: string): Boolean;
+ var
+ I: Integer;
+ begin
+ Result := False;
+ for I := 1 to Length(SubStr) do
+ begin
+ if Pos(SubStr[I], Str) > 0 then
+ begin
+ Result := True;
+ Break;
+ end;
+ end;
+ end;
+
+begin
+ Result := (FileName <> '') and
+ {$IFDEF MSWINDOWS}
+ (not HasAny(FileName, '/<>"?*|'));
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ (not HasAny(FileName, '<>"?*|'));
+ {$ENDIF UNIX}
+ if Result then
+ Result := Pos(PathDelim, ExtractFileName(FileName)) = 0;
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+
+function FileLock(Handle: Integer; Offset, LockSize: Longint): Integer; overload;
+begin
+ if LockFile(Handle, Offset, 0, LockSize, 0) then
+ Result := 0
+ else
+ Result := GetLastError;
+end;
+
+function FileUnlock(Handle: Integer; Offset, LockSize: Longint): Integer; overload;
+begin
+ if UnlockFile(Handle, Offset, 0, LockSize, 0) then
+ Result := 0
+ else
+ Result := GetLastError;
+end;
+
+function FileLock(Handle: Integer; Offset, LockSize: Int64): Integer; overload;
+begin
+ if LockFile(Handle, Int64Rec(Offset).Lo, Int64Rec(Offset).Hi,
+ Int64Rec(LockSize).Lo, Int64Rec(LockSize).Hi) then
+ Result := 0
+ else
+ Result := GetLastError;
+end;
+
+function FileUnlock(Handle: Integer; Offset, LockSize: Int64): Integer; overload;
+begin
+ if UnlockFile(Handle, Int64Rec(Offset).Lo, Int64Rec(Offset).Hi,
+ Int64Rec(LockSize).Lo, Int64Rec(LockSize).Hi) then
+ Result := 0
+ else
+ Result := GetLastError;
+end;
+
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+function ShortToLongFileName(const ShortName: string): string;
+{$IFDEF MSWINDOWS}
+var
+ Temp: TWin32FindData;
+ SearchHandle: THandle;
+begin
+ {$IFDEF CLR}
+ SearchHandle := FindFirstFile(ShortName, Temp);
+ {$ELSE}
+ SearchHandle := FindFirstFile(PChar(ShortName), Temp);
+ {$ENDIF CLR}
+ if SearchHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Result := Temp.cFileName;
+ if Result = '' then
+ Result := Temp.cAlternateFileName;
+ end
+ else
+ Result := '';
+ Windows.FindClose(SearchHandle);
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+begin
+ if FileExists(ShortName) then
+ Result := ShortName
+ else
+ Result := '';
+end;
+{$ENDIF UNIX}
+
+function LongToShortFileName(const LongName: string): string;
+{$IFDEF MSWINDOWS}
+var
+ Temp: TWin32FindData;
+ SearchHandle: THandle;
+begin
+ {$IFDEF CLR}
+ SearchHandle := FindFirstFile(LongName, Temp);
+ {$ELSE}
+ SearchHandle := FindFirstFile(PChar(LongName), Temp);
+ {$ENDIF CLR}
+ if SearchHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Result := Temp.cAlternateFileName;
+ if Result = '' then
+ Result := Temp.cFileName;
+ end
+ else
+ Result := '';
+ Windows.FindClose(SearchHandle);
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+begin
+ if FileExists(LongName) then
+ Result := LongName
+ else
+ Result := '';
+end;
+{$ENDIF UNIX}
+
+function ShortToLongPath(const ShortName: string): string;
+{$IFDEF CLR}
+var
+ LastSlash: Integer;
+ TempPath: string;
+begin
+ Result := '';
+ TempPath := ShortName;
+ LastSlash := PosLastCharIdx(PathDelim, ShortName);
+ while LastSlash > 0 do
+ begin
+ Result := PathDelim + ShortToLongFileName(TempPath) + Result;
+ LastSlash := PosLastCharIdx(PathDelim, ShortName, LastSlash - 1);
+ TempPath := Copy(TempPath, 1, LastSlash);
+ end;
+end;
+{$ELSE}
+var
+ LastSlash: PChar;
+ TempPathPtr: PChar;
+begin
+ Result := '';
+ TempPathPtr := PChar(ShortName);
+ LastSlash := StrRScan(TempPathPtr, PathDelim);
+ while LastSlash <> nil do
+ begin
+ Result := PathDelim + ShortToLongFileName(TempPathPtr) + Result;
+ if LastSlash <> nil then
+ begin
+ LastSlash^ := #0;
+ LastSlash := StrRScan(TempPathPtr, PathDelim);
+ end;
+ end;
+ Result := TempPathPtr + Result;
+end;
+{$ENDIF CLR}
+
+function LongToShortPath(const LongName: string): string;
+{$IFDEF CLR}
+begin
+ Result := ExtractShortPathName(LongName);
+end;
+{$ELSE}
+var
+ LastSlash: PChar;
+ TempPathPtr: PChar;
+begin
+ Result := '';
+ TempPathPtr := PChar(LongName);
+ LastSlash := StrRScan(TempPathPtr, PathDelim);
+ while LastSlash <> nil do
+ begin
+ Result := PathDelim + LongToShortFileName(TempPathPtr) + Result;
+ if LastSlash <> nil then
+ begin
+ LastSlash^ := #0;
+ LastSlash := StrRScan(TempPathPtr, PathDelim);
+ end;
+ end;
+ Result := TempPathPtr + Result;
+end;
+{$ENDIF CLR}
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+
+const
+ IID_IPersistFile: TGUID =
+ (D1: $0000010B; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
+
+const
+ LinkExt = '.lnk';
+
+procedure CreateFileLink(const FileName, DisplayName: string; Folder: Integer);
+var
+ ShellLink: IShellLink;
+ PersistFile: IPersistFile;
+ ItemIDList: PItemIDList;
+ FileDestPath: array [0..MAX_PATH] of Char;
+ FileNameW: array [0..MAX_PATH] of WideChar;
+begin
+ CoInitialize(nil);
+ try
+ OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_SERVER,
+ IID_IShellLinkA, ShellLink));
+ try
+ OleCheck(ShellLink.QueryInterface(IID_IPersistFile, PersistFile));
+ try
+ OleCheck(SHGetSpecialFolderLocation(0, Folder, ItemIDList));
+ SHGetPathFromIDList(ItemIDList, FileDestPath);
+ StrCat(FileDestPath, PChar('\' + DisplayName + LinkExt));
+ ShellLink.SetPath(PChar(FileName));
+ ShellLink.SetIconLocation(PChar(FileName), 0);
+ MultiByteToWideChar(CP_ACP, 0, FileDestPath, -1, FileNameW, MAX_PATH);
+ OleCheck(PersistFile.Save(FileNameW, True));
+ finally
+ PersistFile := nil;
+ end;
+ finally
+ ShellLink := nil;
+ end;
+ finally
+ CoUninitialize;
+ end;
+end;
+
+procedure DeleteFileLink(const DisplayName: string; Folder: Integer);
+var
+ ShellLink: IShellLink;
+ ItemIDList: PItemIDList;
+ FileDestPath: array [0..MAX_PATH] of Char;
+begin
+ CoInitialize(nil);
+ try
+ OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_SERVER,
+ IID_IShellLinkA, ShellLink));
+ try
+ OleCheck(SHGetSpecialFolderLocation(0, Folder, ItemIDList));
+ SHGetPathFromIDList(ItemIDList, FileDestPath);
+ StrCat(FileDestPath, PChar('\' + DisplayName + LinkExt));
+ DeleteFile(FileDestPath);
+ finally
+ ShellLink := nil;
+ end;
+ finally
+ CoUninitialize;
+ end;
+end;
+
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+{ end JvFileUtil }
+
+function PtInRectInclusive(R: TRect; Pt: TPoint): Boolean;
+begin
+ R.Right := R.Right + 1;
+ R.Bottom := R.Bottom + 1;
+ Result := PtInRect(R, Pt);
+end;
+
+function PtInRectExclusive(R: TRect; Pt: TPoint): Boolean;
+begin
+ R.Left := R.Left + 1;
+ R.Top := R.Top + 1;
+ Result := PtInRect(R, Pt);
+end;
+
+function OpenObject(const Value: string): Boolean; overload;
+begin
+ {$IFNDEF CLR}
+ Result := OpenObject(PChar(Value));
+ {$ELSE}
+ Result := ShellExecute(0, 'open', Value, '', '', SW_SHOWNORMAL) > HINSTANCE_ERROR;
+ {$ENDIF !CLR}
+end;
+
+{ (rb) Duplicate of JvFunctions.Exec }
+{$IFNDEF CLR}
+function OpenObject(Value: PChar): Boolean; overload;
+begin
+ Result := ShellExecute(0, 'open', Value, nil, nil, SW_SHOWNORMAL) > HINSTANCE_ERROR;
+end;
+{$ENDIF !CLR}
+
+{$IFDEF MSWINDOWS}
+
+procedure RaiseLastWin32; overload;
+begin
+ PError('');
+end;
+
+procedure RaiseLastWin32(const Text: string); overload;
+begin
+ PError(Text);
+end;
+
+{$IFDEF CLR}
+[SuppressUnmanagedCodeSecurity, DllImport('version.dll', CharSet = CharSet.Auto, SetLastError = True, EntryPoint = 'VerQueryValue')]
+function JvVerQueryValue([in] pBlock: TBytes; lpSubBlock: string;
+ out lplpBuffer: TVSFixedFileInfo; out puLen: UINT): BOOL; external;
+{$ENDIF CLR}
+
+function GetFileVersion(const AFileName: string): Cardinal;
+var
+ FileName: string;
+ InfoSize, Wnd: DWORD;
+ {$IFDEF CLR}
+ VerBuf: TBytes;
+ FI: TVSFixedFileInfo;
+ {$ELSE}
+ VerBuf: Pointer;
+ FI: PVSFixedFileInfo;
+ {$ENDIF CLR}
+ VerSize: DWORD;
+begin
+ Result := 0;
+ // GetFileVersionInfo modifies the filename parameter data while parsing.
+ // Copy the string const into a local variable to create a writeable copy.
+ FileName := AFileName;
+ {$IFDEF CLR}
+ InfoSize := GetFileVersionInfoSize(FileName, Wnd);
+ {$ELSE}
+ UniqueString(FileName);
+ InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
+ {$ENDIF CLR}
+ if InfoSize <> 0 then
+ begin
+ {$IFDEF CLR}
+ if GetFileVersionInfo(FileName, Wnd, InfoSize, VerBuf) then
+ if JvVerQueryValue(VerBuf, '\', FI, VerSize) then
+ Result := FI.dwFileVersionMS;
+ {$ELSE}
+ GetMem(VerBuf, InfoSize);
+ try
+ if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
+ if VerQueryValue(VerBuf, '\', Pointer(FI), VerSize) then
+ Result := FI.dwFileVersionMS;
+ finally
+ FreeMem(VerBuf);
+ end;
+ {$ENDIF CLR}
+ end;
+end;
+
+var
+ ShellVersion: Integer;
+
+function GetShellVersion: Cardinal;
+begin
+ if ShellVersion = 0 then
+ ShellVersion := GetFileVersion('shell32.dll');
+ Result := ShellVersion;
+end;
+
+{$IFNDEF CLR}
+procedure OpenCdDrive;
+begin
+ mciSendString(PChar(RC_OpenCDDrive), nil, 0, Windows.GetForegroundWindow);
+end;
+
+procedure CloseCdDrive;
+begin
+ mciSendString(PChar(RC_CloseCDDrive), nil, 0, Windows.GetForegroundWindow);
+end;
+
+{ (rb) Duplicate of JclFileUtils.DiskInDrive }
+
+function DiskInDrive(Drive: Char): Boolean;
+var
+ DrvNum: Byte;
+ EMode: Word;
+begin
+ DrvNum := Ord(Drive);
+ if DrvNum >= Ord('a') then
+ Dec(DrvNum, $20);
+ EMode := SetErrorMode(SEM_FAILCRITICALERRORS);
+ try
+ Result := DiskSize(DrvNum - $40) <> -1;
+ finally
+ SetErrorMode(EMode);
+ end;
+end;
+
+{$ENDIF MSWINDOWS}
+
+procedure PError(const Text: string);
+var
+ LastError: Integer;
+ St: string;
+begin
+ LastError := GetLastError;
+ if LastError <> 0 then
+ begin
+ St := SysUtils.Format({$IFDEF COMPILER6_UP} SOSError {$ELSE} SWin32Error {$ENDIF},
+ [LastError, SysErrorMessage(LastError)]);
+ if Text <> '' then
+ St := Text + ':' + St;
+ raise {$IFDEF COMPILER6_UP} EOSError{$ELSE} EWin32Error{$ENDIF}.Create(St);
+ end;
+end;
+{$ENDIF !CLR}
+
+procedure Exec(const FileName, Parameters, Directory: string);
+begin
+ {$IFDEF CLR}
+ ShellExecute(Windows.GetForegroundWindow, 'open', FileName, Parameters, Directory,
+ SW_SHOWNORMAL);
+ {$ELSE}
+ {$IFDEF MSWINDOWS}
+ ShellExecute(Windows.GetForegroundWindow, 'open', PChar(FileName), PChar(Parameters), PChar(Directory),
+ SW_SHOWNORMAL);
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ ShellExecute(GetForegroundWindow, 'open', PChar(FileName), PChar(Parameters), PChar(Directory),
+ SW_SHOWNORMAL);
+ {$ENDIF UNIX}
+ {$ENDIF CLR}
+end;
+{$IFDEF UNIX}
+// begin
+// if Directory = '' then Directory := GetCurrentDir;
+// Libc.system(PChar(Format('cd "%s" ; "%s" %s &', [Directory, FileName, Parameters])));
+// end;
+{$ENDIF UNIX}
+
+{ (rb) Duplicate of JclMiscel.WinExec32AndWait }
+
+function ExecuteAndWait(const CommandLine, WorkingDirectory: string; Visibility: Integer): Integer;
+{$IFDEF CLR}
+var
+ Proc: Process;
+begin
+ Result := 0;
+ Proc := Process.Create;
+ Proc.StartInfo.FileName := CommandLine;
+
+ case Visibility of
+ SW_HIDE:
+ Proc.StartInfo.WindowStyle := ProcessWindowStyle.Hidden;
+ SW_SHOWMINIMIZED:
+ Proc.StartInfo.WindowStyle := ProcessWindowStyle.Minimized;
+ SW_SHOWMAXIMIZED:
+ Proc.StartInfo.WindowStyle := ProcessWindowStyle.Maximized;
+ else
+ Proc.StartInfo.WindowStyle := ProcessWindowStyle.Normal
+ end;
+
+ if Proc.Start then
+ Proc.WaitForExit
+ else
+ Result := 1;
+ Proc.Close;
+end;
+{$ELSE}
+{$IFDEF MSWINDOWS}
+var
+ StartupInfo: TStartupInfo;
+ ProcessInfo: TProcessInformation;
+begin
+ Result := 0;
+ FillChar(StartupInfo, SizeOf(StartupInfo), 0);
+ StartupInfo.cb := SizeOf(StartupInfo);
+ StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
+ StartupInfo.wShowWindow := Visibility;
+ if not CreateProcess(nil, PChar(CommandLine), nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
+ nil, Pointer(WorkingDirectory), StartupInfo, ProcessInfo) then
+ begin
+ WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
+
+ // required to avoid running resource leak.
+ CloseHandle(ProcessInfo.hProcess);
+ CloseHandle(ProcessInfo.hThread);
+ end
+ else
+ begin
+ Result := GetLastError;
+ end;
+end;
+{$ENDIF MSWINDOWS}
+{$IFDEF UNIX}
+begin
+ // ignores Visibility
+ { TODO : Untested }
+ if Libc.system(PChar(Format('kfmclient exec "%s"', [CommandLine]))) = -1 then
+ begin
+ if WorkingDirectory = '' then
+ Result := Libc.system(PChar(Format('cd "%s" ; %s',
+ [GetCurrentDir, CommandLine])))
+ else
+ Result := Libc.system(PChar(Format('cd "%s" ; %s',
+ [WorkingDirectory, CommandLine])));
+ end;
+end;
+{$ENDIF UNIX}
+{$ENDIF CLR}
+
+
+
+function FirstInstance(const ATitle: string): Boolean;
+{$IFDEF CLR}
+var
+ Mux: System.Threading.Mutex;
+ IsNew: Boolean;
+begin
+ Mux := System.Threading.Mutex.Create(False, ATitle, IsNew);
+ try
+ Result := IsNew;
+ finally
+ Mux.ReleaseMutex;
+ end;
+end;
+{$ELSE}
+var
+ Mutex: THandle;
+begin
+ Mutex := CreateMutex(nil, False, PChar(ATitle));
+ try
+ Result := (Mutex <> 0) and (GetLastError <> ERROR_ALREADY_EXISTS);
+ finally
+ ReleaseMutex(Mutex);
+ end;
+end;
+{$ENDIF CLR}
+
+procedure RestoreOtherInstance(const MainFormClassName, MainFormCaption: string);
+var
+ OtherWnd, OwnerWnd: HWND;
+begin
+ {$IFDEF CLR}
+ OtherWnd := FindWindow(MainFormClassName, MainFormCaption);
+ {$ELSE}
+ OtherWnd := FindWindow(PChar(MainFormClassName), PChar(MainFormCaption));
+ {$ENDIF CLR}
+ ShowWindow(OtherWnd, SW_SHOW); //in case the window was not visible before
+
+ OwnerWnd := 0;
+ if OtherWnd <> 0 then
+ OwnerWnd := GetWindow(OtherWnd, GW_OWNER);
+
+ if OwnerWnd <> 0 then
+ OtherWnd := OwnerWnd;
+
+ if OtherWnd <> 0 then
+ begin
+ { (rb) Use JvVCLUtils.SwitchToWindow }
+ if IsIconic(OtherWnd) then
+ ShowWindow(OtherWnd, SW_RESTORE);
+
+ SetForegroundWindow(OtherWnd);
+ end;
+end;
+
+procedure HideTraybar;
+begin
+ {$IFDEF CLR}
+ ShowWindow(FindWindow(RC_ShellName, nil), SW_HIDE);
+ {$ELSE}
+ ShowWindow(FindWindow(PChar(RC_ShellName), nil), SW_HIDE);
+ {$ENDIF CLR}
+end;
+
+procedure ShowTraybar;
+begin
+ {$IFDEF CLR}
+ ShowWindow(FindWindow(RC_ShellName, nil), SW_SHOW);
+ {$ELSE}
+ ShowWindow(FindWindow(PChar(RC_ShellName), nil), SW_SHOW);
+ {$ENDIF CLR}
+end;
+
+{$IFNDEF CLR}
+procedure ShowStartButton(Visible: Boolean);
+var
+ Tray, Child: HWND;
+ C: array [0..127] of Char;
+ S: string;
+begin
+ Tray := FindWindow(PChar(RC_ShellName), nil);
+ Child := GetWindow(Tray, GW_CHILD);
+ while Child <> 0 do
+ begin
+ if GetClassName(Child, C, SizeOf(C)) > 0 then
+ begin
+ S := StrPas(C);
+ if UpperCase(S) = 'BUTTON' then
+ if Visible then
+ ShowWindow(Child, SW_SHOWNORMAL)
+ else
+ ShowWindow(Child, SW_HIDE);
+ end;
+ Child := GetWindow(Child, GW_HWNDNEXT);
+ end;
+end;
+{$ENDIF !CLR}
+
+procedure MonitorOn;
+begin
+ SendMessage(GetForegroundWindow, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
+end;
+
+procedure MonitorOff;
+begin
+ SendMessage(GetForegroundWindow, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
+end;
+
+procedure LowPower;
+begin
+ SendMessage(GetForegroundWindow, WM_SYSCOMMAND, SC_MONITORPOWER, 1);
+end;
+
+procedure SendShift(H: THandle; Down: Boolean);
+var
+ VKey, ScanCode: Word;
+ LParam: Cardinal;
+begin
+ VKey := VK_SHIFT;
+ ScanCode := MapVirtualKey(VKey, 0);
+ LParam := Longint(ScanCode) shl 16 or 1;
+ if not Down then
+ LParam := LParam or $C0000000;
+ SendMessage(H, WM_KEYDOWN, VKey, LParam);
+end;
+
+procedure SendCtrl(H: THandle; Down: Boolean);
+var
+ VKey, ScanCode: Word;
+ LParam: Cardinal;
+begin
+ VKey := VK_CONTROL;
+ ScanCode := MapVirtualKey(VKey, 0);
+ LParam := Longint(ScanCode) shl 16 or 1;
+ if not Down then
+ LParam := LParam or $C0000000;
+ SendMessage(H, WM_KEYDOWN, VKey, LParam);
+end;
+
+function SendKey(const AppName: string; Key: Char): Boolean;
+var
+ VKey, ScanCode: Word;
+ ConvKey: Longint;
+ LParam: Cardinal;
+ Shift, Ctrl: Boolean;
+ H: Windows.HWND;
+begin
+ {$IFDEF CLR}
+ H := FindWindow(AppName, nil);
+ {$ELSE}
+ H := FindWindow(PChar(AppName), nil);
+ {$ENDIF CLR}
+ if H <> 0 then
+ begin
+ ConvKey := OemKeyScan(Ord(Key));
+ Shift := (ConvKey and $00020000) <> 0;
+ Ctrl := (ConvKey and $00040000) <> 0;
+ ScanCode := ConvKey and $000000FF or $FF00;
+ VKey := Ord(Key);
+ LParam := Longint(ScanCode) shl 16 or 1;
+ if Shift then
+ SendShift(H, True);
+ if Ctrl then
+ SendCtrl(H, True);
+ SendMessage(H, WM_KEYDOWN, VKey, LParam);
+ SendMessage(H, WM_CHAR, VKey, LParam);
+ LParam := LParam or $C0000000;
+ SendMessage(H, WM_KEYUP, VKey, LParam);
+ if Shift then
+ SendShift(H, False);
+ if Ctrl then
+ SendCtrl(H, False);
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+
+
+{$IFDEF MSWINDOWS}
+
+{$IFNDEF CLR}
+procedure RebuildIconCache;
+var
+ Dummy: DWORD;
+begin
+ SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS,
+ Longint(PChar('WindowMetrics')), SMTO_NORMAL or SMTO_ABORTIFHUNG, 10000, Dummy);
+end;
+
+procedure AssociateFileExtension(const IconPath, ProgramName, Path, Extension: string);
+begin
+ with TRegistry.Create do
+ begin
+ RootKey := HKEY_CLASSES_ROOT;
+ OpenKey(ProgramName, True);
+ WriteString('', ProgramName);
+ if IconPath <> '' then
+ begin
+ OpenKey(RC_DefaultIcon, True);
+ WriteString('', IconPath);
+ end;
+ CloseKey;
+ OpenKey(ProgramName, True);
+ OpenKey('shell', True);
+ OpenKey('open', True);
+ OpenKey('command', True);
+ WriteString('', '"' + Path + '" "%1"');
+ Free;
+ end;
+ with TRegistry.Create do
+ begin
+ RootKey := HKEY_CLASSES_ROOT;
+ OpenKey('.' + Extension, True);
+ WriteString('', ProgramName);
+ Free;
+ end;
+ RebuildIconCache;
+end;
+
+procedure AssociateExtension(const IconPath, ProgramName, Path, Extension: string);
+begin
+ AssociateFileExtension(IconPath, ProgramName, Path, Extension);
+end;
+{$ENDIF !CLR}
+
+function GetRecentDocs: TStringList;
+
+var
+ Path: string;
+ T: TSearchRec;
+ Res: Integer;
+
+begin
+ Result := TStringList.Create;
+ Path := IncludeTrailingPathDelimiter(GetRecentFolder);
+ //search for all files
+ Res := FindFirst(Path + '*.*', faAnyFile, T);
+ try
+ while Res = 0 do
+ begin
+ if (T.Name <> '.') and (T.Name <> '..') then
+ Result.Add(Path + T.Name);
+ Res := FindNext(T);
+ end;
+ finally
+ FindClose(T);
+ end;
+end;
+
+{ (rb) Duplicate of JvWinDialogs.AddToRecentDocs }
+
+{$IFNDEF CLR}
+procedure AddToRecentDocs(const FileName: string);
+begin
+ SHAddToRecentDocs(SHARD_PATH, PChar(FileName));
+end;
+
+function EnumWindowsProc(Handle: THandle; LParam: TStrings): Boolean; stdcall;
+var
+ St: array [0..256] of Char;
+ St2: string;
+begin
+ if Windows.IsWindowVisible(Handle) then
+ begin
+ GetWindowText(Handle, St, SizeOf(St));
+ St2 := St;
+ if St2 <> '' then
+ with TStrings(LParam) do
+ AddObject(St2, TObject(Handle));
+ end;
+ Result := True;
+end;
+
+procedure GetVisibleWindows(List: TStrings);
+begin
+ List.BeginUpdate;
+ try
+ List.Clear;
+ EnumWindows(@EnumWindowsProc, Integer(List));
+ finally
+ List.EndUpdate;
+ end;
+end;
+{$ENDIF !CLR}
+
+{$ENDIF MSWINDOWS}
+// from JvComponentFunctions
+
+function StrPosNoCase(const psSub, psMain: string): Integer;
+begin
+ Result := Pos(AnsiUpperCase(psSub), AnsiUpperCase(psMain));
+end;
+
+function StrRestOf(const Ps: string; const N: Integer): string;
+begin
+ Result := Copy(Ps, N, {(Length(Ps) - N + 1)} MaxInt);
+end;
+
+{!!!!!!!! use these because the JCL one is badly broken }
+
+{ I am using this one purely as an internal for StrReplace
+
+ Replaces parts of a string with new text. iUpdatePos is the last update position
+ i.e. the position where substr was found + the length of the replacement string + 1.
+ Use 0 first time in }
+
+function StrReplaceInstance(const psSource, psSearch, psReplace: string;
+ var piUpdatePos: Integer; const pbCaseSens: Boolean): string;
+var
+ liIndex: Integer;
+ lsCopy: string;
+begin
+ Result := psSource;
+ if piUpdatePos >= Length(psSource) then
+ Exit;
+ if psSearch = '' then
+ Exit;
+
+ Result := Copy(psSource, 1, piUpdatePos - 1);
+ lsCopy := StrRestOf(psSource, piUpdatePos);
+
+ if pbCaseSens then
+ liIndex := Pos(psSearch, lsCopy)
+ else
+ liIndex := StrPosNoCase(psSearch, lsCopy);
+ if liIndex = 0 then
+ begin
+ Result := psSource;
+ piUpdatePos := Length(psSource) + 1;
+ Exit;
+ end;
+
+ Result := Result + Copy(lsCopy, 1, liIndex - 1);
+ Result := Result + psReplace;
+ piUpdatePos := Length(Result) + 1;
+ Result := Result + StrRestOf(lsCopy, liIndex + Length(psSearch));
+end;
+
+function LStrReplace(const psSource, psSearch, psReplace: string;
+ const pbCaseSens: Boolean): string;
+var
+ liUpdatePos: Integer;
+begin
+ liUpdatePos := 0;
+ Result := psSource;
+ while liUpdatePos < Length(Result) do
+ Result := StrReplaceInstance(Result, psSearch, psReplace, liUpdatePos, pbCaseSens);
+end;
+
+{ if it's not a decimal point then it must be a digit, space or Currency symbol
+ also always use $ for money }
+
+function CharIsMoney(const Ch: AnsiChar): Boolean;
+begin
+ Result := CharIsDigit(Ch) or (Ch = AnsiSpace) or (Ch = '$') or (Ch = '-') or
+ (Pos(Ch, CurrencyString) > 0);
+end;
+
+function StrToCurrDef(const Str: string; Def: Currency): Currency;
+var
+ {$IFDEF CLR}
+ LStr: StringBuilder;
+ {$ELSE}
+ LStr: string;
+ {$ENDIF CLR}
+ I: Integer;
+begin
+ {$IFDEF CLR}
+ LStr := StringBuilder.Create(Length(Str));
+ {$ELSE}
+ LStr := '';
+ {$ENDIF CLR}
+ for I := 1 to Length(Str) do
+ if Str[I] in ['0'..'9', '-', '+', AnsiChar(DecimalSeparator{$IFDEF CLR}[1]{$ENDIF})] then
+ {$IFDEF CLR}
+ LStr.Append(Str[I]);
+ {$ELSE}
+ LStr := LStr + Str[I];
+ {$ENDIF CLR}
+ try
+ {$IFDEF CLR}
+ if not TryStrToCurr(LStr.ToString(), Result) then
+ {$ELSE}
+ if not TextToFloat(PChar(LStr), Result, fvCurrency) then
+ {$ENDIF CLR}
+ Result := Def;
+ except
+ Result := Def;
+ end;
+end;
+
+// Note: before using StrToFloatDef, please be aware that it will ignore
+// any character that is not a valid character for a float, which is different
+// from what the one in Delphi 6 up is doing. This has been documented in Mantis
+// issue# 2935: http://homepages.borland.com/jedi/issuetracker/view.php?id=2935
+function StrToFloatDef(const Str: string; Def: Extended): Extended;
+var
+ {$IFDEF CLR}
+ LStr: StringBuilder;
+ d: Double;
+ b: Boolean;
+ {$ELSE}
+ LStr: string;
+ {$ENDIF CLR}
+ I: Integer;
+begin
+ {$IFDEF CLR}
+ LStr := StringBuilder.Create;
+ {$ENDIF CLR}
+ for I := 1 to Length(Str) do
+ if Str[I] in ['0'..'9', '-', '+', 'e', 'E', AnsiChar(DecimalSeparator{$IFDEF CLR}[1]{$ENDIF})] then
+ {$IFDEF CLR}
+ LStr.Append(Str[I]);
+ {$ELSE}
+ LStr := LStr + Str[I];
+ {$ENDIF CLR}
+ Result := Def;
+ {$IFDEF CLR}
+ if LStr.Length > 0 then
+ try
+ { the string '-' fails StrToFloat, but it can be interpreted as 0 }
+ if LStr[LStr.Length] = '-' then
+ LStr.Append('0');
+
+ { a string that ends in a '.' such as '12.' fails StrToFloat,
+ but as far as I am concerned, it may as well be interpreted as 12.0 }
+ if LStr[LStr.Length] = DecimalSeparator then
+ LStr.Append('0');
+
+ b := TryStrToFloat(LStr.ToString(), d);
+ Result := d;
+ if not b then
+ {$ELSE}
+ if LStr <> '' then
+ try
+ { the string '-' fails StrToFloat, but it can be interpreted as 0 }
+ if LStr[Length(LStr)] = '-' then
+ LStr := LStr + '0';
+
+ { a string that ends in a '.' such as '12.' fails StrToFloat,
+ but as far as I am concerned, it may as well be interpreted as 12.0 }
+ if LStr[Length(LStr)] = DecimalSeparator then
+ LStr := LStr + '0';
+ if not TextToFloat(PChar(LStr), Result, fvExtended) then
+ {$ENDIF CLR}
+ Result := Def;
+ except
+ Result := Def;
+ end;
+end;
+
+function IntToExtended(I: Integer): Extended;
+begin
+ Result := I;
+end;
+
+function GetChangedText(const Text: string; SelStart, SelLength: Integer; Key: Char): string;
+begin
+ { take the original text, replace what will be overwritten with new value }
+ Result := Text;
+
+ if SelLength > 0 then
+ Delete(Result, SelStart + 1, SelLength);
+ if Key <> #0 then
+ Insert(Key, Result, SelStart + 1);
+end;
+
+{ "window" technique for years to translate 2 digits to 4 digits.
+ The window is 100 years wide
+ The pivot year is the lower edge of the window
+ A pivot year of 1900 is equivalent to putting 1900 before every 2-digit year
+ if pivot is 1940, then 40 is interpreted as 1940, 00 as 2000 and 39 as 2039
+ The system default is 1950
+
+ Why the reimplementation?
+ JclDatetime.Make4DigitYear will fail after 2100, this won't
+ note that in this implementation pivot is a 4-digit year
+ I have made it accept JclDatetime.Make4DigitYear's 2 digit pivot years.
+ They are expanded by adding 1900.
+
+ It is also better in that a valid 4-digit year will pass through unchanged,
+ not fail an assertion.
+}
+
+function MakeYear4Digit(Year, Pivot: Integer): Integer;
+var
+ Century: Integer;
+begin
+ if Pivot < 0 then
+ {$IFDEF CLR}
+ raise Exception.Create(RsEPivotLessThanZero);
+ {$ELSE}
+ raise Exception.CreateRes(@RsEPivotLessThanZero);
+ {$ENDIF CLR}
+
+ { map 100 to zero }
+ if Year = 100 then
+ Year := 0;
+ if Pivot = 100 then
+ Pivot := 0;
+
+ // turn 2 digit pivot to 4 digit
+ if Pivot < 100 then
+ Pivot := Pivot + 1900;
+
+ { turn 2 digit years to 4 digits }
+ if (Year >= 0) and (Year < 100) then
+ begin
+ Century := (Pivot div 100) * 100;
+
+ Result := Year + Century; // give the result the same century as the pivot
+ if Result < Pivot then
+ // cannot be lower than the Pivot
+ Result := Result + 100;
+ end
+ else
+ Result := Year;
+end;
+
+function StrIsInteger(const S: string): Boolean;
+var
+ I: Integer;
+ Ch: AnsiChar;
+begin
+ Result := S <> '';
+ for I := 1 to Length(S) do
+ begin
+ Ch := AnsiChar(S[I]);
+ if (not CharIsNumber(Ch)) or (Ch = DecimalSeparator) then //Az
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+end;
+
+function StrIsFloatMoney(const Ps: string): Boolean;
+var
+ I, liDots: Integer;
+ Ch: AnsiChar;
+begin
+ Result := True;
+ liDots := 0;
+
+ for I := 1 to Length(Ps) do
+ begin
+ { allow digits, space, Currency symbol and one decimal dot }
+ Ch := AnsiChar(Ps[I]);
+
+ if Ch = DecimalSeparator then
+ begin
+ Inc(liDots);
+ if liDots > 1 then
+ begin
+ Result := False;
+ Break;
+ end;
+ end
+ else
+ if not CharIsMoney(Ch) then
+ begin
+ Result := False;
+ Break;
+ end;
+ end;
+end;
+
+function StrIsDateTime(const Ps: string): Boolean;
+const
+ MIN_DATE_TIME_LEN = 6; {2Jan02 }
+ MAX_DATE_TIME_LEN = 30; { 30 chars or so in '12 December 1999 12:23:23:00' }
+var
+ I: Integer;
+ Ch: AnsiChar;
+ liColons, liSlashes, liSpaces, liDigits, liAlpha: Integer;
+ lbDisqualify: Boolean;
+begin
+ if Length(Ps) < MIN_DATE_TIME_LEN then
+ begin
+ Result := False;
+ Exit;
+ end;
+
+ if Length(Ps) > MAX_DATE_TIME_LEN then
+ begin
+ Result := False;
+ Exit;
+ end;
+
+ lbDisqualify := False;
+ liColons := 0;
+ liSlashes := 0;
+ liSpaces := 0;
+ liDigits := 0;
+ liAlpha := 0;
+
+ for I := 1 to Length(Ps) do
+ begin
+ Ch := AnsiChar(Ps[I]);
+
+ if Ch = ':' then
+ Inc(liColons)
+ else
+ if Ch = AnsiForwardSlash then
+ Inc(liSlashes)
+ else
+ if Ch = AnsiSpace then
+ Inc(liSpaces)
+ else
+ if CharIsDigit(Ch) then
+ Inc(liDigits)
+ else
+ if CharIsAlpha(Ch) then
+ Inc(liAlpha)
+ else
+ begin
+ // no wierd punctuation in dates!
+ lbDisqualify := True;
+ Break;
+ end;
+ end;
+
+ Result := False;
+ if not lbDisqualify then
+ { a date must have colons and slashes and spaces, but not to many of each }
+ if (liColons > 0) or (liSlashes > 0) or (liSpaces > 0) then
+ { only 2 slashes in "dd/mm/yy" or 3 colons in "hh:mm:ss:ms" or 6 spaces "yy mm dd hh mm ss ms" }
+ if (liSlashes <= 2) and (liColons <= 3) and (liSpaces <= 6) then
+ { must have some digits (min 3 digits, eg in "2 jan 02", max 16 dgits in "01/10/2000 10:10:10:10"
+ longest month name is 8 chars }
+ if (liDigits >= 3) and (liDigits <= 16) and (liAlpha <= 10) then
+ Result := True;
+
+ { define in terms of results - if I can interpret it as a date, then I can }
+ if Result then
+ Result := (SafeStrToDateTime(PreformatDateString(Ps)) <> 0);
+end;
+
+function PreformatDateString(Ps: string): string;
+var
+ I: Integer;
+begin
+ { turn any month names to numbers }
+
+ { use the StrReplace in stringfunctions -
+ the one in JclStrings is badly broken and brings down the app }
+
+ for I := Low(LongMonthNames) to High(LongMonthNames) do
+ Ps := LStrReplace(Ps, LongMonthNames[I], IntToStr(I), False);
+
+ { now that 'January' is gone, catch 'Jan' }
+ for I := Low(ShortMonthNames) to High(ShortMonthNames) do
+ Ps := LStrReplace(Ps, ShortMonthNames[I], IntToStr(I), False);
+
+ { remove redundant spaces }
+ Ps := LStrReplace(Ps, AnsiSpace + AnsiSpace, AnsiSpace, False);
+
+ Result := Ps;
+end;
+
+function BooleanToInteger(const B: Boolean): Integer;
+begin
+ Result := Ord(B);
+end;
+
+{ from my ConvertFunctions unit }
+
+function StringToBoolean(const Ps: string): Boolean;
+const
+ TRUE_STRINGS: array [1..5] of string = ('True', 't', 'y', 'yes', '1');
+var
+ I: Integer;
+begin
+ Result := False;
+
+ for I := Low(TRUE_STRINGS) to High(TRUE_STRINGS) do
+ if AnsiSameText(Ps, TRUE_STRINGS[I]) then
+ begin
+ Result := True;
+ Break;
+ end;
+end;
+
+function SafeStrToDateTime(const Ps: string): TDateTime;
+begin
+ try
+ Result := StrToDateTime(PreformatDateString(Ps));
+ except
+ on E: EConvertError do
+ Result := 0.0
+ else
+ raise;
+ end;
+end;
+
+function SafeStrToDate(const Ps: string): TDateTime;
+begin
+ try
+ Result := StrToDate(PreformatDateString(Ps));
+ except
+ on E: EConvertError do
+ Result := 0.0
+ else
+ raise;
+ end;
+end;
+
+function SafeStrToTime(const Ps: string): TDateTime;
+begin
+ try
+ Result := StrToTime(Ps)
+ except
+ on E: EConvertError do
+ Result := 0.0
+ else
+ raise;
+ end;
+end;
+
+{!! from strFunctions }
+
+function StrDeleteChars(const Ps: string; const piPos: Integer; const piCount: Integer): string;
+begin
+ Result := Copy(Ps, 1, piPos - 1) + StrRestOf(Ps, piPos + piCount);
+end;
+
+function StrDelete(const psSub, psMain: string): string;
+var
+ liPos: Integer;
+begin
+ Result := psMain;
+ if psSub = '' then
+ Exit;
+
+ liPos := StrIPos(psSub, psMain);
+
+ while liPos > 0 do
+ begin
+ Result := StrDeleteChars(Result, liPos, Length(psSub));
+ liPos := StrIPos(psSub, Result);
+ end;
+end;
+
+function TimeOnly(pcValue: TDateTime): TTime;
+begin
+ Result := Frac(pcValue);
+end;
+
+function DateOnly(pcValue: TDateTime): TDate;
+begin
+ Result := Trunc(pcValue);
+end;
+
+{ have to do this as it depends what the datekind of the control is}
+
+function DateIsNull(const pdtValue: TDateTime; const pdtKind: TdtKind): Boolean;
+begin
+ Result := False;
+ case pdtKind of
+ dtkDateOnly:
+ Result := pdtValue < 1; //if date only then anything less than 1 is considered null
+ dtkTimeOnly:
+ Result := Frac(pdtValue) = NullEquivalentDate; //if time only then anything without a remainder is null
+ dtkDateTime:
+ Result := pdtValue = NullEquivalentDate;
+ end;
+end;
+
+function OSCheck(RetVal: Boolean): Boolean;
+begin
+ if not RetVal then
+ RaiseLastOSError;
+ Result := RetVal;
+end;
+
+function MinimizeFileName(const FileName: string; Canvas: TCanvas; MaxLen: Integer): string;
+var
+ {$IFDEF CLR}
+ sb: StringBuilder;
+ {$ENDIF CLR}
+ R: TRect;
+begin
+ Result := FileName;
+ R := Rect(0, 0, MaxLen, Canvas.TextHeight('Wq'));
+ {$IFDEF CLR}
+ sb := StringBuilder.Create(Result);
+ // DrawText() doesn't exist with StringBuilder parameter (2005)
+ if DrawTextEx(Canvas.Handle, sb, sb.Length, R,
+ DT_SINGLELINE or DT_MODIFYSTRING or DT_PATH_ELLIPSIS or DT_CALCRECT or
+ DT_NOPREFIX, nil) <= 0 then
+ {$ELSE}
+ UniqueString(Result);
+ if DrawText(Canvas.Handle, PChar(Result), Length(Result), R,
+ DT_SINGLELINE or DT_MODIFYSTRING or DT_PATH_ELLIPSIS or DT_CALCRECT or
+ DT_NOPREFIX) <= 0 then
+ {$ENDIF CLR}
+ Result := FileName;
+end;
+
+function MinimizeText(const Text: string; Canvas: TCanvas;
+ MaxWidth: Integer): string;
+var
+ I: Integer;
+begin
+ Result := Text;
+ I := 1;
+ while (I <= Length(Text)) and (Canvas.TextWidth(Result) > MaxWidth) do
+ begin
+ Inc(I);
+ Result := Copy(Text, 1, Max(0, Length(Text) - I)) + '...';
+ end;
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+
+function RunDLL32(const ModuleName, FuncName, CmdLine: string; WaitForCompletion: Boolean; CmdShow: Integer =
+ SW_SHOWDEFAULT): Boolean;
+var
+ SI: TStartupInfo;
+ PI: TProcessInformation;
+ S: string;
+begin
+ SI.cb := SizeOf(SI);
+ GetStartupInfo(SI);
+ SI.wShowWindow := CmdShow;
+ S := SysUtils.Format('rundll32.exe %s,%s %s', [ModuleName, FuncName, CmdLine]);
+ Result := CreateProcess(nil, PChar(S), nil, nil, False, 0, nil, nil, SI, PI);
+ try
+ if WaitForCompletion then
+ Result := WaitForSingleObject(PI.hProcess, INFINITE) <> WAIT_FAILED;
+ finally
+ CloseHandle(PI.hThread);
+ CloseHandle(PI.hProcess);
+ end;
+end;
+
+procedure RunDll32Internal(Wnd: THandle; const DLLName, FuncName, CmdLine: string; CmdShow: Integer = SW_SHOWDEFAULT);
+var
+ H: THandle;
+ P: TRunDLL32Proc;
+begin
+ H := SafeLoadLibrary(DLLName, SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX);
+ if H <> 0 then
+ begin
+ try
+ P := GetProcAddress(H, PChar(FuncName));
+ if Assigned(P) then
+ P(Wnd, H, PChar(CmdLine), CmdShow);
+ finally
+ FreeLibrary(H);
+ end;
+ end;
+end;
+
+type
+ // (p3) from ShLwAPI
+ TDLLVersionInfo = packed record
+ cbSize: DWORD;
+ dwMajorVersion: DWORD;
+ dwMinorVersion: DWORD;
+ dwBuildNumber: DWORD;
+ dwPlatformId: DWORD;
+ end;
+
+function GetDLLVersion(const DLLName: string; var pdwMajor, pdwMinor: Integer): Boolean;
+var
+ hDLL, hr: THandle;
+ pDllGetVersion: function(var Dvi: TDLLVersionInfo): Integer; stdcall;
+ Dvi: TDLLVersionInfo;
+begin
+ hDLL := SafeLoadLibrary(DLLName);
+ if hDLL <> 0 then
+ begin
+ Result := True;
+ (* You must get this function explicitly
+ because earlier versions of the DLL's
+ don't implement this function.
+ That makes the lack of implementation
+ of the function a version marker in itself. *)
+ @pDllGetVersion := GetProcAddress(hDLL, PChar('DllGetVersion'));
+ if Assigned(pDllGetVersion) then
+ begin
+ FillChar(Dvi, SizeOf(Dvi), #0);
+ Dvi.cbSize := SizeOf(Dvi);
+ hr := pDllGetVersion(Dvi);
+ if hr = 0 then
+ begin
+ pdwMajor := Dvi.dwMajorVersion;
+ pdwMinor := Dvi.dwMinorVersion;
+ end;
+ end
+ else (* If GetProcAddress failed, the DLL is a version previous to the one shipped with IE 3.x. *)
+ begin
+ pdwMajor := 4;
+ pdwMinor := 0;
+ end;
+ FreeLibrary(hDLL);
+ Exit;
+ end;
+ Result := False;
+end;
+
+{$ENDIF MSWINDOWS}
+{from JvVCLUtils }
+
+{ Exceptions }
+
+procedure ResourceNotFound(ResID: PChar);
+var
+ S: string;
+begin
+ if LongRec(ResID).Hi = 0 then
+ S := IntToStr(LongRec(ResID).Lo)
+ else
+ S := StrPas(ResID);
+ raise EResNotFound.CreateResFmt(@SResNotFound, [S]);
+end;
+{$ENDIF !CLR}
+*******************)
+
+function RectWidth(R: TRect): Integer;
+begin
+ Result := Abs(R.Right - R.Left);
+end;
+
+function RectHeight(R: TRect): Integer;
+begin
+ Result := Abs(R.Bottom - R.Top);
+end;
+
+function CompareRect(const R1, R2: TRect): Boolean;
+begin
+ Result := (R1.Left = R2.Left) and (R1.Top = R2.Top) and
+ (R1.Right = R2.Right) and (R1.Bottom = R2.Bottom);
+end;
+
+(******************
+{$IFDEF MSWINDOWS}
+{ Service routines }
+
+{$IFNDEF CLR}
+function LoadDLL(const LibName: string): THandle;
+begin
+ Result := SafeLoadLibrary(LibName);
+ if Result <> 0 then
+ OSCheck(False);
+end;
+
+function GetWindowsVersion: string;
+const
+ sWindowsVersion = 'Windows %s %d.%.2d.%.3d %s';
+var
+ Ver: TOSVersionInfo;
+ Platfrm: string[4];
+begin
+ Ver.dwOSVersionInfoSize := SizeOf(Ver);
+ GetVersionEx(Ver);
+ with Ver do
+ begin
+ case dwPlatformId of
+ VER_PLATFORM_WIN32s:
+ Platfrm := '32s';
+ VER_PLATFORM_WIN32_WINDOWS:
+ begin
+ dwBuildNumber := dwBuildNumber and $0000FFFF;
+ if (dwMajorVersion > 4) or ((dwMajorVersion = 4) and
+ (dwMinorVersion >= 10)) then
+ Platfrm := '98'
+ else
+ Platfrm := '95';
+ end;
+ VER_PLATFORM_WIN32_NT: Platfrm := 'NT';
+ end;
+ Result := Trim(SysUtils.Format(sWindowsVersion, [Platfrm, dwMajorVersion,
+ dwMinorVersion, dwBuildNumber, szCSDVersion]));
+ end;
+end;
+
+{ RegisterServer procedure written by Vladimir Gaitanoff, 2:50/430.2 }
+
+function RegisterServer(const ModuleName: string): Boolean;
+type
+ TCOMFunc = function: HRESULT;
+const
+ S_OK = $00000000;
+var
+ Handle: THandle;
+ DllRegServ: TCOMFunc;
+begin
+ Handle := LoadDLL(ModuleName);
+ try
+ DllRegServ := GetProcAddress(Handle, 'DllRegisterServer');
+ Result := Assigned(DllRegServ) and (DllRegServ() = S_OK);
+ finally
+ FreeLibrary(Handle);
+ end;
+end;
+
+// UnregisterServer by Ralf Kaiser patterned on RegisterServer
+function UnregisterServer(const ModuleName: string): Boolean;
+type
+ TCOMFunc = function: HRESULT;
+const
+ S_OK = $00000000;
+var
+ Handle: THandle;
+ DllUnRegServ: TCOMFunc;
+ DllCanUnloadNow: TCOMFunc;
+begin
+ Handle := LoadDLL(ModuleName);
+ try
+ DllUnRegServ := GetProcAddress(Handle, 'DllUnregisterServer');
+ DllCanUnloadNow := GetProcAddress(Handle, 'DllCanUnloadNow');
+ Result := Assigned(DllCanUnloadNow) and (DllCanUnloadNow() = S_OK) and
+ Assigned(DllUnRegServ) and (DllUnRegServ() = S_OK);
+ finally
+ FreeLibrary(Handle);
+ end;
+end;
+
+procedure FreeUnusedOle;
+begin
+ FreeLibrary(GetModuleHandle('OleAut32'));
+end;
+{$ENDIF !CLR}
+
+function GetEnvVar(const VarName: string): string;
+begin
+ Result := GetEnvironmentVariable(VarName);
+end;
+
+{$ENDIF MSWINDOWS}
+
+{$IFDEF UNIX}
+function GetEnvVar(const VarName: string): string;
+begin
+ Result := getenv(PChar(VarName));
+end;
+{$ENDIF UNIX}
+
+{ Memory routines }
+
+{$IFNDEF CLR}
+function AllocMemo(Size: Longint): Pointer;
+begin
+ if Size > 0 then
+ Result := GlobalAllocPtr(HeapAllocFlags or GMEM_ZEROINIT, Size)
+ else
+ Result := nil;
+end;
+
+function ReallocMemo(fpBlock: Pointer; Size: Longint): Pointer;
+begin
+ Result := GlobalReallocPtr(fpBlock, Size, HeapAllocFlags or GMEM_ZEROINIT);
+end;
+
+procedure FreeMemo(var fpBlock: Pointer);
+begin
+ if fpBlock <> nil then
+ begin
+ GlobalFreePtr(fpBlock);
+ fpBlock := nil;
+ end;
+end;
+
+function GetMemoSize(fpBlock: Pointer): Longint;
+var
+ hMem: THandle;
+begin
+ Result := 0;
+ if fpBlock <> nil then
+ begin
+ hMem := GlobalHandle(fpBlock);
+ if hMem <> 0 then
+ Result := GlobalSize(hMem);
+ end;
+end;
+
+function CompareMem(fpBlock1, fpBlock2: Pointer; Size: Cardinal): Boolean; assembler;
+asm
+ PUSH ESI
+ PUSH EDI
+ MOV ESI,fpBlock1
+ MOV EDI,fpBlock2
+ MOV ECX,Size
+ MOV EDX,ECX
+ XOR EAX,EAX
+ AND EDX,3
+ SHR ECX,2
+ REPE CMPSD
+ JNE @@2
+ MOV ECX,EDX
+ REPE CMPSB
+ JNE @@2
+@@1: INC EAX
+@@2: POP EDI
+ POP ESI
+end;
+{$ENDIF !CLR}
+
+{ Manipulate huge pointers routines by Ray Lischner, The Waite Group, Inc. }
+
+{$IFNDEF CLR}
+procedure HugeInc(var HugePtr: Pointer; Amount: Longint);
+begin
+ HugePtr := PChar(HugePtr) + Amount;
+end;
+
+procedure HugeDec(var HugePtr: Pointer; Amount: Longint);
+begin
+ HugePtr := PChar(HugePtr) - Amount;
+end;
+
+function HugeOffset(HugePtr: Pointer; Amount: Longint): Pointer;
+begin
+ Result := PChar(HugePtr) + Amount;
+end;
+
+procedure HMemCpy(DstPtr, SrcPtr: Pointer; Amount: Longint);
+begin
+ Move(SrcPtr^, DstPtr^, Amount);
+end;
+
+procedure HugeMove(Base: Pointer; Dst, Src, Size: Longint);
+var
+ SrcPtr, DstPtr: PChar;
+begin
+ SrcPtr := PChar(Base) + Src * SizeOf(Pointer);
+ DstPtr := PChar(Base) + Dst * SizeOf(Pointer);
+ Move(SrcPtr^, DstPtr^, Size * SizeOf(Pointer));
+end;
+{$ENDIF !CLR}
+
+{ String routines }
+
+{$IFNDEF CLR}
+{ function GetParamStr copied from SYSTEM.PAS unit of Delphi 2.0 }
+
+function GetParamStr(P: PChar; var Param: string): PChar;
+var
+ Len: Integer;
+ Buffer: array [Byte] of Char;
+begin
+ while True do
+ begin
+ while (P[0] <> #0) and (P[0] <= ' ') do
+ Inc(P);
+ if (P[0] = '"') and (P[1] = '"') then
+ Inc(P, 2)
+ else
+ Break;
+ end;
+ Len := 0;
+ while P[0] > ' ' do
+ if P[0] = '"' then
+ begin
+ Inc(P);
+ while (P[0] <> #0) and (P[0] <> '"') do
+ begin
+ Buffer[Len] := P[0];
+ Inc(Len);
+ Inc(P);
+ end;
+ if P[0] <> #0 then
+ Inc(P);
+ end
+ else
+ begin
+ Buffer[Len] := P[0];
+ Inc(Len);
+ Inc(P);
+ end;
+ SetString(Param, Buffer, Len);
+ Result := P;
+end;
+
+function ParamCountFromCommandLine(CmdLine: PChar): Integer;
+var
+ S: string;
+ P: PChar;
+begin
+ P := CmdLine;
+ Result := 0;
+ while True do
+ begin
+ P := GetParamStr(P, S);
+ if S = '' then
+ Break;
+ Inc(Result);
+ end;
+end;
+
+function ParamStrFromCommandLine(CmdLine: PChar; Index: Integer): string;
+var
+ P: PChar;
+begin
+ P := CmdLine;
+ while True do
+ begin
+ P := GetParamStr(P, Result);
+ if (Index = 0) or (Result = '') then
+ Break;
+ Dec(Index);
+ end;
+end;
+{$ENDIF !CLR}
+
+procedure SplitCommandLine(const CmdLine: string; var ExeName, Params: string);
+{$IFDEF CLR}
+var
+ I, Len: Integer;
+begin
+ ExeName := Trim(CmdLine);
+ Len := Length(ExeName);
+ if Len > 0 then
+ begin
+ if ExeName[1] = '"' then
+ begin
+ I := 2;
+ while (I < Len) do
+ begin
+ if ExeName[I] = '"' then
+ begin
+ if ExeName[I + 1] = '"' then
+ Inc(I)
+ else
+ Break;
+ end;
+ Inc(I);
+ end;
+ end
+ else
+ I := Pos(' ', ExeName);
+
+ if (I = 0) or (I >= Len) then
+ Params := ''
+ else
+ begin
+ Params := Trim(Copy(ExeName, I + 1, MaxInt));
+ Delete(ExeName, I, MaxInt);
+ end;
+ end
+ else
+ Params := '';
+end;
+{$ELSE}
+var
+ Buffer: PChar;
+ Cnt, I: Integer;
+ S: string;
+begin
+ ExeName := '';
+ Params := '';
+ Buffer := StrPAlloc(CmdLine);
+ try
+ Cnt := ParamCountFromCommandLine(Buffer);
+ if Cnt > 0 then
+ begin
+ ExeName := ParamStrFromCommandLine(Buffer, 0);
+ for I := 1 to Cnt - 1 do
+ begin
+ S := ParamStrFromCommandLine(Buffer, I);
+ if Pos(' ', S) > 0 then
+ S := '"' + S + '"';
+ Params := Params + S;
+ if I < Cnt - 1 then
+ Params := Params + ' ';
+ end;
+ end;
+ finally
+ StrDispose(Buffer);
+ end;
+end;
+{$ENDIF CLR}
+
+function AnsiUpperFirstChar(const S: AnsiString): AnsiString;
+var
+ Temp: string[1];
+begin
+ Result := AnsiLowerCase(S);
+ if S <> '' then
+ begin
+ Temp := Result[1];
+ Temp := AnsiUpperCase(Temp);
+ Result[1] := Temp[1];
+ end;
+end;
+
+{$IFNDEF CLR}
+function StrPAlloc(const S: string): PChar;
+begin
+ Result := StrPCopy(StrAlloc(Length(S) + 1), S);
+end;
+
+function StringToPChar(var S: string): PChar;
+begin
+ Result := PChar(S);
+end;
+{$ENDIF !CLR}
+
+function DropT(const S: string): string;
+begin
+ if (UpCase(S[1]) = 'T') and (Length(S) > 1) then
+ Result := Copy(S, 2, MaxInt)
+ else
+ Result := S;
+end;
+
+{$IFNDEF CLR}
+function WindowClassName(Wnd: THandle): string;
+var
+ Buffer: array [0..255] of Char;
+begin
+ SetString(Result, Buffer, GetClassName(Wnd, Buffer, SizeOf(Buffer) - 1));
+end;
+{$ENDIF !CLR}
+
+
+
+function GetAnimation: Boolean;
+var
+ Info: TAnimationInfo;
+begin
+ Info.cbSize := SizeOf(Info);
+ if SystemParametersInfo(SPI_GETANIMATION, Info.cbSize, {$IFNDEF CLR}@{$ENDIF}Info, 0) then
+ Result := Info.iMinAnimate <> 0
+ else
+ Result := False;
+end;
+
+procedure SetAnimation(Value: Boolean);
+var
+ Info: TAnimationInfo;
+begin
+ Info.cbSize := SizeOf(Info);
+ Info.iMinAnimate := Integer(Value);
+ SystemParametersInfo(SPI_SETANIMATION, Info.cbSize, {$IFNDEF CLR}@{$ENDIF}Info, 0);
+end;
+
+procedure ShowWinNoAnimate(Handle: THandle; CmdShow: Integer);
+var
+ Animation: Boolean;
+begin
+ Animation := GetAnimation;
+ if Animation then
+ SetAnimation(False);
+ ShowWindow(Handle, CmdShow);
+ if Animation then
+ SetAnimation(True);
+end;
+
+procedure SwitchToWindow(Wnd: THandle; Restore: Boolean);
+begin
+ if Windows.IsWindowEnabled(Wnd) then
+ begin
+ SetForegroundWindow(Wnd);
+ if Restore and Windows.IsWindowVisible(Wnd) then
+ begin
+ if not IsZoomed(Wnd) then
+ SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+ Windows.SetFocus(Wnd);
+ end;
+ end;
+end;
+
+function GetWindowParent(Wnd: THandle): THandle;
+begin
+ Result := GetWindowLong(Wnd, GWL_HWNDPARENT);
+end;
+
+procedure ActivateWindow(Wnd: THandle);
+begin
+ if Wnd <> 0 then
+ begin
+ ShowWinNoAnimate(Wnd, SW_SHOW);
+ SetForegroundWindow(Wnd);
+ end;
+end;
+
+{$IFNDEF CLR}
+{$IFDEF BCB}
+function FindPrevInstance(const MainFormClass: ShortString;
+ const ATitle: string): THandle;
+{$ELSE}
+function FindPrevInstance(const MainFormClass, ATitle: string): THandle;
+{$ENDIF BCB}
+var
+ BufClass, BufTitle: PChar;
+begin
+ Result := 0;
+ if (MainFormClass = '') and (ATitle = '') then
+ Exit;
+ BufClass := nil;
+ BufTitle := nil;
+ if MainFormClass <> '' then
+ BufClass := StrPAlloc(MainFormClass);
+ if ATitle <> '' then
+ BufTitle := StrPAlloc(ATitle);
+ try
+ Result := FindWindow(BufClass, BufTitle);
+ finally
+ StrDispose(BufTitle);
+ StrDispose(BufClass);
+ end;
+end;
+
+function WindowsEnum(Handle: THandle; Param: Longint): BOOL; export; stdcall;
+begin
+ if WindowClassName(Handle) = 'TAppBuilder' then
+ begin
+ Result := False;
+ PLongint(Param)^ := 1;
+ end
+ else
+ Result := True;
+end;
+
+{$IFDEF BCB}
+function ActivatePrevInstance(const MainFormClass: ShortString;
+ const ATitle: string): Boolean;
+{$ELSE}
+function ActivatePrevInstance(const MainFormClass, ATitle: string): Boolean;
+{$ENDIF BCB}
+var
+ PrevWnd, PopupWnd, ParentWnd: HWND;
+ IsDelphi: Longint;
+begin
+ Result := False;
+ PrevWnd := FindPrevInstance(MainFormClass, ATitle);
+ if PrevWnd <> 0 then
+ begin
+ ParentWnd := GetWindowParent(PrevWnd);
+ while (ParentWnd <> GetDesktopWindow) and (ParentWnd <> 0) do
+ begin
+ PrevWnd := ParentWnd;
+ ParentWnd := GetWindowParent(PrevWnd);
+ end;
+ if WindowClassName(PrevWnd) = 'TApplication' then
+ begin
+ IsDelphi := 0;
+ EnumThreadWindows(GetWindowTask(PrevWnd), @WindowsEnum,
+ LPARAM(@IsDelphi));
+ if Boolean(IsDelphi) then
+ Exit;
+ if IsIconic(PrevWnd) then
+ begin { application is minimized }
+ SendMessage(PrevWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+ Result := True;
+ Exit;
+ end
+ else
+ ShowWinNoAnimate(PrevWnd, SW_SHOWNOACTIVATE);
+ end
+ else
+ ActivateWindow(PrevWnd);
+ PopupWnd := GetLastActivePopup(PrevWnd);
+ if (PrevWnd <> PopupWnd) and Windows.IsWindowVisible(PopupWnd) and
+ Windows.IsWindowEnabled(PopupWnd) then
+ begin
+ SetForegroundWindow(PopupWnd);
+ end
+ else
+ ActivateWindow(PopupWnd);
+ Result := True;
+ end;
+end;
+{$ENDIF !CLR}
+
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+function BrowseForFolderNative(const Handle: THandle; const Title: string; var Folder: string): Boolean;
+var
+ BrowseInfo: TBrowseInfo;
+ Id: PItemIDList;
+ FN: array [0..MAX_PATH] of Char;
+begin
+ with BrowseInfo do
+ begin
+ hwndOwner := Handle;
+ pidlRoot := nil;
+ pszDisplayName := FN;
+ lpszTitle := PChar(Title);
+ ulFlags := 0;
+ lpfn := nil;
+ end;
+ Id := SHBrowseForFolder(BrowseInfo);
+ Result := Id <> nil;
+ if Result then
+ begin
+ SHGetPathFromIDList(Id, FN);
+ Folder := FN;
+ end;
+end;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+procedure FitRectToScreen(var Rect: TRect);
+var
+ X, Y, Delta: Integer;
+begin
+ X := GetSystemMetrics(SM_CXSCREEN);
+ Y := GetSystemMetrics(SM_CYSCREEN);
+ with Rect do
+ begin
+ if Right > X then
+ begin
+ Delta := Right - Left;
+ Right := X;
+ Left := Right - Delta;
+ end;
+ if Left < 0 then
+ begin
+ Delta := Right - Left;
+ Left := 0;
+ Right := Left + Delta;
+ end;
+ if Bottom > Y then
+ begin
+ Delta := Bottom - Top;
+ Bottom := Y;
+ Top := Bottom - Delta;
+ end;
+ if Top < 0 then
+ begin
+ Delta := Bottom - Top;
+ Top := 0;
+ Bottom := Top + Delta;
+ end;
+ end;
+end;
+
+procedure CenterWindow(Wnd: THandle);
+var
+ R: TRect;
+begin
+ GetWindowRect(Wnd, R);
+ R := Rect((GetSystemMetrics(SM_CXSCREEN) - R.Right + R.Left) div 2,
+ (GetSystemMetrics(SM_CYSCREEN) - R.Bottom + R.Top) div 2,
+ R.Right - R.Left, R.Bottom - R.Top);
+ FitRectToScreen(R);
+ SetWindowPos(Wnd, 0, R.Left, R.Top, 0, 0, SWP_NOACTIVATE or
+ SWP_NOSIZE or SWP_NOZORDER);
+end;
+
+
+{ Delete the requested message from the queue, but throw back }
+{ any WM_QUIT msgs that PeekMessage may also return. }
+{ Copied from DbGrid.pas }
+procedure KillMessage(Wnd: THandle; Msg: Cardinal);
+var
+ M: TMsg;
+begin
+ M.Message := 0;
+ if PeekMessage(M, Wnd, Msg, Msg, PM_REMOVE) and (M.Message = WM_QUIT) then
+ PostQuitMessage(M.WParam);
+end;
+
+
+procedure SetWindowTop(const Handle: THandle; const Top: Boolean);
+const
+ TopFlag: array [Boolean] of Longword = (HWND_NOTOPMOST, HWND_TOPMOST);
+begin
+ SetWindowPos(Handle, TopFlag[Top], 0, 0, 0, 0, SWP_NOMOVE or
+ SWP_NOSIZE or SWP_NOACTIVATE);
+end;
+
+function MakeVariant(const Values: array of Variant): Variant;
+begin
+ if High(Values) - Low(Values) > 1 then
+ Result := VarArrayOf(Values)
+ else
+ if High(Values) - Low(Values) = 1 then
+ Result := Values[Low(Values)]
+ else
+ Result := Null;
+end;
+
+{$IFDEF MSWINDOWS}
+{ Dialog units }
+
+function DialogUnitsToPixelsX(DlgUnits: Word): Word;
+begin
+ Result := (DlgUnits * LoWord(GetDialogBaseUnits)) div 4;
+end;
+
+function DialogUnitsToPixelsY(DlgUnits: Word): Word;
+begin
+ Result := (DlgUnits * HiWord(GetDialogBaseUnits)) div 8;
+end;
+
+function PixelsToDialogUnitsX(PixUnits: Word): Word;
+begin
+ Result := PixUnits * 4 div LoWord(GetDialogBaseUnits);
+end;
+
+function PixelsToDialogUnitsY(PixUnits: Word): Word;
+begin
+ Result := PixUnits * 8 div HiWord(GetDialogBaseUnits);
+end;
+
+{$ENDIF MSWINDOWS}
+
+function GetUniqueFileNameInDir(const Path, FileNameMask: string): string;
+var
+ CurrentName: string;
+ I: Integer;
+begin
+ Result := '';
+ for I := 0 to MaxInt do
+ begin
+ CurrentName := SysUtils.Format(FileNameMask, [I]);
+ if not FileExists(NormalDir(Path) + CurrentName) then
+ begin
+ Result := CurrentName;
+ Exit;
+ end;
+ end;
+end;
+
+{$IFNDEF CLR}
+
+procedure AntiAlias(Clip: TBitmap);
+begin
+ AntiAliasRect(Clip, 0, 0, Clip.Width, Clip.Height);
+end;
+
+
+ // (p3) duplicated from JvTypes to avoid JVCL dependencies
+type
+ TJvRGBTriple = packed record
+ rgbBlue: Byte;
+ rgbGreen: Byte;
+ rgbRed: Byte;
+ end;
+
+type
+ PJvRGBArray = ^TJvRGBArray;
+ TJvRGBArray = array [0..32766] of TJvRGBTriple;
+
+
+procedure AntiAliasRect(Clip: TBitmap;
+ XOrigin, YOrigin, XFinal, YFinal: Integer);
+var
+ Tmp, X, Y: Integer;
+ Line0, Line1, Line2: PJvRGBArray;
+ OPF: TPixelFormat;
+begin
+ // swap values
+ if XFinal < XOrigin then
+ begin
+ Tmp := XOrigin;
+ XOrigin := XFinal;
+ XFinal := Tmp;
+ end;
+ if YFinal < YOrigin then
+ begin
+ Tmp := YOrigin;
+ YOrigin := YFinal;
+ YFinal := Tmp;
+ end;
+ XOrigin := Max(1, XOrigin);
+ YOrigin := Max(1, YOrigin);
+ XFinal := Min(Clip.Width - 2, XFinal);
+ YFinal := Min(Clip.Height - 2, YFinal);
+ OPF := Clip.PixelFormat;
+ Clip.PixelFormat := pf24bit;
+ for Y := YOrigin to YFinal do
+ begin
+ Line0 := Clip.ScanLine[Y - 1];
+ Line1 := Clip.ScanLine[Y];
+ Line2 := Clip.ScanLine[Y + 1];
+ for X := XOrigin to XFinal do
+ begin
+ Line1[X].rgbRed := (Line0[X].rgbRed + Line2[X].rgbRed + Line1[X - 1].rgbRed + Line1[X + 1].rgbRed) div 4;
+ Line1[X].rgbGreen := (Line0[X].rgbGreen + Line2[X].rgbGreen + Line1[X - 1].rgbGreen + Line1[X + 1].rgbGreen) div
+ 4;
+ Line1[X].rgbBlue := (Line0[X].rgbBlue + Line2[X].rgbBlue + Line1[X - 1].rgbBlue + Line1[X + 1].rgbBlue) div 4;
+ end;
+ end;
+ Clip.PixelFormat := OPF;
+end;
+
+{$ENDIF !CLR}
+
+
+{$IFNDEF CLR}
+
+procedure CopyRectDIBits(ACanvas: TCanvas; const DestRect: TRect; ABitmap: TBitmap;
+ const SourceRect: TRect);
+var
+ Header, Bits: Pointer;
+ HeaderSize, BitsSize: Cardinal;
+ Bmp: TBitmap;
+begin
+ if ABitmap.PixelFormat < pf15bit then
+ begin
+ Bmp := ABitmap;
+ // this function does not support palettes
+ ABitmap := TBitmap.Create;
+ ABitmap.Assign(Bmp);
+ ABitmap.PixelFormat := pf24bit;
+ end
+ else
+ Bmp := nil;
+ try
+ GetDIBSizes(ABitmap.Handle, HeaderSize, BitsSize);
+ { Do not use Delphi's memory manager. }
+ Header := VirtualAlloc(nil, HeaderSize, MEM_COMMIT, PAGE_READWRITE);
+ Bits := VirtualAlloc(nil, BitsSize, MEM_COMMIT, PAGE_READWRITE);
+ try
+ GetDIB(ABitmap.Handle, ABitmap.Palette, Header^, Bits^);
+ StretchDIBits(ACanvas.Handle,
+ DestRect.Left, DestRect.Top,
+ DestRect.Right - DestRect.Left, DestRect.Bottom - DestRect.Top,
+ SourceRect.Left, SourceRect.Top,
+ SourceRect.Right - SourceRect.Left, SourceRect.Bottom - SourceRect.Top,
+ Bits, TBitmapInfo(Header^),
+ DIB_RGB_COLORS, ACanvas.CopyMode);
+ finally
+ VirtualFree(Bits, 0, MEM_FREE);
+ VirtualFree(Header, 0, MEM_FREE);
+ end;
+ finally
+ if Bmp <> nil then
+ ABitmap.Free;
+ end;
+end;
+{$ENDIF !CLR}
+
+function IsTTFontSelected(const DC: HDC): Boolean;
+var
+ Metrics: TTextMetric;
+begin
+ GetTextMetrics(DC, Metrics);
+ Result := (Metrics.tmPitchAndFamily and TMPF_TRUETYPE) <> 0;
+end;
+
+// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_6rlf.asp
+
+function IsTrueType(const FontName: string): Boolean;
+var
+ Canvas: TCanvas;
+begin
+ Canvas := TCanvas.Create;
+ try
+ Canvas.Handle := GetDC(HWND_DESKTOP);
+ Canvas.Font.Name := FontName;
+ Result := IsTTFontSelected(Canvas.Handle);
+ ReleaseDC(HWND_DESKTOP, Canvas.Handle);
+ Canvas.Handle := NullHandle;
+ finally
+ Canvas.Free;
+ end;
+end;
+
+
+
+function TextToValText(const AValue: string): string;
+var
+ I, J: Integer;
+begin
+ Result := DelRSpace(AValue);
+ if DecimalSeparator <> ThousandSeparator then
+ Result := DelChars(Result, ThousandSeparator{$IFDEF CLR}[1]{$ENDIF});
+
+ if (DecimalSeparator <> '.') and (ThousandSeparator <> '.') then
+ Result := ReplaceStr(Result, '.', DecimalSeparator);
+ if (DecimalSeparator <> ',') and (ThousandSeparator <> ',') then
+ Result := ReplaceStr(Result, ',', DecimalSeparator);
+
+ J := 1;
+ for I := 1 to Length(Result) do
+ if Result[I] in ['0'..'9', '-', '+',
+ AnsiChar(DecimalSeparator{$IFDEF CLR}[1]{$ENDIF}), AnsiChar(ThousandSeparator{$IFDEF CLR}[1]{$ENDIF})] then
+ begin
+ Result[J] := Result[I];
+ Inc(J);
+ end;
+ SetLength(Result, J - 1);
+
+ if Result = '' then
+ Result := '0'
+ else
+ if Result = '-' then
+ Result := '-0';
+end;
+
+******************** NOT CONVERTED *)
+
+function DrawText(Canvas: TCanvas; const Text: string; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+begin
+ Result := DrawText(Canvas, PChar(Text), Len, R, WinFlags and not DT_MODIFYSTRING);
+end;
+
+function DrawText(Canvas: TCanvas; Text: PAnsiChar; Len: Integer; var R: TRect; WinFlags: Integer): Integer;
+begin
+ //TODO: Patch with referenced one by Luiz Americo when GDK used
+ Result := LCLIntf.DrawText(Canvas.Handle, Text, Len, R, WinFlags);
+end;
+
+(******************** NOT CONVERTED
+
+function DrawText(DC: HDC; const Text: TCaption; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+begin
+ {$IFDEF CLR}
+ Result := Windows.DrawText(DC, Text, Len, R, WinFlags and not DT_MODIFYSTRING); // make sure the string cannot be modified
+ {$ELSE}
+ Result := Windows.DrawText(DC, PChar(Text), Len, R, WinFlags and not DT_MODIFYSTRING); // make sure the string cannot be modified
+ {$ENDIF CLR}
+end;
+
+function DrawTextEx(Canvas: TCanvas; const Text: string; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer;
+begin
+ Result := Windows.DrawTextEx(Canvas.Handle, PChar(Text), cchText, p4, dwDTFormat and not DT_MODIFYSTRING, DTParams);
+end;
+
+function DrawTextEx(Canvas: TCanvas; lpchText: PChar; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer;
+begin
+ Result := Windows.DrawTextEx(Canvas.Handle, lpchText, cchText, p4, dwDTFormat, DTParams);
+end;
+
+{$IFDEF COMPILER6_UP}
+
+function DrawText(Canvas: TCanvas; const Text: WideString; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+begin
+ Result := DrawTextW(Canvas, Text, Len, R, WinFlags and not DT_MODIFYSTRING);
+end;
+
+function DrawTextEx(Canvas: TCanvas; const Text: WideString; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer; overload;
+begin
+ Result := DrawTextExW(Canvas, Text, cchText, p4, dwDTFormat and not DT_MODIFYSTRING, DTParams);
+end;
+
+{$ENDIF COMPILER6_UP}
+
+function DrawTextW(Canvas: TCanvas; const Text: WideString; Len: Integer; var R: TRect; WinFlags: Integer): Integer; overload;
+begin
+ Result := DrawTextW(Canvas, PWideChar(Text), Len, R, WinFlags and not DT_MODIFYSTRING);
+end;
+
+function DrawTextW(Canvas: TCanvas; Text: PWideChar; Len: Integer; var R: TRect; WinFlags: Integer): Integer;
+begin
+ Result := Windows.DrawTextW(Canvas.Handle, Text, Len, R, WinFlags);
+end;
+
+function DrawTextExW(Canvas: TCanvas; lpchText: PWideChar; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer;
+begin
+ Result := Windows.DrawTextExW(Canvas.Handle, lpchText, cchText, p4, dwDTFormat, DTParams);
+end;
+
+function DrawTextExW(Canvas: TCanvas; const Text: WideString; cchText: Integer; var p4: TRect; dwDTFormat: UINT; DTParams: PDrawTextParams): Integer;
+begin
+ Result := Windows.DrawTextExW(Canvas.Handle, PWideChar(Text), cchText, p4, dwDTFormat and not DT_MODIFYSTRING, DTParams);
+end;
+
+const
+ // (p3) move to interface?
+ ROP_DSna = $00220326; // RasterOp_NotAndROP
+ {$EXTERNALSYM ROP_DSna}
+ ROP_DSno = MERGEPAINT;
+ {$EXTERNALSYM ROP_DSno}
+ ROP_DPSnoo = PATPAINT;
+ {$EXTERNALSYM ROP_DPSnoo}
+ ROP_D = $00AA0029; // RasterOp_NopROP
+ {$EXTERNALSYM ROP_D}
+ ROP_Dn = DSTINVERT; // DSTINVERT
+ {$EXTERNALSYM ROP_Dn}
+ ROP_SDna = SRCERASE; // SRCERASE
+ {$EXTERNALSYM ROP_SDna}
+ ROP_SDno = $00DD0228; // RasterOp_OrNotROP
+ {$EXTERNALSYM ROP_SDno}
+ ROP_DSan = $007700E6; // RasterOp_NandROP
+ {$EXTERNALSYM ROP_DSan}
+ ROP_DSon = $001100A6; // NOTSRCERASE
+ {$EXTERNALSYM ROP_DSon}
+
+function RasterOpToWinRop(Rop: RasterOp): Cardinal;
+begin
+ case Rop of
+ RasterOp_ClearROP:
+ Result := BLACKNESS;
+ RasterOp_NotROP:
+ Result := DSTINVERT;
+ RasterOp_NotOrROP:
+ Result := MERGEPAINT;
+ RasterOp_NotCopyROP:
+ Result := NOTSRCCOPY;
+ RasterOp_NorROP:
+ Result := NOTSRCERASE;
+ RasterOp_AndROP:
+ Result := SRCAND;
+ RasterOp_CopyROP:
+ Result := SRCCOPY;
+ RasterOp_AndNotROP:
+ Result := SRCERASE;
+ RasterOp_XorROP:
+ Result := SRCINVERT;
+ RasterOp_OrROP:
+ Result := SRCPAINT;
+ RasterOp_SetROP:
+ Result := WHITENESS;
+ RasterOp_NotAndROP:
+ Result := ROP_DSna;
+ RasterOp_NopROP:
+ Result := ROP_D;
+ RasterOp_OrNotROP:
+ Result := ROP_SDno;
+ RasterOp_NandROP:
+ Result := ROP_DSan;
+ else
+ Result := 0;
+ end;
+end;
+
+function BitBlt(DestCanvas: TCanvas; X, Y, Width, Height: Integer; SrcCanvas: TCanvas;
+ XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean = True): LongBool;
+begin
+ // NB! IgnoreMask is not supported in VCL!
+ Result := Windows.BitBlt(DestCanvas.Handle, X, Y, Width, Height, SrcCanvas.Handle,
+ XSrc, YSrc, WinRop);
+end;
+
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
+ XSrc, YSrc: Integer; Rop: RasterOp; IgnoreMask: Boolean): LongBool;
+begin
+ Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, RasterOpToWinRop(Rop));
+end;
+
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
+ XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean): LongBool;
+begin
+ Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, WinRop);
+end;
+
+function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; WinRop: Cardinal): LongBool;
+begin
+ Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, WinRop);
+end;
+
+
+
+
+
+function IsEqualGUID(const IID1, IID2: TGUID): Boolean;
+begin
+ {$IFDEF COMPILER5}
+ Result := CompareMem(@IID1, @IID2, SizeOf(IID1));
+ {$ELSE}
+ Result := SysUtils.IsEqualGUID(IID1, IID2);
+ {$ENDIF COMPILER5}
+end;
+
+{Color functions}
+procedure RGBToHSV(R, G, B: Integer; var H, S, V: Integer);
+
+var
+ Delta: Integer;
+ Min, Max: Integer;
+
+ function GetMax(I, J, K: Integer): Integer;
+ begin
+ if J > I then
+ I := J;
+ if K > I then
+ I := K;
+ Result := I;
+ end;
+
+ function GetMin(I, J, K: Integer): Integer;
+ begin
+ if J < I then
+ I := J;
+ if K < I then
+ I := K;
+ Result := I;
+ end;
+
+
+begin
+ Min := GetMin(R, G, B);
+ Max := GetMax(R, G, B);
+ V := Max;
+ Delta := Max - Min;
+ if Max = 0 then
+ S := 0
+ else
+ S := (255 * Delta) div Max;
+ if S = 0 then
+ H := 0
+ else
+ begin
+ if R = Max then
+ H := (60 * (G - B)) div Delta
+ else
+ if G = Max then
+ H := 120 + (60 * (B - R)) div Delta
+ else
+ H := 240 + (60 * (R - G)) div Delta;
+ if H < 0 then
+ H := H + 360;
+ end;
+end;
+
+function RGBToBGR(Value: Cardinal): Cardinal;
+begin
+ Result :=
+ ((Value and $00FF0000) shr 16) or
+ (Value and $0000FF00) or
+ ((Value and $000000FF) shl 16);
+end;
+
+function ColorToPrettyName(Value: TColor): string;
+var
+ Index: Integer;
+begin
+ for Index := Low(ColorValues) to High(ColorValues) do
+ if Value = ColorValues[Index].Value then
+ begin
+ Result := ColorValues[Index].Description;
+ Exit;
+ end;
+ for Index := Low(StandardColorValues) to High(StandardColorValues) do
+ if Value = StandardColorValues[Index].Value then
+ begin
+ Result := StandardColorValues[Index].Description;
+ Exit;
+ end;
+ for Index := Low(SysColorValues) to High(SysColorValues) do
+ if Value = SysColorValues[Index].Value then
+ begin
+ Result := SysColorValues[Index].Description;
+ Exit;
+ end;
+ Result := ColorToString(Value);
+end;
+
+function PrettyNameToColor(const Value: string): TColor;
+var
+ Index: Integer;
+ ColorResult: Integer;
+begin
+ for Index := Low(ColorValues) to High(ColorValues) do
+ begin
+ if CompareText(Value, ColorValues[Index].Description) = 0 then
+ begin
+ Result := ColorValues[Index].Value;
+ Exit;
+ end;
+ end;
+ for Index := Low(StandardColorValues) to High(StandardColorValues) do
+ begin
+ if CompareText(Value, StandardColorValues[Index].Description) = 0 then
+ begin
+ Result := StandardColorValues[Index].Value;
+ Exit;
+ end;
+ end;
+ for Index := Low(SysColorValues) to High(SysColorValues) do
+ begin
+ if CompareText(Value, SysColorValues[Index].Description) = 0 then
+ begin
+ Result := SysColorValues[Index].Value;
+ Exit;
+ end;
+ end;
+ if IdentToColor(Value, ColorResult) then
+ Result := ColorResult
+ else
+ Result := clNone;
+end;
+
+{$IFNDEF CLR}
+function StartsText(const SubStr, S: string): Boolean;
+begin
+ Result := AnsiStartsText(SubStr, S);
+end;
+
+function EndsText(const SubStr, S: string): Boolean;
+begin
+ Result := AnsiEndsText(SubStr, S);
+end;
+
+function DequotedStr(const S: string; QuoteChar: Char = ''''): string;
+begin
+ Result := AnsiDequotedStr(S, QuoteChar);
+end;
+
+function AnsiDequotedStr(const S: AnsiString; AQuote: AnsiChar): AnsiString;
+var
+ P: PChar;
+begin
+ P := PChar(S);
+ Result := AnsiExtractQuotedStr(P, AQuote);
+end;
+{$ENDIF !CLR}
+
+{$IFNDEF BCB}
+{$IFDEF COMPILER5}
+{ These functions simply call their JvVCL5Utils equivalents }
+
+function TryStrToInt(const S: string; out Value: Integer): Boolean;
+begin
+ Result := JvVCL5Utils.TryStrToInt(S, Value);
+end;
+
+function TryStrToDateTime(const S: string; out Date: TDateTime): Boolean;
+begin
+ Result := JvVCL5Utils.TryStrToDateTime(S, Date);
+end;
+
+function StrToDateTimeDef(const S: string; Default: TDateTime): TDateTime;
+begin
+ Result := JvVCL5Utils.StrToDateTimeDef(S, Default);
+end;
+
+// function StrToFloatDef(const Str: string; Default: Extended): Extended;
+procedure RaiseLastOSError;
+begin
+ JvVCL5Utils.RaiseLastOSError;
+end;
+
+function IncludeTrailingPathDelimiter(const APath: string): string;
+begin
+ Result := JvVCL5Utils.IncludeTrailingPathDelimiter(APath);
+end;
+
+function ExcludeTrailingPathDelimiter(const APath: string): string;
+begin
+ Result := JvVCL5Utils.ExcludeTrailingPathDelimiter(APath);
+end;
+
+function DirectoryExists(const Name: string): Boolean;
+begin
+ Result := JvVCL5Utils.DirectoryExists(Name);
+end;
+
+function ForceDirectories(Dir: string): Boolean;
+begin
+ Result := JvVCL5Utils.ForceDirectories(Dir);
+end;
+
+function SameFileName(const FN1, FN2: string): Boolean;
+begin
+ Result := JvVCL5Utils.SameFileName(FN1, FN2);
+end;
+
+function WideCompareText(const S1, S2: WideString): Integer;
+begin
+ Result := JvVCL5Utils.WideCompareText(S1, S2);
+end;
+
+function WideUpperCase(const S: WideString): WideString;
+begin
+ Result := JvVCL5Utils.WideUpperCase(S);
+end;
+
+function WideLowerCase(const S: WideString): WideString;
+begin
+ Result := JvVCL5Utils.WideLowerCase(S);
+end;
+
+function CompareDateTime(const A, B: TDateTime): Integer;
+begin
+ Result := JvVCL5Utils.CompareDateTime(A, B);
+end;
+
+// StrUtils
+function AnsiStartsText(const SubText, Text: string): Boolean;
+begin
+ Result := JvVCL5Utils.AnsiStartsText(SubText, Text);
+end;
+
+function AnsiEndsText(const SubText, Text: string): Boolean;
+begin
+ Result := JvVCL5Utils.AnsiEndsText(SubText, Text);
+end;
+
+function AnsiStartsStr(const SubStr, Str: string): Boolean;
+begin
+ Result := JvVCL5Utils.AnsiStartsStr(SubStr, Str);
+end;
+
+function AnsiEndsStr(const SubStr, Str: string): Boolean;
+begin
+ Result := JvVCL5Utils.AnsiEndsStr(SubStr, Str);
+end;
+
+// Variants
+function VarIsStr(const V: Variant): Boolean;
+begin
+ Result := JvVCL5Utils.VarIsStr(V);
+end;
+
+{$ENDIF COMPILER5}
+{$ENDIF !BCB}
+
+procedure CollectionQuickSort(List: Classes.TCollection; L, R: Integer; SortProc: TCollectionSortProc);
+var
+ I, J, pix: Integer;
+ P, t1, t2: TCollectionItem;
+begin
+ List.BeginUpdate;
+ repeat
+ I := L;
+ J := R;
+ pix := (L+R) shr 1;
+ if pix > List.Count - 1 then
+ pix := List.Count - 1;
+ P := List.Items[pix];
+
+ repeat
+ while SortProc(List.Items[I], P) < 0 do
+ Inc(I);
+ while SortProc(List.Items[J], P) > 0 do
+ Dec(J);
+
+ if I <= J then
+ begin
+ t1 := List.Items[I];
+ t2 := List.Items[J];
+ t1.Index := J;
+ t2.Index := I;
+
+ if pix = I then
+ pix := J
+ else
+ if pix = J then
+ pix := I;
+
+ P := List.Items[pix];
+ Inc(I);
+ Dec(J);
+ end;
+ until I > J;
+ if L < J then
+ CollectionQuickSort(List, L, J, SortProc);
+ L := I;
+ until I >= R;
+ List.EndUpdate;
+end;
+
+procedure CollectionSort(Collection: Classes.TCollection; SortProc: TCollectionSortProc);
+begin
+ if Assigned(Collection) and Assigned(SortProc) and (Collection.Count >= 2) then
+ CollectionQuickSort(Collection, 0, Collection.Count - 1, SortProc);
+end;
+
+{$IFDEF COMPILER5}
+function SecondsBetween(const Now: TDateTime; const FTime: TDateTime): Integer;
+begin
+ Result := Trunc(86400 * (FTime - Now));
+end;
+{$ENDIF COMPILER5}
+
+{ TIntegerList }
+
+function TIntegerList.Add(Value: Integer): Integer;
+begin
+ Result := inherited Add(Pointer(Value));
+end;
+
+{$IFDEF COMPILER5}
+procedure TIntegerList.Assign(Source: TList);
+var
+ I: Integer;
+begin
+ Clear;
+ Capacity := Source.Count;
+ for I := 0 to Source.Count - 1 do
+ Add(Integer(Source[I]));
+end;
+{$ENDIF COMPILER5}
+
+procedure TIntegerList.DoChange(Item: Integer; Action: TListNotification);
+begin
+ if Assigned(OnChange) then
+ OnChange(Self, Item, Action);
+end;
+
+function TIntegerList.Extract(Item: Integer): Integer;
+begin
+ Result := Integer(inherited Extract(Pointer(Item)));
+end;
+
+function TIntegerList.First: Integer;
+begin
+ Result := Integer(inherited First);
+end;
+
+function TIntegerList.GetItem(Index: Integer): Integer;
+begin
+ Result := Integer(inherited Items[Index]);
+end;
+
+function TIntegerList.IndexOf(Item: Integer): Integer;
+begin
+ Result := inherited IndexOf(Pointer(Item));
+end;
+
+procedure TIntegerList.Insert(Index, Item: Integer);
+begin
+ inherited Insert(Index, Pointer(Item));
+end;
+
+function TIntegerList.Last: Integer;
+begin
+ Result := Integer(inherited Last);
+end;
+
+procedure TIntegerList.Notify(Ptr: Pointer; Action: TListNotification);
+begin
+ DoChange(Integer(Ptr), Action);
+end;
+
+procedure TIntegerList.ReadData(Reader: TReader);
+begin
+ FLoading := True;
+ try
+ Clear;
+ Reader.ReadListBegin;
+ while not Reader.EndOfList do
+ begin
+ Add(Reader.ReadInteger);
+ end;
+ Reader.ReadListEnd;
+ finally
+ FLoading := False;
+ end;
+end;
+
+function TIntegerList.Remove(Item: Integer): Integer;
+begin
+ Result := Integer(inherited Remove(Pointer(Item)));
+end;
+
+procedure TIntegerList.SetItem(Index: Integer; const Value: Integer);
+begin
+ inherited Items[Index] := Pointer(Value);
+end;
+
+procedure TIntegerList.WriteData(Writer: TWriter);
+var
+ I: Integer;
+begin
+ Writer.WriteListBegin;
+ for I := 0 to Count - 1 do
+ Writer.WriteInteger(Items[I]);
+ Writer.WriteListEnd;
+end;
+
+******************** NOT CONVERTED *)
+
+end.
+
+
diff --git a/components/jvcllaz/run/JvJVCLUtils.pas b/components/jvcllaz/run/JvJVCLUtils.pas
new file mode 100644
index 000000000..828bbc95e
--- /dev/null
+++ b/components/jvcllaz/run/JvJVCLUtils.pas
@@ -0,0 +1,7694 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvJVCLUtils.PAS, released on 2002-09-24.
+
+The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
+Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
+Copyright (c) 2001,2002 SGB Software
+All Rights Reserved.
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvJVCLUtils.pas 11413 2007-07-11 20:23:46Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvJVCLUtils;
+
+interface
+uses
+ Classes, Graphics, JvTypes;
+
+(******************** NOT CONVERTED
+// Transform an icon to a bitmap
+function IconToBitmap(Ico: HICON): TBitmap;
+// Transform an icon to a bitmap using an image list
+function IconToBitmap2(Ico: HICON; Size: Integer = 32;
+ TransparentColor: TColor = clNone): TBitmap;
+function IconToBitmap3(Ico: HICON; Size: Integer = 32;
+ TransparentColor: TColor = clNone): TBitmap;
+
+// bitmap manipulation functions
+// NOTE: Dest bitmap must be freed by caller!
+// get red channel bitmap
+procedure GetRBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get green channel bitmap
+procedure GetGBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get blue channel bitmap
+procedure GetBBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get monochrome bitmap
+procedure GetMonochromeBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get hue bitmap (h part of hsv)
+procedure GetHueBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get saturation bitmap (s part of hsv)
+procedure GetSaturationBitmap(var Dest: TBitmap; const Source: TBitmap);
+// get value bitmap (V part of HSV)
+procedure GetValueBitmap(var Dest: TBitmap; const Source: TBitmap);
+
+// hides / shows the a forms caption area
+procedure HideFormCaption(FormHandle: THandle; Hide: Boolean);
+
+{$IFDEF MSWINDOWS}
+
+type
+ TJvWallpaperStyle = (wpTile, wpCenter, wpStretch);
+
+// set the background wallpaper (two versions)
+{$IFNDEF CLR}
+procedure SetWallpaper(const Path: string); overload;
+{$ENDIF !CLR}
+procedure SetWallpaper(const Path: string; Style: TJvWallpaperStyle); overload;
+
+(-* (rom) to be deleted. Use ScreenShot from JCL
+{$IFDEF VCL}
+// screen capture functions
+function CaptureScreen(IncludeTaskBar: Boolean = True): TBitmap; overload;
+function CaptureScreen(Rec: TRect): TBitmap; overload;
+function CaptureScreen(WndHandle: Longword): TBitmap; overload;
+{$ENDIF VCL}
+*-)
+
+{$ENDIF MSWINDOWS}
+
+procedure RGBToHSV(R, G, B: Integer; var H, S, V: Integer);
+
+{ from JvVCLUtils }
+
+procedure CopyParentImage(Control: TControl; Dest: TCanvas);
+{ Windows resources (bitmaps and icons) VCL-oriented routines }
+procedure DrawBitmapTransparent(Dest: TCanvas; DstX, DstY: Integer;
+ Bitmap: TBitmap; TransparentColor: TColor);
+procedure DrawBitmapRectTransparent(Dest: TCanvas; DstX, DstY: Integer;
+ SrcRect: TRect; Bitmap: TBitmap; TransparentColor: TColor);
+procedure StretchBitmapRectTransparent(Dest: TCanvas; DstX, DstY, DstW,
+ DstH: Integer; SrcRect: TRect; Bitmap: TBitmap; TransparentColor: TColor);
+{$IFNDEF CLR}
+function MakeBitmap(ResID: PChar): TBitmap;
+function MakeBitmapID(ResID: Word): TBitmap;
+function MakeModuleBitmap(Module: THandle; ResID: PChar): TBitmap;
+{$ENDIF !CLR}
+function CreateTwoColorsBrushPattern(Color1, Color2: TColor): TBitmap;
+function CreateDisabledBitmap_NewStyle(FOriginal: TBitmap; BackColor: TColor):
+ TBitmap;
+function CreateDisabledBitmapEx(FOriginal: TBitmap; OutlineColor, BackColor,
+ HighLightColor, ShadowColor: TColor; DrawHighlight: Boolean): TBitmap;
+function CreateDisabledBitmap(FOriginal: TBitmap; OutlineColor: TColor):
+ TBitmap;
+procedure AssignBitmapCell(Source: TGraphic; Dest: TBitmap; Cols, Rows,
+ Index: Integer);
+function ChangeBitmapColor(Bitmap: TBitmap; Color, NewColor: TColor): TBitmap;
+procedure ImageListDrawDisabled(Images: TCustomImageList; Canvas: TCanvas;
+ X, Y, Index: Integer; HighLightColor, GrayColor: TColor;
+ DrawHighlight: Boolean);
+
+{$IFNDEF CLR}
+function MakeIcon(ResID: PChar): TIcon;
+function MakeIconID(ResID: Word): TIcon;
+function MakeModuleIcon(Module: THandle; ResID: PChar): TIcon;
+{$ENDIF !CLR}
+function CreateBitmapFromIcon(Icon: TIcon; BackColor: TColor): TBitmap;
+function CreateIconFromBitmap(Bitmap: TBitmap; TransparentColor: TColor): TIcon;
+function CreateRotatedFont(Font: TFont; Angle: Integer): HFONT;
+
+{$IFNDEF CLR}
+// launches the specified CPL file
+// format: [,@n] or [,,m] or [,@n,m]
+// where @n = zero-based index of the applet to start (if there is more than one
+// m is the zero-based index of the tab to display
+
+procedure LaunchCpl(const FileName: string);
+
+// for Win 2000 and XP
+procedure ShowSafeRemovalDialog;
+
+{
+ GetControlPanelApplets retrieves information about all control panel applets in a specified folder.
+ APath is the Path to the folder to search and AMask is the filename mask (containing wildcards if necessary) to use.
+
+ The information is returned in the Strings and Images lists according to the following rules:
+ The Display Name and Path to the CPL file is returned in Strings with the following format:
+ '='
+ You can access the DisplayName by using the Strings.Names array and the Path by accessing the Strings.Values array
+ Strings.Objects can contain either of two values depending on if Images is nil or not:
+ * If Images is nil then Strings.Objects contains the image for the applet as a TBitmap. Note that the caller (you)
+ is responsible for freeing the bitmaps in this case
+ * If Images <> nil, then the Strings.Objects array contains the index of the image in the Images array for the selected item.
+ To access and use the ImageIndex, typecast Strings.Objects to an int:
+ Tmp.Name := Strings.Name[I];
+ Tmp.ImageIndex := Integer(Strings.Objects[I]);
+ The function returns True if any Control Panel Applets were found (i.e Strings.Count is > 0 when returning)
+}
+
+function GetControlPanelApplets(const APath, AMask: string; Strings: TStrings;
+ Images: TCustomImageList = nil): Boolean;
+{ GetControlPanelApplet works like GetControlPanelApplets, with the difference that it only loads and searches one cpl file (according to AFilename).
+ Note though, that some CPL's contains multiple applets, so the Strings and Images lists can contain multiple return values.
+ The function returns True if any Control Panel Applets were found in AFilename (i.e if items were added to Strings)
+}
+function GetControlPanelApplet(const AFileName: string; Strings: TStrings;
+ Images: TCustomImageList = nil): Boolean;
+
+{$ENDIF !CLR}
+
+function PointInPolyRgn(const P: TPoint; const Points: array of TPoint): Boolean;
+function PaletteColor(Color: TColor): Longint;
+procedure PaintInverseRect(const RectOrg, RectEnd: TPoint);
+procedure DrawInvertFrame(ScreenRect: TRect; Width: Integer);
+
+procedure ShowMDIClientEdge(ClientHandle: THandle; ShowEdge: Boolean);
+
+function GetTickCount64: Int64;
+procedure Delay(MSecs: Int64);
+procedure CenterControl(Control: TControl);
+
+procedure MergeForm(AControl: TWinControl; AForm: TForm; Align: TAlign;
+ Show: Boolean);
+function GetAveCharSize(Canvas: TCanvas): TPoint;
+******************** NOT CONVERTED *)
+
+{ Gradient filling routine }
+
+type
+ TFillDirection = (fdTopToBottom, fdBottomToTop, fdLeftToRight, fdRightToLeft);
+
+procedure GradientFillRect(Canvas: TCanvas; ARect: TRect; StartColor,
+ EndColor: TColor; Direction: TFillDirection; Colors: Byte);
+
+(******************** NOT CONVERTED
+procedure StartWait;
+procedure StopWait;
+{$IFNDEF CLR}
+function DefineCursor(Instance: THandle; ResID: PChar): TCursor;
+{$ENDIF !CLR}
+function GetNextFreeCursorIndex(StartHint: Integer; PreDefined: Boolean):
+ Integer;
+function WaitCursor: IInterface;
+function ScreenCursor(ACursor: TCursor): IInterface;
+{$IFDEF MSWINDOWS}
+// loads the more modern looking drag cursors from OLE32.DLL
+function LoadOLEDragCursors: Boolean;
+// set some default cursor from JVCL
+{$ENDIF MSWINDOWS}
+procedure SetDefaultJVCLCursors;
+
+{$IFNDEF CLR}
+function LoadAniCursor(Instance: THandle; ResID: PChar): HCURSOR;
+{$ENDIF !CLR}
+
+{ Windows API level routines }
+
+procedure StretchBltTransparent(DstDC: HDC; DstX, DstY, DstW, DstH: Integer;
+ SrcDC: HDC; SrcX, SrcY, SrcW, Srch: Integer;
+ Palette: HPALETTE; TransparentColor: TColorRef);
+procedure DrawTransparentBitmap(DC: HDC; Bitmap: HBITMAP;
+ DstX, DstY: Integer; TransparentColor: TColorRef);
+function PaletteEntries(Palette: HPALETTE): Integer;
+procedure ShadeRect(DC: HDC; const Rect: TRect);
+
+function ScreenWorkArea: TRect;
+
+{ Grid drawing }
+
+type
+ TVertAlignment = (vaTopJustify, vaCenterJustify, vaBottomJustify);
+
+procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer;
+ const Text: string; Alignment: TAlignment; WordWrap: Boolean; ARightToLeft:
+ Boolean = False);
+procedure DrawCellText(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment); overload;
+procedure DrawCellTextEx(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; WordWrap: Boolean); overload;
+procedure DrawCellText(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; ARightToLeft: Boolean); overload;
+procedure DrawCellTextEx(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; WordWrap: Boolean; ARightToLeft: Boolean);
+overload;
+procedure DrawCellBitmap(Control: TCustomControl; ACol, ARow: Longint;
+ Bmp: TGraphic; Rect: TRect);
+
+type
+ TJvDesktopCanvas = class(TCanvas)
+ private
+ FDC: HDC;
+ protected
+ procedure CreateHandle; override;
+ public
+ destructor Destroy; override;
+ procedure SetOrigin(X, Y: Integer);
+ procedure FreeHandle;
+ end;
+
+ { end from JvVCLUtils }
+
+ { begin JvUtils }
+ {**** other routines - }
+ { FindByTag returns the control with specified class,
+ ComponentClass, from WinContol.Controls property,
+ having Tag property value, equaled to Tag parameter }
+function FindByTag(WinControl: TWinControl; ComponentClass: TComponentClass;
+ const Tag: Integer): TComponent;
+{ ControlAtPos2 equal to TWinControl.ControlAtPos function,
+ but works better }
+function ControlAtPos2(Parent: TWinControl; X, Y: Integer): TControl;
+{ RBTag searches WinControl.Controls for checked
+ RadioButton and returns its Tag property value }
+function RBTag(Parent: TWinControl): Integer;
+{ FindFormByClass returns first form with specified
+ class, FormClass, owned by Application global variable }
+function FindFormByClass(FormClass: TFormClass): TForm;
+function FindFormByClassName(const FormClassName: string): TForm;
+{ AppMinimized returns True, if Application is minimized }
+function AppMinimized: Boolean;
+function IsForegroundTask: Boolean;
+
+{ MessageBox is Application.MessageBox with string (not PChar) parameters.
+ if Caption parameter = '', it replaced with Application.Title }
+function MessageBox(const Msg, Caption: string; const Flags: Integer): Integer;
+function MsgBox(const Caption, Text: string; Flags: Integer): Integer; overload;
+function MsgBox(Handle: THandle; const Caption, Text: string; Flags: Integer): Integer; overload;
+function MsgDlg(const Msg: string; AType: TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
+function MsgDlg2(const Msg, ACaption: string; DlgType: TMsgDlgType;
+ Buttons: TMsgDlgButtons; HelpContext: Integer; Control: TWinControl): Integer;
+function MsgDlgDef(const Msg, ACaption: string; DlgType: TMsgDlgType;
+ Buttons: TMsgDlgButtons; DefButton: TMsgDlgBtn; HelpContext: Integer;
+ Control: TWinControl): Integer;
+
+(-***** Utility MessageBox based dialogs *-)
+// returns True if user clicked Yes
+function MsgYesNo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+// returns True if user clicked Retry
+function MsgRetryCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+// returns IDABORT, IDRETRY or IDIGNORE
+function MsgAbortRetryIgnore(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer;
+// returns IDYES, IDNO or IDCANCEL
+function MsgYesNoCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer;
+// returns True if user clicked OK
+function MsgOKCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+
+// dialog without icon
+procedure MsgOK(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+// dialog with info icon
+procedure MsgInfo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+// dialog with warning icon
+procedure MsgWarn(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+// dialog with question icon
+procedure MsgQuestion(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+// dialog with error icon
+procedure MsgError(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+// dialog with custom icon (must be available in the app resource)
+procedure MsgAbout(Handle: Integer; const Msg, Caption: string; const IcoName: string = 'MAINICON'; Flags: DWORD = MB_OK);
+
+{**** Windows routines }
+
+{ LoadIcoToImage loads two icons from resource named NameRes,
+ into two image lists ALarge and ASmall}
+procedure LoadIcoToImage(ALarge, ASmall: ImgList.TCustomImageList;
+ const NameRes: string);
+
+{ Works like InputQuery but displays 2 edits. If PasswordChar <> #0, the second edit's PasswordChar is set }
+function DualInputQuery(const ACaption, Prompt1, Prompt2: string;
+ var AValue1, AValue2: string; PasswordChar: Char = #0): Boolean;
+
+{ Works like InputQuery but set the edit's PasswordChar to PasswordChar. If PasswordChar = #0, works exactly like InputQuery }
+function InputQueryPassword(const ACaption, APrompt: string; PasswordChar: Char; var Value: string): Boolean;
+
+{ returns the sum of pc.Left, pc.Width and piSpace}
+function ToRightOf(const pc: TControl; piSpace: Integer = 0): Integer;
+{ sets the top of pc to be in the middle of pcParent }
+procedure CenterHeight(const pc, pcParent: TControl);
+procedure CenterHor(Parent: TControl; MinLeft: Integer; Controls: array of TControl);
+procedure EnableControls(Control: TWinControl; const Enable: Boolean);
+procedure EnableMenuItems(MenuItem: TMenuItem; const Tag: Integer; const Enable: Boolean);
+procedure ExpandWidth(Parent: TControl; MinWidth: Integer; Controls: array of TControl);
+function PanelBorder(Panel: TCustomPanel): Integer;
+function Pixels(Control: TControl; APixels: Integer): Integer;
+
+type
+ TMenuAnimation = (maNone, maRandom, maUnfold, maSlide);
+
+procedure ShowMenu(Form: TForm; MenuAni: TMenuAnimation);
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+{ TargetFileName - if FileName is ShortCut returns filename ShortCut linked to }
+function TargetFileName(const FileName: TFileName): TFileName;
+{ return filename ShortCut linked to }
+function ResolveLink(const HWND: THandle; const LinkFile: TFileName;
+ var FileName: TFileName): HRESULT;
+{$ENDIF MSWINDOWS}
+
+type
+ TProcObj = procedure of object;
+
+procedure ExecAfterPause(Proc: TProcObj; Pause: Integer);
+{$ENDIF !CLR}
+
+{ end JvUtils }
+
+{ begin JvAppUtils}
+function GetFirstParentForm(Control: TControl): TCustomForm;
+function GetDefaultSection(Component: TComponent): string;
+function GetDefaultIniName: string;
+
+type
+ TOnGetDefaultIniName = function: string;
+ TPlacementOption = (fpState, fpSize, fpLocation, fpActiveControl);
+ TPlacementOptions = set of TPlacementOption;
+ TPlacementOperation = (poSave, poRestore);
+
+var
+ OnGetDefaultIniName: TOnGetDefaultIniName = nil;
+ DefCompanyName: string = '';
+ RegUseAppTitle: Boolean = False;
+
+function GetDefaultIniRegKey: string;
+function FindForm(FormClass: TFormClass): TForm;
+function FindShowForm(FormClass: TFormClass; const Caption: string): TForm;
+function ShowDialog(FormClass: TFormClass): Boolean;
+function InstantiateForm(FormClass: TFormClass; var Reference): TForm;
+
+procedure SaveFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage; Options: TPlacementOptions);
+procedure RestoreFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage; Options: TPlacementOptions);
+
+procedure SaveMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage);
+procedure RestoreMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage);
+procedure RestoreGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage);
+procedure SaveGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage);
+
+function StrToIniStr(const Str: string): string;
+function IniStrToStr(const Str: string): string;
+
+// Ini Utilitie Functions
+// Added by RDB
+
+function FontStylesToString(Styles: TFontStyles): string;
+function StringToFontStyles(const Styles: string): TFontStyles;
+
+function FontToString(Font: TFont): string;
+function StringToFont(const Str: string): TFont;
+
+function RectToStr(Rect: TRect): string;
+function StrToRect(const Str: string; const Def: TRect): TRect;
+function PointToStr(P: TPoint): string;
+function StrToPoint(const Str: string; const Def: TPoint): TPoint;
+
+{
+function IniReadString(IniFile: TObject; const Section, Ident,
+ Default: string): string;
+procedure IniWriteString(IniFile: TObject; const Section, Ident,
+ Value: string);
+function IniReadInteger(IniFile: TObject; const Section, Ident: string;
+ Default: Longint): Longint;
+procedure IniWriteInteger(IniFile: TObject; const Section, Ident: string;
+ Value: Longint);
+function IniReadBool(IniFile: TObject; const Section, Ident: string;
+ Default: Boolean): Boolean;
+procedure IniWriteBool(IniFile: TObject; const Section, Ident: string;
+ Value: Boolean);
+procedure IniReadSections(IniFile: TObject; Strings: TStrings);
+procedure IniEraseSection(IniFile: TObject; const Section: string);
+procedure IniDeleteKey(IniFile: TObject; const Section, Ident: string);
+}
+
+procedure AppBroadcast(Msg, wParam: Longint; lParam: Longint);
+procedure AppTaskbarIcons(AppOnly: Boolean);
+
+{ Internal using utilities }
+
+procedure InternalSaveFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage;
+ const StorePath: string; Options: TPlacementOptions = [fpState, fpSize, fpLocation]);
+procedure InternalRestoreFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage;
+ const StorePath: string; Options: TPlacementOptions = [fpState, fpSize, fpLocation]);
+procedure InternalSaveGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage; const StorePath: string);
+procedure InternalRestoreGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage; const StorePath: string);
+procedure InternalSaveMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage; const StorePath: string);
+procedure InternalRestoreMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage; const StorePath: string);
+
+{ end JvAppUtils }
+{ begin JvGraph }
+type
+ TMappingMethod = (mmHistogram, mmQuantize, mmTrunc784, mmTrunc666,
+ mmTripel, mmGrayscale);
+
+function GetBitmapPixelFormat(Bitmap: TBitmap): TPixelFormat;
+
+function GetPaletteBitmapFormat(Bitmap: TBitmap): TPixelFormat;
+{$IFNDEF CLR}
+procedure SetBitmapPixelFormat(Bitmap: TBitmap; PixelFormat: TPixelFormat;
+ Method: TMappingMethod);
+function BitmapToMemoryStream(Bitmap: TBitmap; PixelFormat: TPixelFormat;
+ Method: TMappingMethod): TMemoryStream;
+procedure GrayscaleBitmap(Bitmap: TBitmap);
+
+function BitmapToMemory(Bitmap: TBitmap; Colors: Integer): TStream;
+procedure SaveBitmapToFile(const FileName: string; Bitmap: TBitmap;
+ Colors: Integer);
+{$ENDIF !CLR}
+
+function ScreenPixelFormat: TPixelFormat;
+function ScreenColorCount: Integer;
+
+var
+ DefaultMappingMethod: TMappingMethod = mmHistogram;
+
+function GetWorkareaRect(Monitor: TMonitor): TRect;
+function FindMonitor(Handle: HMONITOR): TMonitor;
+
+procedure TileImage(Canvas: TCanvas; Rect: TRect; Image: TGraphic);
+function ZoomImage(ImageW, ImageH, MaxW, MaxH: Integer; Stretch: Boolean): TPoint;
+
+type
+ TJvGradientOptions = class(TPersistent)
+ private
+ FStartColor: TColor;
+ FEndColor: TColor;
+ FDirection: TFillDirection;
+ FStepCount: Byte;
+ FVisible: Boolean;
+ FOnChange: TNotifyEvent;
+ procedure SetStartColor(Value: TColor);
+ procedure SetEndColor(Value: TColor);
+ procedure SetDirection(Value: TFillDirection);
+ procedure SetStepCount(Value: Byte);
+ procedure SetVisible(Value: Boolean);
+ protected
+ procedure Changed; dynamic;
+ public
+ constructor Create;
+ procedure Assign(Source: TPersistent); override;
+ procedure Draw(Canvas: TCanvas; Rect: TRect);
+ published
+ property Direction: TFillDirection read FDirection write SetDirection default fdTopToBottom;
+ property EndColor: TColor read FEndColor write SetEndColor default clGray;
+ property StartColor: TColor read FStartColor write SetStartColor default clSilver;
+ property StepCount: Byte read FStepCount write SetStepCount default 64;
+ property Visible: Boolean read FVisible write SetVisible default False;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+{ end JvGraph }
+
+type
+ // equivalent of TPoint, but that can be a published property
+ TJvPoint = class(TPersistent)
+ private
+ FY: Longint;
+ FX: Longint;
+ FOnChange: TNotifyEvent;
+ procedure SetX(Value: Longint);
+ procedure SetY(Value: Longint);
+ protected
+ procedure DoChange;
+ public
+ procedure Assign(Source: TPersistent); overload; override;
+ procedure Assign(Source: TPoint); reintroduce; overload;
+ procedure CopyToPoint(var Point: TPoint);
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ published
+ property X: Longint read FX write SetX default 0;
+ property Y: Longint read FY write SetY default 0;
+ end;
+
+ // equivalent of TRect, but that can be a published property
+ TJvRect = class(TPersistent)
+ private
+ FTopLeft: TJvPoint;
+ FBottomRight: TJvPoint;
+ FOnChange: TNotifyEvent;
+ function GetBottom: Integer;
+ function GetLeft: Integer;
+ function GetRight: Integer;
+ function GetTop: Integer;
+ procedure SetBottom(Value: Integer);
+ procedure SetLeft(Value: Integer);
+ procedure SetRight(Value: Integer);
+ procedure SetTop(Value: Integer);
+ procedure SetBottomRight(Value: TJvPoint);
+ procedure SetTopLeft(Value: TJvPoint);
+ procedure PointChange(Sender: TObject);
+ function GetHeight: Integer;
+ function GetWidth: Integer;
+ procedure SetHeight(Value: Integer);
+ procedure SetWidth(Value: Integer);
+ protected
+ procedure DoChange;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure Assign(Source: TPersistent); overload; override;
+ procedure Assign(Source: TRect); reintroduce; overload;
+ procedure CopyToRect(var Rect: TRect);
+ property TopLeft: TJvPoint read FTopLeft write SetTopLeft;
+ property BottomRight: TJvPoint read FBottomRight write SetBottomRight;
+ property Width: Integer read GetWidth write SetWidth;
+ property Height: Integer read GetHeight write SetHeight;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ published
+ property Left: Integer read GetLeft write SetLeft default 0;
+ property Top: Integer read GetTop write SetTop default 0;
+ property Right: Integer read GetRight write SetRight default 0;
+ property Bottom: Integer read GetBottom write SetBottom default 0;
+ end;
+
+ TJvSize = class(TPersistent)
+ private
+ FWidth: Longint;
+ FHeight: Longint;
+ FOnChange: TNotifyEvent;
+ procedure SetWidth(Value: Longint);
+ procedure SetHeight(Value: Longint);
+ protected
+ procedure DoChange;
+ public
+ procedure Assign(Source: TPersistent); overload; override;
+ procedure Assign(Source: TSize); reintroduce; overload;
+ procedure CopyToSize(var Size: TSize);
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ published
+ property Width: Longint read FWidth write SetWidth default 0;
+ property Height: Longint read FHeight write SetHeight default 0;
+ end;
+
+{ begin JvCtrlUtils }
+
+//------------------------------------------------------------------------------
+// ToolBarMenu
+//------------------------------------------------------------------------------
+
+procedure JvCreateToolBarMenu(AForm: TForm; AToolBar: TToolBar;
+ AMenu: TMainMenu = nil);
+
+//------------------------------------------------------------------------------
+// ListView functions
+//------------------------------------------------------------------------------
+
+type
+ {$IFDEF CLR}
+ TJvLVItemStateData = record
+ Caption: string;
+ Data: TObject;
+ Focused: Boolean;
+ Selected: Boolean;
+ end;
+ PJvLVItemStateData = TJvLVItemStateData;
+ {$ELSE}
+ PJvLVItemStateData = ^TJvLVItemStateData;
+ TJvLVItemStateData = record
+ Caption: string;
+ Data: Pointer;
+ Focused: Boolean;
+ Selected: Boolean;
+ end;
+ {$ENDIF CLR}
+
+{ listview functions }
+function ConvertStates(const State: Integer): TItemStates;
+
+function ChangeHasDeselect(const peOld, peNew: TItemStates): Boolean;
+function ChangeHasSelect(const peOld, peNew: TItemStates): Boolean;
+
+function ChangeHasDefocus(const peOld, peNew: TItemStates): Boolean;
+function ChangeHasFocus(const peOld, peNew: TItemStates): Boolean;
+
+function GetListItemColumn(const pcItem: TListItem; piIndex: Integer): string;
+
+procedure JvListViewToStrings(ListView: TListView; Strings: TStrings;
+ SelectedOnly: Boolean = False; Headers: Boolean = True);
+
+function JvListViewSafeSubItemString(Item: TListItem; SubItemIndex: Integer): string;
+
+procedure JvListViewSortClick(Column: TListColumn;
+ AscendingSortImage: Integer = -1; DescendingSortImage: Integer = -1);
+
+procedure JvListViewCompare(ListView: TListView; Item1, Item2: TListItem;
+ var Compare: Integer);
+
+procedure JvListViewSelectAll(ListView: TListView; Deselect: Boolean = False);
+
+function JvListViewSaveState(ListView: TListView): TJvLVItemStateData;
+
+function JvListViewRestoreState(ListView: TListView; Data: TJvLVItemStateData;
+ MakeVisible: Boolean = True; FocusFirst: Boolean = False): Boolean;
+
+
+function JvListViewGetOrderedColumnIndex(Column: TListColumn): Integer;
+procedure JvListViewSetSystemImageList(ListView: TListView);
+
+
+//------------------------------------------------------------------------------
+// MessageBox
+//------------------------------------------------------------------------------
+
+function JvMessageBox(const Text, Caption: string; Flags: DWORD): Integer; overload;
+function JvMessageBox(const Text: string; Flags: DWORD): Integer; overload;
+
+{ end JvCtrlUtils }
+********************)
+
+procedure UpdateTrackFont(TrackFont, Font: TFont; TrackOptions: TJvTrackFontOptions);
+(********************
+// Returns the size of the image
+// used for checkboxes and radiobuttons.
+// Originally from Mike Lischke
+function GetDefaultCheckBoxSize: TSize;
+
+function CanvasMaxTextHeight(Canvas: TCanvas): Integer;
+
+{$IFDEF MSWINDOWS}
+// AllocateHWndEx works like Classes.AllocateHWnd but does not use any virtual memory pages
+function AllocateHWndEx(Method: TWndMethod; const AClassName: string = ''): THandle;
+// DeallocateHWndEx works like Classes.DeallocateHWnd but does not use any virtual memory pages
+procedure DeallocateHWndEx(Wnd: THandle);
+
+function JvMakeObjectInstance(Method: TWndMethod): {$IFDEF CLR}TFNWndProc{$ELSE}Pointer{$ENDIF};
+procedure JvFreeObjectInstance(ObjectInstance: {$IFDEF CLR}TFNWndProc{$ELSE}Pointer{$ENDIF});
+{$ENDIF MSWINDOWS}
+
+function GetAppHandle: THandle;
+// DrawArrow draws a standard arrow in any of four directions and with the specifed color.
+// Rect is the area to draw the arrow in and also defines the size of the arrow
+// Note that this procedure might shrink Rect so that it's width and height is always
+// the same and the width and height are always even, i.e calling with
+// Rect(0,0,12,12) (odd) is the same as calling with Rect(0,0,11,11) (even)
+// Direction defines the direction of the arrow. If Direction is akLeft, the arrow point is
+// pointing to the left
+procedure DrawArrow(Canvas: TCanvas; Rect: TRect; Color: TColor = clBlack; Direction: TAnchorKind = akBottom);
+
+function IsPositiveResult(Value: TModalResult): Boolean;
+function IsNegativeResult(Value: TModalResult): Boolean;
+function IsAbortResult(const Value: TModalResult): Boolean;
+function StripAllFromResult(const Value: TModalResult): TModalResult;
+// returns either BrightColor or DarkColor depending on the luminance of AColor
+// This function gives the same result (AFAIK) as the function used in Windows to
+// calculate the desktop icon text color based on the desktop background color
+function SelectColorByLuminance(AColor, DarkColor, BrightColor: TColor): TColor;
+
+// (peter3) implementation moved from JvHTControls.
+type
+ TJvHTMLCalcType = (htmlShow, htmlCalcWidth, htmlCalcHeight);
+
+procedure HTMLDrawTextEx(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; var Width: Integer;
+ CalcType: TJvHTMLCalcType; MouseX, MouseY: Integer; var MouseOnLink: Boolean;
+ var LinkName: string; Scale: Integer = 100);
+function HTMLDrawText(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; Scale: Integer = 100): string;
+function HTMLTextWidth(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; Scale: Integer = 100): Integer;
+function HTMLPlainText(const Text: string): string;
+function HTMLTextHeight(Canvas: TCanvas; const Text: string; Scale: Integer = 100): Integer;
+function HTMLPrepareText(const Text: string): string;
+
+// This type is used to allow an easy migration from a TBitmap property to a
+// TPicture property. It is, for instance, used in TJvXPButton so that users
+// migrating to the JVCL can still open their applications and benefit
+// automatically from the change of format. The whole point is that a TPicture
+// can also contain an Icon, which could be a valid source for a button glyph.
+type
+ TJvPicture = class (TPicture)
+ private
+ procedure ReadBitmapData(Stream: TStream);
+ protected
+ procedure DefineProperties(Filer: TFiler); override;
+ end;
+
+{
+Documentation:
+*************
+
+WHAT IT IS:
+ These are helper functions to register graphic formats than can
+ later be recognized from a stream, thus allowing to rely on the actual
+ content of a file rather than from its filename extension.
+ This is used in TJvDBImage and TJvImage.
+
+IMAGE FORMATS:
+ The implementation is simple: Just register image signatures with
+ RegisterGraphicSignature procedure and the methods takes care
+ of the correct instantiation of the TGraphic object. The signatures
+ register at unit's initialization are: BMP, WMF, EMF, ICO, JPG.
+ If you got some other image library (such as GIF, PCX, TIFF, ANI or PNG),
+ just register the signature:
+
+ RegisterGraphicSignature(, , )
+
+ or
+
+ RegisterGraphicSignature([], , )
+
+ This means:
+ When (or byte values) found at the graphic
+ class to use is
+
+ For example (actual code of the initialization section):
+
+ RegisterGraphicSignature([$D7, $CD], 0, TMetaFile); // WMF
+ RegisterGraphicSignature([1, 0], 0, TMetaFile); // EMF
+ RegisterGraphicSignature('JFIF', 6, TJPEGImage);
+
+ You can also unregister signature. IF you want use TGIFImage instead of
+ TJvGIFImage, you can unregister with:
+
+ UnregisterGraphicSignature('GIF', 0);
+
+ or just
+
+ UnregisterGraphicSignature(TJvGIFImage); // must add JvGIF unit in uses clause
+
+ then:
+ RegisterGraphicSignature('GIF', 0, TGIFImage); // must add GIFImage to uses clause
+
+ If you dont like the signature registration there is a new event called
+ OnGetGraphicClass. The event gets the following parameters:
+
+ Sender: TObject;
+ Stream: TMemoryStream;
+ var GraphicClass: TGraphicClass)
+
+ The memory stream containing the blob data is sent in Stream to allow the user
+ to inspect the contents and figure out which graphic class is.
+
+ The graphic class to be used must implement LoadFromStream and SaveToStream
+ methods in order to work properly.
+}
+
+type
+ TJvGetGraphicClassEvent = procedure(Sender: TObject; AStream: TMemoryStream;
+ var GraphicClass: TGraphicClass) of object;
+
+procedure RegisterGraphicSignature(const ASignature: string; AOffset: Integer;
+ AGraphicClass: TGraphicClass); overload;
+procedure RegisterGraphicSignature(const ASignature: array of Byte; AOffset: Integer;
+ AGraphicClass: TGraphicClass); overload;
+
+procedure UnregisterGraphicSignature(AGraphicClass: TGraphicClass); overload;
+procedure UnregisterGraphicSignature(const ASignature: string; AOffset: Integer); overload;
+procedure UnregisterGraphicSignature(const ASignature: array of Byte; AOffset: Integer); overload;
+
+function GetGraphicClass(AStream: TStream): TGraphicClass;
+function GetGraphicObject(AStream: TStream): TGraphic; overload;
+function GetGraphicObject(AStream: TStream; ASender: TObject; AOnProc: TJvGetGraphicClassEvent): TGraphic; overload;
+********************)
+
+implementation
+
+(********************
+uses
+ SysConst,
+ Consts,
+ {$IFDEF MSWINDOWS}
+ CommCtrl, MMSystem, ShlObj, ActiveX,
+ {$ENDIF MSWINDOWS}
+ Math, jpeg, Contnrs,
+ JclSysInfo,
+ JvConsts, JvProgressUtils, JvResources;
+
+{$R JvConsts.res}
+
+const
+ {$IFDEF MSWINDOWS}
+ RC_ControlRegistry = 'Control Panel\Desktop';
+ RC_WallPaperStyle = 'WallpaperStyle';
+ RC_WallpaperRegistry = 'Wallpaper';
+ RC_TileWallpaper = 'TileWallpaper';
+ RC_RunCpl = 'rundll32.exe shell32,Control_RunDLL ';
+ {$ENDIF MSWINDOWS}
+
+function GetAppHandle: THandle;
+begin
+ Result := Application.Handle;
+end;
+
+type
+ TWaitCursor = class(TInterfacedObject, IInterface)
+ private
+ FCursor: TCursor;
+ public
+ constructor Create(ACursor: TCursor);
+ destructor Destroy; override;
+ end;
+
+constructor TWaitCursor.Create(ACursor: TCursor);
+begin
+ inherited Create;
+ FCursor := Screen.Cursor;
+ Screen.Cursor := ACursor;
+end;
+
+destructor TWaitCursor.Destroy;
+begin
+ Screen.Cursor := FCursor;
+ inherited Destroy;
+end;
+
+
+
+
+
+function IconToBitmap(Ico: HICON): TBitmap;
+var
+ Pic: TPicture;
+begin
+ Pic := TPicture.Create;
+ try
+ Pic.Icon.Handle := Ico;
+ Result := TBitmap.Create;
+ Result.Height := Pic.Icon.Height;
+ Result.Width := Pic.Icon.Width;
+ Result.Canvas.Draw(0, 0, Pic.Icon);
+ finally
+ Pic.Free;
+ end;
+end;
+
+function IconToBitmap2(Ico: HICON; Size: Integer = 32;
+ TransparentColor: TColor = clNone): TBitmap;
+begin
+ // (p3) this seems to generate "better" bitmaps...
+ with TImageList.CreateSize(Size, Size) do
+ try
+ Masked := True;
+ BkColor := TransparentColor;
+ ImageList_AddIcon(Handle, Ico);
+ Result := TBitmap.Create;
+ Result.PixelFormat := pf24bit;
+ if TransparentColor <> clNone then
+ Result.TransparentColor := TransparentColor;
+ Result.Transparent := TransparentColor <> clNone;
+ GetBitmap(0, Result);
+ finally
+ Free;
+ end;
+end;
+
+function IconToBitmap3(Ico: HICON; Size: Integer = 32;
+ TransparentColor: TColor = clNone): TBitmap;
+var
+ Icon: TIcon;
+ Tmp: TBitmap;
+begin
+ Icon := TIcon.Create;
+ Tmp := TBitmap.Create;
+ try
+ Icon.Handle := CopyIcon(Ico);
+ Result := TBitmap.Create;
+ Result.Width := Icon.Width;
+ Result.Height := Icon.Height;
+ Result.PixelFormat := pf24bit;
+ // fill the bitmap with the transparent color
+ Result.Canvas.Brush.Color := TransparentColor;
+ Result.Canvas.FillRect(Rect(0, 0, Result.Width, Result.Height));
+ Result.Canvas.Draw(0, 0, Icon);
+ Result.TransparentColor := TransparentColor;
+ Tmp.Assign(Result);
+ // Result.Width := Size;
+ // Result.Height := Size;
+ Result.Canvas.StretchDraw(Rect(0, 0, Result.Width, Result.Height), Tmp);
+ Result.Transparent := True;
+ finally
+ Icon.Free;
+ Tmp.Free;
+ end;
+end;
+
+
+procedure RGBToHSV(R, G, B: Integer; var H, S, V: Integer);
+
+var
+ Delta: Integer;
+ Min, Max: Integer;
+
+ function GetMax(I, J, K: Integer): Integer;
+ begin
+ if J > I then
+ I := J;
+ if K > I then
+ I := K;
+ Result := I;
+ end;
+
+ function GetMin(I, J, K: Integer): Integer;
+ begin
+ if J < I then
+ I := J;
+ if K < I then
+ I := K;
+ Result := I;
+ end;
+
+begin
+ Min := GetMin(R, G, B);
+ Max := GetMax(R, G, B);
+ V := Max;
+ Delta := Max - Min;
+ if Max = 0 then
+ S := 0
+ else
+ S := (255 * Delta) div Max;
+ if S = 0 then
+ H := 0
+ else
+ begin
+ if R = Max then
+ H := (60 * (G - B)) div Delta
+ else
+ if G = Max then
+ H := 120 + (60 * (B - R)) div Delta
+ else
+ H := 240 + (60 * (R - G)) div Delta;
+ if H < 0 then
+ H := H + 360;
+ end;
+end;
+
+
+
+(-* (rom) to be deleted. Use ScreenShot from JCL
+{$IFDEF VCL}
+
+function CaptureScreen(Rec: TRect): TBitmap;
+const
+ NumColors = 256;
+var
+ R: TRect;
+ C: TCanvas;
+ LP: PLogPalette;
+ TmpPalette: HPALETTE;
+ Size: Integer;
+begin
+ Result := TBitmap.Create;
+ Result.Width := Rec.Right - Rec.Left;
+ Result.Height := Rec.Bottom - Rec.Top;
+ R := Rec;
+ C := TCanvas.Create;
+ try
+ C.Handle := GetDC(HWND_DESKTOP);
+ Result.Canvas.CopyRect(Rect(0, 0, Rec.Right - Rec.Left, Rec.Bottom -
+ Rec.Top), C, R);
+ Size := SizeOf(TLogPalette) + (Pred(NumColors) * SizeOf(TPaletteEntry));
+ LP := AllocMem(Size);
+ try
+ LP^.palVersion := $300;
+ LP^.palNumEntries := NumColors;
+ GetSystemPaletteEntries(C.Handle, 0, NumColors, LP^.palPalEntry);
+ TmpPalette := CreatePalette(LP^);
+ Result.Palette := TmpPalette;
+ DeleteObject(TmpPalette);
+ finally
+ FreeMem(LP, Size);
+ end
+ finally
+ ReleaseDC(HWND_DESKTOP, C.Handle);
+ C.Free;
+ end;
+end;
+
+function CaptureScreen(IncludeTaskBar: Boolean): TBitmap;
+var
+ R: TRect;
+begin
+ if IncludeTaskBar then
+ R := Rect(0, 0, Screen.Width, Screen.Height)
+ else
+ SystemParametersInfo(SPI_GETWORKAREA, 0, Pointer(@R), 0);
+ Result := CaptureScreen(R);
+end;
+
+function CaptureScreen(WndHandle: Longword): TBitmap;
+var
+ R: TRect;
+ WP: TWindowPlacement;
+begin
+ if GetWindowRect(WndHandle, R) then
+ begin
+ GetWindowPlacement(WndHandle, @WP);
+ if IsIconic(WndHandle) then
+ ShowWindow(WndHandle, SW_RESTORE);
+ BringWindowToTop(WndHandle);
+ Result := CaptureScreen(R);
+ SetWindowPlacement(WndHandle, @WP);
+ end
+ else
+ Result := nil;
+end;
+{$ENDIF VCL}
+*-)
+
+{$IFDEF MSWINDOWS}
+
+{$IFNDEF CLR}
+procedure SetWallpaper(const Path: string);
+begin
+ SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, PChar(Path), SPIF_UPDATEINIFILE);
+end;
+{$ENDIF !CLR}
+
+procedure SetWallpaper(const Path: string; Style: TJvWallpaperStyle);
+begin
+ with TRegistry.Create do
+ begin
+ OpenKey(RC_ControlRegistry, False);
+ case Style of
+ wpTile:
+ begin
+ WriteString(RC_TileWallpaper, '1');
+ WriteString(RC_WallPaperStyle, '0');
+ end;
+ wpCenter:
+ begin
+ WriteString(RC_TileWallpaper, '0');
+ WriteString(RC_WallPaperStyle, '0');
+ end;
+ wpStretch:
+ begin
+ WriteString(RC_TileWallpaper, '0');
+ WriteString(RC_WallPaperStyle, '2');
+ end;
+ end;
+ WriteString(RC_WallpaperRegistry, Path);
+ Free;
+ end;
+ SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);
+end;
+
+{$ENDIF MSWINDOWS}
+
+type
+ TGetXBitmapMode =(gxRed, gxGreen, gxBlue, gxHue, gxSaturation, gxValue);
+
+procedure GetXBitmap(var Dest: TBitmap; const Source: TBitmap; Mode: TGetXBitmapMode);
+var
+ I, J, H, S, V: Integer;
+ {$IFDEF CLR}
+ Line: array of TJvRGBTriple;
+ {$ELSE}
+ Line: PJvRGBArray;
+ {$ENDIF CLR}
+begin
+ if not Assigned(Dest) then
+ Dest := TBitmap.Create;
+ Dest.Assign(Source);
+ Dest.PixelFormat := pf24bit;
+ for J := Dest.Height - 1 downto 0 do
+ begin
+ {$IFDEF CLR}
+ Marshal.PtrToStructure(Dest.ScanLine[J], Line);
+ {$ELSE}
+ Line := Dest.ScanLine[J];
+ {$ENDIF CLR}
+ case Mode of
+ gxRed:
+ for I := Dest.Width - 1 downto 0 do
+ begin
+ Line[I].rgbGreen := 0;
+ Line[I].rgbBlue := 0;
+ end;
+ gxGreen:
+ for I := Dest.Width - 1 downto 0 do
+ begin
+ Line[I].rgbRed := 0;
+ Line[I].rgbBlue := 0;
+ end;
+ gxBlue:
+ for I := Dest.Width - 1 downto 0 do
+ begin
+ Line[I].rgbRed := 0;
+ Line[I].rgbGreen := 0;
+ end;
+ gxHue:
+ for I := Dest.Width - 1 downto 0 do
+ with Line[I] do
+ begin
+ RGBToHSV(rgbRed, rgbGreen, rgbBlue, H, S, V);
+ rgbRed := H;
+ rgbGreen := H;
+ rgbBlue := H;
+ end;
+ gxSaturation:
+ for I := Dest.Width - 1 downto 0 do
+ with Line[I] do
+ begin
+ RGBToHSV(rgbRed, rgbGreen, rgbBlue, H, S, V);
+ rgbRed := S;
+ rgbGreen := S;
+ rgbBlue := S;
+ end;
+ gxValue:
+ for I := Dest.Width - 1 downto 0 do
+ with Line[I] do
+ begin
+ RGBToHSV(rgbRed, rgbGreen, rgbBlue, H, S, V);
+ rgbRed := V;
+ rgbGreen := V;
+ rgbBlue := V;
+ end;
+ end;
+ end;
+ Dest.PixelFormat := Source.PixelFormat;
+end;
+
+procedure GetRBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxRed);
+end;
+
+procedure GetBBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxBlue);
+end;
+
+procedure GetGBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxGreen);
+end;
+
+procedure GetMonochromeBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ if not Assigned(Dest) then
+ Dest := TBitmap.Create;
+ Dest.Assign(Source);
+ Dest.Monochrome := True;
+end;
+
+procedure GetHueBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxHue);
+end;
+
+procedure GetSaturationBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxSaturation);
+end;
+
+procedure GetValueBitmap(var Dest: TBitmap; const Source: TBitmap);
+begin
+ GetXBitmap(Dest, Source, gxValue);
+end;
+
+
+{ (rb) Duplicate of JvAppUtils.AppTaskbarIcons }
+
+procedure HideFormCaption(FormHandle: THandle; Hide: Boolean);
+begin
+ if Hide then
+ SetWindowLong(FormHandle, GWL_STYLE,
+ GetWindowLong(FormHandle, GWL_STYLE) and not WS_CAPTION)
+ else
+ SetWindowLong(FormHandle, GWL_STYLE,
+ GetWindowLong(FormHandle, GWL_STYLE) or WS_CAPTION);
+end;
+
+
+{$IFNDEF CLR}
+
+
+procedure LaunchCpl(const FileName: string);
+begin
+ // rundll32.exe shell32,Control_RunDLL ';
+ RunDLL32('shell32.dll', 'Control_RunDLL', FileName, True);
+ // WinExec(PChar(RC_RunCpl + FileName), SW_SHOWNORMAL);
+end;
+
+procedure ShowSafeRemovalDialog;
+begin
+ LaunchCpl('HOTPLUG.DLL');
+end;
+
+const
+ {$EXTERNALSYM WM_CPL_LAUNCH}
+ WM_CPL_LAUNCH = (WM_USER + 1000);
+ {$EXTERNALSYM WM_CPL_LAUNCHED}
+ WM_CPL_LAUNCHED = (WM_USER + 1001);
+
+ { (p3) just define enough to make the Cpl unnecessary for us (for the benefit of PE users) }
+ cCplAddress = 'CPlApplet';
+ CPL_INIT = 1;
+ {$EXTERNALSYM CPL_INIT}
+ CPL_GETCOUNT = 2;
+ {$EXTERNALSYM CPL_GETCOUNT}
+ CPL_INQUIRE = 3;
+ {$EXTERNALSYM CPL_INQUIRE}
+ CPL_EXIT = 7;
+ {$EXTERNALSYM CPL_EXIT}
+ CPL_NEWINQUIRE = 8;
+ {$EXTERNALSYM CPL_NEWINQUIRE}
+
+type
+ TCPLApplet = function(hwndCPl: THandle; uMsg: DWORD;
+ lParam1, lParam2: Longint): Longint; stdcall;
+
+ TCPLInfo = packed record
+ idIcon: Integer;
+ idName: Integer;
+ idInfo: Integer;
+ lData: Longint;
+ end;
+
+ TNewCPLInfoA = packed record
+ dwSize: DWORD;
+ dwFlags: DWORD;
+ dwHelpContext: DWORD;
+ lData: Longint;
+ HICON: HICON;
+ szName: array [0..31] of AnsiChar;
+ szInfo: array [0..63] of AnsiChar;
+ szHelpFile: array [0..127] of AnsiChar;
+ end;
+ TNewCPLInfoW = packed record
+ dwSize: DWORD;
+ dwFlags: DWORD;
+ dwHelpContext: DWORD;
+ lData: Longint;
+ HICON: HICON;
+ szName: array [0..31] of WideChar;
+ szInfo: array [0..63] of WideChar;
+ szHelpFile: array [0..127] of WideChar;
+ end;
+
+function GetControlPanelApplet(const AFileName: string; Strings: TStrings;
+ Images: TCustomImageList = nil): Boolean;
+var
+ hLib: HMODULE; // Library Handle to *.cpl file
+ hIco: HICON;
+ CplCall: TCPLApplet; // Pointer to CPlApplet() function
+ I: Longint;
+ TmpCount, Count: Longint;
+ S: WideString;
+ // the three types of information that can be returned
+ CPLInfo: TCPLInfo;
+ InfoW: TNewCPLInfoW;
+ InfoA: TNewCPLInfoA;
+ HWND: THandle;
+begin
+ Result := False;
+ hLib := SafeLoadLibrary(AFileName);
+ if hLib = 0 then
+ Exit;
+ HWND := GetForegroundWindow;
+ TmpCount := Strings.Count;
+ Strings.BeginUpdate;
+ try
+ @CplCall := GetProcAddress(hLib, PChar(cCplAddress));
+ if not Assigned(CplCall) then
+ Exit;
+ CplCall(HWND, CPL_INIT, 0, 0); // Init the *.cpl file
+ try
+ Count := CplCall(HWND, CPL_GETCOUNT, 0, 0);
+ for I := 0 to Count - 1 do
+ begin
+ FillChar(InfoW, SizeOf(InfoW), 0);
+ FillChar(InfoA, SizeOf(InfoA), 0);
+ FillChar(CPLInfo, SizeOf(CPLInfo), 0);
+ S := '';
+ CplCall(HWND, CPL_NEWINQUIRE, I, Longint(@InfoW));
+ if InfoW.dwSize = SizeOf(InfoW) then
+ begin
+ hIco := InfoW.HICON;
+ S := WideString(InfoW.szName);
+ end
+ else
+ begin
+ if InfoW.dwSize = SizeOf(InfoA) then
+ begin
+ Move(InfoW, InfoA, SizeOf(InfoA));
+ hIco := CopyIcon(InfoA.HICON);
+ S := string(InfoA.szName);
+ end
+ else
+ begin
+ CplCall(HWND, CPL_INQUIRE, I, Longint(@CPLInfo));
+ LoadStringA(hLib, CPLInfo.idName, InfoA.szName,
+ SizeOf(InfoA.szName));
+ hIco := LoadImage(hLib, PChar(CPLInfo.idIcon), IMAGE_ICON, 16, 16,
+ LR_DEFAULTCOLOR);
+ S := string(InfoA.szName);
+ end;
+ end;
+ if S <> '' then
+ begin
+ S := Format('%s=%s,@%d', [S, AFileName, I]);
+ if Images <> nil then
+ begin
+ hIco := CopyIcon(hIco);
+ ImageList_AddIcon(Images.Handle, hIco);
+ Strings.AddObject(S, TObject(Images.Count - 1));
+ end
+ else
+ Strings.AddObject(S, IconToBitmap2(hIco, 16, clMenu));
+ // (p3) not sure this is really needed...
+ // DestroyIcon(hIco);
+ end;
+ end;
+ Result := TmpCount < Strings.Count;
+ finally
+ CplCall(HWND, CPL_EXIT, 0, 0);
+ end;
+ finally
+ FreeLibrary(hLib);
+ Strings.EndUpdate;
+ end;
+end;
+
+function GetControlPanelApplets(const APath, AMask: string; Strings: TStrings;
+ Images: TCustomImageList = nil): Boolean;
+var
+ H: THandle;
+ F: TSearchRec;
+begin
+ Result := False;
+ if Strings = nil then
+ Exit;
+ H := FindFirst(IncludeTrailingPathDelimiter(APath) + AMask, faAnyFile, F);
+ if Images <> nil then
+ begin
+ Images.Clear;
+ Images.BkColor := clMenu;
+ end;
+ Strings.BeginUpdate;
+ try
+ Strings.Clear;
+ while H = 0 do
+ begin
+ if F.Attr and faDirectory = 0 then
+ // if (F.Name <> '.') and (F.Name <> '..') then
+ GetControlPanelApplet(APath + F.Name, Strings, Images);
+ H := FindNext(F);
+ end;
+ SysUtils.FindClose(F);
+ Result := Strings.Count > 0;
+ finally
+ Strings.EndUpdate;
+ end;
+end;
+
+{$ENDIF !CLR}
+
+{ imported from VCLFunctions }
+
+procedure CenterHeight(const pc, pcParent: TControl);
+begin
+ pc.Top := //pcParent.Top +
+ ((pcParent.Height - pc.Height) div 2);
+end;
+
+function ToRightOf(const pc: TControl; piSpace: Integer): Integer;
+begin
+ if pc <> nil then
+ Result := pc.Left + pc.Width + piSpace
+ else
+ Result := piSpace;
+end;
+
+{ compiled from ComCtrls.pas's implmentation section }
+
+function HasFlag(A, B: Integer): Boolean;
+begin
+ Result := (A and B) <> 0;
+end;
+
+function ConvertStates(const State: Integer): TItemStates;
+begin
+ Result := [];
+ if HasFlag(State, LVIS_ACTIVATING) then
+ Include(Result, isActivating);
+ if HasFlag(State, LVIS_CUT) then
+ Include(Result, isCut);
+ if HasFlag(State, LVIS_DROPHILITED) then
+ Include(Result, isDropHilited);
+ if HasFlag(State, LVIS_FOCUSED) then
+ Include(Result, IsFocused);
+ if HasFlag(State, LVIS_SELECTED) then
+ Include(Result, isSelected);
+end;
+
+function ChangeHasSelect(const peOld, peNew: TItemStates): Boolean;
+begin
+ Result := (not (isSelected in peOld)) and (isSelected in peNew);
+end;
+
+function ChangeHasDeselect(const peOld, peNew: TItemStates): Boolean;
+begin
+ Result := (isSelected in peOld) and (not (isSelected in peNew));
+end;
+
+function ChangeHasFocus(const peOld, peNew: TItemStates): Boolean;
+begin
+ Result := (not (IsFocused in peOld)) and (IsFocused in peNew);
+end;
+
+function ChangeHasDefocus(const peOld, peNew: TItemStates): Boolean;
+begin
+ Result := (IsFocused in peOld) and (not (IsFocused in peNew));
+end;
+
+function GetListItemColumn(const pcItem: TListItem; piIndex: Integer): string;
+begin
+ if pcItem = nil then
+ begin
+ Result := '';
+ Exit;
+ end;
+
+ if (piIndex < 0) or (piIndex > pcItem.SubItems.Count) then
+ begin
+ Result := '';
+ Exit;
+ end;
+
+ if piIndex = 0 then
+ Result := pcItem.Caption
+ else
+ Result := pcItem.SubItems[piIndex - 1];
+end;
+
+{from JvVCLUtils }
+
+{ Bitmaps }
+
+
+
+
+// see above for VisualCLX version of CopyParentImage
+type
+ TJvParentControl = class(TWinControl);
+
+procedure CopyParentImage(Control: TControl; Dest: TCanvas);
+var
+ I, Count, SaveIndex: Integer;
+ DC: HDC;
+ R, SelfR, CtlR: TRect;
+ ViewPortOrg: TPoint;
+begin
+ if (Control = nil) or (Control.Parent = nil) then
+ Exit;
+ Count := Control.Parent.ControlCount;
+ DC := Dest.Handle;
+ with Control.Parent do
+ ControlState := ControlState + [csPaintCopy];
+ try
+ // The view port may already be set. This is especially true when
+ // a control using CopyParentImage is placed inside a control that
+ // calls it as well. Best example is a TJvSpeeButton in a TJvPanel,
+ // both with Transparent set to True (discovered while working on
+ // Mantis 3624)
+ GetViewPortOrgEx(DC, ViewPortOrg);
+
+ with Control do
+ begin
+ SelfR := Bounds(Left, Top, Width, Height);
+
+ ViewPortOrg.X := ViewPortOrg.X-Left;
+ ViewPortOrg.Y := ViewPortOrg.Y-Top;
+ end;
+
+ // Copy parent control image
+ SaveIndex := SaveDC(DC);
+ try
+ SetViewPortOrgEx(DC, ViewPortOrg.X, ViewPortOrg.Y, nil);
+ IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth,
+ Control.Parent.ClientHeight);
+ {$IFDEF CLR}
+ Control.Parent.Perform(WM_ERASEBKGND, DC, 0);
+ Control.Parent.GetType.InvokeMember('PaintWindow',
+ BindingFlags.Instance or BindingFlags.InvokeMethod or BindingFlags.NonPublic,
+ nil, Control.Parent, [DC]);
+ {$ELSE}
+ with TJvParentControl(Control.Parent) do
+ begin
+ Perform(WM_ERASEBKGND, DC, 0);
+ PaintWindow(DC);
+ end;
+ {$ENDIF CLR}
+ finally
+ RestoreDC(DC, SaveIndex);
+ end;
+
+ // Copy images of control's siblings
+ // Note: while working on Mantis 3624 it was decided that there was no
+ // real reason to limit this to controls derived from TGraphicControl.
+ for I := 0 to Count - 1 do
+ begin
+ if Control.Parent.Controls[I] = Control then
+ Break
+ else
+ if (Control.Parent.Controls[I] <> nil) then
+ begin
+ with Control.Parent.Controls[I] do
+ begin
+ CtlR := Bounds(Left, Top, Width, Height);
+ if IntersectRect(R, SelfR, CtlR) and Visible then
+ begin
+ ControlState := ControlState + [csPaintCopy];
+ SaveIndex := SaveDC(DC);
+ try
+ SetViewPortOrgEx(DC, Left + ViewPortOrg.X, Top + ViewPortOrg.Y, nil);
+ IntersectClipRect(DC, 0, 0, Width, Height);
+ Perform(WM_PAINT, DC, 0);
+ finally
+ RestoreDC(DC, SaveIndex);
+ ControlState := ControlState - [csPaintCopy];
+ end;
+ end;
+ end;
+ end;
+ end;
+ finally
+ with Control.Parent do
+ ControlState := ControlState - [csPaintCopy];
+ end;
+end;
+
+
+
+{$IFNDEF CLR}
+function MakeModuleBitmap(Module: THandle; ResID: PChar): TBitmap;
+begin
+ Result := TBitmap.Create;
+ try
+ if Module <> 0 then
+ begin
+ if LongRec(ResID).Hi = 0 then
+ Result.LoadFromResourceID(Module, LongRec(ResID).Lo)
+ else
+ Result.LoadFromResourceName(Module, StrPas(ResID));
+ end
+ else
+ begin
+ Result.Handle := LoadBitmap(Module, ResID);
+ if Result.Handle = 0 then
+ ResourceNotFound(ResID);
+ end;
+ except
+ Result.Free;
+ Result := nil;
+ end;
+end;
+
+function MakeBitmap(ResID: PChar): TBitmap;
+begin
+ Result := MakeModuleBitmap(HInstance, ResID);
+end;
+
+function MakeBitmapID(ResID: Word): TBitmap;
+begin
+ Result := MakeModuleBitmap(HInstance, MakeIntResource(ResID));
+end;
+{$ENDIF !CLR}
+
+procedure AssignBitmapCell(Source: TGraphic; Dest: TBitmap;
+ Cols, Rows, Index: Integer);
+var
+ CellWidth, CellHeight: Integer;
+begin
+ if (Source <> nil) and (Dest <> nil) then
+ begin
+ if Cols <= 0 then
+ Cols := 1;
+ if Rows <= 0 then
+ Rows := 1;
+ if Index < 0 then
+ Index := 0;
+ CellWidth := Source.Width div Cols;
+ CellHeight := Source.Height div Rows;
+ with Dest do
+ begin
+ Width := CellWidth;
+ Height := CellHeight;
+ end;
+ if Source is TBitmap then
+ begin
+ Dest.Canvas.CopyRect(Bounds(0, 0, CellWidth, CellHeight),
+ TBitmap(Source).Canvas, Bounds((Index mod Cols) * CellWidth,
+ (Index div Cols) * CellHeight, CellWidth, CellHeight));
+ Dest.TransparentColor := TBitmap(Source).TransparentColor;
+ end
+ else
+ begin
+ Dest.Canvas.Brush.Color := clSilver;
+ Dest.Canvas.FillRect(Bounds(0, 0, CellWidth, CellHeight));
+ Dest.Canvas.Draw(-(Index mod Cols) * CellWidth,
+ -(Index div Cols) * CellHeight, Source);
+ end;
+ Dest.Transparent := Source.Transparent;
+ end;
+end;
+
+{ Transparent bitmap }
+
+
+
+procedure StretchBltTransparent(DstDC: HDC; DstX, DstY, DstW, DstH: Integer;
+ SrcDC: HDC; SrcX, SrcY, SrcW, Srch: Integer; Palette: HPALETTE;
+ TransparentColor: TColorRef);
+var
+ Color: TColorRef;
+ bmAndBack, bmAndObject, bmAndMem, bmSave: HBITMAP;
+ bmBackOld, bmObjectOld, bmMemOld, bmSaveOld: HBITMAP;
+ MemDC, BackDC, ObjectDC, SaveDC: HDC;
+ palDst, palMem, palSave, palObj: HPALETTE;
+begin
+ { Create some DCs to hold temporary data }
+ BackDC := CreateCompatibleDC(DstDC);
+ ObjectDC := CreateCompatibleDC(DstDC);
+ MemDC := CreateCompatibleDC(DstDC);
+ SaveDC := CreateCompatibleDC(DstDC);
+ { Create a bitmap for each DC }
+ bmAndObject := CreateBitmap(SrcW, Srch, 1, 1, nil);
+ bmAndBack := CreateBitmap(SrcW, Srch, 1, 1, nil);
+ bmAndMem := CreateCompatibleBitmap(DstDC, DstW, DstH);
+ bmSave := CreateCompatibleBitmap(DstDC, SrcW, Srch);
+ { Each DC must select a bitmap object to store pixel data }
+ bmBackOld := SelectObject(BackDC, bmAndBack);
+ bmObjectOld := SelectObject(ObjectDC, bmAndObject);
+ bmMemOld := SelectObject(MemDC, bmAndMem);
+ bmSaveOld := SelectObject(SaveDC, bmSave);
+ { Select palette }
+ palDst := 0;
+ palMem := 0;
+ palSave := 0;
+ palObj := 0;
+ if Palette <> 0 then
+ begin
+ palDst := SelectPalette(DstDC, Palette, True);
+ RealizePalette(DstDC);
+ palSave := SelectPalette(SaveDC, Palette, False);
+ RealizePalette(SaveDC);
+ palObj := SelectPalette(ObjectDC, Palette, False);
+ RealizePalette(ObjectDC);
+ palMem := SelectPalette(MemDC, Palette, True);
+ RealizePalette(MemDC);
+ end;
+ { Set proper mapping mode }
+ SetMapMode(SrcDC, GetMapMode(DstDC));
+ SetMapMode(SaveDC, GetMapMode(DstDC));
+ { Save the bitmap sent here }
+ BitBlt(SaveDC, 0, 0, SrcW, Srch, SrcDC, SrcX, SrcY, SRCCOPY);
+ { Set the background color of the source DC to the color, }
+ { contained in the parts of the bitmap that should be transparent }
+ Color := SetBkColor(SaveDC, PaletteColor(TransparentColor));
+ { Create the object mask for the bitmap by performing a BitBlt() }
+ { from the source bitmap to a monochrome bitmap }
+ BitBlt(ObjectDC, 0, 0, SrcW, Srch, SaveDC, 0, 0, SRCCOPY);
+ { Set the background color of the source DC back to the original }
+ SetBkColor(SaveDC, Color);
+ { Create the inverse of the object mask }
+ BitBlt(BackDC, 0, 0, SrcW, Srch, ObjectDC, 0, 0, NOTSRCCOPY);
+ { Copy the background of the main DC to the destination }
+ BitBlt(MemDC, 0, 0, DstW, DstH, DstDC, DstX, DstY, SRCCOPY);
+ { Mask out the places where the bitmap will be placed }
+ StretchBlt(MemDC, 0, 0, DstW, DstH, ObjectDC, 0, 0, SrcW, Srch, SRCAND);
+ { Mask out the transparent colored pixels on the bitmap }
+ BitBlt(SaveDC, 0, 0, SrcW, Srch, BackDC, 0, 0, SRCAND);
+ { XOR the bitmap with the background on the destination DC }
+ StretchBlt(MemDC, 0, 0, DstW, DstH, SaveDC, 0, 0, SrcW, Srch, SRCPAINT);
+ { Copy the destination to the screen }
+ BitBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, SRCCOPY);
+ { Restore palette }
+ if Palette <> 0 then
+ begin
+ SelectPalette(MemDC, palMem, False);
+ SelectPalette(ObjectDC, palObj, False);
+ SelectPalette(SaveDC, palSave, False);
+ SelectPalette(DstDC, palDst, True);
+ end;
+ { Delete the memory bitmaps }
+ DeleteObject(SelectObject(BackDC, bmBackOld));
+ DeleteObject(SelectObject(ObjectDC, bmObjectOld));
+ DeleteObject(SelectObject(MemDC, bmMemOld));
+ DeleteObject(SelectObject(SaveDC, bmSaveOld));
+ { Delete the memory DCs }
+ DeleteDC(MemDC);
+ DeleteDC(BackDC);
+ DeleteDC(ObjectDC);
+ DeleteDC(SaveDC);
+end;
+
+
+
+procedure DrawTransparentBitmapRect(DC: HDC; Bitmap: HBITMAP; DstX, DstY,
+ DstW, DstH: Integer; SrcRect: TRect; TransparentColor: TColorRef);
+var
+ hdcTemp: HDC;
+begin
+ hdcTemp := CreateCompatibleDC(DC);
+ try
+ SelectObject(hdcTemp, Bitmap);
+ with SrcRect do
+ StretchBltTransparent(DC, DstX, DstY, DstW, DstH, hdcTemp,
+ Left, Top, Right - Left, Bottom - Top, 0, TransparentColor);
+ finally
+ DeleteDC(hdcTemp);
+ end;
+end;
+
+procedure DrawTransparentBitmap(DC: HDC; Bitmap: HBITMAP;
+ DstX, DstY: Integer; TransparentColor: TColorRef);
+var
+ BM: tagBITMAP;
+begin
+ {$IFDEF CLR}
+ GetObject(Bitmap, Marshal.SizeOf(BM), BM);
+ {$ELSE}
+ GetObject(Bitmap, SizeOf(BM), @BM);
+ {$ENDIF CLR}
+ DrawTransparentBitmapRect(DC, Bitmap, DstX, DstY, BM.bmWidth, BM.bmHeight,
+ Rect(0, 0, BM.bmWidth, BM.bmHeight), TransparentColor);
+end;
+
+procedure StretchBitmapTransparent(Dest: TCanvas; Bitmap: TBitmap;
+ TransparentColor: TColor; DstX, DstY, DstW, DstH, SrcX, SrcY,
+ SrcW, Srch: Integer);
+var
+ CanvasChanging: TNotifyEvent;
+begin
+ if DstW <= 0 then
+ DstW := Bitmap.Width;
+ if DstH <= 0 then
+ DstH := Bitmap.Height;
+ if (SrcW <= 0) or (Srch <= 0) then
+ begin
+ SrcX := 0;
+ SrcY := 0;
+ SrcW := Bitmap.Width;
+ Srch := Bitmap.Height;
+ end;
+ if not Bitmap.Monochrome then
+ SetStretchBltMode(Dest.Handle, STRETCH_DELETESCANS);
+ CanvasChanging := Bitmap.Canvas.OnChanging;
+ Bitmap.Canvas.Lock;
+ try
+ Bitmap.Canvas.OnChanging := nil;
+ if TransparentColor = clNone then
+ begin
+ StretchBlt(Dest.Handle, DstX, DstY, DstW, DstH, Bitmap.Canvas.Handle,
+ SrcX, SrcY, SrcW, Srch, Cardinal(Dest.CopyMode));
+ end
+ else
+ begin
+ if TransparentColor = clDefault then
+ TransparentColor := Bitmap.Canvas.Pixels[0, Bitmap.Height - 1];
+ if Bitmap.Monochrome then
+ TransparentColor := clWhite
+ else
+ TransparentColor := ColorToRGB(TransparentColor);
+ StretchBltTransparent(Dest.Handle, DstX, DstY, DstW, DstH,
+ Bitmap.Canvas.Handle, SrcX, SrcY, SrcW, Srch,
+ Bitmap.Palette, TransparentColor);
+ end;
+ finally
+ Bitmap.Canvas.OnChanging := CanvasChanging;
+ Bitmap.Canvas.Unlock;
+ end;
+end;
+
+procedure StretchBitmapRectTransparent(Dest: TCanvas; DstX, DstY,
+ DstW, DstH: Integer; SrcRect: TRect; Bitmap: TBitmap;
+ TransparentColor: TColor);
+begin
+ with SrcRect do
+ StretchBitmapTransparent(Dest, Bitmap, TransparentColor,
+ DstX, DstY, DstW, DstH, Left, Top, Right - Left, Bottom - Top);
+end;
+
+procedure DrawBitmapRectTransparent(Dest: TCanvas; DstX, DstY: Integer;
+ SrcRect: TRect; Bitmap: TBitmap; TransparentColor: TColor);
+begin
+ with SrcRect do
+ StretchBitmapTransparent(Dest, Bitmap, TransparentColor,
+ DstX, DstY, Right - Left, Bottom - Top, Left, Top, Right - Left,
+ Bottom - Top);
+end;
+
+procedure DrawBitmapTransparent(Dest: TCanvas; DstX, DstY: Integer;
+ Bitmap: TBitmap; TransparentColor: TColor);
+begin
+ StretchBitmapTransparent(Dest, Bitmap, TransparentColor, DstX, DstY,
+ Bitmap.Width, Bitmap.Height, 0, 0, Bitmap.Width, Bitmap.Height);
+end;
+
+{ CreateDisabledBitmap. Creating TBitmap object with disable button glyph
+ image. You must destroy it outside by calling TBitmap.Free method. }
+
+function CreateDisabledBitmap_NewStyle(FOriginal: TBitmap; BackColor: TColor):
+ TBitmap;
+var
+ MonoBmp: TBitmap;
+ R: TRect;
+ DestDC, SrcDC: HDC;
+begin
+ R := Rect(0, 0, FOriginal.Width, FOriginal.Height);
+ Result := TBitmap.Create;
+ try
+ Result.Width := FOriginal.Width;
+ Result.Height := FOriginal.Height;
+ Result.Canvas.Brush.Color := BackColor;
+ Result.Canvas.FillRect(R);
+
+ MonoBmp := TBitmap.Create;
+ try
+ MonoBmp.Width := FOriginal.Width;
+ MonoBmp.Height := FOriginal.Height;
+ MonoBmp.Canvas.Brush.Color := clWhite;
+ MonoBmp.Canvas.FillRect(R);
+ DrawBitmapTransparent(MonoBmp.Canvas, 0, 0, FOriginal, BackColor);
+ MonoBmp.Monochrome := True;
+
+ SrcDC := MonoBmp.Canvas.Handle;
+ { Convert Black to clBtnHighlight }
+ Result.Canvas.Brush.Color := clBtnHighlight;
+ DestDC := Result.Canvas.Handle;
+ SetTextColor(DestDC, clWhite);
+ SetBkColor(DestDC, clBlack);
+ BitBlt(DestDC, 1, 1, FOriginal.Width, FOriginal.Height, SrcDC, 0, 0,
+ ROP_DSPDxax);
+ { Convert Black to clBtnShadow }
+ Result.Canvas.Brush.Color := clBtnShadow;
+ DestDC := Result.Canvas.Handle;
+ SetTextColor(DestDC, clWhite);
+ SetBkColor(DestDC, clBlack);
+ BitBlt(DestDC, 0, 0, FOriginal.Width, FOriginal.Height, SrcDC, 0, 0,
+ ROP_DSPDxax);
+ finally
+ MonoBmp.Free;
+ end;
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+
+function CreateDisabledBitmapEx(FOriginal: TBitmap; OutlineColor, BackColor,
+ HighLightColor, ShadowColor: TColor; DrawHighlight: Boolean): TBitmap;
+var
+ MonoBmp: TBitmap;
+ IRect: TRect;
+begin
+ IRect := Rect(0, 0, FOriginal.Width, FOriginal.Height);
+ Result := TBitmap.Create;
+ try
+ Result.Width := FOriginal.Width;
+ Result.Height := FOriginal.Height;
+ MonoBmp := TBitmap.Create;
+ try
+ with MonoBmp do
+ begin
+ Width := FOriginal.Width;
+ Height := FOriginal.Height;
+ Canvas.CopyRect(IRect, FOriginal.Canvas, IRect);
+ HandleType := bmDDB;
+ Canvas.Brush.Color := OutlineColor;
+ if Monochrome then
+ begin
+ Canvas.Font.Color := clWhite;
+ Monochrome := False;
+ Canvas.Brush.Color := clWhite;
+ end;
+ Monochrome := True;
+ end;
+ with Result.Canvas do
+ begin
+ Brush.Color := BackColor;
+ FillRect(IRect);
+ if DrawHighlight then
+ begin
+ Brush.Color := HighLightColor;
+ SetTextColor(Handle, clBlack);
+ SetBkColor(Handle, clWhite);
+ BitBlt(Handle, 1, 1, RectWidth(IRect), RectHeight(IRect),
+ MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
+ end;
+ Brush.Color := ShadowColor;
+ SetTextColor(Handle, clBlack);
+ SetBkColor(Handle, clWhite);
+ BitBlt(Handle, 0, 0, RectWidth(IRect), RectHeight(IRect),
+ MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
+ end;
+ finally
+ MonoBmp.Free;
+ end;
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+
+function CreateDisabledBitmap(FOriginal: TBitmap; OutlineColor: TColor):
+ TBitmap;
+begin
+ Result := CreateDisabledBitmapEx(FOriginal, OutlineColor,
+ clBtnFace, clBtnHighlight, clBtnShadow, True);
+end;
+
+{ ChangeBitmapColor. This function create new TBitmap object.
+ You must destroy it outside by calling TBitmap.Free method. }
+
+function ChangeBitmapColor(Bitmap: TBitmap; Color, NewColor: TColor): TBitmap;
+var
+ R: TRect;
+begin
+ Result := TBitmap.Create;
+ try
+ with Result do
+ begin
+ Height := Bitmap.Height;
+ Width := Bitmap.Width;
+ R := Bounds(0, 0, Width, Height);
+ with Canvas do
+ begin
+ Brush.Color := NewColor;
+ FillRect(R);
+ BrushCopy( R, Bitmap, R, Color);
+ end;
+ end;
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+
+procedure ImageListDrawDisabled(Images: TCustomImageList; Canvas: TCanvas;
+ X, Y, Index: Integer; HighLightColor, GrayColor: TColor;
+ DrawHighlight: Boolean);
+var
+ Bmp: TBitmap;
+ SaveColor: TColor;
+begin
+ SaveColor := Canvas.Brush.Color;
+ Bmp := TBitmap.Create;
+ try
+ Bmp.Width := Images.Width;
+ Bmp.Height := Images.Height;
+ with Bmp.Canvas do
+ begin
+ Brush.Color := clWhite;
+ FillRect(Rect(0, 0, Images.Width, Images.Height));
+ ImageList_Draw(Images.Handle, Index, Handle, 0, 0, ILD_MASK);
+ end;
+ Bmp.Monochrome := True;
+ if DrawHighlight then
+ begin
+ Canvas.Brush.Color := HighLightColor;
+ SetTextColor(Canvas.Handle, clWhite);
+ SetBkColor(Canvas.Handle, clBlack);
+ BitBlt(Canvas.Handle, X + 1, Y + 1, Images.Width,
+ Images.Height, Bmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
+ end;
+ Canvas.Brush.Color := GrayColor;
+ SetTextColor(Canvas.Handle, clWhite);
+ SetBkColor(Canvas.Handle, clBlack);
+ BitBlt(Canvas.Handle, X, Y, Images.Width,
+ Images.Height, Bmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
+ finally
+ Bmp.Free;
+ Canvas.Brush.Color := SaveColor;
+ end;
+end;
+
+{ Brush Pattern }
+
+function CreateTwoColorsBrushPattern(Color1, Color2: TColor): TBitmap;
+var
+ X, Y: Integer;
+begin
+ Result := TBitmap.Create;
+ Result.Width := 8;
+ Result.Height := 8;
+ with Result.Canvas do
+ begin
+ Brush.Style := bsSolid;
+ Brush.Color := Color1;
+ FillRect(Rect(0, 0, Result.Width, Result.Height));
+ for Y := 0 to 7 do
+ for X := 0 to 7 do
+ if (Y mod 2) = (X mod 2) then { toggles between even/odd pixles }
+ Pixels[X, Y] := Color2; { on even/odd rows }
+ end;
+end;
+
+{ Icons }
+
+{$IFNDEF CLR}
+function MakeIcon(ResID: PChar): TIcon;
+begin
+ Result := MakeModuleIcon(HInstance, ResID);
+end;
+
+function MakeIconID(ResID: Word): TIcon;
+begin
+ Result := MakeModuleIcon(HInstance, MakeIntResource(ResID));
+end;
+
+function MakeModuleIcon(Module: THandle; ResID: PChar): TIcon;
+begin
+ Result := TIcon.Create;
+ Result.Handle := LoadIcon(Module, ResID);
+ if Result.Handle = 0 then
+ begin
+ Result.Free;
+ Result := nil;
+ end;
+end;
+{$ENDIF !CLR}
+
+{ Create TBitmap object from TIcon }
+
+function CreateBitmapFromIcon(Icon: TIcon; BackColor: TColor): TBitmap;
+var
+ IWidth, IHeight: Integer;
+begin
+ IWidth := Icon.Width;
+ IHeight := Icon.Height;
+ Result := TBitmap.Create;
+ try
+ Result.Width := IWidth;
+ Result.Height := IHeight;
+ with Result.Canvas do
+ begin
+ Brush.Color := BackColor;
+ FillRect(Rect(0, 0, IWidth, IHeight));
+ Draw(0, 0, Icon);
+ end;
+ Result.TransparentColor := BackColor;
+ Result.Transparent := True;
+ except
+ Result.Free;
+ raise;
+ end;
+end;
+
+function CreateIconFromBitmap(Bitmap: TBitmap; TransparentColor: TColor): TIcon;
+
+begin
+ with TImageList.CreateSize(Bitmap.Width, Bitmap.Height) do
+ try
+ if TransparentColor = clDefault then
+ TransparentColor := Bitmap.TransparentColor;
+ AllocBy := 1;
+ AddMasked(Bitmap, TransparentColor);
+ Result := TIcon.Create;
+ try
+ GetIcon(0, Result);
+ except
+ Result.Free;
+ raise;
+ end;
+ finally
+ Free;
+ end;
+end;
+
+type
+ TCustomControlAccessProtected = class(TCustomControl);
+
+
+
+procedure PaintInverseRect(const RectOrg, RectEnd: TPoint);
+var
+ DC: Windows.HDC;
+ R: TRect;
+begin
+ DC := Windows.GetDC(HWND_DESKTOP);
+ try
+ R := Rect(RectOrg.X, RectOrg.Y, RectEnd.X, RectEnd.Y);
+ Windows.InvertRect(DC, R);
+ finally
+ Windows.ReleaseDC(HWND_DESKTOP, DC);
+ end;
+end;
+
+procedure DrawInvertFrame(ScreenRect: TRect; Width: Integer);
+var
+ DC: Windows.HDC;
+ I: Integer;
+begin
+ DC := Windows.GetDC(HWND_DESKTOP);
+ try
+ for I := 1 to Width do
+ begin
+ Windows.DrawFocusRect(DC, ScreenRect);
+ //InflateRect(ScreenRect, -1, -1);
+ end;
+ finally
+ Windows.ReleaseDC(HWND_DESKTOP, DC);
+ end;
+end;
+
+
+
+
+
+function PointInPolyRgn(const P: TPoint; const Points: array of TPoint):
+ Boolean;
+{$IFNDEF CLR}
+type
+ PPoints = ^TPoints;
+ TPoints = array [0..0] of TPoint;
+{$ENDIF CLR}
+var
+ Rgn: HRGN;
+begin
+ {$IFDEF CLR}
+ Rgn := CreatePolygonRgn(Points, Length(Points), WINDING);
+ {$ELSE}
+ Rgn := CreatePolygonRgn(PPoints(@Points)^, High(Points) + 1, WINDING);
+ {$ENDIF CLR}
+ try
+ Result := PtInRegion(Rgn, P.X, P.Y);
+ finally
+ DeleteObject(Rgn);
+ end;
+end;
+
+function PaletteColor(Color: TColor): Longint;
+begin
+ Result := ColorToRGB(Color) or PaletteMask;
+end;
+
+
+
+function CreateRotatedFont(Font: TFont; Angle: Integer): HFONT;
+var
+ LogFont: TLogFont;
+begin
+ {$IFNDEF CLR}
+ FillChar(LogFont, SizeOf(LogFont), 0);
+ {$ENDIF !CLR}
+ with LogFont do
+ begin
+ lfHeight := Font.Height;
+ lfWidth := 0;
+ lfEscapement := Angle * 10;
+ lfOrientation := 0;
+ if fsBold in Font.Style then
+ lfWeight := FW_BOLD
+ else
+ lfWeight := FW_NORMAL;
+ lfItalic := Ord(fsItalic in Font.Style);
+ lfUnderline := Ord(fsUnderline in Font.Style);
+ lfStrikeOut := Byte(fsStrikeOut in Font.Style);
+ lfCharSet := Byte(Font.Charset);
+ {$IFDEF CLR}
+ if SameText(Font.Name, 'Default') then
+ lfFaceName := DefFontData.Name
+ else
+ lfFaceName := Font.Name;
+ {$ELSE}
+ if SameText(Font.Name, 'Default') then
+ StrPCopy(lfFaceName, DefFontData.Name)
+ else
+ StrPCopy(lfFaceName, Font.Name);
+ {$ENDIF CLR}
+ lfQuality := DEFAULT_QUALITY;
+ lfOutPrecision := OUT_TT_PRECIS;
+ lfClipPrecision := CLIP_DEFAULT_PRECIS;
+ case Font.Pitch of
+ fpVariable:
+ lfPitchAndFamily := VARIABLE_PITCH;
+ fpFixed:
+ lfPitchAndFamily := FIXED_PITCH;
+ else
+ lfPitchAndFamily := DEFAULT_PITCH;
+ end;
+ end;
+ Result := CreateFontIndirect(LogFont);
+end;
+
+function PaletteEntries(Palette: HPALETTE): Integer;
+begin
+ {$IFDEF CLR}
+ GetObject(Palette, 4, Result);
+ {$ELSE}
+ GetObject(Palette, SizeOf(Integer), @Result);
+ {$ENDIF CLR}
+end;
+
+
+procedure Delay(MSecs: Int64);
+var
+ FirstTickCount, Now: Int64;
+begin
+ FirstTickCount := GetTickCount64;
+ repeat
+ Application.ProcessMessages;
+ { allowing access to other controls, etc. }
+ Now := GetTickCount64;
+ until (Now - FirstTickCount >= MSecs);
+end;
+
+function GetTickCount64: Int64;
+var
+ QFreq, QCount: Int64;
+begin
+ Result := GetTickCount;
+ if QueryPerformanceFrequency(QFreq) then
+ begin
+ QueryPerformanceCounter(QCount);
+ if QFreq <> 0 then
+ Result := (QCount div QFreq) * 1000;
+ end;
+end;
+
+procedure CenterControl(Control: TControl);
+var
+ X, Y: Integer;
+begin
+ X := Control.Left;
+ Y := Control.Top;
+ if Control is TForm then
+ begin
+ with Control do
+ begin
+ if (TForm(Control).FormStyle = fsMDIChild) and
+ (Application.MainForm <> nil) then
+ begin
+ X := (Application.MainForm.ClientWidth - Width) div 2;
+ Y := (Application.MainForm.ClientHeight - Height) div 2;
+ end
+ else
+ begin
+ X := (Screen.Width - Width) div 2;
+ Y := (Screen.Height - Height) div 2;
+ end;
+ end;
+ end
+ else
+ if Control.Parent <> nil then
+ begin
+ with Control do
+ begin
+ Parent.HandleNeeded;
+ X := (Parent.ClientWidth - Width) div 2;
+ Y := (Parent.ClientHeight - Height) div 2;
+ end;
+ end;
+ if X < 0 then
+ X := 0;
+ if Y < 0 then
+ Y := 0;
+ with Control do
+ SetBounds(X, Y, Width, Height);
+end;
+
+procedure MergeForm(AControl: TWinControl; AForm: TForm; Align: TAlign;
+ Show: Boolean);
+var
+ R: TRect;
+ AutoScroll: Boolean;
+begin
+ AutoScroll := AForm.AutoScroll;
+ AForm.Hide;
+ {$IFDEF CLR}
+ AForm.GetType.InvokeMember('DestroyHandle',
+ BindingFlags.NonPublic or BindingFlags.InvokeMethod or BindingFlags.Instance,
+ nil, AForm, []);
+ {$ELSE}
+ TCustomControlAccessProtected(AForm).DestroyHandle;
+ {$ENDIF CLR}
+ with AForm do
+ begin
+ BorderStyle := bsNone;
+ BorderIcons := [];
+ Parent := AControl;
+ end;
+ AControl.DisableAlign;
+ try
+ if Align <> alNone then
+ AForm.Align := Align
+ else
+ begin
+ R := AControl.ClientRect;
+ AForm.SetBounds(R.Left + AForm.Left, R.Top + AForm.Top, AForm.Width,
+ AForm.Height);
+ end;
+ AForm.AutoScroll := AutoScroll;
+ AForm.Visible := Show;
+ finally
+ AControl.EnableAlign;
+ end;
+end;
+
+
+{ ShowMDIClientEdge function has been copied from Inprise's FORMS.PAS unit,
+ Delphi 4 version }
+
+procedure ShowMDIClientEdge(ClientHandle: THandle; ShowEdge: Boolean);
+var
+ Style: Longint;
+begin
+ if ClientHandle <> 0 then
+ begin
+ Style := GetWindowLong(ClientHandle, GWL_EXSTYLE);
+ if ShowEdge then
+ if Style and WS_EX_CLIENTEDGE = 0 then
+ Style := Style or WS_EX_CLIENTEDGE
+ else
+ Exit
+ else
+ if Style and WS_EX_CLIENTEDGE <> 0 then
+ Style := Style and not WS_EX_CLIENTEDGE
+ else
+ Exit;
+ SetWindowLong(ClientHandle, GWL_EXSTYLE, Style);
+ SetWindowPos(ClientHandle, 0, 0, 0, 0, 0,
+ SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
+ end;
+end;
+
+{ Shade rectangle }
+
+procedure ShadeRect(DC: HDC; const Rect: TRect);
+const
+ HatchBits: array [0..7] of Word = ($11, $22, $44, $88, $11, $22, $44, $88);
+var
+ Bitmap: HBITMAP;
+ SaveBrush: HBRUSH;
+ SaveTextColor, SaveBkColor: TColorRef;
+ {$IFDEF CLR}
+ Mem: IntPtr;
+ {$ENDIF CLR}
+begin
+ {$IFDEF CLR}
+ Marshal.AllocHGlobal(Length(HatchBits));
+ try
+ Marshal.StructureToPtr(HatchBits, Mem, True);
+ Bitmap := CreateBitmap(8, 8, 1, 1, Mem);
+ finally
+ Marshal.DestroyStructure(Mem, TypeOf(HatchBits));
+ end;
+ {$ELSE}
+ Bitmap := CreateBitmap(8, 8, 1, 1, @HatchBits);
+ {$ENDIF CLR}
+ SaveBrush := SelectObject(DC, CreatePatternBrush(Bitmap));
+ try
+ SaveTextColor := SetTextColor(DC, clWhite);
+ SaveBkColor := SetBkColor(DC, clBlack);
+ with Rect do
+ PatBlt(DC, Left, Top, Right - Left, Bottom - Top, $00A000C9);
+ SetBkColor(DC, SaveBkColor);
+ SetTextColor(DC, SaveTextColor);
+ finally
+ DeleteObject(SelectObject(DC, SaveBrush));
+ DeleteObject(Bitmap);
+ end;
+end;
+
+
+function ScreenWorkArea: TRect;
+begin
+ {$IFDEF MSWINDOWS}
+ if not SystemParametersInfo(SPI_GETWORKAREA, 0, {$IFNDEF CLR}@{$ENDIF}Result, 0) then
+ {$ENDIF MSWINDOWS}
+ with Screen do
+ Result := Bounds(0, 0, Width, Height);
+end;
+
+{ Standard Windows MessageBox function }
+
+function MsgBox(const Caption, Text: string; Flags: Integer): Integer;
+
+begin
+ {$IFDEF CLR}
+ Result := Application.MessageBox(Text, Caption, Flags);
+ {$ELSE}
+ Result := Application.MessageBox(PChar(Text), PChar(Caption), Flags);
+ {$ENDIF CLR}
+end;
+
+
+
+function MsgDlg(const Msg: string; AType: TMsgDlgType; AButtons: TMsgDlgButtons;
+ HelpCtx: Longint): Word;
+begin
+ Result := MessageDlg(Msg, AType, AButtons, HelpCtx);
+end;
+
+
+function MsgBox(Handle: THandle; const Caption, Text: string; Flags: Integer): Integer;
+begin
+ {$IFDEF CLR}
+ Result := Windows.MessageBox(Handle, Text, Caption, Flags);
+ {$ELSE}
+ {$IFDEF MSWINDOWS}
+ Result := Windows.MessageBox(Handle, PChar(Text), PChar(Caption), Flags);
+ {$ENDIF MSWINDOWS}
+ {$IFDEF UNIX}
+ Result := MsgBox(Caption, Text, Flags);
+ {$ENDIF UNIX}
+ {$ENDIF CLR}
+end;
+*******************)
+
+{ Gradient fill procedure - displays a gradient beginning with a chosen }
+{ color and ending with another chosen color. Based on TGradientFill }
+{ component source code written by Curtis White, cwhite att teleport dott com. }
+
+procedure GradientFillRect(Canvas: TCanvas; ARect: TRect; StartColor,
+ EndColor: TColor; Direction: TFillDirection; Colors: Byte);
+// 25.09.2007 - SESS - Implemented using TCanvas.GradientFill(),
+// "Colors" parameter just ignored
+var
+ gd: TGradientDirection;
+ c: TColor;
+begin
+ case Direction of
+ fdTopToBottom:
+ gd := gdVertical;
+ fdBottomToTop:
+ begin
+ gd := gdVertical;
+ c := StartColor;
+ StartColor := EndColor;
+ EndColor := c;
+ end;
+ fdLeftToRight:
+ gd := gdHorizontal;
+ fdRightToLeft:
+ begin
+ gd := gdHorizontal;
+ c := StartColor;
+ StartColor := EndColor;
+ EndColor := c;
+ end;
+ end;
+ Canvas.GradientFill(ARect, StartColor, EndColor, gd);
+end;
+
+(******************** NOT CONVERTED
+function GetAveCharSize(Canvas: TCanvas): TPoint;
+var
+ I: Integer;
+ Buffer: array [0..51] of Char;
+ {$IFDEF CLR}
+ Size: TSize;
+ {$ENDIF CLR}
+begin
+ for I := 0 to 25 do
+ Buffer[I] := Chr(I + Ord('A'));
+ for I := 0 to 25 do
+ Buffer[I + 26] := Chr(I + Ord('a'));
+ {$IFDEF CLR}
+ GetTextExtentPoint32(Canvas.Handle, Buffer, 52, Size);
+ Result.X := Size.cx;
+ Result.Y := Size.cy;
+ {$ELSE}
+ GetTextExtentPoint32(Canvas.Handle, Buffer, 52, TSize(Result));
+ {$ENDIF CLR}
+ Result.X := Result.X div 52;
+end;
+
+{ Cursor routines }
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+function LoadAniCursor(Instance: THandle; ResID: PChar): HCURSOR;
+{ Unfortunately I don't know how we can load animated cursor from
+ executable resource directly. So I write this routine using temporary
+ file and LoadCursorFromFile function. }
+var
+ S: TFileStream;
+ Path, FileName: array[0..MAX_PATH] of Char;
+ RSrc: HRSRC;
+ Res: THandle;
+ Data: Pointer;
+begin
+ Integer(Result) := 0;
+ RSrc := FindResource(Instance, ResID, RT_ANICURSOR);
+ if RSrc <> 0 then
+ begin
+ OSCheck(GetTempPath(MAX_PATH, Path) <> 0);
+ OSCheck(GetTempFileName(Path, 'ANI', 0, FileName) <> 0);
+ try
+ Res := LoadResource(Instance, RSrc);
+ try
+ Data := LockResource(Res);
+ if Data <> nil then
+ try
+ S := TFileStream.Create(StrPas(FileName), fmCreate);
+ try
+ S.WriteBuffer(Data^, SizeOfResource(Instance, RSrc));
+ finally
+ S.Free;
+ end;
+ Result := LoadCursorFromFile(FileName);
+ finally
+ UnlockResource(Res);
+ end;
+ finally
+ FreeResource(Res);
+ end;
+ finally
+ Windows.DeleteFile(FileName);
+ end;
+ end;
+end;
+{$ENDIF MSWINDOWS}
+{$ENDIF !CLR}
+
+function GetNextFreeCursorIndex(StartHint: Integer; PreDefined: Boolean):
+ Integer;
+begin
+ Result := StartHint;
+ if PreDefined then
+ begin
+ if Result >= crSizeAll then
+ Result := crSizeAll - 1;
+ end
+ else
+ if Result <= crDefault then
+ Result := crDefault + 1;
+ while (Screen.Cursors[Result] <> Screen.Cursors[crDefault]) do
+ begin
+ if PreDefined then
+ Dec(Result)
+ else
+ Inc(Result);
+ if (Result < Low(TCursor)) or (Result > High(TCursor)) then
+ {$IFDEF CLR}
+ raise EOutOfResources.Create(SOutOfResources);
+ {$ELSE}
+ raise EOutOfResources.CreateRes(@SOutOfResources);
+ {$ENDIF CLR}
+ end;
+end;
+
+{$IFNDEF CLR}
+function DefineCursor(Instance: THandle; ResID: PChar): TCursor;
+var
+ Handle: HCURSOR;
+begin
+ Handle := LoadCursor(Instance, ResID);
+ if Handle = 0 then
+ Handle := LoadAniCursor(Instance, ResID);
+ if Integer(Handle) = 0 then
+ ResourceNotFound(ResID);
+ try
+ Result := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[Result] := Handle;
+ except
+ DestroyCursor(Handle);
+ raise;
+ end;
+end;
+{$ENDIF !CLR}
+
+var
+ WaitCount: Integer = 0;
+ SaveCursor: TCursor = crDefault;
+
+const
+ FWaitCursor: TCursor = crHourGlass;
+
+procedure StartWait;
+begin
+ if WaitCount = 0 then
+ begin
+ SaveCursor := Screen.Cursor;
+ Screen.Cursor := FWaitCursor;
+ end;
+ Inc(WaitCount);
+end;
+
+procedure StopWait;
+begin
+ if WaitCount > 0 then
+ begin
+ Dec(WaitCount);
+ if WaitCount = 0 then
+ Screen.Cursor := SaveCursor;
+ end;
+end;
+
+function WaitCursor: IInterface;
+begin
+ Result := ScreenCursor(crHourGlass);
+end;
+
+function ScreenCursor(ACursor: TCursor): IInterface;
+begin
+ Result := TWaitCursor.Create(ACursor);
+end;
+
+{$IFDEF MSWINDOWS}
+
+var
+ OLEDragCursorsLoaded: Boolean = False;
+
+function LoadOLEDragCursors: Boolean;
+{$IFDEF CLR}
+type
+ PChar = Integer;
+{$ENDIF CLR}
+const
+ cOle32DLL = 'ole32.dll';
+var
+ Handle: Cardinal;
+begin
+ if OLEDragCursorsLoaded then
+ begin
+ Result := True;
+ Exit;
+ end;
+ OLEDragCursorsLoaded := True;
+
+ Result := False;
+ if Screen <> nil then
+ begin
+ Handle := GetModuleHandle(cOle32DLL);
+ if Handle = 0 then
+ Handle := LoadLibraryEx(cOle32DLL, 0, LOAD_LIBRARY_AS_DATAFILE);
+ if Handle <> 0 then // (p3) don't free the lib handle!
+ try
+ Screen.Cursors[crNoDrop] := LoadCursor(Handle, PChar(1));
+ Screen.Cursors[crDrag] := LoadCursor(Handle, PChar(2));
+ Screen.Cursors[crMultiDrag] := LoadCursor(Handle, PChar(3));
+ Screen.Cursors[crMultiDragLink] := LoadCursor(Handle, PChar(4));
+ Screen.Cursors[crDragAlt] := LoadCursor(Handle, PChar(5));
+ Screen.Cursors[crMultiDragAlt] := LoadCursor(Handle, PChar(6));
+ Screen.Cursors[crMultiDragLinkAlt] := LoadCursor(Handle, PChar(7));
+ Result := True;
+ except
+ end;
+ end;
+end;
+
+{$ENDIF MSWINDOWS}
+
+procedure SetDefaultJVCLCursors;
+begin
+ if Screen <> nil then
+ begin
+ // dynamically assign the first available cursor id to our cursor defines
+ crMultiDragLink := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crMultiDragLink] := Screen.Cursors[crMultiDrag];
+ crDragAlt := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crDragAlt] := Screen.Cursors[crDrag];
+ crMultiDragAlt := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crMultiDragAlt] := Screen.Cursors[crMultiDrag];
+ crMultiDragLinkAlt := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crMultiDragLinkAlt] := Screen.Cursors[crMultiDrag];
+ { begin RxLib }
+ crHand := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crHand] := LoadCursor(HInstance, 'JvHANDCURSOR');
+ crDragHand := GetNextFreeCursorIndex(crJVCLFirst, False);
+ Screen.Cursors[crDragHand] := LoadCursor(hInstance, 'JvDRAGCURSOR');
+ { end RxLib }
+ end;
+end;
+
+{ Grid drawing }
+
+var
+ DrawBitmap: TBitmap = nil;
+
+procedure UsesBitmap;
+begin
+ if DrawBitmap = nil then
+ DrawBitmap := TBitmap.Create;
+end;
+
+procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer;
+ const Text: string; Alignment: TAlignment; WordWrap: Boolean;
+ ARightToLeft: Boolean = False);
+const
+ AlignFlags: array [TAlignment] of Integer =
+ (DT_LEFT or DT_EXPANDTABS or DT_NOPREFIX,
+ DT_RIGHT or DT_EXPANDTABS or DT_NOPREFIX,
+ DT_CENTER or DT_EXPANDTABS or DT_NOPREFIX);
+ WrapFlags: array [Boolean] of Integer = (0, DT_WORDBREAK);
+
+ RTL: array [Boolean] of Integer = (0, DT_RTLREADING);
+var
+ B, R: TRect;
+ I, Left: Integer;
+begin
+ UsesBitmap;
+ I := ColorToRGB(ACanvas.Brush.Color);
+ if not WordWrap and (Integer(GetNearestColor(ACanvas.Handle, I)) = I) and
+ (Pos(Cr, Text) = 0) then
+ begin { Use ExtTextOut for solid colors }
+ { In BiDi, because we changed the window origin, the text that does not
+ change alignment, actually gets its alignment changed. }
+ if (ACanvas.CanvasOrientation = coRightToLeft) and (not ARightToLeft) then
+ ChangeBiDiModeAlignment(Alignment);
+ case Alignment of
+ taLeftJustify:
+ Left := ARect.Left + DX;
+ taRightJustify:
+ Left := ARect.Right - ACanvas.TextWidth(Text) - 3;
+ else { taCenter }
+ Left := ARect.Left + (ARect.Right - ARect.Left) shr 1 -
+ (ACanvas.TextWidth(Text) shr 1);
+ end;
+ ACanvas.TextRect(ARect, Left, ARect.Top + DY, Text);
+ end
+ else
+ begin { Use FillRect and DrawText for dithered colors }
+ DrawBitmap.Canvas.Lock;
+ try
+ with DrawBitmap, ARect do { Use offscreen bitmap to eliminate flicker and }
+ begin { brush origin tics in painting / scrolling. }
+ Width := Max(Width, Right - Left);
+ Height := Max(Height, Bottom - Top);
+ R := Rect(DX, DY, Right - Left - 1, Bottom - Top - 1);
+ B := Rect(0, 0, Right - Left, Bottom - Top);
+ end;
+ with DrawBitmap.Canvas do
+ begin
+ Font := ACanvas.Font;
+ Font.Color := ACanvas.Font.Color;
+ Brush := ACanvas.Brush;
+ Brush.Style := bsSolid;
+ FillRect(B);
+ SetBkMode(Handle, Transparent);
+ if (ACanvas.CanvasOrientation = coRightToLeft) then
+ ChangeBiDiModeAlignment(Alignment);
+ DrawText(DrawBitmap.Canvas, Text, Length(Text), R,
+ //Windows.DrawText(Handle, PChar(Text), Length(Text), R,
+ AlignFlags[Alignment] or RTL[ARightToLeft] or WrapFlags[WordWrap]);
+ end;
+ ACanvas.CopyRect(ARect, DrawBitmap.Canvas, B);
+ finally
+ DrawBitmap.Canvas.Unlock;
+ end;
+ end;
+end;
+
+procedure DrawCellTextEx(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; WordWrap: Boolean; ARightToLeft: Boolean); overload;
+const
+ MinOffs = 2;
+var
+ H: Integer;
+begin
+ case VertAlign of
+ vaTopJustify:
+ H := MinOffs;
+ vaCenterJustify:
+ with TCustomControlAccessProtected(Control) do
+ H := Max(1, (ARect.Bottom - ARect.Top - Canvas.TextHeight('W')) div 2);
+ else {vaBottomJustify}
+ begin
+ with TCustomControlAccessProtected(Control) do
+ H := Max(MinOffs, ARect.Bottom - ARect.Top - Canvas.TextHeight('W'));
+ end;
+ end;
+ WriteText(TCustomControlAccessProtected(Control).Canvas, ARect, MinOffs,
+ H, S, Align, WordWrap, ARightToLeft);
+end;
+
+procedure DrawCellText(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; ARightToLeft: Boolean); overload;
+begin
+ DrawCellTextEx(Control, ACol, ARow, S, ARect, Align, VertAlign,
+ Align = taCenter, ARightToLeft);
+end;
+
+procedure DrawCellTextEx(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment; WordWrap: Boolean); overload;
+const
+ MinOffs = 2;
+var
+ H: Integer;
+begin
+ case VertAlign of
+ vaTopJustify:
+ H := MinOffs;
+ vaCenterJustify:
+ with TCustomControlAccessProtected(Control) do
+ H := Max(1, (ARect.Bottom - ARect.Top - Canvas.TextHeight('W')) div 2);
+ else {vaBottomJustify}
+ begin
+ with TCustomControlAccessProtected(Control) do
+ H := Max(MinOffs, ARect.Bottom - ARect.Top - Canvas.TextHeight('W'));
+ end;
+ end;
+ WriteText(TCustomControlAccessProtected(Control).Canvas, ARect, MinOffs, H, S, Align, WordWrap);
+end;
+
+procedure DrawCellText(Control: TCustomControl; ACol, ARow: Longint;
+ const S: string; const ARect: TRect; Align: TAlignment;
+ VertAlign: TVertAlignment); overload;
+begin
+ DrawCellTextEx(Control, ACol, ARow, S, ARect, Align, VertAlign, Align = taCenter);
+end;
+
+procedure DrawCellBitmap(Control: TCustomControl; ACol, ARow: Longint;
+ Bmp: TGraphic; Rect: TRect);
+begin
+ Rect.Top := (Rect.Bottom + Rect.Top - Bmp.Height) div 2;
+ Rect.Left := (Rect.Right + Rect.Left - Bmp.Width) div 2;
+ TCustomControlAccessProtected(Control).Canvas.Draw(Rect.Left, Rect.Top, Bmp);
+end;
+
+//=== { TJvDesktopCanvas } ===================================================
+
+destructor TJvDesktopCanvas.Destroy;
+begin
+ FreeHandle;
+ inherited Destroy;
+end;
+
+procedure TJvDesktopCanvas.CreateHandle;
+begin
+ if FDC = 0 then
+ FDC := GetWindowDC(GetDesktopWindow);
+ Handle := FDC;
+end;
+
+procedure TJvDesktopCanvas.FreeHandle;
+begin
+ if FDC <> 0 then
+ begin
+ Handle := 0;
+ ReleaseDC(GetDesktopWindow, FDC);
+ FDC := 0;
+ end;
+end;
+
+procedure TJvDesktopCanvas.SetOrigin(X, Y: Integer);
+var
+ FOrigin: TPoint;
+begin
+ SetWindowOrgEx(Handle, -X, -Y, {$IFNDEF CLR}@{$ENDIF}FOrigin);
+end;
+
+// (rom) moved to file end to minimize W- switch impact at end of function
+
+{ end JvVCLUtils }
+{ begin JvUtils }
+
+function FindByTag(WinControl: TWinControl; ComponentClass: TComponentClass;
+ const Tag: Integer): TComponent;
+var
+ I: Integer;
+begin
+ for I := 0 to WinControl.ControlCount - 1 do
+ begin
+ Result := WinControl.Controls[I];
+ if (Result is ComponentClass) and (Result.Tag = Tag) then
+ Exit;
+ end;
+ Result := nil;
+end;
+
+function ControlAtPos2(Parent: TWinControl; X, Y: Integer): TControl;
+var
+ I: Integer;
+ P: TPoint;
+begin
+ P := Point(X, Y);
+ for I := Parent.ControlCount - 1 downto 0 do
+ begin
+ Result := Parent.Controls[I];
+ with Result do
+ if PtInRect(BoundsRect, P) then
+ Exit;
+ end;
+ Result := nil;
+end;
+
+function RBTag(Parent: TWinControl): Integer;
+var
+ RB: TRadioButton;
+ I: Integer;
+begin
+ RB := nil;
+ with Parent do
+ for I := 0 to ControlCount - 1 do
+ if (Controls[I] is TRadioButton) and
+ (Controls[I] as TRadioButton).Checked then
+ begin
+ RB := Controls[I] as TRadioButton;
+ Break;
+ end;
+ if RB <> nil then
+ Result := RB.Tag
+ else
+ Result := 0;
+end;
+
+function FindFormByClass(FormClass: TFormClass): TForm;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Application.ComponentCount - 1 do
+ if Application.Components[I].ClassName = FormClass.ClassName then
+ begin
+ Result := Application.Components[I] as TForm;
+ Break;
+ end;
+end;
+
+function FindFormByClassName(const FormClassName: string): TForm;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Application.ComponentCount - 1 do
+ if Application.Components[I].ClassName = FormClassName then
+ begin
+ Result := Application.Components[I] as TForm;
+ Break;
+ end;
+end;
+
+function AppMinimized: Boolean;
+begin
+ Result := IsIconic(GetAppHandle);
+end;
+
+{$IFDEF MSWINDOWS}
+
+{ Check if this is the active Windows task }
+{ Copied from implementation of FORMS.PAS }
+type
+ {$IFNDEF CLR}
+ PCheckTaskInfo = ^TCheckTaskInfo;
+ {$ENDIF !CLR}
+ TCheckTaskInfo = record
+ FocusWnd: Windows.HWND;
+ Found: Boolean;
+ end;
+{$IFDEF CLR}
+ PCheckTaskInfo = TCheckTaskInfo;
+
+var
+ CheckTaskHashLock: TObject = nil;
+ CheckTaskInfo: PCheckTaskInfo;
+{$ENDIF CLR}
+
+function CheckTaskWindow(Window: HWND; Data: Longint): LongBool; {$IFNDEF CLR}stdcall;{$ENDIF}
+begin
+ Result := True;
+ {$IFDEF CLR}
+ if CheckTaskInfo.FocusWnd = Window then
+ begin
+ CheckTaskInfo.Found := True;
+ {$ELSE}
+ if PCheckTaskInfo(Data).FocusWnd = Window then
+ begin
+ PCheckTaskInfo(Data).Found := True;
+ {$ENDIF CLR}
+ Result := False;
+ end;
+end;
+
+function IsForegroundTask: Boolean;
+var
+ Info: TCheckTaskInfo;
+begin
+ Info.FocusWnd := Windows.GetActiveWindow;
+ Info.Found := False;
+
+ {$IFDEF CLR}
+ if CheckTaskHashLock = nil then
+ CheckTaskHashLock := TObject.Create;
+ Monitor.Enter(CheckTaskHashLock);
+ try
+ CheckTaskInfo := Info;
+ EnumThreadWindows(GetCurrentThreadId, CheckTaskWindow, 0);
+ Info := CheckTaskInfo;
+ finally
+ Monitor.Exit(CheckTaskHashLock);
+ end;
+ {$ELSE}
+ EnumThreadWindows(GetCurrentThreadId, @CheckTaskWindow, Longint(@Info));
+ {$ENDIF CLR}
+ Result := Info.Found;
+end;
+
+{$ENDIF MSWINDOWS}
+
+{$IFDEF UNIX}
+function IsForegroundTask: Boolean;
+begin
+ Result := Application.Active;
+end;
+{$ENDIF UNIX}
+
+function MessageBox(const Msg, Caption: string; const Flags: Integer): Integer;
+{$IFDEF CLR}
+begin
+ if Caption = '' then
+ Result := Application.MessageBox(Msg, Caption, Flags)
+ else
+ Result := Application.MessageBox(Msg, Application.Title, Flags);
+end;
+{$ELSE}
+begin
+ if Caption = '' then
+ Result := Application.MessageBox(PChar(Msg), PChar(Caption), Flags)
+ else
+ Result := Application.MessageBox(PChar(Msg), PChar(Application.Title), Flags);
+end;
+{$ENDIF CLR}
+
+const
+ NoHelp = 0; { for MsgDlg2 }
+ MsgDlgCharSet: Integer = DEFAULT_CHARSET;
+
+function MsgDlgDef1(const Msg, ACaption: string; DlgType: TMsgDlgType;
+ Buttons: TMsgDlgButtons; DefButton: TMsgDlgBtn; UseDefButton: Boolean;
+ AHelpContext: Integer; Control: TWinControl): Integer;
+const
+ ButtonNames: array [TMsgDlgBtn] of string =
+ ('Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', 'All', 'NoToAll',
+ 'YesToAll', 'Help');
+var
+ P: TPoint;
+ I: Integer;
+ Btn: TButton;
+ StayOnTop: Boolean;
+begin
+ if AHelpContext <> 0 then
+ Buttons := Buttons + [mbHelp];
+ StayOnTop := False;
+ with CreateMessageDialog(Msg, DlgType, Buttons) do
+ try
+ Font.Charset := MsgDlgCharSet;
+ if (Screen.ActiveForm <> nil) and
+ (Screen.ActiveForm.FormStyle = fsStayOnTop) then
+ begin
+ StayOnTop := True;
+ SetWindowTop(Screen.ActiveForm.Handle, False);
+ end;
+ if ACaption <> '' then
+ Caption := ACaption;
+ if Control = nil then
+ begin
+ Left := (Screen.Width - Width) div 2;
+ Top := (Screen.Height - Height) div 2;
+ end
+ else
+ begin
+ P := Point((Control.Width - Width) div 2,
+ (Control.Height - Height) div 2);
+ P := Control.ClientToScreen(P);
+ Left := P.X;
+ Top := P.Y
+ end;
+ if Left < 0 then
+ Left := 0
+ else
+ if Left > Screen.Width then
+ Left := Screen.Width - Width;
+ if Top < 0 then
+ Top := 0
+ else
+ if Top > Screen.Height then
+ Top := Screen.Height - Height;
+ HelpContext := AHelpContext;
+
+ Btn := FindComponent(ButtonNames[DefButton]) as TButton;
+ if UseDefButton and (Btn <> nil) then
+ begin
+ for I := 0 to ComponentCount - 1 do
+ if Components[I] is TButton then
+ (Components[I] as TButton).Default := False;
+ Btn.Default := True;
+ ActiveControl := Btn;
+ end;
+ Btn := FindComponent(ButtonNames[mbIgnore]) as TButton;
+ if Btn <> nil then
+ begin
+ // Btn.Width := Btn.Width * 5 div 4; {To shift the Help button Help [translated] }
+ end;
+ Result := ShowModal;
+ finally
+ Free;
+ if (Screen.ActiveForm <> nil) and StayOnTop then
+ SetWindowTop(Screen.ActiveForm.Handle, True);
+ end;
+end;
+
+function MsgDlgDef(const Msg, ACaption: string; DlgType: TMsgDlgType;
+ Buttons: TMsgDlgButtons; DefButton: TMsgDlgBtn; HelpContext: Integer;
+ Control: TWinControl): Integer;
+begin
+ Result := MsgDlgDef1(Msg, ACaption, DlgType, Buttons, DefButton, True,
+ HelpContext, Control);
+end;
+
+function MsgDlg2(const Msg, ACaption: string; DlgType: TMsgDlgType;
+ Buttons: TMsgDlgButtons; HelpContext: Integer;
+ Control: TWinControl): Integer;
+begin
+ Result := MsgDlgDef1(Msg, ACaption, DlgType, Buttons, mbHelp, False,
+ HelpContext, Control);
+end;
+
+function MsgYesNo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+begin
+ Result := MsgBox(Handle, Caption, Msg, MB_YESNO or Flags) = IDYES;
+end;
+
+function MsgRetryCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+begin
+ Result := MsgBox(Handle, Caption, Msg, MB_RETRYCANCEL or Flags) = IDRETRY;
+end;
+
+function MsgAbortRetryIgnore(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer;
+begin
+ Result := MsgBox(Handle, Caption, Msg, MB_ABORTRETRYIGNORE or Flags);
+end;
+
+function MsgYesNoCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Integer;
+begin
+ Result := MsgBox(Handle, Caption, Msg, MB_YESNOCANCEL or Flags);
+end;
+
+function MsgOKCancel(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0): Boolean;
+begin
+ Result := MsgBox(Handle, Caption, Msg, MB_OKCANCEL or Flags) = IDOK;
+end;
+
+procedure MsgOK(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+begin
+ MsgBox(Handle, Caption, Msg, MB_OK or Flags);
+end;
+
+procedure MsgInfo(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+begin
+ MsgOK(Handle, Msg, Caption, MB_ICONINFORMATION or Flags);
+end;
+
+procedure MsgWarn(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+begin
+ MsgOK(Handle, Msg, Caption, MB_ICONWARNING or Flags);
+end;
+
+procedure MsgQuestion(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+begin
+ MsgOK(Handle, Msg, Caption, MB_ICONQUESTION or Flags);
+end;
+
+procedure MsgError(Handle: Integer; const Msg, Caption: string; Flags: DWORD = 0);
+begin
+ MsgOK(Handle, Msg, Caption, MB_ICONERROR or Flags);
+end;
+
+function FindIcon(hInstance: DWORD; const IconName: string): Boolean;
+begin
+ {$IFDEF CLR}
+ Result := (IconName <> '') and
+ (FindResource(hInstance, IconName, RT_GROUP_ICON) <> 0) or
+ (FindResource(hInstance, IconName, RT_ICON) <> 0)
+ {$ELSE}
+ if Win32Platform = VER_PLATFORM_WIN32_NT then
+ Result := (IconName <> '') and
+ (FindResourceW(hInstance, PWideChar(WideString(IconName)), PWideChar(RT_GROUP_ICON)) <> 0) or
+ (FindResourceW(hInstance, PWideChar(WideString(IconName)), PWideChar(RT_ICON)) <> 0)
+ else
+ Result := (IconName <> '') and
+ (FindResourceA(hInstance, PChar(IconName), RT_GROUP_ICON) <> 0) or
+ (FindResourceA(hInstance, PChar(IconName), RT_ICON) <> 0);
+ {$ENDIF CLR}
+end;
+
+{$IFNDEF CLR}
+type
+ TMsgBoxParamsRec = record
+ case Boolean of
+ False: (ParamsA: TMsgBoxParamsA);
+ True: (ParamsW: TMsgBoxParamsW);
+ end;
+{$ENDIF !CLR}
+
+procedure MsgAbout(Handle: Integer; const Msg, Caption: string; const IcoName: string = 'MAINICON'; Flags: DWORD = MB_OK);
+{$IFDEF CLR}
+var
+ Params: TMsgBoxParams;
+begin
+ Params.hInstance := hInstance;
+ with Params do
+ begin
+ cbSize := Marshal.SizeOf(Params);
+ hwndOwner := Handle;
+ lpszText := Msg;
+ lpszCaption := Caption;
+ dwStyle := Flags;
+ if FindIcon(hInstance, IcoName) then
+ begin
+ dwStyle := dwStyle or MB_USERICON;
+ lpszIcon := IcoName;
+ end
+ else
+ dwStyle := dwStyle or MB_ICONINFORMATION;
+ dwContextHelpId := 0;
+ lpfnMsgBoxCallback := nil;
+ dwLanguageId := GetUserDefaultLangID;
+ end;
+ MessageBoxIndirect(Params);
+end;
+{$ELSE}
+var
+ Params: TMsgBoxParamsRec;
+begin
+ if Win32Platform = VER_PLATFORM_WIN32_NT then
+ begin
+ Params.ParamsW.hInstance := hInstance;
+ with Params.ParamsW do
+ begin
+ cbSize := SizeOf(TMsgBoxParamsW);
+ hwndOwner := Handle;
+ lpszText := PWideChar(WideString(Msg));
+ lpszCaption := PWideChar(WideString(Caption));
+ dwStyle := Flags;
+ if FindIcon(hInstance, IcoName) then
+ begin
+ dwStyle := dwStyle or MB_USERICON;
+ lpszIcon := PWideChar(WideString(IcoName));
+ end
+ else
+ dwStyle := dwStyle or MB_ICONINFORMATION;
+ dwContextHelpId := 0;
+ lpfnMsgBoxCallback := nil;
+ dwLanguageId := GetUserDefaultLangID;
+ MessageBoxIndirectW(Params.ParamsW);
+ end
+ end
+ else
+ begin
+ Params.ParamsA.hInstance := hInstance;
+ with Params.ParamsA do
+ begin
+ cbSize := SizeOf(TMsgBoxParamsA);
+ hwndOwner := Handle;
+ lpszText := PChar(Msg);
+ lpszCaption := PChar(Caption);
+ dwStyle := Flags;
+ if FindIcon(hInstance, IcoName) then
+ begin
+ dwStyle := dwStyle or MB_USERICON;
+ lpszIcon := PChar(IcoName);
+ end
+ else
+ dwStyle := dwStyle or MB_ICONINFORMATION;
+ dwContextHelpId := 0;
+ lpfnMsgBoxCallback := nil;
+ dwLanguageId := GetUserDefaultLangID;
+ MessageBoxIndirectA(Params.ParamsA);
+ end;
+ end;
+end;
+{$ENDIF CLR}
+
+procedure LoadIcoToImage(ALarge, ASmall: ImgList.TCustomImageList; const NameRes: string);
+var
+ Ico: TIcon;
+begin
+ Ico := TIcon.Create;
+ if ALarge <> nil then
+ begin
+ {$IFDEF CLR}
+ Ico.Handle := LoadImage(HInstance, NameRes, IMAGE_ICON, 32, 32, 0);
+ {$ELSE}
+ Ico.Handle := LoadImage(HInstance, PChar(NameRes), IMAGE_ICON, 32, 32, 0);
+ {$ENDIF CLR}
+ ALarge.AddIcon(Ico);
+ end;
+ if ASmall <> nil then
+ begin
+ {$IFDEF CLR}
+ Ico.Handle := LoadImage(HInstance, NameRes, IMAGE_ICON, 16, 16, 0);
+ {$ELSE}
+ Ico.Handle := LoadImage(HInstance, PChar(NameRes), IMAGE_ICON, 16, 16, 0);
+ {$ENDIF CLR}
+ ASmall.AddIcon(Ico);
+ end;
+ Ico.Free;
+end;
+
+function DualInputQuery(const ACaption, Prompt1, Prompt2: string;
+ var AValue1, AValue2: string; PasswordChar: Char = #0): Boolean;
+var
+ AForm: TForm;
+ ALabel1, ALabel2: TLabel;
+ AEdit1, AEdit2: TEdit;
+ ASize, I: Integer;
+begin
+ Result := False;
+ AForm := CreateMessageDialog(Prompt1, mtCustom, [mbOK, mbCancel]);
+ ASize := 0;
+ if AForm <> nil then
+ try
+ AForm.Caption := ACaption;
+ ALabel1 := AForm.FindComponent('Message') as TLabel;
+ for I := 0 to AForm.ControlCount - 1 do
+ if AForm.Controls[I] is TButton then
+ TButton(AForm.Controls[I]).Anchors := [akRight, akBottom];
+ if ALabel1 <> nil then
+ begin
+ AEdit1 := TEdit.Create(AForm);
+ AEdit1.Left := ALabel1.Left;
+ AEdit1.Width := AForm.ClientWidth - AEdit1.Left * 2;
+ AEdit1.Top := ALabel1.Top + ALabel1.Height + 2;
+ AEdit1.Parent := AForm;
+ AEdit1.Anchors := [akLeft, akTop, akRight];
+ AEdit1.Text := AValue1;
+ ALabel1.Caption := Prompt1;
+ ALabel1.FocusControl := AEdit1;
+ Inc(ASize, AEdit1.Height + 2);
+
+ ALabel2 := TLabel.Create(AForm);
+ ALabel2.Left := ALabel1.Left;
+ ALabel2.Top := AEdit1.Top + AEdit1.Height + 7;
+ ALabel2.Caption := Prompt2;
+ ALabel2.Parent := AForm;
+ Inc(ASize, ALabel2.Height + 7);
+
+ AEdit2 := TEdit.Create(AForm);
+ AEdit2.Left := ALabel1.Left;
+ AEdit2.Width := AForm.ClientWidth - AEdit2.Left * 2;
+ AEdit2.Top := ALabel2.Top + ALabel2.Height + 2;
+ AEdit2.Parent := AForm;
+ AEdit2.Anchors := [akLeft, akTop, akRight];
+ AEdit2.Text := AValue1;
+ if PasswordChar <> #0 then
+ AEdit2.PasswordChar := PasswordChar;
+ ALabel2.FocusControl := AEdit2;
+
+ Inc(ASize, AEdit2.Height + 8);
+ AForm.ClientHeight := AForm.ClientHeight + ASize;
+ AForm.ClientWidth := 320;
+ AForm.ActiveControl := AEdit1;
+ Result := AForm.ShowModal = mrOk;
+ if Result then
+ begin
+ AValue1 := AEdit1.Text;
+ AValue2 := AEdit2.Text;
+ end;
+ end;
+ finally
+ AForm.Free;
+ end;
+end;
+
+function InputQueryPassword(const ACaption, APrompt: string; PasswordChar: Char; var Value: string): Boolean;
+var
+ AForm: TForm;
+ ALabel: TLabel;
+ AEdit: TEdit;
+ ASize: Integer;
+begin
+ Result := False;
+ AForm := CreateMessageDialog(APrompt, mtCustom, [mbOK, mbCancel]);
+ if AForm <> nil then
+ try
+ AForm.Caption := ACaption;
+ ALabel := AForm.FindComponent('Message') as TLabel;
+ for ASize := 0 to AForm.ControlCount - 1 do
+ if AForm.Controls[ASize] is TButton then
+ TButton(AForm.Controls[ASize]).Anchors := [akRight, akBottom];
+ ASize := 0;
+ if ALabel <> nil then
+ begin
+ AEdit := TEdit.Create(AForm);
+ AEdit.Left := ALabel.Left;
+ AEdit.Width := AForm.ClientWidth - AEdit.Left * 2;
+ AEdit.Top := ALabel.Top + ALabel.Height + 2;
+ AEdit.Parent := AForm;
+ AEdit.Anchors := [akLeft, akTop, akRight];
+ AEdit.Text := Value;
+ AEdit.PasswordChar := PasswordChar;
+ ALabel.Caption := APrompt;
+ ALabel.FocusControl := AEdit;
+ Inc(ASize, AEdit.Height + 2);
+
+ AForm.ClientHeight := AForm.ClientHeight + ASize;
+ AForm.ClientWidth := 320;
+ AForm.ActiveControl := AEdit;
+ Result := AForm.ShowModal = mrOk;
+ if Result then
+ Value := AEdit.Text;
+ end;
+ finally
+ AForm.Free;
+ end;
+end;
+
+
+procedure CenterHor(Parent: TControl; MinLeft: Integer; Controls: array of TControl);
+var
+ I: Integer;
+begin
+ for I := Low(Controls) to High(Controls) do
+ Controls[I].Left := Max(MinLeft, (Parent.Width - Controls[I].Width) div 2);
+end;
+
+procedure EnableControls(Control: TWinControl; const Enable: Boolean);
+var
+ I: Integer;
+begin
+ for I := 0 to Control.ControlCount - 1 do
+ Control.Controls[I].Enabled := Enable;
+end;
+
+procedure EnableMenuItems(MenuItem: TMenuItem; const Tag: Integer; const Enable: Boolean);
+var
+ I: Integer;
+begin
+ for I := 0 to MenuItem.Count - 1 do
+ if MenuItem[I].Tag <> Tag then
+ MenuItem[I].Enabled := Enable;
+end;
+
+procedure ExpandWidth(Parent: TControl; MinWidth: Integer; Controls: array of TControl);
+var
+ I: Integer;
+begin
+ for I := Low(Controls) to High(Controls) do
+ Controls[I].Width := Max(MinWidth, Parent.ClientWidth - 2 * Controls[I].Left);
+end;
+
+function PanelBorder(Panel: TCustomPanel): Integer;
+begin
+ Result := TPanel(Panel).BorderWidth;
+ if TPanel(Panel).BevelOuter <> bvNone then
+ Inc(Result, TPanel(Panel).BevelWidth);
+ if TPanel(Panel).BevelInner <> bvNone then
+ Inc(Result, TPanel(Panel).BevelWidth);
+end;
+
+function Pixels(Control: TControl; APixels: Integer): Integer;
+var
+ Form: TForm;
+begin
+ Result := APixels;
+ if Control is TForm then
+ Form := TForm(Control)
+ else
+ Form := TForm(GetParentForm(Control));
+ if Form.Scaled then
+ Result := Result * Form.PixelsPerInch div 96;
+end;
+
+procedure ShowMenu(Form: TForm; MenuAni: TMenuAnimation);
+var
+ I: Integer;
+ H: Integer;
+ W: Integer;
+begin
+ case MenuAni of
+ maNone:
+ Form.Show;
+ maRandom:
+ ;
+ maUnfold:
+ begin
+ H := Form.Height;
+ Form.Height := 0;
+ Form.Show;
+ for I := 0 to H div 10 do
+ if Form.Height < H then
+ Form.Height := Form.Height + 10;
+ end;
+ maSlide:
+ begin
+ H := Form.Height;
+ W := Form.Width;
+ Form.Height := 0;
+ Form.Width := 0;
+ Form.Show;
+ for I := 0 to Max(H div 5, W div 5) do
+ begin
+ if Form.Height < H then
+ Form.Height := Form.Height + 5;
+ if Form.Width < W then
+ Form.Width := Form.Width + 5;
+ end;
+ // CS_SAVEBITS
+ end;
+ end;
+end;
+
+{$IFNDEF CLR}
+{$IFDEF MSWINDOWS}
+
+function TargetFileName(const FileName: TFileName): TFileName;
+begin
+ Result := FileName;
+ if SameFileName(ExtractFileExt(FileName), '.lnk') then
+ if ResolveLink(GetAppHandle, FileName, Result) <> 0 then
+ {$IFDEF CLR}
+ raise EJVCLException.CreateFmt(RsECantGetShortCut, [FileName]);
+ {$ELSE}
+ raise EJVCLException.CreateResFmt(@RsECantGetShortCut, [FileName]);
+ {$ENDIF CLR}
+end;
+
+function ResolveLink(const HWND: THandle; const LinkFile: TFileName;
+ var FileName: TFileName): HRESULT;
+var
+ psl: IShellLink;
+ WLinkFile: array [0..MAX_PATH] of WideChar;
+ wfd: TWin32FindData;
+ ppf: IPersistFile;
+ wnd: Windows.HWND;
+begin
+ wnd := HWND;
+ Pointer(psl) := nil;
+ Pointer(ppf) := nil;
+ Result := CoInitialize(nil);
+ if Succeeded(Result) then
+ begin
+ // Get a Pointer to the IShellLink interface.
+ Result := CoCreateInstance(CLSID_ShellLink, nil,
+ CLSCTX_INPROC_SERVER, IShellLink, psl);
+ if Succeeded(Result) then
+ begin
+
+ // Get a Pointer to the IPersistFile interface.
+ Result := psl.QueryInterface(IPersistFile, ppf);
+ if Succeeded(Result) then
+ begin
+ StringToWideChar(LinkFile, WLinkFile, SizeOf(WLinkFile) - 1);
+ // Load the shortcut.
+ Result := ppf.Load(WLinkFile, STGM_READ);
+ if Succeeded(Result) then
+ begin
+ // Resolve the link.
+ Result := psl.Resolve(wnd, SLR_ANY_MATCH);
+ if Succeeded(Result) then
+ begin
+ // Get the path to the link target.
+ SetLength(FileName, MAX_PATH);
+ Result := psl.GetPath(PChar(FileName), MAX_PATH, wfd,
+ SLGP_UNCPRIORITY);
+ if not Succeeded(Result) then
+ Exit;
+ SetLength(FileName, Length(PChar(FileName)));
+ end;
+ end;
+ // Release the Pointer to the IPersistFile interface.
+ ppf._Release;
+ end;
+ // Release the Pointer to the IShellLink interface.
+ psl._Release;
+ end;
+ CoUninitialize;
+ end;
+ Pointer(psl) := nil;
+ Pointer(ppf) := nil;
+end;
+
+{$ENDIF MSWINDOWS}
+
+var
+ ProcList: TList = nil;
+
+type
+ TJvProcItem = class(TObject)
+ private
+ FProcObj: TProcObj;
+ public
+ constructor Create(AProcObj: TProcObj);
+ end;
+
+constructor TJvProcItem.Create(AProcObj: TProcObj);
+begin
+ inherited Create;
+ FProcObj := AProcObj;
+end;
+
+procedure TmrProc(hwnd: THandle; uMsg: Integer; idEvent: Integer; dwTime: Integer); stdcall;
+var
+ Pr: TProcObj;
+begin
+ if ProcList[idEvent] <> nil then
+ begin
+ Pr := TJvProcItem(ProcList[idEvent]).FProcObj;
+ TJvProcItem(ProcList[idEvent]).Free;
+ end
+ else
+ Pr := nil;
+ ProcList.Delete(idEvent);
+ KillTimer(hwnd, idEvent);
+ if ProcList.Count <= 0 then
+ begin
+ ProcList.Free;
+ ProcList := nil;
+ end;
+ if Assigned(Pr) then
+ Pr;
+end;
+
+procedure ExecAfterPause(Proc: TProcObj; Pause: Integer);
+var
+ Num: Integer;
+ I: Integer;
+begin
+ if ProcList = nil then
+ ProcList := TList.Create;
+ Num := -1;
+ for I := 0 to ProcList.Count - 1 do
+ if @TJvProcItem(ProcList[I]).FProcObj = @Proc then
+ begin
+ Num := I;
+ Break;
+ end;
+ if Num <> -1 then
+ KillTimer(GetAppHandle, Num)
+ else
+ Num := ProcList.Add(TJvProcItem.Create(Proc));
+ SetTimer(GetAppHandle, Num, Pause, @TmrProc);
+end;
+{$ENDIF !CLR}
+
+{ end JvUtils }
+
+{ begin JvApputils }
+
+function GetFirstParentForm(Control: TControl): TCustomForm;
+begin
+ while not (Control is TCustomForm) and (Control.Parent <> nil) do
+ Control := Control.Parent;
+ if Control is TCustomForm then
+ Result := TCustomForm(Control) else
+ Result := nil;
+end;
+
+function GetDefaultSection(Component: TComponent): string;
+var
+ F: TCustomForm;
+ Owner: TComponent;
+begin
+ if Component <> nil then
+ begin
+ if Component is TCustomForm then
+ Result := Component.ClassName
+ else
+ begin
+ Result := Component.Name;
+ if Component is TControl then
+ begin
+ // GetParentForm will not stop at the first TCustomForm it finds.
+ // Starting with Delphi 2005, we can pass False as the second parameter
+ // to stop at the FIRST parent that is a TCustomForm, but this is not
+ // available in earlier versions of Delphi. Hence the creation and
+ // use of GetFirstParentForm.
+ // This is required to fix Mantis 3785. Indeed with GetParentForm, the
+ // returned form would be the top most form.
+ // Say, you have a control in Form2, with an instance of Form2 docked
+ // in Form1. When loading, F would Form1, because the parent chain
+ // is completely set. But when destroying, the parent chain would be
+ // already broken, and F would then be Form2, thus returning a different
+ // section name than the one returned when loading.
+ F := GetFirstParentForm(TControl(Component));
+ if F <> nil then
+ Result := F.ClassName + Result
+ else
+ begin
+ if TControl(Component).Parent <> nil then
+ Result := TControl(Component).Parent.Name + Result;
+ end;
+ end
+ else
+ begin
+ Owner := Component.Owner;
+ if Owner is TForm then
+ Result := Format('%s.%s', [Owner.ClassName, Result]);
+ end;
+ end;
+ end
+ else
+ Result := '';
+end;
+
+function GetDefaultIniName: string;
+begin
+ if Assigned(OnGetDefaultIniName) then
+ Result := OnGetDefaultIniName
+ else
+ {$IFDEF UNIX}
+ Result := GetEnvironmentVariable('HOME') + PathDelim +
+ '.' + ExtractFileName(Application.ExeName);
+ {$ENDIF UNIX}
+ {$IFDEF MSWINDOWS}
+ Result := ExtractFileName(ChangeFileExt(Application.ExeName, '.ini'));
+ {$ENDIF MSWINDOWS}
+end;
+
+function GetDefaultIniRegKey: string;
+begin
+ if RegUseAppTitle and (Application.Title <> '') then
+ Result := Application.Title
+ else
+ Result := ExtractFileName(ChangeFileExt(Application.ExeName, ''));
+ if DefCompanyName <> '' then
+ Result := DefCompanyName + '\' + Result;
+ Result := 'Software\' + Result;
+end;
+
+function FindForm(FormClass: TFormClass): TForm;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Screen.FormCount - 1 do
+ begin
+ if Screen.Forms[I] is FormClass then
+ begin
+ Result := Screen.Forms[I];
+ Break;
+ end;
+ end;
+end;
+
+function InternalFindShowForm(FormClass: TFormClass;
+ const Caption: string; Restore: Boolean): TForm;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Screen.FormCount - 1 do
+ begin
+ if Screen.Forms[I] is FormClass then
+ if (Caption = '') or (Caption = Screen.Forms[I].Caption) then
+ begin
+ Result := Screen.Forms[I];
+ Break;
+ end;
+ end;
+ if Result = nil then
+ begin
+ Application.CreateForm(FormClass, Result);
+ if Caption <> '' then
+ Result.Caption := Caption;
+ end;
+ with Result do
+ begin
+ if Restore and (WindowState = wsMinimized) then
+ WindowState := wsNormal;
+ Show;
+ end;
+end;
+
+function FindShowForm(FormClass: TFormClass; const Caption: string): TForm;
+begin
+ Result := InternalFindShowForm(FormClass, Caption, True);
+end;
+
+function ShowDialog(FormClass: TFormClass): Boolean;
+var
+ Dlg: TForm;
+begin
+ Application.CreateForm(FormClass, Dlg);
+ try
+ Result := Dlg.ShowModal in [mrOk, mrYes];
+ finally
+ Dlg.Free;
+ end;
+end;
+
+function InstantiateForm(FormClass: TFormClass; var Reference): TForm;
+begin
+ if TForm(Reference) = nil then
+ Application.CreateForm(FormClass, Reference);
+ Result := TForm(Reference);
+end;
+
+// (rom) use StrStringToEscaped, StrEscapedToString from JclStrings.pas
+
+function StrToIniStr(const Str: string): string;
+var
+ N: Integer;
+begin
+ Result := Str;
+ repeat
+ N := Pos(CrLf, Result);
+ if N > 0 then
+ Result := Copy(Result, 1, N - 1) + '\n' + Copy(Result, N + 2, Length(Result));
+ until N = 0;
+ repeat
+ N := Pos(#10#13, Result);
+ if N > 0 then
+ Result := Copy(Result, 1, N - 1) + '\n' + Copy(Result, N + 2, Length(Result));
+ until N = 0;
+end;
+
+function IniStrToStr(const Str: string): string;
+var
+ N: Integer;
+begin
+ Result := Str;
+ repeat
+ N := Pos('\n', Result);
+ if N > 0 then
+ Result := Copy(Result, 1, N - 1) + CrLf + Copy(Result, N + 2, Length(Result));
+ until N = 0;
+end;
+
+{ The following strings should not be localized }
+const
+ siFlags = 'Flags';
+ siShowCmd = 'ShowCmd';
+ siMinMaxPos = 'MinMaxPos';
+ siNormPos = 'NormPos';
+ siPixels = 'PixelsPerInch';
+ siMDIChild = 'MDI Children';
+ siListCount = 'Count';
+ siItem = 'Item%d';
+
+(-*
+function IniReadString(IniFile: TObject; const Section, Ident,
+ Default: string): string;
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ Result := TRegIniFile(IniFile).ReadString(Section, Ident, Default)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ Result := TCustomIniFile(IniFile).ReadString(Section, Ident, Default)
+ else
+ Result := Default;
+end;
+
+procedure IniWriteString(IniFile: TObject; const Section, Ident,
+ Value: string);
+var
+ S: string;
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).WriteString(Section, Ident, Value)
+ else
+ {$ENDIF MSWINDOWS}
+ begin
+ S := Value;
+ if S <> '' then
+ begin
+ if ((S[1] = '"') and (S[Length(S)] = '"')) or
+ ((S[1] = '''') and (S[Length(S)] = '''')) then
+ S := '"' + S + '"';
+ end;
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).WriteString(Section, Ident, S);
+ end;
+end;
+
+function IniReadInteger(IniFile: TObject; const Section, Ident: string;
+ Default: Longint): Longint;
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ Result := TRegIniFile(IniFile).ReadInteger(Section, Ident, Default)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ Result := TCustomIniFile(IniFile).ReadInteger(Section, Ident, Default)
+ else
+ Result := Default;
+end;
+
+procedure IniWriteInteger(IniFile: TObject; const Section, Ident: string;
+ Value: Longint);
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).WriteInteger(Section, Ident, Value)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).WriteInteger(Section, Ident, Value);
+end;
+
+function IniReadBool(IniFile: TObject; const Section, Ident: string;
+ Default: Boolean): Boolean;
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ Result := TRegIniFile(IniFile).ReadBool(Section, Ident, Default)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ Result := TCustomIniFile(IniFile).ReadBool(Section, Ident, Default)
+ else
+ Result := Default;
+end;
+
+procedure IniWriteBool(IniFile: TObject; const Section, Ident: string;
+ Value: Boolean);
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).WriteBool(Section, Ident, Value)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).WriteBool(Section, Ident, Value);
+end;
+
+procedure IniEraseSection(IniFile: TObject; const Section: string);
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).EraseSection(Section)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).EraseSection(Section);
+end;
+
+procedure IniDeleteKey(IniFile: TObject; const Section, Ident: string);
+begin
+ {$IFDEF MSWINDOWS}
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).DeleteKey(Section, Ident)
+ else
+ {$ENDIF MSWINDOWS}
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).DeleteKey(Section, Ident);
+end;
+
+procedure IniReadSections(IniFile: TObject; Strings: TStrings);
+begin
+ if IniFile is TCustomIniFile then
+ TCustomIniFile(IniFile).ReadSections(Strings)
+ {$IFDEF MSWINDOWS}
+ else
+ if IniFile is TRegIniFile then
+ TRegIniFile(IniFile).ReadSections(Strings);
+ {$ENDIF MSWINDOWS}
+end;
+*-)
+
+{$HINTS OFF}
+type
+ {*******************************************************}
+ { !! ATTENTION Nasty implementation }
+ {*******************************************************}
+ { }
+ { This class definition was copied from FORMS.PAS. }
+ { It is needed to access some private fields of TForm. }
+ { }
+ { Any changes in the underlying classes may cause }
+ { errors in this implementation! }
+ { }
+ {*******************************************************}
+
+ TJvHackForm = class(TScrollingWinControl)
+ private
+ FActiveControl: TWinControl;
+ FFocusedControl: TWinControl;
+ FBorderIcons: TBorderIcons;
+ FBorderStyle: TFormBorderStyle;
+ FSizeChanging: Boolean;
+ FWindowState: TWindowState; { !! }
+ end;
+
+ TComponentAccessProtected = class(TComponent);
+{$HINTS ON}
+
+function CrtResString: string;
+begin
+ Result := Format('(%dx%d)', [GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN)]);
+end;
+
+function ReadPosStr(AppStorage: TJvCustomAppStorage; const Path: string): string;
+begin
+ if AppStorage.ValueStored(Path + CrtResString) then
+ Result := AppStorage.ReadString(Path + CrtResString)
+ else
+ Result := AppStorage.ReadString(Path);
+end;
+
+procedure WritePosStr(AppStorage: TJvCustomAppStorage; const Path, Value: string);
+begin
+ AppStorage.WriteString(Path + CrtResString, Value);
+ AppStorage.WriteString(Path, Value);
+end;
+
+procedure InternalSaveMDIChildren(MainForm: TForm;
+ const AppStorage: TJvCustomAppStorage; const StorePath: string);
+var
+ I: Integer;
+begin
+ if (MainForm = nil) or (MainForm.FormStyle <> fsMDIForm) then
+ {$IFDEF CLR}
+ raise EInvalidOperation.Create(SNoMDIForm);
+ {$ELSE}
+ raise EInvalidOperation.CreateRes(@SNoMDIForm);
+ {$ENDIF CLR}
+ AppStorage.DeleteSubTree(AppStorage.ConcatPaths([StorePath, siMDIChild]));
+ if MainForm.MDIChildCount > 0 then
+ begin
+ AppStorage.WriteInteger(AppStorage.ConcatPaths([StorePath, siMDIChild,
+ siListCount]), MainForm.MDIChildCount);
+ for I := 0 to MainForm.MDIChildCount - 1 do
+ AppStorage.WriteString(AppStorage.ConcatPaths([StorePath, siMDIChild,
+ Format(siItem, [I])]), MainForm.MDIChildren[I].ClassName);
+ end;
+end;
+
+procedure InternalRestoreMDIChildren(MainForm: TForm;
+ const AppStorage: TJvCustomAppStorage; const StorePath: string);
+var
+ I: Integer;
+ Count: Integer;
+ FormClass: TFormClass;
+begin
+ if (MainForm = nil) or (MainForm.FormStyle <> fsMDIForm) then
+ {$IFDEF CLR}
+ raise EInvalidOperation.Create(SNoMDIForm);
+ {$ELSE}
+ raise EInvalidOperation.CreateRes(@SNoMDIForm);
+ {$ENDIF CLR}
+ StartWait;
+ try
+ Count := AppStorage.ReadInteger(AppStorage.ConcatPaths([StorePath, siMDIChild,
+ siListCount]), 0);
+ if Count > 0 then
+ begin
+ for I := 0 to Count - 1 do
+ begin
+ FormClass :=
+ TFormClass(GetClass(AppStorage.ReadString(AppStorage.ConcatPaths([StorePath,
+ siMDIChild, Format(siItem, [I])]), '')));
+ if FormClass <> nil then
+ InternalFindShowForm(FormClass, '', False);
+ end;
+ end;
+ finally
+ StopWait;
+ end;
+end;
+
+procedure SaveMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage);
+begin
+ InternalSaveMDIChildren(MainForm, AppStorage, '');
+end;
+
+procedure RestoreMDIChildren(MainForm: TForm; const AppStorage: TJvCustomAppStorage);
+begin
+ InternalRestoreMDIChildren(MainForm, AppStorage, '');
+end;
+
+procedure InternalSaveFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage;
+ const StorePath: string; Options: TPlacementOptions = [fpState, fpSize, fpLocation]);
+var
+ Placement: TWindowPlacement;
+begin
+ if Options = [fpActiveControl] then
+ Exit;
+ {$IFDEF CLR}
+ Placement.Length := Marshal.SizeOf(Placement);
+ GetWindowPlacement(Form.Handle, Placement);
+ {$ELSE}
+ Placement.Length := SizeOf(TWindowPlacement);
+ GetWindowPlacement(Form.Handle, @Placement);
+ {$ENDIF CLR}
+ with Placement, TForm(Form) do
+ begin
+ if (Form = Application.MainForm) and AppMinimized then
+ ShowCmd := SW_SHOWMINIMIZED;
+ if (FormStyle = fsMDIChild) and (WindowState = wsMinimized) then
+ Flags := Flags or WPF_SETMINPOSITION;
+ if fpState in Options then
+ AppStorage.WriteInteger(StorePath + '\' + siShowCmd, ShowCmd);
+ if [fpSize, fpLocation] * Options <> [] then
+ begin
+ AppStorage.WriteInteger(StorePath + '\' + siFlags, Flags);
+ AppStorage.WriteInteger(StorePath + '\' + siPixels, Screen.PixelsPerInch);
+ WritePosStr(AppStorage, StorePath + '\' + siMinMaxPos, Format('%d,%d,%d,%d',
+ [ptMinPosition.X, ptMinPosition.Y, ptMaxPosition.X, ptMaxPosition.Y]));
+ WritePosStr(AppStorage, StorePath + '\' + siNormPos, Format('%d,%d,%d,%d',
+ [rcNormalPosition.Left, rcNormalPosition.Top, rcNormalPosition.Right,
+ rcNormalPosition.Bottom]));
+ end;
+ end;
+end;
+
+procedure InternalRestoreFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage;
+ const StorePath: string; Options: TPlacementOptions = [fpState, fpSize, fpLocation]);
+const
+ Delims = [',', ' '];
+var
+ PosStr: string;
+ Placement: TWindowPlacement;
+ WinState: TWindowState;
+ DataFound: Boolean;
+
+ procedure ChangePosition(APosition: TPosition);
+ begin
+ {$IFDEF CLR}
+ Form.GetType.InvokeMember('SetDesigning',
+ BindingFlags.NonPublic or BindingFlags.InvokeMethod or BindingFlags.Instance,
+ nil, Form, [True]);
+ try
+ Form.Position := APosition;
+ finally
+ Form.GetType.InvokeMember('SetDesigning',
+ BindingFlags.NonPublic or BindingFlags.InvokeMethod or BindingFlags.Instance,
+ nil, Form, [False]);
+ end;
+ {$ELSE}
+ TComponentAccessProtected(Form).SetDesigning(True);
+ try
+ Form.Position := APosition;
+ finally
+ TComponentAccessProtected(Form).SetDesigning(False);
+ end;
+ {$ENDIF CLR}
+ end;
+
+begin
+ if Options = [fpActiveControl] then
+ Exit;
+ {$IFDEF CLR}
+ Placement.Length := Marshal.SizeOf(Placement);
+ GetWindowPlacement(Form.Handle, Placement);
+ {$ELSE}
+ Placement.Length := SizeOf(TWindowPlacement);
+ GetWindowPlacement(Form.Handle, @Placement);
+ {$ENDIF CLR}
+ with Placement, TForm(Form) do
+ begin
+ if not IsWindowVisible(Form.Handle) then
+ ShowCmd := SW_HIDE;
+ if [fpSize, fpLocation] * Options <> [] then
+ begin
+ DataFound := False;
+ AppStorage.ReadInteger(StorePath + '\' + siFlags, Flags);
+ PosStr := ReadPosStr(AppStorage, StorePath + '\' + siMinMaxPos);
+ if PosStr <> '' then
+ begin
+ DataFound := True;
+ if fpLocation in Options then
+ begin
+ ptMinPosition.X := StrToIntDef(ExtractWord(1, PosStr, Delims), 0);
+ ptMinPosition.Y := StrToIntDef(ExtractWord(2, PosStr, Delims), 0);
+ end;
+ if fpSize in Options then
+ begin
+ ptMaxPosition.X := StrToIntDef(ExtractWord(3, PosStr, Delims), 0);
+ ptMaxPosition.Y := StrToIntDef(ExtractWord(4, PosStr, Delims), 0);
+ end;
+ end;
+ PosStr := ReadPosStr(AppStorage, StorePath + '\' + siNormPos);
+ if PosStr <> '' then
+ begin
+ DataFound := True;
+ if fpLocation in Options then
+ begin
+ rcNormalPosition.Left := StrToIntDef(ExtractWord(1, PosStr, Delims), Left);
+ rcNormalPosition.Top := StrToIntDef(ExtractWord(2, PosStr, Delims), Top);
+ end
+ else
+ begin
+ rcNormalPosition.Left := Left;
+ rcNormalPosition.Top := Top;
+ end;
+ if fpSize in Options then
+ begin
+ rcNormalPosition.Right := rcNormalPosition.Left +StrToIntDef(ExtractWord(3, PosStr, Delims), Width)-StrToIntDef(ExtractWord(1, PosStr, Delims), Left);
+ rcNormalPosition.Bottom := rcNormalPosition.Top +StrToIntDef(ExtractWord(4, PosStr, Delims), Height)-StrToIntDef(ExtractWord(2, PosStr, Delims), Top);
+ end
+ else
+ if fpLocation in Options then
+ begin
+ rcNormalPosition.Right := rcNormalPosition.Left + Width;
+ rcNormalPosition.Bottom := rcNormalPosition.Top + Height;
+ end;
+ end;
+ DataFound := DataFound and (Screen.PixelsPerInch = AppStorage.ReadInteger(
+ StorePath + '\' + siPixels, Screen.PixelsPerInch));
+ if DataFound then
+ begin
+ if not (BorderStyle in [bsSizeable, bsSizeToolWin]) then
+ rcNormalPosition := Rect(rcNormalPosition.Left,
+ rcNormalPosition.Top, rcNormalPosition.Left + Width, rcNormalPosition.Top + Height);
+ if rcNormalPosition.Right > rcNormalPosition.Left then
+ begin
+ if not (csDesigning in ComponentState) then
+ begin
+ if (fpSize in Options) and (fpLocation in Options) then
+ ChangePosition(poDesigned)
+ else
+ if fpSize in Options then
+ begin
+ {.$IFDEF DELPHI????_UP} // Change to the right version 5 or 6 ?
+ if Position = poDefault then
+ ChangePosition(poDefaultPosOnly);
+ {.ENDIF}
+ end
+ else
+ if fpLocation in Options then // obsolete but better to read
+ {.$IFDEF DELPHI????_UP} // Change to the right version 5 or 6 ?
+ if Position = poDefault then
+ ChangePosition(poDefaultSizeOnly)
+ else
+ {.ENDIF}
+ if Position <> poDesigned then
+ ChangePosition(poDesigned);
+ end;
+ SetWindowPlacement(Handle, {$IFNDEf CLR}@{$ENDIF}Placement);
+ end;
+ end;
+ end;
+ if fpState in Options then
+ begin
+ WinState := wsNormal;
+ { default maximize MDI main form }
+ if ((Application.MainForm = Form) or
+ (Application.MainForm = nil)) and ((FormStyle = fsMDIForm) or
+ ((FormStyle = fsNormal) and (Position = poDefault))) then
+ WinState := wsMaximized;
+ ShowCmd := AppStorage.ReadInteger(StorePath + '\' + siShowCmd, SW_HIDE);
+ case ShowCmd of
+ SW_SHOWNORMAL, SW_RESTORE, SW_SHOW:
+ WinState := wsNormal;
+ SW_MINIMIZE, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE:
+ WinState := wsMinimized;
+ SW_MAXIMIZE:
+ WinState := wsMaximized;
+ end;
+ if (WinState = wsMinimized) and ((Form = Application.MainForm) or
+ (Application.MainForm = nil)) then
+ begin
+ {$IFDEF CLR}
+ SetPrivateField(Form, 'FWindowState', wsNormal);
+ {$ELSE}
+ TJvHackForm(Form).FWindowState := wsNormal;
+ {$ENDIF CLR}
+ PostMessage(Application.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ Exit;
+ end;
+ if FormStyle in [fsMDIChild, fsMDIForm] then
+ {$IFDEF CLR}
+ SetPrivateField(Form, 'FWindowState', WinState)
+ {$ELSE}
+ TJvHackForm(Form).FWindowState := WinState
+ {$ENDIF CLR}
+ else
+ WindowState := WinState;
+ end;
+ Update;
+ end;
+end;
+
+procedure InternalSaveGridLayout(Grid: TCustomGrid;
+ const AppStorage: TJvCustomAppStorage; const StorePath: string);
+var
+ I: Longint;
+begin
+ for I := 0 to TDrawGrid(Grid).ColCount - 1 do
+ AppStorage.WriteInteger(AppStorage.ConcatPaths([StorePath, Format(siItem, [I])]),
+ TDrawGrid(Grid).ColWidths[I]);
+end;
+
+procedure InternalRestoreGridLayout(Grid: TCustomGrid;
+ const AppStorage: TJvCustomAppStorage; const StorePath: string);
+var
+ I: Longint;
+begin
+ for I := 0 to TDrawGrid(Grid).ColCount - 1 do
+ TDrawGrid(Grid).ColWidths[I] :=
+ AppStorage.ReadInteger(AppStorage.ConcatPaths([StorePath,
+ Format(siItem, [I])]), TDrawGrid(Grid).ColWidths[I]);
+end;
+
+procedure RestoreGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage);
+begin
+ InternalRestoreGridLayout(Grid, AppStorage, GetDefaultSection(Grid));
+end;
+
+procedure SaveGridLayout(Grid: TCustomGrid; const AppStorage: TJvCustomAppStorage);
+begin
+ InternalSaveGridLayout(Grid, AppStorage, GetDefaultSection(Grid));
+end;
+
+procedure SaveFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage; Options: TPlacementOptions);
+begin
+ InternalSaveFormPlacement(Form, AppStorage, GetDefaultSection(Form), Options);
+end;
+
+procedure RestoreFormPlacement(Form: TForm; const AppStorage: TJvCustomAppStorage; Options: TPlacementOptions);
+begin
+ InternalRestoreFormPlacement(Form, AppStorage, GetDefaultSection(Form), Options);
+end;
+
+
+
+procedure AppBroadcast(Msg, wParam: Longint; lParam: Longint);
+var
+ I: Integer;
+begin
+ for I := 0 to Screen.FormCount - 1 do
+ SendMessage(Screen.Forms[I].Handle, Msg, wParam, lParam);
+end;
+
+procedure AppTaskbarIcons(AppOnly: Boolean);
+var
+ Style: Longint;
+begin
+ Style := GetWindowLong(Application.Handle, GWL_STYLE);
+ if AppOnly then
+ Style := Style or WS_CAPTION
+ else
+ Style := Style and not WS_CAPTION;
+ SetWindowLong(Application.Handle, GWL_STYLE, Style);
+ if AppOnly then
+ SwitchToWindow(Application.Handle, False);
+end;
+
+
+
+{ end JvAppUtils }
+{ begin JvGraph }
+// (rom) moved here to make JvMaxMin obsolete
+
+function MaxFloat(const Values: array of Extended): Extended;
+var
+ I: Cardinal;
+begin
+ Result := Values[Low(Values)];
+ for I := Low(Values) + 1 to High(Values) do
+ if Values[I] > Result then
+ Result := Values[I];
+end;
+
+procedure InvalidBitmap;
+begin
+ {$IFDEF CLR}
+ raise EInvalidGraphic.Create(SInvalidBitmap);
+ {$ELSE}
+ raise EInvalidGraphic.CreateRes(@SInvalidBitmap);
+ {$ENDIF CLR}
+end;
+
+function WidthBytes(I: Longint): Longint;
+begin
+ Result := ((I + 31) div 32) * 4;
+end;
+
+function PixelFormatToColors(PixelFormat: TPixelFormat): Integer;
+begin
+ case PixelFormat of
+ pf1bit:
+ Result := 2;
+ pf4bit:
+ Result := 16;
+ pf8bit:
+ Result := 256;
+ else
+ Result := 0;
+ end;
+end;
+
+
+
+function ScreenPixelFormat: TPixelFormat;
+var
+ DC: HDC;
+begin
+ DC := CreateIC('DISPLAY', nil, nil, nil);
+ try
+ case GetDeviceCaps(DC, PLANES) * GetDeviceCaps(DC, BITSPIXEL) of
+ 1:
+ Result := pf1bit;
+ 4:
+ Result := pf4bit;
+ 8:
+ Result := pf8bit;
+ 15:
+ Result := pf15bit;
+ 16:
+ Result := pf16bit;
+ 24:
+ Result := pf24bit;
+ 32:
+ Result := pf32bit;
+ else
+ Result := pfDevice;
+ end;
+ finally
+ DeleteDC(DC);
+ end;
+end;
+
+function ScreenColorCount: Integer;
+begin
+ Result := PixelFormatToColors(ScreenPixelFormat);
+end;
+
+
+function GetWorkareaRect(Monitor: TMonitor): TRect;
+var
+ MonInfo: TMonitorInfo;
+begin
+ MonInfo.cbSize := SizeOf(MonInfo);
+ GetMonitorInfo(Monitor.Handle, @MonInfo);
+ Result := MonInfo.rcWork;
+end;
+
+function FindMonitor(Handle: HMONITOR): TMonitor;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Screen.MonitorCount - 1 do
+ if Screen.Monitors[I].Handle = Handle then
+ begin
+ Result := Screen.Monitors[I];
+ Break;
+ end;
+end;
+
+{ Quantizing }
+{ Quantizing procedures based on free C source code written by
+ Joe C. Oliphant, CompuServe 71742, 1451, joe_oliphant att csufresno dott edu }
+
+const
+ MAX_COLORS = 4096;
+
+type
+ TTriple = array [0..2] of Byte;
+
+ {$IFDEF CLR}
+ TQColor = class;
+ PQColor = TQColor;
+ TQColor = class
+ RGB: TTriple;
+ NewColorIndex: Byte;
+ Count: Longint;
+ PNext: PQColor;
+ end;
+
+ PQColorArray = array of TQColor;
+ TQColorArray = array [0..MAX_COLORS - 1] of TQColor;
+
+ PQColorList = array of PQColor;
+ TQColorList = array [0..MaxListSize - 1] of PQColor;
+
+ TNewColor = record
+ RGBMin: TTriple;
+ RGBWidth: TTriple;
+ NumEntries: Longint;
+ Count: Longint;
+ QuantizedColors: PQColor;
+ end;
+ PNewColor = TNewColor;
+
+ PNewColorArray = array of TNewColor;
+ TNewColorArray = array [Byte] of TNewColor;
+ {$ELSE}
+ PQColor = ^TQColor;
+ TQColor = record
+ RGB: TTriple;
+ NewColorIndex: Byte;
+ Count: Longint;
+ PNext: PQColor;
+ end;
+
+ PQColorArray = ^TQColorArray;
+ TQColorArray = array [0..MAX_COLORS - 1] of TQColor;
+
+ PQColorList = ^TQColorList;
+ TQColorList = array [0..MaxListSize - 1] of PQColor;
+
+ PNewColor = ^TNewColor;
+ TNewColor = record
+ RGBMin: TTriple;
+ RGBWidth: TTriple;
+ NumEntries: Longint;
+ Count: Longint;
+ QuantizedColors: PQColor;
+ end;
+
+ PNewColorArray = ^TNewColorArray;
+ TNewColorArray = array [Byte] of TNewColor;
+ {$ENDIF CLR}
+
+procedure PInsert(ColorList: PQColorList; {$IFDEF CLR}Offset: Integer;{$ENDIF}
+ Number: Integer; SortRGBAxis: Integer);
+var
+ Q1, Q2: PQColor;
+ I, J: Integer;
+ Temp: PQColor;
+begin
+ for I := 1 to Number - 1 do
+ begin
+ Temp := ColorList[{$IFDEF CLR}Offset +{$ENDIF}I];
+ J := I - 1;
+ while J >= 0 do
+ begin
+ Q1 := Temp;
+ Q2 := ColorList[{$IFDEF CLR}Offset +{$ENDIF}J];
+ if Q1.RGB[SortRGBAxis] - Q2.RGB[SortRGBAxis] > 0 then
+ Break;
+ ColorList[{$IFDEF CLR}Offset +{$ENDIF}J + 1] := ColorList[{$IFDEF CLR}Offset +{$ENDIF}J];
+ Dec(J);
+ end;
+ ColorList[{$IFDEF CLR}Offset +{$ENDIF}J + 1] := Temp;
+ end;
+end;
+
+procedure PSort(ColorList: PQColorList; {$IFDEF CLR}Offset: Integer;{$ENDIF}
+ Number: Integer; SortRGBAxis: Integer);
+var
+ Q1, Q2: PQColor;
+ I, J, N, Nr: Integer;
+ Temp, Part: PQColor;
+begin
+ if Number < 8 then
+ begin
+ PInsert(ColorList, {$IFDEF CLR}Offset, {$ENDIF} Number, SortRGBAxis);
+ Exit;
+ end;
+ Part := ColorList[{$IFDEF CLR}Offset +{$ENDIF} Number div 2];
+ I := -1;
+ J := Number;
+ repeat
+ repeat
+ Inc(I);
+ Q1 := ColorList[{$IFDEF CLR}Offset +{$ENDIF} I];
+ Q2 := Part;
+ N := Q1.RGB[SortRGBAxis] - Q2.RGB[SortRGBAxis];
+ until N >= 0;
+ repeat
+ Dec(J);
+ Q1 := ColorList[{$IFDEF CLR}Offset +{$ENDIF} J];
+ Q2 := Part;
+ N := Q1.RGB[SortRGBAxis] - Q2.RGB[SortRGBAxis];
+ until N <= 0;
+ if I >= J then
+ Break;
+ Temp := ColorList[{$IFDEF CLR}Offset +{$ENDIF} I];
+ ColorList[{$IFDEF CLR}Offset +{$ENDIF} I] := ColorList[{$IFDEF CLR}Offset +{$ENDIF} J];
+ ColorList[{$IFDEF CLR}Offset +{$ENDIF} J] := Temp;
+ until False;
+ Nr := Number - I;
+ if I < Number div 2 then
+ begin
+ {$IFDEF CLR}
+ PSort(ColorList, Offset, I, SortRGBAxis);
+ PSort(ColorList, Offset + I, Nr, SortRGBAxis);
+ {$ELSE}
+ PSort(ColorList, I, SortRGBAxis);
+ PSort(PQColorList(@ColorList[I]), Nr, SortRGBAxis);
+ {$ENDIF CLR}
+ end
+ else
+ begin
+ {$IFDEF CLR}
+ PSort(ColorList, Offset + I, Nr, SortRGBAxis);
+ PSort(ColorList, Offset, I, SortRGBAxis);
+ {$ELSE}
+ PSort(PQColorList(@ColorList[I]), Nr, SortRGBAxis);
+ PSort(ColorList, I, SortRGBAxis);
+ {$ENDIF CLR}
+ end;
+end;
+
+{$IFDEF CLR}
+function DivideMap(var NewColorSubdiv: PNewColorArray; ColorMapSize: Integer;
+ var NewColormapSize: Integer; var LPSTR: PQColorArray; Offset: Integer): Integer;
+{$ELSE}
+function DivideMap(NewColorSubdiv: PNewColorArray; ColorMapSize: Integer;
+ var NewColormapSize: Integer; LPSTR: Pointer): Integer;
+{$ENDIF CLR}
+var
+ I, J: Integer;
+ MaxSize, Index: Integer;
+ NumEntries, MinColor, MaxColor: Integer;
+ Sum, Count: Longint;
+ QuantizedColor: PQColor;
+ SortArray: PQColorList;
+ SortRGBAxis: Integer;
+begin
+ Index := 0;
+ SortRGBAxis := 0;
+ while ColorMapSize > NewColormapSize do
+ begin
+ MaxSize := -1;
+ for I := 0 to NewColormapSize - 1 do
+ begin
+ for J := 0 to 2 do
+ begin
+ if (NewColorSubdiv[I].RGBWidth[J] > MaxSize) and
+ (NewColorSubdiv[I].NumEntries > 1) then
+ begin
+ MaxSize := NewColorSubdiv[I].RGBWidth[J];
+ Index := I;
+ SortRGBAxis := J;
+ end;
+ end;
+ end;
+ if MaxSize = -1 then
+ begin
+ Result := 1;
+ Exit;
+ end;
+ SortArray := PQColorList(LPSTR);
+ J := 0;
+ QuantizedColor := NewColorSubdiv[Index].QuantizedColors;
+ while (J < NewColorSubdiv[Index].NumEntries) and
+ (QuantizedColor <> nil) do
+ begin
+ SortArray[{$IFDEF CLR}Offset +{$ENDIF} J] := QuantizedColor;
+ Inc(J);
+ QuantizedColor := QuantizedColor.PNext;
+ end;
+ PSort(SortArray, {$IFDEF CLR}Offset,{$ENDIF} NewColorSubdiv[Index].NumEntries, SortRGBAxis);
+ for J := 0 to NewColorSubdiv[Index].NumEntries - 2 do
+ SortArray[{$IFDEF CLR}Offset +{$ENDIF} J].PNext := SortArray[{$IFDEF CLR}Offset +{$ENDIF} J + 1];
+ SortArray[{$IFDEF CLR}Offset +{$ENDIF} NewColorSubdiv[Index].NumEntries - 1].PNext := nil;
+ NewColorSubdiv[Index].QuantizedColors := SortArray[{$IFDEF CLR}Offset +{$ENDIF} 0];
+ QuantizedColor := SortArray[{$IFDEF CLR}Offset +{$ENDIF} 0];
+ Sum := NewColorSubdiv[Index].Count div 2 - QuantizedColor.Count;
+ NumEntries := 1;
+ Count := QuantizedColor.Count;
+ Dec(Sum, QuantizedColor.PNext.Count);
+ while (Sum >= 0) and (QuantizedColor.PNext <> nil) and
+ (QuantizedColor.PNext.PNext <> nil) do
+ begin
+ QuantizedColor := QuantizedColor.PNext;
+ Inc(NumEntries);
+ Inc(Count, QuantizedColor.Count);
+ Dec(Sum, QuantizedColor.PNext.Count);
+ end;
+ MaxColor := (QuantizedColor.RGB[SortRGBAxis]) shl 4;
+ MinColor := (QuantizedColor.PNext.RGB[SortRGBAxis]) shl 4;
+ NewColorSubdiv[NewColormapSize].QuantizedColors := QuantizedColor.PNext;
+ QuantizedColor.PNext := nil;
+ NewColorSubdiv[NewColormapSize].Count := Count;
+ Dec(NewColorSubdiv[Index].Count, Count);
+ NewColorSubdiv[NewColormapSize].NumEntries := NewColorSubdiv[Index].NumEntries - NumEntries;
+ NewColorSubdiv[Index].NumEntries := NumEntries;
+ for J := 0 to 2 do
+ begin
+ NewColorSubdiv[NewColormapSize].RGBMin[J] :=
+ NewColorSubdiv[Index].RGBMin[J];
+ NewColorSubdiv[NewColormapSize].RGBWidth[J] :=
+ NewColorSubdiv[Index].RGBWidth[J];
+ end;
+ NewColorSubdiv[NewColormapSize].RGBWidth[SortRGBAxis] :=
+ NewColorSubdiv[NewColormapSize].RGBMin[SortRGBAxis] +
+ NewColorSubdiv[NewColormapSize].RGBWidth[SortRGBAxis] -
+ MinColor;
+ NewColorSubdiv[NewColormapSize].RGBMin[SortRGBAxis] := MinColor;
+ NewColorSubdiv[Index].RGBWidth[SortRGBAxis] := MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis];
+ Inc(NewColormapSize);
+ end;
+ Result := 1;
+end;
+
+{$IFNDEF CLR}
+function Quantize(const Bmp: TBitmapInfoHeader; gptr, Data8: Pointer;
+ var ColorCount: Integer; var OutputColormap: TRGBPalette): Integer;
+type
+ PWord = ^Word;
+var
+ P: PByteArray;
+ LineBuffer, Data: Pointer;
+ LineWidth: Longint;
+ TmpLineWidth, NewLineWidth: Longint;
+ I, J: Longint;
+ Index: Word;
+ NewColormapSize, NumOfEntries: Integer;
+ Mems: Longint;
+ cRed, cGreen, cBlue: Longint;
+ LPSTR, Temp, Tmp: Pointer;
+ NewColorSubdiv: PNewColorArray;
+ ColorArrayEntries: PQColorArray;
+ QuantizedColor: PQColor;
+begin
+ LineWidth := WidthBytes(Longint(Bmp.biWidth) * Bmp.biBitCount);
+ Mems := (Longint(SizeOf(TQColor)) * (MAX_COLORS)) +
+ (Longint(SizeOf(TNewColor)) * 256) + LineWidth +
+ (Longint(SizeOf(PQColor)) * (MAX_COLORS));
+ LPSTR := AllocMemo(Mems);
+ try
+ Temp := AllocMemo(Longint(Bmp.biWidth) * Longint(Bmp.biHeight) *
+ SizeOf(Word));
+ try
+ ColorArrayEntries := PQColorArray(LPSTR);
+ NewColorSubdiv := PNewColorArray(HugeOffset(LPSTR,
+ Longint(SizeOf(TQColor)) * (MAX_COLORS)));
+ LineBuffer := HugeOffset(LPSTR, (Longint(SizeOf(TQColor)) * (MAX_COLORS))
+ +
+ (Longint(SizeOf(TNewColor)) * 256));
+ for I := 0 to MAX_COLORS - 1 do
+ begin
+ ColorArrayEntries^[I].RGB[0] := I shr 8;
+ ColorArrayEntries^[I].RGB[1] := (I shr 4) and $0F;
+ ColorArrayEntries^[I].RGB[2] := I and $0F;
+ ColorArrayEntries^[I].Count := 0;
+ end;
+ Tmp := Temp;
+ for I := 0 to Bmp.biHeight - 1 do
+ begin
+ HMemCpy(LineBuffer, HugeOffset(gptr, (Bmp.biHeight - 1 - I) *
+ LineWidth), LineWidth);
+ P := LineBuffer;
+ for J := 0 to Bmp.biWidth - 1 do
+ begin
+ Index := (Longint(P^[2] and $F0) shl 4) +
+ Longint(P^[1] and $F0) + (Longint(P^[0] and $F0) shr 4);
+ Inc(ColorArrayEntries^[Index].Count);
+ P := HugeOffset(P, 3);
+ PWord(Tmp)^ := Index;
+ Tmp := HugeOffset(Tmp, 2);
+ end;
+ end;
+ for I := 0 to 255 do
+ begin
+ NewColorSubdiv^[I].QuantizedColors := nil;
+ NewColorSubdiv^[I].Count := 0;
+ NewColorSubdiv^[I].NumEntries := 0;
+ for J := 0 to 2 do
+ begin
+ NewColorSubdiv^[I].RGBMin[J] := 0;
+ NewColorSubdiv^[I].RGBWidth[J] := 255;
+ end;
+ end;
+ I := 0;
+ while I < MAX_COLORS do
+ begin
+ if ColorArrayEntries^[I].Count > 0 then
+ Break;
+ Inc(I);
+ end;
+ QuantizedColor := @ColorArrayEntries^[I];
+ NewColorSubdiv^[0].QuantizedColors := @ColorArrayEntries^[I];
+ NumOfEntries := 1;
+ Inc(I);
+ while I < MAX_COLORS do
+ begin
+ if ColorArrayEntries^[I].Count > 0 then
+ begin
+ QuantizedColor^.PNext := @ColorArrayEntries^[I];
+ QuantizedColor := @ColorArrayEntries^[I];
+ Inc(NumOfEntries);
+ end;
+ Inc(I);
+ end;
+ QuantizedColor^.PNext := nil;
+ NewColorSubdiv^[0].NumEntries := NumOfEntries;
+ NewColorSubdiv^[0].Count := Longint(Bmp.biWidth) * Longint(Bmp.biHeight);
+ NewColormapSize := 1;
+ DivideMap(NewColorSubdiv, ColorCount, NewColormapSize,
+ HugeOffset(LPSTR, Longint(SizeOf(TQColor)) * (MAX_COLORS) +
+ Longint(SizeOf(TNewColor)) * 256 + LineWidth));
+ if NewColormapSize < ColorCount then
+ begin
+ for I := NewColormapSize to ColorCount - 1 do
+ FillChar(OutputColormap[I], SizeOf(TRGBQuad), 0);
+ end;
+ for I := 0 to NewColormapSize - 1 do
+ begin
+ J := NewColorSubdiv^[I].NumEntries;
+ if J > 0 then
+ begin
+ QuantizedColor := NewColorSubdiv^[I].QuantizedColors;
+ cRed := 0;
+ cGreen := 0;
+ cBlue := 0;
+ while QuantizedColor <> nil do
+ begin
+ QuantizedColor^.NewColorIndex := I;
+ Inc(cRed, QuantizedColor^.RGB[0]);
+ Inc(cGreen, QuantizedColor^.RGB[1]);
+ Inc(cBlue, QuantizedColor^.RGB[2]);
+ QuantizedColor := QuantizedColor^.PNext;
+ end;
+ with OutputColormap[I] do
+ begin
+ rgbRed := (Longint(cRed shl 4) or $0F) div J;
+ rgbGreen := (Longint(cGreen shl 4) or $0F) div J;
+ rgbBlue := (Longint(cBlue shl 4) or $0F) div J;
+ rgbReserved := 0;
+ if (rgbRed <= $10) and (rgbGreen <= $10) and (rgbBlue <= $10) then
+ FillChar(OutputColormap[I], SizeOf(TRGBQuad), 0); { clBlack }
+ end;
+ end;
+ end;
+ TmpLineWidth := Longint(Bmp.biWidth) * SizeOf(Word);
+ NewLineWidth := WidthBytes(Longint(Bmp.biWidth) * 8);
+ FillChar(Data8^, NewLineWidth * Bmp.biHeight, #0);
+ for I := 0 to Bmp.biHeight - 1 do
+ begin
+ LineBuffer := HugeOffset(Temp, (Bmp.biHeight - 1 - I) * TmpLineWidth);
+ Data := HugeOffset(Data8, I * NewLineWidth);
+ for J := 0 to Bmp.biWidth - 1 do
+ begin
+ PByte(Data)^ := ColorArrayEntries^[PWord(LineBuffer)^].NewColorIndex;
+ LineBuffer := HugeOffset(LineBuffer, 2);
+ Data := HugeOffset(Data, 1);
+ end;
+ end;
+ finally
+ FreeMemo(Temp);
+ end;
+ finally
+ FreeMemo(LPSTR);
+ end;
+ ColorCount := NewColormapSize;
+ Result := 0;
+end;
+
+{
+ Procedures to truncate to lower bits-per-pixel, grayscale, tripel and
+ histogram conversion based on freeware C source code of GBM package by
+ Andy Key (nyangau att interalpha dott co dott uk). The home page of GBM
+ author is at http://www.interalpha.net/customer/nyangau/.
+}
+
+{ Truncate to lower bits per pixel }
+
+type
+ TTruncLine = procedure(Src, Dest: Pointer; CX: Integer);
+
+ { For 6Rx6Gx6B, 7Rx8Gx4B palettes etc. }
+
+const
+ Scale04: array [0..3] of Byte = (0, 85, 170, 255);
+ Scale06: array [0..5] of Byte = (0, 51, 102, 153, 204, 255);
+ Scale07: array [0..6] of Byte = (0, 43, 85, 128, 170, 213, 255);
+ Scale08: array [0..7] of Byte = (0, 36, 73, 109, 146, 182, 219, 255);
+
+ { For 6Rx6Gx6B, 7Rx8Gx4B palettes etc. }
+
+var
+ TruncTablesInitialized: Boolean = False;
+ TruncIndex04: array [Byte] of Byte;
+ TruncIndex06: array [Byte] of Byte;
+ TruncIndex07: array [Byte] of Byte;
+ TruncIndex08: array [Byte] of Byte;
+
+ { These functions initialises this module }
+
+procedure InitTruncTables;
+
+ function NearestIndex(Value: Byte; const Bytes: array of Byte): Byte;
+ var
+ B, I: Byte;
+ Diff, DiffMin: Word;
+ begin
+ Result := 0;
+ B := Bytes[0];
+ DiffMin := Abs(Value - B);
+ for I := 1 to High(Bytes) do
+ begin
+ B := Bytes[I];
+ Diff := Abs(Value - B);
+ if Diff < DiffMin then
+ begin
+ DiffMin := Diff;
+ Result := I;
+ end;
+ end;
+ end;
+
+var
+ I: Integer;
+begin
+ if not TruncTablesInitialized then
+ begin
+ TruncTablesInitialized := True;
+ // (rom) secured because it is called in initialization section
+ // (ahuser) moved from initialization section to "on demand" initialization
+ try
+ { For 7 Red X 8 Green X 4 Blue palettes etc. }
+ for I := 0 to 255 do
+ begin
+ TruncIndex04[I] := NearestIndex(Byte(I), Scale04);
+ TruncIndex06[I] := NearestIndex(Byte(I), Scale06);
+ TruncIndex07[I] := NearestIndex(Byte(I), Scale07);
+ TruncIndex08[I] := NearestIndex(Byte(I), Scale08);
+ end;
+ except
+ end;
+ end;
+end;
+
+procedure Trunc(const Header: TBitmapInfoHeader; Src, Dest: Pointer;
+ DstBitsPerPixel: Integer; TruncLineProc: TTruncLine);
+var
+ SrcScanline, DstScanline: Longint;
+ Y: Integer;
+begin
+ SrcScanline := (Header.biWidth * 3 + 3) and not 3;
+ DstScanline := ((Header.biWidth * DstBitsPerPixel + 31) div 32) * 4;
+ for Y := 0 to Header.biHeight - 1 do
+ TruncLineProc(HugeOffset(Src, Y * SrcScanline),
+ HugeOffset(Dest, Y * DstScanline), Header.biWidth);
+end;
+
+{ return 6Rx6Gx6B palette
+ This function makes the palette for the 6 red X 6 green X 6 blue palette.
+ 216 palette entrys used. Remaining 40 Left blank.
+}
+
+procedure TruncPal6R6G6B(var Colors: TRGBPalette);
+var
+ I, R, G, B: Byte;
+begin
+ FillChar(Colors, SizeOf(TRGBPalette), $80);
+ I := 0;
+ for R := 0 to 5 do
+ for G := 0 to 5 do
+ for B := 0 to 5 do
+ begin
+ Colors[I].rgbRed := Scale06[R];
+ Colors[I].rgbGreen := Scale06[G];
+ Colors[I].rgbBlue := Scale06[B];
+ Colors[I].rgbReserved := 0;
+ Inc(I);
+ end;
+end;
+
+{ truncate to 6Rx6Gx6B one line }
+
+procedure TruncLine6R6G6B(Src, Dest: Pointer; CX: Integer);
+var
+ X: Integer;
+ R, G, B: Byte;
+begin
+ InitTruncTables;
+ for X := 0 to CX - 1 do
+ begin
+ B := TruncIndex06[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ G := TruncIndex06[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ R := TruncIndex06[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ PByte(Dest)^ := 6 * (6 * R + G) + B;
+ Dest := HugeOffset(Dest, 1);
+ end;
+end;
+
+{ truncate to 6Rx6Gx6B }
+
+procedure Trunc6R6G6B(const Header: TBitmapInfoHeader;
+ const Data24, Data8: Pointer);
+begin
+ Trunc(Header, Data24, Data8, 8, TruncLine6R6G6B);
+end;
+
+{ return 7Rx8Gx4B palette
+ This function makes the palette for the 7 red X 8 green X 4 blue palette.
+ 224 palette entrys used. Remaining 32 Left blank.
+ Colours calculated to match those used by 8514/A PM driver.
+}
+
+procedure TruncPal7R8G4B(var Colors: TRGBPalette);
+var
+ I, R, G, B: Byte;
+begin
+ FillChar(Colors, SizeOf(TRGBPalette), $80);
+ I := 0;
+ for R := 0 to 6 do
+ for G := 0 to 7 do
+ for B := 0 to 3 do
+ begin
+ Colors[I].rgbRed := Scale07[R];
+ Colors[I].rgbGreen := Scale08[G];
+ Colors[I].rgbBlue := Scale04[B];
+ Colors[I].rgbReserved := 0;
+ Inc(I);
+ end;
+end;
+
+{ truncate to 7Rx8Gx4B one line }
+
+procedure TruncLine7R8G4B(Src, Dest: Pointer; CX: Integer);
+var
+ X: Integer;
+ R, G, B: Byte;
+begin
+ InitTruncTables;
+ for X := 0 to CX - 1 do
+ begin
+ B := TruncIndex04[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ G := TruncIndex08[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ R := TruncIndex07[Byte(Src^)];
+ Src := HugeOffset(Src, 1);
+ PByte(Dest)^ := 4 * (8 * R + G) + B;
+ Dest := HugeOffset(Dest, 1);
+ end;
+end;
+
+{ truncate to 7Rx8Gx4B }
+
+procedure Trunc7R8G4B(const Header: TBitmapInfoHeader;
+ const Data24, Data8: Pointer);
+begin
+ Trunc(Header, Data24, Data8, 8, TruncLine7R8G4B);
+end;
+
+{ Grayscale support }
+
+procedure GrayPal(var Colors: TRGBPalette);
+var
+ I: Byte;
+begin
+ FillChar(Colors, SizeOf(TRGBPalette), 0);
+ for I := 0 to 255 do
+ FillChar(Colors[I], 3, I);
+end;
+
+procedure GrayScale(const Header: TBitmapInfoHeader; Data24, Data8: Pointer);
+var
+ SrcScanline, DstScanline: Longint;
+ Y, X: Integer;
+ Src, Dest: PByte;
+ R, G, B: Byte;
+begin
+ SrcScanline := (Header.biWidth * 3 + 3) and not 3;
+ DstScanline := (Header.biWidth + 3) and not 3;
+ for Y := 0 to Header.biHeight - 1 do
+ begin
+ Src := Data24;
+ Dest := Data8;
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ B := Src^;
+ Src := HugeOffset(Src, 1);
+ G := Src^;
+ Src := HugeOffset(Src, 1);
+ R := Src^;
+ Src := HugeOffset(Src, 1);
+ Dest^ := Byte(Longint(Word(R) * 77 + Word(G) * 150 + Word(B) * 29) shr 8);
+ Dest := HugeOffset(Dest, 1);
+ end;
+ Data24 := HugeOffset(Data24, SrcScanline);
+ Data8 := HugeOffset(Data8, DstScanline);
+ end;
+end;
+
+{ Tripel conversion }
+
+procedure TripelPal(var Colors: TRGBPalette);
+var
+ I: Byte;
+begin
+ FillChar(Colors, SizeOf(TRGBPalette), 0);
+ for I := 0 to $40 do
+ begin
+ Colors[I].rgbRed := I shl 2;
+ Colors[I + $40].rgbGreen := I shl 2;
+ Colors[I + $80].rgbBlue := I shl 2;
+ end;
+end;
+
+procedure Tripel(const Header: TBitmapInfoHeader; Data24, Data8: Pointer);
+var
+ SrcScanline, DstScanline: Longint;
+ Y, X: Integer;
+ Src, Dest: PByte;
+ R, G, B: Byte;
+begin
+ SrcScanline := (Header.biWidth * 3 + 3) and not 3;
+ DstScanline := (Header.biWidth + 3) and not 3;
+ for Y := 0 to Header.biHeight - 1 do
+ begin
+ Src := Data24;
+ Dest := Data8;
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ B := Src^;
+ Src := HugeOffset(Src, 1);
+ G := Src^;
+ Src := HugeOffset(Src, 1);
+ R := Src^;
+ Src := HugeOffset(Src, 1);
+ case ((X + Y) mod 3) of
+ 0: Dest^ := Byte(R shr 2);
+ 1: Dest^ := Byte($40 + (G shr 2));
+ 2: Dest^ := Byte($80 + (B shr 2));
+ end;
+ Dest := HugeOffset(Dest, 1);
+ end;
+ Data24 := HugeOffset(Data24, SrcScanline);
+ Data8 := HugeOffset(Data8, DstScanline);
+ end;
+end;
+
+{ Histogram/Frequency-of-use method of color reduction }
+
+const
+ MAX_N_COLS = 2049;
+ MAX_N_HASH = 5191;
+
+function Hash(R, G, B: Byte): Word;
+begin
+ Result := Word(Longint(Longint(R + G) * Longint(G + B) * Longint(B + R)) mod MAX_N_HASH);
+end;
+
+type
+ PFreqRecord = ^TFreqRecord;
+ TFreqRecord = record
+ B: Byte;
+ G: Byte;
+ R: Byte;
+ Frequency: Longint;
+ Nearest: Byte;
+ end;
+
+ PHist = ^THist;
+ THist = record
+ ColCount: Longint;
+ Rm: Byte;
+ Gm: Byte;
+ BM: Byte;
+ Freqs: array [0..MAX_N_COLS - 1] of TFreqRecord;
+ HashTable: array [0..MAX_N_HASH - 1] of Word;
+ end;
+
+function CreateHistogram(R, G, B: Byte): PHist;
+{ create empty histogram }
+begin
+ GetMem(Result, SizeOf(THist));
+ with Result^ do
+ begin
+ Rm := R;
+ Gm := G;
+ BM := B;
+ ColCount := 0;
+ end;
+ FillChar(Result^.HashTable, MAX_N_HASH * SizeOf(Word), 255);
+end;
+
+procedure ClearHistogram(var Hist: PHist; R, G, B: Byte);
+begin
+ with Hist^ do
+ begin
+ Rm := R;
+ Gm := G;
+ BM := B;
+ ColCount := 0;
+ end;
+ FillChar(Hist^.HashTable, MAX_N_HASH * SizeOf(Word), 255);
+end;
+
+procedure DeleteHistogram(var Hist: PHist);
+begin
+ FreeMem(Hist, SizeOf(THist));
+ Hist := nil;
+end;
+
+function AddToHistogram(var Hist: THist; const Header: TBitmapInfoHeader;
+ Data24: Pointer): Boolean;
+{ add bitmap data to histogram }
+var
+ Step24: Integer;
+ HashColor, Index: Word;
+ Rm, Gm, BM, R, G, B: Byte;
+ X, Y, ColCount: Longint;
+begin
+ Step24 := ((Header.biWidth * 3 + 3) and not 3) - Header.biWidth * 3;
+ Rm := Hist.Rm;
+ Gm := Hist.Gm;
+ BM := Hist.BM;
+ ColCount := Hist.ColCount;
+ for Y := 0 to Header.biHeight - 1 do
+ begin
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ B := Byte(Data24^) and BM;
+ Data24 := HugeOffset(Data24, 1);
+ G := Byte(Data24^) and Gm;
+ Data24 := HugeOffset(Data24, 1);
+ R := Byte(Data24^) and Rm;
+ Data24 := HugeOffset(Data24, 1);
+ HashColor := Hash(R, G, B);
+ repeat
+ Index := Hist.HashTable[HashColor];
+ if (Index = $FFFF) or ((Hist.Freqs[Index].R = R) and
+ (Hist.Freqs[Index].G = G) and (Hist.Freqs[Index].B = B)) then
+ Break;
+ Inc(HashColor);
+ if HashColor = MAX_N_HASH then
+ HashColor := 0;
+ until False;
+ { Note: loop will always be broken out of }
+ { We don't allow HashTable to fill up above half full }
+ if Index = $FFFF then
+ begin
+ { Not found in Hash table }
+ if ColCount = MAX_N_COLS then
+ begin
+ Result := False;
+ Exit;
+ end;
+ Hist.Freqs[ColCount].Frequency := 1;
+ Hist.Freqs[ColCount].B := B;
+ Hist.Freqs[ColCount].G := G;
+ Hist.Freqs[ColCount].R := R;
+ Hist.HashTable[HashColor] := ColCount;
+ Inc(ColCount);
+ end
+ else
+ begin
+ { Found in Hash table, update index }
+ Inc(Hist.Freqs[Index].Frequency);
+ end;
+ end;
+ Data24 := HugeOffset(Data24, Step24);
+ end;
+ Hist.ColCount := ColCount;
+ Result := True;
+end;
+
+procedure PalHistogram(var Hist: THist; var Colors: TRGBPalette;
+ ColorsWanted: Integer);
+{ work out a palette from Hist }
+var
+ I, J: Longint;
+ MinDist, Dist: Longint;
+ MaxJ, MinJ: Longint;
+ DeltaB, DeltaG, DeltaR: Longint;
+ MaxFreq: Longint;
+begin
+ I := 0;
+ MaxJ := 0;
+ MinJ := 0;
+ { Now find the ColorsWanted most frequently used ones }
+ while (I < ColorsWanted) and (I < Hist.ColCount) do
+ begin
+ MaxFreq := 0;
+ for J := 0 to Hist.ColCount - 1 do
+ if Hist.Freqs[J].Frequency > MaxFreq then
+ begin
+ MaxJ := J;
+ MaxFreq := Hist.Freqs[J].Frequency;
+ end;
+ Hist.Freqs[MaxJ].Nearest := Byte(I);
+ Hist.Freqs[MaxJ].Frequency := 0; { Prevent later use of Freqs[MaxJ] }
+ Colors[I].rgbBlue := Hist.Freqs[MaxJ].B;
+ Colors[I].rgbGreen := Hist.Freqs[MaxJ].G;
+ Colors[I].rgbRed := Hist.Freqs[MaxJ].R;
+ Colors[I].rgbReserved := 0;
+ Inc(I);
+ end;
+ { Unused palette entries will be medium grey }
+ while I <= 255 do
+ begin
+ Colors[I].rgbRed := $80;
+ Colors[I].rgbGreen := $80;
+ Colors[I].rgbBlue := $80;
+ Colors[I].rgbReserved := 0;
+ Inc(I);
+ end;
+ { For the rest, find the closest one in the first ColorsWanted }
+ for I := 0 to Hist.ColCount - 1 do
+ begin
+ if Hist.Freqs[I].Frequency <> 0 then
+ begin
+ MinDist := 3 * 256 * 256;
+ for J := 0 to ColorsWanted - 1 do
+ begin
+ DeltaB := Hist.Freqs[I].B - Colors[J].rgbBlue;
+ DeltaG := Hist.Freqs[I].G - Colors[J].rgbGreen;
+ DeltaR := Hist.Freqs[I].R - Colors[J].rgbRed;
+ Dist := Longint(DeltaR * DeltaR) + Longint(DeltaG * DeltaG) +
+ Longint(DeltaB * DeltaB);
+ if Dist < MinDist then
+ begin
+ MinDist := Dist;
+ MinJ := J;
+ end;
+ end;
+ Hist.Freqs[I].Nearest := Byte(MinJ);
+ end;
+ end;
+end;
+
+procedure MapHistogram(var Hist: THist; const Header: TBitmapInfoHeader;
+ Data24, Data8: Pointer);
+{ map bitmap data to Hist palette }
+var
+ Step24: Integer;
+ Step8: Integer;
+ HashColor, Index: Longint;
+ Rm, Gm, BM, R, G, B: Byte;
+ X, Y: Longint;
+begin
+ Step24 := ((Header.biWidth * 3 + 3) and not 3) - Header.biWidth * 3;
+ Step8 := ((Header.biWidth + 3) and not 3) - Header.biWidth;
+ Rm := Hist.Rm;
+ Gm := Hist.Gm;
+ BM := Hist.BM;
+ for Y := 0 to Header.biHeight - 1 do
+ begin
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ B := Byte(Data24^) and BM;
+ Data24 := HugeOffset(Data24, 1);
+ G := Byte(Data24^) and Gm;
+ Data24 := HugeOffset(Data24, 1);
+ R := Byte(Data24^) and Rm;
+ Data24 := HugeOffset(Data24, 1);
+ HashColor := Hash(R, G, B);
+ repeat
+ Index := Hist.HashTable[HashColor];
+ if (Hist.Freqs[Index].R = R) and (Hist.Freqs[Index].G = G) and
+ (Hist.Freqs[Index].B = B) then
+ Break;
+ Inc(HashColor);
+ if HashColor = MAX_N_HASH then
+ HashColor := 0;
+ until False;
+ PByte(Data8)^ := Hist.Freqs[Index].Nearest;
+ Data8 := HugeOffset(Data8, 1);
+ end;
+ Data24 := HugeOffset(Data24, Step24);
+ Data8 := HugeOffset(Data8, Step8);
+ end;
+end;
+
+procedure Histogram(const Header: TBitmapInfoHeader; var Colors: TRGBPalette;
+ Data24, Data8: Pointer; ColorsWanted: Integer; Rm, Gm, BM: Byte);
+{ map single bitmap to frequency optimised palette }
+var
+ Hist: PHist;
+begin
+ Hist := CreateHistogram(Rm, Gm, BM);
+ try
+ repeat
+ if AddToHistogram(Hist^, Header, Data24) then
+ Break
+ else
+ begin
+ if Gm > Rm then
+ Gm := Gm shl 1
+ else
+ if Rm > BM then
+ Rm := Rm shl 1
+ else
+ BM := BM shl 1;
+ ClearHistogram(Hist, Rm, Gm, BM);
+ end;
+ until False;
+ { Above loop will always be exited as if masks get rough }
+ { enough, ultimately number of unique colours < MAX_N_COLS }
+ PalHistogram(Hist^, Colors, ColorsWanted);
+ MapHistogram(Hist^, Header, Data24, Data8);
+ finally
+ DeleteHistogram(Hist);
+ end;
+end;
+
+{ expand to 24 bits-per-pixel }
+
+(-*
+procedure ExpandTo24Bit(const Header: TBitmapInfoHeader; Colors: TRGBPalette;
+ Data, NewData: Pointer);
+var
+ Scanline, NewScanline: Longint;
+ Y, X: Integer;
+ Src, Dest: Pointer;
+ C: Byte;
+begin
+ if Header.biBitCount = 24 then
+ begin
+ Exit;
+ end;
+ Scanline := ((Header.biWidth * Header.biBitCount + 31) div 32) * 4;
+ NewScanline := ((Header.biWidth * 3 + 3) and not 3);
+ for Y := 0 to Header.biHeight - 1 do
+ begin
+ Src := HugeOffset(Data, Y * Scanline);
+ Dest := HugeOffset(NewData, Y * NewScanline);
+ case Header.biBitCount of
+ 1:
+ begin
+ C := 0;
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ if (X and 7) = 0 then
+ begin
+ C := Byte(Src^);
+ Src := HugeOffset(Src, 1);
+ end
+ else C := C shl 1;
+ PByte(Dest)^ := Colors[C shr 7].rgbBlue;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 7].rgbGreen;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 7].rgbRed;
+ Dest := HugeOffset(Dest, 1);
+ end;
+ end;
+ 4:
+ begin
+ X := 0;
+ while X < Header.biWidth - 1 do
+ begin
+ C := Byte(Src^);
+ Src := HugeOffset(Src, 1);
+ PByte(Dest)^ := Colors[C shr 4].rgbBlue;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 4].rgbGreen;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 4].rgbRed;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C and 15].rgbBlue;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C and 15].rgbGreen;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C and 15].rgbRed;
+ Dest := HugeOffset(Dest, 1);
+ Inc(X, 2);
+ end;
+ if X < Header.biWidth then
+ begin
+ C := Byte(Src^);
+ PByte(Dest)^ := Colors[C shr 4].rgbBlue;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 4].rgbGreen;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C shr 4].rgbRed;
+ {Dest := HugeOffset(Dest, 1);}
+ end;
+ end;
+ 8:
+ begin
+ for X := 0 to Header.biWidth - 1 do
+ begin
+ C := Byte(Src^);
+ Src := HugeOffset(Src, 1);
+ PByte(Dest)^ := Colors[C].rgbBlue;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C].rgbGreen;
+ Dest := HugeOffset(Dest, 1);
+ PByte(Dest)^ := Colors[C].rgbRed;
+ Dest := HugeOffset(Dest, 1);
+ end;
+ end;
+ end;
+ end;
+end;
+*-)
+{$ENDIF !CLR}
+
+
+{ DIB utility routines }
+
+function GetPaletteBitmapFormat(Bitmap: TBitmap): TPixelFormat;
+var
+ PalSize: Integer;
+begin
+ Result := pfDevice;
+ if Bitmap.Palette <> 0 then
+ begin
+ GetObject(Bitmap.Palette, SizeOf(Integer), {$IFNDEF CLR}@{$ENDIF}PalSize);
+ if PalSize > 0 then
+ begin
+ if PalSize <= 2 then
+ Result := pf1bit
+ else
+ if PalSize <= 16 then
+ Result := pf4bit
+ else
+ if PalSize <= 256 then
+ Result := pf8bit;
+ end;
+ end;
+end;
+
+
+function GetBitmapPixelFormat(Bitmap: TBitmap): TPixelFormat;
+begin
+ Result := Bitmap.PixelFormat;
+end;
+
+function BytesPerScanLine(PixelsPerScanline, BitsPerPixel,
+ Alignment: Longint): Longint;
+begin
+ Dec(Alignment);
+ Result := ((PixelsPerScanline * BitsPerPixel) + Alignment) and not Alignment;
+ Result := Result div 8;
+end;
+
+{$IFNDEF CLR}
+
+
+procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader;
+ PixelFormat: TPixelFormat);
+var
+ DS: TDIBSection;
+ Bytes: Integer;
+begin
+ DS.dsbmih.biSize := 0;
+ { Retrieve the info for the current bitmap, thus with the current bit size/PixelFormat }
+ Bytes := GetObject(Bitmap, SizeOf(DS), @DS);
+ if Bytes = 0 then
+ InvalidBitmap
+ else
+ if (Bytes >= (SizeOf(DS.dsbm) + SizeOf(DS.dsbmih))) and
+ (DS.dsbmih.biSize >= DWORD(SizeOf(DS.dsbmih))) then
+ BI := DS.dsbmih
+ else
+ begin
+ FillChar(BI, SizeOf(BI), 0);
+ with BI, DS.dsbm do
+ begin
+ biSize := SizeOf(BI);
+ biWidth := bmWidth;
+ biHeight := bmHeight;
+ end;
+ end;
+ case PixelFormat of
+ pf1bit:
+ BI.biBitCount := 1;
+ pf4bit:
+ BI.biBitCount := 4;
+ pf8bit:
+ BI.biBitCount := 8;
+ pf24bit:
+ BI.biBitCount := 24;
+ else
+ BI.biBitCount := DS.dsbm.bmBitsPixel * DS.dsbm.bmPlanes;
+ end;
+ BI.biPlanes := 1;
+ { Calculate the size of the image with the new bit count; better would be to
+ call GetDIBits, see http://support.microsoft.com/default.aspx?scid=kb;EN-US;80080
+ }
+ BI.biSizeImage := BytesPerScanLine(BI.biWidth, BI.biBitCount, 32) *
+ Abs(BI.biHeight);
+ BI.biClrUsed := 0;
+ BI.biClrImportant := 0;
+end;
+
+procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
+ var ImageSize: Longint; BitCount: TPixelFormat);
+var
+ BI: TBitmapInfoHeader;
+begin
+ InitializeBitmapInfoHeader(Bitmap, BI, BitCount);
+ if BI.biBitCount > 8 then
+ begin
+ InfoHeaderSize := SizeOf(TBitmapInfoHeader);
+ if (BI.biCompression and BI_BITFIELDS) <> 0 then
+ Inc(InfoHeaderSize, 12);
+ end
+ else
+ InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl BI.biBitCount);
+ ImageSize := BI.biSizeImage;
+end;
+
+function GetDInColors(const BI: TBitmapInfoHeader): Integer;
+begin
+ if (BI.biClrUsed = 0) and (BI.biBitCount <= 8) then
+ Result := 1 shl BI.biBitCount
+ else
+ Result := BI.biClrUsed;
+end;
+
+function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
+ var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean;
+var
+ OldPal: HPALETTE;
+ DC: HDC;
+begin
+ InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat);
+ with TBitmapInfoHeader(BitmapInfo) do
+ biHeight := Abs(biHeight);
+ OldPal := 0;
+ DC := CreateScreenCompatibleDC;
+ try
+ if Palette <> 0 then
+ begin
+ OldPal := SelectPalette(DC, Palette, False);
+ RealizePalette(DC);
+ end;
+ Result := GetDIBits(DC, Bitmap, 0, TBitmapInfoHeader(BitmapInfo).biHeight,
+ @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0;
+
+ TBitmapInfoHeader(BitmapInfo).biClrUsed := GetDInColors(TBitmapInfoHeader(BitmapInfo));
+ finally
+ if OldPal <> 0 then
+ SelectPalette(DC, OldPal, False);
+ DeleteDC(DC);
+ end;
+end;
+
+function DIBFromBit(Src: HBITMAP; Pal: HPALETTE; PixelFormat: TPixelFormat;
+ var Length: Longint): Pointer;
+var
+ HeaderSize: Integer;
+ ImageSize: Longint;
+ FileHeader: PBitmapFileHeader;
+ BI: PBitmapInfoHeader;
+ Bits: Pointer;
+begin
+ if Src = 0 then
+ InvalidBitmap;
+ InternalGetDIBSizes(Src, HeaderSize, ImageSize, PixelFormat);
+ Length := SizeOf(TBitmapFileHeader) + HeaderSize + ImageSize;
+ Result := AllocMemo(Length);
+ try
+ FillChar(Result^, Length, 0);
+ FileHeader := Result;
+ with FileHeader^ do
+ begin
+ bfType := $4D42;
+ bfSize := Length;
+ bfOffBits := SizeOf(FileHeader^) + HeaderSize;
+ end;
+ BI := PBitmapInfoHeader(Longint(FileHeader) + SizeOf(FileHeader^));
+ Bits := Pointer(Longint(BI) + HeaderSize);
+ InternalGetDIB(Src, Pal, BI^, Bits^, PixelFormat);
+ except
+ FreeMemo(Result);
+ raise;
+ end;
+end;
+
+{ Change bits per pixel in a General Bitmap }
+
+function BitmapToMemoryStream(Bitmap: TBitmap; PixelFormat: TPixelFormat;
+ Method: TMappingMethod): TMemoryStream;
+var
+ FileHeader: PBitmapFileHeader;
+ BI, NewBI: PBitmapInfoHeader;
+ Bits: Pointer;
+ NewPalette: PRGBPalette;
+ NewHeaderSize: Integer;
+ ImageSize, Length, Len: Longint;
+ P, InitData: Pointer;
+ ColorCount: Integer;
+ SourceBitmapFormat: TPixelFormat;
+begin
+ Result := nil;
+ if Bitmap.Handle = 0 then
+ InvalidBitmap;
+ SourceBitmapFormat := GetBitmapPixelFormat(Bitmap);
+ if (SourceBitmapFormat = PixelFormat) and
+ (Method <> mmGrayscale) then
+ begin
+ Result := TMemoryStream.Create;
+ try
+ Bitmap.SaveToStream(Result);
+ Result.Position := 0;
+ except
+ Result.Free;
+ raise;
+ end;
+ Exit;
+ end;
+ case PixelFormat of
+ pf1bit, pf4bit, pf24bit:
+ begin
+ P := DIBFromBit(Bitmap.Handle, Bitmap.Palette, PixelFormat, Length);
+ try
+ Result := TMemoryStream.Create;
+ try
+ Result.Write(P^, Length);
+ Result.Position := 0;
+ except
+ Result.Free;
+ raise;
+ end;
+ finally
+ FreeMemo(P);
+ end;
+ end;
+ pf8bit:
+ begin
+ { pf8bit - expand to 24bit first }
+ InitData := DIBFromBit(Bitmap.Handle, Bitmap.Palette, pf24bit, Len);
+ try
+ BI := PBitmapInfoHeader(Longint(InitData) + SizeOf(TBitmapFileHeader));
+ if BI^.biBitCount <> 24 then
+ raise EJVCLException.CreateRes(@RsEBitCountNotImplemented);
+ Bits := Pointer(Longint(BI) + SizeOf(TBitmapInfoHeader));
+ InternalGetDIBSizes(Bitmap.Handle, NewHeaderSize, ImageSize, PixelFormat);
+ Length := SizeOf(TBitmapFileHeader) + NewHeaderSize;
+ P := AllocMemo(Length);
+ try
+ FillChar(P^, Length, #0);
+ NewBI := PBitmapInfoHeader(Longint(P) + SizeOf(TBitmapFileHeader));
+ if NewHeaderSize <= SizeOf(TBitmapInfoHeader) then
+ NewPalette := nil
+ else
+ NewPalette := PRGBPalette(Longint(NewBI) + SizeOf(TBitmapInfoHeader));
+ FileHeader := PBitmapFileHeader(P);
+ InitializeBitmapInfoHeader(Bitmap.Handle, NewBI^, PixelFormat);
+ if Assigned(NewPalette) then
+ case Method of
+ mmQuantize:
+ begin
+ ColorCount := 256;
+ Quantize(BI^, Bits, Bits, ColorCount, NewPalette^);
+ NewBI^.biClrImportant := ColorCount;
+ end;
+ mmTrunc784:
+ begin
+ TruncPal7R8G4B(NewPalette^);
+ Trunc7R8G4B(BI^, Bits, Bits);
+ NewBI^.biClrImportant := 224;
+ end;
+ mmTrunc666:
+ begin
+ TruncPal6R6G6B(NewPalette^);
+ Trunc6R6G6B(BI^, Bits, Bits);
+ NewBI^.biClrImportant := 216;
+ end;
+ mmTripel:
+ begin
+ TripelPal(NewPalette^);
+ Tripel(BI^, Bits, Bits);
+ end;
+ mmHistogram:
+ begin
+ Histogram(BI^, NewPalette^, Bits, Bits,
+ PixelFormatToColors(PixelFormat), 255, 255, 255);
+ end;
+ mmGrayscale:
+ begin
+ GrayPal(NewPalette^);
+ GrayScale(BI^, Bits, Bits);
+ end;
+ end;
+ with FileHeader^ do
+ begin
+ bfType := $4D42;
+ bfSize := Length;
+ bfOffBits := SizeOf(FileHeader^) + NewHeaderSize;
+ end;
+ Result := TMemoryStream.Create;
+ try
+ Result.Write(P^, Length);
+ Result.Write(Bits^, ImageSize);
+ Result.Position := 0;
+ except
+ Result.Free;
+ raise;
+ end;
+ finally
+ FreeMemo(P);
+ end;
+ finally
+ FreeMemo(InitData);
+ end;
+ end
+ else
+ raise EJVCLException.CreateRes(@RsEPixelFormatNotImplemented)
+ end;
+end;
+
+function BitmapToMemory(Bitmap: TBitmap; Colors: Integer): TStream;
+var
+ PixelFormat: TPixelFormat;
+begin
+ if Colors <= 2 then
+ PixelFormat := pf1bit
+ else
+ if Colors <= 16 then
+ PixelFormat := pf4bit
+ else
+ if Colors <= 256 then
+ PixelFormat := pf8bit
+ else
+ PixelFormat := pf24bit;
+ Result := BitmapToMemoryStream(Bitmap, PixelFormat, DefaultMappingMethod);
+end;
+
+procedure SaveBitmapToFile(const FileName: string; Bitmap: TBitmap;
+ Colors: Integer);
+var
+ Memory: TStream;
+begin
+ if Bitmap.Monochrome then
+ Colors := 2;
+ Memory := BitmapToMemory(Bitmap, Colors);
+ try
+ TMemoryStream(Memory).SaveToFile(FileName);
+ finally
+ Memory.Free;
+ end;
+end;
+
+procedure SetBitmapPixelFormat(Bitmap: TBitmap; PixelFormat: TPixelFormat;
+ Method: TMappingMethod);
+var
+ M: TMemoryStream;
+begin
+ if (Bitmap.Handle = 0) or ((GetBitmapPixelFormat(Bitmap) = PixelFormat) and (Method <> mmGrayscale)) then
+ Exit;
+ M := BitmapToMemoryStream(Bitmap, PixelFormat, Method);
+ try
+ Bitmap.LoadFromStream(M);
+ finally
+ M.Free;
+ end;
+end;
+
+procedure GrayscaleBitmap(Bitmap: TBitmap);
+begin
+ SetBitmapPixelFormat(Bitmap, pf8bit, mmGrayscale);
+end;
+
+
+{$ENDIF CLR}
+
+function ZoomImage(ImageW, ImageH, MaxW, MaxH: Integer; Stretch: Boolean):
+ TPoint;
+var
+ Zoom: Double;
+begin
+ Result := Point(0, 0);
+ if (MaxW <= 0) or (MaxH <= 0) or (ImageW <= 0) or (ImageH <= 0) then
+ Exit;
+ with Result do
+ if Stretch then
+ begin
+ Zoom := MaxFloat([ImageW / MaxW, ImageH / MaxH]);
+ if Zoom > 0 then
+ begin
+ X := Round(ImageW * 0.98 / Zoom);
+ Y := Round(ImageH * 0.98 / Zoom);
+ end
+ else
+ begin
+ X := ImageW;
+ Y := ImageH;
+ end;
+ end
+ else
+ begin
+ X := MaxW;
+ Y := MaxH;
+ end;
+end;
+
+procedure TileImage(Canvas: TCanvas; Rect: TRect; Image: TGraphic);
+var
+ X, Y: Integer;
+ SaveIndex: Integer;
+begin
+ if (Image.Width = 0) or (Image.Height = 0) then
+ Exit;
+ SaveIndex := SaveDC(Canvas.Handle);
+ try
+ with Rect do
+ IntersectClipRect(Canvas.Handle, Left, Top, Right, Bottom);
+ for X := 0 to (RectWidth(Rect) div Image.Width) do
+ for Y := 0 to (RectHeight(Rect) div Image.Height) do
+ Canvas.Draw(Rect.Left + X * Image.Width,
+ Rect.Top + Y * Image.Height, Image);
+ finally
+ RestoreDC(Canvas.Handle, SaveIndex);
+ end;
+end;
+
+//=== { TJvGradientOptions } =================================================
+
+constructor TJvGradientOptions.Create;
+begin
+ inherited Create;
+ FStartColor := clSilver;
+ FEndColor := clGray;
+ FStepCount := 64;
+ FDirection := fdTopToBottom;
+end;
+
+procedure TJvGradientOptions.Assign(Source: TPersistent);
+begin
+ if Source is TJvGradientOptions then
+ begin
+ with TJvGradientOptions(Source) do
+ begin
+ Self.FStartColor := StartColor;
+ Self.FEndColor := EndColor;
+ Self.FStepCount := StepCount;
+ Self.FDirection := Direction;
+ Self.FVisible := Visible;
+ end;
+ Changed;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvGradientOptions.Changed;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvGradientOptions.Draw(Canvas: TCanvas; Rect: TRect);
+begin
+ GradientFillRect(Canvas, Rect, FStartColor, FEndColor, FDirection, FStepCount);
+end;
+
+procedure TJvGradientOptions.SetStartColor(Value: TColor);
+begin
+ if Value <> FStartColor then
+ begin
+ FStartColor := Value;
+ Changed;
+ end;
+end;
+
+procedure TJvGradientOptions.SetEndColor(Value: TColor);
+begin
+ if Value <> FEndColor then
+ begin
+ FEndColor := Value;
+ Changed;
+ end;
+end;
+
+procedure TJvGradientOptions.SetDirection(Value: TFillDirection);
+begin
+ if Value <> FDirection then
+ begin
+ FDirection := Value;
+ Changed;
+ end;
+end;
+
+procedure TJvGradientOptions.SetStepCount(Value: Byte);
+begin
+ if Value <> FStepCount then
+ begin
+ FStepCount := Value;
+ Changed;
+ end;
+end;
+
+procedure TJvGradientOptions.SetVisible(Value: Boolean);
+begin
+ if FVisible <> Value then
+ begin
+ FVisible := Value;
+ Changed;
+ end;
+end;
+{ end JvGraph }
+
+{ begin JvCtrlUtils }
+
+//=== ToolBarMenu ============================================================
+
+procedure JvCreateToolBarMenu(AForm: TForm; AToolBar: TToolBar;
+ AMenu: TMainMenu);
+var
+ I, TotalWidth: Integer;
+ Button: TToolButton;
+begin
+ if AForm.FormStyle = fsMDIForm then
+ {$IFDEF CLR}
+ raise EJVCLException.Create(RsENotForMdi);
+ {$ELSE}
+ raise EJVCLException.CreateRes(@RsENotForMdi);
+ {$ENDIF CLR}
+ if AMenu = nil then
+ AMenu := AForm.Menu;
+ if AMenu = nil then
+ Exit;
+ with AToolBar do
+ begin
+ TotalWidth := BorderWidth;
+ for I := ButtonCount - 1 downto 0 do
+ Buttons[I].Free;
+ ShowCaptions := True;
+ end;
+ with AMenu do
+ for I := Items.Count - 1 downto 0 do
+ begin
+ Button := TToolButton.Create(AToolBar);
+ Button.Parent := AToolBar;
+ Button.AutoSize := True;
+ Button.Caption := Items[I].Caption;
+ Button.Grouped := True;
+ Button.MenuItem := Items[I];
+ Inc(TotalWidth, Button.Width + AToolBar.BorderWidth);
+ end;
+ AToolBar.Width := TotalWidth;
+ AForm.Menu := nil;
+end;
+
+//=== ListView functions =====================================================
+
+procedure JvListViewToStrings(ListView: TListView; Strings: TStrings;
+ SelectedOnly: Boolean; Headers: Boolean);
+var
+ R, C: Integer;
+ ColWidths: array of Word;
+ S: string;
+
+ procedure AddLine;
+ begin
+ Strings.Add(TrimRight(S));
+ end;
+
+ function StrPadRight(const S: string; Len: Integer): string;
+ begin
+ Result := S;
+ if Len > Length(S) then
+ Result := Result + MakeStr(' ', Len - Length(S))
+ end;
+
+ function StrPadLeft(const S: string; Len: Integer): string;
+ begin
+ Result := S;
+ if Len > Length(S) then
+ Result := MakeStr(' ', Len - Length(S)) + Result;
+ end;
+
+ function MakeCellStr(const Text: string; Index: Integer): string;
+ begin
+ with ListView.Columns[Index] do
+ if Alignment = taLeftJustify then
+ Result := StrPadRight(Text, ColWidths[Index] + 1)
+ else
+ Result := StrPadLeft(Text, ColWidths[Index]) + ' ';
+ end;
+
+begin
+ SetLength(S, 256);
+ with ListView do
+ begin
+ SetLength(ColWidths, Columns.Count);
+ if Headers then
+ for C := 0 to Columns.Count - 1 do
+ ColWidths[C] := Length(Trim(Columns[C].Caption));
+ for R := 0 to Items.Count - 1 do
+ if not SelectedOnly or Items[R].Selected then
+ begin
+ ColWidths[0] := Max(ColWidths[0], Length(Trim(Items[R].Caption)));
+ for C := 0 to Items[R].SubItems.Count - 1 do
+ ColWidths[C + 1] := Max(ColWidths[C + 1],
+ Length(Trim(Items[R].SubItems[C])));
+ end;
+ Strings.BeginUpdate;
+ try
+ if Headers then
+ with Columns do
+ begin
+ S := '';
+ for C := 0 to Count - 1 do
+ S := S + MakeCellStr(Items[C].Caption, C);
+ AddLine;
+ S := '';
+ for C := 0 to Count - 1 do
+ S := S + StringOfChar('-', ColWidths[C]) + ' ';
+ AddLine;
+ end;
+ for R := 0 to Items.Count - 1 do
+ if not SelectedOnly or Items[R].Selected then
+ with Items[R] do
+ begin
+ S := MakeCellStr(Caption, 0);
+ for C := 0 to Min(SubItems.Count, Columns.Count - 1) - 1 do
+ S := S + MakeCellStr(SubItems[C], C + 1);
+ AddLine;
+ end;
+ finally
+ Strings.EndUpdate;
+ end;
+ end;
+end;
+
+function JvListViewSafeSubItemString(Item: TListItem; SubItemIndex: Integer): string;
+begin
+ if Item.SubItems.Count > SubItemIndex then
+ Result := Item.SubItems[SubItemIndex]
+ else
+ Result := '';
+end;
+
+procedure JvListViewSortClick(Column: TListColumn; AscendingSortImage: Integer;
+ DescendingSortImage: Integer);
+var
+ ListView: TListView;
+ I: Integer;
+begin
+ ListView := TListColumns(Column.Collection).Owner as TListView;
+ ListView.Columns.BeginUpdate;
+ try
+ with ListView.Columns do
+ for I := 0 to Count - 1 do
+ Items[I].ImageIndex := -1;
+ if ListView.Tag and $FF = Column.Index then
+ ListView.Tag := ListView.Tag xor $100
+ else
+ ListView.Tag := Column.Index;
+ if ListView.Tag and $100 = 0 then
+ Column.ImageIndex := AscendingSortImage
+ else
+ Column.ImageIndex := DescendingSortImage;
+ finally
+ ListView.Columns.EndUpdate;
+ end;
+end;
+
+procedure JvListViewCompare(ListView: TListView; Item1, Item2: TListItem;
+ var Compare: Integer);
+var
+ ColIndex: Integer;
+
+ function FmtStrToInt(S: string): Integer;
+ var
+ I: Integer;
+ begin
+ I := 1;
+ while I <= Length(S) do
+ if not (S[I] in (DigitChars + ['-'])) then
+ Delete(S, I, 1)
+ else
+ Inc(I);
+ Result := StrToInt(S);
+ end;
+
+begin
+ with ListView do
+ begin
+ ColIndex := Tag and $FF - 1;
+ if Columns[ColIndex + 1].Alignment = taLeftJustify then
+ begin
+ if ColIndex = -1 then
+ {$IFDEF CLR}
+ Compare := CompareText(Item1.Caption, Item2.Caption)
+ else
+ Compare := CompareText(Item1.SubItems[ColIndex], Item2.SubItems[ColIndex]);
+ {$ELSE}
+ Compare := AnsiCompareText(Item1.Caption, Item2.Caption)
+ else
+ Compare := AnsiCompareText(Item1.SubItems[ColIndex], Item2.SubItems[ColIndex]);
+ {$ENDIF CLR}
+ end
+ else
+ begin
+ if ColIndex = -1 then
+ Compare := FmtStrToInt(Item1.Caption) - FmtStrToInt(Item2.Caption)
+ else
+ Compare := FmtStrToInt(Item1.SubItems[ColIndex]) -
+ FmtStrToInt(Item2.SubItems[ColIndex]);
+ end;
+ if Tag and $100 <> 0 then
+ Compare := -Compare;
+ end;
+end;
+
+procedure JvListViewSelectAll(ListView: TListView; Deselect: Boolean);
+var
+ I: Integer;
+ H: THandle;
+ Data: Integer;
+ SaveOnSelectItem: TLVSelectItemEvent;
+begin
+ with ListView do
+ if MultiSelect then
+ begin
+ Items.BeginUpdate;
+ SaveOnSelectItem := OnSelectItem;
+ WaitCursor;
+ try
+ H := Handle;
+ OnSelectItem := nil;
+ if Deselect then
+ Data := 0
+ else
+ Data := LVIS_SELECTED;
+ for I := 0 to Items.Count - 1 do
+ ListView_SetItemState(H, I, Data, LVIS_SELECTED);
+ finally
+ OnSelectItem := SaveOnSelectItem;
+ Items.EndUpdate;
+ end;
+ end;
+end;
+
+function JvListViewSaveState(ListView: TListView): TJvLVItemStateData;
+var
+ TempItem: TListItem;
+begin
+ with Result do
+ begin
+ Focused := Assigned(ListView.ItemFocused);
+ Selected := Assigned(ListView.Selected);
+ if Focused then
+ TempItem := ListView.ItemFocused
+ else
+ if Selected then
+ TempItem := ListView.Selected
+ else
+ TempItem := nil;
+ if TempItem <> nil then
+ begin
+ Caption := TempItem.Caption;
+ Data := TempItem.Data;
+ end
+ else
+ begin
+ Caption := '';
+ Data := nil;
+ end;
+ end;
+end;
+
+function JvListViewRestoreState(ListView: TListView; Data: TJvLVItemStateData;
+ MakeVisible: Boolean; FocusFirst: Boolean): Boolean;
+var
+ TempItem: TListItem;
+begin
+ with ListView do
+ begin
+ TempItem := FindCaption(0, Data.Caption, False, True, False);
+ Result := TempItem <> nil;
+ if Result then
+ begin
+ TempItem.Focused := Data.Focused;
+ TempItem.Selected := Data.Selected;
+ end
+ else
+ if FocusFirst and (Items.Count > 0) then
+ begin
+ TempItem := Items[0];
+ TempItem.Focused := True;
+ TempItem.Selected := True;
+ end;
+ if MakeVisible and (TempItem <> nil) then
+ TempItem.MakeVisible(True);
+ end;
+end;
+
+
+
+function JvListViewGetOrderedColumnIndex(Column: TListColumn): Integer;
+var
+ {$IFDEF CLR}
+ ColumnOrder: TIntegerDynArray;
+ {$ELSE}
+ ColumnOrder: array of Integer;
+ {$ENDIF CLR}
+ Columns: TListColumns;
+ I: Integer;
+begin
+ Result := -1;
+ Columns := TListColumns(Column.Collection);
+ SetLength(ColumnOrder, Columns.Count);
+ {$IFDEF CLR}
+ ListView_GetColumnOrderArray(Columns.Owner.Handle, Columns.Count, ColumnOrder);
+ {$ELSE}
+ ListView_GetColumnOrderArray(Columns.Owner.Handle, Columns.Count, PInteger(ColumnOrder));
+ {$ENDIF CLR}
+ for I := 0 to High(ColumnOrder) do
+ if ColumnOrder[I] = Column.Index then
+ begin
+ Result := I;
+ Break;
+ end;
+end;
+
+procedure JvListViewSetSystemImageList(ListView: TListView);
+var
+ FileInfo: TSHFileInfo;
+ ImageListHandle: THandle;
+begin
+ {$IFNDEF CLR}
+ FillChar(FileInfo, SizeOf(FileInfo), 0);
+ {$ENDIF !CLR}
+ ImageListHandle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo),
+ SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
+ SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle);
+ {$IFNDEF CLR}
+ FillChar(FileInfo, SizeOf(FileInfo), 0);
+ {$ENDIF !CLR}
+ ImageListHandle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo),
+ SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
+ SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL, ImageListHandle);
+end;
+
+
+//== MessageBox ==============================================================
+
+function JvMessageBox(const Text, Caption: string; Flags: DWORD): Integer;
+begin
+ Result := MsgBox(Text, Caption, Flags);
+end;
+
+function JvMessageBox(const Text: string; Flags: DWORD): Integer;
+begin
+ Result := MsgBox(Text, Application.Title, Flags);
+end;
+********************)
+
+procedure UpdateTrackFont(TrackFont, Font: TFont; TrackOptions: TJvTrackFontOptions);
+begin
+ if hoFollowFont in TrackOptions then
+ begin
+ if not (hoPreserveCharSet in TrackOptions) then
+ TrackFont.Charset := Font.Charset;
+ if not (hoPreserveColor in TrackOptions) then
+ TrackFont.Color := Font.Color;
+ if not (hoPreserveHeight in TrackOptions) then
+ TrackFont.Height := Font.Height;
+ if not (hoPreserveName in TrackOptions) then
+ TrackFont.Name := Font.Name;
+ if not (hoPreservePitch in TrackOptions) then
+ TrackFont.Pitch := Font.Pitch;
+ if not (hoPreserveStyle in TrackOptions) then
+ TrackFont.Style := Font.Style;
+ end;
+end;
+
+(********************
+
+{ end JvCtrlUtils }
+
+function GetDefaultCheckBoxSize: TSize;
+begin
+ with TBitmap.Create do
+ try
+ {$IFDEF CLR}
+ Handle := LoadBitmap(0, OBM_CHECKBOXES);
+ {$ELSE}
+ Handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
+ {$ENDIF CLR}
+ Result.cx := Width div 4;
+ Result.cy := Height div 3;
+ finally
+ Free;
+ end;
+end;
+
+function CanvasMaxTextHeight(Canvas: TCanvas): Integer;
+var
+ tt: TTextMetric;
+begin
+ // (ahuser) Qt returns different values for TextHeight('Ay') and TextHeigth(#1..#255)
+ GetTextMetrics(Canvas.Handle, tt);
+ Result := tt.tmHeight;
+end;
+
+{$IFDEF MSWINDOWS}
+
+//=== AllocateHWndEx =========================================================
+
+{$IFNDEF CLR}
+const
+ cUtilWindowExClass: TWndClass = (
+ style: 0;
+ lpfnWndProc: nil;
+ cbClsExtra: 0;
+ cbWndExtra: SizeOf(TMethod);
+ hInstance: 0;
+ hIcon: 0;
+ hCursor: 0;
+ hbrBackground: 0;
+ lpszMenuName: nil;
+ lpszClassName: 'TPUtilWindowEx');
+
+function StdWndProc(Window: THandle; Message, WParam: WPARAM;
+ LParam: LPARAM): LRESULT; stdcall;
+var
+ Msg: Messages.TMessage;
+ WndProc: TWndMethod;
+begin
+ TMethod(WndProc).Code := Pointer(GetWindowLong(Window, 0));
+ TMethod(WndProc).Data := Pointer(GetWindowLong(Window, SizeOf(Pointer)));
+ if Assigned(WndProc) then
+ begin
+ Msg.Msg := Message;
+ Msg.WParam := WParam;
+ Msg.LParam := LParam;
+ Msg.Result := 0;
+ WndProc(Msg);
+ Result := Msg.Result;
+ end
+ else
+ Result := DefWindowProc(Window, Message, WParam, LParam);
+end;
+{$ENDIF !CLR}
+
+function AllocateHWndEx(Method: TWndMethod; const AClassName: string = ''): THandle;
+{$IFDEF CLR}
+begin
+ Result := AllocateHWnd(Method);
+end;
+{$ELSE}
+var
+ TempClass: TWndClass;
+ UtilWindowExClass: TWndClass;
+ ClassRegistered: Boolean;
+begin
+ UtilWindowExClass := cUtilWindowExClass;
+ UtilWindowExClass.hInstance := HInstance;
+ UtilWindowExClass.lpfnWndProc := @DefWindowProc;
+ if AClassName <> '' then
+ UtilWindowExClass.lpszClassName := PChar(AClassName);
+
+ ClassRegistered := Windows.GetClassInfo(HInstance, UtilWindowExClass.lpszClassName,
+ TempClass);
+ if not ClassRegistered or (TempClass.lpfnWndProc <> @DefWindowProc) then
+ begin
+ if ClassRegistered then
+ Windows.UnregisterClass(UtilWindowExClass.lpszClassName, HInstance);
+ Windows.RegisterClass(UtilWindowExClass);
+ end;
+ Result := Windows.CreateWindowEx(Windows.WS_EX_TOOLWINDOW, UtilWindowExClass.lpszClassName,
+ '', Windows.WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil);
+
+ if Assigned(Method) then
+ begin
+ Windows.SetWindowLong(Result, 0, Longint(TMethod(Method).Code));
+ Windows.SetWindowLong(Result, SizeOf(TMethod(Method).Code), Longint(TMethod(Method).Data));
+ Windows.SetWindowLong(Result, GWL_WNDPROC, Longint(@StdWndProc));
+ end;
+end;
+{$ENDIF CLR}
+
+procedure DeallocateHWndEx(Wnd: THandle);
+begin
+ {$IFDEF CLR}
+ DeallocateHWnd(Wnd);
+ {$ELSE}
+ Windows.DestroyWindow(Wnd);
+ {$ENDIF CLR}
+end;
+
+function JvMakeObjectInstance(Method: TWndMethod): {$IFDEF CLR}TFNWndProc{$ELSE}Pointer{$ENDIF};
+begin
+ Result := MakeObjectInstance(Method);
+end;
+
+procedure JvFreeObjectInstance(ObjectInstance: {$IFDEF CLR}TFNWndProc{$ELSE}Pointer{$ENDIF});
+begin
+ if Assigned(ObjectInstance) then
+ FreeObjectInstance(ObjectInstance);
+end;
+
+{$ENDIF MSWINDOWS}
+
+procedure InitScreenCursors;
+begin
+ try
+ if Screen <> nil then
+ begin
+ // now only available through SetDefaultJVCLCursors
+ { (ahuser) if used in VisualCLX mode Application.Destroy crashes }
+ Screen.Cursors[crMultiDragLink] := Screen.Cursors[crMultiDrag];
+ Screen.Cursors[crDragAlt] := Screen.Cursors[crDrag];
+ Screen.Cursors[crMultiDragAlt] := Screen.Cursors[crMultiDrag];
+ Screen.Cursors[crMultiDragLinkAlt] := Screen.Cursors[crMultiDrag];
+ end;
+ except
+ end;
+end;
+
+const
+ Lefts = ['[', '{', '('];
+ Rights = [']', '}', ')'];
+
+{ Utilities routines }
+
+function FontStylesToString(Styles: TFontStyles): string;
+begin
+ Result := '';
+ if fsBold in Styles then
+ Result := Result + 'B';
+ if fsItalic in Styles then
+ Result := Result + 'I';
+ if fsUnderline in Styles then
+ Result := Result + 'U';
+ if fsStrikeOut in Styles then
+ Result := Result + 'S';
+end;
+
+function StringToFontStyles(const Styles: string): TFontStyles;
+begin
+ Result := [];
+ if Pos('B', UpperCase(Styles)) > 0 then
+ Include(Result, fsBold);
+ if Pos('I', UpperCase(Styles)) > 0 then
+ Include(Result, fsItalic);
+ if Pos('U', UpperCase(Styles)) > 0 then
+ Include(Result, fsUnderline);
+ if Pos('S', UpperCase(Styles)) > 0 then
+ Include(Result, fsStrikeOut);
+end;
+
+
+
+function FontToString(Font: TFont): string;
+begin
+ with Font do
+ Result := Format('%s,%d,%s,%d,%s,%d', [Name, Size,
+ FontStylesToString(Style), Ord(Pitch), ColorToString(Color), Charset]);
+end;
+
+function StringToFont(const Str: string): TFont;
+const
+ Delims = [',', ';'];
+var
+ Pos: Integer;
+ I: Byte;
+ S: string;
+begin
+ Result := TFont.Create;
+ try
+ Pos := 1;
+ I := 0;
+ while Pos <= Length(Str) do
+ begin
+ Inc(I);
+ S := Trim(ExtractSubstr(Str, Pos, Delims));
+ case I of
+ 1:
+ Result.Name := S;
+ 2:
+ Result.Size := StrToIntDef(S, Result.Size);
+ 3:
+ Result.Style := StringToFontStyles(S);
+ 4:
+ Result.Pitch := TFontPitch(StrToIntDef(S, Ord(Result.Pitch)));
+ 5:
+ Result.Color := StringToColor(S);
+ 6:
+ Result.Charset := TFontCharset(StrToIntDef(S, Result.Charset));
+ end;
+ end;
+ finally
+ end;
+end;
+
+
+
+function RectToStr(Rect: TRect): string;
+begin
+ with Rect do
+ Result := Format('[%d,%d,%d,%d]', [Left, Top, Right, Bottom]);
+end;
+
+function StrToRect(const Str: string; const Def: TRect): TRect;
+var
+ S: string;
+ Temp: string[10];
+ I: Integer;
+begin
+ Result := Def;
+ S := Str;
+ if (S[1] in Lefts) and (S[Length(S)] in Rights) then
+ begin
+ Delete(S, 1, 1);
+ SetLength(S, Length(S) - 1);
+ end;
+ I := Pos(',', S);
+ if I > 0 then
+ begin
+ Temp := Trim(Copy(S, 1, I - 1));
+ Result.Left := StrToIntDef(Temp, Def.Left);
+ Delete(S, 1, I);
+ I := Pos(',', S);
+ if I > 0 then
+ begin
+ Temp := Trim(Copy(S, 1, I - 1));
+ Result.Top := StrToIntDef(Temp, Def.Top);
+ Delete(S, 1, I);
+ I := Pos(',', S);
+ if I > 0 then
+ begin
+ Temp := Trim(Copy(S, 1, I - 1));
+ Result.Right := StrToIntDef(Temp, Def.Right);
+ Delete(S, 1, I);
+ Temp := Trim(S);
+ Result.Bottom := StrToIntDef(Temp, Def.Bottom);
+ end;
+ end;
+ end;
+end;
+
+function PointToStr(P: TPoint): string;
+begin
+ with P do
+ Result := Format('[%d,%d]', [X, Y]);
+end;
+
+function StrToPoint(const Str: string; const Def: TPoint): TPoint;
+var
+ S: string;
+ Temp: string[10];
+ I: Integer;
+begin
+ Result := Def;
+ S := Str;
+ if (S[1] in Lefts) and (S[Length(Str)] in Rights) then
+ begin
+ Delete(S, 1, 1);
+ SetLength(S, Length(S) - 1);
+ end;
+ I := Pos(',', S);
+ if I > 0 then
+ begin
+ Temp := Trim(Copy(S, 1, I - 1));
+ Result.X := StrToIntDef(Temp, Def.X);
+ Delete(S, 1, I);
+ Temp := Trim(S);
+ Result.Y := StrToIntDef(Temp, Def.Y);
+ end;
+end;
+
+procedure DrawArrow(Canvas: TCanvas; Rect: TRect; Color: TColor = clBlack; Direction: TAnchorKind = akBottom);
+var
+ I, Size: Integer;
+begin
+ Size := Rect.Right - Rect.Left;
+ if Odd(Size) then
+ begin
+ Dec(Size);
+ Dec(Rect.Right);
+ end;
+ // set to center by dejoy
+ if RectHeight(Rect) > Size then
+ Rect.Top := Rect.Top + (RectHeight(Rect) - (Size div 2)) div 2;
+
+ Rect.Bottom := Rect.Top + Size;
+ Canvas.Pen.Color := Color;
+ case Direction of
+ akLeft:
+ for I := 0 to Size div 2 do
+ begin
+ Canvas.MoveTo(Rect.Right - I, Rect.Top + I);
+ Canvas.LineTo(Rect.Right - I, Rect.Bottom - I);
+ end;
+ akRight:
+ for I := 0 to Size div 2 do
+ begin
+ Canvas.MoveTo(Rect.Left + I, Rect.Top + I);
+ Canvas.LineTo(Rect.Left + I, Rect.Bottom - I);
+ end;
+ akTop:
+ for I := 0 to Size div 2 do
+ begin
+ Canvas.MoveTo(Rect.Left + I, Rect.Bottom - I);
+ Canvas.LineTo(Rect.Right - I, Rect.Bottom - I);
+ end;
+ akBottom:
+ for I := 0 to Size div 2 do
+ begin
+ Canvas.MoveTo(Rect.Left + I, Rect.Top + I);
+ Canvas.LineTo(Rect.Right - I, Rect.Top + I);
+ end;
+ end;
+end;
+
+function IsPositiveResult(Value: TModalResult): Boolean;
+begin
+ Result := Value in [mrOk, mrYes, mrAll, mrYesToAll];
+end;
+
+function IsNegativeResult(Value: TModalResult): Boolean;
+begin
+ Result := Value in [mrNo, mrNoToAll];
+end;
+
+function IsAbortResult(const Value: TModalResult): Boolean;
+begin
+ Result := Value in [mrCancel, mrAbort];
+end;
+
+function StripAllFromResult(const Value: TModalResult): TModalResult;
+begin
+ case Value of
+ mrAll:
+ Result := mrOk;
+ mrNoToAll:
+ Result := mrNo;
+ mrYesToAll:
+ Result := mrYes;
+ else
+ Result := Value;
+ end;
+end;
+
+//=== { TJvPoint } ===========================================================
+
+procedure TJvPoint.Assign(Source: TPersistent);
+begin
+ if Source is TJvPoint then
+ begin
+ FX := TJvPoint(Source).X;
+ FY := TJvPoint(Source).Y;
+ DoChange;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvPoint.Assign(Source: TPoint);
+begin
+ X := Source.X;
+ Y := Source.Y;
+end;
+
+procedure TJvPoint.CopyToPoint(var Point: TPoint);
+begin
+ Point.X := X;
+ Point.Y := Y;
+end;
+
+procedure TJvPoint.DoChange;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvPoint.SetX(Value: Longint);
+begin
+ FX := Value;
+ DoChange;
+end;
+
+procedure TJvPoint.SetY(Value: Longint);
+begin
+ FY := Value;
+ DoChange;
+end;
+
+//=== { TJvRect } ============================================================
+
+procedure TJvRect.Assign(Source: TRect);
+begin
+ TopLeft.Assign(Source.TopLeft);
+ BottomRight.Assign(Source.BottomRight);
+end;
+
+procedure TJvRect.CopyToRect(var Rect: TRect);
+begin
+ TopLeft.CopyToPoint(Rect.TopLeft);
+ BottomRight.CopyToPoint(Rect.BottomRight);
+end;
+
+constructor TJvRect.Create;
+begin
+ inherited Create;
+ FTopLeft := TJvPoint.Create;
+ FBottomRight := TJvPoint.Create;
+ FTopLeft.OnChange := PointChange;
+ FBottomRight.OnChange := PointChange;
+end;
+
+destructor TJvRect.Destroy;
+begin
+ FTopLeft.Free;
+ FBottomRight.Free;
+ inherited Destroy;
+end;
+
+procedure TJvRect.Assign(Source: TPersistent);
+begin
+ if Source is TJvRect then
+ begin
+ TopLeft.Assign(TJvRect(Source).TopLeft);
+ BottomRight.Assign(TJvRect(Source).BottomRight);
+ DoChange;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvRect.DoChange;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+function TJvRect.GetBottom: Integer;
+begin
+ Result := FBottomRight.Y;
+end;
+
+function TJvRect.GetLeft: Integer;
+begin
+ Result := FTopLeft.X;
+end;
+
+function TJvRect.GetRight: Integer;
+begin
+ Result := FBottomRight.X;
+end;
+
+function TJvRect.GetTop: Integer;
+begin
+ Result := FTopLeft.Y;
+end;
+
+procedure TJvRect.PointChange(Sender: TObject);
+begin
+ DoChange;
+end;
+
+procedure TJvRect.SetBottom(Value: Integer);
+begin
+ FBottomRight.Y := Value;
+end;
+
+procedure TJvRect.SetBottomRight(Value: TJvPoint);
+begin
+ FBottomRight.Assign(Value);
+end;
+
+procedure TJvRect.SetLeft(Value: Integer);
+begin
+ FTopLeft.X := Value;
+end;
+
+procedure TJvRect.SetRight(Value: Integer);
+begin
+ FBottomRight.X := Value;
+end;
+
+procedure TJvRect.SetTop(Value: Integer);
+begin
+ FTopLeft.Y := Value;
+end;
+
+procedure TJvRect.SetTopLeft(Value: TJvPoint);
+begin
+ FTopLeft.Assign(Value);
+end;
+
+function TJvRect.GetHeight: Integer;
+begin
+ Result := FBottomRight.Y - FTopLeft.Y;
+end;
+
+function TJvRect.GetWidth: Integer;
+begin
+ Result := FBottomRight.X - FTopLeft.X;
+end;
+
+procedure TJvRect.SetHeight(Value: Integer);
+begin
+ FBottomRight.Y := FTopLeft.Y + Value;
+end;
+
+procedure TJvRect.SetWidth(Value: Integer);
+begin
+ FBottomRight.X := FTopLeft.X + Value;
+end;
+
+ { TJvSize }
+
+procedure TJvSize.Assign(Source: TPersistent);
+begin
+ if Source is TJvSize then
+ begin
+ FWidth := (Source as TJvSize).Width;
+ FHeight := (Source as TJvSize).Height;
+ DoChange;
+ end
+ else
+ begin
+ inherited Assign(Source);
+ end;
+end;
+
+procedure TJvSize.Assign(Source: TSize);
+begin
+ FWidth := Source.cx;
+ FHeight := Source.cy;
+ DoChange;
+end;
+
+procedure TJvSize.CopyToSize(var Size: TSize);
+begin
+ Size.cx := Width;
+ Size.cy := Height;
+end;
+
+procedure TJvSize.DoChange;
+begin
+ if Assigned(OnChange) then
+ OnChange(Self);
+end;
+
+procedure TJvSize.SetHeight(Value: Integer);
+begin
+ if FHeight <> Value then
+ begin
+ FHeight := Value;
+ DoChange;
+ end;
+end;
+
+procedure TJvSize.SetWidth(Value: Integer);
+begin
+ if FWidth <> Value then
+ begin
+ FWidth := Value;
+ DoChange;
+ end;
+end;
+
+function SelectColorByLuminance(AColor, DarkColor, BrightColor: TColor): TColor;
+var
+ ACol: Longint;
+begin
+ ACol := ColorToRGB(AColor) and $00FFFFFF;
+ if ((2.99 * GetRValue(ACol) + 5.87 * GetGValue(ACol) + 1.14 * GetBValue(ACol)) > $400) then
+ Result := DarkColor
+ else
+ Result := BrightColor;
+end;
+
+const
+ cBR = '
';
+ cHR = '
';
+ cTagBegin = '<';
+ cTagEnd = '>';
+ cLT = '<';
+ cGT = '>';
+ cQuote = '"';
+ cCENTER = 'CENTER';
+ cRIGHT = 'RIGHT';
+ cHREF = 'HREF';
+ cIND = 'IND';
+ cCOLOR = 'COLOR';
+ cBGCOLOR = 'BGCOLOR';
+
+// moved from JvHTControls and renamed
+function HTMLPrepareText(const Text: string): string;
+type
+ THtmlCode = packed record
+ Html: string[10];
+ Text: Char;
+ end;
+const
+ Conversions: array [0..6] of THtmlCode =
+ (
+ (Html: '&'; Text: '&'),
+ (Html: '"'; Text: '"'),
+ (Html: '®'; Text: '®'),
+ (Html: '©'; Text: '©'),
+ (Html: '™'; Text: '™'),
+ (Html: '€'; Text: '€'),
+ (Html: ' '; Text: ' ')
+ );
+var
+ I: Integer;
+begin
+ Result := Text;
+ for I := Low(Conversions) to High(Conversions) do
+ with Conversions[I] do
+ Result := StringReplace(Result, Html, Text, [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, sLineBreak, '', [rfReplaceAll, rfIgnoreCase]); // only
can be new line
+ Result := StringReplace(Result, cBR, sLineBreak, [rfReplaceAll, rfIgnoreCase]);
+ Result := StringReplace(Result, cHR, cHR + sLineBreak, [rfReplaceAll, rfIgnoreCase]); // fixed
+end;
+
+function HTMLBeforeTag(var Str: string; DeleteToTag: Boolean = False): string;
+begin
+ if Pos(cTagBegin, Str) > 0 then
+ begin
+ Result := Copy(Str, 1, Pos(cTagBegin, Str)-1);
+ if DeleteToTag then
+ Delete(Str, 1, Pos(cTagBegin, Str)-1);
+ end
+ else
+ begin
+ Result := Str;
+ if DeleteToTag then
+ Str := '';
+ end;
+end;
+
+function GetChar(const Str: string; Pos: Word; Up: Boolean = False): Char;
+begin
+ if Length(Str) >= Pos then
+ Result := Str[Pos]
+ else
+ Result := ' ';
+ if Up then
+ Result := UpCase(Result);
+end;
+
+function HTMLDeleteTag(const Str: string): string;
+begin
+ Result := Str;
+ if (GetChar(Result, 1) = cTagBegin) and (Pos(cTagEnd, Result) > 1) then
+ Delete(Result, 1, Pos(cTagEnd, Result));
+end;
+
+procedure HTMLDrawTextEx(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; var Width: Integer;
+ CalcType: TJvHTMLCalcType; MouseX, MouseY: Integer; var MouseOnLink: Boolean;
+ var LinkName: string; Scale: Integer = 100);
+const
+ DefaultLeft = 0; // (ahuser) was 2
+var
+ vText, vM, TagPrp, Prp, TempLink: string;
+ vCount: Integer;
+ vStr: TStringList;
+ Selected: Boolean;
+ Alignment: TAlignment;
+ Trans, IsLink: Boolean;
+ CurLeft: Integer;
+ // for begin and end
+ OldFontStyles: TFontStyles;
+ OldFontColor: TColor;
+ OldBrushColor: TColor;
+ OldBrushStyle: TBrushStyle;
+ OldAlignment: TAlignment;
+ OldFont: TFont;
+ OldWidth: Integer;
+ // for font style
+ RemFontColor,
+ RemBrushColor: TColor;
+ RemFontSize: Integer;
+
+ function ExtractPropertyValue(const Tag: string; PropName: string): string;
+ var
+ I: Integer;
+ begin
+ Result := '';
+ PropName := UpperCase(PropName);
+ if Pos(PropName, UpperCase(Tag)) > 0 then
+ begin
+ Result := Copy(Tag, Pos(PropName, UpperCase(Tag)) + Length(PropName), Length(Tag));
+ if Pos('"', Result) <> 0 then
+ begin
+ Result := Copy(Result, Pos('"', Result) + 1, Length(Result));
+ Result := Copy(Result, 1, Pos('"', Result) - 1);
+ end
+ else
+ if Pos('''', Result) <> 0 then
+ begin
+ Result := Copy(Result, Pos('''', Result) + 1, Length(Result));
+ Result := Copy(Result, 1, Pos('''', Result) - 1);
+ end
+ else
+ begin
+ Result := Trim(Result);
+ Delete(Result, 1, 1);
+ Result := Trim(Result);
+ I := 1;
+ while (I < Length(Result)) and (Result[I+1] <> ' ') do
+ Inc(I);
+ Result := Copy(Result, 1, I);
+ end;
+ end;
+ end;
+
+ procedure Style(const Style: TFontStyle; const Include: Boolean);
+ begin
+ if Assigned(Canvas) then
+ if Include then
+ Canvas.Font.Style := Canvas.Font.Style + [Style]
+ else
+ Canvas.Font.Style := Canvas.Font.Style - [Style];
+ end;
+
+ function CalcPos(const Str: string): Integer;
+ begin
+ case Alignment of
+ taRightJustify:
+ Result := (Rect.Right {- Rect.Left}) - HTMLTextWidth(Canvas, Rect, State, Str, Scale);
+ taCenter:
+ Result := (Rect.Right {- Rect.Left} - HTMLTextWidth(Canvas, Rect, State, Str)) div 2;
+ else
+ Result := DefaultLeft;
+ end;
+ if Result <= 0 then
+ Result := DefaultLeft;
+ end;
+
+ procedure Draw(const M: string);
+ var
+ Width, Height: Integer;
+ R: TRect;
+ begin
+ R := Rect;
+ Inc(R.Left, CurLeft);
+ if Assigned(Canvas) then
+ begin
+ Width := Canvas.TextWidth(M);
+ Height := CanvasMaxTextHeight(Canvas);
+ if IsLink and not MouseOnLink then
+ if (MouseY >= R.Top) and (MouseY <= R.Top + Height) and
+ (MouseX >= R.Left) and (MouseX <= R.Left + Width) and
+ ((MouseY > 0) or (MouseX > 0)) then
+ begin
+ MouseOnLink := True;
+ Canvas.Font.Color := clRed; // hover link
+ LinkName := TempLink;
+ end;
+ if CalcType = htmlShow then
+ begin
+ if Trans then
+ Canvas.Brush.Style := bsClear; // for transparent
+ Canvas.TextOut(R.Left, R.Top, M);
+ end;
+ CurLeft := CurLeft + Width;
+ end;
+ end;
+
+ procedure NewLine(Always: Boolean = False);
+ begin
+ if Assigned(Canvas) then
+ if Always or (vCount < vStr.Count - 1) then
+ begin
+ Width := Max(Width, CurLeft);
+ CurLeft := DefaultLeft;
+ Rect.Top := Rect.Top + CanvasMaxTextHeight(Canvas);
+ end;
+ end;
+
+begin
+ // (p3) remove warnings
+ OldFontColor := 0;
+ OldBrushColor := 0;
+ OldBrushStyle := bsClear;
+ RemFontSize := 0;
+ RemFontColor := 0;
+ RemBrushColor := 0;
+ OldAlignment := taLeftJustify;
+ OldFont := TFont.Create;
+
+ if Canvas <> nil then
+ begin
+ OldFontStyles := Canvas.Font.Style;
+ OldFontColor := Canvas.Font.Color;
+ OldBrushColor := Canvas.Brush.Color;
+ OldBrushStyle := Canvas.Brush.Style;
+ OldAlignment := Alignment;
+ RemFontColor := Canvas.Font.Color;
+ RemBrushColor := Canvas.Brush.Color;
+ RemFontSize := Canvas.Font.size;
+ end;
+ try
+ Alignment := taLeftJustify;
+ IsLink := False;
+ MouseOnLink := False;
+ vText := Text;
+ vStr := TStringList.Create;
+ vStr.Text := HTMLPrepareText(vText);
+ LinkName := '';
+ TempLink := '';
+
+ Selected := (odSelected in State) or (odDisabled in State);
+ Trans := (Canvas.Brush.Style = bsClear) and not selected;
+
+ Width := DefaultLeft;
+ CurLeft := DefaultLeft;
+
+ vM := '';
+ for vCount := 0 to vStr.Count - 1 do
+ begin
+ vText := vStr[vCount];
+ CurLeft := CalcPos(vText);
+ while Length(vText) > 0 do
+ begin
+ vM := HTMLBeforeTag(vText, True);
+ vM := StringReplace(vM, '<', cLT, [rfReplaceAll, rfIgnoreCase]); // <--+ this must be here
+ vM := StringReplace(vM, '>', cGT, [rfReplaceAll, rfIgnoreCase]); // <--/
+ if GetChar(vText, 1) = cTagBegin then
+ begin
+ Draw(vM);
+ if Pos(cTagEnd, vText) = 0 then
+ Insert(cTagEnd, vText, 2);
+ if GetChar(vText, 2) = '/' then
+ begin
+ case GetChar(vText, 3, True) of
+ 'A':
+ begin
+ IsLink := False;
+ Canvas.Font.Assign(OldFont);
+ end;
+ 'B':
+ Style(fsBold, False);
+ 'I':
+ Style(fsItalic, False);
+ 'U':
+ Style(fsUnderline, False);
+ 'S':
+ Style(fsStrikeOut, False);
+ 'F':
+ begin
+ if not Selected then // restore old colors
+ begin
+ Canvas.Font.Color := RemFontColor;
+ Canvas.Brush.Color := RemBrushColor;
+ Canvas.Font.Size := RemFontSize;
+ Trans := True;
+ end;
+ end;
+ end
+ end
+ else
+ begin
+ case GetChar(vText, 2, True) of
+ 'A':
+ begin
+ if GetChar(vText, 3, True) = 'L' then // ALIGN
+ begin
+ TagPrp := UpperCase(Copy(vText, 2, Pos(cTagEnd, vText)-2));
+ if Pos(cCENTER, TagPrp) > 0 then
+ Alignment := taCenter
+ else
+ if Pos(cRIGHT, TagPrp) > 0 then
+ Alignment := taRightJustify
+ else
+ Alignment := taLeftJustify;
+ CurLeft := DefaultLeft;
+ if CalcType = htmlShow then
+ CurLeft := CalcPos(vText);
+ end
+ else
+ begin // A HREF
+ TagPrp := Copy(vText, 2, Pos(cTagEnd, vText)-2);
+ if Pos(cHREF, UpperCase(TagPrp)) > 0 then
+ begin
+ IsLink := True;
+ OldFont.Assign(Canvas.Font);
+ if not Selected then
+ Canvas.Font.Color := clBlue;
+ TempLink := ExtractPropertyValue(TagPrp, cHREF);
+ end;
+ end;
+ end;
+ 'B':
+ Style(fsBold, True);
+ 'I':
+ if GetChar(vText, 3, True) = 'N' then //IND="%d"
+ begin
+ TagPrp := Copy(vText, 2, Pos(cTagEnd, vText)-2);
+ CurLeft := StrToInt(ExtractPropertyValue(TagPrp, cIND)); // ex IND="10"
+ if odReserved1 in State then
+ CurLeft := Round((CurLeft * Scale) div 100);
+ end
+ else
+ Style(fsItalic, True); // ITALIC
+ 'U':
+ Style(fsUnderline, True);
+ 'S':
+ Style(fsStrikeOut, True);
+ 'H':
+ if (GetChar(vText, 3, True) = 'R') and Assigned(Canvas) then // HR
+ begin
+ if odDisabled in State then // only when disabled
+ Canvas.Pen.Color := Canvas.Font.Color;
+ OldWidth := Canvas.Pen.Width;
+ TagPrp := UpperCase(Copy(vText, 2, Pos(cTagEnd, vText)-2));
+ Canvas.Pen.Width := StrToIntDef(ExtractPropertyValue(TagPrp, 'SIZE'),1); // ex HR="10"
+ if odReserved1 in State then
+ Canvas.Pen.Width := Round((Canvas.Pen.Width * Scale) div 100);
+ if CalcType = htmlShow then
+ begin
+ Canvas.MoveTo(Rect.Left ,Rect.Top + CanvasMaxTextHeight(Canvas));
+ Canvas.LineTo(Rect.Right,Rect.Top + CanvasMaxTextHeight(Canvas));
+ end;
+ Rect.Top := Rect.Top + 1 + Canvas.Pen.Width;
+ Canvas.Pen.Width := OldWidth;
+ NewLine(HTMLDeleteTag(vText) <> '');
+ end;
+ 'F':
+ if (Pos(cTagEnd, vText) > 0) and (not Selected) and Assigned(Canvas) {and (CalcType = htmlShow)} then // F from FONT
+ begin
+ TagPrp := UpperCase(Copy(vText, 2, Pos(cTagEnd, vText)-2));
+ RemFontColor := Canvas.Font.Color;
+ RemBrushColor := Canvas.Brush.Color;
+
+ if Pos(cCOLOR, TagPrp) > 0 then
+ begin
+ Prp := ExtractPropertyValue(TagPrp, cCOLOR);
+ if Prp[1] = '#' then
+ Prp[1] := '$';
+ Canvas.Font.Color := StringToColor(Prp);
+ end;
+ if Pos(cBGCOLOR, TagPrp) > 0 then
+ begin
+ Prp := ExtractPropertyValue(TagPrp, cBGCOLOR);
+ if Prp[1] = '#' then
+ Prp[1] := '$';
+ if UpperCase(Prp) = 'CLNONE' then
+ Trans := True
+ else
+ begin
+ Canvas.Brush.Color := StringToColor(Prp);
+ Trans := False;
+ end;
+ end;
+ if Pos('SIZE', TagPrp) > 0 then
+ begin
+ Prp := ExtractPropertyValue(TagPrp, 'SIZE');
+ Canvas.Font.Size := StrToIntDef(Prp,2) * Canvas.Font.Size div 2;
+ end;
+ end;
+ end;
+ end;
+ vText := HTMLDeleteTag(vText);
+ vM := '';
+ end;
+ end;
+ Draw(vM);
+ NewLine;
+ vM := '';
+ end;
+ finally
+ if Canvas <> nil then
+ begin
+ Canvas.Font.Style := OldFontStyles;
+ Canvas.Font.Color := OldFontColor;
+ Canvas.Brush.Color := OldBrushColor;
+ Canvas.Brush.Style := OldBrushStyle;
+ Alignment := OldAlignment;
+ { Canvas.Font.Color := RemFontColor;
+ Canvas.Brush.Color:= RemBrushColor;}
+ end;
+ FreeAndNil(vStr);
+ FreeAndNil(OldFont);
+ end;
+ if CalcType = htmlCalcHeight then
+ Width := Rect.Top + CanvasMaxTextHeight(Canvas)
+ else
+ Width := Max(Width, CurLeft - DefaultLeft);
+end;
+
+function HTMLDrawText(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; Scale: Integer = 100): string;
+var
+ W: Integer;
+ S: Boolean;
+ St: string;
+begin
+ HTMLDrawTextEx(Canvas, Rect, State, Text, W, htmlShow, 0, 0, S, St, Scale);
+end;
+
+function HTMLPlainText(const Text: string): string;
+var
+ S: string;
+begin
+ Result := '';
+ S := HTMLPrepareText(Text);
+ while Pos(cTagBegin, S) > 0 do
+ begin
+ Result := Result + Copy(S, 1, Pos(cTagBegin, S)-1);
+ if Pos(cTagEnd, S) > 0 then
+ Delete(S, 1, Pos(cTagEnd, S))
+ else
+ Delete(S, 1, Pos(cTagBegin, S));
+ end;
+ Result := Result + S;
+end;
+
+function HTMLTextWidth(Canvas: TCanvas; Rect: TRect;
+ const State: TOwnerDrawState; const Text: string; Scale: Integer = 100): Integer;
+var
+ S: Boolean;
+ St: string;
+begin
+ HTMLDrawTextEx(Canvas, Rect, State, Text, Result, htmlCalcWidth, 0, 0, S, St);
+end;
+
+function HTMLTextHeight(Canvas: TCanvas; const Text: string; Scale: Integer = 100): Integer;
+var
+ S: Boolean;
+ St: string;
+ R: TRect;
+begin
+ R := Rect(0, 0, 0, 0);
+ HTMLDrawTextEx(Canvas, R, [], Text, Result, htmlCalcHeight, 0, 0, S, St, Scale);
+ if Result = 0 then
+ Result := CanvasMaxTextHeight(Canvas);
+ Inc(Result);
+end;
+
+{ TJvPicture }
+procedure TJvPicture.ReadBitmapData(Stream: TStream);
+var
+ Size: Longint;
+begin
+ Stream.Read(Size, SizeOf(Size));
+ Bitmap.LoadFromStream(Stream);
+end;
+
+type
+ TAccessReader = class(TReader)
+ end;
+
+procedure TJvPicture.DefineProperties(Filer: TFiler);
+var
+ SavedPosition: Integer;
+ Reader: TReader;
+ VType : TValueType;
+ WasBitmap : Boolean;
+ Count : Longint;
+ NameLength: Byte;
+begin
+ if Filer is TReader then
+ begin
+ // When we are reading, we must detect if the data is a valid TPicture
+ // data or just a TBitmap data. This is done by having a sneak peak at
+ // what's in the reader stream. If we find a NameLength tag that is
+ // greater than 63 (it's built-in limit, see TPicture.DefineProperties)
+ // then it must be a TBitmap and we then tell the bitmap to load itself
+ // from the Filter.
+ // Note: the test must be done here, before any call to the
+ // DefineBinaryProperty of the Reader. If not, then the FPropName field
+ // would be put back to blank and prevent the inherited DefineProperties
+ // from working correctly.
+ Reader := Filer as TReader;
+ WasBitmap := False;
+ SavedPosition := Reader.Position;
+
+ VType := Reader.ReadValue;
+ if VType = vaBinary then
+ begin
+ Reader.Read(Count, SizeOf(Count));
+ Reader.Read(NameLength, SizeOf(NameLength));
+ WasBitmap := NameLength > 63;
+ end;
+
+ Reader.Position := SavedPosition;
+
+ if WasBitmap then
+ Filer.DefineBinaryProperty('Data', ReadBitmapData, nil, True)
+ else
+ inherited DefineProperties(Filer);
+ end
+ else
+ begin
+ inherited DefineProperties(Filer);
+ end;
+end;
+
+//=== { TGraphicSignature } ==================================================
+
+// Code to manage graphic's signatures.
+type
+ TGraphicSignature = class(TObject)
+ public
+ Signature: string;
+ Offset: Integer;
+ GraphicClass: TGraphicClass;
+ constructor Create(const ASignature: string; AOffset: Integer; AGraphicClass: TGraphicClass);
+ function CheckSignature(AStream: TStream): Boolean;
+ end;
+
+constructor TGraphicSignature.Create(const ASignature: string; AOffset: Integer; AGraphicClass: TGraphicClass);
+begin
+ inherited Create;
+ Signature := ASignature;
+ Offset := AOffset;
+ GraphicClass := AGraphicClass;
+end;
+
+function TGraphicSignature.CheckSignature(AStream: TStream): Boolean;
+var
+ Buffer: string;
+ Count: Integer;
+ BytesRead: Integer;
+begin
+ Result := False;
+ try
+ Count := Length(Signature);
+ SetLength(Buffer, Count);
+ AStream.Position := Offset;
+ BytesRead := AStream.Read(Buffer[1], Count);
+ Result := (BytesRead = Count) and (Buffer = Signature);
+ except
+ // Ignore any error...
+ end;
+end;
+
+var
+ GraphicSignatures: TObjectList = nil;
+
+procedure GraphicSignaturesNeeded;
+begin
+ if not Assigned(GraphicSignatures) then
+ begin
+ GraphicSignatures := TObjectList.Create;
+
+ RegisterGraphicSignature('BM', 0, TBitmap);
+ RegisterGraphicSignature([0, 0, 1, 0], 0, TIcon);
+ RegisterGraphicSignature([$D7, $CD], 0, TMetafile); // WMF
+ RegisterGraphicSignature([1, 0], 0, TMetafile); // EMF
+ RegisterGraphicSignature('JFIF', 6, TJPEGImage);
+ RegisterGraphicSignature('Exif', 6 , TJPEGImage);
+ // NB! Registering these will add a requirement on having the JvMM package installed
+ // Let users register these manually
+ // RegisterGraphicSignature([$0A], 0, TJvPcx);
+ // RegisterGraphicSignature('ACON', 8, TJvAni);
+ // JvCursorImage cannot be registered because it doesn't support
+ // LoadFromStream/SaveToStream but here's the signature for future reference:
+ // RegisterGraphicSignature([0, 0, 2, 0], 0, TJvCursorImage);
+ {$IFDEF USE_JV_GIF}
+ // RegisterGraphicSignature('GIF', 0, TJvGIFImage);
+ {$ENDIF USE_JV_GIF}
+// RegisterGraphicSignature('GIF', 0, TGIFGraphic);
+// RegisterGraphicSignature('PNG', 1, TPNGGraphic);
+ end;
+end;
+
+procedure RegisterGraphicSignature(const ASignature: string; AOffset: Integer; AGraphicClass: TGraphicClass);
+var
+ GraphicSignature: TGraphicSignature;
+begin
+ // Avoid bad signatures
+ if (ASignature = '') or (AOffset < 0) or (AGraphicClass = nil) then
+ {$IFDEF CLR}
+ raise EJVCLException.Create(RsEBadGraphicSignature);
+ {$ELSE}
+ raise EJVCLException.CreateRes(@RsEBadGraphicSignature);
+ {$ENDIF CLR}
+ GraphicSignaturesNeeded;
+ // Should raise an exception if empty signature, negative offset or null class.
+ GraphicSignature := TGraphicSignature.Create(ASignature, AOffset, AGraphicClass);
+ try
+ GraphicSignatures.Add(GraphicSignature);
+ except
+ GraphicSignature.Free;
+ end;
+end;
+
+procedure RegisterGraphicSignature(const ASignature: array of Byte; AOffset: Integer; AGraphicClass: TGraphicClass);
+var
+ Signature: string;
+begin
+ SetLength(Signature, Length(ASignature));
+ Move(ASignature[Low(ASignature)], Signature[1], Length(ASignature));
+ RegisterGraphicSignature(Signature, AOffset, AGraphicClass);
+end;
+
+procedure UnregisterGraphicSignature(AGraphicClass: TGraphicClass); overload;
+var
+ I: Integer;
+begin
+ if Assigned(GraphicSignatures) then
+ for I := GraphicSignatures.Count - 1 downto 0 do
+ if TGraphicSignature(GraphicSignatures[I]).GraphicClass = AGraphicClass then
+ GraphicSignatures.Delete(I);
+end;
+
+procedure UnregisterGraphicSignature(const ASignature: string; AOffset: Integer);
+var
+ I: Integer;
+begin
+ if Assigned(GraphicSignatures) then
+ for I := GraphicSignatures.Count - 1 downto 0 do
+ with TGraphicSignature(GraphicSignatures[I]) do
+ if (Signature = ASignature) and (Offset = AOffset) then
+ GraphicSignatures.Delete(I);
+end;
+
+procedure UnregisterGraphicSignature(const ASignature: array of Byte; AOffset: Integer);
+var
+ Signature: string;
+begin
+ SetLength(Signature, Length(ASignature));
+ Move(ASignature[Low(ASignature)], Signature[1], Length(ASignature));
+ UnregisterGraphicSignature(Signature, AOffset);
+end;
+
+function GetGraphicClass(AStream: TStream): TGraphicClass;
+var
+ P: Integer;
+ I: Integer;
+ S: TGraphicSignature;
+begin
+ Result := nil;
+ GraphicSignaturesNeeded;
+ if Assigned(GraphicSignatures) then
+ begin
+ P := AStream.Position;
+ try
+ for I := 0 to GraphicSignatures.Count - 1 do
+ begin
+ S := TGraphicSignature(GraphicSignatures[I]);
+ if S.CheckSignature(AStream) then
+ begin
+ Result := S.GraphicClass;
+ Exit;
+ end;
+ end;
+ finally
+ AStream.Position := P;
+ end;
+ end;
+end;
+
+function GetGraphicObject(AStream: TStream): TGraphic;
+var
+ LOnProc: TJvGetGraphicClassEvent;
+begin
+ LOnProc := nil;
+ Result := GetGraphicObject(AStream, nil, LOnProc);
+end;
+
+function GetGraphicObject(AStream: TStream; ASender: TObject; AOnProc: TJvGetGraphicClassEvent): TGraphic; overload;
+var
+ GraphicClass: TGraphicClass;
+begin
+ // Figure out which Graphic class is...
+ GraphicClass := GetGraphicClass(AStream);
+ // Call user event
+ if Assigned(AOnProc) and (AStream is TMemoryStream) then
+ AOnProc(ASender, TMemoryStream(AStream), GraphicClass);
+ // If we got one, load it..
+ if Assigned(GraphicClass) then
+ begin
+ Result := GraphicClass.Create;
+ Result.LoadFromStream(AStream);
+ end
+ else // nope.
+ Result := nil;
+end;
+
+initialization
+ InitScreenCursors;
+
+finalization
+ FreeAndNil(DrawBitmap);
+ FreeAndNil(GraphicSignatures);
+******************** NOT CONVERTED *)
+
+end.
+
diff --git a/components/jvcllaz/run/JvNavigationPane.pas b/components/jvcllaz/run/JvNavigationPane.pas
new file mode 100644
index 000000000..372786eb9
--- /dev/null
+++ b/components/jvcllaz/run/JvNavigationPane.pas
@@ -0,0 +1,5192 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvNavigationPane.PAS, released on 2004-03-28.
+
+The Initial Developer of the Original Code is Peter Thornqvist
+Portions created by Peter Thornqvist are Copyright (C) 2004 Peter Thornqvist.
+All Rights Reserved.
+
+Contributor(s):
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvNavigationPane.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// TODO: LM_NCPAINT isnt fired by lazarus, see what we can do about.
+//
+// 26.09.2007:
+// BUG: (I think is of the JVCL base class) - also in Delphi
+// - Made some panels iconic.
+// - Click on popup button of the pane (TJvNavIconButton)
+// - Don't select any menu option, just click and hold for a second any of
+// the iconized pages.
+// - Page isn't selected but button remains as down.
+//
+// LM_NCPAINT isn't fired in LCL (reply on forums from Luiz Americo).
+// Also changing "BorderWidth" does nothing. This is inherited from TControl.
+// This means that TJvExControl descendatns should deflate its bound by BorderWidth
+// before painting itself and at last (after LM_PAINT) "send" LM_NCPAINT.
+// This property should afect also the positioning if the controls inside.
+
+{$mode objfpc}{$H+}
+
+unit JvNavigationPane;
+
+interface
+
+uses
+ SysUtils, Classes, Controls, ExtCtrls, Graphics, ImgList, JvButton,
+ JvComponent, JvExExtCtrls, JvPageList, JvTypes, LCLIntf, LCLType, LMessages, Menus;
+
+const
+ CM_PARENTSTYLEMANAGERCHANGE = CM_BASE + 1;
+ CM_PARENTSTYLEMANAGERCHANGED = CM_BASE + 2;
+
+type
+ TJvCustomNavigationPane = class;
+ TJvNavIconButton = class;
+ TJvNavStyleLink = class;
+ TJvNavPaneStyleManager = class;
+ TMsgStyleManagerChange = record
+ Msg: Cardinal;
+ Sender: TControl;
+ StyleManager: TJvNavPaneStyleManager;
+ Result: Longint;
+ end;
+
+ TJvNavPanelHeader = class(TJvCustomControl)
+ private
+ FColorFrom: TColor;
+ FColorTo: TColor;
+ FImages: TCustomImageList;
+ FImageIndex: TImageIndex;
+ FChangeLink: TChangeLink;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FWordWrap: Boolean;
+ FAlignment: TAlignment;
+ FParentStyleManager: Boolean;
+ procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND;
+ procedure SetColorFrom(const Value: TColor);
+ procedure SetColorTo(const Value: TColor);
+ procedure SetImageIndex(const Value: TImageIndex);
+ procedure SetImages(const Value: TCustomImageList);
+ procedure DoImagesChange(Sender: TObject);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure SetAlignment(const Value: TAlignment);
+ procedure SetWordWrap(const Value: Boolean);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure ParentStyleManagerChange(var Msg: TLMessage); message CM_PARENTSTYLEMANAGERCHANGE;
+ procedure CMControlChange(var Msg: TLMessage); message CM_CONTROLCHANGE;
+ procedure SetParentStyleManager(const Value: Boolean);
+ protected
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure TextChanged; override;
+ procedure Paint; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ property Align;
+ property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
+ property Anchors;
+ property Caption;
+ property Constraints;
+ property DragCursor;
+ property DragKind;
+ property DragMode;
+ property OnStartDock;
+ property OnEndDock;
+ property OnUnDock;
+ property Enabled;
+ property Font;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
+ property ColorFrom: TColor read FColorFrom write SetColorFrom default TColor($D0835C);
+ property ColorTo: TColor read FColorTo write SetColorTo default TColor($903B09);
+ property Images: TCustomImageList read FImages write SetImages;
+ property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property Height default 27;
+ property Width default 225;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+ TJvNavPanelDivider = class(TJvExSplitter)
+ private
+ FColorFrom: TColor;
+ FColorTo: TColor;
+ FFrameColor: TColor;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FAlignment: TAlignment;
+ FParentStyleManager: Boolean;
+ procedure SetColorFrom(const Value: TColor);
+ procedure SetColorTo(const Value: TColor);
+ procedure SetFrameColor(const Value: TColor);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure SetAlignment(const Value: TAlignment);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure SetParentStyleManager(const Value: Boolean);
+ protected
+ procedure Paint; override;
+ procedure TextChanged; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure RequestAlign; override;
+ // 25.09.2007 - SESS
+ procedure SetAlign(Value: TAlign); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ // NB! Color is published but not used
+ property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
+ property Align default alNone;
+ property Anchors;
+ property AutoSnap default False;
+ property Caption;
+ property ColorFrom: TColor read FColorFrom write SetColorFrom default TColor($FFDBBC);
+ property ColorTo: TColor read FColorTo write SetColorTo default TColor($F2C0A4);
+ property Constraints;
+ property Cursor default crSizeNS;
+ property Enabled;
+ property Font;
+ property FrameColor: TColor read FFrameColor write SetFrameColor default TColor($6F2F0C);
+ property Height default 19;
+ property ResizeStyle default rsUpdate;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property Width default 125;
+ end;
+
+ TJvOutlookSplitter = class(TJvExSplitter)
+ private
+ FColorTo: TColor;
+ FColorFrom: TColor;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FParentStyleManager: Boolean;
+ FDragZone: Integer;
+ FOldCursor: TCursor;
+ procedure SetColorFrom(const Value: TColor);
+ procedure SetColorTo(const Value: TColor);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure SetParentStyleManager(const Value: Boolean);
+ procedure SetCursor(const Value: TCursor);
+ function GetDragZoneRect: TRect;
+ function MouseInDragZone(X, Y: Integer): Boolean;
+ protected
+ procedure Paint; override;
+ procedure EnabledChanged; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure WMLButtonDown(var Msg: TLMLButtonDown); message LM_LBUTTONDOWN;
+ procedure WMMouseMove(var Msg: TLMMouseMove); message LM_MOUSEMOVE;
+ procedure RequestAlign; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ // NB! Color is published but not used
+ property Align default alBottom;
+ property AutoSnap default False;
+ property Cursor write SetCursor default crSizeNS;
+ // DragZone is the number of pixels in the center of the control that constitutes the draggable area.
+ // For example, with a left/right aligned splitter and a DragZone of 100, 50 pixels above and 50 pixels below
+ // the vertical midpoint can be clicked to start the sizing. Any clicks outside this area will not start a sizing operation
+ // If DragZone <= 0, the entire control is a drag zone
+ property DragZone: Integer read FDragZone write FDragZone default 0;
+ property ResizeStyle default rsUpdate;
+ property ColorFrom: TColor read FColorFrom write SetColorFrom default TColor($B78676);
+ property ColorTo: TColor read FColorTo write SetColorTo default TColor($A03D09);
+ property Height default 7;
+ property Enabled;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property OnClick;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnDblClick;
+ property OnMouseUp;
+ property OnMouseMove;
+ end;
+
+ TJvNavPanelColors = class(TPersistent)
+ private
+ FButtonColorTo: TColor;
+ FButtonColorFrom: TColor;
+ FFrameColor: TColor;
+ FButtonHotColorFrom: TColor;
+ FButtonHotColorTo: TColor;
+ FButtonSelectedColorFrom: TColor;
+ FButtonSelectedColorTo: TColor;
+ FOnChange: TNotifyEvent;
+ FSplitterColorFrom: TColor;
+ FSplitterColorTo: TColor;
+ FDividerColorTo: TColor;
+ FDividerColorFrom: TColor;
+ FHeaderColorFrom: TColor;
+ FHeaderColorTo: TColor;
+ FButtonSeparatorColor: TColor;
+ FToolPanelColorFrom: TColor;
+ FToolPanelColorTo: TColor;
+ FToolPanelHeaderColorTo: TColor;
+ FToolPanelHeaderColorFrom: TColor;
+ procedure SetButtonColorFrom(const Value: TColor);
+ procedure SetButtonColorTo(const Value: TColor);
+ procedure SetFrameColor(const Value: TColor);
+ procedure SetButtonHotColorFrom(const Value: TColor);
+ procedure SetButtonHotColorTo(const Value: TColor);
+ procedure SetButtonSelectedColorFrom(const Value: TColor);
+ procedure SetButtonSelectedColorTo(const Value: TColor);
+ procedure SetSplitterColorFrom(const Value: TColor);
+ procedure SetSplitterColorTo(const Value: TColor);
+ procedure SetDividerColorFrom(const Value: TColor);
+ procedure SetDividerColorTo(const Value: TColor);
+ procedure SetHeaderColorFrom(const Value: TColor);
+ procedure SetHeaderColorTo(const Value: TColor);
+ procedure SetButtonSeparatorColor(const Value: TColor);
+ procedure SetToolPanelColorFrom(const Value: TColor);
+ procedure SetToolPanelColorTo(const Value: TColor);
+ procedure SetToolPanelHeaderColorFrom(const Value: TColor);
+ procedure SetToolPanelHeaderColorTo(const Value: TColor);
+ protected
+ procedure Change;
+ public
+ constructor Create;
+ procedure Assign(Source: TPersistent); override;
+ published
+ property ButtonColorFrom: TColor read FButtonColorFrom write SetButtonColorFrom default TColor($F7E2CD);
+ property ButtonColorTo: TColor read FButtonColorTo write SetButtonColorTo default TColor($F3A080);
+ property ButtonHotColorFrom: TColor read FButtonHotColorFrom write SetButtonHotColorFrom default TColor($DBFBFF);
+ property ButtonHotColorTo: TColor read FButtonHotColorTo write SetButtonHotColorTo default TColor($5FC8FB);
+ property ButtonSelectedColorFrom: TColor read FButtonSelectedColorFrom write SetButtonSelectedColorFrom default TColor($BBE2EA);
+ property ButtonSelectedColorTo: TColor read FButtonSelectedColorTo write SetButtonSelectedColorTo default TColor($389FDD);
+ property ButtonSeparatorColor: TColor read FButtonSeparatorColor write SetButtonSeparatorColor default clGray;
+ property SplitterColorFrom: TColor read FSplitterColorFrom write SetSplitterColorFrom default TColor($B78676);
+ property SplitterColorTo: TColor read FSplitterColorTo write SetSplitterColorTo default TColor($A03D09);
+ property DividerColorFrom: TColor read FDividerColorFrom write SetDividerColorFrom default TColor($FFDBBC);
+ property DividerColorTo: TColor read FDividerColorTo write SetDividerColorTo default TColor($F2C0A4);
+ property HeaderColorFrom: TColor read FHeaderColorFrom write SetHeaderColorFrom default TColor($D0835C);
+ property HeaderColorTo: TColor read FHeaderColorTo write SetHeaderColorTo default TColor($903B09);
+ property FrameColor: TColor read FFrameColor write SetFrameColor default TColor($6F2F0C);
+ property ToolPanelColorFrom: TColor read FToolPanelColorFrom write SetToolPanelColorFrom default clWindow;
+ property ToolPanelColorTo: TColor read FToolPanelColorTo write SetToolPanelColorTo default clWindow;
+ property ToolPanelHeaderColorFrom: TColor read FToolPanelHeaderColorFrom write SetToolPanelHeaderColorFrom default TColor($F7E2CD);
+ property ToolPanelHeaderColorTo: TColor read FToolPanelHeaderColorTo write SetToolPanelHeaderColorTo default TColor($F3A080);
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+
+ TJvNavPanelFonts = class(TPersistent)
+ private
+ FHeaderFont: TFont;
+ FNavPanelFont: TFont;
+ FDividerFont: TFont;
+ FOnChange: TNotifyEvent;
+ FNavPanelHotTrackFont: TFont;
+ FNavPanelHotTrackFontOptions: TJvTrackFontOptions;
+ procedure SetDividerFont(const Value: TFont);
+ procedure SetHeaderFont(const Value: TFont);
+ procedure SetNavPanelFont(const Value: TFont);
+ procedure SetNavPanelHotTrackFont(const Value: TFont);
+ procedure SetNavPanelHotTrackFontOptions(const Value: TJvTrackFontOptions);
+ protected
+ procedure Change;
+ procedure DoFontChange(Sender: TObject);
+ public
+ procedure Assign(Source: TPersistent); override;
+ constructor Create;
+ destructor Destroy; override;
+ published
+ property NavPanelFont: TFont read FNavPanelFont write SetNavPanelFont;
+ property NavPanelHotTrackFont: TFont read FNavPanelHotTrackFont write SetNavPanelHotTrackFont;
+ property NavPanelHotTrackFontOptions: TJvTrackFontOptions read FNavPanelHotTrackFontOptions write SetNavPanelHotTrackFontOptions default DefaultTrackFontOptions;
+ property DividerFont: TFont read FDividerFont write SetDividerFont;
+ property HeaderFont: TFont read FHeaderFont write SetHeaderFont;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+
+ TJvIconPanel = class(TJvCustomControl)
+ private
+ FDropButton: TJvNavIconButton;
+ FColors: TJvNavPanelColors;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FOnDropDownMenu: TContextPopupEvent;
+ FParentStyleManager: Boolean;
+ procedure SetDropDownMenu(const Value: TPopupMenu);
+ function GetDropDownMenu: TPopupMenu;
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure ParentStyleManagerChange(var Msg: TLMessage); message CM_PARENTSTYLEMANAGERCHANGE;
+ procedure CMControlChange(var Msg: TLMessage); message CM_CONTROLCHANGE;
+ procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND;
+ procedure SetParentStyleManager(const Value: Boolean);
+ protected
+ procedure DoDropDownMenu(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
+ procedure DoColorsChange(Sender: TObject);
+ procedure Paint; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ property Colors: TJvNavPanelColors read FColors write SetColors;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property DropDownMenu: TPopupMenu read GetDropDownMenu write SetDropDownMenu;
+ property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
+ end;
+
+ TJvNavIconButtonType = (nibDropDown, nibImage, nibDropArrow, nibClose);
+
+ TJvNavIconButton = class(TJvCustomGraphicButton)
+ private
+ FChangeLink: TChangeLink;
+ FImages: TCustomImageList;
+ FImageIndex: TImageIndex;
+ FButtonType: TJvNavIconButtonType;
+ FColors: TJvNavPanelColors;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FParentStyleManager: Boolean;
+ procedure SetImages(const Value: TCustomImageList);
+ procedure SetImageIndex(const Value: TImageIndex);
+ procedure DoImagesChange(Sender: TObject);
+ procedure SetButtonType(const Value: TJvNavIconButtonType);
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure DoColorsChange(Sender: TObject);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure SetParentStyleManager(const Value: Boolean);
+ function IsColorsStored: Boolean;
+ protected
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure Paint; override;
+ property OnDropDownMenu;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ property Action;
+ property Align;
+ property AllowAllUp;
+ property Anchors;
+ // property Caption;
+ property Constraints;
+ property Down;
+ property DragCursor;
+ property DragKind;
+ property OnEndDock;
+ property OnStartDock;
+ property DragMode;
+ property DropDownMenu;
+ property GroupIndex;
+ property Enabled;
+ property Font;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ property ButtonType: TJvNavIconButtonType read FButtonType write SetButtonType;
+ property Colors: TJvNavPanelColors read FColors write SetColors stored IsColorsStored;
+ property Images: TCustomImageList read FImages write SetImages;
+ property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property Width default 22;
+ property Height default 22;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+ TJvNavPanelToolButton = class(TJvCustomGraphicButton)
+ private
+ FChangeLink: TChangeLink;
+ FImages: TCustomImageList;
+ FImageIndex: TImageIndex;
+ FButtonType: TJvNavIconButtonType;
+ FDrawPartialMenuFrame: Boolean;
+ FTransparentDown: Boolean;
+ procedure DoImagesChange(Sender: TObject);
+ procedure SetButtonType(const Value: TJvNavIconButtonType);
+ procedure SetImageIndex(const Value: TImageIndex);
+ procedure SetImages(const Value: TCustomImageList);
+ protected
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure Paint; override;
+ procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ property TransparentDown: Boolean read FTransparentDown write FTransparentDown default False;
+ property DrawPartialMenuFrame: Boolean read FDrawPartialMenuFrame write FDrawPartialMenuFrame default False;
+ property Images: TCustomImageList read FImages write SetImages;
+ property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
+ property ButtonType: TJvNavIconButtonType read FButtonType write SetButtonType;
+ property Caption;
+ end;
+
+ TJvNavPanelButton = class(TJvCustomGraphicButton)
+ private
+ FImageIndex: TImageIndex;
+ FImages: TCustomImageList;
+ FColors: TJvNavPanelColors;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FAlignment: TAlignment;
+ FWordWrap: Boolean;
+ FParentStyleManager: Boolean;
+ procedure SetImageIndex(const Value: TImageIndex);
+ procedure SetImages(const Value: TCustomImageList);
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure DoColorsChange(Sender: TObject);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure SetAlignment(const Value: TAlignment);
+ procedure SetWordWrap(const Value: Boolean);
+ procedure CMDialogChar(var Msg: TCMDialogChar); message CM_DIALOGCHAR;
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure SetParentStyleManager(const Value: Boolean);
+ function IsColorsStored: Boolean;
+ protected
+ procedure TextChanged; override;
+ procedure FontChanged; override;
+ procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
+ property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
+ procedure PaintButton(ACanvas: TCanvas); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ property Action;
+ property Align;
+ property AllowAllUp;
+ property Anchors;
+ property Caption;
+ property Constraints;
+ property Down;
+ property DropDownMenu;
+ property DragCursor;
+ property DragKind;
+ property OnEndDock;
+ property OnStartDock;
+ property DragMode;
+ property Enabled;
+ property Font;
+ property GroupIndex;
+ property HotTrack default True;
+ property HotTrackFont;
+ property HotTrackFontOptions;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ property Width default 125;
+ property Height default 28;
+ property Colors: TJvNavPanelColors read FColors write SetColors stored IsColorsStored;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
+ property Images: TCustomImageList read FImages write SetImages;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+ TJvNavPaneBackgroundImage = class(TPersistent)
+ private
+ FCenter: Boolean;
+ FTile: Boolean;
+ FTransparent: Boolean;
+ FProportional: Boolean;
+ FStretch: Boolean;
+ FDrawing: Boolean;
+ FPicture: TPicture;
+ FOnChange: TNotifyEvent;
+ procedure SetCenter(const Value: Boolean);
+ procedure SetPicture(const Value: TPicture);
+ procedure SetProportional(const Value: Boolean);
+ procedure SetStretch(const Value: Boolean);
+ procedure SetTile(const Value: Boolean);
+ procedure SetTransparent(const Value: Boolean);
+ procedure PictureChanged(Sender: TObject);
+ protected
+ procedure DrawImage(Canvas: TCanvas; ARect: TRect); virtual;
+ procedure Change; virtual;
+ function CalcRect(ADestRect: TRect): TRect;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ function HasImage: Boolean;
+ published
+ property Picture: TPicture read FPicture write SetPicture;
+ property Stretch: Boolean read FStretch write SetStretch;
+ property Proportional: Boolean read FProportional write SetProportional;
+ property Center: Boolean read FCenter write SetCenter;
+ property Tile: Boolean read FTile write SetTile;
+ property Transparent: Boolean read FTransparent write SetTransparent;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+
+ TJvNavPanelPage = class(TJvCustomPage)
+ private
+ FNavPanel: TJvNavPanelButton;
+ FIconButton: TJvNavIconButton;
+ FOnClick: TNotifyEvent;
+ FIconPanel: TJvIconPanel;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FHeader: TJvNavPanelHeader;
+ FImageIndex: TImageIndex;
+ FParentStyleManager: Boolean;
+ FBackground: TJvNavPaneBackgroundImage;
+ procedure SetCaption(const Value: TCaption);
+ procedure SetIconic(const Value: Boolean);
+ procedure SetImageIndex(const Value: TImageIndex);
+ function GetCaption: TCaption;
+ function GetIconic: Boolean;
+ function GetImageIndex: TImageIndex;
+ procedure DoButtonClick(Sender: TObject);
+ function GetHint: string;
+ procedure SetHint(const Value: string);
+ procedure SetIconPanel(const Value: TJvIconPanel);
+ function GetColors: TJvNavPanelColors;
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure SetAutoHeader(const Value: Boolean);
+ function GetAutoHeader: Boolean;
+ function GetAlignment: TAlignment;
+ function GetWordWrap: Boolean;
+ procedure SetAlignment(const Value: TAlignment);
+ procedure SetWordWrap(const Value: Boolean);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure ParentStyleManagerChange(var Msg: TLMessage); message CM_PARENTSTYLEMANAGERCHANGE;
+ procedure CMControlChange(var Msg: TLMessage); message CM_CONTROLCHANGE;
+ procedure SetParentStyleManager(const Value: Boolean);
+ procedure SetAction(const Value: TBasicAction); // override;
+ procedure SetBackground(const Value: TJvNavPaneBackgroundImage);
+ procedure DoBackgroundChange(Sender: TObject);
+ protected
+ procedure UpdatePageList;
+ function GetAction: TBasicAction; override;
+ procedure SetParent(AParent: TWinControl); override;
+ procedure SetPageIndex(Value: Integer); override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ property NavPanel: TJvNavPanelButton read FNavPanel;
+ property IconButton: TJvNavIconButton read FIconButton;
+ property IconPanel: TJvIconPanel read FIconPanel write SetIconPanel;
+ property Colors: TJvNavPanelColors read GetColors write SetColors;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property Header: TJvNavPanelHeader read FHeader;
+ property Alignment: TAlignment read GetAlignment write SetAlignment;
+ property WordWrap: Boolean read GetWordWrap write SetWordWrap;
+ procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
+ procedure Paint; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ property AutoHeader: Boolean read GetAutoHeader write SetAutoHeader;
+ published
+ property Action: TBasicAction read GetAction write SetAction;
+ property Background: TJvNavPaneBackgroundImage read FBackground write SetBackground;
+ property Color default clWindow;
+ property ParentColor default False;
+ property Caption: TCaption read GetCaption write SetCaption;
+ property DragCursor;
+ property DragKind;
+ property OnStartDock;
+ property OnDockDrop;
+ property OnDockOver;
+ property OnUnDock;
+ property OnEndDock;
+ property DragMode;
+ property Iconic: Boolean read GetIconic write SetIconic default False;
+ property ImageIndex: TImageIndex read GetImageIndex write SetImageIndex default -1;
+ property Hint: string read GetHint write SetHint;
+ property OnClick: TNotifyEvent read FOnClick write FOnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnKeyDown;
+ property OnKeyPress;
+ property OnKeyUp;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnMouseWheel;
+ property OnMouseWheelDown;
+ property OnMouseWheelUp;
+ property OnResize;
+ property OnShow;
+ property OnStartDrag;
+ end;
+
+ TJvCustomNavPaneToolPanel = class;
+
+ TJvNavPaneToolButton = class(TCollectionItem)
+ private
+ FRealButton: TJvNavPanelToolButton;
+ procedure SetImageIndex(const Value: TImageIndex);
+ procedure SetEnabled(const Value: Boolean);
+ procedure SetAction(const Value: TBasicAction);
+ procedure SetHint(const Value: string);
+ function GetAction: TBasicAction;
+ function GetEnabled: Boolean;
+ function GetHint: string;
+ function GetImageIndex: TImageIndex;
+ public
+ procedure Assign(Source: TPersistent); override;
+ constructor Create(ACollection: Classes.TCollection); override;
+ destructor Destroy; override;
+ property Button: TJvNavPanelToolButton read FRealButton;
+ published
+ property Action: TBasicAction read GetAction write SetAction;
+ property Hint: string read GetHint write SetHint;
+ property ImageIndex: TImageIndex read GetImageIndex write SetImageIndex default -1;
+ property Enabled: Boolean read GetEnabled write SetEnabled default True;
+ end;
+
+ TJvNavPaneToolButtons = class(TOwnedCollection)
+ private
+ FPanel: TJvCustomNavPaneToolPanel;
+ function GetItem(Index: Integer): TJvNavPaneToolButton;
+ procedure SetItem(Index: Integer; const Value: TJvNavPaneToolButton);
+ protected
+ procedure Update(Item: TCollectionItem); override;
+ public
+ constructor Create(AOwner: TJvCustomNavPaneToolPanel);
+ function Add: TJvNavPaneToolButton;
+ property Items[Index: Integer]: TJvNavPaneToolButton read GetItem write SetItem; default;
+ end;
+
+ TJvNavPaneToolButtonClick = procedure(Sender: TObject; Index: Integer) of object;
+ TJvToolPanelHitTestInfo = (phtNowhere, phtAbove, phtBelow, phtToLeft, phtToRight, phtGrabber, phtHeader, phtClient);
+ TJvToolPanelHitTestInfos = set of TJvToolPanelHitTestInfo;
+
+ //SESS
+ TWMNCPaint = TLMessage;
+
+ TJvCustomNavPaneToolPanel = class(TJvCustomControl)
+ private
+ FStyleLink: TJvNavStyleLink;
+ FChangeLink: TChangeLink;
+ FStyleManager: TJvNavPaneStyleManager;
+ FButtonWidth: Integer;
+ FHeaderHeight: Integer;
+ FEdgeRounding: Integer;
+ FButtonHeight: Integer;
+ FImages: TCustomImageList;
+ FButtons: TJvNavPaneToolButtons;
+ FOnButtonClick: TJvNavPaneToolButtonClick;
+ FDropDown: TJvNavPanelToolButton;
+ FCloseButton: TJvNavPanelToolButton;
+ FOnClose: TNotifyEvent;
+ FShowGrabber: Boolean;
+ FOnDropDownMenu: TContextPopupEvent;
+ FParentStyleManager: Boolean;
+ FBackground: TJvNavPaneBackgroundImage;
+ FColors: TJvNavPanelColors;
+ FHeaderVisible: Boolean;
+ procedure DoStyleChange(Sender: TObject);
+ procedure DoImagesChange(Sender: TObject);
+ procedure ButtonsChanged;
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure SetButtonHeight(const Value: Integer);
+ procedure SetButtonWidth(const Value: Integer);
+ procedure SetEdgeRounding(const Value: Integer);
+ procedure SetHeaderHeight(const Value: Integer);
+ procedure SetImages(const Value: TCustomImageList);
+ procedure SetButtons(const Value: TJvNavPaneToolButtons);
+ procedure InternalButtonClick(Sender: TObject);
+ function GetCloseButton: Boolean;
+ function GetDropDownMenu: TPopupMenu;
+ procedure SetCloseButton(const Value: Boolean);
+ procedure SetDropDownMenu(const Value: TPopupMenu);
+ procedure DoCloseClick(Sender: TObject);
+ procedure SetShowGrabber(const Value: Boolean);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure ParentStyleManagerChange(var Msg: TLMessage); message CM_PARENTSTYLEMANAGERCHANGE;
+ procedure SetParentStyleManager(const Value: Boolean);
+ function GetDrawPartialMenuFrame: Boolean;
+ procedure SetDrawPartialMenuFrame(const Value: Boolean);
+ procedure SetBackground(const Value: TJvNavPaneBackgroundImage);
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure SetHeaderVisible(const Value: Boolean);
+ function IsColorsStored: Boolean;
+ procedure CMControlChange(var Msg: TLMessage); message CM_CONTROLCHANGE;
+ procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND;
+ procedure WMNCPaint(var Msg: TWMNCPaint); message LM_NCPAINT;
+ procedure AlignButtons;
+ protected
+ procedure Paint; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure TextChanged; override;
+ procedure FontChanged; override;
+ procedure DoDropDownMenu(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
+ property EdgeRounding: Integer read FEdgeRounding write SetEdgeRounding default 9;
+ procedure AdjustClientRect(var Rect: TRect); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function GetHitTestInfoAt(X, Y: Integer): TJvToolPanelHitTestInfos;
+ procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
+ protected
+ property Background: TJvNavPaneBackgroundImage read FBackground write SetBackground;
+ property DrawPartialMenuFrame: Boolean read GetDrawPartialMenuFrame write SetDrawPartialMenuFrame default False;
+ property Buttons: TJvNavPaneToolButtons read FButtons write SetButtons;
+ property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 25;
+ property ButtonHeight: Integer read FButtonHeight write SetButtonHeight default 22;
+ property CloseButton: Boolean read GetCloseButton write SetCloseButton default True;
+ property Colors: TJvNavPanelColors read FColors write SetColors stored IsColorsStored;
+ property DropDownMenu: TPopupMenu read GetDropDownMenu write SetDropDownMenu;
+ property HeaderHeight: Integer read FHeaderHeight write SetHeaderHeight default 29;
+ property HeaderVisible: Boolean read FHeaderVisible write SetHeaderVisible default True;
+ property Images: TCustomImageList read FImages write SetImages;
+// property ParentColor default False;
+ property ShowGrabber: Boolean read FShowGrabber write SetShowGrabber default True;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property OnButtonClick: TJvNavPaneToolButtonClick read FOnButtonClick write FOnButtonClick;
+ property OnClose: TNotifyEvent read FOnClose write FOnClose;
+ property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
+ end;
+
+ TJvNavPaneToolPanel = class(TJvCustomNavPaneToolPanel)
+ published
+ property Align;
+ property Anchors;
+ property Caption;
+ property Constraints;
+ property BorderWidth;
+ property DragCursor;
+ property DragKind;
+ property DragMode;
+ property Background;
+ property DrawPartialMenuFrame;
+ property Buttons;
+ property ButtonWidth;
+ property ButtonHeight;
+ property CloseButton;
+ property Colors;
+ property DropDownMenu;
+ property HeaderHeight;
+ property HeaderVisible;
+ property Images;
+ property ShowGrabber;
+ property StyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager;
+ property OnButtonClick;
+ property OnClose;
+ property OnDropDownMenu;
+ property Enabled;
+ property Font;
+ property ParentColor;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ property Width default 185;
+ property Height default 41;
+ property OnEndDock;
+ property OnStartDock;
+ property OnUnDock;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+ TJvCustomNavigationPane = class(TJvCustomPageList)
+ private
+ FIconPanel: TJvIconPanel;
+ FSplitter: TJvOutlookSplitter;
+ FLargeImages: TCustomImageList;
+ FSmallImages: TCustomImageList;
+ FColors: TJvNavPanelColors;
+ FNavPanelFont: TFont;
+ FResizable: Boolean;
+ FButtonWidth: Integer;
+ FButtonHeight: Integer;
+ FStyleManager: TJvNavPaneStyleManager;
+ FStyleLink: TJvNavStyleLink;
+ FNavPanelHotTrackFont: TFont;
+ FNavPanelHotTrackFontOptions: TJvTrackFontOptions;
+ FAutoHeaders: Boolean;
+ FWordWrap: Boolean;
+ FAlignment: TAlignment;
+ FOnDropDownMenu: TContextPopupEvent;
+ FParentStyleManager: Boolean;
+ FBackground: TJvNavPaneBackgroundImage;
+ function GetDropDownMenu: TPopupMenu;
+ function GetSmallImages: TCustomImageList;
+ procedure SetDropDownMenu(const Value: TPopupMenu);
+ procedure SetLargeImages(const Value: TCustomImageList);
+ procedure SetSmallImages(const Value: TCustomImageList);
+ function GetMaximizedCount: Integer;
+ procedure SetMaximizedCount(Value: Integer);
+ procedure HidePanel(Index: Integer);
+ procedure ShowPanel(Index: Integer);
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure SetResizable(const Value: Boolean);
+ function GetNavPage(Index: Integer): TJvNavPanelPage;
+ procedure DoSplitterCanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean);
+ procedure DoColorsChange(Sender: TObject);
+ procedure SetNavPanelFont(const Value: TFont);
+ procedure SetNavPanelHotTrackFont(const Value: TFont);
+ procedure SetNavPanelHotTrackFontOptions(const Value: TJvTrackFontOptions);
+ procedure DoNavPanelFontChange(Sender: TObject);
+ procedure SetButtonHeight(const Value: Integer);
+ procedure SetButtonWidth(const Value: Integer);
+ procedure SetSplitterHeight(const Value: Integer);
+ function GetSplitterHeight: Integer;
+ procedure SetStyleManager(const Value: TJvNavPaneStyleManager);
+ procedure DoStyleChange(Sender: TObject);
+ procedure SetAutoHeaders(const Value: Boolean);
+ procedure SetAlignment(const Value: TAlignment);
+ procedure SetWordWrap(const Value: Boolean);
+ procedure ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange); message CM_PARENTSTYLEMANAGERCHANGED;
+ procedure ParentStyleManagerChange(var Msg: TLMessage); message CM_PARENTSTYLEMANAGERCHANGE;
+ procedure CMControlChange(var Msg: TLMessage); message CM_CONTROLCHANGE;
+ procedure WMNCPaint(var Msg: TWMNCPaint); message LM_NCPAINT;
+ procedure WMEraseBkgnd(var Msg: TLMEraseBkgnd); message LM_ERASEBKGND;
+ procedure SetParentStyleManager(const Value: Boolean);
+ procedure SetBackground(const Value: TJvNavPaneBackgroundImage);
+ function GetSplitterClick: TNotifyEvent;
+ function GetSplitterDblClick: TNotifyEvent;
+ function GetSplitterMouseDown: TMouseEvent;
+ function GetSplitterMouseEnter: TNotifyEvent;
+ function GetSplitterMouseLeave: TNotifyEvent;
+ function GetSplitterMouseMove: TMouseMoveEvent;
+ function GetSplitterMouseUp: TMouseEvent;
+ procedure SetSplitterClick(const Value: TNotifyEvent);
+ procedure SetSplitterDblClick(const Value: TNotifyEvent);
+ procedure SetSplitterMouseDown(const Value: TMouseEvent);
+ procedure SetSplitterMouseEnter(const Value: TNotifyEvent);
+ procedure SetSplitterMouseLeave(const Value: TNotifyEvent);
+ procedure SetSplitterMouseMove(const Value: TMouseMoveEvent);
+ procedure SetSplitterMouseUp(const Value: TMouseEvent);
+ function GetSplitterCanResize: TCanResizeEvent;
+ function GetSplitterMoved: TNotifyEvent;
+ function GetSplitterPaint: TNotifyEvent;
+ procedure SetSplitterCanResize(const Value: TCanResizeEvent);
+ procedure SetSplitterMoved(const Value: TNotifyEvent);
+ procedure SetSplitterPaint(const Value: TNotifyEvent);
+ protected
+ function IsColorsStored: Boolean;
+ function IsNavPanelFontStored: Boolean;
+ function IsNavPanelFontHotTrackStored: Boolean;
+ function IsNavPanelHotTrackFontOptionsStored: Boolean;
+ procedure UpdatePages; virtual;
+ procedure SetActivePage(Page: TJvCustomPage); override;
+ procedure InsertPage(APage: TJvCustomPage); override;
+ procedure RemovePage(APage: TJvCustomPage); override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure Loaded; override;
+ procedure DoDropDownMenu(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
+ function InternalGetPageClass: TJvCustomPageClass; override;
+ property NavPages[Index: Integer]: TJvNavPanelPage read GetNavPage;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function HidePage(Page: TJvCustomPage): TJvCustomPage; override;
+ function ShowPage(Page: TJvCustomPage; PageIndex: Integer = -1): TJvCustomPage; override;
+ procedure UpdatePositions;
+ protected
+ property BorderWidth default 1;
+ property AutoHeaders: Boolean read FAutoHeaders write SetAutoHeaders default False;
+ property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
+ property Background: TJvNavPaneBackgroundImage read FBackground write SetBackground;
+ property ButtonHeight: Integer read FButtonHeight write SetButtonHeight default 28;
+ property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 22;
+ property NavPanelFont: TFont read FNavPanelFont write SetNavPanelFont;
+ property NavPanelHotTrackFont: TFont read FNavPanelHotTrackFont write SetNavPanelHotTrackFont;
+ property NavPanelHotTrackFontOptions: TJvTrackFontOptions read FNavPanelHotTrackFontOptions write SetNavPanelHotTrackFontOptions;
+ property Color default clWindow;
+ property Colors: TJvNavPanelColors read FColors write SetColors;
+ property StyleManager: TJvNavPaneStyleManager read FStyleManager write SetStyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager: Boolean read FParentStyleManager write SetParentStyleManager default True;
+ property DropDownMenu: TPopupMenu read GetDropDownMenu write SetDropDownMenu;
+ property LargeImages: TCustomImageList read FLargeImages write SetLargeImages;
+ property MaximizedCount: Integer read GetMaximizedCount write SetMaximizedCount;
+ property ParentColor default False;
+ property Resizable: Boolean read FResizable write SetResizable default True;
+ property SmallImages: TCustomImageList read GetSmallImages write SetSmallImages;
+ property SplitterHeight: Integer read GetSplitterHeight write SetSplitterHeight default 7;
+ property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
+ property Splitter: TJvOutlookSplitter read FSplitter;
+ property IconPanel: TJvIconPanel read FIconPanel;
+ property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
+ property OnSplitterCanResize: TCanResizeEvent read GetSplitterCanResize write SetSplitterCanResize;
+ property OnSplitterMoved: TNotifyEvent read GetSplitterMoved write SetSplitterMoved;
+ property OnSplitterPaint: TNotifyEvent read GetSplitterPaint write SetSplitterPaint;
+ property OnSplitterClick: TNotifyEvent read GetSplitterClick write SetSplitterClick;
+ property OnSplitterMouseEnter: TNotifyEvent read GetSplitterMouseEnter write SetSplitterMouseEnter;
+ property OnSplitterMouseLeave: TNotifyEvent read GetSplitterMouseLeave write SetSplitterMouseLeave;
+ property OnSplitterDblClick: TNotifyEvent read GetSplitterDblClick write SetSplitterDblClick;
+ property OnSplitterMouseDown: TMouseEvent read GetSplitterMouseDown write SetSplitterMouseDown;
+ property OnSplitterMouseMove: TMouseMoveEvent read GetSplitterMouseMove write SetSplitterMouseMove;
+ property OnSplitterMouseUp: TMouseEvent read GetSplitterMouseUp write SetSplitterMouseUp;
+ end;
+
+ TJvNavigationPane = class(TJvCustomNavigationPane)
+ public
+ property NavPages;
+ property Splitter;
+ property IconPanel;
+ published
+ property ActivePage;
+ // property Alignment;
+ property Align;
+ property Anchors;
+ property AutoHeaders;
+ property BorderWidth;
+ property DragCursor;
+ property DragKind;
+ property OnStartDock;
+ property OnDockDrop;
+ property OnDockOver;
+ property OnUnDock;
+ property OnEndDock;
+ property Background;
+ property ButtonHeight;
+ property ButtonWidth;
+ property Caption;
+ property Color;
+ property Colors stored IsColorsStored;
+ property StyleManager;
+ // (p3) must be published after StyleManager
+ property ParentStyleManager;
+ property Constraints;
+ property DragMode;
+ property DropDownMenu;
+ property Enabled;
+ property Font;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property SplitterHeight;
+ property Visible;
+ property LargeImages;
+ property MaximizedCount;
+ property NavPanelFont stored IsNavPanelFontStored;
+ property NavPanelHotTrackFont stored IsNavPanelFontHotTrackStored;
+ property NavPanelHotTrackFontOptions stored IsNavPanelHotTrackFontOptionsStored;
+ property Resizable;
+ property SmallImages;
+ // property WordWrap;
+ property OnChange;
+ property OnChanging;
+ property OnDropDownMenu;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnStartDrag;
+ property OnEnter;
+ property OnExit;
+ property OnKeyDown;
+ property OnKeyPress;
+ property OnKeyUp;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnMouseWheel;
+ property OnMouseWheelDown;
+ property OnMouseWheelUp;
+ property OnResize;
+ property OnSplitterCanResize;
+ property OnSplitterMoved;
+ property OnSplitterPaint;
+ property OnSplitterClick;
+ property OnSplitterMouseEnter;
+ property OnSplitterMouseLeave;
+ property OnSplitterDblClick;
+ property OnSplitterMouseDown;
+ property OnSplitterMouseMove;
+ property OnSplitterMouseUp;
+ end;
+
+ TJvNavStyleLink = class(TObject)
+ private
+ FSender: TObject;
+ FOnChange: TNotifyEvent;
+ public
+ destructor Destroy; override;
+ procedure Change; dynamic;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property Sender: TObject read FSender write FSender;
+ end;
+
+ TJvNavPanelTheme = (nptStandard, nptXPBlue, nptXPSilver, nptXPOlive, nptCustom);
+
+ // TJvNavPaneStyleManager = class(TJvComponent)
+ TJvNavPaneStyleManager = class(TComponent)
+ private
+ FColors: TJvNavPanelColors;
+ FTheme: TJvNavPanelTheme;
+ FClients: TList;
+ FFonts: TJvNavPanelFonts;
+ FOnThemeChange: TNotifyEvent;
+ procedure SetColors(const Value: TJvNavPanelColors);
+ procedure SetTheme(const Value: TJvNavPanelTheme);
+ procedure DoThemeChange(Sender: TObject);
+ procedure SetFonts(const Value: TJvNavPanelFonts);
+ function IsColorsStored: Boolean;
+ function IsFontsStored: Boolean;
+ protected
+ procedure Change; virtual;
+ procedure AssignTo(Dest: TPersistent); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure Assign(Source: TPersistent); override;
+ procedure RegisterChanges(Value: TJvNavStyleLink);
+ procedure UnregisterChanges(Value: TJvNavStyleLink);
+ published
+ property Colors: TJvNavPanelColors read FColors write SetColors stored IsColorsStored;
+ property Fonts: TJvNavPanelFonts read FFonts write SetFonts stored IsFontsStored;
+ property Theme: TJvNavPanelTheme read FTheme write SetTheme nodefault;
+ property OnThemeChange: TNotifyEvent read FOnThemeChange write FOnThemeChange;
+ end;
+
+implementation
+
+uses
+ ActnList, Forms, JvJVCLUtils, JvJCLUtils;
+
+const
+ cNavPanelButtonGroupIndex = 113;
+ cToolButtonHeight = 18;
+ cToolButtonOffset = 14;
+ cToolButtonWidth = 18;
+
+procedure InternalStyleManagerChanged(AControl: TWinControl; AStyleManager: TJvNavPaneStyleManager);
+var
+ Msg: TMsgStyleManagerChange;
+begin
+ Msg.Msg := CM_PARENTSTYLEMANAGERCHANGED;
+ Msg.Sender := AControl;
+ Msg.StyleManager := AStyleManager;
+ Msg.Result := 0;
+ AControl.Broadcast(Msg);
+end;
+
+//=== { TJvIconPanel } =======================================================
+
+constructor TJvIconPanel.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ ControlStyle := ControlStyle - [csAcceptsControls];
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ ControlStyle := ControlStyle + [csOpaque, csAcceptsControls];
+ Height := 28;
+ FDropButton := TJvNavIconButton.Create(Self);
+ FDropButton.Visible := False;
+ FDropButton.ButtonType := nibDropDown;
+ FDropButton.GroupIndex := 0;
+ FDropButton.Width := 22;
+ FDropButton.Left := Width + 10;
+ FDropButton.Align := alRight;
+ FDropButton.Parent := Self;
+ FDropButton.OnDropDownMenu := @DoDropDownMenu;
+ FColors := TJvNavPanelColors.Create;
+ FColors.OnChange := @DoColorsChange;
+ FParentStyleManager := True;
+end;
+
+destructor TJvIconPanel.Destroy;
+begin
+ FStyleLink.Free;
+ FColors.Free;
+ // Don't free FDropButton: it is freed automatically
+ inherited Destroy;
+end;
+
+procedure TJvIconPanel.DoColorsChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvIconPanel.DoStyleChange(Sender: TObject);
+begin
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelFont;
+end;
+
+function TJvIconPanel.GetDropDownMenu: TPopupMenu;
+begin
+ Result := FDropButton.DropDownMenu
+end;
+
+procedure TJvIconPanel.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = StyleManager then
+ StyleManager := nil;
+ end;
+end;
+
+procedure TJvIconPanel.Paint;
+begin
+ GradientFillRect(Canvas, ClientRect, Colors.ButtonColorFrom, Colors.ButtonColorTo, fdTopToBottom, 32);
+ Canvas.Pen.Color := Colors.FrameColor;
+ if Align = alBottom then
+ begin
+ Canvas.MoveTo(0, 0);
+ Canvas.LineTo(Width + 1, 0);
+ end
+ else
+ begin
+ Canvas.MoveTo(0, ClientHeight - 1);
+ Canvas.LineTo(Width + 1, ClientHeight - 1);
+ end;
+end;
+
+procedure TJvIconPanel.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+ FDropButton.Colors := Value;
+end;
+
+procedure TJvIconPanel.SetStyleManager(const Value: TJvNavPaneStyleManager);
+//var
+// I: Integer;
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ end;
+ end;
+ // FDropButton.StyleManager := Value;
+ InternalStyleManagerChanged(Self, Value);
+ // TODO: should this be removed?
+// for I := 0 to ControlCount - 1 do
+// if Controls[I] is TJvNavIconButton then
+// TJvNavIconButton(Controls[I]).StyleManager := Value;
+end;
+
+procedure TJvIconPanel.SetDropDownMenu(const Value: TPopupMenu);
+begin
+ FDropButton.DropDownMenu := Value;
+ FDropButton.Visible := Value <> nil;
+end;
+
+procedure TJvIconPanel.DoDropDownMenu(Sender: TObject; MousePos: TPoint;
+ var Handled: Boolean);
+begin
+ if Assigned(FOnDropDownMenu) then
+ FOnDropDownMenu(Self, MousePos, Handled);
+end;
+
+procedure TJvIconPanel.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ InternalStyleManagerChanged(Self, Msg.StyleManager);
+ end;
+end;
+
+procedure TJvIconPanel.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+
+procedure TJvIconPanel.CMControlChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvIconPanel.WMEraseBkgnd(var Msg: TLMEraseBkgnd);
+begin
+ Msg.Result := 1;
+end;
+
+procedure TJvIconPanel.ParentStyleManagerChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+//=== { TJvCustomNavigationPane } ============================================
+
+var
+ GlobalNavPanelPageRegistered: Boolean = False;
+
+constructor TJvCustomNavigationPane.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ if not GlobalNavPanelPageRegistered then
+ begin
+ GlobalNavPanelPageRegistered := True;
+ RegisterClasses([TJvNavPanelPage]);
+ end;
+
+ FBackground := TJvNavPaneBackgroundImage.Create;
+ FBackground.OnChange := @DoColorsChange;
+ ControlStyle := ControlStyle - [csAcceptsControls];
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ FButtonHeight := 28;
+ FButtonWidth := 22;
+ BorderWidth := 1;
+ ParentColor := False;
+ Color := clWindow;
+ ControlStyle := ControlStyle + [csOpaque];
+ FResizable := True;
+ FColors := TJvNavPanelColors.Create;
+ FColors.OnChange := @DoColorsChange;
+ FIconPanel := TJvIconPanel.Create(Self);
+ FIconPanel.Parent := Self;
+ FIconPanel.Align := alBottom;
+ FIconPanel.OnDropDownMenu := @DoDropDownMenu;
+
+ FNavPanelFont := TFont.Create;
+ FNavPanelHotTrackFont := TFont.Create;
+ //TODO:
+ //FNavPanelFont.Assign(Screen.IconFont);
+ FNavPanelFont.Style := [fsBold];
+ FNavPanelFont.OnChange := @DoNavPanelFontChange;
+ FNavPanelHotTrackFont.Assign(FNavPanelFont);
+ FNavPanelHotTrackFont.OnChange := @DoNavPanelFontChange;
+ FNavPanelHotTrackFontOptions := DefaultTrackFontOptions;
+ FSplitter := TJvOutlookSplitter.Create(Self);
+ with FSplitter do
+ begin
+ ResizeStyle := rsNone;
+ MinSize := 1;
+ OnCanResize := @DoSplitterCanResize;
+ Parent := Self;
+ end;
+ FParentStyleManager := True;
+ FIconPanel.SetSubComponent(True);
+ FSplitter.SetSubComponent(True);
+end;
+
+destructor TJvCustomNavigationPane.Destroy;
+begin
+ FStyleLink.Free;
+ FColors.Free;
+ FNavPanelFont.Free;
+ FNavPanelHotTrackFont.Free;
+ FBackground.Free;
+ inherited Destroy;
+end;
+
+procedure TJvCustomNavigationPane.DoSplitterCanResize(Sender: TObject;
+ var NewSize: Integer; var Accept: Boolean);
+var
+ ACount: Integer;
+begin
+ ACount := MaximizedCount;
+ if NewSize < ButtonHeight div 2 then
+ MaximizedCount := ACount - 1
+ else
+ if NewSize > ButtonHeight + ButtonHeight div 2 then
+ MaximizedCount := ACount + 1;
+ NewSize := 0;
+ Accept := False;
+end;
+
+function TJvCustomNavigationPane.GetDropDownMenu: TPopupMenu;
+begin
+ if FIconPanel <> nil then
+ Result := FIconPanel.DropDownMenu
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSmallImages: TCustomImageList;
+begin
+ Result := FSmallImages;
+end;
+
+function TJvCustomNavigationPane.GetMaximizedCount: Integer;
+var
+ I: Integer;
+begin
+ Result := 0;
+ for I := 0 to PageCount - 1 do
+ if not NavPages[I].Iconic then
+ Inc(Result);
+end;
+
+function TJvCustomNavigationPane.HidePage(Page: TJvCustomPage): TJvCustomPage;
+begin
+ Result := inherited HidePage(Page);
+ if Result <> nil then
+ UpdatePositions;
+end;
+
+function TJvCustomNavigationPane.ShowPage(Page: TJvCustomPage; PageIndex: Integer): TJvCustomPage;
+begin
+ Result := inherited ShowPage(Page, PageIndex);
+ if Result <> nil then
+ UpdatePositions;
+end;
+
+procedure TJvCustomNavigationPane.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = LargeImages then
+ LargeImages := nil;
+ if AComponent = SmallImages then
+ SmallImages := nil;
+ if AComponent = StyleManager then
+ StyleManager := nil;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetDropDownMenu(const Value: TPopupMenu);
+begin
+ if FIconPanel <> nil then
+ FIconPanel.DropDownMenu := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetLargeImages(const Value: TCustomImageList);
+begin
+ if FLargeImages <> Value then
+ begin
+ FLargeImages := Value;
+ UpdatePages;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetSmallImages(const Value: TCustomImageList);
+begin
+ if FSmallImages <> Value then
+ begin
+ FSmallImages := Value;
+ UpdatePages;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.HidePanel(Index: Integer);
+begin
+ if (Index >= 0) and (Index < PageCount) then // don't hide the first panel
+ NavPages[Index].Iconic := True;
+end;
+
+procedure TJvCustomNavigationPane.ShowPanel(Index: Integer);
+begin
+ if (Index >= 0) and (Index < PageCount) then
+ NavPages[Index].Iconic := False;
+end;
+
+procedure TJvCustomNavigationPane.SetMaximizedCount(Value: Integer);
+var
+ I, ACount: Integer;
+begin
+ ACount := MaximizedCount;
+ if Value < 0 then
+ Value := 0;
+ if Value > PageCount then
+ Value := PageCount;
+ if Value = MaximizedCount then
+ Exit;
+ while ACount > Value do
+ begin
+ HidePanel(ACount - 1);
+ Dec(ACount);
+ end;
+ if Value > ACount then
+ for I := Value downto ACount do
+ ShowPanel(I - 1);
+ UpdatePositions;
+end;
+
+procedure TJvCustomNavigationPane.UpdatePositions;
+var
+ bw, bh, I, X, Y: Integer;
+begin
+ if (csDestroying in ComponentState) or (FIconPanel = nil) then
+ Exit;
+ DisableAlign;
+ FIconPanel.DisableAlign;
+ try
+ // 25.09.2007 - SESS: Original code doesn't work in lazarus.
+ (*
+ Y := 0;
+ X := 0;
+ FSplitter.Top := Y;
+ FIconPanel.FDropButton.Left := Width;
+ FIconPanel.Top := Height - FIconPanel.Height;
+ Inc(Y, FSplitter.Height);
+ for I := 0 to PageCount - 1 do
+ begin
+ if (NavPages[I].NavPanel = nil) or (NavPages[I].IconButton = nil) then
+ Exit;
+ NavPages[I].IconButton.Left := X;
+ Inc(X, NavPages[I].IconButton.Width);
+ NavPages[I].NavPanel.Top := Y;
+ Inc(Y, NavPages[I].NavPanel.Height);
+ NavPages[I].Invalidate;
+ end;
+ *)
+
+ // 25.09.2007: Rewrited by SESS.
+ // Buttons heights & widths
+ bw := 0;
+ bh := 0;
+ for I := 0 to PageCount - 1 do
+ if NavPages[I].Iconic then
+ Inc(bw, NavPages[I].IconButton.Width)
+ else
+ Inc(bh, NavPages[I].NavPanel.Height);
+
+ // First positions
+ X := Self.Width - bw - FIconPanel.FDropButton.Width;
+ Y := Self.Height - FSplitter.Height - bh - FIconPanel.Height;
+
+ // Splitter
+ FSplitter.Top := Y;
+ Inc(Y, FSplitter.Height);
+
+ // Pages
+ for I := 0 to PageCount - 1 do
+ begin
+ if (NavPages[I].NavPanel = nil) or (NavPages[I].IconButton = nil) then
+ Exit;
+ if NavPages[I].Iconic then
+ begin
+ NavPages[I].IconButton.Left := X;
+ Inc(X, NavPages[I].IconButton.Width);
+ end
+ else
+ begin
+ NavPages[I].NavPanel.Top := Y;
+ Inc(Y, NavPages[I].NavPanel.Height);
+ end;
+ NavPages[I].Invalidate;
+ end;
+
+ // Icon panel
+ FIconPanel.FDropButton.Left := X;
+ FIconPanel.Top := Y;
+ finally
+ EnableAlign;
+ FIconPanel.EnableAlign;
+ end;
+ Invalidate;
+end;
+
+procedure TJvCustomNavigationPane.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvCustomNavigationPane.DoColorsChange(Sender: TObject);
+begin
+ if FIconPanel <> nil then
+ TJvIconPanel(FIconPanel).Colors := Colors;
+ UpdatePages;
+ FSplitter.ColorFrom := Colors.SplitterColorFrom;
+ FSplitter.ColorTo := Colors.SplitterColorTo;
+ Invalidate;
+end;
+
+procedure TJvCustomNavigationPane.Loaded;
+begin
+ inherited Loaded;
+ UpdatePositions;
+end;
+
+procedure TJvCustomNavigationPane.SetResizable(const Value: Boolean);
+begin
+ if FResizable <> Value then
+ begin
+ FResizable := Value;
+ FSplitter.Enabled := FResizable;
+ end;
+end;
+
+function TJvCustomNavigationPane.InternalGetPageClass: TJvCustomPageClass;
+begin
+ Result := TJvNavPanelPage;
+end;
+
+function TJvCustomNavigationPane.GetNavPage(Index: Integer): TJvNavPanelPage;
+begin
+ Result := TJvNavPanelPage(Pages[Index]);
+end;
+
+procedure TJvCustomNavigationPane.InsertPage(APage: TJvCustomPage);
+begin
+ inherited InsertPage(APage);
+ if APage <> nil then
+ begin
+ TJvNavPanelPage(APage).Top := FIconPanel.Top;
+ if (ActivePage = nil) and not (csLoading in ComponentState) then
+ ActivePage := APage;
+ end;
+ UpdatePositions;
+end;
+
+procedure TJvCustomNavigationPane.SetActivePage(Page: TJvCustomPage);
+begin
+ inherited SetActivePage(Page);
+ if ActivePage <> nil then
+ begin
+ TJvNavPanelPage(ActivePage).NavPanel.Down := True;
+ TJvNavPanelPage(ActivePage).IconButton.Down := True;
+ TJvNavPanelPage(ActivePage).NavPanel.Invalidate;
+ TJvNavPanelPage(ActivePage).IconButton.Invalidate;
+ ActivePage.Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetBackground(const Value: TJvNavPaneBackgroundImage);
+begin
+ FBackground.Assign(Value);
+end;
+
+procedure TJvCustomNavigationPane.SetNavPanelFont(const Value: TFont);
+begin
+ FNavPanelFont.Assign(Value);
+end;
+
+procedure TJvCustomNavigationPane.SetNavPanelHotTrackFont(const Value: TFont);
+begin
+ FNavPanelHotTrackFont.Assign(Value);
+end;
+
+procedure TJvCustomNavigationPane.SetNavPanelHotTrackFontOptions(const Value: TJvTrackFontOptions);
+begin
+ if FNavPanelHotTrackFontOptions <> Value then
+ begin
+ FNavPanelHotTrackFontOptions := Value;
+ UpdatePages;
+ end;
+end;
+
+function TJvCustomNavigationPane.IsNavPanelFontStored: Boolean;
+var
+ F: TFont;
+begin
+ //TODO:
+ (*
+ F := Screen.IconFont;
+ with FNavPanelFont do
+ Result := ((StyleManager = nil) or (StyleManager.Theme = nptCustom)) and ((Name <> F.Name) or (Size <> F.Size) or (Style <> [fsBold]) or
+ (Color <> F.Color) or (Pitch <> F.Pitch) or (Charset <> F.Charset));
+ *)
+ Result := true;
+end;
+
+function TJvCustomNavigationPane.IsNavPanelFontHotTrackStored: Boolean;
+begin
+ Result := IsNavPanelHotTrackFontOptionsStored or IsNavPanelFontStored;
+end;
+
+function TJvCustomNavigationPane.IsNavPanelHotTrackFontOptionsStored: Boolean;
+begin
+ Result := not (hoFollowFont in NavPanelHotTrackFontOptions);
+end;
+
+procedure TJvCustomNavigationPane.DoNavPanelFontChange(Sender: TObject);
+begin
+ UpdatePages;
+end;
+
+procedure TJvCustomNavigationPane.RemovePage(APage: TJvCustomPage);
+begin
+ inherited RemovePage(APage);
+ Invalidate;
+end;
+
+procedure TJvCustomNavigationPane.SetButtonHeight(const Value: Integer);
+begin
+ if FButtonHeight <> Value then
+ begin
+ FButtonHeight := Value;
+ UpdatePages;
+ FIconPanel.Height := FButtonHeight;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetButtonWidth(const Value: Integer);
+begin
+ if FButtonWidth <> Value then
+ begin
+ FButtonWidth := Value;
+ UpdatePages;
+ FIconPanel.FDropButton.Width := FButtonWidth;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterHeight(const Value: Integer);
+begin
+ if FSplitter.Height <> Value then
+ FSplitter.Height := Value;
+end;
+
+function TJvCustomNavigationPane.GetSplitterHeight: Integer;
+begin
+ Result := FSplitter.Height;
+end;
+
+procedure TJvCustomNavigationPane.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ NavPanelFont := FStyleManager.Fonts.FNavPanelFont;
+ NavPanelHotTrackFont := FStyleManager.Fonts.FNavPanelHotTrackFont;
+ NavPanelHotTrackFontOptions := FStyleManager.Fonts.FNavPanelHotTrackFontOptions;
+ end;
+ // FSplitter.StyleManager := Value;
+ InternalStyleManagerChanged(Self, Value);
+ end;
+end;
+
+procedure TJvCustomNavigationPane.DoStyleChange(Sender: TObject);
+begin
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+ NavPanelFont := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelFont;
+ NavPanelHotTrackFont := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFont;
+ NavPanelHotTrackFontOptions := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFontOptions;
+end;
+
+procedure TJvCustomNavigationPane.SetAutoHeaders(const Value: Boolean);
+begin
+ if FAutoHeaders <> Value then
+ begin
+ FAutoHeaders := Value;
+ UpdatePages;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetAlignment(const Value: TAlignment);
+begin
+ if FAlignment <> Value then
+ begin
+ FAlignment := Value;
+ UpdatePages;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetWordWrap(const Value: Boolean);
+begin
+ if FWordWrap <> Value then
+ begin
+ FWordWrap := Value;
+ UpdatePages;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.UpdatePages;
+var
+ I: Integer;
+begin
+ for I := 0 to PageCount - 1 do
+ begin
+ NavPages[I].AutoHeader := AutoHeaders;
+ NavPages[I].NavPanel.Height := ButtonHeight;
+ NavPages[I].IconButton.Width := ButtonWidth;
+ NavPages[I].NavPanel.Colors := Colors;
+ NavPages[I].IconButton.Colors := Colors;
+ NavPages[I].NavPanel.HotTrackFontOptions := NavPanelHotTrackFontOptions;
+ NavPages[I].NavPanel.Font := FNavPanelFont;
+ NavPages[I].NavPanel.HotTrackFont := FNavPanelHotTrackFont;
+
+ NavPages[I].WordWrap := WordWrap;
+ NavPages[I].Alignment := Alignment;
+ NavPages[I].NavPanel.Images := LargeImages;
+ if AutoHeaders then
+ NavPages[I].Header.Images := LargeImages;
+ NavPages[I].IconButton.Images := SmallImages;
+ // NavPages[I].StyleManager := StyleManager;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.DoDropDownMenu(Sender: TObject;
+ MousePos: TPoint; var Handled: Boolean);
+begin
+ if Assigned(FOnDropDownMenu) then
+ FOnDropDownMenu(Self, MousePos, Handled);
+end;
+
+procedure TJvCustomNavigationPane.ParentStyleManagerChanged(
+ var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ InternalStyleManagerChanged(Self, Msg.StyleManager);
+ end;
+end;
+
+procedure TJvCustomNavigationPane.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+
+procedure TJvCustomNavigationPane.CMControlChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvCustomNavigationPane.WMNCPaint(var Msg: TWMNCPaint);
+var
+ AColor: TColor;
+begin
+ AColor := Color;
+ try
+ Color := Colors.FrameColor;
+ inherited;
+ finally
+ Color := AColor;
+ end;
+end;
+
+procedure TJvCustomNavigationPane.WMEraseBkgnd(var Msg: TLMEraseBkgnd);
+begin
+ if ActivePage = nil then
+ begin
+ Canvas.Brush.Color := Color;
+ Canvas.FillRect(ClientRect);
+ FBackground.DrawImage(Canvas, ClientRect);
+ end;
+ Msg.Result := 1;
+end;
+
+procedure TJvCustomNavigationPane.ParentStyleManagerChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+function TJvCustomNavigationPane.IsColorsStored: Boolean;
+begin
+ Result := (StyleManager = nil) or (StyleManager.Theme = nptCustom);
+end;
+
+function TJvCustomNavigationPane.GetSplitterClick: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnClick
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterDblClick: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnDblClick
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMouseDown: TMouseEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMouseDown
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMouseEnter: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMouseEnter
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMouseLeave: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMouseLeave
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMouseMove: TMouseMoveEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMouseMove
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMouseUp: TMouseEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMouseUp
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterCanResize: TCanResizeEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnCanResize
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterMoved: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnMoved
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavigationPane.GetSplitterPaint: TNotifyEvent;
+begin
+ if FSplitter <> nil then
+ Result := FSplitter.OnPaint
+ else
+ Result := nil;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterCanResize(const Value: TCanResizeEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnCanResize := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMoved(const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMoved := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterPaint(const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnPaint := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterClick(const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnClick := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterDblClick(
+ const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnDblClick := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMouseDown(
+ const Value: TMouseEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMouseDown := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMouseEnter(
+ const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMouseEnter := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMouseLeave(
+ const Value: TNotifyEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMouseLeave := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMouseMove(
+ const Value: TMouseMoveEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMouseMove := Value;
+end;
+
+procedure TJvCustomNavigationPane.SetSplitterMouseUp(
+ const Value: TMouseEvent);
+begin
+ if FSplitter <> nil then
+ FSplitter.OnMouseUp := Value;
+end;
+
+//=== { TJvNavIconButton } ===================================================
+
+constructor TJvNavIconButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ FColors := TJvNavPanelColors.Create;
+ FColors.OnChange := @DoColorsChange;
+ FChangeLink := TChangeLink.Create;
+ FChangeLink.OnChange := @DoImagesChange;
+ Width := 22;
+ Height := 22;
+ //TODO:
+ //Font := Screen.IconFont;
+ Font.Style := [fsBold];
+ FParentStyleManager := True;
+end;
+
+destructor TJvNavIconButton.Destroy;
+begin
+ FStyleLink.Free;
+ FChangeLink.Free;
+ FColors.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavIconButton.DoColorsChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavIconButton.DoImagesChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavIconButton.Notification(AComponent: TComponent; Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ if AComponent = Images then
+ Images := nil
+ else
+ if AComponent = StyleManager then
+ StyleManager := nil;
+end;
+
+procedure TJvNavIconButton.Paint;
+var
+ Rect: TRect;
+ P: TPoint;
+ I: Integer;
+
+ h, w: integer;
+begin
+ with Canvas do
+ begin
+ Rect := ClientRect;
+ Brush.Style := bsClear;
+ InflateRect(Rect, 0, -1);
+ if bsMouseInside in MouseStates then
+ begin
+ if bsMouseDown in MouseStates then
+ GradientFillRect(Canvas, Rect, Self.Colors.ButtonSelectedColorFrom,
+ Self.Colors.ButtonSelectedColorTo, fdTopToBottom, 32)
+ else
+ GradientFillRect(Canvas, Rect, Self.Colors.ButtonHotColorFrom,
+ Self.Colors.ButtonHotColorTo, fdTopToBottom, 32)
+ end
+ else
+ if Down then
+ GradientFillRect(Canvas, Rect, Self.Colors.ButtonSelectedColorFrom,
+ Self.Colors.ButtonSelectedColorTo, fdTopToBottom, 32);
+ case ButtonType of
+ nibDropDown:
+ begin // area should be 7x12
+ InflateRect(Rect, -((Rect.Right - Rect.Left) - 7) div 2, -((Rect.Bottom - Rect.Top) - 12) div 2);
+ if bsMouseDown in MouseStates then
+ OffsetRect(Rect, 1, 1);
+ Canvas.Pen.Color := clBlack;
+ P.X := Rect.Left;
+ P.Y := Rect.Top;
+ // chevron, upper
+ for I := 0 to 2 do
+ begin
+ Canvas.MoveTo(P.X, P.Y);
+ Canvas.LineTo(P.X + 2, P.Y);
+ Canvas.MoveTo(P.X + 4, P.Y);
+ Canvas.LineTo(P.X + 6, P.Y);
+ Inc(P.X);
+ Inc(P.Y);
+ end;
+ // chevron, lower
+ Dec(P.X);
+ Dec(P.Y);
+ for I := 0 to 2 do
+ begin
+ Canvas.MoveTo(P.X, P.Y);
+ Canvas.LineTo(P.X + 2, P.Y);
+ Canvas.MoveTo(P.X + 4, P.Y);
+ Canvas.LineTo(P.X + 6, P.Y);
+ Dec(P.X);
+ Inc(P.Y);
+ end;
+ // drop arrow
+ Inc(P.X, 1);
+ Inc(P.Y, 3);
+ for I := 0 to 3 do
+ begin
+ Canvas.MoveTo(P.X + I, P.Y + I);
+ Canvas.LineTo(P.X + 7 - I, P.Y + I);
+ end;
+ end;
+ nibImage:
+ begin
+ if (Images <> nil) and (ImageIndex >= 0) and (ImageIndex < Images.Count) then
+ // draw image only
+ Images.Draw(Canvas,
+ (Self.Width - Images.Width) div 2 + Ord(bsMouseDown in MouseStates),
+ (Self.Height - Images.Height) div 2 + Ord(bsMouseDown in MouseStates),
+ ImageIndex, Enabled);
+ end;
+ nibDropArrow:
+ begin
+ // area should be 9 x 5, centered
+ P.X := Rect.Left + (RectWidth(Rect) - 9) div 2 + Ord(bsMouseDown in MouseStates);
+ P.Y := Rect.Top + (RectHeight(Rect) - 5) div 2 + Ord(bsMouseDown in MouseStates);
+ Canvas.Pen.Color := clBlack;
+ for I := 0 to 4 do
+ begin
+ Canvas.MoveTo(P.X + I, P.Y + I);
+ Canvas.LineTo(P.X + 9 - I, P.Y + I);
+ end;
+ end;
+ nibClose:
+ begin
+ // area should be 8 x 8, centered
+ P.X := (RectWidth(ClientRect) - 8) div 2 + Ord(bsMouseDown in MouseStates);
+ P.Y := (RectHeight(ClientRect) - 8) div 2 + Ord(bsMouseDown in MouseStates);
+ Canvas.Pen.Color := clBlack;
+ for I := 0 to 7 do
+ begin
+ Canvas.MoveTo(P.X + I, P.Y + I);
+ Canvas.LineTo(P.X + I + 2, P.Y + I);
+ end;
+ Inc(P.X, 7);
+ for I := 0 to 7 do
+ begin
+ Canvas.MoveTo(P.X - I, P.Y + I);
+ Canvas.LineTo(P.X - I + 2, P.Y + I);
+ end;
+ end;
+ end;
+ if csDesigning in ComponentState then
+ begin
+ Canvas.Pen.Color := clBlack;
+ Canvas.Pen.Style := psDot;
+ Canvas.Brush.Style := bsClear;
+ Canvas.Rectangle(ClientRect);
+ end;
+ end;
+end;
+
+procedure TJvNavIconButton.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvNavIconButton.SetImageIndex(const Value: TImageIndex);
+begin
+ if FImageIndex <> Value then
+ begin
+ FImageIndex := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavIconButton.SetImages(const Value: TCustomImageList);
+begin
+ if FImages <> Value then
+ begin
+ if FImages <> nil then
+ FImages.UnregisterChanges(FChangeLink);
+ FImages := Value;
+ if FImages <> nil then
+ begin
+ FImages.FreeNotification(Self);
+ FImages.RegisterChanges(FChangeLink);
+ end;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavIconButton.SetButtonType(const Value: TJvNavIconButtonType);
+begin
+ if FButtonType <> Value then
+ begin
+ FButtonType := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavIconButton.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ end;
+ end;
+end;
+
+procedure TJvNavIconButton.DoStyleChange(Sender: TObject);
+begin
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.DividerFont;
+end;
+
+procedure TJvNavIconButton.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ end;
+end;
+
+procedure TJvNavIconButton.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+function TJvNavIconButton.IsColorsStored: Boolean;
+begin
+ Result := (StyleManager = nil) or (StyleManager.Theme = nptCustom);
+end;
+
+//=== { TJvNavPanelButton } ==================================================
+
+constructor TJvNavPanelButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAlignment := taLeftJustify;
+
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ ControlStyle := ControlStyle + [csOpaque, csDisplayDragImage];
+ Flat := True;
+ HotTrack := True;
+ Height := 28;
+ FColors := TJvNavPanelColors.Create;
+ FColors.OnChange := @DoColorsChange;
+ //TODO:
+ //Font := Screen.IconFont;
+ Font.Style := [fsBold];
+ HotTrackFont := Font;
+ HotTrackFont.Style := [fsBold];
+ Width := 125;
+ Height := 28;
+ FParentStyleManager := True;
+end;
+
+destructor TJvNavPanelButton.Destroy;
+begin
+ FStyleLink.Free;
+ FColors.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavPanelButton.ActionChange(Sender: TObject;
+ CheckDefaults: Boolean);
+begin
+ if Sender is TCustomAction then
+ with TCustomAction(Sender) do
+ begin
+ if not CheckDefaults or (Self.Caption = '') or (Self.Caption = Self.Name) then
+ Self.Caption := Caption;
+ if not CheckDefaults or Self.Enabled then
+ Self.Enabled := Enabled;
+ if not CheckDefaults or (Self.Hint = '') then
+ Self.Hint := Hint;
+ if not CheckDefaults or (Self.ImageIndex = -1) then
+ Self.ImageIndex := ImageIndex;
+ if not CheckDefaults or Self.Visible then
+ Self.Visible := Visible;
+ if not CheckDefaults or not Assigned(Self.OnClick) then
+ Self.OnClick := OnExecute;
+ end;
+end;
+
+procedure TJvNavPanelButton.DoColorsChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavPanelButton.DoStyleChange(Sender: TObject);
+begin
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelFont;
+ HotTrackFont := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFont;
+ HotTrackFontOptions := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFontOptions;
+end;
+
+procedure TJvNavPanelButton.FontChanged;
+begin
+ inherited FontChanged;
+ Invalidate;
+end;
+
+procedure TJvNavPanelButton.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = StyleManager then
+ StyleManager := nil;
+ end;
+end;
+
+procedure TJvNavPanelButton.PaintButton(ACanvas:TCanvas);
+//const
+// cAlignment: array [TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER);
+// cWordWrap: array [Boolean] of Cardinal = (DT_SINGLELINE, DT_WORDBREAK);
+var
+ R: TRect;
+ X, Y: Integer;
+
+ function IsValidImage: Boolean;
+ begin
+ Result := Assigned(Images) and (ImageIndex >= 0);
+ end;
+
+begin
+ R := ClientRect;
+ if HotTrack and (bsMouseInside in MouseStates) then
+ begin
+ if bsMouseDown in MouseStates then
+ GradientFillRect(ACanvas, R, Colors.ButtonSelectedColorTo, Colors.ButtonSelectedColorFrom, fdTopToBottom, 32)
+ else
+ GradientFillRect(ACanvas, R, Colors.ButtonHotColorFrom, Colors.ButtonHotColorTo, fdTopToBottom, 32);
+ end
+ else
+ if Down then
+ GradientFillRect(ACanvas, R, Colors.ButtonSelectedColorFrom, Colors.ButtonSelectedColorTo, fdTopToBottom, 32)
+ else
+ if bsMouseDown in MouseStates then
+ GradientFillRect(ACanvas, R, Colors.ButtonSelectedColorTo, Colors.ButtonSelectedColorFrom, fdTopToBottom, 32)
+ else
+ GradientFillRect(ACanvas, ClientRect, Colors.ButtonColorFrom, Colors.ButtonColorTo, fdTopToBottom, 32);
+ InflateRect(R, -4, -4);
+ if IsValidImage then
+ begin
+ Y := (Height - Images.Height) div 2;
+ X := 4;
+ Images.Draw(ACanvas, X, Y, ImageIndex);
+ Inc(R.Left, Images.Width + 4);
+ end;
+ if Caption <> '' then
+ begin
+ if HotTrack and (bsMouseInside in MouseStates) and not (bsMouseDown in MouseStates) then
+ ACanvas.Font := HotTrackFont
+ else
+ ACanvas.Font := Font;
+ SetBkMode(ACanvas.Handle, TRANSPARENT);
+ DrawText(ACanvas, Caption, Length(Caption), R, DT_SINGLELINE or DT_VCENTER);
+ end;
+ if Colors.ButtonSeparatorColor <> clNone then
+ begin
+ ACanvas.Pen.Color := Colors.ButtonSeparatorColor;
+ if Align = alBottom then
+ begin
+ ACanvas.MoveTo(0, 0);
+ ACanvas.LineTo(Width + 1, 0);
+ end
+ else
+ begin
+ ACanvas.MoveTo(0, ClientHeight - 1);
+ ACanvas.LineTo(Width + 1, ClientHeight - 1);
+ end;
+ end;
+end;
+
+procedure TJvNavPanelButton.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvNavPanelButton.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ end;
+ end;
+end;
+
+procedure TJvNavPanelButton.SetImageIndex(const Value: TImageIndex);
+begin
+ if FImageIndex <> Value then
+ begin
+ FImageIndex := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelButton.SetImages(const Value: TCustomImageList);
+begin
+ if FImages <> Value then
+ begin
+ FImages := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelButton.TextChanged;
+begin
+ inherited TextChanged;
+ Invalidate;
+end;
+
+procedure TJvNavPanelButton.SetAlignment(const Value: TAlignment);
+begin
+ if FAlignment <> Value then
+ begin
+ FAlignment := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelButton.SetWordWrap(const Value: Boolean);
+begin
+ if FWordWrap <> Value then
+ begin
+ FWordWrap := Value;
+ Invalidate;
+ end;
+end;
+
+
+procedure TJvNavPanelButton.CMDialogChar(var Msg: TCMDialogChar);
+begin
+ if IsAccel(Msg.CharCode, Caption) then
+ begin
+ Msg.Result := 1;
+ Click;
+ end
+ else
+ inherited;
+end;
+
+procedure TJvNavPanelButton.ParentStyleManagerChanged(
+ var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ end;
+end;
+
+procedure TJvNavPanelButton.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+function TJvNavPanelButton.IsColorsStored: Boolean;
+begin
+ Result := (StyleManager = nil) or (StyleManager.Theme = nptCustom);
+end;
+
+//=== { TJvNavPanelColors } ==================================================
+
+constructor TJvNavPanelColors.Create;
+begin
+ inherited Create;
+ // use XPBlue as standard
+ FButtonColorFrom := TColor($F7E2CD);
+ FButtonColorTo := TColor($F3A080);
+ FButtonSelectedColorFrom := TColor($BBE2EA);
+ FButtonSelectedColorTo := TColor($389FDD);
+ FFrameColor := TColor($6F2F0C);
+ FButtonHotColorFrom := TColor($DBFBFF);
+ FButtonHotColorTo := TColor($5FC8FB);
+ FDividerColorFrom := TColor($FFDBBC);
+ FDividerColorTo := TColor($F2C0A4);
+ FHeaderColorFrom := TColor($D0835C);
+ FHeaderColorTo := TColor($903B09);
+ FSplitterColorFrom := TColor($B78676);
+ FSplitterColorTo := TColor($A03D09);
+ FButtonSeparatorColor := clGray;
+ FToolPanelColorFrom := clWindow;
+ FToolPanelColorTo := clWindow;
+ FToolPanelHeaderColorFrom := TColor($F7E2CD);
+ FToolPanelHeaderColorTo := TColor($F3A080);
+end;
+
+procedure TJvNavPanelColors.Assign(Source: TPersistent);
+begin
+ if (Source is TJvNavPanelColors) then
+ begin
+ if (Source <> Self) then
+ begin
+ FButtonColorFrom := TJvNavPanelColors(Source).ButtonColorFrom;
+ FButtonColorTo := TJvNavPanelColors(Source).ButtonColorTo;
+ FButtonHotColorFrom := TJvNavPanelColors(Source).ButtonHotColorFrom;
+ FButtonHotColorTo := TJvNavPanelColors(Source).ButtonHotColorTo;
+ FButtonSelectedColorFrom := TJvNavPanelColors(Source).ButtonSelectedColorFrom;
+ FButtonSelectedColorTo := TJvNavPanelColors(Source).ButtonSelectedColorTo;
+ FFrameColor := TJvNavPanelColors(Source).FrameColor;
+ FHeaderColorFrom := TJvNavPanelColors(Source).HeaderColorFrom;
+ FHeaderColorTo := TJvNavPanelColors(Source).HeaderColorTo;
+ FDividerColorFrom := TJvNavPanelColors(Source).DividerColorFrom;
+ FDividerColorTo := TJvNavPanelColors(Source).DividerColorTo;
+ FSplitterColorFrom := TJvNavPanelColors(Source).SplitterColorFrom;
+ FSplitterColorTo := TJvNavPanelColors(Source).SplitterColorTo;
+ FButtonSeparatorColor := TJvNavPanelColors(Source).ButtonSeparatorColor;
+ FToolPanelColorFrom := TJvNavPanelColors(Source).ToolPanelColorFrom;
+ FToolPanelColorTo := TJvNavPanelColors(Source).ToolPanelColorTo;
+ FToolPanelHeaderColorFrom := TJvNavPanelColors(Source).ToolPanelHeaderColorFrom;
+ FToolPanelHeaderColorTo := TJvNavPanelColors(Source).ToolPanelHeaderColorTo;
+ Change;
+ end;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvNavPanelColors.Change;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvNavPanelColors.SetButtonColorFrom(const Value: TColor);
+begin
+ if FButtonColorFrom <> Value then
+ begin
+ FButtonColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonColorTo(const Value: TColor);
+begin
+ if FButtonColorTo <> Value then
+ begin
+ FButtonColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetDividerColorFrom(const Value: TColor);
+begin
+ if FDividerColorFrom <> Value then
+ begin
+ FDividerColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetDividerColorTo(const Value: TColor);
+begin
+ if FDividerColorTo <> Value then
+ begin
+ FDividerColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetFrameColor(const Value: TColor);
+begin
+ if FFrameColor <> Value then
+ begin
+ FFrameColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetHeaderColorFrom(const Value: TColor);
+begin
+ if FHeaderColorFrom <> Value then
+ begin
+ FHeaderColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetHeaderColorTo(const Value: TColor);
+begin
+ if FHeaderColorTo <> Value then
+ begin
+ FHeaderColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonHotColorFrom(const Value: TColor);
+begin
+ if FButtonHotColorFrom <> Value then
+ begin
+ FButtonHotColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonHotColorTo(const Value: TColor);
+begin
+ if FButtonHotColorTo <> Value then
+ begin
+ FButtonHotColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonSelectedColorFrom(const Value: TColor);
+begin
+ if FButtonSelectedColorFrom <> Value then
+ begin
+ FButtonSelectedColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonSelectedColorTo(const Value: TColor);
+begin
+ if FButtonSelectedColorTo <> Value then
+ begin
+ FButtonSelectedColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetSplitterColorFrom(const Value: TColor);
+begin
+ if FSplitterColorFrom <> Value then
+ begin
+ FSplitterColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetSplitterColorTo(const Value: TColor);
+begin
+ if FSplitterColorTo <> Value then
+ begin
+ FSplitterColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetButtonSeparatorColor(const Value: TColor);
+begin
+ if FButtonSeparatorColor <> Value then
+ begin
+ FButtonSeparatorColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetToolPanelColorFrom(const Value: TColor);
+begin
+ if FToolPanelColorFrom <> Value then
+ begin
+ FToolPanelColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetToolPanelColorTo(const Value: TColor);
+begin
+ if FToolPanelColorTo <> Value then
+ begin
+ FToolPanelColorTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetToolPanelHeaderColorFrom(
+ const Value: TColor);
+begin
+ if FToolPanelHeaderColorFrom <> Value then
+ begin
+ FToolPanelHeaderColorFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvNavPanelColors.SetToolPanelHeaderColorTo(const Value: TColor);
+begin
+ if FToolPanelHeaderColorTo <> Value then
+ begin
+ FToolPanelHeaderColorTo := Value;
+ Change;
+ end;
+end;
+
+//=== { TJvNavPanelFonts } ===================================================
+
+constructor TJvNavPanelFonts.Create;
+begin
+ inherited Create;
+ FDividerFont := TFont.Create;
+ FNavPanelFont := TFont.Create;
+ FNavPanelHotTrackFont := TFont.Create;
+ FHeaderFont := TFont.Create;
+ FHeaderFont.Name := 'Arial';
+ FHeaderFont.Size := 12;
+ FHeaderFont.Style := [fsBold];
+ FHeaderFont.Color := clWhite;
+ FHeaderFont.OnChange := @DoFontChange;
+
+ //TODO:
+ //FDividerFont.Assign(Screen.IconFont);
+ //FNavPanelFont.Assign(Screen.IconFont);
+
+ FNavPanelFont.Style := [fsBold];
+ FNavPanelHotTrackFont.Assign(FNavPanelFont);
+ FNavPanelHotTrackFontOptions := DefaultTrackFontOptions;
+
+ FDividerFont.OnChange := @DoFontChange;
+ FNavPanelFont.OnChange := @DoFontChange;
+ FNavPanelHotTrackFont.OnChange := @DoFontChange;
+end;
+
+destructor TJvNavPanelFonts.Destroy;
+begin
+ FDividerFont.Free;
+ FHeaderFont.Free;
+ FNavPanelFont.Free;
+ FNavPanelHotTrackFont.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavPanelFonts.Assign(Source: TPersistent);
+begin
+ if Source is TJvNavPanelFonts then
+ begin
+ if Source <> Self then
+ begin
+ NavPanelFont := TJvNavPanelFonts(Source).NavPanelFont;
+ DividerFont := TJvNavPanelFonts(Source).DividerFont;
+ HeaderFont := TJvNavPanelFonts(Source).HeaderFont;
+ end;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvNavPanelFonts.Change;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvNavPanelFonts.DoFontChange(Sender: TObject);
+begin
+ Change;
+end;
+
+procedure TJvNavPanelFonts.SetDividerFont(const Value: TFont);
+begin
+ FDividerFont.Assign(Value);
+end;
+
+procedure TJvNavPanelFonts.SetHeaderFont(const Value: TFont);
+begin
+ FHeaderFont.Assign(Value);
+end;
+
+procedure TJvNavPanelFonts.SetNavPanelFont(const Value: TFont);
+begin
+ FNavPanelFont.Assign(Value);
+end;
+
+procedure TJvNavPanelFonts.SetNavPanelHotTrackFont(const Value: TFont);
+begin
+ FNavPanelHotTrackFont.Assign(Value);
+end;
+
+procedure TJvNavPanelFonts.SetNavPanelHotTrackFontOptions(const Value: TJvTrackFontOptions);
+begin
+ if FNavPanelHotTrackFontOptions <> Value then
+ begin
+ FNavPanelHotTrackFontOptions := Value;
+ Change;
+ end;
+end;
+
+//=== { TJvNavPanelPage } ====================================================
+
+constructor TJvNavPanelPage.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FBackground := TJvNavPaneBackgroundImage.Create;
+ FBackground.OnChange := @DoBackgroundChange;
+ ParentColor := False;
+ Color := clWindow;
+ ControlStyle := ControlStyle + [csDisplayDragImage];
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ FNavPanel := TJvNavPanelButton.Create(Self);
+ FNavPanel.Visible := True;
+ FNavPanel.Align := alBottom;
+ FNavPanel.GroupIndex := cNavPanelButtonGroupIndex; // use a silly number that no one else is probable to use
+ FNavPanel.AllowAllUp := False;
+ FIconButton := TJvNavIconButton.Create(Self);
+ FIconButton.ButtonType := nibImage;
+ FIconButton.Visible := False;
+ FIconButton.Align := alRight;
+ FIconButton.Width := 0;
+ FIconButton.GroupIndex := cNavPanelButtonGroupIndex;
+ FIconButton.AllowAllUp := False;
+ FNavPanel.OnClick := @DoButtonClick;
+ FIconButton.OnClick := @DoButtonClick;
+ ImageIndex := -1;
+ FParentStyleManager := True;
+end;
+
+destructor TJvNavPanelPage.Destroy;
+begin
+ FStyleLink.Free;
+ FBackground.Free;
+ inherited Destroy;
+end;
+
+type
+ TJvCustomGraphicButtonAccess = class(TJvCustomGraphicButton)
+ public
+ property Down;
+ end;
+
+procedure TJvNavPanelPage.DoButtonClick(Sender: TObject);
+begin
+ { We cannot test for NavPanel.Down if the Sender is a icon button }
+ if (Sender is TJvCustomGraphicButton) and TJvCustomGraphicButtonAccess(Sender).Down then
+ begin
+ if Parent <> nil then
+ TJvCustomNavigationPane(Parent).ActivePage := Self; // this sets "Down" as well
+ if Assigned(FOnClick) then
+ FOnClick(Self);
+ end;
+end;
+
+procedure TJvNavPanelPage.DoStyleChange(Sender: TObject);
+begin
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+ NavPanel.Font := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelFont;
+ NavPanel.HotTrackFont := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFont;
+ NavPanel.HotTrackFontOptions := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelHotTrackFontOptions;
+end;
+
+function TJvNavPanelPage.GetCaption: TCaption;
+begin
+ if NavPanel = nil then
+ Result := ''
+ else
+ Result := NavPanel.Caption;
+end;
+
+function TJvNavPanelPage.GetColors: TJvNavPanelColors;
+begin
+ Result := NavPanel.Colors;
+end;
+
+function TJvNavPanelPage.GetHint: string;
+begin
+ if NavPanel = nil then
+ Result := ''
+ else
+ Result := NavPanel.Hint;
+end;
+
+function TJvNavPanelPage.GetIconic: Boolean;
+begin
+ if NavPanel = nil then
+ Result := False
+ else
+ Result := not NavPanel.Visible;
+end;
+
+function TJvNavPanelPage.GetImageIndex: TImageIndex;
+begin
+ if NavPanel = nil then
+ Result := FImageIndex
+ else
+ Result := NavPanel.ImageIndex;
+end;
+
+procedure TJvNavPanelPage.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = IconPanel then
+ IconPanel := nil
+ else
+ if AComponent = StyleManager then
+ StyleManager := nil;
+ end;
+end;
+
+procedure TJvNavPanelPage.SetCaption(const Value: TCaption);
+begin
+ if NavPanel <> nil then
+ NavPanel.Caption := Value;
+ // TODO: StripHotkey
+ (*
+ if AutoHeader then
+ Header.Caption := StripHotkey(Value);
+ *)
+end;
+
+procedure TJvNavPanelPage.SetColors(const Value: TJvNavPanelColors);
+begin
+ NavPanel.Colors := Value;
+ IconButton.Colors := Value;
+ if AutoHeader then
+ begin
+ Header.ColorFrom := Value.HeaderColorFrom;
+ Header.ColorTo := Value.HeaderColorTo;
+ end;
+end;
+
+procedure TJvNavPanelPage.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ end;
+ end;
+ // FNavPanel.StyleManager := Value;
+ // FIconButton.StyleManager := Value;
+ // if AutoHeader then
+ // Header.StyleManager := Value;
+end;
+
+procedure TJvNavPanelPage.SetHint(const Value: string);
+begin
+ NavPanel.Hint := Value;
+ IconButton.Hint := Value;
+end;
+
+procedure TJvNavPanelPage.SetIconic(const Value: Boolean);
+begin
+ NavPanel.Visible := not Value;
+ IconButton.Visible := Value;
+ NavPanel.Height := TJvCustomNavigationPane(Parent).ButtonHeight * Ord(NavPanel.Visible);
+ IconButton.Width := TJvCustomNavigationPane(Parent).ButtonWidth * Ord(IconButton.Visible);
+ UpdatePageList;
+end;
+
+procedure TJvNavPanelPage.SetIconPanel(const Value: TJvIconPanel);
+begin
+ if (FIconPanel <> Value) and not (csDestroying in ComponentState) then
+ begin
+ FIconPanel := Value;
+ if IconButton <> nil then
+ begin
+ if FIconPanel <> nil then
+ begin
+ IconButton.Parent := FIconPanel;
+ FIconPanel.FreeNotification(Self);
+ end
+ else
+ IconButton.Parent := nil;
+ end;
+ end;
+end;
+
+procedure TJvNavPanelPage.SetImageIndex(const Value: TImageIndex);
+begin
+ FImageIndex := Value;
+ NavPanel.ImageIndex := Value;
+ IconButton.ImageIndex := Value;
+ if AutoHeader then
+ Header.ImageIndex := Value;
+end;
+
+procedure TJvNavPanelPage.SetPageIndex(Value: Integer);
+begin
+ inherited SetPageIndex(Value);
+ UpdatePageList;
+end;
+
+procedure TJvNavPanelPage.SetParent( AParent: TWinControl);
+begin
+ inherited SetParent(AParent);
+ if (FNavPanel = nil) or (FIconButton = nil) or (csDestroying in ComponentState) then
+ Exit;
+ NavPanel.Parent := AParent;
+ if AParent is TJvCustomNavigationPane then
+ begin
+ IconPanel := TJvCustomNavigationPane(AParent).FIconPanel;
+ // StyleManager := TJvCustomNavigationPane(AParent).StyleManager;
+
+ NavPanel.Colors := TJvCustomNavigationPane(AParent).Colors;
+ NavPanel.StyleManager := StyleManager;
+ NavPanel.Height := TJvCustomNavigationPane(AParent).ButtonHeight;
+ NavPanel.Images := TJvCustomNavigationPane(AParent).LargeImages;
+ NavPanel.Font := TJvCustomNavigationPane(AParent).NavPanelFont;
+ NavPanel.HotTrackFont := TJvCustomNavigationPane(AParent).NavPanelHotTrackFont;
+ NavPanel.HotTrackFontOptions := TJvCustomNavigationPane(AParent).NavPanelHotTrackFontOptions;
+
+ IconButton.Images := TJvCustomNavigationPane(AParent).SmallImages;
+ IconButton.Width := TJvCustomNavigationPane(AParent).ButtonWidth;
+ AutoHeader := TJvCustomNavigationPane(AParent).AutoHeaders;
+ end
+ else
+ IconButton.Parent := nil;
+end;
+
+procedure TJvNavPanelPage.UpdatePageList;
+begin
+ if PageList <> nil then
+ TJvCustomNavigationPane(PageList).UpdatePositions;
+end;
+
+procedure TJvNavPanelPage.SetAutoHeader(const Value: Boolean);
+begin
+ if AutoHeader <> Value then
+ begin
+ FreeAndNil(FHeader);
+ if Value then
+ begin
+ FHeader := TJvNavPanelHeader.Create(nil);
+ FHeader.ColorFrom := Colors.HeaderColorFrom;
+ FHeader.ColorTo := Colors.HeaderColorTo;
+ FHeader.Images := NavPanel.Images;
+ FHeader.ImageIndex := ImageIndex;
+ //TODO: StripHotkey
+ //FHeader.Caption := StripHotkey(Caption);
+ FHeader.Caption := Caption;
+ // make sure header is top-most
+ FHeader.Top := -10;
+ FHeader.Parent := Self;
+ FHeader.Align := alTop;
+ FHeader.Alignment := Alignment;
+ FHeader.WordWrap := WordWrap;
+ end;
+ end;
+end;
+
+function TJvNavPanelPage.GetAutoHeader: Boolean;
+begin
+ Result := FHeader <> nil;
+end;
+
+function TJvNavPanelPage.GetAlignment: TAlignment;
+begin
+ if NavPanel <> nil then
+ Result := NavPanel.Alignment
+ else
+ Result := taLeftJustify;
+end;
+
+function TJvNavPanelPage.GetWordWrap: Boolean;
+begin
+ if NavPanel <> nil then
+ Result := NavPanel.WordWrap
+ else
+ Result := False;
+end;
+
+procedure TJvNavPanelPage.SetAlignment(const Value: TAlignment);
+begin
+ if NavPanel <> nil then
+ NavPanel.Alignment := Value;
+ if AutoHeader then
+ Header.Alignment := Value;
+end;
+
+procedure TJvNavPanelPage.SetWordWrap(const Value: Boolean);
+begin
+ if NavPanel <> nil then
+ NavPanel.WordWrap := Value;
+ if AutoHeader then
+ Header.WordWrap := Value;
+end;
+
+procedure TJvNavPanelPage.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ InternalStyleManagerChanged(Self, Msg.StyleManager);
+ end;
+end;
+
+procedure TJvNavPanelPage.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+procedure TJvNavPanelPage.CMControlChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvNavPanelPage.ParentStyleManagerChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvNavPanelPage.SetBackground(const Value: TJvNavPaneBackgroundImage);
+begin
+ FBackground.Assign(Value);
+end;
+
+procedure TJvNavPanelPage.DoBackgroundChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavPanelPage.Paint;
+begin
+ inherited Paint;
+ if FBackground.HasImage then
+ FBackground.DrawImage(Canvas, ClientRect)
+ else
+ if (Parent is TJvCustomNavigationPane) and TJvCustomNavigationPane(Parent).Background.HasImage then
+ TJvCustomNavigationPane(Parent).Background.DrawImage(Canvas, ClientRect);
+end;
+
+function TJvNavPanelPage.GetAction: TBasicAction;
+begin
+ Result := inherited GetAction;
+end;
+
+procedure TJvNavPanelPage.SetAction(const Value: TBasicAction);
+begin
+ inherited Action := Value;
+ FNavPanel.Action := Value;
+ FIconButton.Action := Value;
+end;
+
+procedure TJvNavPanelPage.ActionChange(Sender: TObject;
+ CheckDefaults: Boolean);
+begin
+ if Sender is TCustomAction then
+ with TCustomAction(Sender) do
+ begin
+ if not CheckDefaults or (Self.Caption = '') or (Self.Caption = Self.Name) then
+ Self.Caption := Caption;
+ if not CheckDefaults or Self.Enabled then
+ Self.Enabled := Enabled; // NB! This disables resizing if the top-most button is disabled (due to TSplitter.FindControl)
+ if not CheckDefaults or (Self.Hint = '') then
+ Self.Hint := Hint;
+ if not CheckDefaults or (Self.ImageIndex = -1) then
+ Self.ImageIndex := ImageIndex;
+ if not CheckDefaults or Self.Visible then
+ Self.Visible := Visible;
+ if not CheckDefaults or not Assigned(Self.OnClick) then
+ Self.OnClick := OnExecute;
+ end;
+end;
+
+//=== { TJvOutlookSplitter } =================================================
+
+constructor TJvOutlookSplitter.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ ControlStyle := ControlStyle + [csOpaque];
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ FColorFrom := TColor($B78676);
+ FColorTo := TColor($A03D09);
+ Align := alBottom;
+ AutoSnap := False;
+ ResizeStyle := rsUpdate;
+ Height := 7;
+ Cursor := crSizeNS;
+ FParentStyleManager := True;
+end;
+
+destructor TJvOutlookSplitter.Destroy;
+begin
+ FStyleLink.Free;
+ FStyleLink := nil;
+ inherited Destroy;
+end;
+
+procedure TJvOutlookSplitter.EnabledChanged;
+begin
+ inherited EnabledChanged;
+ Invalidate;
+end;
+
+procedure TJvOutlookSplitter.DoStyleChange(Sender: TObject);
+begin
+ with (Sender as TJvNavPaneStyleManager).Colors do
+ begin
+ FColorFrom := SplitterColorFrom;
+ FColorTo := SplitterColorTo;
+ Invalidate;
+ end;
+end;
+
+procedure TJvOutlookSplitter.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ if AComponent = StyleManager then
+ StyleManager := nil;
+end;
+
+procedure TJvOutlookSplitter.Paint;
+var
+ I: Integer;
+ R: TRect;
+begin
+ R := ClientRect;
+ if Align in [alTop, alBottom] then
+ begin
+ GradientFillRect(Canvas, R, ColorFrom, ColorTo, fdTopToBottom, R.Bottom - R.Top);
+ Inc(R.Left, (R.Right - R.Left) div 2 - 20);
+ Inc(R.Top, (R.Bottom - R.Top) div 2 - 1);
+ R.Right := R.Left + 2;
+ R.Bottom := R.Top + 2;
+ if Enabled then
+ for I := 0 to 9 do // draw the dots
+ begin
+ Canvas.Brush.Color := cl3DDkShadow;
+ Canvas.FillRect(R);
+ OffsetRect(R, 1, 1);
+ Canvas.Brush.Color := clWhite;
+ Canvas.FillRect(R);
+ Canvas.Brush.Color := ColorFrom; // (p3) this is probably not the right color, but it's close enough for me...
+ Canvas.FillRect(Rect(R.Left, R.Top, R.Left + 1, R.Top + 1));
+ OffsetRect(R, 3, -1);
+ end;
+ end
+ else
+ begin
+ GradientFillRect(Canvas, R, ColorFrom, ColorTo, fdLeftToRight, R.Right - R.Left);
+ Inc(R.Top, (R.Bottom - R.Top) div 2 - 20);
+ Inc(R.Left, (R.Right - R.Left) div 2 - 1);
+ R.Right := R.Left + 2;
+ R.Bottom := R.Top + 2;
+ if Enabled then
+ for I := 0 to 9 do // draw the dots
+ begin
+ Canvas.Brush.Color := cl3DDkShadow;
+ Canvas.FillRect(R);
+ OffsetRect(R, 1, 1);
+ Canvas.Brush.Color := clWhite;
+ Canvas.FillRect(R);
+ Canvas.Brush.Color := ColorFrom;
+ Canvas.FillRect(Rect(R.Left, R.Top, R.Left + 1, R.Top + 1));
+ OffsetRect(R, -1, 3);
+ end;
+ end;
+end;
+
+procedure TJvOutlookSplitter.SetColorFrom(const Value: TColor);
+begin
+ if FColorFrom <> Value then
+ begin
+ FColorFrom := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvOutlookSplitter.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ ColorFrom := FStyleManager.Colors.SplitterColorFrom;
+ ColorTo := FStyleManager.Colors.SplitterColorTo;
+ end;
+ end;
+end;
+
+procedure TJvOutlookSplitter.SetColorTo(const Value: TColor);
+begin
+ if FColorTo <> Value then
+ begin
+ FColorTo := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvOutlookSplitter.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ end;
+end;
+
+procedure TJvOutlookSplitter.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+function TJvOutlookSplitter.GetDragZoneRect: TRect;
+begin
+ Result := ClientRect;
+ if DragZone <> 0 then
+ begin
+ if Align in [alLeft, alRight] then
+ begin
+ if DragZone < RectHeight(Result) then
+ begin
+ Result.Top := (RectHeight(Result) - DragZone) div 2;
+ Result.Bottom := Result.Top + DragZone;
+ end;
+ end
+ else
+ if Align in [alTop, alBottom] then
+ begin
+ if DragZone < RectWidth(Result) then
+ begin
+ Result.Left := (RectWidth(Result) - DragZone) div 2;
+ Result.Right := Result.Left + DragZone;
+ end;
+ end;
+ end;
+end;
+
+function TJvOutlookSplitter.MouseInDragZone(X, Y: Integer): Boolean;
+begin
+ Result := (DragZone <= 0) or PtInRect(GetDragZoneRect, Point(X, Y));
+end;
+
+procedure TJvOutlookSplitter.WMLButtonDown(var Msg: TLMLButtonDown);
+begin
+ if MouseInDragZone(Msg.XPos, Msg.YPos) then
+ inherited;
+end;
+
+procedure TJvOutlookSplitter.WMMouseMove(var Msg: TLMMouseMove);
+begin
+ inherited;
+ if MouseInDragZone(Msg.XPos, Msg.YPos) then
+ begin
+ if Cursor <> FOldCursor then
+ inherited Cursor := FOldCursor;
+ end
+ else
+ begin
+ if Cursor <> crDefault then
+ begin
+ FOldCursor := Cursor;
+ inherited Cursor := crDefault;
+ end;
+ end;
+end;
+
+procedure TJvOutlookSplitter.SetCursor(const Value: TCursor);
+begin
+ inherited Cursor := Value;
+ FOldCursor := Value;
+end;
+
+procedure TJvOutlookSplitter.RequestAlign;
+begin
+ if (Cursor = crSizeWE) or (Cursor = crSizeNS) then
+ begin
+ if Align in [alLeft, alRight] then
+ Cursor := crSizeWE
+ else
+ Cursor := crSizeNS;
+ end;
+end;
+
+//=== { TJvNavPanelHeader } ==================================================
+
+constructor TJvNavPanelHeader.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FChangeLink := TChangeLink.Create;
+ FChangeLink.OnChange := @DoImagesChange;
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ ControlStyle := ControlStyle + [csOpaque, csAcceptsControls];
+ FColorFrom := TColor($D0835C);
+ FColorTo := TColor($903B09);
+ Font.Name := 'Arial';
+ Font.Size := 12;
+ Font.Style := [fsBold];
+ Font.Color := clWhite;
+ Height := 27;
+ Width := 225;
+ FParentStyleManager := True;
+end;
+
+destructor TJvNavPanelHeader.Destroy;
+begin
+ FChangeLink.Free;
+ FStyleLink.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavPanelHeader.DoImagesChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavPanelHeader.DoStyleChange(Sender: TObject);
+begin
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.HeaderFont;
+ with (Sender as TJvNavPaneStyleManager).Colors do
+ begin
+ FColorFrom := HeaderColorFrom;
+ FColorTo := HeaderColorTo;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ if AComponent = Images then
+ Images := nil
+ else
+ if AComponent = StyleManager then
+ StyleManager := nil;
+end;
+
+procedure TJvNavPanelHeader.Paint;
+const
+ cAlignment: array[TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER);
+ cWordWrap: array[Boolean] of Cardinal = (DT_SINGLELINE, DT_WORDBREAK);
+var
+ R, TempRect: TRect;
+ X, Y, H: Integer;
+
+ function IsValidImage: Boolean;
+ begin
+ Result := (Images <> nil) and (ImageIndex >= 0) and (ImageIndex < Images.Count);
+ end;
+
+begin
+ R := ClientRect;
+ GradientFillRect(Canvas, R, ColorFrom, ColorTo, fdTopToBottom, 32);
+ H := Canvas.TextHeight(Caption);
+ if Caption <> '' then
+ begin
+ Canvas.Font := Font;
+ InflateRect(R, -4, 0);
+ SetBkMode(Canvas.Handle, TRANSPARENT);
+ TempRect := R;
+ DrawText(Canvas, Caption, Length(Caption), TempRect,
+ DT_CALCRECT or cAlignment[Alignment] or cWordWrap[WordWrap] or DT_VCENTER or DT_NOPREFIX or DT_END_ELLIPSIS);
+ if WordWrap then
+ OffsetRect(R, 0, (Height - H) div 2);
+ if IsValidImage and (Alignment = taCenter) then
+ OffsetRect(R, 0, -Images.Height div 2);
+ DrawText(Canvas, Caption, Length(Caption), R,
+ cAlignment[Alignment] or cWordWrap[WordWrap] or DT_VCENTER or DT_NOPREFIX or DT_END_ELLIPSIS);
+ end;
+ if IsValidImage then
+ begin
+ Y := (Height - Images.Height) div 2;
+ case Alignment of
+ taLeftJustify:
+ X := R.Right - Images.Width;
+ taRightJustify:
+ X := R.Left + 4;
+ else // taCenter
+ begin
+ if Caption <> '' then
+ begin
+ if WordWrap then
+ Y := R.Top + H + 4
+ else
+ Y := (Height + Canvas.TextHeight('Wq')) div 2 + 4;
+ end;
+ X := (Width - Images.Width) div 2;
+ end;
+ end;
+ if Y > Height - Images.Height - 4 then
+ Y := Height - Images.Height - 4;
+ Images.Draw(Canvas, X, Y, ImageIndex, True);
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetColorFrom(const Value: TColor);
+begin
+ if FColorFrom <> Value then
+ begin
+ FColorFrom := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ FColorFrom := FStyleManager.Colors.HeaderColorFrom;
+ FColorTo := FStyleManager.Colors.HeaderColorTo;
+ Font := FStyleManager.Fonts.HeaderFont;
+ Invalidate;
+ end;
+ InternalStyleManagerChanged(Self, Value);
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetColorTo(const Value: TColor);
+begin
+ if FColorTo <> Value then
+ begin
+ FColorTo := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetImageIndex(const Value: TImageIndex);
+begin
+ if FImageIndex <> Value then
+ begin
+ FImageIndex := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetImages(const Value: TCustomImageList);
+begin
+ if FImages <> Value then
+ begin
+ if FImages <> nil then
+ FImages.UnregisterChanges(FChangeLink);
+ FImages := Value;
+ if FImages <> nil then
+ begin
+ FImages.RegisterChanges(FChangeLink);
+ FImages.FreeNotification(Self);
+ end;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.TextChanged;
+begin
+ inherited TextChanged;
+ Invalidate;
+end;
+
+procedure TJvNavPanelHeader.WMEraseBkgnd(var Msg: TLMEraseBkgnd);
+begin
+ Msg.Result := 1;
+end;
+
+procedure TJvNavPanelHeader.SetAlignment(const Value: TAlignment);
+begin
+ if FAlignment <> Value then
+ begin
+ FAlignment := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.SetWordWrap(const Value: Boolean);
+begin
+ if FWordWrap <> Value then
+ begin
+ FWordWrap := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelHeader.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ InternalStyleManagerChanged(Self, Msg.StyleManager);
+ end;
+end;
+
+procedure TJvNavPanelHeader.ParentStyleManagerChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvNavPanelHeader.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+procedure TJvNavPanelHeader.CMControlChange(var Msg: TLMessage);
+begin
+ // a control was inserted or removed
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+//=== { TJvNavPanelDivider } =================================================
+
+constructor TJvNavPanelDivider.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAlignment := taLeftJustify;
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ Align := alNone;
+ AutoSnap := False;
+ ResizeStyle := rsUpdate;
+ ControlStyle := ControlStyle + [csOpaque];
+ FColorFrom := TColor($FFDBBC);
+ FColorTo := TColor($F2C0A4);
+ FFrameColor := TColor($6F2F0C);
+ Cursor := crSizeNS;
+ //TODO:
+ //Font := Screen.IconFont;
+ Height := 19;
+ Width := 125;
+ FParentStyleManager := True;
+end;
+
+// 25.09.2007 - SESS
+// When align is assigned height is lost
+procedure TJvNavPanelDivider.SetAlign(Value: TAlign);
+var
+ SaveHeight: integer;
+begin
+ SaveHeight := Height;
+ inherited SetAlign(Value);
+ Height := SaveHeight;
+end;
+
+destructor TJvNavPanelDivider.Destroy;
+begin
+ FStyleLink.Free;
+ FStyleLink := nil;
+ inherited Destroy;
+end;
+
+procedure TJvNavPanelDivider.TextChanged;
+begin
+ inherited TextChanged;
+ Invalidate;
+end;
+
+procedure TJvNavPanelDivider.DoStyleChange(Sender: TObject);
+begin
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.DividerFont;
+ with (Sender as TJvNavPaneStyleManager).Colors do
+ begin
+ FColorFrom := DividerColorFrom;
+ FColorTo := DividerColorTo;
+ Self.FFrameColor := FrameColor;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelDivider.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = StyleManager then
+ StyleManager := nil;
+ end;
+end;
+
+procedure TJvNavPanelDivider.Paint;
+const
+ cAlignment: array[TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER);
+var
+ R: TRect;
+begin
+ R := ClientRect;
+ GradientFillRect(Canvas, R, ColorFrom, ColorTo, fdTopToBottom, 32);
+ if Caption <> '' then
+ begin
+ Canvas.Font := Font;
+ case Alignment of
+ taLeftJustify:
+ Inc(R.Left, 7);
+ taRightJustify:
+ Dec(R.Right, 7);
+ end;
+ SetBkMode(Canvas.Handle, TRANSPARENT);
+ DrawText(Canvas, Caption, Length(Caption), R,
+ DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX or DT_EDITCONTROL or cAlignment[Alignment]);
+ end;
+ Canvas.Pen.Color := FrameColor;
+ Canvas.MoveTo(0, ClientHeight - 1);
+ Canvas.LineTo(Width, ClientHeight - 1);
+end;
+
+procedure TJvNavPanelDivider.SetColorFrom(const Value: TColor);
+begin
+ if FColorFrom <> Value then
+ begin
+ FColorFrom := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelDivider.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ ColorFrom := FStyleManager.Colors.DividerColorFrom;
+ ColorTo := FStyleManager.Colors.DividerColorTo;
+ Font := FStyleManager.Fonts.DividerFont;
+ end;
+ end;
+end;
+
+procedure TJvNavPanelDivider.SetColorTo(const Value: TColor);
+begin
+ if FColorTo <> Value then
+ begin
+ FColorTo := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelDivider.SetFrameColor(const Value: TColor);
+begin
+ if FFrameColor <> Value then
+ begin
+ FFrameColor := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelDivider.SetAlignment(const Value: TAlignment);
+begin
+ if FAlignment <> Value then
+ begin
+ FAlignment := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelDivider.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ end;
+end;
+
+procedure TJvNavPanelDivider.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+procedure TJvNavPanelDivider.RequestAlign;
+begin
+ if (Cursor = crSizeWE) or (Cursor = crSizeNS) then
+ begin
+ if Align in [alLeft, alRight] then
+ Cursor := crSizeWE
+ else
+ Cursor := crSizeNS;
+ end;
+end;
+
+//=== { TJvNavPaneStyleManager } =============================================
+
+constructor TJvNavPaneStyleManager.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FClients := TList.Create;
+ FColors := TJvNavPanelColors.Create;
+ FFonts := TJvNavPanelFonts.Create;
+ FColors.OnChange := @DoThemeChange;
+ FFonts.OnChange := @DoThemeChange;
+ FTheme := nptCustom; // (p3) required to trigger the change method
+ Theme := nptStandard;
+end;
+
+destructor TJvNavPaneStyleManager.Destroy;
+begin
+ while FClients.Count > 0 do
+ UnregisterChanges(TJvNavStyleLink(FClients.Last));
+ FClients.Free;
+ FClients := nil;
+ FColors.Free;
+ FFonts.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavPaneStyleManager.Assign(Source: TPersistent);
+var
+ SourceColors: TJvNavPanelColors;
+ SourceFonts: TJvNavPanelFonts;
+begin
+ SourceFonts := nil;
+ if Source is TJvNavPaneStyleManager then
+ begin
+ Theme := TJvNavPaneStyleManager(Source).Theme;
+ if Theme = nptCustom then
+ begin
+ SourceColors := TJvNavPaneStyleManager(Source).Colors;
+ SourceFonts := TJvNavPaneStyleManager(Source).Fonts;
+ end
+ else
+ Exit;
+ end
+ else
+ if Source is TJvIconPanel then
+ SourceColors := TJvIconPanel(Source).Colors
+ else
+ if Source is TJvNavIconButton then
+ SourceColors := TJvNavIconButton(Source).Colors
+ else
+ if Source is TJvNavPanelButton then
+ SourceColors := TJvNavPanelButton(Source).Colors
+ else
+ if Source is TJvNavPanelPage then
+ SourceColors := TJvNavPanelPage(Source).Colors
+ else
+ if Source is TJvCustomNavigationPane then
+ SourceColors := TJvCustomNavigationPane(Source).Colors
+ else
+ begin
+ inherited Assign(Source);
+ Exit;
+ end;
+ FColors.Assign(SourceColors);
+ if SourceFonts <> nil then
+ FFonts.Assign(SourceFonts);
+end;
+
+procedure TJvNavPaneStyleManager.AssignTo(Dest: TPersistent);
+var
+ DestColors: TJvNavPanelColors;
+ DestFonts: TJvNavPanelFonts;
+begin
+ DestFonts := nil;
+ if Dest is TJvNavPaneStyleManager then
+ begin
+ TJvNavPaneStyleManager(Dest).Theme := Theme;
+ if Theme = nptCustom then
+ begin
+ DestColors := TJvNavPaneStyleManager(Dest).Colors;
+ DestFonts := TJvNavPaneStyleManager(Dest).Fonts;
+ end
+ else
+ Exit;
+ end
+ else
+ if Dest is TJvIconPanel then
+ DestColors := TJvIconPanel(Dest).Colors
+ else
+ if Dest is TJvNavIconButton then
+ DestColors := TJvNavIconButton(Dest).Colors
+ else
+ if Dest is TJvNavPanelButton then
+ DestColors := TJvNavPanelButton(Dest).Colors
+ else
+ if Dest is TJvNavPanelPage then
+ DestColors := TJvNavPanelPage(Dest).Colors
+ else
+ if Dest is TJvCustomNavigationPane then
+ DestColors := TJvCustomNavigationPane(Dest).Colors
+ else
+ begin
+ inherited AssignTo(Dest);
+ Exit;
+ end;
+ DestColors.Assign(Colors);
+ if DestFonts <> nil then
+ DestFonts.Assign(Fonts);
+end;
+
+procedure TJvNavPaneStyleManager.Change;
+var
+ I: Integer;
+begin
+ if FClients <> nil then
+ for I := 0 to FClients.Count - 1 do
+ TJvNavStyleLink(FClients[I]).Change;
+ if Assigned(FOnThemeChange) then
+ FOnThemeChange(Self);
+end;
+
+procedure TJvNavPaneStyleManager.DoThemeChange(Sender: TObject);
+begin
+ Theme := nptCustom;
+ Change;
+end;
+
+procedure TJvNavPaneStyleManager.RegisterChanges(Value: TJvNavStyleLink);
+begin
+ Value.Sender := Self;
+ if FClients <> nil then
+ FClients.Add(Value);
+end;
+
+procedure TJvNavPaneStyleManager.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvNavPaneStyleManager.SetFonts(const Value: TJvNavPanelFonts);
+begin
+ FFonts.Assign(Value);
+end;
+
+procedure TJvNavPaneStyleManager.SetTheme(const Value: TJvNavPanelTheme);
+begin
+ if FTheme <> Value then
+ begin
+ FColors.OnChange := nil;
+ FFonts.OnChange := nil;
+ try
+ case Value of
+ nptStandard:
+ begin
+ FColors.ButtonColorFrom := TColor($FFFFFF);
+ FColors.ButtonColorTo := TColor($BDBEBD);
+ FColors.ButtonSelectedColorFrom := TColor($DECFCE);
+ FColors.ButtonSelectedColorTo := TColor($DECFCE);
+ FColors.FrameColor := TColor($848484);
+ FColors.ButtonHotColorFrom := TColor($C68284);
+ FColors.ButtonHotColorTo := TColor($C68284);
+ FColors.DividerColorFrom := TColor($EFF3EF);
+ FColors.DividerColorTo := TColor($C6C3C6);
+ FColors.HeaderColorFrom := TColor($848284);
+ FColors.HeaderColorTo := TColor($848284);
+ FColors.SplitterColorFrom := TColor($C6C3C6);
+ FColors.SplitterColorTo := TColor($8C8E8C);
+ FColors.ButtonSeparatorColor := clGray;
+ FColors.ToolPanelColorFrom := clWindow;
+ FColors.ToolPanelColorTo := clWindow;
+ FColors.ToolPanelHeaderColorFrom := TColor($FFFFFF);
+ FColors.ToolPanelHeaderColorTo := TColor($BDBEBD);
+ FFonts.HeaderFont.Color := clWindow;
+ FFonts.NavPanelFont.Color := clWindowText;
+ FFonts.NavPanelHotTrackFont.Color := clWindow;
+ FFonts.DividerFont.Color := clWindowText;
+ end;
+ nptXPBlue:
+ begin
+ FColors.ButtonColorFrom := TColor($F7E2CD);
+ FColors.ButtonColorTo := TColor($F3A080);
+ FColors.ButtonSelectedColorFrom := TColor($BBE2EA);
+ FColors.ButtonSelectedColorTo := TColor($389FDD);
+ FColors.FrameColor := TColor($6F2F0C);
+ FColors.ButtonHotColorFrom := TColor($DBFBFF);
+ FColors.ButtonHotColorTo := TColor($5FC8FB);
+ FColors.DividerColorFrom := TColor($FFDBBC);
+ FColors.DividerColorTo := TColor($F2C0A4);
+ FColors.HeaderColorFrom := TColor($D0835C);
+ FColors.HeaderColorTo := TColor($903B09);
+ FColors.SplitterColorFrom := TColor($B78676);
+ FColors.SplitterColorTo := TColor($A03D09);
+ FColors.ButtonSeparatorColor := TColor($602D00); // SESS
+
+ FColors.ToolPanelColorFrom := clWindow;
+ FColors.ToolPanelColorTo := clWindow;
+ FColors.ToolPanelHeaderColorFrom := TColor($F7E2CD);
+ FColors.ToolPanelHeaderColorTo := TColor($F3A080);
+
+ FFonts.HeaderFont.Color := clWindow;
+ FFonts.NavPanelFont.Color := clWindowText;
+ FFonts.NavPanelHotTrackFont.Color := clWindowText;
+ FFonts.DividerFont.Color := clWindowText;
+ end;
+ nptXPSilver:
+ begin
+ FColors.ButtonColorFrom := TColor($F4E2E1);
+ FColors.ButtonColorTo := TColor($B09494);
+ FColors.ButtonSelectedColorFrom := TColor($BBE2EA);
+ FColors.ButtonSelectedColorTo := TColor($389FDD);
+ FColors.FrameColor := TColor($527D92);
+ FColors.ButtonHotColorFrom := TColor($DBFBFF);
+ FColors.ButtonHotColorTo := TColor($5FC8FB);
+ FColors.DividerColorFrom := TColor($F8F3F4);
+ FColors.DividerColorTo := TColor($EADADB);
+ FColors.HeaderColorFrom := TColor($BAA8BA);
+ FColors.HeaderColorTo := TColor($917275);
+ FColors.SplitterColorFrom := TColor($B8ABA9);
+ FColors.SplitterColorTo := TColor($81767E);
+ FColors.ButtonSeparatorColor := TColor($947C7C);
+ FColors.ToolPanelColorFrom := clWindow;
+ FColors.ToolPanelColorTo := clWindow;
+ FColors.ToolPanelHeaderColorFrom := TColor($F4E2E1);
+ FColors.ToolPanelHeaderColorTo := TColor($B09494);
+
+ FFonts.HeaderFont.Color := clWindow;
+ FFonts.NavPanelFont.Color := clWindowText;
+ FFonts.NavPanelHotTrackFont.Color := clWindowText;
+ FFonts.DividerFont.Color := clWindowText;
+ end;
+ nptXPOlive:
+ begin
+ FColors.ButtonColorFrom := TColor($D6F3E3);
+ FColors.ButtonColorTo := TColor($93BFB2);
+ FColors.ButtonSelectedColorFrom := TColor($BBE2EA);
+ FColors.ButtonSelectedColorTo := TColor($389FDD);
+ FColors.FrameColor := TColor($5A7972);
+ FColors.ButtonHotColorFrom := TColor($DBFBFF);
+ FColors.ButtonHotColorTo := TColor($5FC8FB);
+ FColors.DividerColorFrom := TColor($D2F4EE);
+ FColors.DividerColorTo := TColor($B5DFD8);
+ FColors.HeaderColorFrom := TColor($94BFB4);
+ FColors.HeaderColorTo := TColor($427665);
+ FColors.SplitterColorFrom := TColor($758D81);
+ FColors.SplitterColorTo := TColor($3A584D);
+ FColors.ButtonSeparatorColor := TColor($588060);
+ FColors.ToolPanelColorFrom := clWindow;
+ FColors.ToolPanelColorTo := clWindow;
+ FColors.ToolPanelHeaderColorFrom := TColor($D6F3E3);
+ FColors.ToolPanelHeaderColorTo := TColor($93BFB2);
+
+ FFonts.HeaderFont.Color := clWindow;
+ FFonts.NavPanelFont.Color := clWindowText;
+ FFonts.NavPanelHotTrackFont.Color := clWindowText;
+ FFonts.DividerFont.Color := clWindowText;
+ end;
+ nptCustom:
+ begin
+ // do nothing
+ end;
+ end;
+ FTheme := Value;
+ Change;
+ finally
+ FColors.OnChange := @DoThemeChange;
+ FFonts.OnChange := @DoThemeChange;
+ end;
+ end;
+end;
+
+procedure TJvNavPaneStyleManager.UnregisterChanges(Value: TJvNavStyleLink);
+var
+ I: Integer;
+begin
+ if FClients <> nil then
+ for I := 0 to FClients.Count - 1 do
+ if FClients[I] = Pointer(Value) then
+ begin
+ Value.Sender := nil;
+ FClients.Delete(I);
+ Break;
+ end;
+end;
+
+function TJvNavPaneStyleManager.IsColorsStored: Boolean;
+begin
+ Result := Theme = nptCustom;
+end;
+
+function TJvNavPaneStyleManager.IsFontsStored: Boolean;
+begin
+ Result := Theme = nptCustom;
+end;
+
+//=== { TJvNavStyleLink } ====================================================
+
+destructor TJvNavStyleLink.Destroy;
+begin
+ if Sender is TJvNavPaneStyleManager then
+ TJvNavPaneStyleManager(Sender).UnregisterChanges(Self);
+ inherited Destroy;
+end;
+
+procedure TJvNavStyleLink.Change;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Sender);
+end;
+
+//=== { TJvCustomNavPaneToolPanel } ==========================================
+
+constructor TJvCustomNavPaneToolPanel.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHeaderVisible := True;
+ ParentColor := False;
+ FColors := TJvNavPanelColors.Create;
+ FColors.OnChange := @DoImagesChange;
+ FBackground := TJvNavPaneBackgroundImage.Create;
+ FBackground.OnChange := @DoImagesChange;
+ ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
+ csOpaque, csDoubleClicks, csReplicatable];
+ FButtons := TJvNavPaneToolButtons.Create(Self);
+ FStyleLink := TJvNavStyleLink.Create;
+ FStyleLink.OnChange := @DoStyleChange;
+ FChangeLink := TChangeLink.Create;
+ FChangeLink.OnChange := @DoImagesChange;
+ {
+ FColorFrom := TColor($F7E2CD);
+ FColorTo := TColor($F3A080);
+ FButtonColor := TColor($A03D09);
+ }
+ FButtonWidth := 25;
+ FButtonHeight := 22;
+ FHeaderHeight := 29;
+ FEdgeRounding := 9;
+ FShowGrabber := True;
+ //TODO:
+ //Font := Screen.IconFont;
+ Font.Style := [fsBold];
+
+ FCloseButton := TJvNavPanelToolButton.Create(Self);
+ FCloseButton.ButtonType := nibClose;
+ FCloseButton.Parent := Self;
+ FCloseButton.Visible := True;
+ FCloseButton.OnClick := @DoCloseClick;
+
+ FDropDown := TJvNavPanelToolButton.Create(Self);
+ FDropDown.Visible := False;
+ FDropDown.ButtonType := nibDropArrow;
+ FDropDown.OnDropDownMenu := @DoDropDownMenu;
+ FDropDown.Parent := Self;
+
+ Width := 185;
+ Height := 41;
+ FParentStyleManager := True;
+end;
+
+destructor TJvCustomNavPaneToolPanel.Destroy;
+begin
+ FStyleLink.Free;
+ FChangeLink.Free;
+ FButtons.Free;
+ FBackground.Free;
+ FColors.Free;
+ inherited Destroy;
+end;
+
+procedure TJvCustomNavPaneToolPanel.ButtonsChanged;
+var
+ I: Integer;
+ B: TJvNavPanelToolButton;
+begin
+ if HeaderVisible then
+ for I := 0 to Buttons.Count - 1 do
+ begin
+ B := Buttons[I].Button;
+ B.Visible := False;
+ B.SetBounds(0, 0, ButtonWidth - 3, ButtonHeight - 2);
+ B.Images := Images;
+ if B.Action = nil then
+ B.OnClick := @InternalButtonClick;
+ B.Tag := I;
+ B.Parent := Self;
+ end;
+ Invalidate;
+end;
+
+procedure TJvCustomNavPaneToolPanel.DoCloseClick(Sender: TObject);
+begin
+ if Assigned(FOnClose) then
+ FOnClose(Self);
+end;
+
+procedure TJvCustomNavPaneToolPanel.DoDropDownMenu(Sender: TObject;
+ MousePos: TPoint; var Handled: Boolean);
+begin
+ if Assigned(FOnDropDownMenu) then
+ FOnDropDownMenu(Self, MousePos, Handled);
+end;
+
+procedure TJvCustomNavPaneToolPanel.DoImagesChange(Sender: TObject);
+begin
+ ButtonsChanged;
+end;
+
+procedure TJvCustomNavPaneToolPanel.DoStyleChange(Sender: TObject);
+begin
+ Font := (Sender as TJvNavPaneStyleManager).Fonts.NavPanelFont;
+ Colors := (Sender as TJvNavPaneStyleManager).Colors;
+end;
+
+procedure TJvCustomNavPaneToolPanel.FontChanged;
+begin
+ inherited FontChanged;
+ Invalidate;
+end;
+
+function TJvCustomNavPaneToolPanel.GetCloseButton: Boolean;
+begin
+ Result := FCloseButton.Visible; // and HeaderVisible;
+end;
+
+function TJvCustomNavPaneToolPanel.GetDropDownMenu: TPopupMenu;
+begin
+ if not (csDestroying in ComponentState) then
+ Result := FDropDown.DropDownMenu
+ else
+ Result := nil;
+end;
+
+function TJvCustomNavPaneToolPanel.GetHitTestInfoAt(X, Y: Integer): TJvToolPanelHitTestInfos;
+
+ function InRange(Value, Min, Max: Integer): Boolean;
+ begin
+ Result := (Value >= Min) and (Value <= Max);
+ end;
+
+begin
+ if not Visible then
+ begin
+ Result := [phtNowhere];
+ Exit;
+ end;
+ Result := [];
+ if X < 0 then
+ Include(Result, phtToLeft);
+ if X > ClientWidth then
+ Include(Result, phtToRight);
+ if Y < 0 then
+ Include(Result, phtAbove);
+ if Y > ClientHeight then
+ Include(Result, phtBelow);
+ if InRange(Y, 0, HeaderHeight - EdgeRounding) then
+ if InRange(X, 0, ClientWidth) then
+ begin
+ Include(Result, phtHeader);
+ if (X <= 16) and ShowGrabber then
+ Include(Result, phtGrabber);
+ end;
+ if InRange(X, 0, ClientWidth) and InRange(Y, HeaderHeight, ClientHeight) then
+ Include(Result, phtClient);
+end;
+
+procedure TJvCustomNavPaneToolPanel.InternalButtonClick(Sender: TObject);
+begin
+ if Assigned(FOnButtonClick) then
+ FOnButtonClick(Self, TJvNavPanelToolButton(Sender).Tag);
+end;
+
+procedure TJvCustomNavPaneToolPanel.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if Operation = opRemove then
+ begin
+ if AComponent = Images then
+ Images := nil
+ else
+ if AComponent = StyleManager then
+ StyleManager := nil
+ else
+ if AComponent = DropDownMenu then
+ DropDownMenu := nil;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.Paint;
+var
+ R, R2: TRect;
+ I, X, Y: Integer;
+ B: TJvNavPanelToolButton;
+begin
+ // first, fill the background
+ Canvas.Lock;
+ try
+ R := ClientRect;
+ if HeaderVisible then
+ Inc(R.Top, HeaderHeight);
+ GradientFillRect(Canvas, R, Colors.ToolPanelColorFrom, Colors.ToolPanelColorTo, fdTopToBottom, 255);
+ FBackground.DrawImage(Canvas, R);
+ R := ClientRect;
+ if HeaderVisible then
+ begin
+ R.Bottom := HeaderHeight - EdgeRounding;
+ R.Bottom := R.Top + HeaderHeight;
+ GradientFillRect(Canvas, R, Colors.ToolPanelHeaderColorFrom, Colors.ToolPanelHeaderColorTo, fdTopToBottom, 255);
+ // draw the drag dots
+ R2 := Rect(R.Left, R.Top + (HeaderHeight - cToolButtonHeight) div 2 + 2, R.Left + 2, R.Top + (HeaderHeight - cToolButtonHeight) div 2 + 4);
+ OffsetRect(R2, 6, 0);
+ if ShowGrabber then
+ begin
+ for I := 0 to 3 do
+ begin
+ Canvas.Brush.Color := clWhite;
+ OffsetRect(R2, 1, 1);
+ Canvas.FillRect(R2);
+ Canvas.Brush.Color := Colors.FrameColor;
+ OffsetRect(R2, -1, -1);
+ Canvas.FillRect(R2);
+ OffsetRect(R2, 0, 4);
+ end;
+ // draw the text
+ Inc(R.Left, 16);
+ end
+ else
+ Inc(R.Left, 12);
+ Canvas.Font := Self.Font;
+ if (DropDownMenu = nil) and not (csDesigning in ComponentState) then
+ begin
+ OffsetRect(R, 2, -1); // line up with where button caption should have been
+ SetBkMode(Canvas.Handle, TRANSPARENT);
+ if CloseButton then
+ R := Rect(R.Left, R.Top, FCloseButton.Left, R.Bottom);
+ DrawText(Canvas, Caption, Length(Caption), R, DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS);
+ end;
+
+ // draw the client areas top rounding, set pixels directly to avoid messing up any background image
+
+ // just a simple "arrow" in each corner in the same color as the gradient
+ // left corner
+ Y := HeaderHeight;
+ X := 0;
+ for I := 0 to 3 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Inc(X);
+ for I := 0 to 2 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Inc(X);
+ for I := 0 to 1 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Inc(X);
+ Canvas.Pixels[X, Y] := Colors.ToolPanelHeaderColorTo;
+ // Inc(X);
+ // Canvas.Pixels[X, Y] := Colors.HeaderColorTo;
+
+ // right corner
+ Y := HeaderHeight;
+ X := ClientWidth - 1;
+ for I := 0 to 4 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Dec(X);
+ for I := 0 to 2 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Dec(X);
+ for I := 0 to 1 do
+ Canvas.Pixels[X, Y + I] := Colors.ToolPanelHeaderColorTo;
+ Dec(X);
+ Canvas.Pixels[X, Y] := Colors.ToolPanelHeaderColorTo;
+ Dec(X);
+ Canvas.Pixels[X, Y] := Colors.HeaderColorTo;
+
+ // draw the button area
+ R := ClientRect;
+ Inc(R.Top, HeaderHeight);
+ Inc(R.Right);
+ Canvas.Brush.Color := Colors.FrameColor;
+ Canvas.Pen.Style := psClear;
+ if Buttons.Count > 0 then
+ begin
+ R2 := Rect(R.Left, R.Top, R.Left + ButtonWidth * Buttons.Count - 1, R.Top + ButtonHeight);
+ Canvas.RoundRect(R2.Left, R2.Top, R2.Right, R2.Bottom, EdgeRounding, EdgeRounding);
+ // square two corners
+ Canvas.FillRect(Rect(R2.Right - EdgeRounding, R2.Top, R2.Right - 1, R2.Top + EdgeRounding));
+ Canvas.FillRect(Rect(R2.Left, R2.Bottom - EdgeRounding, R2.Left + EdgeRounding, R2.Bottom - 1));
+ Canvas.Pen.Style := psSolid;
+ Y := R2.Top;
+ // adjust the buttons and draw the dividers
+ for I := 0 to Buttons.Count - 1 do
+ begin
+ X := R2.Left + ButtonWidth * I;
+ B := Buttons[I].Button;
+ B.SetBounds(X + 3, Y + 2, ButtonWidth - 6, ButtonHeight - 4);
+ B.Visible := True;
+ if I > 0 then
+ begin
+ Canvas.Pen.Color := TColor($E7EBEF);
+ Canvas.MoveTo(X, R2.Top + 2);
+ Canvas.LineTo(X, R2.Bottom - 3);
+ end;
+ if I < Buttons.Count - 1 then
+ begin
+ Canvas.Pen.Color := TColor($CED3D6);
+ Canvas.MoveTo(X + ButtonWidth - 1, R2.Top + 1);
+ Canvas.LineTo(X + ButtonWidth - 1, R2.Bottom - 4);
+ end;
+ end;
+ end;
+ end;
+ finally
+ Canvas.Unlock;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.AlignButtons;
+var
+ AOffset: Integer;
+begin
+ if HeaderVisible and ShowGrabber then
+ AOffset := cToolButtonOffset
+ else
+ AOffset := 4;
+ if (Parent <> nil) and (HeaderHeight > cToolButtonHeight) then
+ begin
+ FCloseButton.SetBounds(ClientWidth - cToolButtonWidth - 2, (HeaderHeight - cToolButtonHeight) div 2, cToolButtonWidth, cToolButtonHeight);
+ if FCloseButton.Visible or (csDesigning in ComponentState) then
+ FDropDown.SetBounds(AOffset, (HeaderHeight - cToolButtonHeight) div 2, ClientWidth - cToolButtonWidth - AOffset - 2, cToolButtonHeight)
+ else
+ FDropDown.SetBounds(AOffset, (HeaderHeight - cToolButtonHeight) div 2, ClientWidth - AOffset - 4, cToolButtonHeight);
+ end
+ else
+ begin
+ FCloseButton.SetBounds(0, 0, 0, 0);
+ FDropDown.SetBounds(0, 0, 0, 0);
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
+begin
+ inherited SetBounds(ALeft, ATop, AWidth, AHeight);
+ AlignButtons;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetButtonHeight(const Value: Integer);
+begin
+ if FButtonHeight <> Value then
+ begin
+ FButtonHeight := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetButtons(const Value: TJvNavPaneToolButtons);
+begin
+ FButtons.Assign(Value);
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetButtonWidth(const Value: Integer);
+begin
+ if FButtonWidth <> Value then
+ begin
+ FButtonWidth := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetCloseButton(const Value: Boolean);
+begin
+ if FCloseButton.Visible <> Value then
+ begin
+ FCloseButton.Visible := Value;
+ SetBounds(Left, Top, Width, Height);
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetDropDownMenu(const Value: TPopupMenu);
+begin
+ if FDropDown.DropDownMenu <> Value then
+ begin
+ FDropDown.DropDownMenu := Value;
+ FDropDown.Visible := (Value <> nil); // and HeaderVisible;
+ SetBounds(Left, Top, Width, Height);
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetEdgeRounding(const Value: Integer);
+begin
+ if FEdgeRounding <> Value then
+ begin
+ FEdgeRounding := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetHeaderHeight(const Value: Integer);
+begin
+ if FHeaderHeight <> Value then
+ begin
+ FHeaderHeight := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetImages(const Value: TCustomImageList);
+var
+ I: Integer;
+begin
+ if FImages <> Value then
+ begin
+ if FImages <> nil then
+ FImages.UnregisterChanges(FChangeLink);
+ FImages := Value;
+ if FImages <> nil then
+ begin
+ FImages.RegisterChanges(FChangeLink);
+ FImages.FreeNotification(Self);
+ end;
+ for I := 0 to Buttons.Count - 1 do
+ Buttons[I].Button.Images := FImages;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetShowGrabber(const Value: Boolean);
+begin
+ if FShowGrabber <> Value then
+ begin
+ FShowGrabber := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetStyleManager(const Value: TJvNavPaneStyleManager);
+begin
+ if FStyleManager <> Value then
+ begin
+ ParentStyleManager := False;
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterChanges(FStyleLink);
+ FStyleManager := Value;
+ if FStyleManager <> nil then
+ begin
+ FStyleManager.RegisterChanges(FStyleLink);
+ FStyleManager.FreeNotification(Self);
+ Colors := FStyleManager.Colors;
+ Invalidate;
+ end;
+ InternalStyleManagerChanged(Self, StyleManager);
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.ParentStyleManagerChanged(var Msg: TMsgStyleManagerChange);
+begin
+ if (Msg.Sender <> Self) and ParentStyleManager then
+ begin
+ StyleManager := Msg.StyleManager;
+ ParentStyleManager := True;
+ InternalStyleManagerChanged(Self, Msg.StyleManager);
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.TextChanged;
+begin
+ inherited TextChanged;
+ FDropDown.Caption := Caption;
+ Invalidate;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetParentStyleManager(const Value: Boolean);
+begin
+ if FParentStyleManager <> Value then
+ begin
+ FParentStyleManager := Value;
+ if FParentStyleManager and (Parent <> nil) then
+ Parent.Perform(CM_PARENTSTYLEMANAGERCHANGE, 0, 0);
+ end;
+end;
+
+
+procedure TJvCustomNavPaneToolPanel.CMControlChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+procedure TJvCustomNavPaneToolPanel.WMEraseBkgnd(var Msg: TLMEraseBkgnd);
+begin
+ Msg.Result := 1;
+end;
+
+procedure TJvCustomNavPaneToolPanel.WMNCPaint(var Msg: TWMNCPaint);
+var
+ AColor: TColor;
+begin
+ AColor := Color;
+ Color := Colors.FrameColor;
+ inherited;
+ Color := AColor;
+end;
+
+procedure TJvCustomNavPaneToolPanel.ParentStyleManagerChange(var Msg: TLMessage);
+begin
+ InternalStyleManagerChanged(Self, StyleManager);
+end;
+
+function TJvCustomNavPaneToolPanel.GetDrawPartialMenuFrame: Boolean;
+begin
+ if FDropDown <> nil then
+ Result := FDropDown.DrawPartialMenuFrame
+ else
+ Result := False;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetDrawPartialMenuFrame(const Value: Boolean);
+begin
+ if FDropDown <> nil then
+ FDropDown.DrawPartialMenuFrame := Value;
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetBackground(const Value: TJvNavPaneBackgroundImage);
+begin
+ FBackground.Assign(Value);
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetColors(const Value: TJvNavPanelColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvCustomNavPaneToolPanel.SetHeaderVisible(const Value: Boolean);
+begin
+ if FHeaderVisible <> Value then
+ begin
+ FHeaderVisible := Value;
+ FCloseButton.Visible := CloseButton;
+ FDropDown.Visible := (FDropDown.DropDownMenu <> nil); // and Value;
+ ButtonsChanged;
+ end;
+end;
+
+function TJvCustomNavPaneToolPanel.IsColorsStored: Boolean;
+begin
+ Result := (StyleManager = nil) or (StyleManager.Theme = nptCustom);
+end;
+
+//=== { TJvNavPaneToolButton } ===============================================
+
+procedure TJvNavPaneToolButton.Assign(Source: TPersistent);
+begin
+ if Source is TJvNavPaneToolButton then
+ begin
+// if Source <> Self then
+ begin
+ Action := TJvNavPaneToolButton(Source).Action;
+ Hint := TJvNavPaneToolButton(Source).Hint;
+ ImageIndex := TJvNavPaneToolButton(Source).ImageIndex;
+ Enabled := TJvNavPaneToolButton(Source).Enabled
+ end;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+constructor TJvNavPaneToolButton.Create(ACollection: Classes.TCollection);
+begin
+ FRealButton := TJvNavPanelToolButton.Create(nil);
+ FRealButton.ButtonType := nibImage;
+ FRealButton.ImageIndex := -1;
+ inherited Create(ACollection);
+end;
+
+destructor TJvNavPaneToolButton.Destroy;
+begin
+ FRealButton.Free;
+ inherited Destroy;
+end;
+
+function TJvNavPaneToolButton.GetAction: TBasicAction;
+begin
+ Result := FRealButton.Action;
+end;
+
+function TJvNavPaneToolButton.GetEnabled: Boolean;
+begin
+ Result := FRealButton.Enabled;
+end;
+
+function TJvNavPaneToolButton.GetHint: string;
+begin
+ Result := FRealButton.Hint;
+end;
+
+function TJvNavPaneToolButton.GetImageIndex: TImageIndex;
+begin
+ Result := FRealButton.ImageIndex;
+end;
+
+procedure TJvNavPaneToolButton.SetAction(const Value: TBasicAction);
+begin
+ FRealButton.Action := Value;
+ FRealButton.ActionChange(Value, False);
+end;
+
+procedure TJvNavPaneToolButton.SetEnabled(const Value: Boolean);
+begin
+ FRealButton.Enabled := Value;
+end;
+
+procedure TJvNavPaneToolButton.SetHint(const Value: string);
+begin
+ FRealButton.Hint := Value;
+end;
+
+procedure TJvNavPaneToolButton.SetImageIndex(const Value: TImageIndex);
+begin
+ FRealButton.ImageIndex := Value;
+end;
+
+//=== { TJvNavPaneToolButtons } ==============================================
+
+constructor TJvNavPaneToolButtons.Create(AOwner: TJvCustomNavPaneToolPanel);
+begin
+ inherited Create(AOwner, TJvNavPaneToolButton);
+ FPanel := AOwner;
+end;
+
+function TJvNavPaneToolButtons.Add: TJvNavPaneToolButton;
+begin
+ Result := TJvNavPaneToolButton(inherited Add);
+end;
+
+function TJvNavPaneToolButtons.GetItem(Index: Integer): TJvNavPaneToolButton;
+begin
+ Result := TJvNavPaneToolButton(inherited Items[Index]);
+end;
+
+procedure TJvNavPaneToolButtons.SetItem(Index: Integer;
+ const Value: TJvNavPaneToolButton);
+begin
+ inherited Items[Index] := Value;
+end;
+
+procedure TJvNavPaneToolButtons.Update(Item: TCollectionItem);
+begin
+ inherited Update(Item);
+ if FPanel <> nil then
+ FPanel.ButtonsChanged;
+end;
+
+//=== { TJvNavPanelToolButton } ==============================================
+
+constructor TJvNavPanelToolButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FChangeLink := TChangeLink.Create;
+ FChangeLink.OnChange := @DoImagesChange;
+ DrawPartialMenuFrame := False;
+ TransparentDown := False;
+ HotTrack := True;
+end;
+
+destructor TJvNavPanelToolButton.Destroy;
+begin
+ FChangeLink.Free;
+ inherited Destroy;
+end;
+
+procedure TJvNavPanelToolButton.ActionChange(Sender: TObject; CheckDefaults: Boolean);
+begin
+ if Sender is TCustomAction then
+ with TCustomAction(Sender) do
+ begin
+ if not CheckDefaults or Self.Enabled then
+ Self.Enabled := Enabled;
+ if not CheckDefaults or (Self.Hint = '') then
+ Self.Hint := Hint;
+ if not CheckDefaults or (Self.ImageIndex = -1) then
+ Self.ImageIndex := ImageIndex;
+ if not CheckDefaults or Self.Visible then
+ Self.Visible := Visible;
+ if not CheckDefaults or not Assigned(Self.OnClick) then
+ Self.OnClick := OnExecute;
+ end;
+end;
+
+procedure TJvNavPanelToolButton.DoImagesChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvNavPanelToolButton.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if (Operation = opRemove) and (AComponent = Images) then
+ Images := nil;
+end;
+
+procedure TJvNavPanelToolButton.Paint;
+label
+ DrawButton;
+var
+ R: TRect;
+ I: Integer;
+begin
+ // inherited Paint;
+ if MouseStates <> [] then
+ begin
+ Canvas.Pen.Color := TColor($6B2408);
+ if bsMouseInside in MouseStates then
+ Canvas.Brush.Color := TColor($D6BEB5);
+ if (bsMouseDown in MouseStates) or Down then
+ begin
+ if TransparentDown then
+ Canvas.Brush.Style := bsClear; // (p3) don't draw background - looks better IMO
+ if (ButtonType = nibDropArrow) and (DropDownMenu <> nil) then
+ begin
+ Canvas.Brush.Color := clWindow;
+ Canvas.Pen.Color := cl3DDkShadow;
+ if DrawPartialMenuFrame then
+ begin
+ Canvas.FillRect(ClientRect); // if Brush.Style = bsClear, this does nothing
+ Canvas.MoveTo(0, Height);
+ Canvas.LineTo(0, 0);
+ Canvas.LineTo(Width - 1, 0);
+ Canvas.LineTo(Width - 1, Height);
+ // (p3) yucky! first goto in JVCL?!!!
+ goto DrawButton;
+ end;
+ end
+ else
+ Canvas.Brush.Color := TColor($B59284);
+ end;
+ Canvas.Rectangle(ClientRect);
+ end;
+DrawButton:
+ case ButtonType of
+ nibDropArrow: // dropdown arrow is 7x4, right-aligned
+ begin
+ R := ClientRect;
+ if Caption <> '' then
+ begin
+ InflateRect(R, -2, -2);
+ Canvas.Font := Font;
+ SetBkMode(Canvas.Handle, TRANSPARENT);
+ InflateRect(R, -2, 0);
+ Dec(R.Right, 3 + 7);
+ DrawText(Canvas, Caption, Length(Caption), R, DT_LEFT or DT_VCENTER or DT_NOPREFIX or DT_END_ELLIPSIS);
+ Inc(R.Right, 3 + 7);
+ InflateRect(R, 2, 0);
+ end;
+ R.Left := R.Right - 11;
+ Dec(R.Right, 4);
+ R.Top := (RectHeight(ClientRect) - 4) div 2;
+ Canvas.Pen.Color := clWindowText;
+ for I := 0 to 3 do
+ begin
+ Canvas.MoveTo(R.Left, R.Top);
+ Canvas.LineTo(R.Right, R.Top);
+ Dec(R.Right);
+ Inc(R.Left);
+ Inc(R.Top);
+ end;
+ end;
+ nibClose:
+ begin
+ // close button is 8x8, centered
+ if bsMouseDown in MouseStates then
+ Canvas.Pen.Color := clHighlightText
+ else
+ Canvas.Pen.Color := clWindowText;
+ R := ClientRect;
+ InflateRect(R, -(RectWidth(R) div 2 - 4), -(RectHeight(R) div 2 - 4));
+ if Odd(Height) or Odd(Width) then
+ begin
+ Inc(R.Right);
+ Inc(R.Bottom);
+ end;
+ // (p3) this isn't exactly the same as MS's but good enough for me :)
+ for I := 0 to 7 do
+ begin
+ Canvas.MoveTo(R.Left + I, R.Top + I);
+ Canvas.LineTo(R.Left + I + 2, R.Top + I);
+ end;
+ for I := 0 to 7 do
+ begin
+ Canvas.MoveTo(R.Right - I, R.Top + I);
+ Canvas.LineTo(R.Right - I - 2, R.Top + I);
+ end;
+ end;
+ nibImage:
+ if Assigned(Images) then
+ Images.Draw(Canvas,
+ (Width - Images.Width) div 2, (Height - Images.Height) div 2,
+ ImageIndex, Enabled);
+ else
+ //TODO:
+ //raise EJVCLException.CreateRes(@RsEUnsupportedButtonType);
+ raise Exception.Create('RsEUnsupportedButtonType');
+ end;
+end;
+
+procedure TJvNavPanelToolButton.SetButtonType(const Value: TJvNavIconButtonType);
+begin
+ if FButtonType <> Value then
+ begin
+ FButtonType := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelToolButton.SetImageIndex(const Value: TImageIndex);
+begin
+ if FImageIndex <> Value then
+ begin
+ FImageIndex := Value;
+ Invalidate;
+ end;
+end;
+
+procedure TJvNavPanelToolButton.SetImages(const Value: TCustomImageList);
+begin
+ if FImages <> Value then
+ begin
+ if FImages <> nil then
+ FImages.UnregisterChanges(FChangeLink);
+ FImages := Value;
+ if FImages <> nil then
+ begin
+ FImages.RegisterChanges(FChangeLink);
+ FImages.FreeNotification(Self);
+ end;
+ Invalidate;
+ end;
+end;
+
+//=== { TJvNavPaneBackgroundImage } ==========================================
+
+constructor TJvNavPaneBackgroundImage.Create;
+begin
+ inherited Create;
+ FPicture := TPicture.Create;
+ FPicture.OnChange := @PictureChanged;
+end;
+
+destructor TJvNavPaneBackgroundImage.Destroy;
+begin
+ FPicture.Free;
+ inherited Destroy;
+end;
+
+function TJvNavPaneBackgroundImage.CalcRect(ADestRect: TRect): TRect;
+var
+ W, H, CW, CH: Integer;
+ XYAspect: Double;
+begin
+ W := Picture.Width;
+ H := Picture.Height;
+ CW := ADestRect.Right - ADestRect.Left;
+ CH := ADestRect.Bottom - ADestRect.Top;
+ if Stretch or (Proportional and ((W > CW) or (H > CH))) then
+ begin
+ if Proportional and (W > 0) and (H > 0) then
+ begin
+ XYAspect := W / H;
+ if W > H then
+ begin
+ W := CW;
+ H := Trunc(CW / XYAspect);
+ if H > CH then // woops, too big
+ begin
+ H := CH;
+ W := Trunc(CH * XYAspect);
+ end;
+ end
+ else
+ begin
+ H := CH;
+ W := Trunc(CH * XYAspect);
+ if W > CW then // woops, too big
+ begin
+ W := CW;
+ H := Trunc(CW / XYAspect);
+ end;
+ end;
+ end
+ else
+ begin
+ W := CW;
+ H := CH;
+ end;
+ end;
+
+ with Result do
+ begin
+ Left := ADestRect.Left;
+ Top := ADestRect.Top;
+ Right := ADestRect.Left + W;
+ Bottom := ADestRect.Top + H;
+ end;
+
+ if Center then
+ OffsetRect(Result, (CW - W) div 2, (CH - H) div 2);
+end;
+
+procedure TJvNavPaneBackgroundImage.Change;
+begin
+ FDrawing := True;
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+ FDrawing := False;
+end;
+
+procedure TJvNavPaneBackgroundImage.DrawImage(Canvas: TCanvas; ARect: TRect);
+
+ procedure TileImage;
+ var
+ X, Y: Integer;
+ G: TGraphic;
+ begin
+ G := Picture.Graphic;
+ X := ARect.Left;
+ Y := ARect.Top;
+ while Y < ARect.Bottom do
+ begin
+ Canvas.Draw(X, Y, G); // this doesn't clip on the right or bottom sides of ARect :(
+ Inc(X, G.Width);
+ if X > ARect.Right then
+ begin
+ X := ARect.Left;
+ Inc(Y, G.Height);
+ end;
+ end;
+ end;
+
+begin
+ if (Picture.Graphic = nil) or (Picture.Width = 0) or (Picture.Height = 0) then
+ Exit;
+ if Tile then
+ TileImage
+ else
+ with Canvas do
+ StretchDraw(CalcRect(ARect), Picture.Graphic);
+end;
+
+function TJvNavPaneBackgroundImage.HasImage: Boolean;
+begin
+ with Picture do
+ Result := (Graphic <> nil) and (Width <> 0) and (Height <> 0);
+end;
+
+procedure TJvNavPaneBackgroundImage.PictureChanged(Sender: TObject);
+var
+ G: TGraphic;
+begin
+ G := Picture.Graphic;
+ //TODO:
+ (*
+ if G <> nil then
+ if not ( (G is TMetaFile) or (G is TIcon)) then
+ G.Transparent := FTransparent;
+ *)
+ if not FDrawing then
+ Change;
+end;
+
+procedure TJvNavPaneBackgroundImage.SetCenter(const Value: Boolean);
+begin
+ if FCenter <> Value then
+ begin
+ FCenter := Value;
+ PictureChanged(Self);
+ end;
+end;
+
+procedure TJvNavPaneBackgroundImage.SetPicture(const Value: TPicture);
+begin
+ FPicture.Assign(Value);
+end;
+
+procedure TJvNavPaneBackgroundImage.SetProportional(const Value: Boolean);
+begin
+ if FProportional <> Value then
+ begin
+ FProportional := Value;
+ PictureChanged(Self);
+ end;
+end;
+
+procedure TJvNavPaneBackgroundImage.SetStretch(const Value: Boolean);
+begin
+ if FStretch <> Value then
+ begin
+ FStretch := Value;
+ PictureChanged(Self);
+ end;
+end;
+
+procedure TJvNavPaneBackgroundImage.SetTile(const Value: Boolean);
+begin
+ if FTile <> Value then
+ begin
+ FTile := Value;
+ PictureChanged(Self);
+ end;
+end;
+
+procedure TJvNavPaneBackgroundImage.SetTransparent(const Value: Boolean);
+begin
+ if FTransparent <> Value then
+ begin
+ FTransparent := Value;
+ PictureChanged(Self)
+ end;
+end;
+
+procedure TJvCustomNavPaneToolPanel.AdjustClientRect(var Rect: TRect);
+begin
+ if HeaderVisible then
+ begin
+ Rect.Top := Rect.Top + HeaderHeight + EdgeRounding;
+ if Buttons.Count > 0 then
+ Rect.Top := Rect.Top + ButtonHeight - EdgeRounding;
+ end;
+ InflateRect(Rect, -2, -2);
+ inherited AdjustClientRect(Rect);
+end;
+
+{initialization
+ RegisterClasses([TJvNavPanelPage]);} // ahuser: moved to TJvCustomNavigationPane.Create
+
+end.
+
diff --git a/components/jvcllaz/run/JvPageList.pas b/components/jvcllaz/run/JvPageList.pas
new file mode 100644
index 000000000..1e35228fb
--- /dev/null
+++ b/components/jvcllaz/run/JvPageList.pas
@@ -0,0 +1,943 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvPageList.PAS, released on 2003-04-25.
+
+The Initial Developer of the Original Code is Peter Thörnqvist [peter3 at sourceforge dot net] .
+Portions created by Peter Thörnqvist are Copyright (C) 2004 Peter Thörnqvist.
+All Rights Reserved.
+
+Contributor(s):
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+
+-----------------------------------------------------------------------------}
+// $Id: JvPageList.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvPageList;
+
+interface
+
+uses
+ Classes, Controls, Graphics, JvComponent, LCLIntf, LCLType, LMessages,
+ SysUtils;
+
+type
+ EPageListError = class(Exception);
+
+(******************** NOT CONVERTED
+ IPageList = interface
+ ['{6BB90183-CFB1-4431-9CFD-E9A032E0C94C}']
+ function CanChange(AIndex: Integer): Boolean;
+ procedure SetActivePageIndex(AIndex: Integer);
+ function GetPageCount: Integer;
+ function GetPageCaption(AIndex: Integer): string;
+ procedure AddPage(const ACaption: string);
+ procedure DeletePage(Index: Integer);
+ procedure MovePage(CurIndex, NewIndex: Integer);
+ procedure PageCaptionChanged(Index: Integer; const NewCaption: string);
+ end;
+******************** NOT CONVERTED *)
+
+ TJvCustomPageList = class;
+
+ TJvPagePaintEvent = procedure(Sender: TObject; ACanvas: TCanvas; ARect: TRect) of object;
+ TJvPageCanPaintEvent = procedure(Sender: TObject; ACanvas: TCanvas; ARect: TRect; var DefaultDraw: Boolean) of object;
+
+ { TJvCustomPage is the base class for pages in a TJvPageList and implements the basic behaviour of such
+ a control. It has support for accepting components, propagating it's Enabled state, changing it's order in the
+ page list and custom painting }
+
+ TJvCustomPage = class(TJvCustomControl)
+ private
+ FPageList: TJvCustomPageList;
+ FPageIndex: Integer;
+ FOnBeforePaint: TJvPageCanPaintEvent;
+ FOnPaint: TJvPagePaintEvent;
+ FOnAfterPaint: TJvPagePaintEvent;
+ FOnHide: TNotifyEvent;
+ FOnShow: TNotifyEvent;
+ FData: TObject;
+ protected
+ procedure CreateParams(var Params: TCreateParams); override;
+ function DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean; override;
+ procedure SetPageIndex(Value: Integer);virtual;
+ function GetPageIndex: Integer;virtual;
+ procedure SetPageList(Value: TJvCustomPageList);virtual;
+ procedure TextChanged; override;
+ procedure ShowingChanged; override;
+ procedure Paint; override;
+ procedure ReadState(Reader: TReader); override;
+ function DoBeforePaint(ACanvas: TCanvas; ARect: TRect): Boolean; dynamic;
+ procedure DoAfterPaint(ACanvas: TCanvas; ARect: TRect); dynamic;
+ procedure DoPaint(ACanvas: TCanvas; ARect: TRect); virtual;
+ procedure DoShow; virtual;
+ procedure DoHide; virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ property PageList: TJvCustomPageList read FPageList write SetPageList;
+ protected
+ property Left stored False;
+ property Top stored False;
+ property Width stored False;
+ property Height stored False;
+ property OnHide: TNotifyEvent read FOnHide write FOnHide;
+ property OnShow: TNotifyEvent read FOnShow write FOnShow;
+ property OnBeforePaint: TJvPageCanPaintEvent read FOnBeforePaint write FOnBeforePaint;
+ property OnPaint: TJvPagePaintEvent read FOnPaint write FOnPaint;
+ property OnAfterPaint: TJvPagePaintEvent read FOnAfterPaint write FOnAfterPaint;
+ public
+ property Data: TObject read FData write FData;
+ property PageIndex: Integer read GetPageIndex write SetPageIndex stored False;
+ end;
+
+ TJvCustomPageClass = class of TJvCustomPage;
+ TJvPageChangingEvent = procedure(Sender: TObject; PageIndex: Integer; var AllowChange: Boolean) of object;
+
+ {
+ TJvCustomPageList is a base class for components that implements the IPageList interface.
+ It works like TPageControl but does not have any tabs
+ }
+ TJvShowDesignCaption = (sdcNone, sdcTopLeft, sdcTopCenter, sdcTopRight, sdcLeftCenter, sdcCenter, sdcRightCenter, sdcBottomLeft, sdcBottomCenter, sdcBottomRight, sdcRunTime);
+
+ //TODO: 25.09.2007 - SESS - Find a better place...
+ TCMDesignHitTest = TLMMouse;
+
+ // TJvCustomPageList = class(TJvCustomControl, IUnknown, IPageList)
+ TJvCustomPageList = class(TJvCustomControl)
+ private
+ FPages: TList;
+ FActivePage: TJvCustomPage;
+ FPropagateEnable: Boolean;
+ FOnChange: TNotifyEvent;
+ FOnChanging: TJvPageChangingEvent;
+ FShowDesignCaption: TJvShowDesignCaption;
+ FHiddenPages: TList;
+ procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST;
+ procedure UpdateEnabled;
+ procedure SetPropagateEnable(const Value: Boolean);
+ procedure SetShowDesignCaption(const Value: TJvShowDesignCaption);
+ function GetPage(Index: Integer): TJvCustomPage;
+ protected
+ procedure EnabledChanged; override;
+ { IPageList }
+ procedure AddPage(const ACaption: string);
+ procedure DeletePage(Index: Integer);
+ procedure MovePage(CurIndex, NewIndex: Integer);
+ function CanChange(AIndex: Integer): Boolean; virtual;
+ function GetActivePageIndex: Integer; virtual;
+ procedure SetActivePageIndex(AIndex: Integer); virtual;
+ function GetPageFromIndex(AIndex: Integer): TJvCustomPage; virtual;
+ function GetPageCount: Integer;virtual;
+ function GetPageCaption(AIndex: Integer): string; virtual;
+ procedure Paint; override;
+ procedure PageCaptionChanged(Index: Integer; const NewCaption: string); virtual;
+ procedure Change; dynamic;
+ procedure Loaded; override;
+ procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
+ procedure ShowControl(AControl: TControl); override;
+ function InternalGetPageClass: TJvCustomPageClass; virtual;
+ procedure SetActivePage(Page: TJvCustomPage); virtual;
+ procedure InsertPage(APage: TJvCustomPage); virtual;
+ procedure RemovePage(APage: TJvCustomPage); virtual;
+ property PageList: TList read FPages;
+ property HiddenPageList: TList read FHiddenPages;
+ property PropagateEnable: Boolean read FPropagateEnable write SetPropagateEnable;
+ property ShowDesignCaption: TJvShowDesignCaption read FShowDesignCaption write SetShowDesignCaption default sdcCenter;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property OnChanging: TJvPageChangingEvent read FOnChanging write FOnChanging;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function FindNextPage(CurPage: TJvCustomPage; GoForward: Boolean; IncludeDisabled: Boolean): TJvCustomPage;
+ procedure PrevPage;
+ procedure NextPage;
+ function HidePage(Page: TJvCustomPage): TJvCustomPage; virtual;
+ function ShowPage(Page: TJvCustomPage; PageIndex: Integer = -1): TJvCustomPage; virtual;
+ function GetPageClass: TJvCustomPageClass;
+ function GetVisiblePageCount: Integer;
+ property Height default 200;
+ property Width default 300;
+ property ActivePageIndex: Integer read GetActivePageIndex write SetActivePageIndex;
+ property ActivePage: TJvCustomPage read FActivePage write SetActivePage;
+ property Pages[Index: Integer]: TJvCustomPage read GetPage; default;
+ property PageCount: Integer read GetPageCount;
+ end;
+
+(******************** NOT CONVERTED
+ TJvStandardPage = class(TJvCustomPage)
+ published
+ property BorderWidth;
+ property Caption;
+ property Color;
+ property DragMode;
+ property Enabled;
+ property Font;
+ property Constraints;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property PageIndex;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnHide;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnResize;
+ property OnShow;
+ property OnStartDrag;
+ property OnBeforePaint;
+ property OnPaint;
+ property OnAfterPaint;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnParentColorChange;
+ {$IFDEF JVCLThemesEnabled}
+ property ParentBackground default False;
+ {$ENDIF JVCLThemesEnabled}
+ end;
+
+ TJvPageList = class(TJvCustomPageList)
+ protected
+ function InternalGetPageClass: TJvCustomPageClass; override;
+ public
+ property PageCount;
+ published
+ property ActivePage;
+ property PropagateEnable;
+ property ShowDesignCaption;
+ property Action;
+ property Align;
+ property Anchors;
+ property BiDiMode;
+ property BorderWidth;
+ property DragCursor;
+ property DragKind;
+ property OnStartDock;
+ property OnUnDock;
+ property OnEndDock;
+ property OnCanResize;
+ property OnDockDrop;
+ property OnDockOver;
+ property OnGetSiteInfo;
+ property Constraints;
+ property DragMode;
+ property Enabled;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnParentColorChange;
+ property OnChange;
+ property OnChanging;
+ property OnConstrainedResize;
+ property OnContextPopup;
+ property OnDblClick;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnMouseDown;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnMouseWheel;
+ property OnMouseWheelDown;
+ property OnMouseWheelUp;
+ property OnResize;
+ property OnStartDrag;
+ {$IFDEF JVCLThemesEnabled}
+ property ParentBackground default False;
+ {$ENDIF JVCLThemesEnabled}
+ end;
+******************** NOT CONVERTED *)
+
+implementation
+
+uses
+ Forms;
+
+function GetUniqueName(AOwner: TComponent; const AClassName: string): string;
+var
+ i: Integer;
+begin
+ i := 0;
+ if AOwner = nil then
+ begin
+ repeat
+ Inc(i);
+ Result := AClassName + IntToStr(i);
+ until FindGlobalComponent(Result) = nil;
+ end
+ else
+ repeat
+ Inc(i);
+ Result := AClassName + IntToStr(i);
+ until AOwner.FindComponent(Result) = nil;
+end;
+
+//=== { TJvCustomPage } ======================================================
+
+constructor TJvCustomPage.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FPageIndex := -1;
+ Align := alClient;
+ ControlStyle := ControlStyle + [csOpaque, csAcceptsControls, csNoDesignVisible];
+// IncludeThemeStyle(Self, [csParentBackground]);
+ Visible := False;
+ DoubleBuffered := True;
+end;
+
+procedure TJvCustomPage.CreateParams(var Params: TCreateParams);
+begin
+ inherited CreateParams(Params);
+ with Params.WindowClass do
+ Style := Style and not (CS_HREDRAW or CS_VREDRAW);
+end;
+
+destructor TJvCustomPage.Destroy;
+begin
+ PageList := nil;
+ inherited Destroy;
+end;
+
+procedure TJvCustomPage.DoAfterPaint(ACanvas: TCanvas; ARect: TRect);
+begin
+ if Assigned(FOnAfterPaint) then
+ FOnAfterPaint(Self, ACanvas, ARect);
+end;
+
+function TJvCustomPage.DoBeforePaint(ACanvas: TCanvas; ARect: TRect): Boolean;
+begin
+ Result := True;
+ if Assigned(FOnBeforePaint) then
+ FOnBeforePaint(Self, ACanvas, ARect, Result);
+end;
+
+function GetDesignCaptionFlags(Value: TJvShowDesignCaption): Cardinal;
+begin
+ case Value of
+ sdcTopLeft:
+ Result := DT_TOP or DT_LEFT;
+ sdcTopCenter:
+ Result := DT_TOP or DT_CENTER;
+ sdcTopRight:
+ Result := DT_TOP or DT_RIGHT;
+ sdcLeftCenter:
+ Result := DT_VCENTER or DT_LEFT;
+ sdcCenter:
+ Result := DT_VCENTER or DT_CENTER;
+ sdcRightCenter:
+ Result := DT_VCENTER or DT_RIGHT;
+ sdcBottomLeft:
+ Result := DT_BOTTOM or DT_LEFT;
+ sdcBottomCenter:
+ Result := DT_BOTTOM or DT_CENTER;
+ sdcBottomRight:
+ Result := DT_BOTTOM or DT_RIGHT;
+ else
+ Result := 0;
+ end;
+end;
+
+procedure TJvCustomPage.DoPaint(ACanvas: TCanvas; ARect: TRect);
+var
+ S: string;
+begin
+ with ACanvas do
+ begin
+ Font := Self.Font;
+ Brush.Style := bsSolid;
+ Brush.Color := Self.Color;
+ //SESS
+ //DrawThemedBackground(Self, Canvas, ARect);
+ DoEraseBackground(Canvas, 0);
+ if (csDesigning in ComponentState) then
+ begin
+ Pen.Style := psDot;
+ Pen.Color := clBlack;
+ Brush.Style := bsClear;
+ Rectangle(ARect);
+ Brush.Style := bsSolid;
+ Brush.Color := Color;
+ if (PageList <> nil) and (PageList.ShowDesignCaption <> sdcNone) then
+ begin
+ S := Caption;
+ if S = '' then
+ S := Name;
+ // make some space around the edges
+ InflateRect(ARect, -4, -4);
+ if not Enabled then
+ begin
+ SetBkMode(Handle, TRANSPARENT);
+ Canvas.Font.Color := clHighlightText;
+ //TODO: Use JCLUtils one?
+ DrawText(Handle, PChar(S), Length(S), ARect, GetDesignCaptionFlags(PageList.ShowDesignCaption) or DT_SINGLELINE);
+ OffsetRect(ARect, -1, -1);
+ Canvas.Font.Color := clGrayText;
+ end;
+ DrawText(Handle, PChar(S), Length(S), ARect, GetDesignCaptionFlags(PageList.ShowDesignCaption) or DT_SINGLELINE);
+ InflateRect(ARect, 4, 4);
+ end;
+ end;
+ end;
+ if Assigned(FOnPaint) then
+ FOnPaint(Self, ACanvas, ARect);
+end;
+
+function TJvCustomPage.GetPageIndex: Integer;
+begin
+ if Assigned(FPageList) then
+ Result := FPageList.PageList.IndexOf(Self)
+ else
+ Result := FPageIndex;
+end;
+
+procedure TJvCustomPage.Paint;
+var
+ R: TRect;
+begin
+ R := ClientRect;
+ if DoBeforePaint(Canvas, R) then
+ DoPaint(Canvas, R);
+ DoAfterPaint(Canvas, R);
+end;
+
+procedure TJvCustomPage.ReadState(Reader: TReader);
+begin
+ if Reader.Parent is TJvCustomPageList then
+ PageList := TJvCustomPageList(Reader.Parent);
+ inherited ReadState(Reader);
+end;
+
+procedure TJvCustomPage.SetPageList(Value: TJvCustomPageList);
+begin
+ if FPageList <> Value then
+ begin
+ if Assigned(FPageList) then
+ FPageList.RemovePage(Self);
+ FPageList := Value;
+ Parent := FPageList;
+ if FPageList <> nil then
+ FPageList.InsertPage(Self);
+ end;
+end;
+
+procedure TJvCustomPage.SetPageIndex(Value: Integer);
+var
+ OldIndex: Integer;
+begin
+ if (Value <> PageIndex) then
+ begin
+ OldIndex := PageIndex;
+ if Assigned(FPageList) and (Value >= 0) and (Value < FPageList.PageCount) then
+ FPageList.PageList.Move(OldIndex, Value);
+ FPageIndex := Value;
+ end;
+end;
+
+function TJvCustomPage.DoEraseBackground(ACanvas: TCanvas; Param: Integer): Boolean;
+begin
+ ACanvas.Brush.Color := Self.Color;
+ ACanvas.Brush.Style := bsSolid;
+ ACanvas.FillRect(Rect(0, 0, Width, Height));
+ Result := True;
+end;
+
+procedure TJvCustomPage.TextChanged;
+begin
+ inherited TextChanged;
+ if csDesigning in ComponentState then
+ Invalidate;
+end;
+
+procedure TJvCustomPage.DoHide;
+begin
+ if Assigned(FOnHide) then
+ FOnHide(Self);
+end;
+
+procedure TJvCustomPage.DoShow;
+begin
+ if Assigned(FOnShow) then
+ FOnShow(Self);
+end;
+
+procedure TJvCustomPage.ShowingChanged;
+begin
+ inherited ShowingChanged;
+ if Showing then
+ try
+ DoShow
+ except
+ Application.HandleException(Self);
+ end
+ else
+ if not Showing then
+ try
+ DoHide;
+ except
+ Application.HandleException(Self);
+ end;
+end;
+
+//=== { TJvCustomPageList } ==================================================
+
+constructor TJvCustomPageList.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ ControlStyle := ControlStyle + [csAcceptsControls];
+// IncludeThemeStyle(Self, [csParentBackground]);
+ FPages := TList.Create;
+ FHiddenPages := TList.Create;
+ Height := 200;
+ Width := 300;
+ FShowDesignCaption := sdcCenter;
+ ActivePageIndex := -1;
+end;
+
+destructor TJvCustomPageList.Destroy;
+var
+ I: Integer;
+begin
+ for I := FPages.Count - 1 downto 0 do
+ TJvCustomPage(FPages[I]).FPageList := nil;
+ FPages.Free;
+ FHiddenPages.Free;
+ inherited Destroy;
+end;
+
+function TJvCustomPageList.CanChange(AIndex: Integer): Boolean;
+begin
+ Result := (AIndex >= 0) and (AIndex < GetPageCount);
+ if Result and Assigned(FOnChanging) then
+ FOnChanging(Self, AIndex, Result);
+end;
+
+procedure TJvCustomPageList.Change;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvCustomPageList.CMDesignHitTest(var Msg: TCMDesignHitTest);
+var
+ Pt: TPoint;
+begin
+ inherited;
+ Pt := SmallPointToPoint(Msg.Pos);
+ if Assigned(ActivePage) and PtInRect(ActivePage.BoundsRect, Pt) then
+ Msg.Result := 1;
+end;
+
+procedure TJvCustomPageList.GetChildren(Proc: TGetChildProc;
+ Root: TComponent);
+var
+ I: Integer;
+ Control: TControl;
+begin
+ for I := 0 to FPages.Count - 1 do
+ Proc(TComponent(FPages[I]));
+ for I := 0 to ControlCount - 1 do
+ begin
+ Control := Controls[I];
+ if not (Control is TJvCustomPage) and (Control.Owner = Root) then
+ Proc(Control);
+ end;
+end;
+
+function TJvCustomPageList.GetPageCaption(AIndex: Integer): string;
+begin
+ if (AIndex >= 0) and (AIndex < GetPageCount) then
+ Result := TJvCustomPage(FPages[AIndex]).Caption
+ else
+ Result := '';
+end;
+
+function TJvCustomPageList.InternalGetPageClass: TJvCustomPageClass;
+begin
+ Result := TJvCustomPage;
+end;
+
+function TJvCustomPageList.GetPageCount: Integer;
+begin
+ if FPages = nil then
+ Result := 0
+ else
+ Result := FPages.Count;
+end;
+
+procedure TJvCustomPageList.InsertPage(APage: TJvCustomPage);
+begin
+ if (APage <> nil) and (FPages.IndexOf(APage) = -1) then
+ FPages.Add(APage);
+end;
+
+procedure TJvCustomPageList.Loaded;
+begin
+ inherited Loaded;
+ if (GetPageCount > 0) and (ActivePage = nil) then
+ ActivePage := Pages[0];
+end;
+
+procedure TJvCustomPageList.Paint;
+begin
+ if (csDesigning in ComponentState) and (GetPageCount = 0) then
+ with Canvas do
+ begin
+ Pen.Color := clBlack;
+ Pen.Style := psDot;
+ Brush.Style := bsClear;
+ Rectangle(ClientRect);
+ end;
+end;
+
+procedure TJvCustomPageList.RemovePage(APage: TJvCustomPage);
+var
+ I: Integer;
+ WNextPage: TJvCustomPage;
+begin
+ WNextPage := FindNextPage(APage, True, not (csDesigning in ComponentState));
+ if WNextPage = APage then
+ WNextPage := nil;
+ APage.Visible := False;
+ APage.FPageList := nil;
+ FPages.Remove(APage);
+ SetActivePage(WNextPage);
+ // (ahuser) In some cases SetActivePage does not change FActivePage
+ // so we force FActivePage not to be "APage"
+ if (FActivePage = APage) or (FActivePage = nil) then
+ begin
+ FActivePage := nil;
+ for I := 0 to PageCount - 1 do
+ if Pages[I] <> APage then
+ begin
+ FActivePage := Pages[I];
+ Break;
+ end;
+ end;
+end;
+
+function TJvCustomPageList.GetPageFromIndex(AIndex: Integer): TJvCustomPage;
+begin
+ if (AIndex >= 0) and (AIndex < GetPageCount) then
+ Result := TJvCustomPage(Pages[AIndex])
+ else
+ Result := nil;
+end;
+
+function TJvCustomPageList.GetVisiblePageCount: Integer;
+var
+ i: Integer;
+begin
+ Result := 0;
+ for i := 0 to PageCount - 1 do
+ if Pages[i].Visible then
+ Inc(Result);
+end;
+
+procedure TJvCustomPageList.SetActivePageIndex(AIndex: Integer);
+begin
+ if (AIndex > -1) and (AIndex < PageCount) then
+ ActivePage := Pages[AIndex]
+ else
+ ActivePage := nil;
+end;
+
+procedure TJvCustomPageList.ShowControl(AControl: TControl);
+begin
+ if AControl is TJvCustomPage then
+ ActivePage := TJvCustomPage(AControl);
+ inherited ShowControl(AControl);
+end;
+
+function TJvCustomPageList.GetPageClass: TJvCustomPageClass;
+begin
+ Result := InternalGetPageClass;
+end;
+
+function TJvCustomPageList.HidePage(Page: TJvCustomPage): TJvCustomPage;
+var
+ I: Integer;
+begin
+ if (Page <> nil) and (Page.PageList = Self) then
+ begin
+ if ActivePage = Page then
+ NextPage;
+ if ActivePage = Page then
+ ActivePage := nil;
+ I := Page.PageIndex;
+ Page.PageList := nil;
+ Page.PageIndex := I;
+ Result := Page;
+ FHiddenPages.Add(Result);
+ end
+ else
+ Result := nil;
+end;
+
+function TJvCustomPageList.ShowPage(Page: TJvCustomPage; PageIndex: Integer): TJvCustomPage;
+var
+ I: Integer;
+begin
+ if (Page <> nil) and (Page.PageList = nil) then
+ begin
+ I := Page.PageIndex;
+ Page.PageList := Self;
+ Page.Parent := Self;
+ if PageIndex > -1 then
+ Page.PageIndex := PageIndex
+ else
+ if I > -1 then
+ Page.PageIndex := I;
+ Result := Page;
+ FHiddenPages.Remove(Result);
+ end
+ else
+ Result := nil;
+end;
+
+procedure TJvCustomPageList.SetActivePage(Page: TJvCustomPage);
+var
+ ParentForm: TCustomForm;
+ //TODO: why?
+ //{$IFDEF COMPILER9_UP}
+ I: Integer;
+ //{$ENDIF COMPILER9_UP}
+begin
+ // Mantis 3227: Checking if the page can be changed has to be done at the
+ // beginning or the page would change but not the index...
+ if not (csLoading in ComponentState) and not CanChange(FPages.IndexOf(Page)) then
+ Exit;
+
+ if GetPageCount = 0 then
+ FActivePage := nil;
+ if (Page = nil) or (Page.PageList <> Self) then
+ Exit
+ else
+ begin
+ ParentForm := GetParentForm(Self);
+ if (ParentForm <> nil) and (FActivePage <> nil) and
+ FActivePage.ContainsControl(ParentForm.ActiveControl) then
+ begin
+ ParentForm.ActiveControl := FActivePage;
+ if ParentForm.ActiveControl <> FActivePage then
+ begin
+ ActivePage := GetPageFromIndex(FActivePage.PageIndex);
+ Exit;
+ end;
+ end;
+
+ //TODO: why?
+ //{$IFDEF COMPILER9_UP}
+ for I := 0 to GetPageCount - 1 do
+ if Pages[i] <> Page then
+ Pages[i].Hide;
+ //{$ELSE}
+ //Page.BringToFront;
+ //{$ENDIF COMPILER9_UP}
+ Page.Visible := True;
+ if (ParentForm <> nil) and (FActivePage <> nil) and (ParentForm.ActiveControl = FActivePage) then
+ begin
+ if Page.CanFocus then
+ ParentForm.ActiveControl := Page
+ else
+ ParentForm.ActiveControl := Self;
+ end;
+ Page.Refresh;
+
+ if (FActivePage <> nil) and (FActivePage <> Page) then
+ FActivePage.Visible := False;
+ if (FActivePage <> Page) then
+ begin
+ FActivePage := Page;
+ if not (csLoading in ComponentState) then
+ Change;
+ end;
+ if (ParentForm <> nil) and (FActivePage <> nil) and
+ (ParentForm.ActiveControl = FActivePage) then
+ begin
+ FActivePage.SelectFirst;
+ end;
+ end;
+end;
+
+function TJvCustomPageList.GetActivePageIndex: Integer;
+begin
+ if ActivePage <> nil then
+ Result := ActivePage.PageIndex
+ else
+ Result := -1;
+end;
+
+procedure TJvCustomPageList.NextPage;
+begin
+ if (ActivePageIndex < PageCount - 1) and (PageCount > 1) then
+ ActivePageIndex := ActivePageIndex + 1
+ else
+ if PageCount > 0 then
+ ActivePageIndex := 0
+ else
+ ActivePageIndex := -1;
+end;
+
+procedure TJvCustomPageList.PrevPage;
+begin
+ if ActivePageIndex > 0 then
+ ActivePageIndex := ActivePageIndex - 1
+ else
+ ActivePageIndex := PageCount - 1;
+end;
+
+procedure TJvCustomPageList.SetPropagateEnable(const Value: Boolean);
+begin
+ if FPropagateEnable <> Value then
+ begin
+ FPropagateEnable := Value;
+ UpdateEnabled;
+ end;
+end;
+
+procedure TJvCustomPageList.EnabledChanged;
+begin
+ inherited EnabledChanged;
+ UpdateEnabled;
+end;
+
+function TJvCustomPageList.FindNextPage(CurPage: TJvCustomPage;
+ GoForward, IncludeDisabled: Boolean): TJvCustomPage;
+var
+ I, StartIndex: Integer;
+begin
+ if PageCount <> 0 then
+ begin
+ StartIndex := FPages.IndexOf(CurPage);
+ if StartIndex < 0 then
+ if GoForward then
+ StartIndex := FPages.Count - 1
+ else
+ StartIndex := 0;
+ I := StartIndex;
+ repeat
+ if GoForward then
+ begin
+ Inc(I);
+ if I >= FPages.Count - 1 then
+ I := 0;
+ end
+ else
+ begin
+ if I <= 0 then
+ I := FPages.Count - 1;
+ Dec(I);
+ end;
+ Result := Pages[I];
+ if IncludeDisabled or Result.Enabled then
+ Exit;
+ until I = StartIndex;
+ end;
+ Result := nil;
+end;
+
+procedure TJvCustomPageList.SetShowDesignCaption(const Value: TJvShowDesignCaption);
+begin
+ if FShowDesignCaption <> Value then
+ begin
+ FShowDesignCaption := Value;
+ //TODO:
+ (*
+ if HandleAllocated and (csDesigning in ComponentState) then
+ RedrawWindow(Handle, nil, 0, RDW_UPDATENOW or RDW_INVALIDATE or RDW_ALLCHILDREN);
+ *)
+ end;
+end;
+
+procedure TJvCustomPageList.UpdateEnabled;
+
+ procedure InternalSetEnabled(AControl: TWinControl);
+ var
+ I: Integer;
+ begin
+ for I := 0 to AControl.ControlCount - 1 do
+ begin
+ AControl.Controls[I].Enabled := Self.Enabled;
+ if AControl.Controls[I] is TWinControl then
+ InternalSetEnabled(TWinControl(AControl.Controls[I]));
+ end;
+ end;
+
+begin
+ if PropagateEnable then
+ InternalSetEnabled(Self);
+end;
+
+function TJvCustomPageList.GetPage(Index: Integer): TJvCustomPage;
+begin
+ if (Index >= 0) and (Index < FPages.Count) then
+ Result := TJvCustomPage(FPages[Index])
+ else
+ Result := nil;
+end;
+procedure TJvCustomPageList.DeletePage(Index: Integer);
+begin
+ if (Index >= 0) and (Index < PageCount) then
+ Pages[Index].Free;
+end;
+
+procedure TJvCustomPageList.AddPage(const ACaption: string);
+var
+ Page: TJvCustomPage;
+begin
+ Page := GetPageClass.Create(Owner);
+ Page.Caption := ACaption;
+ Page.Name := GetUniqueName(Owner, Copy(Page.ClassName, 2, MaxInt));
+ Page.PageList := Self;
+end;
+
+procedure TJvCustomPageList.MovePage(CurIndex, NewIndex: Integer);
+begin
+ FPages.Move(CurIndex, NewIndex);
+end;
+
+procedure TJvCustomPageList.PageCaptionChanged(Index: Integer;
+ const NewCaption: string);
+begin
+ if (Index >= 0) and (Index < PageCount) then
+ Pages[Index].Caption := NewCaption;
+end;
+
+(**************
+//===TJvPageList =============================================================
+
+function TJvPageList.InternalGetPageClass: TJvCustomPageClass;
+begin
+ Result := TJvStandardPage;
+end;
+*******************)
+
+end.
diff --git a/components/jvcllaz/run/JvTypes.pas b/components/jvcllaz/run/JvTypes.pas
new file mode 100644
index 000000000..a665f0ec3
--- /dev/null
+++ b/components/jvcllaz/run/JvTypes.pas
@@ -0,0 +1,739 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvTypes.PAS, released on 2001-02-28.
+
+The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
+Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
+All Rights Reserved.
+
+Contributor(s): Michael Beck [mbeck att bigfoot dott com].
+ Peter Thornqvist
+ Oliver Giesen
+ Gustavo Bianconi
+ dejoy
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvTypes.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Initial port to Lazarus by Sergio Samayoa - september 2007.
+// Conversion is done in incremental way: as types / classes / routines
+// are needed they are converted.
+
+{$mode objfpc}{$H+}
+
+unit JvTypes;
+
+interface
+
+uses
+ Classes, Controls, Forms, Graphics, LMessages, SysUtils;
+
+const
+ MaxPixelCount = 32767;
+
+(********************
+type
+ TJvBytes = Pointer;
+ IntPtr = Pointer;
+********************)
+
+type
+ PCaptionChar = PChar;
+
+ // used in JvSpeedButton, JvArrowButton, JvButton CM_JVBUTTONPRESSED
+ // asn: can also be used with CM_BUTTONPRESSED
+ TCMButtonPressed = packed record
+ Msg: Cardinal;
+ Index: Integer; { clx has Index and Control switched }
+ Control: TControl;
+ Result: Longint;
+ end;
+
+(********************
+ THintString = string;
+ THintStringList = TStringList;
+
+ { JvExVCL classes }
+ TInputKey = (ikAll, ikArrows, ikChars, ikButton, ikTabs, ikEdit, ikNative{, ikNav, ikEsc});
+ TInputKeys = set of TInputKey;
+
+ {$IFDEF CLR}
+ [StructLayout(LayoutKind.Sequential)]
+ {$ENDIF CLR}
+ TJvRGBTriple = packed record
+ rgbBlue: Byte;
+ rgbGreen: Byte;
+ rgbRed: Byte;
+ end;
+
+const
+ NullHandle = 0;
+ // (rom) deleted fbs constants. They are already in JvConsts.pas.
+
+
+type
+ TTimerProc = procedure(hwnd: THandle; Msg: Cardinal; idEvent: Cardinal; dwTime: Cardinal);
+
+type
+ {$IFDEF COMPILER5}
+ EOSError = class(EWin32Error);
+ IInterface = IUnknown;
+ {$M+}
+ IInvokable = interface(IInterface)
+ end;
+ {$M-}
+ {$ENDIF COMPILER5}
+ {$IFDEF CLR}
+ IUnknown = IInterface;
+ {$ENDIF CLR}
+
+ // Base class for persistent properties that can show events.
+ // By default, Delphi and BCB don't show the events of a class
+ // derived from TPersistent unless it also derives from
+ // TComponent. However, up until version 5, you couldn't have
+ // a Component as a Sub Component of another one, thus preventing
+ // from having events for a sub property.
+ // The design time editor associated with TJvPersistent will display
+ // the events, thus mimicking a Sub Component.
+ {$IFDEF COMPILER6_UP}
+ TJvPersistent = class(TComponent)
+ public
+ constructor Create(AOwner: TComponent); override;
+ end;
+ {$ELSE}
+ TJvPersistent = class(TPersistent);
+ {$ENDIF COMPILER6_UP}
+
+ // Added by dejoy (2005-04-20)
+ // A lot of TJVxxx control persistent properties used TPersistent,
+ // So and a TJvPersistentProperty to do this job. make to support batch-update mode
+ // and property change notify.
+ TJvPropertyChangeEvent = procedure(Sender: TObject; const PropName: string) of object;
+
+ TJvPersistentProperty = class(TPersistent)//?? TJvPersistent
+ private
+ FUpdateCount: Integer;
+ FOnChanging: TNotifyEvent;
+ FOnChange: TNotifyEvent;
+ FOnChangingProperty: TJvPropertyChangeEvent;
+ FOnChangeProperty: TJvPropertyChangeEvent;
+ protected
+ procedure Changed; virtual;
+ procedure Changing; virtual;
+ procedure ChangedProperty(const PropName: string); virtual;
+ procedure ChangingProperty(const PropName: string); virtual;
+ procedure SetUpdateState(Updating: Boolean); virtual;
+ property UpdateCount: Integer read FUpdateCount;
+ public
+ procedure BeginUpdate; virtual;
+ procedure EndUpdate; virtual;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
+ property OnChangeProperty: TJvPropertyChangeEvent read FOnChangeProperty write FOnChangeProperty;
+ property OnChangingProperty: TJvPropertyChangeEvent read FOnChangingProperty write FOnChangingProperty;
+ end;
+
+ TJvRegKey = (hkClassesRoot, hkCurrentUser, hkLocalMachine, hkUsers,
+ hkPerformanceData, hkCurrentConfig, hkDynData);
+ TJvRegKeys = set of TJvRegKey;
+
+ // base JVCL Exception class to derive from
+ EJVCLException = class(Exception);
+
+ TJvLinkClickEvent = procedure(Sender: TObject; Link: string) of object;
+ // TOnRegistryChangeKey = procedure(Sender: TObject; RootKey: HKEY; Path: string) of object;
+ // TAngle = 0..360;
+ TJvOutputMode = (omFile, omStream);
+ // TLabelDirection = (sdLeftToRight, sdRightToLeft); // JvScrollingLabel
+
+ TJvDoneFileEvent = procedure(Sender: TObject; FileName: string; FileSize: Integer; Url: string) of object;
+ TJvDoneStreamEvent = procedure(Sender: TObject; Stream: TStream; StreamSize: Integer; Url: string) of object;
+ TJvHTTPProgressEvent = procedure(Sender: TObject; UserData, Position: Integer; TotalSize: Integer; Url: string; var Continue: Boolean) of object;
+ TJvFTPProgressEvent = procedure(Sender: TObject; Position: Integer; Url: string) of object;
+
+ // from JvComponent.pas
+ TJvClipboardCommand = (caCopy, caCut, caPaste, caClear, caUndo);
+ TJvClipboardCommands = set of TJvClipboardCommand;
+********************)
+
+ // used in JvButton
+ TCMForceSize = record
+ Msg: Cardinal;
+ NewSize: TSmallPoint;
+ Sender: TControl;
+ Result: Longint;
+ end;
+
+(********************
+ PJvRGBArray = ^TJvRGBArray;
+ TJvRGBArray = array [0..MaxPixelCount] of TJvRGBTriple;
+ PRGBQuadArray = ^TRGBQuadArray;
+ TRGBQuadArray = array [0..MaxPixelCount] of TRGBQuad;
+ PRGBPalette = ^TRGBPalette;
+ TRGBPalette = array [Byte] of TRGBQuad;
+
+ { (rom) unused
+ TJvPoint = class(TPersistent)
+ protected
+ FX: Integer;
+ FY: Integer;
+ published
+ property X: Integer read FX write FX;
+ property Y: Integer read FY write FY;
+ end;
+ }
+
+ TJvErrorEvent = procedure(Sender: TObject; ErrorMsg: string) of object;
+ TJvWaveLocation = (frFile, frResource, frRAM);
+
+ TJvPopupPosition = (ppNone, ppForm, ppApplication);
+ // TJvDirMask = (dmFileNameChange, dmDirnameChange, dmAttributesChange, dmSizeChange, dmLastWriteChange, dmSecurityChange); //JvDirectorySpy
+ // TJvDirMasks = set of TJvDirMask;
+ // EJvDirectoryError = class(EJVCLException); // JvDirectorySpy
+ // TListEvent = procedure(Sender: TObject; Title: string; Handle: THandle) of object; // JvWindowsTitle
+
+ TJvProgressEvent = procedure(Sender: TObject; Current, Total: Integer) of object;
+ TJvNextPageEvent = procedure(Sender: TObject; PageNumber: Integer) of object;
+ TJvBitmapStyle = (bsNormal, bsCentered, bsStretched);
+
+ // TOnOpened = procedure(Sender: TObject; Value: string) of object; // archive
+ // TOnOpenCanceled = procedure(Sender: TObject) of object; // archive
+
+ {$IFDEF COMPILER5}
+
+ { TStream seek origins }
+// TSeekOrigin = (soFromBeginning, soFromCurrent, soFromEnd);
+// (outchy)
+// TStream.Seek can not be used with TSeekOrigin
+// soFromBeginning, soFromCurrent and soFromEnd are defined in Classes.pas
+
+ TWMNCPaint = packed record
+ Msg: Cardinal;
+ RGN: HRGN;
+ Unused: Longint;
+ Result: Longint;
+ end;
+
+// (outchy) defined in Windows.pas
+// PInteger = ^Integer;
+// PDouble = ^Double;
+ PBoolean = ^Boolean;
+ PWordBool = ^WordBool;
+ PCardinal = ^Cardinal;
+// PByte = ^Byte;
+
+ TVarType = Word;
+
+ {$ENDIF COMPILER5}
+
+ TJvGradientStyle = (grFilled, grEllipse, grHorizontal, grVertical, grPyramid, grMount);
+ // TOnDelete = procedure(Sender: TObject; Path: string) of object;
+ TJvParentEvent = procedure(Sender: TObject; ParentWindow: THandle) of object;
+ // TOnImage = procedure(Sender: TObject; Image: TBitmap) of object; // JvClipboardViewer
+ // TOnText = procedure(Sender: TObject; Text: string) of object;
+ // TJvRestart = (rsLogoff, rsShutdown, rsReboot, rsRestart, rsRebootSystem, rsExitAndExecApp);
+ // TJvRunOption = (roNoBrowse, roNoDefault, roCalcDirectory, roNoLabel, roNoSeparateMem); // JvRunDlg
+ // TJvRunOptions = set of TJvRunOption; // JvRunDlg
+ // TJvFileKind = (ftFile, ftPrinter); // JvObjectPropertiesDlg
+
+ // TSHFormatDrive = function(Handle: THandle; Drive, ID, Options: Word): LongInt; stdcall; // JvFormatDrive
+ // TFormatOption = (shQuickFormat, shFull, shSystemFilesOnly); // JvFormatDrive
+ // TButtonStyle = (bsAbortRetryIgnore, bsOk, bsOkCancel, bsRetryCancel, bsYesNo, bsYesNoCancel); // JvMessageBox
+ // TButtonDisplay = (bdIconExclamation, bdIconWarning, bdIconInformation, bdIconAsterisk, bdIconQuestion, bdIconStop, bdIconError, bdIconHand); // JvMessageBox
+
+ // TDefault = (dbButton1, dbButton2, dbButton3, dbButton4); // JvMessageBox
+ // TModality = (bmApplModal, bmSystemModal, bmTaskModal); // JvMessageBox
+ // TButtonOption = (boDefaultDesktopOnly, boHelp, boRight, boRtlReading, boSetForeground, boTopMost); // JvMessageBox
+ // TButtonOptions = set of TButtonOption; // JvMessageBox
+ // TButtonResult = (brAbort, brCancel, brIgnore, brNo, brOk, brRetry, brYes); // JvMessageBox
+ // TMsgStyle = (msBeep, msIconAsterisk, msIconExclamation, msIconHand, msIconQuestion, msOk); // JvMessageBeep
+ TJvDiskRes = (dsSuccess, dsCancel, dsSkipfile, dsError);
+ TJvDiskStyle = (idfCheckFirst, idfNoBeep, idfNoBrowse, idfNoCompressed, idfNoDetails,
+ idfNoForeground, idfNoSkip, idfOemDisk, idfWarnIfSkip);
+ TJvDiskStyles = set of TJvDiskStyle;
+ TJvDeleteStyle = (idNoBeep, idNoForeground);
+ TJvDeleteStyles = set of TJvDeleteStyle;
+ // TOnOk = procedure(Sender: TObject; Password: string; var Accept: Boolean) of object; // JvPasswordForm
+
+ // TCoordChanged = procedure(Sender: TObject; Coord: string) of object;
+ TJvNotifyParamsEvent = procedure(Sender: TObject; Params: Pointer) of object;
+
+ TJvFileInfoRec = record
+ Attributes: DWORD;
+ DisplayName: string;
+ ExeType: Integer;
+ Icon: HICON;
+ Location: string;
+ TypeName: string;
+ SysIconIndex: Integer;
+ end;
+
+ TJvAnimation = (anLeftRight, anRightLeft, anRightAndLeft, anLeftVumeter, anRightVumeter);
+ TJvAnimations = set of TJvAnimation;
+ // TOnFound = procedure(Sender: TObject; Path: string) of object; // JvSearchFile
+ // TOnChangedDir = procedure(Sender: TObject; Directory: string) of object; // JvSearchFile
+ // TOnAlarm = procedure(Sender: TObject; Keyword: string) of object; // JvAlarm
+ { TAlarm = record
+ Keyword: string;
+ DateTime: TDateTime;
+ end;
+ } // JvAlarm
+
+ // Bianconi - Moved from JvAlarms.pas
+ TJvTriggerKind =
+ (tkOneShot, tkEachSecond, tkEachMinute, tkEachHour, tkEachDay, tkEachMonth, tkEachYear);
+ // End of Bianconi
+
+ TJvFourCC = array [0..3] of Char;
+ PJvAniTag = ^TJvAniTag;
+ TJvAniTag = packed record
+ ckID: TJvFourCC;
+ ckSize: Longint;
+ end;
+
+ TJvAniHeader = packed record
+ dwSizeof: Longint;
+ dwFrames: Longint;
+ dwSteps: Longint;
+ dwCX: Longint;
+ dwCY: Longint;
+ dwBitCount: Longint;
+ dwPlanes: Longint;
+ dwJIFRate: Longint;
+ dwFlags: Longint;
+ end;
+
+ TJvChangeColorEvent = procedure(Sender: TObject; Foreground, Background: TColor) of object;
+
+ TJvLayout = (lTop, lCenter, lBottom);
+ TJvBevelStyle = (bsShape, bsLowered, bsRaised);
+
+ {for OnLoseFocus the AFocusControl argument will point at the control that
+ receives focus while for OnGetFocus it is the control that lost the focus}
+ TJvFocusChangeEvent = procedure(const ASender: TObject;
+ const AFocusControl: TWinControl) of object;
+
+ // JvJCLUtils
+ TTickCount = Cardinal;
+
+ {**** string handling routines}
+ TSetOfChar = TSysCharSet;
+ TCharSet = TSysCharSet;
+
+ TDateOrder = (doMDY, doDMY, doYMD);
+ TDayOfWeekName = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
+ TDaysOfWeek = set of TDayOfWeekName;
+
+const
+ DefaultDateOrder = doDMY;
+
+ CenturyOffset: Byte = 60;
+ NullDate: TDateTime = 0; {-693594}
+
+type
+ // JvDriveCtrls / JvLookOut
+ TJvImageSize = (isSmall, isLarge);
+ TJvImageAlign = (iaLeft, iaCentered);
+
+ TJvDriveType = (dtUnknown, dtRemovable, dtFixed, dtRemote, dtCDROM, dtRamDisk);
+ TJvDriveTypes = set of TJvDriveType;
+********************)
+
+type
+ // Defines how a property (like a HotTrackFont) follows changes in the component's normal Font
+ TJvTrackFontOption = (
+ hoFollowFont, // makes HotTrackFont follow changes to the normal Font
+ hoPreserveCharSet, // don't change HotTrackFont.Charset
+ hoPreserveColor, // don't change HotTrackFont.Color
+ hoPreserveHeight, // don't change HotTrackFont.Height (affects Size as well)
+ hoPreserveName, // don't change HotTrackFont.Name
+ hoPreservePitch, // don't change HotTrackFont.Pitch
+ hoPreserveStyle); // don't change HotTrackFont.Style
+ TJvTrackFontOptions = set of TJvTrackFontOption;
+
+const
+ DefaultTrackFontOptions = [hoFollowFont, hoPreserveColor, hoPreserveStyle];
+
+(********************
+type
+ // from JvListView.pas
+ TJvSortMethod = (smAutomatic, smAlphabetic, smNonCaseSensitive, smNumeric, smDate, smTime, smDateTime, smCurrency);
+ TJvListViewColumnSortEvent = procedure(Sender: TObject; Column: Integer; var AMethod: TJvSortMethod) of object;
+
+ // from JvOfficeColorPanel.pas
+ TJvAddInControlSiteInfo = record
+ AddInControl: TControl;
+ BoundsRect: TRect;
+ SiteInfoData: TObject;
+ end;
+
+ TJvClickColorType =
+ (cctColors, cctNoneColor, cctDefaultColor, cctCustomColor, cctAddInControl, cctNone);
+ TJvHoldCustomColorEvent = procedure(Sender: TObject; AColor: TColor) of object;
+ TJvColorQuadLayOut = (cqlNone, cqlLeft, cqlRight, cqlClient);
+ TJvGetAddInControlSiteInfoEvent = procedure(Sender: TControl; var ASiteInfo: TJvAddInControlSiteInfo) of object;
+
+ // from JvColorProvider.pas
+ TColorType = (ctStandard, ctSystem, ctCustom);
+
+ TDefColorItem = record
+ Value: TColor;
+ Constant: string;
+ Description: string;
+ end;
+
+const
+ ColCount = 20;
+ StandardColCount = 40;
+ SysColCount = 30;
+ {$IFDEF COMPILER5}
+ clSystemColor = TColor($80000000);
+ clHotLight = TColor(clSystemColor or COLOR_HOTLIGHT);
+ clGradientActiveCaption = TColor(clSystemColor or COLOR_GRADIENTACTIVECAPTION);
+ clGradientInactiveCaption = TColor(clSystemColor or COLOR_GRADIENTINACTIVECAPTION);
+ clMenuHighlight = TColor(clSystemColor or COLOR_MENUHILIGHT);
+ clMenuBar = TColor(clSystemColor or COLOR_MENUBAR);
+ {$ENDIF COMPILER5}
+ {$IFDEF COMPILER6}
+ {$IF not declared(clHotLight)}
+ {$MESSAGE ERROR 'You do not have installed Delphi 6 Update 2. Please install this before installing the JVCL. http://www.borland.com/downloads/registered/del6_reg_updates_prompt.html'}
+ {$IFEND}
+ {$ENDIF COMPILER6}
+
+ ColorValues: array [0 .. ColCount - 1] of TDefColorItem = (
+ (Value: clBlack; Constant: 'clBlack'; Description: RsClBlack),
+ (Value: clMaroon; Constant: 'clMaroon'; Description: RsClMaroon),
+ (Value: clGreen; Constant: 'clGreen'; Description: RsClGreen),
+ (Value: clOlive; Constant: 'clOlive'; Description: RsClOlive),
+ (Value: clNavy; Constant: 'clNavy'; Description: RsClNavy),
+ (Value: clPurple; Constant: 'clPurple'; Description: RsClPurple),
+ (Value: clTeal; Constant: 'clTeal'; Description: RsClTeal),
+ (Value: clGray; Constant: 'clGray'; Description: RsClGray),
+ (Value: clSilver; Constant: 'clSilver'; Description: RsClSilver),
+ (Value: clRed; Constant: 'clRed'; Description: RsClRed),
+ (Value: clLime; Constant: 'clLime'; Description: RsClLime),
+ (Value: clYellow; Constant: 'clYellow'; Description: RsClYellow),
+ (Value: clBlue; Constant: 'clBlue'; Description: RsClBlue),
+ (Value: clFuchsia; Constant: 'clFuchsia'; Description: RsClFuchsia),
+ (Value: clAqua; Constant: 'clAqua'; Description: RsClAqua),
+ (Value: clWhite; Constant: 'clWhite'; Description: RsClWhite),
+ (Value: clMoneyGreen; Constant: 'clMoneyGreen'; Description: RsClMoneyGreen),
+ (Value: clSkyBlue; Constant: 'clSkyBlue'; Description: RsClSkyBlue),
+ (Value: clCream; Constant: 'clCream'; Description: RsClCream),
+ (Value: clMedGray; Constant: 'clMedGray'; Description: RsClMedGray)
+ );
+
+ //added by dejoy (2005-04-20)
+ StandardColorValues: array [0 .. StandardColCount - 1] of TDefColorItem = (
+ (Value: $00000000; Constant: 'clBlack'; Description: RsClBlack),
+ (Value: $00003399; Constant: 'clBrown'; Description: RsClBrown),
+ (Value: $00003333; Constant: 'clOliveGreen'; Description: RsClOliveGreen),
+ (Value: $00003300; Constant: 'clDarkGreen'; Description: RsClDarkGreen),
+ (Value: $00663300; Constant: 'clDarkTeal'; Description: RsClDarkTeal),
+ (Value: $00800000; Constant: 'clDarkBlue'; Description: RsClDarkBlue),
+ (Value: $00993333; Constant: 'clIndigo'; Description: RsClIndigo),
+ (Value: $00333333; Constant: 'clGray80'; Description: RsClGray80),
+
+ (Value: $00000080; Constant: 'clDarkRed'; Description: RsClDarkRed),
+ (Value: $000066FF; Constant: 'clOrange'; Description: RsClOrange),
+ (Value: $00008080; Constant: 'clDarkYellow'; Description: RsClDarkYellow),
+ (Value: $00008000; Constant: 'clGreen'; Description: RsClGreen),
+ (Value: $00808000; Constant: 'clTeal'; Description: RsClTeal),
+ (Value: $00FF0000; Constant: 'clBlue'; Description: RsClBlue),
+ (Value: $00996666; Constant: 'clBlueGray'; Description: RsClBlueGray),
+ (Value: $00808080; Constant: 'clGray50'; Description: RsClGray50),
+
+ (Value: $000000FF; Constant: 'clRed'; Description: RsClRed),
+ (Value: $000099FF; Constant: 'clLightOrange'; Description: RsClLightOrange),
+ (Value: $0000CC99; Constant: 'clLime'; Description: RsClLime),
+ (Value: $00669933; Constant: 'clSeaGreen'; Description: RsClSeaGreen),
+ (Value: $00999933; Constant: 'clAqua'; Description: RsClAqua),
+ (Value: $00FF6633; Constant: 'clLightBlue'; Description: RsClLightBlue),
+ (Value: $00800080; Constant: 'clViolet'; Description: RsClViolet),
+ (Value: $00999999; Constant: 'clGray40'; Description: RsClGray40),
+
+ (Value: $00FF00FF; Constant: 'clPink'; Description: RsClPink),
+ (Value: $0000CCFF; Constant: 'clGold'; Description: RsClGold),
+ (Value: $0000FFFF; Constant: 'clYellow'; Description: RsClYellow),
+ (Value: $0000FF00; Constant: 'clBrightGreen'; Description: RsClBrightGreen),
+ (Value: $00FFFF00; Constant: 'clTurquoise'; Description: RsClTurquoise),
+ (Value: $00F0CAA6; Constant: 'clSkyBlue'; Description: RsClSkyBlue),
+ (Value: $00663399; Constant: 'clPlum'; Description: RsClPlum),
+ (Value: $00C0C0C0; Constant: 'clGray25'; Description: RsClGray25),
+
+ (Value: $00CC99FF; Constant: 'clRose'; Description: RsClRose),
+ (Value: $0099CCFF; Constant: 'clTan'; Description: RsClTan),
+ (Value: $0099FFFF; Constant: 'clLightYellow'; Description: RsClLightYellow),
+ (Value: $00CCFFCC; Constant: 'clLightGreen'; Description: RsClLightGreen),
+ (Value: $00FFFFCC; Constant: 'clLightTurquoise'; Description: RsClLightTurquoise),
+ (Value: $00FFCC99; Constant: 'clPaleBlue'; Description: RsClPaleBlue),
+ (Value: $00FF99CC; Constant: 'clLavender'; Description: RsClLavender),
+ (Value: $00FFFFFF; Constant: 'clWhite'; Description: RsClWhite)
+ );
+
+ SysColorValues: array [0 .. SysColCount - 1] of TDefColorItem = (
+ (Value: clScrollBar; Constant: 'clScrollBar'; Description: RsClScrollBar),
+ (Value: clBackground; Constant: 'clBackground'; Description: RsClBackground),
+ (Value: clActiveCaption; Constant: 'clActiveCaption'; Description: RsClActiveCaption),
+ (Value: clInactiveCaption; Constant: 'clInactiveCaption'; Description: RsClInactiveCaption),
+ (Value: clMenu; Constant: 'clMenu'; Description: RsClMenu),
+ (Value: clWindow; Constant: 'clWindow'; Description: RsClWindow),
+ (Value: clWindowFrame; Constant: 'clWindowFrame'; Description: RsClWindowFrame),
+ (Value: clMenuText; Constant: 'clMenuText'; Description: RsClMenuText),
+ (Value: clWindowText; Constant: 'clWindowText'; Description: RsClWindowText),
+ (Value: clCaptionText; Constant: 'clCaptionText'; Description: RsClCaptionText),
+ (Value: clActiveBorder; Constant: 'clActiveBorder'; Description: RsClActiveBorder),
+ (Value: clInactiveBorder; Constant: 'clInactiveBorder'; Description: RsClInactiveBorder),
+ (Value: clAppWorkSpace; Constant: 'clAppWorkSpace'; Description: RsClAppWorkSpace),
+ (Value: clHighlight; Constant: 'clHighlight'; Description: RsClHighlight),
+ (Value: clHighlightText; Constant: 'clHighlightText'; Description: RsClHighlightText),
+ (Value: clBtnFace; Constant: 'clBtnFace'; Description: RsClBtnFace),
+ (Value: clBtnShadow; Constant: 'clBtnShadow'; Description: RsClBtnShadow),
+ (Value: clGrayText; Constant: 'clGrayText'; Description: RsClGrayText),
+ (Value: clBtnText; Constant: 'clBtnText'; Description: RsClBtnText),
+ (Value: clInactiveCaptionText; Constant: 'clInactiveCaptionText'; Description: RsClInactiveCaptionText),
+ (Value: clBtnHighlight; Constant: 'clBtnHighlight'; Description: RsClBtnHighlight),
+ (Value: cl3DDkShadow; Constant: 'cl3DDkShadow'; Description: RsCl3DDkShadow),
+ (Value: cl3DLight; Constant: 'cl3DLight'; Description: RsCl3DLight),
+ (Value: clInfoText; Constant: 'clInfoText'; Description: RsClInfoText),
+ (Value: clInfoBk; Constant: 'clInfoBk'; Description: RsClInfoBk),
+
+ (Value: clGradientActiveCaption; Constant: 'clGradientActiveCaption'; Description: RsGradientActiveCaption),
+ (Value: clGradientInactiveCaption; Constant: 'clGradientInactiveCaption';Description: RsGradientInactiveCaption),
+ (Value: clHotLight; Constant: 'clHotLight'; Description: RsHotLight),
+ (Value: clMenuBar; Constant: 'clMenuBar'; Description: RsMenuBar),
+ (Value: clMenuHighlight; Constant: 'clMenuHighlight'; Description: RsMenuHighlight)
+ );
+
+
+type
+ TJvSizeRect = packed record
+ Top: Integer;
+ Left: Integer;
+ Width: Integer;
+ Height: Integer;
+ end;
+
+{$IFNDEF CLR}
+ TJvMessage = packed record
+ Msg: Integer;
+ case Integer of
+ 0:
+ (
+ WParam: Integer;
+ LParam: Integer;
+ Result: Integer;
+ );
+ 1:
+ (
+ WParamLo: Word;
+ WParamHi: Word;
+ LParamLo: Word;
+ LParamHi: Word;
+ ResultLo: Word;
+ ResultHi: Word;
+ );
+ 2:
+ ( // WM_NOPARAMS
+ Unused: array[0..3] of Word;
+ Handled: LongBool; // "Result"
+ );
+ 3:
+ ( // WM_SCROLL
+ Pos: Integer; // WParam
+ ScrollCode: Integer; // LParam
+ );
+ 4:
+ ( // WM_TIMER
+ TimerID: Integer; // WParam
+ TimerProc: TTimerProc;// LParam
+ );
+ 5:
+ ( // WM_MOUSEACTIVATE
+ TopLevel: HWND; // WParam
+ HitTestCode: Word; // LParamLo
+ MouseMsg: Word; // LParamHi
+ );
+ 6:
+ ( // WM_MOUSE(WHEEL) | WM_MOVE
+ case Integer of
+ 0:
+ ( // WM_MOUSE
+ Keys: Integer; // WParam
+ // LParam: Pos | (XPos, YPos)
+ case Integer of
+ 0:
+ (
+ Position: TSmallPoint;
+ );
+ 1:
+ (
+ XPos: Smallint;
+ YPos: Smallint;
+ )
+ );
+ 1:
+ ( // WM_MOUSEWHEEL
+ WheelDelta: Integer; // WParam
+ );
+ );
+ 7:
+ ( // WM_ACTIVATE
+ Active: Word; { WA_INACTIVE, WA_ACTIVE, WA_CLICKACTIVE } // WParamLo
+ Minimized: WordBool; // WParamHi
+ ActiveWindow: HWND; // LParam
+ );
+
+ 8:
+ ( // WM_COMMAND
+ ItemID: Word; // WParamLo
+ NotifyCode: Word; // WParamHi
+ Ctl: HWND; // LParam
+ );
+ 9:
+ ( // WM_GETICON
+ BigIcon: LongBool;
+ );
+ 10:
+ ( // CM_(FOCUS|CONTROL)CHANGED | CM_HINTSHOW
+ Reserved: Integer; // WParam
+ case Integer of
+ 0:
+ ( // CM_(CONTROL)CHANGED
+ Child: TControl; // LParam
+ );
+ 1:
+ ( // CM_FOCUSCHANGED | CM_FORCESIZE }
+ Sender: TControl; // LParam
+ );
+ 2:
+ ( //CM_HINTSHOW
+ HintInfo: PHintInfo;
+ )
+ );
+ 11:
+ ( // CM_CONTROLLISTCHANGE | CM_(CONTROL)CHANGED (| CM_BUTTONPRESSED for clx)
+ Control: TControl; // WParam
+ case Integer of
+ 0:
+ ( // CM_(CONTROL)CHANGED
+ Inserting: LongBool; // LParam
+ );
+ 1: // CM_BUTTONPRESSED (clx)
+ (
+ Index: Integer;
+ )
+ );
+ 12:
+ ( // CM_HINTSHOWPAUSE
+ WasActive: LongBool;
+ Pause: PInteger;
+ );
+ 13:
+ ( // WM_KEY
+ CharCode: Word;
+ NotUsed: Word;
+ KeyData: Integer;
+ );
+ 14:
+ ( // WM_GETTEXT
+ TextMax: Integer;
+ Text: PChar
+ );
+ 15:
+ ( // WM_ERASEBKGND | WM_PAINT
+ DC: HDC;
+ );
+ 16:
+ ( // WM_KILLFOCUS
+ FocusedWnd: HWND;
+ );
+ 17:
+ (
+ NewSize: TSmallPoint; //CM_FORCESIZE wParam
+ );
+ 18:
+ ( { alternative naming for VCL CM_BUTTONPRESSED }
+ GroupIndex: Integer;
+ Button: TControl;
+ );
+ end;
+{$ENDIF !CLR}
+***************)
+
+implementation
+
+(***************
+{$IFDEF COMPILER6_UP}
+constructor TJvPersistent.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ SetSubComponent(True);
+ Name := 'SubComponent';
+end;
+{$ENDIF COMPILER6_UP}
+
+{ TJvPersistentProperty }
+
+procedure TJvPersistentProperty.BeginUpdate;
+begin
+ if FUpdateCount = 0 then
+ SetUpdateState(True);
+ Inc(FUpdateCount);
+end;
+
+procedure TJvPersistentProperty.Changed;
+begin
+ if (FUpdateCount = 0) and Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvPersistentProperty.ChangedProperty(const PropName: string);
+begin
+ if Assigned(FOnChangeProperty) then
+ FOnChangeProperty(Self, PropName);
+end;
+
+procedure TJvPersistentProperty.Changing;
+begin
+ if (FUpdateCount = 0) and Assigned(FOnChanging) then
+ FOnChanging(Self);
+end;
+
+procedure TJvPersistentProperty.ChangingProperty(const PropName: string);
+begin
+ if Assigned(FOnChangingProperty) then
+ FOnChangingProperty(Self, PropName);
+end;
+
+procedure TJvPersistentProperty.EndUpdate;
+begin
+ Dec(FUpdateCount);
+ if FUpdateCount = 0 then
+ SetUpdateState(False);
+end;
+
+procedure TJvPersistentProperty.SetUpdateState(Updating: Boolean);
+begin
+ if Updating then
+ Changing
+ else
+ Changed;
+end;
+***************)
+
+end.
+
diff --git a/components/jvcllaz/run/JvXPBar.pas b/components/jvcllaz/run/JvXPBar.pas
new file mode 100644
index 000000000..5f176e804
--- /dev/null
+++ b/components/jvcllaz/run/JvXPBar.pas
@@ -0,0 +1,2336 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvXPBar.PAS, released on 2004-01-01.
+
+The Initial Developer of the Original Code is Marc Hoffman.
+Portions created by Marc Hoffman are Copyright (C) 2002 APRIORI business solutions AG.
+Portions created by APRIORI business solutions AG are Copyright (C) 2002 APRIORI business solutions AG
+All Rights Reserved.
+
+Contributor(s): dejoy
+ //dejoy 2004-4-20
+ --add GroupIndex,AutoCheck,Checked property in TJvXPBarItem.
+ --add GetItemClass in TJvXPBarItems.
+ --add GetBarItemsClass in TJvXPCustomWinXPBar.
+
+Contributor(s): dierk schmid
+ //dierk 2004-4-23
+ --add property RoundedItemFrame in TJvXPCustomWinXPBar (Integer>0 is the edge radius)
+ --add property ItemFrameColor in TJvXPBarColors
+ //dejoy 2004-4-25
+ -- splitt ItemFrameColor to CheckedFrameColor , FocusedFrameColor in TJvXPBarColors.
+
+Contributors(s): matej golob
+ //matej 2004-5-3
+ --add property BorderColor in TJvXPBarColors.
+ --add property HeaderRounded
+ --add property TopSpace
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvXPBar.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Ported to Lazarus (no too hard after all) by Sergio Samayoa - september 2007.
+// Still dont tested on linux.
+
+{$mode objfpc}{$H+}
+
+unit JvXPBar;
+
+interface
+
+uses
+ ActnList, Classes, Controls, Graphics, ExtCtrls, Forms, ImgList,
+ LCLIntf, LCLProc, LCLType, LMessages, LResources, SysUtils,
+ JvXPCore, JvXPCoreUtils;
+
+type
+ TJvXPBarRollDirection = (rdExpand, rdCollapse);
+
+ TJvXPBarRollMode = (rmFixed, rmShrink); // rmFixed is default
+
+ TJvXPBarHitTest =
+ (
+ htNone, // mouse is inside non-supported rect
+ htHeader, // mouse is inside header
+ htRollButton // mouse is inside rollbutton
+ );
+
+ TJvXPBarRollDelay = 1..200;
+ TJvXPBarRollStep = 1..50;
+
+const
+ WM_XPBARAFTERCOLLAPSE = WM_USER + 303; // Ord('J') + Ord('V') + Ord('C') + Ord('L')
+ WM_XPBARAFTEREXPAND = WM_XPBARAFTERCOLLAPSE + 1;
+
+ { color constants.
+ }
+
+// dxColor_CheckedColorXP := TColor($00c9b4e2);
+// dxColor_CheckedColorXP := TColor($00d9c1bb);
+// dxColor_CheckedColorXP := TColor($00e8ccae);
+
+ dxColor_FocusedColorXP = TColor($00D8ACB0);
+ dxColor_CheckedColorXP = TColor($00D9C1BB);
+ dxColor_BodyColorXP = TColor($00F7DFD6);
+ clHotLight = TColor(COLOR_HOTLIGHT or $80000000);
+
+ dxColor_FocusedFrameColorXP = clHotLight;
+ dxColor_CheckedFrameColorXP = clHighlight;
+
+type
+ TJvXPBarItem = class;
+ TJvXPBarItems = class;
+ TJvXPCustomWinXPBar = class;
+
+ TJvXPBarOnCanChangeEvent = procedure(Sender: TObject; Item: TJvXPBarItem;
+ var AllowChange: Boolean) of object;
+
+ TJvXPBarOnCollapsedChangeEvent = procedure(Sender: TObject;
+ Collapsing: Boolean) of object;
+
+ TJvXPBarOnDrawItemEvent = procedure(Sender: TObject; ACanvas: TCanvas;
+ Rect: TRect; State: TJvXPDrawState; Item: TJvXPBarItem; Bitmap: TBitmap) of object;
+ TJvXPBarOwnerDrawEvent = procedure(Sender: TObject; ACanvas: TCanvas; var ARect: TRect) of object;
+
+ TJvXPBarOnItemClickEvent = procedure(Sender: TObject; Item: TJvXPBarItem) of object;
+
+ TJvXPBarItemActionLink = class(TActionLink)
+ private
+ FClient: TJvXPBarItem;
+ protected
+ procedure AssignClient(AClient: TObject); override;
+ function IsCaptionLinked: Boolean; override;
+ function IsCheckedLinked: Boolean; override;
+ function IsEnabledLinked: Boolean; override;
+ function IsHintLinked: Boolean; override;
+ function IsImageIndexLinked: Boolean; override;
+ function IsVisibleLinked: Boolean; override;
+ function IsOnExecuteLinked: Boolean; override;
+ procedure SetCaption(const Value: string); override;
+ procedure SetHint(const Value: string); override;
+ function DoShowHint(var HintStr: string): Boolean; virtual;
+ function IsAutoCheckLinked: Boolean; virtual;
+ procedure SetAutoCheck(Value: Boolean); override;
+ procedure SetChecked(Value: Boolean); override;
+ procedure SetEnabled(Value: Boolean); override;
+ procedure SetImageIndex(Value: Integer); override;
+ procedure SetVisible(Value: Boolean); override;
+ procedure SetOnExecute(Value: TNotifyEvent); override;
+ property Client: TJvXPBarItem read FClient write FClient;
+ end;
+
+ TJvXPBarItemActionLinkClass = class of TJvXPBarItemActionLink;
+
+ TJvXPBarItemClass = class of TJvXPBarItem;
+
+ TJvXPBarItem = class(TCollectionItem)
+ private
+ FActionLink: TJvXPBarItemActionLink;
+ FCollection: TJvXPBarItems;
+ FCaption: TCaption;
+ FData: Pointer;
+ FDataObject: TObject;
+ FEnabled: Boolean;
+ FHint: string;
+ FImageIndex: TImageIndex;
+ FImageList: TCustomImageList;
+ FName: string;
+ FWinXPBar: TJvXPCustomWinXPBar;
+ FTag: Integer;
+ FVisible: Boolean;
+ FOnClick: TNotifyEvent;
+ FOnDblClick: TNotifyEvent;
+ FGroupIndex: Integer;
+ FChecked: Boolean;
+ FAutoCheck: Boolean;
+ function IsAutoCheckStored: Boolean;
+ function IsCaptionStored: Boolean;
+ function IsEnabledStored: Boolean;
+ function IsHintStored: Boolean;
+ function IsImageIndexStored: Boolean;
+ function IsVisibleStored: Boolean;
+ function IsOnClickStored: Boolean;
+ function IsCheckedStored: Boolean;
+ function GetImages: TCustomImageList;
+ procedure DoActionChange(Sender: TObject);
+ procedure SetAction(Value: TBasicAction);
+ procedure SetCaption(Value: TCaption);
+ procedure SetEnabled(Value: Boolean);
+ procedure SetImageIndex(Value: TImageIndex);
+ procedure SetImageList(Value: TCustomImageList);
+ procedure SetName(const Value: string);
+ procedure SetVisible(Value: Boolean);
+ procedure SetGroupIndex(const Value: Integer);
+ procedure SetChecked(const Value: Boolean);
+ procedure TurnSiblingsOff;
+ protected
+ function GetActionLinkClass: TJvXPBarItemActionLinkClass; dynamic;
+ function GetAction: TBasicAction; virtual;
+ function GetDisplayName: string; override;
+ procedure Notification(AComponent: TComponent); virtual;
+ procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); dynamic;
+
+ procedure DrawItem(AWinXPBar: TJvXPCustomWinXPBar; ACanvas: TCanvas;
+ Rect: TRect; State: TJvXPDrawState; ShowItemFrame: Boolean; Bitmap: TBitmap); virtual;
+ property ActionLink: TJvXPBarItemActionLink read FActionLink write FActionLink;
+ public
+ constructor Create(ACollection: TCollection); override;
+ destructor Destroy; override;
+ procedure Assign(Source: TPersistent); override;
+ property Data: Pointer read FData write FData;
+ property DataObject: TObject read FDataObject write FDataObject;
+ property Images: TCustomImageList read GetImages;
+ property WinXPBar: TJvXPCustomWinXPBar read FWinXPBar;
+ published
+ property Action: TBasicAction read GetAction write SetAction;
+ property AutoCheck: Boolean read FAutoCheck write FAutoCheck
+ stored IsAutoCheckStored default False;
+ property Caption: TCaption read FCaption write SetCaption stored IsCaptionStored;
+ property Checked: Boolean read FChecked write SetChecked stored IsCheckedStored default False;
+ property Enabled: Boolean read FEnabled write SetEnabled stored IsEnabledStored default True;
+ property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
+ property Hint: string read FHint write FHint stored IsHintStored;
+ property ImageIndex: TImageIndex read FImageIndex write SetImageIndex stored IsImageIndexStored default -1;
+ property ImageList: TCustomImageList read FImageList write SetImageList;
+ property Name: string read FName write SetName;
+ property Tag: Integer read FTag write FTag default 0;
+ property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored default True;
+ property OnClick: TNotifyEvent read FOnClick write FOnClick stored IsOnClickStored;
+ property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
+ end;
+
+ TJvXPBarItemsClass = class of TJvXPBarItems;
+
+ TJvXPBarItems = class(TCollection)
+ private
+ FWinXPBar: TJvXPCustomWinXPBar;
+ function GetItem(Index: Integer): TJvXPBarItem;
+ procedure SetItem(Index: Integer; Value: TJvXPBarItem);
+ protected
+ procedure Update(Item: TCollectionItem); override;
+ function GetOwner: TPersistent; override;
+ class function GetItemClass: TJvXPBarItemClass; virtual;
+ public
+ constructor Create(WinXPBar: TJvXPCustomWinXPBar);
+ function Add: TJvXPBarItem; overload;
+ function Add(Action: TBasicAction): TJvXPBarItem; overload;
+ function Add(DataObject: TObject): TJvXPBarItem; overload;
+ function Insert(Index: Integer): TJvXPBarItem; overload;
+ function Insert(Index: Integer; Action: TBasicAction): TJvXPBarItem; overload;
+ function Insert(Index: Integer; DataObject: TObject): TJvXPBarItem; overload;
+ function Find(const AName: string): TJvXPBarItem; overload;
+ function Find(const Action: TBasicAction): TJvXPBarItem; overload;
+ function Find(const DataObject: TObject): TJvXPBarItem; overload;
+ property Items[Index: Integer]: TJvXPBarItem read GetItem write SetItem; default;
+ end;
+
+ TJvXPBarVisibleItems = class(TPersistent)
+ private
+ FItems: TList;
+ FWinXPBar: TJvXPCustomWinXPBar;
+ function Exists(Item: TJvXPBarItem): Boolean;
+ function GetItem(Index: Integer): TJvXPBarItem;
+ procedure Add(Item: TJvXPBarItem);
+ procedure Delete(Item: TJvXPBarItem);
+ public
+ constructor Create(WinXPBar: TJvXPCustomWinXPBar);
+ destructor Destroy; override;
+ function Count: Integer;
+ property Items[Index: Integer]: TJvXPBarItem read GetItem; default;
+ end;
+
+ TJvXPFadeThread = class(TThread)
+ private
+ FWinXPBar: TJvXPCustomWinXPBar;
+ FRollDirection: TJvXPBarRollDirection;
+ FWinXPBarNewOffSet: Integer;
+ protected
+ procedure DoWinXPBarSetRollOffset;
+ procedure DoWinXPBarInternalRedraw;
+ public
+ constructor Create(WinXPBar: TJvXPCustomWinXPBar; RollDirection: TJvXPBarRollDirection);
+ procedure Execute; override;
+ end;
+
+ TJvXPBarColors = class(TPersistent)
+ private
+ FCheckedFrameColor: TColor;
+ FFocusedFrameColor: TColor;
+ FCheckedColor: TColor;
+ FFocusedColor: TColor;
+ FBodyColor: TColor;
+ FBodyBorderColor: TColor;
+ FGradientTo: TColor;
+ FGradientFrom: TColor;
+ FSeparatorColor: TColor;
+ FBorderColor: TColor;
+ FOnChange: TNotifyEvent;
+ procedure SetBorderColor(const Value: TColor);
+ procedure SetBodyColor(const Value: TColor);
+ procedure SetGradientFrom(const Value: TColor);
+ procedure SetGradientTo(const Value: TColor);
+ procedure SetSeparatorColor(const Value: TColor);
+ procedure SetCheckedColor(const Value: TColor);
+ procedure SetFocusedColor(const Value: TColor);
+ procedure SetCheckedFrameColor(const Value: TColor);
+ procedure SetFocusedFrameColor(const Value: TColor);
+ procedure SetBodyBorderColor(const Value: TColor);
+ public
+ constructor Create;
+ procedure Assign(Source: TPersistent); override;
+ procedure Change;
+ published
+ property BorderColor: TColor read FBorderColor write SetBorderColor default clWhite;
+ property CheckedColor: TColor read FCheckedColor write SetCheckedColor default dxColor_CheckedColorXP;
+ property FocusedColor: TColor read FFocusedColor write SetFocusedColor default dxColor_FocusedColorXP;
+ property CheckedFrameColor: TColor read FCheckedFrameColor write SetCheckedFrameColor
+ default dxColor_CheckedFrameColorXP;
+ property FocusedFrameColor: TColor read FFocusedFrameColor write SetFocusedFrameColor
+ default dxColor_FocusedFrameColorXP;
+ property BodyColor: TColor read FBodyColor write SetBodyColor default dxColor_BodyColorXP;
+ property BodyBorderColor: TColor read FBodyBorderColor write SetBodyBorderColor default dxColor_BodyColorXP;
+ property GradientFrom: TColor read FGradientFrom write SetGradientFrom default clWhite;
+ property GradientTo: TColor read FGradientTo write SetGradientTo default TColor($00F7D7C6);
+ property SeparatorColor: TColor read FSeparatorColor write SetSeparatorColor default TColor($00F7D7C6);
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+
+ TJvXPBarOptions = class(TPersistent)
+ end;
+
+ TJvXPCustomWinXPBar = class(TJvXPCustomControl)
+ private
+ FCollapsed: Boolean;
+ FFadeThread: TJvXPFadeThread;
+ FFont: TFont;
+ FFontChanging: Boolean;
+ FGradientWidth: Integer;
+ FHeaderFont: TFont;
+ FHeaderRounded: Boolean;
+ FHitTest: TJvXPBarHitTest;
+ FHotTrack: Boolean;
+ FHoverIndex: Integer;
+ FIcon: TIcon;
+ FImageList: TCustomImageList;
+ FItemHeight: Integer;
+ FItems: TJvXPBarItems;
+ FRollDelay: TJvXPBarRollDelay;
+ FRolling: Boolean;
+ FRollMode: TJvXPBarRollMode;
+ FRollOffset: Integer;
+ FRollStep: TJvXPBarRollStep;
+ FShowLinkCursor: Boolean;
+ FShowRollButton: Boolean;
+ FHotTrackColor: TColor;
+ FVisibleItems: TJvXPBarVisibleItems;
+ FAfterCollapsedChange: TJvXPBarOnCollapsedChangeEvent;
+ FBeforeCollapsedChange: TJvXPBarOnCollapsedChangeEvent;
+ FOnCollapsedChange: TJvXPBarOnCollapsedChangeEvent;
+ FOnCanChange: TJvXPBarOnCanChangeEvent;
+ FOnDrawItem: TJvXPBarOnDrawItemEvent;
+ FOnItemClick: TJvXPBarOnItemClickEvent;
+ FColors: TJvXPBarColors;
+ FRollImages: TCustomImageList;
+ FImageChangeLink: TChangeLink;
+ FRollChangeLink: TChangeLink;
+ FGrouped: Boolean;
+ FHeaderHeight: Integer;
+ FStoredHint: string;
+ FShowItemFrame: Boolean;
+ FRoundedItemFrame: Integer; // DS
+ FTopSpace: Integer;
+ FOwnerDraw: Boolean;
+ FOnDrawBackground: TJvXPBarOwnerDrawEvent;
+ FOnDrawHeader: TJvXPBarOwnerDrawEvent;
+ procedure FontChange(Sender: TObject);
+ procedure SetCollapsed(Value: Boolean);
+ procedure SetFont(Value: TFont);
+ procedure SetHeaderFont(Value: TFont);
+ procedure SetHotTrack(Value: Boolean);
+ procedure SetHotTrackColor(Value: TColor);
+ procedure SetIcon(Value: TIcon);
+ procedure SetImageList(Value: TCustomImageList);
+ procedure SetItemHeight(Value: Integer);
+ procedure SetItems(Value: TJvXPBarItems);
+ procedure SetRollOffset(const Value: Integer);
+ procedure SetShowRollButton(Value: Boolean);
+ procedure ResizeToMaxHeight;
+ procedure SetColors(const Value: TJvXPBarColors);
+ procedure SetRollImages(const Value: TCustomImageList);
+ procedure SetGrouped(const Value: Boolean);
+ procedure GroupMessage;
+ procedure SetHeaderHeight(const Value: Integer);
+ function GetRollHeight: Integer;
+ function GetRollWidth: Integer;
+ procedure SetHeaderRounded(const Value: Boolean);
+ procedure SetTopSpace(const Value: Integer);
+ procedure SetOwnerDraw(const Value: Boolean);
+ protected
+ procedure CMDialogChar(var Msg: TCMDialogChar); message CM_DIALOGCHAR;
+ class function GetBarItemsClass: TJvXPBarItemsClass; virtual;
+ function GetHitTestRect(const HitTest: TJvXPBarHitTest): TRect;
+ function GetItemRect(Index: Integer): TRect; virtual;
+ procedure ItemVisibilityChanged(Item: TJvXPBarItem); dynamic;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure HookMouseDown; override;
+ procedure HookMouseEnter; override;
+ procedure HookMouseLeave; override;
+ procedure HookMouseMove(X: Integer = 0; Y: Integer = 0); override;
+ procedure HookParentFontChanged; override;
+ procedure HookResized; override;
+ procedure SortVisibleItems(const Redraw: Boolean);
+ procedure DoColorsChange(Sender: TObject);
+ procedure DoDrawItem(const Index: Integer; State: TJvXPDrawState); virtual;
+ procedure Paint; override;
+ procedure EndUpdate; override;
+ procedure WMAfterXPBarCollapse(var Msg: TLMessage); message WM_XPBARAFTERCOLLAPSE;
+ procedure WMAfterXPBarExpand(var Msg: TLMessage); message WM_XPBARAFTEREXPAND;
+ property Collapsed: Boolean read FCollapsed write SetCollapsed default False;
+ property Colors: TJvXPBarColors read FColors write SetColors;
+ property RollImages: TCustomImageList read FRollImages write SetRollImages;
+ property Font: TFont read FFont write SetFont;
+ property Grouped: Boolean read FGrouped write SetGrouped default False;
+ property HeaderFont: TFont read FHeaderFont write SetHeaderFont stored;
+ property HeaderHeight: Integer read FHeaderHeight write SetHeaderHeight default 28;
+ property HeaderRounded: Boolean read FHeaderRounded write SetHeaderRounded default True;
+ property OwnerDraw: Boolean read FOwnerDraw write SetOwnerDraw;
+ property HotTrack: Boolean read FHotTrack write SetHotTrack default True;
+ property HotTrackColor: TColor read FHotTrackColor write SetHotTrackColor default $00FF7C35;
+ property Icon: TIcon read FIcon write SetIcon;
+ property ImageList: TCustomImageList read FImageList write SetImageList;
+ property ItemHeight: Integer read FItemHeight write SetItemHeight default 20;
+ property Items: TJvXPBarItems read FItems write SetItems;
+ property RollDelay: TJvXPBarRollDelay read FRollDelay write FRollDelay default 25;
+ property Rolling: Boolean read FRolling default False;
+ property RollMode: TJvXPBarRollMode read FRollMode write FRollMode default rmShrink;
+ property RollOffset: Integer read FRollOffset write SetRollOffset;
+ property RollStep: TJvXPBarRollStep read FRollStep write FRollStep default 3;
+ property ShowLinkCursor: Boolean read FShowLinkCursor write FShowLinkCursor default True;
+ property ShowRollButton: Boolean read FShowRollButton write SetShowRollButton default True;
+ property ShowItemFrame: Boolean read FShowItemFrame write FShowItemFrame;
+ property RoundedItemFrame: Integer read FRoundedItemFrame write FRoundedItemFrame default 1; //DS
+ property TopSpace: Integer read FTopSpace write SetTopSpace default 5;
+ property AfterCollapsedChange: TJvXPBarOnCollapsedChangeEvent read FAfterCollapsedChange
+ write FAfterCollapsedChange;
+ property BeforeCollapsedChange: TJvXPBarOnCollapsedChangeEvent read FBeforeCollapsedChange
+ write FBeforeCollapsedChange;
+ property OnCollapsedChange: TJvXPBarOnCollapsedChangeEvent read FOnCollapsedChange write FOnCollapsedChange;
+ property OnCanChange: TJvXPBarOnCanChangeEvent read FOnCanChange write FOnCanChange;
+ property OnDrawItem: TJvXPBarOnDrawItemEvent read FOnDrawItem write FOnDrawItem;
+ property OnDrawBackground: TJvXPBarOwnerDrawEvent read FOnDrawBackground write FOnDrawBackground;
+ property OnDrawHeader: TJvXPBarOwnerDrawEvent read FOnDrawHeader write FOnDrawHeader;
+ property OnItemClick: TJvXPBarOnItemClickEvent read FOnItemClick write FOnItemClick;
+ procedure AdjustClientRect(var Rect: TRect); override;
+ // show hints for individual items in the list
+ function HintShow(var HintInfo: THintInfo): Boolean; dynamic;
+ procedure CMHintShow(var Msg: TCMHintShow); message CM_HINTSHOW;
+ procedure DblClick; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function GetHitTestAt(X, Y: Integer): TJvXPBarHitTest;
+ function GetItemAt(X, Y: Integer): Integer;
+ procedure Click; override;
+ property Height default 46;
+ property VisibleItems: TJvXPBarVisibleItems read FVisibleItems;
+ property Width default 153;
+ procedure InitiateAction; override;
+ end;
+
+ TJvXPBar = class(TJvXPCustomWinXPBar)
+ published
+ property Caption;
+ property Collapsed;
+ property Colors;
+ property Items;
+ property RollImages;
+ property Font;
+ property Grouped;
+ property HeaderFont;
+ property HeaderHeight;
+ property HeaderRounded;
+ property HotTrack;
+ property HotTrackColor;
+ property OwnerDraw;
+ property Icon;
+ property ImageList;
+ property ItemHeight;
+ property RollDelay;
+ property RollMode;
+ property RollStep;
+ property ShowLinkCursor;
+ property ShowRollButton;
+ property ShowItemFrame;
+ property RoundedItemFrame;
+ property TopSpace;
+
+ property AfterCollapsedChange;
+ property BeforeCollapsedChange;
+ property OnCollapsedChange;
+ property OnCanChange;
+ property OnDrawItem;
+ property OnDrawBackground;
+ property OnDrawHeader;
+ property OnItemClick;
+
+ //property BevelInner;
+ //property BevelOuter;
+ //property BevelWidth;
+ //property BiDiMode;
+ //property Ctl3D;
+ //property DockSite;
+ //property ParentBiDiMode;
+ //property ParentCtl3D;
+ //property TabOrder;
+ //property TabStop;
+ //property UseDockManager default True;
+ property Align;
+ property Anchors;
+ //property AutoSize;
+ property Constraints;
+ property DragCursor;
+ property DragKind;
+ //21.09.07 - SESS
+ //property OnCanResize;
+ property DragMode;
+ //property Enabled;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ //property OnDockDrop;
+ //property OnDockOver;
+ //property OnEndDock;
+ //property OnGetSiteInfo;
+ //property OnStartDock;
+ //property OnUnDock;
+ property OnClick;
+ property OnDblClick;
+ property OnConstrainedResize;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnKeyDown;
+ property OnKeyPress;
+ property OnKeyUp;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+procedure RoundedFrame(Canvas: TCanvas; ARect: TRect; AColor: TColor; R: Integer);
+
+implementation
+
+uses
+ Menus;
+
+resourcestring
+ RsUntitled = 'untitled';
+ RsUntitledFmt = '(%s %d)';
+ RsHintShortcutFmt = '%s (%s)';
+
+const
+ FC_HEADER_MARGIN = 6;
+ FC_ITEM_MARGIN = 8;
+
+function SortByIndex(Item1, Item2: Pointer): Integer;
+var
+ Idx1, Idx2: Integer;
+begin
+ Idx1 := TCollectionItem(Item1).Index;
+ Idx2 := TCollectionItem(Item2).Index;
+ if Idx1 < Idx2 then
+ Result := -1
+ else
+ if Idx1 = Idx2 then
+ Result := 0
+ else
+ Result := 1;
+end;
+
+//=== { TJvXPBarItemActionLink } =============================================
+
+procedure TJvXPBarItemActionLink.AssignClient(AClient: TObject);
+begin
+ Client := AClient as TJvXPBarItem;
+end;
+
+
+function TJvXPBarItemActionLink.IsAutoCheckLinked: Boolean;
+begin
+ Result := (Client.AutoCheck = (Action as TCustomAction).AutoCheck);
+end;
+
+function TJvXPBarItemActionLink.IsCaptionLinked: Boolean;
+begin
+ Result := inherited IsCaptionLinked and
+ (Client.Caption = (Action as TCustomAction).Caption);
+end;
+
+function TJvXPBarItemActionLink.IsCheckedLinked: Boolean;
+begin
+ Result := inherited IsCheckedLinked and
+ (Client.Checked = (Action as TCustomAction).Checked);
+end;
+
+function TJvXPBarItemActionLink.IsEnabledLinked: Boolean;
+begin
+ Result := inherited IsEnabledLinked and
+ (Client.Enabled = (Action as TCustomAction).Enabled);
+end;
+
+function TJvXPBarItemActionLink.IsHintLinked: Boolean;
+begin
+ Result := inherited IsHintLinked and
+ (Client.Hint = (Action as TCustomAction).Hint);
+end;
+
+function TJvXPBarItemActionLink.IsImageIndexLinked: Boolean;
+begin
+ Result := inherited IsImageIndexLinked and
+ (Client.ImageIndex = (Action as TCustomAction).ImageIndex);
+end;
+
+function TJvXPBarItemActionLink.IsVisibleLinked: Boolean;
+begin
+ Result := inherited IsVisibleLinked and
+ (Client.Visible = (Action as TCustomAction).Visible);
+end;
+
+function TJvXPBarItemActionLink.IsOnExecuteLinked: Boolean;
+begin
+ Result := inherited IsOnExecuteLinked and
+ JvXPMethodsEqual(TMethod(Client.OnClick), TMethod(Action.OnExecute));
+end;
+
+procedure TJvXPBarItemActionLink.SetAutoCheck(Value: Boolean);
+begin
+ if IsAutoCheckLinked then
+ Client.AutoCheck := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetCaption(const Value: string);
+begin
+ if IsCaptionLinked then
+ Client.Caption := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetEnabled(Value: Boolean);
+begin
+ if IsEnabledLinked then
+ Client.Enabled := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetChecked(Value: Boolean);
+begin
+ if IsCheckedLinked then
+ Client.Checked := Value;
+end;
+
+
+procedure TJvXPBarItemActionLink.SetHint(const Value: string);
+begin
+ if IsHintLinked then
+ Client.Hint := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetImageIndex(Value: Integer);
+begin
+ if IsImageIndexLinked then
+ Client.ImageIndex := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetVisible(Value: Boolean);
+begin
+ if IsVisibleLinked then
+ Client.Visible := Value;
+end;
+
+procedure TJvXPBarItemActionLink.SetOnExecute(Value: TNotifyEvent);
+begin
+ if IsOnExecuteLinked then
+ Client.OnClick := Value;
+end;
+
+//===TJvXPBarItem ============================================================
+
+constructor TJvXPBarItem.Create(ACollection: TCollection);
+begin
+ inherited Create(ACollection);
+ FCollection := TJvXPBarItems(ACollection);
+ FCaption := '';
+ FData := nil;
+ FDataObject := nil;
+ FEnabled := True;
+ FImageIndex := -1;
+ FImageList := nil;
+ FHint := '';
+ FName := '';
+ FWinXPBar := FCollection.FWinXPBar;
+ FTag := 0;
+ FVisible := True;
+ FAutoCheck := False;
+ FChecked := False;
+ FGroupIndex := 0;
+ FWinXPBar.ItemVisibilityChanged(Self);
+ FWinXPBar.ResizeToMaxHeight;
+end;
+
+destructor TJvXPBarItem.Destroy;
+begin
+ FVisible := False; // required to remove from visible list!
+ FWinXPBar.ItemVisibilityChanged(Self);
+ FActionLink.Free;
+ FActionLink := nil;
+
+ inherited Destroy;
+ FWinXPBar.ResizeToMaxHeight;
+end;
+
+procedure TJvXPBarItem.Notification(AComponent: TComponent);
+begin
+ if AComponent = Action then
+ Action := nil;
+ if AComponent = FImageList then
+ FImageList := nil;
+end;
+
+function TJvXPBarItem.GetDisplayName: string;
+var
+ _DisplayName, ItemName: string;
+begin
+ _DisplayName := FCaption;
+ if _DisplayName = '' then
+ _DisplayName := RsUntitled;
+ ItemName := FName;
+ if ItemName <> '' then
+ DisplayName := DisplayName + ' [' + ItemName + ']';
+ if not FVisible then
+ _DisplayName := _DisplayName + '*';
+ Result := _DisplayName;
+end;
+
+function TJvXPBarItem.GetImages: TCustomImageList;
+begin
+ Result := nil;
+ if Assigned(FImageList) then
+ Result := FImageList
+ else
+ if Assigned(Action) and Assigned(TAction(Action).ActionList.Images) then
+ Result := TAction(Action).ActionList.Images
+ else
+ if Assigned(FWinXPBar.FImageList) then
+ Result := FWinXPBar.FImageList;
+end;
+
+procedure TJvXPBarItem.ActionChange(Sender: TObject; CheckDefaults: Boolean);
+begin
+ if Sender is TCustomAction then
+ with TCustomAction(Sender) do
+ begin
+ if not (csLoading in ComponentState) then
+ Update;
+ if not CheckDefaults or not Self.AutoCheck then
+ Self.AutoCheck := AutoCheck;
+ if not CheckDefaults or (Self.Caption = '') or (Self.Caption = Self.Name) then
+ Self.Caption := Caption;
+ if not CheckDefaults or not Self.Checked then
+ Self.Checked := Checked;
+ if not CheckDefaults or Self.Enabled then
+ Self.Enabled := Enabled;
+ if not CheckDefaults or (Self.Hint = '') then
+ Self.Hint := Hint;
+ if not CheckDefaults or (Self.ImageIndex = -1) then
+ Self.ImageIndex := ImageIndex;
+ if not CheckDefaults or Self.Visible then
+ Self.Visible := Visible;
+ if not CheckDefaults or not Assigned(Self.OnClick) then
+ Self.OnClick := OnExecute;
+ end;
+end;
+
+procedure TJvXPBarItem.DrawItem(AWinXPBar: TJvXPCustomWinXPBar; ACanvas: TCanvas;
+ Rect: TRect; State: TJvXPDrawState; ShowItemFrame: Boolean; Bitmap: TBitmap);
+var
+ ItemCaption: TCaption;
+ HasImages: Boolean;
+ LBar: TJvXPCustomWinXPBar;
+begin
+ LBar := (AWinXPBar as TJvXPCustomWinXPBar);
+ HasImages := Self.Images <> nil;
+ with ACanvas do
+ begin
+ Font.Assign(LBar.Font);
+ Brush.Color := LBar.Colors.BodyColor;
+ if not ShowItemFrame then
+ FillRect(Rect);
+ if not Self.Enabled then
+ Font.Color := clGray
+ else
+ begin
+ if dsFocused in State then
+ begin
+ if LBar.HotTrack then
+ begin
+ if LBar.FHotTrackColor <> clNone then
+ Font.Color := LBar.FHotTrackColor;
+ Font.Style := Font.Style + [fsUnderline];
+ end;
+ if ShowItemFrame then
+ begin
+ Brush.Color := LBar.Colors.FocusedColor;
+ if LBar.RoundedItemFrame > 0 then
+ RoundedFrame(ACanvas, Rect, LBar.Colors.FocusedFrameColor, LBar.RoundedItemFrame)
+ else
+ begin
+ FillRect(Rect);
+ JvXPFrame3D(ACanvas, Rect, LBar.Colors.FocusedFrameColor, LBar.Colors.FocusedFrameColor);
+ end;
+ end;
+ end
+ else
+ if dsClicked in State then
+ begin
+ if ShowItemFrame then
+ begin
+ Brush.Color := LBar.Colors.CheckedColor;
+ if LBar.RoundedItemFrame > 0 then
+ RoundedFrame(ACanvas, Rect, LBar.Colors.CheckedFrameColor, LBar.RoundedItemFrame)
+ else
+ begin
+ FillRect(Rect);
+ JvXPFrame3D(ACanvas, Rect, LBar.Colors.CheckedFrameColor, LBar.Colors.CheckedFrameColor);
+ end;
+ end;
+ end
+ else
+ FillRect(Rect);
+ end;
+ if HasImages then
+ begin
+ if (Self.ImageIndex <> -1) then
+ Self.Images.Draw(ACanvas, Rect.Left + 1,
+ Rect.Top + (LBar.FItemHeight - Bitmap.Height) div 2, Self.ImageIndex);
+ //Original:
+ //Draw(Rect.Left + 1, Rect.Top + (LBar.FItemHeight - Bitmap.Height) div 2, Bitmap);
+ Inc(Rect.Left, Self.Images.Width + 4);
+ end
+ else
+ Inc(Rect.Left, 4);
+ ItemCaption := Self.Caption;
+ if (ItemCaption = '') and ((csDesigning in LBar.ComponentState) or (LBar.ControlCount = 0)) then
+ ItemCaption := Format(RsUntitledFmt, [RsUntitled, Index]);
+ DrawText(ACanvas.Handle, PAnsiChar(ItemCaption), Length(ItemCaption), Rect,
+ DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS);
+ end;
+end;
+
+function TJvXPBarItem.GetActionLinkClass: TJvXPBarItemActionLinkClass;
+begin
+ Result := TJvXPBarItemActionLink;
+end;
+
+procedure TJvXPBarItem.Assign(Source: TPersistent);
+begin
+ if Source is TJvXPBarItem then
+ with TJvXPBarItem(Source) do
+ begin
+ Self.Action := Action;
+ Self.Caption := Caption;
+ Self.Data := Data;
+ Self.DataObject := DataObject;
+ Self.Enabled := Enabled;
+ Self.Hint := Hint;
+ Self.ImageList := ImageList;
+ Self.ImageIndex := ImageIndex;
+ Self.Name := Name;
+ Self.Tag := Tag;
+ Self.Visible := Visible;
+ Self.OnClick := OnClick;
+ Self.AutoCheck := AutoCheck;
+ Self.Checked := Checked;
+ Self.GroupIndex := GroupIndex;
+ Self.OnDblClick := OnDblClick;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+function TJvXPBarItem.IsAutoCheckStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsAutoCheckLinked;
+end;
+
+function TJvXPBarItem.IsCaptionStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsCaptionLinked;
+end;
+
+function TJvXPBarItem.IsEnabledStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsEnabledLinked;
+end;
+
+function TJvXPBarItem.IsHintStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsHintLinked;
+end;
+
+function TJvXPBarItem.IsImageIndexStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsImageIndexLinked;
+end;
+
+function TJvXPBarItem.IsVisibleStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsVisibleLinked;
+end;
+
+function TJvXPBarItem.IsOnClickStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsOnExecuteLinked;
+end;
+
+function TJvXPBarItem.IsCheckedStored: Boolean;
+begin
+ Result := (ActionLink = nil) or not FActionLink.IsCheckedLinked;
+end;
+
+procedure TJvXPBarItem.DoActionChange(Sender: TObject);
+begin
+ if Sender = Action then
+ ActionChange(Sender, False);
+end;
+
+function TJvXPBarItem.GetAction: TBasicAction;
+begin
+ if FActionLink <> nil then
+ Result := FActionLink.Action
+ else
+ Result := nil;
+end;
+
+procedure TJvXPBarItem.SetAction(Value: TBasicAction);
+begin
+ if Value = nil then
+ begin
+ FActionLink.Free;
+ FActionLink := nil;
+ FWinXPBar.InternalRedraw; // redraw image
+ end
+ else
+ begin
+ if FActionLink = nil then
+ FActionLink := GetActionLinkClass.Create(Self);
+ FActionLink.Action := Value;
+ FActionLink.OnChange := @DoActionChange;
+ ActionChange(Value, csLoading in Value.ComponentState);
+ Value.FreeNotification(FWinXPBar); // deligates notification to WinXPBar!
+ end;
+end;
+
+procedure TJvXPBarItem.SetCaption(Value: TCaption);
+begin
+ if Value <> FCaption then
+ begin
+ FCaption := Value;
+ FWinXPBar.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPBarItem.SetEnabled(Value: Boolean);
+begin
+ if Value <> FEnabled then
+ begin
+ FEnabled := Value;
+ FWinXPBar.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPBarItem.SetImageIndex(Value: TImageIndex);
+begin
+ if Value <> FImageIndex then
+ begin
+ FImageIndex := Value;
+ FWinXPBar.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPBarItem.SetImageList(Value: TCustomImageList);
+begin
+ if Value <> FImageList then
+ begin
+ FImageList := Value;
+ FWinXPBar.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPBarItem.SetName(const Value: string);
+begin
+ if (Value <> FName) and (FCollection.Find(Value) = nil) then
+ FName := Value;
+end;
+
+procedure TJvXPBarItem.SetVisible(Value: Boolean);
+begin
+ if Value <> FVisible then
+ begin
+ FVisible := Value;
+ FWinXPBar.ItemVisibilityChanged(Self);
+ FWinXPBar.ResizeToMaxHeight;
+ end;
+end;
+
+procedure TJvXPBarItem.SetGroupIndex(const Value: Integer);
+begin
+ if FGroupIndex <> Value then
+ begin
+ FGroupIndex := Value;
+ if Checked then
+ TurnSiblingsOff;
+ end;
+end;
+
+procedure TJvXPBarItem.SetChecked(const Value: Boolean);
+begin
+ if FChecked <> Value then
+ begin
+ FChecked := Value;
+// Change(False);
+ if Value then
+ TurnSiblingsOff;
+ end;
+end;
+
+procedure TJvXPBarItem.TurnSiblingsOff;
+var
+ I: Integer;
+ Item: TJvXPBarItem;
+begin
+ if (GroupIndex <> 0) and Assigned(FWinXPBar) then
+ begin
+ for I := 0 to FWinXPBar.Items.Count - 1 do
+ begin
+ Item := FWinXPBar.Items[I];
+ if (Item <> Self) and (Item.GroupIndex = GroupIndex) then
+ Item.Checked := False;
+ end;
+ end;
+end;
+
+//=== { TJvXPBarItems } ======================================================
+
+constructor TJvXPBarItems.Create(WinXPBar: TJvXPCustomWinXPBar);
+begin
+ inherited Create(GetItemClass);
+ FWinXPBar := WinXPBar;
+end;
+
+function TJvXPBarItems.Add: TJvXPBarItem;
+begin
+ Result := TJvXPBarItem(inherited Add);
+end;
+
+function TJvXPBarItems.Add(Action: TBasicAction): TJvXPBarItem;
+begin
+ Result := Add;
+ Result.Action := Action;
+end;
+
+function TJvXPBarItems.Add(DataObject: TObject): TJvXPBarItem;
+begin
+ Result := Add;
+ Result.DataObject := DataObject;
+end;
+
+function TJvXPBarItems.Insert(Index: Integer): TJvXPBarItem;
+begin
+ Result := TJvXPBarItem(inherited Insert(Index));
+end;
+
+function TJvXPBarItems.Insert(Index: Integer; Action: TBasicAction): TJvXPBarItem;
+begin
+ Result := Insert(Index);
+ Result.Action := Action;
+end;
+
+function TJvXPBarItems.Insert(Index: Integer; DataObject: TObject): TJvXPBarItem;
+begin
+ Result := Insert(Index);
+ Result.DataObject := DataObject;
+end;
+
+function TJvXPBarItems.GetOwner: TPersistent;
+begin
+ Result := FWinXPBar;
+end;
+
+class function TJvXPBarItems.GetItemClass: TJvXPBarItemClass;
+begin
+ Result := TJvXPBarItem;
+end;
+
+function TJvXPBarItems.GetItem(Index: Integer): TJvXPBarItem;
+begin
+ Result := TJvXPBarItem(inherited GetItem(Index));
+end;
+
+procedure TJvXPBarItems.SetItem(Index: Integer; Value: TJvXPBarItem);
+begin
+ inherited SetItem(Index, Value);
+end;
+
+procedure TJvXPBarItems.Update(Item: TCollectionItem);
+begin
+ FWinXPBar.SortVisibleItems(True);
+end;
+
+function TJvXPBarItems.Find(const AName: string): TJvXPBarItem;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Count - 1 do
+ if Items[I].Name = AName then
+ begin
+ Result := Items[I];
+ Break;
+ end;
+end;
+
+function TJvXPBarItems.Find(const Action: TBasicAction): TJvXPBarItem;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Count - 1 do
+ if Items[I].Action = Action then
+ begin
+ Result := Items[I];
+ Break;
+ end;
+end;
+
+function TJvXPBarItems.Find(const DataObject: TObject): TJvXPBarItem;
+var
+ I: Integer;
+begin
+ Result := nil;
+ for I := 0 to Count - 1 do
+ if Items[I].DataObject = DataObject then
+ begin
+ Result := Items[I];
+ Break;
+ end;
+end;
+
+//=== { TJvXPBarVisibleItems } ===============================================
+
+constructor TJvXPBarVisibleItems.Create(WinXPBar: TJvXPCustomWinXPBar);
+begin
+ inherited Create;
+ FItems := TList.Create;
+ FWinXPBar := WinXPBar;
+end;
+
+destructor TJvXPBarVisibleItems.Destroy;
+begin
+ FItems.Free;
+ inherited Destroy;
+end;
+
+function TJvXPBarVisibleItems.GetItem(Index: Integer): TJvXPBarItem;
+begin
+ Result := nil;
+ if Index < FItems.Count then
+ Result := TJvXPBarItem(FItems[Index]);
+end;
+
+function TJvXPBarVisibleItems.Count: Integer;
+begin
+ Result := FItems.Count;
+end;
+
+function TJvXPBarVisibleItems.Exists(Item: TJvXPBarItem): Boolean;
+var
+ I: Integer;
+begin
+ Result := False;
+ for I := 0 to Count - 1 do
+ if Items[I] = Item then
+ begin
+ Result := True;
+ Break;
+ end;
+end;
+
+procedure TJvXPBarVisibleItems.Add(Item: TJvXPBarItem);
+begin
+ if not Exists(Item) then
+ begin
+ FItems.Add(Item);
+ FWinXPBar.SortVisibleItems(False);
+ end;
+end;
+
+procedure TJvXPBarVisibleItems.Delete(Item: TJvXPBarItem);
+begin
+ if Exists(Item) then
+ FItems.Delete(FItems.IndexOf(Item));
+end;
+
+//=== { TJvXPFadeThread } ====================================================
+
+constructor TJvXPFadeThread.Create(WinXPBar: TJvXPCustomWinXPBar;
+ RollDirection: TJvXPBarRollDirection);
+begin
+ inherited Create(True);
+ FWinXPBar := WinXPBar;
+ FRollDirection := RollDirection;
+ FreeOnTerminate := True;
+ Suspended := False;
+end;
+
+procedure TJvXPFadeThread.DoWinXPBarInternalRedraw;
+begin
+ FWinXPBar.InternalRedraw;
+end;
+
+procedure TJvXPFadeThread.DoWinXPBarSetRollOffset;
+begin
+ FWinXPBar.RollOffset := FWinXPBarNewOffSet;
+end;
+
+procedure TJvXPFadeThread.Execute;
+var
+ NewOffset: Integer;
+begin
+ while not Terminated do
+ try
+ FWinXPBar.FRolling := True;
+
+ { calculate new roll offset }
+ if FRollDirection = rdCollapse then
+ NewOffset := FWinXPBar.RollOffset - FWinXPBar.FRollStep
+ else
+ NewOffset := FWinXPBar.RollOffset + FWinXPBar.FRollStep;
+
+ { validate offset ranges }
+ if NewOffset < 0 then
+ NewOffset := 0;
+ if NewOffset > FWinXPBar.FItemHeight then
+ NewOffset := FWinXPBar.FItemHeight;
+
+ FWinXPBarNewOffSet := NewOffset;
+
+ Synchronize(@DoWinXPBarSetRollOffset);
+
+ { terminate on 'out-of-range' }
+ if ((FRollDirection = rdCollapse) and (NewOffset = 0)) or
+ ((FRollDirection = rdExpand) and (NewOffset = FWinXPBar.FItemHeight)) then
+ Terminate;
+
+ { idle process }
+ Sleep(FWinXPBar.FRollDelay);
+ finally
+ FWinXPBar.FRolling := False;
+ end;
+
+ { redraw button state }
+ FWinXPBar.FCollapsed := FRollDirection = rdCollapse;
+ if FWinXPBar.FShowRollButton then
+ Synchronize(@DoWinXPBarInternalRedraw);
+
+ { update inspector }
+ if csDesigning in FWinXPBar.ComponentState then
+ TCustomForm(FWinXPBar.Owner).Designer.Modified
+ else
+ PostMessage(FWinXPBar.Handle, WM_XPBARAFTERCOLLAPSE,
+ Ord(FRollDirection = rdCollapse), 0);
+end;
+
+//=== { TJvXPBarColors } =====================================================
+
+constructor TJvXPBarColors.Create;
+begin
+ inherited Create;
+ // (rom) needs local color constants
+ FBodyColor := dxColor_BodyColorXP;
+ FBodyBorderColor := dxColor_BodyColorXP;
+ FBorderColor := clWhite;
+ FGradientFrom := clWhite;
+ FGradientTo := TColor($00F7D7C6);
+ FSeparatorColor := TColor($00F7D7C6);
+ FCheckedColor := dxColor_CheckedColorXP;
+ FFocusedColor := dxColor_FocusedColorXP;
+ FCheckedFrameColor := dxColor_CheckedFrameColorXP;
+ FFocusedFrameColor := dxColor_FocusedFrameColorXP;
+end;
+
+procedure TJvXPBarColors.Assign(Source: TPersistent);
+begin
+ if Source is TJvXPBarColors then
+ with TJvXPBarColors(Source) do
+ begin
+ Self.CheckedColor := CheckedColor;
+ Self.FocusedColor := FocusedColor;
+ Self.CheckedFrameColor := CheckedFrameColor;
+ Self.FocusedFrameColor := FocusedFrameColor;
+ Self.BodyColor := BodyColor;
+ Self.GradientTo := GradientTo;
+ Self.GradientFrom := GradientFrom;
+ Self.SeparatorColor := SeparatorColor;
+ end
+ else
+ inherited Assign(Source);
+end;
+
+procedure TJvXPBarColors.Change;
+begin
+ if Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TJvXPBarColors.SetBodyColor(const Value: TColor);
+begin
+ if FBodyColor <> Value then
+ begin
+ FBodyColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetGradientFrom(const Value: TColor);
+begin
+ if FGradientFrom <> Value then
+ begin
+ FGradientFrom := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetGradientTo(const Value: TColor);
+begin
+ if FGradientTo <> Value then
+ begin
+ FGradientTo := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetSeparatorColor(const Value: TColor);
+begin
+ if FSeparatorColor <> Value then
+ begin
+ FSeparatorColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetCheckedColor(const Value: TColor);
+begin
+ if FCheckedColor <> Value then
+ begin
+ FCheckedColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetBorderColor(const Value: TColor);
+begin
+ if FBorderColor <> Value then
+ begin
+ FBorderColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetFocusedColor(const Value: TColor);
+begin
+ if FFocusedColor <> Value then
+ begin
+ FFocusedColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetCheckedFrameColor(const Value: TColor);
+begin
+ if FCheckedFrameColor <> Value then
+ begin
+ FCheckedFrameColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetFocusedFrameColor(const Value: TColor);
+begin
+ if FFocusedFrameColor <> Value then
+ begin
+ FFocusedFrameColor := Value;
+ Change;
+ end;
+end;
+
+procedure TJvXPBarColors.SetBodyBorderColor(const Value: TColor);
+begin
+ if FBodyBorderColor <> Value then
+ begin
+ FBodyBorderColor := Value;
+ Change;
+ end;
+end;
+
+//=== { TJvXPCustomWinXPBar } ================================================
+
+constructor TJvXPCustomWinXPBar.Create(AOwner: TComponent);
+const
+ MouseEvents: TJvXPControlStyle = [csRedrawMouseEnter, csRedrawMouseLeave];
+begin
+ inherited Create(AOwner);
+ FStoredHint := '|'; // no one in their right mind uses a pipe as the only character in a hint...
+ ControlStyle := ControlStyle {- [csDoubleClicks]} + [csAcceptsControls, csActionClient];
+ ExControlStyle := [csRedrawCaptionChanged];
+ ExControlStyle := ExControlStyle + MouseEvents;
+ Height := 46;
+ HotTrack := True; // initialize mouse events
+ Width := 153;
+ FColors := TJvXPBarColors.Create;
+ FColors.OnChange := @DoColorsChange;
+ FCollapsed := False;
+ FFadeThread := nil;
+ FImageChangeLink := TChangeLink.Create;
+ FImageChangeLink.OnChange := @DoColorsChange;
+ FRollChangeLink := TChangeLink.Create;
+ FRollChangeLink.OnChange := @DoColorsChange;
+ FTopSpace := 5;
+
+ FFont := TFont.Create;
+ FFont.Color := $00840000;
+ FFont.Size := 8;
+ FFont.OnChange := @FontChange;
+ FHeaderHeight := 28;
+ FHeaderRounded := True;
+ FGradientWidth := 0;
+ FHeaderFont := TFont.Create;
+ FHeaderFont.Color := $00840000;
+ FHeaderFont.Size := 8;
+ FHeaderFont.Style := [fsBold];
+ FHeaderFont.OnChange := @FontChange;
+
+ FHitTest := htNone;
+
+ FHotTrackColor := $00FF7C35;
+ FHoverIndex := -1;
+ FIcon := TIcon.Create;
+ FItemHeight := 20;
+ FItems := GetBarItemsClass.Create(Self);
+ FRollDelay := 25;
+ FRolling := False;
+ FRollMode := rmShrink;
+ FRollOffset := FItemHeight;
+ FRollStep := 3;
+ FShowLinkCursor := True;
+ FShowRollButton := True;
+ FVisibleItems := TJvXPBarVisibleItems.Create(Self);
+end;
+
+destructor TJvXPCustomWinXPBar.Destroy;
+begin
+ FFont.Free;
+ FHeaderFont.Free;
+ FIcon.Free;
+ FItems.Free;
+ FVisibleItems.Free;
+ FColors.Free;
+ FImageChangeLink.Free;
+ FRollChangeLink.Free;
+ inherited Destroy;
+end;
+
+procedure TJvXPCustomWinXPBar.Notification(AComponent: TComponent;
+ Operation: TOperation);
+var
+ I: Integer;
+begin
+ if not (csDestroying in ComponentState) and (Operation = opRemove) then
+ begin
+ if AComponent = FImageList then
+ ImageList := nil;
+ if AComponent = FRollImages then
+ RollImages := nil;
+ for I := 0 to FItems.Count - 1 do
+ FItems[I].Notification(AComponent);
+ end;
+ inherited Notification(AComponent, Operation);
+end;
+
+procedure TJvXPCustomWinXPBar.FontChange(Sender: TObject);
+begin
+ if (not FFontChanging) and not (csLoading in ComponentState) then
+ ParentFont := False;
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomWinXPBar.ResizeToMaxHeight;
+var
+ NewHeight: Integer;
+begin
+ { TODO: Check this!!! }
+ if IsLocked then
+ Exit;
+ NewHeight := FC_HEADER_MARGIN + HeaderHeight + FVisibleItems.Count * FRollOffset + FC_ITEM_MARGIN + 1;
+ { full collapsing }
+ if ((FRolling and not FCollapsed) or (not FRolling and FCollapsed) or
+ (FVisibleItems.Count = 0)) then
+ Dec(NewHeight, FC_ITEM_MARGIN);
+// if Height <> NewHeight then
+ Height := NewHeight - 5 + FTopSpace;
+end;
+
+function TJvXPCustomWinXPBar.GetHitTestAt(X, Y: Integer): TJvXPBarHitTest;
+begin
+ Result := htNone;
+ if PtInRect(GetHitTestRect(htHeader), Point(X, Y)) then
+ Result := htHeader;
+ if PtInRect(GetHitTestRect(htRollButton), Point(X, Y)) then
+ Result := htRollButton;
+end;
+
+function TJvXPCustomWinXPBar.GetItemRect(Index: Integer): TRect;
+begin
+ Result.Left := 3;
+ Result.Right := Width - 3;
+ if FRollMode = rmShrink then
+ Result.Top := FC_HEADER_MARGIN + HeaderHeight + FC_ITEM_MARGIN div 2 +
+ Index * FRollOffset - 4 + FTopSpace
+ else
+ Result.Top := FC_HEADER_MARGIN + HeaderHeight + FC_ITEM_MARGIN div 2 +
+ Index * FItemHeight - 4 + FTopSpace;
+ Result.Bottom := Result.Top + FItemHeight;
+end;
+
+function TJvXPCustomWinXPBar.GetRollHeight: Integer;
+begin
+ if Assigned(FRollImages) then
+ Result := FRollImages.Height
+ else
+ Result := 18;
+end;
+
+function TJvXPCustomWinXPBar.GetRollWidth: Integer;
+begin
+ if Assigned(FRollImages) then
+ Result := FRollImages.Width
+ else
+ Result := 18;
+end;
+
+function TJvXPCustomWinXPBar.GetHitTestRect(const HitTest: TJvXPBarHitTest): TRect;
+
+begin
+ case HitTest of
+ htHeader:
+ Result := Bounds(0, FTopSpace, Width, FHeaderHeight);
+ htRollButton:
+ Result := Bounds(Width - 24, FTopSpace + (FHeaderHeight - GetRollHeight) div 2, GetRollWidth, GetRollHeight);
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SortVisibleItems(const Redraw: Boolean);
+begin
+ if (csLoading in ComponentState) or (csDestroying in ComponentState) then
+ Exit;
+ FVisibleItems.FItems.Sort(@SortByIndex);
+ if Redraw then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomWinXPBar.ItemVisibilityChanged(Item: TJvXPBarItem);
+begin
+ // update visible-item list
+ if Item.Visible then
+ FVisibleItems.Add(Item)
+ else
+ FVisibleItems.Delete(Item);
+end;
+
+procedure TJvXPCustomWinXPBar.HookMouseDown;
+var
+ Rect: TRect;
+begin
+ inherited HookMouseDown; // update drawstate
+ if FHitTest = htRollButton then
+ begin
+ Rect := GetHitTestRect(htRollButton);
+ Invalidate;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.HookMouseEnter;
+begin
+ inherited HookMouseEnter;
+ if FHoverIndex <> -1 then
+ DoDrawItem(FHoverIndex, [dsFocused]);
+end;
+
+procedure TJvXPCustomWinXPBar.HookMouseLeave;
+begin
+ inherited HookMouseLeave;
+ if (FHoverIndex <> -1) and (FVisibleItems[FHoverIndex] <> nil) and
+ (not FVisibleItems[FHoverIndex].Checked) then
+ DoDrawItem(FHoverIndex, []);
+end;
+
+
+function TJvXPCustomWinXPBar.GetItemAt(X, Y: Integer): Integer;
+var
+ Header: Integer;
+begin
+ Header := FC_HEADER_MARGIN div 2 + HeaderHeight + FC_ITEM_MARGIN div 2 + FTopSpace;
+ if (Y < Header) or (Y > Height - FC_ITEM_MARGIN div 2) then
+ Result := -1
+ else
+ Result := (Y - Header) div ItemHeight;
+end;
+
+procedure TJvXPCustomWinXPBar.HookMouseMove(X, Y: Integer);
+const
+ cPipe = '|';
+var
+ Rect: TRect;
+ OldHitTest: TJvXPBarHitTest;
+ NewIndex: Integer;
+begin
+ OldHitTest := FHitTest;
+ FHitTest := GetHitTestAt(X, Y);
+ if FHitTest <> OldHitTest then
+ begin
+ Rect := Bounds(0, FTopSpace, Width, FHeaderHeight); // header
+ Invalidate;
+ if FShowLinkCursor then
+ if FHitTest <> htNone then
+ Cursor := crHandPoint
+ else
+ Cursor := crDefault;
+ end;
+
+ NewIndex := GetItemAt(X, Y);
+
+ if (NewIndex >= 0) and (NewIndex < VisibleItems.Count) then
+ begin
+ if FStoredHint = cPipe then
+ FStoredHint := Hint;
+ if Action is TCustomAction then
+ inherited Hint := TCustomAction(Action).Hint
+ else
+ inherited Hint := VisibleItems[NewIndex].Hint;
+ end
+ else
+ begin
+ NewIndex := -1;
+ if FStoredHint <> cPipe then
+ inherited Hint := FStoredHint;
+ FStoredHint := cPipe;
+ end;
+
+ if NewIndex <> FHoverIndex then
+ begin
+ if (FHoverIndex <> -1) and (FVisibleItems[FHoverIndex] <> nil) then
+ if FVisibleItems[FHoverIndex].Checked then
+ DoDrawItem(FHoverIndex, [dsClicked])
+ else
+ DoDrawItem(FHoverIndex, []);
+ FHoverIndex := NewIndex;
+ if (FHoverIndex <> -1) and (FVisibleItems[FHoverIndex] <> nil) and
+ (FVisibleItems[FHoverIndex].Enabled) then
+ begin
+ DoDrawItem(FHoverIndex, [dsFocused]);
+ if FShowLinkCursor then
+ Cursor := crHandPoint;
+ end
+ else
+ if FShowLinkCursor then
+ Cursor := crDefault;
+ end;
+
+ inherited HookMouseMove(X, Y);
+end;
+
+procedure TJvXPCustomWinXPBar.HookParentFontChanged;
+begin
+ if ParentFont then
+ begin
+ FFontChanging := True;
+ try
+ FFont.Color := $00E75100;
+ FFont.Name := inherited Font.Name;
+ FFont.Size := 8;
+ FFont.Style := inherited Font.Style;
+ FHeaderFont.Color := $00E75100;
+ FHeaderFont.Name := Font.Name;
+ FHeaderFont.Size := 8;
+ FHeaderFont.Style := [fsBold];
+ finally
+ FFontChanging := False;
+ end;
+ inherited HookParentFontChanged;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.HookResized;
+begin
+ // perform actions only on 'width'-change
+ if FGradientWidth <> Width then
+ FGradientWidth := Width;
+
+ // resize to maximum height
+ ResizeToMaxHeight;
+ inherited HookResized;
+end;
+
+procedure TJvXPCustomWinXPBar.SetCollapsed(Value: Boolean);
+begin
+ if Value <> FCollapsed then
+ begin
+ // Using fading while loading is useless.
+ // Using the fading thread at design time is NOT safe. See Mantis 3547.
+ if ComponentState * [csLoading, csDesigning] = [] then
+ begin
+ if Assigned(FBeforeCollapsedChange) then
+ FBeforeCollapsedChange(Self, Value);
+ if Value then
+ FFadeThread := TJvXPFadeThread.Create(Self, rdCollapse)
+ else
+ FFadeThread := TJvXPFadeThread.Create(Self, rdExpand);
+ if Assigned(FOnCollapsedChange) then
+ FOnCollapsedChange(Self, Value);
+ end
+ else
+ begin
+ FCollapsed := Value;
+ FRolling := True;
+ if Value then
+ RollOffset := 0
+ else
+ RollOffset := FItemHeight;
+ FRolling := False;
+ if Grouped and not Value then
+ GroupMessage;
+ end;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetFont(Value: TFont);
+begin
+ FFont.Assign(Value);
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomWinXPBar.SetHeaderFont(Value: TFont);
+begin
+ FHeaderFont.Assign(Value);
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomWinXPBar.SetHotTrack(Value: Boolean);
+const
+ MouseEvents: TJvXPControlStyle = [csRedrawMouseEnter, csRedrawMouseLeave];
+begin
+ if Value <> FHotTrack then
+ begin
+ FHotTrack := Value;
+// if FHotTrack then
+// ExControlStyle := ExControlStyle + MouseEvents
+// else
+// ExControlStyle := ExControlStyle - MouseEvents;
+ if not (csLoading in ComponentState) then
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetHotTrackColor(Value: TColor);
+begin
+ if Value <> FHotTrackColor then
+ begin
+ FHotTrackColor := Value;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetIcon(Value: TIcon);
+begin
+ if Value <> FIcon then
+ begin
+ FIcon.Assign(Value);
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetImageList(Value: TCustomImageList);
+begin
+ if Value <> FImageList then
+ begin
+ if FImageList <> nil then
+ FImageList.UnRegisterChanges(FImageChangeLink);
+ FImageList := Value;
+ if FImageList <> nil then
+ begin
+ FImageList.FreeNotification(Self);
+ FImageList.RegisterChanges(FImageChangeLink);
+ end;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetItemHeight(Value: Integer);
+begin
+ if Value <> FItemHeight then
+ begin
+ FItemHeight := Value;
+ if not FCollapsed then
+ RollOffset := FItemHeight;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetItems(Value: TJvXPBarItems);
+begin
+ FItems.Assign(Value);
+end;
+
+procedure TJvXPCustomWinXPBar.SetRollOffset(const Value: Integer);
+begin
+ if Value <> FRollOffset then
+ begin
+ FRollOffset := Value;
+ ResizeToMaxHeight;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetShowRollButton(Value: Boolean);
+begin
+ if Value <> FShowRollButton then
+ begin
+ FShowRollButton := Value;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.EndUpdate;
+begin
+ inherited EndUpdate;
+ ResizeToMaxHeight;
+end;
+
+procedure TJvXPCustomWinXPBar.Click;
+var
+ AllowChange, CallInherited: Boolean;
+ LItem: TJvXPBarItem;
+begin
+ CallInherited := True;
+ if FShowRollButton and (FHitTest <> htNone) then
+ Collapsed := not Collapsed;
+ if (FHoverIndex <> -1) and (FVisibleItems[FHoverIndex] <> nil) and
+ FVisibleItems[FHoverIndex].Enabled then
+ begin
+ AllowChange := True;
+ if Assigned(FOnCanChange) then
+ FOnCanChange(Self, FVisibleItems[FHoverIndex], AllowChange);
+ if not AllowChange then
+ Exit;
+
+ //dejoy add
+ LItem := FVisibleItems[FHoverIndex];
+ with LItem do
+ begin
+ if (not Assigned(ActionLink) and AutoCheck) or
+ (Assigned(ActionLink) and not ActionLink.IsAutoCheckLinked and AutoCheck) then
+ LItem.Checked := not LItem.Checked;
+ end;
+ if FVisibleItems[FHoverIndex].Checked then
+ DrawState := DrawState + [dsClicked]
+ else
+ DrawState := DrawState - [dsClicked];
+
+ if Assigned(FOnItemClick) then
+ begin
+ FOnItemClick(Self, FVisibleItems[FHoverIndex]);
+ CallInherited := False;
+ end;
+ if Assigned(FVisibleItems[FHoverIndex].FOnClick) then
+ begin
+ { set linked 'action' as Sender }
+ if Assigned(FVisibleItems[FHoverIndex].Action) and
+ (@FVisibleItems[FHoverIndex].FOnClick <> @FVisibleItems[FHoverIndex].Action.OnExecute) then
+ FVisibleItems[FHoverIndex].FOnClick(FVisibleItems[FHoverIndex])
+ else
+ if not (csDesigning in ComponentState) and Assigned(FVisibleItems[FHoverIndex].ActionLink) then
+ FVisibleItems[FHoverIndex].ActionLink.Execute(Self)
+ else
+ if Assigned(FVisibleItems[FHoverIndex].FOnClick) then
+ FVisibleItems[FHoverIndex].FOnClick(FVisibleItems[FHoverIndex]);
+
+ CallInherited := False;
+ end;
+ Collapsed := False;
+ InternalRedraw; //dejoy
+ end;
+ if CallInherited then
+ inherited Click;
+end;
+
+procedure TJvXPCustomWinXPBar.DoDrawItem(const Index: Integer; State: TJvXPDrawState);
+var
+ Bitmap: TBitmap;
+ ItemRect: TRect;
+ HasImages: Boolean;
+begin
+ Bitmap := TBitmap.Create;
+ with Canvas do
+ try
+ Bitmap.Assign(nil);
+ ItemRect := GetItemRect(Index);
+ HasImages := FVisibleItems[Index].Images <> nil;
+ if HasImages then
+ begin
+ FVisibleItems[Index].Images.GetBitmap(FVisibleItems[Index].ImageIndex, Bitmap);
+ end;
+ Bitmap.Transparent := True;
+ if OwnerDraw then
+ begin
+ if Assigned(FOnDrawItem) then
+ FOnDrawItem(Self, Canvas, ItemRect, State, FVisibleItems[Index], Bitmap);
+ end
+ else
+ FVisibleItems[Index].DrawItem(Self, Canvas, ItemRect, State, ShowItemFrame, Bitmap);
+ finally
+ Bitmap.Free;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.Paint;
+var
+ ARect: TRect;
+ Bitmap: TBitmap;
+ Index, I: Integer;
+ OwnColor: TColor;
+
+ // (rom) Do as prefix for a local function is not ideal
+ procedure DoDrawBackground(ACanvas: TCanvas; var R: TRect);
+ begin
+ ACanvas.Brush.Color := FColors.BodyColor; // $00F7DFD6;
+ Inc(R.Top, FTopSpace + FHeaderHeight);
+ if OwnerDraw then
+ begin
+ if Assigned(FOnDrawBackground) then
+ FOnDrawBackground(Self, ACanvas, R);
+ end
+ else
+ begin
+ if not FCollapsed and (FColors.FBodyColor <> FColors.FBodyBorderColor) then
+ begin
+ ACanvas.Pen.Color := FColors.FBodyBorderColor;
+ ACanvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom - 1);
+ end
+ else
+ ACanvas.FillRect(R);
+ end;
+ end;
+
+ procedure DoDrawHeader(ACanvas: TCanvas; var R: TRect);
+ begin
+ Dec(R.Top, FHeaderHeight);
+ R.Bottom := R.Top + FHeaderHeight;
+ if OwnerDraw then
+ begin
+ ACanvas.Brush.Color := FColors.FBorderColor;
+ if Assigned(FOnDrawHeader) then
+ FOnDrawHeader(Self, ACanvas, R);
+ end
+ else
+ begin
+ ACanvas.GradientFill(Rect(0, R.Top, Width, R.Top + FHeaderHeight),
+ FColors.GradientFrom, FColors.GradientTo, gdHorizontal);
+
+ { draw frame... }
+ ACanvas.Brush.Color := FColors.FBorderColor;
+ ACanvas.FrameRect(R);
+
+ if FHeaderRounded then
+ begin
+ OwnColor := TJvXPWinControl(Parent).Color;
+ ACanvas.Pixels[0, R.Top] := OwnColor;
+ ACanvas.Pixels[0, R.Top + 1] := OwnColor;
+ ACanvas.Pixels[1, R.Top] := OwnColor;
+ ACanvas.Pixels[1, R.Top + 1] := FColors.FBorderColor;
+ ACanvas.Pixels[Width - 1, R.Top] := OwnColor;
+ ACanvas.Pixels[Width - 2, R.Top] := OwnColor;
+ ACanvas.Pixels[Width - 1, R.Top + 1] := OwnColor;
+ ACanvas.Pixels[Width - 2, R.Top + 1] := FColors.FBorderColor;
+ end;
+
+ // Paint rollover button: (expanded/collapsed state button images)
+ if FShowRollButton and (Width >= 115) then
+ begin
+ Bitmap := TBitmap.Create;
+ try
+ if Assigned(FRollImages) then
+ begin
+ // format:
+ // 0 - normal collapsed
+ // 1 - normal expanded
+ // 2 - hot collapsed
+ // 3 - hot expanded
+ // 4 - down collapsed
+ // 5 - down expanded
+ Index := 0; // normal
+ if FHitTest = htRollButton then
+ begin
+ if dsHighlight in DrawState then
+ Index := 2; // hot
+ if (dsClicked in DrawState) and (dsHighlight in DrawState) then
+ Index := 4; // down
+ end;
+ if not FCollapsed then
+ Inc(Index);
+ if Index >= FRollImages.Count then
+ Index := Ord(not FCollapsed);
+ FRollImages.GetBitmap(Index, Bitmap);
+ end
+ else
+ begin
+ Index := 0;
+ if FHitTest = htRollButton then
+ begin
+ if dsHighlight in DrawState then
+ Index := 1; // hot
+ if (dsClicked in DrawState) and (dsHighlight in DrawState) then
+ Index := 2; // down
+ end;
+ Bitmap.Assign(nil); // fixes GDI resource leak
+ if FCollapsed then
+ //Bitmap.LoadFromResourceName(HInstance, 'JvXPCustomWinXPBarEXPAND' + IntToStr(Index))
+ Bitmap.LoadFromLazarusResource('JvXPCustomWinXPBarEXPAND' + IntToStr(Index))
+ else
+ //Bitmap.LoadFromResourceName(HInstance, 'JvXPCustomWinXPBarCOLLAPSE' + IntToStr(Index));
+ Bitmap.LoadFromLazarusResource('JvXPCustomWinXPBarCOLLAPSE' + IntToStr(Index));
+ end;
+ // Transparency fix not needed Here! -WPostma
+ Bitmap.Transparent := True;
+ ACanvas.Draw(R.Right - 24, R.Top + (HeaderHeight - GetRollHeight) div 2, Bitmap);
+ finally
+ Bitmap.Free;
+ end;
+ Dec(R.Right, 25);
+ end;
+ Inc(R.Left, 22);
+ ACanvas.Pen.Color := FColors.SeparatorColor;
+ JvXPDrawLine(ACanvas, 1, ARect.Top + FHeaderHeight, Width - 1, ARect.Top + FHeaderHeight);
+ if not FIcon.Empty then
+ begin
+ ACanvas.Draw(2, 0, FIcon);
+ Inc(R.Left, 16);
+ end;
+ Dec(ARect.Right, 25);
+ end;
+
+ { draw seperator line }
+ ACanvas.Pen.Color := FColors.SeparatorColor;
+ JvXPDrawLine(ACanvas, 1, ARect.Top + FHeaderHeight, Width - 1, ARect.Top + FHeaderHeight);
+
+ { draw icon }
+// Inc(ARect.Left, 22);
+ if not FIcon.Empty then
+ begin
+ ACanvas.Draw(2, 1, FIcon);
+ Inc(ARect.Left, 6);
+ end
+ else
+ Dec(ARect.Left, 16);
+ SetBkMode(ACanvas.Handle, TRANSPARENT);
+ ACanvas.Font.Assign(FHeaderFont);
+ if FHotTrack and (dsHighlight in DrawState) and (FHitTest <> htNone) and (FHotTrackColor <> clNone) then
+ ACanvas.Font.Color := FHotTrackColor;
+ ARect.Bottom := ARect.Top + FHeaderHeight;
+ Dec(ARect.Right, 3);
+ DrawText(ACanvas.Handle, PChar(Caption), Length(Caption), ARect,
+ DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS or DT_NOPREFIX);
+ end;
+begin
+ { get client rect }
+ ARect := GetClientRect;
+ DoDrawBackground(Canvas, ARect);
+ { draw header }
+ DoDrawHeader(Canvas, ARect);
+ { draw visible items }
+ Canvas.Brush.Color := FColors.BodyColor;
+ if not FCollapsed or FRolling then
+ for I := 0 to FVisibleItems.Count - 1 do
+ if FVisibleItems[I].Checked then
+ DoDrawItem(I, [dsClicked])
+ else
+ DoDrawItem(I, []);
+end;
+
+procedure TJvXPCustomWinXPBar.WMAfterXPBarCollapse(var Msg: TLMessage);
+begin
+ if Assigned(FAfterCollapsedChange) then
+ FAfterCollapsedChange(Self, Msg.WParam <> 0);
+ if Grouped and not FCollapsed then
+ GroupMessage;
+end;
+
+procedure TJvXPCustomWinXPBar.DoColorsChange(Sender: TObject);
+begin
+ Invalidate;
+end;
+
+procedure TJvXPCustomWinXPBar.SetColors(const Value: TJvXPBarColors);
+begin
+ FColors.Assign(Value);
+end;
+
+procedure TJvXPCustomWinXPBar.SetRollImages(const Value: TCustomImageList);
+begin
+ if FRollImages <> Value then
+ begin
+ if FRollImages <> nil then
+ FRollImages.UnRegisterChanges(FRollChangeLink);
+ FRollImages := Value;
+ if FRollImages <> nil then
+ begin
+ FRollImages.FreeNotification(Self);
+ FRollImages.RegisterChanges(FRollChangeLink);
+ end;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.GroupMessage;
+var
+ Msg: TLMessage;
+begin
+ if Parent <> nil then
+ begin
+ Msg.Msg := WM_XPBARAFTEREXPAND;
+ Msg.WParam := WPARAM(Self);
+ Msg.Result := 0;
+ Parent.Broadcast(Msg);
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.WMAfterXPBarExpand(var Msg: TLMessage);
+begin
+ if Grouped and (TObject(Msg.WParam) <> Self) then
+ Collapsed := True;
+end;
+
+procedure TJvXPCustomWinXPBar.SetGrouped(const Value: Boolean);
+begin
+ if FGrouped <> Value then
+ begin
+ FGrouped := Value;
+ if FGrouped and not Collapsed then
+ Collapsed := True;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.AdjustClientRect(var Rect: TRect);
+begin
+ inherited AdjustClientRect(Rect);
+ if ControlCount > 0 then
+ begin
+ Inc(Rect.Top, FHeaderHeight + 4);
+ InflateRect(Rect, -4, -4);
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetHeaderHeight(const Value: Integer);
+begin
+ if FHeaderHeight <> Value then
+ begin
+ FHeaderHeight := Value;
+ ResizeToMaxHeight;
+// InternalRedraw;
+ end;
+end;
+
+function TJvXPCustomWinXPBar.HintShow(var HintInfo: THintInfo): Boolean;
+begin
+ // draw the item hint (if available)
+ if (FHoverIndex > -1) and (FVisibleItems[FHoverIndex] <> nil) then
+ begin
+ HintInfo.CursorRect := GetItemRect(FHoverIndex);
+ with VisibleItems[FHoverIndex] do
+ begin
+ if Action is TCustomAction then
+ HintInfo.HintStr := TCustomAction(Action).Hint
+ else
+ HintInfo.HintStr := VisibleItems[FHoverIndex].Hint;
+ end;
+ end
+ else
+ if (VisibleItems.Count > 0) and not Collapsed then
+ HintInfo.CursorRect := GetHitTestRect(htHeader);
+
+ if HintInfo.HintStr = '' then
+ HintInfo.HintStr := Hint;
+ Result := False; // use default hint window
+end;
+
+procedure TJvXPCustomWinXPBar.CMHintShow(var Msg: TCMHintShow);
+begin
+ Msg.Result := Ord(HintShow(Msg.HintInfo^));
+end;
+
+function TJvXPBarItemActionLink.DoShowHint(var HintStr: string): Boolean;
+begin
+ Result := True;
+ if Action is TCustomAction then
+ begin
+ Result := TCustomAction(Action).DoHint(HintStr);
+ if Result and Application.HintShortCuts and (TCustomAction(Action).ShortCut <> scNone) then
+ if HintStr <> '' then
+ HintStr := Format(RsHintShortcutFmt, [HintStr, ShortCutToText(TCustomAction(Action).ShortCut)]);
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.InitiateAction;
+var
+ I: Integer;
+begin
+ inherited InitiateAction;
+ // go through each item and update
+ // Note: Do not call ActionChange as it would trigger Mantis 3244 and it is
+ // basically wrong as the point of InitiateAction is to call Update (see in
+ // the inherited code).
+ for I := 0 to Items.Count - 1 do
+ if Assigned(Items[I].ActionLink) then
+ Items[I].ActionLink.Update;
+end;
+
+
+procedure TJvXPCustomWinXPBar.CMDialogChar(var Msg: TCMDialogChar);
+var
+ I: Integer;
+begin
+ if CanFocus then
+ begin
+ if IsAccel(Msg.CharCode, Caption) then
+ begin
+ Collapsed := not Collapsed;
+ Msg.Result := 1;
+ end
+ else
+ if not Collapsed then
+ for I := 0 to VisibleItems.Count - 1 do
+ if IsAccel(Msg.CharCode, VisibleItems[I].Caption) and VisibleItems[I].Enabled then
+ begin
+ Msg.Result := 1;
+ FHitTest := htNone;
+ FHoverIndex := I;
+ Click;
+ Exit;
+ end;
+ end;
+ // 21.07.2007 - SESS: Parece no estar en la clase base
+ // inherited;
+end;
+
+class function TJvXPCustomWinXPBar.GetBarItemsClass: TJvXPBarItemsClass;
+begin
+ Result := TJvXPBarItems;
+end;
+
+procedure TJvXPCustomWinXPBar.DblClick;
+var
+ LItem: TJvXPBarItem;
+begin
+ if (FHoverIndex <> -1) and (FVisibleItems[FHoverIndex] <> nil) and
+ FVisibleItems[FHoverIndex].Enabled then
+ begin
+ LItem := FVisibleItems[FHoverIndex];
+ if Assigned(LItem.FOnDblClick) then
+ LItem.FOnDblClick(LItem);
+ end;
+ inherited DblClick;
+end;
+
+procedure RoundedFrame(Canvas: TCanvas; ARect: TRect; AColor: TColor; R: Integer);
+begin
+ // Draw Frame with round edges
+ with Canvas, ARect do
+ begin
+ Pen.Color := AColor;
+ Dec(Right);
+ Dec(Bottom);
+ Polygon(
+ [Point(Left + R, Top),
+ Point(Right - R, Top),
+ Point(Right, Top + R),
+ Point(Right, Bottom - R),
+ Point(Right - R, Bottom),
+ Point(Left + R, Bottom),
+ Point(Left, Bottom - R),
+ Point(Left, Top + R),
+ Point(Left + R, Top)]);
+ Inc(Right);
+ Inc(Bottom);
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetHeaderRounded(const Value: Boolean);
+begin
+ if FHeaderRounded <> Value then
+ begin
+ FHeaderRounded := Value;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetTopSpace(const Value: Integer);
+begin
+ if Value <> FTopSpace then
+ begin
+ FTopSpace := Value;
+ if FTopSpace < 0 then
+ FTopSpace := 0;
+ ResizeToMaxHeight;
+ InternalRedraw;
+ end;
+end;
+
+procedure TJvXPCustomWinXPBar.SetOwnerDraw(const Value: Boolean);
+begin
+ if FOwnerDraw <> Value then
+ begin
+ FOwnerDraw := Value;
+ Invalidate;
+ end;
+end;
+
+initialization
+ {$I JvXPBar.lrs}
+
+end.
+
diff --git a/components/jvcllaz/run/JvXPCore.pas b/components/jvcllaz/run/JvXPCore.pas
new file mode 100644
index 000000000..f6ab4c0f1
--- /dev/null
+++ b/components/jvcllaz/run/JvXPCore.pas
@@ -0,0 +1,913 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvXPCore.PAS, released on 2004-01-01.
+
+The Initial Developer of the Original Code is Marc Hoffman.
+Portions created by Marc Hoffman are Copyright (C) 2002 APRIORI business solutions AG.
+Portions created by APRIORI business solutions AG are Copyright (C) 2002 APRIORI business solutions AG
+All Rights Reserved.
+
+Contributor(s):
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvXPCore.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Ported to Lazarus (no too hard after all) by Sergio Samayoa - september 2007.
+// Still dont tested on linux.
+
+unit JvXPCore;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, Controls, Forms, Graphics, LCLIntf, LCLType, LMessages;
+
+(* 23.09.2007 - SESS - unused
+const
+ { color constants.
+
+ these constants are used as default colors for descendant controls
+ and may be replaced with other (common) values.
+
+ syntax: JvXPColor_[Control]_[Enabled: Enb, Dis]_[Type]_[Theme: WXP, OXP] }
+
+ { button colors - WindowsXP }
+ dxColor_Btn_Enb_Border_WXP = TColor($00733800); // border line
+ dxColor_Btn_Dis_Border_WXP = TColor($00BDC7CE); // border line (disabled)
+ dxColor_Btn_Enb_Edges_WXP = TColor($00AD9E7B); // border edges
+ dxColor_Btn_Dis_Edges_WXP = TColor($00BDC7CE); // border edges (disabled)
+ dxColor_Btn_Enb_BgFrom_WXP = TColor($00FFFFFF); // background from
+ dxColor_Btn_Enb_BgTo_WXP = TColor($00E7EBEF); // background to
+ dxColor_Btn_Enb_CkFrom_WXP = TColor($00C6CFD6); // clicked from
+ dxColor_Btn_Enb_CkTo_WXP = TColor($00EBF3F7); // clicked to
+ dxColor_Btn_Enb_FcFrom_WXP = TColor($00FFE7CE); // focused from
+ dxColor_Btn_Enb_FcTo_WXP = TColor($00EF846D); // focused to
+ dxColor_Btn_Enb_HlFrom_WXP = TColor($00CEF3FF); // highlight from
+ dxColor_Btn_Enb_HlTo_WXP = TColor($000096E7); // highlight to
+
+ { checkbox colors - WindowsXP }
+ dxColor_Chk_Enb_Border_WXP = TColor($00845118); // border line
+ dxColor_Chk_Enb_NmSymb_WXP = TColor($0021A621); // symbol normal
+ dxColor_Chk_Enb_GraSymb_WXP = TColor($0071C671); // symbol grayed
+
+ { misc colors - WindowsXP }
+ dxColor_Msc_Dis_Caption_WXP = TColor($0094A6A5); // caption color (disabled)
+
+ dxColor_DotNetFrame = TColor($00F7FBFF); // $00E7EBEF;
+ dxColor_BorderLineOXP = TColor($00663300);
+ dxColor_BgOXP = TColor($00D6BEB5);
+ dxColor_BgCkOXP = TColor($00CC9999);
+
+type
+ TJvXPCustomStyleControl = class;
+
+ TJvXPBoundLines = set of
+ (
+ blLeft, // left line
+ blTop, // top line
+ blRight, // right line
+ blBottom // bottom line
+ );
+23.09.2007 - SESS - unused *)
+
+type
+ TJvXPControlStyle = set of
+ (
+ csRedrawCaptionChanged, // (default)
+ csRedrawBorderChanged, //
+ csRedrawEnabledChanged, // (default)
+ csRedrawFocusedChanged, // (default)
+ csRedrawMouseDown, // (default)
+ csRedrawMouseEnter, // (default)
+ csRedrawMouseLeave, // (default)
+ csRedrawMouseMove, //
+ csRedrawMouseUp, // (default)
+ csRedrawParentColorChanged, // (default)
+ csRedrawParentFontChanged, //
+ csRedrawPosChanged, //
+ csRedrawResized //
+ );
+
+type
+ TJvXPDrawState = set of
+ (
+ dsDefault, // default
+ dsHighlight, // highlighted
+ dsClicked, // clicked
+ dsFocused // focused
+ );
+
+(* 23.09.2007 - SESS - unused
+ TJvXPGlyphLayout =
+ (
+ glBottom, // bottom glyph
+ glCenter, // centered glyph
+ glTop // top glyph
+ );
+
+ TJvXPTheme =
+ (
+ WindowsXP, // WindowsXP theme
+ OfficeXP // OfficeXP theme
+ );
+
+ { baseclass for non-focusable component descendants. }
+ TJvXPCustomComponent = class(TComponent)
+ private
+ FVersion: string;
+ procedure SetVersion(const Value: string);
+ public
+ constructor Create(AOwner: TComponent); override;
+ published
+ property Version: string read FVersion write SetVersion stored False;
+ end;
+23.09.2007 - SESS - unused *)
+
+type
+ TJvXPWinControl = class(TWinControl)
+ published
+ property Color;
+ end;
+
+ { baseclass for focusable control descendants. }
+
+ TJvXPCustomControl = class(TCustomControl)
+ private
+ FClicking: Boolean;
+ FDrawState: TJvXPDrawState;
+ FIsLocked: Boolean;
+ FIsSibling: Boolean;
+ FModalResult: TModalResult;
+ FOnMouseLeave: TNotifyEvent;
+ FOnMouseEnter: TNotifyEvent;
+ FVersion: string;
+ procedure SetVersion(const Value: string);
+ procedure CMFocusChanged(var Msg: TLMessage); message CM_FOCUSCHANGED;
+ procedure CMDialogChar(var Msg: TCMDialogChar); message CM_DIALOGCHAR;
+ procedure CMBorderChanged(var Msg: TLMessage); message CM_BORDERCHANGED;
+ procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED;
+ procedure CMMouseEnter(var Msg: TLMessage); message CM_MOUSEENTER;
+ procedure CMMouseLeave(var Msg: TLMessage); message CM_MOUSELEAVE;
+ procedure CMParentColorChanged(var Msg: TLMessage); message CM_PARENTCOLORCHANGED;
+
+ //21.09.07 - SESS
+ //procedure CMParentFontChanged(var Msg: TLMessage); message CM_PARENTFONTCHANGED;
+
+ procedure CMTextChanged(var Msg: TLMessage); message CM_TEXTCHANGED;
+ procedure WMMouseMove(var Msg: TLMMouse); message LM_MOUSEMOVE;
+ procedure WMSize(var Msg: TLMSize); message LM_SIZE;
+ procedure WMWindowPosChanged(var Msg: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED;
+ protected
+ ExControlStyle: TJvXPControlStyle;
+ procedure InternalRedraw; dynamic;
+ procedure HookBorderChanged; dynamic;
+ procedure HookEnabledChanged; dynamic;
+ procedure HookFocusedChanged; dynamic;
+ procedure HookMouseDown; dynamic;
+ procedure HookMouseEnter; dynamic;
+ procedure HookMouseLeave; dynamic;
+ procedure HookMouseMove(X: Integer = 0; Y: Integer = 0); dynamic;
+ procedure HookMouseUp; dynamic;
+ procedure HookParentColorChanged; dynamic;
+ procedure HookParentFontChanged; dynamic;
+ procedure HookPosChanged; dynamic;
+ procedure HookResized; dynamic;
+ procedure HookTextChanged; dynamic;
+ procedure BeginUpdate; dynamic;
+ procedure EndUpdate; dynamic;
+ procedure LockedInvalidate; dynamic;
+ procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+ procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+ procedure Click; override;
+ property ModalResult: TModalResult read FModalResult write FModalResult default 0;
+ property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
+ property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property Canvas;
+ property DrawState: TJvXPDrawState read FDrawState write FDrawState;
+ property IsLocked: Boolean read FIsLocked write FIsLocked;
+ property IsSibling: Boolean read FIsSibling write FIsSibling;
+ published
+ property Version: string read FVersion write SetVersion stored False;
+ end;
+
+(* 23.09.2007 - SESS - unused
+ TJvXPUnlimitedControl = class(TJvXPCustomControl)
+ published
+ //property BevelInner;
+ //property BevelOuter;
+ //property BevelWidth;
+ //property BiDiMode;
+ //property Ctl3D;
+ //property DockSite;
+ //property ParentBiDiMode;
+ //property ParentCtl3D;
+ //property TabOrder;
+ //property TabStop;
+ //property UseDockManager default True;
+ property Align;
+ property Anchors;
+ //property AutoSize;
+ property Constraints;
+ property DragCursor;
+ property DragKind;
+
+ //21.09.07 - SESS resolver
+ //property OnCanResize;
+
+ property DragMode;
+ //property Enabled;
+ property Font;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property Visible;
+ //property OnDockDrop;
+ //property OnDockOver;
+ //property OnEndDock;
+ //property OnGetSiteInfo;
+ //property OnStartDock;
+ //property OnUnDock;
+ property OnClick;
+ property OnConstrainedResize;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnKeyDown;
+ property OnKeyPress;
+ property OnKeyUp;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnStartDrag;
+ end;
+
+ TJvXPStyle = class(TPersistent)
+ private
+ FTheme: TJvXPTheme;
+ FUseStyleManager: Boolean;
+ protected
+ Parent: TJvXPCustomStyleControl;
+ procedure SetTheme(Value: TJvXPTheme); virtual;
+ procedure SetUseStyleManager(Value: Boolean); virtual;
+ public
+ constructor Create(AOwner: TComponent);
+ function GetTheme: TJvXPTheme;
+ published
+ property Theme: TJvXPTheme read FTheme write SetTheme default WindowsXP;
+ property UseStyleManager: Boolean read FUseStyleManager write SetUseStyleManager default True;
+ end;
+
+ TJvXPStyleManager = class(TJvXPCustomComponent)
+ private
+ FControls: TList;
+ FTheme: TJvXPTheme;
+ FOnThemeChanged: TNotifyEvent;
+ procedure InvalidateControls;
+ protected
+ procedure SetTheme(Value: TJvXPTheme); virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure RegisterControls(const AControls: array of TJvXPCustomControl);
+ procedure UnregisterControls(const AControls: array of TJvXPCustomControl);
+ published
+ property Theme: TJvXPTheme read FTheme write SetTheme default WindowsXP;
+ property OnThemeChanged: TNotifyEvent read FOnThemeChanged write FOnThemeChanged;
+ end;
+
+ TJvXPCustomStyleControl = class(TJvXPCustomControl)
+ private
+ FStyle: TJvXPStyle;
+ FStyleManager: TJvXPStyleManager;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ protected
+ procedure SetStyleManager(Value: TJvXPStyleManager); virtual;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ property Style: TJvXPStyle read FStyle write FStyle;
+ property StyleManager: TJvXPStyleManager read FStyleManager write SetStyleManager;
+ end;
+23.09.2007 - SESS - unused *)
+
+ TJvXPGradientColors = 2..255;
+
+ TJvXPGradientStyle = (gsLeft, gsTop, gsRight, gsBottom);
+
+(* 23.09.2007 - SESS - unused
+ TJvXPGradient = class(TPersistent)
+ private
+ FColors: TJvXPGradientColors;
+ FDithered: Boolean;
+ FEnabled: Boolean;
+ FEndColor: TColor;
+ FStartColor: TColor;
+ FGradientStyle: TJvXPGradientStyle;
+ protected
+ Parent: TJvXPCustomControl;
+ procedure SetDithered(Value: Boolean); virtual;
+ procedure SetColors(Value: TJvXPGradientColors); virtual;
+ procedure SetEnabled(Value: Boolean); virtual;
+ procedure SetEndColor(Value: TColor); virtual;
+ procedure SetGradientStyle(Value: TJvXPGradientStyle); virtual;
+ procedure SetStartColor(Value: TColor); virtual;
+ public
+ Bitmap: TBitmap;
+ constructor Create(AOwner: TControl);
+ destructor Destroy; override;
+ procedure RecreateBands; virtual;
+ published
+ property Dithered: Boolean read FDithered write SetDithered default True;
+ property Colors: TJvXPGradientColors read FColors write SetColors default 16;
+ property Enabled: Boolean read FEnabled write SetEnabled default False;
+ property EndColor: TColor read FEndColor write SetEndColor default clSilver;
+ property StartColor: TColor read FStartColor write SetStartColor default clGray;
+ property Style: TJvXPGradientStyle read FGradientStyle write SetGradientStyle default gsLeft;
+ end;
+23.09.2007 - SESS - unused *)
+
+implementation
+
+(* 23.09.2007 - SESS - Original strings
+uses
+ JvXPCoreUtils;
+
+resourcestring
+ RsCopyright = 'Design eXperience. (c) 2002 M. Hoffmann Version ';
+ RsCopyright2 = 'Design eXperience II - (c) 2002 M. Hoffmann Version ';
+ RsVersion = '2.0.1'; // always increase version number on new releases!
+*)
+
+(* 23.09.2007 - SESS - unused
+//=== { TJvXPCustomComponent } ===============================================
+
+constructor TJvXPCustomComponent.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FVersion := RsCopyright + RsVersion;
+end;
+
+procedure TJvXPCustomComponent.SetVersion(const Value: string);
+begin
+ // do not enable overwriting this constant.
+end;
+23.09.2007 - SESS - unused *)
+
+//=== { TJvXPCustomControl } =================================================
+
+constructor TJvXPCustomControl.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ ControlStyle := ControlStyle + [csOpaque, csReplicatable];
+ DoubleBuffered := True;
+ ExControlStyle := [csRedrawEnabledChanged, csRedrawFocusedChanged,
+ csRedrawMouseDown, csRedrawMouseEnter, csRedrawMouseLeave, csRedrawMouseUp,
+ csRedrawParentColorChanged, csRedrawCaptionChanged];
+ FClicking := False;
+ FDrawState := [dsDefault];
+ FIsLocked := False;
+ FIsSibling := False;
+ FModalResult := 0;
+ // 23.09.2007 - SESS
+ // FVersion := RsCopyright2 + RsVersion;
+ FVersion := 'JvXP (JVCL) for Lazarus 1.0';
+end;
+
+procedure TJvXPCustomControl.SetVersion(const Value: string);
+begin
+ // disallow changing this property.
+end;
+
+procedure TJvXPCustomControl.BeginUpdate;
+begin
+ FIsLocked := True;
+end;
+
+procedure TJvXPCustomControl.EndUpdate;
+begin
+ FIsLocked := False;
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.LockedInvalidate;
+begin
+ if not IsLocked then
+ Invalidate;
+end;
+
+procedure TJvXPCustomControl.InternalRedraw;
+begin
+ if not FIsLocked then
+ Invalidate;
+end;
+
+
+
+procedure TJvXPCustomControl.CMDialogChar(var Msg: TCMDialogChar);
+begin
+ with Msg do
+ if IsAccel(CharCode, Caption) and CanFocus and
+ (Focused or ((GetKeyState(VK_MENU) and $8000) <> 0)) then
+ begin
+ Click;
+ Result := 1;
+ end
+ else
+ inherited;
+end;
+
+procedure TJvXPCustomControl.CMBorderChanged(var Msg: TLMessage);
+begin
+ // delegate message "BorderChanged" to hook.
+ inherited;
+ HookBorderChanged;
+end;
+
+procedure TJvXPCustomControl.CMEnabledChanged(var Msg: TLMessage);
+begin
+ // delegate message "EnabledChanged" to hook.
+ inherited;
+ HookEnabledChanged;
+end;
+
+
+procedure TJvXPCustomControl.CMFocusChanged(var Msg: TLMessage);
+begin
+ // delegate message "FocusChanged" to hook.
+ inherited;
+ HookFocusedChanged;
+end;
+
+
+procedure TJvXPCustomControl.CMMouseEnter(var Msg: TLMessage);
+begin
+ // delegate message "MouseEnter" to hook.
+ inherited;
+ HookMouseEnter;
+end;
+
+procedure TJvXPCustomControl.CMMouseLeave(var Msg: TLMessage);
+begin
+ // delegate message "MouseLeave" to hook.
+ inherited;
+ HookMouseLeave;
+end;
+
+procedure TJvXPCustomControl.CMParentColorChanged(var Msg: TLMessage);
+begin
+ // delegate message "ParentColorChanged" to hook.
+ inherited;
+ HookParentColorChanged;
+end;
+
+//21.09.07 - SESS resolver
+(*
+procedure TJvXPCustomControl.CMParentFontChanged(var Msg: TLMessage);
+begin
+ // delegate message "ParentFontChanged" to hook.
+ inherited;
+ HookParentFontChanged;
+end;
+*)
+procedure TJvXPCustomControl.CMTextChanged(var Msg: TLMessage);
+begin
+ // delegate message "TextChanged" to hook.
+ inherited;
+ HookTextChanged;
+end;
+
+procedure TJvXPCustomControl.WMMouseMove(var Msg: TLMMouse);
+begin
+ // delegate message "MouseMove" to hook.
+ inherited;
+ HookMouseMove(Msg.XPos, Msg.YPos);
+end;
+
+procedure TJvXPCustomControl.WMSize(var Msg: TLMSize);
+begin
+ // delegate message "Size" to hook.
+ inherited;
+ HookResized;
+end;
+
+procedure TJvXPCustomControl.WMWindowPosChanged(var Msg: TLMWindowPosChanged);
+begin
+ // delegate message "WindowPosChanged" to hook.
+ inherited;
+ HookPosChanged;
+end;
+
+procedure TJvXPCustomControl.MouseDown(Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+begin
+ // delegate message "MouseDown" to hook.
+ inherited MouseDown(Button, Shift, X, Y);
+ if Button = mbLeft then
+ begin
+ FClicking := True;
+ HookMouseDown;
+ end;
+end;
+
+procedure TJvXPCustomControl.MouseUp(Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+begin
+ // delegate message "MouseUp" to hook.
+ inherited MouseUp(Button, Shift, X, Y);
+ if FClicking then
+ begin
+ FClicking := False;
+ HookMouseUp;
+ end;
+end;
+
+procedure TJvXPCustomControl.Click;
+var
+ Form: TCustomForm;
+begin
+ Form := GetParentForm(Self);
+ if Form <> nil then
+ Form.ModalResult := ModalResult;
+ inherited Click;
+end;
+
+//
+// hooks are used to interrupt default windows messages in an easier
+// way - it's possible to override them in descendant classes.
+// Beware of multiple redraw calls - if you know that the calling
+// hooks always redraws the component, use the lock i.e. unlock methods
+// (rom) or LockedInvalidate.
+
+procedure TJvXPCustomControl.HookBorderChanged;
+begin
+ // this hook is called, if the border property was changed.
+ // in that case we normaly have to redraw the control.
+ if csRedrawBorderChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookEnabledChanged;
+begin
+ // this hook is called, if the enabled property was switched.
+ // in that case we normaly have to redraw the control.
+ if csRedrawEnabledChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookFocusedChanged;
+begin
+ // this hook is called, if the currently focused control was changed.
+ if Focused then
+ Include(FDrawState, dsFocused)
+ else
+ begin
+ Exclude(FDrawState, dsFocused);
+ Exclude(FDrawState, dsClicked);
+ end;
+ FIsSibling := GetParentForm(Self).ActiveControl is TJvXPCustomControl;
+ if csRedrawFocusedChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookMouseEnter;
+begin
+ // this hook is called, if the user moves (hover) the mouse over the control.
+ if not (csDesigning in ComponentState) then
+ begin
+ Include(FDrawState, dsHighlight);
+ if csRedrawMouseEnter in ExControlStyle then
+ InternalRedraw;
+ end;
+ if Assigned(FOnMouseEnter) then
+ FOnMouseEnter(Self);
+end;
+
+procedure TJvXPCustomControl.HookMouseLeave;
+begin
+ // this hook is called, if the user moves the mouse away (unhover) from
+ // the control.
+ if not (csDesigning in ComponentState) then
+ begin
+ Exclude(FDrawState, dsHighlight);
+ if csRedrawMouseLeave in ExControlStyle then
+ InternalRedraw;
+ end;
+ if Assigned(FOnMouseLeave) then
+ FOnMouseLeave(Self);
+end;
+
+procedure TJvXPCustomControl.HookMouseMove(X: Integer = 0; Y: Integer = 0);
+begin
+ // this hook is called if the user moves the mouse inside the control.
+ if not (csDesigning in ComponentState) then
+ if csRedrawMouseMove in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookMouseDown;
+begin
+ // this hook is called, if the user presses the left mouse button over the
+ // controls.
+ if not Focused and CanFocus then
+ SetFocus;
+ Include(FDrawState, dsClicked);
+ if csRedrawMouseDown in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookMouseUp;
+var
+ CurrentPos: TPoint;
+ NewControl: TWinControl;
+begin
+ // this hook is called, if the user releases the left mouse button.
+ begin
+ Exclude(FDrawState, dsClicked);
+ if csRedrawMouseUp in ExControlStyle then
+ InternalRedraw;
+
+ // does the cursor is over another supported control?
+ GetCursorPos(CurrentPos);
+ //21.09.2007 - SESS resolver
+ //NewControl := FindVCLWindow(CurrentPos);
+ NewControl := nil;
+ if (NewControl <> nil) and (NewControl <> Self) and
+ (NewControl.InheritsFrom(TJvXPCustomControl)) then
+ TJvXPCustomControl(NewControl).HookMouseEnter;
+ end;
+end;
+
+procedure TJvXPCustomControl.HookParentColorChanged;
+begin
+ // this hook is called if, the parent color was changed.
+ if csRedrawParentColorChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookParentFontChanged;
+begin
+ // this hook is called if, the parent font was changed.
+ if csRedrawParentFontChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookPosChanged;
+begin
+ // this hook is called, if the window position was changed.
+ if csRedrawPosChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookResized;
+begin
+ // this hook is called, if the control was resized.
+ if csRedrawResized in ExControlStyle then
+ InternalRedraw;
+end;
+
+procedure TJvXPCustomControl.HookTextChanged;
+begin
+ // this hook is called, if the caption was changed.
+ if csRedrawCaptionChanged in ExControlStyle then
+ InternalRedraw;
+end;
+
+(* 23.09.2007 - SESS - unused
+//=== { TJvXPStyle } =========================================================
+
+constructor TJvXPStyle.Create(AOwner: TComponent);
+begin
+ inherited Create;
+ Parent := TJvXPCustomStyleControl(AOwner);
+ FTheme := WindowsXP;
+ FUseStyleManager := True;
+end;
+
+procedure TJvXPStyle.SetTheme(Value: TJvXPTheme);
+begin
+ if Value <> FTheme then
+ begin
+ FTheme := Value;
+ Parent.InternalRedraw;
+ end;
+end;
+
+function TJvXPStyle.GetTheme: TJvXPTheme;
+begin
+ Result := FTheme;
+ if FUseStyleManager and Assigned(Parent.StyleManager) then
+ Result := Parent.StyleManager.Theme;
+end;
+
+procedure TJvXPStyle.SetUseStyleManager(Value: Boolean);
+begin
+ if Value <> FUseStyleManager then
+ begin
+ FUseStyleManager := Value;
+ Parent.InternalRedraw;
+ end;
+end;
+
+//=== { TJvXPStyleManager } ==================================================
+
+constructor TJvXPStyleManager.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FControls := TList.Create;
+ FTheme := WindowsXP;
+end;
+
+destructor TJvXPStyleManager.Destroy;
+begin
+ InvalidateControls;
+ FControls.Free;
+ inherited Destroy;
+end;
+
+procedure TJvXPStyleManager.InvalidateControls;
+var
+ I: Integer;
+begin
+ for I := 0 to FControls.Count - 1 do
+ with TJvXPCustomControl(FControls[I]) do
+ InternalRedraw;
+end;
+
+procedure TJvXPStyleManager.SetTheme(Value: TJvXPTheme);
+begin
+ if Value <> FTheme then
+ begin
+ FTheme := Value;
+ if Assigned(FOnThemeChanged) then
+ FOnThemeChanged(Self);
+ InvalidateControls;
+ end;
+end;
+
+procedure TJvXPStyleManager.RegisterControls(const AControls: array of TJvXPCustomControl);
+var
+ I: Integer;
+begin
+ for I := Low(AControls) to High(AControls) do
+ if FControls.IndexOf(AControls[I]) = -1 then
+ FControls.Add(AControls[I]);
+end;
+
+procedure TJvXPStyleManager.UnregisterControls(const AControls: array of TJvXPCustomControl);
+var
+ I: Integer;
+begin
+ for I := Low(AControls) to High(AControls) do
+ if FControls.IndexOf(AControls[I]) <> -1 then
+ FControls.Delete(FControls.IndexOf(AControls[I]));
+end;
+
+//=== { TJvXPCustomStyleControl } ============================================
+
+constructor TJvXPCustomStyleControl.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FStyle := TJvXPStyle.Create(Self);
+ FStyleManager := nil;
+end;
+
+destructor TJvXPCustomStyleControl.Destroy;
+begin
+ if FStyleManager <> nil then
+ FStyleManager.UnregisterControls([Self]);
+ FStyle.Free;
+ inherited Destroy;
+end;
+
+procedure TJvXPCustomStyleControl.Notification(AComponent: TComponent;
+ Operation: TOperation);
+begin
+ if (AComponent is TJvXPStyleManager) and (Operation = opRemove) then
+ FStyleManager := nil;
+ inherited Notification(AComponent, Operation);
+end;
+
+procedure TJvXPCustomStyleControl.SetStyleManager(Value: TJvXPStyleManager);
+begin
+ if Value <> FStyleManager then
+ begin
+ if Value <> nil then
+ Value.RegisterControls([Self])
+ else
+ FStyleManager.UnregisterControls([Self]);
+ FStyleManager := Value;
+ InternalRedraw;
+ end;
+end;
+
+//=== { TJvXPGradient } ======================================================
+
+constructor TJvXPGradient.Create(AOwner: TControl);
+begin
+ inherited Create;
+ Parent := TJvXPCustomControl(AOwner);
+ Bitmap := TBitmap.Create;
+ FColors := 16;
+ FDithered := True;
+ FEnabled := False;
+ FEndColor := clSilver;
+ FGradientStyle := gsLeft;
+ FStartColor := clGray;
+end;
+
+destructor TJvXPGradient.Destroy;
+begin
+ Bitmap.Free;
+ inherited Destroy;
+end;
+
+procedure TJvXPGradient.RecreateBands;
+begin
+ if Assigned(Bitmap) then
+ JvXPCreateGradientRect(Parent.Width, Parent.Height, FStartColor, FEndColor,
+ FColors, FGradientStyle, FDithered, Bitmap);
+end;
+
+procedure TJvXPGradient.SetDithered(Value: Boolean);
+begin
+ if FDithered <> Value then
+ begin
+ FDithered := Value;
+ RecreateBands;
+ Parent.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPGradient.SetColors(Value: TJvXPGradientColors);
+begin
+ if FColors <> Value then
+ begin
+ FColors := Value;
+ RecreateBands;
+ Parent.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPGradient.SetEnabled(Value: Boolean);
+begin
+ if FEnabled <> Value then
+ begin
+ FEnabled := Value;
+ Parent.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPGradient.SetEndColor(Value: TColor);
+begin
+ if FEndColor <> Value then
+ begin
+ FEndColor := Value;
+ RecreateBands;
+ Parent.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPGradient.SetGradientStyle(Value: TJvXPGradientStyle);
+begin
+ if FGradientStyle <> Value then
+ begin
+ FGradientStyle := Value;
+ RecreateBands;
+ Parent.InternalRedraw;
+ end;
+end;
+
+procedure TJvXPGradient.SetStartColor(Value: TColor);
+begin
+ if FStartColor <> Value then
+ begin
+ FStartColor := Value;
+ RecreateBands;
+ Parent.InternalRedraw;
+ end;
+end;
+*)
+end.
+
diff --git a/components/jvcllaz/run/JvXPCoreUtils.pas b/components/jvcllaz/run/JvXPCoreUtils.pas
new file mode 100644
index 000000000..dadb05783
--- /dev/null
+++ b/components/jvcllaz/run/JvXPCoreUtils.pas
@@ -0,0 +1,419 @@
+{-----------------------------------------------------------------------------
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is: JvXPCoreUtils.PAS, released on 2004-01-01.
+
+The Initial Developer of the Original Code is Marc Hoffman.
+Portions created by Marc Hoffman are Copyright (C) 2002 APRIORI business solutions AG.
+Portions created by APRIORI business solutions AG are Copyright (C) 2002 APRIORI business solutions AG
+All Rights Reserved.
+
+Contributor(s):
+
+You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
+located at http://jvcl.sourceforge.net
+
+Known Issues:
+-----------------------------------------------------------------------------}
+// $Id: JvXPCoreUtils.pas 11400 2007-06-28 21:24:06Z ahuser $
+
+// Ported to Lazarus (no too hard after all) by Sergio Samayoa - september 2007.
+// Still dont tested on linux.
+
+unit JvXPCoreUtils;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, Controls, Graphics, LCLIntf, LCLType, SysUtils,
+ TypInfo, JvXPCore;
+
+function JvXPMethodsEqual(const Method1, Method2: TMethod): Boolean;
+procedure JvXPDrawLine(const ACanvas: TCanvas; const X1, Y1, X2, Y2: Integer);
+
+(* 23.09.2007 - SESS - unused
+procedure JvXPCreateGradientRect(const AWidth, AHeight: Integer; const StartColor,
+ EndColor: TColor; const AColors: TJvXPGradientColors; const Style: TJvXPGradientStyle;
+ const Dithered: Boolean; var Bitmap: TBitmap);
+procedure JvXPAdjustBoundRect(const BorderWidth: Byte;
+ const ShowBoundLines: Boolean; const BoundLines: TJvXPBoundLines; var Rect: TRect);
+procedure JvXPDrawBoundLines(const ACanvas: TCanvas; const BoundLines: TJvXPBoundLines;
+ const AColor: TColor; const Rect: TRect);
+
+//
+// attic!
+//
+
+procedure JvXPConvertToGray2(Bitmap: TBitmap);
+procedure JvXPRenderText(const AParent: TControl; const ACanvas: TCanvas;
+ ACaption: TCaption; const AFont: TFont; const AEnabled, AShowAccelChar: Boolean;
+ var ARect: TRect; AFlags: Integer);
+23.09.2007 - SESS - unused *)
+procedure JvXPFrame3D(const ACanvas: TCanvas; const ARect: TRect;
+ const TopColor, BottomColor: TColor; const Swapped: Boolean = False);
+(* 23.09.2007 - SESS - unused
+procedure JvXPColorizeBitmap(Bitmap: TBitmap; const AColor: TColor);
+procedure JvXPSetDrawFlags(const AAlignment: TAlignment; const AWordWrap: Boolean;
+ var Flags: Integer);
+procedure JvXPPlaceText(const AParent: TControl; const ACanvas: TCanvas;
+ const AText: TCaption; const AFont: TFont; const AEnabled, AShowAccelChar: Boolean;
+ const AAlignment: TAlignment; const AWordWrap: Boolean; var Rect: TRect);
+23.09.2007 - SESS - unused *)
+
+implementation
+
+function JvXPMethodsEqual(const Method1, Method2: TMethod): Boolean;
+begin
+ Result := (Method1.Code = Method2.Code) and (Method1.Data = Method2.Data);
+end;
+
+(* 23.09.2007 - SESS - unused
+procedure JvXPCreateGradientRect(const AWidth, AHeight: Integer; const StartColor,
+ EndColor: TColor; const AColors: TJvXPGradientColors; const Style: TJvXPGradientStyle;
+ const Dithered: Boolean; var Bitmap: TBitmap);
+{ // Short version...
+var
+ gd: TGradientDirection;
+begin
+ if (AHeight <= 0) or (AWidth <= 0) then
+ Exit;
+ Bitmap.Height := AHeight;
+ Bitmap.Width := AWidth;
+ Bitmap.PixelFormat := pf24bit;
+ if Style in [gsLeft, gsRight] then
+ gd := gdHorizontal
+ else
+ gd := gdVertical;
+ Bitmap.Canvas.GradientFill(Rect(0, 0, AWidth, AHeight), StartColor, EndColor, gd);
+end;
+}
+const
+ PixelCountMax = 32768;
+ DitherDepth = 16;
+type
+ TGradientBand = array [0..255] of TColor;
+ TRGBMap = packed record
+ case Boolean of
+ True:
+ (RGBVal: DWord);
+ False:
+ (R, G, B, D: Byte);
+ end;
+ PRGBTripleArray = ^TRGBTripleArray;
+ TRGBTripleArray = array [0..PixelCountMax-1] of TRGBTriple;
+var
+ iLoop, xLoop, yLoop, XX, YY: Integer;
+ iBndS, iBndE: Integer;
+ GBand: TGradientBand;
+ Row: PRGBTripleArray;
+
+ procedure CalculateGradientBand;
+ var
+ rR, rG, rB: Real;
+ lCol, hCol: TRGBMap;
+ iStp: Integer;
+ begin
+ if Style in [gsLeft, gsTop] then
+ begin
+ lCol.RGBVal := ColorToRGB(StartColor);
+ hCol.RGBVal := ColorToRGB(EndColor);
+ end
+ else
+ begin
+ lCol.RGBVal := ColorToRGB(EndColor);
+ hCol.RGBVal := ColorToRGB(StartColor);
+ end;
+ rR := (hCol.R - lCol.R) / (AColors - 1);
+ rG := (hCol.G - lCol.G) / (AColors - 1);
+ rB := (hCol.B - lCol.B) / (AColors - 1);
+ for iStp := 0 to (AColors - 1) do
+ GBand[iStp] := RGB(
+ lCol.R + Round(rR * iStp),
+ lCol.G + Round(rG * iStp),
+ lCol.B + Round(rB * iStp));
+ end;
+
+begin
+ // Exit if Height or Width are not positive. If not, the calls would lead to
+ // GDI errors about "Invalid parameter" and/or "Out Of Resources".
+ if (AHeight <= 0) or (AWidth <= 0) then
+ Exit;
+
+ Bitmap.Height := AHeight;
+ Bitmap.Width := AWidth;
+ Bitmap.PixelFormat := pf24bit;
+
+ CalculateGradientBand;
+
+ with Bitmap.Canvas do
+ begin
+ Brush.Color := StartColor;
+ FillRect(Bounds(0, 0, AWidth, AHeight));
+ if Style in [gsLeft, gsRight] then
+ begin
+ for iLoop := 0 to AColors - 1 do
+ begin
+ iBndS := MulDiv(iLoop, AWidth, AColors);
+ iBndE := MulDiv(iLoop + 1, AWidth, AColors);
+ Brush.Color := GBand[iLoop];
+ PatBlt(Handle, iBndS, 0, iBndE, AHeigth, PATCOPY);
+ if (iLoop > 0) and Dithered then
+ for yLoop := 0 to DitherDepth - 1 do
+ if yLoop < AHeight then
+ begin
+ Row := Bitmap.ScanLine[yLoop];
+ for xLoop := 0 to AWidth div (AColors - 1) do
+ begin
+ XX := iBndS + Random(xLoop);
+ if (XX < AWidth) and (XX > -1) then
+ with Row[XX] do
+ begin
+ rgbtRed := GetRValue(GBand[iLoop - 1]);
+ rgbtGreen := GetGValue(GBand[iLoop - 1]);
+ rgbtBlue := GetBValue(GBand[iLoop - 1]);
+ end;
+ end;
+ end;
+ end;
+ for yLoop := 1 to AHeight div DitherDepth do
+ CopyRect(Bounds(0, yLoop * DitherDepth, AWidth, DitherDepth),
+ Bitmap.Canvas, Bounds(0, 0, AWidth, DitherDepth));
+ end
+ else
+ begin
+ for iLoop := 0 to AColors - 1 do
+ begin
+ iBndS := MulDiv(iLoop, AHeight, AColors);
+ iBndE := MulDiv(iLoop + 1, AHeight, AColors);
+ Brush.Color := GBand[iLoop];
+ PatBlt(Handle, 0, iBndS, AWidth, iBndE, PATCOPY);
+ if (iLoop > 0) and Dithered then
+ for yLoop := 0 to AHeight div (AColors - 1) do
+ begin
+ YY := iBndS + Random(yLoop);
+ if (YY < AHeight) and (YY > -1) then
+ begin
+ Row := Bitmap.ScanLine[YY];
+ for xLoop := 0 to DitherDepth - 1 do
+ if xLoop < AWidth then
+ with Row[xLoop] do
+ begin
+ rgbtRed := GetRValue(GBand[iLoop - 1]);
+ rgbtGreen := GetGValue(GBand[iLoop - 1]);
+ rgbtBlue := GetBValue(GBand[iLoop - 1]);
+ end;
+ end;
+ end;
+ end;
+ for xLoop := 0 to AWidth div DitherDepth do
+ CopyRect(Bounds(xLoop * DitherDepth, 0, DitherDepth, AHeight),
+ Bitmap.Canvas, Bounds(0, 0, DitherDepth, AHeight));
+ end;
+ end;
+end;
+*)
+
+procedure JvXPDrawLine(const ACanvas: TCanvas; const X1, Y1, X2, Y2: Integer);
+begin
+ with ACanvas do
+ begin
+ MoveTo(X1, Y1);
+ LineTo(X2, Y2);
+ end;
+end;
+
+(* 23.09.2007 - SESS - unused
+procedure JvXPAdjustBoundRect(const BorderWidth: Byte;
+ const ShowBoundLines: Boolean; const BoundLines: TJvXPBoundLines;
+ var Rect: TRect);
+begin
+ InflateRect(Rect, -BorderWidth, -BorderWidth);
+ if not ShowBoundLines then
+ Exit;
+ if blLeft in BoundLines then
+ Inc(Rect.Left);
+ if blRight in BoundLines then
+ Dec(Rect.Right);
+ if blTop in BoundLines then
+ Inc(Rect.Top);
+ if blBottom in BoundLines then
+ Dec(Rect.Bottom);
+end;
+
+procedure JvXPDrawBoundLines(const ACanvas: TCanvas; const BoundLines: TJvXPBoundLines;
+ const AColor: TColor; const Rect: TRect);
+begin
+ with ACanvas do
+ begin
+ Pen.Color := AColor;
+ Pen.Style := psSolid;
+ if blLeft in BoundLines then
+ JvXPDrawLine(ACanvas, Rect.Left, Rect.Top, Rect.Left, Rect.Bottom - 1);
+ if blTop in BoundLines then
+ JvXPDrawLine(ACanvas, Rect.Left, Rect.Top, Rect.Right, Rect.Top);
+ if blRight in BoundLines then
+ JvXPDrawLine(ACanvas, Rect.Right - 1, Rect.Top, Rect.Right - 1, Rect.Bottom - 1);
+ if blBottom in BoundLines then
+ JvXPDrawLine(ACanvas, Rect.Top, Rect.Bottom - 1, Rect.Right, Rect.Bottom - 1);
+ end;
+end;
+
+//
+// attic
+//
+
+procedure JvXPConvertToGray2(Bitmap: TBitmap);
+var
+ x, y, c: Integer;
+ PxlColor: TColor;
+begin
+ for x := 0 to Bitmap.Width - 1 do
+ for y := 0 to Bitmap.Height - 1 do
+ begin
+ PxlColor := ColorToRGB(Bitmap.Canvas.Pixels[x, y]);
+ c := (PxlColor shr 16 + ((PxlColor shr 8) and $00FF) + PxlColor and $0000FF) div 3 + 100;
+ if c > 255 then
+ c := 255;
+ Bitmap.Canvas.Pixels[x, y] := RGB(c, c, c);
+ end;
+end;
+
+procedure JvXPRenderText(const AParent: TControl; const ACanvas: TCanvas;
+ ACaption: TCaption; const AFont: TFont; const AEnabled, AShowAccelChar: Boolean;
+ var ARect: TRect; AFlags: Integer);
+
+ procedure DoDrawText;
+ begin
+ // (rom) Kludge! This will probably not work for CLX
+ DrawText(ACanvas.Handle, PChar(ACaption), -1, ARect, AFlags);
+ end;
+
+begin
+ if (AFlags and DT_CALCRECT <> 0) and ((ACaption = '') or AShowAccelChar and
+ (ACaption[1] = '&') and (ACaption[2] = #0)) then
+ ACaption := ACaption + ' ';
+ if not AShowAccelChar then
+ AFlags := AFlags or DT_NOPREFIX;
+ AFlags := AParent.DrawTextBiDiModeFlags(AFlags);
+ with ACanvas do
+ begin
+ Font.Assign(AFont);
+ if not AEnabled then
+ Font.Color := dxColor_Msc_Dis_Caption_WXP;
+ if not AEnabled then
+ begin
+ OffsetRect(ARect, 1, 1);
+ Font.Color := clBtnHighlight;
+ DoDrawText;
+ OffsetRect(ARect, -1, -1);
+ Font.Color := clBtnShadow;
+ DoDrawText;
+ end
+ else
+ DoDrawText;
+ end;
+end;
+23.09.2007 - SESS - unused *)
+
+procedure JvXPFrame3D(const ACanvas: TCanvas; const ARect: TRect;
+ const TopColor, BottomColor: TColor; const Swapped: Boolean = False);
+var
+ ATopColor, ABottomColor: TColor;
+begin
+ ATopColor := TopColor;
+ ABottomColor := BottomColor;
+ if Swapped then
+ begin
+ ATopColor := BottomColor;
+ ABottomColor := TopColor;
+ end;
+ with ACanvas do
+ begin
+ Pen.Color := ATopColor;
+ // 21.09.07 - SESS
+ Polyline([
+ Classes.Point(ARect.Left, ARect.Bottom - 1),
+ Classes.Point(ARect.Left, ARect.Top),
+ Classes.Point(ARect.Right - 1, ARect.Top)]);
+ Pen.Color := ABottomColor;
+ Polyline([
+ Classes.Point(ARect.Right - 1, ARect.Top + 1),
+ Classes.Point(ARect.Right - 1 , ARect.Bottom - 1),
+ Classes.Point(ARect.Left, ARect.Bottom - 1)]);
+ end;
+end;
+
+(* 23.09.2007 - SESS - unused
+procedure JvXPColorizeBitmap(Bitmap: TBitmap; const AColor: TColor);
+var
+ ColorMap: TBitmap;
+ Rect: TRect;
+begin
+ Rect := Bounds(0, 0, Bitmap.Width, Bitmap.Height);
+ ColorMap := TBitmap.Create;
+ try
+ ColorMap.Assign(Bitmap);
+ Bitmap.FreeImage;
+ with ColorMap.Canvas do
+ begin
+ Brush.Color := AColor;
+ BrushCopy( Rect, Bitmap, Rect, clBlack);
+ end;
+ Bitmap.Assign(ColorMap);
+ finally
+ ColorMap.Free;
+ end;
+end;
+
+procedure JvXPSetDrawFlags(const AAlignment: TAlignment; const AWordWrap: Boolean;
+ var Flags: Integer);
+begin
+ Flags := DT_END_ELLIPSIS;
+ case AAlignment of
+ taLeftJustify:
+ Flags := Flags or DT_LEFT;
+ taCenter:
+ Flags := Flags or DT_CENTER;
+ taRightJustify:
+ Flags := Flags or DT_RIGHT;
+ end;
+ if not AWordWrap then
+ Flags := Flags or DT_SINGLELINE
+ else
+ Flags := Flags or DT_WORDBREAK;
+end;
+
+procedure JvXPPlaceText(const AParent: TControl; const ACanvas: TCanvas; const AText: TCaption;
+ const AFont: TFont; const AEnabled, AShowAccelChar: Boolean; const AAlignment: TAlignment;
+ const AWordWrap: Boolean; var Rect: TRect);
+var
+ Flags, DX, OH, OW: Integer;
+begin
+ OH := Rect.Bottom - Rect.Top;
+ OW := Rect.Right - Rect.Left;
+ JvXPSetDrawFlags(AAlignment, AWordWrap, Flags);
+ JvXPRenderText(AParent, ACanvas, AText, AFont, AEnabled, AShowAccelChar, Rect,
+ Flags or DT_CALCRECT);
+ if AAlignment = taRightJustify then
+ DX := OW - (Rect.Right + Rect.Left)
+ else
+ if AAlignment = taCenter then
+ DX := (OW - Rect.Right) div 2
+ else
+ DX := 0;
+ OffsetRect(Rect, DX, (OH - Rect.Bottom) div 2);
+ JvXPRenderText(AParent, ACanvas, AText, AFont, AEnabled, AShowAccelChar, Rect, Flags);
+end;
+23.09.2007 - SESS - unused *)
+
+end.
+