Сейчас на форуме: hgdagon, asfa (+3 невидимых)

 eXeL@B —› Программирование —› Как Windows делает скриншот
Посл.ответ Сообщение

Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 08 июня 2007 07:35
· Личное сообщение · #1

Скоко не пытался, не получается сделать хароший скриншот: не фоткаются панельки и календарики на рабочем столе; а в играх не все модели; но printscreen фоткает нормально. Вот мне интересно - как она это делает.




Ранг: 85.4 (постоянный)
Активность: 0.080
Статус: Участник

Создано: 08 июня 2007 07:47
· Личное сообщение · #2

fDc:=GetDC(0);
fCan.Handle := fDc;

помоему так должно работать..

-----
radio uno in ibisa ...




Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 08 июня 2007 10:44 · Поправил: AnXIouS
· Личное сообщение · #3

lcelot, как раз это и не работает.




Ранг: 60.1 (постоянный)
Активность: 0.120
Статус: Участник

Создано: 08 июня 2007 12:04
· Личное сообщение · #4

AnXIouS, может они у тебя прозрачные?




Ранг: 120.9 (ветеран), 5thx
Активность: 0.080
Статус: Участник
Programmer and reverser

Создано: 08 июня 2007 12:20
· Личное сообщение · #5

CreateCompatibleBitmap, SelectObject, а можно просто BitBlt или PrintWindow (но вроде она с дэсктопом не работает)

-----
Уважайте других и пишите грамотно.




Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 08 июня 2007 13:51
· Личное сообщение · #6

BitBlt непашет, я его и использую, PrintWindow кажется тоже.
Shidla, наверное в этом и проблема.
Обьясню подробнее: у мя робочий стол отключен, нету значков, заместь этого я пользуюсь разными виджетами, они с альфа прозрачностью; и пишу прогу-скриншот майкер. и надумал другу рабочим столом похвастатся. сфоткал, а он пустой . в играх такая же байда. но винда делает все на ура, от мне интересно, как ...




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 08 июня 2007 16:16 · Поправил: Rascal
· Личное сообщение · #7

была такая проблема у меня в проге. смело забрасываем делфи и открываем msdn.com и читаем внимательно про BitBlt.

ЗЫ: на счёт игр - там все гораздо сложнее. чтоб самому фоткать надо изгаляться. думаю, если вы не сумели сфоткать прозрачные окна, делать сеимки игр врядле получится. то что нет части моделей - читаем про вертикальную синхронизацию. опять же проблема лечится продвинутым способом, который достаточно нетривиален и нигде не описан =)

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 08 июня 2007 16:29
· Личное сообщение · #8

я бы на месте ТС поставил в сайсе bpx на OpenClipboard/SetClipboardData или чёнить такое и нажал PrtScr =]

-----
Shalom ebanats!





Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 08 июня 2007 17:27
· Личное сообщение · #9

ну ещё вариант просто сфоткать камерой, и дальше скинуть картинку. На баше были способы получения изображения экрана, так что простор для тестов есть =)

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 09 июня 2007 00:17
· Личное сообщение · #10

Pascal, очень смешно :-l



Ранг: 15.5 (новичок)
Активность: 0.010
Статус: Участник

Создано: 09 июня 2007 08:04 · Поправил: lapslap
· Личное сообщение · #11

AnXIouS небудет скриншотиться курсор и все Layered окна ( примером винамп со скином winamp_modern етц) и все что идет через directshow LA примером.. кино вопщем
если вас неустраивает то пешите мирор дрв ;)



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 09 июня 2007 08:18
· Личное сообщение · #12

Как делает виндос - хз. Скриншот можно сделать причитав видеопамять напрямую. Это должно работать и для большенства игр, только с оверлеями проблемы.

Вот довольно кривой (только для 32 битного цвета) пример (заштриховка экрана) с которого можно начать

#define INITGUID
#include <ddraw.h>
#include <windows.h>
#pragma comment(lib, "ddraw.lib")

void shade()
{
IDirectDraw7 * direct_draw;
IDirectDrawSurface7 * primary_surface;
DDSURFACEDESC2 surface_descriptor = { sizeof(surface_descriptor) };

DirectDrawCreateEx(0, (void**)&direct_draw, IID_IDirectDraw7, 0);

direct_draw->SetCooperativeLevel(0, DDSCL_NORMAL);

surface_descriptor.dwFlags = DDSD_CAPS;
surface_descriptor.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

direct_draw->CreateSurface(&surface_descriptor, &primary_surface, NULL);

primary_surface->Lock(0, &surface_descriptor, 0, 0);
void * memory = surface_descriptor.lpSurface;

for( int dy = surface_descriptor.dwHeight;
dy;
dy--, memory = (char *)memory + surface_descriptor.lPitch )
{
for( int dx = surface_descriptor.dwWidth; dx; --dx )
if ( (dx ^ dy) & 1 )
*((int *)memory + dx) = -1;
}
primary_surface->Unlock(0);
}




Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 11 июня 2007 00:14
· Личное сообщение · #13

S_T_A_S_, сенкс за пример. буду пробывать. у мня в самого идея про чтото подобное возникла, но мало инфы, мож кто нить ещо чо подкинет. если у когото есть чо нить то пусь в личных отпишется, я мыло дам, скините.



Ранг: 36.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 12 июня 2007 22:42
· Личное сообщение · #14

AnXIouS - Держи полностью рабочий пример... А то некоторые считают, что тут примеров не дают...
Просто жадины и лентяии...
#include "stdafx.h"
#define MAX_LOADSTRING 100

////////////////////////////////////////////////////////////////////// /////////

bool Capture(char *file) // Где аргумент - файл,в который сохранять рисунок.
{
HDC hdc;
HBITMAP bitmap;
BITMAPINFO bmpinfo;
LPVOID pBits;
HDC hdc2;
DWORD dwWidth, dwHeight, dwBPP, dwNumColors;
HGDIOBJ gdiobj;
HANDLE hfile;
DWORD dwBytes;

hdc=CreateDC("DISPLAY", NULL, NULL, NULL);
if(hdc==NULL) {
return FALSE;
}
dwWidth = GetDeviceCaps(hdc, HORZRES);
dwHeight = GetDeviceCaps(hdc, VERTRES);
dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
if(dwBPP<=8) {
dwNumColors = GetDeviceCaps(hdc, NUMCOLORS);
dwNumColors = 256;
} else {
dwNumColors = 0;
}
hdc2=CreateCompatibleDC(hdc);
if(hdc2==NULL) {
DeleteDC(hdc);
return FALSE;
}
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = dwWidth;
bmpinfo.bmiHeader.biHeight = dwHeight;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
bmpinfo.bmiHeader.biCompression = BI_RGB;
bmpinfo.bmiHeader.biSizeImage = 0;
bmpinfo.bmiHeader.biXPelsPerMeter = 0;
bmpinfo.bmiHeader.biYPelsPerMeter = 0;
bmpinfo.bmiHeader.biClrUsed = dwNumColors;
bmpinfo.bmiHeader.biClrImportant = dwNumColors;
bitmap = CreateDIBSection(hdc, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);
if(bitmap==NULL) {
DeleteDC(hdc);
DeleteDC(hdc2);
return FALSE;
}
gdiobj = SelectObject(hdc2, (HGDIOBJ)bitmap);
if((gdiobj==NULL) || (gdiobj==(void *)GDI_ERROR)) {
DeleteDC(hdc);
DeleteDC(hdc2);
return FALSE;
}
if (!BitBlt(hdc2, 0,0, dwWidth, dwHeight, hdc, 0,0, SRCCOPY)) {
DeleteDC(hdc);
DeleteDC(hdc2);
return FALSE;
}
RGBQUAD colors[256];
if(dwNumColors!=0) {
dwNumColors = GetDIBColorTable(hdc2, 0, dwNumColors, colors);
}
BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER bitmapinfoheader;
bitmapfileheader.bfType = 0x4D42;
bitmapfileheader.bfSize = ((dwWidth * dwHeight * dwBPP)/8) +
sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (dwNumColors *
sizeof(RGBQUAD));
bitmapfileheader.bfReserved1 = 0;
bitmapfileheader.bfReserved2 = 0;
bitmapfileheader.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER) + (dwNumColors * sizeof(RGBQUAD));
bitmapinfoheader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfoheader.biWidth = dwWidth;
bitmapinfoheader.biHeight = dwHeight;
bitmapinfoheader.biPlanes = 1;
bitmapinfoheader.biBitCount = (WORD)dwBPP;
bitmapinfoheader.biCompression = BI_RGB;
bitmapinfoheader.biSizeImage = 0;
bitmapinfoheader.biXPelsPerMeter = 0;
bitmapinfoheader.biYPelsPerMeter = 0;
bitmapinfoheader.biClrUsed = dwNumColors;
bitmapinfoheader.biClrImportant = 0;
hfile=CreateFile(file,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUT E_NORMAL,NULL);
if(hfile==INVALID_HANDLE_VALUE) {
DeleteObject(bitmap);
DeleteDC(hdc2);
DeleteDC(hdc);
return FALSE;
}
WriteFile(hfile,&bitmapfileheader,sizeof(BITMAPFILEHEADER), &dwBytes,
NULL);
WriteFile(hfile,&bitmapinfoheader,sizeof(BITMAPINFOHEADER), &dwBytes,
NULL);
if(dwNumColors!=0)
WriteFile(hfile,colors,sizeof(RGBQUAD)*dwNumColors,&dwBytes,NULL);
WriteFile(hfile,pBits,(dwWidth*dwHeight*dwBPP)/8,&dwBytes,NULL);
CloseHandle(hfile);
DeleteObject(bitmap);
DeleteDC(hdc2);
DeleteDC(hdc);
return TRUE;
}


