ReactOS 0.4.15-dev-7928-g68a8619
screenshot.c File Reference
#include "screenshot.h"
Include dependency graph for screenshot.c:

Go to the source code of this file.

Functions

static VOID GetError (VOID)
 
static BOOL DoWriteFile (PSCREENSHOT pScrSht, LPTSTR pstrFileName)
 
static BOOL DoSaveFile (HWND hwnd, LPTSTR szFileName)
 
static BOOL CaptureScreen (PSCREENSHOT pScrSht)
 
static BOOL ConvertDDBtoDIB (PSCREENSHOT pScrSht)
 
int WINAPI _tWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR szCmdLine, int iCmdShow)
 

Function Documentation

◆ _tWinMain()

int WINAPI _tWinMain ( HINSTANCE  hInstance,
HINSTANCE  hPrevInstance,
LPTSTR  szCmdLine,
int  iCmdShow 
)

Definition at line 341 of file screenshot.c.

345{
346 PSCREENSHOT pScrSht;
347 TCHAR szFileName[MAX_PATH] = _T("");
348
349 BOOL bFullScreen = TRUE;
350
351 pScrSht = HeapAlloc(GetProcessHeap(),
352 0,
353 sizeof(SCREENSHOT));
354 if (pScrSht == NULL)
355 return -1;
356
357 if (bFullScreen)
358 {
359 pScrSht->hSelf = GetDesktopWindow();
360 }
361 else
362 {
363 pScrSht->hSelf = GetForegroundWindow();
364 }
365
366 if (pScrSht->hSelf == NULL)
367 {
369 0,
370 pScrSht);
371
372 return -1;
373 }
374
375 if (CaptureScreen(pScrSht))
376 {
377 /* convert the DDB image to DIB */
378 if(ConvertDDBtoDIB(pScrSht))
379 {
380 /* Get filename from user */
381 if(DoSaveFile(pScrSht->hSelf, szFileName))
382 {
383 /* build the headers and write to file */
384 DoWriteFile(pScrSht, szFileName);
385 }
386 }
387 }
388
389 /* cleanup */
390 if (pScrSht->hSelf != NULL)
391 ReleaseDC(pScrSht->hSelf, pScrSht->hDC);
392 if (pScrSht->hBitmap != NULL)
393 DeleteObject(pScrSht->hBitmap);
394 if (pScrSht->lpbi != NULL)
396 0,
397 pScrSht->lpbi);
398 if (pScrSht->lpvBits != NULL)
400 0,
401 pScrSht->lpvBits);
402 if (pScrSht != NULL)
404 0,
405 pScrSht);
406
407 return 0;
408}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned int BOOL
Definition: ntddk_ex.h:94
pKey DeleteObject()
static BOOL DoSaveFile(HWND hwnd, LPTSTR szFileName)
Definition: screenshot.c:137
static BOOL ConvertDDBtoDIB(PSCREENSHOT pScrSht)
Definition: screenshot.c:224
static BOOL CaptureScreen(PSCREENSHOT pScrSht)
Definition: screenshot.c:164
static BOOL DoWriteFile(PSCREENSHOT pScrSht, LPTSTR pstrFileName)
Definition: screenshot.c:34
HWND hSelf
Definition: screenshot.h:6
LPVOID lpvBits
Definition: screenshot.h:10
HBITMAP hBitmap
Definition: screenshot.h:8
LPBITMAPINFO lpbi
Definition: screenshot.h:9
#define _T(x)
Definition: vfdio.h:22
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
char TCHAR
Definition: xmlstorage.h:189

◆ CaptureScreen()

static BOOL CaptureScreen ( PSCREENSHOT  pScrSht)
static

Definition at line 164 of file screenshot.c.

