私が最近取り組んでいるソフトウェアは、他のソフトウェアを呼び出すことで完了する必要がありますが、そのソフトウェアは実行可能ファイルのみであり、幸いなことに、私がやりたいことは難しくありません。私のプログラムが開始された後、ソフトウェアを開き、必要に応じてテキスト鉱山の1つにテキストを設定し、ボタンをクリックします。
これについて言えば、あなたはこの機能についていくつかの予備的なアイデアを持っていると思います。
1)CreateProcess()を呼び出して、ターゲットプログラムを開きます。
2)FindWindow()を使用して、ターゲットプログラムのウィンドウハンドルを見つけます。
3)テキストボックスのハンドルとボタンのメッセージを見つけ、sendMessage()メソッドを使用してテキストを設定し、イベントをトリガーします。
OK、これは本当に非常に簡単ですが、実装したとき、この結果は次のとおりであることがわかりました。ターゲットプログラムを開始して開いたとき、そのスプラッシュウィンドウとメインウィンドウが表示されます。 ()メインのウィンドウハンドルを見つけて、sendmessage(windowhandle、sw_hide)を呼び出して、メインウィンドウを少しの間表示します。
それでは、まずこの問題を解決するのですか? 、それは効果がありません。 。 。 。この時点で、LPDESKTOPのようなプロパティを備えたcreateProcess()のパラメーターを見ています。 、そして、デスクトップ名の後に割り当てられている場合、指定されたデスクトップでプロセスが起動されます。
1)最初に、仮想デスクトップを作成します。
const
desktopname = 'mydesk';
fdesktop:= createdesktop(desktopname、nil、nil、0、generic_all、nil);
複数のデスクトップをWindowsで作成でき、Switchdesktop()を使用して、WindowsをLinuxにシミュレートし、実際にその種のプログラムを切り替えることができます。 Windows自体は、Virtual Desktop機能によって実装されています。 。 材料:
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(desktopname);
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)。'の場合、 'エラー(application.title)、mb_iconwarning);
出口;
終わり;
3)FindWindowを使用して、プログラムのメインウィンドウを見つけます
最初はこのようなコードを書き留めました:
i:= 0〜60は始まります//メインウィンドウを開くのを30秒待ちます
WindowHandle:= FindWindow(nil、 'windowcaption');
WindowHandle <> 0の場合、開始します
壊す;
終わり;
睡眠(500);
終わり;
ただし、このように、現在のデスクトップにないウィンドウが見つからないことを証明しています。
答えは、SetThreadDeskTop()関数を使用できることです。これにより、スレッドが機能する場所にデスクトップを設定できるため、上記のコードの前に別の文を追加しました。
setThreaddesktop(fdesktop)をsetThreaddesktop)しない場合は開始します
出口;
終わり;
ただし、プログラムが実行された後、関数はfalseを返し、メソッドコールが慎重に故障したことを示します。
SETTHREADDESKTOP関数は、現在のデスクトップに呼び出しスレッドにWindowsまたはフックがある場合に失敗します( HDESKTOPパラメーターが現在のデスクトップのハンドルでない限り)。
ああ、スレッドにはデスクトップを切り替える必要があるUIはありませんが、プログラムのメインスレッドでこの方法を呼び出します「クリーン」スレッドを新しいデスクトップにバインドしてから、FindWindow()メソッドを使用して、私が探しているWindowHandleを見つける必要があります。コードは次のとおりです。
tfindwindowthread = class(tthread)
プライベート
fdesktop:thandle;
fwindowhandle:thandle;
保護されています
手順execute(); Override;
公共
Constructor create(acreatesuspended:boolean; const adesktop:thandle);再導入;
プロパティウィンドウハンドル:fwindowhandleを読みます。
終わり;
{tfindwindowthread}
手順tfindwindowthread.execute();
var
I:整数;
始める
//新しいデスクトップで現在のスレッドを見つけてください!
setThreaddesktop(fdesktop)をsetThreaddesktop)しない場合は開始します
出口;
終わり;
i:= 0〜60は始まります//メインウィンドウを開くのを30秒待ちます
fwindowhandle:= findwindow(nil、pchar( 'windowcaption'));
fwindowhandle <> 0の場合、開始します
壊す;
終わり;
睡眠(500);
終わり;
終わり;
Constructor tfindwindowthread.create(acreatesuspedended:boolean; const adesktop:thandle);
始める
継承されたcreate(acreatesuspended);
fdesktop:= adesktop;
終わり;
メインプログラムのコードは次のようになります。
FindWindowThread:= tfindwindowthread.create(false、fdesktop);
試す
FindWindowThread.waitfor;
fmainWindowHandle:= findWindowThread.WindowHandle;
ついに
FindWindowThread.free;
終わり;
fmainwindowhandle = 0の場合、開始します
messagebox(application.handle、 'init voice(6)。'の場合、 'エラー(application.title)、mb_iconwarning);
出口;
終わり;
ハハ、成功しているので、ウィンドウをスムーズに見つけることができます。
4)最後に、このメインウィンドウハンドルを使用して、次のように内部の編集ボックスハンドルを見つけます。
FeditWindow:= findWindowex(fmainwindowhandle、0、pchar( 'edit')、nil);
ここでこのテキストボックスのクラス名を指定しましたが、この名前はSpy ++で取得できます。
初期化作業はここで終了します。プログラムはバックグラウンドで実行されます。したがって、関数呼び出しは通常と同じです。
(fmainWindowHandle = 0)または(feditWindow = 0)の場合、開始します
出口;
終わり;
sendMessage(feditwindow、wm_settext、0、longint(@atext [1]));
sendMessage(fmainWindowHandle、wm_command、$ 8012、0 $ 0);
番号8012は、Spy ++を使用して取得したリソースIDでもあります。
最後に、プログラムを閉じて仮想デスクトップをリリースすることを忘れないでください。
fproceinfo.hprocess <> 0の場合、開始します
TerminateProcess(fproceinfo.hprocess、0);
終わり;
fdesktop <> 0の場合、開始します
closedesktop(fdesktop);
終わり;
OK、これはほぼ完全に完全に実装されています。バックグラウンドコールプログラムは、最終的な顧客に対して完全に透過的であり、顧客はバックグラウンドで別のプログラムが機能しているとは感じていません。他の多くの人々のプログラムを直接使用することはできませんか?
改善の提案がある場合、または交換のための提案がある場合は、次のようにメールを送信できます。