Советы пользователям 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