Анимация
JavaScript
|
Главная Библионтека • 1 - нет загрузочного сектора; • 2 - устройство для сменного носителя данных; • 3 - жесткий диск; • 4 - сетевое устройство; • 5 - дисковод для лазерных дисков; • 6 - виртуальный диск. Эта функция поможет нам украсить список устройств соответствующим его типу изображением. Для определения готовности дисковода к записи нам потребуется еще одна функция, которая переопределяет реакцию операционной системы на критические ошибки, например, на отсутствие дискеты в дисководе при попытке записи: UINT SetErrorMode(UINT fuErrorMode); Эта функция возвращает предыдущую установку реакции на ошибки. В Visual FoxPro нет такого многообразия типов данных, как в Си ++, поэтому тип возвращаемого этими тремя функциями значения DWORD (двойное слово) или UINT (целое без знака) заменим имеющим 4 бита INTEGER. Теперь, проведя необходимую теоретическую подготовку, можно приступать к практическому созданию требуемого класса. В Project Manager при активной вкладке Classes щелкнем на кнопке New и в диалоговом окне New Class укажем название создаваемого класса, класс, на основании которого он создается, и имя библотеки, где он будет храниться. Будем надеяться, что к этому моменту у вас уже есть собственный набор классов и класс для списка в том числе. Дадим этому классу имя lstDrives и установим для него следующие свойства: • BoundColumn = 2 (две колонки); • ColumnLines = .F. (без разграничительных линий); • FontSize = 12 (размер шрифта, обычно лучше использовать 10, но отдельные буквы можно увеличить). Код для создания требуемого списка в событии Init может выглядеть следующим образом: * Определяем функцию для получения списка доступных * устройств DECLARE INTEGER GetLogicalDriveStrings IN Win32API AS GetDrive; INTEGER, STRING * Определяем функцию для определения типа устройства DECLARE INTEGER GetDriveType IN Win32API AS GetType; STRING * Описываем локальные переменные LOCAL cLetter, nLetter, NType, nDrivesNum * Резервируем строку для размещения списка доступных * устройств lpString=SPACE(200) * Определяем размер буфера для строки nBuffSize=LEN(lpString) * Получаем список устройств = GetDrive(nBuffSize,@lpString) * Определяем количество устройств nDrivesNum = OCCURS(":",lpString) * Получаем их имена FOR nLetter = 1 TO nDrivesNum cLetter = UPPER(" " + SUBSTR(lpString,AT(":",lpString,nLetter)-1,1)) • Определяем тип устройства nType = GetType(ALLTRIM(cLetter + ":\")) • Добавляем обозначение устройства (первая колонка) • и его тип (вторая колонка) в список This.AddItem(cLetter, nLetter, 1) This.List(nLetter, 2) = STR(nType) • Задаем соответствующее изображение DO CASE CASE NType = 2 This.Picture(nLetter) = "FLOPPY.BMP" CASE NType = 3 This.Picture(nLetter) = "DRIVE.BMP" CASE NType = 4 This.Picture(nLetter) = "NET.BMP" CASE NType = 5 This.Picture(nLetter) = "CDROM.BMP" ENDCASE ENDFOR Все необходимые файлы изображений вы найдете на дискете. Нам их пришлось создать заново, так как обширная библиотека изображений, поставляемая с Visual FoxPro, содержала подходящие изображения только в формате ICO 32x32. В подобных списках лучше смотрятся изображения 16x16. Впрочем, это легко сделать с помощью утилиты Imagedit из состава Visual FoxPro. Здесь только необходимо учесть, что при выводе изображения Visual FoxPro очень своеобразно обходится с белым цветом, считая, что его вообще нет. Если вы выведете изображение, содержащее белый цвет, например, на серую кнопку, то те места изображения, которые были белые, станут серыми. Для сохранения белого цвета для каждого изображения надо создать двойника - маску (файл с расширением MSK), в котором на месте белого цвета должен располагаться черный. В качестве примера этой операции можно руководствоваться изображениями, которые использует Wizard (Мастер) для графических кнопок управления в форме. В событии Click класса запишем следующий код: LOCAL cLetter cLetter = This.DisplayValue + ":" * Если устройством является дисковод для гибких дисков, * то проверяем наличие * дискеты с помощью метода IsDiskIn IF ALLTRIM(This.Value) = "2" IF This.IsDiskIn(cLetter) = .T. This.Parent.cmdOk.Enabled = .T. ELSE = MESSAGEBOX("Вставьте дискету в выбранное устройство !",0,; "Не готов дисковод") IF This.IsDiskIn(cLetter) = .T. This.Parent.cmdOk.Enabled = .T. ELSE This.Parent.cmdOk.Enabled = .F. ENDIF ENDIF RETURN ENDIF This.Parent.cmdOk.Enabled = .T. Для определения наличия дискеты в дисководе создадим в нашем классе путем выбора команды New Method в меню Class специальный метод IsDiskIn() и запишем в него следующий код: LPARAMETERS cDrive LOCAL lOldError * Регистрируем функцию SetErrorMode, которая определяет, * как ОС реагирует на некоторые критические ошибки, * в том числе дисковые операции DECLARE INTEGER SetErrorMode IN Win32API INTEGER * Определяем наличие и сохраняем имя обработчика ошибок lOldError = ON(ERROR) ON ERROR lDiskError = .T. * Задание функции SetErrorMode с аргументом 1 позволяет * приложению самому обрабатывать критические ошибки * вместо ОС nOldErrorState = SetErrorMode(1) * По умолчанию считаем, что ошибки нет, если не так, * значение будет изменено lDiskError = .f. * Пытаемся найти NUL файл в загрузочной области * указанного устройства lDriveState = FILE(cDrive + "\NUL") IF .NOT. lDiskError IF lDriveState lDriveOk = .t. ELSE lDriveOk = .f. ENDIF ELSE lDriveOk = .f. ENDIF * Восстанавливаем прежний обработчик ошибок IF .NOT. EMPTY(lOldError) ON ERROR DO (lOldError) ELSE ON ERROR ENDIF * Восстанавливаем реакцию на ошибки ОС nRestState = SetErrorMode(nOldErrorState) RETURN lDriveOk После этого класс списка можно помещать в любой требуемой форме. Во втором примере использования функций Windows API рассмотрим возможность ускорения выполнения графических операций. Сначала создадим форму, в которой будем выводить зигзагообразную линию средствами Visual FoxPro (используя метод Line). Для этого в методе Paint формы запишем следующий код: nY = 1 FOR nX = 5 TO 375 STEP 5 ThisForm.Line(nX, nY*100) nY = -nY ENDFOR Теперь попробуем такую же линию нарисовать средствами Windows API. В методе Paint второй формы запишем: *** Возвращает указатель на контекст указанного окна DECLARE INTEGER GetDC IN WIN32API INTEGER * HWND Указатель окна *** Стирает контекст указанного окна DECLARE INTEGER ReleaseDC IN WIN32API INTEGER, INTEGER * HWND Указатель окна * HDC Указатель контекста устройства *** Рисует линию с текущей позиции до указанных координат DECLARE INTEGER LineTo IN WIN32API INTEGER, INTEGER, INTEGER * HDC Указатель контекста устройства * int nXEnd x-координата конечной точки линии * int nYEnd y-координата конечной точки линии *** Обновляет текущее положение указанной точки DECLARE INTEGER MoveToEx IN WIN32API INTEGER, INTEGER, INTEGER, STRING * HDC Указатель контекста устройства * int X x-координата нового текущего положения * int Y y-координата нового текущего положения * LPPOINT адрес предыдущего положения (NULL in FoxPro) *** Функция GetFocus не имеет параметров и возвращает HWND активного окна DECLARE INTEGER GetFocus IN WIN32API mynull = .NULL. pmhand = GetFocus() IF pmhand<<>>0 && Если есть открытое активное окно hmdc = GetDC(pmhand) = MoveToEx(hmdc, 0, 0, mynull) nY = 1 FOR nX = 5 TO 375 STEP 5 = LineTo(hmdc, nX, nY*100) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 [ 102 ] 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |