Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> handle of the application в handle of the window, определение указателя окна 
V
    Опции темы
Fedia
Дата 5.9.2006, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Приветствую всех !
Задачка такая: запускаю приложение через ShellExecute и как результат функции ShellExecute получаю его указатель. Например:
Код

var
  hApp: Cardinal;
//....
hApp:=ShellExecute(0, 'open', 'C:\text.exe', nil, nil, SW_SHOWNORMAL)

Необходимо по указателю hApp получить хендл активного окна запущенного приложения в том виде, в котором его возвращает функция FindWindow. Например:
Код

var
  AHWND: HWND;
//....
AHWND:=FindWindow(nil, 'Тест'); //'Тест' - заголовок нужного мне окна приложения

Т.е. мне необходимо из hApp получить AHWND. Возможно ли это реализовать ?

Это сообщение отредактировал(а) Fedia - 5.9.2006, 02:49


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
bazzzman
Дата 5.9.2006, 03:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 24.7.2006

Репутация: нет
Всего: 2



Не совсем понял вопрос...
Если надо найти дочернее окно какого-то конкретного окна, то:
1. GetWindow
2. EnumChildWindows
3. FindWindowEx
PM MAIL WWW   Вверх
Fedia
Дата 5.9.2006, 04:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(bazzzman @  5.9.2006,  03:10 Найти цитируемый пост)
Если надо найти дочернее окно какого-то конкретного окна, то:

Мне нужно найти хендл активного окна приложения, зная хендл самого приложения. Хендл приложения получаю при его запуске посредством ShellExecute.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
dumb
Дата 5.9.2006, 04:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



