Дата публикации статьи: 09.07.2003 00:00

Для каждого программного языка существует своя ниша, в том числе и для VB. Появившись на свет, как средство для обучения студентов основам программирования, Visual Basic давно уже перешагнул из своих "коротких штанишек" в разряд полноценных языков. И продолжает развиваться. Что может VB? Да очень многое. И разработчики пытаются научить его делать все больше и больше. Эта статья написана для тех, кто только начинает осваивать VB. Поэтому я постараюсь показать в ней различные подходы и уловки, которые не всегда можно найти в справочной литературе. А так же и некоторые недоработки языка и как их обходить.

С чем познакомимся в этой статье:
* естественно, с созданием защитника экрана;
* работой с некоторыми API-функциями;
* как работать с реестром стандартными VB-методами;
* как работать со шрифтами через элемент управления CommonDialog;
* как создать нестандартный элемент управления (кнопка с выпадающим меню);
Разделим всю работу на две части. В первой мы создадим "болванку", на основе которой, в дальнейшем можно будет создавать свои защитники. А во второй, создадим простой защитник "Бегущая строка", отличающийся от стандартного, тем, что выполняться будет не одна запись, а несколько. И назовем мы его скромно – CleverThoughts ("умные мысли") :)

Часть первая.

Шаг 1. Создайте новый проект Standard EXE. Не откладывая дела в долгий ящик, зайдем в свойства проекта: меню Project/Project1 Properties… В открывшемся диалоговом окне заполним данные:

Project Name = CleverThoughts
Project Description = "Screen saver"

И самое главное!

Title = "SCRNSAVE:CleverThoughts"

Нажмите кнопку ОК.

NB! Слово "SCRNSAVE", отделенное от названия двоеточием (без пробелов!), необходимо будет окну "Свойства", откуда запускается защитник.

Далее изменим некоторые свойства формы:

Name=frmSsaver
ControlBox=False
BorderStyle=0 (None)
Font=любой
ForeColor=&H00FF00FF&
WindowState=2 (Maximized)

NB! Установка свойства ForeColor в розовый цвет необходима только на начальном этапе. По своему желанию вы можете ее изменить на любой другой, хорошо видный на черном фоне.

Сохраним проект.

Далее (будьте внимательны!), делаем первую компиляцию файла. Меню File/Make CleverThoughts.exe ... В диалоговом окне сохранения файлов изменим расширение файла с EXE на SCR, т.к. защитники экрана носят именно такое расширение.

NB! В дальнейшем, сохраняя промежуточные версии защитника, Вы уже увидите меню File/Make CleverThoughts.scr ...



Шаг 2. Разместим на форме таймер, отвечающий (кроме всех прочих ухищрений) за закрытие приложения.

Name=tmrExit
Enabled=False
Interval=1

NB! Не смотря на то, что интервал позволяет устанавливать такие параметры, как 1, реально точность Timer начинается приблизительно с 18-20 (т.е. 0,02 сек).
Объявим декларации и константы API-функций. Первая функция отвечает за информирование системы, что защитник экрана на данный момент является активным.

Private Declare Function SystemParametersInfo _
Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, _
ByVal uParam As Long, _
ByVal lpvParam As Any, _
ByVal fuWinIni As Long) _
As Long
Const SPI_SETSCREENSAVEACTIVE = 17



Вторая – руководит скрытием и показом курсора.


Private Declare Function ShowCursor Lib "user32" _
(ByVal bShow As Long) _
As Long




Шаг 3. Сейчас займемся событиями, в которых отслеживается, что защитник экрана пора выгружать. По логике самого защитника он должен выгружаться, если:
1. Произведен щелчок мыши по форме – событие Form_Click
2. Нажата любая клавиша – событие Form_KeyDown
3. Изменено положение курсора (сдвинута мышь) – событие Form_MouseMove
4. Как подстраховка, включился таймер – событие tmrExit_Timer
В раздел деклараций добавим переменную, сигнализирующую о необходимости закрытия защитника.

Dim QuitFlag As Boolean

