2016-10-19 4 views
0

私は、ウィンドウが非プライマリに配置されたときにいくつかのGUI要素のスクロールが正しく再描画されないという厄介なバグを持つレガシー(1999)コードベースで作業しています。モニター。複数のモニタでウィンドウ相対DeviceContextを作成する

私の知る限りでは(WindowsのAPIに慣れていない)、問題はコードがDeviceContextを取り出してGetDC(hwnd)を使用して描画することです。プライマリモニタのみ(しかし、ドキュメントは非常に明確ではない、TBH)。

私は基本的に使用して、画面上のものを描くことができた:

RECT rect; 
GetWindowRect(hwnd, &rect); 
HMONITOR monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY); 
MONITORINFOEX minfo; 
minfo.cbSize = sizeof(MONITORINFOEX); 
GetMonitorInfo(monitor, &minfo); 
HDC = CreateDC(NULL, minfo.szDevice, NULL, NULL); 

は、これは正しいモニターに描かれたものを取得しますが、すべてがで終わるため、アプリケーションは明らかに、ウィンドウ相対何かを期待デスクトップの左上隅で、ウィンドウには表示されません。

ここで、私のグーグルは、EnumDisplayMonitors(GetDC(), &rect, PaintCallback, NULL)を使用してペイントコードを2回実行すると正しいことを行う必要があることを示しているようです。残念ながら、私のコードはCやC++ではありません。それはスモールトークのイメージです(そして、サポートは15年前に終了しました。そのため、ベンダーに不平を言っています)、私がアクセスできるコードでペイント処理が行われるかどうか、あるいは私が得ることができないSmallTalkの勇気。

私の疑問:私のウィンドウのクライアント領域に関連するDCを作成することは可能でしょうか(DCをおそらくCreateDCから調整することによって)。ウィンドウが2つのモニターに跨っていれば、これはおそらく壊れることに気づきますが、それは少なくとも現在の状態よりも壊れていません。

UPDATE:

私はEnumDisplayMonitorsを使用して、二回レンダリングコードを実行するために管理してきましたが、それは奇妙な方法でクラッシュ(最も可能性の高いSmalltalkの問題である。これをコンパイラが古いと特有ですが、デバッグコードスタックの深いところに問題がある)。

コメントに答えるには:コードは基本的にウィンドウに描画したいと思う、はい。さまざまなGUI要素を表すSmallTalkオブジェクトは、GetDC(hwnd)でDCを作成するために使用されるウィンドウハンドルを持ち歩くので、十分に簡単です。だから、GetDC(hwnd)のように聞こえます。この場合、正しいことをするDCを取得してください。 STコードがDCをどこかにキャッシュしていて、GetDCは、ウィンドウが別の画面に移動したときに別のDCを返すことになります(私の大雑把な知識からそう考えられます)。

+0

いくつかのウィンドウで描画したいように見えます。 'FindWindow'を使用してウィンドウハンドルを取得するか、Visual StudioでSpy ++ユーティリティを使用してウィンドウハンドルを探します。完了したら、DC: 'HDC hdc = GetDC(hwnd)'を作成し、 'ReleaseDC(hwnd、hdc)'を呼び出します。しかし、これは安価なハックです、あなたの図面は非常に迅速に消去されます。あなた自身のウィンドウを作成して、それを正しくしないのはなぜですか? –

+0

問題はGetDC自体に関連しているとは思わない。たぶん、GetClientRect/GetWindowRectを使用するコードもあり、座標は何とかプライマリスクリーンからの相対座標になります。 – VuVirt

答えて

0

GetDCによって作成されたDCの問題が実際にキャッシュされているようです。私はキャッシュを使用しないようにレンダリングコードをハッキングしました(多かれ少なかれ、コードはちょっと絡んでいます)。

Visual Smalltalk Enterpriseのユーザーがグーグルでこの答えを見つけた場合は、GraphicsTool>>ifNilHandle:を編集して、ハンドルがnilであるかどうかを実際にチェックしないようにしましたが、常に新しいハンドルを取得してtrueを返します最後に。こうすることで、新しいDCが毎回取得されます。

UPDATE:

これは私が修正しようとしていた当面の問題を修正し、残念ながら他のもの(特にWindowBuilder Proは、GUI構築ツールキット)のカップルを破ります。問題は明らかにコードのどこかにあるDCの過度の熱心なキャッシュですが、上記のスレッジハンマーのアプローチよりもはるかに焦点を絞った方法で修正する必要があります。

関連する問題