Q&A

  • EnumWindows 로 잡히지를 않네요. 부탁드립니다.


프로그램인스톨 자동으로 하는 프로그램을 작성중인데요. 얼마전에 용일님께서 알려주신것으로 해보았는데
안되더라구요.. 그래서 이것 저것 해보았지만 안되서 다시 문의드립니다.
위하면의 edit 박스에 각각 string을 넣으려고 합니다. enumwindows로 돌리는데 찾아지지가 않습니다.
무엇때문이지 모르겠습니다.
소스하고 인스톨프로그램 동봉합니다. 한번만 봐주세요..

소스는 다음과 같습니다.
-----------------------------------------------------------------------------------------------
unit Umain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Registry,shellapi;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//function EnumwindowsProc(WindowHandle: THandle; Param: PHandle): BOOL; stdcall;
//function EnumWindowsProc(WindowHandle: THandle; Param: THandle): BOOL; stdcall;
function EnumWindowsProc(WindowHandle: THandle; Param: THandle): BOOL; stdcall;
var
  VrayStaticHandle: THandle;
begin
  Result := True;
  Param := 0;
  VrayStaticHandle := FindWindowEx(WindowHandle,0,'Static','V-Ray destination folder(your plugins directory)');
  if VrayStaticHandle <> 0 then
  begin
    Result := False;
//    Param := WindowHandle;
//    Param^ := WindowHandle;
    Param := WindowHandle;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  VrayHwnd,VrayChildHwnd,VrayNextHwnd,VrayAgreeBtHwnd,MainHandle,AgreeBTHwnd : THandle;
  VrayMsBoxHwnd,VrayMsBoxBTHwnd,VrayStaticHandle,VrayStaticParentHwnd,VrayPluginDirctoryHwnd,VrayRootDirctoryHwnd : THandle;
  VrayReg : TRegistry;
  Drive,DrivePath,VrayOrinPath,VrayOrinFile,VeriS,VrayFullPath,VrayRootDirctory,VrayPluginDirctory : string;
begin
  VrayReg := TRegistry.Create;
  VrayReg.RootKey := HKEY_LOCAL_MACHINE;
  VrayReg.OpenKey('Software\Autodesk\3dsmax\7.0',false);
  edit1.Text := VrayReg.Readstring('installdir');
  VrayReg.Closekey;
  VrayOrinPath := '..\Util\Max_Prog\VRay_14703\';
  VrayOrinFile := 'Vray_14703.exe';
  VrayFullPath := VrayOrinPath+VrayOrinFile;
  Edit2.text := VrayFullPath;
  ShellExecute(Handle, 'Open', PChar(VrayFullPath), nil, nil, SW_SHOWNORMAL );
  sleep(4000);
  VrayHwnd := FindWindow(nil,'V-Ray installation wizard'); //  다음 버튼 클릭
  VrayNextHwnd := FindWindowEx(VrayHwnd,0,'Button','다음(&N) >');
  PostMessage(VrayNextHwnd,WM_LBUTTONDOWN,0,0);
  PostMessage(VrayNextHwnd,WM_LBUTTONUP,0,0);
  PostMessage(VrayNextHwnd,WM_LBUTTONDOWN,0,0);
  PostMessage(VrayNextHwnd,WM_LBUTTONUP,0,0);

  sleep(1000);

  VrayHwnd := FindWindow(nil,'V-Ray installation wizard');  // I agree 버튼클릭
  if VrayHwnd <> 0 then
    begin
      ShowMessage('VrayHwnd :'+inttostr(VrayHwnd));
    end;

  VrayChildHwnd := FindWindowEx(VrayHwnd,0,'#32770',nil); // child 윈도우찾기
  if VrayChildHwnd = 0 then
    begin
      ShowMessage('VrayChildHwnd 버튼을 찾지못했습니다'+inttostr(VrayHwnd));
    end;

  VrayAgreeBtHwnd := GetDlgItem(VrayChildHwnd,$000003EC);   // i agree버튼 클릭
  if VrayAgreeBtHwnd <> 0 then
    begin
      ShowMessage('VrayAgreeBtHwnd :' +inttostr(AgreeBtHwnd));
      PostMessage(VrayAgreeBtHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayAgreeBtHwnd,WM_LBUTTONUP,0,0);
      PostMessage(VrayAgreeBtHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayAgreeBtHwnd,WM_LBUTTONUP,0,0);
    end
  else begin
      ShowMessage('VrayAgreeBtHwnd을 찾지못했습니다.' +inttostr(VrayAgreeBtHwnd));
      Exit;
    end;

  VrayNextHwnd := FindWindowEx(VrayHwnd,0,'Button','다음(&N) >');  //다음버튼 클릭
  if VrayNextHwnd <> 0 then
    begin
      PostMessage(VrayNextHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayNextHwnd,WM_LBUTTONUP,0,0);
      PostMessage(VrayNextHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayNextHwnd,WM_LBUTTONUP,0,0);
    end
  else begin
      ShowMessage('다음버튼을을 찾지못했습니다.' +inttostr(VrayNextHwnd));
      Exit;
    end;

  Sleep(1000);

  VrayHwnd := FindWindow(nil,'V-Ray installation wizard');
  ShowMessage('VrayHwnd :' +inttostr(VrayHwnd));
  if VrayHwnd = 0 then
    begin
      ShowMessage('VrayHwnd핸들을 찾지못했습니다.' +inttostr(VrayHwnd));
      Exit;
    end;

