- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开发了以下 AnimateRects() 方法来在 Windows 桌面上绘制动画矩形。我用它来动画显示模态表单,使它看起来像是从网格单元格中“生长”出来的。
在表单显示之前,我使用 bExpand 参数 = True 调用该方法一次。然后当用户关闭表单时,我再次调用它,但使用 bExpand = False,以显示表单“折叠”到网格单元中。
问题在于 bExpand = False 情况...在循环的第一次迭代中,第一个 调用 Rectangle(r) 会按预期绘制矩形,但就像 第二对 Rectangle(r) 的调用从未被调用——第一个矩形永远不会被异或。因此,在绘制了“折叠”矩形序列之后,我最终将第一个矩形保留为 。神器屏幕上。
任何想法我做错了什么?
const
MSECS_PER_DAY = 24.0 * 60.0 * 60.0 * 1000;
procedure DelayMSecs(msecs: Word);
var
Later: TDateTime;
begin
Later := Now + (msecs / MSECS_PER_DAY);
while Now < Later do begin
Application.ProcessMessages;
sleep(0); //give up remainder of our time slice
end;
end;
procedure T_fmExplore.AnimateRects(ASourceRect, ADestRect: TRect; bExpand:
boolean; bAdjustSourceForFrame: boolean = True);
const
MINSTEPS = 10;
MAXSTEPS = 30;
MAXDELAY = 180; //150 - 200 is about right
MINDELAY = 1;
var
iSteps: integer;
DeltaHt: Integer; //Rect size chg for each redraw of animation window
DeltaWidth: Integer;
DeltaTop : integer; //Origin change for each redraw
DeltaLeft : integer;
NewWidth, NewHt: Integer;
iTemp: Integer;
iDelay: integer;
r : Trect;
ScreenCanvas: TCanvas;
begin
r := ASourceRect;
with r do begin
NewWidth := ADestRect.Right - ADestRect.Left; //Target rect's Width
NewHt := ADestRect.Bottom - ADestRect.Top; //Target rect's Height
//Temporarily, Deltas hold the total chg in Width & Height
DeltaWidth := NewWidth - (Right - Left); //NewWidth - old width
DeltaHt := NewHt - (Bottom - Top);
//With a static number of iSteps, animation was too jerky for large windows.
//So we adjust the number of iSteps & Delay relative to the window area.
iSteps := Max( DeltaWidth * DeltaHt div 6500, MINSTEPS ); //eg. 10 iSteps for 250x250 deltas (62500 pixels)
iSteps := Min( iSteps, MAXSTEPS );
//Now convert Deltas to the delta in window rect size
DeltaWidth := DeltaWidth div iSteps;
DeltaHt := DeltaHt div iSteps;
DeltaTop := (ADestRect.Top - ASourceRect.Top) div iSteps;
DeltaLeft := (ADestRect.Left - ASourceRect.Left) div iSteps;
iDelay := Max( MAXDELAY div iSteps, MINDELAY );
ScreenCanvas := TCanvas.Create;
try
ScreenCanvas.Handle := GetDC( 0 ); //Desktop
try
with ScreenCanvas do begin
Pen.Color := clWhite;
Pen.Mode := pmXOR;
Pen.Style := psSolid;
Pen.Width := GetSystemMetrics(SM_CXFRAME);
Brush.Style := bsClear;
if bAdjustSourceForFrame then
InflateRect(ASourceRect, -Pen.Width, -Pen.Width);
repeat
iTemp := (Bottom - Top) + DeltaHt; //Height
if (bExpand and (iTemp > NewHt)) or (not bExpand and (iTemp < NewHt)) then begin
Top := ADestRect.Top;
Bottom := Top + NewHt;
end else begin
Top := Top + DeltaTop; //Assign Top first...Bottom is calc'd from it
Bottom := Top + iTemp;
end;
iTemp := (Right - Left) + DeltaWidth; //Width
if (bExpand and (iTemp > NewWidth)) or (not bExpand and (iTemp < NewWidth)) then begin
Left := Left + DeltaLeft;
Right := Left + NewWidth;
end else begin
Left := Left + DeltaLeft; //Assign Left first...Right is calc'd from it
Right := Left + iTemp;
end;
ScreenCanvas.Rectangle(r);
SysStuff.DelayMSecs( iDelay );
ScreenCanvas.Rectangle(r); //pmXOR pen ...erase ourself
until (Right - Left = NewWidth) and (Bottom - Top = NewHt);
end;
finally
ReleaseDC( 0, ScreenCanvas.Handle );
ScreenCanvas.Handle := 0;
end;
finally
ScreenCanvas.Free;
end;
end;
end;
最佳答案
问题很可能是您在模态表单仍然可见时开始绘制矩形。有一次,表格从屏幕上消失了,上面有一个矩形,当您绘制相同的矩形以删除前一个矩形时,它现在在屏幕上。请注意,在表单上调用“免费”、“隐藏”等不会立即隐藏它。
(编辑: 这需要一些解释:在下一行代码运行之前表单将被隐藏,但无法保证未覆盖的窗口何时会更新其无效区域 )。
解决方案是 Sleep
在模态窗体关闭之后和 AnimateRects
之前的一段时间被调用,或者可能调用 Application.ProcessMessages
.如果模态表单没有完全在您自己的应用程序的窗口上,后者可能不会有太大帮助。如果模态表单位于同时不断进行自己绘图的应用程序上,前者可能不会有太大帮助。就像任务管理器一样...
编辑:虽然我可能对此不满意,但这个问题正是 LockWindowUpdate
的原因。存在。当您考虑它时,您会发现您所做的与外壳在您移动它时显示窗口的拖动轮廓时所做的没有什么不同(当“拖动时显示窗口内容”被禁用时) .
关于delphi - 为什么带有 pmXOR 笔的 TCanvas.Rectangle() 只能工作 "sometimes"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4806866/
有一条(相对)众所周知的 Perl 公理:“只有 Perl 可以解析 Perl”。我想知道 Perl 6 是否仍然如此? 扩大讨论...考虑到 PyPy 最近的更新,我想到了这个问题。 Perl 独特
这是设置。在上一个问题中,我发现我可以通过子组件中的状态传递对象属性,然后使用 componentDidUpdate 获取该对象属性。在这种情况下,状态和属性都称为到达。 这是基本代码... expo
我运行的是 10.5.2 社区版。我已经标记了 源/主要/资源 作为源目录。我可以右键单击并“编译”某些文件,据我所知,这意味着 IDE 将文件复制到与发送类文件的“com.mydomain.pack
我是一名优秀的程序员,十分优秀!