Приветствую!
Программирую на обычном C++, без MFC. Разрабатываю DLL-ку "Printer", которая присоединяется к основной программе. Хочу научиться грамотно выводить на печать картинку (из файла или из HBITMAP - не важно) с возможностью автоматического масштабирования по ширине страницы. И, конечно же, хочется это делать с минимальными усилиями с моей стороны :-)
Для этого я воспользовался возможностями GDI+. Вот фрагмент кода функции непосредственно печати (только убрал загромождающие проверки ошибок, чтобы было читабельнее):
  GdiplusStartupInput gdiplusStartupInput;
  ULONG_PTR           gdiplusToken;
  // Initialize GDI+
  GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
  DWORD   size;
  HDC     hdcPrint;
  DOCINFO docInfo;
  ZeroMemory(&docInfo, sizeof(docInfo));
  docInfo.cbSize = sizeof(docInfo);
  docInfo.lpszDocName = "GdiplusPrint";
  // Get the size of the default printer name.
  GetDefaultPrinter(NULL, &size);
  // Allocate a buffer large enough to hold the printer name.
  TCHAR* buffer = new TCHAR[size];
  // Get the printer name.
  if(!GetDefaultPrinter(buffer, &size)) {
    UtilsR1_ShowLastErrorMessage("Printing");
  }
  else {
    // Get a device context for the printer.
    hdcPrint = CreateDC(NULL, buffer, NULL, NULL);
    StartDoc(hdcPrint, &docInfo);
       Graphics* graphics;
       Bitmap*   img = new Bitmap(CT2CW(img_file), FALSE);
       img->SetResolution((float)GetDeviceCaps(hdcPrint, LOGPIXELSX), (float)GetDeviceCaps(hdcPrint, LOGPIXELSY));
       StartPage(hdcPrint);
         graphics = new Graphics(hdcPrint);
         graphics->SetInterpolationMode(InterpolationModeHighQualityBicubic);
         graphics->DrawImage(img, 0, 0); // (img, 0, 0, 0, 0, img->GetWidth(), img->GetHeight(), UnitPixel);
         delete graphics;
       EndPage(hdcPrint);
    EndDoc(hdcPrint);
    DeleteDC(hdcPrint);
  }
  delete buffer;
  GdiplusShutdown(gdiplusToken);
Переменная "img_file" - параметр функции, имя файла картинки. Размер - 1024 х 768 пикселей. Метод "SetResolution" необходим из-за того, что иначе размер печати совершенно неправильный (естественно, т.к. картинка получена с экрана, 96 dpi).
Можно предположить, что это, по всей видимости, минимальный по размерам вариант кода. Это - хорошо.
Печатаю на термопринтере (ширина бумаги 105 мм, принтер по умолчанию), все нормально. Изменяю принтер по умолчанию на лазерный с обычной бумагой А4, печатаю, получаю малюсенькую картинку в верхнем левом углу. Что за черт? Смотрю в свойства обеих принтеров. И, конечно, у термопринтера есть включенная опция "Fit to page", а у лазерника этой опции вообще нет. Похоже на то, что нужно масштабировать картинку вручную. Использовать "StretchBlt" как-то не очень хочется... Во-первых, некачественно (я использую, конечно, "SetStretchBltMode", но все равно - не то). Во-вторых, интерполяция методом "InterpolationModeHighQualityBicubic" по-любому качественнее. 
Думал, думал - ничего лучше (и проще) соответствующей коррекции параметров метода "SetResolution" не придумал. Правда, вроде работает нормально. Вот фрагмент добавленного кода (строка с "zoom_coef"):
       Bitmap*   img = new Bitmap(CT2CW(img_file), FALSE);
       float zoom_coef = float(img->GetWidth()) / float(GetDeviceCaps(hdcPrint, HORZRES));
       img->SetResolution(float(GetDeviceCaps(hdcPrint, LOGPIXELSX))*zoom_coef, float(GetDeviceCaps(hdcPrint, LOGPIXELSY))*zoom_coef);
Подскажите, пожалуйста, как такую печать по-грамотнее сделать? Правильно ли я выкрутился с разрешением картинки? Чему учит нас Партия в этом животрепещущем вопросе?
Спасибо!
P.S. Система Win XP, среда Visual Studio 2008.