-
Здравсте. Не знал где писать, здесь или в Медиа. Но написал здесь, т.к. это касается 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] Возникает вопрос - а как же? Ведь разные видео плееры это делают даже на Висте с установленным паролем....
-
В каком-то из старых 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) ;
public
end;
var
Form1: TForm1;
implementation
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.
-
> Фишер (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.
-
Никто не против, если я слегонца апну ветку?
-
На 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;
Сам не проверял:(
-
> Фишер (05.08.08 18:23) [4]
> Следующие варианты исключаются: > стереть из system.ini или реестра (SystemParametersInfo > делает примерно тоже)
-
> Как отключить (или предотвратить) запуск скринсейвера во > время работы моего приложения?Так это ж только на время работы приложения, при выходе SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);
-
> Так это ж только на время работы приложения, при выходе
а если программа вылетела с ошибкой или ее убили через TerminateProcess? Заставка так и останется выключенной.
-
> DVM © (05.08.08 18:53) [7] В любом случае могут выдернуть шнур из UPS, или нажать Reset, да мало ли форсмажорных ситуаций. Если программа вылетела с ошибкой, то надо "лечить" программу. И если юзер вынужден убивать ее с помошью TerminateProcess, то это тоже проблема данного приложения.
-
> Фишер (05.08.08 19:04) [8]
Это не я так хочу, это DeadMeat-у так хочется.
-
> [8] Фишер (05.08.08 19:04)
Это не выход... А если зависание системы? Вариантов неожиданного завершения приложения масса.... поэтому полноценное выключение заставки не приемлимо. И все же.... как то медиаплееры ведь это делают. Я проверял, завершая их ножиданно. Заставка остается включенной, но во время работы самого плеера не включается.
-
-
прочитать из реестра через сколько мин запускается заставка, и чуть до этого посылать нажатие клавиши (какой - на выбор ))
-
> DVM © (05.08.08 22:59) [11]
Мда... ну если на майкрософте такой способ предлагают.... Все-же странно, что нет штатного способа для этого. Т.е. он был, но теперь "перестал быть".
> brother © (06.08.08 05:24) [12]
Видимо придется все-таки делать таким способом.. Эхх.....
Спасибо всем...
ЗЫ. Но если вдруг, кто найдет еще способ "постандартнее", то пожалуйста, дайте знать...
-
единственный стандартный способ - WM_SYSCOMMAND+SC_SCREENSAVE поскольку отключение скринсейвера - само по себе нстандартно
-
> DeadMeat (05.08.08 22:35) [10] > Это не выход... А если зависание системы? Вариантов неожиданного > завершения приложения масса.... поэтому полноценное выключение > заставки не приемлимо.Ты прежде чем постить о "теоретическом" поведении скрисейвера, лучше бы проверил это практически ( Я проверял, завершая их ножиданно. Заставка остается включенной, но во время работы самого плеера не включается) Проверь это практически на своем приложении с SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0); а потом уже пости:(
-
> [14] miek (08.08.08 09:15)
Эмм... чуть выше я про это написал уже.
> [15] _Milk (08.08.08 09:40)
А вот для абсолютных дЭбилов, которые знают обо всем только в теории.... можно объяснить смысл сего поста? Только так, чтобы я понял.. Если можно конечно....
-
Ну, а если конкретно, то заверши свое приложение аварийно (да хоть вытащи вилку из розетки во время работы твоего приложения), потом перезагрузись, проверь - свойства экрана - заставка - интервал. Если удивишься (или нет) сообщи.
-
> _Milk (09.08.08 19:55) [17]
Вы знаете... уважжаемый. Я проверял.... Я всегда проверяю то, о чем пишу.. То, что профиль не обновился, это понятно... И теперь вы предлагаете после неожиданного завершения программы каждый раз перегружать компьютер чтобы заработал скринсейвер? Заставка не заработает, если было сделано 0 и не сделано 1, пока не будет "перезапущен" профиль юзера. Дальше объяснять будете? Я с удовольствием выслушаю... Может найдем таки способ "нормальный".
-
Дорогой мой, неужели абсолютно все нужно распИсывать по пунктам? Не перезагружайтесь, "убейте" свое приложение любым другим не ординарным способом (боюсь что-либо предлагать) и далее > проверь - свойства экрана - заставка - интервал. Если удивишься (или нет) сообщи.
-
> _Milk (09.08.08 20:16) [19]
Вы меня поражаете... очень. Вы чуть выше читали? Ладно... перецитирую? > Я проверял.... Я всегда проверяю то, о чем пишу..
По всей видимости, статус скринсейвера вы проверяли по внешнему виду этого окна? А вы попробуйте после SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0); подождать выставленный вами интервал... И если скринсейвер после этого заработает, то я специально для Вас переустановлю две висты и одну ХР, на которых я все это проверял... и проверю снова на свежей версии, чтобы исключить баги "древней" установки. Потом прошу отписаться сюда....
-
> _Milk (08.08.08 09:40) [15] > > > DeadMeat (05.08.08 22:35) [10] > > > Это не выход... А если зависание системы? Вариантов неожиданного > > завершения приложения масса.... поэтому полноценное выключение > > заставки не приемлимо. > > Ты прежде чем постить о "теоретическом" поведении скрисейвера, > лучше бы проверил это практически (Я проверял, завершая > их ножиданно. Заставка остается включенной, но во время > работы самого плеера не включается) > Проверь это практически на своем приложении с SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, > 1, nil, 0); > а потом уже пости:(
Угу если программа глюканет то после перезугрузки станет все как раньше, ведь четвёртый параметр fWinIni установлен в 0, а вот если установить его в SPIF_UPDATEINIFILE ....
-
> Городской Шаман (10.08.08 00:24) [21]
А "ДО" перезагрузки? Или надо будет в ридми указать, что мол если программа вылетит, то обязательно перезагрузитесь.. Вот об этом и речь... жаль что уважжаемый _Milk этого не хочет принять. Где он кстати? Проверил?
-
Программно, раз в минуту например, делай: SetCursorPos(Mouse.CursorPos.X, Mouse.CursorPos.Y);
-
Интересно, а я вот не понимаю, каким образом код: 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? То есть, допустим достаточно всего одного приложения, которое подвисло или еще что и не выбирает из очереди сообщения - чтобы отключения экрана никогда не произошло? Вообще как-то немного бредово выглядит
|