Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Как активировать мое приложение после работы другой программы?  (Прочитано 37285 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
jur
Помогающий

lt
Offline Offline

« : 13-09-2013 18:29 » 

Привет!

Пятница 13-го, да еще в 13-м году - это вам не фунт изюму... Очередная напасть обрушилась на мою бедную голову... (Черт! Говорил же шефу, что сегодня нельзя работать!)

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

Как и в предыдущем случае я подумал: "Какие пустяки!" и после завершения внешней программы (я этого ожидаю WaitForSingleObject( pi.hProcess, INFINITE )) вставил строку:

::SetForegroundWindow(hMainWindow);

Нифига. Плоская иконка на таскбаре помигала рыжим цветом, но мое приложение клавиатурного ввода не получило. Ладно. Добавил:

::SetActiveWindow(hMainWindow);

Все осталось по-прежнему. Добавил:

::SetFocus(hMainWindow);

Никакого эффекта. На этом моя фантазия исчерпалась. Помогите пожалуйста!

(задумчиво) Чего этой заразе надобно?!...

P.S. Тут же нажимаю Alt-Tab и преспокойно перехожу в мою программу. Но ведь не посылать же системе эту комбинацию!

P.P.S. Внешнюю программу пишет другой программист, любитель всяких .NET приблуд и кривизн...

« Последнее редактирование: 13-09-2013 18:31 от jur » Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 13-09-2013 18:41 » 

А не пробовал ShowWindow(hMainWindow, SW_SHOW... SW_RESTORE -> флаг зависит от того какое у тебя основное окно
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #2 : 13-09-2013 18:49 » 

Попробовал. Добавил:

::ShowWindow(hMainWindow, SW_SHOW);

Один черт... Еще вспомнил незабвенную "сладкую парочку" ShowWindow/UpdateWindow. Все едино...

Ёлки! Может завтра попробовать?! :-)

« Последнее редактирование: 13-09-2013 21:54 от jur » Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 13-09-2013 20:21 » 

Что-то знакомое... Если вспомню, где у меня такая проблема была - скажу, что я там делал. Но мучался долго -  всё фокус на окно не попадал.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 13-09-2013 23:12 » 

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

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #5 : 14-09-2013 01:04 » 

Так это гадание на кофейной гуще...

Совершенно верно. Вот это меня и удивляет: почему наистандартнейшие функции не выполняют того, что написано в MSDN. Т.е. не делают мою программу нормально активной.

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

Не, без эмоций - никак :-) У меня кроме эмоций уже ничего не осталось... Вот код вызова:

Код:
  if( !CreateProcess(
        NULL,   // No module name (use command line)
        cmd,    // Command line
        NULL,   // Process handle not inheritable
        NULL,   // Thread handle not inheritable
        FALSE,  // Set handle inheritance to FALSE
        0,      // No creation flags
        NULL,   // Use parent's environment block
        NULL,   // Use parent's starting directory
        &si,    // Pointer to STARTUPINFO structure
        &pi )   // Pointer to PROCESS_INFORMATION structure
    )
  {
    DBG_LOG(1,"%s: Bad path: \"%s\"\r\n", module, cmd);
  }
  else {
    // Wait for complete
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    // Grab focus - Вот тут я перепробовал все известные варианты
    ::SetForegroundWindow(hMainWindow);  // Not gets focus
    ::SetActiveWindow(hMainWindow);      // Not gets focus
    ::SetFocus(hMainWindow);
    ::ShowWindow(hMainWindow, SW_SHOWNA);
    ::ShowWindow(hMainWindow, SW_SHOW);
    ::UpdateWindow(hMainWindow);
  }

Командная строка (cmd) элементарная: "ProbeAndApplication.exe". Эта программа написана, как проект CLR в 2010 Студии (исходный код на работе, сейчас недоступен). Программа крайне простая: выбирается датчик сканирования и протокол (список методов измерения). Когда пользователь выберет то, что ему нужно, программа записывает полный путь к файлу пресета в конфигурационный файл State.ini. И все, она закрывается, и WaitForSingleObject возобнавляет выполнение моей программы.

Записан

MPEG-4 - в массы!
zubr
Гость
« Ответ #6 : 14-09-2013 02:32 » 

SetWindowPos HWND_TOPMOST
Только после выполнения необходимых действий с окном желательно вернуть ему прежнее состояние SetWindowPos HWND_NOTOPMOST
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 14-09-2013 04:53 » 

или ещё можно попробовать пару  SW_HIDE - SW_SHOW
Записан

jur
Помогающий

lt
Offline Offline

« Ответ #8 : 14-09-2013 16:49 » 

