Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11631
Последний выпуск: 19.06.2015

Применение функций Windows API

Автор: Вячеслав Клепинин
ИФ Гортис, Санкт-Петербург

В этом разделе вы познакомитесь с некоторыми полезными Windows API функциями. Для каждой функции сначала приводится её прототип на Си, а затем - объявление на Visual FoxPro и примеры использования.

Функции LoadKeyboardLayout и UnloadKeyboardLayout

Функция LoadKeyboardLayout из библиотеки User32.dll загружает новую языковую раскладку клавиатуры. Вот её прототип:

 
 HKL LoadKeyboardLayout(
	LPCTSTR pwszKLID, // Наименование загружаемой языковой раскладки 
	UINT Flags        // Флаг
	);
 

Объявление функции в Visual FoxPro:

 
 DECLARE Long LoadKeyboardLayout IN WIN32API String KLID, Long Flags
 

Функция возвращает дескриптор раскладки клавиатуры (32-х разрядное целое) или ноль в случае ошибки.

Передаваемый функции параметр KLID определяет язык раскладки клавиатуры. Вот некоторые допустимые значения параметра:

Параметр KLID Описание
 "00000407"  Немецкий (стандартный)
 "00000409"  Английский (США)
 "0000040C"  Французский (стандартный)
 "0000040D"  Финский
 "00000410"  Итальянский
 "00000415"  Польский
 "00000419"  Русский
 "00000422"  Украинский
 "00000423"  Белорусский
 "00000425"  Эстонский
 "00000426"  Латвийский
 "00000427"  Литовский

Второй параметр, Flags,  указывает, как будет загружаться раскладка клавиатуры. Для приложений на Visual FoxPro его значение всегда равно единице.

Для удаления клавиатурной раскладки используется функция UnloadKeyboardLayout. Она так же находится в библиотеке User32.dll. Вот её прототип:

 
 BOOL UnloadKeyboardLayout(
	HKL hkl // Дескриптор раскладки клавиатуры
	);
 

Объявление функции в Visual FoxPro:

 
 DECLARE Long UnloadKeyboardLayout IN WIN32API Long hkl
 

Передаваемый функции параметр hkl - дескриптор выгружаемой клавиатурной раскладки. Функция возвращает отличное от нуля значение при успешном выполнении или ноль в случае ошибки.

В следующем примере загружается раскладка клавиатуры для немецкого языка:

 
 HKL = LoadKeyboardLayout("00000407", 1)
 

В следующем примере показано, как удалить существующую раскладку клавиатуры:

 
 UnloadKeyboardLayout(HKL)
 

  

Функция GetLocalTime

Функция GetLocalTime из библиотеки Kernel32.dll возвращает текущие дату и время в формате UTC (Universal Time Coordinated). Вот её прототип:

 
 VOID GetLocalTime(
	LPSYSTEMTIME lpSystemTime // Адрес структуры SystemTime
	);
 

Тип данных LPSYSTEMTIME - это указатель на структуру SystemTime:

 
 typedef struct _SYSTEMTIME {
	WORD wYear; 		// Год
	WORD wMonth; 		// Месяц
	WORD wDayOfWeek; 	// День недели
	WORD wDay; 		// День месяца 
	WORD wHour; 		// Часы
	WORD wMinute; 		// Минуты
	WORD wSecond; 		// Секунды
	WORD wMilliseconds; 	// Миллисекунды
	} SYSTEMTIME;
 

Как видите, все поля структуры - это 16-ти разрядные целые числа. Месяцы нумеруются начиная с единицы, то есть для января wMonth=1 и так далее. Номера дней недели начинаются с нуля, то есть для воскресенья wDayOfWeek=0, для понедельника wDayOfWeek=1, и так далее.

Функция GetLocalTime не возвращает никаких значений. Вот её объявление в Visual FoxPro:

 
 DECLARE GetSystemTime IN WIN32API String @ SystemTime
 

