Как получить BitMap из DC

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Eugie, Romeo, Hawk

Ответить
Аватара пользователя
AiK
Сообщения: 2271
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

08 апр 2005, 01:14

Задача: нарисовать поверх битмапины текст и передать новую битмапину контролу, чтобы он сам её отрисовывал.

Что делаю:
1. Гружу картинку с помощью LoadImage
2. Создаю DC через вызов CreateCompatibleDС
3. Связываю картинку и ранее созданный шрифт с DC с помощью SelectObject
4. Рисую текcт на DC DrawText
5. Нужно получить хэндл битмапины.
Если скопировать "замученный" DC в DC контрола, то на контроле отображается нужная картинка с нужным текстом. Т.е. до этого этапа всё сделано правильно.
Пытался получить хендл битмапины при помощи SelectObject - не получается. То же с помощью GetCurrentObject - опять не получается.
Что делать?

Спасибо.
Даже самый дурацкий замысел можно воплотить мастерски
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

08 апр 2005, 11:08

Если нужен хендл на DDB (Device-Dependent bitmap) Я бы сделал так
1) shadowHdc = CreateCompatibleDC(Hdc)
2) Загрузил ручками битмэп в пямять (К LoadImage я почему-то отношусь с недоверием)
3) CreateCompatibleBitmap(shadowHdc,image.width,image.heigth)
4) SetDIBitsToDevice(shadowHdc,...,rawImageBitsPtr )
5) CreateFont & TextOut(shadowHdc,....)
6) Селектим старый битмэп в shadowHdc и юзаем хендл от CreateCompatibleBitmap.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

08 апр 2005, 12:44

Вобщем, AiK, ты всё сделал правильно. Недостающий шаг - CreateCompatibleBitmap.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
AiK
Сообщения: 2271
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

08 апр 2005, 13:03

Romeo, именно его и не хватало. Кроме того, CompatibleBitmap нужно высвобождать, загружая в DC с ним связанный, дефолтную BitMap через SelectObject. Без этого использовать CompatibleBitmap не получится.
Даже самый дурацкий замысел можно воплотить мастерски
Kolinus
Сообщения: 449
Зарегистрирован: 23 авг 2004, 14:02
Откуда: Минск

08 апр 2005, 21:19

Реализую похожую задачу: с окна PowerPoint'a снимаю битмап (как описано выше), но если это окно перекрывается другим окном, то оно тоже попадает на битмап.
От этого можно как-нить избавиться?

Спасибо
В SAD - все в SAD.
VladT
Сообщения: 3
Зарегистрирован: 20 апр 2005, 17:57

20 апр 2005, 18:08

Kolinus,
у меня похожая задача, только снять и сохранить скриншот с IE
Все вроде сделал как здесь описано:

hresult = pBrowser->get_HWND(&hwnd);
HDC dcBrowser = GetDC((HWND)hwnd);
HDC dcCompatible = CreateCompatibleDC(dcBrowser);

HBITMAP pBitMap = CreateCompatibleBitmap(dcBrowser, width, height);
if (pBitMap == 0)
{ // error}

if (!SelectObject(dcCompatible, pBitMap))
{//"error in compatible bitmap selection"
}

if (!BitBlt(dcCompatible, 0, 0, width, height, dcBrowser, 0, 0, SRCCOPY))
{//("bitbit failed");
}

BITMAP bm;
GetObject(pBitMap, sizeof(bm), &bm);

в результате получаем в bm правильные размеры экрана,
но байт массив там NULL. Те копирование не произошло.

Что сделал не так?

Спасибо
VladT
Сообщения: 3
Зарегистрирован: 20 апр 2005, 17:57

21 апр 2005, 12:38

Вообщем заработало, оказывается нужно было не CreateCompatibleBitmap,
а CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&dibvalues,0,0);
SelectObject и BitBit тогда получаем bmp нормально.

По ходу возникла другая трабла.
bmp снимается не с окна IE.
Хотя эта строчка hresult = pBrowser->get_HWND(&hwnd)
возвращает валидный hwnd именно окна IE !!!!! И дальше работаю только с этим хендлом
В чем грабли ?
Аватара пользователя
AiK
Сообщения: 2271
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

21 апр 2005, 13:22

VladT, с битмапом всё нормально работает, только как я писал выше, его высвобождать нужно:
pOldBitmap = SelectObject(dcCompatible, pBitMap);
...
SelectObject(dcCompatible, pOldBitmap);
bmp снимается не с окна IE.
Хотя эта строчка hresult =
У IE окон воз и маленькая тележка...
Даже самый дурацкий замысел можно воплотить мастерски
VladT
Сообщения: 3
Зарегистрирован: 20 апр 2005, 17:57

21 апр 2005, 21:10

Пошел другим путем:
Пробую сделать как по науке получить у HtmlDocument IHtmlElement, и у него уже взять IHtmlElementRender, который уже может отрисовать нужный нам контент окна методом DrawToDC. Вроде все замечательно.

Однако и здесь засада, получить IHtmlElementRender путем
pElement->QueryInterface(IID_IHTMLElementRender, (void**) &pDisp); не получается ибо E_NOINTERFACE error !!!!
Спрашивается и гиде он подевался?
Вот такие вот будни Win программерства :)
Ответить