C ++ Win32, самый простой способ показать окно с растровым изображением - PullRequest
3 голосов
/ 16 февраля 2010

Это только для целей «отладки», поэтому я не хочу тратить на это много времени, и это не очень важно. Программа экспортирует данные в формате png, jpg, svg и т. Д. - так что это не имеет большого значения, хотя было бы неплохо увидеть изображение во время его генерации. Кроме того, программа будет использоваться на сервере Linux; но я ограничу эту «функцию» версией Win.

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

У меня есть изображение в формате ARGB (32bpp), хотя преобразование формата не будет проблемой вообще. Я хотел бы использовать Win32, создать окно из функции глубоко внутри кода (без известного hInstance и т. Д.) И написать растровое изображение. Быстро и легко, надеюсь.

Но я недостаточно знаю win32api. Я видел, что единственный вариант рисования (GDI) - это объект HBITMAP ... Любой фрагмент кода или пример, на который я могу положиться? Любое соображение, которое я не мог бы пропустить? Или, может быть, учитывая мои временные ограничения, мне просто забыть об этом?

Спасибо!

Ответы [ 2 ]

5 голосов
/ 16 февраля 2010

Самая большая часть работы здесь - это на самом деле регистрация класса окна и написание минимальной оконной процедуры. Но если это только отладочный код, вы можете пропустить эту часть. (Я вернусь к этому позже).

Если у вас есть HBITMAP, вы бы использовали BitBlt или StretchBlt , чтобы нарисовать его, но если у вас еще нет изображения в качестве HBITMAP, тогда StretchDIBits , вероятно, является лучшим выбором, поскольку вы можете использовать его, если у вас есть только указатель на растровые данные. Вы должны передать ему исходный и целевой прямоугольник, BITMAPINFOHEADER и указатель на необработанные растровые данные. Как то так

SIZE sBmp = { 100, 200 };
LPBITMAPINFOHEADER pbi;    // the bitmap header from the file, etc.
LPVOID             pvBits; // the raw bitmap bits

StretchDIBits (hdc, 0, 0, sBmp.cx, sBmp.cy, 
               0, 0, sBmp.cx, sBmp.cy,
               pvBits, pbi, 
               DIB_RGB_COLORS, 
               SRCCOPY);

Итак, следующая часть - как получить HDC для рисования? Что касается кода отладки, я часто рисую прямо на экране. HDC hdc = GetDC(NULL) получит DC, который может рисовать на экране, но есть проблемы с безопасностью, и он не работает с Aero в Windows Vista, поэтому другой способ - рисовать на окне. Если у вас есть окно, которое вы можете просто нарисовать, то HDC hdc = GetDC (hwnd) будет работать.

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

Для более долгосрочного решения Вы можете создать диалоговое окно и поместить вызов рисования растрового изображения в обработчик сообщений WM_PAINT или WM_ERASEBKGND для этого диалогового окна. Но я не рекомендую показывать диалоговое окно изнутри кода, который не должен выполнять пользовательский интерфейс. Отображение окна, особенно диалогового окна, будет мешать нормальному потоку сообщений в вашем приложении. Если вы хотите использовать диалоговое окно для этого средства просмотра растровых изображений, то вы хотите, чтобы это диалоговое окно было чем-то, что показывает пользователь, и которое вы просто рисуете, если оно там есть.

Если у вас нет доступа к HINSTANCE, все равно возможно отобразить диалоговое окно, это просто дополнительная работа. Это своего рода другой вопрос.

1 голос
/ 16 февраля 2010

Все, что вам нужно, это дескриптор контекста устройства (HDC). Для отображения ваших данных на нем:

  1. CreateDibSection для создания DIBSection.
  2. Скопируйте ваши данные в блок памяти, возвращенный CreateDibSection.
  3. создать DC, совместимый с целевым DC.
  4. Выберите раздел DIBSection для вновь созданного DC.
  5. BitBlt (или StretchBlt) от вашего DC до целевого DC.
...