Далее –на закладку Путь компоновки Java (см. рис.7.11). Слева в списке выбираем Путь компоновки Java.
Рис. 7.11
Здесь переходим на закладку Библиотеки (см. рис. 7.11), нажимаем кнопку Добавить внешние JAR (см. рис.7.11).
jna.jar и platform.jar –это внешниеjar-файлы.
Переходим в корень дискаC:\ и выбираем два jar-файла в списке. Нажимаем открыть (см. рис. 7.12):
Рис. 7.12
Видим в списке два новыхjar-файла (см. рис. 7.13):
Рис. 7.13
Нажимаем кнопку "Ok".Посмотрим структуру проекта. Добавились два внешних jar-файла (см. рис.7.14).
Рис. 7.14
Начиная с этого момента,функционал, находящийся в этих файлах,доступен в нашем приложении. По такому же принципу подключается и любая другая внешняя библиотека, необходимая для работы, если используется функционалJava, не включенный в стандартную поставку.
После подключения внешних jar-файлов для возможности задействовать новый функционал нужно подключить четыре строкиimport,Здесь содержатся необходимые нам классы из добавленныхjar-файлов.
После подключения новых четырёх строк, функционал, находящийся в подключаемых классах, стал доступен в приложении, как, например, функционал библиотеки javax.swing (выделен жирным шрифтом):
// Подключение необходимых библиотек
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Подключение библиотек для работы с JNA
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.win32.*;
// Главный класс
public class prog {
. . . . . .
Далее, для работы понадобится ещё несколько переменных, их нужно добавить к классу okno.
Некоторые переменные уже есть: переменная rTimer, текстовое полеtext и переменнаяflagExit–признак разрешения закрытия блокировщика. Переменная flagExit–переменная логического типа. При попытке закрытия приложения, если переменная flagExitустановлена в значении false,закрыть его будет невозможно. Зададим изменение значения этой переменной в тот момент, когда пользователь введёт правильное имя. Таким образом, приложение не закроется, flagExitне примет значение true. Добавим еще несколько переменных.
// Таймер
private Timer rTimer;
// Текстовое поле
private JTextArea text;
// Переменная-флаг -признак
// разрешения закрытия блокировщика
private boolean flagExit=false;
private HWND hWnd;
private int wWidth,wHeight;
Первая переменная–закрытого типа, private.Название переменной –hWnd.Название переменной может быть и другим, но тип переменной необходимо указать именноHWND.
Это тип данных,относящийся к так называемому, Windows APIили к WinAPI (см. рис. 7.15).
Рис. 7.15
Создавая операционную систему Windows,разработчики предоставили программистам некий функционал, называемый Windows API или, сокращенно,WinAPI.
Application Program Interface (сокращённо API) –список методов или команд, которые программист может вызывать в своих программах.
Программист, вызывая эти методы, может выполнять определенные задачи, например, так же, как в случае, когда мы добавляли библиотеку swingи вызывали методы работы с окном: setBounds, setVisible и т. д.
Windows API был написан на языке С/C++, а не на языке Java.
В этом функционале присутствуют новые типы данных, не связанные с языком Java. Один из таких типов данных –тип, называемыйДескриптором окна.
Дескриптор(если простыми словами) число, при помощи которого можно идентифицировать объект.
Пусть на рабочем столе открыто три окна. Условно: у первого окна дескриптор 1, у второго –2и, наконец, у третьего 3. По этому дескриптору, т. е. по значению, можно обратиться к нужному окну. У каждого окна уникальный дескриптор, однозначно идентифицирующий данное окно.
В нашем случае дескриптор будет идентифицировать окно блокировщика. Используя дескриптор, мы сможем к нему обратиться.
Обратите внимание, этот тип данных никак не связан с языком программирования Java, он входит в Windows API.
Данная тема заслуживает отдельного изучения, мы на ней подробно останавливаться не будем, используем этот функционал только для единичного случая–для решения определенной задачи. Добавили ещё две переменных: wWidth, wHeightцелого типа.
В этих переменных будут храниться размеры, устанавливаемые для окна блокировщика. Таким образом, мы работаем с окном блокировщика уже не средствами языка Java, а средствами Windows API.
Под объявлением переменных необходимо поместить следующий блок:
private HWND hWnd;
private int wWidth,wHeight;
public interface MyUser32 extends User32
{
static final MyUser32 instance=
(MyUser32) Native.loadLibrary("user32",
MyUser32.class,W32APIOptions.DEFAULT_OPTIONS);
public boolean SetWindowPos(HWND hwnd, int hwnd2, int arg1, int arg2, int arg3, int arg4, int flags);
public int EnableWindow(HWND hwnd, boolean enabled);
public HWND SetFocus(HWND hwnd);
}
Этот блок позволяет использовать методы, команды, находящиеся в Windows API.
Этот фрагмент программного кода можно сохранить и, в дальнейшем, использовать как своего рода рецепт, когда понадобится работать сWindows API.
Воспользуемся тремя методами, предоставленными разработчиками операционной системы Windows.
Первый метод, или первая команда, SetWindowPos–установить позицию окна. Она позволяет задать окну определённые координаты и размеры. В языкеJavaто же самое делает команда setBoundsиз библиотеки swing, мы её многократно использовали. SetWindowPos–это метод, или команда, Windows API, она никак не относится к языку программирования Java.
Вторая команда –EnableWindow. Она либо позволяет, либо запрещает окну принимать события от клавиатуры.
Если указывается значение true,окно может принимать события от клавиатуры, т. е. отслеживать нажимаемые клавиши.
Третья команда –SetFocus, установить или дать фокус окну. Окно, находящееся в фокусе,будет принимать события от клавиатуры.
Таким образом, этот блок позволяет использовать три команды изWindows API.
После указания каждой команды следует список параметров,находящийся внутри круглых скобок. Эти параметры используются вместе с командой.Вспомним, список этих параметров никак не относится к языку программирования Java, а команда создана разработчиками операционной системыWindows. Но этот функционал можно использовать в любом языке программирования, например (Cили из Delphi), - операционная система предоставляет его в пользование разработчикам для решения задач, связанных с операционной системой Windows.
Ниже добавим новый метод. Сделаем его закрытым и назовемsetAct.
Назначение методаsetAct–сделать окно активным. Метод возвращает значение void, т. е.он не имеет возвращаемого значения. Этот метод устанавливает необходимый размер окна, помещает его в определенное положение и располагает поверх всех других окон.
Именно метод setActбудет многократно вызываться при помощи таймера. Частота вызова –100раз в секунду, т. е.,100 раз в секунду окно блокировщика будет помещаться поверх всех других окон, и будут устанавливаться соответствующие размеры окна, достаточные для полного перекрытия экрана.
Внутри открывающей и закрывающей фигурных скобок метода setActосуществляется вызов следующих трёх методов WinAPI:
Первый метод –SetWindowPosпомещает окно в определённое положение и устанавливает его размеры. Параметры этого метода:
Следующий параметр,-1, указывает тип отображения окна и означает, что окно будет всегда размещаться поверх всех других окон, т. е. будет самым верхним.
При помощи следующих четырех параметров: 0, 0, wWidth, wHeightуказываются расположение и размеры окна,здесь такая схема параметров, как и вsetBoundsязыкаJava.
И последний параметр:0x0040|0x0002|0x0001отвечает за возможность окна отображаться в различных вариациях:максимально развёрнутым или свёрнутым,либо в обычном виде.
В нашем случае, этот параметр отображает окно блокировщика максимально развёрнутым, соответственно указанным значениям. Снова обратите внимание, эти значения не относятся напрямую к языку программирования Java, а принадлежатWinAPI, или Windows API.
Далее, вызывается методEnableWindow,позволяющий получать события от клавиатуры.
MyUser32.instance.EnableWindow(hWnd, true);
Первый его параметр:hWnd–дескриптор окна, как и в предыдущем методе. Второй параметр:true, означает,что окно может принимать события от клавиатуры. И, наконец, последний методSetFocus.
MyUser32.instance.SetFocus(hWnd);
У него есть единственный параметр –дескриптор окна,дающий окну фокус, т. е., окно может принимать события от клавиатуры. По умолчанию, если окно в фокусе, событие от клавиатуры поступает именно в это окно.
Таким образом, методsetAct100раз в секунду вызывает три описанные в нём команды,принадлежащие Windows API.
Обратите внимание,наименование MyUser32, описанное на предыдущем шаге,используется в дальнейшем при вызове методов Windows API.
public interface MyUser32 extends User32
{
. . . . . . .
Добавим строку в методsetWindow_(выделенную жирным шрифтом):
wWidth = dm.width;
wHeight = dm.height;
// Указываем заголовок окна
this.setTitle("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Отображение окна
setVisible(true);
Была добавлена строчка с присвоением имени testзаголовку окна. При помощи методаsetTitleуказывается название окна. У окна блокировщика заголовок простой –test. По заголовку всегда можно найти это окно при помощи методовWindows APIсреди других открытых окон. WinAPIпозволяет найти открытое окно по его названию, заголовку.
Дальше рассмотрим, как происходит проверка правильности введённого имени.
Имеется обработчик событий, срабатывающий при нажатии на кнопку, под названием actionPerformed.
В нём проверяется правильность введённого имени. Если пользователь правильно вводит имя, при помощи showMessageDialogему выводится сообщение: "Примите ещё раз наши поздравления!!!", и осуществляется выход из приложения. Здесь добавляем следующие две строки:
rTimer.stop();
MyUser32.instance.CloseWindow(hWnd);
// Вывод диалогового окна с сообщением
JOptionPane.showMessageDialog(null, "Еще раз поздравляем!!! Всего доброго!");
// Признак закрытия приложения устанавливаем
// в истину - закрытие окна - разрешено
flagExit=true;
Таймер работает постоянно, но после того как пользователь введёт правильное имя, имеет смысл остановить таймер.
rTimer.stop();
Далее вызывается методCloseWindow, тоже относящийся к Windows API.
MyUser32.instance.CloseWindow(hWnd);
В круглых скобках указывается дескриптор окна, т. е. окно закрывается.
Далее вводится поздравительное сообщение. Флаг выхода(значение переменной flagExit), контролирущий закрытие блокировщика, устанавливается в истинном значении. Пока значение переменной flagExitне станет равной true, закрыть приложение, будет невозможно.
Перейдём в конструктор класса окна и сделаем здесь также некоторые доработки.
// Конструктор класса окна
public okno()
{
// Подключение обработчика события при закрытии окна
Мы подключили обработчик событий под названием windowClosing. Этот обработчик срабатывает при закрытии приложения.
Например, если открыто окно Windows, при нажатии крестика в правом верхнем углу экрана,срабатывает метод windowClosing, окно закрывается. В этом методе мы будем контролировать возможность закрытия окна блокировщика. Если флаг выхода (flagExit) равен false, вызывается методsetWindow_и приложение закрываться не должно.Оно закрывается, если флаг выхода (flagExit) равен true, это происходит только при правильно введенном имени.
Если пользователь попытается закрыть окно блокировщика,например, нажав клавиши Alt+F4, позволяющие по умолчанию закрыть открытое окно, при отсутствии контроля приложение закроется.Чтобы не дать пользователю возможности закрыть окно каким бы то ни было способом,сделан контроль, т. е. блокировка окна при закрытии. При попытке закрытия окна вызывается метод setWindow_.
Метод setWindow_производит начальную настройку окна: устанавливает нужные размеры и выводит его на экран при помощи метода setVisible. Таким образом, если пользователь пытается закрыть окно, оно появляется вновь.
При помощи обработчиков событий можно отслеживать разные события,происходящие с окном.
Эта строка добавляется также в конструктор класса окна.
Данная строка связана функционалом Windows API.
Метод FindWindow (Find–найти, Window–окно) осуществляет поиск окна по его заголовку.
По значению заголовка окна testраспознаётся окно блокировщика и определяется его дескриптор. Метод FindWindowвозвращает дескриптор окна и помещает его в переменную hWnd,созданную в самом начале. Далее методыWindows APIбудут работать через дескриптор, т. е. все дальнейшие операции с окном будут осуществляться через обращение к его номеру, дескриптору.
Отображение заголовка окна на экране отключено при помощи методаsetUndecorated, тем не менее, окно все равно имеет этот заголовок.По названию заголовка можно найти окно,используя метод FindWindow.
Также в конструкторе делается настройка таймера, для этой цели добавлен стандартный фрагмент:
// Подключаем и запускаем таймер
rTimer = new Timer(10,new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
setAct();
}
});
rTimer.start();
Используется объявленная переменная rTimer–переменная типаTimer.
Важный параметр этого блока: время срабатывания таймера, десять тысячных секунды.
Соответственно, таймер будет срабатывать 100раз в секунду, 100раз в секунду окно блокировщика будет всплывать поверх всех остальных окон, и 100 раз в секунду ему будут устанавливаться необходимые размеры.
Метод actionPerformedсрабатывает при срабатывании таймера. Внутри методаactionPerformedвызывается метод setAct.
Перейдём к методуsetActи вспомним,метод setActвызывает три метода из Windows API: SetWindowPos, EnableWindowи SetFocus.
Таким образом,устанавливаются нужные размер и расположение окна, свойства– поверх других окон, а также, приём нажатых клавиш в данное окно.Запускаем таймер при помощи команды start.
Сохраним проект и запустим приложение на исполнение.Интерфейс не изменился.
Вызываем Диспетчер задач (Ctrl+Alt+Del).Окно диспетчераWindows появилось и сразу исчезло. Окно блокировщика перекрыло его сверху. При каждом повторном нажатии клавиш Ctrl+Alt+Delрезультат тот же –диспетчер задач открывается, но окно блокировщика мгновенно перекрывает его сверху (см. рис. 7.16).
Рис. 7.16
Пользователь теперь не сможет вызвать и любое другое приложение.Вводим правильное имя. Закрылся блокировщик –диспетчер задачWindowsоткрыт. На экране –наше поздравительное сообщение.
Теперь поздравительный блокировщик создан. Полностью программный код блокировщика выглядит так:
// Подключение необходимых библиотек
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Подключение библиотек для работы с JNA
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.win32.*;
// Главный класс
public class prog {
// Метод запуска приложения - точка входа в программу
public static void main(String[] args) {
// Создание окна
okno myOkno = new okno();
}
}
// Класс окна
class okno extends JFrame
{
// Таймер
private Timer rTimer;
// Текстовое поле
private JTextArea text;
// Переменная-флаг -признак
// разрешения закрытия блокировщика
private boolean flagExit=false;
private HWND hWnd;
private int wWidth,wHeight;
public interface MyUser32 extends User32
{
static final MyUser32 instance=
(MyUser32) Native.loadLibrary("user32",
MyUser32.class,W32APIOptions.DEFAULT_OPTIONS);
public boolean SetWindowPos
(HWND hwnd, int hwnd2, int arg1, int arg2, int arg3,int arg4, int flags);
public int EnableWindow(HWND hwnd, boolean enabled);
Для лучшего понимания,обсудим ещё раз смысл использования обработчика при закрытии. Запустим приложение.
У приложения нет рамки,нет заголовка окна и нет привычных кнопок,находящихся справа сверху (свернуть,развернуть, закрыть окно). Но существует сочетание клавиш Alt+F4, закрывающее окно и без этих кнопок.
Если не сделать контроль при закрытии окна, можно было бы сбросить блокировщик, используя эти клавиши. Обработчик при закрытии приложения блокирует эту возможность.
Создадим запускаемыйjar-архив, для возможности использования блокировщика в его конечном варианте.
Переходим к списку проектов, находим текущий проект, lesson18(см.рис. 7.17):
Рис. 7.17
Нажимаем правую клавишу и выбираем "Экспортировать"(см. рис. 7.18).
Рис. 7.18
В появившемся окне находим закладку Java, открываем и выбираем Runnable JAR file(см. рис. 7.19)- запускаемый jar-архив.
Рис. 7.19
Нажимаем кнопку"Далее". В верхней строке выбираем название нашего проектаlesson18(см. рис. 7.20).
Рис. 7.20
Указываем путь, место,куда будет помещён jar-архив. Называем его, например,blok (от слова блокировщик), указываем путь в корень дискаC:\.Путь записывается в строке Export destination. Настройку для подключения библиотек, используемых с данным проектом, под названием Library handling,помещаем во вторую позицию. При выборе переключателя"Package required libraries into generated JAR"(см. рис. 20)используемыебиблиотеки будут упакованы внутрь jar-архива. Нажимаем кнопку "Готово".В корне диска C:\появляется результат наших действий–архив blok.jar. Щёлкнем дважды на него мышкой –запустился блокировщик. Вызовем Диспетчер задач(Ctrl+Alt+Del). Диспетчер задач появляется и пропадает. Вводим имя и выходим из блокировщика.
Теперь обеспечим запуск блокировщика при запуске операционной системы Windows.Для этого нужно вписать блокировщик в реестр. Зайдём в редактор реестра.
Находим команду "Выполнить"(см. рис. 7.21)
Рис. 7.21
В строке "Открыть"укажем regedit(см. рис. 7.22).
Рис. 7.22
Открывается окно для редактирования реестра (см.рис. 7.23).
Рис. 7.23
Нужная ветка: HKEY_LOCAL_MACHINE(см. рис. 7.24).
Рис. 7.24
Сделав в ней некоторые настройки, можно запускать блокировщик для любого пользователя, загружающего данную операционную систему Windows.
Если эту настройку поместить в HKEY_CURRENT_USER, блокировщик будет появляться только для текущего пользователя.
Если нужно заблокировать компьютер для любого входящего пользователя, необходимо поместить эту настройку в ветку HKEY_LOCAL_MACHINE.
Далее, находим веткуSoftware(см. рис. 7.24), открываем.Внутри неё
находим ветку Microsoft(см. рис. 7.25), раскроем ее содержимое:
Рис. 7.25
Далее открываем веткуWindows(см. рис. 7.26).
Рис. 7.26
В ней находим веткуCurrentVersion (см. рис. 7.27).
Рис. 7.27
И, последнее, находим ветку Run (см. рис. 7.28).
Рис. 7.28
Здесь собраны автоматически запускаемые при стартеWindows программы,т. е. автозагрузка.
Добавим блокировщик в автозагрузку.
Для этого выделяем ветку Run,нажимаем правую клавишу, выбираем "Cоздать" и "Cтроковый параметр"(см. рис. 7.29).
Рис. 7.29
Название может быть произвольным. В нашем случае –blok (см. рис. 7.30).
Рис. 7.30
Далее, пропишем блокировщику путь.
Выбираем добавленное значение blok,нажимаем "Изменить"(см.рис. 7.31).
Рис. 7.31
Для появления этого окошка нужно нажать правую клавишу мыши и выбрать "Изменить".