Советы пользователям Delphi и C++Builder

Часть 2. Немного о внешних устройствах и операционной системе

Наталия Елманова

В данной статье содержатся советы, позволяющие решить некоторые из множества проблем, возникающих при использовании внешних устройств в приложениях Delphi и С++Builder.

Совет 1. Определение наличия дискеты или компакт-диска в дисководе

Нередко в процессе работы приложения следует произвести запись на дискету или считать данные с компакт-диска. Во избежание возникновения сообщений об ошибке при отсутствии диска или дискеты либо об отсутствии свободного места на диске следует определить, готово ли устройство и каков объем свободного пространства на нем.

Для получения информации о диске можно использовать функцию Windows API GetVolumeInformation. Эта функция возвращает информацию об имени и метке тома, а также о характеристиках его файловой системы.

Для получения информации о наличии свободного места на диске можно использовать функцию GetDiskFreeSpace. Эта функция возвращает информацию о числе свободных кластеров и секторов и о размерах сектора и кластера для данного диска. Число свободных байтов равно числу свободных кластеров, умноженному на число секторов в кластере и на число байтов в секторе.

Создадим простейший пример, определяющий тип устройства, его готовность и количество свободных байтов. На форму приложения поместим компонент TDriveComboBox со страницы Win31 и четыре метки (рис. 1).

Создадим обработчик события OnChange компонента TDriveComboBox. В случае C++Builder он выглядит следующим образом:

void __fastcall TForm1::DriveComboBox1Change(TObject *Sender) { DWORD VolSN,MaxCompLen,FSFlags, FC,SPC,BPS,NC; char VolName[255],FSName[100]; AnsiString s=UpperCase(DriveComboBox1->Drive)+”:\\”; Label1->Caption=s; if (GetVolumeInformation(s.c_str(),VolName,255,&VolSN,&MaxCompLen, &FSFlags,FSName,100)) { Label2->Caption=”Имя тома: “+AnsiString(VolName); Label3->Caption=”Файловая система: “+AnsiString(FSName); if (GetDiskFreeSpace(s.c_str(), &SPC,&FC,&BPS,&NC)) { Label4->Caption=”Свободных байт: “+IntToStr(SPC*FC*BPS); } else { Label4->Caption=””; } } else { Label2->Caption=”Диск не готов”; Label3->Caption=””; Label4->Caption=””; } }

В случае Delphi этот же обработчик события выглядит так:

procedure TForm1.DriveComboBox1Change(Sender: TObject);
var
 VolName: array [0..255] of char;
 FSName : array [0..100] of char;
 VolSN: PDWORD;
 MaxCompLen,FSFlags: Cardinal;
 FC,SPC,BPS,NC:DWORD;
 s: string;
begin
 VolSN:=nil;
 s:=UpperCase(DriveComboBox1.Drive)+’:\’;
 Label1.Caption:=s;
 if (GetVolumeInformation(PChar(s),VolName,255,
 VolSN, MaxCompLen, FSFlags,FSName,100)) then 
 begin
  Label2.Caption:=’Имя тома: ‘+AnsiString(VolName);
  Label3.Caption:=’Файловая система: ‘+AnsiString(FSName) ;
  if GetDiskFreeSpace(PChar(s),SPC,BPS,FC,NC) then
  Label4.Caption:=’Свободных байт: ‘+IntToStr(SPC*FC*BPS)
  else Label4.Caption:=’’
 end 
 else 
   begin
    Label2.Caption:=’Диск не готов’;
    Label3.Caption:=’’;
    Label4.Caption:=’’
   end;
end;

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

Совет 2. Получение сведений о видеорежиме

Приложения, активно использующие работу с графикой или видеофрагментами, нередко нуждаются в информации о текущем цветовом разрешении видеоадаптера. Каким образом можно получить такие сведения?

Обычно для этой цели применяется функция Windows API GetDeviceCaps, использующая в качестве входного параметра контекст графического устройства (каковым является экран). В данном примере мы воспользуемся обычной формой VCL для доступа к этому контексту, задействуя ее свойство Canvas.

В качестве второго параметра этой функции используется именованная целая константа, в зависимости от значения которой возвращается одно из значений, связанных с параметрами графического устройства. В данном случае нас интересуют цветовое разрешение в битах на пиксел и число поддерживаемых системой цветов. Последнее зависит от числа оттенков цвета. Число оттенков равно 2 в степени, равной цветовому разрешению в битах на пиксел. Число же поддерживаемых системой цветов равно числу оттенков, возведенному в степень, равную числу цветовых плоскостей. Следовательно, для вычисления числа поддерживаемых цветов функцию GetDeviceCaps следует вызвать дважды: один раз для получения информации о цветовом разрешении, другой раз – о числе цветовых плоскостей.

Создадим простейшее приложение для определения этих параметров. С этой целью поместим на форму кнопку и несколько меток (рис. 3).

Создадим обработчик события, связанный с нажатием на кнопку. В C++Builder он выглядит следующим образом:

void __fastcall 
         TForm1::Button1Click(TObject *Sender)
  {
   long int TC,BPP,CP,VR;
   BPP=GetDeviceCaps(Form1->Canvas->Handle,BITSPIXEL);
   CP=GetDeviceCaps(Form1->Canvas->Handle,PLANES);
   TC=pow(pow(2,BPP),CP);
   Label1->Caption=”Бит на пиксел: “+IntToStr(BPP);
   if (TC<3) 
   {
   Label2->Caption=”Монохромный дисплей “;
   } 
   else
   {
   Label2->Caption=”Число цветов: “+IntToStr(TC);
   } ;
  }

