Проблема со свёрнутой формой
:(
У меня в программе в определённый момент по таймеру выполняются некоторые действия и совершенно необходимо, чтобы окно в этот момент восстановилось, если пользователь его свернул (программой удобнее пользоваться, если пользователь после установки времени срабатывания сворачивает её). Попытка обрабатывать WM_SYSCOMMAND не помогла, потому что при этом не отслеживается сворачивание формы щелчком левой кнопки мыши по значку в панели задач.
:(
Причем тут WM_SYSCOMMAND?
Сворачивание можно отследить с помощью WM_SIZE.
Только тебе это, видимо, не надо. Если ты хочешь просто восстанавливать (разворачивать свернутое окно), то надо использовать ShowWindow.
Причем тут 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
Когда я с этим столкнулся, то разворачивал и активизировал окно из dll.
Когда я с этим столкнулся, то разворачивал и активизировал окно из dll.
ну и что, помогло?
У меня в программе в определённый момент по таймеру выполняются некоторые действия и совершенно необходимо, чтобы окно в этот момент восстановилось, если пользователь его свернул (программой удобнее пользоваться, если пользователь после установки времени срабатывания сворачивает её). Попытка обрабатывать WM_SYSCOMMAND не помогла, потому что при этом не отслеживается сворачивание формы щелчком левой кнопки мыши по значку в панели задач.
:(
Всем большое спаибо, но задачу сам решил: в нужном месте вставил
:D
ну и что, помогло?
Да, помогло.
У меня окно, за которым нужно было следить, было не главным. С главным можно и без dll обойтись.
Да, помогло.
У меня окно, за которым нужно было следить, было не главным. С главным можно и без dll обойтись.
Ребята, Вы что-то путаете...
В Windows нет деления окон на главные и неглавные. Есть только родительские и дочерние.
И при чем тут DLL? Это какая-то специальная DLL? Тогда укажите её название, интересно. А если это просто перенесение части кода из своего exe в свою же dll, то это просто бред.
Может, вы имели в виду Foreground и Background Windows, но тогда там все несколько иначе.
Ребята, Вы что-то путаете...
В Windows нет деления окон на главные и неглавные. Есть только родительские и дочерние.
Согласен. Все эти названия пошли вероятно от того, что в билдере есть понятие "Main form".
И при чем тут DLL? Это какая-то специальная DLL? Тогда укажите её название, интересно. А если это просто перенесение части кода из своего exe в свою же dll, то это просто бред.
Почему?
Может, вы имели в виду Foreground и Background Windows, но тогда там все несколько иначе.
Вот что я имел в виду (две страницы).
М-да, так я и не понял, что это за волшебная DLL.
Хук ставиться, что ли? Не понятно, зачем? Хотя, тогда понятно, зачем DLL.
Думаю, раз "С главным можно и без dll обойтись", то это очередной баг/фича от Борланда, поздравляю! :D
Посмотрел свои проекты, я использую такой алгоритм:
OpenIcon(hWnd);
Так что это за волшебная DLL такая?
М-да, так я и не понял, что это за волшебная 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);
}
}
//------------------------------------------------
Ничего волшебного. И хука нет. Просто в ней по таймеру идёт проверка, минимизировано ли окно. И если да, то вызываются 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);
}
}
//------------------------------------------------
А ведь интересное решение (что и как можно делать, можно спорить, а инфа интересная. Сенк)
Ничего волшебного. И хука нет. Просто в ней по таймеру идёт проверка, минимизировано ли окно. И если да, то вызываются ShowWindow() и SetForegroundWindow().
А какой смысл выносить это в DLL ???
P.S. Я бы поменял ShowWindow() и SetForegroundWindow() местами и заменил ShowWindow() на OpenIcon.
А какой смысл выносить это в DLL ???
Потому, что иначе не работает!
Можете проверить.
P.S. Я бы поменял ShowWindow() и SetForegroundWindow() местами и заменил ShowWindow() на OpenIcon.
Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.
{
if(IsIconic(Form2->Handle))
{
SetForegroundWindow(Form2->Handle);
OpenIcon(Form2->Handle);
}
}
Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.
Потому, что иначе не работает!
Можете проверить.
Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.
{
if(IsIconic(Form2->Handle))
{
SetForegroundWindow(Form2->Handle);
OpenIcon(Form2->Handle);
}
}
Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.
Да хватает проблем на самом деле. Тут
http://www.rsdn.ru/article/qna/ui/wndsetfg.xml например с этим согласны. Сам с год назад трахался (тоже хук был, все как положено) так вот окно распахивалось, а не активное. Мало того, на самом-то деле это фикция была, т.к. если по кнопке на панели задач щелкнуть то окно - Minimize и пока не щелкнешь по Maximize с окном работать нельзя - хотя оно на экране и все ОК. Наш небольшой кол-ив тогда кричал - тупняк, быть этого не может, пару дней протрахались и бросили. Я потом и знакомым код подбрасывал (говорили, пять сек и проблема решена) так по сей день и решается, жаль код не сохранился, сейчас бы выложил, а так обошли и забыли. ТАК ЧТО ЕСЛИ ЕСТЬ ХОТЬ КАКОЕ РЕШЕНИЕ - ЭТО ПЛЮС, МОЖНО НЕ ПОЛЬЗОВАТЬСЯ (пока не приперло:)) НО ЗАПОМНИТЬ НУЖНО.
Потому, что иначе не работает!
Можете проверить.
Это не научный подход. Конкретное объяснение ведь должно быть. Лично я не вижу разницы в данном случае между вызовом метода из DLL и из EXE.
Одно могу сказать: это проблемы не Win32API, а Борландовской обертки, т.е. VCL. Ну и наворотили же они...
При использовании MFC и WTL таких проблем не происходит.
Т.е. так? Допустим, просто по таймеру на форме проверяем это же окно.
{
if(IsIconic(Form2->Handle))
{
SetForegroundWindow(Form2->Handle);
OpenIcon(Form2->Handle);
}
}
Если это дочернее окно и оно просто минимизировано, то работает. Но если произошло переключение на другое приложение, т.е. наше окно стало неактивным - то фигушки.
С родительским окном проще.
А зачем IsIconic() ?
"Нам кузнец не нужен..."
{
SetForegroundWindow(Form2->Handle);
OpenIcon(Form2->Handle);
}