さおりと申します。いつも参考にさせていただいてます。
環境:VC6.0、MFC、Windows
某サイトの参考プログラムをほとんどそのままいただいて下のように書きました。
やりたいことは、Pictureを使用してSDIでウィンドウの中央に画像を表示することで
す。
中央への表示をあきらめてpPicture->Render(pDC, &rcCleint, &rcPicture);
とすると、ウィンドウ全体に拡縮されてうまく表示されるのですが、
はみ出しはしょうがないにしても拡縮なしで中央に表示をさせようと
下のようなコードにすると、ノイズ画像?のようなものが表示されてしまいます。
サンプルコードをほぼそのまま使わせていただいてるのになぜかうまくいかないです。
どなたか原因を教えていただけないでしょうか?
よろしくお願いいたします。
void CtestView::OnDraw(CDC* pDC)
{
CtestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
LPDISPATCH pDisp;
COleVariant varName(sunset.jpg);
if (SUCCEEDED( OleLoadPictureFile(varName, &pDisp) ))
{
CPictureHolder *pPicture = new CPictureHolder;
OLE_XSIZE_HIMETRIC width, height;
CSize size(0,0);
CRect rcClient;
pPicture->SetPictureDispatch((LPPICTUREDISP)pDisp);
pPicture->m_pPict->get_Width(&width);
pPicture->m_pPict->get_Height(&height);
GetClientRect(&rcClient);
size = CSize(width,height);
CPoint ptOffset((rcClient.right - size.cx) / 2,
(rcClient.bottom - size.cy) / 2);
if (ptOffset.x < 0) ptOffset.x = 0;
if (ptOffset.y < 0) ptOffset.y = 0;
rcClient = CRect(ptOffset, size);
pPicture->Render(pDC, &rcClient, &rcClient);
delete pPicture;
}
}
> pPicture->m_pPict->get_Width(&width);
> pPicture->m_pPict->get_Height(&height);
これで取得できる値の単位は mm。
> GetClientRect(&rcClient);
これで取得できる値の単位は pixel。
つまり足し算、引き算等をする際は単位を揃えてやらないと酷い事になります。
ちなみに mm から pixel への変換式はこんな感じ。
pixel = ::MulDiv(mm, DCのdpi, 2540); // WinAPI使用
こんばんは。さおりです。
レス遅くなり申し訳ありませんでした。
Gakさんのおっしゃるとおり単位の違いのようでした。
初心者でMulDivでのDCのdpiの取得の方法がわからなかった
のですが、pDC->HIMETRICtoDP(&size);の関数をつかったら
とりあえず、希望の表示が得られました。
たいへんありがとうございました。
もう一点なんですが、メモリリークがあるようで、プログラムを
動作させて再描画させていくとどんどんメモリを消費していきます。
こちらもどなたか教えていただけないでしょうか?
> DCのdpiの取得
pDC->GetDeviceCaps(LOGPIXELSX); // 水平
pDC->GetDeviceCaps(LOGPIXELSY); // 垂直
で取れます。
> もう一点なんですが、メモリリークがあるようで、
少なくとも、OleLoadPictureFile() が成功した場合
pDisp->Release();
を
pPicture->SetPictureDispatch((LPPICTUREDISP)pDisp);
より後に入れる必要があるかと。
> pDisp->Release();
でメモリリークの問題も解消したように思います。
Gak様、大変的確なご指摘を頂き、ありがとうございました。
また機会があったらよろしくお願いいたします・・・。