Программное обеспечение, над которым я работаю в последнее время, некоторые из которых должны быть завершены, вызывая другое программное обеспечение, но в этом программном обеспечении есть только исполняемые файлы и вообще нет исходного кода. Начнется после того, как моя программа запускается.
Говоря об этом, я считаю, что у вас есть предварительные идеи для этой функции.
1) Вызовите CreateProcess (), чтобы открыть целевую программу.
2) Используйте FindWindow (), чтобы найти ручку оконной программы.
3) Найдите ручку текстового поля и MessageID кнопки, установите текст, используя метод SendMessage () и запустите событие.
Хорошо, это действительно очень просто, но когда я его реализовал, я обнаружил, что результатом этого стало: когда моя программа запустила и открыла целевую программу, ее окно брызги и главное окно отобразится, даже если я использую FindWindow () Чтобы найти ручку главного окна, и вызовите Sendmessage (Windowhandle, SW_HIDE), чтобы скрыть окно, главное окно будет отображаться на мгновение.
Итак, как решить эту проблему? , это не имеет никакого эффекта. Полем Полем Полем Продолжайте искать документ. , и если он назначен ему после названия рабочего стола, на указанном рабочем столе будет запущен процесс.
1) Во -первых, создайте виртуальный рабочий стол.
констант
DesktopName = 'mydesk';
Fdesktop: = createdesktop (DesktopName, nil, nil, 0, generic_all, nil);
Несколько рабочих столов могут быть созданы в Windows, и SwitchDeskTop () может использоваться для переключения, какое рабочие столы отображаются. Сама Windows реализована виртуальной работой. .
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/enumdesktops.asp
2) Когда CreateProcess укажите программу для запуска на моем недавно сгенерированном рабочем столе:
вар
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 goice (5).», Pchar (application.title), mb_iconwarnning);
Выход;
конец;
3) Используйте FindWindow, чтобы найти главное окно программы
Сначала я записал код так:
для i: = от 0 до 60, начинайте // ждать 30 секунд, чтобы открыть главное окно
Windownhandle: = findwindow (ноль, 'windowscaption');
Если windownhandle <> 0, тогда начните
перерыв;
конец;
Сон (500);
конец;
Тем не менее, практика доказала, что таким образом, окно, которое не находится в текущем рабочем столе, не может быть найдено.
Ответ заключается в том, что вы можете использовать функцию SetThreadDeskTop (), которая может установить рабочий стол, где работает поток, поэтому я добавил другое предложение перед вышеуказанным кодом:
Если не SetThreadDesktop (fdesktop), тогда начинайте
Выход;
конец;
Однако после запуска программы функция возвращает ложь, указывая, что вызов метода не удался.
Функция SetThreadDeskTop не удастся, если в вызовом потоке есть какие -либо окна или крючки на его текущем рабочем столе (если только параметр HDESKTop не является ручкой для текущего рабочего стола).
О, оказывается, что в потоке нет никакого пользовательского интерфейса, которая должна переключить настольный компьютер, но я позвонил в этот метод в основной потоке программы, и, конечно, он потерпит неудачу. Необходимо использовать его, не нормально связывать «чистый» поток с новым рабочим столом, а затем использовать метод FindWindow (), чтобы найти поиск Windowhandle, который я ищу? Код заключается в следующем:
Tfindwindowthread = class (tthread)
Частный
Fdesktop: Thandle;
Fwindowhandle: Тандл;
защищен
процедура execute (); переопределить;
публичный
Конструктор Create (AcreAtesusded: Boolean; const adesktop: thandle); реинтроду;
Hindowhandle Property: Thandle Read Fwindowhandle;
конец;
{TfindWindowThread}
Процедура tfindWindowthread.execute ();
вар
Я: целое число;
Начинать
// Сделайте текущее окно находить окно на новом рабочем столе!
Если не SetThreadDesktop (fdesktop), тогда начинайте
Выход;
конец;
для i: = от 0 до 60, начинайте // ждать 30 секунд, чтобы открыть главное окно
Fwindowhandle: = findwindow (nil, pchar ('windowscaption'));
Если fwindowhandle <> 0, то начните
перерыв;
конец;
Сон (500);
конец;
конец;
конструктор tfindwindowthread.create (acreatesusded: boolean; const adesktop: thandle);
Начинать
унаследованное создание (AcreateSped);
Fdesktop: = adesktop;
конец;
И код в основной программе становится таким:
FindWindowThread: = tfindWindowThread.Create (false, fdesktop);
пытаться
Findwindowthread.waitfor;
Fmainwindowhandle: = findwindowthread.windowhandle;
Окончательно
Findwindowthread.free;
конец;
Если fmainwindowhandle = 0, то начните
MessageBox (Application.Handle, «Ошибка, когда init goice (6).», Pchar (application.title), mb_iconwarning);
Выход;
конец;
Ха -ха, это успешно, так что вы можете найти ручку с оконным ручком.
4) Наконец, используйте эту ручку основного окна, чтобы найти ручку Editbox внутри, следующим образом:
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 ++.
Наконец, не забудьте закрыть программу и выпустить виртуальный рабочий стол:
Если fproceinfo.hprocess <> 0, то начните
TerminateProcess (fProceInfo.hprocess, 0);
конец;
Если fdesktop <> 0, то начните
Закрытый
конец;
Хорошо, это почти идеально реализует функцию программы фоновых вызовов, которая будет полностью прозрачна для конечного клиента, и клиент просто не чувствует, что в фоновом режиме работают другая программа. Разве это не очень хорошо?
Если у вас есть какие -либо предложения по улучшению или обмену, вы можете отправить по почте: Tonyki [at] citister.net