gpt4 book ai didi

c++ - Windows 7 和 ScreenShot.cpp GDI+ PNG 问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:35:00 26 4
gpt4 key购买 nike

长时间使用 XP 没有问题。切换到 7 并尝试使用我以前运行的代码捕获屏幕截图不再有效。简单的概念和相对通用的代码...只需找到我调用的窗口并将其另存为 .png。有什么想法可以让这个坏男孩再次逃跑吗?无法使用我当前的设置进行调试,但它一直运行并在 bmp->save(...) 之后吐出错误消息...无法保存图像文件。编辑:也确实创建/保存了一个文件,但它是空白的并且没有写入。也许位图编码或 GDI 搞砸了?

bool CScreenShot::Snap(CString wintitle, CString file, CString& ermsg)
{
ermsg = ""; // no error message

// create screen shot bitmap
EnumWinProcStruct prm = {0, (LPSTR)(LPCTSTR)wintitle, 0};

// Find the descriptor of the window with the caption wintitle
EnumDesktopWindows(0, EnumWindowsProc, (LPARAM)&prm);
if(!prm.hwnd)
{
ermsg.Format("couldn't find window \"%s\"", wintitle);
return false;
}

// Make the window the topmost window
SetWindowPos(prm.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
Sleep(300);

// Get device context for the top-level window and client rect
HDC hDC = GetDC(prm.hwnd);
RECT rc;
GetClientRect(prm.hwnd, &rc);

HDC memDC = CreateCompatibleDC(hDC);

// Set the size and color depth for the screen shot image
BITMAPINFO bmpInfo;
memset(&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
bmpInfo.bmiHeader.biWidth = rc.right - rc.left;
bmpInfo.bmiHeader.biHeight = rc.bottom - rc.top;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biHeight * 3;

// Create memory buffer and perform a bit-block transfer of the color data from the window to the memory
LPVOID addr;
HBITMAP memBM = CreateDIBSection(memDC, &bmpInfo, DIB_RGB_COLORS, &addr, 0, 0);

HGDIOBJ stdBM = SelectObject(memDC, memBM);
BOOL OK = BitBlt(memDC, 0, 0, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, hDC, 0, 0, SRCCOPY);
ReleaseDC(prm.hwnd, hDC);

SetWindowPos(prm.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
if(GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != Ok)
{
ermsg.Format("couldn't start GDI+");
return false;
}

// Create a Bitmap object for work with images defined by pixel data from the GDI HBitmap and the GDI HPalette.
Bitmap* bmp = ::new Bitmap(memBM, DIB_RGB_COLORS);
SelectObject(memDC, stdBM);
DeleteObject(memBM);
DeleteDC(memDC);

// Find the encoder for "image/png" mime type
CLSID encoderClsid;
EncoderParameters encoderParameters;

GetEncoderClsid(L"image/png", &encoderClsid);

encoderParameters.Count = 0;

// Convert file name to Unicode (wide-char) string.
WCHAR fn[_MAX_PATH];
MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, file, file.GetLength() + 1, fn, _MAX_PATH);
// Save the screen shot into the specified file using image encoder with the mime style "image/png"
if(bmp->Save(fn, &encoderClsid, &encoderParameters) != Ok)
{
ermsg.Format("couldn't save image file \"%s\"", file);
return false;
}

::delete bmp;
GdiplusShutdown(gdiplusToken);

return true;
}

最佳答案

该错误消息表示您正在尝试将文件保存到您无权写入的文件夹中。 Program Files 等许多文件夹现在都受到保护。由于您没有在示例代码中包含路径,因此我无法确定这是否是实际问题。

编辑:另一种可能是位图构造不当,导致保存失败。构造函数的第二个参数应该是调色板的句柄,我认为 DIB_RGB_COLORS 在这里无效,您应该使用 NULL。 Microsoft documentation 中还有一些注意事项当您违反规则时,不同的操作系统版本可能会有不同的 react :

You are responsible for deleting the GDI bitmap and the GDI palette. However, you should not delete the GDI bitmap or the GDI palette until after the GDI+ Bitmap::Bitmap object is deleted or goes out of scope.

Do not pass to the GDI+ Bitmap::Bitmap constructor a GDI bitmap or a GDI palette that is currently (or was previously) selected into a device context.

关于c++ - Windows 7 和 ScreenShot.cpp GDI+ PNG 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6117163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com