Попробовал два новых варианта. Первый вариант такой:

SetWindowPos HWND_TOPMOST
Только после выполнения необходимых действий с окном желательно вернуть ему прежнее состояние SetWindowPos HWND_NOTOPMOST
Код:
  else {
    // Wait for complete
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    // Grab focus back
    ::SetWindowPos(hMainWindow, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
    ::SetActiveWindow(hMainWindow);  // OK
  }

Второй вариант такой:

или ещё можно попробовать пару  SW_HIDE - SW_SHOW
Код:
  else {
    ::ShowWindow(hMainWindow, SW_HIDE);

    // Wait for complete
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    // Grab focus back
    ::ShowWindow(hMainWindow, SW_SHOW);
  }

Оба варианта работают! Второй вариант имеет маленький недостаток: сначала окно пропадает, а потом появляется окно другой программы. Не фатально, но неудобно: у нас в приборе не будет десктопа (велено его убрать, также как и вообще все следы Винды). Что получится в результате - пока не знаю.

В первом варианте мне пока не понятно, когда восстанавливать HWND_NOTOPMOST. Пробовал сразу после SetActiveWindow - тогда фокус не приходит. Попробую в главный цикл обработки сообщений воткнуть.

А так вообще здорово! Чувствуется приближение скорой победы :-)

P.S. Получилось! Вставил восстановление HWND_NOTOPMOST в главный цикл обработки сообщений моего приложения. В моем случае это совсем просто, т.к. после отработки внешней программы я всегда посылаю главному окну команду спрятать курсор мыши.

« Последнее редактирование: 14-09-2013 17:00 от jur » Записан

MPEG-4 - в массы!
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 14-09-2013 16:55 » 

>>Второй вариант имеет маленький недостаток: сначала окно пропадает,
ну да, так и будет - моргнёт один раз

>>В первом варианте мне пока не понятно, когда восстанавливать HWND_NOTOPMOST
можно попробовать в WM_SETFOCUS

>>Попробую в главный цикл обработки сообщений воткнуть.
либо сделать это в idle блоке окна, если есть такая возможность
Записан

jur
Помогающий

lt
Offline Offline

« Ответ #10 : 14-09-2013 17:05 » 

>>Второй вариант имеет маленький недостаток: сначала окно пропадает,
ну да, так и будет - моргнёт один раз

Некузяво :-) Какой-нить въедливый пользователь обязательно на это укажет...

>>В первом варианте мне пока не понятно, когда восстанавливать HWND_NOTOPMOST
можно попробовать в WM_SETFOCUS
>>Попробую в главный цикл обработки сообщений воткнуть.
либо сделать это в idle блоке окна, если есть такая возможность

Да, нашел подходящее решение: я после отработки внешней программы всегда посылаю главному окну команду спрятать курсор мыши. Вот в его обработчик и вставил. Работает.

Большое спасибо за помощь, друзья!

Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 14-09-2013 22:23 » 

Не, без эмоций - никак Улыбаюсь У меня кроме эмоций уже ничего не осталось...

Так не, ты не понял. Если не можешь без эмоций, нууу дык... Не возбраняется. Но вот какая получается штука. Смотри, я беру и в первом попавшемся под руку диалоге (с которым я сейчас работаю) я вставляю код запуска другого приложения c ожиданием и последующим активированием. И... всё работает. У тебя - нет. Значит разница в деталях. С какими параметрами создаётся твоё окно. В какой момент происходит вызов другого приложения (может ты его в OnInitDialog вызываешь), чем твоё приложение в этот момент занимается - может нужна "асинхронизация". С какими параметрами создаётся окно другого приложения (тот же самый TOPMOST). И тд. Это уже даст почву для размышлений. А иначе, с одними только эмоциями - гадание на кофейной гуще.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 15-09-2013 10:23 » 

Джон, ну и посочувствуй - не развалишься же Ага Не всем нужны ответы, некоторым достаточно моральной поддержки Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 15-09-2013 18:29 » 

Нууу дык, если бы одно только сочуствие помогало... Улыбаюсь
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #14 : 16-09-2013 08:53 » 


Нууу дык, если бы одно только сочуствие помогало... :)

За сочуствие - огромное спасибо! Тем более, что оно мне еще не раз понадобится :-)

Понедельник. Этим все сказано... Как я уже писал, все заработало. Но... Только первый раз :-) При втором вызове внешней программы - снова фокуса нема.

