DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 3
在线用户: 21
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
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.
----------------------------------------------
==========
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/19 15:09:21
1楼: 测试项目文件:OnResize.rar
此帖子包含附件:smartdata_2018101915921.rar 大小:5.7K
----------------------------------------------
==========
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2018/10/20 9:06:16
2楼: 很久很久以前貌似有微软的ide开发人员说过,程序员很大程度是在避坑,而不是在跳坑,更不要在坑里转来转去。
那么,有什么东西非得放这里不可呢?
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。又不靠它 delphi 吃饭,怕甚?
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/20 10:29:30
3楼: to:sail2000 (小帆工作室)
确实是能够避开的就避开。
由于项目需要根据窗体重新绘制图形,且绘制耗时较多,尚未找到其它方案,如果您能给出替代方案就最好了,我也一直在寻找其它方案。
谢谢!
----------------------------------------------
==========
作者:
男 pankangkang (aaaa) ★☆☆☆☆ -
普通会员
2018/10/20 10:51:18
4楼: 相信我  
你能想出来的办法 或者是 确实能解决的办法 也绝对是歪门邪道。

譬如 
用计数器第一次Exit 第二 todo 并且计数清零 
这样的结果就是 你必须保证每次都会触发两次 否则可能造成BUG
接着 第二个维护你的代码的人 在没看到注释 或者即使看到注释 也无法理解 同样掉进坑里去
----------------------------------------------
-
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
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工程师联合开发网
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/10/20 11:30:27
7楼: 你重绘窗口去抓resize做什么?
----------------------------------------------
--
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/20 11:45:36
8楼: to:go_on (go_on)
子窗体在最大化的2次触发中,窗体的width和Height也不一样,在HD显示器上是差4个像素。
窗体大小变化,是客户在使用过程中重排窗口,变更窗口大小,因此感觉定时处理不太合适。
谢谢!
----------------------------------------------
==========
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/20 11:47:48
9楼: to:bahamut8348 (leonna)
就是在窗口变化时要重新绘制上面的曲线和图形。你有更好的方案,放在哪里处理呢?
谢谢!
----------------------------------------------
==========
作者:
男 nickemma (N.E Zhou) ★☆☆☆☆ -
普通会员
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吗?
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/10/20 12:39:13
11楼: 重绘窗口都是去处理wm_paint消息的。本身这个消息就会告诉你窗口到底哪个区域需要被刷新。
----------------------------------------------
--
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
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-}

谢谢!
----------------------------------------------
==========
作者:
男 nickemma (N.E Zhou) ★☆☆☆☆ -
普通会员
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和恢复的过程都不会再触发。

另外再提醒你一点,引用单元用相对路径啦,用鬼绝对路径么。
此帖子包含附件:nickemma_2018102017539.rar 大小:5.5K
----------------------------------------------
-
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/21 12:08:02
14楼: to:nickemma (N.E)
谢谢!
你这个确实跳出了这个坑!
----------------------------------------------
==========
作者:
男 smartdata (Jack) ★☆☆☆☆ -
普通会员
2018/10/21 12:49:22
15楼: to:nickemma (N.E)
有意思的是:
当将PaintBox1的Width和Height都设置为1时,坑又出现了
----------------------------------------------
==========
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行99.60938毫秒 RSS