mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-02 10:12:35 +02:00
3754 lines
122 KiB
PHP
3754 lines
122 KiB
PHP
// included by controls.pp
|
|
|
|
{******************************************************************************
|
|
TWinControl
|
|
******************************************************************************
|
|
|
|
*****************************************************************************
|
|
* *
|
|
* This file is part of the Lazarus Component Library (LCL) *
|
|
* *
|
|
* See the file COPYING.LCL, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
|
|
{$IFOPT C-}
|
|
// Uncomment for local trace
|
|
// {$C+}
|
|
// {$DEFINE ASSERT_IS_ON}
|
|
{$ENDIF}
|
|
|
|
{ $DEFINE CHECK_POSITION}
|
|
{ $DEFINE VerboseMouseBugfix}
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl AdjustSize
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.AdjustSize;
|
|
begin
|
|
inherited AdjustSize;
|
|
// Unneeded: RequestAlign;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl AdjustClientRect
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.AdjustClientRect(var Rect: TRect);
|
|
Begin
|
|
//Not used. It's a virtual procedure that should be overriden.
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl AlignControls
|
|
|
|
Align child controls
|
|
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.AlignControls(AControl : TControl; var ARect : TRect);
|
|
var
|
|
AlignList: TList;
|
|
|
|
function AlignWork: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := True;
|
|
|
|
for I := ControlCount - 1 downto 0 do
|
|
begin
|
|
if (Controls[I].Align <> alNone)
|
|
or (Controls[I].Anchors <> [akLeft, akTop])
|
|
then Exit;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
function Anchored(Align: TAlign; Anchors: TAnchors): Boolean;
|
|
begin
|
|
case Align of
|
|
alLeft: Result := akLeft in Anchors;
|
|
alTop: Result := akTop in Anchors;
|
|
alRight: Result := akRight in Anchors;
|
|
alBottom: Result := akBottom in Anchors;
|
|
alClient: Result := Anchors = [akLeft, akTop, akRight, akBottom];
|
|
else
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
procedure DoPosition(Control: TControl; AAlign: TAlign);
|
|
var
|
|
NewLeft, NewTop, NewWidth, NewHeight: Integer;
|
|
ParentBaseClientSize: TPoint;
|
|
CurBaseBounds: TRect;
|
|
NewRight: Integer;
|
|
NewBottom: Integer;
|
|
begin
|
|
{$IFDEF CHECK_POSITION}
|
|
with Control do
|
|
writeln('[TWinControl.AlignControls.DoPosition] A Control=',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height,' recalculate the anchors=',(Control.Anchors <> AnchorAlign[AAlign]),' Align=',AlignNames[AAlign]);
|
|
{$ENDIF}
|
|
|
|
// get default bounds
|
|
with Control do
|
|
begin
|
|
NewLeft:=Left;
|
|
NewTop:=Top;
|
|
NewWidth:=Width;
|
|
NewHeight:=Height;
|
|
end;
|
|
|
|
{ Recalculate the anchors
|
|
|
|
Use Anchors to ensure that a control maintains its current position
|
|
relative to an edge of its parent, even if the parent is resized. When
|
|
its parent is resized, the control holds its position relative to the
|
|
edges to which it is anchored.
|
|
If a control is anchored to opposite edges of its parent, the control
|
|
stretches when its parent is resized. For example, if a control has its
|
|
Anchors property set to [akLeft,akRight], the control stretches when the
|
|
width of its parent changes.
|
|
Anchors is enforced only when the parent is resized. Thus, for example,
|
|
if a control is anchored to opposite edges of a form at design time and
|
|
the form is created in a maximized state, the control is not stretched
|
|
because the form is not resized after the control is created.
|
|
}
|
|
if (AAlign = alNone) or (Control.Anchors <> AnchorAlign[AAlign]) then
|
|
begin
|
|
with Control do
|
|
begin
|
|
// Get the base bounds. The base bounds are the user defined bounds
|
|
// without automatic aligning and/or anchoring
|
|
|
|
// get base size of parents client area
|
|
ParentBaseClientSize:=FBaseParentClientSize;
|
|
if (ParentBaseClientSize.X=0)
|
|
and (ParentBaseClientSize.Y=0) then
|
|
ParentBaseClientSize:=Point(Parent.ClientWidth,Parent.ClientHeight);
|
|
|
|
// get base bounds of Control
|
|
CurBaseBounds:=FBaseBounds;
|
|
if (CurBaseBounds.Right=CurBaseBounds.Left)
|
|
and (CurBaseBounds.Bottom=CurBaseBounds.Top) then
|
|
CurBaseBounds:=BoundsRect;
|
|
|
|
{if csDesigning in ComponentState then
|
|
writeln('[TWinControl.AlignControls.DoPosition] Before Anchoring ',
|
|
' ',Name,':',ClassName,
|
|
' CurBaseBounds=',CurBaseBounds.Left,',',CurBaseBounds.Top,',',CurBaseBounds.Right-CurBaseBounds.Left,',',CurBaseBounds.Bottom-CurBaseBounds.Top,
|
|
' ParBaseClient=',ParentBaseClientSize.X,',',ParentBaseClientSize.Y,
|
|
' ParClient=',Parent.ClientWidth,',',Parent.ClientHeight,
|
|
'');}
|
|
|
|
if akLeft in Anchors then begin
|
|
// keep distance to left side of parent
|
|
NewLeft:=CurBaseBounds.Left;
|
|
if akRight in Anchors then begin
|
|
// keep distance to right side of parent
|
|
// -> change the width
|
|
NewWidth:=Parent.ClientWidth
|
|
-(ParentBaseClientSize.X-CurBaseBounds.Right)
|
|
-NewLeft;
|
|
end else begin
|
|
// do not anchor to the right
|
|
// -> keep new width
|
|
NewWidth:=Width;
|
|
end;
|
|
end else begin
|
|
// do not anchor to the left
|
|
if akRight in Anchors then begin
|
|
// keep distance to right side of parent
|
|
// and keep new width
|
|
NewWidth:=Width;
|
|
NewLeft:=Parent.ClientWidth
|
|
-(ParentBaseClientSize.X-CurBaseBounds.Right)
|
|
-NewWidth;
|
|
end else begin
|
|
// do not anchor to the right
|
|
// -> keep new width and center horizontally
|
|
NewWidth:=Width;
|
|
NewLeft:=(Parent.ClientWidth-NewWidth) div 2;
|
|
end;
|
|
end;
|
|
|
|
if akTop in Anchors then begin
|
|
// keep distance to top side of parent
|
|
NewTop:=CurBaseBounds.Top;
|
|
if akBottom in Anchors then begin
|
|
// keep distance to bottom side of parent
|
|
// -> change the height
|
|
NewHeight:=Parent.ClientHeight
|
|
-(ParentBaseClientSize.Y-CurBaseBounds.Bottom)
|
|
-NewTop;
|
|
end else begin
|
|
// do not anchor to the bottom
|
|
// -> keep new height
|
|
NewHeight:=Height;
|
|
end;
|
|
end else begin
|
|
// do not anchor to the top
|
|
if akBottom in Anchors then begin
|
|
// keep distance to bottom side of parent
|
|
// and keep new height
|
|
NewHeight:=Height;
|
|
NewTop:=Parent.ClientHeight
|
|
-(ParentBaseClientSize.Y-CurBaseBounds.Bottom)
|
|
-NewHeight;
|
|
end else begin
|
|
// do not anchor to the bottom
|
|
// -> keep new height and center vertically
|
|
NewHeight:=Height;
|
|
NewTop:=(Parent.ClientHeight-NewHeight) div 2;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
{if csDesigning in ComponentState then
|
|
with Control do
|
|
writeln('[TWinControl.AlignControls.DoPosition] After Anchoring',
|
|
' ',Name,':',ClassName,
|
|
' Align=',AlignNames[AAlign],
|
|
' Control=',Name,':',ClassName,
|
|
' Old=',Left,',',Top,',',Width,',',Height,
|
|
' New=',NewLeft,',',NewTop,',',NewWidth,',',NewHeight,
|
|
'');}
|
|
end;
|
|
|
|
// set min size
|
|
if NewWidth<0 then NewWidth:=0;
|
|
if NewHeight<0 then NewHeight:=0;
|
|
|
|
if AAlign<>alNone then begin
|
|
{ Realign
|
|
|
|
Use Align to align a control to the top, bottom, left, or right of a
|
|
form or panel and have it remain there even if the size of the form,
|
|
panel, or component that contains the control changes. When the parent
|
|
is resized, an aligned control also resizes so that it continues to span
|
|
the top, bottom, left, or right edge of the parent.
|
|
}
|
|
NewRight:=NewLeft+NewWidth;
|
|
NewBottom:=NewTop+NewHeight;
|
|
if akLeft in AnchorAlign[AAlign] then begin
|
|
if not (akRight in Control.Anchors) then
|
|
dec(NewRight,NewLeft-ARect.Left);
|
|
NewLeft:=ARect.Left;
|
|
end;
|
|
if akTop in AnchorAlign[AAlign] then begin
|
|
if not (akBottom in Control.Anchors) then
|
|
dec(NewBottom,NewTop-ARect.Top);
|
|
NewTop:=ARect.Top;
|
|
end;
|
|
if akRight in AnchorAlign[AAlign] then begin
|
|
if not (akLeft in Control.Anchors) then
|
|
inc(NewLeft,ARect.Right-NewRight);
|
|
NewRight:=ARect.Right;
|
|
end;
|
|
if akBottom in AnchorAlign[AAlign] then begin
|
|
if not (akTop in Control.Anchors) then
|
|
inc(NewTop,ARect.Bottom-NewBottom);
|
|
NewBottom:=ARect.Bottom;
|
|
end;
|
|
NewWidth:=Max(0,NewRight-NewLeft);
|
|
NewHeight:=Max(0,NewBottom-NewTop);
|
|
end;
|
|
|
|
// set the new bounds
|
|
if (Control.Left <> NewLeft) or (Control.Top <> NewTop)
|
|
or (Control.Width <> NewWidth) or (Control.Height <> NewHeight) then begin
|
|
{$IFDEF CHECK_POSITION}
|
|
if csDesigning in Control.ComponentState then
|
|
with Control do
|
|
writeln('[TWinControl.AlignControls.DoPosition] NEW BOUNDS Control=',Name,':',ClassName,' NewBounds=',NewLeft,',',NewTop,',',NewWidth,',',NewHeight,' Align=',AlignNames[AAlign]);
|
|
{$ENDIF}
|
|
// lock the base bounds, so that the new automatic bounds do not override
|
|
// the user settings
|
|
Control.SetAlignedBounds(NewLeft, NewTop, NewWidth, NewHeight);
|
|
// Sometimes SetBounds change the bounds. For example due to constraints.
|
|
// update the new bounds
|
|
with Control do
|
|
begin
|
|
NewLeft:=Left;
|
|
NewTop:=Top;
|
|
NewWidth:=Width;
|
|
NewHeight:=Height;
|
|
end;
|
|
{$IFDEF CHECK_POSITION}
|
|
if csDesigning in Control.ComponentState then
|
|
with Control do
|
|
writeln('[TWinControl.AlignControls.DoPosition] AFTER SETBOUND Control=',Name,':',ClassName,' Bounds=',Left,',',Top,',',Width,',',Height);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
// adjust the remaining client area
|
|
with ARect do begin
|
|
case AAlign of
|
|
alTop:
|
|
Inc(Top, NewHeight);
|
|
alBottom:
|
|
begin
|
|
Dec(Bottom, NewHeight);
|
|
NewTop := Bottom;
|
|
end;
|
|
alLeft:
|
|
Inc(Left, NewWidth);
|
|
alRight:
|
|
begin
|
|
Dec(Right, NewWidth);
|
|
NewLeft := Right;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF CHECK_POSITION}
|
|
with Control do
|
|
writeln('[TWinControl.AlignControls.DoPosition] END Control=',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height,' Align=',AlignNames[AAlign]);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function InsertBefore(Control1, Control2: TControl;
|
|
AAlign: TAlign): Boolean;
|
|
begin
|
|
Result := False;
|
|
case AAlign of
|
|
alTop: Result := Control1.Top < Control2.Top;
|
|
alBottom: Result := (Control1.Top + Control1.Height)
|
|
>= (Control2.Top + Control2.Height);
|
|
alLeft: Result := Control1.Left < Control2.Left;
|
|
alRight: Result := (Control1.Left + Control1.Width)
|
|
>= (Control2.Left + Control2.Width);
|
|
end;
|
|
end;
|
|
|
|
procedure DoAlign(AAlign: TAlign);
|
|
var
|
|
I, X: Integer;
|
|
Control: TControl;
|
|
begin
|
|
AlignList.Clear;
|
|
if (AControl <> nil)
|
|
and (AControl.Align = AAlign)
|
|
and ((AAlign = alNone)
|
|
or AControl.Visible
|
|
or ((csDesigning in AControl.ComponentState)
|
|
and not (csNoDesignVisible in AControl.ControlStyle)))
|
|
then
|
|
AlignList.Add(AControl);
|
|
|
|
for I := 0 to ControlCount - 1 do
|
|
begin
|
|
Control := Controls[I];
|
|
|
|
if (Control.Align = AAlign)
|
|
and ((AAlign = alNone)
|
|
or (Control.Visible
|
|
or (Control.ControlStyle * [csAcceptsControls, csNoDesignVisible] =
|
|
[csAcceptsControls, csNoDesignVisible]))
|
|
or ((csDesigning in Control.ComponentState)
|
|
and not (csNoDesignVisible in Control.ControlStyle))) then
|
|
begin
|
|
if Control = AControl then Continue;
|
|
|
|
X := 0;
|
|
while (X < AlignList.Count)
|
|
and not InsertBefore(Control, TControl(AlignList[X]), AAlign) do
|
|
Inc(X);
|
|
AlignList.Insert(X, Control);
|
|
end;
|
|
end;
|
|
for I := 0 to AlignList.Count - 1 do
|
|
DoPosition(TControl(AlignList[I]), AAlign);
|
|
end;
|
|
|
|
var
|
|
i: Integer;
|
|
ChildControl: TControl;
|
|
begin
|
|
if wcfAligningControls in FFlags then exit;
|
|
Include(FFlags,wcfAligningControls);
|
|
|
|
// unset all align needed flags
|
|
Exclude(FFlags,wcfReAlignNeeded);
|
|
for i:=ControlCount-1 downto 0 do begin
|
|
ChildControl:=Controls[i];
|
|
Exclude(ChildControl.FControlFlags,cfRequestAlignNeeded);
|
|
end;
|
|
|
|
try
|
|
{if csDesigning in ComponentState then begin
|
|
writeln('[TWinControl.AlignControls] ',Name,':',Classname,' ',Left,',',Top,',',Width,',',Height,' AlignWork=',AlignWork);
|
|
if AControl<>nil then writeln(' AControl=',AControl.Name,':',AControl.ClassName);
|
|
end;}
|
|
if AlignWork then
|
|
begin
|
|
AdjustClientRect(ARect);
|
|
FAdjustClientRectRealized:=ARect;
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
writeln('[TWinControl.AlignControls] ',Name,':',Classname,' ',Left,',',Top,',',Width,',',Height,' ClientRect=',Rect.Left,',',Rect.Top,',',Rect.Right,',',Rect.Bottom);
|
|
{$ENDIF}
|
|
AlignList := TList.Create;
|
|
try
|
|
DoAlign(alTop);
|
|
DoAlign(alBottom);
|
|
DoAlign(alLeft);
|
|
DoAlign(alRight);
|
|
DoAlign(alClient);
|
|
DoAlign(alCustom);
|
|
DoAlign(alNone);
|
|
ControlsAligned;
|
|
finally
|
|
AlignList.Free;
|
|
end;
|
|
end;
|
|
finally
|
|
Exclude(FFlags,wcfAligningControls);
|
|
end;
|
|
|
|
if Showing then AdjustSize;
|
|
end;
|
|
|
|
Procedure TWinControl.DoAutoSize;
|
|
var
|
|
I : Integer;
|
|
NewBounds : TRect;
|
|
NewClientWidth: Integer;
|
|
NewClientHeight: Integer;
|
|
AControl: TControl;
|
|
begin
|
|
If AutoSize and not AutoSizing then
|
|
If csAcceptsControls in ControlStyle then
|
|
If ControlCount > 0 then begin
|
|
AutoSizing := True;
|
|
NewBounds := Rect(High(Integer),High(Integer),0,0);
|
|
For I := 0 to ControlCount - 1 do begin
|
|
AControl:=Controls[I];
|
|
If AControl.Visible then
|
|
With NewBounds do begin
|
|
Left := Min(AControl.Left, Left);
|
|
Top := Min(AControl.Top, Top);
|
|
Right := Max(AControl.Left + AControl.Width, Right);
|
|
Bottom := Max(AControl.Top + AControl.Height, Bottom);
|
|
end;
|
|
end;
|
|
For I := 0 to ControlCount - 1 do begin
|
|
AControl:=Controls[I];
|
|
If AControl <> nil then begin
|
|
If AControl.Visible then begin
|
|
AControl.Left := AControl.Left - NewBounds.Left;
|
|
AControl.Top := AControl.Top - NewBounds.Top;
|
|
end;
|
|
end;
|
|
end;
|
|
NewClientWidth := NewBounds.Right - NewBounds.Left;
|
|
NewClientHeight := NewBounds.Bottom - NewBounds.Top;
|
|
SetClientSize(Point(NewClientWidth, NewClientHeight));
|
|
AutoSizing := False;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl BroadCast }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.BroadCast(var Message);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ControlCount - 1 do
|
|
begin
|
|
Controls[I].WindowProc(TLMessage(Message));
|
|
if TLMessage(Message).Result <> 0 then Exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CanFocus }
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.CanFocus : Boolean;
|
|
var
|
|
Control: TWinControl;
|
|
Form: TCustomForm;
|
|
begin
|
|
Result := False;
|
|
//Verify that every parent is enabled and visible before returning true.
|
|
Form := GetParentForm(Self);
|
|
if Form <> nil then
|
|
begin
|
|
Control := Self;
|
|
while Control <> Form do
|
|
begin
|
|
if not (Control.FVisible and Control.Enabled) then Exit;
|
|
Control := Control.Parent;
|
|
end;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CMDrag }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.CMDrag(var Message: TCMDrag);
|
|
Begin
|
|
with Message, DragRec^ do
|
|
Begin
|
|
case DragMessage of
|
|
dmDragEnter, dmDragLeave,dmDragMove, dmDragDrop :
|
|
if target <> nil then TControl(target).DoDragMsg(Message);
|
|
dmFindTarget:
|
|
begin
|
|
Writeln('dmFindTarget');
|
|
Result := longint(ControlatPos(ScreentoClient(pos),False));
|
|
if Result = 0 then Result := longint(Self);
|
|
end;
|
|
end;//case
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CreateSubClass }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.CreateSubClass(var Params: TCreateParams;
|
|
ControlClassName: PChar);
|
|
(*
|
|
const
|
|
CS_OFF = CS_OWNDC or CS_CLASSDC or CS_PARENTDC or CS_GLOBALCLASS;
|
|
CS_ON = CS_VREDRAW or CS_HREDRAW;
|
|
var
|
|
SaveInstance: THandle;
|
|
begin
|
|
if ControlClassName <> nil then
|
|
with Params do
|
|
begin
|
|
SaveInstance := WindowClass.hInstance;
|
|
if not GetClassInfo(HInstance, ControlClassName, WindowClass) and
|
|
not GetClassInfo(0, ControlClassName, WindowClass) and
|
|
not GetClassInfo(MainInstance, ControlClassName, WindowClass) then
|
|
GetClassInfo(WindowClass.hInstance, ControlClassName, WindowClass);
|
|
WindowClass.hInstance := SaveInstance;
|
|
WindowClass.style := WindowClass.style and not CS_OFF or CS_ON;
|
|
end;
|
|
*)
|
|
begin
|
|
// TODO: implement missing funcs
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DisableAlign }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.DisableAlign;
|
|
begin
|
|
Inc(FAlignLevel);
|
|
End;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl DoAdjustClientRectChange
|
|
|
|
Asks the interface if clientrect has changed since last AlignControl
|
|
and calls AlignControl(nil) on change.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.DoAdjustClientRectChange;
|
|
var r: TRect;
|
|
begin
|
|
if (csLoading in ComponentState) then exit;
|
|
r:=GetClientRect;
|
|
AdjustClientRect(r);
|
|
//writeln(' TWinControl.DoAdjustClientRectChange ',Name,':',ClassName,' ',r.Right,',',r.Bottom);
|
|
if (r.Left<>FAdjustClientRectRealized.Left)
|
|
or (r.Top<>FAdjustClientRectRealized.Top)
|
|
or (r.Right<>FAdjustClientRectRealized.Right)
|
|
or (r.Bottom<>FAdjustClientRectRealized.Bottom)
|
|
then begin
|
|
// client rect changed since last AlignControl
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
writeln('UUU TWinControl.DoAdjustClientRectChange ClientRect changed ',Name,':',ClassName,
|
|
' Old=',FAdjustClientRectRealized.Right,'x',FAdjustClientRectRealized.Bottom,
|
|
' New=',r.RIght,'x',r.Bottom);
|
|
{$ENDIF}
|
|
ReAlign;
|
|
Resize;
|
|
end;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl DoConstraintsChange
|
|
Params: Sender : TObject
|
|
|
|
Call inherited, then send the constraints to the interface
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.DoConstraintsChange(Sender : TObject);
|
|
begin
|
|
inherited DoConstraintsChange(Sender);
|
|
SendMsgToInterface(LM_SETGEOMETRY, Self, nil);
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl InvalidateClientRectCache
|
|
|
|
The clientrect is cached. Call this procedure to invalidate the cache, so that
|
|
next time the clientrect is fetched from the interface.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.InvalidateClientRectCache;
|
|
begin
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
writeln('[TWinControl.InvalidateClientRectCache] ',Name,':',ClassName);
|
|
{$ENDIF}
|
|
Include(FFlags,wcfClientRectNeedsUpdate);
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl DoSetBounds
|
|
Params: ALeft, ATop, AWidth, AHeight : integer
|
|
|
|
Anticipate the new clientwidth/height and call inherited
|
|
|
|
Normally the clientwidth/clientheight is adjusted automatically by the
|
|
interface. But it is up to interface when this will be done. The gtk for
|
|
example just puts resize requests into a queue. The LCL resizes the childs
|
|
just after this procedure due to the clientrect. On complex forms with lots
|
|
of nested controls, this results in thousands of resizes.
|
|
Changing the clientrect in the LCL to the most probable size reduce
|
|
unneccessary resizes.
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.DoSetBounds(ALeft, ATop, AWidth, AHeight : integer);
|
|
begin
|
|
if wcfClientRectNeedsUpdate in FFlags then begin
|
|
GetClientRect;
|
|
end;
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
write('[TWinControl.DoSetBounds] ',Name,':',ClassName,' OldClient=',FClientWidth,',',FClientHeight,
|
|
' OldHeight=',FHeight,' NewHeight=',AHeight);
|
|
{$ENDIF}
|
|
inc(FClientWidth,AWidth-FWidth);
|
|
if (FClientWidth<0) then FClientWidth:=0;
|
|
inc(FClientHeight,AHeight-FHeight);
|
|
if (FClientHeight<0) then FClientHeight:=0;
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
writeln(' NewClient=',FClientWidth,',',FClientHeight);
|
|
{$ENDIF}
|
|
|
|
inherited DoSetBounds(ALeft,ATop,AWidth,AHeight);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl EnableAlign }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.EnableAlign;
|
|
begin
|
|
Dec(FAlignLevel);
|
|
if FAlignLevel = 0 then begin
|
|
if csAlignmentNeeded in ControlState then ReAlign;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl.CanTab
|
|
}
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.CanTab: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl GetChildren }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.GetChildren(Proc: TGetChildProc; Root : TComponent);
|
|
var
|
|
I : Integer;
|
|
Control : TControl;
|
|
Begin
|
|
for I := 0 to ControlCount-1 do
|
|
Begin
|
|
Control := Controls[i];
|
|
if Control.Owner = Root then Proc(Control);
|
|
end;
|
|
End;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl GetClientOrigin
|
|
Result: TPoint
|
|
|
|
returns the screen coordinate of the topleft coordinate 0,0 of the client area
|
|
Note that this value is the position as stored in the interface and is not
|
|
always consistent with the LCL. When a control is moved, the LCL sets the
|
|
bounds to the wanted position and sends a move message to the interface. It is
|
|
up to the interface to handle moves instantly or queued.
|
|
-------------------------------------------------------------------------------}
|
|
Function TWinControl.GetClientOrigin: TPoint;
|
|
var
|
|
AControl: TWinControl;
|
|
Begin
|
|
Result.X := 0;
|
|
Result.Y := 0;
|
|
//writeln('[TWinControl.GetClientOrigin] ',Name,':',ClassName,' ',Handle);
|
|
if HandleAllocated then begin
|
|
// get the interface idea where the client area is on the screen
|
|
LCLLinux.ClientToScreen(Handle,Result);
|
|
// adjust the result by all bounds, that are not yet sent to the interface
|
|
AControl:=Self;
|
|
repeat
|
|
inc(Result.X,AControl.Left-AControl.FBoundsRealized.Left);
|
|
inc(Result.Y,AControl.Top-AControl.FBoundsRealized.Top);
|
|
AControl:=AControl.Parent;
|
|
until AControl=nil;
|
|
end else
|
|
Result:=inherited GetClientOrigin;
|
|
Assert(False, Format('Trace:[TWinControl.GetClientOrigin] %s --> (%d, %d)', [Classname, Result.X, Result.Y]));
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
TWinControl GetClientRect
|
|
Result: TRect
|
|
|
|
returns the client area. Starting at 0,0.
|
|
-------------------------------------------------------------------------------}
|
|
function TWinControl.GetClientRect: TRect;
|
|
|
|
procedure StoreClientRect(NewClientRect: TRect);
|
|
begin
|
|
if wcfClientRectNeedsUpdate in FFlags then begin
|
|
FClientWidth:=NewClientRect.Right;
|
|
FClientHeight:=NewClientRect.Bottom;
|
|
{$IFDEF VerboseClientRectBugFix}
|
|
writeln('StoreClientRect ',Name,':',ClassName,' ',FClientWidth,',',FClientHeight);
|
|
{$ENDIF}
|
|
Exclude(FFlags,wcfClientRectNeedsUpdate);
|
|
end;
|
|
end;
|
|
|
|
var //r: TRect;
|
|
InterfaceWidth, InterfaceHeight: integer;
|
|
begin
|
|
if not HandleAllocated then begin
|
|
Result:=inherited GetClientRect;
|
|
StoreClientRect(Result);
|
|
end else if wcfClientRectNeedsUpdate in FFlags then begin
|
|
// update clientrect from interface
|
|
LCLLinux.GetClientRect(Handle, Result);
|
|
// the LCL is not always in sync with the interface
|
|
// -> adjust client rect based on LCL bounds
|
|
// for example: if the Width in LCL differ from the Width of the Interface
|
|
// object, then adjust the clientwidth accordingly
|
|
LCLLinux.GetWindowSize(Handle, InterfaceWidth, InterfaceHeight);
|
|
Result.Right:=Width-(InterfaceWidth-Result.Right);
|
|
Result.Bottom:=Height-(InterfaceHeight-Result.Bottom);
|
|
StoreClientRect(Result);
|
|
|
|
{r:=inherited GetClientRect;
|
|
if (r.Left<>Result.Left)
|
|
or (r.Top<>Result.Top)
|
|
or (r.Right<>Result.Right)
|
|
or (r.Bottom<>Result.Bottom) then begin
|
|
//writeln(' TWinControl.GetClientRect ',Name,':',ClassName,
|
|
// ' Old=',r.Left,',',r.Top,',',r.Right,',',r.Bottom,
|
|
// ' New=',Result.Left,',',Result.Top,',',Result.Right,',',Result.Bottom
|
|
// );
|
|
end;}
|
|
|
|
end else begin
|
|
Result:=Rect(0,0,FClientWidth,FClientHeight);
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
function TWinControl.GetChildsRect(Scrolled: boolean): TRect;
|
|
|
|
Returns the Client rectangle relative to the controls left, top.
|
|
If Scrolled is true, the rectangle is moved by the current scrolling values
|
|
(for an example see TScrollingWincontrol).
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.GetChildsRect(Scrolled: boolean): TRect;
|
|
var
|
|
ScrolledOffset: TPoint;
|
|
begin
|
|
if HandleAllocated then begin
|
|
LCLLinux.GetClientBounds(Handle,Result);
|
|
if Scrolled then begin
|
|
ScrolledOffset:=GetClientScrollOffset;
|
|
inc(Result.Left,ScrolledOffset.X);
|
|
inc(Result.Top,ScrolledOffset.Y);
|
|
inc(Result.Right,ScrolledOffset.X);
|
|
inc(Result.Bottom,ScrolledOffset.Y);
|
|
end;
|
|
end else
|
|
Result:=inherited GetChildsRect(Scrolled);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl ReCreateWnd }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.ReCreateWnd;
|
|
Begin
|
|
//send a message to inform the interface that we need to destroy and recreate this control
|
|
if HandleAllocated then
|
|
CNSendMessage(LM_RECREATEWND,Self,Nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl SetBorderWidth }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.SetBorderWidth(value : TBorderWidth);
|
|
Begin
|
|
//TODO: SETBORDERWIDTH - Not sure if anything more is needed here
|
|
FBorderWidth := Value;
|
|
end;
|
|
|
|
Procedure TWinControl.SetZOrder(Topmost: Boolean);
|
|
const
|
|
WindowPos: array[Boolean] of Word = (HWND_BOTTOM, HWND_TOP);
|
|
var
|
|
i: integer;
|
|
begin
|
|
if FParent <> nil then
|
|
begin
|
|
if TopMost then
|
|
i := FParent.FWinControls.Count - 1
|
|
else
|
|
i := 0;
|
|
if FParent.FControls <> nil then inc(i, FParent.FControls.Count);
|
|
SetZOrderPosition(i);
|
|
end
|
|
else if FHandle <> 0 then begin
|
|
SetWindowPos(FHandle, WindowPos[TopMost], 0, 0, 0, 0,
|
|
SWP_NOMOVE + SWP_NOSIZE);
|
|
end;
|
|
end;
|
|
|
|
procedure TWinControl.SendMoveSizeMessages(SizeChanged, PosChanged: boolean);
|
|
var
|
|
SizeMsg : TLMSize;
|
|
MoveMsg : TLMMove;
|
|
begin
|
|
if (not HandleAllocated)
|
|
or ((not SizeChanged) and (not PosChanged)) then exit;
|
|
|
|
{ TODO : Replace this with LCL functions eventually.
|
|
Right now we have to call these messages as some
|
|
descendents incorrectly depend on it, so force it
|
|
down their throat }
|
|
|
|
Perform(LM_WindowposChanged, 0, 0);
|
|
|
|
if SizeChanged then begin
|
|
with SizeMsg do begin
|
|
Msg:= LM_SIZE;
|
|
SizeType:= 6; // force realign
|
|
Width:= FWidth;
|
|
Height:= FHeight;
|
|
{$IFDEF CHECK_POSITION}
|
|
writeln(' [TControl.SendMoveSizeMessages] ',Name,':',ClassName,' SizeMsg Width=',Width,' Height=',Height);
|
|
{$ENDIF}
|
|
end;
|
|
WindowProc(TLMessage(SizeMsg));
|
|
end;
|
|
|
|
if PosChanged then begin
|
|
with MoveMsg do begin
|
|
Msg:= LM_MOVE;
|
|
MoveType:= 1;
|
|
XPos:= FLeft;
|
|
YPos:= FTop;
|
|
{$IFDEF CHECK_POSITION}
|
|
writeln(' [TControl.SendMoveSizeMessages] ',Name,':',ClassName,' MoveMsg XPos=',XPos,' YPos=',YPos);
|
|
{$ENDIF}
|
|
end;
|
|
WindowProc(TLMessage(MoveMsg));
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl UpdateShowing }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.UpdateShowing;
|
|
var
|
|
bShow: Boolean;
|
|
n: Integer;
|
|
ok: boolean;
|
|
begin
|
|
bShow := HandleObjectShouldBeVisible;
|
|
|
|
if bShow then begin
|
|
if not HandleAllocated then CreateHandle;
|
|
if FWinControls <> nil
|
|
then begin
|
|
for n := 0 to FWinControls.Count - 1 do
|
|
TWinControl(FWinControls[n]).UpdateShowing;
|
|
end;
|
|
end;
|
|
|
|
if HandleAllocated then begin
|
|
if FShowing <> bShow
|
|
then begin
|
|
FShowing := bShow;
|
|
ok:=false;
|
|
try
|
|
Perform(CM_SHOWINGCHANGED, 0, 0);
|
|
ok:=true;
|
|
finally
|
|
if not ok then
|
|
FShowing := not bShow;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
procedure TWinControl.SetZOrderPosition(Position: Integer);
|
|
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.SetZOrderPosition(Position: Integer);
|
|
var
|
|
I, Count: Integer;
|
|
Pos: HWND;
|
|
begin
|
|
if FParent <> nil then
|
|
begin
|
|
if FParent.FControls <> nil then
|
|
Dec(Position, FParent.FControls.Count);
|
|
I := FParent.FWinControls.IndexOf(Self);
|
|
if I >= 0 then
|
|
begin
|
|
Count := FParent.FWinControls.Count;
|
|
if Position < 0 then Position := 0;
|
|
if Position >= Count then Position := Count - 1;
|
|
if Position <> I then
|
|
begin
|
|
FParent.FWinControls.Delete(I);
|
|
FParent.FWinControls.Insert(Position, Self);
|
|
end;
|
|
end;
|
|
if HandleAllocated then
|
|
begin
|
|
if Position = 0 then Pos := HWND_BOTTOM
|
|
else if Position = FParent.FWinControls.Count - 1 then Pos := HWND_TOP
|
|
else if Position > I then
|
|
Pos := TWinControl(FParent.FWinControls[Position + 1]).Handle
|
|
else if Position < I then
|
|
Pos := TWinControl(FParent.FWinControls[Position]).Handle
|
|
else Exit;
|
|
SetWindowPos(Handle, Pos, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Focused }
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.Focused : Boolean;
|
|
Begin
|
|
Result := CanTab and ((FHandle <> 0) and (GetFocus = FHandle));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl FindChildControl }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.FindChildControl(ControlName: string): TControl;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
if FWinControls <> nil then
|
|
for I := 0 to FWinControls.Count - 1 do
|
|
if CompareText(TWinControl(FWinControls[I]).Name, ControlName) = 0 then
|
|
begin
|
|
Result := TControl(FWinControls[I]);
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl FindNextControl }
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.FindNextControl(CurrentControl: TControl;
|
|
GoForward, CheckTabStop, CheckParent, OnlyWinControls: Boolean) : TControl;
|
|
var
|
|
List : TList;
|
|
Next : TControl;
|
|
I, J : Longint;
|
|
begin
|
|
Try
|
|
Result := nil;
|
|
List := TList.Create;
|
|
GetTabOrderList(List);
|
|
If List.Count > 0 then begin
|
|
J := List.IndexOf(CurrentControl);
|
|
if J<0 then exit;
|
|
I := J;
|
|
Repeat
|
|
If GoForward then begin
|
|
Inc(I);
|
|
if I>=List.Count then
|
|
I:=0;
|
|
end else begin
|
|
Dec(I);
|
|
if I<0 then
|
|
I:=List.Count-1;
|
|
end;
|
|
if I=J then exit;
|
|
|
|
Next := TControl(List[I]);
|
|
If (((Not CheckTabStop) or Next.TabStop)
|
|
and ((not CheckParent) or (Next.Parent = Self)))
|
|
and (Next.Enabled and Next.Visible)
|
|
and ((not OnlyWinControls) or (Next is TWinControl)) then
|
|
Result := Next;
|
|
until (Result <> nil);
|
|
end;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
function TWinControl.FindNextControl(CurrentControl: TWinControl; GoForward,
|
|
CheckTabStop, CheckParent: Boolean): TWinControl;
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.FindNextControl(CurrentControl: TWinControl; GoForward,
|
|
CheckTabStop, CheckParent: Boolean): TWinControl;
|
|
begin
|
|
Result:=TWinControl(FindNextControl(CurrentControl,
|
|
GoForward,CheckTabStop,CheckParent,true));
|
|
end;
|
|
|
|
procedure TWinControl.FixupTabList;
|
|
var
|
|
Count, I, J: Integer;
|
|
List: TList;
|
|
Control: TWinControl;
|
|
begin
|
|
if FWinControls <> nil then
|
|
begin
|
|
List := TList.Create;
|
|
try
|
|
Count := FWinControls.Count;
|
|
List.Count := Count;
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Control := TWinControl(FWinControls[I]);
|
|
J := Control.FTabOrder;
|
|
if (J >= 0) and (J < Count) then List[J] := Control;
|
|
end;
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
Control := TWinControl(List[I]);
|
|
if Control <> nil then Control.UpdateTabOrder(I);
|
|
end;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl GetTabOrderList
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.GetTabOrderList(List : TList);
|
|
var
|
|
I : Integer;
|
|
Control : TControl;
|
|
begin
|
|
If FTabList <> nil then
|
|
For I := 0 to FTabList.Count - 1 do begin
|
|
Control := TControl(FTabList[I]);
|
|
If Control.CanTab and Control.TabStop then
|
|
List.Add(Control);
|
|
If Control is TWinControl then
|
|
TWinControl(Control).GetTabOrderList(List);
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl IsControlMouseMsg }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.IsControlMouseMsg(var TheMessage: TLMMouse) : Boolean;
|
|
var
|
|
Control : TControl;
|
|
P : TPoint;
|
|
ClientBounds: TRect;
|
|
begin
|
|
if GetCapture = Handle
|
|
then begin
|
|
Control := nil;
|
|
if (CaptureControl <> nil)
|
|
and (CaptureControl.Parent = Self)
|
|
then Control := CaptureControl;
|
|
end
|
|
else begin
|
|
Control := ControlAtPos(SmallPointToPoint(TheMessage.Pos),False,True,False);
|
|
end;
|
|
|
|
Result := False;
|
|
if Control <> nil then
|
|
begin
|
|
// map mouse coordinates to control
|
|
P.X := TheMessage.XPos - Control.Left;
|
|
P.Y := TheMessage.YPos - Control.Top;
|
|
if (Control is TWinControl) and TWinControl(Control).HandleAllocated then
|
|
begin
|
|
// map coordinates to client area of control
|
|
LCLLinux.GetClientBounds(TWinControl(Control).Handle,ClientBounds);
|
|
dec(P.X,ClientBounds.Left);
|
|
dec(P.Y,ClientBounds.Top);
|
|
{$IFDEF VerboseMouseBugfix}
|
|
writeln('TWinControl.IsControlMouseMsg ',Name,' -> ',Control.Name,
|
|
' MsgPos=',TheMessage.Pos.X,',',TheMessage.Pos.Y,
|
|
' Control=',Control.Left,',',Control.Top,
|
|
' ClientBounds=',ClientBounds.Left,',',ClientBounds.Top,
|
|
' Scrolled=',GetClientScrollOffset.X,',',GetClientScrollOffset.Y,
|
|
' P=',P.X,',',P.Y
|
|
);
|
|
{$ENDIF}
|
|
end;
|
|
Control.Perform(TheMessage.Msg, TheMessage.Keys,
|
|
LongInt(PointtoSmallPoint(P)));
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TWinControl.SetColor(Value: TColor);
|
|
begin
|
|
if Value=Color then exit;
|
|
inherited SetColor(Value);
|
|
if HandleAllocated and (not (csLoading in ComponentState)) then
|
|
CNSendMessage(LM_SETCOLOR, Self, nil)
|
|
else
|
|
Include(FFlags,wcfColorChanged);
|
|
end;
|
|
|
|
procedure TWinControl.PaintHandler(var TheMessage: TLMPaint);
|
|
|
|
function ControlMustBeClipped(AControl: TControl): boolean;
|
|
begin
|
|
with AControl do
|
|
Result:=(Visible or (csDesigning in ComponentState)
|
|
and not (csNoDesignVisible in ControlStyle))
|
|
and (csOpaque in ControlStyle);
|
|
end;
|
|
|
|
var
|
|
I, Clip, SaveIndex: Integer;
|
|
DC: HDC;
|
|
PS: TPaintStruct; //defined in LCLLinux.pp
|
|
ControlsNeedsClipping: boolean;
|
|
begin
|
|
//writeln('[TWinControl.PaintHandler] ',Name,':',ClassName,' DC=',HexStr(Message.DC,8));
|
|
Assert(False, Format('Trace:> [TWinControl.PaintHandler] %s --> Msg.DC: 0x%x', [ClassName, TheMessage.DC]));
|
|
DC := TheMessage.DC;
|
|
if DC = 0 then DC := BeginPaint(Handle, PS);
|
|
try
|
|
// check if controls needs clipping
|
|
ControlsNeedsClipping:=false;
|
|
if FControls<>nil then
|
|
for I := 0 to FControls.Count - 1 do
|
|
if ControlMustBeClipped(TControl(FControls[I])) then begin
|
|
ControlsNeedsClipping:=true;
|
|
break;
|
|
end;
|
|
// exclude controls and send new paint message
|
|
if not ControlsNeedsClipping then
|
|
PaintWindow(DC)
|
|
else
|
|
begin
|
|
SaveIndex := SaveDC(DC);
|
|
Clip := SimpleRegion;
|
|
for I := 0 to FControls.Count - 1 do
|
|
if ControlMustBeClipped(TControl(FControls[I])) then
|
|
with TControl(FControls[I]) do begin
|
|
Clip := ExcludeClipRect(DC, Left, Top, Left + Width, Top + Height);
|
|
if Clip = NullRegion then Break;
|
|
end;
|
|
if Clip <> NullRegion then
|
|
PaintWindow(DC);
|
|
RestoreDC(DC, SaveIndex);
|
|
end;
|
|
// paint controls
|
|
PaintControls(DC, nil);
|
|
finally
|
|
if TheMessage.DC = 0 then EndPaint(Handle, PS);
|
|
end;
|
|
Assert(False, Format('Trace:< [TWinControl.PaintHandler] %s', [ClassName]));
|
|
//writeln('[TWinControl.PaintHandler] END ',Name,':',ClassName,' DC=',HexStr(Message.DC,8));
|
|
end;
|
|
|
|
procedure TWinControl.PaintControls(DC: HDC; First: TControl);
|
|
var
|
|
I, Count, SaveIndex: Integer;
|
|
// FrameBrush: HBRUSH;
|
|
TempControl : TCOntrol;
|
|
begin
|
|
//writeln('[TWinControl.PaintControls] ',Name,':',ClassName,' DC=',HexStr(DC,8));
|
|
// Controls that are not TWinControl, have no handle of their own, and so
|
|
// they are repainted as part of the parent:
|
|
if FControls <> nil then
|
|
begin
|
|
I := 0;
|
|
if First <> nil then
|
|
begin
|
|
I := FControls.IndexOf(First);
|
|
if I < 0 then I := 0;
|
|
end;
|
|
Count := FControls.Count;
|
|
while I < Count do
|
|
begin
|
|
TempControl := TControl(FControls.Items[I]);
|
|
with (TempControl) do
|
|
if (Visible or (csDesigning in ComponentState)
|
|
and not (csNoDesignVisible in ControlStyle))
|
|
and RectVisible(DC, Rect(Left, Top, Left + Width, Top + Height)) then
|
|
begin
|
|
if csPaintCopy in Self.ControlState then
|
|
Include(FControlState, csPaintCopy);
|
|
SaveIndex := SaveDC(DC);
|
|
MoveWindowOrg(DC, Left, Top);
|
|
IntersectClipRect(DC, 0, 0, Width, Height);
|
|
Perform(LM_PAINT, DC, 0);
|
|
RestoreDC(DC, SaveIndex);
|
|
Exclude(FControlState, csPaintCopy);
|
|
end;
|
|
Inc(I);
|
|
end;
|
|
end;
|
|
// draw specials for the wincontrols:
|
|
if FWinControls <> nil then
|
|
for I := 0 to FWinControls.Count - 1 do
|
|
with TWinControl(FWinControls.Items[I]) do
|
|
if FCtl3D and (csFramed in ControlStyle)
|
|
and (Visible or (csDesigning in ComponentState)
|
|
and not (csNoDesignVisible in ControlStyle)) then
|
|
begin
|
|
//TODO: CreateSolidBrush and FrameRect
|
|
{FrameBrush := CreateSolidBrush(ColorToRGB(clBtnShadow));
|
|
FrameRect(DC, Rect(Left - 1, Top - 1, Left + Width, Top + Height),
|
|
FrameBrush);
|
|
DeleteObject(FrameBrush);
|
|
FrameBrush := CreateSolidBrush(ColorToRGB(clBtnHighlight));
|
|
FrameRect(DC, Rect(Left, Top, Left + Width + 1, Top + Height + 1),
|
|
FrameBrush);
|
|
DeleteObject(FrameBrush);
|
|
}
|
|
end;
|
|
//writeln('[TWinControl.PaintControls] END ',Name,':',ClassName,' DC=',HexStr(DC,8));
|
|
end;
|
|
|
|
procedure TWinControl.PaintWindow(DC: HDC);
|
|
var
|
|
Message: TLMessage;
|
|
begin
|
|
//writeln('[TWinControl.PaintWindow] ',Name,':',Classname,' DC=',HexStr(DC,8));
|
|
Message.Msg := LM_PAINT;
|
|
Message.WParam := DC;
|
|
Message.LParam := 0;
|
|
Message.Result := 0;
|
|
DefaultHandler(Message);
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl ControlAtPos
|
|
Params: const Pos : TPoint
|
|
AllowDisabled: Boolean
|
|
Results: TControl
|
|
|
|
Searches a child (not grand child) control, which client area contains Pos.
|
|
Pos is relative to the ClientOrigin.
|
|
------------------------------------------------------------------------------}
|
|
Function TWinControl.ControlAtPos(const Pos : TPoint;
|
|
AllowDisabled : Boolean): TControl;
|
|
Begin
|
|
Result := ControlAtPos(Pos,AllowDisabled,false,true);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl ControlAtPos
|
|
Params: const Pos : TPoint
|
|
AllowDisabled, AllowWinControls: Boolean
|
|
Results: TControl
|
|
|
|
Searches a child (not grand child) control, which client area contains Pos.
|
|
Pos is relative to the ClientOrigin.
|
|
------------------------------------------------------------------------------}
|
|
Function TWinControl.ControlAtPos(const Pos : TPoint;
|
|
AllowDisabled, AllowWinControls: Boolean): TControl;
|
|
begin
|
|
Result := ControlAtPos(Pos,AllowDisabled,AllowWinControls,true);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl ControlAtPos
|
|
Params: const Pos : TPoint
|
|
AllowDisabled, AllowWinControls: Boolean
|
|
Results: TControl
|
|
|
|
Searches a child (not grand child) control, which contains Pos.
|
|
Pos is relative to the ClientOrigin.
|
|
If AllowDisabled is true it will also search in disabled controls.
|
|
If AllowWinControls is true it will also search in the child wincontrols.
|
|
If OnlyClientAreas is true then the only the client areas are compared.
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.ControlAtPos(const Pos: TPoint; AllowDisabled,
|
|
AllowWinControls, OnlyClientAreas: Boolean): TControl;
|
|
var
|
|
I: Integer;
|
|
P: TPoint;
|
|
LControl: TControl;
|
|
ClientBounds: TRect;
|
|
|
|
function GetControlAtPos(AControl: TControl): Boolean;
|
|
var
|
|
ControlPos: TPoint;
|
|
ControlClientBounds: TRect;
|
|
begin
|
|
with AControl do
|
|
begin
|
|
// MG: Delphi checks for PtInRect(ClientRect,P). But the client area is
|
|
// not always at 0,0, so I guess this is a bug in the VCL.
|
|
|
|
ControlPos:=Point(P.X-Left,P.Y-Top);
|
|
Result:=(ControlPos.X>=0) and (ControlPos.Y>=0)
|
|
and (ControlPos.X<Width) and (ControlPos.Y<Height);
|
|
if Result and OnlyClientAreas then begin
|
|
ControlClientBounds:=GetChildsRect(false);
|
|
Result:=PtInRect(ControlClientBounds,ControlPos);
|
|
end;
|
|
|
|
Result:= Result
|
|
and (
|
|
(
|
|
(csDesigning in ComponentState)
|
|
and
|
|
(Visible or not (csNoDesignVisible in ControlStyle))
|
|
)
|
|
or
|
|
(
|
|
(Visible)
|
|
and
|
|
(Enabled or AllowDisabled)
|
|
and
|
|
(Perform(CM_HITTEST, 0,
|
|
LongInt(PointtoSmallPoint(ControlPos))) <> 0)
|
|
)
|
|
);
|
|
{$IFDEF VerboseMouseBugfix}
|
|
{writeln('GetControlAtPos ',Name,
|
|
' Pos=',Pos.X,',',Pos.Y,
|
|
' P=',P.X,',',P.Y,
|
|
' ClientBounds=',ClientBounds.Left,',',ClientBounds.Top,',',ClientBounds.Right,',',ClientBounds.Bottom,
|
|
' OnlyCl=',OnlyClientAreas,
|
|
' Result=',Result);}
|
|
{$ENDIF}
|
|
if Result then
|
|
LControl := AControl;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
ScrolledOffset: TPoint;
|
|
begin
|
|
// check if Pos in visible client area
|
|
ClientBounds:=GetClientRect;
|
|
if not PtInRect(ClientBounds,Pos) then begin
|
|
Result:=nil;
|
|
exit;
|
|
end;
|
|
|
|
// map Pos to logical client area
|
|
ScrolledOffset:=GetClientScrollOffset;
|
|
P:=Point(Pos.X+ScrolledOffset.X,Pos.Y+ScrolledOffset.Y);
|
|
|
|
LControl := nil;
|
|
// check wincontrols
|
|
if AllowWinControls and (FWinControls <> nil) then
|
|
for I := FWinControls.Count - 1 downto 0 do
|
|
if GetControlAtPos(TControl(FWinControls[I])) then
|
|
Break;
|
|
// check controls
|
|
if (FControls <> nil) and (LControl = nil) then
|
|
for I := FControls.Count - 1 downto 0 do
|
|
if GetControlAtPos(TControl(FControls[I])) then
|
|
Break;
|
|
Result := LControl;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
function TWinControl.GetControlIndex(AControl: TControl): integer;
|
|
|
|
|
|
-------------------------------------------------------------------------------}
|
|
function TWinControl.GetControlIndex(AControl: TControl): integer;
|
|
begin
|
|
if FControls<>nil then
|
|
Result:=FControls.IndexOf(AControl)
|
|
else
|
|
Result:=-1;
|
|
if (Result<0) and (FWinControls<>nil) then begin
|
|
Result:=FWinControls.IndexOf(AControl);
|
|
if (Result>=0) and (FControls<>nil) then
|
|
inc(Result,FControls.Count);
|
|
end;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
function TWinControl.GetControlIndex(AControl: TControl): integer;
|
|
|
|
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWinControl.SetControlIndex(AControl: TControl; NewIndex: integer);
|
|
begin
|
|
if AControl<>nil then
|
|
AControl.SetZOrderPosition(NewIndex);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DestroyHandle }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.DestroyHandle;
|
|
var i : integer;
|
|
begin
|
|
if not HandleAllocated then begin
|
|
writeln('Warning: TWinControl.DestroyHandle ',Name,':',ClassName,' Handle not Allocated');
|
|
// create an gdb catchable exception:
|
|
// if (length(Name) div (length(Name) div 10000))=0 then ;
|
|
end;
|
|
|
|
{ Destroy all children handles, too }
|
|
{ If we don't do that, GTK does this without notification for us and we crash }
|
|
{ TODO : We can enable HandleAllocated condition only when all controls, especially
|
|
TNotebook / TPage set their Handles correctly, i.e. mirror the GTK behavior }
|
|
// if HandleAllocated then begin
|
|
if FWinControls <> nil then begin
|
|
for i:= 0 to FWinControls.Count - 1 do begin
|
|
//writeln(' i=',i);
|
|
//writeln(' ',TWinControl(FWinControls[i]).Name,':',TWinControl(FWinControls[i]).ClassName);
|
|
if TWinControl(FWinControls[i]).HandleAllocated then
|
|
TWinControl(FWinControls[i]).DestroyHandle;
|
|
end;
|
|
end;
|
|
DestroyWnd;
|
|
// end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl WndPRoc
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.WndProc(Var Message: TLMessage);
|
|
Var
|
|
Form: TCustomForm;
|
|
// KeyState: TKeyboardState;
|
|
// WheelMsg : TCMMouseWheel;
|
|
Begin
|
|
// Assert(False, Format('Trace:[TWinControl.WndPRoc] %s(%s) --> Message = %d', [ClassName, Name, Message.Msg]));
|
|
case Message.Msg of
|
|
|
|
LM_SETFOCUS:
|
|
begin
|
|
Assert(False, Format('Trace:[TWinControl.WndPRoc] %s --> LM_SETFOCUS', [ClassName]));
|
|
Form := GetParentForm(Self);
|
|
{$IFDEF VerboseFocus}
|
|
writeln('TWinControl.WndProc A ',Name,':',ClassName);
|
|
{$ENDIF}
|
|
if (Form <> nil) and not Form.SetFocusedControl(Self) then Exit;
|
|
Message.Result:=0;
|
|
end;
|
|
|
|
LM_KILLFOCUS:
|
|
begin
|
|
Assert(False, Format('Trace:[TWinControl.WndPRoc] %s --> _KILLFOCUS', [ClassName]));
|
|
if csFocusing in ControlState then Exit;
|
|
Message.Result:=0;
|
|
end;
|
|
|
|
LM_NCHITTEST:
|
|
begin
|
|
inherited WndPRoc(Message);
|
|
if (Message.Result = HTTRANSPARENT)
|
|
and (ControlAtPos(ScreenToClient(SmallPointToPoint(TLMNCHitTest(Message).Pos)), False) <> nil)
|
|
then Message.Result := HTCLIENT;
|
|
Exit;
|
|
end;
|
|
|
|
LM_MOUSEFIRST..LM_MOUSELAST,LM_MOUSEFIRST2..LM_MOUSELAST2:
|
|
begin
|
|
{$IFDEF VerboseMouseBugfix}
|
|
writeln('TWinControl.WndPRoc A ',Name,':',ClassName);
|
|
{$ENDIF}
|
|
if IsControlMouseMSG(TLMMouse(Message)) then
|
|
Exit;
|
|
{$IFDEF VerboseMouseBugfix}
|
|
writeln('TWinControl.WndPRoc B ',Name,':',ClassName);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
LM_KEYFIRST..LM_KEYLAST:
|
|
if Dragging then Exit;
|
|
|
|
LM_CANCELMODE:
|
|
if (GetCapture = Handle)
|
|
and (CaptureControl <> nil)
|
|
and (CaptureControl.Parent = Self)
|
|
then CaptureControl.Perform(LM_CANCELMODE,0,0);
|
|
|
|
else
|
|
//TODO:Implement TMOUSE
|
|
{ with Mouse do
|
|
if WheelPresent and (RegWheelMessage <> 0) and (Message.Msg = RegWheelMessage) then
|
|
Begin
|
|
GetKeyboardState(KeyState);
|
|
with WheelMsg do
|
|
Begin
|
|
Msg := Message.Msg;
|
|
ShiftState := KeyboardStateToShiftState(KeyState);
|
|
WheelData :=Message.WParam;
|
|
Pos := TSmallPoint(Message.LPaream);
|
|
end;
|
|
MouseWheelHandler(TMessage(WheelMsg));
|
|
Exit;
|
|
end;
|
|
}
|
|
end;
|
|
|
|
inherited WndProc(Message);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.MainWndProc
|
|
Params: Message:
|
|
Returns: Nothing
|
|
|
|
Description of the procedure for the class.
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.MainWndProc(Var Message : TLMessage);
|
|
Begin
|
|
Assert(False, Format('Trace:[TWinControl.MainWndPRoc] %s(%s) --> Message = %d', [ClassName, Name, Message.Msg]));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl SetFocus }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.SetFocus;
|
|
var
|
|
Form : TCustomForm;
|
|
begin
|
|
{$IFDEF VerboseFocus}
|
|
writeln('[TWinControl.SetFocus] ',Name,':',ClassName,' Visible=',Visible,' HandleAllocated=',HandleAllocated);
|
|
{$ENDIF}
|
|
Form := GetParentForm(Self);
|
|
if Form <> nil then
|
|
Form.FocusControl(Self)
|
|
else if Visible and HandleAllocated then
|
|
LCLLinux.SetFocus(Handle);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl SetParentCtl3D }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.SetParentCtl3D(value : Boolean);
|
|
Begin
|
|
if FParentCtl3D <> Value then
|
|
Begin
|
|
FParentCtl3D := Value;
|
|
if FParent <> nil then
|
|
Begin
|
|
//Sendmessage to do something?
|
|
End;
|
|
end;
|
|
end;
|
|
|
|
procedure TWinControl.UpdateTabOrder(NewTabValue: TTabOrder);
|
|
var
|
|
CurIndex, Count: Integer;
|
|
begin
|
|
if FParent=nil then exit;
|
|
CurIndex := GetTabOrder;
|
|
if CurIndex >= 0 then
|
|
begin
|
|
if NewTabValue < 0 then NewTabValue := 0;
|
|
Count := FParent.FTabList.Count;
|
|
if NewTabValue >= Count then NewTabValue := Count - 1;
|
|
if NewTabValue <> CurIndex then
|
|
begin
|
|
FParent.FTabList.Delete(CurIndex);
|
|
FParent.FTabList.Insert(NewTabValue, Self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl KeyDown
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.KeyDown(var Key: Word; shift : TShiftState);
|
|
Begin
|
|
if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl KeyUp }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.KeyUp(var Key: Word; shift : TShiftState);
|
|
begin
|
|
if Assigned(FOnKeyUp) then FOnKeyUp(Self, Key, Shift);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl KeyPress }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.KeyPress(var Key: Char);
|
|
begin
|
|
if Assigned(FOnKeyPress) then FOnKeyPress(Self, Key);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoKeyDown }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.DoKeyDown(Var Message : TLMKey): Boolean;
|
|
var
|
|
F: TCustomForm;
|
|
ShiftState: TShiftState;
|
|
begin
|
|
// Writeln('name is ',self.name);
|
|
Result := True;
|
|
F := GetParentForm(Self);
|
|
if (F <> nil)
|
|
and (F <> Self)
|
|
and (F.KeyPreview)
|
|
and (TWinControl(F).DoKeyDown(Message)) then Exit;
|
|
|
|
with Message do
|
|
begin
|
|
ShiftState := KeyDataToShiftState(KeyData);
|
|
//ShiftState := [];
|
|
if not (csNoStdEvents in ControlStyle)
|
|
then begin
|
|
KeyDown(CharCode, ShiftState);
|
|
if CharCode = VK_UNKNOWN then Exit;
|
|
end;
|
|
if Application<>nil then
|
|
Application.NotifyKeyDownHandler(Self, CharCode, ShiftState);
|
|
end;
|
|
|
|
Result := False;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoKeyPress }
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.DoKeyPress(Var Message : TLMKey): Boolean;
|
|
var
|
|
F: TCustomForm;
|
|
C: Char;
|
|
begin
|
|
Result := True;
|
|
F := GetParentForm(Self);
|
|
if (F <> nil)
|
|
and (F <> Self)
|
|
and (F.KeyPreview)
|
|
and (TWinControl(F).DoKeyPress(Message)) then Exit;
|
|
if not (csNoStdEvents in ControlStyle)
|
|
then with Message do
|
|
begin
|
|
C := Char(CharCode);
|
|
KeyPress(C);
|
|
CharCode := Ord(C);
|
|
if Char(CharCode) = #0 then Exit;
|
|
end;
|
|
|
|
Result := False;
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoKeyUp }
|
|
{------------------------------------------------------------------------------}
|
|
Function TWinControl.DoKeyUp(Var Message : TLMKey): Boolean;
|
|
var
|
|
F: TCustomForm;
|
|
ShiftState: TShiftState;
|
|
begin
|
|
Result := True;
|
|
F := GetParentForm(Self);
|
|
if (F <> nil)
|
|
and (F <> Self)
|
|
and (F.KeyPreview)
|
|
and (TWinControl(F).DoKeyUp(Message)) then Exit;
|
|
|
|
with Message do
|
|
begin
|
|
ShiftState := KeyDataToShiftState(KeyData);
|
|
if not (csNoStdEvents in ControlStyle)
|
|
then begin
|
|
KeyUp(CharCode, ShiftState);
|
|
if CharCode = 0 then Exit;
|
|
end;
|
|
|
|
// TODO
|
|
//if (CharCode = VK_APPS) and not (ssAlt in ShiftState) then
|
|
// CheckMenuPopup(SmallPoint(0, 0));
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CreateParams }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.CreateParams(var Params : TCreateParams);
|
|
begin
|
|
FillChar(Params, SizeOf(Params),0);
|
|
with Params do
|
|
begin
|
|
Caption := @FText;
|
|
Style := WS_CHILD or WS_CLIPSIBLINGS;
|
|
if (Parent <> nil) then WndParent := Parent.Handle;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Invalidate }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.Invalidate;
|
|
Begin
|
|
if HandleAllocated
|
|
then CNSendMessage(LM_Invalidate,Self,Nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Repaint }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.Repaint;
|
|
Begin
|
|
if HandleAllocated
|
|
then begin
|
|
CNSendMessage(LM_PAINT, Self, nil);
|
|
end;
|
|
end;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoMouseWheel "Event Handler" }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean;
|
|
begin
|
|
Result := False;
|
|
|
|
if Assigned(FOnMouseWheel)
|
|
then FOnMouseWheel(Self, Shift, WheelDelta, MousePos, Result);
|
|
|
|
if not Result
|
|
then begin
|
|
if WheelDelta < 0
|
|
then Result := DoMouseWheelDown(Shift, MousePos)
|
|
else Result := DoMouseWheelUp(Shift, MousePos);
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoMouseWheelDown "Event Handler" }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnMouseWheelDown) then
|
|
FOnMouseWheelDown(Self, Shift, MousePos, Result);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl DoMouseWheelUp "Event Handler" }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnMouseWheelUp) then
|
|
FOnMouseWheelUp(Self, Shift, MousePos, Result);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Insert }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.Insert(AControl : TControl);
|
|
begin
|
|
if AControl <> nil then
|
|
begin
|
|
if AControl = Self
|
|
then begin
|
|
Assert(False, 'Trace:[TControl.SetParent] EInvalidOperation --> AControl = Self');
|
|
raise EInvalidOperation.Create(rsAControlCanNotHaveItselfAsParent);
|
|
end;
|
|
|
|
if AControl is TWinControl then
|
|
begin
|
|
ListAdd(FWinControls, AControl);
|
|
ListAdd(FTabList, AControl);
|
|
end else
|
|
ListAdd(FControls, AControl);
|
|
|
|
AControl.FParent := Self;
|
|
|
|
If (csDesigning in ComponentState)
|
|
and not (csLoading in ComponentState)
|
|
then
|
|
If AControl.CanTab then
|
|
AControl.TabStop := True;
|
|
end;
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl ReAlign
|
|
|
|
Realign all childs
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.ReAlign;
|
|
begin
|
|
if (csLoading in ComponentState) or (not HandleAllocated) then begin
|
|
Include(FFlags,wcfReAlignNeeded);
|
|
exit;
|
|
end;
|
|
//writeln('TWinControl.ReAlign ',Name,':',ClassName);
|
|
AlignControl(nil);
|
|
Exclude(FFlags,wcfReAlignNeeded);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Remove }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.Remove(AControl : TControl);
|
|
begin
|
|
if AControl <> nil then
|
|
begin
|
|
Assert(False, Format('trace:[TWinControl.Remove] %s(%S) --> Remove: %s(%s)', [ClassName, Name, AControl.ClassName, AControl.Name]));
|
|
if AControl is TWinControl then
|
|
begin
|
|
ListRemove(FTabList, AControl);
|
|
ListRemove(FWInControls, ACOntrol);
|
|
end else
|
|
Listremove(FControls, AControl);
|
|
AControl.FParent := Nil;
|
|
end;
|
|
End;
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl RemoveFocus }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.RemoveFocus(Removing : Boolean);
|
|
//TODO: FINISH TWINCONTROL.REMOVEFOCUS
|
|
var
|
|
Form: TCustomForm;
|
|
begin
|
|
Form := GetParentForm(Self);
|
|
if Form <> nil then ;//Form.DefocusControl(Self, Removing);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl UpdateControlState }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.UpdateControlState;
|
|
var AWinControl : TWinControl;
|
|
begin
|
|
AWinControl:= Self;
|
|
{ If any of the parent is not visible, exit }
|
|
while AWinControl.Parent <> nil do
|
|
begin
|
|
AWinControl:= AWinControl.Parent;
|
|
if (not AWinControl.Showing) or (not AWinControl.HandleAllocated) then Exit;
|
|
end;
|
|
|
|
if (AWinControl is TCustomForm)
|
|
or (AWinControl.FParentWindow <> 0)
|
|
then UpdateShowing;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl InsertControl }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.InsertControl(AControl : TControl);
|
|
Begin
|
|
AControl.ValidateContainer(Self);
|
|
Perform(CM_CONTROLLISTCHANGE, Integer(AControl), Integer(True));
|
|
Insert(AControl);
|
|
if not (csReadingState in AControl.ControlState) then
|
|
begin
|
|
AControl.Perform(CM_PARENTCOLORCHANGED, 0, 0);
|
|
AControl.Perform(CM_PARENTFONTCHANGED, 0, 0);
|
|
AControl.Perform(CM_PARENTSHOWHINTCHANGED, 0, 0);
|
|
AControl.Perform(CM_PARENTBIDIMODECHANGED, 0, 0);
|
|
if AControl is TWinControl then
|
|
begin
|
|
AControl.Perform(CM_PARENTCTL3DCHANGED, 0, 0);
|
|
UpdateControlState;
|
|
end else
|
|
if HandleAllocated then AControl.Invalidate;
|
|
//writeln('TWinControl.InsertControl ',Name,':',ClassName);
|
|
end;
|
|
AControl.RequestAlign;
|
|
Perform(CM_CONTROLCHANGE, Integer(AControl), Integer(True));
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl removeControl }
|
|
{------------------------------------------------------------------------------}
|
|
Procedure TWinControl.RemoveControl(AControl : TControl);
|
|
Begin
|
|
Perform(CM_CONTROLCHANGE, Integer(AControl), Integer(False));
|
|
if AControl is TWinControl then
|
|
with TWinControl(AControl) do
|
|
begin
|
|
RemoveFocus(True);
|
|
if HandleAllocated then DestroyHandle;
|
|
end
|
|
else
|
|
if HandleAllocated then
|
|
AControl.InvalidateControl(AControl.Visible, False, True);
|
|
Remove(AControl);
|
|
// Perform(CM_CONTROLLISTCHANGE, Integer(AControl), Integer(False));
|
|
Realign;
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl AlignControl }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.AlignControl(AControl: TControl);
|
|
var
|
|
ARect: TRect;
|
|
i: Integer;
|
|
ChildControl: TControl;
|
|
begin
|
|
//if csDesigning in ComponentState then begin
|
|
// write('TWinControl.AlignControl ',Name,':',ClassName);
|
|
// if AControl<>nil then writeln(' AControl=',AControl.Name,':',AControl.ClassName) else writeln(' AControl=nil');;
|
|
//end;
|
|
if csDestroying in ComponentState then exit;
|
|
|
|
if FAlignLevel <> 0 then begin
|
|
Include(FControlState, csAlignmentNeeded);
|
|
exit;
|
|
end;
|
|
|
|
// check if all childs have finished loading
|
|
for i:=0 to ControlCount-1 do begin
|
|
ChildControl:=Controls[i];
|
|
if csLoading in ChildControl.ComponentState then begin
|
|
// child is loading
|
|
// -> mark the child, that itself and its brothers needs realigning
|
|
// (it will do this, when it has finished loading)
|
|
Include(ChildControl.FControlFlags,cfRequestAlignNeeded);
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
DisableAlign;
|
|
try
|
|
ARect:= GetClientRect;
|
|
AlignControls(AControl, ARect);
|
|
finally
|
|
Exclude(FControlState, csAlignmentNeeded);
|
|
EnableAlign;
|
|
end;
|
|
End;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl GetControl }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.GetControl(const Index: Integer): TControl;
|
|
var
|
|
N: Integer;
|
|
begin
|
|
if FControls <> nil then
|
|
N := FControls.Count
|
|
else
|
|
N := 0;
|
|
if Index < N then
|
|
Result := TControl(FControls[Index])
|
|
else
|
|
Result := TControl(FWinControls[Index - N]);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl GetControlCount }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.GetControlCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
if FControls <> nil then Inc(Result, FControls.Count);
|
|
if FWinControls <> nil then Inc(Result, FWinControls.Count);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl GetHandle }
|
|
{------------------------------------------------------------------------------}
|
|
function TWinControl.GetHandle: HWND;
|
|
begin
|
|
if not HandleAllocated then Assert(False, Format('Trace:[TWinControl.GetHandle] %s(%s)', [ClassNAme, Name]));
|
|
HandleNeeded;
|
|
Result := FHandle;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl SetHandle
|
|
Params: NewHandle
|
|
Returns: Nothing
|
|
-------------------------------------------------------------------------------}
|
|
procedure TWincontrol.SetHandle(NewHandle: HWND);
|
|
begin
|
|
FHandle:=NewHandle;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.Create
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
Contructor for the class.
|
|
------------------------------------------------------------------------------}
|
|
constructor TWinControl.Create(TheOwner : TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
FCompStyle := csFixed;
|
|
FBrush := nil;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CreateParented }
|
|
{------------------------------------------------------------------------------}
|
|
constructor TWinControl.CreateParented(ParentWindow: hwnd);
|
|
begin
|
|
FParentWindow := ParentWindow;
|
|
inherited Create(nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl CreateParentedControl }
|
|
{------------------------------------------------------------------------------}
|
|
class function TWinControl.CreateParentedControl(ParentWindow : hwnd): TWinControl;
|
|
begin
|
|
// ToDo
|
|
Result:=nil;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ TWinControl Hide }
|
|
{------------------------------------------------------------------------------}
|
|
procedure TWinControl.Hide;
|
|
begin
|
|
Visible := False;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.Destroy
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
Destructor for the class.
|
|
------------------------------------------------------------------------------}
|
|
destructor TWinControl.Destroy;
|
|
var
|
|
n: Integer;
|
|
Control: TControl;
|
|
begin
|
|
//writeln('[TWinControl.Destroy] A ',Name,':',ClassName);
|
|
if HandleAllocated then
|
|
DestroyHandle;
|
|
//writeln('[TWinControl.Destroy] B ',Name,':',ClassName);
|
|
|
|
//for n:=0 to ComponentCount-1 do
|
|
// writeln(' n=',n,' ',Components[n].ClassName);
|
|
|
|
n := ControlCount;
|
|
|
|
while n > 0 do
|
|
begin
|
|
Control := Controls[n - 1];
|
|
//writeln('[TWinControl.Destroy] C ',Name,':',ClassName,' ',Control.Name,':',Control.ClassName);
|
|
Remove(Control);
|
|
// don't free the control just set parent to nil
|
|
// controls are freed by the owner
|
|
//Control.Free;
|
|
Control.Parent := nil;
|
|
n := ControlCount;
|
|
end;
|
|
|
|
FBrush.Free;
|
|
FBrush:=nil;
|
|
//writeln('[TWinControl.Destroy] D ',Name,':',ClassName);
|
|
inherited Destroy;
|
|
//writeln('[TWinControl.Destroy] END ',Name,':',ClassName);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.DoEnter
|
|
Params: none
|
|
Returns: Nothing
|
|
|
|
Call user's callback for OnEnter.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.DoEnter;
|
|
begin
|
|
if Assigned(FOnEnter) then FOnEnter(Self);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.DoExit
|
|
Params: none
|
|
Returns: Nothing
|
|
|
|
Call user's callback for OnExit.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.DoExit;
|
|
begin
|
|
if Assigned(FOnExit) then FOnExit(Self);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.CMEnabledChanged
|
|
Params: Message
|
|
Returns: Nothing
|
|
|
|
Called when enabled is changed. Takes action to enable control
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CMEnabledChanged(var Message: TLMEssage);
|
|
begin
|
|
if not Enabled and (Parent <> nil)
|
|
then RemoveFocus(False);
|
|
|
|
if HandleAllocated
|
|
and not (csDesigning in ComponentState)
|
|
then EnableWindow(FHandle, Enabled);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMSetFocus
|
|
Params: Message
|
|
Returns: Nothing
|
|
|
|
SetFocus event handler
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.WMSetFocus(var Message : TLMSetFocus);
|
|
Begin
|
|
Assert(False, Format('Trace:TODO: [TWinControl.LMSetFocus] %s', [ClassName]));
|
|
DoEnter;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMPaint
|
|
Params: Msg: The paint message
|
|
Returns: nothing
|
|
|
|
Paint event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMPaint(var Msg: TLMPaint);
|
|
var
|
|
dc,Memdc : hdc;
|
|
MemBitmap, OldBitmap : HBITMAP;
|
|
PS : TPaintStruct;
|
|
begin
|
|
//writeln('[TWinControl.WMPaint] ',Name,':',ClassName,' ',HexStr(Msg.DC,8));
|
|
Assert(False, Format('Trace:> [TWinControl.WMPaint] %s Msg.DC: 0x%x', [ClassName, Msg.DC]));
|
|
if (Msg.DC <> 0) then
|
|
begin
|
|
if not (csCustomPaint in ControlState) and (ControlCount = 0) then
|
|
begin
|
|
// no inherited method to call...
|
|
end
|
|
else
|
|
PaintHandler(Msg);
|
|
end
|
|
else begin
|
|
DC := GetDC(0);
|
|
MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
|
|
ReleaseDC(0, DC);
|
|
MemDC := CreateCompatibleDC(0);
|
|
OldBitmap := SelectObject(MemDC, MemBitmap);
|
|
try
|
|
DC := BeginPaint(Handle, PS);
|
|
//ToDO:define wm_erasebkgnd
|
|
// Perform(WM_ERASEBKGND, MemDC, MemDC);
|
|
Msg.DC := MemDC;
|
|
WMPaint(Msg);
|
|
Msg.DC := 0;
|
|
//TODO:bitblt
|
|
BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
|
|
EndPaint(Handle, PS);
|
|
finally
|
|
SelectObject(MemDC, OldBitmap);
|
|
DeleteDC(MemDC);
|
|
DeleteObject(MemBitmap);
|
|
end;
|
|
end;
|
|
Assert(False, Format('Trace:< [TWinControl.WMPaint] %s', [ClassName]));
|
|
//writeln('[TWinControl.WMPaint] END ',Name,':',ClassName);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMDestroy
|
|
Params: Msg: The destroy message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMDestroy(var Message: TLMDestroy);
|
|
begin
|
|
Assert(False, Format('Trace: [TWinControl.LMDestroy] %s', [ClassName]));
|
|
//writeln('TWinControl.WMDestroy ',Name,':',ClassName);
|
|
// Our widget/window doesn't exist anymore
|
|
FHandle := 0;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMMove
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMMove(var Message: TLMMove);
|
|
begin
|
|
if Message.MoveType=Move_SourceIsInterface then begin
|
|
// interface widget has moved
|
|
FBoundsRealized:=Bounds(Message.XPos,Message.YPos,
|
|
FBoundsRealized.Right-FBoundsRealized.Left,
|
|
FBoundsRealized.Bottom-FBoundsRealized.Top);
|
|
end;
|
|
inherited WMMove(Message);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMSize
|
|
Params: Message: TLMSize
|
|
Returns: nothing
|
|
|
|
Event handler for size messages. This is called, whenever width, height,
|
|
clientwidth or clientheight have changed.
|
|
If the source of the message is the interface, the new size is stored
|
|
in FBoundsRealized to avoid sending a size message back to the interface.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMSize(var Message: TLMSize);
|
|
begin
|
|
if Message.SizeType=Size_SourceIsInterface then begin
|
|
// interface widget has resized
|
|
FBoundsRealized.Right:=FBoundsRealized.Left+Message.Width;
|
|
FBoundsRealized.Bottom:=FBoundsRealized.Top+Message.Height;
|
|
end;
|
|
inherited WMSize(Message);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMNofity
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWInControl.WMNotify(var Message: TLMNotify);
|
|
Begin
|
|
if not DoControlMsg(Message.NMHdr^.hwndfrom,Message) then exit;
|
|
|
|
//Inherited ;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.LMKillFocus
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMKillFocus(var Message: TLMKillFocus);
|
|
begin
|
|
Assert(False, Format('Trace: TODO: [TWinControl.LMKillFocus] %s', [ClassName]));
|
|
DoExit;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMShowWindow
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMShowWindow(var Message: TLMShowWindow);
|
|
begin
|
|
Assert(False, Format('Trace: TODO: [TWinControl.LMShowWindow] %s', [ClassName]));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMEnter
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMEnter(var Message: TLMEnter);
|
|
begin
|
|
Assert(False, Format('Trace: TODO: [TWinControl.LMEnter] %s', [ClassName]));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMEraseBkgnd
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMEraseBkgnd(var Message: TLMEraseBkgnd);
|
|
begin
|
|
Assert(False, Format('Trace: TODO: [TWinControl.LMEraseBkgnd] %s', [ClassName]));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMExit
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMExit(var Message: TLMExit);
|
|
begin
|
|
Assert(False, Format('Trace: TODO: [TWinControl.LMExit] %s', [ClassName]));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMMouseWheel
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMMouseWheel(var Message: TLMMouseEvent);
|
|
Var
|
|
MousePos : TPoint;
|
|
Shift : TShiftState;
|
|
begin
|
|
Assert(False, Format('Trace: [TWinControl.LMMouseWheel] %s', [ClassName]));
|
|
|
|
MousePos.X := Message.X;
|
|
MousePos.Y := Message.Y;
|
|
|
|
{ always the middle button }
|
|
Shift := [ssMiddle];
|
|
|
|
DoMouseWheel(Shift, Message.WheelDelta, MousePos);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMChar
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.WMChar(var Message: TLMChar);
|
|
begin
|
|
Assert(False, Format('Trace:[TWinControl.WMChar] %s', [ClassName]));
|
|
if not DoKeyPress(Message) then {inherited}; // there is nothing to inherit
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMKeyDown
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.WMKeyDown(Var Message : TLMKeyDown);
|
|
begin
|
|
Assert(False, Format('Trace:[TWinControl.WMKeyDown] %s', [ClassName]));
|
|
if not DoKeyDown(Message) then begin
|
|
{inherited} ; // there is nothing to inherit
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.WMKeyUp
|
|
Params: Msg: The message
|
|
Returns: nothing
|
|
|
|
event handler.
|
|
------------------------------------------------------------------------------}
|
|
Procedure TWinControl.WMKeyUp(Var Message : TLMKeyUp);
|
|
Begin
|
|
Assert(False, Format('Trace:[TWinControl.WMKeyUp] %s', [ClassName]));
|
|
if not DoKeyUp(Message) then {inherited}; // there is nothing to inherit
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Function: TWinControl.HandleAllocated
|
|
Params: None
|
|
Returns: True is handle is allocated
|
|
|
|
Checks if a handle is allocated. I.E. if the control is mapped
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.HandleAllocated : Boolean;
|
|
begin
|
|
HandleAllocated := (FHandle <> 0);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.CreateHandle
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
Creates the handle ( = object).
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CreateHandle;
|
|
begin
|
|
if (not HandleAllocated) then CreateWnd;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.CreateWnd
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
Creates the interface object.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CreateWnd;
|
|
var
|
|
Params: TCreateParams;
|
|
n: Integer;
|
|
|
|
{ procedure WriteClientRect(const Prefix: string);
|
|
var r: TRect;
|
|
begin
|
|
LCLLinux.GetClientRect(Handle,r);
|
|
if csDesigning in ComponentState then
|
|
writeln('WriteClientRect ',Prefix,' ',Name,':',ClassName,' r=',r.Right,',',r.Bottom);
|
|
end;}
|
|
|
|
begin
|
|
//writeln('[TWinControl.CreateWnd] START ',Name,':',Classname);
|
|
if (FCompstyle = csNone) then
|
|
begin
|
|
WriteLn(Format('WARNING: [TWinControl.CreateWnd] %s --> FCompstyle = csNone', [ClassName]));
|
|
Exit;
|
|
end;
|
|
|
|
CreateParams(Params);
|
|
with Params do begin
|
|
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
|
|
RaiseGDBException('TWinControl.CreateWnd: no parent '+Name+':'+ClassName);
|
|
Assert((parent <> nil) or (WndParent = 0), 'TODO: find parent if parent=nil and WndParent <> 0');
|
|
end;
|
|
|
|
CreateComponent(nil);
|
|
|
|
//WriteClientRect('A');
|
|
if Parent <> nil then AddControl;
|
|
|
|
//WriteClientRect('B');
|
|
InitializeWnd;
|
|
|
|
//writeln('[TWinControl.CreateWnd] ',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height);
|
|
//WriteClientRect('C');
|
|
|
|
// realign childs
|
|
ReAlign;
|
|
|
|
if FWinControls <> nil then begin
|
|
for n := 0 to FWinControls.Count - 1 do
|
|
with TWinControl(FWinControls.Items[n]) do
|
|
if Visible then HandleNeeded;
|
|
end;
|
|
|
|
//writeln('[TWinControl.CreateWnd] END ',Name,':',Classname);
|
|
//WriteClientRect('D');
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
procedure TWinControl.CreateComponent(TheOwner : TComponent);
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CreateComponent(TheOwner : TComponent);
|
|
begin
|
|
if HandleAllocated then
|
|
RaiseGDBException('TWinControl.CreateComponent: Handle already created');
|
|
CNSendMessage(LM_CREATE, Self, nil);
|
|
if not HandleAllocated then
|
|
RaiseGDBException('TWinControl.CreateComponent: Handle creation failed');
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
TWinControl Destroy Component
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.DestroyComponent;
|
|
begin
|
|
CNSendMessage(LM_DESTROY, Self, nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.InitializeWnd
|
|
Params: none
|
|
Returns: Nothing
|
|
|
|
Gets called after the window is created, but before the owned controls are
|
|
created. Place cached property code here.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.InitializeWnd;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Assert(False, Format('Trace:[TWinControl.InitializeWnd] %s', [ClassName]));
|
|
// set all cached properties
|
|
|
|
// MWE:All of this should be handled to the interface create routine
|
|
Assert(False, 'Trace:TODO: [TWinControl.InitializeWnd] move this code to the interface');
|
|
|
|
R:= Rect(Left, Top, Width, Height);
|
|
//writeln('[TWinControl.InitializeWnd] ',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height);
|
|
FBoundsRealized:=Bounds(Left, Top, Width, Height);
|
|
CNSendMessage(LM_SETSIZE, Self, @R);
|
|
CNSendMessage(LM_SHOWHIDE, Self, nil);
|
|
CNSendMessage(LM_SETCOLOR, Self, nil);
|
|
Exclude(FFlags,wcfColorChanged);
|
|
|
|
EnableWindow(Handle, Enabled);
|
|
|
|
SetTextBuf(PChar(FCaption));
|
|
Assert(False, 'Trace:SETPROP**********************************************');
|
|
|
|
SetProp(Handle,'WinControl',TWinControl(Self));
|
|
SetProp(Handle,'Control',TControl(Self));
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
procedure TWinControl.Loaded;
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
RealizeBounds;
|
|
FixupTabList;
|
|
if wcfColorChanged in FFlags then begin
|
|
CNSendMessage(LM_SETCOLOR, Self, nil);
|
|
Exclude(FFlags,wcfColorChanged);
|
|
end;
|
|
// align the childs
|
|
if wcfReAlignNeeded in FFlags then
|
|
ReAlign;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.DestroyWnd
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
Creates the interface object.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.DestroyWnd;
|
|
begin
|
|
if HandleAllocated then begin
|
|
DestroyComponent;
|
|
FHandle := 0;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.HandleNeeded
|
|
Params: AOwner: the owner of the class
|
|
Returns: Nothing
|
|
|
|
Description of the procedure for the class.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.HandleNeeded;
|
|
begin
|
|
if not HandleAllocated then
|
|
begin
|
|
if Parent = Self
|
|
then begin
|
|
Assert(False, Format('Trace:[TWinControl.HandleNeeded] Somebody set Parent := Self in %s. DONT DO THAT !!', [Classname]));
|
|
end
|
|
else begin
|
|
if (Parent <> nil) then
|
|
Parent.HandleNeeded;
|
|
end;
|
|
CreateHandle;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TControl.BeginUpdateBounds
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
increases the BoundsLockCount
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.BeginUpdateBounds;
|
|
begin
|
|
inc(FBoundsLockCount);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TControl.EndUpdateBounds
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
decreases the BoundsLockCount
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.EndUpdateBounds;
|
|
begin
|
|
if BoundsLockCount<=0 then exit;
|
|
dec(FBoundsLockCount);
|
|
if BoundsLockCount=0 then begin
|
|
SetBounds(Left,Top,Width,Height);
|
|
end;
|
|
end;
|
|
|
|
procedure TWinControl.LockRealizeBounds;
|
|
begin
|
|
inc(FRealizeBoundsLockCount);
|
|
end;
|
|
|
|
procedure TWinControl.UnlockRealizeBounds;
|
|
begin
|
|
if FRealizeBoundsLockCount<=0 then
|
|
RaiseGDBException('UnlockRealizeBounds');
|
|
dec(FRealizeBoundsLockCount);
|
|
if FRealizeBoundsLockCount=0 then
|
|
RealizeBounds;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TControl.GetIsResizing
|
|
Params: None
|
|
Returns: Nothing
|
|
|
|
decreases the BoundsLockCount
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.GetIsResizing: boolean;
|
|
begin
|
|
Result:=BoundsLockCount>0;
|
|
end;
|
|
|
|
function TWinControl.GetTabOrder: TTabOrder;
|
|
begin
|
|
if FParent <> nil then
|
|
Result := FParent.FTabList.IndexOf(Self)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.SetBounds
|
|
Params: aLeft, aTop, aWidth, aHeight
|
|
Returns: Nothing
|
|
|
|
Sets the bounds of the control.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.SetBounds(aLeft, aTop, aWidth, aHeight : integer);
|
|
var
|
|
NewBounds, OldBounds: TRect;
|
|
begin
|
|
{$IFDEF CHECK_POSITION}
|
|
//if csDesigning in ComponentState then
|
|
writeln('[TWinControl.SetBounds] START ',Name,':',ClassName,
|
|
' Old=',Left,',',Top,',',Width,',',Height,
|
|
' -> New=',ALeft,',',ATop,',',AWidth,',',AHeight,
|
|
' Lock=',BoundsLockCount,
|
|
' Realized=',FBoundsRealized.Left,',',FBoundsRealized.Top,
|
|
',',FBoundsRealized.Right-FBoundsRealized.Left,',',FBoundsRealized.Bottom-FBoundsRealized.Top
|
|
);
|
|
{$ENDIF}
|
|
if BoundsLockCount<>0 then exit;
|
|
OldBounds:=BoundsRect;
|
|
NewBounds:=Bounds(ALeft, ATop, AWidth, AHeight);
|
|
|
|
LockRealizeBounds;
|
|
try
|
|
if not CompareRect(@NewBounds,@OldBounds) then begin
|
|
// LCL bounds are not up2date -> process new bounds
|
|
{$IFDEF CHECK_POSITION}
|
|
//if csDesigning in ComponentState then
|
|
writeln('[TWinControl.SetBounds] Set LCL Bounds ',Name,':',ClassName,
|
|
' OldBounds=',Left,',',Top,',',Left+Width,',',Top+Height,
|
|
' -> New=',ALeft,',',ATop,',',ALeft+AWidth,',',ATop+AHeight);
|
|
{$ENDIF}
|
|
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
|
|
NewBounds:=Bounds(Left, Top, Width, Height);
|
|
end;
|
|
finally
|
|
UnlockRealizeBounds;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.SetText
|
|
Params: Value: the text to be set
|
|
Returns: Nothing
|
|
|
|
Sets the text/caption of a control
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.SetText(const Value: TCaption);
|
|
begin
|
|
if HandleAllocated
|
|
then inherited SetText(Value)
|
|
else FCaption := Value;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.GetDeviceContext
|
|
Params: WindowHandle: the windowhandle of this control
|
|
Returns: a Devicecontext
|
|
|
|
Get the devicecontext for this WinControl.
|
|
------------------------------------------------------------------------------}
|
|
function TWinControl.GetDeviceContext(var WindowHandle: HWnd): HDC;
|
|
begin
|
|
(*
|
|
if Handle = 0
|
|
then begin
|
|
// we aren't created yet
|
|
Result := 0;
|
|
WindowHandle := 0;
|
|
end
|
|
else begin
|
|
Result := GetDC(FHandle);
|
|
if Result = 0
|
|
then raise EOutOfResources.Create('Error creating device context');
|
|
end;
|
|
WindowHandle := FHandle;
|
|
(*)
|
|
Result := GetDC(Handle);
|
|
//writeln('[TWinControl.GetDeviceContext] ',ClassName,' DC=',HexStr(Cardinal(Result),8),' Handle=',HexStr(Cardinal(FHandle),8));
|
|
if Result = 0
|
|
then raise EOutOfResources.CreateFmt(rsErrorCreatingDeviceContext, [Name,
|
|
ClassName]);
|
|
|
|
WindowHandle := FHandle;
|
|
//*)
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.CMVisibleChanged
|
|
Params: Message : not used
|
|
Returns: nothing
|
|
|
|
Performs actions when visibility has changed
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CMVisibleChanged(var TheMessage : TLMessage);
|
|
begin
|
|
if not FVisible and (Parent <> nil)
|
|
then RemoveFocus(False);
|
|
|
|
if not (csDesigning in ComponentState)
|
|
or (csNoDesignVisible in ControlStyle)
|
|
then
|
|
UpdateControlState;
|
|
end;
|
|
|
|
procedure TWinControl.ControlsAligned;
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TWinControl.RealizeBounds;
|
|
var
|
|
NewBounds: TRect;
|
|
begin
|
|
NewBounds:=Bounds(Left, Top, Width, Height);
|
|
if HandleAllocated
|
|
and (not (csLoading in ComponentState))
|
|
and (not CompareRect(@NewBounds,@FBoundsRealized)) then
|
|
begin
|
|
// the new bounds were not yet send to the InterfaceObject -> send them
|
|
{$IFDEF CHECK_POSITION}
|
|
if csDesigning in ComponentState then
|
|
writeln('[TWinControl.RealizeBounds] A ',Name,':',ClassName,
|
|
' OldRelBounds=',FBoundsRealized.Left,',',FBoundsRealized.Top,',',FBoundsRealized.Right,',',FBoundsRealized.Bottom,
|
|
' -> NewBounds=',NewBounds.Left,',',NewBounds.Top,',',NewBounds.Right,',',NewBounds.Bottom);
|
|
{$ENDIF}
|
|
BeginUpdateBounds;
|
|
try
|
|
FBoundsRealized:=NewBounds;
|
|
CNSendMessage(LM_SetSize, Self, @NewBounds);
|
|
finally
|
|
EndUpdateBounds;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.CMShowingChanged
|
|
Params: Message : not used
|
|
Returns: nothing
|
|
|
|
Shows or hides a control
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.CMShowingChanged(var Message: TLMessage);
|
|
begin
|
|
if HandleAllocated then
|
|
CNSendMessage(LM_ShowHide, Self, nil);
|
|
// SetWindowPos(FHandle, 0, 0, 0, 0, 0, ShowFlags[FShowing]);
|
|
end;
|
|
{------------------------------------------------------------------------------
|
|
Method: TWinControl.ShowControl
|
|
Params: AControl: Control to show
|
|
Returns: nothing
|
|
|
|
Askes the parent to show ourself.
|
|
------------------------------------------------------------------------------}
|
|
procedure TWinControl.ShowControl(AControl: TControl);
|
|
begin
|
|
if Parent <> nil then Parent.ShowControl(Self);
|
|
end;
|
|
|
|
|
|
{$IFDEF ASSERT_IS_ON}
|
|
{$UNDEF ASSERT_IS_ON}
|
|
{$C-}
|
|
{$ENDIF}
|
|
{ =============================================================================
|
|
|
|
$Log$
|
|
Revision 1.139 2003/06/19 16:36:35 mattias
|
|
started codeexplorer
|
|
|
|
Revision 1.138 2003/06/19 09:26:58 mattias
|
|
fixed changing unitname during update
|
|
|
|
Revision 1.137 2003/06/18 11:21:06 mattias
|
|
fixed taborder=0, implemented TabOrder Editor
|
|
|
|
Revision 1.136 2003/06/12 18:55:44 mattias
|
|
improved designer to recognize auto child moves
|
|
|
|
Revision 1.135 2003/06/11 22:29:42 mattias
|
|
fixed realizing bounds after loading form
|
|
|
|
Revision 1.134 2003/06/10 17:23:35 mattias
|
|
implemented tabstop
|
|
|
|
Revision 1.133 2003/06/10 12:28:23 mattias
|
|
fixed anchoring controls
|
|
|
|
Revision 1.132 2003/06/10 00:46:16 mattias
|
|
fixed aligning controls
|
|
|
|
Revision 1.131 2003/06/01 21:09:09 mattias
|
|
implemented datamodules
|
|
|
|
Revision 1.130 2003/05/24 08:51:41 mattias
|
|
implemented designer close query
|
|
|
|
Revision 1.129 2003/04/20 20:32:40 mattias
|
|
implemented removing, re-adding, updating project dependencies
|
|
|
|
Revision 1.128 2003/04/11 10:31:57 mattias
|
|
added Sender to Application OnKeyDownHandler
|
|
|
|
Revision 1.127 2003/04/11 10:23:23 mattias
|
|
added Application OnKeyDownHandler
|
|
|
|
Revision 1.126 2003/04/10 09:22:42 mattias
|
|
implemented changing dependency version
|
|
|
|
Revision 1.125 2003/04/04 09:19:22 mattias
|
|
activated TDataSource
|
|
|
|
Revision 1.124 2003/03/28 19:39:54 mattias
|
|
started typeinfo for double extended
|
|
|
|
Revision 1.123 2003/03/25 10:45:41 mattias
|
|
reduced focus handling and improved focus setting
|
|
|
|
Revision 1.122 2003/03/18 13:04:25 mattias
|
|
improved focus debugging output
|
|
|
|
Revision 1.121 2003/03/17 08:51:09 mattias
|
|
added IsWindowVisible
|
|
|
|
Revision 1.120 2003/03/11 07:46:44 mattias
|
|
more localization for gtk- and win32-interface and lcl
|
|
|
|
Revision 1.119 2003/03/09 17:44:12 mattias
|
|
finshed Make Resourcestring dialog and implemented TToggleBox
|
|
|
|
Revision 1.118 2003/02/26 12:44:52 mattias
|
|
readonly flag is now only saved if user set
|
|
|
|
Revision 1.117 2003/02/09 18:07:42 mattias
|
|
cleanup
|
|
|
|
Revision 1.116 2003/01/24 13:53:53 mattias
|
|
fixed TRadioGroup.Items editing in IDE
|
|
|
|
Revision 1.115 2003/01/18 21:31:43 mattias
|
|
fixed scrolling offset of TScrollingWinControl
|
|
|
|
Revision 1.114 2003/01/01 13:04:26 mattias
|
|
clean ups
|
|
|
|
Revision 1.113 2003/01/01 13:01:01 mattias
|
|
fixed setcolor for streamed components
|
|
|
|
Revision 1.112 2002/12/29 18:13:38 mattias
|
|
identifier completion: basically working, still hidden
|
|
|
|
Revision 1.111 2002/12/28 17:43:43 mattias
|
|
fixed FindControl and searching overloaded procs
|
|
|
|
Revision 1.110 2002/12/28 12:42:38 mattias
|
|
focus fixes, reduced lpi size
|
|
|
|
Revision 1.109 2002/12/27 17:46:04 mattias
|
|
fixed SetColor
|
|
|
|
Revision 1.108 2002/12/27 17:12:38 mattias
|
|
added more Delphi win32 compatibility functions
|
|
|
|
Revision 1.107 2002/02/09 01:48:23 mattias
|
|
renamed TinterfaceObject.Init to AppInit and TWinControls can now contain childs in gtk
|
|
|
|
Revision 1.106 2002/12/04 20:39:15 mattias
|
|
patch from Vincent: clean ups and fixed crash on destroying window
|
|
|
|
Revision 1.105 2002/12/03 09:28:31 mattias
|
|
cleaned up
|
|
|
|
Revision 1.104 2002/11/30 08:35:42 mattias
|
|
TCustomForm.WMDestroy does not Free anymore
|
|
|
|
Revision 1.103 2002/11/29 15:14:48 mattias
|
|
replaced many invalidates by invalidaterect
|
|
|
|
Revision 1.102 2002/11/27 15:40:36 mattias
|
|
fixed resize request
|
|
|
|
Revision 1.101 2002/11/21 18:49:53 mattias
|
|
started OnMouseEnter and OnMouseLeave
|
|
|
|
Revision 1.100 2002/11/10 21:49:28 lazarus
|
|
MG: added smart hints in edit mode
|
|
|
|
Revision 1.99 2002/11/09 18:13:33 lazarus
|
|
MG: fixed gdkwindow checks
|
|
|
|
Revision 1.98 2002/11/03 22:40:28 lazarus
|
|
MG: fixed ControlAtPos
|
|
|
|
Revision 1.97 2002/11/01 14:40:31 lazarus
|
|
MG: fixed mouse coords on scrolling wincontrols
|
|
|
|
Revision 1.96 2002/10/31 22:14:16 lazarus
|
|
MG: fixed GetClipBox when clipping region invalid
|
|
|
|
Revision 1.95 2002/10/31 21:29:47 lazarus
|
|
MG: implemented TControlScrollBar.Size
|
|
|
|
Revision 1.94 2002/10/26 15:15:49 lazarus
|
|
MG: broke LCL<->interface circles
|
|
|
|
Revision 1.93 2002/10/09 10:22:54 lazarus
|
|
MG: fixed client origin coordinates
|
|
|
|
Revision 1.92 2002/10/08 22:32:27 lazarus
|
|
MG: fixed cool little bug (menu double attaching bug)
|
|
|
|
Revision 1.91 2002/10/04 20:46:51 lazarus
|
|
MG: improved TComboBox.SetItemIndex
|
|
|
|
Revision 1.90 2002/10/04 14:24:15 lazarus
|
|
MG: added DrawItem to TComboBox/TListBox
|
|
|
|
Revision 1.89 2002/09/29 15:08:38 lazarus
|
|
MWE: Applied patch from "Andrew Johnson" <aj_genius@hotmail.com>
|
|
Patch includes:
|
|
-fixes Problems with hiding modal forms
|
|
-temporarily fixes TCustomForm.BorderStyle in bsNone
|
|
-temporarily fixes problems with improper tabbing in TSynEdit
|
|
|
|
Revision 1.88 2002/09/27 20:52:23 lazarus
|
|
MWE: Applied patch from "Andrew Johnson" <aj_genius@hotmail.com>
|
|
|
|
Here is the run down of what it includes -
|
|
|
|
-Vasily Volchenko's Updated Russian Localizations
|
|
|
|
-improvements to GTK Styles/SysColors
|
|
-initial GTK Palette code - (untested, and for now useless)
|
|
|
|
-Hint Windows and Modal dialogs now try to stay transient to
|
|
the main program form, aka they stay on top of the main form
|
|
and usually minimize/maximize with it.
|
|
|
|
-fixes to Form BorderStyle code(tool windows needed a border)
|
|
|
|
-fixes DrawFrameControl DFCS_BUTTONPUSH to match Win32 better
|
|
when flat
|
|
|
|
-fixes DrawFrameControl DFCS_BUTTONCHECK to match Win32 better
|
|
and to match GTK theme better. It works most of the time now,
|
|
but some themes, noteably Default, don't work.
|
|
|
|
-fixes bug in Bitmap code which broke compiling in NoGDKPixbuf
|
|
mode.
|
|
|
|
-misc other cleanups/ fixes in gtk interface
|
|
|
|
-speedbutton's should now draw correctly when flat in Win32
|
|
|
|
-I have included an experimental new CheckBox(disabled by
|
|
default) which has initial support for cbGrayed(Tri-State),
|
|
and WordWrap, and misc other improvements. It is not done, it
|
|
is mostly a quick hack to test DrawFrameControl
|
|
DFCS_BUTTONCHECK, however it offers many improvements which
|
|
can be seen in cbsCheck/cbsCrissCross (aka non-themed) state.
|
|
|
|
-fixes Message Dialogs to more accurately determine
|
|
button Spacing/Size, and Label Spacing/Size based on current
|
|
System font.
|
|
-fixes MessageDlgPos, & ShowMessagePos in Dialogs
|
|
-adds InputQuery & InputBox to Dialogs
|
|
|
|
-re-arranges & somewhat re-designs Control Tabbing, it now
|
|
partially works - wrapping around doesn't work, and
|
|
subcontrols(Panels & Children, etc) don't work. TabOrder now
|
|
works to an extent. I am not sure what is wrong with my code,
|
|
based on my other tests at least wrapping and TabOrder SHOULD
|
|
work properly, but.. Anyone want to try and fix?
|
|
|
|
-SynEdit(Code Editor) now changes mouse cursor to match
|
|
position(aka over scrollbar/gutter vs over text edit)
|
|
|
|
-adds a TRegion property to Graphics.pp, and Canvas. Once I
|
|
figure out how to handle complex regions(aka polygons) data
|
|
properly I will add Region functions to the canvas itself
|
|
(SetClipRect, intersectClipRect etc.)
|
|
|
|
-BitBtn now has a Stored flag on Glyph so it doesn't store to
|
|
lfm/lrs if Glyph is Empty, or if Glyph is not bkCustom(aka
|
|
bkOk, bkCancel, etc.) This should fix most crashes with older
|
|
GDKPixbuf libs.
|
|
|
|
Revision 1.87 2002/09/16 15:42:17 lazarus
|
|
MG: fixed calling DestroyHandle if not HandleAllocated
|
|
|
|
Revision 1.86 2002/09/10 06:49:19 lazarus
|
|
MG: scrollingwincontrol from Andrew
|
|
|
|
Revision 1.85 2002/09/05 12:11:43 lazarus
|
|
MG: TNotebook is now streamable
|
|
|
|
Revision 1.84 2002/09/03 08:07:20 lazarus
|
|
MG: image support, TScrollBox, and many other things from Andrew
|
|
|
|
Revision 1.83 2002/09/01 16:11:22 lazarus
|
|
MG: double, triple and quad clicks now works
|
|
|
|
Revision 1.82 2002/08/31 11:37:09 lazarus
|
|
MG: fixed destroying combobox
|
|
|
|
Revision 1.81 2002/08/30 12:32:21 lazarus
|
|
MG: MoveWindowOrgEx, Splitted FWinControls/FControls, TControl drawing, Better DesignerDrawing, ...
|
|
|
|
Revision 1.80 2002/08/30 06:46:03 lazarus
|
|
|
|
Use comboboxes. Use history. Prettify the dialog. Preselect text on show.
|
|
Make the findreplace a dialog. Thus removing resiying code (handled by Anchors now anyway).
|
|
Make Anchors work again and publish them for various controls.
|
|
SelStart and Co. for TEdit, SelectAll procedure for TComboBox and TEdit.
|
|
Clean up and fix some bugs for TComboBox, plus selection stuff.
|
|
|
|
Revision 1.79 2002/08/25 14:32:11 lazarus
|
|
MG: calendar now ignores double clicks
|
|
|
|
Revision 1.78 2002/08/24 12:54:59 lazarus
|
|
MG: fixed mouse capturing, OI edit focus
|
|
|
|
Revision 1.77 2002/08/24 06:51:22 lazarus
|
|
MG: from Andrew: style list fixes, autosize for radio/checkbtns
|
|
|
|
Revision 1.76 2002/08/17 15:45:33 lazarus
|
|
MG: removed ClientRectBugfix defines
|
|
|
|
Revision 1.75 2002/08/05 07:43:28 lazarus
|
|
MG: fixed BadCursor bug and Circle Reference of FixedWidget of csPanel
|
|
|
|
Revision 1.74 2002/06/21 15:41:56 lazarus
|
|
MG: moved RectVisible, ExcludeClipRect and IntersectClipRect to interface dependent functions
|
|
|
|
Revision 1.73 2002/06/19 19:46:09 lazarus
|
|
MG: Form Editing: snapping, guidelines, modified on move/resize, creating components in csDesigning, ...
|
|
|
|
Revision 1.72 2002/06/11 13:41:09 lazarus
|
|
MG: fixed mouse coords and fixed mouse clicked thru bug
|
|
|
|
Revision 1.71 2002/05/28 15:05:59 lazarus
|
|
MG: reduced output
|
|
|
|
Revision 1.70 2002/05/28 14:58:30 lazarus
|
|
MG: added scrollbars for TListView
|
|
|
|
Revision 1.69 2002/05/27 14:38:34 lazarus
|
|
MG; fixed find declaration of overloaded procs and expression input types
|
|
|
|
Revision 1.68 2002/05/24 07:16:32 lazarus
|
|
MG: started mouse bugfix and completed Makefile.fpc
|
|
|
|
Revision 1.67 2002/05/13 14:47:00 lazarus
|
|
MG: fixed client rectangles, TRadioGroup, RecreateWnd
|
|
|
|
Revision 1.66 2002/05/12 04:56:20 lazarus
|
|
MG: client rect bugs nearly completed
|
|
|
|
Revision 1.65 2002/05/10 06:05:56 lazarus
|
|
MG: changed license to LGPL
|
|
|
|
Revision 1.64 2002/05/09 12:41:28 lazarus
|
|
MG: further clientrect bugfixes
|
|
|
|
Revision 1.63 2002/05/06 08:50:36 lazarus
|
|
MG: replaced logo, increased version to 0.8.3a and some clientrectbugfix
|
|
|
|
Revision 1.62 2002/04/28 14:10:31 lazarus
|
|
MG: fixes for saving resource files
|
|
|
|
Revision 1.61 2002/04/27 15:35:50 lazarus
|
|
MG: fixed window shrinking
|
|
|
|
Revision 1.60 2002/04/24 16:11:17 lazarus
|
|
MG: started new client rectangle
|
|
|
|
Revision 1.59 2002/04/22 13:07:45 lazarus
|
|
MG: fixed AdjustClientRect of TGroupBox
|
|
|
|
Revision 1.58 2002/04/18 08:13:36 lazarus
|
|
MG: added include comments
|
|
|
|
Revision 1.56 2002/04/04 12:25:01 lazarus
|
|
MG: changed except statements to more verbosity
|
|
|
|
Revision 1.55 2002/03/31 23:20:38 lazarus
|
|
MG: fixed initial size of TPage
|
|
|
|
Revision 1.54 2002/03/29 14:32:49 lazarus
|
|
MG: further internationalization
|
|
|
|
Revision 1.53 2002/03/25 17:59:20 lazarus
|
|
GTK Cleanup
|
|
Shane
|
|
|
|
Revision 1.52 2002/03/16 21:40:55 lazarus
|
|
MG: reduced size+move messages between lcl and interface
|
|
|
|
Revision 1.51 2002/03/14 23:25:52 lazarus
|
|
MG: fixed TBevel.Create and TListView.Destroy
|
|
|
|
Revision 1.50 2002/03/13 22:48:16 lazarus
|
|
Constraints implementation (first cut) and sizig - moving system rework to
|
|
better match Delphi/Kylix way of doing things (the existing implementation
|
|
worked by acident IMHO :-)
|
|
|
|
Revision 1.49 2002/01/21 14:17:47 lazarus
|
|
MG: added find-block-start and renamed find-block-other-end
|
|
|
|
Revision 1.48 2002/01/01 15:50:15 lazarus
|
|
MG: fixed initial component aligning
|
|
|
|
Revision 1.47 2001/12/31 22:43:00 lazarus
|
|
Added a TViewColumn editor to be used in the object inspector as TViewColumn's property editor.
|
|
Shane
|
|
|
|
Revision 1.46 2001/12/28 15:12:02 lazarus
|
|
MG: LM_SIZE and LM_MOVE messages are now send directly, not queued
|
|
|
|
Revision 1.45 2001/12/20 14:41:20 lazarus
|
|
Fixed setfocus for TComboBox and TMemo
|
|
Shane
|
|
|
|
Revision 1.44 2001/12/08 08:54:45 lazarus
|
|
MG: added TControl.Refresh
|
|
|
|
Revision 1.43 2001/12/07 20:12:15 lazarus
|
|
Added a watch dialog.
|
|
Shane
|
|
|
|
Revision 1.42 2001/11/10 10:48:00 lazarus
|
|
MG: fixed set formicon on invisible forms
|
|
|
|
Revision 1.41 2001/11/09 19:14:23 lazarus
|
|
HintWindow changes
|
|
Shane
|
|
|
|
Revision 1.40 2001/10/31 16:29:22 lazarus
|
|
Fixed the gtk mousemove bug where the control gets the coord's based on it's parent instead of itself.
|
|
Shane
|
|
|
|
Revision 1.39 2001/10/10 17:55:04 lazarus
|
|
MG: fixed caret lost, gtk cleanup, bracket lvls, bookmark saving
|
|
|
|
Revision 1.38 2001/10/07 07:28:33 lazarus
|
|
MG: fixed setpixel and TCustomForm.OnResize event
|
|
|
|
Revision 1.37 2001/10/03 17:34:27 lazarus
|
|
MG: activated TCustomForm.OnCreate event
|
|
|
|
Revision 1.35 2001/08/07 11:05:51 lazarus
|
|
MG: small bugfixes
|
|
|
|
Revision 1.34 2001/06/27 21:43:23 lazarus
|
|
MG: added project bookmark support
|
|
|
|
Revision 1.33 2001/06/15 10:31:06 lazarus
|
|
MG: set longstrings as default
|
|
|
|
Revision 1.32 2001/06/14 14:57:59 lazarus
|
|
MG: small bugfixes and less notes
|
|
|
|
Revision 1.31 2001/06/05 10:32:05 lazarus
|
|
MG: small bugfixes for bitbtn, handles
|
|
|
|
Revision 1.30 2001/05/16 10:00:00 lazarus
|
|
MG: fixed wrong page index in editor closing
|
|
|
|
Revision 1.29 2001/05/13 22:07:08 lazarus
|
|
Implemented BringToFront / SendToBack.
|
|
|
|
Revision 1.28 2001/04/02 14:45:26 lazarus
|
|
MG: bugfixes for TBevel
|
|
|
|
Revision 1.27 2001/03/27 14:27:43 lazarus
|
|
Changes from Nagy Zsolt
|
|
Shane
|
|
|
|
Revision 1.26 2001/03/26 14:58:31 lazarus
|
|
MG: setwindowpos + bugfixes
|
|
|
|
Revision 1.24 2001/03/19 14:38:39 lazarus
|
|
MG: fixed many unreleased DC and GDIObj bugs
|
|
|
|
Revision 1.21 2001/03/12 12:17:02 lazarus
|
|
MG: fixed random function results
|
|
|
|
Revision 1.20 2001/02/28 13:17:33 lazarus
|
|
Added some debug code for the top,left reporting problem.
|
|
Shane
|
|
|
|
Revision 1.19 2001/02/06 20:59:17 lazarus
|
|
Trying to get the last control of the last form focused when a dialog closes.
|
|
Still working on it.
|
|
Shane
|
|
|
|
Revision 1.18 2001/02/06 18:19:37 lazarus
|
|
Shane
|
|
|
|
Revision 1.17 2001/02/06 14:52:47 lazarus
|
|
Changed TSpeedbutton in gtkobject so it erases itself when it's set to visible=false;
|
|
Shane
|
|
|
|
Revision 1.15 2001/02/04 04:18:12 lazarus
|
|
Code cleanup and JITFOrms bug fix.
|
|
Shane
|
|
|
|
Revision 1.14 2001/02/01 19:34:50 lazarus
|
|
TScrollbar created and a lot of code added.
|
|
|
|
It's cose to working.
|
|
Shane
|
|
|
|
Revision 1.13 2001/01/30 18:15:02 lazarus
|
|
Added code for TStatusBar
|
|
I'm now capturing WMPainT and doing the drawing myself.
|
|
Shane
|
|
|
|
Revision 1.12 2001/01/28 21:06:07 lazarus
|
|
Changes for TComboBox events KeyPress Focus.
|
|
Shane
|
|
|
|
Revision 1.11 2001/01/23 23:33:54 lazarus
|
|
MWE:
|
|
- Removed old LM_InvalidateRect
|
|
- did some cleanup in old code
|
|
+ added some comments on gtkobject data (gtkproc)
|
|
|
|
Revision 1.10 2001/01/18 13:27:31 lazarus
|
|
Minor changees
|
|
Shane
|
|
|
|
Revision 1.9 2001/01/15 18:25:51 lazarus
|
|
Fixed a stupid error I caused by using a variable as an index in main.pp and this variable sometimes caused an exception because the index was out of range.
|
|
Shane
|
|
|
|
Revision 1.8 2001/01/12 20:22:09 lazarus
|
|
Shiftstate fixed so it reports ssCtrl and ssShift now.
|
|
You can use Shift-Ctrl-Up and Down to jump to procedures in the code explorer.
|
|
Shane
|
|
|
|
Revision 1.7 2001/01/09 18:23:21 lazarus
|
|
Worked on moving controls. It's just not working with the X and Y coord's I'm getting.
|
|
Shane
|
|
|
|
Revision 1.6 2000/12/29 18:33:54 lazarus
|
|
TStatusBar's create and destroy were not set to override TWinControls so they were never called.
|
|
Shane
|
|
|
|
Revision 1.5 2000/12/29 13:14:05 lazarus
|
|
Using the lresources.pp and registering components.
|
|
This is a major change but will create much more flexibility for the IDE.
|
|
Shane
|
|
|
|
Revision 1.4 2000/12/20 17:35:58 lazarus
|
|
Added GetChildren
|
|
Shane
|
|
|
|
Revision 1.3 2000/09/10 23:08:30 lazarus
|
|
MWE:
|
|
+ Added CreateCompatibeleBitamp function
|
|
+ Updated TWinControl.WMPaint
|
|
+ Added some checks to avoid gtk/gdk errors
|
|
- Removed no fixed warning from GetDC
|
|
- Removed some output
|
|
|
|
Revision 1.2 2000/07/30 21:48:32 lazarus
|
|
MWE:
|
|
= Moved ObjectToGTKObject to GTKProc unit
|
|
* Fixed array checking in LoadPixmap
|
|
= Moved LM_SETENABLED to API func EnableWindow and EnableMenuItem
|
|
~ Some cleanup
|
|
|
|
Revision 1.1 2000/07/13 10:28:28 michael
|
|
+ Initial import
|
|
|
|
Revision 1.16 2000/07/09 20:18:56 lazarus
|
|
MWE:
|
|
+ added new controlselection
|
|
+ some fixes
|
|
~ some cleanup
|
|
|
|
Revision 1.15 2000/06/28 13:11:37 lazarus
|
|
Fixed TNotebook so it gets page change events. Shane
|
|
|
|
Revision 1.14 2000/06/19 18:21:22 lazarus
|
|
Spinedit was never getting created
|
|
Shane
|
|
|
|
Revision 1.13 2000/06/16 13:33:21 lazarus
|
|
Created a new method for adding controls to the toolbar to be dropped onto the form!
|
|
Shane
|
|
|
|
Revision 1.12 2000/06/01 21:53:19 lazarus
|
|
MWE:
|
|
+ Added check for HandleCreated in CMShowHintChanged
|
|
|
|
Revision 1.11 2000/05/27 22:20:55 lazarus
|
|
MWE & VRS:
|
|
+ Added new hint code
|
|
|
|
Revision 1.10 2000/05/17 22:34:07 lazarus
|
|
MWE:
|
|
* Fixed Sizing & events
|
|
|
|
Revision 1.9 2000/05/14 21:56:11 lazarus
|
|
MWE:
|
|
+ added local messageloop
|
|
+ added PostMessage
|
|
* fixed Peekmessage
|
|
* fixed ClientToScreen
|
|
* fixed Flat style of Speedutton (TODO: Draw)
|
|
+ Added TApplicatio.OnIdle
|
|
|
|
Revision 1.8 2000/05/10 22:52:58 lazarus
|
|
MWE:
|
|
= Moved some global api stuf to gtkobject
|
|
|
|
Revision 1.7 2000/05/09 12:52:03 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.6 2000/05/09 02:07:40 lazarus
|
|
Replaced writelns with Asserts. CAW
|
|
|
|
Revision 1.5 2000/05/08 16:07:32 lazarus
|
|
fixed screentoclient and clienttoscreen
|
|
Shane
|
|
|
|
Revision 1.4 2000/04/10 15:05:30 lazarus
|
|
Modified the way the MOuseCapture works.
|
|
Shane
|
|
|
|
Revision 1.2 2000/04/07 16:59:55 lazarus
|
|
Implemented GETCAPTURE and SETCAPTURE along with RELEASECAPTURE.
|
|
Shane
|
|
|
|
Revision 1.1 2000/04/02 20:49:57 lazarus
|
|
MWE:
|
|
Moved lazarus/lcl/*.inc files to lazarus/lcl/include
|
|
|
|
Revision 1.77 2000/03/30 18:07:55 lazarus
|
|
Added some drag and drop code
|
|
Added code to change the unit name when it's saved as a different name. Not perfect yet because if you are in a comment it fails.
|
|
|
|
Shane
|
|
|
|
Revision 1.76 2000/03/21 23:47:33 lazarus
|
|
MWE:
|
|
+ Added TBitmap.MaskHandle & TGraphic.Draw & TBitmap.Draw
|
|
|
|
Revision 1.75 2000/03/15 00:51:58 lazarus
|
|
MWE:
|
|
+ Added LM_Paint on expose
|
|
+ Added forced creation of gdkwindow if needed
|
|
~ Modified DrawFrameControl
|
|
+ Added BF_ADJUST support on DrawEdge
|
|
- Commented out LM_IMAGECHANGED in TgtkObject.IntSendMessage3
|
|
(It did not compile)
|
|
|
|
Revision 1.74 2000/03/14 19:49:05 lazarus
|
|
Modified the painting process for TWincontrol. Now it runs throug it's FCONTROLS list and paints all them
|
|
Shane
|
|
|
|
Revision 1.73 2000/03/09 23:48:10 lazarus
|
|
MWE:
|
|
* Fixed colorcache
|
|
* Fixed black window in new editor
|
|
~ Did some cosmetic stuff
|
|
|
|
From Peter Dyson <peter@skel.demon.co.uk>:
|
|
+ Added Rect api support functions
|
|
+ Added the start of ScrollWindowEx
|
|
|
|
Revision 1.72 2000/03/08 23:57:39 lazarus
|
|
MWE:
|
|
Added SetSysColors
|
|
Fixed TEdit text bug (thanks to hans-joachim ott <hjott@compuserve.com>)
|
|
Finished GetKeyState
|
|
Added changes from Peter Dyson <peter@skel.demon.co.uk>
|
|
- a new GetSysColor
|
|
- some improvements on ExTextOut
|
|
|
|
Revision 1.71 2000/03/03 22:58:27 lazarus
|
|
MWE:
|
|
Fixed focussing problem.
|
|
LM-FOCUS was bound to the wrong signal
|
|
Added GetKeyState api func.
|
|
Now LCL knows if shift/trl/alt is pressed (might be handy for keyboard
|
|
selections ;-)
|
|
|
|
Revision 1.70 2000/03/01 00:41:03 lazarus
|
|
MWE:
|
|
Fixed updateshowing problem
|
|
Added some debug code to display the name of messages
|
|
Did a bit of cleanup in main.pp to get the code a bit more readable
|
|
(my editor does funny things with tabs if the indent differs)
|
|
|
|
Revision 1.69 2000/02/28 00:15:54 lazarus
|
|
MWE:
|
|
Fixed creation of visible componets at runtime. (when a new editor
|
|
was created it didn't show up)
|
|
Made the hiding/showing of controls more delphi compatible
|
|
|
|
Revision 1.68 2000/02/26 23:31:50 lazarus
|
|
MWE:
|
|
Fixed notebook crash on insert
|
|
Fixed loadfont problem for win32 (tleast now a fontname is required)
|
|
|
|
Revision 1.67 2000/02/25 19:28:34 lazarus
|
|
Played with TNotebook to see why it crashes when I add a tab and the tnotebook is showing. Havn't figured it out
|
|
Shane
|
|
|
|
Revision 1.66 2000/02/22 23:26:13 lazarus
|
|
MWE: Fixed cursor movement in editor
|
|
Started on focus problem
|
|
|
|
Revision 1.65 2000/02/22 22:19:50 lazarus
|
|
TCustomDialog is a descendant of TComponent.
|
|
Initial cuts a form's proper Close behaviour.
|
|
|
|
Revision 1.64 2000/02/22 17:32:49 lazarus
|
|
Modified the ShowModal call.
|
|
For TCustomForm is simply sets the visible to true now and adds fsModal to FFormState. In gtkObject.inc FFormState is checked. If it contains fsModal then either gtk_grab_add or gtk_grab_remove is called depending on the value of VISIBLE.
|
|
|
|
The same goes for TCustomDialog (open, save, font, color).
|
|
I moved the Execute out of the individual dialogs and moved it into TCustomDialog and made it virtual because FONT needs to set some stuff before calling the inherited execute.
|
|
Shane
|
|
|
|
Revision 1.63 2000/02/20 20:13:47 lazarus
|
|
On my way to make alignments and stuff work :-)
|
|
|
|
Revision 1.62 2000/02/19 18:11:59 lazarus
|
|
More work on moving, resizing, forms' border style etc.
|
|
|
|
Revision 1.61 2000/02/18 19:38:53 lazarus
|
|
Implemented TCustomForm.Position
|
|
Better implemented border styles. Still needs some tweaks.
|
|
Changed TComboBox and TListBox to work again, at least partially.
|
|
Minor cleanups.
|
|
|
|
Revision 1.60 2000/01/18 21:47:00 lazarus
|
|
Added OffSetRec
|
|
|
|
Revision 1.59 2000/01/10 00:07:13 lazarus
|
|
MWE:
|
|
Added more scrollbar support for TWinControl
|
|
Most signals for TWinContorl are jet connected to the wrong widget
|
|
(now scrolling window, should be fixed)
|
|
Added some cvs entries
|
|
|
|
Revision 1.58 2000/01/04 21:00:34 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.57 2000/01/03 00:19:21 lazarus
|
|
MWE:
|
|
Added keyup and buttonup events
|
|
Added LM_MOUSEMOVE callback
|
|
Started with scrollbars in editor
|
|
|
|
Revision 1.56 2000/01/02 00:29:27 lazarus
|
|
Stoppok:
|
|
- safety check if fCompStyle <> csNone before call to CreateHandle
|
|
|
|
Revision 1.55 1999/12/31 14:58:01 lazarus
|
|
MWE:
|
|
Set unkown VK_ codesto 0
|
|
Added pfDevice support for bitmaps
|
|
|
|
Revision 1.54 1999/12/23 21:48:13 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.52 1999/12/22 01:16:04 lazarus
|
|
MWE:
|
|
Changed/recoded keyevent callbacks
|
|
We Can Edit!
|
|
Commented out toolbar stuff
|
|
|
|
Revision 1.51 1999/12/21 21:35:54 lazarus
|
|
committed the latest toolbar code. Currently it doesn't appear anywhere and I have to get it to add buttons correctly through (I think) setstyle. I think I'll implement the LM_TOOLBARINSERTBUTTON call there.
|
|
Shane
|
|
|
|
Revision 1.50 1999/12/21 00:07:06 lazarus
|
|
MWE:
|
|
Some fixes
|
|
Completed a bit of DraWEdge
|
|
|
|
Revision 1.49 1999/12/20 21:01:14 lazarus
|
|
Added a few things for compatability with Delphi and TToolbar
|
|
Shane
|
|
|
|
Revision 1.48 1999/12/18 18:27:32 lazarus
|
|
MWE:
|
|
Rearranged some events to get a LM_SIZE, LM_MOVE and LM_WINDOWPOSCHANGED
|
|
Initialized the TextMetricstruct to zeros to clear unset values
|
|
Get mwEdit to show more than one line
|
|
Fixed some errors in earlier commits
|
|
|
|
Revision 1.47 1999/12/14 21:16:26 lazarus
|
|
Added Autosize to TControl
|
|
Shane
|
|
|
|
Revision 1.46 1999/12/14 00:16:43 lazarus
|
|
MWE:
|
|
Renamed LM... message handlers to WM... to be compatible and to
|
|
get more edit parts to compile
|
|
Started to implement GetSystemMetrics
|
|
Removed some Lazarus specific parts from mwEdit
|
|
|
|
Revision 1.45 1999/12/10 00:47:01 lazarus
|
|
MWE:
|
|
Fixed some samples
|
|
Fixed Dialog parent is no longer needed
|
|
Fixed (Win)Control Destruction
|
|
Fixed MenuClick
|
|
|
|
Revision 1.44 1999/12/08 21:42:37 lazarus
|
|
Moved more messages over to wndproc.
|
|
Shane
|
|
|
|
Revision 1.43 1999/12/08 00:56:07 lazarus
|
|
MWE:
|
|
Fixed menus. Events aren't enabled yet (dumps --> invalid typecast ??)
|
|
|
|
Revision 1.42 1999/12/07 01:19:26 lazarus
|
|
MWE:
|
|
Removed some double events
|
|
Changed location of SetCallBack
|
|
Added call to remove signals
|
|
Restructured somethings
|
|
Started to add default handlers in TWinControl
|
|
Made some parts of TControl and TWinControl more delphi compatible
|
|
... and lots more ...
|
|
|
|
|
|
Revision 1.41 1999/12/03 00:26:47 lazarus
|
|
MWE:
|
|
fixed control location
|
|
added gdiobject reference counter
|
|
|
|
Revision 1.40 1999/12/02 19:00:59 lazarus
|
|
MWE:
|
|
Added (GDI)Pen
|
|
Changed (GDI)Brush
|
|
Changed (GDI)Font (color)
|
|
Changed Canvas to use/create pen/brush/font
|
|
Hacked mwedit to allow setting the number of chars (till it get a WM/LM_SIZE event)
|
|
The editor shows a line !
|
|
|
|
Revision 1.39 1999/11/30 21:30:06 lazarus
|
|
Minor Issues
|
|
Shane
|
|
|
|
Revision 1.38 1999/11/25 23:45:08 lazarus
|
|
MWE:
|
|
Added font as GDIobject
|
|
Added some API testcode to testform
|
|
Commented out some more IFDEFs in mwCustomEdit
|
|
|
|
Revision 1.37 1999/11/19 01:09:43 lazarus
|
|
MWE:
|
|
implemented TCanvas.CopyRect
|
|
Added StretchBlt
|
|
Enabled creation of TCustomControl.Canvas
|
|
Added a temp hack in TWinControl.Repaint to get a LM_PAINT
|
|
|
|
Revision 1.36 1999/11/17 01:16:40 lazarus
|
|
MWE:
|
|
Added some more API stuff
|
|
Added an initial TBitmapCanvas
|
|
Added some DC stuff
|
|
Changed and commented out, original gtk linedraw/rectangle code. This
|
|
is now called through the winapi wrapper.
|
|
|
|
Revision 1.35 1999/11/05 17:48:17 lazarus
|
|
Added a mwedit1 component to lazarus (MAIN.PP)
|
|
It crashes on create.
|
|
Shane
|
|
|
|
Revision 1.34 1999/11/04 21:52:08 lazarus
|
|
wndproc being used a little
|
|
Shane
|
|
|
|
Revision 1.33 1999/11/01 01:28:30 lazarus
|
|
MWE: Implemented HandleNeeded/CreateHandle/CreateWND
|
|
Now controls are created on demand. A call to CreateComponent shouldn't
|
|
be needed. It is now part of CreateWnd
|
|
|
|
Revision 1.32 1999/10/30 17:03:15 lazarus
|
|
MWE: Typo
|
|
|
|
Revision 1.31 1999/10/30 16:42:12 lazarus
|
|
MWE: Moved the Parent <> self check to the Parent property
|
|
|
|
Revision 1.30 1999/10/30 12:30:02 peter
|
|
* fixed some stupid crashes
|
|
|
|
Revision 1.29 1999/10/28 23:48:57 lazarus
|
|
MWE: Added new menu classes and started to use handleneeded
|
|
|
|
Revision 1.28 1999/10/28 19:25:10 lazarus
|
|
Added a ton of messaging stuff
|
|
Shane
|
|
|
|
Revision 1.27 1999/10/28 17:17:43 lazarus
|
|
Removed references to FCOmponent.
|
|
Shane
|
|
|
|
Revision 1.26 1999/10/27 17:27:08 lazarus
|
|
Added alot of changes and TODO: statements
|
|
shane
|
|
|
|
Revision 1.25 1999/10/25 21:07:49 lazarus
|
|
Many changes for compatability made again..
|
|
|
|
Shane
|
|
|
|
Revision 1.24 1999/10/25 17:38:52 lazarus
|
|
More stuff added for compatability. Most stuff added was put in the windows.pp file. CONST scroll bar messages and such. 2 functions were also added to that unit that needs to be completed.
|
|
Shane
|
|
|
|
Revision 1.23 1999/10/25 15:33:54 lazarus
|
|
Added a few more procedures for compatability.
|
|
Shane
|
|
|
|
Revision 1.22 1999/10/22 18:56:36 lazarus
|
|
Fixed a linking error in wincontrol.inc
|
|
Shane
|
|
|
|
Revision 1.21 1999/10/22 18:39:43 lazarus
|
|
Added kEYUP- KeyPress - Keydown, etc.
|
|
|
|
Shane
|
|
|
|
Revision 1.20 1999/10/20 21:08:16 lazarus
|
|
added OnDblClick, OnShowHint, OnParentShowHint, etc for compatability.
|
|
|
|
Revision 1.18 1999/09/30 21:59:03 lazarus
|
|
MWE: Fixed TNoteBook problems
|
|
Modifications: A few
|
|
- Removed some debug messages
|
|
+ Added some others
|
|
* changed fixed widged of TPage. Code is still broken.
|
|
+ TWinControls are also added to the Controls collection
|
|
+ Added TControl.Controls[] property
|
|
|
|
Revision 1.17 1999/09/26 13:30:15 lazarus
|
|
|
|
Implemented OnEnter & OnExit events for TTrackbar. These properties
|
|
and handler functions have been added to TWincontrol, two new
|
|
callbacks have been added to gtkcallback.
|
|
stoppok
|
|
|
|
Revision 1.16 1999/09/17 23:12:58 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.15 1999/09/15 03:17:32 lazarus
|
|
Changes to Editor.pp
|
|
If the text was actually displayed, then it would work better. :-)
|
|
|
|
Revision 1.14 1999/09/15 02:14:44 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.13 1999/09/11 12:16:16 lazarus
|
|
Fixed a bug in key press evaluation. Initial cut at Invalidate problem.
|
|
|
|
Revision 1.12 1999/08/26 23:36:03 peter
|
|
+ paintbox
|
|
+ generic keydefinitions and gtk conversion
|
|
* gtk state -> shiftstate conversion
|
|
|
|
Revision 1.11 1999/08/24 21:26:53 lazarus
|
|
*** empty log message ***
|
|
|
|
Revision 1.9 1999/08/16 15:48:50 lazarus
|
|
Changes by file:
|
|
Control: TCOntrol-Function GetRect added
|
|
ClientRect property added
|
|
TImageList - Added Count
|
|
TWinControl- Function Focused added.
|
|
Graphics: TCanvas - CopyRect added - nothing finished on it though
|
|
Draw added - nothing finiushed on it though
|
|
clbtnhighlight and clbtnshadow added. Actual color values not right.
|
|
IMGLIST.PP and IMGLIST.INC files added.
|
|
|
|
A few other minor changes for compatability added.
|
|
|
|
Shane
|
|
|
|
Revision 1.8 1999/08/12 18:36:58 lazarus
|
|
Added a bunch of "stuff" for compatablility. Not sure if it'll all compile yet, will look at that shortly.
|
|
|
|
Revision 1.7 1999/08/11 20:41:35 lazarus
|
|
|
|
Minor changes and additions made. Lazarus may not compile due to these changes
|
|
|
|
Revision 1.6 1999/08/07 17:59:25 lazarus
|
|
|
|
buttons.pp the DoLeave and DoEnter were connected to the wrong
|
|
event.
|
|
|
|
The rest were modified to use the new SendMessage function. MAH
|
|
|
|
Revision 1.5 1999/07/31 14:27:04 peter
|
|
* mouse fixes
|
|
* wheel support
|
|
|
|
Revision 1.4 1999/07/31 06:39:32 lazarus
|
|
|
|
Modified the IntSendMessage3 to include a data variable. It isn't used
|
|
yet but will help in merging the Message2 and Message3 features.
|
|
|
|
Adjusted TColor routines to match Delphi color format
|
|
|
|
Added a TGdkColorToTColor routine in gtkproc.inc
|
|
|
|
Finished the TColorDialog added to comDialog example. MAH
|
|
|
|
}
|