Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Отключение скринсейвера   Найти похожие ветки 

 
DeadMeat ©   (2008-08-02 14:27) [0]

Здравсте.
Не знал где писать, здесь или в Медиа. Но написал здесь, т.к. это касается WinAPI больше, чем Медиа.
И так... собсна сабж.
Как отключить (или предотвратить) запуск скринсейвера во время работы моего приложения?
Следующие варианты исключаются:
стереть из system.ini или реестра (SystemParametersInfo делает примерно тоже)
самому стать скринсейвером
забивать процесс скринсейвера при запуске
"двигать мышку" или "нажимать клаву" для имитации работы юзера

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

Пробовал перехват WM_SYSCOMMAND с параметром SC_SCREENSAVE, но прочитав чуть ниже (в МСДН) понял, что не подходит:
[i]Microsoft Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification—even if fails to pass it to DefWindowProc.[/i]
Возникает вопрос - а как же? Ведь разные видео плееры это делают даже на Висте с установленным паролем....


 
Фишер   (2008-08-02 14:59) [1]

В каком-то из старых FAQ нашел:

Как  запретить  запускаться  скринсэйверу,  когда  моя  программа
 активна?

 
 unit Unit1;
 
 interface
 
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls,
   Forms, Dialogs, StdCtrls, ExtCtrls;
   
 type
   TForm1 = class(TForm)
     RadioGroup1: TRadioGroup;
     procedure FormCreate(Sender: TObject);
       private
       procedure ProcessMess(var msg:TMsg; var handled:boolean) ;
     { Private declarations }
   public
     { Public declarations }
   end;
   
 var
   Form1: TForm1;
   
 implementation
 
 {$R *.DFM}
 
 { TForm1 }
 procedure TForm1.ProcessMess(var msg: TMsg; var handled: boolean);
 begin
     if (msg.message=WM_SYSCOMMAND) and
        (msg.wParam=SC_SCREENSAVE)  then
      handled:=true
     else
      handled:=false;
 end;
 
 procedure TForm1.FormCreate(Sender: TObject);
 begin
 Application.OnMessage:=ProcessMess;
 end;
 
 end.


 
DeadMeat ©   (2008-08-02 15:17) [2]


> Фишер   (02.08.08 14:59) [1]


> DeadMeat ©   (02.08.08 14:27) 

Пробовал перехват WM_SYSCOMMAND с параметром SC_SCREENSAVE, но прочитав чуть ниже (в МСДН) понял, что не подходит:
Microsoft Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification—even if fails to pass it to DefWindowProc.


 
DeadMeat ©   (2008-08-05 17:47) [3]

Никто не против, если я слегонца апну ветку?


 
Фишер   (2008-08-05 18:23) [4]

На DelphiWord есть такой код:

Как отключить хранитель экрана
Автор: Олег Кулабухов

procedure TForm1.Button1Click(Sender: TObject);
begin
 {Turn it off}
 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0);

 {Turn it on}
 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);
end;


Сам не проверял:(


 
DVM ©   (2008-08-05 18:38) [5]


> Фишер   (05.08.08 18:23) [4]


> Следующие варианты исключаются:
> стереть из system.ini или реестра (SystemParametersInfo
> делает примерно тоже)


 
Фишер   (2008-08-05 18:52) [6]

> Как отключить (или предотвратить) запуск скринсейвера во
> время работы моего приложения?


Так это ж только на время работы приложения, при выходе
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);


 
DVM ©   (2008-08-05 18:53) [7]


> Так это ж только на время работы приложения, при выходе

а если программа вылетела с ошибкой или ее убили через TerminateProcess? Заставка так и останется выключенной.


 
Фишер   (2008-08-05 19:04) [8]


> DVM ©   (05.08.08 18:53) [7]

В любом случае могут выдернуть шнур из UPS, или нажать Reset, да мало ли форсмажорных ситуаций.
Если программа вылетела с ошибкой, то надо "лечить" программу. И если юзер вынужден убивать ее с помошью TerminateProcess, то это тоже проблема данного приложения.


 
DVM ©   (2008-08-05 22:33) [9]


