MFCのMDIで、DirectXおよびWinAPIを仕様して領域に描画を行うものを作っています。
環境ですが、
VS2008
DirectX9.0
です。
子ウィンドウは4分割しており、(0,0)と(1,0)が描画領域で、(0,1)(1,1)はフォームです。
そこで、以前は各子ウィンドウごとに、デバイスを取得し、描画をおこなっていたのですが、ファイルを5個以上作成すると、WinAPIで描画されるものが表示されなくなりました。
それは、デバイスコンテキストは、5個以上もてないことが発覚したためとわかったので、デバイスは親で持つことにし、共通化することになりました。
しかし、それでは、親ウィンドウで取得しているため、描画のウィンドウサイズなどが異なるため、意図した領域にかけておりません。
そこで、各領域に再設定を行いたいのですが、どうすればよいのでしょうか?
対策として、下記のように考えたのですが、検討違いでしょうか?
・デバイスの画面の設定をResetなどをつかって、リセットし、描画領域の再設定を行う。(Resetだと、再度デバイスの取得を行うと思っているのですが、これだとファイルごとにもっているのと変わらないような気がします。)
・CreateOffscreenPlainSurface等でオフスクリーン サーフェイスを作成し、描画する。(描画の座標情報等の微調整がいるような気がします。)
・単純に再設定できるから再設定を行う。
アドバイスを御願い致します。
No.2ベストアンサー
- 回答日時:
こんばんは。
以前の方で御礼頂きました。相当難航している様で・・・。
一番手っ取り早いのは、#No1さんが説明されている通り、GetDC()/ReleaseDC()でもって、サーフェースからMDIウィンドウに描写してしまう事です。
pDev->BeginScene();
//処理
pDev->EndScene();
を使用すると、MDIドキュメントごとぶっ潰されてしまいます・・・。どうやら、MDIでDirect3Dを使用するのはそう容易では無いみたいです。
で、調べまわしていたのですが、漸くサイトを発見できました。
「SetViewportメソッドで分割」(但し事例がSDI、実験失敗)
http://www.shader.jp/xoops/html/masafumi/directx …
「Presentメソッドの第3パラメータにウィンドウハンドルを渡す」(此方で実験成功)
http://monsho.hp.infoseek.co.jp/dx/dx77.html
非常に強引ですが・・・、前回の続編的に書けば、
/////////////////////////////////////////////////////////////////////////////
// CMyMDIView クラスの描画
void CMyMDIView::OnDraw(CDC* pDC)
{
CMyMDIDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: この場所にネイティブ データ用の描画コードを追加します。
//スプライトの作成
LPD3DXSPRITE pSprite = NULL;
::D3DXCreateSprite(DirectX::g_pDEVPlan, &pSprite);
//シーン開始
DirectX::g_pDEVPlan->BeginScene();
DirectX::g_pDEVPlan->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 0, 0), 1.0f, 0);
//スプライトにテクスチャを貼って描写
pSprite->Begin(D3DXSPRITE_ALPHABLEND);
pSprite->Draw(pDoc->GetTexture(), NULL, NULL, NULL, D3DCOLOR_ARGB(255, 255, 255, 255));
pSprite->End();
//シーン終了
DirectX::g_pDEVPlan->EndScene();
//第3パラメータにMDIビューのハンドルを入れる
DirectX::g_pDEVPlan->Present(NULL, NULL, this->GetSafeHwnd(), NULL);
//スプライトの開放(本来は何処か別の場所に作成して常駐させて置く)
DirectX::ReleaseCOM(pSprite);
}
No.1
- 回答日時:
>それは、デバイスコンテキストは、5個以上もてないことが発覚したためと
>わかったので、デバイスは親で持つことにし、共通化することになりました。
DCを親で持つ必要はありません。
GetDCは、子ウィンドウごとで構いません。
但し「描画が終ったらReleaseDCですぐに解放する」と言う処理が必要です。
つまり、描画ルーチンは
HDC hDC; /* ここだけにしかスコープを持たないauto変数にする。publicにしない */
if ((hDC = GetDC(hWnd) != NULL) { /* 座標系はhWndで指定したウィンドゥの座標系になる */
描画処理; /* ファイル1つに対する描画はすべてここで行う */
if (ReleaseDC(hWnd,hDC) != 1) {
alert("DCの解放に失敗!");
}
}
と言う事になります。
描画が終ったのにReleaseDCしないままだと「6回目のGetDCで失敗する」と言う事になります。
GetDCとReleaseDCがペアになっている限り、GetDCは何万回繰り返しても大丈夫です。
>しかし、それでは、親ウィンドウで取得しているため、描画のウィンドウサイズなどが異なるため、意図した領域にかけておりません。
親ウィンドゥでGetDCすると、座標系は親ウィンドゥになるので、座標(0,0)は「親ウィンドゥのクライアント描画領域の原点」になります。
なので「子ウィンドウの特定の座標が、親ウィンドゥのクライアント座標のどこに相当するかを求める必要」があります。
つまり「子のクライアント座標を親のクライアント座標に変換する必要」があるのです。
「子ウィンドゥのクライアント座標を、親ウィンドゥのクライアント座標に変換する」には、ClientToScreenとScreenToClientを使います(双方のウィンドウが同じスクリーンにある事が条件)
子ウィンドゥのクライアント座標系から、親ウィンドゥのクライアント座標系に変換するには
POINT Po;
Po.x = 子ウィンドゥのX座標;
Po.y = 子ウィンドゥのY座標;
ClientToScreen(Child_hWnd,&Po); /* 子の座標をスクリーン座標に */
ScreenToClient(Parent_hWnd,&Po); /* スクリーン座標を親の座標に */
で行います。これでPOINT構造体のx、yに、子の座標から親の座標に変換した座標が入ります。
>対策として、下記のように考えたのですが、検討違いでしょうか?
見当違い(「検討違い」ではなく「見当違い」が正しい)
「描画の直前にGetDCし、GetDCしたらすぐに描画を行い、描画が終ったらすぐにReleaseDCする」と言うのが正しい処理。
GetDCしたデバイスコンテキストのハンドルは、保持したままにしない事。
もし、ユーザーが「画面のプロパティを変更」したりすると、保持したままのデバイスコンテキストは、無効なハンドルになってしまうでしょう。
つまり、質問者さんのように「親ウィンドゥのデバイスコンテキストのハンドルをGetDCしたまま、ずっと保持して使い回す」と、ユーザーが「画面のプロパティを変更」した瞬間、それ以降、何も描画されなくなる可能性があります(画面のプロパティの変更を検知したらReleaseDCしてGetDCし直しても良いが、それだったら、描画処理の直前にGetDCして、描画終了してからReleaseDCすれば良い筈)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Illustrator(イラストレーター) ワードに貼った画像のキャンバスと画像本体のサイズの調整 2 2022/05/19 18:31
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- ルーター・ネットワーク機器 echoshow8の音声をBluetoothを介してパソコンで出力するやり方を教えて下さい。 3 2023/04/03 17:09
- フリーソフト GIMPの使い方 1 2022/07/11 13:52
- ホームページ作成・プログラミング CGIが実行可能なHP領域又はレンタルサーバーでおすすめの所を教えてください 現在ホームページ領域の 1 2023/01/01 11:47
- ビデオカード・サウンドカード PCに接続したイヤフォンのマイクが使えません。 3 2022/10/22 11:07
- マンガ・コミック AIの発展で、これからの漫画は面白くなると思いますか? 6 2023/05/09 13:42
- その他(パソコン・周辺機器) デバイスのペアリングのウィンドウサイズがおかしい 1 2023/01/18 18:48
- 美術・アート メディバンペイント。マウスでの描画。 3 2022/11/09 10:53
- マウス・キーボード real vnc viewer で遠隔先で操作が出来ない。 2 2023/07/24 15:00
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
外付ディスプレイで AutoHotkey...
-
Excel VBAで他アプリケーション...
-
Visual Studio .NET 2003:右揃...
-
NoxPlayerとUWSCのadbの座標に...
-
IEに表示されるウェブ画像のあ...
-
uwscについて、同一の画像(仮...
-
UWSCのCHKIMG関数について
-
C#で、画像の、指定した座標の...
-
エクセルVBAで画像を貼り付ける...
-
「VBS」について教えてください
-
bitbltからの画像保存ができま...
-
VBA HTML要素または文字の座標...
-
99BASICで五目並べを作りたい...
-
スクリーンキーボードについて
-
「ご処理進めて頂きますようお...
-
CloseとDisposeの違い
-
VBAでループ内で使う変数名を可...
-
エクセルで、日付を入力すると...
-
UPS警告音を止めたい
-
アクセスVBAのMe!と[ ]
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルVBAで画像を貼り付ける...
-
C#で、画像の、指定した座標の...
-
Excel VBAで他アプリケーション...
-
VBでクリックイベントを発生さ...
-
外付ディスプレイで AutoHotkey...
-
UWSC画像認識で座標の位置がず...
-
バナーにリンクを埋め込む方法
-
UWSCのCHKIMG関数について
-
マウスストーカーのようにカー...
-
VBA HTML要素または文字の座標...
-
uwscについて、同一の画像(仮...
-
マウスイベントが動かない
-
UWSファイルの編集?
-
VBAで ScreenToClient を使いたい
-
Unityでピクセル情報を取得する...
-
グラフの変化をアニメにするには?
-
エディットボックスの色変更に...
-
puctureBoxの一部の色を変えた...
-
マウスカーソルの移動
-
JPGの画像ファイルの結合
おすすめ情報