Значит разница в деталях. С какими параметрами создаётся твоё окно. В какой момент происходит вызов другого приложения (может ты его в OnInitDialog вызываешь), чем твоё приложение в этот момент занимается - может нужна "асинхронизация". С какими параметрами создаётся окно другого приложения (тот же самый TOPMOST). И тд. Это уже даст почву для размышлений. А иначе, с одними только эмоциями - гадание на кофейной гуще.

Да, полностью согласен. Значит так. Моя головная программа написана как простое Dialog based MFC-приложение. Никакой экзотики, все предельно стандартно и максимально просто. При нажатии пользователем нашей спец-клавиши (например, клавиши "PROBE" для выбора рабочего датчика) в цикл обработки сообщений поступает соответствующая команда (с кодом WM_USER+3). Она перенаправляется так:

  ON_MESSAGE(WM_SCUSB_KEY_PRESS, OnSleKeyPress)

В функции обработки (т.е. в OnSleKeyPress) оператор case выбирает действие: вызывается функция Preset_key(). Эта функция запускает внешнюю программу так: Start_process("ProbeAndApplication.exe"); Вот эта самая Start_process и запускает внешнюю программу, завершения которой я жду с помощью WaitForSingleObject( pi.hProcess, INFINITE ). Эта внешняя программа написана как CLR-приложение, вроде использует TOPMOST. (Но ведь когда она завершается, этот TOPMOST перестает действовать, верно? К тому же, первый раз все отрабатывает нормально.)

Далее происходит возврат из цепочки функций и OnSleKeyPress работу завершает. Головная программа возвращается обратно в цикл обработки сообщений.

Что там происходит с этими окнами - непонятно...

Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 16-09-2013 11:27 » 

Мне так кажется ты запутал свою программу в сообщениях. Что у тебя с очередью творится непонятно. Одно вызвает другое, оно ещё не отработало, но уже вызывает третье...

Давай с простого. Вот есть у тебя кнопка IDOK, если в её обработчике процесс запускаешь, всё нормально?

Код: (C++)
void CWndStarterDlgDlg::OnBnClickedOk()
{
        BOOL bOk = FALSE;

        CString stExternApp = GetModulePath() + _T("TestdotNETWnd.exe");
        CPath externAppPath(stExternApp);
        if(externAppPath.FileExists())
        {
                STARTUPINFO si;
                PROCESS_INFORMATION pi;
                ZeroMemory(&si, sizeof(si));
                si.cb = sizeof(si);
                ZeroMemory(&pi, sizeof(pi));
                bOk = ::CreateProcess(NULL, (LPTSTR)stExternApp.GetBuffer(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

                if(!bOk)
                {
                        CString stMsg;
                        stMsg.Format(_T("CreateProcess failed: %s, Last SystemError: %d"), stExternApp, ::GetLastError());
                        AfxMessageBox(stMsg);
                }
                else
                {
                        GetDlgItem(IDOK)->EnableWindow(FALSE);
                        // Wait for complete
                        WaitForSingleObject( pi.hProcess, INFINITE );

                        // Close process and thread handles
                        CloseHandle( pi.hProcess );
                        CloseHandle( pi.hThread );

                        ::SetForegroundWindow(this->GetSafeHwnd());  // Not gets focus
                        ::SetActiveWindow(this->GetSafeHwnd());      // Not gets focus
                        ::SetFocus(this->GetSafeHwnd());
                        ::ShowWindow(this->GetSafeHwnd(), SW_SHOW);
                        ::UpdateWindow(this->GetSafeHwnd());

                        GetDlgItem(IDOK)->EnableWindow(TRUE);
                }
        }
        else
        {
                CString stMsg;
                stMsg.Format(_T("File not exist: %s"), stExternApp);
                AfxMessageBox(stMsg);
        }
       
}

ps В примере создаётся процесс с .NET окном TopMost

ps ps Пойдём дальше

Я так думаю, что тебе надо восстановление окна делать после ЭТОГО
Далее происходит возврат из цепочки функций и OnSleKeyPress работу завершает. Головная программа возвращается обратно в цикл обработки сообщений.
а не ВНУТРИ.

* TestdotNETWnd.zip (143.49 Кб - загружено 731 раз.)
« Последнее редактирование: 16-09-2013 11:35 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #16 : 17-09-2013 11:14 » 

Мне так кажется ты запутал свою программу в сообщениях. Что у тебя с очередью творится непонятно. Одно вызвает другое, оно ещё не отработало, но уже вызывает третье...

Не, не запутал :-) У меня там посылается одно единственное сообщение: включить/выключить курсор. Т.е. включаем курсор, запускаем внешнюю программу, ждем ее завершения, выключаем курсор.

Давай с простого. Вот есть у тебя кнопка IDOK, если в её обработчике процесс запускаешь, всё нормально?

Фактически у меня так и есть, только не по кнопке IDOK, а по моей приборной кнопке.

ps В примере создаётся процесс с .NET окном TopMost

На обе программы из TestdotNETWnd.zip коммандер пишет: "Is not a valid Win32 application". И перекомпилировать не могу, т.к. они из-под 12-й Студии, а у меня 2008.

Я так думаю, что тебе надо восстановление окна делать после ЭТОГО
Далее происходит возврат из цепочки функций и OnSleKeyPress работу завершает. Головная программа возвращается обратно в цикл обработки сообщений.
а не ВНУТРИ.

Сначала у меня было точно так же, как в твоем примере, т.е. внутри обработки нажатия кнопки. Потом я сделал по таймеру (у меня есть 100 ms таймер), по одной команде за раз, т.к. думал, может обработка очереди должна происходить. Нифига, не пашет...

Портит всю малину следующий порядок действий:

1. Запускаем наше приложение. Подразумеваем, что запущено еще что-нибудь, например коммандер.
2. Из нашего приложения запускаем внешнюю программу.
3. Делаем такой финт: кликаем в таскбаре на коммандере, а потом обратно на внешней программе. Т.о. коммандер становится вторым после внешней программы.
4. Закрываем внешнюю программу. В этом месте у меня становится активным коммандер, а не моя программа. Несмотря на все мои безплодные усилия... :-)