> Фишер   (05.08.08 19:04) [8]

Это не я так хочу, это DeadMeat-у так хочется.


 
DeadMeat   (2008-08-05 22:35) [10]

> [8] Фишер   (05.08.08 19:04)

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


 
DVM ©   (2008-08-05 22:59) [11]


> DeadMeat   (05.08.08 22:35) [10]

Наверное ничего нового, но все же (советуют иммитировать нажатия на клавиатуру) http://www.microsoft.com/Rus/Msdn/Activ/MSVB/Archive/Interaction/264.mspx


 
brother ©   (2008-08-06 05:24) [12]

прочитать из реестра через сколько мин запускается заставка, и чуть до этого посылать нажатие клавиши (какой - на выбор ))


 
DeadMeat ©   (2008-08-06 09:42) [13]


> DVM ©   (05.08.08 22:59) [11]

Мда... ну если на майкрософте такой способ предлагают....
Все-же странно, что нет штатного способа для этого. Т.е. он был, но теперь "перестал быть".

> brother ©   (06.08.08 05:24) [12]

Видимо придется все-таки делать таким способом.. Эхх.....

Спасибо всем...

ЗЫ. Но если вдруг, кто найдет еще способ "постандартнее", то пожалуйста, дайте знать...


 
miek   (2008-08-08 09:15) [14]

единственный стандартный способ - WM_SYSCOMMAND+SC_SCREENSAVE
поскольку отключение скринсейвера - само по себе нстандартно


 
_Milk   (2008-08-08 09:40) [15]

> DeadMeat   (05.08.08 22:35) [10]

> Это не выход... А если зависание системы? Вариантов неожиданного
> завершения приложения масса.... поэтому полноценное выключение
> заставки не приемлимо.


Ты прежде чем постить о "теоретическом" поведении скрисейвера, лучше бы проверил это практически (Я проверял, завершая их ножиданно. Заставка остается включенной, но во время работы самого плеера не включается)
Проверь это практически на своем приложении с SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);
а потом уже пости:(


 
DeadMeat   (2008-08-09 19:48) [16]

> [14] miek   (08.08.08 09:15)

Эмм... чуть выше я про это написал уже.


> [15] _Milk   (08.08.08 09:40)

А вот для абсолютных дЭбилов, которые знают обо всем только в теории.... можно объяснить смысл сего поста? Только так, чтобы я понял.. Если можно конечно....


 
_Milk   (2008-08-09 19:55) [17]

Ну, а если конкретно, то заверши свое приложение аварийно (да хоть вытащи вилку из розетки во время работы твоего приложения), потом перезагрузись, проверь - свойства экрана - заставка - интервал. Если удивишься (или нет) сообщи.


 
DeadMeat ©   (2008-08-09 20:11) [18]


> _Milk   (09.08.08 19:55) [17]

Вы знаете... уважжаемый. Я проверял.... Я всегда проверяю то, о чем пишу.. То, что профиль не обновился, это понятно... И теперь вы предлагаете после неожиданного завершения программы каждый раз перегружать компьютер чтобы заработал скринсейвер? Заставка не заработает, если было сделано 0 и не сделано 1, пока не будет "перезапущен" профиль юзера.
Дальше объяснять будете? Я с удовольствием выслушаю... Может найдем таки способ "нормальный".


 
_Milk   (2008-08-09 20:16) [19]

Дорогой мой, неужели абсолютно все нужно распИсывать по пунктам? Не перезагружайтесь, "убейте" свое приложение любым другим не ординарным способом (боюсь что-либо предлагать) и далее
> проверь - свойства экрана - заставка - интервал. Если удивишься  (или нет) сообщи.


 
DeadMeat ©   (2008-08-09 22:47) [20]


> _Milk   (09.08.08 20:16) [19]

Вы меня поражаете... очень. Вы чуть выше читали? Ладно... перецитирую?

> Я проверял.... Я всегда проверяю то, о чем пишу..

По всей видимости, статус скринсейвера вы проверяли по внешнему виду этого окна? А вы попробуйте после SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0); подождать выставленный вами интервал... И если скринсейвер после этого заработает, то я специально для Вас переустановлю две висты и одну ХР, на которых я все это проверял... и проверю снова на свежей версии, чтобы исключить баги "древней" установки.
Потом прошу отписаться сюда....


 
Городской Шаман   (2008-08-10 00:24) [21]