В следующем примере показан код функции LocalTime. Функция получает массив, переустанавливает его размер и заполняет его элементы значениями даты и времени:

 
 FUNCTION LocalTime
 PARAMETERS taTimeArray
    EXTERNAL ARRAY taTimeArray
    DIMENSION taTimeArray[8]
    DECLARE GetLocalTime IN WIN32API String @
    LOCAL lcSystemTime				&& Для структуры SYSTEMTIME
    lcSystemTime = REPLICATE(CHR(0), 16)	&& Размечаем память для структуры
    GetLocalTime(@lcSystemTime)			&& Заполняем поля структуры
 * Заполняем переданный функции массив значениями полей структуры
    taTimeArray[1] = CTOBIN(LEFT(lcSystemTime,2), '2RS')	&& Год
    taTimeArray[2] = CTOBIN(SUBSTR(lcSystemTime,3,2), '2RS')	&& Месяц
    taTimeArray[3] = CTOBIN(SUBSTR(lcSystemTime,5,2), '2RS')	&& День недели
    taTimeArray[4] = CTOBIN(SUBSTR(lcSystemTime,7,2), '2RS')	&& День месяца
    taTimeArray[5] = CTOBIN(SUBSTR(lcSystemTime,9,2), '2RS')	&& Часы
    taTimeArray[6] = CTOBIN(SUBSTR(lcSystemTime,11,2), '2RS')	&& Минуты
    taTimeArray[7] = CTOBIN(SUBSTR(lcSystemTime,13,2), '2RS')	&& Секунды
    taTimeArray[8] = CTOBIN(SUBSTR(lcSystemTime,15,2), '2RS')	&& Миллисекунды
    RETURN
 ENDFUNC
 

Пример вызова функции LocalTime из вашего приложения:

 
 LOCAL laTime[1], laDayOfWeek[7], laMonth[12], lcResult
 laDayOfWeek[1] = 'воскресенье'
 laDayOfWeek[2] = 'понедельник'
 laDayOfWeek[3] = 'вторник'
 laDayOfWeek[4] = 'среда'
 laDayOfWeek[5] = 'четверг'
 laDayOfWeek[6] = 'пятница'
 laDayOfWeek[7] = 'суббота'

 laMonth[1] = 'января'
 laMonth[2] = 'февраля'
 laMonth[3] = 'марта'
 laMonth[4] = 'апреля'
 laMonth[5] = 'мая'
 laMonth[6] = 'июня'
 laMonth[7] = 'июля'
 laMonth[8] = 'августа'
 laMonth[9] = 'сентября'
 laMonth[10] = 'октября'
 laMonth[11] = 'ноября'
 laMonth[12] = 'декабря'

 = LocalTime(@laTime)
 lcResult = 'Сейчас ' + STR(laTime[4],2) + ' ' + laMonth[laTime[2]] + ;
	    STR(laTime[1],4) + ' года, ' + laDayOfWeek[laTime[3]+1] + CHR(13) + ;
	    LTRIM(STR(laTime[5])) + ' час ' + LTRIM(STR(laTime[6])) + ' мин'
 = MESSAGEBOX(lcResult)
 

Обратите внимание: массив laTime передаётся по ссылке.

Функция GetTickCount

Функция GetTickCount из библиотеки Kernel32.dll возвращает количество миллисекунд, прошедшее с момента запуска системы. Минимальный интервал времени в Windows - около 55 миллисекунд. Вот её прототип:

 
 DWORD GetTickCount(VOID)
 

Объявление функции в Visual FoxPro:

 
 DECLARE Long GetTickCount IN WIN32API

Пример вызова функции из вашего приложения:

 
 nMilliSeconds = GetTickCount()
 

Функция GlobalMemoryStatus

Функция GlobalMemoryStatus из библиотеки Kernel32.dll предоставляет информацию об использовании физической и виртуальной памяти компьютера. Вот её прототип:

 
 VOID GlobalMemoryStatus(
	LPMEMORYSTATUS lpBuffer // Адрес структуры MemoryStatus
	);
 

Тип данных LPMEMORYSTATUS - это указатель на структуру MemoryStatus:

 
 typedef struct _MEMORYSTATUS {
	DWORD dwLength; 	// Размер структуры
	DWORD dwMemoryLoad;	// Процент использования памяти
	DWORD dwTotalPhys;	// Физическая память, байт
	DWORD dwAvailPhys;	// Свободная физическая память, байт
	DWORD dwTotalPageFile;	// Размер файла подкачки, байт
	DWORD dwAvailPageFile;	// Свободных байт в файле подкачки
	DWORD dwTotalVirtual;	// Виртуальная память, используемая процессом 
	DWORD dwAvailVirtual;   // Свободная виртуальная память
	} MEMORYSTATUS, *LPMEMORYSTATUS;
 

