diff --git a/README.md b/README.md
index 693154d..992110f 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,11 @@
+
+
+
+
+
+
+
+
What is Linkbar ?
===============================
Linkbar is a free source code desktop toolbar. Running in the MS Windows Vista+ environment, its use is governed by
diff --git a/components/ColorPicker/ColorPicker.pas b/components/ColorPicker/ColorPicker.pas
index 9809442..374371b 100644
--- a/components/ColorPicker/ColorPicker.pas
+++ b/components/ColorPicker/ColorPicker.pas
@@ -91,6 +91,7 @@ TfrmColorPicker = class(TForm)
LastHue: Integer;
TextEnter: Boolean;
AlpBarHeight: Integer;
+ procedure L10n;
public
procedure PaintVar;
procedure PaintColorHue;
@@ -104,7 +105,7 @@ implementation
{$R *.dfm}
uses
- ColorUtils, GdiPlusHelpers, GdiPlus;
+ ColorUtils, GdiPlusHelpers, GdiPlus, Linkbar.L10n;
function TfrmColorPicker.GetColor: Cardinal;
begin
@@ -244,6 +245,13 @@ procedure TfrmColorPicker.editColor1KeyUp(Sender: TObject; var Key: Word;
TextEnter := False;
end;
+procedure TfrmColorPicker.L10n;
+begin
+ L10nControl(Self, 'Color.Caption');
+ L10nControl(btnOk, 'Color.OK');
+ L10nControl(btnCancel, 'Color.Cancel');
+end;
+
procedure TfrmColorPicker.FormCreate(Sender: TObject);
const
Colors: array[0..15] of TColor = (clBlack, clWhite, clGray, clSilver,
@@ -252,6 +260,8 @@ procedure TfrmColorPicker.FormCreate(Sender: TObject);
var
i: Integer;
begin
+ L10n;
+
AlpBarHeight := imgAlpha.Height - 1;
HBoxBmp := TBitmap.Create;
diff --git a/components/DelLoc/LcUnitXe.pas b/components/DelLoc/LcUnitXe.pas
deleted file mode 100644
index e42770e..0000000
--- a/components/DelLoc/LcUnitXe.pas
+++ /dev/null
@@ -1,875 +0,0 @@
-{* DelLocXe. LcUnitXe.pas. Serge Gavrilov ( C ) 2005-2012 *************************************** *}
-
-unit LcUnitXE;
-
-{
- DelLocXE (Delphi localization compiler for Xe) for Delphi XE. Interface unit.
-
- All right reserved. Serge Gavrilov (C) 2005-2012.
-
- e-mail: s.gav@mail.ru
- icq: 777807
- http://delloc.narod.ru/en.html
-
-
- To localize your delphi program You have to make next simple things:
- 1. Create with DelLoc the localization file that will
- include translations of the resourcestrings and translations of the form's
- and component's string properties.
- 2. Include unit LcUnitXe.pas in your project or make it available in search
- pathes.
- 3. In project source: after loading application call function LoadLcf() where
- pass as parameters localization file name and locale identificator (LCID)
- that will be used to translate. You may place the call of LoadLcf() in
- project source file after "begin" keyword or in the initialization section
- of the any project unit.
- 4. After creating form which interface and components need to be translatad
- call function TranslateComponent() and pass as parameter the created form.
- You may place call at the body of the overrided constructor after
- "inherited" keyword or in the OnCreate event handler. If you inherites
- all project forms from one base form class you may provide call of the
- TranslateComponent() only for the base form class.
-
- Unit LcUnitXe.pas includes declaration of the two functions: LoadLcf() and
- TranslateComponent(), and declare one type: TLcCallBack.
-
- Function LoadLcf() loads localization file and activates translation for
- the passed locale identificator.
-
- function LoadLcf(
- const sFileName : nstr;
- iLCID : LCID;
- pCallBack : TLcCallBack;
- pUd : pointer
- ) : integer;
-
- Parameters:
- sFileName - localization file name;
- iLCID - locale identificator to activate. Use Delphi's class TLanguages
- to inspect all available locale identificators and its string
- descriptions.
- pCallBack - pointer to callback function of type TLcCallBack. If this
- parameter is not null then the callback function will be called
- for each locale identificator supported by the localization
- file.
- pUd - used difened pointer. Will be passed as parameter to the callback
- function pCallBack.
-
- Result:
- 1 - localization file was loaded and translation for requeted locale
- was activated;
- 0 - localization file was loaded but translation for requeted locale is
- not present in the localization file. Translation will not be make.
- <0 - localization file error loading. Translation will not be make.
-
- Function TranslateComponent() translate the interface and form's
- components string propertied.
-
- function TranslateComponent(
- oComponent : TComponent
- ) : boolean;
-
- Parameters:
- oComponent - Form which interface and components will be localized.
- Result:
- true - localization success;
- false - localization error.
-
- The type TLcCallBack is a prototype of the callback function which pointer is
- passed into LoadLcf() as parameter. The callback function will be called
- for each locale identificator supported by the localization file.
-
- type
- TLcCallBack = function(
- iLCID : integer;
- pUd : pointer
- ) : integer; stdcall;
-
- Parameters:
- iLCID - locale identificator supported in localization file;
- pUd - user defined pointer passed into LoadLcf() as parameter.
- Result:
- 0 - stop calling callback for the next locale ids;
- <>0 - continue the callback calls for the next locale ids.
-
- To switch the langauges at runtime You may use next code:
-
- var
- i : integer;
- begin
- for i := 0 to Screen.FormCount - 1
- do TranslateComponent( Screen.Forms[ i ] );
- end;
-
-
- THIS UNIT IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED
- OR IMPLIED. YOU USE AT YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE
- FOR DATA LOSS, DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS
- WHILE USING OR MISUSING THIS SOFTWARE.
-
-}
-
-interface
-
-uses
- SysUtils, Windows, Classes, StrUtils, TypInfo;
-
-type
-
- str = AnsiString;
- nstr = string;
- nchr = Char;
- chr = AnsiChar;
- wstr = WideString;
- pchr = PAnsiChar;
- wchr = WideChar;
- pwchr = PWideChar;
- pnchr = PChar;
-
- TLcCallBack = function( iLCID : integer; pUd : pointer ) : integer; stdcall;
- TLcOnGetRes = function(
- const sResStr : wstr;
- var iLCID : integer;
- var iCPage : integer;
- pUd : pointer ) : integer; stdcall;
-
- TPLcLoadOpts = ^TLcLoadOpts;
- TLcLoadOpts = record
- iSize : integer;
- iLCID : LCID;
- pCallBack : TLcCallBack;
- pOnGetResStr : TLcOnGetRes;
- pUd : pointer;
- end;
-
-function LoadLcf(
- const sFileName : nstr;
- iLCID : LCID;
- pCallBack : TLcCallBack;
- pUd : pointer
- ) : integer;
-
-function LoadLcfEx(
- const sFileName : nstr;
- pOpts : TPLcLoadOpts
- ) : integer;
-
-function TranslateComponent( oComponent : TComponent ) : boolean;
-function TranslateComponentEx(
- oComponent : TComponent;
- iLCID : LCID ) : boolean;
-
-
-
-implementation
-
-{* ************************************************************************** *}
-
-const
- LC_OPT_PROJINFO = 1;
- LC_SIGNATURE = 'LCHEADER';
- LC_HEADE3_RESID = 'LCHEADE3';
-
-type
-
-{* ************************************************************************** *}
-
- TLcHeaderRec = packed record
- aSign : packed array[ 0..Length( LC_SIGNATURE ) - 1 ] of chr;
- iOpts : integer;
- iLCIDCount : integer;
- end;
- TPLcHeaderRec = ^TLcHeaderRec;
-
-{* ************************************************************************** *}
-
- TLcHeaderResRec = packed record
- rHeader : TLcHeaderRec;
- aLCID : packed array[ 0..0 ] of LCID;
- end;
- TPLcHeaderResRec = ^TLcHeaderResRec;
-
-{* ************************************************************************** *}
-
- TLcCPages = packed array[ 0..0 ] of UINT;
- TPLcCPages = ^TLcCPages;
-
-{* ************************************************************************** *}
-
- TLcResItemStr = packed record
- iOffset : integer;
- iLength : integer;
- end;
- TLcResItemRec = packed array[ 0..0 ] of TLcResItemStr;
- TPLcResItemRec = ^TLcResItemRec;
-
-{* ************************************************************************** *}
-
-type
-
- TProc = class
- private
- aOriginal : packed array[ 0..4 ] of byte;
- pOldProc, pNewProc : pointer;
- pPosition : PByteArray;
- public
- constructor Create( pOldProc, pNewProc : pointer );
- destructor Destroy; override;
- end;
-
-{* ************************************************************************** *}
-
- TLcf = class
- private
- iLangIndex : integer;
- iPropLangIndex : integer;
- iLibHandle : THANDLE;
- iLCID : LCID;
- iCPage : UINT;
- aProc : array[ 0..0 ] of TProc;
- pUd : pointer;
- pOnGetResStr : TLcOnGetRes;
- pHeader : TPLcHeaderResRec;
- isOldFormat : boolean;
- public
- constructor Create;
- destructor Destroy; override;
- function LoadLib( szFileName : PChar; iLCID : LCID;
- pCallBack : TLcCallBack; pOnGetResStr : TLcOnGetRes;
- pUd : pointer ) : integer;
- function LoadLibEx( szFileName : PChar; pOpts : TPLcLoadOpts ) : integer;
- function GetResString( pResStrRec : PResStringRec ) : nstr;
- function TranslateComponent(
- oComponent : TComponent;
- iLCID : LCID ) : boolean;
- procedure RegProcs( pN1, pO1 : pointer );
- function GetLangIndex( iLCID : LCID;
- pLangIndex : pinteger;
- pPropLangIndex : pinteger;
- var iCPage : UINT ) : boolean;
- end;
-
-{* ************************************************************************** *}
-
-var
-
- _oLcf : TLcf = nil;
-
-{* ************************************************************************** *}
-
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-constructor TProc.Create;
-var
- iOffset : integer;
- iMemProtect : cardinal;
- i : integer;
-begin
- Self.pOldProc := pOldProc;
- Self.pNewProc := pNewProc;
-
- pPosition := pOldProc;
- iOffset := integer( pNewProc ) - integer( pointer( pPosition ) ) - 5;
-
- for i := 0 to 4 do aOriginal[ i ] := pPosition^[ i ];
-
- if not VirtualProtect( pointer( pPosition ), 5, PAGE_EXECUTE_READWRITE, @iMemProtect )
- then RaiseLastOsError;
-
- pPosition^[ 0 ] := $E9;
- pPosition^[ 1 ] := byte( iOffset );
- pPosition^[ 2 ] := byte( iOffset shr 8 );
- pPosition^[ 3 ] := byte( iOffset shr 16 );
- pPosition^[ 4 ] := byte( iOffset shr 24 );
-
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-destructor TProc.Destroy;
-var
- i : integer;
-begin
- for i := 0 to 4 do pPosition^[ i ] := aOriginal[ i ];
- inherited;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-
-{* ************************************************************************** *}
-
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-constructor TLcf.Create;
-begin
- _oLcf := Self;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-destructor TLcf.Destroy;
-var
- i : integer;
-begin
- _oLcf := nil;
- for i := Low( aProc ) to High( aProc ) do aProc[ i ].Free;
- if iLibHandle <> 0 then FreeLibrary( iLibHandle );
- inherited;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function LCIDToCodePage( iLCID : LCID ) : UINT;
-var
- iResultCode : integer;
- p : array[ 0..6 ] of nchr;
-begin
- GetLocaleInfo( iLCID, LOCALE_IDEFAULTANSICODEPAGE, p, Length( p ) );
- Val( p, result, iResultCode );
- if iResultCode <> 0 then result := CP_ACP;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TLcf.GetLangIndex;
-var
- i : integer;
- pPages : TPLcCPages;
-begin
-
- result := false;
- if pHeader = nil then exit;
-
- if iLCID = Self.iLCID
- then begin
- if pLangIndex <> nil then pLangIndex^ := Self.iLangIndex;
- if pPropLangIndex <> nil then pPropLangIndex^ := Self.iPropLangIndex;
- iCPage := Self.iCPage;
- result := true;
- exit;
- end;
-
- for i := 0 to pHeader^.rHeader.iLCIDCount - 1
- do if pHeader^.aLCID[ i ] = iLCID
- then begin
- result := true;
- if pLangIndex <> nil
- then begin
- pLangIndex^ := i;
- if ( pHeader^.rHeader.iOpts and LC_OPT_PROJINFO ) <> 0
- then Inc( pLangIndex^ );
- end;
- if pPropLangIndex <> nil then pPropLangIndex^ := i;
- if not isOldFormat
- then begin
- pPages := pointer( integer( pHeader ) +
- sizeof( TLcHeaderRec ) +
- pHeader^.rHeader.iLCIDCount * sizeof( LCID ) );
- iCPage := pPages^[ i ];
- end
- else iCPage := LCIDToCodePage( iLCID );
- exit;
- end;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TLcf.LoadLib;
-var
- iRes : HRSRC;
- iGlobal : HGLOBAL;
- i : integer;
- s : str;
-begin
- result := -1;
- iLibHandle := LoadLibraryEx( szFileName, 0,
- LOAD_LIBRARY_AS_DATAFILE or DONT_RESOLVE_DLL_REFERENCES );
- if iLibHandle = 0 then exit;
- Self.pUd := pUd;
- Self.pOnGetResStr := pOnGetResStr;
- isOldFormat := true;
- iRes := FindResource( iLibHandle, LC_HEADE3_RESID, RT_RCDATA );
- if iRes = 0 then exit;
-
- iGlobal := LoadResource( iLibHandle, iRes );
- if iGlobal = 0 then exit;
- if SizeOfResource( iLibHandle, iRes ) < sizeof( TLcHeaderRec ) then exit;
- pHeader := pointer( iGlobal );
- s := LC_SIGNATURE;
- if not CompareMem( @pHeader^.rHeader.aSign[ 0 ], @s[ 1 ], Length( s ) )
- then begin
- pHeader := nil;
- exit;
- end;
- result := 0;
- if Assigned( pCallBack )
- then for i := 0 to pHeader^.rHeader.iLCIDCount - 1
- do if pCallBack( pHeader^.aLCID[ i ], pUd ) = 0 then break;
- if not GetLangIndex( iLCID, @iLangIndex, @iPropLangIndex, iCPage ) then exit;
- Self.iLCID := iLCID;
- result := 1;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TLcf.LoadLibEx;
-begin
- result := -1;
- if ( pOpts = nil ) or ( pOpts^.iSize <> sizeof( pOpts^ ) ) then exit;
- result := LoadLib( szFileName, pOpts^.iLCID, pOpts^.pCallBack, pOpts^.pOnGetResStr, pOpts^.pUd );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TLcf.GetResString;
-var
- iDefLen : integer;
- wBuffer : array [ 0..1023 ] of wchr;
- iPrefix : integer;
- iLCID : integer;
- iCPage : UINT;
- iLangIndex : integer;
- iChangedCPage : integer;
-
- iRes : HRSRC;
- iGlobal : HGLOBAL;
- pResItem : TPLcResItemRec;
- wString : wstr;
-
- procedure GetDefault;
- begin
- if iDefLen > 0 then exit;
- iDefLen := LoadStringW(
- FindResourceHInstance( pResStrRec.Module^ ),
- pResStrRec.Identifier,
- wBuffer,
- SizeOf( wBuffer ) div SizeOf( wBuffer[ 0 ] ) );
- end;
-
-begin
- iDefLen := 0;
- iPrefix := 0;
-
- iLCID := Self.iLCID;
- iChangedCPage := 0;
-
- if Assigned( pOnGetResStr )
- then begin
- GetDefault;
- if iDefLen > 0
- then iPrefix := pOnGetResStr( PWideChar( @wBuffer ), iLCID, iChangedCPage, pUd );
- end;
-
- if not GetLangIndex( iLCID, @iLangIndex, nil, iCPage )
- then iLCID := 0
- else if iChangedCPage <> 0 then iCPage := iChangedCPage;
-
- if iLCID <> 0
- then begin
- iRes := FindResource( iLibHandle,
- MAKEINTRESOURCE( IntToStr( pResStrRec^.Identifier ) ), RT_RCDATA );
- if iRes <> 0
- then begin
- iGlobal := LoadResource( iLibHandle, iRes );
- if iGlobal <> 0
- then begin
- pResItem := pointer( iGlobal );
- if pResItem^[ iLangIndex ].iLength >= 0
- then begin
- SetLength( wString,
- pResItem^[ iLangIndex ].iLength shr 1 );
- Move(
- PByteArray( pResItem )^
- [ pResItem^[ iLangIndex ].iOffset ],
- pointer( wString )^,
- pResItem^[ iLangIndex ].iLength );
- result := wString;
- exit;
- end;
- end;
- end;
- end;
-
- GetDefault;
- if iDefLen > 0
- then begin
- result := pwchr( @wBuffer );
- if iPrefix > 0 then Delete( result, 1, iPrefix );
- end
- else result := '';
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-procedure TLcf.RegProcs;
-begin
- if Assigned( pO1 ) and Assigned( pN1 )
- then aProc[ 0 ] := TProc.Create( pO1, pN1 );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-
-{* ************************************************************************** *}
-
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function NewLoadResString( ResStringRec : PResStringRec ) : nstr;
-const
- MAX_ID = 64 * 1024;
-begin
- if ResStringRec = nil then exit;
- if ResStringRec.Identifier >= MAX_ID
- then result := pnchr( ResStringRec.Identifier )
- else result := _oLcf.GetResString( ResStringRec );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function LoadLcf;
-begin
- _oLcf.Free;
- _oLcf := TLcf.Create;
- result := _oLcf.LoadLib( PChar( sFileName ), iLCID, pCallBack, nil, pUd );
- if result < 1
- then begin
- _oLcf.Free; _oLcf := nil;
- exit;
- end;
- _oLcf.RegProcs( @NewLoadResString, @System.LoadResString );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function LoadLcfEx;
-begin
- _oLcf.Free;
- _oLcf := TLcf.Create;
- result := _oLcf.LoadLibEx( pwchr( sFileName ), pOpts );
- if result < 1
- then begin
- _oLcf.Free; _oLcf := nil;
- exit;
- end;
- _oLcf.RegProcs( @NewLoadResString, @System.LoadResString );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TranslateComponent;
-begin
- result := false;
- if _oLcf = nil then exit;
- result := _oLcf.TranslateComponent( oComponent, _oLcf.iLCID );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TranslateComponentEx;
-begin
- result := false;
- if _oLcf = nil then exit;
- result := _oLcf.TranslateComponent( oComponent, iLCID );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-
-{* ************************************************************************** *}
-
-type
-
- TProp = class
- private
- oLcf : TLcf;
- sCompName : nstr;
- sPropName : nstr;
- wTranslation : wstr;
- isTranslated : boolean;
- public
- function LoadFromResource( iLangIndex : integer; pRes : PByteArray ) : boolean;
- procedure Translate( iCPage : UINT; oComponent : TComponent );
- end;
-
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-
- TProps = class
- private
- oLcf : TLcf;
- oComponent : TComponent;
- oItems : TList;
- public
- constructor Create;
- destructor Destroy; override;
- function LoadFromResource( iLangIndex : integer ) : boolean; overload;
- function LoadFromResource( iLangIndex : integer;
- oClassType : TClass ) : boolean; overload;
- end;
-
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TextToChar( const s : nstr; c : nchr; var iPos : integer ) : nstr;
-var
- iNextPos : integer;
-begin
- iNextPos := PosEx( c, s, iPos );
- if iNextPos = 0
- then result := Copy( s, iPos, Length( s ) - iPos + 1 )
- else begin
- result := Copy( s, iPos, iNextPos - iPos );
- Inc( iNextPos );
- if iNextPos > Length( s ) then iNextPos := 0;
- end;
- iPos := iNextPos;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TProp.LoadFromResource;
-var
- sFullName : nstr;
- pBytes : PByteArray;
- iPos : integer;
- iLength : integer;
- iOffset : integer;
-begin
- SetLength( sFullName, TPLcResItemRec( pRes )^[ 0 ].iLength div sizeof( wchr ) );
- pBytes := pRes;
- Move( pBytes^[ TPLcResItemRec( pRes )^[ 0 ].iOffset ],
- sFullName[ 1 ],
- TPLcResItemRec( pRes )^[ 0 ].iLength );
- iPos := 1;
- sCompName := TextToChar( sFullName, '-', iPos );
- sPropName := TextToChar( sFullName, '-', iPos );
- iLength := TPLcResItemRec( pRes )^[ iLangIndex + 1 ].iLength;
- iOffset := TPLcResItemRec( pRes )^[ iLangIndex + 1 ].iOffset;
- isTranslated := iLength >= 0;
- if isTranslated
- then begin
- SetLength( wTranslation, iLength div sizeof( wchr ) );
- Move( pBytes^[ iOffset ], pointer( wTranslation )^, iLength );
- end;
- result := true;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-procedure TProp.Translate;
-
- function FindObject( const sName : nstr ) : TObject;
- begin
- if SameText( sName, oComponent.Name )
- then begin
- result := oComponent;
- exit;
- end;
- result := oComponent.FindComponent( sName );
- end;
-
-type
- TPropTypeFromName = ( ptfnGeneral, ptfnList, ptfnCollection );
-
-const
- AS_ENDS : array[ TPropTypeFromName ] of nchr = ( ' ', ')', '>' );
-
- function ExtractPropName(
- const sPropName : nstr;
- var iType : TPropTypeFromName;
- var iCollListIndex : integer ) : nstr;
- var
- iPos : integer;
- begin
- iType := ptfnGeneral;
- iCollListIndex := 0;
- iPos := Pos( '<', sPropName );
- if iPos >= 1
- then begin
- iType := ptfnCollection;
- end
- else begin
- iPos := Pos( '(', sPropName );
- if iPos >= 1
- then begin
- iType := ptfnList;
- end
- else begin
- result := sPropName;
- exit;
- end;
- end;
- result := Copy( sPropName, 1, iPos - 1 );
- Inc( iPos );
- iCollListIndex := StrToInt( TextToChar( sPropName, AS_ENDS[ iType ],
- iPos ) );
- end;
-
- function FindPropInfo(
- var oObject : TObject;
- oPropNames : TStrings;
- iIndex : integer;
- var iTypeFromName : TPropTypeFromName;
- var iCollListIndex : integer
- ) : PPropInfo;
- var
- sPropName : nstr;
- begin
- sPropName := ExtractPropName( oPropNames[ iIndex ],
- iTypeFromName,
- iCollListIndex );
-
- result := GetPropInfo( oObject.ClassInfo, sPropName );
-
- if ( result <> nil )
- and ( iIndex < oPropNames.Count - 1 )
- then begin
- if ( result^.PropType^.Kind = tkClass )
- then begin
- oObject := GetObjectProp( oObject, sPropName );
- case iTypeFromName of
- ptfnList :
- begin
- result := nil;
- end;
- ptfnCollection :
- begin
- oObject := ( oObject as TCollection ).Items
- [ iCollListIndex ];
- if oObject <> nil
- then result := FindPropInfo( oObject,
- oPropNames,
- iIndex + 1,
- iTypeFromName,
- iCollListIndex );
- end;
- else
- if oObject <> nil
- then result := FindPropInfo( oObject,
- oPropNames,
- iIndex + 1,
- iTypeFromName,
- iCollListIndex )
- else result := nil;
- end;
- end
- else result := nil;
- end;
- end;
-
-var
- oObject : TObject;
- iPos : integer;
- oPropNames : TStrings;
- pProp : PPropInfo;
- wOldTranslation : wstr;
- iTypeFromName : TPropTypeFromName;
- iCollListIndex : integer;
-begin
- oObject := FindObject( sCompName );
- if oObject = nil then exit;
- iPos := 1;
- oPropNames := TStringList.Create;
- try
- while iPos > 0
- do begin
- oPropNames.Add( TextToChar( sPropName, '.', iPos ) );
- end;
- pProp := FindPropInfo( oObject, oPropNames, 0,
- iTypeFromName,
- iCollListIndex );
- if ( pProp <> nil )
- then begin
- if pProp^.PropType^.Kind in [ tkString, tkLString, tkWString, tkUString ]
- then begin
- {asaq GetWideStrProp depricated {/asaq}
- wOldTranslation := GetStrProp( oObject, nstr( pProp^.Name ) );
- if ( pProp^.SetProc <> nil ) and ( wOldTranslation <> wTranslation )
- then begin
- SetWideStrProp( oObject, pProp, wTranslation );
- end;
- end;
- end
- else begin
- if oObject = nil then exit;
- if ( oObject is TStrings ) and ( iTypeFromName = ptfnList )
- then begin
- if ( iCollListIndex < ( oObject as TStrings ).Count )
- then begin
- wOldTranslation := ( oObject as TStrings )[ iCollListIndex ];
- if wOldTranslation <> wTranslation
- then begin
- ( oObject as TStrings )[ iCollListIndex ] := wTranslation;
- end;
- end;
- exit;
- end;
- if oObject is TCollection
- then begin
- exit;
- end;
- end;
- finally
- oPropNames.Free;
- end;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-constructor TProps.Create;
-begin
- oItems := TList.Create;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-destructor TProps.Destroy;
-var
- i : integer;
-begin
- for i := 0 to oItems.Count - 1 do TObject( oItems[ i ] ).Free;
- oItems.Free;
- inherited;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TProps.LoadFromResource( iLangIndex : integer ) : boolean;
-begin
- result := LoadFromResource( iLangIndex, oComponent.ClassType );
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TProps.LoadFromResource( iLangIndex : integer;
- oClassType : TClass ) : boolean;
-var
- iRes : HRSRC;
- iGlobal : HGLOBAL;
- iPropCount : integer;
- oProp : TProp;
- sClassName : wstr;
- oClassParent : TClass;
- n : integer;
-begin
- result := false;
- oClassParent := oClassType.ClassParent;
- if Assigned( oClassParent ) and oClassParent.InheritsFrom( TComponent )
- then LoadFromResource( iLangIndex, oClassParent );
- iRes := FindResource( oLcf.iLibHandle, pwchr( UpperCase( oClassType.ClassName ) ), RT_RCDATA );
- if iRes = 0 then exit;
- iGlobal := LoadResource( oLcf.iLibHandle, iRes );
- if iGlobal = 0 then exit;
- n := integer( pointer( iGlobal )^ );
- SetLength( sClassName, n div sizeof( wchr ) );
- Inc( iGlobal, sizeof( integer ) );
- Move( pointer( iGlobal )^, sClassName[ 1 ], n );
- Inc( iGlobal, n );
- iPropCount := integer( pointer( iGlobal )^ );
- Inc( iGlobal, sizeof( integer ) );
- while iPropCount > 0
- do begin
- Dec( iPropCount );
- oProp := TProp.Create;
- oProp.oLcf := oLcf;
- if not oProp.LoadFromResource( iLangIndex, pointer( iGlobal +
- Cardinal( TPLcResItemRec( pointer( iGlobal ) )^[ iPropCount ].
- iOffset ) ) )
- then oProp.Free
- else oItems.Add( oProp );
- end;
- result := true;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-function TLcf.TranslateComponent;
-var
- oProps : TProps;
- oProp : TProp;
- i : integer;
- iPropLangIndex : integer;
- iCPage : UINT;
-begin
- result := false;
- if not GetLangIndex( iLCID, nil, @iPropLangIndex, iCPage ) then exit;
- oProps := TProps.Create;
- oProps.oLcf := Self;
- oProps.oComponent := oComponent;
- try
- result := oProps.LoadFromResource( iPropLangIndex );
- if not result then exit;
- for i := 0 to oProps.oItems.Count - 1
- do begin
- oProp := oProps.oItems[ i ];
- if oProp.isTranslated then oProp.Translate( iCPage, oComponent );
- end;
- finally
- oProps.Free;
- end;
-end;
-{* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *}
-
-{* ************************************************************************** *}
-
-initialization
-
-finalization
-
- _oLcf.Free;
-
-end.
-
-
-
diff --git a/components/HotKey/HotKey.dfm b/components/HotKey/HotKey.dfm
new file mode 100644
index 0000000..b7863eb
--- /dev/null
+++ b/components/HotKey/HotKey.dfm
@@ -0,0 +1,69 @@
+object HotkeyEdit: THotkeyEdit
+ Left = 0
+ Top = 0
+ Width = 353
+ Height = 22
+ TabOrder = 0
+ OnResize = FrameResize
+ object Bevel1: TBevel
+ Left = 227
+ Top = 0
+ Width = 126
+ Height = 22
+ Align = alClient
+ Shape = bsSpacer
+ ExplicitLeft = 228
+ ExplicitWidth = 86
+ end
+ object chbWin: TCheckBox
+ Left = 172
+ Top = 0
+ Width = 55
+ Height = 22
+ Align = alLeft
+ Caption = 'WIN +'
+ TabOrder = 3
+ OnClick = Changed
+ end
+ object chbAlt: TCheckBox
+ Left = 121
+ Top = 0
+ Width = 51
+ Height = 22
+ Align = alLeft
+ Caption = 'ALT +'
+ TabOrder = 2
+ OnClick = Changed
+ end
+ object chbCtrl: TCheckBox
+ Left = 63
+ Top = 0
+ Width = 58
+ Height = 22
+ Align = alLeft
+ Caption = 'CTRL +'
+ TabOrder = 1
+ OnClick = Changed
+ end
+ object chbShift: TCheckBox
+ Left = 0
+ Top = 0
+ Width = 63
+ Height = 22
+ Align = alLeft
+ Caption = 'SHIFT +'
+ TabOrder = 0
+ OnClick = Changed
+ end
+ object htkKey: THotKey
+ Left = 255
+ Top = 1
+ Width = 86
+ Height = 21
+ AutoSize = False
+ HotKey = 112
+ Modifiers = []
+ TabOrder = 4
+ OnChange = Changed
+ end
+end
diff --git a/components/HotKey/HotKey.pas b/components/HotKey/HotKey.pas
new file mode 100644
index 0000000..3814b6b
--- /dev/null
+++ b/components/HotKey/HotKey.pas
@@ -0,0 +1,224 @@
+{*******************************************************}
+{ Linkbar - Windows desktop toolbar }
+{ Copyright (c) 2010-2017 Asaq }
+{*******************************************************}
+
+unit HotKey;
+
+interface
+
+uses
+ Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
+ Vcl.Controls, Vcl.Forms, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.StdCtrls,
+ Vcl.Dialogs, Vcl.Menus;
+
+const
+ LB_HOTKEY_ID = 1;
+
+type
+ THotkeyInfo = record
+ private
+ const SSHIFT = 'Shift';
+ SCTRL = 'Ctrl';
+ SALT = 'Alt';
+ SWIN = 'Win';
+ SNONE = 'None';
+ public
+ Modifiers: Word; // Winapi.Windows.MOD_...
+ KeyCode: Word; // Virtual Key Code
+ constructor Create(const AInteger: Integer); overload;
+ constructor Create(const AString: String); overload;
+ class operator NotEqual(const Lhs, Rhs: THotkeyInfo): Boolean;
+ class operator Implicit(A: THotkeyInfo): string;
+ class operator Implicit(A: THotkeyInfo): Integer;
+ function ToUserString: string;
+ end;
+
+ THotkeyEdit = class(TFrame)
+ htkKey: THotKey;
+ chbWin: TCheckBox;
+ chbAlt: TCheckBox;
+ chbCtrl: TCheckBox;
+ chbShift: TCheckBox;
+ Bevel1: TBevel;
+ procedure Changed(Sender: TObject);
+ procedure FrameResize(Sender: TObject);
+ private
+ FOnChange: TNotifyEvent;
+ procedure SetHotkeyInfo(AHotKeyInfo: THotkeyInfo);
+ function GetHotkeyInfo: THotkeyInfo;
+ procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
+ public
+ constructor Create(AOwner: TComponent); override;
+ property HotkeyInfo: THotkeyInfo read GetHotkeyInfo write SetHotkeyInfo;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ end;
+
+ TMyTaskDialog = class(TCustomTaskDialog)
+ protected
+ function CallbackProc(hwnd: HWND; msg: UINT; wParam: WPARAM;
+ lParam: LPARAM; lpRefData: LONG_PTR): HResult; override;
+ end;
+
+ function RegisterHotkeyNotify(AWnd: HWND; AHotkeyInfo: THotkeyInfo; AWarnings: Boolean = True): Boolean;
+ function UnregisterHotkeyNotify(AWnd: HWND): Boolean;
+ function CheckHotkey(AWnd: HWND; AHotkeyInfo: THotkeyInfo): Boolean;
+
+implementation
+
+{$R *.dfm}
+
+uses Linkbar.Consts, Winapi.CommCtrl, Linkbar.Shell;
+
+{ THotKeyInfo }
+
+constructor THotkeyInfo.Create(const AInteger: Integer);
+begin
+ Self.KeyCode := Word(AInteger);
+ Self.Modifiers := HiWord(AInteger);
+end;
+
+constructor THotkeyInfo.Create(const AString: String);
+begin
+ Create( StrToIntDef(AString, 0) );
+end;
+
+class operator THotkeyInfo.Implicit(A: THotkeyInfo): string;
+begin
+ Result := HexDisplayPrefix + IntToHex(A, 8);
+end;
+
+class operator THotkeyInfo.Implicit(A: THotkeyInfo): Integer;
+begin
+ Result := (A.Modifiers shl 16) or A.KeyCode;
+end;
+
+class operator THotkeyInfo.NotEqual(const Lhs, Rhs: THotkeyInfo): Boolean;
+begin
+ Result := (Lhs.KeyCode <> Rhs.KeyCode) or (Lhs.Modifiers <> Rhs.Modifiers);
+end;
+
+function THotkeyInfo.ToUserString: string;
+begin
+ Result := ShortCutToText(KeyCode);
+ if Result = ''
+ then Result := 'None';
+
+ if (Modifiers and MOD_WIN > 0) then Result := SWIN + '+' + Result;
+ if (Modifiers and MOD_ALT > 0) then Result := SALT + '+' + Result;
+ if (Modifiers and MOD_CONTROL > 0) then Result := SCTRL + '+' + Result;
+ if (Modifiers and MOD_SHIFT > 0) then Result := SSHIFT + '+' + Result;
+end;
+
+{ THotKeyEdit }
+
+constructor THotkeyEdit.Create(AOwner: TComponent);
+begin
+ inherited;
+ htkKey.InvalidKeys := [hcNone, hcShift, hcCtrl, hcAlt, hcShiftCtrl, hcShiftAlt, hcCtrlAlt, hcShiftCtrlAlt];
+ htkKey.Modifiers := [];
+ htkKey.HotKey := 0;
+end;
+
+procedure THotkeyEdit.FrameResize(Sender: TObject);
+begin
+ htkKey.BoundsRect := Bevel1.BoundsRect;
+end;
+
+procedure THotkeyEdit.CMEnabledChanged(var Message: TMessage);
+begin
+ chbShift.Enabled := Enabled;
+ chbCtrl.Enabled := Enabled;
+ chbAlt.Enabled := Enabled;
+ chbWin.Enabled := Enabled;
+ htkKey.Enabled := Enabled;
+end;
+
+procedure THotkeyEdit.SetHotkeyInfo(AHotKeyInfo: THotKeyInfo);
+begin
+ htkKey.HotKey := AHotKeyInfo.KeyCode;
+ chbShift.Checked := (AHotKeyInfo.Modifiers and MOD_SHIFT) > 0;
+ chbCtrl.Checked := (AHotKeyInfo.Modifiers and MOD_CONTROL) > 0;
+ chbAlt.Checked := (AHotKeyInfo.Modifiers and MOD_ALT) > 0;
+ chbWin.Checked := (AHotKeyInfo.Modifiers and MOD_WIN) > 0;
+end;
+
+function THotkeyEdit.GetHotkeyInfo: THotkeyInfo;
+begin
+ Result.KeyCode := htkKey.HotKey;
+ Result.Modifiers := 0;
+ if (chbShift.Checked) then Inc(Result.Modifiers, MOD_SHIFT);
+ if (chbCtrl.Checked) then Inc(Result.Modifiers, MOD_CONTROL);
+ if (chbAlt.Checked) then Inc(Result.Modifiers, MOD_ALT);
+ if (chbWin.Checked) then Inc(Result.Modifiers, MOD_WIN);
+end;
+
+procedure THotkeyEdit.Changed(Sender: TObject);
+begin
+ if Assigned(FOnChange)
+ then FOnChange(Self);
+end;
+
+function RegisterHotkeyNotify(AWnd: HWND; AHotkeyInfo: THotkeyInfo;
+ AWarnings: Boolean = True): Boolean;
+var err: string;
+ td: TMyTaskDialog;
+begin
+ UnregisterHotkeyNotify(AWnd);
+
+ if (AHotkeyInfo.KeyCode = 0)
+ then Exit(False);
+
+ Result := RegisterHotKey(AWnd, LB_HOTKEY_ID, MOD_NOREPEAT or AHotkeyInfo.Modifiers, AHotkeyInfo.KeyCode);
+
+ if (not Result)
+ and (AWarnings)
+ then begin
+ err := SysErrorMessage(GetLastError);
+ td := TMyTaskDialog.Create(nil);
+ try
+ td.Flags := td.Flags + [tfEnableHyperlinks];
+ td.Caption := ' ' + APP_NAME_LINKBAR;
+ td.MainIcon := tdiNone;
+ td.Title := AHotkeyInfo.ToUserString;
+ td.Text := err;
+ td.ExpandButtonCaption := 'Learn More';
+ td.ExpandedText :=
+ 'Keyboard shortcuts in Windows: ' + #13 +
+ '' + URL_WINDOWS_HOTKEY + '';
+ td.CommonButtons := [tcbOk];
+ td.DefaultButton := tcbOk;
+ td.Execute;
+ finally
+ td.Free;
+ end;
+ end;
+end;
+
+function UnregisterHotkeyNotify(AWnd: HWND): Boolean;
+begin
+ Result := UnregisterHotKey(AWnd, LB_HOTKEY_ID);
+end;
+
+function CheckHotkey(AWnd: HWND; AHotkeyInfo: THotkeyInfo): Boolean;
+begin
+ Result := RegisterHotkeyNotify(AWnd, AHotkeyInfo);
+ UnregisterHotkeyNotify(AWnd);
+end;
+
+{ TMyTaskDialog }
+
+function TMyTaskDialog.CallbackProc(hwnd: HWND; msg: UINT; wParam: WPARAM;
+ lParam: LPARAM; lpRefData: LONG_PTR): HResult;
+begin
+ Result := S_OK;
+ if (msg = TDN_HYPERLINK_CLICKED)
+ then begin
+ if SameText(string(LPCWSTR(lParam)), 'hotkeys')
+ then LBShellExecute(hwnd, 'open', URL_WINDOWS_HOTKEY);
+ Exit;
+ end;
+ inherited;
+end;
+
+end.
diff --git a/components/Jumplist/JumpLists.Api.pas b/components/Jumplist/JumpLists.Api.pas
index cac2cec..bcb2084 100644
--- a/components/Jumplist/JumpLists.Api.pas
+++ b/components/Jumplist/JumpLists.Api.pas
@@ -89,7 +89,7 @@ implementation
uses Winapi.PropSys, Winapi.PropKey, Winapi.KnownFolders, Winapi.ShLwApi,
Winapi.ObjectArray, Winapi.CommCtrl,
System.Win.Registry,
- Linkbar.OS, Linkbar.Loc;
+ Linkbar.OS, Linkbar.L10n;
const
// In Delphi XE3 the following constants are not defined
@@ -654,13 +654,13 @@ function GetJumplist(const AAppId: PChar; AList: TJumplist; AMaxCount: Integer):
if (iType = 1)
then begin
oGroup.eType := jgFrequent;
- oGroup.Name := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_FREQUENT);
+ oGroup.Name := L10NFind('Jumplist.Frequent', 'Frequent');
GetKnownCategory(AAppId, oGroup, ADLT_FREQUENT);
end
else if (iType = 2)
then begin
oGroup.eType := jgRecent;
- oGroup.Name := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_RECENT);
+ oGroup.Name := L10NFind('Jumplist.Recent', 'Recent');
GetKnownCategory(AAppId, oGroup, ADLT_RECENT);
end;
end
@@ -684,7 +684,7 @@ function GetJumplist(const AAppId: PChar; AList: TJumplist; AMaxCount: Integer):
Dec(groupIdx);
oGroup := AList.Groups[customheader.iGroupCount+1];
end;
- oGroup.Name := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_TASKS);
+ oGroup.Name := L10NFind('Jumplist.Tasks', 'Tasks');
oGroup.eType := jgTasks;
end;
@@ -714,7 +714,7 @@ function GetJumplist(const AAppId: PChar; AList: TJumplist; AMaxCount: Integer):
AList.Groups.Add(oGroup);
oGroup := TJumpGroup.Create;
oGroup.eType := jgRecent;
- oGroup.Name := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_RECENT);
+ oGroup.Name := L10NFind('Jumplist.Recent', 'Recent');
GetKnownCategory(AAppId, oGroup, ADLT_RECENT);
AList.Groups.Add(oGroup);
end;
@@ -722,7 +722,7 @@ function GetJumplist(const AAppId: PChar; AList: TJumplist; AMaxCount: Integer):
// update pinned items
oGroupPinned := AList.Groups[0];
oGroupPinned.eType := jgPinned;
- oGroupPinned.Name := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_PINNED);
+ oGroupPinned.Name := L10NFind('Jumplist.Pinned', 'Pinned');
// read the DestList stream as described here: http://www.forensicswiki.org/wiki/Jump_Lists
pStorage := nil;
diff --git a/components/Jumplist/Jumplists.Form.pas b/components/Jumplist/Jumplists.Form.pas
index fad16d0..ffeb484 100644
--- a/components/Jumplist/Jumplists.Form.pas
+++ b/components/Jumplist/Jumplists.Form.pas
@@ -26,6 +26,8 @@ TVtItem = record
IsLatesPinned: Boolean;
Pinnable: Boolean;
Caption: string;
+ function IsSelectable: Boolean;
+ function IsHeader: Boolean;
end;
TVtList = TList;
@@ -48,6 +50,7 @@ TFormJumpList = class(TForm)
FAlign: TJumplistAlign;
FVtList: TVtList;
FPopupMenuVisible: Boolean;
+ FHotSelectedByMouse: Boolean;
oBgBmp: TBitmap;
oIconCache: TIconCache;
RectBody: TRect;
@@ -57,6 +60,7 @@ TFormJumpList = class(TForm)
procedure OnFormContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
procedure OnFormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+ procedure CMDialogKey(var AMsg: TCMDialogKey); message CM_DIALOGKEY;
procedure OnFormMouseLeave(Sender: TObject);
procedure OnFormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure OnFormMouseDown(Sender: TObject; Button: TMouseButton;
@@ -68,6 +72,7 @@ TFormJumpList = class(TForm)
procedure OnJumpListRemove(Sender: TObject);
procedure OnJumpListExecute(Sender: TObject);
function ScaleDimension(const X: Integer): Integer;
+ procedure KeyboardControl(const AKeyCode: Word);
private
hImageList: HIMAGELIST;
function ExtractIcon(AItem: IUnknown; AItemType: TJumpItemType): Integer;
@@ -88,7 +93,7 @@ TFormJumpList = class(TForm)
procedure SetHotIndex(AValue: integer);
procedure AlphaBlendAndClose;
function PinSelected: boolean; inline;
- function Index: Integer; inline;
+ function Index: Integer;// inline;
private
TipHwnd: HWND;
TipPinText: string;
@@ -101,6 +106,8 @@ TFormJumpList = class(TForm)
procedure PrepareTooltips;
function GetDescription(const AItem: TVtItem; const AText: PChar; ASize: Integer): Boolean;
procedure WMTimer(var Message: TMessage); message WM_TIMER;
+ private
+ TempX, TempY: Integer;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure PaintWindow(DC: HDC); override;
@@ -119,7 +126,7 @@ TFormJumpList = class(TForm)
implementation
uses Math, Vcl.Themes, Winapi.Dwmapi, Winapi.ShellAPI, Winapi.ShLwApi,
- Winapi.ActiveX, Winapi.UxTheme, Linkbar.OS, Linkbar.Loc, Linkbar.Shell,
+ Winapi.ActiveX, Winapi.UxTheme, Linkbar.OS, Linkbar.L10n, Linkbar.Shell,
Jumplists.Themes, ExplorerMenu, System.Win.Registry;
const
@@ -155,16 +162,27 @@ implementation
TextColorItemSelected: TColor;
TextColorItemNew: TColor;
+{ TVtItem }
+
+function TVtItem.IsSelectable: Boolean;
+begin
+ Result := Style in [vtItem, vtFooter];
+end;
+
+function TVtItem.IsHeader: Boolean;
+begin
+ Result := not IsSelectable;
+end;
+
// Macros from windowsx.h:
// Important Do not use the LOWORD or HIWORD macros to extract the x- and y-
// coordinates of the cursor position because these macros return incorrect results
// on systems with multiple monitors. Systems with multiple monitors can have
// negative x- and y- coordinates, and LOWORD and HIWORD treat the coordinates
// as unsigned quantities.
-
-function MakePoint(const Param : DWord): TPoint; inline;
+function MakePoint(const L: DWORD): TPoint; inline;
Begin
- Result := TPoint.Create(Param and $FFFF, Param shr 16);
+ Result := TPoint.Create(SmallInt(L and $FFFF), SmallInt(L shr 16));
End;
procedure JumpListClose;
@@ -449,8 +467,8 @@ constructor TFormJumpList.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
TipHideTime := TipShowTime * 10;
// Get pin/unpin button hint text
- TipUnpinText := StripHotkey( MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_UNPIN) );
- TipPinText := StripHotkey( MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_PIN) );
+ TipUnpinText := StripHotkey( L10NFind('Jumplist.UnpinTip', 'Unpin from this list') );
+ TipPinText := StripHotkey( L10NFind('Jumplist.PinTip', 'Pin to this list') );
LastPinUnpinHash := 0;
TipHwnd := 0;
@@ -747,26 +765,34 @@ procedure TFormJumpList.OnFormContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var vi: TVtItem;
shift: Boolean;
+ pt: TPoint;
begin
Handled := True;
if (Index <> INDEX_NONE)
then begin
vi := FVtList[Index];
+
+ // Keyboard "Menu" button
+ if (MousePos.X = -1)
+ and (MousePos.Y = -1)
+ then pt := Point(vi.Rect.Left + ItemPadding + FIconSize div 2, vi.Rect.CenterPoint.Y)
+ else pt := MousePos;
+
if (vi.Style = vtItem)
then begin
FJumpItemIndex := MakeLong(vi.Item, vi.Group);
- MapWindowPoints(Handle, HWND_DESKTOP, MousePos, 1);
- JumpListPopupMenuPopup(MousePos.X, MousePos.Y);
+ MapWindowPoints(Handle, HWND_DESKTOP, pt, 1);
+ JumpListPopupMenuPopup(pt.X, pt.Y);
Exit;
end;
if (vi.Style = vtFooter)
then begin
- MapWindowPoints(Handle, HWND_DESKTOP, MousePos, 1);
+ MapWindowPoints(Handle, HWND_DESKTOP, pt, 1);
shift := (GetKeyState(VK_SHIFT) < 0);
// TODO: may will be need AlphaBlendAndClose and process messages after invokecommand
FPopupMenuVisible := True;
- ExplorerMenuPopup(FWnd, FAppExe, MousePos, shift, 0);
+ ExplorerMenuPopup(FWnd, FAppExe, pt, shift, 0);
FPopupMenuVisible := False;
Exit;
end;
@@ -776,8 +802,87 @@ procedure TFormJumpList.OnFormContextPopup(Sender: TObject; MousePos: TPoint;
procedure TFormJumpList.OnFormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
- if (Key = VK_ESCAPE)
- then Close;
+ KeyboardControl(Key);
+end;
+
+procedure TFormJumpList.KeyboardControl(const AKeyCode: Word);
+var i: Integer;
+begin
+ if (FVtList.Count = 0)
+ then Exit;
+
+ FHotSelectedByMouse := False;
+
+ case AKeyCode of
+ VK_ESCAPE: // Close Jumplist
+ begin
+ Close;
+ end;
+ VK_SPACE, VK_RETURN: // Run
+ begin
+ Click;
+ end;
+ VK_UP: // Select prev non-header item
+ begin
+ i := Index;
+ Dec(i);
+ if (i < 1)
+ then i := FVtList.Count-1;
+ if (not FVtList[i].IsSelectable)
+ then Dec(i);
+ HotIndex := i;
+ end;
+ VK_DOWN: // Select next non-header item
+ begin
+ i := Index;
+ Inc(i);
+ if (i >= FVtList.Count)
+ then i := 1;
+ if (not FVtList[i].IsSelectable)
+ then Inc(i);
+ HotIndex := i;
+ end;
+ VK_LEFT: // Unselect Pin
+ begin
+ i := Index;
+ if (i <> INDEX_NONE)
+ then HotIndex := i;
+ end;
+ VK_RIGHT: // Select Pin for pinnable item
+ begin
+ i := Index;
+ if (i <> INDEX_NONE)
+ and FVtList[i].Pinnable
+ then HotIndex := i or INDEX_PIN;
+ end;
+ VK_TAB: // Select first item for next group or footer item
+ begin
+ i := Index;
+ if (i < 1)
+ or (i = FVtList.Count-1)
+ then
+ i := 1
+ else
+ while (i < FVtList.Count) do
+ begin
+ Inc(i);
+ if (FVtList[i].Style = vtFooter)
+ or (FVtList[i-1].IsHeader)
+ then Break;
+ end;
+ HotIndex := i;
+ end;
+ end;
+end;
+
+procedure TFormJumpList.CMDialogKey(var AMsg: TCMDialogKey);
+begin
+ if (AMsg.CharCode = VK_TAB)
+ then begin
+ KeyboardControl(VK_TAB);
+ AMsg.Result := 1;
+ end
+ else inherited;
end;
procedure TFormJumpList.OnFormMouseLeave(Sender: TObject);
@@ -801,9 +906,6 @@ function TFormJumpList.GetItemIndexAt(AX, AY: Integer): Integer;
Result := res;
end;
-var TempX: Integer = -1;
- TempY: Integer = -1;
-
procedure TFormJumpList.OnFormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var idx: Integer;
@@ -825,6 +927,8 @@ procedure TFormJumpList.OnFormMouseMove(Sender: TObject; Shift: TShiftState; X,
else idx := INDEX_NONE;
end;
+ FHotSelectedByMouse := True;
+
HotIndex := idx;
end;
@@ -1282,11 +1386,20 @@ procedure TFormJumpList.WMTimer(var Message: TMessage);
else TipToolInfo.lpszText := PChar(TipPinText);
end;
- pt := MakePoint(GetMessagePos);
- if (WindowFromPoint(pt) <> Handle)
- then Exit;
-
- pt.Offset(TipPosOffset);
+ if FHotSelectedByMouse
+ then begin
+ pt := MakePoint(GetMessagePos);
+ if (WindowFromPoint(pt) <> Handle)
+ then Exit;
+ pt.Offset(TipPosOffset)
+ end
+ else begin
+ if (vi.Pinnable)
+ and PinSelected
+ then pt := Point(vi.Rect.Right - PinButtonWidth, vi.Rect.Bottom)
+ else pt := Point(vi.Rect.Left + ItemPadding + FIconSize, vi.Rect.Bottom);
+ MapWindowPoints(Handle, HWND_DESKTOP, pt, 1);
+ end;
SendMessage(TipHwnd, TTM_UPDATETIPTEXT, 0, LParam(@TipToolInfo));
SendMessage(TipHwnd, TTM_TRACKPOSITION, 0, MakeLParam(pt.X, pt.Y));
@@ -1574,7 +1687,7 @@ procedure TFormJumpList.JumpListPopupMenuPopup(const X, Y: Integer);
// Open
mi := FPopupMenu.CreateMenuItem;
- mi.Caption := MUILoadResString(shell32, LB_RS_JL_OPEN);
+ mi.Caption := L10NFind('Jumplist.Open', '&Open');
mi.Default := True;
mi.OnClick := OnJumpListExecute;
FPopupMenu.Items.Add(mi);
@@ -1589,7 +1702,7 @@ procedure TFormJumpList.JumpListPopupMenuPopup(const X, Y: Integer);
begin
// Unpin
mi := FPopupMenu.CreateMenuItem;
- mi.Caption := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_UNPIN);
+ mi.Caption := L10NFind('JumpList.Unpin', '&Unpin from this list');
mi.OnClick := OnJumpListUnPin;
FPopupMenu.Items.Add(mi);
end;
@@ -1597,12 +1710,12 @@ procedure TFormJumpList.JumpListPopupMenuPopup(const X, Y: Integer);
begin
// Pin
mi := FPopupMenu.CreateMenuItem;
- mi.Caption := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_PIN);
+ mi.Caption := L10NFind('JumpList.Pin', 'P&in to this list');
mi.OnClick := OnJumpListPin;
FPopupMenu.Items.Add(mi);
// Remove
mi := FPopupMenu.CreateMenuItem;
- mi.Caption := MUILoadResString(LB_FN_JUMPLIST, LB_RS_JL_REMOVE);
+ mi.Caption := L10NFind('JumpList.Remove', 'Remove &from this list');
mi.OnClick := OnJumpListRemove;
FPopupMenu.Items.Add(mi);
end;
diff --git a/components/L10n/Linkbar.L10n.pas b/components/L10n/Linkbar.L10n.pas
new file mode 100644
index 0000000..eb15d23
--- /dev/null
+++ b/components/L10n/Linkbar.L10n.pas
@@ -0,0 +1,277 @@
+{*******************************************************}
+{ Linkbar - Windows desktop toolbar }
+{ Copyright (c) 2010-2017 Asaq }
+{*******************************************************}
+
+unit Linkbar.L10n;
+
+{$i linkbar.inc}
+
+interface
+
+uses
+ Winapi.Windows, System.Classes, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.Menus, Vcl.Forms;
+
+const
+ // MUI
+
+ // New shortcut file name
+ // shell32.dll.mui - String table - ?
+ LB_FN_NEWSHORTCUT = 'shell32.dll';
+ LB_RS_NSC_FILENAME = 30397;
+
+ // Autohide fail message
+ // explorerframe.dll.mui
+ LB_FN_TOOLBAR = 'explorerframe.dll';
+ LB_RS_TB_AUTOHIDEALREADYEXISTS = 28676;
+ LB_RS_TB_NEWTOOLBAROPENDIALOGTITLE = 12387;
+
+ // Invalid file name symbols
+ // shell32.dll.mui - String table - 257, 793
+ LB_FN_INVALIDFILENAMECHARS = 'shell32.dll';
+ LB_RS_IFNC_HINT = 4109;
+
+ // Rename dialog need file name message
+ LB_FN_NEEDFILENAME = 'shell32.dll';
+ LB_RS_NFN_CUE = 4123;
+
+ procedure L10nLoad(const APath: string; AForcedLocale: string = '');
+ function L10NFind(const AName: string; ADefault: string = ''): string;
+ function L10nMui(const AModuleName: String; const AStringID: Cardinal): String; overload;
+ function L10nMui(const AModule: HINST; const AStringID: Cardinal): String; overload;
+ procedure L10nControl(AControl: TForm; const AName: String); overload;
+ procedure L10nControl(AControl: TMenuItem; const AName: String); overload;
+ procedure L10nControl(AControl: TLabel; const AName: String); overload;
+ procedure L10nControl(AControl: TCheckbox; const AName: String); overload;
+ procedure L10nControl(AControl: TRadioButton; const AName: String); overload;
+ procedure L10nControl(AControl: TButton; const AName: String); overload;
+ procedure L10nControl(AControl: TTabSheet; const AName: String); overload;
+ procedure L10nControl(AControl: TComboBox; const ANames: array of String); overload;
+
+var
+ LbLongLang: Boolean = True deprecated;
+ Locale: string = '';
+
+implementation
+
+uses
+ System.SysUtils, System.Types, System.StrUtils, System.Generics.Collections;
+
+type
+ TTranslations = class
+ private
+ type TTr = TDictionary;
+ private
+ class var tr: TTr;
+ class destructor Destroy;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure LoadFromFile(const AFileName, ALocaleName: string);
+ procedure LoadFromPath(const APath, ALocales: string);
+ function Find(const AName: string; ADefault: string = ''): string;
+ procedure Clear;
+ end;
+
+{ Return localized string by ModuleInstance and StringID }
+function L10nMui(const AModule: HINST; const AStringID: Cardinal): String;
+var p: PChar;
+begin
+ if (AModule <> 0) and (AStringID < 65536)
+ then SetString(Result, p, LoadString(AModule, AStringID, @p, 0))
+ else Result := 'resource_string_not_found';
+end;
+
+{ Return localized string by ModuleName and StringID }
+function L10nMui(const AModuleName: String; const AStringID: Cardinal): String;
+var h: THandle;
+begin
+ h := LoadLibraryEx(PChar(AModuleName), 0, LOAD_LIBRARY_AS_DATAFILE);
+ Result := L10nMui(h, AStringID);
+ if (h <> 0)
+ then FreeLibrary(h);
+end;
+
+procedure L10nControl(AControl: TForm; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TMenuItem; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TLabel; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TCheckbox; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TRadioButton; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TButton; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TTabSheet; const AName: String); overload;
+begin
+ AControl.Caption := L10NFind(AName, AControl.Caption);
+end;
+
+procedure L10nControl(AControl: TComboBox; const ANames: array of String); overload;
+var i: Integer;
+begin
+{$IFDEF DEBUG}
+ Assert(AControl.Items.Count = Length(ANames));
+{$ENDIF}
+ for i := 0 to AControl.Items.Count-1 do
+ begin
+ AControl.Items[i] := L10NFind(ANames[i], AControl.Items[i]);
+ end;
+end;
+
+var FTranslations: TTranslations;
+
+function Translations: TTranslations;
+begin
+ if FTranslations = nil then
+ FTranslations := TTranslations.Create;
+
+ Result := FTranslations;
+end;
+
+{ TTranslations }
+
+constructor TTranslations.Create;
+begin
+ tr := TTr.Create(78);
+end;
+
+destructor TTranslations.Destroy;
+begin
+ tr.Free;
+ inherited;
+end;
+
+class destructor TTranslations.Destroy;
+begin
+ FreeAndNil(FTranslations);
+end;
+
+procedure TTranslations.LoadFromFile(const AFileName, ALocaleName: string);
+var list: TStringList;
+ i, ii, j: Integer;
+ s, key, value: string;
+begin
+ list := TStringList.Create;
+ try
+ list.LoadFromFile(AFileName);
+ // Find section
+ ii := list.Count;
+ for i := 0 to list.Count-1 do
+ begin
+ s := Copy(list[i], 2, Length(ALocaleName));
+ if SameText(s, ALocaleName)
+ then begin
+ ii := i + 1;
+ Break;
+ end;
+ end;
+
+ // Read translations
+ for i := ii to list.Count-1 do
+ begin
+ s := list[i];
+
+ if (Length(s) = 0) or (s[1] = '[')
+ then Break;
+
+ j := Pos('=', s, 1);
+ if (j > 1)
+ then begin
+ key := LowerCase( Trim( Copy(s, 1, j - 1) ) );
+ value := TrimLeft( Copy(s, j + 1, Length(s)) );
+ if (key <> '') and (value <> '')
+ then tr.AddOrSetValue(key, value);
+ end;
+ end;
+ finally
+ list.Free;
+ end;
+end;
+
+procedure TTranslations.LoadFromPath(const APath, ALocales: string);
+var sda: TStringDynArray;
+ i: Integer;
+ fn: string;
+begin
+ sda := SplitString(ALocales, ',');
+ for i := Length(sda)-1 downto 0 do
+ begin
+ fn := APath + sda[i] + '.ini';
+ if FileExists(fn)
+ then Self.LoadFromFile(fn, sda[i]);
+ end;
+end;
+
+procedure TTranslations.Clear;
+begin
+ tr.Clear;
+end;
+
+function TTranslations.Find(const AName: string; ADefault: string): string;
+begin
+ if not tr.TryGetValue(LowerCase(AName), Result)
+ then begin
+ Result := ADefault;
+ {$IFDEF DEBUG}
+ MessageBox(0, PChar(Format('Key not found: "%s"'#13'Default value: "%s"', [AName, ADefault])),
+ PChar('Linkbar - L10n'), MB_OK or MB_ICONEXCLAMATION);
+ {$ENDIF}
+ end;
+end;
+
+function GetLocaleNameFromLocaleID(ID: TLocaleID): string;
+var i: Integer;
+begin
+ Result := '';
+ i := Languages.IndexOf(ID);
+ if (i <> - 1)
+ then Result := Languages.LocaleName[i];
+end;
+
+procedure L10nLoad(const APath: string; AForcedLocale: string = '');
+var languages: string;
+ localeId: Integer;
+begin
+ Translations.Clear;
+ Locale := AForcedLocale;
+
+ if (Locale = '')
+ then languages := PreferredUILanguages
+ else begin
+ // Convert to LocaleName if needed
+ localeId := StrToIntDef(Locale, -1);
+ if (localeId = -1)
+ then languages := Locale
+ else languages := GetLocaleNameFromLocaleID(localeId);
+ end;
+
+ Translations.LoadFromPath(APath, languages);
+end;
+
+function L10NFind(const AName: string; ADefault: string = ''): string;
+begin
+ Result := Translations.Find(AName, ADefault);
+end;
+
+end.
\ No newline at end of file
diff --git a/components/NewBar/Linkbar.Newbar.dfm b/components/NewBar/Linkbar.Newbar.dfm
index 4d4be15..c058955 100644
--- a/components/NewBar/Linkbar.Newbar.dfm
+++ b/components/NewBar/Linkbar.Newbar.dfm
@@ -77,7 +77,7 @@ object BarCreatorWCl: TBarCreatorWCl
Width = 404
Height = 17
Anchors = [akLeft, akTop, akRight]
- Caption = 'Only for &me'
+ Caption = 'Only for &me (%s)'
TabOrder = 1
TabStop = True
ExplicitWidth = 408
@@ -126,6 +126,7 @@ object BarCreatorWCl: TBarCreatorWCl
Width = 79
Height = 25
Anchors = [akTop, akRight]
+ Cancel = True
Caption = 'C&ancel'
TabOrder = 2
OnClick = btnCancelClick
diff --git a/components/NewBar/Linkbar.Newbar.pas b/components/NewBar/Linkbar.Newbar.pas
index ffea454..59d7bce 100644
--- a/components/NewBar/Linkbar.Newbar.pas
+++ b/components/NewBar/Linkbar.Newbar.pas
@@ -38,6 +38,7 @@ TBarCreatorWCl = class(TForm)
FWorkinDirectoryPath: string;
procedure UpdateThemeStyle;
function ScaleDimension(const X: Integer): Integer;
+ procedure L10n;
protected
procedure WMSysColorChanged(var message : TMessage); message WM_SYSCOLORCHANGE;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
@@ -51,7 +52,7 @@ implementation
{$R *.dfm}
uses ShlObj, System.IniFiles, Vcl.Themes, Linkbar.Common,
- Linkbar.Shell, Linkbar.Consts, Linkbar.Loc, Linkbar.Themes, MyHint;
+ Linkbar.Shell, Linkbar.Consts, Linkbar.L10n, Linkbar.Themes, MyHint;
function GetUserNameEx(NameFormat: DWORD; lpBuffer: LPWSTR; var nSize: DWORD): Boolean;
stdcall; external 'secur32.dll' Name 'GetUserNameExW';
@@ -90,7 +91,7 @@ procedure TBarCreatorWCl.btnCancelClick(Sender: TObject);
procedure TBarCreatorWCl.btnCreateClick(Sender: TObject);
var
lini: TIniFile;
- lfilename: string;
+ lfilename, cmd: string;
begin
if rbAppDir.Checked
then begin
@@ -106,13 +107,26 @@ procedure TBarCreatorWCl.btnCreateClick(Sender: TObject);
lini := TIniFile.Create(lfilename);
lini.WriteString(INI_SECTION_MAIN, INI_DIR_LINKS, FWorkinDirectoryPath);
lini.Free;
-
- LBCreateProcess( ParamStr(0), LBCreateCommandParam(CLK_LANG, IntToStr(LbLangID))
- + LBCreateCommandParam(CLK_FILE, lfilename) );
-
+
+ cmd := LBCreateCommandParam(CLK_FILE, lfilename);
+ if (Locale <> '')
+ then cmd := LBCreateCommandParam(CLK_LANG, Locale) + cmd;
+ LBCreateProcess(ParamStr(0), cmd);
+
Close;
end;
+procedure TBarCreatorWCl.L10n;
+begin
+ L10nControl(Self, 'New.Caption');
+ L10nControl(Label1, 'New.ToWhom');
+ L10nControl(rbAppDir, 'New.ForAll');
+ L10nControl(rbUserDir, 'New.ForMe');
+ L10nControl(lblWorkDir, 'New.Folder');
+ L10nControl(btnCreate, 'New.Create');
+ L10nControl(btnCancel, 'New.Cancel');
+end;
+
procedure TBarCreatorWCl.Button1Click(Sender: TObject);
begin
if FileOpenDialog_NL.Execute
@@ -129,13 +143,13 @@ procedure TBarCreatorWCl.FormCreate(Sender: TObject);
HintWindowClass := TTooltipHintWindow;
Font.Name := Screen.IconFont.Name;
- LbTranslateComponent(Self);
+ L10n;
ReduceSysMenu(Handle);
UpdateThemeStyle;
- FileOpenDialog_NL.Title := MUILoadResString(LB_FN_TOOLBAR, LB_RS_TB_NEWTOOLBAROPENDIALOGTITLE);
+ FileOpenDialog_NL.Title := L10nMui(LB_FN_TOOLBAR, LB_RS_TB_NEWTOOLBAROPENDIALOGTITLE);
InitiatedAppDir := ExtractFilePath(Application.ExeName) + DN_SHARED_BARS;
InitiatedUserDir := GetLinkbarRoamingFolderPath + DN_USER_BARS;
@@ -148,7 +162,7 @@ procedure TBarCreatorWCl.FormCreate(Sender: TObject);
edtWorkDir.Color := Self.Color;
if GetLoggedOnUserName(username)
- then rbUserDir.Caption := rbUserDir.Caption + Format(' (%s)',[username]);
+ then rbUserDir.Caption := Format(rbUserDir.Caption,[username]);
Label1.ShowHint := True;
Label1.Hint := RemovePrefix(rbAppDir.Caption)
diff --git a/components/RenameDialog/RenameDialog.pas b/components/RenameDialog/RenameDialog.pas
index 8e70e81..845b1a1 100644
--- a/components/RenameDialog/RenameDialog.pas
+++ b/components/RenameDialog/RenameDialog.pas
@@ -27,6 +27,7 @@ TRenamingWCl = class(TForm)
FInvalidFileNameCharsHintText: string;
procedure SetPidl(APidl: PItemIDList);
procedure ShowBalloonTip(const AText: string);
+ procedure L10n;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
@@ -38,7 +39,7 @@ implementation
{$R *.dfm}
-uses Vcl.Clipbrd, Linkbar.Loc, Linkbar.Shell, Linkbar.Common;
+uses Vcl.Clipbrd, Linkbar.Shell, Linkbar.Common, Linkbar.L10n;
var FInvalidFileNameChars: TCharArray;
@@ -57,7 +58,7 @@ procedure TRenamingWCl.FormCreate(Sender: TObject);
var cue: String;
begin
Font.Name := Screen.IconFont.Name;
- LbTranslateComponent(Self);
+ L10n;
ReduceSysMenu(Handle);
@@ -65,14 +66,21 @@ procedure TRenamingWCl.FormCreate(Sender: TObject);
FInvalidFileNameChars := TCharArray.Create('"', '*', '/', ':', '<', '>', '?', '\', '|');
FInvalidFileNameCharsHintText :=
- MUILoadResString(GetModuleHandle(LB_FN_INVALIDFILENAMECHARS), LB_RS_IFNC_HINT);
+ L10nMui(GetModuleHandle(LB_FN_INVALIDFILENAMECHARS), LB_RS_IFNC_HINT);
- cue := MUILoadResString(GetModuleHandle(LB_FN_NEEDFILENAME), LB_RS_NFN_CUE);
+ cue := L10nMui(GetModuleHandle(LB_FN_NEEDFILENAME), LB_RS_NFN_CUE);
f_Edit_SetCueBannerText(edtFileName.Handle, PChar(cue));
btnOk.ModalResult := mrNone;
end;
+procedure TRenamingWCl.L10n;
+begin
+ L10nControl(Self, 'Rename.Caption');
+ L10nControl(btnOk, 'Rename.OK');
+ L10nControl(btnCancel, 'Rename.Cancel');
+end;
+
procedure TRenamingWCl.SetPidl(APidl: PItemIDList);
var ppszName: PChar;
begin
@@ -117,26 +125,21 @@ function IsValidFileNameChar(const AChar: Char): Boolean;
Result := not IsCharInOrderedArray(AChar, FInvalidFileNameChars);
end;
-function HasValidFileNameChars(const FileName: string): Boolean;
-var
- PFileName: PChar;
- FileNameLen: Integer;
- Ch: Char;
- I: Integer;
+function HasInvalidFileNameCharsFix(var AFileName: string): Boolean;
+var pname: PChar;
+ len, i, j: Integer;
begin
- // Result will become True if an invalid file name char is found
- I := 0;
- PFileName := PChar(FileName);
- FileNameLen := Length(FileName);
- Result := False;
- while (not Result) and (I < FileNameLen) do
+ pname := PChar(AFileName);
+ len := Length(AFileName);
+ j := 0;
+ for i := 0 to len-1 do
begin
- Ch := PFileName[I];
- if not IsValidFileNameChar(Ch)
- then Result := True
- else Inc(I);
+ pname[j] := pname[i];
+ if IsValidFileNameChar(pname[i])
+ then Inc(j);
end;
- Result := not Result;
+ SetLength(AFileName, j);
+ Result := j <> len;
end;
procedure TRenamingWCl.btnOkClick(Sender: TObject);
@@ -155,24 +158,31 @@ procedure TRenamingWCl.edtFileNameChange(Sender: TObject);
end;
procedure TRenamingWCl.edtFileNameKeyPress(Sender: TObject; var Key: Char);
+var str: string;
begin
+ // Ctrl+V
if (Key = #$16)
then begin
- if Clipboard.HasFormat(CF_TEXT)
- and HasValidFileNameChars(Clipboard.AsText)
- then Exit;
- end
- else begin
- if not IsCharInOrderedArray(Key, FInvalidFileNameChars)
- then Exit;
+ Key := #0;
+ str := Clipboard.AsText;
+ if HasInvalidFileNameCharsFix(str)
+ then ShowBalloonTip(FInvalidFileNameCharsHintText);
+ edtFileName.SetSelText(str);
+ Exit;
+ end;
+
+ // Other Keys
+ if not IsValidFileNameChar(Key)
+ then begin
+ Key := #0;
+ ShowBalloonTip(FInvalidFileNameCharsHintText);
end;
- Key := #0;
- ShowBalloonTip(FInvalidFileNameCharsHintText);
end;
procedure TRenamingWCl.ShowBalloonTip(const AText: String);
var ebt: TEditBalloonTip;
begin
+ FillChar(ebt, SizeOf(ebt), 0);
ebt.cbStruct := SizeOf(ebt);
ebt.pszTitle := nil;
ebt.pszText := Pointer(AText);
diff --git a/components/SpinEdit/NewSpin.pas b/components/SpinEdit/NewSpin.pas
index 3ab3b98..6ddf1ea 100644
--- a/components/SpinEdit/NewSpin.pas
+++ b/components/SpinEdit/NewSpin.pas
@@ -11,10 +11,6 @@ interface
Windows, Classes, StdCtrls, ExtCtrls, Controls, Messages, SysUtils,
Forms, Graphics, Menus, Buttons, ComCtrls;
-const
- InitRepeatPause = 400; { pause before repeat timer (ms) }
- RepeatPause = 100; { pause before hint window displays (ms)}
-
type
TTimerSpeedButton = class;
@@ -173,6 +169,10 @@ TTimerSpeedButton = class(TUpDown)
implementation
uses Themes;
+
+const
+ InitRepeatPause = 400; { pause before repeat timer (ms) }
+ RepeatPause = 100; { pause before hint window displays (ms)}
procedure Register;
begin
diff --git a/exe/CMD.txt b/exe/CMD.txt
index 940ea79..8ea5361 100644
--- a/exe/CMD.txt
+++ b/exe/CMD.txt
@@ -4,7 +4,15 @@ Set startup delay
-l[param]
Set UI language
-[param] = 1033 (English), 1036 (French), 1031 (German), 1041 (Japanese), 1049 (Russian)
+[param] = 1033 or en-US (English)
+ 1036 or fr-FR (French)
+ 1031 or de-DE (German)
+ 1032 or el-GR (Greek)
+ 1041 or ja-JP (Japanese)
+ 1045 or pl-PL (Polish)
+ 1049 or ru-RU (Russian)
+ 2052 or zh-CN (Chinese-Simplified)
+ 1042 or ko-KR (Korean)
-f[param]
Set path to configuration file
diff --git a/exe/Linkbar.lc3 b/exe/Linkbar.lc3
deleted file mode 100644
index 0c1ff55..0000000
Binary files a/exe/Linkbar.lc3 and /dev/null differ
diff --git a/exe/Locales/de-DE.ini b/exe/Locales/de-DE.ini
new file mode 100644
index 0000000..1940a01
--- /dev/null
+++ b/exe/Locales/de-DE.ini
@@ -0,0 +1,82 @@
+[de-DE] - German (Germany)
+New.Caption = Neue Linkbar
+New.ToWhom = Erstellen Sie Linkbar für:
+New.ForAll = Jeder, der diesen Computer verwendet (alle Benutzer)
+New.ForMe = Nur für mich (%s)
+New.Folder = Wählen Sie einen Ordner:
+New.Create = Erstellen
+New.Cancel = Abbrechen
+Menu.Shortcut = Neue Verknüpfung
+Menu.Open = Offene Arbeitsverzeichnis
+Menu.Create = Erstellen Linkbar...
+Menu.Delete = Löschen Sie das Linkbar
+Menu.Lock = Linkbar fixieren
+Menu.Sort = Alphabetisch sortieren
+Menu.Properties = Eigenschaften
+Menu.Close = Schließen
+Menu.CloseAll = Schließen Sie alle
+Jumplist.Recent = Zuletzt verwendet
+Jumplist.Frequent = Häufig
+Jumplist.Tasks = Aufgaben
+Jumplist.Pinned = Angeheftet
+Jumplist.Open = Ö&ffnen
+Jumplist.Pin = An diese Liste an&heften
+Jumplist.Unpin = V&on dieser Liste lösen
+Jumplist.Remove = &Aus Liste entfernen
+Jumplist.PinTip = An diese Liste anheften
+Jumplist.UnpinTip = Von dieser Liste lösen
+Rename.Caption = Umbenennung
+Rename.OK = OK
+Rename.Cancel = Abbrechen
+Color.Caption = Farbe
+Color.OK = OK
+Color.Cancel = Abbrechen
+Delete.Title = Sie entfernen die Linkbar "%s"
+Delete.Text = Arbeitsverzeichnis: %s
+Delete.Verification = Löschen Arbeitsverzeichnis
+Message.FileNotFound = Datei existiert nicht
+Message.DeleteShortcut = Verknüpfung löschen?
+Properties.View = Ansicht
+Properties.Appearance = Konfigurieren Sie Aussehen
+Properties.Position = Position auf dem Bildschirm:
+Properties.Left = Links
+Properties.Top = Oben
+Properties.Right = Rechts
+Properties.Bottom = Unten
+Properties.IconSize = Symbolgröße:
+Properties.BgColor = Hintergrundfarbe:
+Properties.Margins = Ränder (horizontal / vertikal):
+Properties.Order = Reihenfolge der Verknüpfungen:
+Properties.LtR = Links nach rechts
+Properties.UtD = Oben nach unten
+Properties.TextPos = Textpositionierung:
+Properties.Without = Ohne Text
+Properties.TextWidth = Textbreite / Einzug:
+Properties.TextColor = Textfarbe:
+Properties.GlowSize = Glühengröße:
+Properties.AlwaysOnTop = Linkbar immer im Vordergrund halten
+Properties.PageAutoHide = Automatische Ausblenden
+Properties.AutoHide = Konfigurieren Sie das automatische Ausblenden
+Properties.Hide = Ausblenden:
+Properties.Automatically = Automatisch
+Properties.Show = Anzeigen:
+Properties.MouseHover = Mausbewegung
+Properties.MouseLC = Maus Linksklick
+Properties.MouseRC = Maus Rechtsklick
+Properties.Delay = Verzögerung, ms:
+Properties.HotKey = Tastenkombination:
+Properties.Transparent = Transparent wenn Ausblenden
+Properties.Additional = Ansicht
+Properties.Jumplists = Sprunglisten
+Properties.No = Nein
+Properties.ForW7 = Für Windows 7:
+Properties.Style1 = Verwenden Sie Stil wie Taskleiste mit kombinierten Tasten
+Properties.ForW8 = Für Windows 8/8.1:
+Properties.AeroGlass = AeroGlass-Unterstützung aktivieren (separat installiert)
+Properties.About = Über
+Properties.Version = Version: %s
+Properties.SystemInfo = Systeminformationen:
+Properties.Localizer = Localizer: Asaq
+Properties.OK = OK
+Properties.Cancel = Abbrechen
+Properties.Apply = Übernehmen
\ No newline at end of file
diff --git a/exe/Locales/el-GR.ini b/exe/Locales/el-GR.ini
new file mode 100644
index 0000000..2a3b63e
--- /dev/null
+++ b/exe/Locales/el-GR.ini
@@ -0,0 +1,82 @@
+[el-GR] - Greek (Greece)
+New.Caption = Νέα γραμμή σύνδεσης
+New.ToWhom = Δημιουργία γραμμής σύνδεσης για:
+New.ForAll = &Οποιονδήποτε χρησιμοποιεί αυτόν τον υπολογιστή (όλοι οι χρήστες)
+New.ForMe = Μόνο για &μένα (%s)
+New.Folder = Επιλέξτε έναν φάκελο:
+New.Create = &Δημιουργία
+New.Cancel = Άκυρο
+Menu.Shortcut = Νέα συντόμευση
+Menu.Open = Άνοιγμα φακέλου εργασίας
+Menu.Create = Δημιουργία γραμμής σύνδεσης...
+Menu.Delete = Διαγραφή της γραμμής σύνδεσης
+Menu.Lock = Κλείδωμα της γραμμής σύνδεσης
+Menu.Sort = Ταξινόμηση αλφαβητικά
+Menu.Properties = Ιδιότητες
+Menu.Close = Κλείσιμο
+Menu.CloseAll = Κλείσιμο όλων
+Jumplist.Recent = Πρόσφατα
+Jumplist.Frequent = Στοιχεία που επιλέγονται συχνότερα
+Jumplist.Tasks = Εργασίες
+Jumplist.Pinned = Καρφιτσωμένα
+Jumplist.Open = Άν&οιγμα
+Jumplist.Pin = &Καρφίτσωμα σε αυτήν τη λίστα
+Jumplist.Unpin = &Ξεκαρφίτσωμα από αυτήν τη λίστα
+Jumplist.Remove = Κατά&ργηση από τη λίστα
+Jumplist.PinTip = Καρφίτσωμα σε αυτήν τη λίστα
+Jumplist.UnpinTip = Ξεκαρφίτσωμα από αυτήν τη λίστα
+Rename.Caption = Μετονομασία
+Rename.OK = Εντάξει
+Rename.Cancel = Άκυρο
+Color.Caption = Χρώμα
+Color.OK = Εντάξει
+Color.Cancel = Άκυρο
+Delete.Title = Θα διαγράψετε τη γραμμή σύνδεσης "%s"
+Delete.Text = Κατάλογος εργασίας: %s
+Delete.Verification = Διαγραφή καταλόγου εργασίας
+Message.FileNotFound = Το αρχείο δεν υπάρχει
+Message.DeleteShortcut = Διαγραφή σύνδεσης;
+Properties.View = Προβολή
+Properties.Appearance = Ρύθμιση εμφάνισης
+Properties.Position = Θέση στην οθόνη:
+Properties.Left = Αριστερά
+Properties.Top = Πάνω
+Properties.Right = Δεξιά
+Properties.Bottom = Κάτω
+Properties.IconSize = Μέγεθος εικονιδίου:
+Properties.BgColor = Χρώμα φόντου:
+Properties.Margins = Περιθώρια (οριζόντια / κάθετα):
+Properties.Order = Σειρά των συντομεύσεων:
+Properties.LtR = Αριστερά προς δεξιά
+Properties.UtD = Πάνω προς κάτω
+Properties.TextPos = Θέση κειμένου:
+Properties.Without = Χωρίς κείμενο
+Properties.TextWidth = Πλάτος/Εσοχή κειμένου:
+Properties.TextColor = Χρώμα κειμένου:
+Properties.GlowSize = Μέγεθος λάμψης:
+Properties.AlwaysOnTop = Πάντα στην κορυφή η γραμμή σύνδεσης
+Properties.PageAutoHide = Αυτόματη απόκρυψη
+Properties.AutoHide = Ρύθμιση αυτόματης απόκρυψης
+Properties.Hide = Απόκρυψη:
+Properties.Automatically = Αυτόματα
+Properties.Show = Εμφάνιση:
+Properties.MouseHover = Παραμονή του δείκτη
+Properties.MouseLC = Αριστερό κλικ ποντικιού
+Properties.MouseRC = Δεξί κλικ ποντικιού
+Properties.Delay = Καθυστέρηση (ms):
+Properties.HotKey = Συνδυασμός κλειδιών:
+Properties.Transparent = Διαφανές όταν είναι κρυμμένο
+Properties.Additional = Πρόσθετα
+Properties.Jumplists = Οι λίστες συντομεύσεων
+Properties.No = Οχι
+Properties.ForW7 = Για Windows 7
+Properties.Style1 = Χρήση στυλ, όπως της γραμμής εργασιών με συνδυασμό κουμπιών
+Properties.ForW8 = Για Windows 8/8.1
+Properties.AeroGlass = Ενεργ/ση υποστήριξης AeroGlass (εγκαθίσταται χωριστά)
+Properties.About = Περί
+Properties.Version = Έκδοση: %s
+Properties.SystemInfo = Πληροφορίες συστήματος:
+Properties.Localizer = Μεταφραστής: geogeo.gr
+Properties.OK = &Εντάξει
+Properties.Cancel = Ά&κυρο
+Properties.Apply = Εφαρμογή
\ No newline at end of file
diff --git a/exe/Locales/en-US.ini b/exe/Locales/en-US.ini
new file mode 100644
index 0000000..4d152ce
--- /dev/null
+++ b/exe/Locales/en-US.ini
@@ -0,0 +1,82 @@
+[en-US] - English (United States)
+New.Caption = New linkbar
+New.ToWhom = Create linkbar for:
+New.ForAll = &Anyone who uses this computer (all users)
+New.ForMe = Only for &me (%s)
+New.Folder = Choose a folder:
+New.Create = Create
+New.Cancel = Cancel
+Menu.Shortcut = New shortcut
+Menu.Open = Open working directory
+Menu.Create = Create linkbar...
+Menu.Delete = Delete the linkbar
+Menu.Lock = Lock the linkbar
+Menu.Sort = Sort alphabetically
+Menu.Properties = Properties
+Menu.Close = Close
+Menu.CloseAll = Close all
+Jumplist.Recent = Recent
+Jumplist.Frequent = Frequent
+Jumplist.Tasks = Tasks
+Jumplist.Pinned = Pinned
+Jumplist.Open = &Open
+Jumplist.Pin = P&in to this list
+Jumplist.Unpin = &Unpin from this list
+Jumplist.Remove = Remove &from this list
+Jumplist.PinTip = Pin to this list
+Jumplist.UnpinTip = Unpin from this list
+Rename.Caption = Renaming
+Rename.OK = OK
+Rename.Cancel = Cancel
+Color.Caption = Color
+Color.OK = OK
+Color.Cancel = Cancel
+Delete.Title = You remove the linkbar "%s"
+Delete.Text = Working directory: %s
+Delete.Verification = Delete working directory
+Message.FileNotFound = File does not exists
+Message.DeleteShortcut = Delete shortcut?
+Properties.View = View
+Properties.Appearance = Configure appearance
+Properties.Position = Position on screen:
+Properties.Left = Left
+Properties.Top = Top
+Properties.Right = Right
+Properties.Bottom = Bottom
+Properties.IconSize = Icon size:
+Properties.BgColor = Background color:
+Properties.Margins = Margins (horizontal/vertical):
+Properties.Order = Order of shortcuts:
+Properties.LtR = Left to right
+Properties.UtD = Up to down
+Properties.TextPos = Text position:
+Properties.Without = Without text
+Properties.TextWidth = Text width/indent:
+Properties.TextColor = Text color:
+Properties.GlowSize = Glow size:
+Properties.AlwaysOnTop = Keep the Linkbar on top of other windows
+Properties.PageAutoHide = AutoHide
+Properties.AutoHide = Configure auto-hide
+Properties.Hide = Hide:
+Properties.Automatically = Automatically
+Properties.Show = Show:
+Properties.MouseHover = Mouse hover
+Properties.MouseLC = Mouse left-click
+Properties.MouseRC = Mouse right-click
+Properties.Delay = Delay, ms:
+Properties.HotKey = Keyboard shortcut:
+Properties.Transparent = Transparent when hidden
+Properties.Additional = Additional
+Properties.Jumplists = Jumplists
+Properties.No = No
+Properties.ForW7 = For Windows 7
+Properties.Style1 = Use style like taskbar with combined buttons
+Properties.ForW8 = For Windows 8/8.1
+Properties.AeroGlass = Enable AeroGlass support (installed separately)
+Properties.About = About
+Properties.Version = Version: %s
+Properties.SystemInfo = System info:
+Properties.Localizer = localizer: Asaq
+Properties.OK = OK
+Properties.Cancel = Cancel
+Properties.Apply = Apply
\ No newline at end of file
diff --git a/exe/Locales/fr-FR.ini b/exe/Locales/fr-FR.ini
new file mode 100644
index 0000000..b7a6208
--- /dev/null
+++ b/exe/Locales/fr-FR.ini
@@ -0,0 +1,82 @@
+[fr-FR] - French (France)
+New.Caption = Nouvelle linkbar
+New.ToWhom = Créer la linkbar:
+New.ForAll = Pour tous les utilisateurs (de cette machine)
+New.ForMe = Seulement pour moi (%s)
+New.Folder = Choisir une dossier:
+New.Create = Créer
+New.Cancel = Annuler
+Menu.Shortcut = Nouveau raccourci
+Menu.Open = Ouvrir le répertoire de travail
+Menu.Create = Créer une linkbar...
+Menu.Delete = Supprimer la linkbar
+Menu.Lock = Verrouiller la linkbar
+Menu.Sort = Classer par ordre alphabétique
+Menu.Properties = Propriétés
+Menu.Close = Fermer
+Menu.CloseAll = Fermer tout
+Jumplist.Recent = Récent
+Jumplist.Frequent = Fréquent
+Jumplist.Tasks = Tâches
+Jumplist.Pinned = Épinglé
+Jumplist.Open = &Ouvrir
+Jumplist.Pin = Ép&ingler à cette liste
+Jumplist.Unpin = &Détacher de cette liste
+Jumplist.Remove = Suppri&mer de cette liste
+Jumplist.PinTip = Épingler à cette liste
+Jumplist.UnpinTip = Détacher de cette liste
+Rename.Caption = Changement de nom
+Rename.OK = OK
+Rename.Cancel = Annuler
+Color.Caption = Couleur
+Color.OK = OK
+Color.Cancel = Annuler
+Delete.Title = Vous supprimez la linkbar « %s »
+Delete.Text = Le répertoire de travail: %s
+Delete.Verification = Supprimer le répertoire de travail
+Message.FileNotFound = Fichier n’existe pas
+Message.DeleteShortcut = Supprimer le raccourci?
+Properties.View = Vue
+Properties.Appearance = Configurer l’apparence
+Properties.Position = Position sur l’écran:
+Properties.Left = À gauche
+Properties.Top = En haut
+Properties.Right = À droite
+Properties.Bottom = En bas
+Properties.IconSize = Taille des icônes:
+Properties.BgColor = Couleur de fond:
+Properties.Margins = Marges (horizontales/verticales):
+Properties.Order = Ordre des raccourcis:
+Properties.LtR = De gauche à droit
+Properties.UtD = De haute en bas
+Properties.TextPos = Position du texte:
+Properties.Without = Sans texte
+Properties.TextWidth = Largeur du texte/le retrait:
+Properties.TextColor = Couleur de texte:
+Properties.GlowSize = Taille glow:
+Properties.AlwaysOnTop = Conserver la Linkbar au-dessus des autres fenêtres
+Properties.PageAutoHide = Masquage automatique
+Properties.AutoHide = Configurer le masquage automatique
+Properties.Hide = Masquer:
+Properties.Automatically = Automatiquement
+Properties.Show = Afficher:
+Properties.MouseHover = Passant la souris
+Properties.MouseLC = Clic-gauche
+Properties.MouseRC = Clic-droit
+Properties.Delay = Retard (ms):
+Properties.HotKey = Combinaison de clés:
+Properties.Transparent = Transparente quand masquée
+Properties.Additional = En outre
+Properties.Jumplists = Les listes de raccourcis
+Properties.No = Non
+Properties.ForW7 = Pour Windows 7
+Properties.Style1 = Utilizer le style comme la barre des tâches avec les boutons combinés
+Properties.ForW8 = Pour Windows 8/8.1
+Properties.AeroGlass = Activer le support d’AeroGlass (installer séparément)
+Properties.About = À propos
+Properties.Version = Version: %s
+Properties.SystemInfo = Informations système:
+Properties.Localizer = localisation: nth_mkr
+Properties.OK = OK
+Properties.Cancel = Annuler
+Properties.Apply = Appliquer
\ No newline at end of file
diff --git a/exe/Locales/ja-JP.ini b/exe/Locales/ja-JP.ini
new file mode 100644
index 0000000..57a8543
--- /dev/null
+++ b/exe/Locales/ja-JP.ini
@@ -0,0 +1,82 @@
+[ja-JP] - Japanese (Japan)
+New.Caption = 新規 リンクバー
+New.ToWhom = リンクバーを作成する範囲:
+New.ForAll = このコンピューターを使用する全員(すべてのユーザー)
+New.ForMe = 現ユーザーのみ (%s)
+New.Folder = フォルダの選択:
+New.Create = 作成
+New.Cancel = キャンセル
+Menu.Shortcut = 新しいショートカット
+Menu.Open = 作業ディレクトリを開く
+Menu.Create = リンクバーを作成...
+Menu.Delete = リンクバーを削除
+Menu.Lock = リンクバーを固定
+Menu.Sort = アルファベット順にソート
+Menu.Properties = プロパティ
+Menu.Close = 閉じる
+Menu.CloseAll = すべて閉じる
+Jumplist.Recent = 最近使ったもの
+Jumplist.Frequent = よく使うもの
+Jumplist.Tasks = タスク
+Jumplist.Pinned = いつも表示
+Jumplist.Open = 開く(&O)
+Jumplist.Pin = いつも表示する(&I)
+Jumplist.Unpin = いつも表示するものから外す(&U)
+Jumplist.Remove = この一覧から削除(&F)
+Jumplist.PinTip = いつも表示する
+Jumplist.UnpinTip = いつも表示するものから外す
+Rename.Caption = 名称変更
+Rename.OK = OK
+Rename.Cancel = キャンセル
+Color.Caption = 色
+Color.OK = OK
+Color.Cancel = キャンセル
+Delete.Title = 削除するツールバー 「%s」
+Delete.Text = 作業ディレクトリ: %s
+Delete.Verification = 作業ディレクトリを削除します
+Message.FileNotFound = ファイルが存在しません
+Message.DeleteShortcut = リンクを削除しますか?
+Properties.View = 外観設定
+Properties.Appearance = 外観設定
+Properties.Position = スクリーン上の位置:
+Properties.Left = 左
+Properties.Top = 上
+Properties.Right = 右
+Properties.Bottom = 下
+Properties.IconSize = アイコンサイズ:
+Properties.BgColor = 背景色:
+Properties.Margins = 選択幅 (横幅/縦幅):
+Properties.Order = ショートカットの順番:
+Properties.LtR = 左から右へ
+Properties.UtD = 上から下へ
+Properties.TextPos = 文字位置:
+Properties.Without = 文字非表示
+Properties.TextWidth = 文字幅/字下げ:
+Properties.TextColor = テキストの色:
+Properties.GlowSize = グローサイズ:
+Properties.AlwaysOnTop = リンクバーをほかのウィンドウの手前に表示する
+Properties.PageAutoHide = 自動非表示
+Properties.AutoHide = 自動非表示設定
+Properties.Hide = 非表示:
+Properties.Automatically = 自動
+Properties.Show = 表示:
+Properties.MouseHover = マウス オーバー
+Properties.MouseLC = マウス 左クリック
+Properties.MouseRC = マウス 右クリック
+Properties.Delay = 遅延 (ミリ秒):
+Properties.HotKey = キーの組み合わせ:
+Properties.Transparent = 非表示時に透明化
+Properties.Additional = 拡張設定
+Properties.Jumplists = ジャンプ リスト
+Properties.No = いいえ
+Properties.ForW7 = Windows 7
+Properties.Style1 = 標準のタスクバーと同一のスタイルを利用
+Properties.ForW8 = Windows 8/8.1の場合
+Properties.AeroGlass = AeroGlassをサポート (別途インストール)
+Properties.About = ソフトについて
+Properties.Version = バージョン: %s
+Properties.SystemInfo = システム情報:
+Properties.Localizer = 翻訳者: Takahiro
+Properties.OK = OK
+Properties.Cancel = キャンセル
+Properties.Apply = 適用
\ No newline at end of file
diff --git a/exe/Locales/ko-KR.ini b/exe/Locales/ko-KR.ini
new file mode 100644
index 0000000..3d8cfc3
--- /dev/null
+++ b/exe/Locales/ko-KR.ini
@@ -0,0 +1,82 @@
+[ko-KR] - Korean (Korea)
+New.Caption = 툴바 새로 만들기
+New.ToWhom = 에 대한 툴바 생성:
+New.ForAll = 이 컴퓨터를 사용하는 사람 (모든 유저)
+New.ForMe = 특정 사용자 (%s)
+New.Folder = 폴더 선택:
+New.Create = 생성
+New.Cancel = 취소
+Menu.Shortcut = 바로 가기 만들기
+Menu.Open = 대상 폴더 열기
+Menu.Create = 툴바 새로 만들기...
+Menu.Delete = 툴바 삭제
+Menu.Lock = 툴바 잠금
+Menu.Sort = 알파벳순으로 정렬
+Menu.Properties = 환경 설정
+Menu.Close = 종료
+Menu.CloseAll = 모두 종료
+Jumplist.Recent = 최근 항목
+Jumplist.Frequent = 자주 사용하는 항목
+Jumplist.Tasks = 작업
+Jumplist.Pinned = 고정됨
+Jumplist.Open = 열기(&O)
+Jumplist.Pin = 이 목록에 고정(&I)
+Jumplist.Unpin = 이 목록에서 제거(&U)
+Jumplist.Remove = 이 목록에서 제거(&F)
+Jumplist.PinTip = 이 목록에 고정
+Jumplist.UnpinTip = 이 목록에서 제거
+Rename.Caption = 이름 바꾸기
+Rename.OK = 확인
+Rename.Cancel = 취소
+Color.Caption = 색깔
+Color.OK = 확인
+Color.Cancel = 취소
+Delete.Title = 툴바 삭제 "%s"
+Delete.Text = 대상 폴더: %s
+Delete.Verification = 작업 디렉토리 삭제
+Message.FileNotFound = 파일이 존재하지 않습니다.
+Message.DeleteShortcut = 바로 가기 삭제?
+Properties.View = 보기
+Properties.Appearance = 모양 구성
+Properties.Position = 화면상의 위치 :
+Properties.Left = 왼쪽
+Properties.Top = 위
+Properties.Right = 오른쪽
+Properties.Bottom = 아래
+Properties.IconSize = 아이콘 크기:
+Properties.BgColor = 배경색:
+Properties.Margins = 여백(가로/세로):
+Properties.Order = 바로 가기 순서:
+Properties.LtR = 왼쪽에서 오른쪽으로
+Properties.UtD = 위에서 아래로
+Properties.TextPos = 텍스트 위치:
+Properties.Without = 텍스트 표시하지 않음
+Properties.TextWidth = 텍스트 너비 / 들여 쓰기:
+Properties.TextColor = 텍스트 색:
+Properties.GlowSize = 글로우 크기:
+Properties.AlwaysOnTop = 툴바 표시 줄을 항상 위로 유지
+Properties.PageAutoHide = 자동 숨김
+Properties.AutoHide = 자동 숨기기 설정
+Properties.Hide = 툴바 숨김:
+Properties.Automatically = 자동으로
+Properties.Show = 툴바 표시:
+Properties.MouseHover = 툴바를 마우스에 가져갔을 때
+Properties.MouseLC = 툴바를 마우스로 클릭할 때
+Properties.MouseRC = 툴바를 마우스로 우클릭할 때
+Properties.Delay = 지연 시간:
+Properties.HotKey = 단축키:
+Properties.Transparent = 숨겨진 상태시 투명화
+Properties.Additional = 추가 기능
+Properties.Jumplists = 점프 목록은
+Properties.No = 아니
+Properties.ForW7 = 윈도우 7
+Properties.Style1 = 작업 표시 줄과 같은 스타일 사용
+Properties.ForW8 = 윈도우 7 8/8.1
+Properties.AeroGlass = AeroGlass 지원 사용 (별도 설치)
+Properties.About = 정보
+Properties.Version = 번역: %s
+Properties.SystemInfo = 시스템 정보:
+Properties.Localizer = 로컬 라이저: 미유키로즈
+Properties.OK = 확인
+Properties.Cancel = 취소
+Properties.Apply = 적용
\ No newline at end of file
diff --git a/exe/Locales/pl-PL.ini b/exe/Locales/pl-PL.ini
new file mode 100644
index 0000000..2e74ed1
--- /dev/null
+++ b/exe/Locales/pl-PL.ini
@@ -0,0 +1,82 @@
+[pl-PL] - Polish (Poland)
+New.Caption = Nowy pasek łączy
+New.ToWhom = Utwórz pasek łączy dla:
+New.ForAll = &Każdego, kto używa tego komputera (wszyscy użytkownicy)
+New.ForMe = Tylko dla &mnie (%s)
+New.Folder = Wybierz folder:
+New.Create = Utwórz
+New.Cancel = Anuluj
+Menu.Shortcut = Nowy skrót
+Menu.Open = Otwórz katalog roboczy
+Menu.Create = Utwórz pasek łączy...
+Menu.Delete = Usuń pasek łączy
+Menu.Lock = Zablokuj pasek łączy
+Menu.Sort = Sortuj alfabetycznie
+Menu.Properties = Właściwości
+Menu.Close = Zamknij
+Menu.CloseAll = Zamknij wszystkie
+Jumplist.Recent = Najnowsze
+Jumplist.Frequent = Częste
+Jumplist.Tasks = Zadania
+Jumplist.Pinned = Zakotwiczony
+Jumplist.Open = &Otwórz
+Jumplist.Pin = P&rzypnij do tej listy
+Jumplist.Unpin = &Odepnij z tej listy
+Jumplist.Remove = Usuń &z tej listy
+Jumplist.PinTip = Przypnij do tej listy
+Jumplist.UnpinTip = Odepnij z tej listy
+Rename.Caption = Zmiana nazwy
+Rename.OK = OK
+Rename.Cancel = Anuluj
+Color.Caption = Kolor
+Color.OK = OK
+Color.Cancel = Anuluj
+Delete.Title = Usuniesz pasek łączy "%s"
+Delete.Text = Katalog roboczy: %s
+Delete.Verification = Usuń katalog roboczy
+Message.FileNotFound = Plik nie istnieje
+Message.DeleteShortcut = Usunąć skrót?
+Properties.View = Widok
+Properties.Appearance = Konfiguracja wyglądu
+Properties.Position = Pozycja na ekranie:
+Properties.Left = Z lewej
+Properties.Top = Na górze
+Properties.Right = Z prawej
+Properties.Bottom = Na dole
+Properties.IconSize = Rozmiar ikon:
+Properties.BgColor = Kolor tła:
+Properties.Margins = Marginesy (poziomy/pionowy):
+Properties.Order = Kolejność skrótów:
+Properties.LtR = Od lewej do prawej
+Properties.UtD = Do dołu
+Properties.TextPos = Pozycja tekstu:
+Properties.Without = Bez tekstu
+Properties.TextWidth = Tekst szerokość/wcięcie:
+Properties.TextColor = Kolor tekstu:
+Properties.GlowSize = Rozmiar poświaty:
+Properties.AlwaysOnTop = Trzymaj pasek łączy na wierzchu
+Properties.PageAutoHide = Automatycznego ukrywania
+Properties.AutoHide = Konfiguracja automatycznego ukrywania
+Properties.Hide = Ukryj:
+Properties.Automatically = Automatycznie
+Properties.Show = Pokaż:
+Properties.MouseHover = Przesunięcie myszy
+Properties.MouseLC = Lewy klik myszy
+Properties.MouseRC = Prawy klik myszy
+Properties.Delay = Opóźnienie, ms:
+Properties.HotKey = Skrót klawiszowy:
+Properties.Transparent = Przezroczysty, kiedy ukryty
+Properties.Additional = Dodatkowo
+Properties.Jumplists = Listy szybkiego dostępu
+Properties.No = Nie
+Properties.ForW7 = Dla Windows 7
+Properties.Style1 = Użyj stylu jak w pasku zadań z połączonymi przyciskami
+Properties.ForW8 = Dla Windows 8/8.1
+Properties.AeroGlass = Włącz wsparcie dla AeroGlass (zainstalowane oddzielnie)
+Properties.About = O Linkbar
+Properties.Version = Wersja: %s
+Properties.SystemInfo = Informacje o systemie:
+Properties.Localizer = lokalizator: Galileusz
+Properties.OK = OK
+Properties.Cancel = Anuluj
+Properties.Apply = Zastosuj
\ No newline at end of file
diff --git a/exe/Locales/ru-RU.ini b/exe/Locales/ru-RU.ini
new file mode 100644
index 0000000..9e521a1
--- /dev/null
+++ b/exe/Locales/ru-RU.ini
@@ -0,0 +1,82 @@
+[ru-RU] - Russian (Russia)
+New.Caption = Новая панелька
+New.ToWhom = Создать панельку:
+New.ForAll = Для всех пользователей компьютера
+New.ForMe = Для меня (%s)
+New.Folder = Выбор папки:
+New.Create = Создать
+New.Cancel = Отмена
+Menu.Shortcut = Новый ярлык
+Menu.Open = Открыть рабочий каталог
+Menu.Create = Создать панельку...
+Menu.Delete = Удалить панельку
+Menu.Lock = Закрепить панельку
+Menu.Sort = Сортировать по алфавиту
+Menu.Properties = Свойства
+Menu.Close = Закрыть
+Menu.CloseAll = Закрыть все
+Jumplist.Recent = Последние
+Jumplist.Frequent = Часто используемые
+Jumplist.Tasks = Задачи
+Jumplist.Pinned = Закреплено
+Jumplist.Open = &Открыть
+Jumplist.Pin = &Закрепить в списке
+Jumplist.Unpin = &Изъять из списка
+Jumplist.Remove = Удалить &из этого списка
+Jumplist.PinTip = Закрепить в списке
+Jumplist.UnpinTip = Изъять из списка
+Rename.Caption = Переименование
+Rename.OK = OK
+Rename.Cancel = Отмена
+Color.Caption = Цвет
+Color.OK = OK
+Color.Cancel = Отмена
+Delete.Title = Вы удаляете панельку "%s"
+Delete.Text = Рабочий каталог: %s
+Delete.Verification = Удалить рабочий каталог
+Message.FileNotFound = Файл не существует
+Message.DeleteShortcut = Удалить ярлык?
+Properties.View = Вид
+Properties.Appearance = Настройте внешний вид
+Properties.Position = Положение на экране:
+Properties.Left = Слева
+Properties.Top = Сверху
+Properties.Right = Cправа
+Properties.Bottom = Cнизу
+Properties.IconSize = Размер значков:
+Properties.BgColor = Цвет фона:
+Properties.Margins = Поля (горизонтальные/вертикальные):
+Properties.Order = Порядок ярлыков:
+Properties.LtR = Слева направо
+Properties.UtD = Сверху вниз
+Properties.TextPos = Положение текста:
+Properties.Without = Без текста
+Properties.TextWidth = Ширина/отступ текста:
+Properties.TextColor = Цвет текста:
+Properties.GlowSize = Размер тени:
+Properties.AlwaysOnTop = Отображать панельку поверх остальных окон
+Properties.PageAutoHide = Автоскрытие
+Properties.AutoHide = Настройте автоскрытие
+Properties.Hide = Скрывать:
+Properties.Automatically = Автоматически
+Properties.Show = Показывать:
+Properties.MouseHover = При наведении
+Properties.MouseLC = По левому клику
+Properties.MouseRC = По правому клику
+Properties.Delay = Задержка (мс):
+Properties.HotKey = Сочетание клавиш:
+Properties.Transparent = Прозрачная когда скрыта
+Properties.Additional = Дополнительно
+Properties.Jumplists = Списки переходов
+Properties.No = Нет
+Properties.ForW7 = Для Windows 7
+Properties.Style1 = Использовать стиль панели задач с группировкой
+Properties.ForW8 = Для Windows 8/8.1
+Properties.AeroGlass = Включить поддержку AeroGlass (устанавливается отдельно)
+Properties.About = О программе
+Properties.Version = Версия: %s
+Properties.SystemInfo = Информация о системе:
+Properties.Localizer = локализатор: Asaq
+Properties.OK = OK
+Properties.Cancel = Отмена
+Properties.Apply = Применить
\ No newline at end of file
diff --git a/exe/Locales/zh-CN.ini b/exe/Locales/zh-CN.ini
new file mode 100644
index 0000000..dfbd020
--- /dev/null
+++ b/exe/Locales/zh-CN.ini
@@ -0,0 +1,82 @@
+[zh-CN] - Chinese (Simplified)
+New.Caption = 新建 Linkbar
+New.ToWhom = 为以下用户创建:
+New.ForAll = 所有使用此计算机的用户(所有用户)
+New.ForMe = 仅为我创建(%s)
+New.Folder = 选择文件夹:
+New.Create = 新建
+New.Cancel = 取消
+Menu.Shortcut = 添加 快捷方式
+Menu.Open = 打开工作目录
+Menu.Create = 新建 Linkbar...
+Menu.Delete = 删除 Linkbar
+Menu.Lock = 锁定 Linkbar
+Menu.Sort = 按 A-Z 顺序排列
+Menu.Properties = 偏好设置
+Menu.Close = 关闭
+Menu.CloseAll = 关闭所有
+JumpList.Recent = 最近
+JumpList.Frequent = 常用
+JumpList.Tasks = 任务
+JumpList.Pinned = 已固定
+Jumplist.Open = 打开
+JumpList.Pin = 锁定到此列表
+JumpList.Unpin = 从此列表解锁
+JumpList.Remove = 从列表中删除
+JumpList.PinTip = 锁定到此列表
+JumpList.UnpinTip = 从此列表解锁
+Rename.Caption = 重命名
+Rename.OK = 确定
+Rename.Cancel = 取消
+Color.Caption = 颜色
+Color.OK = 确定
+Color.Cancel = 取消
+Delete.Title = 已移除 Linkbar "%s"
+Delete.Text = 工作目录路径 %s
+Delete.Verification = 删除工作目录
+Message.FileNotFound = 文件不存在
+Message.DeleteShortcut = 是否删除快捷方式?
+Properties.View = 视图设置
+Properties.Appearance = 外观配置
+Properties.Position = 屏幕位置:
+Properties.Left = 左边
+Properties.Top = 顶部
+Properties.Right = 右边
+Properties.Bottom = 底部
+Properties.IconSize = 图标大小:
+Properties.BgColor = 背景颜色:
+Properties.Margins = 边框大小(水平宽度/垂直长度):
+Properties.Order = 快捷方式排序:
+Properties.LtR = 从左到右
+Properties.UtD = 从上往下
+Properties.TextPos = 字体位置:
+Properties.Without = 不显示文字
+Properties.TextWidth = 字体间距/缩进:
+Properties.TextColor = 字体颜色:
+Properties.GlowSize = 发光大小:
+Properties.AlwaysOnTop = Linkbar 保持在其他窗口的前端
+Properties.PageAutoHide = 自动隐藏
+Properties.AutoHide = 配置自动隐藏
+Properties.Hide = 隐藏:
+Properties.Automatically = 自动
+Properties.Show = 显示:
+Properties.MouseHover = 鼠标靠近
+Properties.MouseLC = 鼠标左键
+Properties.MouseRC = 鼠标右键
+Properties.Delay = 延迟,毫秒:
+Properties.HotKey = 键盘快捷键:
+Properties.Transparent = 隐藏时透明显示
+Properties.Additional = 附加设置
+Properties.Jumplists = 跳转列表
+Properties.No = 没有
+Properties.ForW7 = 针对 Windows7
+Properties.Style1 = 使用纽扣式风格任务栏
+Properties.ForW8 = 针对 Windows8/8.1
+Properties.AeroGlass = 开启毛玻璃特效支持(需另行安装)
+Properties.About = 关于
+Properties.Version = 版本号:%s
+Properties.SystemInfo = 系统信息:
+Properties.Localizer = 翻译者:Hue Liu
+Properties.OK = 确定
+Properties.Cancel = 取消
+Properties.Apply = 应用
\ No newline at end of file
diff --git a/exe/README.txt b/exe/README.txt
index 9e5966a..339ba24 100644
--- a/exe/README.txt
+++ b/exe/README.txt
@@ -8,10 +8,10 @@ Note:
1) Linkbar support Windows Vista and above
2) Linkbar work with .lnk, .url and .website files
-Version: 1.6.6
+Version: 1.6.7
License type: Freeware
OS: Windows Vista/7/8/8.1/10
-Languages: English (default), French, German, Japanese, Russian, localization support (see LOCALIZATION.TXT)
+Languages: English (default), Chinese-Simplified, French, German, Greek, Japanese, Korean, Polish, Russian, localization support
Email: linkbar@yandex.ru
===============================================================================
@@ -23,11 +23,11 @@ Email: linkbar@yandex.ru
- Classic Shell
- DelLocXE
- GunSmoker-a blog
+- Localizers
- MSDN
- Near users
- Ru-Board community
- StartIsBack
-- Takahiro
- Unknown programmers from internet
===============================================================================
@@ -35,6 +35,9 @@ Email: linkbar@yandex.ru
== Links
===============================================================================
+- Source code:
+ https://github.com/ATGH15102AFMLD/Linkbar
+
- Project page on Sourceforge:
https://sourceforge.net/projects/linkbar/
@@ -52,6 +55,26 @@ Email: linkbar@yandex.ru
== History
===============================================================================
+== Version 1.6.7 general release (Dec, 2017):
+
+add: New localization system. Simple and clear
+add: Chinese-Simplified localization (Hue Liu)
+add: Greek localization (geogeo.gr)
+add: Korean localization (미유키로즈)
+add: Polish localization (Galileusz)
+add: AutoHide by Keyboard shortcut
+add: Restoring the panels after restarting Explorer.exe
+add: Keyboard control. Arrows, Spacebar/Enter, Menu, F2, Delete(+Shift) and Esc supported
+add: Jumplist keyboard control
+add: Option for disable Jumplists
+add: Option "Keep the Linkbar on top of other windows"
+del: Old localization files - Linkbar.lc3, LOCALIZATION.txt
+fix: Exception on closing if the Properties is open
+fix: Multiple separators in Shell menu (e.g. for a shortcut to an HTML-file)
+fix: Incorrect behavior in negative desktop coordinates
+
+===============================================================================
+
== Version 1.6.6 general release (Feb, 2017):
add: German localization (Asaq)
diff --git a/src/AccessBar.pas b/src/AccessBar.pas
index 14e9212..c330a9d 100644
--- a/src/AccessBar.pas
+++ b/src/AccessBar.pas
@@ -14,10 +14,6 @@ interface
Messages, SysUtils, Classes, Controls, Forms,
ShellApi, Vcl.Dialogs, Linkbar.Consts, Linkbar.OS;
-const
- APPBAR_CALLBACK = WM_USER + 1;
- CUSTOM_ABN_FULLSCREENAPP = WM_USER + 2;
-
type
TQuerySizingEvent = procedure(Sender: TObject; AVertical: Boolean;
var AWidth, AHeight: Integer) of object;
@@ -26,7 +22,6 @@ interface
THiddenForm = class (TCustomForm)
private
-
FAccessHandle: THandle;
protected
procedure CreateParams(var Params: TCreateParams); override;
@@ -39,6 +34,9 @@ THiddenForm = class (TCustomForm)
end;
TAccessBar = class(TComponent)
+ private
+ const
+ HWND_STYLE: array[Boolean] of HWND = (HWND_NOTOPMOST, HWND_TOPMOST);
private
gABRegistered: boolean;
FOwnerOriginalWndProc: TWndMethod;
@@ -49,8 +47,10 @@ TAccessBar = class(TComponent)
FQueryAutoHide: TQueryHideEvent;
FHandle: HWND;
FBoundRect: TRect;
+ FStayOnTop: Boolean;
// special form for autohide
ahform: THiddenForm;
+ FTaskbarCreated: UINT;
procedure SetAutoHide(const AValue: boolean);
procedure SetSide(const AValue: TScreenAlign);
procedure AppBWndProc(var Msg: TMessage);
@@ -71,6 +71,7 @@ TAccessBar = class(TComponent)
procedure AppBarPosChanged;
procedure AppBarFullScreenApp(AEnabled: Boolean);
published
+ property StayOnTop: Boolean read FStayOnTop write FStayOnTop;
property AutoHide: boolean read FAutoHide write SetAutoHide;
property Side: TScreenAlign read FSide write SetSide default saTop;
property QuerySizing: TQuerySizingEvent read FQuerySizing write FQuerySizing;
@@ -83,13 +84,49 @@ TAccessBar = class(TComponent)
implementation
-uses Types, Math, Linkbar.Loc;
+uses Types, Math, Linkbar.L10n;
const
+ APPBAR_CALLBACK = WM_USER + 1;
+ APPBAR_FULLSCREENAPP = WM_USER + 2;
+ APPBAR_TASKBARSTARTED = WM_USER + 3;
+
// Multi Monitor support, introduced in Windows 8
ABM_GETAUTOHIDEBAREX = $0000000b;
ABM_SETAUTOHIDEBAREX = $0000000c;
+procedure ChangeWindowMessageFilterEx(const AWnd: HWND; const AMessage: UINT);
+const MSGFLT_ALLOW = 1;
+type
+ CHANGEFILTERSTRUCT = packed record
+ cbSize: DWORD;
+ ExtStatus: DWORD;
+ end;
+ TChangeFilterStruct = CHANGEFILTERSTRUCT;
+ PChangeFilterStruct = ^TChangeFilterStruct;
+
+ TChangeWindowMessageFilter = function (hWnd: HWND; Message: UINT; Action: DWORD): BOOL; stdcall;
+ TChangeWindowMessageFilterEx = function (hWnd: HWND; Message: UINT; Action: DWORD; pChangeFilterStruct: PChangeFilterStruct): BOOL; stdcall;
+
+var proc: TChangeWindowMessageFilter;
+ procEx: TChangeWindowMessageFilterEx;
+begin
+ @procEx := GetProcAddress(GetModuleHandle(user32), 'ChangeWindowMessageFilterEx');
+ if Assigned(procEx)
+ then begin
+ if not procEx(AWnd, AMessage, MSGFLT_ALLOW, nil)
+ then MessageBox(0, PChar(SysErrorMessage(GetLastError)), nil, MB_OK);
+ end
+ else begin
+ @proc := GetProcAddress(GetModuleHandle(user32), 'ChangeWindowMessageFilter');
+ if Assigned(proc)
+ then begin
+ if not proc(AWnd, AMessage, MSGFLT_ALLOW)
+ then MessageBox(0, PChar(SysErrorMessage(GetLastError)), nil, MB_OK);
+ end;
+ end;
+end;
+
function IsVertical(const AEdge: TScreenAlign): Boolean; inline;
begin
Result := (AEdge = saLeft) or (AEdge = saRight);
@@ -123,8 +160,8 @@ constructor THiddenForm.CreateNew(AOwner: TComponent; Dummy: Integer = 0);
rabd.hWnd := Self.Handle;
rabd.uCallbackMessage := APPBAR_CALLBACK;
FAccessHandle := 0;
- if SHAppBarMessage(ABM_NEW, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ if SHAppBarMessage(ABM_NEW, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
end;
procedure THiddenForm.CreateParams(var Params: TCreateParams);
@@ -141,8 +178,8 @@ destructor THiddenForm.Destroy;
FillChar(rabd, SizeOf(rabd), 0);
rabd.cbSize := SizeOf(rabd);
rabd.hWnd := Self.Handle;
- if SHAppBarMessage(ABM_REMOVE, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ if SHAppBarMessage(ABM_REMOVE, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
inherited Destroy;
end;
@@ -158,8 +195,8 @@ procedure THiddenForm.SetMonitor(const AMonitorNum: Integer);
rabd.rc.Width := 0;
rabd.rc.Height := 0;
- if SHAppBarMessage(ABM_SETPOS, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ if SHAppBarMessage(ABM_SETPOS, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
MoveWindow(Handle, rabd.rc.Left, rabd.rc.Top, 0, 0, False);
end;
@@ -169,7 +206,7 @@ procedure THiddenForm.WndProc(var Msg: TMessage);
if Msg.Msg = APPBAR_CALLBACK
then begin
if (Msg.wParam = ABN_FULLSCREENAPP) and IsWindow(FAccessHandle)
- then SendMessage(FAccessHandle, CUSTOM_ABN_FULLSCREENAPP, 0, Msg.lParam);
+ then SendMessage(FAccessHandle, APPBAR_FULLSCREENAPP, 0, Msg.lParam);
end
else inherited WndProc(Msg);
end;
@@ -183,44 +220,31 @@ procedure TAccessBar.RegisterAppBar;
var rabd: TAppBarData;
begin
if gABRegistered then exit;
- // check if we are not in the Delphi IDE
- if not (csDesigning in ComponentState) then
- begin
- // make sure we get the notification messages
- FOwnerOriginalWndProc := TWinControl(Owner).WindowProc;
- TWinControl(Owner).WindowProc := AppBWndProc;
- FillChar(rabd, SizeOf(rabd), 0);
- rabd.cbSize:= SizeOf(rabd);
- rabd.hWnd := FHandle;
- rabd.uCallbackMessage:= APPBAR_CALLBACK;
- // register the application bar within the system
- if SHAppBarMessage(ABM_NEW, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ FillChar(rabd, SizeOf(rabd), 0);
+ rabd.cbSize:= SizeOf(rabd);
+ rabd.hWnd := FHandle;
+ rabd.uCallbackMessage:= APPBAR_CALLBACK;
+ // register the application bar within the system
+ if SHAppBarMessage(ABM_NEW, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
- gABRegistered := TRUE;
- end;
+ gABRegistered := TRUE;
end;
procedure TAccessBar.UnregisterAppBar;
var rabd: TAppBarData;
begin
if not gABRegistered then exit;
- // check if the form is not being destroyed and not in the Delphi IDE
- if not (csDesigning in ComponentState) then
- begin
- if not (csDestroying in ComponentState) then
- TWinControl(Owner).WindowProc := FOwnerOriginalWndProc;
- FillChar(rabd, SizeOf(rabd), 0);
- rabd.cbSize:= SizeOf(rabd);
- rabd.hWnd := FHandle;
- // remove the application bar
- if SHAppBarMessage(ABM_REMOVE, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
- gABRegistered := FALSE;
- FBoundRect := TRect.Empty;
- end;
+ FillChar(rabd, SizeOf(rabd), 0);
+ rabd.cbSize:= SizeOf(rabd);
+ rabd.hWnd := FHandle;
+ // remove the application bar
+ if SHAppBarMessage(ABM_REMOVE, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
+ gABRegistered := FALSE;
+ FBoundRect := TRect.Empty;
end;
constructor TAccessBar.Create(AOwner: TComponent);
@@ -236,6 +260,16 @@ constructor TAccessBar.Create(AOwner: TComponent);
// for Delphi we only use descendants of TCustomForm
if (AOwner is TCustomForm) then
begin
+ // make sure we are the only one
+ for I:=0 to AOwner.ComponentCount -1 do
+ begin
+ if (AOwner.Components[I] is TAccessBar) and (AOwner.Components[I] <> Self)
+ then raise Exception.Create('Ooops, you need only *ONE* of these');
+ end;
+
+ FOwnerOriginalWndProc := TWinControl(Owner).WindowProc;
+ TWinControl(Owner).WindowProc := AppBWndProc;
+
FHandle := TWinControl(AOwner).Handle;
ahform := THiddenForm.CreateNew(nil);
ahform.AccessHandle := FHandle;
@@ -243,12 +277,10 @@ constructor TAccessBar.Create(AOwner: TComponent);
FBoundRect := TRect.Empty;
- // make sure we are the only one
- for I:=0 to AOwner.ComponentCount -1 do
- begin
- if (AOwner.Components[I] is TAccessBar) and (AOwner.Components[I] <> Self) then
- raise Exception.Create('Ooops, you need only *ONE* of these');
- end;
+ FTaskbarCreated := RegisterWindowMessage('TaskbarCreated');
+ if (FTaskbarCreated = 0)
+ then raise Exception.Create(SysErrorMessage(GetLastError));
+ ChangeWindowMessageFilterEx(FHandle, FTaskbarCreated);
end
else
raise Exception.Create('Sorry, can''t do this only with TCustomForms');
@@ -266,6 +298,8 @@ constructor TAccessBar.Create2(AOwner: TComponent; iSide: TScreenAlign; iAutoHid
destructor TAccessBar.Destroy;
begin
+ TWinControl(Owner).WindowProc := FOwnerOriginalWndProc;
+
if Assigned(ahform) then
begin
ahform.FAccessHandle := 0;
@@ -286,8 +320,6 @@ procedure TAccessBar.AppBarQuerySetPos;
iHeight, iWidth: Integer;
rabd: TAppBarData;
begin
- if (csDesigning in ComponentState) then Exit;
-
if not InRange(MonitorNum, 0, Screen.MonitorCount-1)
then MonitorNum := Screen.PrimaryMonitor.MonitorNum;
@@ -299,8 +331,8 @@ procedure TAccessBar.AppBarQuerySetPos;
if not AutoHide then
// query the new position
- if SHAppBarMessage(ABM_QUERYPOS, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ if SHAppBarMessage(ABM_QUERYPOS, rabd) = 0
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
iWidth := rabd.rc.Width;
iHeight := rabd.rc.Height;
@@ -330,9 +362,9 @@ procedure TAccessBar.AppBarQuerySetPos;
end;
// set the new size
- if not AutoHide then
- if SHAppBarMessage(ABM_SETPOS, rabd) = 0 then
- raise Exception.Create(SysErrorMessage(GetLastError()));
+ if (not AutoHide)
+ and (SHAppBarMessage(ABM_SETPOS, rabd) = 0)
+ then raise Exception.Create(SysErrorMessage(GetLastError()));
// request the new size
if Assigned(FQuerySized)
@@ -389,6 +421,21 @@ procedure TAccessBar.AppBWndProc(var Msg: TMessage);
var rabd: TAppBarData;
begin
case Msg.Msg of
+ APPBAR_TASKBARSTARTED:
+ begin
+ // TODO: Check logic
+ if (AutoHide)
+ then
+ SetSide(FSide)
+ else begin
+ UnregisterAppBar;
+ RegisterAppBar;
+ end;
+ end;
+ APPBAR_FULLSCREENAPP:
+ begin
+ Self.AppBarFullScreenApp(Msg.LParam <> 0);
+ end;
APPBAR_CALLBACK:
begin
case Msg.wParam of
@@ -411,6 +458,10 @@ procedure TAccessBar.AppBWndProc(var Msg: TMessage);
SHAppBarMessage(ABM_ACTIVATE, rabd);
inherited;
end;
+ else begin
+ if (Msg.Msg = FTaskbarCreated)
+ then PostMessage(FHandle, APPBAR_TASKBARSTARTED, 0, 0);
+ end;
end;
// call the original WndProc
if Assigned(FOwnerOriginalWndProc) then FOwnerOriginalWndProc(Msg);
@@ -422,8 +473,6 @@ procedure TAccessBar.AppBarSetAutoHide(AEnabled: Boolean);
rabd: TAppBarData;
hr: Cardinal;
begin
- if (csDesigning in ComponentState) then Exit;
-
FillChar(rabd, SizeOf(rabd), 0);
rabd.cbSize := SizeOf(rabd);
rabd.hWnd := FHandle;
@@ -450,31 +499,32 @@ procedure TAccessBar.AppBarSetAutoHide(AEnabled: Boolean);
if Assigned(FQueryAutoHide) then
FQueryAutoHide(Self, TRUE);
- SetWindowPos(FHandle, HWND_TOPMOST, 0, 0, 0, 0,
+ SetWindowPos(FHandle, HWND_STYLE[FStayOnTop], 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER);
AppBarQuerySetPos;
- end else begin
- FAutoHide := FALSE;
- RegisterAppBar;
+ end
+ else begin
+ FAutoHide := FALSE;
+ RegisterAppBar;
- SetWindowPos(FHandle, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER);
+ SetWindowPos(FHandle, HWND_STYLE[FStayOnTop], 0, 0, 0, 0,
+ SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER);
- AppBarQuerySetPos;
- if Assigned(FQueryAutoHide)
- then FQueryAutoHide(Self, FALSE);
- if AEnabled then
- begin
- td := TTaskDialog.Create(Self.Owner);
- td.MainIcon := tdiInformation;
- td.Caption := APP_NAME_LINKBAR;
- td.Title := '';
- td.text := MUILoadResString(LB_FN_TOOLBAR, LB_RS_TB_AUTOHIDEALREADYEXISTS);
- td.CommonButtons := [tcbOk];
- td.Execute;
- td.Free;
- end;
+ AppBarQuerySetPos;
+ if Assigned(FQueryAutoHide)
+ then FQueryAutoHide(Self, FALSE);
+ if AEnabled then
+ begin
+ td := TTaskDialog.Create(Self.Owner);
+ td.MainIcon := tdiInformation;
+ td.Caption := APP_NAME_LINKBAR;
+ td.Title := '';
+ td.text := L10nMui(LB_FN_TOOLBAR, LB_RS_TB_AUTOHIDEALREADYEXISTS);
+ td.CommonButtons := [tcbOk];
+ td.Execute;
+ td.Free;
+ end;
end;
end;
@@ -486,10 +536,9 @@ procedure TAccessBar.AppBarPosChanged;
procedure TAccessBar.AppBarFullScreenApp(AEnabled: Boolean);
var Flags: HWND;
begin
- Flags := HWND_BOTTOM;
-
- if not AEnabled and AutoHide
- then Flags := HWND_TOPMOST;
+ if AEnabled
+ then Flags := HWND_BOTTOM
+ else Flags := HWND_STYLE[FStayOnTop];
SetWindowPos(FHandle, Flags, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER);
diff --git a/src/ExplorerMenu.pas b/src/ExplorerMenu.pas
index e8d4eeb..8baa152 100644
--- a/src/ExplorerMenu.pas
+++ b/src/ExplorerMenu.pas
@@ -97,6 +97,32 @@ function BitmapFromIcon(AIcon: HICON; ASize: integer): HBITMAP;
procedure ExplorerMenuPopup(const AWnd: HWND; const APidl: PItemIDList;
const AScrPt: TPoint; const AShift: Boolean; const ASubMenu: HMENU);
+
+ procedure RemoveMultipleSeparators(const AMenu: HMENU);
+ var i, count: Integer;
+ separator: Boolean;
+ mi: TMenuItemInfo;
+ begin
+ FillChar(mi, SizeOf(mi), 0);
+ mi.cbSize := SizeOf(mi);
+ mi.fMask := MIIM_FTYPE;
+ separator := True;
+ count := GetMenuItemCount(AMenu);
+ i := 0;
+ while (i < count) do
+ begin
+ mi.fType := 0;
+ if (GetMenuItemInfo(AMenu, i, True, mi))
+ and (mi.fType = MFT_SEPARATOR)
+ and separator
+ then DeleteMenu(AMenu, i, MF_BYPOSITION)
+ else Inc(i);
+ separator := mi.fType = MFT_SEPARATOR
+ end;
+ if (count > 0) and separator
+ then DeleteMenu(AMenu, count-1, MF_BYPOSITION);
+ end;
+
var
CoInit: HRESULT;
Menu: HMenu;
@@ -112,7 +138,6 @@ procedure ExplorerMenuPopup(const AWnd: HWND; const APidl: PItemIDList;
miinfo: TMenuItemInfo;
hIco: HICON;
hbmp: HBITMAP;
- hr: HRESULT;
iconsize: Integer;
begin
CoInit := CoInitializeEx(nil, COINIT_MULTITHREADED);
@@ -163,12 +188,10 @@ procedure ExplorerMenuPopup(const AWnd: HWND; const APidl: PItemIDList;
miinfo.dwTypeData := PChar('Linkbar');
InsertMenuItem(Menu, insertBefore, True, miinfo);
- hr := S_OK;
+ // Icon for Linkbar submenu item
iconsize := GetSystemMetrics(SM_CXSMICON);
- hIco := LoadImage(HInstance, MakeIntResource('MAINICON'), IMAGE_ICON,
- iconsize, iconsize, LR_DEFAULTCOLOR); {}
- if Succeeded(hr)
- and (hIco <> 0)
+ hIco := LoadImage(HInstance, MakeIntResource('MAINICON'), IMAGE_ICON, iconsize, iconsize, LR_DEFAULTCOLOR);
+ if (hIco <> 0)
then begin
hbmp := BitmapFromIcon(hIco, GetSystemMetrics(SM_CXSMICON));
DestroyIcon(hIco);
@@ -178,6 +201,9 @@ procedure ExplorerMenuPopup(const AWnd: HWND; const APidl: PItemIDList;
miinfo.hbmpItem := hbmp;
SetMenuItemInfo(Menu, insertBefore, True, miinfo);
end;
+
+ // Sometimes menus have multiple separators e.g. for html shortcut. In Explorer.exe there is no such
+ RemoveMultipleSeparators(Menu);
end;
ICMenu.QueryInterface(IContextMenu2, g_cm2);
diff --git a/src/LBToolbar.pas b/src/LBToolbar.pas
index e8d1bbe..c6977b6 100644
--- a/src/LBToolbar.pas
+++ b/src/LBToolbar.pas
@@ -7,7 +7,7 @@
{$i linkbar.inc}
-{;$define CHACE_BB_ICON} // chache Bit Bucket icon
+{;$define CHACE_BB_ICON} // chache Bit Bucket icon. However, if the user changes the icon of the Bit Bucket, this is incorrect.
interface
@@ -60,10 +60,6 @@ implementation
uses Winapi.ActiveX, Winapi.ShellAPI, System.Win.ComObj, Winapi.KnownFolders,
Linkbar.OS, Linkbar.Consts, Linkbar.Shell;
-const
- ICON_SHIELD_FLAG = $08000; // draw the shield overlay
- ICON_INDEX_MASK = ICON_SHIELD_FLAG - 1;
-
var
FKnownFolderManager: IKnownFolderManager;
@@ -130,14 +126,10 @@ function CheckBitBucket(const APidl: PItemIDList): Boolean;
and (pidl <> APidl)
then CoTaskMemFree(pidl);
- if Succeeded(hr)
- then begin
- if Succeeded( pKnownFolder.GetId(id) )
- then begin
- if (id = FOLDERID_RecycleBinFolder)
- then Result := True;
- end;
- end;
+ Result := Succeeded(hr)
+ and Assigned(pKnownFolder)
+ and Succeeded( pKnownFolder.GetId(id) )
+ and (id = FOLDERID_RecycleBinFolder);
end;
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/Linkbar.Consts.pas b/src/Linkbar.Consts.pas
index cb93a96..a35a32a 100644
--- a/src/Linkbar.Consts.pas
+++ b/src/Linkbar.Consts.pas
@@ -20,11 +20,15 @@ interface
TAutoShowMode = (smMouseHover = 0, smMouseClickLeft = 1, smMouseClickRight = 2);
+ TJumplistShowMode = (jsmDisabled = 0, jsmMouseClickRight = 1);
+
const
APP_NAME_LINKBAR = 'Linkbar';
URL_WEB = 'https://sourceforge.net/projects/linkbar/';
URL_EMAIL = 'linkbar@yandex.ru';
+ URL_WINDOWS_HOTKEY = 'https://support.microsoft.com/en-ie/help/12445/windows-keyboard-shortcuts';
+
// Supported extentions
ES_ARRAY: array[0..2] of string = ('.lnk', '.url', '.website');
@@ -37,6 +41,7 @@ interface
DN_SHARED_BARS = 'Shared bars\';
DN_USER_BARS = 'User bars\';
+ DN_LOCALES = 'Locales/';
EXT_LBR = '.lbr';
MASK_LBR = '*' + EXT_LBR;
@@ -70,9 +75,12 @@ interface
ITEM_NONE = -1;
ITEM_ALL = -1;
+ TIMER_AUTO_HIDE_DELAY = 300;
+
DEF_AUTOHIDE = False;
DEF_AUTOHIDE_TRANSPARENCY = False;
DEF_AUTOHIDE_SHOWMODE = Integer(Low(TAutoShowMode));
+ DEF_AUTOHIDE_HOTKEY = '$0007004C'; // Shift+Ctrl+Alt+L
DEF_DIR_LINKS = '.\links';
DEF_EDGE = Integer(saTop);
DEF_HINT_SHOW = True;
@@ -91,7 +99,9 @@ interface
DEF_TXTCOLOR = $00000000;
DEF_USECOLOR = False;
DEF_GLOWSIZE = 12;
- DEF_ENABLE_AG = False;
+ DEF_ENABLE_AG = False;
+ DEF_JUMPLISTSHOWMODE = Integer(jsmMouseClickRight);
+ DEF_STAYONTOP = True;
// INI sections
INI_SECTION_MAIN = 'Main'; { Main }
@@ -100,6 +110,7 @@ interface
INI_AUTOHIDE = 'autohide';
INI_AUTOHIDE_TRANSPARENCY = 'autohidetransparency';
INI_AUTOHIDE_SHOWMODE = 'autohideshowmode';
+ INI_AUTOHIDE_HOTKEY = 'autohidehotkey';
INI_DIR_LINKS = 'dirlinks';
INI_EDGE = 'edge';
INI_HINT_SHOW = 'hintshow';
@@ -120,6 +131,8 @@ interface
INI_USETXTCOLOR = 'usetxtcolor';
INI_TXTCOLOR = 'txtcolor'; { Text color }
INI_GLOWSIZE = 'glowsize';
+ INI_JUMPLISTSHOWMODE = 'jumplistshowmode';
+ INI_STAYONTOP = 'stayontop';
INI_ENABLE_AG = 'enableaeroglass';
diff --git a/src/Linkbar.Loc.pas b/src/Linkbar.Loc.pas
deleted file mode 100644
index 4e23862..0000000
--- a/src/Linkbar.Loc.pas
+++ /dev/null
@@ -1,108 +0,0 @@
-{*******************************************************}
-{ Linkbar - Windows desktop toolbar }
-{ Copyright (c) 2010-2017 Asaq }
-{*******************************************************}
-
-unit Linkbar.Loc;
-
-{$i linkbar.inc}
-
-interface
-
-uses Windows, SysUtils, Classes, LcUnitXe;
-
-const
- // explorerframe.dll.mui
- LB_FN_TOOLBAR = 'explorerframe.dll';
- LB_RS_TB_AUTOHIDEALREADYEXISTS = 28676;
- LB_RS_TB_NEWTOOLBAROPENDIALOGTITLE = 12387;
-
- // New shortcut
- // shell32.dll.mui - String table - ?
- LB_FN_NEWSHORTCUT = 'shell32.dll';
- LB_RS_NSC_FILENAME = 30397;
-
- // Jumplists
- // explorer.exe.mui - String table - 21
- LB_FN_JUMPLIST = 'explorer.exe';
- LB_RS_JL_PINNED = 326;
- LB_RS_JL_RECENT = 327;
- LB_RS_JL_FREQUENT = 328;
- LB_RS_JL_TASKS = 329;
- LB_RS_JL_UNPIN = 330; // En: Unpin from this list
- LB_RS_JL_PIN = 331; // En: Pin to this list
- LB_RS_JL_REMOVE = 8225; // En: Remove from this list
-
- // Invalid file name symbols
- // shell32.dll.mui - String table - 257, 793
- LB_FN_INVALIDFILENAMECHARS = 'shell32.dll';
- LB_RS_IFNC_HINT = 4109;
-
- // Rename dialog need file name
- LB_FN_NEEDFILENAME = 'shell32.dll';
- LB_RS_NFN_CUE = 4123;
- // and "Open"
- LB_RS_JL_OPEN = 12850;
-
- function MUILoadResString(const AModuleName: String; const AStringID: Cardinal): String; overload;
- function MUILoadResString(const AModule: HINST; const AStringID: Cardinal): String; overload;
-
- function LbTranslateInit(ALCID: LCID): Integer;
- function LbTranslateComponent(AComponent: TComponent): Boolean;
- function LbLongLang: Boolean;
-
-var
- LbLangID: LCID = 0;
-
-implementation
-
-uses Linkbar.Consts;
-
-function MUILoadResString(const AModule: HINST; const AStringID: Cardinal): String;
-var p: PChar;
-begin
- if (AModule <> 0) and (AStringID < 65536)
- then SetString(Result, p, LoadString(AModule, AStringID, @p, 0))
- else Result := 'resource_string_not_found';
-end;
-
-function MUILoadResString(const AModuleName: String; const AStringID: Cardinal): String;
-var h: THandle;
-begin
- h := LoadLibraryEx(PChar(AModuleName), 0, LOAD_LIBRARY_AS_DATAFILE);
- Result := MUILoadResString(h, AStringID);
- if (h <> 0)
- then FreeLibrary(h);
-end;
-
-function LCIDTo36LanguageID(ALCID: LCID): LCID;
-begin
- if (ALCID = 0)
- then ALCID := TLanguages.UserDefaultLocale;
- case Lo(ALCID) of
- LANG_ENGLISH : Result := $0409; // English (US)
- LANG_FRENCH : Result := $040C; // French
- LANG_JAPANESE: Result := $0411; // Japanese
- LANG_RUSSIAN : Result := $0419; // Russian
- LANG_GERMAN : Result := $0407; // German (Germany)
- else Result := ALCID; // Use default language English-US
- end;
-end;
-
-function LbTranslateInit(ALCID: LCID): Integer;
-begin
- LbLangID := LCIDTo36LanguageID(ALCID);
- Result := LcUnitXe.LoadLcf( ExtractFilePath(ParamStr(0)) + FN_LOCALIZATION, LbLangID, nil, nil );
-end;
-
-function LbTranslateComponent(AComponent: TComponent): Boolean;
-begin
- Result := LcUnitXe.TranslateComponent(AComponent);
-end;
-
-function LbLongLang: Boolean;
-begin
- Result := (LbLangID = $040C);
-end;
-
-end.
diff --git a/src/Linkbar.ResStr.pas b/src/Linkbar.ResStr.pas
deleted file mode 100644
index d1220ed..0000000
--- a/src/Linkbar.ResStr.pas
+++ /dev/null
@@ -1,25 +0,0 @@
-{*******************************************************}
-{ Linkbar - Windows desktop toolbar }
-{ Copyright (c) 2010-2017 Asaq }
-{*******************************************************}
-
-unit Linkbar.ResStr;
-
-{$i linkbar.inc}
-
-interface
-
-resourcestring
-
- RS_FILENOTFOUND = 'File does not exists';
- RS_Q_DELETELINK = 'Delete shortcut?';
-
- RS_REMDLG_TITLE = 'You remove the linkbar "%s"';
- RS_REMDLG_TEXT = 'Working directory: %s';
- RS_REMDLG_VERIFICATIONTEXT = 'Delete working directory';
-
- RS_FILE_ALREADY_EXISTS = 'File with this name already exists';
-
-implementation
-
-end.
diff --git a/src/Linkbar.Settings.dfm b/src/Linkbar.Settings.dfm
index 7cd58d7..df791a5 100644
--- a/src/Linkbar.Settings.dfm
+++ b/src/Linkbar.Settings.dfm
@@ -17,41 +17,29 @@ object FrmProperties: TFrmProperties
FormStyle = fsStayOnTop
OldCreateOrder = False
ParentBiDiMode = False
- Position = poScreenCenter
+ Position = poDesigned
OnClose = FormClose
OnDestroy = FormDestroy
OnMouseWheel = FormMouseWheel
DesignSize = (
- 383
- 517)
+ 408
+ 409)
PixelsPerInch = 96
TextHeight = 14
object pgc1: TPageControl
Left = 5
Top = 6
- Width = 374
- Height = 470
- ActivePage = tsAdditionally
+ Width = 399
+ Height = 361
+ ActivePage = tsView
Align = alCustom
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
- object tsOptions: TTabSheet
+ object tsView: TTabSheet
Caption = 'View'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 366
- 441)
- object lblSection2: TLabel
- Left = 8
- Top = 296
- Width = 108
- Height = 14
- Caption = 'Configure auto-hide'
- Transparent = True
- end
+ 391
+ 332)
object lblSection1: TLabel
Left = 8
Top = 8
@@ -63,7 +51,7 @@ object FrmProperties: TFrmProperties
object pnlDummy11: TPanel
Left = 8
Top = 227
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -72,18 +60,18 @@ object FrmProperties: TFrmProperties
object chbUseTxtColor: TCheckBox
Left = 0
Top = 0
- Width = 160
+ Width = 185
Height = 22
Align = alLeft
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = 'Text color:'
TabOrder = 0
- OnClick = OptionsChanged
+ OnClick = Changed
end
object clbTextColor: TColorBox
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
DefaultColorColor = clWhite
@@ -97,10 +85,11 @@ object FrmProperties: TFrmProperties
object pnlDummy1: TPanel
Left = 8
Top = 31
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
+ Color = clRed
ShowCaption = False
TabOrder = 0
object lblScreenEdge: TLabel
@@ -114,14 +103,14 @@ object FrmProperties: TFrmProperties
ExplicitHeight = 14
end
object cbbScreenPosition: TComboBox
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
Style = csDropDownList
TabOrder = 0
- OnChange = OptionsChanged
+ OnChange = Changed
Items.Strings = (
'Left'
'Top'
@@ -132,7 +121,7 @@ object FrmProperties: TFrmProperties
object pnlDummy2: TPanel
Left = 8
Top = 59
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -142,37 +131,29 @@ object FrmProperties: TFrmProperties
Left = 0
Top = 0
Width = 51
- Height = 14
+ Height = 22
Align = alLeft
Caption = 'Icon size:'
Layout = tlCenter
- end
- object bvlSpacer1: TBevel
- Left = 192
- Top = 0
- Width = 4
- Height = 22
- Align = alRight
- Shape = bsSpacer
- ExplicitLeft = 194
+ ExplicitHeight = 14
end
object nseIconSize: TnSpinEdit
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
MaxValue = 0
MinValue = 0
TabOrder = 0
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
end
object pnlDummy3: TPanel
Left = 8
Top = 115
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -182,49 +163,49 @@ object FrmProperties: TFrmProperties
Left = 0
Top = 0
Width = 153
- Height = 14
+ Height = 22
Align = alLeft
Caption = 'Margins (horizontal/vertical):'
Layout = tlCenter
+ ExplicitHeight = 14
end
object bvlSpacer2: TBevel
- Left = 269
+ Left = 287
Top = 0
- Width = 4
+ Width = 5
Height = 22
Align = alRight
Shape = bsSpacer
- ExplicitLeft = 268
end
object nseMarginH: TnSpinEdit
- Left = 196
+ Left = 208
Top = 0
- Width = 73
+ Width = 79
Height = 22
Align = alRight
MaxValue = 0
MinValue = 0
TabOrder = 0
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
object nseMarginV: TnSpinEdit
- Left = 273
+ Left = 292
Top = 0
- Width = 73
+ Width = 79
Height = 22
Align = alRight
MaxValue = 0
MinValue = 0
TabOrder = 1
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
end
object pnlDummy4: TPanel
Left = 8
Top = 143
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -241,14 +222,14 @@ object FrmProperties: TFrmProperties
ExplicitHeight = 14
end
object cbbItemOrder: TComboBox
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
Style = csDropDownList
TabOrder = 0
- OnChange = OptionsChanged
+ OnChange = Changed
Items.Strings = (
'Left to right'
'Up to down')
@@ -257,7 +238,7 @@ object FrmProperties: TFrmProperties
object pnlDummy5: TPanel
Left = 8
Top = 171
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -274,14 +255,14 @@ object FrmProperties: TFrmProperties
ExplicitHeight = 14
end
object cbbTextLayout: TComboBox
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
Style = csDropDownList
TabOrder = 0
- OnChange = OptionsChanged
+ OnChange = Changed
Items.Strings = (
'Without text'
'Left'
@@ -293,7 +274,7 @@ object FrmProperties: TFrmProperties
object pnlDummy6: TPanel
Left = 8
Top = 199
- Width = 346
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
@@ -303,313 +284,415 @@ object FrmProperties: TFrmProperties
Left = 0
Top = 0
Width = 105
- Height = 14
+ Height = 22
Align = alLeft
Caption = 'Text width/indent:'
Layout = tlCenter
+ ExplicitHeight = 14
end
object bvlSpacer3: TBevel
- Left = 269
+ Left = 287
Top = 0
- Width = 4
+ Width = 5
Height = 22
Align = alRight
Shape = bsSpacer
- ExplicitLeft = 268
end
object nseTextWidth: TnSpinEdit
- Left = 196
+ Left = 208
Top = 0
- Width = 73
+ Width = 79
Height = 22
Align = alRight
MaxValue = 0
MinValue = 0
TabOrder = 0
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
object nseTextOffset: TnSpinEdit
- Left = 273
+ Left = 292
Top = 0
- Width = 73
+ Width = 79
Height = 22
Align = alRight
MaxValue = 0
MinValue = 0
TabOrder = 1
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
end
- object pnlDummy7: TPanel
+ object pnlDummy10: TPanel
Left = 8
- Top = 317
- Width = 346
- Height = 21
+ Top = 87
+ Width = 371
+ Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
ShowCaption = False
- TabOrder = 9
- object lbl2: TLabel
- Left = 0
+ TabOrder = 2
+ object btnBgColorShowHide: TSpeedButton
+ Left = 348
Top = 0
- Width = 28
- Height = 14
- Align = alLeft
- Caption = 'Hide:'
- Layout = tlCenter
+ Width = 23
+ Height = 22
+ Align = alRight
+ Caption = '...'
+ OnClick = btnBgColorClick
end
- object chbAutoHide: TCheckBox
- Left = 196
+ object edtColorBg: TEdit
+ Tag = 3
+ Left = 208
Top = 0
- Width = 150
- Height = 21
+ Width = 140
+ Height = 22
Align = alRight
- Caption = 'Automatically'
+ Alignment = taCenter
+ CharCase = ecUpperCase
+ MaxLength = 8
+ TabOrder = 1
+ Text = 'FFFFFFFF'
+ OnChange = edtColorBgChange
+ OnKeyPress = edtColorBgKeyPress
+ end
+ object chbUseBkgColor: TCheckBox
+ Left = 0
+ Top = 0
+ Width = 185
+ Height = 22
+ Align = alLeft
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ Caption = 'Background color:'
TabOrder = 0
- OnClick = OptionsChanged
+ OnClick = Changed
end
end
- object pnlDummy8: TPanel
+ object pnlDummy12: TPanel
Left = 8
- Top = 344
- Width = 346
+ Top = 255
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
ShowCaption = False
- TabOrder = 10
- object lbl1: TLabel
+ TabOrder = 8
+ object lblGlowSize: TLabel
Left = 0
Top = 0
- Width = 35
+ Width = 54
Height = 22
Align = alLeft
- Caption = 'Show:'
+ Caption = 'Glow size:'
Layout = tlCenter
ExplicitHeight = 14
end
- object cbbAutoShowMode: TComboBox
- Left = 196
+ object nseGlowSize: TnSpinEdit
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
- Style = csDropDownList
+ MaxValue = 16
+ MinValue = 0
TabOrder = 0
- OnChange = OptionsChanged
- Items.Strings = (
- 'Mouse hover'
- 'Mouse left-click'
- 'Mouse right-click')
+ Value = 0
+ OnChange = Changed
+ end
+ end
+ object pnlDummy13: TPanel
+ Left = 8
+ Top = 283
+ Width = 371
+ Height = 21
+ Anchors = [akLeft, akTop, akRight]
+ BevelOuter = bvNone
+ ShowCaption = False
+ TabOrder = 9
+ object chbStayOnTop: TCheckBox
+ Left = 0
+ Top = 0
+ Width = 371
+ Height = 21
+ Align = alClient
+ Caption = 'Always on top'
+ TabOrder = 0
+ OnClick = Changed
+ ExplicitWidth = 348
end
end
+ end
+ object tsAutohide: TTabSheet
+ Caption = 'Autohide'
+ ImageIndex = 3
+ DesignSize = (
+ 391
+ 332)
+ object lblSection2: TLabel
+ Left = 8
+ Top = 8
+ Width = 108
+ Height = 14
+ Caption = 'Configure auto-hide'
+ Transparent = True
+ end
object chbAutoHideTransparency: TCheckBox
Left = 8
- Top = 412
- Width = 345
+ Top = 183
+ Width = 370
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Transparent when hidden'
- TabOrder = 12
- OnClick = OptionsChanged
+ TabOrder = 5
+ OnClick = Changed
end
- object pnlDummy9: TPanel
+ object pnlDelay: TPanel
Left = 8
- Top = 372
- Width = 346
+ Top = 84
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
+ ParentColor = True
ShowCaption = False
- TabOrder = 11
- object Label3: TLabel
+ TabOrder = 2
+ object lblDelay: TLabel
Left = 0
Top = 0
Width = 56
- Height = 14
+ Height = 22
Align = alLeft
Caption = 'Delay, ms:'
Layout = tlCenter
- end
- object bvlSpacer4: TBevel
- Left = 192
- Top = 0
- Width = 4
- Height = 22
- Align = alRight
- Shape = bsSpacer
- ExplicitLeft = 194
+ ExplicitHeight = 14
end
object nseAutoShowDelay: TnSpinEdit
- Left = 196
+ Left = 208
Top = 0
- Width = 150
+ Width = 163
Height = 22
Align = alRight
MaxValue = 60000
MinValue = 0
TabOrder = 0
Value = 0
- OnChange = OptionsChanged
+ OnChange = Changed
end
end
- object pnlDummy10: TPanel
+ object pnlDummy7: TPanel
Left = 8
- Top = 87
- Width = 346
- Height = 22
+ Top = 29
+ Width = 371
+ Height = 21
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
ShowCaption = False
- TabOrder = 2
- object btnBgColorShowHide: TSpeedButton
- Left = 322
+ TabOrder = 0
+ object lbl2: TLabel
+ Left = 0
Top = 0
- Width = 24
- Height = 22
- Align = alRight
- Caption = '...'
- OnClick = btnBgColorClick
+ Width = 28
+ Height = 21
+ Align = alLeft
+ Caption = 'Hide:'
+ Layout = tlCenter
+ ExplicitHeight = 14
end
- object edtColorBg: TEdit
- Tag = 3
- Left = 196
+ object chbAutoHide: TCheckBox
+ Left = 208
Top = 0
- Width = 126
- Height = 22
+ Width = 163
+ Height = 21
Align = alRight
- Alignment = taCenter
- CharCase = ecUpperCase
- MaxLength = 8
- TabOrder = 1
- Text = 'FFFFFFFF'
- OnChange = edtColorBgChange
- OnKeyPress = edtColorBgKeyPress
- end
- object chbUseBkgColor: TCheckBox
- Left = 0
- Top = 0
- Width = 160
- Height = 22
- Align = alLeft
- Anchors = [akLeft, akTop, akRight, akBottom]
- Caption = 'Background color:'
+ Caption = 'Automatically'
TabOrder = 0
- OnClick = OptionsChanged
+ OnClick = Changed
end
end
- object pnlDummy12: TPanel
+ object pnlDummy8: TPanel
Left = 8
- Top = 255
- Width = 346
+ Top = 56
+ Width = 371
Height = 22
Anchors = [akLeft, akTop, akRight]
BevelOuter = bvNone
+ ParentColor = True
ShowCaption = False
- TabOrder = 8
- object lblGlowSize: TLabel
+ TabOrder = 1
+ object lblShow: TLabel
Left = 0
Top = 0
- Width = 54
- Height = 14
+ Width = 35
+ Height = 22
Align = alLeft
- Caption = 'Glow size:'
+ Caption = 'Show:'
Layout = tlCenter
+ ExplicitHeight = 14
end
- object bvlSpacer5: TBevel
- Left = 192
+ object cbbAutoShowMode: TComboBox
+ Left = 208
Top = 0
- Width = 4
+ Width = 163
Height = 22
Align = alRight
- Shape = bsSpacer
- ExplicitLeft = 194
+ Style = csDropDownList
+ TabOrder = 0
+ OnChange = Changed
+ Items.Strings = (
+ 'Mouse hover'
+ 'Mouse left-click'
+ 'Mouse right-click')
end
- object nseGlowSize: TnSpinEdit
- Left = 196
+ end
+ object pnlHotkey: TPanel
+ Left = 8
+ Top = 108
+ Width = 371
+ Height = 22
+ Anchors = [akLeft, akTop, akRight]
+ BevelOuter = bvNone
+ ParentColor = True
+ ShowCaption = False
+ TabOrder = 3
+ object lblHotKey: TLabel
+ Left = 0
Top = 0
- Width = 150
+ Width = 105
Height = 22
- Align = alRight
- MaxValue = 16
- MinValue = 0
- TabOrder = 0
- Value = 0
- OnChange = OptionsChanged
+ Align = alLeft
+ Caption = 'Keyboard shortcut:'
+ Layout = tlCenter
+ ExplicitHeight = 14
end
end
+ object pnlHotkeyEdit: TPanel
+ Left = 8
+ Top = 136
+ Width = 371
+ Height = 22
+ Anchors = [akLeft, akTop, akRight]
+ BevelOuter = bvNone
+ ParentColor = True
+ ShowCaption = False
+ TabOrder = 4
+ end
end
object tsAdditionally: TTabSheet
Caption = 'Additional'
ImageIndex = 1
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
+ DesignSize = (
+ 391
+ 332)
+ object lblSectionWin7: TLabel
+ Left = 8
+ Top = 98
+ Width = 82
+ Height = 14
+ Caption = 'For Windows 7'
+ Transparent = True
+ end
object lblSectionWin8: TLabel
Left = 8
- Top = 82
+ Top = 149
Width = 105
Height = 14
Caption = 'For Windows 8/8.1'
Transparent = True
end
- object lblSectionWin7: TLabel
+ object lblJumplist: TLabel
Left = 8
Top = 8
- Width = 82
+ Width = 48
Height = 14
- Caption = 'For Windows 7'
+ Caption = 'Jumplists'
Transparent = True
end
- object chbAeroGlass: TCheckBox
+ object pnlLightStyle: TPanel
Left = 8
- Top = 118
- Width = 343
- Height = 17
- Align = alCustom
+ Top = 110
+ Width = 371
+ Height = 34
Anchors = [akLeft, akTop, akRight]
- Caption = 'Enable AeroGlass support (installed separately)'
+ BevelOuter = bvNone
+ ParentColor = True
+ ShowCaption = False
TabOrder = 1
- WordWrap = True
- OnClick = OptionsChanged
+ object chbLightStyle: TCheckBox
+ Left = 0
+ Top = 0
+ Width = 371
+ Height = 34
+ Align = alTop
+ Caption = 'Use style like taskbar with combined buttons'
+ TabOrder = 0
+ WordWrap = True
+ OnClick = Changed
+ end
end
- object chbLightStyle: TCheckBox
+ object chbAeroGlass: TCheckBox
Left = 8
- Top = 28
- Width = 343
- Height = 48
+ Top = 185
+ Width = 368
+ Height = 17
Align = alCustom
Anchors = [akLeft, akTop, akRight]
- Caption = 'Use style like taskbar with combined buttons'
- TabOrder = 0
+ Caption = 'Enable AeroGlass support (installed separately)'
+ TabOrder = 2
WordWrap = True
- OnClick = OptionsChanged
+ OnClick = Changed
end
object chbShowHints: TCheckBox
- Left = 3
- Top = 371
+ Left = 8
+ Top = 216
Width = 367
Height = 17
Align = alCustom
Caption = 'Show hints'
- TabOrder = 2
+ TabOrder = 3
Visible = False
- OnClick = OptionsChanged
+ OnClick = Changed
+ end
+ object pnlJumplistShowMode: TPanel
+ Left = 8
+ Top = 31
+ Width = 371
+ Height = 22
+ Anchors = [akLeft, akTop, akRight]
+ BevelOuter = bvNone
+ Color = clRed
+ ShowCaption = False
+ TabOrder = 0
+ object lblJumplistShowMode: TLabel
+ Left = 0
+ Top = 0
+ Width = 35
+ Height = 22
+ Align = alLeft
+ Caption = 'Show:'
+ Layout = tlCenter
+ ExplicitHeight = 14
+ end
+ object cbbJumplistShowMode: TComboBox
+ Left = 208
+ Top = 0
+ Width = 163
+ Height = 22
+ Align = alRight
+ Style = csDropDownList
+ TabOrder = 0
+ OnChange = Changed
+ Items.Strings = (
+ 'Disabled'
+ 'Mouse right-click')
+ end
end
end
object tsAbout: TTabSheet
Caption = 'About'
ImageIndex = 1
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 366
- 441)
+ 391
+ 332)
object lblVer: TLabel
Left = 8
Top = 8
@@ -650,13 +733,13 @@ object FrmProperties: TFrmProperties
object lblSysInfo: TLabel
Left = 8
Top = 135
- Width = 347
- Height = 60
+ Width = 372
+ Height = 70
Anchors = [akLeft, akTop, akRight]
AutoSize = False
- Caption = 'lblSysInfo'
+ Caption = 'lblSysInfo'#13#10'1'#13#10'2'#13#10'3'#13#10'4'
+ PopupMenu = pmSysInfo
WordWrap = True
- ExplicitWidth = 361
end
object linkEmail: TLinkLabel
Left = 46
@@ -681,8 +764,8 @@ object FrmProperties: TFrmProperties
end
end
object btnApply: TButton
- Left = 298
- Top = 488
+ Left = 324
+ Top = 374
Width = 80
Height = 25
Anchors = [akTop, akRight]
@@ -691,8 +774,8 @@ object FrmProperties: TFrmProperties
OnClick = DialogButtonClick
end
object btnCancel: TButton
- Left = 214
- Top = 488
+ Left = 240
+ Top = 374
Width = 80
Height = 25
Anchors = [akTop, akRight]
@@ -712,4 +795,12 @@ object FrmProperties: TFrmProperties
TabOrder = 1
OnClick = DialogButtonClick
end
+ object pmSysInfo: TPopupMenu
+ Left = 168
+ Top = 80
+ object imCopy: TMenuItem
+ Caption = 'Copy'
+ OnClick = imCopyClick
+ end
+ end
end
diff --git a/src/Linkbar.Settings.pas b/src/Linkbar.Settings.pas
index d0ab94e..f9e292f 100644
--- a/src/Linkbar.Settings.pas
+++ b/src/Linkbar.Settings.pas
@@ -11,12 +11,13 @@ interface
uses
Windows, SysUtils, Classes, Forms, StdCtrls, NewSpin, ExtCtrls, Controls, mUnit,
- Vcl.ComCtrls, Winapi.Messages, Vcl.Buttons, ColorPicker, VCLTee.TeCanvas;
+ Vcl.ComCtrls, Winapi.Messages, Vcl.Buttons, ColorPicker, VCLTee.TeCanvas,
+ Vcl.Menus, HotKey;
type
TFrmProperties = class(TForm)
pgc1: TPageControl;
- tsOptions: TTabSheet;
+ tsView: TTabSheet;
tsAbout: TTabSheet;
lblScreenEdge: TLabel;
lblIconSize: TLabel;
@@ -52,7 +53,7 @@ TFrmProperties = class(TForm)
lblSection2: TLabel;
lblSection1: TLabel;
pnlDummy8: TPanel;
- lbl1: TLabel;
+ lblShow: TLabel;
cbbAutoShowMode: TComboBox;
pnlDummy7: TPanel;
lbl2: TLabel;
@@ -64,8 +65,8 @@ TFrmProperties = class(TForm)
chbLightStyle: TCheckBox;
chbAeroGlass: TCheckBox;
lblSysInfo: TLabel;
- pnlDummy9: TPanel;
- Label3: TLabel;
+ pnlDelay: TPanel;
+ lblDelay: TLabel;
nseAutoShowDelay: TnSpinEdit;
pnlDummy10: TPanel;
btnBgColorShowHide: TSpeedButton;
@@ -75,13 +76,23 @@ TFrmProperties = class(TForm)
chbUseTxtColor: TCheckBox;
bvlSpacer2: TBevel;
bvlSpacer3: TBevel;
- bvlSpacer1: TBevel;
- bvlSpacer4: TBevel;
pnlDummy12: TPanel;
lblGlowSize: TLabel;
- bvlSpacer5: TBevel;
nseGlowSize: TnSpinEdit;
clbTextColor: TColorBox;
+ pmSysInfo: TPopupMenu;
+ imCopy: TMenuItem;
+ pnlLightStyle: TPanel;
+ pnlHotkey: TPanel;
+ lblHotKey: TLabel;
+ pnlHotkeyEdit: TPanel;
+ tsAutohide: TTabSheet;
+ pnlJumplistShowMode: TPanel;
+ lblJumplistShowMode: TLabel;
+ cbbJumplistShowMode: TComboBox;
+ lblJumplist: TLabel;
+ pnlDummy13: TPanel;
+ chbStayOnTop: TCheckBox;
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
procedure linkEmailLinkClick(Sender: TObject; const Link: string;
@@ -89,7 +100,7 @@ TFrmProperties = class(TForm)
procedure linkWebLinkClick(Sender: TObject; const Link: string;
LinkType: TSysLinkType);
procedure DialogButtonClick(Sender: TObject);
- procedure OptionsChanged(Sender: TObject);
+ procedure Changed(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnCancelClick(Sender: TObject);
@@ -97,6 +108,7 @@ TFrmProperties = class(TForm)
procedure SpeedButton2Click(Sender: TObject);
procedure edtColorBgKeyPress(Sender: TObject; var Key: Char);
procedure edtColorBgChange(Sender: TObject);
+ procedure imCopyClick(Sender: TObject);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
@@ -105,9 +117,12 @@ TFrmProperties = class(TForm)
FColorPicker: TfrmColorPicker;
FBackgroundColor: Cardinal;
FTextColor: Cardinal;
+ edtHotKey: THotKeyEdit;
+ FCanChanged: Boolean;
procedure SetBackgroundColor(AValue: Cardinal);
procedure SetTextColor(AValue: Cardinal);
function ScaleDimension(const X: Integer): Integer;
+ procedure L10n;
public
constructor Create(AOwner: TLinkbarWcl); reintroduce;
property BackgroundColor: Cardinal read FBackgroundColor write SetBackgroundColor;
@@ -123,7 +138,7 @@ implementation
uses
Math, Graphics, Linkbar.Consts, Linkbar.OS, Linkbar.Shell, Linkbar.Themes,
- Linkbar.Loc, Linkbar.Common;
+ Linkbar.L10n, Linkbar.Common, Vcl.Clipbrd;
function TFrmProperties.ScaleDimension(const X: Integer): Integer;
begin
@@ -150,14 +165,25 @@ procedure TFrmProperties.CreateParams(var Params: TCreateParams);
constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
var
- lang: TLanguages;
maxlabelwidth, ctrlwidth, y1: integer;
VO1, VO2, VO3: Integer;
begin
+ FCanChanged := False;
+
inherited Create(AOwner);
+ FLinkbar := AOwner;
Font.Name := Screen.MenuFont.Name;
- LbTranslateComponent(Self);
+
+ // Create editors
+ edtHotKey := THotKeyEdit.Create(pnlHotkeyEdit);
+ edtHotKey.Parent := pnlHotkeyEdit;
+ edtHotKey.Align := alClient;
+ edtHotKey.OnChange := Changed;
+ FColorPicker := TfrmColorPicker.Create(Self);
+ FColorPicker.Font := Font;
+
+ L10n;
ReduceSysMenu(Handle);
@@ -165,8 +191,6 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
VO2 := ScaleDimension(9);
VO3 := ScaleDimension(12);
- FLinkbar := AOwner;
-
pgc1.ActivePageIndex := 0;
maxlabelwidth := 0;
@@ -185,7 +209,7 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
lblVer.Font := lblSection1.Font;
// ---------------------------------------------------------------------------
- // Page Options
+ // Page View
// ---------------------------------------------------------------------------
// Position on screen --------------------------------------------------------
pnlDummy1.Top := lblSection1.BoundsRect.Bottom + VO1;
@@ -201,10 +225,6 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
pnlDummy10.Top := pnlDummy2.BoundsRect.Bottom + VO1;
pnlDummy10.Height := pnlDummy1.Height;
- FColorPicker := TfrmColorPicker.Create(Self);
- FColorPicker.Font := Font;
- LbTranslateComponent(FColorPicker);
-
// Margins -------------------------------------------------------------------
pnlDummy3.Top := pnlDummy10.BoundsRect.Bottom + VO1;
pnlDummy3.Height := pnlDummy1.Height;
@@ -248,7 +268,14 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
nseGlowSize.MaxValue := GLOW_SIZE_MAX;
nseGlowSize.Value := FLinkbar.GlowSize;
- lblSection2.Top := pnlDummy12.BoundsRect.Bottom + VO1*2;
+ pnlDummy13.Top := pnlDummy12.BoundsRect.Bottom + VO1;
+ pnlDummy13.Height := pnlDummy1.Height;
+
+ // ---------------------------------------------------------------------------
+ // Page AutoHide
+ // ---------------------------------------------------------------------------
+
+ //lblSection2.Top := pnlDummy12.BoundsRect.Bottom + VO1*2;
pnlDummy7.Top := lblSection2.BoundsRect.Bottom + VO1;
pnlDummy7.Height := pnlDummy1.Height;
@@ -256,32 +283,39 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
pnlDummy8.Top := pnlDummy7.BoundsRect.Bottom + VO1;
pnlDummy8.Height := pnlDummy1.Height;
- pnlDummy9.Top := pnlDummy8.BoundsRect.Bottom + VO1;
- pnlDummy9.Height := pnlDummy1.Height;
+ pnlDelay.Top := pnlDummy8.BoundsRect.Bottom + VO1;
+ pnlDelay.Height := pnlDummy1.Height;
+
+ pnlHotkey.Top := pnlDelay.BoundsRect.Bottom + VO1;
+ pnlHotkey.Height := pnlDummy1.Height;
- chbAutoHideTransparency.Top := pnlDummy9.BoundsRect.Bottom + VO3;
+ pnlHotkeyEdit.Top := pnlHotkey.BoundsRect.Bottom + VO1;
+ pnlHotkeyEdit.Height := pnlDummy1.Height;
+
+ chbAutoHideTransparency.Top := pnlHotkeyEdit.BoundsRect.Bottom + VO3;
// ---------------------------------------------------------------------------
// Page Additionally
// ---------------------------------------------------------------------------
+ lblJumplist.Font := lblSection1.Font;
+ pnlJumplistShowMode.Top := lblJumplist.BoundsRect.Bottom + VO1;
+ pnlJumplistShowMode.Height := pnlDummy1.Height;
lblSectionWin7.Font := lblSection1.Font;
- if LbLongLang
- then chbLightStyle.Height := chbLightStyle.Height * 2;
- chbLightStyle.Top := lblSectionWin7.BoundsRect.Bottom + VO1;
- chbLightStyle.Hint := chbLightStyle.Caption;
- chbLightStyle.ShowHint := True;
+ lblSectionWin7.Top := pnlJumplistShowMode.BoundsRect.Bottom + VO1*2;
+ pnlLightStyle.Top := lblSectionWin7.BoundsRect.Bottom + VO1;
lblSectionWin8.Font := lblSection1.Font;
- lblSectionWin8.Top := chbLightStyle.BoundsRect.Bottom + VO1*2;
+ lblSectionWin8.Top := pnlLightStyle.BoundsRect.Bottom + VO1*2;
chbAeroGlass.Top := lblSectionWin8.BoundsRect.Bottom + VO1;
- pgc1.Height := tsOptions.Top + chbAutoHideTransparency.BoundsRect.Bottom
- + VO2 + tsOptions.Left;
+ pgc1.Height := tsView.Top + pnlDummy13.BoundsRect.Bottom
+ + VO2 + tsView.Left;
btnOk.Top := pgc1.BoundsRect.Bottom + ScaleDimension(8);
btnCancel.Top := btnOk.Top;
btnApply.Top := btnOk.Top;
- ClientWidth := maxlabelwidth + ctrlwidth + (pnlDummy1.Left + tsOptions.Left + pgc1.Left) * 2;
+ // Calc Client Width & Height
+ ClientWidth := maxlabelwidth + ctrlwidth + (pnlDummy1.Left + tsView.Left + pgc1.Left) * 2;
if IsWindows7 then y1 := 5 else y1 := 8;
ClientHeight := btnOk.BoundsRect.Bottom + ScaleDimension(y1);
@@ -297,17 +331,18 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
cbbAutoShowMode.ItemIndex := Ord(FLinkbar.AutoShowMode);
nseAutoShowDelay.Value := FLinkbar.AutoShowDelay;
chbLightStyle.Checked := FLinkbar.IsLightStyle;
-
chbUseBkgColor.Checked := FLinkbar.UseBkgColor;
chbUseTxtColor.Checked := FLinkbar.UseTxtColor;
+ cbbJumplistShowMode.ItemIndex := Ord(FLinkbar.JumplistShowMode);
+ chbStayOnTop.Checked := FLinkbar.StayOnTop;
+
+ edtHotKey.HotkeyInfo := FLinkbar.HotkeyInfo;
BackgroundColor := FLinkbar.BkgColor;
TextColor := FLinkbar.TxtColor;
chbAeroGlass.Checked := FLinkbar.EnableAeroGlass;
- OptionsChanged(nil);
-
{ Disable OS-dependent options }
// Windows 7
lblSectionWin7.Enabled := IsWindows7;
@@ -316,20 +351,70 @@ constructor TFrmProperties.Create(AOwner: TLinkbarWcl);
lblSectionWin8.Enabled := IsWindows8And8Dot1;
chbAeroGlass.Enabled := IsWindows8And8Dot1;
- lblVer.Caption := lblVer.Caption + ' ' + VersionToString;
+ lblVer.Caption := Format(lblVer.Caption, [VersionToString]);
linkWeb.Caption := '' + URL_WEB + '';
linkEmail.Caption := '' + URL_EMAIL + '';
- lang := TLanguages.Create;
lblSysInfo.Caption := TOSVersion.ToString
- + '; LCID '
- + IntToStr(lang.UserDefaultLocale) + ' (' + IntToHex(lang.UserDefaultLocale, 3) + ')'
- + ' ' + lang.NameFromLocaleID[lang.UserDefaultLocale];
- lang.Free;
+ + ' ' + Languages.LocaleName[Languages.IndexOf(Languages.UserDefaultLocale)]
+ + ' ' + IntToStr(Languages.UserDefaultLocale)
+ + ' (' + IntToHex(Languages.UserDefaultLocale, 3) + ')'
+ + ' ' + Languages.NameFromLocaleID[Languages.UserDefaultLocale];
+ FCanChanged := True;
+ Changed(nil);
btnApply.Enabled := False;
end;
+procedure TFrmProperties.L10n;
+begin
+ // Tabs
+ L10nControl(tsView, 'Properties.View');
+ L10nControl(tsAutoHide, 'Properties.PageAutoHide');
+ L10nControl(tsAdditionally, 'Properties.Additional');
+ L10nControl(tsAbout, 'Properties.About');
+ // View
+ L10nControl(lblSection1, 'Properties.Appearance');
+ L10nControl(lblScreenEdge, 'Properties.Position');
+ L10nControl(cbbScreenPosition, ['Properties.Left', 'Properties.Top', 'Properties.Right', 'Properties.Bottom']);
+ L10nControl(lblIconSize, 'Properties.IconSize');
+ L10nControl(chbUseBkgColor, 'Properties.BgColor');
+ L10nControl(lblMargin, 'Properties.Margins');
+ L10nControl(lblOrder, 'Properties.Order');
+ L10nControl(cbbItemOrder, ['Properties.LtR', 'Properties.UtD']);
+ L10nControl(Label1, 'Properties.TextPos');
+ L10nControl(cbbTextLayout, ['Properties.Without' , 'Properties.Left', 'Properties.Top', 'Properties.Right', 'Properties.Bottom']);
+ L10nControl(Label6, 'Properties.TextWidth');
+ L10nControl(chbUseTxtColor, 'Properties.TextColor');
+ L10nControl(lblGlowSize, 'Properties.GlowSize');
+ L10nControl(chbStayOnTop, 'Properties.AlwaysOnTop');
+ // Autohide
+ L10nControl(lblSection2, 'Properties.AutoHide');
+ L10nControl(lbl2, 'Properties.Hide');
+ L10nControl(chbAutoHide, 'Properties.Automatically');
+ L10nControl(lblShow, 'Properties.Show');
+ L10nControl(cbbAutoShowMode, ['Properties.MouseHover', 'Properties.MouseLC', 'Properties.MouseRC']);
+ L10nControl(lblDelay, 'Properties.Delay');
+ L10nControl(lblHotKey, 'Properties.HotKey');
+ L10nControl(chbAutoHideTransparency, 'Properties.Transparent');
+ // Additional
+ L10nControl(lblJumplist, 'Properties.Jumplists');
+ L10nControl(lblJumplistShowMode, 'Properties.Show');
+ L10nControl(cbbJumplistShowMode, ['Properties.No', 'Properties.MouseRC']);
+ L10nControl(lblSectionWin7, 'Properties.ForW7');
+ L10nControl(chbLightStyle, 'Properties.Style1');
+ L10nControl(lblSectionWin8, 'Properties.ForW8');
+ L10nControl(chbAeroGlass, 'Properties.AeroGlass');
+ // About
+ L10nControl(lblVer, 'Properties.Version');
+ L10nControl(lblLocalizer, 'Properties.Localizer');
+ L10nControl(Label2, 'Properties.SystemInfo');
+ // Buttons
+ L10nControl(btnOk, 'Properties.Ok');
+ L10nControl(btnCancel, 'Properties.Cancel');
+ L10nControl(btnApply, 'Properties.Apply');
+end;
+
procedure TFrmProperties.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
@@ -358,12 +443,17 @@ procedure TFrmProperties.FormMouseWheel(Sender: TObject; Shift: TShiftState;
end;
end;
+procedure TFrmProperties.imCopyClick(Sender: TObject);
+begin
+ Clipboard.AsText := lblSysInfo.Caption;
+end;
+
procedure TFrmProperties.linkEmailLinkClick(Sender: TObject; const Link: string;
LinkType: TSysLinkType);
begin
if not SendShellEmail(Application.Handle, URL_EMAIL,
APP_NAME_LINKBAR,
- 'Version: ' + VersionToString
+ lblVer.Caption
+ '%0D%0A' + 'OS: ' + lblSysInfo.Caption)
then begin
end;
@@ -375,8 +465,11 @@ procedure TFrmProperties.linkWebLinkClick(Sender: TObject; const Link: string;
LBShellExecute(0, 'open', URL_WEB);
end;
-procedure TFrmProperties.OptionsChanged(Sender: TObject);
+procedure TFrmProperties.Changed(Sender: TObject);
begin
+ if (not FCanChanged)
+ then Exit;
+
btnApply.Enabled := True;
// Color additional options
@@ -387,15 +480,25 @@ procedure TFrmProperties.OptionsChanged(Sender: TObject);
// Autohide additional options
cbbAutoShowMode.Enabled := chbAutoHide.Checked;
chbAutoHideTransparency.Enabled := chbAutoHide.Checked;
- lbl1.Enabled := chbAutoHide.Checked;
- Label3.Enabled := chbAutoHide.Checked
- and (TAutoShowMode(cbbAutoShowMode.ItemIndex)= smMouseHover);
- nseAutoShowDelay.Enabled := Label3.Enabled;
+ lblShow.Enabled := chbAutoHide.Checked;
+ // Mouse-Hover Delay
+ lblDelay.Enabled := chbAutoHide.Checked;
+ nseAutoShowDelay.Enabled := lblDelay.Enabled;
+ // Hotkey
+ lblHotKey.Enabled := chbAutoHide.Checked;
+ edtHotKey.Enabled := lblHotKey.Enabled;
// Text additional options
Label6.Enabled := cbbTextLayout.ItemIndex > 0;
nseTextWidth.Enabled := cbbTextLayout.ItemIndex > 0;
nseTextOffset.Enabled := cbbTextLayout.ItemIndex > 0;
+
+ // Check Hotkey
+ if ((Sender = edtHotKey) and (FLinkbar.HotkeyInfo <> edtHotKey.HotkeyInfo))
+ or
+ ((Sender = chbAutoHide) and chbAutoHide.Checked)
+ then CheckHotkey(Handle, edtHotKey.HotkeyInfo);
+
end;
procedure TFrmProperties.btnCancelClick(Sender: TObject);
@@ -441,6 +544,8 @@ procedure TFrmProperties.DialogButtonClick(Sender: TObject);
EnsureRange(nseMarginV.Value, MARGIN_MIN, MARGIN_MAX)
);
FLinkbar.AutoHideTransparency := chbAutoHideTransparency.Checked;
+ FLinkbar.JumplistShowMode := TJumplistShowMode(cbbJumplistShowMode.ItemIndex);
+ FLinkbar.StayOnTop := chbStayOnTop.Checked;
FLinkbar.UpdateItemSizes;
@@ -450,6 +555,8 @@ procedure TFrmProperties.DialogButtonClick(Sender: TObject);
if (temp_ah = FLinkbar.AutoHide)
then FLinkbar.AutoHide := chbAutohide.Checked;
+ FLinkbar.HotkeyInfo := edtHotKey.HotkeyInfo;
+
if (Sender = btnOk)
then begin
Close;
@@ -469,7 +576,7 @@ procedure TFrmProperties.edtColorBgChange(Sender: TObject);
if (Sender = clbTextColor)
then FTextColor := clbTextColor.Selected;
- OptionsChanged(Sender);
+ Changed(Sender);
end;
procedure TFrmProperties.edtColorBgKeyPress(Sender: TObject; var Key: Char);
diff --git a/src/Linkbar.Shell.pas b/src/Linkbar.Shell.pas
index 8311b24..9f129d4 100644
--- a/src/Linkbar.Shell.pas
+++ b/src/Linkbar.Shell.pas
@@ -47,7 +47,7 @@ interface
implementation
-uses Linkbar.OS, Linkbar.Consts, Linkbar.Loc, StrUtils, Graphics;
+uses StrUtils, Graphics, Linkbar.OS, Linkbar.Consts, Linkbar.L10n;
type
TSHExtractIconsW = function(pszFileName: LPCWSTR; nIconIndex: Integer; cxIcon,
@@ -263,7 +263,7 @@ function NewShortcut(const APath: string): HRESULT;
cmd: string;
begin
Result := S_FALSE;
- lnkname := MUILoadResString(GetModuleHandle(LB_FN_NEWSHORTCUT), LB_RS_NSC_FILENAME);
+ lnkname := L10nMui(GetModuleHandle(LB_FN_NEWSHORTCUT), LB_RS_NSC_FILENAME);
if PathMakeUniqueName(filename, MAX_PATH, 'scut.lnk', PChar(lnkname + '.lnk'), PChar(APath))
then begin
hFile := CreateFile(filename, GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
diff --git a/src/Linkbar.Themes.pas b/src/Linkbar.Themes.pas
index 4fff65d..6e4e255 100644
--- a/src/Linkbar.Themes.pas
+++ b/src/Linkbar.Themes.pas
@@ -96,7 +96,7 @@ procedure ThemeSetWindowAttribute(AWnd: HWND);
if IsWindows10
then begin
// Set window accent policy
- // http://withinrafael.com/adding-the-aero-glass-blur-to-your-windows-10-apps/
+ // https://withinrafael.com/2015/07/08/adding-the-aero-glass-blur-to-your-windows-10-apps/
if Assigned(UDwmSetWindowCompositionAttributeProc)
then begin
AccentPolicy.AccentState := U_WCA_ACCENT_STATE_ENABLE_BLURBEHIND;
diff --git a/src/Linkbar.dpr b/src/Linkbar.dpr
index 9255960..0095e01 100644
--- a/src/Linkbar.dpr
+++ b/src/Linkbar.dpr
@@ -8,8 +8,6 @@ program Linkbar;
{$i linkbar.inc}
uses
- Linkbar.ResStr, // If this unit not place first then 32- and 64-bit verision have
- // different resource string identificator
Windows,
SysUtils,
Forms,
@@ -24,7 +22,7 @@ uses
mUnit in 'mUnit.pas',
Linkbar.Newbar,
Linkbar.Shell,
- Linkbar.Loc,
+ Linkbar.L10n,
Linkbar.Settings in 'Linkbar.Settings.pas' {FrmProperties};
{$R *.res}
@@ -71,9 +69,8 @@ begin
//-----------------------
// Apply localization
//-----------------------
- if FindCmdLineSwitch(CLK_LANG, cmd, True)
- then LbTranslateInit( StrToIntDef(cmd, 0) )
- else LbTranslateInit(0);
+ FindCmdLineSwitch(CLK_LANG, cmd, True);
+ L10nLoad(ExtractFilePath(ParamStr(0)) + DN_LOCALES, cmd);
if FindCmdLineSwitch(CLK_NEW, True)
then begin
@@ -129,10 +126,11 @@ begin
Continue;
end;
- LBCreateProcess(ParamStr(0),
- LBCreateCommandParam(CLK_LANG, IntToStr(LbLangID))
- + LBCreateCommandParam(CLK_FILE, sl[i])
- );
+ cmd := LBCreateCommandParam(CLK_FILE, sl[i]);
+ if (Locale <> '')
+ then cmd := LBCreateCommandParam(CLK_LANG, Locale) + cmd;
+
+ LBCreateProcess(ParamStr(0), cmd);
Inc(CreatedPanels);
end;
diff --git a/src/mUnit.dfm b/src/mUnit.dfm
index 9518464..f8b3158 100644
--- a/src/mUnit.dfm
+++ b/src/mUnit.dfm
@@ -12,10 +12,10 @@ object LinkbarWcl: TLinkbarWcl
Font.Style = []
FormStyle = fsStayOnTop
OldCreateOrder = False
- Position = poDefault
OnContextPopup = FormContextPopup
OnCreate = FormCreate
OnDestroy = FormDestroy
+ OnKeyDown = FormKeyDown
OnMouseDown = FormMouseDown
OnMouseEnter = FormMouseEnter
OnMouseLeave = FormMouseLeave
@@ -59,10 +59,10 @@ object LinkbarWcl: TLinkbarWcl
GroupIndex = 2
OnClick = imLockBarClick
end
- object imSortAlphabetically: TMenuItem
+ object imSortAlphabet: TMenuItem
Caption = 'Sort alphabetically'
GroupIndex = 2
- OnClick = imSortAlphabeticallyClick
+ OnClick = imSortAlphabetClick
end
object imProperties: TMenuItem
Caption = 'Properties'
diff --git a/src/mUnit.pas b/src/mUnit.pas
index ab7c13e..e0012bd 100644
--- a/src/mUnit.pas
+++ b/src/mUnit.pas
@@ -14,7 +14,7 @@ interface
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
System.UITypes, IniFiles, Menus, Vcl.ExtCtrls, Winapi.ShlObj,
DDForms, Cromis.DirectoryWatch,
- AccessBar, LBToolbar, Linkbar.Consts, Linkbar.Hint, Linkbar.Taskbar;
+ AccessBar, LBToolbar, Linkbar.Consts, Linkbar.Hint, Linkbar.Taskbar, HotKey;
type
@@ -32,7 +32,7 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
imOpenWorkdir: TMenuItem;
imLockBar: TMenuItem;
N3: TMenuItem;
- imSortAlphabetically: TMenuItem;
+ imSortAlphabet: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
@@ -53,7 +53,8 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
procedure imLockBarClick(Sender: TObject);
procedure FormContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
- procedure imSortAlphabeticallyClick(Sender: TObject);
+ procedure imSortAlphabetClick(Sender: TObject);
+ procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
CBmpSelectedItem: TBitmap;
CBmpDropPosition: TBitmap;
@@ -78,13 +79,17 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
FButtonCenter: TPoint;
FGripSize: Integer;
FHintShow: Boolean;
+ FHotkeyInfo: THotkeyInfo;
+ FHotkeyPressed: Boolean;
FItemMargin: TSize;
FIconSize: Integer;
FIsLightStyle: Boolean;
FItemOrder: TItemOrder;
+ FJumplistShowMode: TJumplistShowMode;
FLockLinkbar: Boolean;
FLockHotIndex: Boolean;
FSortAlphabetically: Boolean;
+ FStayOnTop: Boolean;
FBkgColor: Cardinal;
FTxtColor: Cardinal;
FUseBkgColor: Boolean;
@@ -97,12 +102,15 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
FTextHeight: Integer;
FIconOffset: TPoint;
FTextRect: TRect;
+ IconsInLine, IconLinesCount: integer;
+ FPrevForegroundWnd: HWND;
procedure UpdateWindowSize;
procedure SetScreenAlign(AValue: TScreenAlign);
procedure SetAutoHide(AValue: Boolean);
procedure SetItemOrder(AValue: TItemOrder);
procedure SetPressedIndex(AValue: integer);
procedure SetHotIndex(AValue: integer);
+ procedure SetHotkeyInfo(AValue: THotkeyInfo);
procedure SetButtonSize(AValue: TSize);
procedure SetIconSize(AValue: integer);
procedure SetIsLightStyle(AValue: Boolean);
@@ -111,6 +119,7 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
procedure SetTextOffset(AValue: Integer);
procedure SetTextWidth(AValue: Integer);
procedure SetSortAlphabetically(AValue: Boolean);
+ procedure SetStayOnTop(AValue: Boolean);
function GetScreenAlign: TScreenAlign;
procedure DrawBackground(const ABitmap: TBitmap; const AClipRect: TRect);
procedure DrawCaption(const ABitmap: TBitmap; const AIndex: Integer;
@@ -128,6 +137,7 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
function CheckItem(AIndex: Integer): Boolean;
function ScaleDimension(const X: Integer): Integer; inline;
private
+ procedure L10n;
procedure LoadProperties(const AFileName: string);
procedure SaveProperties;
private
@@ -152,6 +162,7 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
var AWidth, AHeight: Integer);
procedure QuerySizedEvent(Sender: TObject; const AX, AY, AWidth, AHeight: Integer);
procedure QueryHideEvent(Sender: TObject; AEnabled: boolean);
+ function IsItemIndex(const AIndex: Integer): Boolean;
private
FRemoved: boolean;
procedure DoPopupMenuItemExecute(const ACmd: Integer);
@@ -175,6 +186,8 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure WndProc(var Msg: TMessage); override;
+ procedure WmHotKey(var Msg: TMessage); message WM_HOTKEY;
+ procedure CMDialogKey(var Msg: TCMDialogKey); message CM_DIALOGKEY;
protected
FAutoHiden: Boolean;
FCanAutoHide: Boolean;
@@ -183,8 +196,8 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
FAfterAutoHideBound: TRect;
FAutoShowDelay: Integer;
procedure DoAutoHide;
- procedure _DoAutoShow;
- procedure _DoDelayedAutoShow;
+ procedure DoAutoShow;
+ procedure DoDelayedAutoShow;
procedure OnFormJumplistDestroy(Sender: TObject);
public
procedure UpdateItemSizes;
@@ -193,10 +206,12 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
property AutoHideTransparency: Boolean read FAutoHideTransparency write FAutoHideTransparency;
property AutoShowMode: TAutoShowMode read FAutoShowMode write FAutoShowMode;
property ButtonSize: TSize read FButtonSize write SetButtonSize;
+ property HotkeyInfo: THotkeyInfo read FHotkeyInfo write SetHotkeyInfo;
property ItemMargin: TSize read FItemMargin write SetItemMargin;
property IconSize: Integer read FIconSize write SetIconSize;
property IsLightStyle: Boolean read FIsLightStyle write SetIsLightStyle;
property ItemOrder: TItemOrder read FItemOrder write SetItemOrder;
+ property JumplistShowMode: TJumplistShowMode read FJumplistShowMode write FJumplistShowMode;
property TextLayout: TTextLayout read FTextLayout write SetTextLayout;
property TextOffset: Integer read FTextOffset write SetTextOffset;
property TextWidth: Integer read FTextWidth write SetTextWidth;
@@ -211,6 +226,7 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
property UseBkgColor: Boolean read FUseBkgColor write FUseBkgColor;
property UseTxtColor: Boolean read FUseTxtColor write FUseTxtColor;
property GlowSize: Integer read FGlowSize write FGlowSize;
+ property StayOnTop: Boolean read FStayOnTop write SetStayOnTop;
private
FEnableAeroGlass: Boolean;
procedure SetEnableAeroGlass(AValue: Boolean);
@@ -222,8 +238,6 @@ TLinkbarWcl = class(TLinkbarCustomFrom)
var
LinkbarWcl: TLinkbarWcl;
- IconsInLine,
- IconLinesCount: integer;
FPreferencesFileName: string;
implementation
@@ -233,7 +247,7 @@ implementation
uses Types, Math, Dialogs, StrUtils,
ExplorerMenu, Linkbar.Settings, Linkbar.Shell, Linkbar.Themes,
Linkbar.OS, JumpLists.Api, JumpLists.Form,
- Linkbar.ResStr, Linkbar.Loc, RenameDialog,
+ Linkbar.L10n, RenameDialog,
Themes;
const
@@ -242,6 +256,7 @@ implementation
WM_LB_SHELLNOTIFY = WM_USER + 88;
TIMER_AUTO_SHOW = 15;
+ TIMER_AUTO_HIDE = 16;
function IsValidPreferenceFile(const AFileName: string): Boolean;
var ini: TMemIniFile;
@@ -355,7 +370,9 @@ function TLinkbarWcl.CheckItem(AIndex: Integer): Boolean;
Result := FileExists(fn);
if not Result
then begin
- if MessageDlg( RS_FILENOTFOUND + #13 + fn + #13 + RS_Q_DELETELINK,
+ if MessageDlg( L10NFind('Message.FileNotFound', 'File does not exists')
+ + #13 + fn + #13 +
+ L10NFind('Message.DeleteShortcut', 'Delete shortcut?'),
mtConfirmation, [mbOK, mbCancel], 0, mbCancel) = mrOk
then begin
Items.Delete(AIndex);
@@ -704,6 +721,7 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
DEF_AUTOHIDE_TRANSPARENCY);
FAutoShowMode := TAutoShowMode(IniFile.ReadInteger(INI_SECTION_MAIN, INI_AUTOHIDE_SHOWMODE,
DEF_AUTOHIDE_SHOWMODE));
+ FHotkeyInfo.Create( IniFile.ReadString(INI_SECTION_MAIN, INI_AUTOHIDE_HOTKEY, DEF_AUTOHIDE_HOTKEY) );
FIconSize := IniFile.ReadInteger(INI_SECTION_MAIN, INI_ICON_SIZE, DEF_ICON_SIZE);
FItemMargin.cx := IniFile.ReadInteger(INI_SECTION_MAIN, INI_MARGINX, DEF_MARGINX);
FItemMargin.cy := IniFile.ReadInteger(INI_SECTION_MAIN, INI_MARGINY, DEF_MARGINY);
@@ -729,6 +747,8 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
FGlowSize := IniFile.ReadInteger(INI_SECTION_MAIN, INI_GLOWSIZE, DEF_GLOWSIZE);
FHintShow := IniFile.ReadBool(INI_SECTION_DEV, INI_HINT_SHOW, DEF_HINT_SHOW);
+ StayOnTop := IniFile.ReadBool(INI_SECTION_MAIN, INI_STAYONTOP, DEF_STAYONTOP);
+ FJumplistShowMode := TJumplistShowMode(IniFile.ReadInteger(INI_SECTION_MAIN, INI_JUMPLISTSHOWMODE, DEF_JUMPLISTSHOWMODE));
finally
IniFile.Free;
end;
@@ -739,6 +759,7 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
FAutoHide := DEF_AUTOHIDE;
FAutoHideTransparency := DEF_AUTOHIDE_TRANSPARENCY;
FAutoShowMode := TAutoShowMode(DEF_AUTOHIDE_SHOWMODE);
+ FHotkeyInfo.Create(DEF_AUTOHIDE_HOTKEY);
FIconSize := DEF_ICON_SIZE;
FItemMargin := TSize.Create(DEF_MARGINX, DEF_MARGINY);
@@ -758,6 +779,8 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
FAutoShowDelay := DEF_AUTOSHOW_DELAY;
FSortAlphabetically := DEF_SORT_AB;
+ StayOnTop := DEF_STAYONTOP;
+ FJumplistShowMode := TJumplistShowMode(DEF_JUMPLISTSHOWMODE);
end;
{ Check values }
@@ -770,7 +793,10 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
// Screen edge
if ( FScreenEdge < Low(TScreenAlign) ) or ( FScreenEdge > High(TScreenAlign) )
then FScreenEdge := TScreenAlign(DEF_EDGE);
-
+ // Jumplists
+ if ( FJumplistShowMode < Low(TJumplistShowMode) ) or ( FJumplistShowMode > High(TJumplistShowMode) )
+ then FJumplistShowMode := TJumplistShowMode(DEF_JUMPLISTSHOWMODE);
+
FIconSize := EnsureRange(FIconSize, ICON_SIZE_MIN, ICON_SIZE_MAX);
FItemMargin.cx := EnsureRange(FItemMargin.cx, MARGIN_MIN, MARGIN_MAX);
FItemMargin.cy := EnsureRange(FItemMargin.cy, MARGIN_MIN, MARGIN_MAX);
@@ -801,6 +827,10 @@ procedure TLinkbarWcl.LoadProperties(const AFileName: string);
FDragingItem := False;
ExpAeroGlassEnabled := FEnableAeroGlass;
+
+ // Register Hotkey
+ if (AutoHide)
+ then RegisterHotkeyNotify(Handle, FHotkeyInfo);
end;
procedure TLinkbarWcl.SaveProperties;
@@ -840,6 +870,7 @@ procedure TLinkbarWcl.SaveProperties;
IniFile.WriteBool(INI_SECTION_MAIN, INI_AUTOHIDE, AutoHide);
IniFile.WriteBool(INI_SECTION_MAIN, INI_AUTOHIDE_TRANSPARENCY, FAutoHideTransparency);
IniFile.WriteInteger(INI_SECTION_MAIN, INI_AUTOHIDE_SHOWMODE, Integer(AutoShowMode));
+ IniFile.WriteString(INI_SECTION_MAIN, INI_AUTOHIDE_HOTKEY, HotkeyInfo);
IniFile.WriteInteger(INI_SECTION_MAIN, INI_ICON_SIZE, IconSize);
IniFile.WriteInteger(INI_SECTION_MAIN, INI_MARGINX, ItemMargin.cx);
@@ -868,6 +899,10 @@ procedure TLinkbarWcl.SaveProperties;
IniFile.WriteInteger(INI_SECTION_MAIN, INI_GLOWSIZE, FGlowSize);
+ IniFile.WriteBool(INI_SECTION_MAIN, INI_STAYONTOP, FStayOnTop);
+ // Jumplists
+ IniFile.WriteInteger(INI_SECTION_MAIN, INI_JUMPLISTSHOWMODE, Integer(JumplistShowMode));
+
IniFile.UpdateFile;
finally
IniFile.Free;
@@ -894,7 +929,8 @@ procedure TLinkbarWcl.CreateWnd;
procedure TLinkbarWcl.FormCreate(Sender: TObject);
begin
- LbTranslateComponent(Self);
+ L10n;
+ oHint := TTooltip32.Create(Handle);
pMenu.Items.RethinkHotkeys;
@@ -912,11 +948,10 @@ procedure TLinkbarWcl.FormCreate(Sender: TObject);
GetOrCreateFilesList(WorkDir + LINKSLIST_FILE_NAME);
- oHint := TTooltip32.Create(Handle);
-
UpdateItemSizes;
oAppBar := TAccessBar.Create2(self, FScreenEdge, FALSE);
+ oAppBar.StayOnTop := StayOnTop;
oAppBar.MonitorNum := FMonitorNum;
oAppBar.QuerySizing := QuerySizingEvent;
oAppBar.QuerySized := QuerySizedEvent;
@@ -928,13 +963,35 @@ procedure TLinkbarWcl.FormCreate(Sender: TObject);
BitBucketNotify := RegisterBitBucketNotify(Handle, WM_LB_SHELLNOTIFY);
end;
+procedure TLinkbarWcl.L10n;
+begin
+ L10nControl(imNewShortcut, 'Menu.Shortcut');
+ L10nControl(imOpenWorkdir, 'Menu.Open');
+ L10nControl(imAddBar, 'Menu.Create');
+ L10nControl(imRemoveBar, 'Menu.Delete');
+ L10nControl(imLockBar, 'Menu.Lock');
+ L10nControl(imSortAlphabet, 'Menu.Sort');
+ L10nControl(imProperties, 'Menu.Properties');
+ L10nControl(imClose, 'Menu.Close');
+ L10nControl(imCloseAll, 'Menu.CloseAll');
+end;
+
procedure TLinkbarWcl.FormDestroy(Sender: TObject);
begin
- StopDirWatch;
DeregisterBitBucketNotify(BitBucketNotify);
- if not FRemoved
+ UnregisterHotkeyNotify(Handle);
+
+ if Assigned(FrmProperties)
+ then FrmProperties.Free;
+
+ oAppBar.Free;
+ StopDirWatch;
+
+ if (not FRemoved)
then SaveProperties;
+
ThemeCloseData;
+
if Assigned(oHint) then oHint.Free;
if Assigned(BmpMain) then BmpMain.Free;
if Assigned(BmpBtn) then BmpBtn.Free;
@@ -943,6 +1000,136 @@ procedure TLinkbarWcl.FormDestroy(Sender: TObject);
if Assigned(Items) then Items.Free;
end;
+function TLinkbarWcl.IsItemIndex(const AIndex: Integer): Boolean;
+begin
+ Result := (AIndex >= 0) and (AIndex < Items.Count);
+end;
+
+procedure TLinkbarWcl.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+begin
+{$IFNDEF DEBUG}
+ //if (Shift <> []) then Exit;
+{$ENDIF}
+
+ if (Items.Count = 0) then Exit;
+
+ case Key of
+ VK_SPACE, VK_RETURN: // Run
+ begin
+ if IsItemIndex(HotIndex)
+ then begin
+ oHint.Cancel;
+ DoExecuteItem(HotIndex);
+ end;
+ Exit;
+ end;
+ VK_ESCAPE: // Deselect
+ begin
+ HotIndex := ITEM_NONE;
+ Exit;
+ end;
+ VK_F2: // Rename
+ begin
+ if IsItemIndex(HotIndex)
+ then begin
+ oHint.Cancel;
+ DoRenameItem(HotIndex);
+ end;
+ Exit;
+ end;
+ VK_DELETE:
+ begin
+ if IsItemIndex(HotIndex)
+ then begin
+ oHint.Cancel;
+ SHDeleteOp(Handle, Items[HotIndex].FileName, GetKeyState(VK_SHIFT) >= 0);
+ end;
+ Exit;
+ end;
+ // Arrows
+ VK_LEFT, VK_RIGHT, VK_DOWN, VK_UP:
+ begin
+ // No hot item:
+ // Left/Up - last
+ // Right/Down - first
+ if (HotIndex = ITEM_NONE)
+ then begin
+ if (Key in [VK_LEFT, VK_UP])
+ then HotIndex := Items.Count-1
+ else HotIndex := 0;
+ Exit;
+ end;
+
+ // One-line panel:
+ // Left/Up - prev
+ // Right/Down - next
+ if (IconLinesCount = 1)
+ then begin
+ if (Key in [VK_LEFT, VK_UP])
+ then HotIndex := Max(HotIndex - 1, 0)
+ else HotIndex := Min(HotIndex + 1, Items.Count-1);
+ Exit;
+ end;
+
+ // Multi-line panel:
+ case Key of
+ VK_LEFT:
+ begin
+ if (ItemOrder = ioLeftToRight)
+ then HotIndex := Max(HotIndex - 1, 0)
+ else begin
+ if (oAppBar.Vertical)
+ then HotIndex := Max(HotIndex - IconsInLine, 0)
+ else HotIndex := Max(HotIndex - IconLinesCount, 0);
+ end;
+ end;
+ VK_RIGHT:
+ begin
+ if (ItemOrder = ioLeftToRight)
+ then HotIndex := Min(HotIndex + 1, Items.Count-1)
+ else begin
+ if (oAppBar.Vertical)
+ then HotIndex := Min(HotIndex + IconsInLine, Items.Count-1)
+ else HotIndex := Min(HotIndex + IconLinesCount, Items.Count-1)
+ end;
+ end;
+ VK_UP:
+ begin
+ if (ItemOrder = ioUpToDown)
+ then HotIndex := Max(HotIndex - 1, 0)
+ else begin
+ if (oAppBar.Vertical)
+ then HotIndex := Max(HotIndex - IconLinesCount, 0)
+ else HotIndex := Max(HotIndex - IconsInLine, 0)
+ end;
+ end;
+ VK_DOWN:
+ begin
+ if (ItemOrder = ioUpToDown)
+ then HotIndex := Min(HotIndex + 1, Items.Count-1)
+ else begin
+ if (oAppBar.Vertical)
+ then HotIndex := Min(HotIndex + IconLinesCount, Items.Count-1)
+ else HotIndex := Min(HotIndex + IconsInLine, Items.Count-1)
+ end;
+ end;
+ end;
+ end;
+ else
+ Exit;
+ end;
+end;
+
+procedure TLinkbarWcl.CMDialogKey(var Msg: TCMDialogKey);
+begin
+ if (Msg.CharCode = VK_TAB)
+ then begin
+ HotIndex := HotIndex + 1;
+ Exit;
+ end;
+ inherited;
+end;
+
function TLinkbarWcl.ItemIndexByPoint(const APt: TPoint;
const ALastIndex: integer = ITEM_NONE): Integer;
var
@@ -983,9 +1170,16 @@ procedure TLinkbarWcl.FormMouseDown(Sender: TObject; Button: TMouseButton;
end;
end;
-procedure TLinkbarWcl.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
+var
+ prevX: Integer = -MaxInt;
+ prevY: Integer = -MaxInt;
+
+procedure TLinkbarWcl.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
+ if (X = prevX) and (Y = prevY)
+ then Exit;
+ prevX := X; prevY := Y;
+
if FAutoHiden then Exit;
if Self.IsDragDrop then Exit;
@@ -1044,8 +1238,9 @@ procedure TLinkbarWcl.FormMouseUp(Sender: TObject; Button: TMouseButton;
or
( (AutoShowMode = smMouseClickRight) and (Button = mbRight) )
then begin
+
if PtInRect(Rect(0,0,Width,Height), Point(X, Y))
- then _DoAutoShow;
+ then DoAutoShow;
end;
Exit;
end;
@@ -1094,7 +1289,7 @@ procedure TLinkbarWcl.DoDragItem(X, Y: Integer);
procedure TLinkbarWcl.DoExecuteItem(const AIndex: Integer);
begin
- if AIndex <> ITEM_NONE
+ if (AIndex <> ITEM_NONE)
then begin
if CheckItem(AIndex)
then OpenByDefaultVerb(Handle, Items[AIndex].Pidl);
@@ -1237,7 +1432,7 @@ procedure TLinkbarWcl.DoPopupMenu(APt: TPoint; AShift: Boolean);
and (FLockLinkbar)
then Flags := Flags or MF_CHECKED;
- if (pMenu.Items[i] = imSortAlphabetically)
+ if (pMenu.Items[i] = imSortAlphabet)
and (FSortAlphabetically)
then Flags := Flags or MF_CHECKED;
@@ -1320,31 +1515,34 @@ procedure TLinkbarWcl.DoPopupJumplist(APt: TPoint; AShift: Boolean);
fjl: TFormJumpList;
maxcount: Integer;
begin
- item := Items[FItemPopup];
-
- { Check and show Jumplist }
- maxcount := GetJumpListMaxCount;
- if (maxcount > 0)
- and GetAppInfoForLink(item.Pidl, appid)
- and HasJumpList(appid)
+ if (FJumplistShowMode <> jsmDisabled)
then begin
- oHint.Cancel;
- r := item.Rect;
- case ScreenAlign of
- saLeft: pt := Point(r.Right, r.Bottom);
- saRight: pt := Point(r.Left, r.Bottom);
- saTop: pt := Point(r.CenterPoint.X, r.Bottom);
- saBottom: pt := Point(r.CenterPoint.X, r.Top);
- end;
- MapWindowPoints(Handle, 0, pt, 1);
- fjl := TFormJumpList.CreateNew(Self);
- fjl.OnDestroy := OnFormJumplistDestroy;
- if fjl.Popup(Handle, pt.X, pt.Y, JUMPLIST_ALIGN[ScreenAlign], appid,
- item.Pidl, maxcount)
+ item := Items[FItemPopup];
+
+ { Check and show Jumplist }
+ maxcount := GetJumpListMaxCount;
+ if (maxcount > 0)
+ and GetAppInfoForLink(item.Pidl, appid)
+ and HasJumpList(appid)
then begin
- FLockHotIndex := True;
- FLockAutoHide := True;
- Exit;
+ oHint.Cancel;
+ r := item.Rect;
+ case ScreenAlign of
+ saLeft: pt := Point(r.Right, r.Bottom);
+ saRight: pt := Point(r.Left, r.Bottom);
+ saTop: pt := Point(r.CenterPoint.X, r.Bottom);
+ saBottom: pt := Point(r.CenterPoint.X, r.Top);
+ end;
+ MapWindowPoints(Handle, 0, pt, 1);
+ fjl := TFormJumpList.CreateNew(Self);
+ fjl.OnDestroy := OnFormJumplistDestroy;
+ if fjl.Popup(Handle, pt.X, pt.Y, JUMPLIST_ALIGN[ScreenAlign], appid,
+ item.Pidl, maxcount)
+ then begin
+ FLockHotIndex := True;
+ FLockAutoHide := True;
+ Exit;
+ end;
end;
end;
@@ -1365,8 +1563,10 @@ procedure TLinkbarWcl.FormContextPopup(Sender: TObject; MousePos: TPoint;
if (pt.X = -1) and (pt.Y = -1)
then begin
// Pressed keyboard key "Menu"
- pt := Point(0, 0);
- FItemPopup := ITEM_NONE;
+ FItemPopup := HotIndex;
+ if IsItemIndex(FItemPopup)
+ then pt := Items[HotIndex].Rect.CenterPoint
+ else pt := Point(0, 0);
end
else
FItemPopup := ItemIndexByPoint(pt);
@@ -1512,6 +1712,9 @@ procedure TLinkbarWcl.SetHotIndex(AValue: integer);
HA: TAlignment;
VA: TVerticalAlignment;
begin
+ if not IsItemIndex(AValue)
+ then AValue := ITEM_NONE;
+
if (FLockHotIndex)
or (AValue = FHotIndex)
then Exit;
@@ -1579,6 +1782,15 @@ procedure TLinkbarWcl.SetHotIndex(AValue: integer);
end;
end;
+procedure TLinkbarWcl.SetHotkeyInfo(AValue: THotkeyInfo);
+begin
+ FHotkeyInfo := AValue;
+ if (AutoHide)
+ // (AutoShowMode = smHotKey)
+ then RegisterHotkeyNotify(Handle, FHotkeyInfo)
+ else UnregisterHotkeyNotify(Handle);
+end;
+
procedure TLinkbarWcl.SetScreenAlign(AValue: TScreenAlign);
begin
FScreenEdge := AValue;
@@ -1597,6 +1809,17 @@ procedure TLinkbarWcl.SetSortAlphabetically(AValue: Boolean);
end;
end;
+procedure TLinkbarWcl.SetStayOnTop(AValue: Boolean);
+const FORM_STYLE: array[Boolean] of TFormStyle = (fsNormal, fsStayOnTop);
+begin
+ if FStayOnTop = AValue then Exit;
+ FStayOnTop := AValue;
+ Self.FormStyle := FORM_STYLE[FStayOnTop];
+
+ if Assigned(oAppBar)
+ then oAppBar.StayOnTop := FStayOnTop;
+end;
+
procedure TLinkbarWcl.QuerySizingEvent(Sender: TObject; AVertical: Boolean;
var AWidth, AHeight: Integer);
begin
@@ -1686,10 +1909,6 @@ procedure TLinkbarWcl.WndProc(var Msg: TMessage);
var i: Integer;
begin
case Msg.Msg of
- CUSTOM_ABN_FULLSCREENAPP:
- begin
- oAppBar.AppBarFullScreenApp(Msg.LParam <> 0);
- end;
// DWM Messaages
WM_THEMECHANGED:
begin
@@ -1733,6 +1952,8 @@ procedure TLinkbarWcl.WndProc(var Msg: TMessage);
WM_KILLFOCUS:
begin
Msg.Result := 0;
+ if (csDestroying in ComponentState)
+ then Exit;
FCanAutoHide := not Assigned(FrmProperties);
DoAutoHide;
end;
@@ -1776,11 +1997,19 @@ procedure TLinkbarWcl.WndProc(var Msg: TMessage);
{ Delayed auto show (timer) }
WM_TIMER:
begin
- if (Msg.WParam = TIMER_AUTO_SHOW)
- then begin
- KillTimer(Handle, TIMER_AUTO_SHOW);
- _DoAutoShow;
- Exit;
+ case Msg.WParam of
+ TIMER_AUTO_SHOW:
+ begin
+ KillTimer(Handle, TIMER_AUTO_SHOW);
+ DoAutoShow;
+ Exit;
+ end;
+ TIMER_AUTO_HIDE:
+ begin
+ KillTimer(Handle, TIMER_AUTO_HIDE);
+ DoAutoHide;
+ Exit;
+ end;
end;
end
else
@@ -1788,6 +2017,65 @@ procedure TLinkbarWcl.WndProc(var Msg: TMessage);
end;
end;
+function SetForegroundWindowInternal(AWnd: HWND): HWND;
+var ip: TInput; // This structure will be used to create the keyboard input event.
+begin
+ Result := 0;
+
+ if not IsWindow(AWnd)
+ then Exit;
+
+ Result := GetForegroundWindow;
+
+ // Set up a generic keyboard event.
+ FillChar(ip, SizeOf(ip), 0);
+ ip.Itype := INPUT_KEYBOARD;
+ ip.ki.wScan := 0; // hardware scan code for key
+ ip.ki.time := 0;
+ ip.ki.dwExtraInfo := 0;
+
+ // Press the "Alt" key
+ ip.ki.wVk := VK_MENU; // virtual-key code for the "Alt" key
+ ip.ki.dwFlags := 0; // 0 for key press
+ SendInput(1, ip, SizeOf(ip));
+
+ //Sleep(100); //Sometimes SetForegroundWindow will fail and the window will flash instead of it being show. Sleeping for a bit seems to help.
+ Application.ProcessMessages;
+
+ SetForegroundWindow(AWnd);
+
+ // Release the "Alt" key
+ ip.ki.dwFlags := KEYEVENTF_KEYUP; // for key release
+ SendInput(1, ip, sizeof(ip));
+end;
+
+procedure TLinkbarWcl.WmHotKey(var Msg: TMessage);
+begin
+ if (Msg.Msg = WM_HOTKEY)
+ and (Msg.WParam = LB_HOTKEY_ID)
+ and (Msg.LParamHi = FHotkeyInfo.KeyCode)
+ and (Msg.LParamLo = FHotkeyInfo.Modifiers)
+ and AutoHide
+ //and (FAutoShowMode = smHotkey)
+ then begin
+ FHotkeyPressed := True;
+ if (FAutoHiden)
+ then begin
+ DoAutoShow;
+ FPrevForegroundWnd := SetForegroundWindowInternal(Handle);
+ end
+ else begin
+ SetForegroundWindowInternal(FPrevForegroundWnd);
+ // Linkbar will be hidden when it loses Focus
+ //DoAutoHide;
+ end;
+ FHotkeyPressed := False;
+ Exit;
+ end;
+
+ inherited;
+end;
+
procedure TLinkbarWcl.UpdateBitBuckets;
begin
Items.BitBucketUpdateIcon;
@@ -1860,9 +2148,12 @@ procedure TLinkbarWcl.imLockBarClick(Sender: TObject);
end;
procedure TLinkbarWcl.imAddBarClick(Sender: TObject);
+var cmd: string;
begin
- LBCreateProcess( ParamStr(0), LBCreateCommandParam(CLK_NEW, '')
- + LBCreateCommandParam(CLK_LANG, IntToStr(LbLangID)) );
+ cmd := LBCreateCommandParam(CLK_NEW, '');
+ if (Locale <> '')
+ then cmd := cmd + LBCreateCommandParam(CLK_LANG, Locale);
+ LBCreateProcess(ParamStr(0), cmd);
end;
procedure TLinkbarWcl.imNewShortcutClick(Sender: TObject);
@@ -1883,9 +2174,9 @@ procedure TLinkbarWcl.imRemoveBarClick(Sender: TObject);
try
td.Caption := ' ' + APP_NAME_LINKBAR;
td.MainIcon := tdiNone;
- td.Title := Format(RS_REMDLG_TITLE, [PanelName]);
- td.Text := Format(RS_REMDLG_TEXT, [WorkDir]);
- td.VerificationText := RS_REMDLG_VERIFICATIONTEXT + Format('%*s', [24, ' ']);
+ td.Title := Format( L10NFind('Delete.Title', 'You remove the linkbar "%s"'), [PanelName] );
+ td.Text := Format( L10NFind('Delete.Text', 'Working directory: %s'), [WorkDir] );
+ td.VerificationText := L10NFind('Delete.Verification', 'Delete working directory') + Format('%*s', [24, ' ']);
td.CommonButtons := [tcbOk, tcbCancel];
td.DefaultButton := tcbCancel;
@@ -1907,7 +2198,7 @@ procedure TLinkbarWcl.imRemoveBarClick(Sender: TObject);
end;
end;
-procedure TLinkbarWcl.imSortAlphabeticallyClick(Sender: TObject);
+procedure TLinkbarWcl.imSortAlphabetClick(Sender: TObject);
begin
SortAlphabetically := not SortAlphabetically;
end;
@@ -1921,9 +2212,15 @@ function TLinkbarWcl.ScaleDimension(const X: Integer): Integer;
Result := MulDiv(X, Self.PixelsPerInch, 96);
end;
-function MakePoint(const Param : DWord): TPoint; inline;
+// Macros from windowsx.h:
+// Important Do not use the LOWORD or HIWORD macros to extract the x- and y-
+// coordinates of the cursor position because these macros return incorrect results
+// on systems with multiple monitors. Systems with multiple monitors can have
+// negative x- and y- coordinates, and LOWORD and HIWORD treat the coordinates
+// as unsigned quantities.
+function MakePoint(const L: DWORD): TPoint; inline;
Begin
- Result := TPoint.Create(Param and $FFFF, Param shr 16);
+ Result := TPoint.Create(SmallInt(L and $FFFF), SmallInt(L shr 16));
End;
procedure TLinkbarWcl.DoAutoHide;
@@ -1936,7 +2233,6 @@ procedure TLinkbarWcl.DoAutoHide;
if FCanAutoHide and not FAutoHiden
then begin
-
FAutoHiden := True;
r := FBeforeAutoHideBound;
case ScreenAlign of
@@ -1952,15 +2248,14 @@ procedure TLinkbarWcl.DoAutoHide;
end;
end;
-procedure TLinkbarWcl._DoAutoShow;
+procedure TLinkbarWcl.DoAutoShow;
+var pt: TPoint;
begin
- if (not AutoHide)
- then Exit;
-
- if ( WindowFromPoint(MakePoint(GetMessagePos)) <> Handle )
- then Exit;
-
- if FAutoHiden
+ pt := MakePoint(GetMessagePos);
+ if (AutoHide)
+ and (FAutoHiden)
+ and (FHotkeyPressed or (WindowFromPoint(pt) = Handle))
+ //(FAutoShowMode <> smHotKey)
then begin
FAutoHiden := False;
MoveWindow(Handle, FBeforeAutoHideBound.Left, FBeforeAutoHideBound.Top,
@@ -1970,13 +2265,13 @@ procedure TLinkbarWcl._DoAutoShow;
end;
end;
-procedure TLinkbarWcl._DoDelayedAutoShow;
+procedure TLinkbarWcl.DoDelayedAutoShow;
begin
if (not AutoHide)
then Exit;
if (FAutoShowDelay = 0)
- then _DoAutoShow
+ then DoAutoShow
else SetTimer(Handle, TIMER_AUTO_SHOW, FAutoShowDelay, nil);
end;
@@ -1985,14 +2280,14 @@ procedure TLinkbarWcl.FormMouseEnter(Sender: TObject);
if AutoHide
and FAutoHiden
and (FAutoShowMode = smMouseHover)
- then _DoDelayedAutoShow;
+ then DoDelayedAutoShow;
end;
procedure TLinkbarWcl.FormMouseLeave(Sender: TObject);
begin
HotIndex := -1;
if (FAutoShowMode = smMouseHover) or FCanAutoHide
- then DoAutoHide;
+ then SetTimer(Handle, TIMER_AUTO_HIDE, TIMER_AUTO_HIDE_DELAY, nil);// DoAutoHide;
end;
////////////////////////////////////////////////////////////////////////////////
@@ -2130,7 +2425,7 @@ procedure TLinkbarWcl.DoDragEnter(const pt: TPoint);
and FAutoHiden
then begin
FCanAutoHide := False;
- _DoAutoShow;
+ DoAutoShow;
end;
end;
@@ -2149,7 +2444,7 @@ procedure TLinkbarWcl.DoDragLeave;
if AutoHide and not Active
then begin
FCanAutoHide := True;
- DoAutoHide;
+ SetTimer(Handle, TIMER_AUTO_HIDE, TIMER_AUTO_HIDE_DELAY, nil); // DoAutoHide;
end;
end;