CreateProcess + EnumThreadWindows( pi.dwThreadId, ...
PM MAIL   Вверх
bazzzman
Дата 5.9.2006, 04:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 24.7.2006

Репутация: нет
Всего: 2



Цитата(dumb @ 5.9.2006,  04:32)
CreateProcess + EnumThreadWindows( pi.dwThreadId, ...

Это не то... При чем тут CreateProcess, если "нужно найти хендл активного окна приложения, зная хендл самого приложения"?

Вот как это делаю я:
Код

function GetFocusWindow(hWnd:THandle=0) : THandle;
var FgThreadID: Integer;
begin
 if hWnd=0 then hWnd:=GetForegroundWindow;

 FgThreadID := GetWindowThreadProcessID(hWnd, nil);
 if AttachThreadInput(GetCurrentThreadID, FgThreadID, True) then
  begin
    Result := GetFocus;
    AttachThreadInput(GetCurrentThreadID, FgThreadID, False);
  end else Result := GetFocus;
end;


По-хорошему надо сделать более серьезную проверку ошибок...  smile 
PM MAIL WWW   Вверх
Fedia
Дата 5.9.2006, 05:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(bazzzman @  5.9.2006,  04:42 Найти цитируемый пост)
Вот как это делаю я:

Не работает. Проверяю так:
Код

var
  hAp: Cardinal;
  AHWND, AHWND_test: HWND;
begin
  hAp:=ShellExecute(0, 'open', 'C:\test.exe', nil, nil, SW_SHOWNORMAL);
  AHWND:=FindWindow(nil, 'Тест');
  AHWND_test:=GetFocusWindow(hAp);
  if AHWND = AHWND_test then
  ShowMessage('1');
end;


bazzzman, кстати сейчас проверил, твоя функция возвращает хендл окна, запустившего приложение.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
bazzzman
Дата 5.9.2006, 06:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 24.7.2006

Репутация: нет
Всего: 2



Значит это окно имеет фокус ввода. Что не так?

Надо что-то другое? Тогда сформулируй нормально вопрос. 

hAp:=ShellExecute(0, 'open', 'C:\test.exe', nil, nil, SW_SHOWNORMAL); - возвращает не handle окна:
Цитата

Returns a value greater than 32 if successful, or an error value that is less than or equal to 32 otherwise. The following table lists the error values. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. The only thing that can be done with the returned HINSTANCE is to cast it to an int and compare it with the value 32 or one of the error codes below.


Значит GetWindowThreadProcessID(hWnd, nil); мы не можем сделать. Нежен threadId => CreateProcess как и предлагал dumb или ShellExecuteEx. И уже потом AttachThreadInput.

Думаю информации и так уже достаточно, чтобы ты самостоятельно с этим разобрался. Читай MSDN.


PM MAIL WWW   Вверх
Fedia
Дата 5.9.2006, 06:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(bazzzman @  5.9.2006,  06:12 Найти цитируемый пост)
Надо что-то другое? Тогда сформулируй нормально вопрос. 

Вопрос я вроде сформулировал довольно четко:
Цитата(Fedia @  5.9.2006,  04:18 Найти цитируемый пост)
Мне нужно найти хендл активного окна приложения, зная хендл самого приложения. Хендл приложения получаю при его запуске посредством ShellExecute.

Твоя функция возвращает:
Цитата(Fedia @  5.9.2006,  05:33 Найти цитируемый пост)
хендл окна, запустившего приложение.
,
а нужно: хендл активного окна запущенного через ShellExecute приложения. Разница надеюсь понятна ?

Цитата(bazzzman @  5.9.2006,  06:12 Найти цитируемый пост)
Думаю информации и так уже достаточно, чтобы ты самостоятельно с этим разобрался. Читай MSDN.

Как раз разбираюсь. За советы спасибо. Думаю перечисленных в этой ветке функций точно хватит для реализации сабжа.

Цитата(bazzzman @  5.9.2006,  06:12 Найти цитируемый пост)
Значит GetWindowThreadProcessID(hWnd, nil); мы не можем сделать.

А еще спрашиваешь, что не так ...
Значит если запускать приложение посредством ShellExecute, то по результату, возвращаемому этой функцией хендл активного окна запущенного (именно через ShellExecute) приложения не получить ?

Это сообщение отредактировал(а) Fedia - 5.9.2006, 07:17


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 5.9.2006, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  5.9.2006,  05:34 Найти цитируемый пост)
Значит если запускать приложение посредством ShellExecute, то по результату, возвращаемому этой функцией хендл активного окна запущенного (именно через ShellExecute) приложения не получить ?

почему? можно 

Цитата(Fedia @  5.9.2006,  01:48 Найти цитируемый пост)
var
  hApp: Cardinal;
//....
hApp:=ShellExecute(0, 'open', 'C:\text.exe', nil, nil, SW_SHOWNORMAL)

здесь надо заюзать ф-цию 
pid:=GetProcessId(hApp);
дабы поличить пид, а далее юзая
Цитата(dumb @  5.9.2006,  03:32 Найти цитируемый пост)
EnumThreadWindows( pi.dwThreadId, ...

EnumThreadWindows(pid,....

Добавлено @ 10:25 
правда
Код

GetProcessId

Retrieves the process identifier of the specified process.

DWORD WINAPI GetProcessId(
  HANDLE Process
);

Parameters

Process
    [in] A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. 

Return Values

If the function succeeds, the return value is the process identifier of the specified process.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Until a process terminates, its process identifier uniquely identifies it on the system. For more information about access rights, see Process Security and Access Rights.
Requirements
Client    Requires Windows Vista or Windows XP SP1.
Server    Requires Windows Server "Longhorn" or Windows Server 2003.
Header    

Declared in Winbase.h; include Windows.h.
Library    

Use Kernel32.lib.
DLL    Requires Kernel32.dll.



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 5.9.2006, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  5.9.2006,  10:21 Найти цитируемый пост)
pid:=GetProcessId(hApp);

Цитата(Romikgy @  5.9.2006,  10:21 Найти цитируемый пост)
Declared in Winbase.h; include Windows.h.

По этой функции ничего нет в справке Windows SDK. Модуль Winbase также отсутствует. Не могу найти модуль, который необходимо было бы подключить, для использования этой функции.
Кроме того, функция ShellExecute возвращает:
Цитата

return value is the instance handle of the application that was run, or the handle of a dynamic data exchange (DDE) server application.
, а в качестве параметра функция GetProcessId требует:
Цитата

A handle to the process
 Это разве одно и тоже ?
ЗЫ: спасибо, что отвечаешь, хочу таки добить этот вопрос, давно меня волновавший.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 6.9.2006, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  5.9.2006,  22:06 Найти цитируемый пост)
Это разве одно и тоже ?

получается да , т.к. я видел что для получения своего хистенса надо юзать GetModuleHandle с параметром nil (хотя я и не разобрался конкретно что есть этот инстанс smile)
Цитата(Fedia @  5.9.2006,  22:06 Найти цитируемый пост)
По этой функции ничего нет в справке Windows SDK. Модуль Winbase также отсутствует. Не могу найти модуль, который необходимо было бы подключить, для использования этой функции.

А ключевая фраза здесь вот какая
Цитата(Romikgy @  5.9.2006,  09:21 Найти цитируемый пост)
Client    Requires Windows Vista or Windows XP SP1.

ниже ХР СП1 этой фичи нет!
(имхо если этой ф-ции нет то проще будет перечислить все процессы в системе и от них взять хендлы и сравнить с нужным)


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 6.9.2006, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  6.9.2006,  08:45 Найти цитируемый пост)
А ключевая фраза здесь вот какая

Я вообще не придал этой фразе значения, потому, что у меня Windows XP SP2 smile

Цитата(Romikgy @  6.9.2006,  08:45 Найти цитируемый пост)
имхо если этой ф-ции нет то проще будет перечислить все процессы в системе и от них взять хендлы и сравнить с нужным

Ок. Завтра попробую, если время на это будет.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 6.9.2006, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  6.9.2006,  08:07 Найти цитируемый пост)
Я вообще не придал этой фразе значения, потому, что у меня Windows XP SP2

тогда это в кернеле32, есть такая ф-ция, можно динамически открыть ее через лоадлибрари и попросить адрес этой ф-ции


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 11.9.2006, 05:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  6.9.2006,  09:25 Найти цитируемый пост)
тогда это в кернеле32, есть такая ф-ция, можно динамически открыть ее через лоадлибрари и попросить адрес этой ф-ции