События Form_Click и Form_KeyDown не сложны. Они только командуют изменением булевой переменной, и состоят всего из одной строки:

QuitFlag = True

Событие таймера – не сложнее. Оно просто командует выгрузкой формы.

Unload Me

А вот событие Form_MouseMove, чуть-чуть посложнее. Оно должно действительно убедиться, что мышь была сдвинута:

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Static Xlast, Ylast
Dim Xnow
Dim Ynow
'Получение текущей позиции
Xnow = X
Ynow = Y
'При первом перемещении, просто производится запись текущей позиции
If Xlast = 0 And Ylast = 0 Then
Xlast = Xnow
Ylast = Ynow
Exit Sub
End If
'Выход, если мышь действительно изменила свою позицию
If Xnow <> Xlast Or Ynow <> Ylast Then
QuitFlag = True
End If
End Sub


Ну и, наконец, событие Form_Unload, в котором происходит сообщение системе, что защитник неактивен.

Private Sub Form_Unload(Cancel As Integer)
Dim X
X = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, ByVal 0&, 0)
End Sub




Шаг 4. Самый важный. Обработаем событие Form_Load. Именно здесь определяется, как загружено наше приложение: в режиме просмотра или работы, запущен пароль или открыто окно настроек. Приложение "Свойства экрана" запрашивает это командной строкой. Поэтому и обработку мы должны выполнять, подразумевая, что оно запросило.

Но перед этим мы должны вначале послать сигнал системе, что приложение активно, т.е. еще раз использовать ту же API-функцию.

Private Sub Form_Load()
Dim X
X = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, ByVal 0&, 0)
...


Теперь займемся командной строкой. "Свойства экрана" используют следующие буквы для определения активности защитника экрана:

1. Р - просмотр
2. С - настройки
3. А - пароль
4. S - работа

Используем функцию Select … Case для отслеживания запроса:

Select Case UCase$(Left$(Command$, 2))
Case "/P"
'Обычная выгрузка после завершения просмотра
Unload Me
Exit Sub
Case "/C"
'Загрузка окна настроек (ее мы создадим чуть позже)
frmSSetup.Show vbModal
'Выгрузка всего приложения после изменения настроек
Unload Me
Exit Sub
Case "/A"
'Мы не будем создавать паролирование данного защитника,
'так как разбор вопросов кодирования и раскодирования
'слишком велик и должен представлять отдельную статью.
'Для желающих все-таки заняться паролированием: необходимо
'создать для этого отдельную форму или использовать InputBox,
'которые будут запускаться отсюда
MsgBox "Данный защитник не предусмотрен для паролей"
'Выгрузка всего приложения после изменения пароля
Unload Me
Exit Sub
Case "/S"
'Запускаем приложение
Show
'Следующая строка временная, в дальнейшем фон будет
'определяться из настроек
BackColor = vbBlack
'Скрываем курсор
X = ShowCursor(False)
'Зацикливаем процесс, до момента изменения флага
Do
DoEvents
Loop Until QuitFlag = True
'Если мы вышли из цикла, значит, приложение завершило свою
'работу. Мы показываем курсор и включаем таймер выхода из
'программы
X = ShowCursor(True)
tmrExit.Enabled = True
'Во всех остальных случаях – просто выгружаем приложение
Case Else
Unload Me
Exit Sub
End Select


NB! API-функция, скрывающая курсор, скрывает только его изображение. Поэтому событие MouseMove все равно будет работать.



Шаг 5. Займемся окном для настроек. Выберем меню Project/Add Form …, и в диалоговом окне выберем обычную форму. Изменим некоторые ее параметры:

Name=frmSSetup
BorderStyle=3 (Fixel Dialog)
Caption=Настройки
StartupPosition=2 (CenterScreen)

Добавим две кнопки. Первая:

Name=cmdOK
Default=True
Caption=ОК

И вторая:

Name=cmdCancel
Cancel=True
Caption=Отмена

Для каждой из кнопок введем код (в дальнейшем для кнопки ОК мы его расширим):

Unload Me

На этом создание "болванки" для защитника экрана можно считать законченным. Скомпилируйте промежуточную версию проекта.