HBITMAP GetScreenBmp()
{
   HWND hwnd = ::GetDesktopWindow();
   HDC hsrc = ::GetDC(hwnd);
   HDC hmemdc = ::CreateCompatibleDC(hsrc);
   RECT rc;
   ::GetWindowRect(hwnd,&rc);   SIZE sz;
   sz.cx=rc.right - rc.left;
   sz.cy=rc.bottom - rc.top;   HBITMAP hbmp = ::CreateCompatibleBitmap(hsrc, sz.cx, sz.cy);
   HGDIOBJ holdbmp = ::SelectObject(hmemdc, hbmp);
   ::BitBlt(hmemdc, 0, 0, sz.cx, sz.cy, hsrc, rc.left, rc.top, SRCCOPY);
    //得到屏幕位图的句柄
    POINT pt;
    ::GetCursorPos(&pt);
    HCURSOR hCursor = ::GetCursor();
    DrawIcon(hmemdc, pt.x-10, pt.y-10, hCursor);
    //hbmp = (HBITMAP)SelectObject(hmemdc, holdbmp);
   ::SelectObject(hmemdc,holdbmp);
   ::DeleteObject(hmemdc);
   ::ReleaseDC(hwnd,hsrc);
   return hbmp;
}BOOL WriteBmp(HBITMAP hBitmap,const char *FileName)
{
        BITMAPINFO *m_pBMI;
        BYTE *m_pDIBData;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bi;
BITMAP BM;
GetObject(hBitmap,sizeof(BM),&BM);
HDC hdc=GetDC(0);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = BM.bmWidth;
bi.biHeight  = BM.bmHeight;
bi.biPlanes  = 1;
bi.biBitCount = 24;
bi.biCompression = 0;  //压缩,0,1,2,为什么 1,2 无效
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
    
bfh.bfType=0x4d42;
bfh.bfOffBits=sizeof(bfh)+sizeof(BITMAPINFOHEADER);
bfh.bfSize=bfh.bfOffBits+BM.bmWidth*BM.bmHeight*3;
bfh.bfReserved1=0;
bfh.bfReserved2=0; m_pBMI=(BITMAPINFO*)new char[sizeof(BITMAPINFO)];
        m_pDIBData=(BYTE*)new char[bfh.bfSize-bfh.bfOffBits];

        memcpy(m_pBMI,&bi,sizeof(BITMAPINFOHEADER));
GetDIBits(hdc,hBitmap, 01, (DWORD)bi.biHeight,
(LPVOID)m_pDIBData,(LPBITMAPINFO)m_pBMI, (DWORD)DIB_RGB_COLORS);
                        // 01?
//StretchDIBits(dc.GetSafeHdc(),0,0,800,600,0,0,800,600,m_pDIBData,m_pBMI,DIB_RGB_COLORS,SRCCOPY);
HANDLE hFile;
DWORD dw; hFile=CreateFile(FileName,
GENERIC_READ|GENERIC_WRITE,
0,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
WriteFile(hFile,(LPVOID)&bfh,sizeof(bfh),&dw,NULL);
WriteFile(hFile,(LPVOID)m_pBMI,sizeof(BITMAPINFOHEADER),&dw,NULL);
WriteFile(hFile,(LPVOID)m_pDIBData,BM.bmWidth*BM.bmHeight*3,&dw,NULL);
CloseHandle(hFile);
                delete[] m_pBMI;
                delete[] m_pDIBData;
return TRUE;
}
        delete[] m_pBMI;
        delete[] m_pDIBData;
return FALSE;}HBITMAP CopyScreenToBitmap(TRect Rect)
{
HDC       hScrDC, hMemDC;
//屏幕和内存设备描述表
HBITMAP    hBitmap, hOldBitmap;
        HGDIOBJ  holdbmp;
//位图句柄
int       nWidth, nHeight;
// 位图宽度和高度
// 确保选定区域不为空矩形
if (IsRectEmpty(&Rect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC); nWidth  = Rect.right - Rect.left;
nHeight = Rect.bottom-Rect.top;
//创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
//把新位图选到内存设备描述表中
holdbmp = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
   hScrDC, Rect.top, Rect.top, SRCCOPY);
//得到屏幕位图的句柄
POINT pt;
::GetCursorPos(&pt);
//HCURSOR hCursor = ::GetCursor();
DrawIcon(hMemDC, pt.x-10, pt.y-10, ::GetCursor());
//hBitmap = (HBITMAP)
        ::SelectObject(hMemDC, holdbmp);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}这里有三个函数是C的,谁能帮我改成delphi的 WriteBmp一定要,其他两个有一个就可以了,三个都改更
好,改完后我会加多50分上去的

解决方案 »

  1.   

    你直接说你要实现什么功能,我觉的重写要比改好一些吧!!C与DELPHI的设备和句柄的描述是不一样的!
      

  2.   

    截图,捉取桌面,其实这个我会,不过没有象上面这样写的,都是普通把屏幕画到Bitmap上,但是我发现
    1027*768的图像要3M,到是这样出来的,是2.25M,怎么会有这么大的差别
      

  3.   

    你将这三个函数编译成API函数或动态连接库 *.dll 文甚致是COM.然后再在Delphi中调用就可以啦!
      

  4.   

    截屏是吧,简单
    var
      BMP: TBitmap;
      FullscreenCanvas: TCanvas;
      DC: HDC;
    begin
      BMP := TBitmap.Create;
      BMP.Width := Screen.Width;
      BMP.Height := Screen.Height;
      DC := GetDC (0);   //取得屏幕的 DC,参数0指的是屏幕
      FullscreenCanvas := TCanvas.Create;
      FullscreenCanvas.Handle := DC;
      BMP.Canvas.CopyRect
        (Rect (0, 0, Screen.Width, Screen.Height), FullscreenCanvas,
         Rect (0, 0, Screen.Width, Screen.Height));
      BMP.SaveToFile('e:\1.bmp');
      BMP.Free;
      FullscreenCanvas.Free;
      ReleaseDC (0, DC);
    end;
    1024X768只有1573KB
      

  5.   

    其实无论用什么方法,无论用哪种语言,同样尺寸同样位数的BMP图像大小是一样的
    1024X768大小的BMP图像之所以有3M,2.25M,1537KB,是因为他们的位数不一样,如:
    var
      BMP: TBitmap;
    begin
      BMP := TBitmap.Create;
      BMP.Width := 1024;
      BMP.Height := 768;
      BMP.PixelFormat := pf32bit;  //产生3M文件
      //BMP.PixelFormat := pf24bit;  //产生2.25M文件
      //BMP.PixelFormat := pf15bit;  //产生1537K文件
      BMP.SaveToFile('e:\1.bmp');
      BMP.Free;
    end;