Q&A

  • 핸들값을 가져오는데 Access violation에러 메세지가 나오네요.
안녕하세요.
지금 버튼 하나를 찾지 못해서 일주일을 헤매고 있습니다.
최용일님께서 끝까지 자세히 가르쳐주셨는데.. 에러가 나는 이유를 도데체 모르겠네요. 왠만하면 혼자 해결해 볼려구 했는데.. 워낙 지식이 짧아서 .. ㅠ.ㅠ

지난 금요일날 최용일님의 답변 소스입니다.

implementation

{$R *.dfm}

function EnumWindowsProc(WindowHandle: THandle; var Param: THandle): BOOL; stdcall;
var
  ButtonHandle: THandle;

begin
  Result := True;
  Param := 0;
  ButtonHandle := FindWindowEx(WindowHandle, 0, 'Button', '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.');
  if ButtonHandle <> 0 then
  begin
    Result := False;
    Param := WindowHandle;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MainHandle: THandle;
  ButtonHandle: THandle;
  StaticHandle: THandle;

begin
  EnumWindows(@EnumWindowsProc, MainHandle);
  if MainHandle <> 0 then
  begin
    ButtonHandle := FindWindowEx(MainHandle, 0, 'Button', '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.');
    StaticHandle := GetDlgItem(MainHandle, $000001F7);
end;
end;

이 소스를 실행시키고 버튼을 클릭하면 'Access violation'이라는 에러 메세지가 나옵니다. 그래서 'F7'로 단계를 넘겨보니

function EnumWindowsProc(WindowHandle: THandle; var Param: THandle): BOOL; stdcall;
var
  ButtonHandle: THandle;

begin
  Result := True;
  Param := 0;
  ButtonHandle := FindWindowEx(WindowHandle, 0, 'Button', '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.');
  if ButtonHandle <> 0 then
  begin
    Result := False;
    Param := WindowHandle;
  end;
end; --> 이 함수에서 무한 루프에 빠지더군요.
ButtonHandle값이 '0'이 되는군요.

여기서 의문나는 사항이 두가지가 있는데 WindowHandle과 MainHandle은 값이 나오더라구요.
소스에서 보면 찾는 값이 아무것도 없는것 같은데..
그리고 Spy ++를 이용하여 찾고자 하는 버튼인 '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.'의 Control ID를 '000001F7'이라는 값을 찾아서 'StaticHandle := GetDlgItem(MainHandle, $000001F7);' 와 같은 식으로 해보았는데.. 아무런 값을 얻을수 없었습니다.

제가 잘못생각하고 있는 것에 관해서 많은 질타 부탁드립니다.
부탁드리겠습니다.
2  COMMENTS
  • Profile
    최용일 2004.05.18 23:07
    안녕하세요. 최용일입니다.

    쩝~ 그냥 대강 짠거라서... 테스트도 안해봤구요...

    이렇게 바꾸어보세요...
    function EnumWindowsProc(WindowHandle: THandle; Param: PHandle): BOOL; stdcall;
    begin
        ......
        Param^ := WindowHandle;
        ......
    end;

    EnumWindows(@EnumWindowsProc, Integer(@MainHandle));

    그리고 디버깅할때 Spy++의 값과 프로그램에서 구한값을 비교해보세요...

    더이상은 저도 몰라요...

    ^^ 항상 즐코하세요...

  • Profile
    술한잔기울이며 2004.05.19 00:37
    아~~감사합니다..
    님께서 말씀해 주신것이 맞네요..
    우선 버튼을 찾는데는 성공했습니다.

    제가 테스트 할려고 만든 것인데..

    procedure TForm1.Button1Click(Sender: TObject);
    var
      s1, s2, s3 : String;
      AlHandle1, StaticHandle : THandle;

    begin
      s1 := '#32770';
      s2 := '설치';
      s3 := '아니오,나중에 다시 시작하겠습니다.';
      AlHandle1 := FindWindow(PChar(s1), PChar(s2));
      if AlHandle1 <> 0 then
        ShowMessage('윈도우를 찾았습니다.')
      else ShowMessage('윈도우를 찾지 못했습니다.');
      StaticHandle := GetDlgItem(AlHandle1, $000001F7);
      if GetWindowText(StaticHandle, PChar(s3),1) = 0 then
        ShowMessage('ok');

      if StaticHandle <> 0 then
        begin
          ShowMessage('버튼을 찾았습니다.');
          SendMessage(StaticHandle,WM_LBUTTONDOWN,0,$10001);
          sleep(1);
          SendMessage(StaticHandle,WM_LBUTTONUP,0,$10001);
        end
      else ShowMessage('버튼을 찾지 못했습니다.');
    end;
    이렇게 하니깐.. 그 문제의 버튼을 찾는 군요..
    지금 GetWindowText라는 것때문에 또 골머리를 썩고 있지만.. 후후.
    감사합니다.
    많은 도움이 되었습니다.