Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема со свёрнутой формой

2.5K
18 августа 2003 года
VladСD
24 / / 20.04.2003
У меня в программе в определённый момент по таймеру выполняются некоторые действия и совершенно необходимо, чтобы окно в этот момент восстановилось, если пользователь его свернул (программой удобнее пользоваться, если пользователь после установки времени срабатывания сворачивает её). Попытка обрабатывать WM_SYSCOMMAND не помогла, потому что при этом не отслеживается сворачивание формы щелчком левой кнопки мыши по значку в панели задач.
:(
3
18 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by VladСD
У меня в программе в определённый момент по таймеру выполняются некоторые действия и совершенно необходимо, чтобы окно в этот момент восстановилось, если пользователь его свернул (программой удобнее пользоваться, если пользователь после установки времени срабатывания сворачивает её). Попытка обрабатывать WM_SYSCOMMAND не помогла, потому что при этом не отслеживается сворачивание формы щелчком левой кнопки мыши по значку в панели задач.
:(



Причем тут WM_SYSCOMMAND?
Сворачивание можно отследить с помощью WM_SIZE.
Только тебе это, видимо, не надо. Если ты хочешь просто восстанавливать (разворачивать свернутое окно), то надо использовать ShowWindow.

401
19 августа 2003 года
Br@in RIPper
289 / / 15.02.2003
Цитата:
Originally posted by Green


Причем тут WM_SYSCOMMAND?
Сворачивание можно отследить с помощью WM_SIZE.
Только тебе это, видимо, не надо. Если ты хочешь просто восстанавливать (разворачивать свернутое окно), то надо использовать ShowWindow.



В Win версии, по-моему, с 98, есть такая фишка: prevent from stealing focus. то есть если развернуть окно при помощи ShowWindow, то оно не будет активным а ее значек в панели "Пуск" будет мигать. Никакие SetActiveWindow и ей подобные не помогут. Отключить сию фичу можно где-то в реестре или при помощи спец программ (вроде TweakUI) или так:
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE);


SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001

429
19 августа 2003 года
Slon
78 / / 20.01.2000
Цитата:
то есть если развернуть окно при помощи ShowWindow, то оно не будет активным а ее значек в панели "Пуск" будет мигать. Никакие SetActiveWindow и ей подобные не помогут.



Когда я с этим столкнулся, то разворачивал и активизировал окно из dll.

401
19 августа 2003 года
Br@in RIPper
289 / / 15.02.2003
Цитата:
Originally posted by Slon
Когда я с этим столкнулся, то разворачивал и активизировал окно из dll.


ну и что, помогло?

2.5K
19 августа 2003 года
VladСD
24 / / 20.04.2003
Цитата:
Originally posted by VladСD
У меня в программе в определённый момент по таймеру выполняются некоторые действия и совершенно необходимо, чтобы окно в этот момент восстановилось, если пользователь его свернул (программой удобнее пользоваться, если пользователь после установки времени срабатывания сворачивает её). Попытка обрабатывать WM_SYSCOMMAND не помогла, потому что при этом не отслеживается сворачивание формы щелчком левой кнопки мыши по значку в панели задач.
:(


Всем большое спаибо, но задачу сам решил: в нужном месте вставил

 
Код:
Application->Restore();
- и всё прекрасно работает и не надо ничего отслеживать.
:D
429
20 августа 2003 года
Slon
78 / / 20.01.2000
Цитата:
Originally posted by Br@in RIPper

ну и что, помогло?



Да, помогло.
У меня окно, за которым нужно было следить, было не главным. С главным можно и без dll обойтись.

3
20 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Slon

Да, помогло.
У меня окно, за которым нужно было следить, было не главным. С главным можно и без dll обойтись.



Ребята, Вы что-то путаете...
В Windows нет деления окон на главные и неглавные. Есть только родительские и дочерние.
И при чем тут DLL? Это какая-то специальная DLL? Тогда укажите её название, интересно. А если это просто перенесение части кода из своего exe в свою же dll, то это просто бред.
Может, вы имели в виду Foreground и Background Windows, но тогда там все несколько иначе.

429
20 августа 2003 года
Slon
78 / / 20.01.2000
Цитата:
Originally posted by Green

Ребята, Вы что-то путаете...
В Windows нет деления окон на главные и неглавные. Есть только родительские и дочерние.


Согласен. Все эти названия пошли вероятно от того, что в билдере есть понятие "Main form".

Цитата:

И при чем тут DLL? Это какая-то специальная DLL? Тогда укажите её название, интересно. А если это просто перенесение части кода из своего exe в свою же dll, то это просто бред.


Почему?

Цитата:

Может, вы имели в виду Foreground и Background Windows, но тогда там все несколько иначе.


Вот что я имел в виду (две страницы).

3
20 августа 2003 года
Green
4.8K / / 20.01.2000



М-да, так я и не понял, что это за волшебная DLL.
Хук ставиться, что ли? Не понятно, зачем? Хотя, тогда понятно, зачем DLL.

Думаю, раз "С главным можно и без dll обойтись", то это очередной баг/фича от Борланда, поздравляю! :D

Посмотрел свои проекты, я использую такой алгоритм:

 
Код:
SetForegroundWindow(hWnd);
OpenIcon(hWnd);


Так что это за волшебная DLL такая?
429
20 августа 2003 года
Slon
78 / / 20.01.2000
Цитата:
Originally posted by Green


М-да, так я и не понял, что это за волшебная DLL.
Хук ставиться, что ли? Не понятно, зачем? Хотя, тогда понятно, зачем DLL.
Так что это за волшебная DLL такая?



Ничего волшебного. И хука нет. Просто в ней по таймеру идёт проверка, минимизировано ли окно. И если да, то вызываются ShowWindow() и SetForegroundWindow().
Думаю, и без таймера можно обойтись. Просто вызывать из оконной процедуры ф-цию, реализованную в dll. Надо будет попробывать.

Код:
//------------------------------------------------
#include <windows.h>
#pragma hdrstop

#define __BUILDING_THE_DLL
int TimerID = 0; //идентификатор таймера
HWND hWindow; //хэндл окна программы
//------------------------------------------------
#pragma argsused

//------------------------------------------------
// Включение таймера
//------------------------------------------------
void WINAPI DoNotMinimized(HWND hWind)
{
if(!TimerID)
  {
  hWindow = hWind;
  TimerID = timeSetEvent(200, 1, TimerProc, NULL, TIME_PERIODIC);
  }
}

//------------------------------------------------
//  Выключение таймера
//------------------------------------------------
void WINAPI AllowMinimized()
{
if(TimerID)
  {
  timeKillEvent(TimerID);
  TimerID = 0;
  }
}

//------------------------------------------------
//Таймер
//------------------------------------------------
void CALLBACK TimerProc(unsigned int uID, unsigned int uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{    
if(IsIconic(hWindow)) //hWindow - хэндл окна программы
  {
  ShowWindow(hWindow, SW_RESTORE);
  SetForegroundWindow(hWindow);
  }
}
//------------------------------------------------
989
20 августа 2003 года
Vlad232ua
182 / / 02.04.2003
Цитата:
Originally posted by Slon


Ничего волшебного. И хука нет. Просто в ней по таймеру идёт проверка, минимизировано ли окно. И если да, то вызываются ShowWindow() и SetForegroundWindow().
Думаю, и без таймера можно обойтись. Просто вызывать из оконной процедуры ф-цию, реализованную в dll. Надо будет попробывать.
Код:
//------------------------------------------------
#include <windows.h>
#pragma hdrstop

#define __BUILDING_THE_DLL
int TimerID = 0; //идентификатор таймера
HWND hWindow; //хэндл окна программы
//------------------------------------------------
#pragma argsused

//------------------------------------------------
// Включение таймера
//------------------------------------------------
void WINAPI DoNotMinimized(HWND hWind)
{
if(!TimerID)
  {
  hWindow = hWind;
  TimerID = timeSetEvent(200, 1, TimerProc, NULL, TIME_PERIODIC);
  }
}

//------------------------------------------------
//  Выключение таймера
//------------------------------------------------
void WINAPI AllowMinimized()
{
if(TimerID)
  {
  timeKillEvent(TimerID);
  TimerID = 0;
  }
}

//------------------------------------------------
//Таймер
//------------------------------------------------
void CALLBACK TimerProc(unsigned int uID, unsigned int uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{    
if(IsIconic(hWindow)) //hWindow - хэндл окна программы
  {
  ShowWindow(hWindow, SW_RESTORE);
  SetForegroundWindow(hWindow);
  }
}
//------------------------------------------------


А ведь интересное решение (что и как можно делать, можно спорить, а инфа интересная. Сенк)

3
20 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Slon

Ничего волшебного. И хука нет. Просто в ней по таймеру идёт проверка, минимизировано ли окно. И если да, то вызываются ShowWindow() и SetForegroundWindow().



А какой смысл выносить это в DLL ???

P.S. Я бы поменял ShowWindow() и SetForegroundWindow() местами и заменил ShowWindow() на OpenIcon.

429
20 августа 2003 года
Slon
78 / / 20.01.2000
Цитата:
Originally posted by Green

А какой смысл выносить это в DLL ???


Потому, что иначе не работает!
Можете проверить.

Цитата:

P.S. Я бы поменял ShowWindow() и SetForegroundWindow() местами и заменил ShowWindow() на OpenIcon.


Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.

 
Код:
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
if(IsIconic(Form2->Handle))
  {
  SetForegroundWindow(Form2->Handle);
  OpenIcon(Form2->Handle);
  }
}

Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.
989
20 августа 2003 года
Vlad232ua
182 / / 02.04.2003
Цитата:
Originally posted by Slon

Потому, что иначе не работает!
Можете проверить.

Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.
 
Код:
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
if(IsIconic(Form2->Handle))
  {
  SetForegroundWindow(Form2->Handle);
  OpenIcon(Form2->Handle);
  }
}

Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.


Да хватает проблем на самом деле. Тут
http://www.rsdn.ru/article/qna/ui/wndsetfg.xml например с этим согласны. Сам с год назад трахался (тоже хук был, все как положено) так вот окно распахивалось, а не активное. Мало того, на самом-то деле это фикция была, т.к. если по кнопке на панели задач щелкнуть то окно - Minimize и пока не щелкнешь по Maximize с окном работать нельзя - хотя оно на экране и все ОК. Наш небольшой кол-ив тогда кричал - тупняк, быть этого не может, пару дней протрахались и бросили. Я потом и знакомым код подбрасывал (говорили, пять сек и проблема решена) так по сей день и решается, жаль код не сохранился, сейчас бы выложил, а так обошли и забыли. ТАК ЧТО ЕСЛИ ЕСТЬ ХОТЬ КАКОЕ РЕШЕНИЕ - ЭТО ПЛЮС, МОЖНО НЕ ПОЛЬЗОВАТЬСЯ (пока не приперло:)) НО ЗАПОМНИТЬ НУЖНО.

3
20 августа 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Slon

Потому, что иначе не работает!
Можете проверить.



Это не научный подход. Конкретное объяснение ведь должно быть. Лично я не вижу разницы в данном случае между вызовом метода из DLL и из EXE.

Одно могу сказать: это проблемы не Win32API, а Борландовской обертки, т.е. VCL. Ну и наворотили же они...
При использовании MFC и WTL таких проблем не происходит.

Цитата:
Originally posted by Slon

Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.
 
Код:
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
if(IsIconic(Form2->Handle))
  {
  SetForegroundWindow(Form2->Handle);
  OpenIcon(Form2->Handle);
  }
}

Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.



А зачем IsIconic() ?
"Нам кузнец не нужен..."

 
Код:
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
  SetForegroundWindow(Form2->Handle);
  OpenIcon(Form2->Handle);
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог