summaryrefslogtreecommitdiffstats
path: root/testing/tools/screenshot/win32-screenshot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'testing/tools/screenshot/win32-screenshot.cpp')
-rw-r--r--testing/tools/screenshot/win32-screenshot.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/testing/tools/screenshot/win32-screenshot.cpp b/testing/tools/screenshot/win32-screenshot.cpp
new file mode 100644
index 000000000..0a357ef2f
--- /dev/null
+++ b/testing/tools/screenshot/win32-screenshot.cpp
@@ -0,0 +1,116 @@
+/*
+ * 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;
+}