截图功能 的 实现问题

专写匿名信 2013-10-09 10:27:10
我在网上找了一个截图程序来学习
但是在 winXP 系统下 截取不到 QQ聊天 时 双击聊天栏里图片弹出来的原图查看器:
(QQ截图的效果)

(网上找的截图例子的效果)



为什么中间那块黑色的查看器无法获取到..我在网上找了很多 win32 的截图例子都是这样

附上其中一个我在网上找的截图例子 拷贝屏幕 的代码:

HBITMAP CCatchScreenDlg::CopyScreenToBitmap(LPRECT lpRect,BOOL bSave)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;

// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;

//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > m_xScreen)
nX2 = m_xScreen;
if (nY2 > m_yScreen)
nY2 = m_yScreen;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
if(bSave)
{
//创建军兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);

BitBlt(hMemDC, 0, 0, nWidth, nHeight,
dcCompatible, nX, nY, SRCCOPY);

}
else
{
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
}

hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//得到屏幕位图的句柄
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);

if(bSave)
{

if (OpenClipboard())
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
//hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
}
// 返回位图句柄

return hBitmap;
}


跪求大神 解救
...全文
261 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
专写匿名信 2013-10-28
  • 打赏
  • 举报
回复
问题解决了 但是忘了结贴
赵4老师 2013-10-28
  • 打赏
  • 举报
回复
求帖主给我发一份打包好的“截图”项目源代码。zhao4zhong1@163.com
langzi_1949 2013-10-12
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
赵老师就是牛啊
碼上道 2013-10-11
  • 打赏
  • 举报
回复
我是来学习的
lazy_virus 2013-10-11
  • 打赏
  • 举报
回复
驾船出海时一定只带一个指南针。 ——学习了!
SKATE11 2013-10-09
  • 打赏
  • 举报
回复
楼主截不到的那张图片可能是直接往显存里面贴的 而你的截屏程序是直接从内存DC上截的吧 比如视频图片你也是截不到的
专写匿名信 2013-10-09
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
谢谢赵老师的提醒
赵4老师 2013-10-09
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
专写匿名信 2013-10-09
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
//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;
}

用这段代码就能在 winXP 上获取到那个QQ的图片查看器么
赵4老师 2013-10-09
  • 打赏
  • 举报
回复
//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;
}

5t4rk 2013-10-09
  • 打赏
  • 举报
回复
引用 4 楼 TNT_101 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
谢谢赵老师的提醒[/quote] 这才是金玉良言
项目名称:[精仿]360安全卫士-10.30更新(CSkin Demo) 界面库版本号:10.30 最新版本 下载内容: 精仿360安全卫士源码一份, 可引用至工具箱最新版CSkin.dll一份 实现功能: 1.发光标题。 2.直角边框和阴影。 3.360安全卫士主界面模仿。 4.多系统支持,不需要win8系统,即可实现win8风格的360。 5.自定义控件的美化使用。 界面库更新文档: CC2013-10.30 1.由于SkinForm名字太多人使用,界面库命名正式改为CSkin.dll,官网www.cskin.net。 2.SkinTabControl标签中添加菜单箭头,可点击展开菜单。 3.SkinTabControl添加标签关闭按钮。 4.修复部分中文乱码问题。 5.优化好友列表右键菜单。 6.将窗体自定义系统按钮改为集合模式,可添加无数个自定义系统按钮。自定义系统按钮事件中可以 e.参数 来判断。 7.增加360安全卫士-DEMO案例。 8.增加SkinAnimatorImg控件,用于支持位图动画的播放。如360的动态logo。 9.各种细节BUG优化。 CC2013-10.11 1.添加SkinTabControlEx,加入更加自定义的美化属性和动画效果。 2.添加SkinAnimator,通用动画控件。 3.添加Html编辑器控件 4.修复SkinButton图标和文本相对位置的BUG CC2013-9.26 1.优化好友列表CPU占用 2.好友列表加入好友登录平台属性:安卓 苹果 WEBQQ PC 3.优化标题绘制模式,新添标题绘制模式属性。 4.新添标题偏移度属性。 5.加入圆形进度条控件:ProgressIndicator。 CC2013-9.5.2 1.优化截图控件,截图工具栏加入新功能。 2.解决个人信息卡和天气窗体显示后不会消失的问题。 3.各种细节BUG优化。 CC2013-9.5.1 1.解决贴边左右隐藏的BUG。 2.解决窗体点击事件不能触发的问题。 3.优化SkinButton继承父容器背景色的代码。 4.解决SkinButton异常错误。 CC2013-9.3 1.好友列表右键菜单没反应问题。 2.新增美化控件SkinDatagridview。 3.密码软件盘回删不了文字问题。 4.双击窗体最大化,最大化后再双击恢复原大小,(win7)。 5.部分细节调优。 小编:下载不要分,DEMO教你如何熟练使用CSkin界面库美化自己的窗体。 友情链接: http://bbs.csdn.net/topics/390510544 (精仿QQ2013局域通讯) http://download.csdn.net/detail/lyx_520/5710799 (C#实现Win8窗体)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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