Как использовать IPictureDisp::Invoke для правильного вызова члена Render

У меня есть растровое изображение 23x23, которое я загружаю из файла в экземпляр IPictureDisp COM интерфейс. Я загружаю картинку с помощью OleLoadPicture, проходя IID_IPictureDisp, Пожалуйста, предположите, что это работает и возвращает мне действительный указатель на IPictureDisp из которого я могу получить IDispatch указатель без проблем.

Я также могу использовать IDispatch::Invoke чтобы получить значения Height а также Width Участники картины, которые возвращаются как 23 и 23, как и ожидалось.

Проблема по какой-то причине в использовании IDispatch::Invoke призвать Render Метод рисует монохромный квадрат 23x23 вместо ожидаемой картины. Кроме того, цвет монохромного квадрата соответствует цвету нижнего левого пикселя растрового изображения (который, я предполагаю, является нулевым пикселем растрового изображения).

Растровое изображение, которое я пытаюсь визуализировать, размером 23х23 и увеличенным до 92х92

Что на самом деле рисует в ДК.  Обратите внимание, что это изображение 23x23, соответствующее цвету нижнего левого пикселя желаемого изображения

Верхнее изображение - это растровое изображение, которое я использую (в нормальном размере и увеличено в 4 раза, чтобы вы могли видеть цвета). Нижнее изображение - это то, что фактически отображается.

Я думаю, что проблема, вероятно, связана с тем, как я звоню IDispatch::Invoke,

Что я хочу сделать, это (псевдокод):

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

где rc это RECT структура, которая выглядит как: 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 ответа

Решение

Хорошо, теперь я помню это. Параметры для Render сбивают с толку. Исходные значения представлены в химерных значениях, а не в пикселях.

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

По сути, он использует только несколько пикселей в качестве источника, а не все изображение.

Мое предложение, вы получите Himetric ширину / высоту, используя get_Width а также get_Height, Или использовать AtlPixelToHiMetric конвертировать их:

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

Я действительно думаю, что мы не можем предположить, что вы загружаете изображение правильно. Изучите это и увидите. У меня были такие проблемы, когда я предполагал, что это был код рендеринга, тогда как на самом деле это был код загрузки изображения. Убедитесь, что ваши исходные данные имеют идеальное качество, и найдите способ проверить данные после их загрузки. Я думаю, что вы можете быть удивлены тем, что вы найдете.

Другие вопросы по тегам