Left aligned Tabsheets on JvgPageControl Delphi + Vcl Styles Enabled Issue - delphi

On Windows default appearance the tabsheet caption are showed in horizontal (left to right 1) and with the VCL styles enabled they are displayed in vertical (down to top[2]). How I can fix this on Delphi XE5?
Detail: I'm using the JvgPageControl component, from JEDI-VCL 3.58.
I want to create an similar interface of DisplayFusion welcome screen [3]. Suggestions are welcome!
Images:
Thanks in advance!

The TJvgPageControl uses the same vcl style hook (TTabControlStyleHook) of the TPageControl control, so you must create a new style hook inherited from the TTabControlStyleHook and override the DrawTab method.
Check this basic implementation for the new style hook
type
TTabControlStyleHookExt = class(TTabControlStyleHook)
protected
procedure DrawTab(Canvas: TCanvas; Index: Integer); override;
end;
TCustomTabControlClass = class(TCustomTabControl);
{ TTabControlStyleHookExt }
procedure TTabControlStyleHookExt.DrawTab(Canvas: TCanvas; Index: Integer);
var
R, LayoutR, GlyphR: TRect;
ImageWidth, ImageHeight, ImageStep : Integer;
LDrawState: TThemedTab;
LDetails: TThemedElementDetails;
ThemeTextColor: TColor;
FImageIndex: Integer;
begin
if TabPosition <> tpLeft then
begin
inherited ;
exit;
end;
if (Images <> nil) and (Index < Images.Count) then
begin
ImageWidth := Images.Width;
ImageHeight := Images.Height;
ImageStep := 3;
end
else
begin
ImageWidth := 0;
ImageHeight := 0;
ImageStep := 0;
end;
R := TabRect[Index];
if R.Left < 0 then Exit;
if Index = TabIndex then
Dec(R.Left, 2)
else
Dec(R.Right, 2);
Canvas.Font.Assign(TCustomTabControlClass(Control).Font);
LayoutR := R;
if Index = TabIndex then
LDrawState := ttTabItemLeftEdgeSelected
else if (Index = HotTabIndex) and MouseInControl then
LDrawState := ttTabItemLeftEdgeHot
else
LDrawState := ttTabItemLeftEdgeNormal;
LDetails := StyleServices.GetElementDetails(LDrawState);
StyleServices.DrawElement(Canvas.Handle, LDetails, R);
{ Image }
if Control is TCustomTabControl then
FImageIndex := TCustomTabControlClass(Control).GetImageIndex(Index)
else
FImageIndex := Index;
if (Images <> nil) and (FImageIndex >= 0) and (FImageIndex < Images.Count) then
begin
GlyphR := LayoutR;
GlyphR.Bottom := GlyphR.Bottom - ImageStep;
GlyphR.Top := GlyphR.Bottom - ImageHeight;
LayoutR.Bottom := GlyphR.Top;
GlyphR.Left := GlyphR.Left + (GlyphR.Right - GlyphR.Left) div 2 - ImageWidth div 2;
if StyleServices.Available then
StyleServices.DrawIcon(Canvas.Handle, LDetails, GlyphR, Images.Handle, FImageIndex);
end;
{ Text }
if StyleServices.GetElementColor(LDetails, ecTextColor, ThemeTextColor) then
Canvas.Font.Color := ThemeTextColor;
//use the top tab style to draw the text
if Index = TabIndex then
LDetails := StyleServices.GetElementDetails(ttTabItemSelected)
else
if (Index = HotTabIndex) and MouseInControl then
LDetails := StyleServices.GetElementDetails(ttTabItemHot)
else
LDetails := StyleServices.GetElementDetails(ttTabItemNormal);
DrawControlText(Canvas, LDetails, Tabs[Index], LayoutR, DT_VCENTER or DT_CENTER or DT_SINGLELINE or DT_NOCLIP);
end;
Then register the new style hook like this
initialization
TStyleEngine.RegisterStyleHook(TJvgPageControl, TTabControlStyleHookExt);

