PDA

Просмотр полной версии : Как получить BitMap из DC



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

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

Спасибо.

Absurd
08.04.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.

Romeo
08.04.2005, 12:44
Вобщем, AiK, ты всё сделал правильно. Недостающий шаг - CreateCompatibleBitmap.

AiK
08.04.2005, 13:03
Romeo, именно его и не хватало. Кроме того, CompatibleBitmap нужно высвобождать, загружая в DC с ним связанный, дефолтную BitMap через SelectObject. Без этого использовать CompatibleBitmap не получится.

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

Спасибо

VladT
20.04.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
21.04.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
21.04.2005, 13:22
VladT, с битмапом всё нормально работает, только как я писал выше, его высвобождать нужно:
pOldBitmap = SelectObject(dcCompatible, pBitMap);
...
SelectObject(dcCompatible, pOldBitmap);

bmp снимается не с окна IE.
Хотя эта строчка hresult =
У IE окон воз и маленькая тележка...

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

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