Вывести на экран картинку как CStatic (Picture Control)?
Использую MFC.
Делаю так:
CStatic m_bitMap;
m_bitMap.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP,
CRect(100,100,250,250), this, IDB_PICTURE);
m_bitMap.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_PICTURE)));
//картинка в ресурсах с идентификатором IDB_PICTURE
Ничего не выводится!!!
Может есть другой путь???
Самый простой и проверенный способ :-)))
Создаешь ресурс Bitmap. Перетаскиваешь на форму элемент управления Picture Control, У него в свойствах параметр Type стоит Frame по умолчанию... Меняешь на Bitmap. Становится доступным свойство Image,
выставляешь там свой битмап, например IDB_BITMAP1.
:-)))
Ты как всегда помогаешь.
Твой способ хорош, но у меня не ресурсное диалоговое окно и туда статически не перетащить.
Я нашел способ. В моем коде нужно изменить последнюю строку с:
m_bitMap.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_PICTURE)));
на:
m_bitMap.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_PICTURE)));
и все работает!!!
Я не правильно перевел документацию в MSDN по поводу LoadBitmap().
Если первый параметр NULL, то загружается картинка не из ресурса приложения, а из ресурсов Windows (например, изображение курсора)
Надо было в школе лучше учить английский!!!
:-))))
CStatic m_bitMap;
m_bitMap.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP,
CRect(100,100,250,250), this, IDB_BITMAP1);
m_bitMap.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)));
Это прописал в событии нажатия на кнопку. Но при нажатии ничего не отображается, я раньше с C# работал, а тут на с++ нужно. Я так подозреваю что-то нужно указывать в OnPaint. Короче, не правильна сама логика или не там прописую. Подскажите, пожалуйста, где ошибка. Заранее благодарен.
Дебаггером пройдитесь на предмет LoadBitmap() и SetBitmap()
Цитата: Pipec
я тоже мучаюсь с этой проблемой. Сделал как написано:
CStatic m_bitMap;
m_bitMap.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP,
CRect(100,100,250,250), this, IDB_BITMAP1);
m_bitMap.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)));
Это прописал в событии нажатия на кнопку. Но при нажатии ничего не отображается, я раньше с C# работал, а тут на с++ нужно. Я так подозреваю что-то нужно указывать в OnPaint. Короче, не правильна сама логика или не там прописую. Подскажите, пожалуйста, где ошибка. Заранее благодарен.
CStatic m_bitMap;
m_bitMap.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BITMAP,
CRect(100,100,250,250), this, IDB_BITMAP1);
m_bitMap.SetBitmap(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)));
Это прописал в событии нажатия на кнопку. Но при нажатии ничего не отображается, я раньше с C# работал, а тут на с++ нужно. Я так подозреваю что-то нужно указывать в OnPaint. Короче, не правильна сама логика или не там прописую. Подскажите, пожалуйста, где ошибка. Заранее благодарен.
CStatic m_bitMap должен быть членом класса. Когда управление выходит из функции автоматический объект m_bitMap разрушается. С ним же разрушается и окно статика с вашим изображением.
Склеил всё вместе и получил следующее:
Код:
HBITMAP CMainWnd::GetScreen()//взять часть экрана
{
HDC scrdc, memdc;
HBITMAP membit;
scrdc=::GetDC(0);
scrdc=::GetWindowDC(::GetDesktopWindow());
memdc=::CreateCompatibleDC(scrdc);
int xx=70;
int yy=70;
membit=::CreateCompatibleBitmap(scrdc,xx,yy);
HBITMAP oldBMP=(HBITMAP)SelectObject(memdc,membit);
BitBlt(memdc,0,0,xx,yy,scrdc,0,0,SRCCOPY);
return oldBMP;
}
void CMainWnd::OnPaint()//прорисовка окна
{
int a;
CDC sourceDC;
HBITMAP image1;
CBitmap image2;
CPaintDC targetDC(this);
sourceDC.CreateCompatibleDC(&targetDC);
image1=GetScreen();
image2.FromHandle(image1);
sourceDC.SelectObject(&image2);
sourceDC.Ellipse(20,20,60,60);
targetDC.BitBlt(0,0,70,70,&sourceDC,0,0,SRCCOPY);
}
{
HDC scrdc, memdc;
HBITMAP membit;
scrdc=::GetDC(0);
scrdc=::GetWindowDC(::GetDesktopWindow());
memdc=::CreateCompatibleDC(scrdc);
int xx=70;
int yy=70;
membit=::CreateCompatibleBitmap(scrdc,xx,yy);
HBITMAP oldBMP=(HBITMAP)SelectObject(memdc,membit);
BitBlt(memdc,0,0,xx,yy,scrdc,0,0,SRCCOPY);
return oldBMP;
}
void CMainWnd::OnPaint()//прорисовка окна
{
int a;
CDC sourceDC;
HBITMAP image1;
CBitmap image2;
CPaintDC targetDC(this);
sourceDC.CreateCompatibleDC(&targetDC);
image1=GetScreen();
image2.FromHandle(image1);
sourceDC.SelectObject(&image2);
sourceDC.Ellipse(20,20,60,60);
targetDC.BitBlt(0,0,70,70,&sourceDC,0,0,SRCCOPY);
}
В итоге, image1!=NULL, а image2 не содержит изображения, т.е. вывода в форму НЕТ. Сам вывод на форму работает, проверял загрузкой BMP-файла из ресурсов (image2.LoadBitmap(IDB_BITMAP1)).
Подскажите пожалуйста в какую сторону копать.
и поясните это:
scrdc=::GetDC(0);
scrdc=::GetWindowDC(::GetDesktopWindow());
Почему захват экрана пытаетесь произвести в OnPaint ?
Цитата: Phodopus
Почему захват экрана пытаетесь произвести в OnPaint ?
Посчитал, что нет разницы, где делать захват. А в OnPaint сразу и выведу результат.
PS. У меня в проекте есть ещё таймер, который запускается каждую секунду. Там дальше и будет захват производиться с прорисовкой окна.
PPS. Программирую только неделю, поэтому опыта маловато.
Битмап нужно освобождать из контекста, контекст уничтожать
Цитата: Phodopus
Битмап нужно освобождать из контекста, контекст уничтожать
Можно по-подробнее? Хотя сомневаюсь, что это решит проблему.
Как мне кажется, или захват экрана не происходит, или image2.FromHandle(image1) не работает.
Сам понять этого не могу, поэтому и обращаюсь за помощью.
Еще один SelectObject и DeleteDC походу. MSDN почитайте
Код:
void CMainWnd::Init()
{
hDC =::GetDC(hWind);
sx=320;
sy=240;
scrx=320;
scry=240;
ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biWidth = sx;
bi.bmiHeader.biHeight = sy;
bi.bmiHeader.biSizeImage = 0;
pBuff = NULL;
pBuff2 = new BYTE[sx*sy*4];
newDC = CreateCompatibleDC(hDC);
hBitmap = CreateDIBSection(newDC, &bi, DIB_RGB_COLORS, (void **)&pBuff, NULL, NULL);
hOldBitmap = (HBITMAP)SelectObject(newDC, hBitmap);
hBrush = CreateSolidBrush(0xFF);
hOldBrush = (HBRUSH)SelectObject(newDC, hBrush);
//---
ZeroMemory(&bh, sizeof(bh));
bh.biSize = sizeof(BITMAPINFOHEADER);
bh.biPlanes = 1;
bh.biBitCount = 32;
bh.biCompression = BI_RGB;
bh.biWidth = sx;
bh.biHeight = -sy;
bh.biSizeImage=0;
}
//=============================
void CMainWnd::Get_2()
{
int a,y,x,z;
int flag = BitBlt(newDC,0,0,scrx,scry,hDC,0,0,SRCCOPY);
GetDIBits(newDC,hBitmap,0,sy,pBuff2,(BITMAPINFO*)&bh, DIB_RGB_COLORS);
HDC hdc=GetDC()->m_hDC;
for(y=0; y<bi.bmiHeader.biHeight; y++)
for(x=0; x<bi.bmiHeader.biWidth; x++)
{
SetPixel(hdc,x,y,*((DWORD*)pBuff2 + y*bi.bmiHeader.biWidth + x));
}
a=GetLastError();
if(a!=0)num=0;
}
//==============================
void CMainWnd::OnPaint()
{
CPaintDC targetDC(this);
ReleaseDC(&targetDC);
}
//===============================
CMainWnd::CMainWnd()
{
num=0;
sec=0;
CRect r1;
r1.SetRect(100,100,500,500);
Create(NULL,"GetWindow",WS_OVERLAPPEDWINDOW,r1,NULL,NULL);
SetTimer(1, 40, NULL);
//---
hWind=::FindWindow(NULL,"Open Video Capture");
if(hWind!=NULL){num=1;}
Init();
}
//=============================
void CMainWnd::OnTimer(UINT)
{
sec++;
if(num==1)Get_2();
OnPaint();
}
{
hDC =::GetDC(hWind);
sx=320;
sy=240;
scrx=320;
scry=240;
ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biWidth = sx;
bi.bmiHeader.biHeight = sy;
bi.bmiHeader.biSizeImage = 0;
pBuff = NULL;
pBuff2 = new BYTE[sx*sy*4];
newDC = CreateCompatibleDC(hDC);
hBitmap = CreateDIBSection(newDC, &bi, DIB_RGB_COLORS, (void **)&pBuff, NULL, NULL);
hOldBitmap = (HBITMAP)SelectObject(newDC, hBitmap);
hBrush = CreateSolidBrush(0xFF);
hOldBrush = (HBRUSH)SelectObject(newDC, hBrush);
//---
ZeroMemory(&bh, sizeof(bh));
bh.biSize = sizeof(BITMAPINFOHEADER);
bh.biPlanes = 1;
bh.biBitCount = 32;
bh.biCompression = BI_RGB;
bh.biWidth = sx;
bh.biHeight = -sy;
bh.biSizeImage=0;
}
//=============================
void CMainWnd::Get_2()
{
int a,y,x,z;
int flag = BitBlt(newDC,0,0,scrx,scry,hDC,0,0,SRCCOPY);
GetDIBits(newDC,hBitmap,0,sy,pBuff2,(BITMAPINFO*)&bh, DIB_RGB_COLORS);
HDC hdc=GetDC()->m_hDC;
for(y=0; y<bi.bmiHeader.biHeight; y++)
for(x=0; x<bi.bmiHeader.biWidth; x++)
{
SetPixel(hdc,x,y,*((DWORD*)pBuff2 + y*bi.bmiHeader.biWidth + x));
}
a=GetLastError();
if(a!=0)num=0;
}
//==============================
void CMainWnd::OnPaint()
{
CPaintDC targetDC(this);
ReleaseDC(&targetDC);
}
//===============================
CMainWnd::CMainWnd()
{
num=0;
sec=0;
CRect r1;
r1.SetRect(100,100,500,500);
Create(NULL,"GetWindow",WS_OVERLAPPEDWINDOW,r1,NULL,NULL);
SetTimer(1, 40, NULL);
//---
hWind=::FindWindow(NULL,"Open Video Capture");
if(hWind!=NULL){num=1;}
Init();
}
//=============================
void CMainWnd::OnTimer(UINT)
{
sec++;
if(num==1)Get_2();
OnPaint();
}
и т.д.
А как массив BYTE *pBuff2; можно запихнуть в IplImage *img ???