안녕하세요.
제가 오늘 비가 와서 그런지 잘 풀려간다고 생각했던 문제들에서 자꾸 막히네요.
다름이 아니라 제가 드라이버 설치를 진행하는데요.
버튼을 찾아서 그 버튼에 클릭효과를 줌으로써 단계를 진행합니다.
근데 좀 이상한 상황이 나타나서 질문을 올리게 되었습니다.
질문을 위해서 파일 두개를 첨부하겠습니다.
'의문 화면.Bmp'라는 파일은 제가 이상하다고 생각한 부분의 화면의 캡쳐 부분이고 'project1.exe'라는 프로그램은 마우스 위치의 핸들과 클래스 이름, 그리고 그것의 텍스트를 가져오는 실행파일(델아맏의 김도완님이 올려주신 파일-죄송합니다. 유용한것 같아서 쓰고 있었습니다.이해해주세요.)입니다.
좀 수고우시더라도 봐주셨으면 합니다. 죄송합니다.
첨부된 그림을 보면 spy의 화면의 빨간색 선에는 분명이 클래스가 'button'으로 되어 있고 텍스트가 '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.'라고 되어 있습니다.
하지만 실행파일 화면의 'ClassName'을 보면 'static'으로 되어 있고, text는 아무런 내용이 없습니다.
어떤 것이 정확한 값일까요?
제가 만든 소스를 보여드리면 아래와 같습니다.
unit uInstallLevel;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, iniFiles, StdCtrls;
type
TfrmInstallOrder = class(TForm)
btnNextEnter: TButton;
edtDeviceName: TEdit;
edtMClassName: TEdit;
edtMText: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
edtCClassName: TEdit;
edtCText: TEdit;
Label5: TLabel;
Label6: TLabel;
btnClose: TButton;
btnNewDevice: TButton;
Label7: TLabel;
btnClickTest: TButton;
btnClear: TButton;
procedure FormCreate(Sender: TObject);
procedure btnNextEnterClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure btnNewDeviceClick(Sender: TObject);
procedure Update_File;
procedure btnClickTestClick(Sender: TObject);
procedure btnClearClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
InstallOrder : TIniFile;
i : integer;
end;
var
frmInstallOrder: TfrmInstallOrder;
implementation
{$R *.dfm}
procedure TfrmInstallOrder.FormCreate(Sender: TObject);
begin
i := 0;
Label7.Caption := 'Level = ' + IntToStr(i+1);
end;
procedure TfrmInstallOrder.btnNextEnterClick(Sender: TObject);
//var
// DeviceName, MClassName, MText, CClassName, CText : String;
begin
Label7.Visible := false;
Update_file;
{ InstallOrder := TIniFile.Create('C:\Result\InstallOrder.ini');
DeviceName := edtDeviceName.Text;
MClassName := edtMClassName.Text;
MText := edtMText.Text;
CClassName := edtCClassName.Text;
CText := edtCText.Text;
inc(i);
InstallOrder.WriteString(DeviceName, 'Level', IntToStr(i));
InstallOrder.WriteString(DeviceName, 'MClassName' + IntToStr(i), MClassName);
InstallOrder.WriteString(DeviceName, 'MText' + IntToStr(i), MText);
InstallOrder.WriteString(DeviceName, 'CClassName' + IntToStr(i), CClassName);
InstallOrder.WriteString(DeviceName, 'CText' + IntToStr(i), CText);
Label4.Caption := 'Level = ' + IntToStr(i);
InstallOrder.Free;
edtMClassName.Clear;
edtMText.Clear;
edtCClassName.Clear;
edtCText.Clear;
edtMClassName.SetFocus;}
end;
procedure TfrmInstallOrder.btnCloseClick(Sender: TObject);
begin
frmInstallOrder.Close;
end;
procedure TfrmInstallOrder.btnNewDeviceClick(Sender: TObject);
var
NewDeviceName : String;
begin
i := 0;
NewDeviceName := InputBox('New DeviceName', '새로입력할 장치의 이름을 입력하세요!','');
edtDeviceName.clear;
edtDeviceName.Text := NewDeviceName;
Label7.Caption := 'Level =' + IntToStr(i+1);
Label4.Visible := false;
Update_File;
Label4.Visible := true;
end;
procedure TfrmInstallOrder.Update_File;
var
DeviceName, MClassName, MText, CClassName, CText : String;
begin
InstallOrder := TIniFile.Create('C:\Result\InstallOrder.ini');
DeviceName := edtDeviceName.Text;
MClassName := edtMClassName.Text;
MText := edtMText.Text;
CClassName := edtCClassName.Text;
CText := edtCText.Text;
inc(i);
Label4.Caption := 'Level = ' + IntToStr(i);
InstallOrder.WriteString(DeviceName, 'Level', IntToStr(i));
InstallOrder.WriteString(DeviceName, 'MClassName' + IntToStr(i), MClassName);
InstallOrder.WriteString(DeviceName, 'MText' + IntToStr(i), MText);
InstallOrder.WriteString(DeviceName, 'CClassName' + IntToStr(i), CClassName);
InstallOrder.WriteString(DeviceName, 'CText' + IntToStr(i), CText);
InstallOrder.Free;
edtMClassName.Clear;
edtMText.Clear;
edtCClassName.Clear;
edtCText.Clear;
edtMClassName.SetFocus;
end;
procedure TfrmInstallOrder.btnClickTestClick(Sender: TObject);
var
s1, s2, s3, s4 : String;
AlHandle1, AlHandle2 : THandle;
Temp : Integer;
begin
Temp := 0;
s1 := edtMClassName.Text;
s2 := edtMText.Text;
s3 := edtCClassName.Text;
s4 := edtCText.Text;
ALHandle1:=FindWindow(PChar(s1),PChar(s2));
if ALHandle1 <> 0 then
ShowMessage('프로그램을 찾았어요. 핸들:'+IntToStr(ALHandle1))
// ** 찾지 못 했다면 나갑니다. ** //
else Exit;
ALHandle2:=FindWindowEx(ALHandle1,0,PChar(s3),PChar(s4));
if ALHandle2 <> 0 then
ShowMessage('버튼을 찾았어요. 핸들:'+IntToStr(ALHandle2))
// ** 찾지 못 했다면 나갑니다. ** //
else Exit;
// ** 다음 버튼을 클릭합니다. ** //
Repeat
begin
SendMessage(ALHandle2,WM_LBUTTONDOWN,0,$10001);
sleep(1);
SendMessage(ALHandle2,WM_LBUTTONUP,0,$10001);
inc(Temp);
if Temp = 10 then exit;
sleep(100);
end;
Until AlHandle2 <> (FindWindowEx(ALHandle1,0,PChar(s3),PChar(s4)));
end;
procedure TfrmInstallOrder.btnClearClick(Sender: TObject);
begin
edtMClassName.Clear;
edtMText.Clear;
edtCClassName.Clear;
edtCText.Clear;
end;
end.
에디트 박스에 각 클래스 이름과 텍스트를 넣고 버튼을 누르면 '프로그램을 찾았어요', '버튼을 찾았어요'라는 팝업창을 띄워줍니다.
그리고 그 버튼에 마우스 클릭효과를 주어서 단계를 넘깁니다.
하지만 spy에 나온 것처럼 'button'과 '아니오, 컴퓨터를 나중에 다시 시작하겠습니다.'라고 넣으면 '버튼을 찾았어요'라는 메세지가 뜨지 않습니다.
이런 현상이 일어날 수도 있는 건가요?
제가 경험과 지식이 부족해서 해결할 방법을 찾아내지 못하겠네요.
부디 버튼을 찾아 단계를 넘길 수 있는 방법을 아시는 분은 꼭 좀 알려주세요.
질문이 너무 장황해서 죄송합니다.
나름대로 요약해서 올린건데.. 소스를 짜르면 님들께서 혹시 보시기 불편해 하실까봐..
그럼 꼭 부탁 좀 드리겠습니다.
비오는데 정말 소주한잔 생각나네요.. ㅠ.ㅠ
핸들을 잘못찾으신거 같습니다.
님이 찾으신 static이란 클래스의 핸들은 918728인데 아래 스파이에서 보이는 핸들은 $11056E이네요. 두 개의 값이 틀린걸 보면 님께서 버튼의 핸들을 제대로 못 찾았다고 생각되네요...
^^ 항상 즐코하세요...