c++ - Gdi+ 截屏多台显示器

标签 c++ screenshot gdi+ gdi

我有一个在 Windows 平台上用 gdi plus 和 c++ 截屏的例程,它只用一个显示器就可以完美地工作,但是当我在一台有 2 个显示器的 VM 机器上运行它时,它只拍一张图片。

这就是我正在做的:

#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <GdiPlus.h>
#include <wingdi.h>
#include <fstream>
#include <unistd.h>

#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "ws2_32.lib")

using namespace std;

// Se encarga de configurar, por asi decirlo, el formato
// de la imagen, este metodo es llamado en gdiscreen al
// momento de guardar la imagen.

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
  using namespace Gdiplus;
  UINT  num = 0;          // number of image encoders
  UINT  size = 0;         // size of the image encoder array in bytes

  ImageCodecInfo* pImageCodecInfo = NULL;

  GetImageEncodersSize(&num, &size);
  if(size == 0)
    return -1;  // Failure

  pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
  if(pImageCodecInfo == NULL)
    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 0;
}

// Este es el metodo que tomo la captura.
// c es solo una variable que utilice para probar el
// metodo en un loop, la puede quitar y remplazar c
// por el log_sec_num.

inline void take_screenshot(const std::string & filename)
{
    using namespace Gdiplus;
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    {
        HDC scrdc, memdc;
        HBITMAP membit;
        scrdc = ::GetDC(0);
        int Height = GetSystemMetrics(SM_CYSCREEN);
        int Width = GetSystemMetrics(SM_CXSCREEN);
        memdc = CreateCompatibleDC(scrdc);
        membit = CreateCompatibleBitmap(scrdc, Width, Height);
        HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit);
        BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);

        Gdiplus::Bitmap bitmap(membit, NULL);
        CLSID clsid;
        const char* name = filename.c_str();
        const size_t cSize = strlen(name)+1;
        wchar_t* wc = new wchar_t[cSize];
        mbstowcs (wc, name, cSize);
        GetEncoderClsid(L"image/png", &clsid);
        bitmap.Save(wc, &clsid,NULL);

        SelectObject(memdc, hOldBitmap);

        DeleteObject(memdc);

        DeleteObject(membit);

        ::ReleaseDC(0,scrdc);
    }

    GdiplusShutdown(gdiplusToken);
}

int main ()
{
    const std::string & filename = "C:\\Screenshot.png";
    take_screenshot(filename);
}

如果尝试获取整个屏幕,但我最终只得到图片。谁能看出我的错误在哪里??

最佳答案

    int Height = GetSystemMetrics(SM_CYSCREEN);

引自 MSDN 文档:“主显示器屏幕的高度”。您完全得到了您想要的,主显示器是您的显示器之一。第一个。

改用 SM_CYVIRTUALSCREEN。 X 也一样。

关于c++ - Gdi+ 截屏多台显示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34444865/

相关文章:

c++ - 将缓冲区转换为字符串 C++ boost

python - 使用 Python PIL 和 Windows API : how to deal with rounded corners? 的事件窗口屏幕截图

android - 移动设备上的程序化屏幕捕获

.net - .NET库,用于使用GDI +绘制表格

.net - 设置字体真的有多重要?

c++ - 确定斐波那契字符串的各个字母?

C++,为什么array=ptr合法?

c++ - 基于模板的 switch 语句的 if constexpr

c++ - 使用c++和cygwin sshd服务的黑色截图

C# - 用于 Windows 窗体应用程序位图的 SetPixel 和 GetPixel 的更快替代方案