Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Подскажите, как снять скриншот с экрана?


Автор: Dmitriy2k 23.7.2009, 15:16
Нужно снять скриншот с рабочего экрана и сохранить в перемненной типа BITMAP
Снятие скриншота(взял из билдера, а пишу я на VC60)

Код
                       
             HDC hDc,hMemDc;
             BITMAP hBmpNew,hBmpOld; 
             
             hDc=GetDC(hWnd);//вообще, мне нужен хэндл всего рабочего стола со всеми открытыми окнами
             hMemDc = CreateCompatibleDC(hDc);
             hBmpNew = CreateCompatibleBitmap(hDc, 500, 500);
                          ///////////ошибка!!!///////////////////////////////////////////////////////////////////////////////////////////////////////
                         error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'struct
                         HBITMAP__ *' (or there is no acceptable conversion)
                          //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            hBmpOld = SelectObject(hMemDc, (void*)hBmpNew);
                          ///////ошибка!!!///////////////////////////////////////////////////////////////////////////////////////////////////////
                            error C2664: 'SelectObject' : cannot convert parameter 2 from 'struct tagBITMAP' to 'void *'
                          BitBlt(hMemDc, 0, 0, 500, 500, hDc, 0, 0, SRCCOPY);
                           ////////////////////////////////////////////////////////////////////////////////////////////////



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

Автор: Andrey44 23.7.2009, 15:25
Код

    HDC hDc,hMemDc;
    HBITMAP hBmpNew,hBmpOld; 

    hDc = ::GetDC(NULL);//хэндл всего рабочего стола со всеми открытыми окнами
    hMemDc = CreateCompatibleDC(hDc);
    hBmpNew = CreateCompatibleBitmap(hDc, 500, 500);

    hBmpOld = (HBITMAP)SelectObject(hMemDc, hBmpNew);
    
    BitBlt(hMemDc, 0, 0, 500, 500, hDc, 0, 0, SRCCOPY);//?? не вижу смысла в этой строкке
    ////////////////////////////////////////////////////////////////////////////////////////////////


Автор: Alca 23.7.2009, 15:39
http://weseetips.com/2008/07/14/how-to-capture-the-screenshot-of-window/

Добавлено через 40 секунд
Код

#include <atlimage.h>
#include <Gdiplusimaging.h>
        //...
        CBitmap bitmap;
        bitmap.CreateBitmap(width, height, 1, 32, rgbData);
        CImage image;
        image.Attach(bitmap);
        image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);


Добавлено через 1 минуту и 24 секунды
http://www.developerfusion.com/code/1708/screen-capture-to-the-clipboard/

Автор: GremlinProg 23.7.2009, 18:51
Dmitriy2k, уточняю, ошибка была тут:
Цитата(Dmitriy2k @  23.7.2009,  17:16 Найти цитируемый пост)
BITMAP hBmpNew,hBmpOld; 

Цитата(Andrey44 @  23.7.2009,  17:25 Найти цитируемый пост)
BitBlt(hMemDc, 0, 0, 500, 500, hDc, 0, 0, SRCCOPY);//?? не вижу смысла в этой строкке

все нормально, к этой строке и приводился весь предыдущий код

Автор: Andrey44 24.7.2009, 06:41
Цитата(GremlinProg @  23.7.2009,  18:51 Найти цитируемый пост)
все нормально, к этой строке и приводился весь предыдущий код

Так в hMemDc мы уже и так имеем картинку стола
Код

hBmpNew = CreateCompatibleBitmap(hDc, 500, 500);
hBmpOld = (HBITMAP)SelectObject(hMemDc, hBmpNew);

Или я что-то не так понимаю?

Автор: GremlinProg 24.7.2009, 22:34
CreateCompatibleBitmap - создаст пустой битмап (обычно черный)
SelectObject - выберет этот битмап в hMemDc
и только BitBlt заполнит этот битмап картинкой

Автор: Dmitriy2k 25.7.2009, 14:03
Спасибо за ответы!!!
Дело в том, что мне не только нужно сохранить скриншот в BITMAPE, но и отобразить его в окне.

Делал я следующее:

Код

case WM_PAINT:
HDC hDc,hCompatibleDC;
HANDLE hBmpNew,hBmpOld; 
PAINTSTRUCT PaintStruct;
BITMAP Bitmap;
RECT Rect;
             

