Q&A

  • 이상우님 보세요. - ShowMessage 후킹하기
이상우 wrote:

> 안녕하세요...

>

> ShowMessage화면에서 OK버튼을 제어하는 방법을 알고 싶습니다.

>

> ShowMessage화면이 나타나면 Ok버튼을 누른효과로 ShowMessage화면을 사라지게

> 하려고 합니다.

>

> 아시는 분 답변 좀 해주세요..

>

> 그럼 좋은 하루 되시길....



안녕하세요. 최용일입니다



먼저 ShowMessage로 생성되는 윈도우 핸들을 얻어야 합니다. FindWindow와



FindWindowEx함수로 이 핸들을 얻어야 하는데 ShowMessage로 생성되는 윈도우는



TMessageForm이라는 TForm에서 파생된 클래스로 Dialog.pas의 implementation셋션에



구현되어고 Gloval Atom값을 등록을 하지 않아서 FindWindowEx로



이 핸들을 얻으려면 Gloval Atom을 등록해야 하는데 이러자면 추가되는 코드가



많으므로 좀 다른 방법으로 생각해 보았습니다. ShowMessage함수에 의해 생성되는



윈도우의 Owner는 Application이 됩니다. Application.Components를 조사해 보면



이 윈도우가 생성되어 있는지 알 수 있겠죠... 여기에서 얻은 윈도우의 핸들과



FindWindowEx를 이용해서 버튼의 핸들을 얻은 후 버튼에 마우스 클릭메세지를



보내시면 됩니다. (버튼의 클래스는 'TButton'이고 윈도우이름은 'OK'입니다.



그런데 또 한가지 문제점은 ShowMessage는 모들뷰로 생성되는 것입니다.



ShowMessage('this is message');

ShowMessageButtonClick;



위와 같은식으로 코딩을 한다면 ShowMessage 윈도우가 닫히기 전에는 결코



ShowMessageButtonClick이라는 함수는 실행이 안됩니다. 그러므로 부득이하게



타이머를 사용하지 않을 수가 없더군요. 아래는 버튼하나와 타이머하나로 구성된



완전한 유닛소스입니다. 타이머를 적당히 제어를 하면 일정한 시간이 지난후에



ShowMessage윈도우가 닫히도록 할 수도 있습니다.



^^ 항상 즐코하세요.



unit Unit1;



interface



uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls;



type

TForm1 = class(TForm)

Timer1: TTimer;

Button1: TButton;

procedure Button1Click(Sender: TObject);

procedure Timer1Timer(Sender: TObject);

private

// ShowMessage에 의해 생성된 폼을 저장하는 변수

MsgForm: TForm;

// ShowMessage에 의해 생성된 폼에 있는 버튼의 핸들값

ButtonHWnd: HWnd;

end;



var

Form1: TForm1;



implementation



{$R *.DFM}



procedure TForm1.Button1Click(Sender: TObject);

begin

Timer1.Enabled := True; // 타이머를 활성화

ShowMessage('This is message window'); // 메세지 윈도우 표시

Timer1.Enabled := False; // 타이머를 비활성화

end;



procedure TForm1.Timer1Timer(Sender: TObject);

var

I: Integer;

begin

MsgForm := nil;



// ShowMessage에 의해 생성된 폼을 찾는다.

for I := 0 to Application.ComponentCount - 1 do

if Application.Components[I] is TForm then



// 'Project1'은 ShowMessage에 의해 생성된 폼의 윈도우 캡션입니다.

// 이 값은 프로젝트에 맞게 적당히 바꾸어 주어야 합니다.

if (Application.Components[I] as TForm).Caption = 'Project1' then



// ShowMessage에 의해 생성된 폼의 클래스네임은 '' 입니다.

if (Application.Components[I] as TForm).Name = '' then

MsgForm := (Application.Components[I] as TForm);



if Assigned(MsgForm) then // 만일 ShowMessage에 의해 생성된 폼이 있다면

begin

// ShowMessage에 의해 생성된 폼에 있는 버튼의 핸들을 얻습니다.

ButtonHWnd := FindWindowEx(MsgForm.Handle, 0, 'TButton', 'OK');



if ButtonHWnd <> 0 then // 버튼의 윈도우 핸들을 얻었다면

begin

// 버튼에 마우스클릭 이벤트를 전달합니다.

SendMessage(ButtonHWnd, WM_LBUTTONDOWN, 0, 0);

SendMessage(ButtonHWnd, WM_LBUTTONUP, 0, 0);

end;

end;

end;



end.

0  COMMENTS