看了一段抓屏的代码,就是不知道他的原理。

解决方案 »

  1.   

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_5a5h.asp
      

  2.   

    抓屏?很容易吧
    这是一个网友的例子:
    HDC hScrDC, hMemDC; 
    // 屏幕和内存设备描述表 
    HBITMAP hBitmap, hOldBitmap; 
    // 位图句柄 
    int nX, nY, nX2, nY2; 
    // 选定区域坐标 
    int nWidth, nHeight; 
    // 位图宽度和高度 
    int xScrn, yScrn; 
    // 屏幕分辨率 // 确保选定区域不为空矩形 
    // (IsRectEmpty(lpRect)) 
    //return NULL; 
    //为屏幕创建设备描述表 
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); 
    //为屏幕设备描述表创建兼容的内存设备描述表 
    hMemDC = CreateCompatibleDC(hScrDC); 
    // 获得选定区域坐标 
    nX = 0; 
    nY = 0; 
    nX2 = 1024; 
    nY2 = 768; 
    // 获得屏幕分辨率 
    xScrn = GetDeviceCaps(hScrDC, HORZRES); 
    yScrn = GetDeviceCaps(hScrDC, VERTRES); 
    //确保选定区域是可见的 
    if (nX<0) 
    nX = 0; 
    if (nY<0) 
    nY = 0; 
    if (nX2>xScrn) 
    nX2 = xScrn; 
    if (nY2>yScrn) 
    nY2 = yScrn; 
    nWidth = nX2-nX; 
    nHeight = nY2-nY; 
    // 创建一个与屏幕设备描述表兼容的位图 
    hBitmap = CreateCompatibleBitmap (hScrDC, nWidth, nHeight); 
    // 把新位图选到内存设备描述表中 
    hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap); 
    // 把屏幕设备描述表拷贝到内存设备描述表中 
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, 
    hScrDC, nX, nY, SRCCOPY); 
    //得到屏幕位图的句柄 
    hBitmap = (HBITMAP) SelectObject(hMemDC, hOldBitmap); 
    //清除 HDC hDC;
    WORD wBitCount;
    int iBits;
    DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize,dwWritten; 
    BITMAP Bitmap;
    BITMAPFILEHEADER bmfHdr; 
    BITMAPINFOHEADER bi; 
    LPBITMAPINFOHEADER lpbi; 
    HANDLE fh, hDib, hPal=NULL,hOldPal=NULL; 
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL); 
    iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); DeleteDC(hDC); 
    if (iBits<= 1) 
    wBitCount = 1; 
    else if (iBits<= 4) 
    wBitCount = 4; 
    else if (iBits<= 8) 
    wBitCount = 8; 
    else if (iBits<= 24) 
    wBitCount = 24; 
    //计算调色板大小 
    if (wBitCount<= 8) 
    dwPaletteSize = (1<<wBitCount) * 
    sizeof(RGBQUAD);
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); 
    bi.biSize = sizeof(BITMAPINFOHEADER); 
    bi.biWidth = Bitmap.bmWidth; 
    bi.biHeight = Bitmap.bmHeight; 
    bi.biPlanes = 1; 
    bi.biBitCount = wBitCount; 
    bi.biCompression = BI_RGB; 
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0;
    dwBmBitsSize = ((Bitmap.bmWidth *wBitCount+31)/32)*4 *Bitmap.bmHeight;
    hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
    *lpbi = bi;
    hPal = GetStockObject(DEFAULT_PALETTE); 
    if (hPal) 

    hDC=(HDC)GetDC();
    hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE); 
    RealizePalette(hDC); 

    // 获取该调色板下新的像素值 
    GetDIBits(hMemDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) 
    +dwPaletteSize, 
    (BITMAPINFO *)lpbi, DIB_RGB_COLORS); 
    //恢复调色板 
    if (hOldPal) 

    SelectPalette(hDC,(HPALETTE)hOldPal,TRUE); 
    RealizePalette(hDC); 
    ReleaseDC(NULL); 

    //创建位图文件 fh = CreateFile("d:\\temp.bmp",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" 
    dwDIBSize = sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER) +dwPaletteSize + dwBmBitsSize;bmfHdr.bfSize = dwDIBSize;
    bmfHdr.bfReserved1 = 0; 
    bmfHdr.bfReserved2 = 0; 
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; 
    // 写入位图文件头 
    WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); 
    // 写入位图文件其余内容 
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize,&dwWritten, NULL); 
    //清除 
    GlobalUnlock(hDib); 
    GlobalFree(hDib); 
    CloseHandle(fh); DeleteDC(hScrDC); 
    DeleteDC(hMemDC);
    DeleteObject(hBitmap);
    ============================
    方法就是先创建一个与当前屏幕兼容的DC
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); 
    //为屏幕设备描述表创建兼容的内存设备描述表 
    hMemDC = CreateCompatibleDC(hScrDC);然后为内存DC选入一副位图
     
    然后将当前屏幕的内容都贴到内存DC中。其实就贴在了这个位图上。然后将这个位图取出,保存成位图文件。
      

  3.   

    我这里也有个抓屏的函数,里面注视讲的比较详细
    HBITMAP CopyScreenToBitmap(LPRECT lpRect) //lpRect 代表选定区域
    {
    HDC hScrDC, hMemDC;      
     // 屏幕和内存设备描述表
    HBITMAP hBitmap,hOldBitmap;   
     // 位图句柄
    int       nX, nY, nX2, nY2;      
    // 选定区域坐标
    int       nWidth, nHeight;      
    // 位图宽度和高度
    int       xScrn, yScrn;         
    // 屏幕分辨率
       // 确保选定区域不为空矩形
       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;
       // 获得屏幕分辨率
       xScrn = GetDeviceCaps(hScrDC, HORZRES);
       yScrn = GetDeviceCaps(hScrDC, VERTRES);
       //确保选定区域是可见的
       if (nX < 0)
          nX = 0;
       if (nY < 0)
          nY = 0;
       if (nX2 > xScrn)
          nX2 = xScrn;
       if (nY2 > yScrn)
          nY2 = yScrn;
       nWidth = nX2 - nX;
       nHeight = nY2 - nY;
       // 创建一个与屏幕设备描述表兼容的位图
       hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
       // 把新位图选到内存设备描述表中
       hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
       // 把屏幕设备描述表拷贝到内存设备描述表中
       BitBlt(hMemDC,0,0, nWidth,nHeight,hScrDC, nX, nY, SRCCOPY);
       //得到屏幕位图的句柄
       hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
       //清除 
       DeleteDC(hScrDC);
       DeleteDC(hMemDC);
       // 返回位图句柄
       return hBitmap;
    }