Related

How to get icon for hidden file (like Explorer) for ListView in Delphi?

I useSHGetFileInfo('', 0, aFileInfo, SizeOf(TSHFileInfo), SHGFI_ICON or SHGFI_SYSICONINDEX) to extract an icon list in TImageList and then associate index with TListView. Which flag I must use to get hidden style like Explorer?
To the best of my knowledge, the system does not offer such functionality. You need to create faded icons yourself, based on the original icon. You can use a function along these lines to do that:
function CreateFadedIcon(Icon: HICON): HICON;
type
TRGBA = record
B,G,R,A: Byte
end;
procedure InitialiseBitmapInfoHeader(Width, Height: Integer; var bih: BITMAPINFOHEADER);
begin
bih.biSize := SizeOf(BITMAPINFOHEADER);
bih.biWidth := Width;
bih.biHeight := 2*Height;//height of xor bitmap plus height of and bitmap
bih.biPlanes := 1;
bih.biBitCount := 32;
bih.biCompression := BI_RGB;
end;
procedure CreateXORbitmap(const sbih, dbih: BITMAPINFOHEADER; sptr, dptr: PDWORD);
var
i, j: Integer;
begin
for i := 0 to sbih.biHeight-1 do begin
for j := 0 to sbih.biWidth-1 do begin
dptr^ := sptr^;
TRGBA(dptr^).A := TRGBA(dptr^).A div 3;
inc(dptr);//relies on the fact that no padding is needed for RGBA scanlines
inc(sptr);//likewise
end;
end;
end;
var
IconInfo: TIconInfo;
sBits, xorBits: PDWORD;
xorScanSize, andScanSize: Integer;
xorBitsSize, andBitsSize: Integer;
sbih: BITMAPINFOHEADER;
dbih: ^BITMAPINFOHEADER;
resbitsSize: DWORD;
resbits: Pointer;
begin
Result := 0;
Try
if not GetIconInfo(Icon, IconInfo) then begin
exit;
end;
Try
GetDIBheaderAndBits(IconInfo.hbmColor, sbih, Pointer(sBits));
if Assigned(sBits) then begin
Try
if (sbih.biPlanes<>1) or (sbih.biBitCount<>32) then begin
exit;
end;
xorScanSize := BytesPerScanline(sbih.biWidth, 32, 32);
Assert(xorScanSize=SizeOf(DWORD)*sbih.biWidth);
andScanSize := BytesPerScanline(sbih.biWidth, 1, 32);
xorBitsSize := sbih.biHeight*xorScanSize;
andBitsSize := sbih.biHeight*andScanSize;
resbitsSize := SizeOf(BITMAPINFOHEADER) + xorBitsSize + andBitsSize;
resbits := AllocMem(resbitsSize);//AllocMem zeroises the memory
Try
dbih := resbits;
InitialiseBitmapInfoHeader(sbih.biWidth, sbih.biHeight, dbih^);
xorBits := resbits;
inc(PByte(xorBits), SizeOf(BITMAPINFOHEADER));
CreateXORbitmap(sbih, dbih^, sBits, xorBits);
//don't need to fill in the mask bitmap when using RGBA
Result := CreateIconFromResourceEx(resbits, resbitsSize, True, $00030000, sbih.biWidth, sbih.biHeight, LR_DEFAULTCOLOR);
Finally
FreeMem(resbits);
End;
Finally
FreeMem(sBits);
End;
end;
Finally
if IconInfo.hbmMask<>0 then begin
DeleteObject(IconInfo.hbmMask);
end;
if IconInfo.hbmColor<>0 then begin
DeleteObject(IconInfo.hbmColor);
end;
End;
Finally
DestroyIcon(Icon);
End;
end;

TListView scrolling bug when using VCL Styles - Delphi XE8

