Пытаюсь переучиться с DOS'а на Windows, проблемы возникли буквально сразу - вывод изображения на экран. Что было легко реализовать в досе, почему то стало нереализуемым в винде: Задача следующая: есть массив данных - изображение, которое может быть представлено не только в 32 битной форме, но и в любой другой из существующих, даже с палитрой. Причем порядок строк - человеческий: сверху вниз, а не как в DIB. Смотрел много примеров, в основном практикуют нечто вроде: CreteDIBitmap(...); CreateCompatibleDC(...); SelectObject(&bitmap); BitBlt(...); но, данный вариант не устраивает, т.к. сжирается очень много памяти, за счет того, что исходное изображение сперва конвертируется в формат пригодный для вывода в текущем видеорежиме. И исходное изображение должно быть представлено в виде DIB, т.е. с перевернутыми порядком строк, что крайне не удобно при работе с таким форматом данных. Потом, при каждом изменении исходного изображения необходимо вызывать CreteDIBitmap, и только потом BitBlt - перетаскивание данных из пустого в порожнее. Как сделать по человечески, а не через ж... т.е. исходный массив сразу отправить на DC ? P.S. из за подобных задрочек начинаешь все больше ненавидеть Win32.
Exception13 Для создания картинки используй CreateDIBSection, эта функция может выделить необходимое количество памяти, и вернуть на неё указатель, через который туда можно записать всё что угодно. Для изменения порядка строк можно в структуре описывающей заголовок изображения можно указать отрицательный вертикальный размер.
Спасибо за ответ тов. Black_mirror, все замечательно сработало. Только одно теперь не пойму: если эту память за меня кто то выделяет, то кто её удалит, обычным free() - не получается, чувствуется еще одна фича win32, в которой самостоятельно разобраться не получится.
Читайте в msdn описания функций, которые используются в коде. Для каждой из функций, создающей в памяти какие-либо объекты, есть функции, удаляющие эти объекты.
Спасибо конечно за ссылку. Я прекрасно осведомлен о том, что на свете существует MSDN, но проблема в том, что достать его нет возможности. Выкачать на модемном соединении сами понимаете - нереально. Есть только справочник по API функциям, да и тот на русском, из которого мало что понятно. Именно по этому и обратился на форум. Огромное спасибо тов. cresta за ответ в стиле RTFM.
msdn доставать необязательно. Он всегда есть в онлайне, и совершенно бесплатно. Более того, совсем не обязательно выкачивать весь msdn. Достаточно открыть страницу http://msdn.microsoft.com и в окошке поиска набрать CreateCompatibleDC. После чего нажать "Go" и получить ссылку на страницу с описанием функции. Так что, rtfm. Больше тут нечего сказать.
Exception13 Я в англицком не силен, так что сам переведи: ___MSDN___ Remarks As noted above, if hSection is NULL, the system allocates memory for the device-independent bitmap. The system closes the handle to that memory when you later delete the device-independent bitmap by calling the DeleteObject function. If hSection is not NULL, you must close the hSection memory handle yourself after calling DeleteObject to delete the bitmap.
Придется учить англицкий, как же ты собираешься программировать? Не так уж и плохо владеть несколькими языками!
NaZGuL Если hSection равен нулю, тогда система сама выделить память под картинку, которая, затем будет автоматически освобождена, если в hSection лежит адрес памяти, то картинка будет находится там. crypto Это правда, без этого будет очень сложно.
crypto,mix_mix, мне пока и этого хватает! Общий смысл понятен и ладно Но все равно я над этим подумаю. mix_mix, ты забыл сказать про самое главное, чтобы удалить из памяти нужно удалить bitmap, а затем вызвать DeleteObject... (вроде так)
О как !, сколько тонкостей, тут чувствуется не как в DOSe твори что хочешь, а еще и последовательность важна С битмапом на силу разобрался, конечно крайне непонравилось то что функция CreateDIBSection сама выделяет память, вот если бы я самостаятельно мог её выделять, а потом подсунуть указатель в эту функцию - это было бы гораздо прямее. А вот что делать с палитрой, интересно. Если её подсунуть вместе со структурой BITMAPINFO в CrateDIBSection, то все отображается как надо. Теперь встает задача изменить палитру, делаю следующие действия: hPal = CreatePalette(...) SelectPalette(hDC,hPal,FALSE) RealizePalette(hDC) в результате чего меняется только часть палитры, причем RealizePalette возвращает 0. Если же при создании битмапа в функции CreateDIBSection установить параметр iUsage = DIB_PAL_COLORS и, соответственно не передавать в структуре BITMAPINFO информацию о палитре, а задать её самому вышеперечисленными функциями, то - в итоге получается нераскрашеная черная картинка. В чем может быть косяк ? Основные мои предположения в том что используется 32 битный CompatibleDC, и он не поддерживает работу с палитрой, но почему все функции работы с палитрой возвращают ненулевые значения, кроме RealizePalette. Как-нибудь можно решить вопрос с установкой палитры для текущего битмапа?
Exception13, может попробовать SetDIBColorTable. В MSDN пишут про нее что она должна устанавливать палитру для DIB. PS: Заодно может глянеш тут?
Exception13 кароче, все в винде ништяк!!! открываешь gdi+ в msdn и читаешь. Там то, что тебе нужно делается в три строчки когда-то писал, но уже не помню ничего. все там очень просто делается и не загоняйся с gdi, это уже в прошлом! На rsdn.ru есть отличные примеры как работать с gdi+. И реализация работы BitBlt (не помню как там все это называется) там на много приятней, т.к. там все на ООП и ты можешь пользоваться этими удобствами.
Многие современные адаптеры не поддерживают операции с палитрой! API GetDeviceCaps может подтвердить это. Косвенно это ограничение обычно обходят через StretchDIBits или по-ламерски, т.е. прямо через массив RGB пиксельными функциями.