Аналогичный код для Delphi имеет вид:

procedure TForm1.Button1Click(Sender: TObject);
Var TC,BPP,CP,VR,x: integer; x2:real;
begin
   BPP:=GetDeviceCaps(Form1.Canvas.Handle,BITSPIXEL);
   CP:=GetDeviceCaps(Form1.Canvas.Handle,PLANES);
   x2:=intpower(2,BPP);
   x2:=intpower(x2,CP); TC:=round(x2);
   Label1.Caption:=’Бит на пиксел: ‘+IntToStr(BPP);
   if (TC<3) then Label2.Caption:=’Монохромный дисплей ‘ else
   Label2.Caption:=’Число цветов: ‘+IntToStr(TC);
end;

Запущенное приложение выглядит примерно как на рис. 4.

Помимо цветового разрешения и числа поддерживаемых цветов c помощью функции GetDeviceCaps можно получить много другой информации о графических устройствах, например о разрешении в пикселах на дюйм, числе поддерживаемых шрифтов и др. При работе в Windows NT можно даже определить частоту развертки монитора.

Совет 3. Получение сведений о частоте развертки монитора

Модифицируем ранее созданный пример, добавив определение типа операционной системы и, если это Windows NT, — определение частоты развертки. Для этого необходимо в первую очередь определить тип операционной системы.

Для этой цели воспользуемся функцией Windows API GetVersionEx. Но прежде чем ее вызвать, следует создать структуру типа OSVERSIONINFO, содержащую сведения об имени и версии операционной системы (подробное описание этой структуры можно найти в справке по функциям Windows API, поставляемой с обоими средствами разработки), и корректно определить ее размер с помощью функции sizeof.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 long int TC,BPP,CP,VR;
 OSVERSIONINFO OV;
 BPP=GetDeviceCaps(Form1->Canvas->Handle,BITSPIXEL);
 CP=GetDeviceCaps(Form1->Canvas->Handle,PLANES);
 TC=pow(pow(2,BPP),CP);
 Label1->Caption=”Бит на пиксел: “+IntToStr(BPP);
 if (TC<3)
 { 
 Label2->Caption=”Монохромный дисплей “;
 } 
 else
 {
 Label2->Caption=”Число цветов: “+IntToStr(TC); 
 } ;
 OV.dwOSVersionInfoSize=sizeof(OV);
 GetVersionEx(&OV);
 if (OV.dwPlatformId==VER_PLATFORM_WIN32_NT)
 {
 VR=GetDeviceCaps(Form1->Canvas->Handle,VREFRESH);
 Label3->Caption=”Частота развертки: “+IntToStr(VR)+” Гц”;
 }
 else
 {
 Label3->Caption=”Частота развертки не определяется в данной ОС”;
 }
}

Соответствующий код для Delphi выглядит так:

procedure TForm1.Button1Click(Sender: TObject);
Var TC,BPP,CP,VR,x: integer; x1,x2:real;
OV: TOSVersionInfo;
begin
BPP:=GetDeviceCaps(Form1.Canvas.Handle,BITSPIXEL);
CP:=GetDeviceCaps(Form1.Canvas.Handle,PLANES);
x2:=intpower(2,BPP);
x2:=intpower(x2,CP); TC:=round(x2);
Label1.Caption:=’Бит на пиксел: ‘+IntToStr(BPP);
if (TC<3) then Label2.Caption:=’Монохромный дисплей ‘ else
Label2.Caption:=’Число цветов: ‘+IntToStr(TC);
OV.dwOSVersionInfoSize:=SizeOf(OV);
GetVersionEx(OV);
if OV.dwPlatformID=VER_PLATFORM_WIN32_NT then begin
VR:=GetDeviceCaps(Form1.Canvas.Handle,VREFRESH);
Label3.Caption:=’Частота развертки: ‘+IntToStr(VR)+’ Гц’;
end else Label3.Caption:=’Частота развертки не определяется в данной ОС’;
end;

end.

Если запустить это приложение в операционной системе Windows NT, оно отобразит сведения о частоте развертки (рис. 5 и 6).

КомпьютерПресс 3'1999

1999 1 2 3 4 5 6 7 8 9 10 11 12
2000 1 2 3 4 5 6 7 8 9 10 11 12
2001 1 2 3 4 5 6 7 8 9 10 11 12
2002 1 2 3 4 5 6 7 8 9 10 11 12
2003 1 2 3 4 5 6 7 8 9 10 11 12
2004 1 2 3 4 5 6 7 8 9 10 11 12
2005 1 2 3 4 5 6 7 8 9 10 11 12
2006 1 2 3 4 5 6 7 8 9 10 11 12
2007 1 2 3 4 5 6 7 8 9 10 11 12
2008 1 2 3 4 5 6 7 8 9 10 11 12
2009 1 2 3 4 5 6 7 8 9 10 11 12
2010 1 2 3 4 5 6 7 8 9 10 11 12
2011 1 2 3 4 5 6 7 8 9 10 11 12
2012 1 2 3 4 5 6 7 8 9 10 11 12
2013 1 2 3 4 5 6 7 8 9 10 11 12
Популярные статьи
КомпьютерПресс использует