aqdockingutils.pas
来自「AutomatedDocking Library 控件源代码修改 适合Delp」· PAS 代码 · 共 2,359 行 · 第 1/5 页
PAS
2,359 行
constructor TaqClassObjectList.Create(AOwnItems: Boolean);
begin
inherited Create;
FOwnItems := AOwnItems;
end;
function TaqClassObjectList.DeleteItem(ABucket, AIndex: Integer): Pointer;
begin
Result := inherited DeleteItem(ABucket, AIndex);
if FOwnItems then TObject(Result).Free;
end;
function TaqClassObjectList.FindParented(AItem: TClass): TObject;
begin
while not Find(AItem, Pointer(Result)) do
begin
AItem := AItem.ClassParent;
if AItem = nil then
begin
Result := nil;
Exit;
end;
end;
end;
function TaqClassObjectList.GetData(AItem: TClass): TObject;
begin
Result := TObject(inherited Data[AItem]);
end;
function TaqClassObjectList.Remove(AItem: TClass): TObject;
begin
Result := TObject(inherited Remove(AItem));
end;
procedure TaqClassObjectList.SetData(AItem: TClass; const AData: TObject);
begin
inherited Data[AItem] := AData;
end;
{ TaqIntegerList }
function TaqIntegerList.Add(AIndex: Integer; AData: TObject): TObject;
begin
Result := TObject(inherited Add(Pointer(AIndex), AData));
end;
constructor TaqIntegerList.Create;
begin
inherited Create;
end;
function TaqIntegerList.GetData(AIndex: Integer): TObject;
begin
Result := inherited Data[Pointer(AIndex)];
end;
procedure TaqIntegerList.SetData(AIndex: Integer; const Value: TObject);
begin
inherited Data[Pointer(AIndex)] := Value;
end;
{ TaqIntegerListIterator }
constructor TaqBucketListIterator.Create(AList: TaqBucketList);
begin
inherited Create;
FList := AList;
FSearch := New(PaqBucketListSearch);
PaqBucketListSearch(FSearch)^.CurBucket := -2;
Reset;
end;
destructor TaqBucketListIterator.Destroy;
begin
Dispose(FSearch);
inherited;
end;
function TaqBucketListIterator.FindNext(out ABucket: Integer; out AIndex: Integer): Boolean;
var
i: Integer;
begin
with PaqBucketListSearch(FSearch)^ do
begin
if (CurBucket = FBucket) and (CurIndex = FIndex) then
begin
ABucket := NextBucket;
AIndex := NextIndex;
Result := SearchResult;
Exit;
end;
CurBucket := FBucket;
CurIndex := FIndex;
end;
Result := False;
if FBucket < FList.BucketCount then
begin
if (FBucket >= 0) and (FIndex < TaqBucketListFriend(FList).Buckets[FBucket].Count - 1) then
begin
AIndex := FIndex + 1;
ABucket := FBucket;
Result := True;
end
else
begin
for i := FBucket + 1 to FList.BucketCount - 1 do
if TaqBucketListFriend(FList).Buckets[i].Count > 0 then
begin
ABucket := i;
AIndex := 0;
Result := True;
Break;
end;
if not Result then
ABucket := FList.BucketCount;
end;
end;
with PaqBucketListSearch(FSearch)^ do
begin
NextBucket := ABucket;
NextIndex := AIndex;
SearchResult := Result;
end;
end;
function TaqBucketListIterator.HasNext: Boolean;
var
i, j: Integer;
begin
Result := FindNext(i, j);
end;
function TaqBucketListIterator.Next: TaqBucketListItem;
begin
if not FindNext(FBucket, FIndex) then
raise EaqBucketList.Create(SEListNoItems);
with FList.Buckets[FBucket].Items[FIndex] do
begin
Result.Key := Item;
Result.Data := Data;
Assert(Result.Data <> nil);
end;
end;
procedure TaqBucketListIterator.Reset;
begin
FBucket := -1; FIndex := 0;
end;
{$IFDEF VCL}
type
TGetWindowLongPtr = function(Handle: hWnd; nIndex: Integer): Longint; stdcall;
TSetWindowLongPtr = function(Handle: hWnd; nIndex: Integer; dwNewLong: Longint): Longint; stdcall;
var
user32dll: TaqHandle;
GetWindowLongPtr : TGetWindowLongPtr;
GetWindowLongPtrW: TGetWindowLongPtr;
SetWindowLongPtr : TSetWindowLongPtr;
SetWindowLongPtrW: TSetWindowLongPtr;
procedure InitializeWindowManagmentFunctions;
const
User32dllName = 'user32.dll';
GetWindowLongPtrName = 'GetWindowLongPtrA';
GetWindowLongPtrWName = 'GetWindowLongPtrW';
SetWindowLongPtrName = 'SetWindowLongPtrA';
SetWindowLongPtrWName = 'SetWindowLongPtrW';
begin
user32dll := LoadLibrary(PChar(User32dllName));
GetWindowLongPtr := GetProcAddress(user32dll, PChar(GetWindowLongPtrName));
if @GetWindowLongPtr = nil then
GetWindowLongPtr := GetWindowLong;
GetWindowLongPtrW := GetProcAddress(user32dll, PChar(GetWindowLongPtrWName));
if @GetWindowLongPtrW = nil then
GetWindowLongPtrW := GetWindowLongW;
SetWindowLongPtr := GetProcAddress(user32dll, PChar(SetWindowLongPtrName));
if @SetWindowLongPtr = nil then
SetWindowLongPtr := SetWindowLong;
SetWindowLongPtrW := GetProcAddress(user32dll, PChar(SetWindowLongPtrWName));
if @SetWindowLongPtrW = nil then
SetWindowLongPtrW := SetWindowLongW;
end;
procedure ReleaseWindowManagementFunctions;
begin
FreeLibrary(user32dll);
end;
{$ENDIF}
{ TaqWindowEventFilter }
procedure TaqWindowEventFilter.AttachTo(ControlHandle: TaqHandle);
var
{$IFDEF VCL}
PrevDefWndProc: Pointer;
{$ELSE}
Method: TMethod;
{$ENDIF}
begin
{$IFDEF VCL}
FDefWndProc := Classes.MakeObjectInstance(WndProc);
FIsUnicode := IsWindowUnicode(ControlHandle);
if FIsUnicode then
PrevDefWndProc := Pointer(GetWindowLongPtrW(ControlHandle, GWL_WNDPROC))
else
PrevDefWndProc := Pointer(GetWindowLongPtr(ControlHandle, GWL_WNDPROC));
GetHooks.AddHook(ControlHandle, PrevDefWndProc, FDefWndProc);
if FIsUnicode then
SetWindowLongPtrW(ControlHandle, GWL_WNDPROC, Integer(FDefWndProc))
else
SetWindowLongPtr(ControlHandle, GWL_WNDPROC, Integer(FDefWndProc));
{$ELSE}
FHooks := QWidget_hook_create(ControlHandle);
TEventFilterMethod(Method) := MainEventFilter;
Qt_hook_hook_events(FHooks, Method);
{$ENDIF}
end;
procedure TaqWindowEventFilter.DetachFrom(ControlHandle: TaqHandle);
{$IFDEF VCL}
var
PrevDefWndProc: Pointer;
{$ENDIF}
begin
{$IFDEF VCL}
PrevDefWndProc := GetHooks.RemoveHook(ControlHandle, FDefWndProc);
if FIsUnicode then
SetWindowLongW(FControlHandle, GWL_WNDPROC, Longint(PrevDefWndProc))
else
SetWindowLong(FControlHandle, GWL_WNDPROC, Longint(PrevDefWndProc));
Classes.FreeObjectInstance(FDefWndProc);
FDefWndProc := nil;
{$ELSE}
QWidget_hook_destroy(FHooks);
FHooks := nil;
{$ENDIF}
end;
procedure TaqWindowEventFilter.AttachToWindow(Wnd: TaqControl);
begin
if FControl <> nil then
DetachFromWindow
else
FDestroying := False;
FControl := Wnd;
if FControl = nil then
Exit;
{$IFDEF VCL}
FControlHandle := FControl.Handle;
{$ELSE}
FControlHandle := TWidgetControl(FControl).Handle;
{$ENDIF}
AttachTo(FControlHandle);
end;
procedure TaqWindowEventFilter.DetachFromWindow;
begin
if FControl <> nil then
DetachFrom(FControlHandle);
FControl := nil;
FControlHandle := 0;
end;
destructor TaqWindowEventFilter.Destroy;
begin
DetachFromWindow;
inherited;
end;
procedure TaqWindowEventFilter.DoMove;
begin
if Assigned(FOnMove) then
FOnMove(FControl);
end;
procedure TaqWindowEventFilter.DoResize;
begin
if Assigned(FOnResize) then
FOnResize(FControl);
end;
procedure TaqWindowEventFilter.DoScroll;
begin
if Assigned(FOnScroll) then
FOnScroll(FControl);
end;
procedure TaqWindowEventFilter.DoDestroy;
begin
if Assigned(FOnDestroy) then
FOnDestroy(FControl);
end;
{$IFDEF VCL}
procedure TaqWindowEventFilter.WndProc(var Message: TMessage);
procedure CallDefWndProc;
begin
with Message do
begin
if FIsUnicode then
Result := CallWindowProcW(GetHooks.GetPrevHook(FControlHandle, FDefWndProc),
FControlHandle, Msg, WParam, LParam)
else
Result := CallWindowProc(GetHooks.GetPrevHook(FControlHandle, FDefWndProc),
FControlHandle, Msg, WParam, LParam);
end;
end;
var
TempHandle: THandle;
begin
Assert(FControlHandle <> 0);
case Message.Msg of
WM_MOVE:
if not FDestroying then
begin
CallDefWndProc;
DoMove;
Exit;
end;
WM_SIZE:
if not FDestroying then
begin
CallDefWndProc;
DoResize;
Exit;
end;
WM_HSCROLL, WM_VSCROLL:
if not FDestroying then
begin
CallDefWndProc;
DoScroll;
Exit;
end;
WM_SETFOCUS:
if FDestroying then
Exit;
WM_DESTROY:
begin
if not FDestroying then
begin
TempHandle := FControlHandle;
FDestroying := True;
DoDestroy;
DetachFromWindow;
with Message do
SendMessage(TempHandle, Msg, WParam, LParam);
Exit;
end;
end;
end;
CallDefWndProc;
end;
{$ELSE}
function TaqWindowEventFilter.MainEventFilter(Sender: QObjectH;
Event: QEventH): Boolean;
begin
Assert(FControl <> nil);
case QEvent_type(Event) of
QEventType_Move: DoMove;
QEventType_Resize: DoResize;
end;
Result := TaqControlFriend(FControl).MainEventFilter(Sender, Event);
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
{ TaqWindowEventFilterEx }
constructor TaqWindowEventFilterEx.Create;
begin
inherited Create;
FInitialized := False;
end;
procedure TaqWindowEventFilterEx.AttachToWindowByHandle(Handle: TaqHandle);
begin
if (FControlHandle <> 0) then
DetachFromWindow
else
FDestroying := False;
FControlHandle := Handle;
FControl := FindControl(Handle);
if FControlHandle = 0 then
Exit;
FInitialized := True;
AttachTo(FControlHandle);
end;
procedure TaqWindowEventFilterEx.DetachFromWindow;
begin
if not FInitialized then
inherited
else
begin
if FControlHandle <> 0 then
DetachFrom(FControlHandle);
FControlHandle := 0;
FControl := nil;
FInitialized := False;
end;
end;
{$ENDIF}
{ TaqCustomControl }
{$IFDEF VCL}
procedure TaqCustomControl.Paint;
begin
// By default, fill client rect with default Brush.
Canvas.Brush := Brush;
Canvas.FillRect(ClientRect);
end;
procedure TaqCustomControl.WMEraseBackground(var Message: TWMEraseBkgnd);
begin
// Do not clear control's background. Move all painting procedures to
// the Paint method.
Message.Result := 1;
end;
{$ELSE}
procedure TaqCustomControl.BoundsChanged;
begin
inherited BoundsChanged;
if Masked then
UpdateMask;
end;
constructor TaqCustomControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TaqControlCanvas.Create;
TaqControlCanvas(FCanvas).Control := Self;
end;
procedure TaqCustomControl.CreateWidget;
begin
FHandle := QWidget_create(ParentWidget, nil, WidgetFlags);
Hooks := QWidget_hook_create(FHandle);
// Control should not not clear its background, all
// painting operations are moved to the Paint method.
QWidget_setBackgroundMode(Handle, QWidgetBackgroundMode_NoBackground);
end;
destructor TaqCustomControl.Destroy;
begin
FreeAndNil(FCanvas);
inherited Destroy;
end;
procedure TaqCustomControl.DrawMask(Canvas: TCanvas);
var
R: TRect;
I: Integer;
begin
R := ClientRect;
Canvas.Brush.Color := clMask;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?