I've tried to set TListView control's direction to RTL by following function:
procedure RTL_LV(lv:TListView);
const
LVM_FIRST = $1000;
LVM_GETHEADER = LVM_FIRST + 31;
var
header: THandle;
begin
header:= SendMessage (lv.Handle, LVM_GETHEADER, 0, 0);
SetWindowLong (header, GWL_EXSTYLE,
GetWindowLong (header, GWL_EXSTYLE) or
WS_EX_LAYOUTRTL or WS_EX_NOINHERITLAYOUT);
SetWindowLong (lv.Handle, GWL_EXSTYLE,
GetWindowLong (lv.Handle, GWL_EXSTYLE) or
WS_EX_LAYOUTRTL or WS_EX_NOINHERITLAYOUT);
lv.invalidate;
end;
But I have two problems as follows when the project uses VCL Styles:
1: Vertical scrollbar not appearing without clicking on it.
2: When i change the size of the ListView columns and the horizontal scrollbar is clicked, the following error message is displayed:
Exception source: Vcl.ComCtrls.TListViewStyleHook.WMMouseMove
procedure TListViewStyleHook.WMMouseMove(var Message: TWMMouse);
var
SF: TScrollInfo;
SPos: Integer;
R: TRect;
begin
if VertSliderState = tsThumbBtnVertPressed then
begin
SF.fMask := SIF_ALL;
SF.cbSize := SizeOf(SF);
GetScrollInfo(Handle, SB_VERT, SF);
ScrollPos := ScrollPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.Y - PrevScrollPos) / VertTrackRect.Height);
PrevScrollPos := Mouse.CursorPos.Y;
if Control is TCustomListView then
begin
PostMessage(Handle, WM_VSCROLL, Integer(SmallPoint(SB_THUMBTRACK, Round(ScrollPos))), 0);
if TCustomListView(Control).ViewStyle = vsReport then
begin
if (Abs(ScrollPos - ListPos) >= 1) or
((ScrollPos = SF.nMin) and (ListPos <> ScrollPos)) or
((ScrollPos = SF.nMax) and (ListPos <> ScrollPos)) then
begin
if TCustomListView(Control).GroupView then
begin
SPos := Round(ScrollPos - ListPos);
if SF.nPos + SPos < 0 then SPos := -SF.nPos;
end
else
begin
ListView_GetItemRect(Handle, 0, R, LVIR_BOUNDS);
SPos := Round((ScrollPos - ListPos) * R.Height);
end;
ListView_Scroll(Handle, 0, SPos);
ListPos := ScrollPos;
end;
end
else
begin
if Abs(ScrollPos - ListPos) >= 1 then
begin
ListView_Scroll(Handle, 0, Round((ScrollPos - ListPos)));
ListPos := ScrollPos;
end;
end;
end
else
PostMessage(Handle, WM_VSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(ScrollPos))), 0);
PaintScroll;
Handled := True;
Exit;
end;
if HorzSliderState = tsThumbBtnHorzPressed then
begin
SF.fMask := SIF_ALL;
SF.cbSize := SizeOf(SF);
GeTScrollInfo(Handle, SB_HORZ, SF);
ScrollPos := ScrollPos + (SF.nMax - SF.nMin) * ((Mouse.CursorPos.X - PrevScrollPos) / HorzTrackRect.Width);
if ScrollPos < SF.nMin then
ScrollPos := SF.nMin;
if ScrollPos > SF.nMax then
ScrollPos := SF.nMax;
PrevScrollPos := Mouse.CursorPos.X;
if Control is TCustomListView then
begin
if TCustomListView(Control).ViewStyle = vsReport then
begin
if Abs(ScrollPos - ListPos) >= 1 then
begin
ListView_Scroll(Handle, Round((ScrollPos - ListPos)), 0);
ListPos := ScrollPos;
end;
end
else
begin
if Abs(ScrollPos - ListPos) >= 0.5 then
begin
ListView_Scroll(Handle, Round((ScrollPos - ListPos)), 0);
ListPos := ScrollPos;
end;
end;
end
else
PostMessage(Handle, WM_HSCROLL, Integer(SmallPoint(SB_THUMBPOSITION, Round(ScrollPos))), 0);
PaintScroll;
Handled := True;
Exit;
end;
if (HorzSliderState <> tsThumbBtnHorzPressed) and (HorzSliderState = tsThumbBtnHorzHot) then
begin
HorzSliderState := tsThumbBtnHorzNormal;
PaintScroll;
end;
if (VertSliderState <> tsThumbBtnVertPressed) and (VertSliderState = tsThumbBtnVertHot) then
begin
VertSliderState := tsThumbBtnVertNormal;
PaintScroll;
end;
if (HorzUpState <> tsArrowBtnLeftPressed) and (HorzUpState = tsArrowBtnLeftHot) then
begin
HorzUpState := tsArrowBtnLeftNormal;
PaintScroll;
end;
if (HorzDownState <> tsArrowBtnRightPressed) and (HorzDownState =tsArrowBtnRightHot) then
begin
HorzDownState := tsArrowBtnRightNormal;
PaintScroll;
end;
if (VertUpState <> tsArrowBtnUpPressed) and (VertUpState = tsArrowBtnUpHot) then
begin
VertUpState := tsArrowBtnUpNormal;
PaintScroll;
end;
if (VertDownState <> tsArrowBtnDownPressed) and (VertDownState = tsArrowBtnDownHot) then
begin
VertDownState := tsArrowBtnDownNormal;
PaintScroll;
end;
CallDefaultProc(TMessage(Message));
if LeftButtonDown then
PaintScroll;
Handled := True;
end;
How should this problems be solved?
Thanks.
There are multiple problems with your approach. The quick answer is:
Do not do this. Instead, set the controls's BiDiMode property to bdRightToLeft. Unless I am missing something, that will get you the behavior you need and I tested it now, there are no problems with scrolling with themes this way.
There are two big problems with the way you are tying to do this:
You can't guarantee the control will keep the settings you are forcing into it. The first time the VCL needs to recreate the Window for the control, your settings will be obliterated.
You are assuming that the VCL doesn't need to account for this setting in some way. Clearly it does, because you are getting bad behavior when trying to undercut the VCL and send the style directly to the Window. If you really want to directly control the window style, you need to create your own descendant of the control class and handle everything related in the proper places-- you can't just pick any old time you want to change the control to RTL with a Windows API call (rather than the control's properties) and expect that the control will continue to work properly.

TTreeView custom draw item width

I use the OnCustomDrawItem event to draw a TTreeView like this :
Here is my code :
procedure Tform1.trvArbreCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
vRect : TRect;
vBmp : TBitmap;
vBmpRect : TRect;
vTreeView : TTreeView;
vBarreInfo : TScrollInfo;
vDeltaX : Integer;
begin
DefaultDraw := False;
vTreeView := TTreeView(Sender);
vRect := Node.DisplayRect(False);
vBmp := TBitmap.Create();
FillChar(vBarreInfo, SizeOF(vBarreInfo), 0);
vBarreInfo.cbSize := SizeOf(vBarreInfo);
vBarreInfo.fMask := SIF_RANGE or SIF_POS;
if GetScrollInfo(trvArbre.Handle, SB_HORZ, vBarreInfo) then
begin
if vBarreInfo.nMax > vRect.Right - vRect.Left then
begin
vBmp.Width := vBarreInfo.nMax + 1;
vBmp.Height := vRect.Bottom - vRect.Top;
vDeltaX := vBarreInfo.nPos;
end
else
begin
vBmp.Width := vRect.Right - vRect.Left;
vBmp.Height := vRect.Bottom - vRect.Top;
vDeltaX := 0;
end;
end
else
begin
vBmp.Width := vRect.Right - vRect.Left;
vBmp.Height := vRect.Bottom - vRect.Top;
vDeltaX := 0;
end;
vBmpRect := Rect(0, 0, vBmp.Width, vBmp.Height);
if cdsSelected in State then
begin
vBmp.Canvas.Brush.Color := cMenuDownFond;
vBmp.Canvas.Pen .Color := cMenuDownBordure;
end
else if cdsHot in State then
begin
vBmp.Canvas.Brush.Color := cMenuSurvolFond;
vBmp.Canvas.Pen .Color := cMenuSurvolBordure;
end
else
begin
vBmp.Canvas.Brush.Color := clWhite;
vBmp.Canvas.Pen .Color := clwhite;
end;
vBmp.Canvas.Rectangle(vBmpRect);
vBmpRect.Left := vBmpRect.Left + 3;
vBmpRect.Left := vBmpRect.Left + (Node.Level * vTreeView.Indent);
if Node.StateIndex >= 0 then
begin
vTreeView.StateImages.Draw(vBmp.Canvas, vBmpRect.Left, vBmpRect.Top, Node.StateIndex);
end;
vBmpRect.Left := vBmpRect.Left + 18;
vTreeView.Images.Draw(vBmp.Canvas, vBmpRect.Left, vBmpRect.Top, Node.ImageIndex);
vBmpRect.Left := vBmpRect.Left + 18 + 3;
vBmp.Canvas.Font := vTreeView.Font;
DrawText
(
vBmp.Canvas.Handle,
PChar(Node.Text),
Length(Node.Text),
vBmpRect,
DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_NOPREFIX or DT_END_ELLIPSIS
);
BitBlt
(
Sender.Canvas.Handle,
vRect.Left,
vRect.Top,
vRect.Right - vRect.Left,
vRect.Bottom - vRect.Top,
vBmp.Canvas.Handle,
vDeltaX,
0,
SRCCOPY
);
FreeAndNil(vBmp);
end;
My problem is that the node "My last node wich is not too long" is not too long to justify the presence of the horizontal scrollbar.
When I set DefaultDraw to true I obtain :
It seems that the width of the node is computed with a font I don't use.
I tried to change the font of the canvas, to use Windows API, to use the OnAdvancedCustomDrawItem with no result.
Thanks.
I use Delphi 7. I copied ComCtrls.pas in the folder of my application. I changed procedure TCustomTreeView.CNNotify(var Message: TWMNotify);. Line 8979 from Result := Result or CDRF_SKIPDEFAULT to Result := Result or CDRF_SKIPDEFAULT; and I commented line 8980 else if FCanvasChanged then in order to simulate DefaultDraw=True and FCanvasChanged even if I set DefaultDraw to False in event et don't change font. After a lot of tests, I don't see any caveats.

TImage Not Showing up

When dropping this component onto the form, The TImage is not showing the map image (hexagons) Until i drag the component around on the form , Then it will show it until i stop dragging it around on the form. (this is all in desgin mode). How do i make it show all the time? not when just dragging it.
type
THexMap = Class(TScrollingWinControl)
Constructor
Constructor THexMap.Create(AOwner: Tcomponent);
begin
inherited Create(AOwner);
Width := DEFAULT_MAP_WIDTH;
Height := DEFAULT_MAP_HEIGHT;
FCanvas := timage.Create(self);
tempMap := timage.Create(self);
fcanvas.Parent := self;
tempmap.Parent := self;
fCanvas.Width := DEFAULT_MAP_WIDTH;
fCAnvas.Height := DEFAULT_MAP_WIDTH;
{ Set intial property values for component }
//create map
MakeSolidMap;
end;
MakeSolidMap
Procedure THexMap.MakeSolidMap;
var
p0 : TPoint;
looprow,Loopcol : integer;
begin
TempMap.width := ((HexColumns-1) * round((1.5 * HexRadius))) + (2 * hexRadius);
TempMap.height := ((HexRows) * (2 * rise)) + rise;
With TempMap.Canvas do
begin
{set Background color}
brush.Color := BackColor;
fillrect(rect(0,0,TempMap.Width,TempMap.Height));
{draw Hex's left to right / top to bottom}
for looprow := 1 to HexRows do
begin
for loopcol := 1 to HexColumns do
begin
{compute center coords}
p0 := ConvertCoords(Point(LoopCol,LoopRow),ptROWCOL);
{draw the hex}
DrawSolidHex(Tempmap,bsSolid,hexColor,psSolid,LineColor,P0.X,p0.Y,hexRadius,hex3d);
end;
end;
end;
end;
DrawSoildHex
procedure THexMap.DrawSolidHex(Target: timage;
FillStyle: TBrushStyle;
FillColor: TColor;
LineStyle: TPenStyle;
LineColor: TColor;
x: Integer;
y: Integer;
Radius: Integer;
button: Boolean);
var
p0,p1,p2,p3,p4,p5,p6:TPoint;
begin
p0 := Point(x,y);
{compute each point based on hex center}
p1.X := p0.X - round(Radius /2);
p1.Y := p0.Y - rise;
p2.X := p0.X + round(Radius/2);
p2.Y := p1.Y;
p3.X := p0.X + Radius;
p3.Y := p0.Y;
p4.X := p2.X;
p4.Y := p0.Y + rise;
p5.X := p1.X;
p5.Y := p4.Y;
p6.X := p0.X - Radius;
p6.Y := p0.Y;
{set color / style of lines}
target.canvas.Pen.Color := LineColor;
target.canvas.Pen.Style := LineStyle;
{set color / style of hex}
target.canvas.Brush.Color := FillColor;
Target.canvas.Brush.Style := FillStyle;
{draw the hex}
target.canvas.Polygon([p1,p2,p3,p4,p5,p6]);
{if desired, draw the boarder for the hex}
if button = true then
begin
with target.canvas do
begin
pen.Mode :=pmCopy;
pen.Color :=clWhite;
moveto(p5.X+1,p5.Y-1);
lineto(p6.X+1,p6.Y);
lineto(p1.X+1,p1.Y+1);
lineto(p2.X-1,p2.Y+1);
pen.Color :=clBlack;
lineto(p3.X-1,p3.Y);
lineto(p4.X-1,p4.Y-1);
lineto(p5.X+1,p5.Y-1);
end;
end;
invalidate;
end;
WndProc
procedure THexMap.WndProc(var Message: TMessage);
const
DISCARD_CURRENT_ORIGIN = nil;
var
R : TRect;
PS : PAINTSTRUCT;
begin
if Message.Msg = WM_PAINT then
begin
if GetUpdateRect( Handle, nil, false ) then
begin
BeginPaint( Handle, PS );
try
R := PS.rcPaint;
bitblt(fCanvas.Canvas.Handle, R.Left, R.Top, R.Width, R.Height, TempMap.Canvas.Handle, R.Left+FOffset.X, R.Top+FOffset.Y, SRCCOPY);
finally
EndPaint( Handle, PS );
end;
end
else
inherited;
end
else
inherited;
end;
Nothing shows because you have taken over painting the control by handing WM_PAINT. And in your handling of WM_PAINT you do not paint anything to the device context returned by BeginPaint. You do not call the inherited handler which would call Paint and then paint children. Hence nothing appears in your control.
It seems to me that you need to decide to either use visual controls and let the VCL paint them, or paint your control yourself. You are currently attempting to do both but achieving neither!
I cannot suggest a fix because I've really no idea what you are doing. I don't understand why you have visual controls and override the paint message handler. To go forward you'll need to pick one approach or the other.

AnimateWindow Slide

I want my form slide down and back to position with slide animation, how to make correct AnimateWinows, if it real for sure ...
void __fastcall TUsers::BitBtn1Click(TObject *Sender)
{
if (!pressed)
{
Height=700;
//AnimateWindow(Handle, 500, AW_CENTER | AW_SLIDE | AW_VER_POSITIVE);
pressed=true;
}
else
{
pressed=false;
//AnimateWindow(Handle, 500, AW_CENTER | AW_SLIDE | AW_VER_NEGATIVE);
Height=425;
}
}
to moderators : here is no mutters Builder or Delphi :)
If you are interested in controlling the animation yourself, here is a sample of code we wrote to accomplish that. It looks and works great. We are sliding Tform1 from the right to the left within a TPanel control on the main form. We ensure that Self.Parent and DoubleBuffered gets set correctly in MyCreate. ShiftLeft and then ShiftRight do the work. We ran into a problem for certain users where the Self.Top was being shifted so we are making sure that Self.Top := 0 with each iteration and when fully shifted. That solved all of the weird issues we were seeing.
Hope this helps!
{
TForm1.MyCreate
---------------------------------------------------------------------------
}
constructor TForm1.MyCreate(AOwner: TComponent);
var
OwnerControl: TWinControl;
begin
inherited Create(AOwner);
if Owner is TWinControl then
begin
OwnerControl := Owner as TWinControl;
Self.Parent := OwnerControl;
end;
Self.Visible := false;
Self.DoubleBuffered := true;
Self.BorderStyle := bsNone;
end;
{
TForm1.ShiftLeft
---------------------------------------------------------------------------
}
procedure TForm1.ShiftLeft;
var
TicksStart: int64;
InitLeftValue: integer;
StartLeftValue: integer;
NewLeftValue: integer;
LeftValueDif: integer;
RemainingTicks: int64;
begin
Self.Top := 0;
Self.Height := Self.Parent.ClientHeight;
Self.Width := Self.Parent.ClientWidth;
InitLeftValue := Self.Parent.Left;
StartLeftValue := Self.Parent.Left + Self.Parent.ClientWidth;
LeftValueDif := StartLeftValue - InitLeftValue;
Self.Left := StartLeftValue;
Self.Visible := true;
TicksStart := GetTickCount();
RemainingTicks := FadeTime;
while RemainingTicks > 0 do
begin
NewLeftValue := (LeftValueDif * RemainingTicks) div FadeTime;
Self.Left := Max(InitLeftValue, NewLeftValue);
Self.Parent.Repaint;
Self.Top := 0;
Self.Repaint;
RemainingTicks := FadeTime - int64(GetTickCount - TicksStart);
end;
if Self.Left > InitLeftValue then
Self.Left := InitLeftValue;
Self.Parent.Repaint;
Self.Top := 0;
Self.Repaint;
end;
{
TForm1.ShiftRight
---------------------------------------------------------------------------
}
procedure TForm1.ShiftRight;
var
TicksStart: int64;
StartLeftValue: integer;
EndLeftValue: integer;
NewLeftValue: integer;
LeftValueDif: integer;
RemainingTicks: int64;
begin
Self.Top := 0;
StartLeftValue := Self.Left;
EndLeftValue := Self.Left + Self.Width;
LeftValueDif := EndLeftValue - StartLeftValue;
TicksStart := GetTickCount();
RemainingTicks := FadeTime;
while RemainingTicks > 0 do
begin
NewLeftValue := (LeftValueDif * (FadeTime - RemainingTicks)) div FadeTime;
Self.Left := Max(StartLeftValue, NewLeftValue);
Self.Parent.Repaint;
Self.Top := 0;
Self.Repaint;
RemainingTicks := FadeTime - int64(GetTickCount - TicksStart);
end;
if Self.Left < EndLeftValue then
Self.Left := EndLeftValue;
Self.Parent.Repaint;
Self.Top := 0;
Self.Repaint;
end;
That's not what AnimateWindow is for. That function hides or shows a window using some animation. Your window is already visible, and you want it to stay visible, so AnimateWindow is not for you.
What you should do instead is make your window successively taller or shorter in a loop until you reach the new desired height.
Check the following link for an answer and a cool demo program.
http://delphi.about.com/od/delphi-tips-2011/qt/hide-slide-fade-away-controls-delphi-form.htm

Resources