{  VrayMsBoxHwnd := FindWindow('#32770','V-Ray installation'); //메세지박스 확인 버튼 클릭
  ShowMessage('VrayMsBoxHwnd :' +inttostr(VrayMsBoxHwnd));
  if VrayMsBoxHwnd = 0 then
    begin
      ShowMessage('Vray메세지박스핸들을 찾지못했습니다.' +inttostr(VrayMsBoxHwnd));
      Exit;
    end;

  VrayMsBoxBTHwnd := FindWindowEx(VrayMsBoxHwnd,0,'Button','확인');
  if VrayMsBoxBTHwnd = 0 then
    begin
      ShowMessage('확인버튼핸들을 찾지못했습니다.' +inttostr(VrayMsBoxBTHwnd));
      Exit;
    end
  else
    begin
      PostMessage(VrayMsBoxBTHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayMsBoxBTHwnd,WM_LBUTTONUP,0,0);
      PostMessage(VrayMsBoxBTHwnd,WM_LBUTTONDOWN,0,0);
      PostMessage(VrayMsBoxBTHwnd,WM_LBUTTONUP,0,0);
    end;}



// 브레이 디렉토리설정의 브라우저 핸들구하기
  EnumWindows(@EnumwindowsProc,MainHandle);
//  EnumWindows(@EnumWindowsProc,integer(@MainHandle));
  ShowMessage('MainHandle: ' +inttostr(MainHandle));
  ShowMessage('MainHandle의 부모핸들 :'+ inttostr(GetParent(MainHandle)));
  VrayStaticHandle := FindWindowEx(MainHandle,0,'Static','V-Ray destination folder(your plugins directory)');
  if VrayStaticHandle = 0 then
    begin
      ShowMessage('VrayStaticHandle핸들을 찾지못했습니다.' +inttostr(VrayStaticHandle));
      exit;
    end

  else
    begin
      VrayRootDirctory := 'c:\3dsmax7\';
      VrayPluginDirctory := 'c:\3dsmax7\Plugin\';
       VrayStaticParentHwnd := GetParent(VrayStaticHandle);
       VrayRootDirctoryHwnd := GetDlgItem(VrayStaticParentHwnd,$000003EE);
       VrayPluginDirctoryHwnd := GetDlgItem(VrayStaticParentHwnd,$000003EC);
      SendMessage(VrayRootDirctoryHwnd,WM_SETTEXT,0,LParam(Pchar(VrayRootDirctory)));
      SendMessage(VrayPluginDirctoryHwnd ,WM_SETTEXT,0,LParam(Pchar(VrayPluginDirctory)));
   end;


