|
|
导航: |
论坛 -> DELPHI技术
斑竹:liumazi,sephil |
|
作者: |
|
2018/10/19 15:03:48 |
标题: |
子窗体的OnResize会触发2次,各位有啥好办法? |
浏览:1151 |
|
加入我的收藏 |
楼主: |
当窗体的属性为子窗体,在OnResize事件会触发2次,如何解决只触发一次? 测试代码如下: //主窗体 unit Unit4;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit5, Vcl.Menus;
type TForm4 = class(TForm) MainMenu1: TMainMenu; aaaaaa1: TMenuItem; bbbbb1: TMenuItem; procedure bbbbb1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.bbbbb1Click(Sender: TObject); var fm:TForm5; begin fm:= TForm5.Create(nil); fm.Show; end;
end.
//子窗体
unit Unit5;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type TForm5 = class(TForm) mmo: TMemo; procedure FormResize(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form5: TForm5;
implementation
{$R *.dfm} {$J+} procedure TForm5.FormResize(Sender: TObject); const i: integer=0 ; begin mmo.Lines.Add(IntToStr(i)); i:=i+1; end; {$J-} end.
----------------------------------------------
========== |
作者: |
|
2018/10/19 15:09:21 |
1楼: |
测试项目文件:OnResize.rar
----------------------------------------------
==========
|
作者: |
|
2018/10/20 9:06:16 |
2楼: |
很久很久以前貌似有微软的ide开发人员说过,程序员很大程度是在避坑,而不是在跳坑,更不要在坑里转来转去。 那么,有什么东西非得放这里不可呢?
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。又不靠它 delphi 吃饭,怕甚?
|
作者: |
|
2018/10/20 10:29:30 |
3楼: |
to:sail2000 (小帆工作室) 确实是能够避开的就避开。 由于项目需要根据窗体重新绘制图形,且绘制耗时较多,尚未找到其它方案,如果您能给出替代方案就最好了,我也一直在寻找其它方案。 谢谢!
----------------------------------------------
==========
|
作者: |
|
2018/10/20 10:51:18 |
4楼: |
相信我 你能想出来的办法 或者是 确实能解决的办法 也绝对是歪门邪道。
譬如 用计数器第一次Exit 第二 todo 并且计数清零 这样的结果就是 你必须保证每次都会触发两次 否则可能造成BUG 接着 第二个维护你的代码的人 在没看到注释 或者即使看到注释 也无法理解 同样掉进坑里去
----------------------------------------------
-
|
作者: |
|
2018/10/20 11:23:55 |
5楼: |
to: pankangkang (aaaa) 谢谢您的参与! OnResize的行为:当窗体变为最大化时,触发2次,从最大变为普通时,触发1次,在普通状态下变更大小时触发1次,因此不是每次都时2次触发。 如果不放在OnResize事件上处理,还可以用哪些其它方案?欢迎更多的人参与。
谢谢!
----------------------------------------------
==========
|
作者: |
go_on (go_on) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2018/10/20 11:26:26 |
6楼: |
定时查询窗体大小,有变化就重绘
----------------------------------------------
www.eudn.cn工程师联合开发网
|
作者: |
|
2018/10/20 11:30:27 |
7楼: |
你重绘窗口去抓resize做什么?
----------------------------------------------
--
|
作者: |
|
2018/10/20 11:45:36 |
8楼: |
to:go_on (go_on) 子窗体在最大化的2次触发中,窗体的width和Height也不一样,在HD显示器上是差4个像素。 窗体大小变化,是客户在使用过程中重排窗口,变更窗口大小,因此感觉定时处理不太合适。 谢谢!
----------------------------------------------
==========
|
作者: |
|
2018/10/20 11:47:48 |
9楼: |
to:bahamut8348 (leonna) 就是在窗口变化时要重新绘制上面的曲线和图形。你有更好的方案,放在哪里处理呢? 谢谢!
----------------------------------------------
==========
|
作者: |
|
2018/10/20 12:23:02 |
10楼: |
@ smartdata (smartdata) 新建一个初始化过程,放入Public处,比如:Form5.Init,然后将所有计算、绘制内容的放入去,然后根据需求调用。
如果窗体的OnReSize有问题就放入某个panel的OnPaint处。 如果只执行一次就放入OnCreat,总有一个地方是没问题。
另外你确认你的代码没有问题? const i: integer=0 ; begin mmo.Lines.Add(IntToStr(i)); i:=i+1; end;
i定义为常量,可以i+1吗?
----------------------------------------------
-
|
作者: |
|
2018/10/20 12:39:13 |
11楼: |
重绘窗口都是去处理wm_paint消息的。本身这个消息就会告诉你窗口到底哪个区域需要被刷新。
----------------------------------------------
--
|
作者: |
|
2018/10/20 14:59:05 |
12楼: |
to:nickemma (N.E) 谢谢您的建议!项目中的绘制操作是在一个单独的函数中进行的。 刚才测试,发现Panel 没有OnPaint事件,只有OnResize,且其行为和窗体的一样。 另外:const需要加编译开关{$J+}/{$J-}才可以,之所以要用const,是要显示每次在Resize时会执行的次数。下面的代码仅仅是用来观察OnResize的。 {$J+} procedure TForm5.FormResize(Sender: TObject); const i: integer=0 ; begin mmo.Lines.Add(IntToStr(i)); i:=i+1; end; {$J-}
谢谢!
----------------------------------------------
==========
|
作者: |
|
2018/10/20 17:32:19 |
13楼: |
@ smartdata (smartdata) 大意了,没有看清楚你的标题(“子窗体”字眼)。看了你的代码才知道。现在把您的问题明晰如下: 1、Form4 FormStyle设置为“父MDI窗口”,即:fsMDIForm 2、Form5 FormStyle设置为“子MDI窗口”,即:fsMDIChild
问题: Form4创建Form5后。在Form5在窗口放大时OnReSize会触发两次。但Form5的FormStyle如果设置为fsNormal则正常。
我猜想应该是“MDI子窗体”设计问题,究竟是微软的设计问题?还是Delphi的设计问题?还是本来就是Delphi的Bug? 懒得去深究。
我的跳坑方法: 把计算、绘制内容放入一个有OnPaint属性的控件内,经测试正常。
其中放入OnPaint内会产生另外一个效果:父窗体如果进行缩放动作亦将会触发子窗体的OnPaint,还需要跳一个坑。总之附件代码内已作相应处理,效果符合你的要求了。而且我这种方法更好,在子窗体Minimized和恢复的过程都不会再触发。
另外再提醒你一点,引用单元用相对路径啦,用鬼绝对路径么。
----------------------------------------------
-
|
作者: |
|
2018/10/21 12:08:02 |
14楼: |
to:nickemma (N.E) 谢谢! 你这个确实跳出了这个坑!
----------------------------------------------
==========
|
作者: |
|
2018/10/21 12:49:22 |
15楼: |
to:nickemma (N.E) 有意思的是: 当将PaintBox1的Width和Height都设置为1时,坑又出现了
----------------------------------------------
==========
|
|