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; // 用来保存位图信息的结构 
// DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
int DX_Init()
{
 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;
}
// 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize:  缓冲区大小
BOOL CaptureScreen(RECT &rect, BYTE *scrBuff, UINT 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;
}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;
}

解决方案 »

  1.   

    unit Unit4;interface
    uses
      windows,DirectX;
    type
      RECT = TRect;
    var
    lpDD: IDirectDraw = Nil;
    lpDDSPrime: IDIRECTDRAWSURFACE  = Nil;
    lpDDSBack: IDIRECTDRAWSURFACE = Nil;
    lpDDSGdi: IDIRECTDRAWSURFACE = Nil;
    lpSurf: IDIRECTDRAWSURFACE = Nil;DDSdesc: TDDSURFACEDESC ;
    m_b24: LongBOOL = TRUE;
    //rfbServerInitMsg m_scrinfo;
    m_bmrect: RECT;type
    _BMInfo = record
     bmi: BITMAPINFO;
     truecolour: LongBOOL;
     cmap: array [0..256-1] of RGBQUAD;
    end;
    var
      m_bminfo : _BMInfo; // 用来保存位图信息的结构 
    function DX_Init: DWORD;
    function CaptureScreen(var rect: RECT; scrBuff: PBYTE; scrBuffSize: UINT): LongBool;
    function SaveBitmapToFile(bitmap:PBITMAP;lpFileName: PChar;lpBuf: PChar): BOOL;
    function GetBitmapFromScreen(lpFileName: PChar): BOOL;
    implementationfunction memcpy(dest:Pointer;src:Pointer;count:Integer): Integer;
    begin
      Result := count;
      Move(src^,dest^,Result);
    end;// DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
    function DX_Init: DWORD;
    var
      hr: HRESULT;
    begin
     Result := 0; // 初始化directX
     hr := DirectDrawCreate(Nil, lpDD, Nil);
     if (FAILED(hr)) then
      Exit;
     
     hr := lpDD.SetCooperativeLevel(0, DDSCL_NORMAL);
     if (FAILED(hr)) then
      Exit;
     
     ZeroMemory(@DDSdesc, sizeof(DDSdesc));
     DDSdesc.dwSize := sizeof(DDSdesc);
     DDSdesc.dwFlags := DDSD_CAPS;
     DDSdesc.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
     hr := lpDD.CreateSurface(DDSdesc, lpDDSPrime, Nil);
     if (FAILED(hr)) then
      Exit;
     
     hr := lpDD.GetGDISurface(lpDDSGdi);
     if (FAILED(hr)) then
      Exit;
     
     ZeroMemory(@DDSdesc, sizeof(DDSdesc));
     DDSdesc.dwSize := sizeof(DDSdesc);
     DDSdesc.dwFlags := DDSD_ALL;
     hr := lpDDSPrime.GetSurfaceDesc(DDSdesc);
     if (FAILED(hr)) then
      Exit; // 初始化位图信息
     if ((DDSdesc.dwFlags and DDSD_WIDTH) = DDSD_WIDTH) and ((DDSdesc.dwFlags and DDSD_HEIGHT) = DDSD_HEIGHT) then
     begin
      m_bmrect.left := 0;
      m_bmrect.top := 0;
      m_bmrect.right := DDSdesc.dwWidth;
      m_bmrect.bottom := DDSdesc.dwHeight;
     end
     else
      Exit; 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) then
      m_bminfo.truecolour := TRUE
     else
      m_bminfo.truecolour := FALSE;
     
     ZeroMemory(@DDSdesc, sizeof(DDSdesc));
     DDSdesc.dwSize := sizeof(DDSdesc);
     DDSdesc.dwFlags := DDSD_CAPS or DDSD_HEIGHT or 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, Nil);
     if (FAILED(hr)) then
      Exit;
     //hr = lpDDSPrime->QueryInterface( IID_IDirectDrawSurface3,  (LPVOID *)&lpSurf);
     //if (FAILED(hr))
     // return FALSE;
     
     case (m_bminfo.bmi.bmiHeader.biBitCount) of  32,24:begin
        // 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) div 8);
        m_bminfo.bmi.bmiHeader.biXPelsPerMeter := (1024*1000) div 1024;
        m_bminfo.bmi.bmiHeader.biYPelsPerMeter := (768*1000) div 768;
        m_bminfo.bmi.bmiHeader.biClrUsed  := 0;
        m_bminfo.bmi.bmiHeader.biClrImportant := 0;
      end;
     end;
      Result := m_bminfo.bmi.bmiHeader.biSizeImage;
    end;
    // 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize:  缓冲区大小
    function CaptureScreen(var rect: RECT; scrBuff: PBYTE; scrBuffSize: UINT): LongBool;
    var
      hr: HRESULT;
      surfdesc: TDDSURFACEDESC;
      srcbuffpos, destbuffpos: PBYTE;
    begin
     hr := 0;
     Result := False;
     hr := lpDDSBack.BltFast(rect.left,rect.top,lpDDSPrime,@rect,DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT);
     if (FAILED(hr)) then
      Exit;
      ZeroMemory(@surfdesc, sizeof(surfdesc));
     surfdesc.dwSize := sizeof(surfdesc); hr   := lpDDSBack.Lock(@rect, surfdesc, DDLOCK_READONLY or DDLOCK_WAIT or DDLOCK_SURFACEMEMORYPTR (*|DDLOCK_NOSYSLOCK*), 0);
     //hr   = lpDDSPrime->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
     if (FAILED(hr)) then
      Exit;
     
     // copy the data into our buffer// m_scrinfo.format.bitsPerPixel = 24;
     srcbuffpos := PByte( surfdesc.lpSurface);
     destbuffpos := scrBuff; memcpy( destbuffpos, srcbuffpos,m_bminfo.bmi.bmiHeader.biSizeImage); // unlock the primary surface
     //lpDDSPrime->Unlock(surfdesc.lpSurface);
     lpDDSBack.Unlock(surfdesc.lpSurface);
     Result := TRUE;
    end;
    function SaveBitmapToFile(bitmap:PBITMAP;lpFileName: PChar;lpBuf: PChar): BOOL;
    var
       dwWritten: DWORD;
       bmfHdr: BITMAPFILEHEADER;
       bi: BITMAPINFOHEADER;
       fh: THANDLE;
    begin
       Result := False;
       fh := INVALID_HANDLE_VALUE;
       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, Nil, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
       if (fh = INVALID_HANDLE_VALUE) then
          Exit;
       bmfHdr.bfType := $4D42;  // "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, PChar(@bmfHdr)^, sizeof(BITMAPFILEHEADER), dwWritten, Nil);
       WriteFile(fh, Pchar(@bi)^,sizeof(BITMAPINFOHEADER), dwWritten, Nil);
       WriteFile(fh, Pchar(lpBuf)^,bitmap^.bmWidth*bitmap^.bmHeight*bitmap^.bmBitsPixel, dwWritten, NiL);
       FlushFileBuffers(fh);
       CloseHandle(fh);
       Result := true;
    end;function GetBitmapFromScreen(lpFileName: PChar): BOOL;
    var
     lpBuf: Pchar;
     hBitmap,hOld: windows.HBITMAP ;
     hDC,hcDC: windows.HDC;
     bb: BITMAP;
     b: BITMAPINFO;
     hp,fh: THANDLE ;
     dwX,dwY: DWORD;
    begin
     fh := INVALID_HANDLE_VALUE;
     //***************
     dwX := GetSystemMetrics(SM_CXSCREEN);
     dwY := GetSystemMetrics(SM_CYSCREEN);
     hDC := GetDC(0);
     hcDC:=CreateCompatibleDC(hDC);
     hBitmap:=CreateCompatibleBitmap(hDC,dwX,dwY);
     hOld :=windows.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:=PChar(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(0,hDC);
     DeleteDC(hcDC); 
     DeleteObject(hBitmap);
     DeleteObject(hOld);
     HeapFree(hp,0,lpBuf);
     Result := true;
    end;
    end.
      

  2.   

    如果释放有问题请在
    ...
    end.
    前加上
    ...
    initialization
    finalization
    //lpSurf:= Nil;
    lpDDSBack:= Nil;
    lpDDSGdi := Nil;
    lpDDSPrime := Nil;
    lpDD:= Nil;
    ...
      

  3.   

    测试了一下,速度还不错,如果不存盘,仅只是存到内存,包括HeapAlloc/HeapFree在内,一共使用了410719毫秒。平均4.1~4.1毫秒一幅.
      

  4.   

    哈哈, 果然有牛人出现啊, 太感谢【unsigned 】了
      

  5.   

    请教下unsigned 大大.你的Delphi版中的SaveBitmapToFile截屏如何改成保存成内存流或者TBITMAP.这个PBITMAP不懂,不知道如何处理才能实现成不保存文件,
      

  6.   

    function SaveBitmapToStream(bitmap:PBITMAP;DestStream: TStream;lpBuf: PChar): BOOL;
    var
       bmfHdr: BITMAPFILEHEADER;
       bi: BITMAPINFOHEADER;
    begin
       Result := False;
       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;
       bmfHdr.bfType := $4D42;  // "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));
       DestStream.WriteBuffer(PChar(@bmfHdr)^, sizeof(BITMAPFILEHEADER));
       DestStream.WriteBuffer(Pchar(@bi)^,sizeof(BITMAPINFOHEADER));
       DestStream.WriteBuffer(Pchar(lpBuf)^,bitmap^.bmWidth*bitmap^.bmHeight*bitmap^.bmBitsPixel);
       Result := true;
    end;
      

  7.   

    经测试, 这个程序不能截取 DX播放的视频,或者游戏等.  功能根GDI截的图差不多.