Не мог бы ты повторить эти действия на своем компе, с использованием этих двух тестовых программ из архива?

P.S. Нашел компьютер с 64-битами, попробовал твой тестовай пример. Не работает точно так же, как и мои программы... Т.е. внешняя программа возвращается к последней активной программе, а не к моей, чего я упорно добиваюсь.

« Последнее редактирование: 17-09-2013 11:28 от jur » Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 17-09-2013 12:07 » 

Да, я компильнул MFC без поддержки XРюши, поэтому пишет что "Is not a valid Win32 application" ну и ещё будет требовать 11-ю MFC библиотеку, а иначе прицеп большой получается (больше допустимого). А dotNET прога на версии 4.5. К сожалению ща под рукой ничего меньше 12-ой студии нет. Но собственно там нет ничего сложного, можно и на 2008 повторить: для .NET любое (стандартное из мастера) окно с TopMost; + MFC Dialog тоже стандартный из мастера в нём одна единственная ф-я обработки OnOk, ну я ещё добавил пару ф-ций для нахождения внешней EXE для запуска - она у меня лежит там же, где и MFC Dialog.

Не мог бы ты повторить эти действия на своем компе, с использованием этих двух тестовых программ из архива?

Ща попробую твой сценарий...

Ок, попробовал. Всё как ты описываешь. Один в один. Ща посмотрим.

Добавлено через 13 минут и 19 секунд:
Ок, у окошек приложений есть тн z-order, и похоже по такому сценарию этот порядок нарушается так, что простой SetForegroundWindow уже не хватает. Видимо ребята из мелкософта это знают и поэтому у них есть хитрый приёмчик - ф-я
SwitchToThisWindow. Вот так работает даже с "твоим сценарием":

Код: (C++)
...
else
{
    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    ::SwitchToThisWindow(this->GetSafeHwnd(), FALSE);
    ::SetFocus(this->GetSafeHwnd());
}

Ну, исключение конечно составляют приложения, которые открывают в промежутке свои окна с TopMost. Тогда тебе остаётся только свой диалог с TopMost восстанавливать.


Добавлено через 20 минут и 59 секунд:
Проект закинул сюда
http://www.sendspace.com/file/p5mgf2

MFC компильнул статиком и для ХРюши, .NET 3.5 (кажется у 2008 студии эта версия?) теперь должно работать.

линк для удаления с sendspace
http://www.sendspace.com/delete/p5mgf2/8e8063fc590c07d0671220cbdcec822b
(чтобы не забыть)

Добавлено через 9 минут и 35 секунд:
А, да совсем забыл предупредить. Ф-ю SwitchToThisWindow ребята похоже сделали для себя, и не рекомендуют её использовать. Но я так понял, что вы загоняете винду в свой приборчик просто как ОСь, и никто её не будет, например, на 8-ку апгрейдить. Или? Ну, во всяком случае проверяй, всё ли она ещё доступна. Пока требования начиная с w2k ну, а что дальше будет...
« Последнее редактирование: 17-09-2013 13:07 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #18 : 17-09-2013 19:28 » 

