Считываем информацию из реестра о наличии соединения с интернетом
Звонит любовник любовнице:
- Давай встретимся.
- Давай.
- А где?
- Давай у меня дома.
- А муж?
- А его сейчас нет, он в интернете.
Информация о том, есть ли в данный момент соединение с Интернетом, лежит в реестре. Если каждую секунду считывать это значение, то можно определить, когда соединение было установлено и разорвано. При этом чтение их реестра не будет сильно загружать компьютер - весь HKEY_LOCAL_MACHINE лежит в памяти и обращение к диску не понадобится. Естественно, здесь опять понадобится резидентная программа.
Для работы с реестром здесь используются непосредственно функции WinAPI. Это позволяет сэкономить память и ускорить проверку соединения. При изменении соединения вызывается процедура InetConnectionChange. Таким образом, чтобы изменить действия программы, достаточно переписать эту процедуру. Эта программа при соединении с Интернетом создает tray. В его меню включены пункты открыть страницу http://program.dax.ru и послать письмо на program@dax.ru с темой subscribe. При выходе из Интернета tray исчезае
program Project1;
uses
Windows, ShellAPI, Messages;
const
ClassName = 'MyResident'; // Имя класса{ Это сообщение будет генерироваться при событиях с tray }
WM_NOTIFYTRAYICON = WM_USER + 1;
var
menu: hMenu = 0; // Всплывающее меню
mywnd: hWnd; // Окно программы
reg: HKEY;
connection: longint;
// Создание всплывающего меню:function CreateMyMenu: hMenu;
begin
result := CreatePopupMenu;
if result = 0 then
Exit;
AppendMenu(result, MF_STRING, 0, 'site');
AppendMenu(result, MF_STRING, 1, 'letter');
AppendMenu(result, MF_SEPARATOR, 2, nil);
AppendMenu(result, MF_STRING, 3, 'Exit');
end;
// Создание Tray:procedure CreateTray;
var
tray: TNotifyIconData;
beginwith tray dobegin
cbSize := sizeof(TNotifyIconData);
wnd := mywnd;
uID := 0;
uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
uCallBackMessage := WM_NOTIFYTRAYICON;
hIcon := LoadIcon(0, IDI_ASTERISK);
szTip := ('My Resident');
end;
Shell_NotifyIcon(NIM_ADD, @tray);
end;
// Удаление tray:procedure DeleteTray;
var
tray: TNotifyIconData;
beginwith tray dobegin
cbSize := sizeof(TNotifyIconData);
wnd := mywnd;
uID := 0;
end;
Shell_NotifyIcon(NIM_DELETE, @tray);
end;
// Изменение соединенияprocedure InetConnectionChange(connecting: boolean);
beginif connecting thenbegin
CreateTray; // Создание tray
menu := CreateMyMenu; // Создание мунюendelsebegin
DestroyMenu(menu); // удалить мнею
DeleteTray; // удалить tray
menu := 0;
end;
end;
// Главная оконная процедура:function MyWndProc(wnd: hWnd; msg, wParam,
lParam: longint): longint; stdcall;
var
p: TPoint;
DataType, DataSize: cardinal;
begincase msg of
WM_TIMER:
begin// проверка соединения:
DataSize := 4;
if RegQueryValueEx(reg, 'Remote Connection', nil, @DataType,
@connection, @DataSize) <> ERROR_SUCCESS then
MessageBeep(0);
if (connection = 0) <> (menu = 0) then
InetConnectionChange(connection > 0);
result := 0;
end;
WM_NOTIFYTRAYICON:
begin// Событие tray// Если нажата правая кнопка, показать меню:if lparam = WM_RBUTTONUP thenbegin
SetForegroundWindow(mywnd);
GetCursorPos(p);
TrackPopupMenu(menu, TPM_LEFTALIGN, p.x, p.x, 0, wnd, nil);
end;
result := 0;
end;
WM_COMMAND:
begin// Выбран пункт меню{ В зависимости от выбранного пункта меню открывается
program.dax.ru в браузере или создается письмо или
закрывается программа: }case loword(wparam) of
0: ShellExecute(hinstance, nil, 'http://program.dax.ru/',
nil, nil, SW_SHOWNORMAL);
1: ShellExecute(hinstance, nil,
'mailto:program@dax.ru?subject=subscribe',
nil, nil, SW_SHOWNORMAL);
else
SendMessage(mywnd, WM_CLOSE, 0, 0);
end;
result := 0;
end;
WM_DESTROY:
begin// Закрытие программы
DeleteTray; // Удаление Tray
PostQuitMessage(0);
result := 0;
end;
else
result := DefWindowProc(wnd, msg, WParam, LParam);
end;
end;
// Создание окна:function CreateMyWnd: hWnd;
var
wc: WndClass;
begin// Регистрация класса:
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @MyWndProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := LoadIcon(hinstance, IDI_ASTERISK);
wc.hCursor := LoadCursor(hinstance, IDC_ARROW);
wc.hbrBackground := COLOR_INACTIVECAPTION;
wc.lpszMenuName := nil;
wc.lpszClassName := ClassName;
if RegisterClass(wc) = 0 then
halt(0);
// Создание окна:
result := CreateWindowEx(WS_EX_APPWINDOW, ClassName,
'My Window', WS_POPUP, 100, 100, 200, 200, 0, 0, hInstance, nil);
if result = 0 then
halt(0);
end;
var
msg: TMsg;
begin
mywnd := CreateMyWnd; // Создание окна// Установка низкого приоритета:
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_IDLE);
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'System\CurrentControlSet\Services\RemoteAccess', 0,
KEY_NOTIFY, reg) <> ERROR_SUCCESS then
halt(0);
SetTimer(mywnd, 0, 1000, nil); // Создание таймера// Распределение сообщений:while (GetMessage(msg, 0, 0, 0)) dobegin
TranslateMessage(msg);
DispatchMessage(msg);
end;
KillTimer(mywnd, 0); // Удаление таймера
RegCloseKey(reg); // Закрытие раздела реестраend.
Программа Delphi, которая создает резидентное приложение, мониторирующее статус интернет-соединения и отображающее иконку в трее с пунктами меню для открытия веб-страницы или отправки электронной почты при активном соединении.
Вот разбивка кода:
Программа использует функции WinAPI для взаимодействия с реестром и системными сервисами.
Процедура InetConnectionChange вызывается каждый раз, когда изменяется статус интернет-соединения. Она создает или уничтожает иконку в трее и пункты меню соответственно.
Процедура CreateTray создает иконку в трее с подсказкой и настраивает обработчик сообщений (WM_NOTIFYTRAYICON) для обрабатывания кликов по иконке в трее.
Процедура DeleteTray удаляет иконку в трее, когда она больше не нужна.
Функция MyWndProc является процедурой окна основного программного окна. Она обрабатывает различные сообщения, включая события таймера, уведомления о клике по иконке в трее и выбор пунктов меню.
Функция CreateMyMenu создает всплывающее меню с тремя пунктами: "site", "letter" и "Exit".
Функция CreateMyWnd создает основное программное окно с помощью функций RegisterClass и CreateWindowEx.
Программа также включает в себя обработку ошибок для операций реестра и настраивает таймер для проверки статуса интернет-соединения каждую секунду.
Некоторые предложения по улучшению:
Вместо использования функции halt(0), рассмотрите более элегантные способы обрабатывания ошибок, такие как поднятие исключений или логирование ошибок.
Рассмотрите использование более описательных имен переменных и комментариев для улучшения читаемости кода.
Программа использует фиксированный интервал (1000 миллисекунд) для проверки статуса интернет-соединения. Вам может потребоваться изменение этого значения в зависимости от вашей конкретной задачи.
Функция RegOpenKeyEx используется для открытия ключа реестра, но она не закрывается, когда больше не нужна. Рассмотрите использование функции RegCloseKey для освобождения системных ресурсов.
В целом, программа кажется хорошо структурированной и легко понятной. С некоторыми минорными изменениями она может стать еще более robust и maintainable.
Считывая информацию из реестра о наличии соединения с интернетом, программа может определять момент установления и разрыва соединения, а также изменять свое поведение в зависимости от состояния соединения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.