45856 (665197)

Файл №665197 45856 (Создание хранителя экрана)45856 (665197)2016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла

Создание хранителя экрана

Главное о чем стоит упомянуть это, что ваш хранитель экрана будет работать в фоновом режиме, и он не должен мешать работе других запущенных программ. Поэтому сам хранитель должен быть как можно меньшего объема. Для уменьшения объема файла в описанной ниже программе не используется визуальные компоненты Delphi, включение хотя бы одного из них приведет к увеличению размера файла свыше 200кб, а так, описанная ниже программа, имеет размер всего 20кб!!!

Технически, хранитель экрана является нормальным EXE файлом (с расширением .SCR), который управляется через командные параметры строки. Например, если пользователь хочет изменить параметры вашего хранителя, Windows выполняет его с параметром "-c" в командной строке. Поэтому начать создание вашего хранителя экрана следует с создания примерно следующей функции:

Procedure RunScreenSaver;

Var S : String;

Begin

S := ParamStr(1);

If (Length(S) > 1) Then Begin

Delete(S,1,1);

{ delete first char - usally "/" or "-" }

S[1] := UpCase(S[1]);

End;

LoadSettings; { load settings from registry }

If (S = 'C') Then RunSettings

Else If (S = 'P') Then RunPreview

Else If (S = 'A') Then RunSetPassword

Else RunFullScreen;

End;

Поскольку нам нужно создавать небольшое окно предварительного просмотра и полноэкранное окно, их лучше объединить, используя единственный класс окна. Следуя правилам хорошего тона, нам также нужно использовать многочисленные нити. Дело в том, что, во-первых, хранитель не должен переставать работать, даже если что-то "тяжелое" случилось, и, во-вторых, нам не нужно использовать таймер.

Процедура для запуска хранителя на полном экране - приблизительно такова:

Procedure RunFullScreen;

Var

R : TRect;

Msg : TMsg;

Dummy : Integer;

Foreground : hWnd;

Begin

IsPreview := False; MoveCounter := 3;

Foreground := GetForegroundWindow;

While (ShowCursor(False) > 0) do ;

GetWindowRect(GetDesktopWindow,R);

CreateScreenSaverWindow(R.Right-R.Left, R.Bottom-R.Top,0);

CreateThread(nil,0,@PreviewThreadProc, nil,0,Dummy);

SystemParametersInfo(spi_ScreenSaverRunning, 1,@Dummy,0);

While GetMessage(Msg,0,0,0) do Begin //отвечаем на сообщения

TranslateMessage(Msg); //что бы не повесить windows

DispatchMessage(Msg);

End;

SystemParametersInfo(spi_ScreenSaverRunning,0,@Dummy,0);

ShowCursor(True);

SetForegroundWindow(Foreground);

End;

Во-первых, мы проинициализировали некоторые глобальные переменные (описанные далее), затем прячем курсор мыши и создаем окно хранителя экрана. Имейте в виду, что важно уведомлять Windows, что это - хранителя экрана через SystemParametersInfo (это выводит из строя Ctrl-Alt-Del чтобы нельзя было вернуться в Windows не введя пароль). Создание окна хранителя:

Function CreateScreenSaverWindow(Width, Height : Integer;ParentWindow : hWnd) : hWnd;

Var WC : TWndClass;

Begin

With WC do Begin

Style := cs_ParentDC;

lpfnWndProc := @PreviewWndProc;

cbClsExtra := 0; cbWndExtra := 0;

hIcon := 0; hCursor := 0;

hbrBackground := 0; lpszMenuName := nil;

lpszClassName:='MyDelphiScreenSaverClass';

hInstance := System.hInstance;

end;

RegisterClass(WC);

If (ParentWindow 0) Then

Result := CreateWindow('MyDelphiScreenSaverClass','MySaver',ws_Child Or ws_Visible or ws_Disabled,0,0,Width,Height,ParentWindow,0,hInstance,nil)

Else Begin

Result := CreateWindow('MyDelphiScreenSaverClass','MySaver',ws_Visible or ws_Popup,0,0,Width,Height,0,0,hInstance,nil);

SetWindowPos(Result,hwnd_TopMost,0,0,0,0,swp_NoMove or swp_NoSize or swp_NoRedraw);

End;

PreviewWindow := Result;

End;

Теперь окна созданы используя вызовы API. Я удалил проверку ошибки, но обычно все проходит хорошо, особенно в этом типе приложения.

Теперь Вы можете погадать, как мы получим handle родительского окна предварительного просмотра ? В действительности, это совсем просто: Windows просто передает handle в командной строке, когда это нужно. Таким образом:

Procedure RunPreview;

Var

R : TRect;

PreviewWindow : hWnd;

Msg : TMsg;

Dummy : Integer;

Begin

IsPreview := True;

PreviewWindow := StrToInt(ParamStr(2));

GetWindowRect(PreviewWindow,R);

CreateScreenSaverWindow(R.Right-R.Left,R.Bottom-R.Top,PreviewWindow);

CreateThread(nil,0,@PreviewThreadProc,nil,0,Dummy);

While GetMessage(Msg,0,0,0) do Begin

TranslateMessage(Msg);

DispatchMessage(Msg);

End;

End;

Как Вы видите, window handle является вторым параметром (после "-p").

Чтобы "выполнять" хранителя экрана - нам нужна нить. Это создается с вышеуказанным CreateThread. Процедура нити выглядит примерно так:

Function PreviewThreadProc(Data:Integer) : Integer; StdCall;

Var R : TRect;

Begin

Result := 0; Randomize;

GetWindowRect(PreviewWindow,R);

MaxX := R.Right-R.Left;

MaxY := R.Bottom-R.Top;

ShowWindow(PreviewWindow,sw_Show);

UpdateWindow(PreviewWindow);

Repeat

InvalidateRect(PreviewWindow,nil,False);

Sleep(30);

Until QuitSaver;

PostMessage(PreviewWindow,wm_Destroy,0,0);

End;

Нить просто заставляет обновляться изображения в нашем окне, спит на некоторое время, и обновляет изображения снова. А Windows будет посылать сообщение WM_PAINT на наше окно (не в нить !). Для того, чтобы оперировать этим сообщением, нам нужна процедура:

Function PreviewWndProc(Window:hWnd; Msg,WParam,LParam:Integer) : Integer;StdCall;

Begin

Result := 0;

Case Msg of

wm_NCCreate : Result := 1;

wm_Destroy : PostQuitMessage(0);

{ paint something }

wm_Paint : DrawSingleBox;

wm_KeyDown : QuitSaver := AskPassword;

wm_LButtonDown, wm_MButtonDown,

wm_RButtonDown, wm_MouseMove :

Begin

If (Not IsPreview) Then Begin

Dec(MoveCounter);

If (MoveCounter <= 0) Then

QuitSaver :=AskPassword;

End;

End;

Else Result := DefWindowProc

(Window,Msg,WParam,LParam);

End;

End;

Если мышь перемещается или нажата кнопки, мы спрашиваем у пользователя пароль:

Function AskPassword : Boolean;

Var

Key : hKey;

D1,D2 : Integer; { two dummies }

Value : Integer;

Lib : THandle;

F : TVSSPFunc;

Begin

Result := True;

If (RegOpenKeyEx(hKey_Current_User,'Control Panel\Desktop',0,Key_Read,Key) = Error_Success) Then

Begin

D2 := SizeOf(Value);

If (RegQueryValueEx(Key,'ScreenSaveUsePassword',nil,@D1, @Value,@D2) = Error_Success) Then

Begin

If (Value 0) Then Begin

Lib := LoadLibrary('PASSWORD.CPL');

If (Lib > 32) Then Begin

@F := GetProcAddress(Lib,'VerifyScreenSavePwd');

ShowCursor(True);

If (@F nil) Then Result := F(PreviewWindow);

ShowCursor(False);

{ reset again if password was wrong }

MoveCounter := 3;

FreeLibrary(Lib);

End;

End;

End;

RegCloseKey(Key);

End;

End;

Это также демонстрирует использование registry на уровне API. Также имейте в виду как мы динамически загружаем функции пароля, используя LoadLibrary. Запомните тип функции?

TVSSFunc ОПРЕДЕЛЕН как:

Type

TVSSPFunc = Function(Parent : hWnd) : Bool; StdCall;

Теперь почти все готово, кроме диалога конфигурации. Это запросто:

Procedure RunSettings;

Var Result : Integer;

Begin

Result := DialogBox(hInstance,'SaverSettingsDlg',0,@SettingsDlgProc);

If (Result = idOK) Then SaveSettings;

End;

Трудная часть -это создать диалоговый сценарий (запомните: мы не используем здесь Delphi формы!). Я сделал это, используя 16-битовую Resource Workshop (остался еще от Turbo Pascal для Windows). Я сохранил файл как сценарий (текст), и скомпилированный это с BRCC32:

SaverSettingsDlg DIALOG 70, 130, 166, 75

STYLE WS_POPUP | WS_DLGFRAME | WS_SYSMENU

CAPTION "Settings for Boxes"

FONT 8, "MS Sans Serif"

BEGIN

DEFPUSHBUTTON "OK", 5, 115, 6, 46, 16

PUSHBUTTON "Cancel", 6, 115, 28, 46, 16

CTEXT "Box &Color:", 3, 2, 30, 39, 9

COMBOBOX 4, 4, 40, 104, 50, CBS_DROPDOWNLIST |

CBS_HASSTRINGS

CTEXT "Box &Type:", 1, 4, 3, 36, 9

COMBOBOX 2, 5, 12, 103, 50,