Ок, у окошек приложений есть тн z-order, и похоже по такому сценарию этот порядок нарушается так, что простой SetForegroundWindow уже не хватает. Видимо ребята из мелкософта это знают и поэтому у них есть хитрый приёмчик - ф-я SwitchToThisWindow. Вот так работает даже с "твоим сценарием":

Точно, работает! Класс! :-)

Ёлки! Я-же эту функцию пробовал, но в другой "паре":

   SwitchToThisWindow(GetSafeHwnd(), TRUE);
   SetActiveWindow();

а надо было второй поставить SetFocus :-)

Причем, у меня постоянно запущен Task Manager, в режиме Always On Top. Так теперь моя программа даже сквозь него прорывается! Ее окно, конечно, остается за Таск Мэнеджером, но фокус ввода она получает! И ее иконка на таскбаре активизирована, и клавиатура с мышой работают как надо. (Наши спец-органы управления и так работают, т.к. поступают по отдельному каналу, но мне было важно, чтобы стандартные клавиатура с мышью (у нас установлен трэкбол) тоже работали.)

Люкс! :-)

Большое спасибо за помощь!

« Последнее редактирование: 17-09-2013 19:31 от jur » Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #19 : 18-09-2013 07:26 » 

У меня получилось без SetFocus, что оно "вылезает", но без фокуса.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #20 : 23-09-2013 12:51 » 


У меня получилось без SetFocus, что оно "вылезает", но без фокуса.

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

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

Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #21 : 23-09-2013 13:11 » 

Это было к:
а надо было второй поставить SetFocus Улыбаюсь
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #22 : 26-09-2013 18:34 » 


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

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

Записан

MPEG-4 - в массы!
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #23 : 26-09-2013 18:41 » 

jur, Билли уже давно ничего не мудрит, он на пенсию отошел наверно лет так 7 назад. Для этого есть Стиви. http://www.youtube.com/watch?v=KMU0tzLwhbE
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
jur
Помогающий

lt
Offline Offline

« Ответ #24 : 26-09-2013 19:05 » 


jur, Билли уже давно ничего не мудрит, он на пенсию отошел наверно лет так 7 назад. Для этого есть Стиви. http://www.youtube.com/watch?v=KMU0tzLwhbE

Билли на пенсию отошел, но аура-то его зловредная осталась! :-) А наивреднейшего Стиви, есть надежда, скоро попрут нечистыми тряпками! :-)

Записан

MPEG-4 - в массы!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 27-09-2013 12:59 » 

jur, ну а как ты себе это представляешь в самом общем случае, с кучей окон? А если какая-нить другая прога тоже захочет быть "первой"? Ведь top most мы убрали.

щы тут даже дело не стиле, а скорее в тайминге. Попробуй чисто тупо, после получения окном сообщения "будь первым", запусти таймер, в котором проверяй, является ли твоё окно "первым" и имеет ли оно фокус. Если нет, то соответственно... принимай меры, пока оно таким не станет. Нехорошо, конечно, по отношению к другим прогам, но если сильно хочется, то как известно - можно. Ага
« Последнее редактирование: 27-09-2013 13:02 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #26 : 27-09-2013 14:25 » 


По таймеру я пробовал уже... Тут вот какое дело. Если я кликну на окне моей программы, когда она не имеет фокуса, то она становится активной и фокус получает. Логически рассуждая, должна быть возможность сделать то же самое программно. Но не всегда получается...

У меня такое чувство, что правильное срабатывание операции получения фокуса зависит от погоды в Африке :-) Сегодня на работе целый день сталкивался с периодическим неполучением фокуса. Сейчас пришел домой, распаковал свой рабочий архив, запускаю мою программу - фокус получает! Даже если запущен Task Manager в режиме "всегда первый", и даже когда он не минимизирован. Что за дела?... Придется пока "забить" :-) Ждут дела поважнее: вставление в мою программу LUA :-)

Записан

MPEG-4 - в массы!
zubr
Гость
« Ответ #27 : 27-09-2013 15:49 » 

А зачем вообще все эти танцы с бубном?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 27-09-2013 16:34 » 

zubr, чтоб когда отработает дочка, родитель получал фокус назад, и пользователь продолжал бы работу без лишнего телодвижения.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zubr
Гость
« Ответ #29 : 27-09-2013 19:05 » 

Тогда самое тупое простое, но имхо действенное решение:
1. Выводим окно в топ (SwitchToThisWindow или SetWindowPos HWND_TOPMOST)
2. Определяем экранные координаты окна в которое надо вставить фокус (FindWindowEx, ClientToScreen)
3. Делаем клик в окно
      mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
      mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, x, y, 0, 0);
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines