CPictureHolderの使用方法?

[戻る]
さおり 2004/09/26(日) 21:15:25
さおりと申します。いつも参考にさせていただいてます。
環境: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;
    }
}

Gak 2004/09/28(火) 15:07:21
> 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使用

さおり 2004/09/30(木) 22:31:22
[[解決]]
こんばんは。さおりです。
レス遅くなり申し訳ありませんでした。

Gakさんのおっしゃるとおり単位の違いのようでした。
初心者でMulDivでのDCのdpiの取得の方法がわからなかった
のですが、pDC->HIMETRICtoDP(&size);の関数をつかったら
とりあえず、希望の表示が得られました。

たいへんありがとうございました。

もう一点なんですが、メモリリークがあるようで、プログラムを
動作させて再描画させていくとどんどんメモリを消費していきます。
こちらもどなたか教えていただけないでしょうか?

Gak 2004/10/01(金) 16:44:39
> DCのdpiの取得
 pDC->GetDeviceCaps(LOGPIXELSX); // 水平
 pDC->GetDeviceCaps(LOGPIXELSY); // 垂直
で取れます。

> もう一点なんですが、メモリリークがあるようで、
少なくとも、OleLoadPictureFile() が成功した場合
 pDisp->Release();
を
 pPicture->SetPictureDispatch((LPPICTUREDISP)pDisp); 
より後に入れる必要があるかと。

さおり 2004/10/02(土) 23:33:26
[[解決]]
> pDisp->Release();

でメモリリークの問題も解消したように思います。
Gak様、大変的確なご指摘を頂き、ありがとうございました。
また機会があったらよろしくお願いいたします・・・。

古いスレッドには追加発言できません。