如何使用IPictureDisp :: Invoke正确调用Render成员

时间:2013-09-16 03:37:24

标签: c winapi com gdi win32ole

我有一个23x23位图,我正在从一个文件加载到IPictureDisp COM接口的实例中。我正在使用OleLoadPicture加载图片,并传递IID_IPictureDisp。请假设这是有效的,并返回一个指向IPictureDisp的有效指针,从中我可以毫无问题地获得IDispatch指针。

我还可以使用IDispatch::Invoke获取图片的HeightWidth成员的值,按照预期返回23和23。

问题出于某种原因使用IDispatch::Invoke调用Render方法绘制一个23x23单色方块而不是我期望的图片。此外,单色方块的颜色对应于位图左下角像素的颜色(我假设是位图的零-eth像素)。

The bitmap I'm trying to render, at 23x23 and blown up to 92x92

What actually paints to the DC. Note that it is a 23x23 image corresponding to the colour of the bottom left pixel of the desired picture

上图是我正在使用的位图(正常尺寸,最大尺寸为4倍,因此您可以看到颜色)。较低的图像是实际渲染的图像。

我认为问题可能与我如何调用IDispatch::Invoke有关。

我想做的是(伪代码):

pic.Render(hdc, x, y, w, h, 0, h-1, w, -h, &rc)

其中rcRECT结构,如下所示:left => x ; top => y ; right => x + w ; bottom => y + h

最终被调用的C代码等同于:

// NOTE: x = 0, y = 0, w = 23, h = 23, and -h => 0xffffffe9 in a 32-bit int
DISPPARAMS args = { NULL, NULL, 0, 0 };
args.cArgs = 10;
args.rgvarg = (VARIANT *)alloca(10 * sizeof(VARIANT));
int values[10] = { (int)hdc, x, y, w, h, 0, h-1, w, -h, (int)&rc };
for (int k = 0; k < 10; ++k)
{
    V_VT(args.rgvarg[10-k-1]) = VT_I4;
    V_I4(args.rgvarg[10-k-1]) = values[k];
}

VARIANT result;
VariantInit(&result);

// assume dispid is the correct DISPID for the "Render" method
HRESULT hresult = idisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &args, &result, NULL, NULL);

当呼叫返回时,hresult的值为0(S_OK),但渲染的图片是我显示的单色图像,仅使用左下角的颜色图像。

我如何滥用IDispatch::Invoke

2 个答案:

答案 0 :(得分:1)

好吧,我现在记得了。 Render的参数令人困惑。源值以himetric值表示,而不是以像素为单位。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms693441%28v=vs.85%29.aspx

基本上,它只使用几个像素作为源,而不是整个图像。

我的建议是使用get_Widthget_Height获取himetric宽度/高度。或者使用AtlPixelToHiMetric转换它们:

http://msdn.microsoft.com/en-CA/library/8ca5swet%28v=vs.90%29.aspx

答案 1 :(得分:0)

我真的认为我们不能假设您正确加载图像。检查一下,看看。我有这样的问题,我认为它是渲染代码,当它实际上是图像加载代码。确保您的源数据具有完美的质量,并找到一种方法来检查数据加载后的数据。我想你可能会对你发现的东西感到惊讶。