- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一些代码,在给定窗口句柄的情况下,使用 C++ 截取另一个应用程序的屏幕截图。我使用的方法是使用BitBlt
。我的应用程序成功截取了屏幕截图,并且我有一个函数可以将该图像数据保存到 bmp 文件中。
虽然屏幕截图包含窗口的镶边。即边框和标题栏。根据我的理解,GetClientRect
应该排除窗口的边框和标题栏。我知道 GetWindowRect
返回用户桌面内的坐标,而 GetClientRect
返回相对于应用程序本身的坐标。
我注意到在我的屏幕截图中,标题栏和左边框是可见的,但应用程序的右边框和底部被截断了。所以,我在想,如果我想排除标题和边框,那么我需要对 GetWindowRect
和 GetClientRect
进行某种组合,并使用有关例如,无论窗口标题栏的高度是多少,窗口本身都会偏移 GetClientRect
尺寸。
这听起来准确吗,还是我下面的代码做错了什么?
#include <Windows.h>
#include "ScreenshotManager.h"
namespace Managers {
ScreenshotManager::ScreenshotManager(HWND gameHandle) {
// get a device context for the window
m_gameContext = GetWindowDC(gameHandle);
// create a compatible device context for bitblt
m_bitmapContext = CreateCompatibleDC(m_gameContext);
// get window client area dimensions
GetClientRect(gameHandle, &m_gameClientArea);
}
bool ScreenshotManager::TakeScreenshot() {
// create a compatible bitmap for the game screenshots
m_bitmap = CreateCompatibleBitmap(m_gameContext, m_gameClientArea.right, m_gameClientArea.bottom);
// select the bitmap into the compatible device context
SelectObject(m_bitmapContext, m_bitmap);
// perform bit block transfer
if (BitBlt(m_bitmapContext, 0, 0, m_gameClientArea.right, m_gameClientArea.bottom, m_gameContext, 0, 0, SRCCOPY) == false)
return false;
// get information about the taken screenshot
GetObject(m_bitmap, sizeof(BITMAP), &m_bitmapInformation);
return true;
}
void ScreenshotManager::SaveScreenshot(LPCWSTR outputPath) {
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = m_bitmapInformation.bmWidth;
bi.biHeight = m_bitmapInformation.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((m_bitmapInformation.bmWidth * bi.biBitCount + 31) / 32) * 4 * m_bitmapInformation.bmHeight;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
// Gets the "bits" from the bitmap and copies them into a buffer which is pointed to by lpbitmap.
GetDIBits(m_gameContext, m_bitmap, 0, (UINT)m_bitmapInformation.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
// A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//Offset to where the actual bitmap bits start.
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfHeader.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfHeader.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
CloseHandle(hFile);
}
}
最佳答案
GetClientRect()
不包括边框和标题栏。它所做的只是告诉您客户区的尺寸。
BitBlt()
将一个矩形像素区域从一个设备上下文复制到另一个。在此示例中,源 DC 是一个窗口 DC,因此原点坐标是相对于该窗口的。
您的代码所做的是从窗口 的原点复制一个客户端 大小的矩形。 (这就是右边缘和底部边缘缺失的原因。)
您可能对 AdjustWindowRectEx()
感兴趣以帮助识别您要复制的区域的坐标。
关于c++ - 为什么 GetClientRect 包括窗口边框和标题栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11066923/
我在 C# 中通过 pinvoke 调用 GetClientRect 来获取我用作 DirectX 渲染目标区域的面板的尺寸(在 WindowsForm 上)。我原以为 WinAPI 会给我未缩放的尺
我正在编写一个在 Windows 上运行的屏幕保护程序。 在预览模式下,Windows 这样调用程序: Screensaver.exe/p ParentWindowHandle 但是,当我在我的程序中
我正在编写一些代码,在给定窗口句柄的情况下,使用 C++ 截取另一个应用程序的屏幕截图。我使用的方法是使用BitBlt。我的应用程序成功截取了屏幕截图,并且我有一个函数可以将该图像数据保存到 bmp
我有下面的代码片段。如果您按“运行代码片段”,那么您将看到以下内容 1 - p.getClientRects().length 2 - span.getClientRects().length 但是如
每次我调用 Element.getClientRects() 时,它都会返回一个仅包含一个 DOMRect 对象的集合。 Element.getClientRects() 何时返回多个 DOMRect
我目前在 IE 11 中遇到文本选择问题(尽管在以前的 IE 中也会发生这种情况)。我的目标是让文本选择工作,它返回给我 getClientRects。我所拥有的是一个简单的设置。我有一个容器 div
在调整窗口大小时,我需要获得窗口客户区的正确大小(宽度/高度)。我尝试使用 GetClientRect,但它总是提供错误的值(请参阅下面的详细信息)。 User32.RECT clientRECT;
我正在尝试通过以下链接在 KendoUI 网格中创建自定义工具栏:http://demos.telerik.com/kendo-ui/grid/toolbar-template但遇到错误。 这就是我想
尝试在 UIWebView 中查找最顶层的可见元素。我使用 JS 方法来执行此操作,该方法在 Safari 中效果很好,但从 UIWebView 执行时永远不会执行超过 getClientRects
我在我的 MFC 应用程序中设置了一个分层窗口。我已经设置了我自己的 CDialog 派生,以允许我自定义窗口呈现方式的各个部分。一切正常,直到我开始担心最小化和最大化。 如果您单击最小化或最大化,则
我无法找到使用这些函数的明确引用:getBBox() 对比 getBoundingClientRect() 对比 getClientRects()。 您能否解释一下它们的作用以及它们返回的坐标(及其引
我正在尝试获取不同元素的边界矩形。我使用 getClientRects 获取元素的矩形,然后在该矩形上绘制一个红色 div。在 Firefox 上它可以工作,但在 chrome 和 safari 中我
初学者问题。 在Win32API中,::GetClientRect的第二个参数是LPRECT,但它同时接收CRect和CRect*. 我试图查看 LPRECT 是如何定义的,但它似乎只是指向结构的普通
初学者问题。 在Win32API中,::GetClientRect的第二个参数是LPRECT,但它同时接收CRect和CRect*. 我试图查看 LPRECT 是如何定义的,但它似乎只是指向结构的普通
在 webkit 浏览器中(这在 IE9 或 Mozilla 中似乎不是问题)当查询 clientRects (getClientRects) 的范围时,返回的 clientrects 包含与所选文本
我试图让 jQuery UI 工作,但它没有。这是发生了什么。 我正在加载依赖项: 那是我的 main.js 文件: $(function () { $("input[typ
我可以让它工作: [] extern bool GetClientRect(nativeint, RECT*) let getClientRect hwnd = let mutable r =
我可以让它工作: [] extern bool GetClientRect(nativeint, RECT*) let getClientRect hwnd = let mutable r =
我正在为 Visual Studio 2003 使用 MFC。我有一个 ID 为 IDC_COMMENT_EDIT 的编辑控件。在下面的代码中,在我第一次调用 GetClientRect 之后,我不希
Uncaught TypeError: elem.getClientRects is not a function at F.fn.init.offset (jquery-3.2.1.js:9
我是一名优秀的程序员,十分优秀!