Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];
ВнизБьюсь над проблемой: как узнать, что скринсэйвер работает? Найти похожие ветки
← →
Song (2002-09-03 14:31) [0]Отлавливаю WM_SYSCOOMAND c WParam=SC_SCREESAVE
по наступлению события включаю выполнениие нити (TThread), где постоянно опрашиваю:
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING,0,@IsActive,0);
IF not IsActive then ...
При выключении хранителя экрана условие не срабатывает!
Пробовал также через GetActiveWindow(). Почему-то на второй "итерации" TThread.Synchronize GetActiveWindow() возвращает ноль, хотя заставка запущена.
MSDN также советует через OpenDeskTop(), но.. это дремучая вещь, хотя и придётся сделать, если не получится.
Может у кого идеи есть?
← →
Внук (2002-09-03 14:37) [1]Если я не брежу, на время работы ScreenSaver в реестре выставляется флажок... Надо будет поглядеть дома книгу
← →
Song (2002-09-03 14:43) [2]О.. класс, а могёшь мне на почту скинуть? Надо...
← →
Внук (2002-09-03 14:45) [3]Завтра, постараюсь не забыть, если не соврал, конечно :)
← →
Виктор Щербаков (2002-09-03 15:15) [4]Вот здесь вроде что-то есть:
http://cw.net.gaming.ru/Russian/ARTS/Screen_Saver.html
← →
Song (2002-09-03 15:54) [5]Не работает SPI_GETSCREENSAVERRUNNING в Windows98SE, хоть убей...
← →
Виктор Щербаков (2002-09-03 16:06) [6]Song © (03.09.02 15:54)
Ага. Она вообще без изменений оставляет значение по адресу @IsActive. Наверно Билл и его ребята оставили это на сладкое, а потом и вовсе забыли :)
← →
Song (2002-09-03 16:14) [7]Вообще интересно.. почему не работает GetActiveWindow ?
В момент запуска GetActiveWindow возвращает дискриптор приложения-скринсэйвера, а потом на следующий вызов в нити возвращает ноль... Отчего бы... ??
← →
Виктор Щербаков (2002-09-03 16:17) [8]
> Отчего бы... ??
The GetActiveWindow function retrieves the window handle to the active window associated with the thread that calls the function.
Может по-этому?
← →
Виктор Щербаков (2002-09-03 16:21) [9]Наверно стоит попробовать GetForeGroundWindow?
← →
Song (2002-09-03 16:23) [10]MSDN советует использовать для скринсэйвера именно GetActiveWindow.. хотя ща попробую и foreground :-)
← →
Внук (2002-09-03 16:27) [11]Нашел я веточку
HKEY_CURRENT_USER\Control Panel\Desktop
Параметр ScreenSaveActive, да по-моему лажа это...
← →
Виктор Щербаков (2002-09-03 16:34) [12]Внук © (03.09.02 16:27)
Не, этот параметр означает несколько иное. А именно, активен какой-нибудь скринсейвер или нет. При этом нельзя определить запущен ли он в данный момент.
← →
Song (2002-09-03 16:36) [13]С GetForeGroundWindow тоже ничего не вышло..
Вот интересно, я встроил "шпиона" в лице экземпляра TStringList и вот что у меня вышло:
unit ScreenSaverThread;
interface
uses
Classes, Windows, Kld, SysUtils;
type
TScreenSaveObject = class(TThread)
protected
procedure CheckForScreenSaverRunning;
procedure Execute; override;
end;
Procedure InitializeThread;
implementation
Var Thread:TScreenSaveObject; // Экземлпяр потока
ScreenSaverHandle:HWND;
Str:TStringList;
Procedure InitializeThread;
Begin
Sleep(5000);
Thread:=TScreenSaveObject.Create(False);
With Thread Do
Begin
FreeOnTerminate:=True;
Priority:=tpNormal;
End;
ScreenSaverHandle:=GetForeGroundWindow;
Str:=TStringList.Create;
Str.Add(IntToStr(ScreenSaverHandle));
End;
procedure TScreenSaveObject.CheckForScreenSaverRunning;
Begin
Str.Add(IntToStr(GetForeGroundWindow));
IF GetForeGroundWindow<>ScreenSaverHandle then // Терминируем поток, когда скринсэйвер закроется
Begin
...
// Скринсэйвер закрыт
Str.SaveToFile("c:\results");
Str.Free;
Thread.Terminate; // Закрываем поток
End;
End;
procedure TScreenSaveObject.Execute;
begin
While not Terminated Do Synchronize(CheckForScreenSaverRunning);
end;
end.
И вот реультат файла results:
*********************
936
3840
********************
Отчего бы?
С GetActiveWindow() примерно также, только последний ноль.
P.S. InitializeThread вызывается по WM_SYSCOMMAND
← →
Alx2 (2002-09-03 16:41) [14]Где-то вычитал, что класс окошка ScreenSavera зовется "WindowsScreenSaverClass". Может стоит попробовать FindWindow на это дело?
Screen savers contain specific exported functions, resource definitions, and variable declarations. The static-link library SCRNSAVE.LIB contains the main function and other startup code required for a screen saver. When a screen saver starts, the startup code in SCRNSAVE.LIB creates a full-screen window. The window class for this window is declared as follows.
WNDCLASS cls;
cls.hCursor = NULL;
cls.hIcon = LoadIcon(hInst, MAKEINTATOM(ID_APP));
cls.lpszMenuName = NULL;
cls.lpszClassName = "WindowsScreenSaverClass";
cls.hbrBackground = GetStockObject(BLACK_BRUSH);
cls.hInstance = hInst;
cls.style = CS_VREDRAW | CS_HREDRAW |
CS_SAVEBITS | CS_DBLCLKS;
cls.lpfnWndProc = (WNDPROC) ScreenSaverProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
← →
Игорь Шевченко (2002-09-03 16:43) [15]Я бы рекомендовал заглянуть на
http://www.codeproject.com/samples/winmgr.asp
Может, что по теме найдется.
С уважением,
← →
Виктор Щербаков (2002-09-03 16:46) [16]Я делал очень просто:
procedure TForm1.Button1Click(Sender: TObject);
var IsActive: Integer;
begin
SendMessage(Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
Sleep(500);
Label1.Caption := IntToStr(GetForeGroundWindow);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Label1.Caption := IntToStr(GetForeGroundWindow);
end;
После примерно секунды работы заставки, я её выключал. Затем сравнивал хэндл с получаемым при нажатии на Button2. Они были разными. Так, конечно, делать нельзя (это о sleep(500)), но в качестве проверки - вполне.
← →
Набережных С. (2002-09-03 17:37) [17]
> Song © (03.09.02 16:36)
> И вот реультат файла results:
> *********************
> 936
> 3840
> ********************
> Отчего бы?
Первый - хендл окна, активного перед запуском хранителя(вероятно, твоей проги).
Второй - хендл окна хранителя.
Добавь запись в файл класса окна.
← →
Song (2002-09-03 17:38) [18]А я вот думаю, а если у него вообще окошко-то? Все заставки что я проверял были с OpenGL т.е. там метаморфозы, объёмный текст и прочая дребедень... Может тогда есть какой-нибудь другой уникальный номер, PID например, по которому можно проверить.
Так или иначе сейчас проверять ничего не могу.. радиомышь сдохла :-((( Только завтра на работе.
Спасибо всем. Приходите завтра :-)
← →
Song (2002-09-03 17:40) [19]2Набережных С.
Нет, а задержку в 5 сек я для чего сделал?
← →
Набережных С. (2002-09-03 17:54) [20]Да ты попробуй:)
← →
Набережных С. (2002-09-03 18:03) [21]
> Song © (03.09.02 17:40)
> 2Набережных С.
> Нет, а задержку в 5 сек я для чего сделал?
А я почем знаю?:)))))
А если серьезно, так ты же ее в обработчике WM_SYSCOMMAND делаешь - ну и что с нее толку?
← →
Song (2002-09-03 18:42) [22]Всё, спасибо большое, Набережных С.
Сделал, завтра проверю на сети.
Надо было в WM_SYSCOMMAND сделать цикл до тех пор пока не поменяется GetForeGroundWindow(т.е. до тех пор пока не запуститься хранитель), а потом в потоке подождать пока дискриптор не поменяется снова, но теперь уже на ноль (дискрптор рабочего стола) что означает что хранитель экрана закрыт.
А... что до записи классов.. я сделал - TForm1 везде было :-))))
← →
Внук (2002-09-04 09:55) [23]Посмотрел я книгу, да, про параметр реестра я имел в виду именно ScreenSaveActive, но это не то (см. Виктор Щербаков © 03.09.02 16:34)
Пришлось идти другим путем (через SDK :)), вот этот код работает:
program ScreenTest;
uses Windows;
{$R *.RES}
var Flag:Bool;
ResFile:Text;
begin
Flag:=false;
Sleep(90000);
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING,0,@Flag,0);
AssignFile(ResFile,"ResFile.txt");
Rewrite(ResFile);
if Flag then WriteLn(ResFile,"ScreenSaver is active")
else WriteLn(ResFile,"ScreenSaver is passive");
CloseFile(ResFile);
end.
Проверено под WinXP, WinMe, будет работать под Win98, Win2000.
А вот под WinNT и Win95, скорее всего нужно что-то другое изобретать :)
← →
Song (2002-09-04 09:59) [24]Под Win95 - SPI_SCREENSAVERRUNING. Под NT - OpenDeskTop()
Ну вообщем уже не надо, всё работает, спасибо Набережных С.
Но теперь новая проблема. TThread у меня запускается, как я уже говорил, по WM_SYSCOMMAND, SC_SCREENSAVE. И это всё теперь Ok работает, НО только когда прога активная, а когда скрыта и значок в трее или просто на заднем плане - хрен! Без хука как-нить можно обойтись?
← →
Виктор Щербаков (2002-09-04 10:11) [25]
> Под Win95 - SPI_SCREENSAVERRUNING
Вот именно под Win95 она и не работает :(
См. Виктор Щербаков © (03.09.02 16:21)
Похоже, что работа функции с параметром SPI_SCREENSAVERRUNING не реализована в этой ОС.
← →
Внук (2002-09-04 10:15) [26]>>Виктор Щербаков © (04.09.02 10:11)
SPI_SCREENSAVERRUNNING
Windows 95 only: Used internally; applications should not use this flag.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.047 c