2016-10-26 23 views
2

私はBoundsRectが保存されている起動時に2番目のモニタに子フォームが配置されたマルチフォームアプリケーションを持っています。Delphi:モニタの設定が変更されたときにフォームの元の場所を復元する方法

コンピュータの表示構成が変更されると、Windowsは最初の(プライマリ)モニタにフォームを移動します。私はWM_DISPLAYCHANGEでこの変更をキャッチすることができます:

procedure WMDisplayChange(var msg: TWMDisplayChange); message WM_DISPLAYCHANGE; 

それは設定で再表示されたときに私は何をやってに興味がバックセカンドモニタに子フォームを移動さ(すなわちScreen.MonitorCountが1から2に行きます)、例えば:

childForm.BoundsRect := childForm.m_WorkingBounds; 
// (or) 
childForm.BoundsRect := Screen.Monitors[Screen.MonitorCount-1].BoundsRect; 

しかし、この割り当てはありません影響を及ぼすある - 子フォームはありません成功し、モニター0私は、このようなSetWindowPos()などの他のアプローチを、試してみた

にとどまります。.. 。

+1

「BoundsRect」に何らかの形で割り当てても機能しないことは、私にはあまりにも信じられないようです。私はそれが正しく動作することを知っていると思います。明らかに 'SetWindowPos'でその呼び出しを置き換えても、' SetWindowPos'の呼び出しではなく 'BoundsRect'への代入がどのように実装されていると思いますか。したがって、可能性のある説明は、割り当てのrhsがあなたが期待するものではないということです。あなたは実際に 'Screen.Monitors [Screen.MonitorCount-1] .BoundsRect'の値があなたの期待に合っているかどうかチェックしましたか?あなたは言い換えればどんなデバッグをしましたか? –

+1

非常に特殊な用途でない場合は、これは妥当ではありません。別の場所に別のモニタが表示されることがあります。 –

+0

@David:はい私はデバッガでこれらの値を調べました。すべては予想どおりでした。 –

答えて

5

実際のところ、Delphi VCLは実際に変更されたときにその内部のモニタリストを更新しません。あなたは、自分自身を強制的にリフレッシュする必要があります。

モニターはTScreen.GetMonitorsメソッドでリフレッシュされますが、残念ながらプライベートな方法であるため、モニターを直接呼び出すことはできません。

TApplication.WndProc(var Message: TMessage)WM_WTSSESSION_CHANGEメッセージを受け取ったときに、それはScreen.GetMonitorsを呼び出します。これはあなたの目標を達成するための最も善意の方法です。あなたはモニターが変更された通知を受け取るとき

だけでアプリケーションに送信:

SendMessage(Application.Handle, WM_WTSSESSION_CHANGE, 0, 0); 
+0

関連する[TScreen.GetMonitorsを公開](http://qc.embarcadero.com/wc/qcmain.aspx?d=88635) –

+1

私はそれが私だったら私はあきらめるだろうVCLのプロパティと私自身のロール。 –

+0

@DavidHeffernan私が今まで行ってきたことを推測してください... –

0

を私は古いバージョンDelphi5でこれをテストし、それだけに簡単に働いた:

Screen.Free; 
Screen := TScreen.Create(Nil); 

画面処理が持っていますDelphiのそれ以降のバージョンでは変更されましたが、同様のアプローチが有効です。

関連する問題