tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

win32-screenshot.cpp (4223B)


      1 /*
      2 * Copyright (c) 2009, The Mozilla Foundation
      3 * All rights reserved.
      4 *
      5 * Redistribution and use in source and binary forms, with or without
      6 * modification, are permitted provided that the following conditions are met:
      7 *     * Redistributions of source code must retain the above copyright
      8 *       notice, this list of conditions and the following disclaimer.
      9 *     * Redistributions in binary form must reproduce the above copyright
     10 *       notice, this list of conditions and the following disclaimer in the
     11 *       documentation and/or other materials provided with the distribution.
     12 *     * Neither the name of the Mozilla Foundation nor the
     13 *       names of its contributors may be used to endorse or promote products
     14 *       derived from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED BY The Mozilla Foundation ''AS IS'' AND ANY
     17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 * DISCLAIMED. IN NO EVENT SHALL The Mozilla Foundation BE LIABLE FOR ANY
     20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 *
     27 * Contributors:
     28 *   Ted Mielczarek <ted.mielczarek@gmail.com>
     29 */
     30 /*
     31 * win32-screenshot.cpp: Save a screenshot of the Windows desktop in .png
     32 * format. If a filename is specified as the first argument on the commandline,
     33 *  then the image will be saved to that filename. Otherwise, the image will
     34 *  be saved as "screenshot.png" in the current working directory.
     35 */
     36 
     37 // VS2015: Platform SDK 8.1's GdiplusTypes.h uses the min macro
     38 #undef NOMINMAX
     39 #undef WIN32_LEAN_AND_MEAN
     40 #include <windows.h>
     41 #include <gdiplus.h>
     42 
     43 // Link w/ subsystem windows so we don't get a console when executing
     44 // this binary.
     45 #ifndef __MINGW32__
     46 #  pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
     47 #endif
     48 
     49 using namespace Gdiplus;
     50 
     51 // From http://msdn.microsoft.com/en-us/library/ms533843%28VS.85%29.aspx
     52 static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
     53  UINT num = 0;   // number of image encoders
     54  UINT size = 0;  // size of the image encoder array in bytes
     55 
     56  ImageCodecInfo* pImageCodecInfo = nullptr;
     57 
     58  GetImageEncodersSize(&num, &size);
     59  if (size == 0) return -1;  // Failure
     60 
     61  pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
     62  if (pImageCodecInfo == nullptr) return -1;  // Failure
     63 
     64  GetImageEncoders(num, size, pImageCodecInfo);
     65 
     66  for (UINT j = 0; j < num; ++j) {
     67    if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
     68      *pClsid = pImageCodecInfo[j].Clsid;
     69      free(pImageCodecInfo);
     70      return j;  // Success
     71    }
     72  }
     73 
     74  free(pImageCodecInfo);
     75  return -1;  // Failure
     76 }
     77 
     78 #ifdef __MINGW32__
     79 extern "C"
     80 #endif
     81    int
     82    wmain(int argc, wchar_t** argv) {
     83  GdiplusStartupInput gdiplusStartupInput;
     84  ULONG_PTR gdiplusToken;
     85  GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
     86 
     87  HWND desktop = GetDesktopWindow();
     88  HDC desktopdc = GetDC(desktop);
     89  HDC mydc = CreateCompatibleDC(desktopdc);
     90  int width = GetSystemMetrics(SM_CXSCREEN);
     91  int height = GetSystemMetrics(SM_CYSCREEN);
     92  HBITMAP mybmp = CreateCompatibleBitmap(desktopdc, width, height);
     93  HBITMAP oldbmp = (HBITMAP)SelectObject(mydc, mybmp);
     94  BitBlt(mydc, 0, 0, width, height, desktopdc, 0, 0, SRCCOPY | CAPTUREBLT);
     95  SelectObject(mydc, oldbmp);
     96 
     97  const wchar_t* filename = (argc > 1) ? argv[1] : L"screenshot.png";
     98  Bitmap* b = Bitmap::FromHBITMAP(mybmp, nullptr);
     99  CLSID encoderClsid;
    100  Status stat = GenericError;
    101  if (b && GetEncoderClsid(L"image/png", &encoderClsid) != -1) {
    102    stat = b->Save(filename, &encoderClsid, nullptr);
    103  }
    104  if (b) delete b;
    105 
    106  // cleanup
    107  GdiplusShutdown(gdiplusToken);
    108  ReleaseDC(desktop, desktopdc);
    109  DeleteObject(mybmp);
    110  DeleteDC(mydc);
    111  return stat == Ok ? 0 : 1;
    112 }