알송을 보면 폼 위에서 클릭을 해도 마우스 이벤트가 통과하여 그 뒤에 있는 창이 클릭된다.

이 기능을 하는 함수이다.

윈도우 핸들을 받아서 마우스 이벤트를 통과시킨다.

 

SetTransparent(핸들, True or False); 처럼 사용하면 됨. True 는 통과시키기, False 는 통과시키지 않기.

 

 

procedure SetTransparent(aHWND: HWND; Transparent: Boolean);
var
  orgStyle: Integer;
  Style: Integer;
begin
  orgStyle:=GetWindowLong(aHWND, GWL_EXSTYLE);

 

  // 이벤트 통과 시키기

  if Transparent then Style:=orgStyle or WS_EX_LAYERED or WS_EX_TRANSPARENT

  // 이벤트 통과 안되게 복구하기
  else                     Style:=orgStyle and (not WS_EX_TRANSPARENT) and (not WS_EX_LAYERED);

 

  SetWindowLong(aHWND, GWL_EXSTYLE, Style);
end;

 

 

 

 

키포인트는 WS_EX_TRANSPARENT 였다.

하지만 여기서 약간의 문제가 있으니 WS_EX_LAYERED 가 문제다.

원래부터 WS_EX_LAYERED 가 없었던 윈도우라면 저 함수로 아무 문제가 없으나,

델파이 TForm 의 property 에서 AlphaBlend 를 True 로 하고 반투명 창으로 쓴다면,

이벤트 통과 시키기를 하고 난 후 통과시키지 않게 복구하는데 and (not WS_EX_LAYERED) 가 적용되어 반투명 효과가 사라져버린다.

static 같은게 있었으면 어떻게 쓰겠는데 그냥 클래스로 하나 만들어 버렸다.

 

생성자에서 원래부터 WS_EX_LAYERED 가 있었는지 여부를 Boolean 변수로 받아서,

복구시킬 때 WS_EX_LAYERED 를 뺄지 말지 결정한다.

 

 

{ interface }

type
  TTransparent=class
    private
      FAlphaBlend: Boolean;
    public
      constructor Create(AlphaBlend: Boolean); reintroduce;
      procedure SetTransparent(aHWND: HWND; Transparent: Boolean);
  end;

 

 

{ implementation }

constructor TTransparent.Create(AlphaBlend: Boolean);
begin
  FAlphaBlend:=AlphaBlend;
end;

 

procedure TTransparent.SetTransparent(aHWND: HWND; Transparent: Boolean);
var
  orgStyle: Integer;
  Style: Integer;
begin
  orgStyle:=GetWindowLong(aHWND, GWL_EXSTYLE);

 

  if Transparent then
    Style:=orgStyle or WS_EX_LAYERED or WS_EX_TRANSPARENT
  else begin
    Style:=orgStyle and (not WS_EX_TRANSPARENT);

    if not FAlphaBlend then Style:=Style and (orgStyle and (not WS_EX_LAYERED));
  end;

 

  SetWindowLong(aHWND, GWL_EXSTYLE, Style);
end;

 

 

 

 

 

 

 

... ...

var

  TP: TTransparent;

 

원래부터 반투명창이었다면,

TP:=TTransparent.Create(True); 로 생성해서 아래처럼 사용하면 되고,

TP.SetTransparent(Form2.Handle, True); // 통과시키기

TP.SetTransparent(Form2.Handle, False); // 통과시키지 않기

 

 

반투명이 아니었다면,

생성할 때만 TP:=TTransparent.Create(False); 로 생성해서 똑같이 사용하면 된다.

 

 

 

가르침을 주신 '김호영'님께 감사의 마음을.










Posted by bloodguy
,