Тема: HDC в файл
Показать сообщение отдельно
  #10  
Старый 06.12.2012, 09:53
reqyz reqyz вне форума
Начинающий
 
Регистрация: 13.02.2010
Сообщения: 104
Репутация: 10
По умолчанию

Ну, спасибо что хоть зашли сюда, но справляться самому пришлось, привожу рабочий код на делфи, вдруг кто нибудь захочет сохранять HDC в BMP файл:
Код:
function DibNumColors(pv:pointer):WORD;
var
  bits:Integer;
  lpbi:PBITMAPINFOHEADER;
  lpbc:PBITMAPCOREHEADER;
begin
  lpbi := PBITMAPINFOHEADER(pv);
  lpbc := PBITMAPCOREHEADER(pv);

  if (lpbi^.biSize <> sizeof(BITMAPCOREHEADER))then
  begin
    if (lpbi^.biClrUsed <> 0)then
    begin
      Result:=lpbi^.biClrUsed;
      exit;
    end;
    bits := lpbi^.biBitCount;
  end
  else
    bits := lpbc^.bcBitCount;

  case (bits) of
    1: Result := 2;
    4: Result := 16;
    8: Result := 256;
    else
      Result:=0
  end;
end;


function PaletteSize(lpbi:PBITMAPINFOHEADER):WORD;
var
  NumColors:WORD;
begin
    NumColors := DibNumColors(lpbi);
    if (lpbi^.biSize = sizeof(BITMAPCOREHEADER))then
        Result := (NumColors * sizeof(RGBTRIPLE))
    else
        Result := (NumColors * sizeof(RGBQUAD));
end;


procedure WriteMapFileHeaderandConvertFromDwordAlignToPacked(fh:HFILE;pbf:PBITMAPFILEHEADER);
begin
  _lwrite(fh, @pbf^.bfType, sizeof (WORD));
  _lwrite(fh, @pbf^.bfSize, sizeof(DWORD) * 3);
end;

function lwrite(fh:Integer;pv:Pointer;ul:DWORD):DWORD;
const
  MAXREAD = 32768;
var
  ulT:DWORD;
  hp:PByte;
begin
  ulT := ul;
  hp := pv;
  Result:=0;

  while (ul > MAXREAD) do
  begin
    if (_lwrite(fh, LPSTR(hp), MAXREAD) <> MAXREAD)then
      exit;
    dec(ul,MAXREAD);
    inc(hp,MAXREAD);
  end;
  if (_lwrite(fh, LPSTR(hp), ul) <> ul)then
    exit;

  result := ulT;
end;



function WriteDIB(szFile:LPSTR;hdib:THANDLE):BOOL;
const
  BFT_BITMAP = $4d42;
  SIZEOF_BITMAPFILEHEADER_PACKED  = (
    sizeof(WORD) +
    sizeof(DWORD) +
    sizeof(WORD) +
    sizeof(WORD) +
    sizeof(DWORD));
var
  hdr:BITMAPFILEHEADER;
  lpbi:PBITMAPINFOHEADER;
  fh:HFILE;
  off:OFSTRUCT;
begin
  result:=false;
  if (hdib = 0)then
    exit;

  fh := OpenFile(szFile, off, OF_CREATE or OF_READWRITE);
  if (fh = -1)then
    exit;

  lpbi := GlobalLock(hdib);

  hdr.bfType          := BFT_BITMAP;
  hdr.bfSize          := DWORD(GlobalSize (hdib) + SIZEOF_BITMAPFILEHEADER_PACKED);
  hdr.bfReserved1     := 0;
  hdr.bfReserved2     := 0;
  hdr.bfOffBits       := DWORD(SIZEOF_BITMAPFILEHEADER_PACKED + lpbi^.biSize +
                          PaletteSize(lpbi));

{$IFDEF FIXDWORDALIGNMENT}
  _lwrite(fh, @hdr, SIZEOF_BITMAPFILEHEADER_PACKED);
{$ELSE}
  WriteMapFileHeaderandConvertFromDwordAlignToPacked(fh, @hdr);
{$ENDIF}

    lwrite (fh, LPSTR(lpbi), GlobalSize (hdib));

    GlobalUnlock (hdib);
    _lclose(fh);
    Result := TRUE;
end;

function WIDTHBYTES(i:integer):integer;
begin
  result:=round((i+31)/32*4);
end;

function DibFromBitmap(hbm:HBITMAP;biStyle:DWORD;biBits:WORD;hpal:HPALETTE):THANDLE;
var
  bm:BITMAP;
  bi:BITMAPINFOHEADER;
  lpbi:PBITMAPINFOHEADER;
  dwLen:DWORD;
  hdib,h:THANDLE;
  dc:HDC;
  p:pointer;
begin
  Result:=0;
  if (hbm=0)then
    Exit;

  if (hpal = 0)then
    hpal := GetStockObject(DEFAULT_PALETTE);//(HPALETTE__ *)

  GetObject(hbm,sizeof(bm),LPSTR(@bm));

  if (biBits = 0)then
    biBits :=  bm.bmPlanes * bm.bmBitsPixel;

  bi.biSize               := sizeof(BITMAPINFOHEADER);
  bi.biWidth              := bm.bmWidth;
  bi.biHeight             := bm.bmHeight;
  bi.biPlanes             := 1;
  bi.biBitCount           := biBits;
  bi.biCompression        := biStyle;
  bi.biSizeImage          := 0;
  bi.biXPelsPerMeter      := 0;
  bi.biYPelsPerMeter      := 0;
  bi.biClrUsed            := 0;
  bi.biClrImportant       := 0;
  dwLen  := bi.biSize + PaletteSize(@bi);

  dc := GetDC(0);
  hpal := SelectPalette(dc,hpal,FALSE);
  RealizePalette(dc);

  hdib := GlobalAlloc(GHND,dwLen);

  if (hdib<0)then
  begin
    SelectPalette(dc,hpal,FALSE);
    ReleaseDC(0,dc);
    exit;
  end;

  lpbi := GlobalLock(hdib);

  lpbi^ := bi;

  GetDIBits(dc, hbm, 0, bi.biHeight,nil, PBitMAPINFO(lpbi)^, DIB_RGB_COLORS);

  bi := lpbi^;
  GlobalUnlock(hdib);

  if (bi.biSizeImage = 0)then
  begin
    bi.biSizeImage := WIDTHBYTES(bm.bmWidth * biBits) * bm.bmHeight;

    if (biStyle <> BI_RGB)then
      bi.biSizeImage := round((bi.biSizeImage * 3) / 2);
  end;

  dwLen := bi.biSize + PaletteSize(@bi) + bi.biSizeImage;
  h := GlobalReAlloc(hdib,dwLen,0);
  if (h <> 0)then
    hdib := h
  else
  begin
    GlobalFree(hdib);
    hdib := 0;

    SelectPalette(dc,hpal,FALSE);
    ReleaseDC(0,dc);
    result:=hdib;
    exit;
  end;

  lpbi := GlobalLock(hdib);

  if (GetDIBits(dc,hbm,0,bi.biHeight,Pointer(longword(lpbi) + lpbi.biSize + PaletteSize(lpbi)),
    PBitMAPINFO(lpbi)^, DIB_RGB_COLORS) = 0)then
  begin
    GlobalUnlock(hdib);
    hdib := 0;
    SelectPalette(dc,hpal,FALSE);
    ReleaseDC(0,dc);
    Result := 0;
    exit;
  end;

  bi := lpbi^;
  GlobalUnlock(hdib);

  SelectPalette(dc,hpal,FALSE);
  ReleaseDC(0,dc);
  result:=hdib;
end;


function ScreenGrab(szFileName:PChar):boolean;
var
  xshift,yshift,xScreen,yScreen:integer;
  sz:SIZE;
  dstDC,srcDC,memDC:HDC;
  bm:HBITMAP;
  h:THANDLE;
begin
//////////////////////?????? ?????/////////////////////////////
  xshift := 0;
  yshift := 0;
  xScreen := GetSystemMetrics(SM_CXSCREEN);
  yScreen := GetSystemMetrics(SM_CYSCREEN);
	sz.cx := xScreen;
  sz.cy := yScreen;
  dstDC := GetDC(0);
  srcDC := GetWindowDC(0);
  memDC := CreateCompatibleDC(srcDC);
  bm := CreateCompatibleBitmap(dstDC,xScreen, yScreen);
  SelectObject(memDC,bm);
  BitBlt(memDC, 0, 0, sz.cx, sz.cy, srcDC,xshift, yshift, SRCCOPY);
///////////////////////////////////////////////////////////////
  h := DibFromBitmap(bm,0,16,0);
    if(not WriteDIB(szFileName,h))then
        result := FALSE
  else
  	result := TRUE;
end;
Ответить с цитированием