屏幕截图,为什么在桌面的窗口被透明了,只截到桌面。

玉生香 2022-10-26 18:09:35

窗口在桌面上显示,但截图时,这个窗口被透明化。只显示了桌面。

BOOL ScreenCapture(const char* filename, LPRECT lpRect)
{
	BOOL ret = FALSE;
	if (filename != NULL)
	{
		//HDC hScreenDC = GetDC(GetDesktopWindow());
		HDC hScreenDC = CreateDCA("DISPLAY", NULL, NULL, NULL);	 //通过指定DISPLAY来获取一个显示设备上下文环境
		HDC hmemDC = CreateCompatibleDC(hScreenDC);			     //该函数创建一个与指定设备兼容的内存设备上下文环境(DC)
																 //截图x位置 //截图y位置 //截图宽度//截图高度
		int startX, startY, width, height;
		long BitmapSize;
		DWORD BitsOffset;
		DWORD ImageSize;
		DWORD FileSize;
		BITMAPINFOHEADER bmInfo; //BITMAPINFOHEADER结构所包含的成员表明了图像的尺寸、原始设备的颜色格式、以及数据压缩方案
		BITMAPFILEHEADER bmFileHeader;
		DWORD dwWritten;
		if (lpRect == NULL)
		{
			startX = startY = 0;
			width = GetDeviceCaps(hScreenDC, HORZRES);	 //获取指定设备的性能参数(此处获取屏幕宽度);
			height = GetDeviceCaps(hScreenDC, VERTRES);	 //获取指定设备的性能参数(此处获取屏幕高度);
		}
		else
		{
			float fact = factor();
			startX = (int)(fact*lpRect->left);
			startY = (int)(fact*lpRect->top);
			width = (int)(fact*lpRect->right) - startX;
			height = (int)(fact*lpRect->bottom) - startY;
		}
		int     iBits = GetDeviceCaps(hScreenDC, BITSPIXEL)     *     GetDeviceCaps(hScreenDC, PLANES);

		if (iBits <= 1)
			iBits = 1;
		else  if (iBits <= 4)
			iBits = 4;
		else if (iBits <= 8)
			iBits = 8;
		else if (iBits <= 24)
			iBits = 24;
		else
			iBits = 32;

		//创建一张长width,宽height的画布,用于后面绘制图形
		HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
		//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
		HBITMAP hOldBM = (HBITMAP)SelectObject(hmemDC, hBitmap);
		//该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
		BitBlt(hmemDC, 0, 0, width, height, hScreenDC, startX, startY, SRCCOPY);
		hBitmap = (HBITMAP)SelectObject(hmemDC, hOldBM);
		BitmapSize = ((((width * iBits) + iBits) / iBits) * 4)*height;
		//用来在指定的堆上分配内存,并且分配后的内存不可移动(HEAP_NO_SERIALIZE 不使用连续存取)
		PVOID lpData = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, BitmapSize);//内存分配成功返回的指向所分配内存块的首地址指针
		ZeroMemory(lpData, BitmapSize);
		ZeroMemory(&bmInfo, sizeof(BITMAPINFOHEADER));

		bmInfo.biSize = sizeof(BITMAPINFOHEADER);   //位图信息结构长度 ,必须为40
		bmInfo.biWidth = width;					    //图像宽度 单位是像素
		bmInfo.biHeight = height;					//图像高度 单位是像素
		bmInfo.biPlanes = 1;						//必须为1
		bmInfo.biBitCount = iBits;				//设置图像的位数。比如8位,16位,32位位数越高分辨率越高
		bmInfo.biCompression = BI_RGB;			    //位图是否压缩 BI_RGB为不压缩

		ZeroMemory(&bmFileHeader, sizeof(BITMAPFILEHEADER));
		BitsOffset = sizeof(BITMAPFILEHEADER) + bmInfo.biSize;
		ImageSize = ((((bmInfo.biWidth*bmInfo.biBitCount) + iBits -1) / iBits) * 4)*bmInfo.biHeight;
		FileSize = BitsOffset + ImageSize;
		bmFileHeader.bfType = 0x4d42;//'B'+('M'<<8);
		bmFileHeader.bfSize = FileSize;
		bmFileHeader.bfOffBits = BitsOffset;
		HANDLE hpal = GetStockObject(DEFAULT_PALETTE);
		HANDLE holdpal = NULL;
		if (hpal)
		{
			holdpal = SelectPalette(hmemDC, (HPALETTE)hpal, FALSE);
			RealizePalette(hmemDC);
		}
		GetDIBits(hmemDC, hBitmap, 0, bmInfo.biHeight, lpData, (BITMAPINFO *)&bmInfo, DIB_RGB_COLORS);
		if (holdpal)
		{
			SelectPalette(hmemDC, (HPALETTE)holdpal, TRUE);
			RealizePalette(hmemDC);
		}

		HANDLE bmFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (bmFile != INVALID_HANDLE_VALUE)
		{
			WriteFile(bmFile, &bmFileHeader, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
			WriteFile(bmFile, &bmInfo, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
			WriteFile(bmFile, lpData, ImageSize, &dwWritten, NULL);
			CloseHandle(bmFile);
			ret = TRUE;
		}
		HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpData);
		//::ReleaseDC(0, hScreenDC);
		DeleteDC(hScreenDC);
		DeleteDC(hmemDC);
		DeleteObject(hBitmap);


	}
	return ret;
}

 

...全文
183 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2022-10-28
  • 打赏
  • 举报
回复

仅供参考:

//GDI与DX截屏API操作
LPDIRECTDRAW        lpDD       = NULL;
LPDIRECTDRAWSURFACE lpDDSPrime = NULL;
LPDIRECTDRAWSURFACE lpDDSBack  = NULL;
LPDIRECTDRAWSURFACE lpDDSGdi   = NULL;
LPDIRECTDRAWSURFACE lpSurf     = NULL;

DDSURFACEDESC DDSdesc;
BOOL m_b24=TRUE;
//rfbServerInitMsg m_scrinfo;
RECT    m_bmrect;

struct _BMInfo {
    BITMAPINFO bmi       ;
    BOOL       truecolour;
    RGBQUAD    cmap[256] ;
} m_bminfo; // 用来保存位图信息的结构

int DX_Init() {// DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
    HRESULT hr;

    // 初始化directX
    hr = DirectDrawCreate(0, &lpDD, 0);
    if (FAILED(hr)) return FALSE;

    hr = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
    if (FAILED(hr)) return FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize  = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_CAPS;
    DDSdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hr = lpDD->CreateSurface(&DDSdesc, &lpDDSPrime, 0);
    if (FAILED(hr)) return FALSE;

    hr = lpDD->GetGDISurface(&lpDDSGdi);
    if (FAILED(hr)) return FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize  = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_ALL;
    hr = lpDDSPrime->GetSurfaceDesc(&DDSdesc);
    if (FAILED(hr)) return FALSE;

    // 初始化位图信息
    if ((DDSdesc.dwFlags & DDSD_WIDTH) && (DDSdesc.dwFlags & DDSD_HEIGHT)) {
        m_bmrect.left = m_bmrect.top = 0;
        m_bmrect.right = DDSdesc.dwWidth;
        m_bmrect.bottom = DDSdesc.dwHeight;
    } else return FALSE;

    m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;//BI_BITFIELDS;
    m_bminfo.bmi.bmiHeader.biBitCount = DDSdesc.ddpfPixelFormat.dwRGBBitCount;

    // m_bminfo.truecolour = DDSdesc.ddpfPixelFormat.dwFlags & DDPF_RGB;
    if (m_bminfo.bmi.bmiHeader.biBitCount > 8)
        m_bminfo.truecolour = TRUE;
    else
        m_bminfo.truecolour = FALSE;

    ZeroMemory(&DDSdesc, sizeof(DDSdesc));
    DDSdesc.dwSize = sizeof(DDSdesc);
    DDSdesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    DDSdesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    DDSdesc.dwHeight = m_bmrect.bottom - m_bmrect.top;
    DDSdesc.dwWidth  = m_bmrect.right  - m_bmrect.left;
    hr = lpDD->CreateSurface(&DDSdesc, &lpDDSBack, 0);
    if (FAILED(hr)) return FALSE;
//  hr = lpDDSPrime->QueryInterface( IID_IDirectDrawSurface3, (LPVOID *)&lpSurf);
//  if (FAILED(hr)) return FALSE;

    switch (m_bminfo.bmi.bmiHeader.biBitCount) {
    case 32:
    case 24:
       // Update the bitmapinfo header
       m_b24 = TRUE;
       m_bminfo.bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
       m_bminfo.bmi.bmiHeader.biWidth = 1024;
       m_bminfo.bmi.bmiHeader.biHeight = 768;
       m_bminfo.bmi.bmiHeader.biPlanes = 1;
//     m_bminfo.bmi.bmiHeader.biBitCount = 24;
       m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;
       m_bminfo.bmi.bmiHeader.biSizeImage = abs((m_bminfo.bmi.bmiHeader.biWidth * m_bminfo.bmi.bmiHeader.biHeight * m_bminfo.bmi.bmiHeader.biBitCount)/8);
       m_bminfo.bmi.bmiHeader.biXPelsPerMeter = (1024*1000)/1024;
       m_bminfo.bmi.bmiHeader.biYPelsPerMeter = (768*1000)/768;
       m_bminfo.bmi.bmiHeader.biClrUsed   = 0;
       m_bminfo.bmi.bmiHeader.biClrImportant = 0;
       break;
    }

    return m_bminfo.bmi.bmiHeader.biSizeImage;
}

