MDI子フォームを最大化で表示するときにちらつきをなくすには?


くみっき  2009-08-21 23:01:18  No: 146253

MDIフォーム内に子フォームを表示するようなプログラムを作成しています。
ここで質問なのですが、開いた子フォーム(Aとします)を最大化の状態にすると、次に開く別の子フォーム(Bとします)も最大化表示されますが、
Bフォームを開くとき、まずMDIの子フォーム表示エリアの左側にフォームのイメージが描画され、その後で最大化されます。
(BフォームのStartPositionがManualで、Locationが(0,0)なのでこのように見えるのかもしれませんが。)
動作が遅いPCだと、この動きが目障りな気もするので、この動きを表示しない(あるいは目障りにならない)方法はあるでしょうか?
バージョンはVB2008です。
よろしくお願いします。


特攻隊長まるるう  2009-08-24 20:58:53  No: 146254

WinXp(sp3)、VB2008pro
CPU2GHz、960MB RAM
重めのコントロール70個貼り付けて実行しましたが、再現しませんでした。
(コントロールの描画が遅れることはあっても、フォームが表示されて
から最大化するような動きは目に残らなかった)

ラベル1つだけ貼り付けたようなサンプルプログラムでも
再現するか確認してください。
その後、こちらで再現できるような情報をください。


くみっき  2009-08-26 00:20:01  No: 146255

特攻隊長まるるう様、コメントありがとうございます。
ラベルの場合は分かりにくいので、テキストボックスをひとつ貼り付けたものを検証してみました。

環境1:Vista(sp1)、CPU 2.83GMHz、4GB RAM
環境2:XP(sp3)、CPU 902MHz、192MB RAM
このマシンにはVS(VB)がインストールされていないので、環境1のVS2008 Std.でEXE化したものをこのPCにコピー

作成したフォームは、以下のようになっています。
MDIフォーム:MDIParent1
子フォーム:Form1(テキストボックスTextBox1が張り付いている)
子フォームのプロパティ(Form1.Designer.vb内のInitializeComponent()で設定)
    Private Sub InitializeComponent()
        Me.TextBox1 = New System.Windows.Forms.TextBox
        Me.SuspendLayout()
        '
        'TextBox1
        '(アンカーはTopおよびBottomにし、MultilineをTrueにしてある。)
        Me.TextBox1.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom), System.Windows.Forms.AnchorStyles)
        Me.TextBox1.Location = New System.Drawing.Point(82, 28)
        Me.TextBox1.Multiline = True
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.Size = New System.Drawing.Size(100, 195)
        Me.TextBox1.TabIndex = 0
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(284, 263)
        Me.Controls.Add(Me.TextBox1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
        Me.PerformLayout()
    End Sub

MDIフォームから新しい子フォームを開く
(MenuStripにNewWindowToolStripMenuItemアイテムを設定し、これをクリックしたときのイベント)
    Private Sub ShowNewForm(ByVal sender As Object, ByVal e As EventArgs) Handles NewWindowToolStripMenuItem.Click
        ' 子フォームの新しいインスタンスを作成します
        Dim ChildForm As New Form1
        ' 表示する前に、この MDI フォームの子に設定します
        ChildForm.MdiParent = Me

        m_ChildFormNumber += 1    'この変数はクラス内で定義してください。
        ChildForm.Text = "ウィンドウ " & m_ChildFormNumber
        ChildForm.TextBox1.Text = ChildForm.Text

        ChildForm.Show()
    End Sub

このプログラムを起動し、
1.MDIフォームより子フォームを開き、子フォームを最大化する。
2.この状態で新しい子フォームを開く。

この結果、環境1でも環境2でも子フォームに貼り付けたテキストボックスのチラつきが確認できました。
(MDI子フォーム表示エリアの左側にテキストボックスの白い枠が見え、それから、最大化され、
テキストボックスはMDI子フォーム表示エリアの中央に表示される。)
もちろん、PCのパフォーマンスが良くない環境2のほうが画面表示に時間がかかるため、この挙動がどうしても目障りになります。
子フォームのテキストボックスのアンカーをTopとBottomにしているためにこのような挙動が見えてしまうのだと思いますが、
どのようにして回避すればよいでしょうか?
よろしくお願いします。


特攻隊長まるるう  2009-09-01 19:11:31  No: 146256

ChildForm.SuspendLayout()
        ChildForm.Show()
        ChildForm.PerformLayout()
にするとどうなりますか?


くみっき  2009-09-02 18:26:38  No: 146257

特攻隊長まるるう様、ご連絡ありがとうございます。お待ち申しておりました。
早速上記を確認してみましたが、ChildForm.PerformLayout()を行うと、画面表示が期待とは異なるものになってしまいます。
例えば、子フォームのテキストボックスをフォームの中央に配置し、このテキストボックスのアンカーをTopとBottomのみに設定しているため、
最大化を行うと子フォームのテキストボックスは均等に中央に配置される(Locationが調整される)ことを期待するのですが、
ChildForm.PerformLayout()を行うと、子フォームのテキストボックスのLocationは変更されず、左側に寄った状態となります。
MDIフォーム側で何か設定が必要なのでしょうか?
よろしくお願いします。


特攻隊長まるるう  2009-09-03 20:43:32  No: 146258

> 画面表示が期待とは異なるものになってしまいます。
あ、提示したコードが全然だめでした。申し訳ないです。
レイアウト変更が適用されていないのは ResumeLayout で
変更を適用する処理がぬけていた為ですが、それを入れると
質問時の動作に戻ってしまいますね。

ちらつきといっても、正常に最大化前の状態で表示される
画面の描画処理を実行しないようなことを考えないといけない
のかなぁ。。。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加