123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /*
- * Copyright (c) 2009, The Mozilla Foundation
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Foundation nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY The Mozilla Foundation ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL The Mozilla Foundation BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Contributors:
- * Ted Mielczarek <ted.mielczarek@gmail.com>
- */
- /*
- * win32-screenshot.cpp: Save a screenshot of the Windows desktop in .png format.
- * If a filename is specified as the first argument on the commandline,
- * then the image will be saved to that filename. Otherwise, the image will
- * be saved as "screenshot.png" in the current working directory.
- */
- // VS2015: Platform SDK 8.1's GdiplusTypes.h uses the min macro
- #undef NOMINMAX
- #undef WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <gdiplus.h>
- // Link w/ subsystem windows so we don't get a console when executing
- // this binary.
- #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
- using namespace Gdiplus;
- // From http://msdn.microsoft.com/en-us/library/ms533843%28VS.85%29.aspx
- static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
- {
- UINT num = 0; // number of image encoders
- UINT size = 0; // size of the image encoder array in bytes
- ImageCodecInfo* pImageCodecInfo = nullptr;
- GetImageEncodersSize(&num, &size);
- if(size == 0)
- return -1; // Failure
- pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
- if(pImageCodecInfo == nullptr)
- return -1; // Failure
- GetImageEncoders(num, size, pImageCodecInfo);
- for(UINT j = 0; j < num; ++j)
- {
- if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
- {
- *pClsid = pImageCodecInfo[j].Clsid;
- free(pImageCodecInfo);
- return j; // Success
- }
- }
- free(pImageCodecInfo);
- return -1; // Failure
- }
- #ifdef __MINGW32__
- extern "C"
- #endif
- int wmain(int argc, wchar_t** argv)
- {
- GdiplusStartupInput gdiplusStartupInput;
- ULONG_PTR gdiplusToken;
- GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
- HWND desktop = GetDesktopWindow();
- HDC desktopdc = GetDC(desktop);
- HDC mydc = CreateCompatibleDC(desktopdc);
- int width = GetSystemMetrics(SM_CXSCREEN);
- int height = GetSystemMetrics(SM_CYSCREEN);
- HBITMAP mybmp = CreateCompatibleBitmap(desktopdc, width, height);
- HBITMAP oldbmp = (HBITMAP)SelectObject(mydc, mybmp);
- BitBlt(mydc,0,0,width,height,desktopdc,0,0, SRCCOPY|CAPTUREBLT);
- SelectObject(mydc, oldbmp);
- const wchar_t* filename = (argc > 1) ? argv[1] : L"screenshot.png";
- Bitmap* b = Bitmap::FromHBITMAP(mybmp, nullptr);
- CLSID encoderClsid;
- Status stat = GenericError;
- if (b && GetEncoderClsid(L"image/png", &encoderClsid) != -1) {
- stat = b->Save(filename, &encoderClsid, nullptr);
- }
- if (b)
- delete b;
- // cleanup
- GdiplusShutdown(gdiplusToken);
- ReleaseDC(desktop, desktopdc);
- DeleteObject(mybmp);
- DeleteDC(mydc);
- return stat == Ok ? 0 : 1;
- }
|