Корректный захват скриншота?
От: creatman Германия  
Дата: 21.02.08 15:10
Оценка:
Подскажите, как можно программно получить снимок экрана эквивалентный тому, который получается при нажатии клавиши Print Screen. Попробывал делать через GetDesktopWindow. Но обнаружил следующее: некоторые окна програм написанных под .NET не снимаются (отсутствуют в снимке экрана), а если делать через Print Screen они отображены на скриншоте. Какие есть еще способы получить снимок экрана, чтобы захвачено было все?


Re: Корректный захват скриншота?
От: niko_ Россия www.KGBSpy.ru
Дата: 21.02.08 15:34
Оценка: +1
Здравствуйте, creatman, Вы писали:

C>Подскажите, как можно программно получить снимок экрана эквивалентный тому, который получается при нажатии клавиши Print Screen. Попробывал делать через GetDesktopWindow. Но обнаружил следующее: некоторые окна програм написанных под .NET не снимаются (отсутствуют в снимке экрана), а если делать через Print Screen они отображены на скриншоте. Какие есть еще способы получить снимок экрана, чтобы захвачено было все?



Вот хороший кусочек кода (из MSDN'а):

// Create a normal DC and a memory DC for the entire screen. The 
// normal DC provides a "snapshot" of the screen contents. The 
// memory DC keeps a copy of this "snapshot" in the associated 
// bitmap. 
 
hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); 
hdcCompatible = CreateCompatibleDC(hdcScreen); 
 
// Create a compatible bitmap for hdcScreen. 
 
hbmScreen = CreateCompatibleBitmap(hdcScreen, 
                     GetDeviceCaps(hdcScreen, HORZRES), 
                     GetDeviceCaps(hdcScreen, VERTRES)); 
 
if (hbmScreen == 0) 
    errhandler("hbmScreen", hwnd); 
 
// Select the bitmaps into the compatible DC. 
 
if (!SelectObject(hdcCompatible, hbmScreen)) 
    errhandler("Compatible Bitmap Selection", hwnd); 
 
        // Hide the application window. 
 
        ShowWindow(hwnd, SW_HIDE); 
 
         //Copy color data for the entire display into a 
         //bitmap that is selected into a compatible DC. 
 
        if (!BitBlt(hdcCompatible, 
               0,0, 
               bmp.bmWidth, bmp.bmHeight, 
               hdcScreen, 
               0,0, 
               SRCCOPY)) 
 
        errhandler("Screen to Compat Blt Failed", hwnd); 
 
        // Redraw the application window. 
 
        ShowWindow(hwnd, SW_SHOW);
The truth is out there
Re[2]: Корректный захват скриншота?
От: Andrew S Россия http://alchemy-lab.com
Дата: 21.02.08 17:27
Оценка: +1
C>>Подскажите, как можно программно получить снимок экрана эквивалентный тому, который получается при нажатии клавиши Print Screen. Попробывал делать через GetDesktopWindow. Но обнаружил следующее: некоторые окна програм написанных под .NET не снимаются (отсутствуют в снимке экрана), а если делать через Print Screen они отображены на скриншоте. Какие есть еще способы получить снимок экрана, чтобы захвачено было все?


_>Вот хороший кусочек кода (из MSDN'а):


[skipped]

Указанный код не снимет лайеред окна (это решается соотв. флагом в bitblt). Ну и оверлей... (а это уже не решается)
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Корректный захват скриншота?
От: AndNot Россия  
Дата: 22.02.08 07:33
Оценка: +1 -1
Здравствуйте, creatman, Вы писали:

C>Подскажите, как можно программно получить снимок экрана эквивалентный тому, который


Да никак, пускай винда сама это делает, а мы лучше возьмем результат:
keybd_event(VK_SNAPSHOT, 0, 0, 0); // нажимаем PrintScreen
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); // отжимаем его

А дальше берем битмап из буфера обмена
Re[2]: Корректный захват скриншота?
От: Pavel Dvorkin Россия  
Дата: 22.02.08 07:44
Оценка:
Здравствуйте, AndNot, Вы писали:

AN>Да никак, пускай винда сама это делает, а мы лучше возьмем результат:

AN>
AN>keybd_event(VK_SNAPSHOT, 0, 0, 0); // нажимаем PrintScreen
AN>keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); // отжимаем его
AN>

AN>А дальше берем битмап из буфера обмена

И получаем по шее от пользователя за порчу Clipboard.
With best regards
Pavel Dvorkin
Re[3]: Корректный захват скриншота?
От: AndNot Россия  
Дата: 22.02.08 09:18
Оценка: +1 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>И получаем по шее от пользователя за порчу Clipboard.


Не смеши мои ботинки :D Про буфер обмена, в условии, нет ни слова. Если уж так нужно сохранить его "девственность", то можно сделать это самому. В чем проблемы то?
Re[3]: Корректный захват скриншота?
От: creatman Германия  
Дата: 22.02.08 11:56
Оценка:
Здравствуйте, Andrew S, Вы писали:

C>>>Подскажите, как можно программно получить снимок экрана эквивалентный тому, который получается при нажатии клавиши Print Screen. Попробывал делать через GetDesktopWindow. Но обнаружил следующее: некоторые окна програм написанных под .NET не снимаются (отсутствуют в снимке экрана), а если делать через Print Screen они отображены на скриншоте. Какие есть еще способы получить снимок экрана, чтобы захвачено было все?



_>>Вот хороший кусочек кода (из MSDN'а):


AS>[skipped]


AS>Указанный код не снимет лайеред окна (это решается соотв. флагом в bitblt). Ну и оверлей... (а это уже не решается)


Действительно, нехватало флажка CAPTUREBLT


Re: Корректный захват скриншота?
От: Druidoff  
Дата: 22.02.08 20:18
Оценка:
Здравствуйте, creatman, Вы писали:

C>Подскажите, как можно программно получить снимок экрана эквивалентный тому, который получается при нажатии клавиши Print Screen. Попробывал делать через GetDesktopWindow. Но обнаружил следующее: некоторые окна програм написанных под .NET не снимаются (отсутствуют в снимке экрана), а если делать через Print Screen они отображены на скриншоте. Какие есть еще способы получить снимок экрана, чтобы захвачено было все?



Я делаю так:

#include "atlimage.h" //использую для вызова newImage.Save(A2W(buf)); // чтобы сохранить полученую картинку в jpg формате.

HDC DC,newDC;
HBITMAP hBmp;
CImage newImage;

DC = GetDC(NULL); //взять контекст устройств дисплея
newDC = CreateCompatibleDC(DC); // создать ему совместимый контекст устройства
int xD= GetSystemMetrics(SM_CXSCREEN); размары экрана
int yD = GetSystemMetrics(SM_CYSCREEN);размары экрана
hBmp = CreateCompatibleBitmap(DC,xD,yD); создания совместимого с контекстом устройства битмапа
SelectObject(newDC,hBmp);
if (!BitBlt(newDC,0,0,xD,yD,DC,0,0,SRCCOPY|CAPTUREBLT)) ATLTRACE("\nErrror!!\n"); CAPTUREBLT для отображеняи layred окон

newImage.Attach(hBmp);
char buf[30]={""};
USES_CONVERSION;
sprintf(buf,"C:\\%d.jpg",i); /
newImage.Save(A2W(buf));// сохранние картиники на диск!

Осталось добавить токо проверки на работу апишек и в принцыпе все! Работает проверял!
Re[4]: Корректный захват скриншота?
От: Leonid Troyanovsky  
Дата: 24.02.08 16:57
Оценка:
Здравствуйте, AndNot, Вы писали:

AN>Не смеши мои ботинки :D Про буфер обмена, в условии, нет ни слова. Если уж так нужно сохранить его "девственность", то можно сделать это самому. В чем проблемы то?


Код собс-ручного сохранения невинности — в студию.
--
С уважением, LVT
Re[4]: Корректный захват скриншота?
От: Pavel Dvorkin Россия  
Дата: 25.02.08 10:49
Оценка:
Здравствуйте, AndNot, Вы писали:

AN>Не смеши мои ботинки :D Про буфер обмена, в условии, нет ни слова.


И не надо. В любой задаче портить Clipboard нельзя. Только в операциях типа Copy/Cut... можно. Иными словами, только с прямого указания юзера
With best regards
Pavel Dvorkin
Re[2]: Корректный захват скриншота?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 25.02.08 11:03
Оценка:
Здравствуйте, AndNot, Вы писали:

AN>
AN>keybd_event(VK_SNAPSHOT, 0, 0, 0); // нажимаем PrintScreen
AN>keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); // отжимаем его
AN>

Race condition. Нет гарантии, что из буфера получишь именно результат PrintScreen.
Ce n'est que pour vous dire ce que je vous dis.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.