> _Milk   (08.08.08 09:40) [15]
>
> > DeadMeat   (05.08.08 22:35) [10]
>
> > Это не выход... А если зависание системы? Вариантов неожиданного
> > завершения приложения масса.... поэтому полноценное выключение
> > заставки не приемлимо.
>
> Ты прежде чем постить о "теоретическом" поведении скрисейвера,
>  лучше бы проверил это практически (Я проверял, завершая
> их ножиданно. Заставка остается включенной, но во время
> работы самого плеера не включается)
> Проверь это практически на своем приложении с SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
>  1, nil, 0);
> а потом уже пости:(


Угу если программа глюканет то после перезугрузки станет все как раньше, ведь четвёртый параметр
fWinIni установлен в 0, а вот если установить его в
SPIF_UPDATEINIFILE ....


 
DeadMeat ©   (2008-08-11 09:04) [22]


> Городской Шаман   (10.08.08 00:24) [21]

А "ДО" перезагрузки? Или надо будет в ридми указать, что мол если программа вылетит, то обязательно перезагрузитесь..
Вот об этом и речь... жаль что уважжаемый _Milk этого не хочет принять.
Где он кстати? Проверил?


 
ALFA   (2008-10-15 11:17) [23]

Программно, раз в минуту например, делай: SetCursorPos(Mouse.CursorPos.X, Mouse.CursorPos.Y);


 
Добежал   (2009-01-22 19:44) [24]

Интересно, а я вот не понимаю, каким образом код:

if (msg.message=WM_SYSCOMMAND) and
       (msg.wParam=SC_SCREENSAVE)  then
     handled:=true
    else
     handled:=false;


может помочь? Получается, тут только или выставляется handled или нет. Если смотреть VCL:

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
 Handled: Boolean;
begin
 Result := False;
 if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
 begin
   Result := True;
   if Msg.Message <> WM_QUIT then
   begin
     Handled := False;
     if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
     if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
       not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
     begin
       TranslateMessage(Msg);
       DispatchMessage(Msg);
     end;
   end
   else
     FTerminate := True;
 end;
end;


От того, выставлен ли Handled, зависит фактически только то, будет ли вызван DispatchMessage.
В нашем примере при приходе "msg.wParam=SC_SCREENSAVE" будет handled выставлен в true и соответственно не будет вызван DispatchMessage.

Не понимаю... А как это выглядит с точки зрения Windows? То есть, перед тем как включить заставку она всем окнам рассылает данное сообщение - логично.
Но как она потом собирает результат?! Если над этим сообщением все потоки сделали DispatchMessage, то заставка включается, а если поток хоть одного окна не сделал DispatchMessage над этим сообщением - заставка не включается что ли, логика такова? А интересно сколько по времени тогда ждет винда, чтобы все потоки успели сделать DispatchMessage?

То есть, допустим достаточно всего одного приложения, которое подвисло или еще что и не выбирает из очереди сообщения - чтобы отключения экрана никогда не произошло? Вообще как-то немного бредово выглядит



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.063 c
15-1264627806
Юрий
2010-01-28 00:30
2010.08.27
С днем рождения ! 28 января 2010 четверг


15-1265194467
зодиак
2010-02-03 13:54
2010.08.27
Странный метод


2-1269838242
tippa
2010-03-29 08:50
2010.08.27
а чего он пищит?


15-1266096606
Юрий
2010-02-14 00:30
2010.08.27
С днем рождения ! 14 февраля 2010 воскресенье


15-1263939469
Маша
2010-01-20 01:17
2010.08.27
Странная задачка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский