Excel. Трюки и эффекты
Шрифт:
Дополнительные (по сравнению с OS VERS ION INFO) поля структуры может заполнить ОС Windows NT 4.0 SP6 и более поздние версии Windows NT (в том числе 2000 и ХР). Значения дополнительных полей структуры OSVERSIONINFOEX пояснены комментариями в объявлении структуры.
Значение поля wSuiteMask (является битовой маской) может быть составлено из значений следующих констант (увы, но их объявления также пришлось добавить самостоятельно).
VER_SUITE_BACKOFFICE = 4; //Установлена Microsoft Back Office
VER_SUITE_DATACENTER = 128;//Установлена Microsoft Data Center
VER_SUITE_ENTERPRISE = 2; //Установлена ОС Windows 2000
//Advanced Server
VER_SUITE_SMALLBUSINESS = 1; //Установлена Microsoft Small
//Business Server
VER_SUITE_SMALLBUSINESS_RESTRICTED = 32; //Установлена
//ограниченная версия Microsoft
//Small Business Server
VER_SUITE_TERMINAL = 16; //Установлены терминальные службы
VER_SUITE_PERSONAL = 512; //Персональная версия ОС (типичный
//набор
Значение поля wProductType может быть одним из приведенных ниже (тип сетевой ОС и соответственно роль, которую компьютер с данной ОС может исполнять при подключении в сети):
VER_NT_WORKSTATION = 1; //Рабочая станция
VER_NT_DOMAIN_CONTROLLER = 2; //Контроллер домена
VER_NT_SERVER = 3; //Сервер
Чтобы можно было просто передавать в функцию GetVersionEx ссылку на структуру OSVERSIONINFOEX, а не OSVERSIONINFO, перегрузим эту функцию следующим образом:
function GetVersionEx(var lpVersionInformation: OSVERSIONINFOEX): BOOL;
stdcall; external kernel32 name \'GetVersionExA\
Теперь определение полной информации о версии ОС для случая Windows на платформе NT (выше NT 4.0 SP6) может выглядеть следующим образом (листинг 7.2) (часть, одинаковая с листингом 7.1, опущена).
Листинг 7.2.
Определение версии ОС (NT, 2000, ХР)
procedure TForm1.FormCreate(Sender: TObject);
var
info: OSVERSIONINFOEX;
item: TListItem;
suite, additional: String;
begin
//Получаем информацию о версии ОС
info.dwOSVersionInfoSize := SizeOf(info);
GetVersionEx(info);
//Заполняем список информацией об ОС
//…
//..версия о пакете обновлений
item := lvwVerInfo.Items.Add;
item.Caption := \'Версия ServicePack\
item.SubItems.Insert
(0, IntToStr(Integer(info.wServicePackMajor)) + \'.\' +
IntToStr(Integer(info.wServicePackMinor)));
//..комплекация ОС
suite := \'\
if info.wSuiteMask and VER_SUITE_BACKOFFICE <> 0 then
suite := suite + \'[Установлен Back Office] \
if info.wSuiteMask and VER_SUITE_DATACENTER <> 0 then
suite := suite + \'[Microsoft Data Center] \
if info.wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
suite := suite + \'[Windows 2000 Advanced Server] \
if info.wSuiteMask and VER_SUITE_SMALLBUSINESS <> 0 then
suite := suite + \'[Small Business Server] \
if info.wSuiteMask and VER_SUITE_SMALLBUSINESS_RESTRICTED <> 0
then
suite := suite + \'[Small Business Server, ограниченная версия] \
if info.wSuiteMask and VER_SUITE_TERMINAL <> 0 then
suite := suite + \'[Terminal Service] \
if info.wSuiteMask and VER_SUITE_PERSONAL <> 0 then
suite := suite + \'[Workstation Personal (не Professional)] \
item := lvwVerInfo.Items.Add;
item.Caption := \'Комплектация\
item.SubItems.Add(suite);
//..дополнительные сведения
additional := \'\
if info.wProductType and VER_NT_WORKSTATION <> 0 then
additional := additional + \'[Рабочая станция] \
if info.wProductType and VER_NT_DOMAIN_CONTROLLER <> 0 then
additional := additional + \'[Контроллер домена] \
if info.wProductType and VER_NT_SERVER <> 0 then
additional := additional + \'[Сервер] \
item := lvwVerInfo.Items.Add;
item.Caption := \'Дополнительно\
item.SubItems.Add(additional);
end;
Имя компьютера
Следующий простой пример (листинг 7.3) показывает, как можно определить сетевое имя компьютера. Функция ComputerName скрывает «прелести» работы со строковым буфером, который нужно передавать в API-функцию GetComputerName.
Листинг 7.3.
Определение сетевого имени компьютера
function ComputerName: String;
var
buffer: String;
len: Cardinal;
begin
len := MAX_COMPUTERNAME_LENGTH + 1;
SetLength(buffer, len);
if GetComputerName(PAnsiChar(buffer), len) <> False then
ComputerName := Copy(buffer, 1, len)
else
ComputerName := \'\
end;
Имя пользователя
Определить имя пользователя, от имени которого запущена программа (а точнее – вызывающий функцию поток), можно с использованием функции из листинга 7.4.
Листинг 7.4.
Определение имени пользователя
function UserName: String;
var
buffer: String;
len: Cardinal;
begin
len := 100; //Увы, но константы UNLEN в модуле Windows найти
//не удалось. Буфера такой длины должно хватить
SetLength(buffer, len);
if GetUserName(PAnsiChar(buffer), len)
<> False then
UserName := Copy(buffer, 1, len)
else
UserName := \'\
end;
Чаще всего приведенная в листинге 7.4 функция определяет пользователя, выполнившего вход в систему. Но если приложение запущено от имени другого пользователя (например, User при вошедшем пользователе Admin), то, соответственно, определяется имя пользователя User.
Состояние системы питания компьютера
Следующий
Для определения состояния системы питания компьютера используется API-функция GetSystemPowerStatus. Она заполняет структуру TSystemPowerStatus и в случае успеха возвращает ненулевое значение. Упомянутая структура имеет следующие поля:
TSystemPowerStatus = packed record
ACLineStatus : Byte; //Подключение к сети
//переменного тока
BatteryFlag : Byte; //Состояние батареи
//(уровень заряда и прочее)
BatteryLifePercent : Byte; //Оставшийся ресурс батареи (в %)
Reserved1 : Byte;
BatteryLifeTime : DWORD; //Оставшееся время (в сек.)
//работы батареи
BatteryFullLifeTime : DWORD; //Полное время (в сек.)
//работы батареи
end;
Если значения полей BatteryLifePercent, BatteryLif eTime, BatteryFull-Lif eTime предельно ясны, то извлечение информации из полей ACLineStatus и BatteryFlag можно посмотреть в листинге 7.5.
Листинг 7.5.
Определение состояния системы питания
procedure TForm1.LoadPowerStatus;
var
batFlags: String;
status: TSystemPowerStatus;
prof_info: THWProfileInfo;
begin
lvwPowerStatus.Clear;
//Получаем информацию о состоянии питания
ZeroMemory(Addr(status), SizeOf(status));
GetSystemPowerStatus(status);
//Заполняем список информацией о состоянии питания
//..подключение к сети
case status.ACLineStatus of
0: AddParam(\'Подключение к сети\', \'Отключен\');
1: AddParam(\'Подключение к сети\', \'Подключен\');
else AddParam(\'Подключение к сети\', \'Неизвестно\');
end;
//..заряд батареи (битовая маска)
if status.BatteryFlag and 1 <> 0 then batFlags := \'Высокий \
if status.BatteryFlag and 2 <> 0 then batFlags := batFlags +
\'Низкий \
if status.BatteryFlag and 4 <> 0 then
batFlags := batFlags + \'Критический \
if status.BatteryFlag and 8 <> 0 then
batFlags := batFlags + \'(Идет зарядка)\
if status.BatteryFlag and 128 <> 0 then
batFlags := batFlags + \'Батарея не установлена\
if status.BatteryFlag = 255 then batFlags := batFlags + \'Не-
известно\
AddParam(\'Заряд батареи\', batFlags);
//..численные характеристики батареи
if status.BatteryLifePercent <> 255 then
AddParam(\'Остаток заряда батареи\',
IntToStr(Integer(status.BatteryLifePercent)))
else
AddParam(\'Остаток заряда батареи\', \'Неизвестно\');
if status.BatteryLifeTime <> Cardinal(–1) then
AddParam(\'Время работы батареи (остаток, сек.)\',
IntToStr(Integer(status.BatteryLifeTime)))
else
AddParam(\'Время работы батареи (остаток, сек.)\', \'Неизвестно\');
if status.BatteryFullLifeTime <> Cardinal(–1) then
AddParam(\'Полное время работы батареи, сек.\',
IntToStr(Integer(status.BatteryFullLifeTime)))
else
AddParam(\'Полное время работы батареи, сек.\', \'Неизвестно\');
end;
В листинге 7.5 для отображения каждого параметра системы питания вызывается процедура AddParam, добавляющая в элемент управления формы название параметра и его значение. Этим элементом управления может быть, например, ListView. Для такого случая возможный результат работы процедуры LoadPowerStatus показан на рис. 7.2.
Рис. 7.2. Собранная информация о системе питания
В нашем случае можно заключить, что программа испытывалась на компьютере, хоть и снабженном аккумулятором, но с явно недоделанной системой питания.
И последние несколько слов о том, когда рассмотренный пример может реально пригодиться. А пригодится он в случае, если ваше приложение оперирует большим объемом важных данных, на сохранение которых требуется длительное время и потеря которых может принести большие неприятности. Тогда при обнаружении разрядки батареи приложение может сохранить (а точнее, длительное время сохранять) данные на диск до лучших времен, например, до тех пор, пока питание вновь не будет включено, а заряд батареи не достигнет требуемого значения.
Состояние памяти компьютера
Получение снимка текущего состояния памяти компьютера также является несложной задачей. Недаром эту информацию многие приложения, тот же Блокнот, выводят в окне О программе: заполнить форму чем-то надо, а сведения об объеме памяти кажутся довольно актуальными.
Итак, получить состояние памяти компьютера можно при помощи API-функции GlobalMemoryStatus. Данная функция принимает в качестве параметра структуру TMemoryStatus, заполняет ее поля значениями и в случае успеха возвращает отличное от нуля число. Объявление структуры TMemoryStatus с комментариями роли ее полей приводится ниже:TMemoryStatus = record
dwLength: DWORD; //Размер структуры (байт)
dwMemoryLoad: DWORD; //Процент загрузки физической памяти
dwTotalPhys: DWORD; //Полный объем физической памяти
dwAvailPhys: DWORD; //Объем свободной оперативной памяти
dwTotalPageFile: DWORD; //Полный объем файла подкачки
dwAvailPageFile: DWORD; //Объем свободного пространства
//в файле подкачки
dwTotalVirtual: DWORD; //Полный объем виртуальной памяти
dwAvailVirtual: DWORD; //Объем свободной виртуальной памяти
end;