165{
166 HDC ScreenDC;
167 RECT rect;
168
169 /* get window resolution */
170 //pScrSht->Width = GetSystemMetrics(SM_CXSCREEN);
171 //pScrSht->Height = GetSystemMetrics(SM_CYSCREEN);
172
173 GetWindowRect(pScrSht->hSelf, &rect);
174 pScrSht->Width = rect.right - rect.left;
175 pScrSht->Height = rect.bottom - rect.top;
176
177 /* get a DC for the screen */
178 if (!(ScreenDC = GetDC(pScrSht->hSelf)))
179 return FALSE;
180
181 /* get a bitmap handle for the screen
182 * needed to convert to a DIB */
183 pScrSht->hBitmap = CreateCompatibleBitmap(ScreenDC,
184 pScrSht->Width,
185 pScrSht->Height);
186 if (pScrSht->hBitmap == NULL)
187 {
188 GetError();
189 ReleaseDC(pScrSht->hSelf, ScreenDC);
190 return FALSE;
191 }
192
193 /* get a DC compatable with the screen DC */
194 if (!(pScrSht->hDC = CreateCompatibleDC(ScreenDC)))
195 {
196 GetError();
197 ReleaseDC(pScrSht->hSelf, ScreenDC);
198 return FALSE;
199 }
200
201 /* select the bitmap into the DC */
202 SelectObject(pScrSht->hDC,
203 pScrSht->hBitmap);
204
205 /* copy the screen DC to the bitmap */
206 BitBlt(pScrSht->hDC,
207 0,
208 0,
209 pScrSht->Width,
210 pScrSht->Height,
211 ScreenDC,
212 0,
213 0,
214 SRCCOPY);
215
216 /* we're finished with the screen DC */
217 ReleaseDC(pScrSht->hSelf, ScreenDC);
218
219 return TRUE;
220}
#define FALSE
Definition: types.h:117
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:57
static HDC
Definition: imagelist.c:92
static VOID GetError(VOID)
Definition: screenshot.c:10
& rect
Definition: startmenu.cpp:1413
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define SRCCOPY
Definition: wingdi.h:333
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
HDC WINAPI GetDC(_In_opt_ HWND)

Referenced by _tWinMain().

◆ ConvertDDBtoDIB()

static BOOL ConvertDDBtoDIB ( PSCREENSHOT  pScrSht)
static

Definition at line 224 of file screenshot.c.