Добрался я таки и до этой части. В общем ты частично прав, в библиотеке kernel32.dll есть функция GetProcessId. Правда если в качестве параметра ей передавать результат возвращаемый функцией ShellExecute, то GetProcessId возвращает 0. Следовательно, не такой параметр ей требуется.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 11.9.2006, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Код

DWORD WINAPI GetProcessId(
  HANDLE Process
);

Код

HINSTANCE ShellExecute(

    HWND hwnd,    // handle to parent window
    LPCTSTR lpOperation,    // pointer to string that specifies operation to perform
    LPCTSTR lpFile,    // pointer to filename or folder name string
    LPCTSTR lpParameters,    // pointer to string that specifies executable-file parameters 
    LPCTSTR lpDirectory,    // pointer to string that specifies default directory
    INT nShowCmd    // whether file is shown when opened
   );

GetProcessId требует хендл процесса , а не его хистенс

Добавлено @ 08:56 
http://www.codeproject.com/win32/Remote.asp


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 11.9.2006, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  11.9.2006,  08:49 Найти цитируемый пост)
GetProcessId требует хендл процесса , а не его хистенс

Я же уже подводил к этому smile
Цитата(Romikgy @  6.9.2006,  08:45 Найти цитируемый пост)
Цитата(Fedia @  5.9.2006,  22:06 )    
Это разве одно и тоже ?    

получается да

Или я тебя не понял ?


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 11.9.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



скорее всего smile
Цитата(Romikgy @  11.9.2006,  07:49 Найти цитируемый пост)
http://www.codeproject.com/win32/Remote.asp 

смотрел?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 12.9.2006, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  11.9.2006,  12:59 Найти цитируемый пост)
смотрел?

Посмотрел. Не нашел там прямого указания, как вообще можно использовать HINSTANCE от ShellExecute. Кроме того заинтересовала терминология, озвученная автором статьи. Имеем:
Цитата

- TDB (Thread Database);
- pointer to the Process Database (PDB);
- pointer to the thread object (pTDB);
- process identifier (PID);
- process handle;
- pointer to a process object (PDB);
- thread identifier (TID);

Является ли результат, возвращаемый ShellExecute чем-то из вышеперечисленного ? Мне кажется что нет.

Romikgy, в общем, хватит говорить загадками, колись, что хотел сказать smile


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 12.9.2006, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  12.9.2006,  00:33 Найти цитируемый пост)
хватит говорить загадками, колись, что хотел сказать

Че ?! да ни че просто помочь хотел, а там есть 3 способа получения пида чужего процесса
Код

GetProcessId

GetProcessId() returns the process identifier (PID) of the specified process. It's a convenient way of converting a process handle to the corresponding PID. The Kernel32 function GetProcessId() is only implemented on Win XP or higher. On Windows NT, the semi-documented NTDLL function NtQueryInformationProcess() can be used to emulate GetProcessId():
Collapse

DWORD WINAPI GetProcessIdNT(HANDLE hProcess)
{
    NTSTATUS                  Status;
    PROCESS_BASIC_INFORMATION pbi;
    HANDLE                    hDupHandle;
    HANDLE                    hCurrentProcess;

    hCurrentProcess = GetCurrentProcess();

    // Use DuplicateHandle() to get PROCESS_QUERY_INFORMATION access right
    if (!DuplicateHandle(hCurrentProcess,
                         hProcess,
                         hCurrentProcess,
                         &hDupHandle,
                         PROCESS_QUERY_INFORMATION,
                         FALSE,
                         0))
    {
        SetLastError(ERROR_ACCESS_DENIED);
        return 0;
    }

    Status = NtQueryInformationProcess(hDupHandle,
                                       ProcessBasicInformation,
                                       &pbi,
                                       sizeof(pbi),
                                       NULL);

    CloseHandle(hDupHandle);

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return 0;
    }

    // Return PID
    return pbi.UniqueProcessId;
}

It's advisable to use the DuplicateHandle() function to obtain the PROCESS_QUERY_INFORMATION access right before calling NtQueryInformationProcess() (because the passed hProcess could not have this access right).

In Win9x, a PID is in reality a pointer to a process object (PDB) (actually XORed with a DWORD called "Obfuscator") [for a detailed explanation of the process object and how to obtain a pointer to it, see the GetPDB() function description below; and for an explanation of the meaning of "Obfuscator", see the GetObsfucator() function below]. Using the process handle as an index to the handle table, we retrieve a pointer to the process object. This pointer XORed with the Obfuscator provides the PID.

DWORD GetProcessId9x(HANDLE hProcess)
{
    PPDB           pPDB, pObject;
    PHANDLE_TABLE  pHandleTable;
    int            index;

    // Current PDB
    pPDB = GetPDB();

    // Handle table index
    if (OSWin95)
        index = hProcess;
    else if (OSWin98)
        index = hProcess / 4;

    // Handle table pointer
    pHandleTable = pPDB->pHandleTable;

    // Pointer to process database
    pObject = pHandleTable->array[index].pObject;

    // Return PID
    return pObject ^ dwObsfucator;
}

