최근에 작업중 인 소프트웨어는 다른 소프트웨어를 호출하여 완료해야하지만 소프트웨어에는 실행 가능한 파일 만 가지고 있으며 소스 코드가 전혀 없습니다. 내 프로그램이 시작된 후 시작하고 소프트웨어를 열고 필요할 때 텍스트 광산 중 하나에 텍스트를 설정하고 버튼을 클릭하십시오.
이것에 대해 말하면, 나는 당신 이이 기능에 대한 예비 아이디어를 가지고 있다고 생각합니다.
1) CreateProcess ()를 호출하여 대상 프로그램을 열십시오.
2) FindWindow ()를 사용하여 대상 프로그램의 창 핸들을 찾으십시오.
3) 텍스트 상자의 핸들과 버튼의 MessageId를 찾아서 sendMessage () 메소드를 사용하여 텍스트를 설정하고 이벤트를 트리거합니다.
좋아, 이것은 실제로 매우 간단하지만, 구현했을 때, 나는 이것의 결과가 : 내 프로그램이 대상 프로그램을 시작하고 열었을 때, splash 창과 기본 창이 표시 되더라도 FindWindow를 사용하더라도 표시됩니다. () 기본 창 손잡이를 찾아서 SendMessage (Windowhandle, SW_HIDE)를 호출하려면 기본 창이 잠시 표시됩니다.
따라서이 문제를 해결하는 방법은 무엇입니까? , 그것은 효과가 없습니다. . . . 문서를 계속 검색하십시오. 현재 LPDESKTOP과 같은 속성을 가진 CreateProcess ()의 매개 변수를 보았습니다. 그리고 데스크탑 이름 후에 지정된 경우 지정된 데스크탑에서 프로세스가 시작됩니다.
1) 먼저 가상 데스크탑을 만듭니다.
Const
DesktopName = 'MyDesk';
fdesktop : = createSktop (goodtopname, nil, nil, 0, generic_all, nil);
Windows에서 여러 데스크탑을 만들 수 있으며 SwitchDeskTop ()은 Windows를 Linux로 시뮬레이션하는 프로그램이 있으며 실제로 여러 가상 데스크톱을 전환 할 수 있습니다. Windows 자체는 가상 데스크톱 기능에 의해 구현되며, Windows Startup Screen 및 Screensaver 화면도 가상 데스크탑에서 구현되면 MSDN에서 자세히 설명 할 수 있습니다. . 재료:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/enumdesktops.asp
2) CreateProcess는 새로 생성 된 데스크탑에서 실행할 프로그램을 지정합니다.
var
StartInfo : tstartupinfo;
fillchar (startInfo, sizeof (startInfo), 0);
startInfo.cb : = sizeof (startInfo);
startinfo.lpdesktop : = pchar (goodtopname);
startinfo.wshowwindow : = sw_hide;
startinfo.dwflags : = startf_useshowwindow;
startInfo.hstderror : = 0;
startInfo.hstdInput : = 0;
startInfo.hstdOutput : = 0;
CreateProcess (pchar (filename), nil, nil, nil, nil, true, create_new_console+high_priority_class, nil, pchar (extractfilepath (filepath)), startinfo, fproceinfo)가 아닌 경우
MessageBox (Application.Handle, 'init Voice (5).
출구;
끝;
3) FindWindow를 사용하여 프로그램의 주요 창을 찾으십시오.
처음에 나는 다음과 같은 코드를 기록했다.
i : = 0 ~ 60의 경우 시작 // 메인 창을 열기 위해 30 초 기다립니다.
WindowHandle : = FindWindow (NIL, 'WindowCaption');
Windowhandle <> 0이면 시작하십시오
부서지다;
끝;
수면 (500);
끝;
그러나 연습은 이런 식으로 현재 데스크탑에없는 창을 찾을 수 없다는 것을 증명했습니다.
답은 SetTheRreadDeskTop () 함수를 사용할 수 있다는 것입니다.이 기능은 스레드가 작동하는 데스크탑을 설정할 수 있으므로 위의 코드 전에 다른 문장을 추가했습니다.
setThreadDeskTop (fdesktop)이 아닌 경우 시작하십시오
출구;
끝;
그러나 프로그램이 실행되면 기능이 False를 반환하여 MSDN을주의 깊게 살펴본 후에는 실패했음을 나타냅니다.
호출 스레드에 현재 데스크탑에 Windows 또는 Hooks가 있으면 SetThreadDeskTop 함수가 실패합니다 ( HDESKTOP 매개 변수가 현재 데스크탑의 핸들이 아닌 한).
오, 스레드에는 데스크탑을 전환 해야하는 UI가 없지만 프로그램의 주요 스레드 에서이 방법을 불렀습니다 "클린"스레드를 새 데스크탑에 바인딩 한 다음 FindWindow () 메소드를 사용하여 원하는 Windowhandle을 찾는 것은 좋지 않습니까? 코드는 다음과 같습니다.
tfindwindowthread = class (tthread)
사적인
fdesktop : thandle;
Fwindowhandle : Thandle;
보호
프로 시저 execute (); 재정의;
공공의
생성자 생성 (AcreatesPended : Boolean; Const Adesktop : Thandle); 재 도입;
Property Windowhandle : Thandle 읽기 Fwindowhandle;
끝;
{tfindwindowthread}
절차 tfindwindowthread.execute ();
var
I : 정수;
시작하다
// 새 데스크톱에서 현재 스레드를 찾으십시오!
setThreadDeskTop (fdesktop)이 아닌 경우 시작하십시오
출구;
끝;
i : = 0 ~ 60의 경우 시작 // 메인 창을 열기 위해 30 초 기다립니다.
fwindowhandle : = findwindow (nil, pchar ( 'windowcaption'));
fwindowhandle <> 0이면 시작하십시오
부서지다;
끝;
수면 (500);
끝;
끝;
생성자 tfindwindowthread.create (Acreatesuspended : boolean; const adesktop : thandle);
시작하다
상속 된 생성 (Acreatespended);
fdesktop : = adesktop;
끝;
그리고 메인 프로그램의 코드는 다음과 같습니다.
FindWindowthread : = tfindwindowthread.create (false, fdesktop);
노력하다
findwindowthread.waitfor;
fmainwindowhandle : = findwindowthread.windowhandle;
마지막으로
findwindowthread.free;
끝;
fmainwindowhandle = 0이면 시작하십시오
MessageBox (Application.Handle, 'init Voice (6).
출구;
끝;
하하, 성공적이므로 창 핸들을 부드럽게 찾을 수 있습니다.
4) 마지막 으로이 기본 창 핸들을 사용하여 다음과 같이 내부의 편집 박스 핸들을 찾으십시오.
FeditWindow : = FindWindowEx (FmainwindowHandle, 0, PCHAR ( 'edit'), NIL);
여기 에이 텍스트 상자의 클래스 이름을 지정 했으며이 이름은 Spy ++로 얻을 수 있습니다.
초기화 작업은 여기서 끝나면 프로그램이 백그라운드에서 실행됩니다. 따라서 기능 호출은 평소와 동일합니다.
if (fmainwindowhandle = 0) 또는 (FeditWindow = 0)을 시작합니다
출구;
끝;
sendMessage (FeditWindow, WM_Settext, 0, longint (@atext [1]);
SendMessage (fmainwindowhandle, wm_command, $ 8012, $ 0);
$ 8012는 Spy ++를 사용하여 얻은 리소스 ID입니다.
마지막으로 프로그램을 닫고 가상 데스크탑을 해제하는 것을 잊지 마십시오.
fproceinfo.hprocess <> 0 인 경우 시작하십시오
TerminateProcess (fproceinfo.hprocess, 0);
끝;
fdesktop <> 0이면 시작하십시오
ClosedEsktop (fdesktop);
끝;
좋아, 이것은 거의 최종 고객에게 투명 할 것이며 고객은 백그라운드에서 다른 프로그램이 작동한다고 생각하지 않습니다. 그다지 좋지 않습니까? 우리는 다른 많은 사람들의 프로그램을 직접 사용할 수 있습니다 (물론 저작권을 따라야합니다).
개선 또는 교환에 대한 제안이 있으면 다음으로 우편으로 보내주십시오. Tonyki [at] Citiz.net