SOU*_*ser 1 delphi mdichild repaint
综述:
请参阅Andreas的知识渊博的评论!
==========================================
如下面的代码所示,TForm7是MDIForm形式,TForm8是MDIChild形式.TForm8包含一个alClient对齐的面板,它还包含一个TPaintBox.如果TForm8的面板的ParentBackground设置为False,我无法从TForm7触发TForm8的paintbox的绘制事件.我想知道为什么会发生这种情况,如何在不明确引用它的情况下触发TForm8的paintbox绘制事件.任何建议表示赞赏!
注意:如果我调用Self.Repaintwithint TForm8,例如在其Click事件中,可以触发TForm8的paintbox的paint事件.只有当我form8.repaint在TForm8外面打电话时才能触发它.我想知道为什么会这样?
可能相关的SO页面:
如何在模态表单处于活动状态时重新绘制父表单?
包含MDIForm表单的单元.
unit Unit7;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm7 = class(TForm)
procedure FormShow(Sender: TObject);
procedure FormClick(Sender: TObject);
end;
var
Form7: TForm7;
implementation
{$R *.dfm}
uses
Unit8;
procedure TForm7.FormShow(Sender: TObject);
begin
TForm8.Create(Self);
end;
procedure TForm7.FormClick(Sender: TObject);
begin
TForm8(ActiveMDIChild).Repaint;
end;
end.
Run Code Online (Sandbox Code Playgroud)
上述单位的Dfm.
object Form7: TForm7
Left = 0
Top = 0
Caption = 'Form7'
ClientHeight = 379
ClientWidth = 750
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
FormStyle = fsMDIForm
OldCreateOrder = False
OnClick = FormClick
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
end
Run Code Online (Sandbox Code Playgroud)
包含MDIChild表单的单元.
unit Unit8;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm8 = class(TForm)
pb1: TPaintBox;
pnl1: TPanel;
procedure pb1Paint(Sender: TObject);
procedure pb1Click(Sender: TObject);
private
fCounter: Integer;
end;
implementation
{$R *.dfm}
procedure TForm8.pb1Click(Sender: TObject);
begin
Self.Repaint;
end;
procedure TForm8.pb1Paint(Sender: TObject);
begin
Self.pb1.Canvas.TextOut(30, 30, IntToStr(Self.fCounter));
Self.fCounter := Self.fCounter + 1;
end;
end.
Run Code Online (Sandbox Code Playgroud)
上述单位的Dfm.
object Form8: TForm8
Left = 0
Top = 0
Caption = 'Form8'
ClientHeight = 226
ClientWidth = 233
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
FormStyle = fsMDIChild
OldCreateOrder = False
Visible = True
PixelsPerInch = 96
TextHeight = 13
object pnl1: TPanel
Left = 0
Top = 0
Width = 233
Height = 226
Align = alClient
ShowCaption = False
TabOrder = 0
object pb1: TPaintBox
Left = 1
Top = 1
Width = 231
Height = 224
Align = alClient
OnClick = pb1Click
OnPaint = pb1Paint
ExplicitLeft = 56
ExplicitTop = -64
ExplicitWidth = 105
ExplicitHeight = 105
end
end
end
Run Code Online (Sandbox Code Playgroud)
我认为情况就是这样:
信不信由你,"正常"的行为是,如果你重新绘制一个表单(或其他一些容器),只有那个容器被重新绘制,而不是包含在其中的子容器.然而,随着视觉主题的来临,控制了半透明的部分,突然你需要重绘子控件当父重绘,只是因为孩子需要reblend到新的背景.
我的假设通过仔细检查VCL源代码(相对)很容易验证,例如
procedure TWinControl.CMInvalidate(var Message: TMessage);
begin
{ Removed irrelevant code to avoid copyvio issues. }
InvalidateRect(WindowHandle, nil, not (csOpaque in ControlStyle));
{ Invalidate child windows which use the parentbackground when themed }
if ThemeServices.ThemesEnabled then
for I := 0 to ControlCount - 1 do
if csParentBackground in Controls[I].ControlStyle then
Controls[I].Invalidate;
{ Removed irrelevant code to avoid copyvio issues. }
end;
Run Code Online (Sandbox Code Playgroud)
因此,当ParentBackground设置为false,并且面板像经典面板一样时,它的父母不会重新绘制.另一方面,如果ParentBackground是true,它确实与其父母一起重新粉刷.
因此,没有问题,真的; 你只是期望一种不可预期的行为.
因此,您需要按照David的建议手动重新绘制油漆盒.
| 归档时间: |
|
| 查看次数: |
1085 次 |
| 最近记录: |