////////////////////////////////////////////////////////////////////// /////////
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SCREENSHORT2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SCREENSHORT2);

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int) msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SCREENSHORT2);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_SCREENSHORT2;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
Capture ("C:\1.bmp");// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}




Ранг: 22.6 (новичок)
Активность: 0.010
Статус: Участник

Создано: 14 июня 2007 02:04
· Личное сообщение · #15

sxd, опупеный пример, сенкс. з.ы. полезно иногда проги диасемблить: знач windowblinds я поковырял, и увидел что в функц. bitblt передается не scrcopy а 40000000h, зделал и себе так - фоткать стало лучше




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 14 июня 2007 02:21 · Поправил: Rascal
· Личное сообщение · #16

ну наконецто.
Rascal пишет:
смело забрасываем делфи и открываем msdn.com и читаем внимательно про BitBlt.

Вот что в мсдн, и что я тебе предлагал найти.
CAPTUREBLT Windows 98/Me, Windows 2000/XP: Includes any windows that are layered on top of your window in the resulting image. By default, the image only contains your window. Note that this generally cannot be used for printing device contexts.

Полезно пользоваться документацией, а не копаца в каждой программе по плёвому вопросу.

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 36.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 14 июня 2007 19:06
· Личное сообщение · #17

AnXIouS пишет:
sxd, опупеный пример, сенкс. з.ы.

Если надо ещё будет что-нибудь из исходников можешь смело писать личное сообщение... Буду только рад помочь... Помогая другим - помогаешь себе...



Ранг: 36.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 14 июня 2007 19:09
· Личное сообщение · #18

Rascal пишет:
Полезно пользоваться документацией

да это верно...

Rascal пишет:
а не копаца в каждой программе по плёвому вопросу

вот у меня тоже был вопрос плёвый с \r просмотрели всё документацию тока результат - "Дырка от бублика" поэтому и коверкали autochk.exe только всё-равно не помогло....




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 14 июня 2007 21:00
· Личное сообщение · #19

Я тоже ищу много информации в чужих программах. Только это происходит, когда я изучил все источники доступной информации, и не получил ответа. Здесь же человеку чётко было сказано где искать и по каким ключевым словам. Таких ленивых людей я не люблю. Сами задают вопрос, и сами игнорируют ответ =)
Закрывайте флудотопик

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 36.3 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 14 июня 2007 21:38
· Личное сообщение · #20

Rascal пишет:
Я тоже ищу много информации в чужих программах. Только это происходит, когда я изучил все источники доступной информации, и не получил ответа. Здесь же человеку чётко было сказано где искать и по каким ключевым словам. Таких ленивых людей я не люблю. Сами задают вопрос, и сами игнорируют ответ =)
Закрывайте флудотопик


Зачем так резко относиться к людям... Все разные... Вы уважаемый Rascal - ветеран... и Вам конечно всё легко и просто... А кто-то только делает первые шаги... Люди - не роботы... Все обучаемся...

Rascal пишет:
Закрывайте флудотопик

Да вопрос исчерпан... Пора килять...


 eXeL@B —› Программирование —› Как Windows делает скриншот
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати