Avoid New MDI Child Resizing Animation (and Delay) in Delphi MDI Applications

本文介绍了一种在Delphi MDI应用程序中消除创建MDI子窗体时出现的窗口调整大小动画的方法。通过使用WM_SETREDRAW消息来阻止窗口更新,可以避免创建过程中可能出现的视觉混乱。这种方法不仅提高了MDI子窗体的加载速度,还改善了用户体验。

Avoid New MDI Child Resizing Animation (and Delay) in Delphi MDI Applications


Lock (Prevent) Window Updating When Creating New MDI Child Forms
By Zarko Gajic

 

If you are creating MDI applications using Delphi, you must have noticed some "quirks" or issues that you cannot simply handle / fix from your code.

 

MDI interface was designed in the days of Windows 3 (some 10+ years ago) and it was designed with a single type of application in mind: a parent window that hosts multiple instances of the same class of "document" window (just think of you first MS Word).

 

Nasty MDI Child Resizing Animation


When creating (to show) an MDI child an animation of resizing will take place. This animation might look ugly if the code executed during the creation of your MDI child takes some time to process.


Even if WindowState property was set to wsMaximized when an MDI child is created it will be created using Default Pos at X, Y coordinates where you left your form at design time.

Windows simply insists on creating MDI children visible and at a default position.

After creation, the MDI child will get maximized but an ugly animation will take place.

 

Quickly Create MDI Children - Eliminate "Create & Resize" Animation


To eliminate the MDI child creation and resizing animation you can send a special message to the MDI parent form, WM_SETREDRAW. The WM_SETREDRAW can be sent to a window to enable changes in that window to be redrawn or to prevent changes in that window from being redrawn.
To prevent the animation flicker, have the next code in your MDI Parent form's unit:

 

TMDIMainForm = class(TForm)
private
  fLockClientWindowUpdateCount: Integer;
public
  constructor Create(aOwner: TComponent) ; override;
  procedure LockClientWindowUpdate;
  procedure UnlockClientWindowUpdate;
end;

...

 

constructor TMDIMainForm.Create(aOwner: TComponent) ;
begin
  inherited Create(aOwner) ;
  fLockClientWindowUpdateCount := 0;
end;

 

procedure TMDIMainForm.LockClientWindowUpdate;
begin
  if fLockClientWindowUpdateCount = 0 then SendMessage(ClientHandle, WM_SETREDRAW, 0, 0) ;
  Inc(fLockClientWindowUpdateCount) ;
end;

 

procedure TMDIMainForm.UnlockClientWindowUpdate;
begin
  Dec(fLockClientWindowUpdateCount) ;
  if fLockClientWindowUpdateCount = 0 then
  begin
    SendMessage(ClientHandle, WM_SETREDRAW, 1, 0) ;
    RedrawWindow(ClientHandle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN or RDW_NOINTERNALPAINT)
  end
end;

 

Now, when you need to create (and show) an MDI client form(s), just call LockClientWindowUpdate and UnlockClientWindowUpdate.
If a client window takes some time to create, you can change the cursor to let the user something (form creation) is going on:

 

LockClientWindowUpdate;
Screen.Cursor := crHourGlass;
try
  Application.CreateForm(MDIChildForm) ;
finally
  Screen.Cursor := crDefault;
  UnlockClientWindowUpdate;
end;

 

That's it. Now your MDI child forms will load faster and without the confusing animation.

<think>嗯,用户的问题是关于如何通过多变量正态分布初始化新的嵌入向量,以及如何禁用这个操作。他们提到了Stanford NLP的词汇扩展,参数是mean_resizing=False。我需要先理解这两个部分:初始化嵌入向量的方法和如何禁用该操作。 首先,多变量正态分布初始化。通常,在NLP中,当扩展词汇表时,新词的嵌入向量需要初始化。一种方法是用已有词向量的均值和协方差来生成新的向量。这样新词的分布会和旧词相似,可能有助于模型保持一致性。 那具体怎么做呢?假设已有嵌入矩阵old_embeddings,形状是(vocab_size, embedding_dim)。计算均值mean和协方差covariance,然后用numpy或PyTorch生成新向量。比如,用numpy.random.multivariate_normal(mean, covariance, size=new_words_num)。然后合并到原矩阵中。 接下来,用户提到Stanford NLP的词汇扩展,参数mean_resizing=False。可能是指是否调整均值。如果设为False,可能直接使用旧词向量的原始均值和协方差,而不做调整。需要查看相关文档或代码确认,但用户可能希望禁用基于正态分布的初始化,改用其他方式,比如零初始化或随机初始化。 如何禁用这个操作呢?可能是在创建嵌入层时设置某个参数,比如mean_resizing=False,或者直接修改初始化方法。比如在代码中,如果原本有逻辑是当mean_resizing为True时用正态分布初始化,否则用其他方法,那么设置该参数为False即可。 现在,结合用户提供的引用,特别是引用[1]中的LSTMCharEmbedding例子,可能需要参考类似的嵌入初始化方法。例如,在fastNLP中,可能通过参数控制是否使用预训练向量的统计信息来初始化新词。 用户的需求可能是在扩展词汇表时,新词的嵌入不使用旧词的正态分布,而采用其他初始化方式。所以,回答需要给出具体步骤:计算均值和协方差,生成新向量,合并;禁用的话,可能设置mean_resizing=False,或者手动修改初始化方法。 需要确保回答中的代码示例正确,比如使用PyTorch或numpy来实现,并提到如何设置参数禁用。同时,用户可能是在使用某个特定库(如Stanford NLP),但问题中没有明确说明,所以需要假设一般情况,或者询问是否针对特定框架。 最后,生成相关问题,比如如何计算协方差矩阵,其他初始化方法,参数作用等。</think>### 多变量正态分布初始化新嵌入向量的方法 #### 1. 初始化新嵌入向量的步骤 当需要扩展词汇表时,**已有词向量**的统计特性(均值 $\mu$ 和协方差矩阵 $\Sigma$)可用于生成新词的初始化向量: 1. 计算旧嵌入矩阵的均值 $\mu$ 和协方差 $\Sigma$: $$ \mu = \frac{1}{N}\sum_{i=1}^{N} e_i $$ $$ \Sigma = \frac{1}{N-1}\sum_{i=1}^{N} (e_i - \mu)(e_i - \mu)^T $$ 其中 $e_i$ 表示旧嵌入向量,$N$ 是旧词汇量。 2. 生成新向量: ```python import numpy as np new_embeddings = np.random.multivariate_normal(mean=μ, cov=Σ, size=new_words_num) ``` 3. 合并到原嵌入矩阵中(例如在PyTorch中): ```python import torch old_embeddings = torch.randn(old_vocab_size, 300) # 假设原始维度300 combined_embeddings = torch.cat([old_embeddings, torch.from_numpy(new_embeddings).float()]) ``` #### 2. 禁用该操作的实现 在Stanford NLP的词汇扩展中,`mean_resizing=False` 参数直接控制是否使用统计特性初始化新词: ```python from stanfordnlp.models.glove import GloVe # 禁用多变量正态分布初始化 model = GloVe(vocab, mean_resizing=False) # 此时新词向量将采用默认初始化(如均匀分布) ``` ### 关键参数说明 | 参数 | 类型 | 作用 | |------|------|------| | `mean_resizing` | bool | True时使用旧词统计特性初始化新词,False时禁用[^1] | ### 补充说明 - 协方差矩阵的计算可能需要进行**正则化处理**,避免维度灾难问题 - 在PyTorch中可直接通过`torch.distributions.MultivariateNormal`实现分布采样 - 禁用后新词初始化方式取决于框架默认设置,可能需要检查具体实现文档[^2]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值