end;
end.
2  COMMENTS
  • Profile
    최용일 2007.01.17 22:54
    안녕하세요. 최용일입니다.

    EnumWindows 쓸 필요없습니다. FindWindow, FindWindowEx, GetDlgItem만 이용하셔도 충분합니다.

    아래는 님께서 했던데까지만 대강 만들어봤습니다. 참고해서 만드세요...

    <!--CodeS-->
    procedure TForm1.Button1Click(Sender: TObject);
    var
      VRayPath: string;
      VRayMain: THandle;
      Page1Wnd, Page2Wnd, Page3Wnd: THandle;
      NextButton, AgreeRadio, RootFolderEdit, PluginFolderEdit: THandle;
      RootFolder, PluginFolder: ShortString;
    begin
      VRayPath := ExtractFilePath(Application.ExeName) + 'VRay_14703.exe';
      ShellExecute(handle, 'open', PChar(VRayPath), nil, nil, SW_SHOWNORMAL);
      VRayMain := FindWindow(nil,'V-Ray installation wizard');
      while VRayMain = 0 do
      begin
        Sleep(100);
        VRayMain := FindWindow(nil,'V-Ray installation wizard');
        // To Do: Infinite Loop
      end;
      // Page 1: Welcome to ...
      Page1Wnd := FindWindowEx(VRayMain, 0, '#32770', nil);
      NextButton := GetDlgItem(VRayMain, $3024);
      SendMessage(NextButton, BM_CLICK, 0, 0);
      // Page 2: License Agreement
      Page2Wnd := FindWindowEx(VRayMain, 0, '#32770', nil);
      AgreeRadio := GetDlgItem(Page2Wnd, $03EC);
      SendMessage(AgreeRadio, BM_CLICK, 0, 0);
      SendMessage(NextButton, BM_CLICK, 0, 0);
      // Page 3: Destination Folder
      RootFolder := 'c:\3dsmax7\'+#0;
      PluginFolder := 'c:\3dsmax7\Plugin\'+#0;
      Page3Wnd := FindWindowEx(VRayMain, 0, '#32770', nil);
      RootFolderEdit := GetDlgItem(Page3Wnd, $03EE);
      PluginFolderEdit := GetDlgItem(Page3Wnd, $03EC);
      SendMessage(RootFolderEdit, WM_SETTEXT, 0, Integer(@RootFolder[1]));
      SendMessage(PluginFolderEdit, WM_SETTEXT, 0, Integer(@PluginFolder[1]));
      SendMessage(NextButton, BM_CLICK, 0, 0);
    <!--CodeE-->

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

  • Profile
    박진수 2007.01.23 08:59
    답변주신것 보고 깨달음을 얻었습니다. 너무 감사합니다.  미약한 소스나마 저같은 사람을 위해 올립니다.

    ------------------------------------------------------------------------------------------------------------------------
    <!--CodeS-->
    unit uMain;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ShellApi,Shlobj;

    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}



    // Program Files 폴더 알아내기
    function GetProgramFilesFolder1() : String;
    var
      ProgramFileDir : String;
    const
    CSIDL_PROGRAM_FILES = $0026;
    begin
      SetLength (ProgramFileDir, MAX_PATH);
      SHGetSpecialFolderPath(Application.Handle , PChar(ProgramFileDir), CSIDL_PROGRAM_FILES, FALSE);
      SetLength (ProgramFileDir, StrLen (PChar(ProgramFileDir)));
      Result := ProgramFileDir;
    end;



    //얼지않는 함수
    procedure winDelay(msectime:Cardinal);
    var
      fcontinue : Boolean;
      start : Cardinal;
    begin
      fcontinue := True;
      start := GetTickCount;
      while fcontinue do
        begin
          application.ProcessMessages;
          if start + msectime < GetTickCount then fcontinue := False;
        end;
    end;


    procedure TForm1.Button1Click(Sender: TObject);
    var
    PBWnd,PBNextWnd,PbPage2Wnd,PbChangeWnd,PbChooseDirWnd,PbChooseDirOkWnd,PbChooseDirEditWnd,
    PbPage3Wnd,PbInstallWnd,PbPage4Wnd,PbSkipWnd,PbFinishWnd         : THandle;
    MaxinstallDir,PbFromDir : string;
    CopyFiles : TSHFileOpStruct;
    begin
      ShellExecute(Handle,'open',PChar('..\Util\Max Plugin\Power Booleans\PowerBolleanR261.exe'),nil,nil,SW_SHOWNORMAL);

    // Page 1 :  Welcome to PowerBooleans for 3ds Max Installer
      repeat
      PbWnd := FindWindow('#32770','PowerBooleans for MAX 6 - InstallShield Wizard');
      PbNextWnd := FindWindowEx(PBWnd,0,'Button','&Next >');
      if (PbWnd = 0) and (PbNextWnd = 0) and not IsWindowEnabled(PbNextWnd) then
        begin
          winDelay(2000);
        end
      until (PbWnd <> 0) and (PbNextWnd <> 0) and IsWindowEnabled(PbNextWnd);
      winDelay(1000);
      SendMessage(PbNextWnd,BM_CLICK,0,0);  //Next 버튼 클릭

    // Page 2 : Enter Path to the Top Level 3ds Max Directory to install
      repeat
      PbPage2Wnd := FindWindow('#32770','PowerBooleans for MAX 6 - InstallShield Wizard');
      PbChangeWnd := FindWindowEx(PbPage2Wnd,0,'Button','&Change...');
      PbNextWnd := FindWindowEx(PbPage2Wnd,0,'Button','&Next >');
      if (PbPage2Wnd = 0) and (PbChangeWnd = 0) and not IsWindowVisible(PbChangeWnd) then
        begin
          winDelay(2000);
        end;
      until (PbPage2Wnd <> 0) and (PbChangeWnd <> 0)and IsWindowVisible(PbChangeWnd);
      winDelay(1000);
      SendMessage(PbChangeWnd,BM_CLICK,0,0);   // Change.. 버튼 클릭

      //Change 폴더 바꾸기
      repeat
      PbChooseDirWnd := FindWindow('#32770','Choose Folder');
      PbChooseDirOkWnd := FindWindowEx(PbChooseDirWnd,0,'Button','확인');
      PbChooseDirEditWnd := FindWindowEx(PbChooseDirWnd,0,'Edit','Edit');

      if (PbChooseDirWnd = 0) and (PbChooseDirOkWnd = 0) then
        begin
          winDelay(2000);
        end;
      until (PbChooseDirWnd <> 0) and (PbChooseDirOkWnd <> 0);
      winDelay(1000);
      // 맥스 디렉토리 읽기
      MaxinstallDir := Copy(GetProgramFilesFolder1,0,3) + '3dsmax7\'+#0;
      SendMessage(PbChooseDirEditWnd,WM_SETTEXT,0,integer(@MaxinstallDir[1]));
      winDelay(1000);

      SendMessage(PbChooseDirOkWnd,BM_CLICK,0,0); //확인 버튼 클릭
      winDelay(1000);

      SendMessage(PbNextWnd,BM_CLICK,0,0);  //Next 버튼 클릭

    // Page 3 :  Ready to install the Program
      repeat
      PbPage3Wnd := FindWindow('#32770','PowerBooleans for MAX 6 - InstallShield Wizard');
      PbInstallWnd := FindWindowEx(PbPage3Wnd,0,'Button','&Install');
      if (PbPage3Wnd = 0) and (PbInstallWnd = 0) and not IsWindowVisible(PbInstallWnd) then
        begin
          winDelay(2000);
        end;
      until (PbPage3Wnd <> 0) and (PbInstallWnd <> 0)and IsWindowVisible(PbInstallWnd);
      winDelay(1000);
      SendMessage(PbInstallWnd,BM_CLICK,0,0);   // Install 버튼 클릭

    // Pae 4 : InstallShield Wizard Complete
      repeat
      PbPage4Wnd := FindWindow('#32770','PowerBooleans for MAX 6 - InstallShield Wizard');
      PbSkipWnd := FindWindowEx(PbPage4Wnd,0,'Button','N&o, skip this step.');
      PbFinishWnd := FindWindowEx(PbPage4Wnd,0,'Button','Finish');
      if (PbPage4Wnd = 0) and (PbSkipWnd = 0) and not IsWindowVisible(PbFinishWnd) then
        begin
          winDelay(2000);
        end;
      until (PbPage4Wnd <> 0) and (PbSkipWnd <> 0)and IsWindowVisible(PbFinishWnd);
      winDelay(1000);
      SendMessage(PbSkipWnd,BM_CLICK,0,0);   // No,SKip the step버튼 클릭
      winDelay(1000);
      SendMessage(PbFinishWnd,BM_CLICK,0,0);   // Finish 버튼 클릭
      winDelay(2000);

    //Page 5 : Licence 화일 카피
      MaxinstallDir := Copy(GetProgramFilesFolder1,0,3) + '3dsmax7\'+#0;
      PbFromDir := '..\Util\Max Plugin\Power Booleans\License\' + '*.*' + #0;
      with copyFiles do
        begin
          wnd := 0;
          Wfunc := fo_copy;
          pfrom := PChar(PbFromDir);
          pto := PChar(MaxinstallDir);
         fflags := FOF_NOCONFIRMATION or FOF_MULTIDESTFILES or FOF_NOCONFIRMMKDIR  //FOF_ALLOWUNDO OR FOF_NOCONFIRMation; //FOF_ALLOWUNDO or FOF_NOCONFIRMATION; // FOF_FILESONLY
        end;
      shfileoperation(copyfiles);
      Sleep(3000);

    end;
    end.
    <!--CodeE-->