An alternative method that works for all Windows versions is to call GetCurrentProcessId() in the context of the specified process:

DWORD _GetProcessId(HANDLE hProcess)
{
    HANDLE  hThread;
    DWORD   Pid;

    GetCurrentProcessId = GetProcAddress(GetModuleHandle("Kernel32.dll"),
                                         "GetCurrentProcessId");

    hThread = _CreateRemoteThread(hProcess,
                                  NULL,
                                  0,
                                  (LPTHREAD_START_ROUTINE)GetCurrentProcessId,
                                  NULL,
                                  0,
                                  NULL);
    if (!hThread)
        return 0;
    else
    {
        WaitForSingleObject(hThread, INFINITE);
        // Exit code of remote thread is the PID
        GetExitCodeThread(hThread, &Pid);
        CloseHandle(hThread);
        return Pid;
   }
}

Цитата(Fedia @  12.9.2006,  00:33 Найти цитируемый пост)
Является ли результат, возвращаемый ShellExecute чем-то из вышеперечисленного ? Мне кажется что нет.

ща посмотрю


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Romikgy
Дата 12.9.2006, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  5.9.2006,  01:48 Найти цитируемый пост)
ShellExecute

кса а вместо этого , вот это юзать не?
ShellExecuteEx
Код

WINSHELLAPI BOOL WINAPI ShellExecuteEx(

    LPSHELLEXECUTEINFO lpExecInfo    // pointer to SHELLEXECUTEINFO structure
   );    
 

Parameters

lpExecInfo

Pointer to a SHELLEXECUTEINFO structure that contains and receives information about the application to start. 

Код

typedef struct _SHELLEXECUTEINFO {   // sei  
    DWORD     cbSize; 
    ULONG     fMask; 
    HWND      hwnd; 
    LPCSTR    lpVerb; 
    LPCSTR    lpFile; 
    LPCSTR    lpParameters; 
    LPCSTR    lpDirectory; 
    int       nShow; 
    HINSTANCE hInstApp; 
 
    // Optional members 
    LPVOID lpIDList; 
    LPCSTR lpClass; 
    HKEY   hkeyClass; 
    DWORD  dwHotKey; 
    HANDLE hIcon; 
    HANDLE hProcess; 
} SHELLEXECUTEINFO, FAR *LPSHELLEXECUTEINFO;



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
dumb
Дата 12.9.2006, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



извините, что влезаю: а чем CreateProcess то не угодил? к чему эти шаманские танцы с бубнами?.. user posted image
PM MAIL   Вверх
Fedia
Дата 12.9.2006, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  12.9.2006,  08:54 Найти цитируемый пост)
Че ?! да ни че просто помочь хотел, а там есть 3 способа получения пида чужего процесса

Не просто хотел, а и помогаешь. Я думал, что у тебя уже есть решение задачи, и ты пытаешься натолкнуть меня на какую-то мысль. Так что надеюсь без обид.

Цитата(Romikgy @  12.9.2006,  09:29 Найти цитируемый пост)
кса а вместо этого , вот это юзать не?
ShellExecuteEx

Ну мне ж уже на самом деле dumb предлагал уже использовать CreateProcess. Если бы мне требовалось срочное решение проблемы, я бы этим вариантом воспользовался. А мне лишь хотелось узнать, можно ли использовать результат функции ShellExecute для поиска окон запущенного приложения.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 12.9.2006, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Только у меня не получилось отделить хендл апликейшена smile
Код

function EnumWindowsProc(h: HWND; lp: LPARAM): BOOL; stdcall;
var sx,str: string;

pid,pidreq: DWORD;
begin
  SetLength(sx,300);
    begin
    GetWindowThreadProcessId(h,pid);
    GetWindowText(h,PChar(sx),255);
    if (pid=DWORD(lp)) then
    if  IsWindowEnabled(h) then
      Form1.ListBox1.Items.Add(IntToHex(h,8)+' '+inttostr(pid)+' '+strpas(PChar(sx)));
  end;
  Result:=True;
end;

procedure GetHWND_from_Histance(Hist: HMODULE);
var c1:Cardinal;
pe:TProcessEntry32;
histan: HMODULE;
s1:string;
x:integer;
 begin
 X:=0;
 c1:=CreateToolHelp32Snapshot(TH32CS_SnapProcess,0);
 if c1=INVALID_HANDLE_VALUE then
                begin
                 //Form1.Statusbar1.SimpleText:=('Èíôîðìàöèÿ î ïðîöåññàõ çàêðûòà.');
                exit;
                end;
try
pe.dwSize:=sizeof(pe);
if Process32First(c1,pe) then
repeat
inc(x);
s1:=ExtractFileName(pe.szExeFile);
histan:=GetModuleHandle(PChar(s1));
if  histan= Hist then
begin
 EnumWindows(@ EnumWindowsProc,pe.th32ProcessID);
end;
//ProcessId[x]:=pe.th32ProcessID;
until not Process32Next(c1,pe);
finally CloseHandle(c1); 
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Listbox1.Clear;
 GetHWND_from_Histance(
 GetModuleHandle(nil));
end;



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 13.9.2006, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  12.9.2006,  12:27 Найти цитируемый пост)
Только у меня не получилось отделить хендл апликейшена

Да вообще, то, что называется 
Цитата

instance handle of the application
 в спавке по ShellExecute в SDK или 
Цитата

HINSTANCE for backward compatibility with 16-bit Windows applications
 в MSDN похоже довольно бесполезная штука, созданная для совместимости с 16-bit Windows. И использовать ее скорее всего не получиться.

Romikgy, Спасибо за помощь в рассмотрении этого вопроса  smile 


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 13.9.2006, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Fedia, Имхо я привел код который ищет то что те нужно по хистенсу, или нет?
А 
Цитата(Fedia @  12.9.2006,  23:57 Найти цитируемый пост)
хендл апликейшена

я имел ввиду, не хендл процесса апликейшена , а хендл окна апликейшена!
(я проверял на приложении написаном на дельфи!)
Ведь в этом приложении имеется окно апликухи и главная форма(окно) т.е. 2 окна и как определить какое окно относится к апликухе , а какое к форме , я пока не в курсе, но если знаешь название окна то можно по нему отсеят, тогда вопросов не будет!

Добавлено @ 08:57 
Цитата(Fedia @  12.9.2006,  23:57 Найти цитируемый пост)
Romikgy, Спасибо за помощь в рассмотрении этого вопроса

Пазям.
PS только я так и не понял помогло те это или нет?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 13.9.2006, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  13.9.2006,  08:56 Найти цитируемый пост)
PS только я так и не понял помогло те это или нет?

Нет, просто эта ветка начинает напоминать сломанный телефон. Не исключаю, что я не могу точно сформулировать свой вопрос, возможно ты не можешь меня понять, возможно я не могу понять твои ответы (я ведь только принялся за изучение API). ХЗ в общем.
Цитата

HINSTANCE ShellExecute(          HWND hwnd,
    LPCTSTR lpOperation,
    LPCTSTR lpFile,
    LPCTSTR lpParameters,
    LPCTSTR lpDirectory,
    INT nShowCmd
);

HMODULE GetModuleHandle( 
LPCTSTR lpModuleName
);

Цитата(Romikgy @  13.9.2006,  08:56 Найти цитируемый пост)
я имел ввиду, не хендл процесса апликейшена , а хендл окна апликейшена!

Попробуй в качестве параметра функции GetHWND_from_Histance передать HINSTANCE от ShellExecute, а не HMODULE от GetModuleHandle. Хоть эти два типа и объявлены в Delphi как Саrdinal, но похоже разнятся по смыслу. Может тогда будет понятно, что я пытался реализовать. Ведь именно от HINSTANCE, возвращаемого ShellExecute я пытался получить перечень окон. И неоднократно об этом писал. 
Но все равно, благодаря твоим примерам и ссылкам на статьи я много чего полезного для себя подчеркнул. За это и +.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 13.9.2006, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  13.9.2006,  08:58 Найти цитируемый пост)
Попробуй в качестве параметра функции GetHWND_from_Histance передать HINSTANCE от ShellExecute, а не HMODULE от GetModuleHandle. 

попробую когда домой дойду
а ф-ция ShellExecute у мя где то был исходник , так он юзает GetModuleHandle , найду выложу


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 13.9.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Romikgy @  13.9.2006,  11:38 Найти цитируемый пост)
попробую когда домой дойду

Попробуй конечно.

Цитата(Romikgy @  13.9.2006,  11:38 Найти цитируемый пост)
ShellExecute у мя где то был исходник , так он юзает GetModuleHandle

Результирующие значения этих функций находятся в разном числовом диапазоне. Если HINSTANCE от ShellExecute как правило не больше 1000, то HMODULE от GetModuleHandle переваливает за миллион. А исходник посмотреть интересно было бы.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 13.9.2006, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Код

HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpOperation,LPCSTR lpFile,
                               LPCSTR lpParameters,LPCSTR lpDirectory, INT iShowCmd)
{
    SHELLEXECUTEINFOA sei;

    TRACE("%p,%s,%s,%s,%s,%d\n",
          hWnd, debugstr_a(lpOperation), debugstr_a(lpFile),
          debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);

    sei.cbSize = sizeof(sei);
    sei.fMask = 0;
    sei.hwnd = hWnd;
    sei.lpVerb = lpOperation;
    sei.lpFile = lpFile;
    sei.lpParameters = lpParameters;
    sei.lpDirectory = lpDirectory;
    sei.nShow = iShowCmd;
    sei.lpIDList = 0;
    sei.lpClass = 0;
    sei.hkeyClass = 0;
    sei.dwHotKey = 0;
    sei.hProcess = 0;

    ShellExecuteExA (&sei);
    return sei.hInstApp;
}

Код

BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
{
    SHELLEXECUTEINFOW seiW;
    BOOL ret;
    WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;

    TRACE("%p\n", sei);

    memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));

    if (sei->lpVerb)
    seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);

    if (sei->lpFile)
        seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);

    if (sei->lpParameters)
        seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);

    if (sei->lpDirectory)
        seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);

    if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
        seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
    else
        seiW.lpClass = NULL;

    ret = SHELL_execute( &seiW, SHELL_ExecuteW );

    sei->hInstApp = seiW.hInstApp;

    if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
        sei->hProcess = seiW.hProcess;

    if (wVerb) SHFree(wVerb);
    if (wFile) SHFree(wFile);
    if (wParameters) SHFree(wParameters);
    if (wDirectory) SHFree(wDirectory);
    if (wClass) SHFree(wClass);

    return ret;
}

Код

static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
                LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{
    STARTUPINFOW  startup;
    PROCESS_INFORMATION info;
    UINT_PTR retval = 31;
    UINT gcdret = 0;
    WCHAR curdir[MAX_PATH];

    TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
    /* ShellExecute specifies the command from psei->lpDirectory
     * if present. Not from the current dir as CreateProcess does */
    if( psei->lpDirectory && psei->lpDirectory[0] )
        if( ( gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
            if( !SetCurrentDirectoryW( psei->lpDirectory))
                ERR("cannot set directory %s\n", debugstr_w(psei->lpDirectory));
    ZeroMemory(&startup,sizeof(STARTUPINFOW));
    startup.cb = sizeof(STARTUPINFOW);
    startup.dwFlags = STARTF_USESHOWWINDOW;
    startup.wShowWindow = psei->nShow;
    if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT,
                       env, *psei->lpDirectory? psei->lpDirectory: NULL, &startup, &info))
    {
        /* Give 30 seconds to the app to come up, if desired. Probably only needed
           when starting app immediately before making a DDE connection. */
        if (shWait)
            if (WaitForInputIdle( info.hProcess, 30000 ) == WAIT_FAILED)
                WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
        retval = 33;
        if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
            psei_out->hProcess = info.hProcess;
        else
            CloseHandle( info.hProcess );
        CloseHandle( info.hThread );
    }
    else if ((retval = GetLastError()) >= 32)
    {
        TRACE("CreateProcess returned error %d\n", retval);
        retval = ERROR_BAD_FORMAT;
    }

    TRACE("returning %u\n", retval);

    psei_out->hInstApp = (HINSTANCE)retval;
    if( gcdret )
        if( !SetCurrentDirectoryW( curdir))
            ERR("cannot return to directory %s\n", debugstr_w(curdir));

    return retval;
}


Добавлено @ 23:31 
т.е. в конце все равно приходим к 
Код

if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT,
                       env, *psei->lpDirectory? psei->lpDirectory: NULL, &startup, &info))



--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Yanis
Дата 14.9.2006, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(Romikgy @  14.9.2006,  00:29 Найти цитируемый пост)
т.е. в конце все равно приходим к
Цитата(Romikgy @  14.9.2006,  00:29 Найти цитируемый пост)
CreateProcess


Кто бы сомневался smile

P. S. А вопрос то решён или вы за так ликбез устроили? smile 



--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Romikgy
Дата 14.9.2006, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Yanis @  14.9.2006,  08:29 Найти цитируемый пост)
P. S. А вопрос то решён или вы за так ликбез устроили?

А че? человек спрашает , я отвечаю smile


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Yanis
Дата 14.9.2006, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(Romikgy @  14.9.2006,  11:34 Найти цитируемый пост)
А че? человек спрашает , я отвечаю

Просто интересно стало. Тема досих пор не тонет и вопрос вроде не помечен как решённый.

P. S. Вдруг я тоже хочу поучавствовать smile


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Fedia
Дата 17.9.2006, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Yanis @  14.9.2006,  09:29 Найти цитируемый пост)
P. S. А вопрос то решён или вы за так ликбез устроили?

Оказалось, что вопрос скорее всего не имеет решения smile. Обходные пути есть (CreateProcess, ShellExecuteEx), а напрямую, после ShellExecute, по результатам этой функции получить перечень хэндлов окон запущенного приложения ни как. Таки помечу тему как решенную, дабы не вводить в заблуждение массы  smile



--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 18.9.2006, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Еще одно предложение, напоследок, правда оно не будет иметь отношения к 
Цитата(Fedia @  17.9.2006,  22:57 Найти цитируемый пост)
ShellExecute

им только запускаешь файл,
а потом делаешь снимок всех процессов, и отбираешь те нужный по имени ехе файла, после этого перечисляешь все окна данного процесса и находишь нужно те окно ,и в конце получается и волки  сыты и овцы целы, т.е. юзаешь shellexecute и получаешь хендл окна  smile 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fedia
Дата 18.9.2006, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Romikgy, это решение уже есть в моей копилке. Обсуждалось здесь.  smile 


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Romikgy
Дата 18.9.2006, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Fedia @  17.9.2006,  23:17 Найти цитируемый пост)
это решение уже есть в моей копилке.

ну как знаешь  smile 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Yanis
Дата 18.9.2006, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(Fedia @  18.9.2006,  00:57 Найти цитируемый пост)
Обходные пути есть (CreateProcess, ShellExecuteEx), а напрямую, после ShellExecute, по результатам этой функции получить перечень хэндлов окон запущенного приложения ни как.

Так вот, что требуется то smile Я вот попробовал тут набросать немного кода.
Код
{ стили overlapped окон }
const
  aTrueWndStyles: array[1..6] of DWORD = (WS_OVERLAPPED, WS_POPUP, WS_MINIMIZE,
                                          WS_THICKFRAME, WS_CAPTION, WS_SYSMENU);

function EnumThreadWndProc(hwnd: DWORD; lParam: Integer): Boolean; stdcall;

{ ... }

function GetWindowText(hWnd: HWND): string;
begin
  SetLength(Result, MAX_PATH);
  Windows.GetWindowText(hWnd, Pchar(Result), MAX_PATH);
  Result := StrPas(Pchar(Result));
end;

function EnumThreadWndProc(hwnd: DWORD; lParam: Integer): Boolean; stdcall;
var
  dwWndStyle: DWORD;
  i: Integer;
begin
  Result := True;

  dwWndStyle := GetWindowLong(hwnd, GWL_STYLE);

  { теоретически, если в стиле окна есть хотя бы один из перечисленных флагов, то
    это overlapped окно }

//  if (((dwWndStyle and WS_OVERLAPPED) = WS_OVERLAPPED) or
//    ((dwWndStyle and WS_POPUP) = WS_POPUP) or
//    ((dwWndStyle and WS_MINIMIZE) = WS_MINIMIZE) or
//    ((dwWndStyle and WS_THICKFRAME) = WS_THICKFRAME) or
//    ((dwWndStyle and WS_CAPTION) = WS_CAPTION) or
//    ((dwWndStyle and WS_SYSMENU) = WS_SYSMENU)) and
//    ((dwWndStyle and WS_VISIBLE) = WS_VISIBLE) then

  for i := Low(aTrueWndStyles) to High(aTrueWndStyles) do
    if ((dwWndStyle and aTrueWndStyles[i]) = aTrueWndStyles[i]) and
       ((dwWndStyle and WS_VISIBLE) = WS_VISIBLE) then
        begin
          Form1.ListBox1.Items.Add(GetWindowText(hwnd) + ' - ' + IntToHex(hwnd, 8));
          Break;
        end;
end;

var
  hWnd: DWORD;
  pi: TProcessInformation;
  si: TStartupInfo;
begin
  ZeroMemory(@si, SizeOf(si));
  ZeroMemory(@pi, SizeOf(pi));

  CreateProcess(nil, 'notepad.exe', nil, nil, False, NORMAL_PRIORITY_CLASS, nil,
    nil, si, pi);

  WaitForInputIdle(pi.hProcess, INFINITE);
  Application.MessageBox(PChar('Приступаем к перечислению окон.'+#13#10+
                               'Для продолжения нажмите OK'), nil, MB_ICONWARNING or MB_SYSTEMMODAL);

  EnumThreadWindows(pi.dwThreadId, @EnumThreadWndProc, 0);

  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
end;


При запуске будет выдано окошко с сообщением, что сейчас будут перечислены окна запущенного процесса notepad.exe. Для большей наглядности можно в запустившемся окне Блокнота сначала вызвать окно замены (Ctrl+H) и плюс к этому вызвать пункт меню Открыть. В этом случае будут перечислены 3 дочерних окна (а точнее их текст, полученый через GetWindowText) и их описатели. У меня это выглядит так:
Цитата
Открыть - 00D10DB4
Замена - 00470A1A
Безымянный - Блокнот - 00740AA2

При проверке учитывается тот факт, что окно что бы быть окном должно иметь хотя бы один флаг среди флагов перечисленных в aTrueWndStyles и иметь флаг WS_VISIBLE. 
Код не универсальный и он умеет определять окна только одного потока, ID которого возвращается в pi.dwThreadId. Конечно для универсальности нужно определять окна всех потоков. Для этого придётся немного усложнить код и получить ID всех потоков и уже для каждого вызвать EnumThreadWindows. Получить список всех потоков процесса можно через функцию CreateToolhelp32Snapshot с флагом TH32CS_SNAPTHREAD и далее перечислить их из получившегося снимка при помощи Thread32First & Thread32Next.

P. S. Извиняюсь, если боян smile
P. S. S. Коментарии не писал. Код довольно прозрачный smile

Это сообщение отредактировал(а) Yanis - 18.9.2006, 14:40


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Fedia
Дата 26.9.2006, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



Цитата(Yanis @  14.9.2006,  10:39 Найти цитируемый пост)
Тема досих пор не тонет

Вот и потонула ветка smile. Извиняюсь, что долго не отвечал. Занят был сильно, а этот вопрос у меня совсем не приоритетный. Хороший пример, хоть и не совсем в тему.
А через ShellExecuteEx тоже самое реализовать сможешь ? Я пробовал так:
Код

function EnumWindowsProc(h: HWND; lp: LPARAM): BOOL; stdcall;
var
  sx, str: string;
  pid,pidreq: DWORD;
begin
  SetLength(sx,300);

  GetWindowThreadProcessId(h, pid);
  GetWindowText(h,PChar(sx),255);
  if (pid=DWORD(lp)) then
  if  IsWindowEnabled(h) then
    Form1.ListBox1.Items.Add(IntToHex(h,8)+' '+inttostr(pid)+' '+strpas(PChar(sx)));

  Result:=True;
end;

procedure GetHWND_from_Histance(PId: Cardinal);
var
  c1:Cardinal;
  pe:TProcessEntry32;
  histan: HMODULE;
  s1:string;
  x:integer;
begin
  c1:=CreateToolHelp32Snapshot(TH32CS_SNAPALL, 0);
  if c1=INVALID_HANDLE_VALUE then
  exit;

  try
    pe.dwSize:=sizeof(pe);
    if Process32First(c1, pe) then
    repeat
      if  pe.th32ParentProcessID = PId then
      begin
        EnumWindows(@EnumWindowsProc,pe.th32ProcessID);
        Break;
      end;
    until not Process32Next(c1,pe);
  finally
    CloseHandle(c1);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
type
  TGetPId = function (Process: HWND): DWORD;
var
  SEInfo: TSHELLEXECUTEINFO;
  Ar: TIntegerDynArray;
  TopW: HWND;
  pi: TProcessInformation;
  si: TStartupInfo;
begin
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize:=SizeOf(SEInfo);
  SEInfo.Wnd:=Application.Handle;
  SEInfo.fMask:=SEE_MASK_NOCLOSEPROCESS;
  SEInfo.lpFile:='C:\test.exe';
  SEInfo.nShow:=SW_SHOWNORMAL;
  ShellExecuteEx(@SEInfo);

  GetHWND_from_Histance(SEInfo.hProcess);
end;
, но это пример не работает из-за того, что th32ParentProcessID и hProcess не одно и тоже. А как получить из hProcess - th32ProcessID не знаю.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
dumb
Дата 26.9.2006, 07:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



Fedia, для нормальной работы с хэндлами таки стоит использовать CreateProcess. почему? - вот цитата из MSDN по SHELLEXECUTEINFO.hProcess:
Цитата(MSDN)

hProcess
Handle to the newly started application. This member is set on return and is always NULL unless fMask is set to SEE_MASK_NOCLOSEPROCESS. Even if fMask is set to SEE_MASK_NOCLOSEPROCESS, hProcess will be NULL if no process was launched. For example, if a document to be launched is a URL and an instance of Microsoft Internet Explorer is already running, it will display the document. No new process is launched, and hProcess will be NULL.

Note ShellExecuteEx does not always return an hProcess, even if a process is launched as the result of the call. For example, an hProcess does not return when you use SEE_MASK_INVOKEIDLIST to invoke IContextMenu.

PM MAIL   Вверх
Yanis
Дата 26.9.2006, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(Fedia @  26.9.2006,  01:37 Найти цитируемый пост)
Хороший пример, хоть и не совсем в тему.

Почему? Потому что пример с CreateProcess, а не с ShellExecute(Ex)?
Ну да ладно...

Вобщем тебе выбирать каким способом пользоваться. Проблема
Цитата(Fedia @  26.9.2006,  01:37 Найти цитируемый пост)
А как получить из hProcess - th32ProcessID не знаю.

решается с помощью функции GetProcessId. Присутствует она начиная с XP, поэтому даже в 2000 работать уже не будет.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Fedia
Дата 26.9.2006, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 465
Регистрация: 2.8.2006
Где: первым встречаю р ассвет

Репутация: 1
Всего: 13



dumb, 
Ага, читал я справку MSDN по SHELLEXECUTEINFO. И судя по ней в моих задачах hProcess будет не NULL. А в большей эффективности использования CreateProcess я убедился после того, как стало понятно, что ShellExecute(Ex) все равно вызывают CreateProcess. Поэтому полностью с тобой согласен  smile 

Yanis, 
Цитата(Yanis @  26.9.2006,  09:32 Найти цитируемый пост)
Почему? Потому что пример с CreateProcess, а не с ShellExecute(Ex)?
Ну да ладно...

Нет, вопрос в этой ветке изначально звучал даже уже, и касался он только ShellExecute. Единственно, что мне необходимо было узнать в этой ветке, это то, что результат ShellExecute для решения задачи использовать не получиться. А за твой пример отдельное спасибо.

Цитата(Yanis @  26.9.2006,  09:32 Найти цитируемый пост)
решается с помощью функции GetProcessId.

Ах да, мне же эту функцию Romikgy уже приводил, сорри.


--------------------
Накануне решающей битвы
Я иду, и надеждою зыбкой
Озаряется эта дорога,
Я мечтаю увидеть улыбку
На лице победившего Бога…
PM MAIL ICQ   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1069 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.