Функция не возвращает никаких значений. Вот её объявление в Visual FoxPro:

 
 DECLARE GlobalMemoryStatus IN WIN32API String @ MemoryStatus
 

В следующем примере показан код функции GlobalMemory, которая вызывает Windows API функцию GlobalMemoryStatus и заполняет массив taMemoryStatus данными из структуры MemoryStatus:

 
 FUNCTION GlobalMemory
 PARAMETERS taMemoryStatus
    EXTERNAL ARRAY taMemoryStatus
    DIMENSION taMemoryStatus[7]
    LOCAL lcMemoryStatus
    DECLARE GlobalMemoryStatus IN WIN32API String @
    lcMemoryStatus = CHR(32) + REPLICATE(CHR(0), 31)	&& Подготовка структуры
    GlobalMemoryStatus(@lcMemoryStatus)
    taMemoryStatus[1] = CTOBIN(SUBSTR(lcMemoryStatus,5,4), '4RS') 
    taMemoryStatus[2] = CTOBIN(SUBSTR(lcMemoryStatus,9,4), '4RS')
    taMemoryStatus[3] = CTOBIN(SUBSTR(lcMemoryStatus,13,4), '4RS')
    taMemoryStatus[4] = CTOBIN(SUBSTR(lcMemoryStatus,17,4), '4RS')
    taMemoryStatus[5] = CTOBIN(SUBSTR(lcMemoryStatus,21,4), '4RS')
    taMemoryStatus[6] = CTOBIN(SUBSTR(lcMemoryStatus,25,4), '4RS')
    taMemoryStatus[7] = CTOBIN(SUBSTR(lcMemoryStatus,29,4), '4RS')
    RETURN
 ENDFUNC
 

Структура MemoryStatus формируется в переменной lcMemoryStatus. В первое поле структуры заносится значение её длины (32 байта). Остальные поля заполняются нулями. 

После выполнения функции GlobalMemoryStatus структура MemoryStatus "расшифровывается" при помощи функции CTOBIN.

Пример вызова функции GlobalMemory из вашего приложения:

 
 LOCAL lcInfo, laMemoryStatus[1]
 DECLARE GlobalMemoryStatus IN WIN32API String @
 GlobalMemory(@laMemoryStatus)
 lcInfo = 'Физическая память, байт: ' + LTRIM(STR(laMemoryStatus[2])) + ;
	  ', свободно: ' + LTRIM(STR(laMemoryStatus[3])) + CHR(13) + ;
	  'Виртуальная память, байт: ' + LTRIM(STR(laMemoryStatus[6])) + ;
	  ', свободно: ' + LTRIM(STR(laMemoryStatus[7]))
 = MESSAGEBOX(lcInfo)
 

Функция Sleep

Функция Sleep из библиотеки Kernel32.dll приостанавливает выполнение приложения на указанное количество миллисекунд. Вот её прототип:

 
 VOID Sleep(
	DWORD dwMilliseconds // "Время сна" в миллисекундах 
	);
 

А вот объявление этой функции в Visual FoxPro:

 
 DECLARE Sleep IN WIN32API Long Milliseconds
 

Пример вызова функции Sleep из вашего приложения:

 
 FUNCTION ToSleep(tnMilliseconds)
    DECLARE Sleep IN WIN32API Long
    Sleep(tnMilliseconds)
 ENDFUNC
 

Функции для работы с GUID

GUID (Global Unique ID), он же UUID, он же ClsID - глобальный идентификатор, представляющий собой двоичный тип данных длиной 16 байт. Microsoft гарантирует уникальность значения GUID на всей Земле в течение обозримого будущего. В Windows существует достаточное количество функций, генерирующих и преобразующих значения уникальных идентификаторов. Здесь мы рассмотрим три из них:

  • CoCreateGUID
  • StringFromGUID2
  • CLSIDFromString

Эти функции находятся в библиотеке Ole32.dll.

Функция CoCreateGUID генерирует новое значение GUID в виде двоичной строки длиной 16 байт. Вот её прототип:

 
 HRESULT CoCreateGuid(
	GUID *pguid // Указатель на строку с GUID
	);
 

Объявление функции в Visual FoxPro:

 
 DECLARE Long CoCreateGuid IN Ole32.dll String @ guid
 

Функция возвращает ноль при успешном выполнении либо отличное от нуля значение в случае ошибки. 

