私は、ウィンドウが非プライマリに配置されたときにいくつかの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を返すことになります(私の大雑把な知識からそう考えられます)。
いくつかのウィンドウで描画したいように見えます。 'FindWindow'を使用してウィンドウハンドルを取得するか、Visual StudioでSpy ++ユーティリティを使用してウィンドウハンドルを探します。完了したら、DC: 'HDC hdc = GetDC(hwnd)'を作成し、 'ReleaseDC(hwnd、hdc)'を呼び出します。しかし、これは安価なハックです、あなたの図面は非常に迅速に消去されます。あなた自身のウィンドウを作成して、それを正しくしないのはなぜですか? –
問題はGetDC自体に関連しているとは思わない。たぶん、GetClientRect/GetWindowRectを使用するコードもあり、座標は何とかプライマリスクリーンからの相対座標になります。 – VuVirt