225{
226 INT Ret;
228 WORD cClrBits;
229
230
231/*
232 / * can't call GetDIBits with hBitmap selected * /
233 //SelectObject(hDC, hOldBitmap);
234
235 / * let GetDIBits fill the lpbi structure by passing NULL pointer * /
236 Ret = GetDIBits(hDC,
237 hBitmap,
238 0,
239 Height,
240 NULL,
241 lpbi,
242 DIB_RGB_COLORS);
243 if (Ret == 0)
244 {
245 GetError();
246 ReleaseDC(hwnd, hDC);
247 HeapFree(GetProcessHeap(), 0, lpbi);
248 return -1;
249 }
250*/
251
253
254 if (!GetObjectW(pScrSht->hBitmap,
255 sizeof(BITMAP),
256 (LPTSTR)&bitmap))
257 {
258 GetError();
259 return FALSE;
260 }
261
262 cClrBits = (WORD)(bitmap.bmPlanes * bitmap.bmBitsPixel);
263 if (cClrBits == 1)
264 cClrBits = 1;
265 else if (cClrBits <= 4)
266 cClrBits = 4;
267 else if (cClrBits <= 8)
268 cClrBits = 8;
269 else if (cClrBits <= 16)
270 cClrBits = 16;
271 else if (cClrBits <= 24)
272 cClrBits = 24;
273 else cClrBits = 32;
274
275 if (cClrBits != 24)
276 {
278 0,
279 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << cClrBits));
280 }
281 else
282 {
284 0,
285 sizeof(BITMAPINFOHEADER));
286 }
287
288 if (!pScrSht->lpbi)
289 {
290 GetError();
291 return FALSE;
292 }
293
294 pScrSht->lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
295 pScrSht->lpbi->bmiHeader.biWidth = bitmap.bmWidth;
296 pScrSht->lpbi->bmiHeader.biHeight = bitmap.bmHeight;
297 pScrSht->lpbi->bmiHeader.biPlanes = bitmap.bmPlanes;
298 pScrSht->lpbi->bmiHeader.biBitCount = bitmap.bmBitsPixel;
299
300 if (cClrBits < 24)
301 pScrSht->lpbi->bmiHeader.biClrUsed = (1 << cClrBits);
302
304 pScrSht->lpbi->bmiHeader.biSizeImage = ((pScrSht->lpbi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
305 * pScrSht->lpbi->bmiHeader.biHeight;
306
307 pScrSht->lpbi->bmiHeader.biClrImportant = 0;
308
310
311 /* reserve memory to hold the screen bitmap */
312 pScrSht->lpvBits = HeapAlloc(GetProcessHeap(),
313 0,
314 pScrSht->lpbi->bmiHeader.biSizeImage);
315 if (pScrSht->lpvBits == NULL)
316 {
317 GetError();
318 return FALSE;
319 }
320
321 /* convert the DDB to a DIB */
322 Ret = GetDIBits(pScrSht->hDC,
323 pScrSht->hBitmap,
324 0,
325 pScrSht->Height,
326 pScrSht->lpvBits,
327 pScrSht->lpbi,
329 if (Ret == 0)
330 {
331 GetError();
332 return FALSE;
333 }
334
335 return TRUE;
336
337}
#define BI_RGB
Definition: precomp.h:56
ULONG RGBQUAD
Definition: precomp.h:59
unsigned short WORD
Definition: ntddk_ex.h:93
Definition: bl.h:1331
Definition: uimain.c:89
ULONG biClrImportant
Definition: precomp.h:52
USHORT biBitCount
Definition: precomp.h:46
ULONG biCompression
Definition: precomp.h:47
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
int32_t INT
Definition: typedefs.h:58
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
struct tagBITMAPINFO * PBITMAPINFO
CHAR * LPTSTR
Definition: xmlstorage.h:192

Referenced by _tWinMain().

◆ DoSaveFile()

static BOOL DoSaveFile ( HWND  hwnd,
LPTSTR  szFileName 
)
static

Definition at line 137 of file screenshot.c.

138{
140
141 static TCHAR Filter[] = _T("24 bit Bitmap (*.bmp,*.dib)\0*.bmp\0");
142
143 ZeroMemory(&ofn, sizeof(ofn));
144 ofn.lStructSize = sizeof(OPENFILENAME);
148 ofn.lpstrDefExt = _T("bmp");
150 ofn.lpstrFile = szFileName;
152
153 if (GetSaveFileName(&ofn))
154 return TRUE;
155
157 MessageBox(NULL, _T("Save to file failed"), NULL, 0);
158
159 return FALSE;
160}
#define CDERR_GENERALCODES
Definition: cderr.h:5
DWORD WINAPI CommDlgExtendedError(void)
Definition: cdlg32.c:148
#define OFN_OVERWRITEPROMPT
Definition: commdlg.h:116
#define GetSaveFileName
Definition: commdlg.h:666
#define OFN_EXPLORER
Definition: commdlg.h:104
#define OFN_HIDEREADONLY
Definition: commdlg.h:107
#define OFN_PATHMUSTEXIST
Definition: commdlg.h:117
OPENFILENAMEA OPENFILENAME
Definition: commdlg.h:657
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
OPENFILENAME ofn
Definition: sndrec32.cpp:56
LPCSTR lpstrDefExt
Definition: commdlg.h:345
HWND hwndOwner
Definition: commdlg.h:330
LPSTR lpstrFile
Definition: commdlg.h:336
DWORD nMaxFileTitle
Definition: commdlg.h:339
DWORD Flags
Definition: commdlg.h:342
DWORD lStructSize
Definition: commdlg.h:329
LPCSTR lpstrFilter
Definition: commdlg.h:332
DWORD nMaxFile
Definition: commdlg.h:337
#define ZeroMemory
Definition: winbase.h:1712
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define MessageBox
Definition: winuser.h:5822

Referenced by _tWinMain().

◆ DoWriteFile()

static BOOL DoWriteFile ( PSCREENSHOT  pScrSht,
LPTSTR  pstrFileName 
)
static

Definition at line 34 of file screenshot.c.

36{
39 DWORD dwBytesWritten;
41 //INT PalEntries;
42
43 hFile = CreateFile(pstrFileName,
45 0,
46 NULL,
49 NULL);
50
52 return FALSE;
53
54 /* write the BITMAPFILEHEADER to file */
55 bmfh.bfType = *(WORD *)"BM"; // 0x4D 0x42
56 bmfh.bfReserved1 = 0;
57 bmfh.bfReserved2 = 0;
59 &bmfh,
60 sizeof(bmfh),
61 &dwBytesWritten,
62 NULL);
63 if ((!bSuccess) || (dwBytesWritten < sizeof(bmfh)))
64 goto fail;
65
66 /* write the BITMAPINFOHEADER to file */
68 &pScrSht->lpbi->bmiHeader,
69 sizeof(BITMAPINFOHEADER),
70 &dwBytesWritten,
71 NULL);
72 if ((!bSuccess) || (dwBytesWritten < sizeof(BITMAPINFOHEADER)))
73 goto fail;
74
75 /* calculate the size of the pallete * /
76 if (pScrSht->lpbi->bmiHeader.biCompression == BI_BITFIELDS)
77 PalEntries = 3;
78 else
79 {
80 if (pScrSht->lpbi->bmiHeader.biBitCount <= 8)
81 PalEntries = (INT)(1 << pScrSht->lpbi->bmiHeader.biBitCount);
82 else
83 PalEntries = 0;
84 }
85 if (pScrSht->lpbi->bmiHeader.biClrUsed)
86 PalEntries = pScrSht->lpbi->bmiHeader.biClrUsed;
87
88 / * write pallete to file * /
89 if (PalEntries != 0)
90 {
91 bSuccess = WriteFile(hFile,
92 &pScrSht->lpbi->bmiColors,
93 PalEntries * sizeof(RGBQUAD),
94 &dwBytesWritten,
95 NULL);
96 if ((!bSuccess) || (dwBytesWritten < PalEntries * sizeof(RGBQUAD)))
97 goto fail;
98 }
99*/
100 /* save the current file position at the bginning of the bitmap bits */
102
103 /* write the bitmap bits to file */
105 pScrSht->lpvBits,
106 pScrSht->lpbi->bmiHeader.biSizeImage,
107 &dwBytesWritten,
108 NULL);
109 if ((!bSuccess) || (dwBytesWritten < pScrSht->lpbi->bmiHeader.biSizeImage))
110 goto fail;
111
112 /* save the current file position at the final file size */
114
115 /* rewrite the updated file headers */
118 &bmfh,
119 sizeof(bmfh),
120 &dwBytesWritten,
121 NULL);
122 if ((!bSuccess) || (dwBytesWritten < sizeof(bmfh)))
123 goto fail;
124
125 return TRUE;
126
127fail:
128 GetError();
129 if (hFile) CloseHandle(hFile);
130 DeleteFile(pstrFileName);
131 return FALSE;
132
133}
#define CloseHandle
Definition: compat.h:739
#define FILE_BEGIN
Definition: compat.h:761
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static BOOLEAN bSuccess
Definition: drive.cpp:433
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CREATE_ALWAYS
Definition: disk.h:72
_In_ HANDLE hFile
Definition: mswsock.h:90
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_CURRENT
Definition: winbase.h:113
#define DeleteFile
Definition: winbase.h:3764
#define CreateFile
Definition: winbase.h:3749

Referenced by _tWinMain().

◆ GetError()

static VOID GetError ( VOID  )
static

Definition at line 10 of file screenshot.c.

11{
12 LPVOID lpMsgBuf;
13
17 NULL,
20 (LPTSTR) &lpMsgBuf,
21 0,
22 NULL );
23
25 lpMsgBuf,
26 _T("Error!"),
28
29 LocalFree(lpMsgBuf);
30}
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define FormatMessage
Definition: winbase.h:3795
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define MB_ICONERROR
Definition: winuser.h:787
#define MB_OK
Definition: winuser.h:790

Referenced by CaptureScreen(), ConvertDDBtoDIB(), and DoWriteFile().