//Получаем контекст устройства
hDc=BeginPaint(hWnd,&PaintStruct);
//Загружаем bitmap, который будет отображаться в окне, из файла
hBmpNew=LoadImage(NULL,"C:\\puziri.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//БЕЗ ЭТОГО ПОЧЕМУ ТО НИЧЕГО НЕ РАБОТАЕТ
//Получаем размерность загруженного bitmapa
GetObject(hBmpNew,sizeof(BITMAP),&Bitmap);
//Создаем совместимый с контекстом окна контекст в памяти
//hCompatibleDC=CreateCompatibleDC(hDc);
//Создаем контекст рабочего стола.
hCompatibleDC=::GetDC(NULL);
//Делаем загруженный из файла bitmap текущим в совместимом контексте.
hBmpOld=SelectObject(hCompatibleDC,hBmpNew);
//Определяем размер рабочей области окна.
GetClientRect(hWnd,&Rect);
//Копируем bitmap c совместимого на основной контекст с масштабированием
StretchBlt(hDc,0,0,Rect.right,Rect.bottom,
hCompatibleDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,SRCCOPY);
//вновь делаем старый bitmap текущим.
SelectObject(hCompatibleDC,hBmpOld);
//удаляем загруженный с диска bitmap
DeleteObject(hBmpNew);
//Удаляем совместимый контекст.
DeleteDC(hCompatibleDC);
//Освобождаем основной контекст,завершая перерисовку рабочей области окна.
EndPaint(hWnd,&PaintStruct);
return 0;

break;            

это не мое творение. это из книги Румянцева 2001г. Конечно, я кое что переделал.

Отображение куска(левый верхний угол) скриншота отображается растянутым.
При передвижении данного окна срабатывает сообщение WM_PAINT, и собственно происходит перерисовка.

Я хотел бы сделать скриншот всего экрана(на разных компьютерах разное разрешение)
Вообще, реально это сделать?



ПС: Скриншот данного скриншота я прикркпляю в файле.

Автор: Andrey44 27.7.2009, 07:06
Код

PAINTSTRUCT PaintStruct;
    HDC hDc;
    hDc = ::BeginPaint(hWnd, &PaintStruct);
    HDC hdesktopDC = ::GetDC(0);
    HDC memDC = ::CreateCompatibleDC(hdesktopDC);
    DWORD dwWidth = GetDeviceCaps(hdesktopDC, HORZRES);
    DWORD dwHeight = GetDeviceCaps(hdesktopDC, VERTRES);

    HBITMAP hBMP = ::CreateCompatibleBitmap(hdesktopDC, dwWidth, dwHeight);
    HBITMAP oldBitmap = ::SelectObject(memDC, hBMP);
    BitBlt(memDC, 0, 0, dwWidth, dwHeight, hdesktopDC, 0, 0, SRCCOPY);

    BitBlt(hDC, 0, 0, dwWidth, dwHeight, memDC, 0, 0, SRCCOPY);

    SelectObject(memDC, oldBitmap);
    ReleaseDC(hdesktopDC);
    DeleteObject(hBMP); 
    EndPaint(hWnd,&PaintStruct);

Вот что-то наподобие этого.

Автор: Dmitriy2k 27.7.2009, 19:42
Andrey44

Спасибо, так работает(переделав немного)!

Автор: Dmitriy2k 27.7.2009, 20:03
Код

case WM_PAINT:{
        PAINTSTRUCT PaintStruct;
        HDC hDC;
        RECT Rect;

                                hDC = BeginPaint(hWnd, &PaintStruct);
        HDC hdesktopDC = ::GetDC(0);
        HDC memDC = CreateCompatibleDC(hdesktopDC);
        DWORD dwWidth = GetDeviceCaps(hdesktopDC, HORZRES);
        DWORD dwHeight = GetDeviceCaps(hdesktopDC, VERTRES);

        HBITMAP hBMP = CreateCompatibleBitmap(hdesktopDC, dwWidth, dwHeight);
        HBITMAP oldBitmap = (struct HBITMAP__*)SelectObject(memDC, hBMP);
        BitBlt(memDC, 0, 0, dwWidth, dwHeight, hdesktopDC, 0, 0, SRCCOPY);

        BitBlt(hDC, 0, 0, dwWidth, dwHeight, memDC, 0, 0, SRCCOPY);
         
        //Определяем размер рабочей области
        GetClientRect(hWnd,&Rect);
            
        //копируем bitmap c совместимого на основной контекст с масштабированием
        StretchBlt(hDC,0,0,Rect.right,Rect.bottom,memDC,0,0,dwWidth,dwHeight,SRCCOPY);
        //вновь делаем старый bitmap текущим
        SelectObject(memDC, oldBitmap);
  
        ReleaseDC(hWnd,hdesktopDC);
        DeleteObject(hBMP); 
        EndPaint(hWnd,&PaintStruct);
        return 0;}
        break;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)