Пример использования функции:

 
 lqGUID = REPLICATE(CHR(0), 16))
 nReturn = CoCreateGuid(@lqGUID)
 

Полученное значение может быть использовано как уникальный индекс. Хранить такие индексы можно в полях таблиц типа Character Binary.

Функция StringFromGUID2 преобразует двоичное значение GUID в его символьное представление, которое, например, может выглядеть так: {c200e360-38c5-11ce-ae62-08002b2b79ef}. Вот её прототип:

 
 int StringFromGUID2(
	REFGUID rguid,	// Двоичное значение GUID
	LPOLESTR lpsz,	// Указатель на строку с символьным
                            // значением GUID (в Unicode)
	int cchMax 	// Количество 16-ти битовых символов в строке
	);
 

Объявление этой функции в Visual FoxPro выглядит так:

 
 DECLARE Long StringFromGUID2 IN Ole32.dll String guid,
         String @ unicodeGuid, Integer cchMax
 
Функция возвращает количество символов, включая нулевой завершающий символ, в случае успешного выполнения, и ноль, если произошла ошибка.

Формируемое функцией символьное представление GUID может быть использовано, например, для формирования веток ClsID в реестре Windows. Ниже показан пример кода функции GuidToString, показывающий применение функции StringFromGUID2. Функция получает двоичное значение уникального идентификатора и возвращает его символьное представление. 

 
 FUNCTION GuidToString(tqGuid)
    LOCAL unicodeGuid, lnResult
    DECLARE Long StringFromGUID2 IN Ole32.dll String, String @, Integer
    unicodeGuid = REPLICATE(CHR(0), 80)
    lnResult = StringFromGUID2(qGuid, @unicodeGuid, 40)
    IF lnResult > 0
	RETURN STRCONV(LEFT(unicodeGuid,(lnResult-1)*2,6)
    ELSE
	RETURN ''
    ENDIF
 ENDFUNC
 

Так как функция StringFromGUID2 при работе с символьными строками использует формат Unicode, то применяем функцию STRCONV для конвертирования результата в формат ANSI.

Функция CLSIDFromString преобразует символьное представление уникального идентификатора в двоичную 16-ти байтовую строку. Вот её прототип:

 
 HRESULT CLSIDFromString(
	LPOLESTR lpsz, // Указатель на строку с символьным представлением GUID
	LPCLSID pclsid // Указатель на строку с двоичным представлением GUID 
	);
 

Объявление функции в Visual FoxPro:

 
 DECLARE Long CLSIDFromString IN Ole32.dll String unicodeGuid, String @ qGuid
 

Функция возвращает ноль при успешном выполнении и отличное от нуля значение в случае ошибки.

Вот пример кода функции StringToGuid, показывающий применение функции CLSIDFromString. Функция получает символьное представление уникального идентификатора и возвращает его двоичное значение:

 
 FUNCTION StringToGuid(tcGuid)
    LOCAL lqGUID, lnResult
    DECLARE Long StringToGuid IN Ole32.dll String, String @
    lqGUID = REPLICATE(CHR(0), 16)
    lnResult = StringToGuid(STRCONV(tcGuid,5), @lqGUID)
    IF lnResult = 0
	RETURN lqGuid
    ELSE
	RETURN ''
    ENDIF
 ENDFUNC
 

Функция ShellExecute

Функция ShellExecute из библиотеки Shell32.dll выполняет операцию над указанным файлом. Вот её прототип:

 
 HINSTANCE ShellExecute(
	HWND hwnd,
	LPCTSTR lpOperation,
	LPCTSTR lpFile,
	LPCTSTR lpParameters,
	LPCTSTR lpDirectory,
	INT nShowCmd 
	);
 

Объявление функции в Visual FoxPro:

 
 DEСLARE Long ShellExecute IN Shell32.dll Long hwnd, String Operation, String File, ;
	 String Parameters, String Directory, Integer ShowCmd
 

В случае успешного завершения функция возвращает значение, большее 32. При возникновении ошибки функция вернёт одно из следующих значений:

Код
ошибки
Описание
0 Недостаточно памяти или ресурсов Windows
2 Указанный файл не найден
3 Указанный путь не существует
5 Операционная система не имеет доступа к указанному файлу
8 Недостаточно памяти для завершения операции
26 Невозможен совместный доступ к файлу
27 Невозможно загрузить приложение, ассоциированное с типом файла
28 DDE транзакция не может быть завершена из-за истечения времени
29 Неудача при выполнении DDE транзакции
30 DDE транзакция не может быть завершена, так как обрабатываются другие DDE-транзакции
31 Нет никакого приложения, ассоциированного с расширением файла
32 Не найдена указанная DLL-библиотека

Функции передаются следующие параметры:

Параметр Описание
 hwnd Дескриптор родительского окна. При вызове функции из Visual FoxPro должен быть равен нулю. 
 Operation Может принимать одно из следующих значений: "find", "explore", "edit", "open" или "print"
 File Имя файла или папки - в зависимости от значения параметра Operation.
 Parameters Список параметров, передаваемых загружаемому приложению
 Directory Путь к файлу, указанному в File
 ShowCmd Определяет вид главного окна загружаемого приложения

Если Operation="find", функция выводит диалоговое окно для поиска файлов по условиям. Параметр File должен указывать путь к папке, начиная с которой будет выполняться поиск. Остальные параметры не используются.

Если Operation="explore", функция выводит диалоговое окно - список папок. Параметр File должен указывать путь к папке, содержимое которой нужно посмотреть. Остальные параметры не используются.

Если Operation="edit", функция открывает файл на редактирование, загружая приложение, ассоциированное с расширением файла. Параметр Edit должен содержать имя файла, параметр Directory - указывать путь к этому файлу; если параметр Directory не используется, то параметр Edit должен указывать путь и имя файла.

Если Operation="open", функция выполняет следующие действия: если в File указан исполняемый файл (например, типа EXE), то он запускается на выполнение; загружаемой программе передаётся список параметров, указанных в Parameters; в противном файл открывается на редактирование.

Если Operation="print", то выполняется печать файла на принтере (фактически загружается ассоциированное с расширением файла приложение, которое и печатает документ).

Параметр ShowCmd может принимать значения от 0 до 10, реальный интерес представляют значения, перечисленные в таблице:

ShowCmd Описание
0 Скрывает окно загружаемого приложения и активизирует другое окно.
1 Отображает главное окно приложения и делает его активным. Если окно приложения минимизировано или максимизировано, Windows восстанавливает его первоначальный размер и позицию.
2 Окно загружаемого приложения минимизировано.
3 Раскрывает окно приложения на весь экран и делает его активным. 
4 Отображает окно приложения в его последних сохранённых размерах, но не делает его активным.

Примеры использования функции в вашем приложении.

В следующем примере запускается приложение Notepad (блокнот); окно приложения распахивается на весь экран и становится активным:

 
 nReturn = ShellExecute(0,'open','c:\Windows\Notepad.exe',NULL,NULL,3)
 

В следующем примере загружается приложение MS Word для редактирования файла MyDocument.doc, расположенного в папке c:\MyDocs:

 
 nReturn = ShellExecute(0,'open','MyDocument.doc', NULL,'c:\MyDocs',1)
 

И последний пример, в котором при помощи MS Word выполняется печать файла MyDocument.doc. MS Word загружается в скрытом (Hide) режиме (окно не выводится, индикатор в панели "Пуск" не отображается). Документ распечатывается на принтере, используемом по умолчанию.

 
 nReturn = ShellExecute(0,'print','c:\MyDocs\MyDocument.doc',NULL,NULL,0)
 

  

Функция SHFileOperation

Функция SHFileOperation из библиотеки Shell32.dll выполняет копирование, перемещение, переименование и удаление объектов файловой системы (папок и файлов). В процессе выполнения выводится стандартное окно Windows для отображения процесса, подобное показанному на рисунке: 

Вот её прототип:

 
 int SHFileOperation(
	LPSHFILEOPSTRUCT lpFileOp
	);
 

Тип данных LPSHFILEOPSTRUCT - это указатель на структуру SHFILEOPSTRUCT:

 
 typedef struct _SHFILEOPSTRUCT{
	HWND hwnd;
	UINT wFunc;
	LPCSTR pFrom;
	LPCSTR pTo;
	FILEOP_FLAGS fFlags;
	BOOL fAnyOperationsAborted;
	LPVOID hNameMappings;
	LPCSTR lpszProgressTitle;
	} SHFILEOPSTRUCT, FAR *LPSHFILEOPSTRUCT;
 

Описание полей структуры SHFILEOPSTRUCT:

Поле Описание
 hwnd Дескриптор родительского окна. Это может быть hWnd вашей формы или главного окна Visual FoxPro.
 wFunc
Выполняемая операция. Может принимать одно из следующих значений:
1 Выполняет перемещение файла.
2 Копирует файлы.
3 Удаляет файлы. Значение поля pTo игнорируется.
4 Переименовывает файлы
 pFrom Адрес строки, в которой перечислены один или большее количество наименований  исходных файлов (возможно, с указанием путей). Если используется более одного наименования файла, то каждая последующая спецификация отделяется от предыдущей нулевым байтом. Строка должна завершаться двумя нулевыми байтами.
 pTo Адрес строки, в которой указана конечная папка для перемещения (копирования) файлов.Строка должна завершаться двумя нулевыми байтами. 
 fFlags 16-ти разрядное целое. Конкатенация флагов, определяющих порядок выполнения операции.
 fAnyOperationsAborted В поле записывается ноль, если пользователь прервал операцию, и отличное от нуля значение, если операция завершена успешно.
 hNameMappings В приложениях на Visual FoxPro не используется. Должен быть равен нулю.
 lpszProgressTitle В приложениях на Visual FoxPro не используется. Должен быть равен нулю.

Параметр fFlags определяется как конкатенация (сложение) значений, перечисленных ниже:

fFlags = 512
Если папка, в которую необходимо копировать файлы, не существует, выводится диалоговое окно с запросом о создание папки:

fFlags = 256
Отображает шкалу прогресса, но не показывает имена файлов

fFlags = 128
Операция выполняется только над файлами указанной папки, если для имени и типа файла указан шаблон (*.*). Над вложенными папками никаких действий не выполняется.

fFlags = 8
Если при копировании, перемещении или переименовании файл с указанным именем уже существует в папке-адресате, то он будет заменён без предупреждающего сообщения. Иначе - выводится диалог для подтверждения замены:

fFlags = 4
Операция выполняется, окно отображения процесса не выводится.

Объявление функции SHFileOperation в Visual FoxPro:

  
 DECLARE Long SHFileOperation IN Shell32.dll String @ FileOperation
 

Функция возвращает ноль при успешном выполнении.

Структура FileOperation может быть сформирована в символьной переменной длиной 26 байт; если вы хотите отслеживать ситуацию, когда пользователь отказался от файловой операции в процессе её выполнения, то передавайте эту переменную по ссылке, так как вам в этом случае потребуется проанализировать значение поля fAnyOperationsAborted.

В следующем примере показан код функции FileOperation, которая выполняет файловые операции, используя возможности, предоставляемые функцией SHFileOperation. Функция возвращает .T. при успешном выполнении операции. 

 
 FUNCTION FileOperation
 LPARAMETER tcFrom, tcTo, tnOper
 *
 *  tcFrom - спецификация исходных файлов
 *  tcTo   - спецификация результирующих файлов (папки)
 *  tnOper - определяет тип операции.
 *	     tnOper=1 - переместить файлы
 *	     tnOper=2 - копировать файлы
 *	     tnOper=3 - удалить файлы
 *	     tnOper=4 - переименовать файл
 *
    LOCAL lcSHFO, lcFrom, lnLenFrom, lcTo, lnLenTo, hGlobalFrom, hGlobalTo
    LOCAL lnFlag, lnReturn
  
    DECLARE Long SHFileOperation IN Shell32.dll String @
    DECLARE Long GlobalAlloc IN WIN32API Long, Long
    DECLARE Long GlobalFree IN WIN32API Long
 * Начинаем формировать структуру в переменной lcSHFO
    lcSHFO = BINTOC(thisform.HWnd, '4RS')	   && Поле hwnd
    lcSHFO = lcSHFO + BINTOC(tnOper, '4RS')	   && Поле wFunc - вид операции
 * Обработка спецификации исходных файлов
    tcFrom = tcFrom + CHR(0) + CHR(0)		   && Дописываем нули 
    lnLenFrom = LEN(tcFrom)			   && Длина исходной строки
    hGlobalFrom = GlobalAlloc(0x0040, lnLenFrom)   && Выделяем для неё блок памяти
    SYS(2600, hGlobalFrom, lnLenFrom, tcFrom)	   && и копируем туда строку
    lcSHFO = lcSHFO + BINTOC(hGlobalFrom, '4RS')   && Поле pFrom
 * Обработка спецификайии результирующих файлов
    IF tnOper = 3
	lcSHFO = lcSHFO + BINTOC(0, '4RS')	   && для операции удаления
    ELSE
	tcTo = tcTo + CHR(0) + CHR(0)		   && Дописываем нули 
	lnLenTo = LEN(tcTo)   && Длина результирующей строки
	hGlobalTo = GlobalAlloc(0x0040, lnLenTo)   && Выделяем для неё блок памяти
	SYS(2600, hGlobalFrom, lnLenFrom, tcFrom)  && и копируем туда строку
	lcSHFO = lcSHFO + BINTOC(hGlobalTo, '4RS') && Поле pTo
    ENDIF
    lnFlag = 8 + 256
    lcSHFO = lcSHFO + BINTOC(lnFlag, '2RS')	   && Поле fFlags
    lcSHFO = lcSHFO + REPLICATE(CHR(0), 12)	   && Последние 3 поля структуры
 * Выполняем операцию
    lnReturn = SHFileOperation(@lcSHFO)
 * Чистим память
    GlobalFree(hGlobalFrom)
    IF tnOper != 3
	GlobalFree(hGlobalTo)
    ENDIF
 * Если lnReturn = 0, то операция завершена успешно
    IF lnReturn != 0
	RETURN .f.
    ENDIF
    RETURN .t.
 ENDFUNC
 

Проанализируем код.

Структура SHFILEOPSTRUCT для функции SHFileOperation формируется в переменной lcSHFO. Записываем в первые четыре байта переменной значение hwnd, в следующие 4 байта - значение wFunc, определяющее характер операции. Поля pFrom и pTo содержат указатели на строки, содержащие информацию о спецификациях исходных и конечных файлов. Каждая такая строка должна заканчиваться двумя нулевыми байтами. Такой вид окончания строки используется потому, что при задании спецификации, например, исходных файлов, могут быть заданы файлы, расположенные в различных папках. В этом случае спецификации этих файлов разделяются одиночным нулевым байтом. Например:

 
 cFiles = 'c:\Foder1\File1.typ' + CHR(0) + 'd:\Folder2\File2.typ' + CHR(0) + CHR(0)
 

Выделяем блок в глобальной памяти Windows и получаем указатель на него:

 
 hGlobalFrom = GlobalAlloc(0x0040, lnLenFrom)
 

Переписываем в выделенный блок памяти значение строки спецификации файла:

 
 SYS(2600, hGlobalFrom, lnLenFrom, tcFrom)
 

Помещаем полученный указатель в поле структуры. Для преобразования целочисленного значения указателя в строку используем функцию BINTOC:

 
 lcSHFO = lcSHFO + BINTOC(hGlobalFrom, '4RS')
 

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

Далее формируем значение флага fFlags и добавляем его в структуру. Обратите внимание, что поле для хранения флага - двухбайтовое:

 
 lnFlag = 8 + 256
 lcSHFO = lcSHFO + BINTOC(lnFlag, '2RS')
 

Указанные значения флага определяют, что функция будет запрашивать необходимость создания новой папки и не будет запрашивать необходимость замены при одинаковых именах и типах исходных и конечных файлов.

Дописываем в переменную lcSHFO 12 нулевых байтов - это поля структуры fAnyOperationsAborted, hNameMappings и lpszProgressTitle.

После выполнения файловой операции возвращаем Windows память, выделенную функциями GlobalAlloc:

 
 GlobalFree(hGlobalFrom)
 

Вы можете проверить содержимое поля  fAnyOperationsAborted, которое после успешного выполнения функции будет содержать ноль либо отличное от нуля значение, если операция была прервана пользователем. Вот этот код:

 
 IF CTOBIN(SUBSTR(lcSHFO, 19, 4), '4N') != 0
 * Код, выполняющийся, если операция прервана пользователем
 ENDIF 
 

При написании раздела мною не ставилась цель дать информацию о всех Windows API функциях, которые вы могли бы применять в ваших приложениях. Главная цель - объяснить, как, пользуясь описанием любой такой функции в MSDN, правильно её объявить в Visual FoxPro и, самое главное, правильно использовать. В следующих разделах этого руководства постоянно будут применяться различные Windows API функции, но уже без такого подробного объяснения, как здесь.

<< Назад — "Введение в Windows API"

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог