Transparent 나 AlphaBlend 가 먹힌 윈도우는 GetDC(0) 으로 캡쳐되지 않음.
(AlphaBlendValue 가 254 라도 안됨)
 
 
결론: Window Styles 의 Extended Styles 에 WS_EX_LAYERED 가 있다면 일반적 GetDC(0) 으로는 화면이 가져와지지 않음.
하지만 특정 윈도우의 핸들을 통해 GetDC(HWND) 로 받아오면 그려지는 걸로 봐서는
(하지만 Transparent, AlphaBlend 는 사라진 상태로)
WS_EX_LAYERED 가 먹힌 윈도우의 화면은 바탕화면의 DC에서 관장하지 않는 듯함.
 
 
 
아래는 원격제어 중 화면전송에서 저게 필요해서 부린 꼼수.
그냥 최상위 윈도우는 따로 받아와서 GetDC(0) 으로 그려놓은 비트맵에 덧그리기임.
별로 느리지 않아서 다행.
 
 
 
// 매개변수로 받은 비트맵에 최상위 윈도우의 화면을 덧그려줌.
// 매개변수로 받은 비트맵이 무조건 전체화면의 그림이라는 전제이므로 안전장치 같은 건 없음...
procedure DrawTopMostWnd(aBitmap: TBitmap);
var
  aHWND: HWND;
  aDC: HDC;
  cRect, wRect: TRect;
  X, Y: Integer;
  BorderThick: Integer;
  btm: TBitmap;

begin
  // 최상위 윈도우의 핸들을 가져옴
  aHWND:=GetForegroundWindow;
  // 그런거 없다면 그냥 관둠...
  if aHWND=0 then Exit;
  // 최상위 윈도우의 ClientRect, WindowRect 가져옴
  Windows.GetClientRect(aHWND, cRect);
  Windows.GetWindowRect(aHWND, wRect);

  btm:=TBitmap.Create;
  try
    // 비트맵 크기 맞춤   
    btm.Width:=cRect.Right;
    btm.Height:=cRect.Bottom;
    // 최상위 윈도우의 DC를 가져옴
    aDC:=GetDC(aHWND);
    // 일단 그려주고
    Bitblt(btm.Canvas.Handle,0,0,btm.Width,btm.Height,aDC,0,0,SRCCOPY);
    // 테두리 영역의 크기를 구하고 전체화면에서 클라이언트 영역의 위치계산 (좀 더 스마트한 방법은 없을까...)
    BorderThick:=(wRect.Right-wRect.Left-cRect.Right) div 2;
    X:=wRect.Left+BorderThick;
    Y:=wRect.Top+((wRect.Bottom-wRect.Top-cRect.Bottom))-BorderThick;
    // 전체화면에 최상위 윈도우의 화면을 덧그려줌
    Bitblt(aBitmap.Canvas.Handle,X,Y,btm.Width,btm.Height,btm.Canvas.Handle,0,0,SRCCOPY);
  finally
    FreeAndNil(btm);
    ReleaseDC(aHWND, aDC);
    CloseHandle(aHWND);
  end;
end;
 
 
 
// 위의 함수를 이용해 최상위 윈도우가 WS_EX_LAYERED 라도 포함시켜 화면캡쳐 해주는 예제
procedure TForm1.Button1Click(Sender: TObject);
var
  btm: TBitmap;

begin
  btm:=TBitmap.Create;
  try
    btm.Width:=Screen.Width;
    btm.Height:=Screen.Height;
    Bitblt(btm.Canvas.Handle,0,0,btm.Width,btm.Height,GetDC(0),0,0,SRCCOPY);
    DrawTopMostWnd(btm);
    Image1.Picture.Assign(btm);
    Image1.Refresh;
  finally
    FreeAndNil(btm);
  end;
end;







Posted by bloodguy
,