BOOL CaptureScreen(RECT &rect, BYTE *scrBuff, UINT scrBuffSize) {// 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize: 缓冲区大小
    HRESULT hr=0;

    hr = lpDDSBack->BltFast(rect.left,rect.top,lpDDSPrime,&rect,DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
    if (FAILED(hr)) return FALSE;

    DDSURFACEDESC surfdesc;
    ZeroMemory(&surfdesc, sizeof(surfdesc));
    surfdesc.dwSize = sizeof(surfdesc);

    hr = lpDDSBack->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
//  hr = lpDDSPrime->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
    if (FAILED(hr)) return FALSE;

    // copy the data into our buffer
    BYTE * destbuffpos, * srcbuffpos;
//  m_scrinfo.format.bitsPerPixel = 24;
    srcbuffpos = (BYTE *) surfdesc.lpSurface;
    destbuffpos = scrBuff;

    memcpy( destbuffpos, srcbuffpos,m_bminfo.bmi.bmiHeader.biSizeImage);

    // unlock the primary surface
//  lpDDSPrime->Unlock(surfdesc.lpSurface);
    lpDDSBack->Unlock(surfdesc.lpSurface);
    return TRUE;
}

int SaveBitmapToFile(BITMAP *bitmap, LPSTR lpFileName,char *lpBuf) {
   DWORD dwWritten;
   BITMAPFILEHEADER   bmfHdr;
   BITMAPINFOHEADER   bi;
   HANDLE          fh=NULL;
   bi.biSize = sizeof(BITMAPINFOHEADER);
   bi.biWidth= bitmap->bmWidth;
   bi.biHeight = bitmap->bmHeight;
   bi.biPlanes = 1;
   bi.biBitCount      = bitmap->bmBitsPixel*8;
   bi.biCompression   = BI_RGB;
   bi.biSizeImage     = 0;
   bi.biXPelsPerMeter = 0;
   bi.biYPelsPerMeter = 0;
   bi.biClrUsed       = 0;
   bi.biClrImportant  = 0;
   fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
   if (fh == INVALID_HANDLE_VALUE) return FALSE;
   bmfHdr.bfType = 0x4D42; // "BM"
   bmfHdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel;
   bmfHdr.bfReserved1 = 0;
   bmfHdr.bfReserved2 = 0;
   bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
   WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
   WriteFile(fh, (char *)&bi,sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
   WriteFile(fh, (char *)lpBuf,bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel, &dwWritten, NULL);
   FlushFileBuffers(fh);
   CloseHandle(fh);
   return true;
}

//(1)获取屏幕绘图设备
//(2)创建一个与屏幕绘图设备相兼容的内存绘图设备
//(2)在内存中创建一个与屏幕绘图设备相兼容的图像对象
//(3)将屏幕设备中的图像复制到内存绘图设备中
//(4)将内存图像保存到文件中
//相关函数:
//GetDIBits:按位的方式返回指定的BITMAP,并按指定的格式存储到内存中
int GetBitmapFromScreen(char *lpFileName) {
    char *lpBuf;
    HBITMAP hBitmap,hOld ;
    HDC hDC,hcDC;
    BITMAP bb;
    BITMAPINFO b;
    HANDLE hp,fh=NULL;
    DWORD dwX,dwY;

    dwX=GetSystemMetrics(SM_CXSCREEN);
    dwY=GetSystemMetrics(SM_CYSCREEN);
    hDC=GetDC(NULL);
    hcDC=CreateCompatibleDC(hDC);
    hBitmap=CreateCompatibleBitmap(hDC,dwX,dwY);
    hOld=(HBITMAP)SelectObject(hcDC,hBitmap);
    BitBlt(hcDC,0, 0,dwX,dwY, hDC, 0, 0, SRCCOPY);
    bb.bmWidth=dwX;
    bb.bmHeight =dwY;
    bb.bmPlanes = 1;
    bb.bmWidthBytes=bb.bmWidth*3;
    bb.bmBitsPixel=3;
    bb.bmType=0;
    b.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    b.bmiHeader.biWidth        =dwX;
    b.bmiHeader.biHeight       =dwY;
    b.bmiHeader.biPlanes       =1;
    b.bmiHeader.biBitCount     =3*8;
    b.bmiHeader.biCompression  =BI_RGB;
    b.bmiHeader.biSizeImage    =0;
    b.bmiHeader.biXPelsPerMeter=0;
    b.bmiHeader.biYPelsPerMeter=0;
    b.bmiHeader.biClrUsed      =0;
    b.bmiHeader.biClrImportant =0;
    b.bmiColors[0].rgbBlue     =8;
    b.bmiColors[0].rgbGreen    =8;
    b.bmiColors[0].rgbRed      =8;
    b.bmiColors[0].rgbReserved =0;
    hp=GetProcessHeap();
    lpBuf=(char *)HeapAlloc(hp,HEAP_ZERO_MEMORY,bb.bmHeight*bb.bmWidth*4);
    GetDIBits(hcDC,hBitmap,0,dwY,lpBuf,&b,DIB_RGB_COLORS);
    SaveBitmapToFile(&bb,lpFileName,lpBuf);
    ReleaseDC(NULL,hDC);
    DeleteDC(hcDC);
    DeleteObject(hBitmap);
    DeleteObject(hOld);
    HeapFree(hp,0,lpBuf);
    return true;
}




玉生香 2022-10-30
  • 举报
回复
@赵4老师 已解决 ,

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