![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Изменить заголовок окна после ShellExecute [D6, Win2k]
LordOfSilence © (2002-07-19 13:02:00)Знатоки, подскажите, пожалуйста, как решить следующую задачку:
Запускаю из своей программы другое приложение, возможно много экземпляров. Делаю это с помощью ShellExecute. Необходимо после запуска внешней программы заменить, вернее, дополнить ее заголовок.
Не получается даже просто считать заголовок чужой программы.
Проблема, видимо, в том, что ShellExecute возвращает дескриптор приложения, а не окна. Делаю примерно следующее:
procedure AppExec( _Program, _CmdLine : string );
var
Inst_ : HINST;
Title_ : array [ 0..80 ] of char;
begin
Inst_ := ShellExecute( 0, "open", PChar( _Program ), PChar( _CmdLine ), nil, SW_SHOWNORMAL );
GetWindowText( Inst_, Title_, SizeOf( Title_ ) );
ShowMessage( Title_ );
end;
Вызов ShowMessage выдает пустую строку. Будьте любезны, выскажите свои мысли по этому поводу. Заранее благодарен.
Song (2002-07-19 16:12:00) [1]Всё правильно, она возращает Вам имя файла от дискриптора HWND в приёмник lpszFileName.
Т.е. алгоритм такой:
Function CurrentFileName:String;
Begin
GetWindowFileName(GetForeGroundWindow,Result,MAX_PATH);
End;
...
ShellExecute(...,"temp.exe",...);
While CurrentFileName<>"temp.exe" Do pplication.ProcessMessages;
...
Конечно, это пишется не так с точки зрения синтаксиса, но теперь надеюсь идея понятна.
LordOfSilence (2002-07-19 16:06:00) [2]Миша, с функцией GetWindowModuleFileName все наоборот. На входе
она требует HWND (его я не знаю), а выдает мне имя файла (его я
знаю). Возвращает она, как резултат функции, число символов в
имени файла. Привожу пример из MSDN:
GetWindowModuleFileName Function
The GetWindowModuleFileName function retrieves the full path and file name of the module associated with the specified window handle.
Syntax
UINT GetWindowModuleFileName(
HWND hwnd,
LPTSTR lpszFileName,
UINT cchFileNameMax
);
Parameters
hwnd
[in] Handle to the window whose module file name will be retrieved. lpszFileName
[out] Pointer to a buffer that receives the path and file name. cchFileNameMax
[in] Specifies the maximum number of TCHAR that can be copied into the lpszFileName buffer.
Return Value
The return value is the total number of TCHAR copied into the buffer.
Song (2002-07-19 15:40:00) [3]Ok, тогда воспользуемся тем, что имя запущенного фала Вам будет известно (оно фигурирует в ShellExecute()).
Для этого мы воспользуемся недокументированной ф-ией GetWindowModuleFileName(), она вернёт нам имя файла ассоциированного с данным дискриптором, поэтому нам надо в цикле ждать до тех пор пока путь, вытащенный для текущего дискриптора GetForeGroundWindow не будет равен тому, файл которого мы запустили.
Ф-ию см. в MSDN, в Дельфи нет.
LordOfSilence (2002-07-19 15:30:00) [4]Миша, вся загвоздка в том, что FindWindow требует заголовка окна,
а в запускаемой мною программе они могут быть разными в зависимости от ее режима запуска, к тому же, с другой стороны, может быть запущено несколько экземпляров этой проги с одним заголовком. Какой из них найдет этот поиск через FindWindow - не знаю. То есть мне
надо запустить программу, получить заголовок именно этого экземпляра, и добавить к нему строку, допустим "всем привет".
LordOfSilence (2002-07-19 15:07:00) [5]Спасибо, я попробую
Song (2002-07-19 15:04:00) [6]Я поэтому и написал толи foreground толи active. Одно из них Вам поможет точно.
Если не знаете времени сколько приложение будет грузиться тогда придётся сделать цикл, ожидающий его загрузку:
While FindWindow(...)=0 Do Application.ProcessMessages;
LordOfSilence (2002-07-19 15:00:00) [7]Вся проблема в том, что запускаю я не классический "Блокнот",
который "пестрит" во всех примерах, а серьезный пакет, который может, вообще говоря, грузиться разное время в зависимости от объема уже им подгружаемых данных, "усталости" виндового кеша и прочей ерундистики, которую заранее не предугадаешь. Поэтому можно просто не попасть на нужный момент активности окна. К тому же цитирую:
The GetActiveWindow function retrieves the window handle to the active window associated with the thread that calls the function.
Как я понимаю, "эта функция получает дескриптор для активного
окна, ассоциированного с потоком, который вызывают эту функцию".
То есть с потоком моего приложения, а не того, которое я запускаю. Поправьте меня, если я заблуждаюсь.
Song (2002-07-19 14:43:00) [8]Inst_ это не тот дискриптор. Сделайте после ShellExecute() не большую паузу и найдите нужный дискриптор через GetForeGroundWindow или GetActiveWindow