unit UCommon;
interface
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
{$I switches.inc}
uses
SysUtils,
Classes,
Messages,
{$IFDEF LCL}
lResources,
{$ENDIF}
{$IFDEF win32}
Windows,
{$ENDIF}
ULog;
{$IFNDEF DARWIN}
// FIXME: remove this if it is not needed anymore
type
hStream = THandle;
HGLRC = THandle;
TLargeInteger = Int64;
TWin32FindData = LongInt;
{$ENDIF}
{$IFDEF LCL}
function LazFindResource( const aName, aType : String ): TLResource;
{$ENDIF}
procedure ShowMessage( const msg : String );
{$IFDEF FPC}
function RandomRange(aMin: Integer; aMax: Integer) : Integer;
{$ENDIF}
{$IF Defined(MSWINDOWS) and Defined(FPC)}
function AllocateHWnd(Method: TWndMethod): HWND;
procedure DeallocateHWnd(hWnd: HWND);
{$IFEND}
function StringReplaceW(text : WideString; search, rep: WideChar):WideString;
function AdaptFilePaths( const aPath : widestring ): widestring;
{$IFNDEF win32}
procedure ZeroMemory( Destination: Pointer; Length: DWORD );
{$ENDIF}
(*
* Character classes
*)
function IsAlphaChar(ch: WideChar): boolean;
function IsNumericChar(ch: WideChar): boolean;
function IsAlphaNumericChar(ch: WideChar): boolean;
function IsPunctuationChar(ch: WideChar): boolean;
function IsControlChar(ch: WideChar): boolean;
implementation
uses
{$IFDEF Delphi}
Dialogs,
{$ENDIF}
UConfig;
function StringReplaceW(text : WideString; search, rep: WideChar):WideString;
var
iPos : integer;
// sTemp : WideString;
begin
(*
result := text;
iPos := Pos(search, result);
while (iPos > 0) do
begin
sTemp := copy(result, iPos + length(search), length(result));
result := copy(result, 1, iPos - 1) + rep + sTEmp;
iPos := Pos(search, result);
end;
*)
result := text;
if search = rep then
exit;
for iPos := 0 to length( result ) - 1 do
begin
if result[ iPos ] = search then
result[ iPos ] := rep;
end;
end;
function AdaptFilePaths( const aPath : widestring ): widestring;
begin
result := StringReplaceW( aPath, '\', PathDelim );//, [rfReplaceAll] );
end;
{$IFNDEF win32}
procedure ZeroMemory( Destination: Pointer; Length: DWORD );
begin
FillChar( Destination^, Length, 0 );
end; //ZeroMemory
(*
function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
// From http://en.wikipedia.org/wiki/RDTSC
function RDTSC: Int64; register;
asm
rdtsc
end;
begin
// Use clock_gettime here maybe ... from libc
lpPerformanceCount := RDTSC();
result := true;
end;
function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
begin
lpFrequency := 0;
result := true;
end;
*)
{$ENDIF}
{$IFDEF LCL}
function LazFindResource( const aName, aType : String ): TLResource;
var
iCount : Integer;
begin
result := nil;
for iCount := 0 to LazarusResources.count -1 do
begin
if ( LazarusResources.items[ iCount ].Name = aName ) AND
( LazarusResources.items[ iCount ].ValueType = aType ) THEN
begin
result := LazarusResources.items[ iCount ];
exit;
end;
end;
end;
{$ENDIF}
{$IFDEF FPC}
function RandomRange(aMin: Integer; aMax: Integer) : Integer;
begin
RandomRange := Random(aMax-aMin) + aMin ;
end;
{$ENDIF}
{$IF Defined(MSWINDOWS) and Defined(FPC)}
function AllocateHWndCallback(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
Msg: TMessage;
MethodPtr: ^TWndMethod;
begin
FillChar(Msg, SizeOf(Msg), 0);
Msg.msg := uMsg;
Msg.wParam := wParam;
Msg.lParam := lParam;
MethodPtr := Pointer(GetWindowLongPtr(hwnd, GWL_USERDATA));
if Assigned(MethodPtr) then
MethodPtr^(Msg);
Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end;
function AllocateHWnd(Method: TWndMethod): HWND;
var
ClassExists: Boolean;
WndClass, OldClass: TWndClass;
MethodPtr: ^TMethod;
begin
Result := 0;
// setup class-info
FillChar(WndClass, SizeOf(TWndClass), 0);
WndClass.hInstance := HInstance;
// Important: do not enable AllocateHWndCallback before the msg-handler method is assigned,
// otherwise race-conditions might occur
WndClass.lpfnWndProc := @DefWindowProc;
WndClass.lpszClassName:= 'USDXUtilWindowClass';
// check if class is already registered
ClassExists := GetClassInfo(HInstance, WndClass.lpszClassName, OldClass);
// create window-class shared by all windows created by AllocateHWnd()
if (not ClassExists) or (@OldClass.lpfnWndProc <> @DefWindowProc) then
begin
if ClassExists then
UnregisterClass(WndClass.lpszClassName, HInstance);
if (RegisterClass(WndClass) = 0) then
Exit;
end;
// create window
Result := CreateWindowEx(WS_EX_TOOLWINDOW, WndClass.lpszClassName, '',
WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil);
if (Result = 0) then
Exit;
// assign individual callback procedure to the window
if Assigned(Method) then
begin
// TMethod contains two pointers but we can pass just one as USERDATA
GetMem(MethodPtr, SizeOf(TMethod));
MethodPtr^ := TMethod(Method);
SetWindowLongPtr(Result, GWL_USERDATA, LONG_PTR(MethodPtr));
end;
// now enable AllocateHWndCallback for this window
SetWindowLongPtr(Result, GWL_WNDPROC, LONG_PTR(@AllocateHWndCallback));
end;
procedure DeallocateHWnd(hWnd: HWND);
var
MethodPtr: ^TMethod;
begin
if (hWnd <> 0) then
begin
MethodPtr := Pointer(GetWindowLongPtr(hWnd, GWL_USERDATA));
DestroyWindow(hWnd);
if Assigned(MethodPtr) then
FreeMem(MethodPtr);
end;
end;
{$IFEND}
procedure ShowMessage( const msg : String );
begin
{$IF Defined(MSWINDOWS)}
MessageBox(0, PChar(msg), PChar(USDXVersionStr()), MB_ICONINFORMATION);
{$ELSE}
debugwriteln(msg);
{$IFEND}
end;
function IsAlphaChar(ch: WideChar): boolean;
begin
// TODO: add chars > 255 when unicode-fonts work?
case ch of
'A'..'Z', // A-Z
'a'..'z', // a-z
#170,#181,#186,
#192..#214,
#216..#246,
#248..#255:
Result := true;
else
Result := false;
end;
end;
function IsNumericChar(ch: WideChar): boolean;
begin
case ch of
'0'..'9':
Result := true;
else
Result := false;
end;
end;
function IsAlphaNumericChar(ch: WideChar): boolean;
begin
Result := (IsAlphaChar(ch) or IsNumericChar(ch));
end;
function IsPunctuationChar(ch: WideChar): boolean;
begin
// TODO: add chars outside of Latin1 basic (0..127)?
case ch of
' '..'/',':'..'@','['..'`','{'..'~':
Result := true;
else
Result := false;
end;
end;
function IsControlChar(ch: WideChar): boolean;
begin
case ch of
#0..#31,
#127..#159:
Result := true;
else
Result := false;
end;
end;
end.