Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Отобразить окно и сделать его активным


Автор: artsb 19.12.2009, 19:50
Всем привет!

Никак не могу сделать окно активным. Пробовал ShowWindow, BringWindowToTop, SetActiveWindow, SetWindowPos, Send(Post)Message. Всё одно - окно разворачивается но не становится активным, а остаётся под текущим окном. Уже не знаю что делать.
Все танцы с бубном происходят под Vista'ой.

Автор: 586 19.12.2009, 21:16
Есть ещё SetForegroundWindow. smile

Автор: artsb 20.12.2009, 12:23
586, спс. Испробую.

Автор: artsb 20.12.2009, 13:50
Помогло! Спасибо 586.
Осталась единственная проблема, о которой я не упомянул сразу.
Если окно было в свёрнутом состоянии, то после того как оно развернётся, перестаёт работать кнопка свернуть. Она подсвечивается и нажимается, но толку от этого никакого (тоже самое с пунктом системного меню). Причем само приложение работает отлично и остальные системные кнопки тоже. Если нажать на кнопку приложения на панели задач, происходит анимация развёртывания окна (?!) и кнопка свернуть начинает работать нормально.
Что это за ерунда и как это можно вылечить?

ЗЫ окно разворачиваю так:
Код

ShowWindow(window, SW_SHOW);

Со всеми остальными флагами та же песня.

Автор: 586 20.12.2009, 15:38
А если так:
Код
ShowWindow(Application->Handle, SW_RESTORE);


Можно ещё окно приложения восстановить классическим для VCL способом, но не знаю, как это будет работать в висте:
Код
Application->Restore();

Автор: artsb 20.12.2009, 15:56
586, так окно "не моё". Я его ищу через FindWindow.
Я, вообще, делаю так, чтобы при запуске второго экземпляра моей программы, открывалось окно первой, а не запускалась вторая копия. Так что, ту можно воспользоваться и сообщениями. Но если можно обойти предыдущий косяк, то нет смысла извращаться.

Автор: THandle 20.12.2009, 16:04
artsb, хмм... как то странно... Я бы сделал так:

Окошком приложения обрабатываем некое наше сообщение. В нем один из параметров я бы задействовал под передачу строки. (LPARAM пусть будет).
Ну и в этом же сообщении разворачиваем свое окно.

Когда запускается новая копия то, если находим старую - отправляем окошку сообщение(в LPARAM засунуть командную строку. если у тебя конечно в ней что то ценное бывает) и завершаемся.

Как то так наверное.

Автор: artsb 20.12.2009, 16:20
THandle, я этот вариант тоже рассматривал. Если ничего исправить не получится, буду реализовывать его.

Автор: artsb 22.12.2009, 14:56
Использование сообщений не помогло...
Обработчик сообщения:
Код

TForm *frm;
// проверяю какое окно сейчас активно: дочернее или основное

// разворачиваю окно

SetForegroundWindow(frm->Handle);

Вместо строки "// разворачиваю окно" пробовал много чего, но помогло только:
Код

ShowWindow(frm->Handle, SW_SHOW);

И опять теже проблемы с кнопкой свернуть  smile 

Автор: THandle 22.12.2009, 15:02
artsb, выложи тестовый пример поного твоего случая smile

Автор: artsb 22.12.2009, 15:57
Вот тестовый проект. Абсолютно голый. Та же беда.

ЗЫ если проект открыт в билдере и окно запущенного приложения свёрнуто, то FindWindow находит окно из проекта smile Может показаться, что код не работает. Поэтому для тестирования я закрывал проект полностью.

ЗЗЫ Под Win7 та же беда. Мне кажется, версия билдера роли тут не играет это же WinAPI...

Автор: shklowsky 23.12.2009, 02:09
http://forum.sources.ru/index.php?showtopic=284009

Автор: artsb 23.12.2009, 09:54
shklowsky, спасибо. Помогло.
Кстати, я тоже баловался с кнопкой приложения. Но нужно было юзать флаг SW_SHOWNORMAL, а я использовал SW_SHOW.
Код

 ShowWindow(Application->Handle, SW_SHOWNORMAL);
 ShowWindow(frm->Handle, SW_SHOW);
 SetForegroundWindow(frm->Handle);

В висте отлично работает, а вот в вин7 не хочет выдвигать окно вперёд, просто кнопка приложения мигает и всё. Но это мелочи.

Автор: artsb 25.12.2009, 14:36
Полазил на сайте MSDN и некоторых зарубежных сайтах и решил проблему!
Вся беда в том, что функция SetForegroundWindow и ей подобные корректно отрабатывают только из активного процесса. А у меня была ситуация, что я отправляю сообщение из активного приложения в неактивное и уже из него пытаюсь "выдвинуть" окно. И если в Висте это прокатывало, то Win7 здесь будет по строже smile
В общем, вот:
Код

SetLastError(0);
if(!CreateMutex(NULL, true, "CarInsurance"))
 return 1;
else if(GetLastError() == ERROR_ALREADY_EXISTS) {
 void *window;
 window = FindWindow("TMainForm", NULL);
 if(window && (window = GetWindow(window, GW_OWNER))) {
  ShowWindow(window, SW_SHOWNORMAL);
  SetForegroundWindow(window);
  return 1;
 }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)