Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2011, 22:08   #1
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
Сообщение Получение дескриптора окна по данным процесса/потока.

Всем доброго времени суток! Есть такая задача: Получить дескриптор окна приложения, запускаемого через CreateProcess(). После запуска имеем данные: Дескриптор процесса/потока, ID процесса/потока. Как по этим данным сделать задуманное, простым и надёжным способом? ЗЫ: FindWindow() не предлогать.

Реализовал это через EnumThreadWindows().

Код:
#include <windows.h>
#include <stdio.h>

INT nCount = 0;
HWND hWnd;

BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam)
{
    // Считаем количество вызовов функции.
    nCount++;

    hWnd = hwnd;

    return FALSE;
}

INT main(INT argc, LPCSTR argv[])
{
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));

    si.cb = sizeof(si);

    // Запускаем консольное приложение.
    CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE, NULL, "C:\\Windows\\System32", &si, &pi);

    // Ждем 2 секунды для гарантированного появления окна.
    Sleep(2000);

    // Перечисляем окна принадлежащие потоку.
    EnumThreadWindows(pi.dwThreadId, (WNDENUMPROC)EnumThreadWndProc, 0);

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

    // Выводим количество вызовов функции EnumThreadWndProc.
    printf("%d\n", nCount);

    ShowWindow(hWnd, SW_HIDE);

    printf("Wait for 5 seconds...");
    Sleep(5000);

    ShowWindow(hWnd, SW_SHOW);

    return 0;
}
Если запускаю блокнот, то всё работает - функция обратного вызова вызывается и я получаю дескриптор окна. Если запускаю консольное приложение то функция не вызывается. В чем может быть дело?
StIX-S вне форума Ответить с цитированием
Старый 06.07.2011, 22:14   #2
_Engine_
Форумчанин
 
Регистрация: 29.06.2008
Сообщений: 603
По умолчанию

для консольных приложений есть GetConsoleWindow
_Engine_ вне форума Ответить с цитированием
Старый 06.07.2011, 22:33   #3
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
Сообщение

Вы меня наверно не правильно поняли. Есть некое приложение, которое я запускаю из своего приложения. Мне нужно получить дескриптор окна дочернего процесса, т.е не моего приложения, а которое я запустил из своего.
StIX-S вне форума Ответить с цитированием
Старый 06.07.2011, 23:04   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

PID процесса вам должен быть тогда известен.
делаете банальный EnumWindows по верхним окнам и сравниваете принадлежит ли это окно нужному процессу.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.07.2011, 23:15   #5
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
Сообщение

Ладно, я подумаю насчет этого варианта, хотя мне кажется, что FindWindow() внутри себя вызывает тот же EnumWindows() а затем сравнивает заголовок окна с искомым. Как то не очень Интересно, почему мой вариант то не хочет работать...
StIX-S вне форума Ответить с цитированием
Старый 06.07.2011, 23:31   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ошибка в функции для перечисления, она должна возвращать true чтоб продолжить перечислять окна.
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
кстати попробуйте всетаки по процессу, консольное окно может не принадлежать основному потоку приложения.(или там хитрость с запуском)

те функции используют http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 07.07.2011, 00:06   #7
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
По умолчанию

С TRUE уже пробовал, это ничего не дает. Если не консольное приложение то достаточно 1 вызова этой функции, поэтому поставил FALSE. Передал pi.dwProcessId в EnumThreadWindows() всёравно не работает. Попробую ваш метод с EnumWindows().
StIX-S вне форума Ответить с цитированием
Старый 07.07.2011, 02:13   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Передал pi.dwProcessId в EnumThreadWindows() всёравно не работает.
да как бы и не должно
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 07.07.2011, 05:21   #9
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
Сообщение

Сделал как Вы посоветовали.

Код:
#include <windows.h>
#include <stdio.h>

HWND g_hWnd;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    DWORD dwPID;
    GetWindowThreadProcessId(hwnd, &dwPID);

    if (dwPID == (DWORD)lParam)
    {
        g_hWnd = hwnd;

        return FALSE;
    }

    return TRUE;
}

INT main(INT argc, LPCSTR argv[])
{
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));

    si.cb = sizeof(si);

    // Запускаем консольное приложение.
    CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE, NULL, "C:\\Windows\\System32", &si, &pi);

    // Ждем 2 секунды для гарантированного появления окна.
    Sleep(2000);

    EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)pi.dwProcessId);

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

    ShowWindow(g_hWnd, SW_HIDE);

    printf("Wait for 5 seconds...");
    Sleep(5000);

    ShowWindow(g_hWnd, SW_SHOW);

    return 0;
}
Метод работает на ура спасибо
StIX-S вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ожидание создания окна после запуска процесса Аникейка Общие вопросы Delphi 3 26.01.2011 03:45
хэндл окна по PID процесса? Johnson Win Api 1 16.12.2010 16:05
Получение имени процесса по его ID Johnson Общие вопросы Delphi 6 07.11.2009 21:55
Получение адресса по имени процесса (Delphi) dyonysos Помощь студентам 5 14.09.2009 16:55