いつもお世話になっています。
クリップボードがから画像データを取り出して、
取り出した画像データをメタファイルに表示するプログラムを
作成しています。
以下のコードを組んだのですが表示される画像が上下反転して
表示されます。
反転しないようにしたいのですがどうしたらよいのでしょうか?
おわかりになる方がいらっしゃいましたら教えてください。
-----------ソース----------------
// クリップボードから画像データを取得
// 画像データがクリップボードにあるとき
if (IsClipboardFormatAvailable(CF_BITMAP)){
OpenClipboard(NULL); // クリップボードを開く
hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP); // 画像データの取得
// hDCは作成したいメタファイルのデバイスコンテキストのハンドル
memhDC = CreateCompatibleDC(hDC); // メモリデバイスコンテキストの作成
SelectObject(memhDC, hBitmap);
// グラフィックオブジェクトの情報を取得
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
// 画像の転送
// x,yは転送先の位置。描画したい位置の値が入っていることは確認済
BitBlt(hDC, x, y,
bm.bmWidth, bm.bmHeight, memhDC, 0, 0, SRCCOPY);
DeleteDC(memhDC); // デバイスコンテキストを削除
CloseClipboard(); // クリップボードを閉じる
}
-------------ここまで----------------
このときhDCのモードをSetMapMode(hDC, MM_LOMETRIC);で指定してあります。
開発環境 Windows2000・VS6SP5・Win32 Dynamic-Link Libraryで作成
ご自分で書いてらっしゃるじゃないですか。
> SetMapMode(hDC, MM_LOMETRIC);
って。
これが何かわからずにやってるわけじゃないですよね?
MSDN には
> x の正の値は右方向、y の正の値は上方向を指します。
とあります。
つまり、座標原点が左下なんですよ。
対して、SetMapMode をやらないと、既定のマッピングモードは MM_TEXT 。
これは
> x 座標の正方向は右、y 座標の正方向は下になります。
座標原点は左上です。
これを考慮してやらないと、反転しちゃいます
シャノン様 返信ありがとうございます。
おっしゃる通りSetMapMode(hDC, MM_LOMETRIC);のせい
だとはわかるのですが、どのよう考慮してやれば
反転せずにすむかがわかりません。
BitBltでhDCに転送する際に何か設定があるのかとも
思ったんですが、見つけることはできませんでした。
hBitmapの内容を変えてあげないといけないのでしょうか?
なぜ、MM_LOMETRICにしないといけないのかという説明が無いので
コメントしにくいのですが、MM_LOMETRICにする理由が無いのであれば、
MM_TEXT(つまりSetMapModeを変えない)で描画すれば良いと思うのですが。
PATIO様返信ありがとうございます。
ある画像データ(線のデータや円のデータも含む)からメタファイル
を作成しているのですが、この画像データがmm単位で存在しています。
Xmm×Ymmの用紙である点から5mmの線を引けというようなデータです。
画像データの位置や長さを一致させるためと計算を楽にするために、
設定をMM_LOMETRICに変更しています。
MM_LOMETRICを設定しない方法は使えません。
MM_LOMETRICの設定のまま反転をどうにかしたいと思っているのですが
おわかりになられる方がいらっしゃいましたら教えてください。
MM_LOMETRICでどうしてもやりたいのであれば、
BitBltでは駄目でしょう。
他の関数を探してみた方が良いと思います。
メタファイルをMM_LOMETRICで作成しているからと言う理屈はわかるんですが、
ビットマップが絡むとなると話は別な気もしますね。
座標変換の計算がそこまで複雑な物だとは思えませんし、
むしろ、メタファイルの方をMM_TEXTにあわせて作成した方が
他のGDIオブジェクトとの親和性は良いと思います。
なにせ、デフォルトのモードがMM_TEXTであると言うのは、
それば一番自然に描画できるモードだからな訳で、
GDIの各関数もその状態で描画するのが一番効率よく動くように
なっていると思いますので。
こんな感じ?
if( IsClipboardFormatAvailable( CF_BITMAP ) )
{
OpenClipboard( NULL );
hBitmap = ( HBITMAP )GetClipboardData( CF_BITMAP );
memhDC = CreateCompatibleDC( hDC );
SelectObject( memhDC, hBitmap );
GetObject( hBitmap, sizeof( BITMAP ), &bm );
// 座標変換
POINT pt = { bm.bmWidth, bm.bmHeight };
DPtoLP( hDC, &pt, 1 );
// 鏡像描画
StretchBlt( hDC, x, y, pt.x, pt.y,
memhDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
DeleteDC( memhDC );
CloseClipboard();
}
PATIO様、シャノン様返信ありがとうございます。
できました。
// 座標変換
POINT pt = { bm.bmWidth, bm.bmHeight };
DPtoLP( hDC, &pt, 1 );
// 鏡像描画
StretchBlt( hDC, x, y, pt.x, pt.y,
memhdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
と返信の通りに変更することで表示できました。
座標を変換することで対応するんですね。
ありがとうございます。
すみません。解決で。チェック付け忘れたので