ReactOS 0.4.15-dev-7953-g1f49173
screenshot.c
Go to the documentation of this file.
1#include "screenshot.h"
2
3/*
4 * Save a screenshot to file until the clipboard
5 * is ready to accept images.
6 */
7
8
9static VOID
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}
31
32
33static BOOL
35 LPTSTR pstrFileName)
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}
134
135
136static BOOL
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}
161
162
163static BOOL
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}
221
222
223static BOOL
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}
338
339
340// INT WINAPI GetScreenshot(BOOL bFullScreen)
342 HINSTANCE hPrevInstance,
343 LPTSTR szCmdLine,
344 int iCmdShow)
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 CDERR_GENERALCODES
Definition: cderr.h:5
DWORD WINAPI CommDlgExtendedError(void)
Definition: cdlg32.c:148
HINSTANCE hInstance
Definition: charmap.c:19
#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
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define FILE_BEGIN
Definition: compat.h:761
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#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
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
#define BI_RGB
Definition: precomp.h:56
ULONG RGBQUAD
Definition: precomp.h:59
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
pKey DeleteObject()
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define _tWinMain
Definition: tchar.h:498
#define CREATE_ALWAYS
Definition: disk.h:72
static HDC
Definition: imagelist.c:92
_In_ HANDLE hFile
Definition: mswsock.h:90
#define GENERIC_WRITE
Definition: nt_native.h:90
static VOID GetError(VOID)
Definition: screenshot.c:10
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
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
OPENFILENAME ofn
Definition: sndrec32.cpp:56
& rect
Definition: startmenu.cpp:1413
Definition: bl.h:1331
HWND hSelf
Definition: screenshot.h:6
LPVOID lpvBits
Definition: screenshot.h:10
HBITMAP hBitmap
Definition: screenshot.h:8
LPBITMAPINFO lpbi
Definition: screenshot.h:9
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
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
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
#define FormatMessage
Definition: winbase.h:3795
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FILE_CURRENT
Definition: winbase.h:113
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define DeleteFile
Definition: winbase.h:3764
#define CreateFile
Definition: winbase.h:3749
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#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)
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)
struct tagBITMAPINFO * PBITMAPINFO
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define MB_ICONERROR
Definition: winuser.h:787
HDC WINAPI GetDC(_In_opt_ HWND)
#define MB_OK
Definition: winuser.h:790
#define MessageBox
Definition: winuser.h:5822
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192