CBS_DROPDOWNLIST | CBS_HASSTRINGS

LTEXT "Boxes Screen Saver for

Win32 Copyright(c) 1996 Jani Jurvinen."

, 7, 4, 57, 103, 16,

WS_CHILD | WS_VISIBLE | WS_GROUP

END

Почти также легко сделать диалоговое меню:

Function SettingsDlgProc(Window:hWnd;Msg,WParam,LParam : Integer) : Integer; StdCall;

Var S : String;

Begin

Result := 0;

Case Msg of

wm_InitDialog : Begin

{ initialize the dialog box }

Result := 0;

End;

wm_Command : Begin

If (LoWord(WParam) = 5) Then

EndDialog(Window,idOK)

Else

If (LoWord(WParam) = 6) Then

EndDialog(Window,idCancel);

End;

wm_Close : DestroyWindow(Window);

wm_Destroy : PostQuitMessage(0);

Else Result := 0;

End;

End;

После того, как пользователь выбрал некоторые установочные параметры, нам нужно сохранить их.

Procedure SaveSettings;

Var

Key : hKey;

Dummy : Integer;

Begin

If (RegCreateKeyEx(hKey_Current_User,

'Software\SilverStream\SSBoxes',

0,nil,Reg_Option_Non_Volatile,

Key_All_Access,nil,Key,

@Dummy) = Error_Success) Then Begin

RegSetValueEx(Key,'RoundedRectangles',0,Reg_Binary,@RoundedRectangles,

SizeOf(Boolean));

RegSetValueEx(Key,'SolidColors',0,Reg_Binary, @SolidColors,SizeOf(Boolean));

RegCloseKey(Key);

End;

End;

Загружаем параметры так:

Procedure LoadSettings;

Var

Key : hKey;

D1,D2 : Integer; { two dummies }

Value : Boolean;

Begin

If (RegOpenKeyEx(hKey_Current_User,'Software\SilverStream\SSBoxes',0,Key_Read,Key) = Error_Success) Then Begin

D2 := SizeOf(Value);

If (RegQueryValueEx(Key,'RoundedRectangles',nil,@D1,@Value, @D2) = Error_Success) Then

Begin

RoundedRectangles := Value;

End;

If (RegQueryValueEx(Key,'SolidColors',nil,@D1,@Value,@D2) = Error_Success) Then

Begin

SolidColors := Value;

End;

RegCloseKey(Key);

End;

End;

Легко? Нам также нужно позволить пользователю, установить пароль. Я честно не знаю почему это оставлено разработчику приложений! Тем не менее:

Procedure RunSetPassword;

Var

Lib : THandle;

F : TPCPAFunc;

Begin

Lib := LoadLibrary('MPR.DLL');

If (Lib > 32) Then Begin

@F := GetProcAddress(Lib,'PwdChangePasswordA');

If (@F nil) Then F('SCRSAVE',StrToInt(ParamStr(2)),0,0);

FreeLibrary(Lib);

End;

End;

Мы динамически загружаем (недокументированную) библиотеку MPR.DLL, которая имеет функцию, чтобы установить пароль хранителя экрана, так что нам не нужно беспокоиться об этом.

TPCPAFund ОПРЕДЕЛЕН как:

Type

TPCPAFunc = Function(A : PChar; Parent : hWnd; B,C : Integer) : Integer; StdCall;

(Не спрашивайте меня что за параметры B и C ! :-)

Теперь единственная вещь, которую нам нужно рассмотреть, - самая странная часть: создание графики. Я не великий ГУРУ графики, так что Вы не увидите затеняющие многоугольники, вращающиеся в реальном времени. Я только сделал некоторые ящики.

Procedure DrawSingleBox;

Var

PaintDC : hDC;

Info : TPaintStruct;

OldBrush : hBrush;

X,Y : Integer;

Color : LongInt;

Begin

PaintDC := BeginPaint(PreviewWindow,Info);

X := Random(MaxX); Y := Random(MaxY);

If SolidColors Then

Color := GetNearestColor(PaintDC,

RGB(Random(255),Random(255)

,Random(255)))

Else Color := RGB(Random(255),

Random(255),Random(255));

OldBrush := SelectObject(PaintDC,

CreateSolidBrush(Color));

If RoundedRectangles Then

RoundRect(PaintDC,X,Y,X+Random(MaxX-X),

Y+Random(MaxY-Y),20,20)

Else Rectangle(PaintDC,X,Y,X+Random(MaxX-X),

Y+Random(MaxY-Y));

DeleteObject(SelectObject(PaintDC,OldBrush));

Характеристики

Тип файла
Документ
Размер
34,89 Kb
Тип материала
Учебное заведение
Неизвестно

Тип файла документ

Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.

Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.

Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6566
Авторов
на СтудИзбе
298
Средний доход
с одного платного файла
Обучение Подробнее