Faq преобразование текста oem ansi


Содержание

4. Работа с файлами

Операционная система Windows версии 3.1, к сожалению, не имеет своей собственной файловой системы. Приложения Windows работают с файловой системой MS-DOS, поэтому они «скованы» ограничениями этой файловой системы. В добавок Windows накладывает свои ограничения, связанные с мультизадачным режимом работы.

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

Для предотвращения одновременного доступа на запись к файлам со стороны нескольких приложений можно использовать утилиту MS-DOS share.exe , загрузив ее при помощи файла autoexec.bat. Однако пользователи часто забывают загрузить эту утилиту или не загружают ее специально, надеясь сэкономить таким образом оперативную память.

Если вы разрабатываете приложение, работающее с файлами, вам необходимо убедить пользователя загрузить утилиту share.exe. Здесь возможны разные приемы.

Инсталлятор текстового процессора Microsoft Word for Windows версии 2.0 в процессе установки изменяет файл autoexec.bat, добавляя в него строку загрузки утилиты share.exe.

Однако при оптимизации своей системы пользователь, обнаружив эту строку в файле autoexec.bat после установки текстового процессора, может ее удалить. При этом сам текстовый процессор будет работать нормально (некоторое время).

Поэтому в текстовом процессоре Microsoft Word for Windows версии 6.0 использован более сильный способ «убеждения» пользователей в необходимости утилиты share.exe — если эта утилита не загружена, текстовый процессор выводит на экран сообщение о том, что в системе нет share.exe и отказывается работать.

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

Файлы и обработка сообщений

Так как работа приложений Windows (и самой операционной системы Windows) основана на передаче и обработке сообщений, вся файловая активность приложения также начинается во время обработки какого-либо сообщения. Например, редактор текста загружает редактируемый файл, когда приходит сообщение от строки «Open. » меню «File».

С файлами можно работать по-разному.

Первый способ (используемый программами MS-DOS) заключается в том, чтобы открыть все нужные им файлы в начале работы программы и закрыть их перед завершением работы программы. Если, однако, программа работает с большим количеством файлов, ей может не хватить управляющих блоков DFCB, используемых MS-DOS для каждого открытого файла (см. 1 том «Библиотеки системного программиста», раздел 2.4 «Таблица файлов MS-DOS»). Количество таких блоков определяется оператором «FILES=» в файле config.sys.

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

Приложения Windows не должны держать файлы открытыми на протяжении всего времени своей работы. Более того, вся обработка файла должна выполнятся во время обработки одного сообщения. То есть обработчик сообщения должен открыть файл, выполнить над ним все нужные операции ввода/вывода, а затем закрыть файл. Есть и еще одно ограничение — необходимо закрыть все файлы перед выводом на экран немодальной или модальной диалоговой панели (в том числе и перед вызовом функции MessageBox).

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

Почему нельзя переключаться на другое приложение, не закрыв предварительно все файлы?

Представьте себе, что ваше приложение открыло файл, расположенный на дискете. После этого пользователь переключился на другое приложение, которое также работает с дискетами. Для него потребовалось установить другую дискету и пользователь это сделал. Затем он снова переключился на первое приложение, которое продолжило, например, прерванную операцию записи. Но теперь эта операция будет выполняться с другой дискетой, в результате чего обе дискеты скорее всего придется форматировать.

Поэтому приложения Windows должны придерживаться следующего правила:

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

Временные файлы

Программы MS-DOS иногда создают на диске временные файлы , задавая для них либо фиксированное имя, которое зависит от программы, либо имя, созданное на основе текущей даты и времени.

Первый способ непригоден для приложений Windows, так как в системе могут работать несколько копий одного приложения. Поэтому, если, например, две копии приложения SUPERCAD попытаются создать два временных файла с именем !suprcad.tmp, такая операция получится только у той копии приложения, которая попытается сделать это первой.

В составе программного интерфейса Windows имеется функция GetTempFileName , предназначенная для получения имени временного файла:

Параметр bDriveLetter задает диск, на котором будет расположен временный файл. Если значение этого параметра равно нулю, временный файл будет создан на текущем диске.

Параметр lpszPrefixString должен содержать указатель на текстовую строку, содержащую префикс, который будет добавлен к имени временного файла. В префиксе необходимо использовать кодировку OEM.

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

Подготовленный полный путь для временного файла будет записан в буфер размером не менее 144 байт, адрес которого передается функции через параметр lpszTempFileName. При этом будет использована кодировка OEM.

Функция GetTempFileName возвращает значение, переданное ей через параметр uUnique, или значение, вычисленное исходя из текущего системного времени, если значение параметра uUnique равно нулю.

Учтите, что функция GetTempFileName не создает временные файлы. За создание и удаление временных файлов отвечает само приложение.

Остановимся подробнее на выборе диска для создания временных файлов.

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

Для назначения каталога в простейшем случае можно использовать переменную среды TEMP, устанавливаемую в файле autoexec.bat.

Если передать функции GetTempFileName в качестве параметра bDriveLetter нулевое значение, для определения диска, на котором будет расположен временный файл, используется следующий алгоритм.

Если определена переменная среды TEMP, для размещения временного файла используется диск, указанный в этой переменной.

Если переменная TEMP не определена, для размещения временного файла используется первый жесткий диск, обычно C:.

Вы можете в параметре bDriveLetter указать дополнительно константу TF_FORCEDRIVE, определенную в файле windows.h как 0x80. В этом случае для размещения файлов используется указанный в этом параметре диск без учета переменной среды TEMP или буквы, которой обозначается первый установленный в системе жесткий диск.

В программном интерфейсе Windows есть еще одна функция, которая может быть использована для создания временных файлов. Это функция GetTempDrive :

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

Функция GetTempDrive возвращает имя диска, который можно использовать для создания временных файлов. Если в системе есть жесткие диски, функция возвращает букву, соответствующую первому диску (обычно C:). В противном случае возвращается имя текущего диска.

Таким образом, для приложений Windows можно сформулировать еще одно правило.

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

Кодировка OEM

Так как для работы с файлами операционная система Windows использует файловую систему MS-DOS, для указания пути к файлам и каталогам необходимо использовать кодировку OEM , принятую в MS-DOS. Так как Windows работает с кодировкой ANSI , в некоторых случаях необходимо выполнять соответствующие преобразования, вызывая функции AnsiToOem и OemToAnsi .

Однако при открытии файла с помощью функций OpenFile и _lopen, определенных в программном интерфейсе Windows, вы можете не беспокоиться о кодировке, так как эти функции выполняют сами все необходимые преобразования.

Итак, следующее правило.

Принимайте во внимание то обстоятельство, что Windows и MS-DOS используют разную кодировку. При необходимости выполняйте преобразования из кодировки ANSI в кодировку OEM и обратно.

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

Открытие файлов

Для открытия файлов вы можете воспользоваться универсальной функцией OpenFile или более простой (но и более ограниченной) функцией _lopen.

Приложения Windows могут воспользоваться функцией OpenFile , которая предназначена для создания, открытия, повторного открытия и удаления файлов. Приведем прототип этой функции:

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

Параметр lpszFileName является указателем на текстовую строку в кодировке ANSI, содержащую путь к файлу и закрытую двоичным нулем. В имени файла не допускается указывать символы шаблона, такие как «*» и «?».

Через параметр lpOpenStruct передается адрес структуры OFSTRUCT, которая заполняется информацией при первом открытии файла.

Параметр fuMode используется для определения действий, выполняемых функцией OpenFile, а также атрибуты файла. Приведем список возможных значений для этого параметра.


Константа Описание
OF_READ Файл открывается только для чтения
OF_WRITE Файл открывается только для записи
OF_READWRITE Файл открывается для чтения и записи
OF_SHARE_COMPAT Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причем все эти приложения должны открывать файл в режиме совместимости
OF_SHARE_EXCLUSIVE Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещен
OF_SHARE_DENY_WRITE После открытия файла к нему запрещается доступ со стороны других приложений на запись
OF_SHARE_DENY_READ После открытия файла к нему запрещается доступ со стороны других приложений на чтение
OF_SHARE_DENY_NONE Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись
OF_PARSE Если указан этот флаг, функция OpenFile не выполняет никаких других действий, кроме заполнения структуры OFSTRUCT
OF_DELETE Уничтожение существующего файла
OF_VERIFY Если указан этот флаг, функция OpenFile сравнивает время и дату, записанную в структуре OFSTRUCT с временем и датой изменений указанного файла. Если обнаружено несоответствие, функция OpenFile возвращает значение HFILE_ERROR
OF_SEARCH Операционная система Windows выполняет поиск файла в каталогах даже в том случае, когда текстовая строка, указанная параметром lpszFileName, содержит полный путь к файлу
OF_PROMPT Если указан этот флаг, то в случае невозможности найти указанный файл Windows выдает диалоговую панель с предложением вставить в дисковод A: дискету с файлом. Этот флаг используется очень редко
OF_CANCEL Флаг OF_CANCEL используется в сочетании с флагом OF_PROMPT. Если он указан, то в описанную выше диалоговую панель будет добавлена кнопка «Cancel», позволяющая отменить открытие файла. Приложение получит в этом случае код ошибки, соответствующий ненайденному файлу, а пользователь — возможность выйти из безвыходного состояния, в которое он может попасть, не имея под рукой дискеты с нужным файлом
OF_CREATE Выполняется создание нового файла. Если указанный файл существует, он обрезается до нулевой длины
OF_EXIST При указании этого флага функция OpenFile вначале открывает файл, а затем сразу же его закрывает. Эта бесполезная на первый взгляд операция может быть использована для того чтобы убедиться в существовании указанного файла на диске
OF_REOPEN Этот флаг используется при повторном открытии файла на основе информации, хранящейся в структуре OFSTRUCT

Когда функция OpenFile вызывается в первый раз для открытия файла, она заполняет структуру OFSTRUCT , описанную в файле windows.h следующим образом:

Поле cBytes содержит размер самой структуры OFSTRUCT в байтах.

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

Если при открытии файла произошла ошибка, в поле nErrCode записывается код ошибки. Возможные значения для кода ошибки приведены в приложении 1.

Поле reserved зарезервировано и не должно использоваться.

В поле szPathName находится полный путь к файлу в кодировке OEM.

Если функция OpenFile показалась вам слишком сложной в использовании, в ряде случаев для открытия файла вы сможете ограничиться функцией _lopen :

Функция возвращает идентификатор открытого файла или HFILE_ERROR при ошибке.

Параметр lpszFileName, так же как и для функции OpenFile, является указателем на текстовую строку в кодировке ANSI, содержащую путь к файлу и закрытую двоичным нулем. В имени файла не допускается указывать символы шаблона, такие как «*» и «?».

Параметр fuOpenMode определяет режим, в котором открывается файл. Приведем список возможных значений для этого параметра.

Константа Описание
READ Файл открывается только для чтения
WRITE Файл открывается только для записи
READWRITE Файл открывается для чтения и записи
OF_SHARE_COMPAT Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причем все эти приложения должны открывать файл в режиме совместимости
OF_SHARE_EXCLUSIVE Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещен
OF_SHARE_DENY_WRITE После открытия файла к нему запрещается доступ со стороны других приложений на запись
OF_SHARE_DENY_READ После открытия файла к нему запрещается доступ со стороны других приложений на чтение
OF_SHARE_DENY_NONE Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись

Если вам надо открыть файл в каталоге, где находится сама операционная система Windows или в системном каталоге Windows, воспользуйтесь функциями, соответственно, GetWindowsDirectory и GetSystemDirectory.

Функция GetWindowsDirectory позволяет определить расположение каталога, в который была установлена операционная система Windows:

Параметр lpSysPath является указателем на буфер размером не менее 144 байт, в который будет записан путь к искомому каталогу.

С помощью параметра cbSysPath необходимо указать размер буфера в байтах.

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

Для определения пути к системному каталогу Windows предназначена функция GetSystemDirectory :

Назначение параметров этой функции аналогично назначению параметров функции GetWindowsDirectory.

Так как системный каталог Windows может находиться на сервере, приложение не должно пытаться создавать или изменять файлы в этом каталоге. Как правило, пользователь не имеет права записи в системный каталог Windows.

Стандартные диалоговые панели для открытия файлов

В составе операционной системы Windows версии 3.1 имеется DLL-библиотека commdlg.dll, экспортирующая среди прочих две функции, очень удобные для организации пользовательского интерфейса при открытии файлов. Это функции GetOpenFileName и GetSaveFileName . Мы уже пользовались этими функциями в приложениях OEM2ANSI и OEM3ANSI.

Функция GetOpenFileName выводит на экран стандартную или измененную приложением диалоговую панель «Open», позволяющую выбрать файл (рис. 4.1).

Рис. 4.1. Диалоговая панель «Open»

Функция GetSaveFileName выводит стандартную или измененную приложением диалоговую панель «Save As. » (рис. 4.2).

Рис. 4.2. Диалоговая панель «Save As. «

Внешний вид этих диалоговых панелей определяется структурой типа OPENFILENAME , определенной в файле commdlg.h (этот файл находится в каталоге include системы разработки Borland C++ или Microsoft Visual C++):

Адрес структуры передается функциям GetOpenFileName и GetSaveFileName в качестве параметра lpofn:

Обе функции возвращают ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку «Cancel» или выбрав строку «Close» из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибки.

В результате выбора некоторые поля структуры будут заполнены информацией о выбранном файле.

Опишем назначение отдельных полей структуры OPENFILENAME.

lStructSize

Поле lStructSize перед вызовом функций должно содержать размер структуры OPENFILENAME в байтах.

Flags

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

Флаг Описание
OFN_ALLOWMULTISELECT Разрешается выбор нескольких файлов одновременно. Если указан этот флаг, после выбора поле lpstrFile будет указывать на буфер, заполненный именами выбранных файлов (или путями к выбранным файлам), разделенными пробелом
OFN_CREATEPROMPT При использовании этого флага если указанный файл не существует, создается диалоговая панель, в которой предлагается создать файл. Этот флаг устанавливается автоматически при использовании флагов OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST
OFN_ENABLEHOOK Разрешается использовать функцию фильтра, адрес которой указан в поле lpfnHook
OFN_ENABLETEMPLATE Если указан этот флаг, для создания диалоговой панели Windows будет использовать шаблон, определяемый содержимым полей hInstance и lpTemplateName
OFN_ENABLETEMPLATEHANDLE При использовании этого флага поле hInstance используется для идентификации блока памяти, содержащий предварительно загруженный шаблон диалоговой панели. В этом случае содержимое поля lpTemplateName игнорируется
OFN_EXTENSIONDIFFERENT Устанавливается после возвращения из функции и указывает, что расширение возвращенного имени файла отличается от заданного в поле lpstrDefExt. Этот флаг не устанавливается, если перед вызовом функции в поле lpstrDefExt было записано значение NULL, или если файл не имеет расширения имени
OFN_FILEMUSTEXIST Можно выбирать только имена тех файлов, которые существуют. Если в поле «File Name» диалоговой панели набрать имя несуществующего файла, на экране появится диалоговая панель с предупреждающим сообщением
OFN_HIDEREADONLY Убрать переключатель «Read Only»
OFN_NOCHANGEDIR Для выбора используется каталог, который был текущим при вызове функции
OFN_NOREADONLYRETURN Выбранные файлы не могут иметь атрибут «только чтение» или располагаться в защищенном от записи каталоге
OFN_NOTESTFILECREATE Перед завершением работы диалоговой панели создание файла не выполняется. Не выполняются и проверки на переполнение диска, защиту записи или наличие доступа в сети
OFN_NOVALIDATE В возвращаемом имени файла могут присутствовать неразрешенные символы
OFN_OVERWRITEPROMPT Используется для диалоговой панели «Save As. «. Если выбранный файл существует, на экран выводится диалоговая панель с предупреждением
OFN_PATHMUSTEXIST Можно вводить только существующие пути к файлам
OFN_READONLY После вызова функции переключатель «Read Only» будет находиться во включенном состоянии
OFN_SHAREWARE Флаг устанавливается после возвращения из функции и указывает, что при вызове функции OpenFile произошла ошибка при совместном доступе к файлу в сети
OFN_SHOWHELP Если указан этот флаг, в диалоговой панели будет создана кнопка «Help». Если указан этот флаг, поле hwndOwner не должно содержать значение NULL
Илон Маск рекомендует:  StringOfChar - Функция Delphi

hwndOwner

Поле hwndOwner должно содержать идентификатор окна, создавшего диалоговую панель. Можно указать значение NULL, при этом диалоговая панель не будет иметь окно-владельца. В этом случае нельзя использовать флаг OFN_SHOWHELP.

hInstance

Поле hInstance используется перед вызовом функции для идентификации блока памяти, содержащего шаблон диалоговой панели. Содержимое поля игнорируется в том случае, если не указаны флаги OFN_ENABLETEMPLATE или OFN_ENABLETEMPLATEHANDLE.

lpstrFilter

В поле lpstrFilter должен быть указан адрес текстовой строки, задающей фильтр для выбора имен файлов (шаблоны имен файлов).

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

Первая строка в паре строк описывает название фильтра, например «Text Files» (текстовые файлы), во второй строке пары через символ «;» перечисляются возможные шаблоны для имен файлов.

lpstrCustomFilter

В поле lpstrCustomFilter должен быть указан адрес текстовой строки, задающей фильтр для выбора имен файлов (шаблон для выбора файлов).

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

Первая строка в паре строк описывает название фильтра, например «Text Files» (текстовые файлы), во второй строке пары через символ «;» перечисляются возможные шаблоны для имен файлов.

Если поле lpstrFilter содержит NULL, используется фильтр lpstrCustomFilter.

nMaxCustFilter

Определяет размер буфера в байтах, указанного в поле lpstrCustomFilter. Размер этого буфера должен быть не меньше 40 байт.

nFilterIndex

Поле nFilterIndex определяет номер пары строк, используемой для фильтра, указанного в поле lpstrFilter. Если в качестве значения для этого поля указать 0, будет использован фильтр, определенный в поле lpstrCustomFilter.

lpstrFile

Поле lpstrFile должно содержать адрес текстовой строки, в которую будет записан полный путь к выбранному файлу.


Если по указанному выше адресу перед вызовом функции GetOpenFileName или GetSaveFileName расположить текстовую строку, содержащую путь к файлу, этот путь будет выбран по умолчанию сразу после отображения диалоговой панели «Open» или «Save As. «.

nMaxFile

Поле nMaxFile должно содержать размер в байтах буфера, расположенного по адресу, указанному в поле lpstrFile.

Размер этого буфера должен быть достаточным для записи полного пути к файлу. Файловая система MS-DOS допускает использование для указания пути к файлу не более 128 символов.

lpstrFileTitle

В поле lpstrFileTitle необходимо записать адрес буфера, в который после выбора будет записано имя файла с расширением, но без пути к файлу. Это поле должно быть использовано приложением для отображения имени выбранного файла.

nMaxFileTitle

Поле nMaxFileTitle должно содержать размер указанного выше буфера.

lpstrInitialDir

Поле lpstrInitialDir позволяет указать начальный каталог, который будет выбран для поиска файла сразу после отображения диалоговой панели «Open». Для того чтобы начать поиск в текущем каталоге, в это поле следует записать значение NULL.

lpstrTitle

С помощью этого поля можно определить заголовок диалоговой панели, появляющейся при вызове функции. Если это поле содержит NULL, будут использованы стандартные заголовки «Open» и «Save As. «.

nFileOffset

После возврата из функции это поле содержит смещение первого символа имени файла относительно начала буфера lpstrFile.

nFileExtension

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

lpstrDefExt

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

lCustData

Значение, передаваемой функции фильтра через параметр lParam.

lpfhHook

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

lpTemplatename

Идентификатор ресурса, содержащего шаблон диалоговой панели, используемого вместо имеющегося в DLL-библиотеке commdlg.dll. Для ссылки на ресурс можно использовать макрокоманду MAKEINTRESOURCE. Для использования альтернативного шаблона (и, соответственно, данного поля), в поле Flags следует установить флаг OFN_ENABLETEMPLATE.

Закрытие файлов

Теперь о том, как закрыть файл. Для закрытия файла вы должны использовать функцию _lclose :

Идентификатор закрываемого файла передается функции через параметр hf.

Если файл закрыт успешно, функция _lclose возвращает нулевое значение. При ошибке возвращается значение HFILE_ERROR.

Создание файлов

Для создания файлов вы можете использовать как универсальную функцию OpenFile, описанную нами ранее, так и более простую функцию _lcreat :

В качестве параметра lpszFileName этой функции необходимо передать адрес строки, содержащей путь к создаваемому файлу в кодировке ANSI.

С помощью параметра fuAttribute можно определить атрибуты создаваемого файла:

Значение атрибута Описание
Нормальный файл, для которого разрешено выполнение операций чтения и записи
1 Этот файл можно открыть только для чтения
2 Скрытый файл
3 Системный файл

Если указанный первым параметром файл не существует, функция _lcreat создает его и открывает для записи, возвращая идентификатор файла. Если файл существует, он обрезается до нулевой длины и затем открывается для чтения и записи.

Чтение и запись

Для выполнения операций чтения и записи в программном интерфейсе операционной системы Windows версии 3.1 предусмотрены четыре функции: _lread, _hread, _lwrite, _hwrite.

Функция _lread предназначена для чтения из открытого файла:

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

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

Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызывав, например, функцию GlobalAlloc или LocalAlloc. Размер буфера не должен превышать 65534 байт.

В программном интерфейсе операционной системы Windows версии 3.1 появилась функция _hread , с помощью которой можно выполнять чтение из файла блоков практически любого размера:

Так же как и функция _lread, функция _hread возвращает количество байт данных, прочитанных из файла. Возвращенное значение может быть меньше затребованного в параметре cbBuffer, если в процессе чтения был достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR.

Вы можете с помощью функции GlobalAlloc заказать для функции _hread буфер размером, большим 64 Кбайт.

С помощью функции _lwrite вы можете выполнить запись данных в файл:

Назначение параметров этой функции аналогично назначению параметров функции _lread. Перед вызовом функции _lwrite буфер должен содержать записываемые в файл данные.

Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке.

Если вам надо писать в файл блоки, имеющие размер больше 64 Кбайт, воспользуйтесь функцией _hwrite , которая впервые появилась в программном интерфейсе Windows версии 3.1:

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

Позиционирование

Для выполнения операции позиционирования внутри файла приложения Windows могут использовать функцию _llseek :

Функция _llseek перемещает указатель текущей позиции в файле на lOffset байт, причем направление смещения зависит от значения параметра nOrigin следующим образом:

Значение Описание
SEEK_SET Указатель текущей позиции в файле перемещается на lOffset байт от начала файла
SEEK_CUR Указатель текущей позиции в файле перемещается на lOffset байт от текущей позиции
SEEK_END Указатель текущей позиции в файле перемещается на lOffset байт от конца файла

Таким образом, с помощью этой функции вы можете обеспечить прямой доступ к файлу.

Функция возвращает новое значение текущей позиции от начала файла или HFILE_ERROR при ошибке.

Определение типа устройства ввода/вывода



Иногда приложению требуется определить тип и расположение используемого дискового устройства ввода/вывода. Для этого можно воспользоваться функцией GetDriveType :

Параметр DriveNumber определяет номер диска, для которого требуется определить тип и расположение (0 соответствует устройству A:, 1 — B:, и т. д.).

Функция может вернуть 0 при ошибке или одно из следующих значений:

Значение Описание
DRIVE_REMOVABLE Сменный диск
DRIVE_FIXED Несменный диск
DRIVE_REMOTE Удаленный диск, расположен на другой машине в сети

Использование стандартной библиотеки транслятора

Для работы с файлами в приложениях Windows вы можете использовать функции из стандартной библиотеки транслятора C или C++, такие как read , fread , write , fwrite , lseek , fstat , tell , close .

Можно также использовать функции потокового ввода/вывода , если преобразовать идентификатор файла в указатель на структуру FILE при помощи функции fdopen . Для того чтобы закрыть такой файл следует воспользоваться функцией fclose .

Перечисленные выше функции были описаны в третьей книге первого тома «Библиотеки системного программиста» в главе «Файловая система DOS».

Проверка присутствия share.exe

Как мы уже говорили, в многозадачной среде утилита MS-DOS share.exe приобретает особое значение, выступая координатором доступа работающих параллельно приложений к файлам. Для того чтобы приучить забывчивых или беспечных пользователей не удалять команду загрузки этой утилиты из файла autoexec.bat вы можете сделать так, чтобы ваше приложение выдавала предупреждающее сообщение, если утилита share.exe не загружена.

Однако проблема не так проста, как кажется. Для того чтобы определить, загружена ли утилита share.exe , программы MS-DOS могли воспользоваться функцией 1000h прерывания INT 2Fh. Эта функция используется самой утилитой share.exe для предотвращения повторной загрузки.

Но вызвав эту функцию из приложения Windows, вы можете, к своему огорчению, убедиться, что она всегда сообщает о том, что share.exe загружена в память, даже если вы вообще стерли файл share.exe с диска. Это сделано специально, но не для того чтобы затруднить обнаружение share.exe, а для того чтобы предотвратить ее загрузку из виртуальной машины MS-DOS, работающей в среде Windows.

Мы, однако, можем найти выход из этого затруднительного положения, если для определения присутствия share.exe попробуем использовать одну из функций, для выполнения которой она предназначена.

В качестве такой функции проще всего использовать блокирование участка файла (функция 0x5c прерывания INT 21h). Как мы уже говорили, Windows выполняет эмуляцию большого числа функций прерывания MS-DOS, позволяя приложениям Windows обращаться к этим функциям.

В листинге 4.1 приведены исходные тексты приложения ISSHARE, которое проверяет присутствие share.exe, выполняя попытку заблокировать первый байт созданного временного файла.

Листинг 4.1. Файл isshare/isshare.cpp

Функция WinMain проверяет, загружена ли утилита share.exe, вызывая функцию ShareLoaded, определенную в приложении.

Эта функция может вернуть 0, 1 или -1. Если функция вернула 0, share.exe не загружена. Если функция вернула -1, произошла ошибка при создании временного файла. И, наконец, если функция ShareLoaded вернула 1, share.exe загружена.

Для создания временного файла используется функции GetTempFileName и _lcreat. Первая из этих двух функций получает имя временного файла, вторая — создает и открывает временный файл.

Для выполнения блокировки приложение вызывает функцию MS-DOS, пользуясь известной вам функцией intdos.

Если утилита share.exe установлена и блокировка файла выполнена успешно, функция ShareLoaded разблокирует файл, вызывая функцию MS-DOS с кодом 0x5c еще раз, но с другим значением регистра AL.

В любом случае перед возвратом из функции временный файл закрывается функцией _lclose и затем удаляется функцией OpenFile.

Файл определения модуля для приложения ISSHARE приведен в листинге 4.2.

Листинг 4.2. Файл isshare/isshare.def

Приведем еще один вариант приложения OEM3ANSI, описанного в предыдущем томе «Библиотеки системного программиста». В новом варианте приложение заказывает в глобальной области памяти буфер для чтения перекодируемого файла, причем размер этого буфера равен. размеру файла! Далее с помощью одного вызова функции _hread весь файл переписывается в буфер и перекодируется «по месту». Результат перекодировки из буфера переписывается в выходной файл за один вызов функции _hwrite. Таким образом, в нашем приложении нет привычного цикла чтения файла, который прерывается при достижении конца файла, а также нет цикла записи в файл. Механизм виртуальной памяти расширенного режима операционной системы Windows и функции _hread, _hwrite облегчают работу с файлами.

Кроме демонстрации работы перечисленных выше двух функций в новом варианте приложения OEM3ANSI для выбора входного и выходного файла мы использовали вместе со стандартными функциями GetOpenFileName и GetSaveFileName нестандартные шаблоны диалоговых панелей «Open» и «Save as. «. Внешний вид диалоговой панели для выбора входного файла представлен на рис. 4.3, для выбора выходного файла — на рис. 4.4.

Рис. 4.3. Выбор входного файла

Рис. 4.4. Выбор выходного файла

Механизм шаблонов, предусмотренный во всех функциях стандартных диалоговых панелей из DLL-библиотеки commdlg.dll, можно использовать в тех случаях, когда вас не устраивает внешний вид стандартных диалоговых панелей. Например, все надписи в стандартной диалоговой панели «Open» выполнены на английском языке. Вы, вероятно, сумеете найти другой вариант библиотеки commdlg.dll (например, русифицированный), но лучше создать свой шаблон диалоговой панели, в котором вы можете перевести надписи на любой язык или внести другие изменения.

Как создать свой шаблон для стандартной диалоговой панели ?

Для этого проще всего воспользоваться приложением Borland Resource Workshop. С помощью этого приложения вы сможете «вытянуть» из DLL-библиотеки commdlg.dll описание любого имеющегося там ресурса, записав его в текстовый файл с расширением имени rc.

Запустите приложение Borland Resource Workshop. С помощью строки «Open Project» меню «File» загрузите DLL-библиотеку commdlg.dll. Вариант этой библиотеки, который вы можете распространять вместе с созданными вами приложениями, как правило, поставляется в составе системы разработки приложений. Кроме того, эта библиотека есть в системном каталоге операционной системы Windows версии 3.1.

После загрузки библиотеки в окне «commdlg.dll» вы увидите список ресурсов (рис. 4.5).

Рис. 4.5. Шаблоны диалоговых панелей и другие ресурсы в DLL-библиотеке commdlg.dll

Из ресурсов типа DIALOG выберите шаблон 1536. На экране появится окно «DIALOG:1536», в котором вы сможете редактировать стандартную диалоговую панель «Open» (рис. 4.6).

Рис. 4.6. Редактирование стандартной диалоговой панели «Open»

Однако перед тем как редактировать шаблон, его лучше сохранить в отдельном файле. Для этого из меню «Resource» выберите строку «Save resource as. » и сохраните описание шаблона, например, в файле с именем open.rc.

Таким образом, вы выделили описание нужного вам шаблона диалоговой панели в отдельный файл. Содержимое этого файла можно включить в файл описания ресурсов вашего приложения и использовать для работы с функциями GetOpenFileName и GetSaveFileName (как мы и поступили в приложении OEM3ANSI).

Учтите, что при редактировании шаблона не следует удалять из него органы управления, даже если по логике работы приложения они не нужны. Дело в том, что функции DLL-библиотеки commdlg.dll могут обращаться к ним. Например, они могут инициализировать списки. Поэтому, если вам надо сделать какой-либо стандартный орган управления невидимым, вы можете указать для него расположение вне видимой части экрана.

Теперь перейдем к описанию приложения OEM3ANSI. Исходные тексты главного файла приложения приведены в листинге 4.3.

Листинг 4.3. Файл oem3ansi/oem3ansi.cpp

Функция WinMain сохраняет идентификатор копии приложения в глобальной переменной hInst. Этот идентификатор потребуется впоследствии для загрузки шаблона диалоговой панели из ресурсов приложения.

Далее, так же как и первой версии приложения OEM3ANSI, функция WinMain загружает из ресурсов дополнительную таблицу перекодировки, сохраняя ее адрес в переменной lpXlatTable.

Затем функция WinMain открывает входной и выходной файлы, вызывая функции GetSrcFile и GetDstFile, определенные в нашем приложении. Эти функции выбирают файлы с использованием шаблона, созданного нами на основе стандартного шаблона диалоговой панели «Open» и функций GetOpenFileName, GetSaveFileName.

После перекодировки выбранного файла (которая выполняется функцией Oem3Ansi), файлы закрываются, ресурс, содержащий таблицу перекодировки, расфиксируется и освобождается.

Так как диалоговые панели выбора входного и выходного файла отличаются только заголовком, для них мы создали только один шаблон. В файле ресурсов этот шаблон имеет имя «Open».

Илон Маск рекомендует:  Работа со спрайтами

Перед тем, как вызвать функцию GetOpenFileName, предназначенную для выбора входного файла, мы должны подготовить соответствующим образом структуру ofn типа OPENFILENAME. В частности, для обеспечения возможности работы с шаблоном в поле Flags структуры ofn необходимо указать флаг OFN_ENABLETEMPLATE. В поле hInstance этой же структуры необходимо записать идентификатор копии приложения, ресурсы которого содержат шаблон, а в поле lpTemplateName нужно записать указатель на строку имени ресурса:

Функция GetDstFile инициализирует структуру ofn аналогичным образом. Единственное отличие заключается в том, что в поле lpstrTitle записывается адрес строки, содержащей заголовок «Выберите выходной файл»:

Для перекодирования файла в приложении OEM3ANSI определена функция с именем Oem3Ansi.

Прежде всего эта функция определяет размер входного файла. Для этого она выполняет позиционирование на конец файла, используя функцию _llseek:

Эта функция возвращает текущее смещение в файле от начала файла. Так как мы установили текущую позицию н конец файла, текущее смещение от начала файла, очевидно, равно размеру файла.

После определения размера файла необходимо установить текущую позицию на начало файла. В противном случае при попытке прочитать данные мы получим состояние «Конец файла». Для установки текущей позиции на начало файла мы вызываем функцию _llseek еще раз, но с другими параметрами:

После определения размера входного файла функция Oem3Ansi заказывает фиксированный блок из глобальной области памяти (при помощи функции GlobalAlloc), и фиксирует его для получения адреса (при помощи функции GlobalLock). Адрес блока записывается в переменную hBuf типа unsigned char huge*. Размер заказанного блока равен размеру файла.

Затем весь файл читается в буфер, для чего используется функция _hread:

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


Для перекодировки по дополнительной таблице мы адресуемся к блоку памяти через указатель типа huge, так как размер блока памяти может превышать 64 Кбайт.

Функция OemToAnsiBuff может перекодировать буфер размером не более 64 Кбайт, поэтому мы вызываем ее отдельно для каждого байта перекодируемого буфера.

После подготовки буфера мы записываем его в выходной файл, вызывая функцию _hwrite:

Перед возвратом управления функция Oem3Ansi расфиксирует и освобождает заказанный ранее блок памяти, вызывая функции GlobalUnlock и GlobalFree.

Файл описания ресурсов приложения OEM3ANSI приведен в листинге 4.4.

Листинг 4.4. Файл oem3ansi/oem3ansi.rc

В этом файле описаны два ресурса: дополнительная таблица перекодировки XlatTable и шаблон диалоговой панели Open.

Файл определения модуля для приложения OEM3ANSI приведен в листинге 4.5.

Что за кодировка ANSI в Notepad++

Приветствую всех. Открыл Notepad++. Там есть возможность преобразовать в ANSI. Непонятно, что в этой программе подразумевается под кодировкой ANSI, ведь такой кодировки вроде как несуществует. Насколько я знаю ANSI — это неофициальное обобщенное название кодировок windows 1251, windows 1252, ascii(7bit). Так в какую кодировку будет преобразован текст ?

3 ответа 3

В Windows под ANSI codepage обычно понимается «системная» кодировка. Она используется для не-юникодных программ (и кажется для не-юникодных файловых систем). Для стандартной американской версии это CP 1252, для русской — CP 1251.

Хотя название и ссылается на стандарт ANSI, реально оно ничего общего со стандартом не имеет.

Чаще всего это однобайтная кодировка, но для некоторых систем (например, японской) это MBCS.

Следует различать ANSI-кодировку (используемую для не-юникодных Windows-программ) и OEM-кодировку (используемую для не-юникодных DOS-программ, в случае русской Windows это CP 866).

Автоматическое преобразование символьных данных Autotranslation of Character Data

Символьные данные, такие как ANSI символьные переменные, объявленные с помощью SQL_C_CHAR или данные, хранящиеся в SQL Server SQL Server с помощью char, varchar, или текст типы данных, можно представляют только ограниченный набор символов. Character data, such as ANSI character variables declared with SQL_C_CHAR or data stored in SQL Server SQL Server using the char, varchar, or text data types, can represent only a limited number of characters. Символьные данные, в которых для обозначения одного символа требуется один байт данных, могут представлять только 256 символов. Character data stored using one byte per character can only represent 256 characters. Для интерпретации значений, содержащихся в переменных SQL_C_CHAR, используются кодовые страницы ANSI (ACP) клиентского компьютера. The values stored in SQL_C_CHAR variables are interpreted using the ANSI code page (ACP) of the client computer. Значения, сохраненные с использованием char, varchar, или текст типов данных на сервере, вычисляются с помощью ACP сервера. The values stored using char, varchar, or text data types on the server are evaluated using the ACP of the server.

Если сервер и клиент имеют та же кодовая страница, а затем без проблем в интерпретации значения, хранящиеся в SQL_C_CHAR, char, varchar, или текст объектов. If both the server and the client have the same ACP, then they have no problems in interpreting the values stored in SQL_C_CHAR, char, varchar, or text objects. Если сервер и клиент имеют разные кодовые, а затем данные SQL_C_CHAR от клиента могут интерпретироваться как другой знак на сервере, если он используется в char, varchar, или текст столбцов, переменных или параметров. If the server and client have different ACPs, then SQL_C_CHAR data from the client may be interpreted as a different character on the server if it is used in char, varchar, or text columns, variables, or parameters. Например символьный байт, содержащий значение 0xA5, интерпретируется как символ?? For example, a character byte containing the value 0xA5 is interpreted as the character ?? на компьютере, использующем кодовую страницу 437 и интерпретируется как знак иены (?) на компьютере под управлением кодовую страницу 1252. on a computer using code page 437 and is interpreted as the yen sign (??) on a computer running code page 1252.

Символы в формате Юникода записываются с использованием двух байт данных. Unicode data is stored using two bytes per character. В стандарт Юникод включены все дополнительные символы, поэтому все символы Юникода интерпретируются всеми компьютерами одинаково. All extended characters are covered by the Unicode specification, so all Unicode characters are interpreted the same by all computers.

Функция AutoTranslate SQL Server SQL Server драйвер ODBC собственного клиента пытается свести к минимуму проблемы при перемещении символьных данных между клиентом и сервером, имеющими различные кодовые страницы. The AutoTranslate feature of the SQL Server SQL Server Native Client ODBC driver attempts to minimize the problems in moving character data between a client and a server that have different code pages. Можно задать AutoTranslate в строке соединения SQLDriverConnect, в строке конфигурации SQLConfigDataSource, или при настройке источников данных для SQL Server SQL Server ODBC для собственного клиента драйвер с помощью администратора ODBC. AutoTranslate can be set in the connect string of SQLDriverConnect, in the configuration string of SQLConfigDataSource, or when configuring data sources for the SQL Server SQL Server Native Client ODBC driver using ODBC Administrator.

Если AutoTranslate имеет значение «no», не подвергаются преобразованиям данные, перемещаемые между переменными SQL_C_CHAR на клиенте и char, varchar, или текст столбцов, переменных, или параметров в SQL Server SQL Server базы данных. When AutoTranslate is set to «no», no conversions are done on data moved between SQL_C_CHAR variables on the client and char, varchar, or text columns, variables, or parameters in a SQL Server SQL Server database. Эти битовые шаблоны могут по-разному интерпретироваться клиентом и сервером, если данные содержат символы национального алфавита, и два компьютера имеют различные кодовые страницы. The bit patterns may be interpreted differently on the client and server computers if the data contains extended characters and the two computers have different code pages. Данные интерпретируются единообразно, если оба компьютера используют одну и ту же кодовую страницу. The data will be interpreted the same if both computers have the same code page.

Если AutoTranslate имеет значение «yes», SQL Server SQL Server драйвер ODBC собственного клиента использует формат Юникод для преобразования данных, перемещаемых между переменными SQL_C_CHAR на клиенте и char, varchar, или текст столбцов, переменных или параметров в SQL Server SQL Server базы данных: When AutoTranslate is set to «yes», the SQL Server SQL Server Native Client ODBC driver uses Unicode to convert data moved between SQL_C_CHAR variables on the client and char, varchar, or text columns, variables, or parameters in a SQL Server SQL Server database:

Когда данные передаются из переменной SQL_C_CHAR на клиенте, чтобы char, varchar, или текст столбцу, переменной или параметра в SQL Server SQL Server базы данных ODBC Сначала драйвер преобразует из SQL_C_CHAR в Юникод с помощью кодовой страницы ANSI клиента, затем из Юникода обратно на символ, с помощью ACP сервера. When data is sent from an SQL_C_CHAR variable on the client to a char, varchar, or text column, variable, or parameter in an SQL Server SQL Server database, the ODBC driver first converts from SQL_C_CHAR to Unicode using the ACP of the client, then from Unicode back to character using the ACP of the server.

Когда данные отправляются из char, varchar, или текст столбцу, переменной или параметра в SQL Server SQL Server базы данных в переменную SQL_C_CHAR на клиенте, SQL Server SQL Server Драйвер собственного клиента ODBC сначала преобразует символ Юникода, с помощью кодовой страницы ANSI сервера, затем из Юникода обратно в SQL_C_CHAR, с помощью кодовой страницы ANSI клиента. When data is sent from a char, varchar, or text column, variable, or parameter in a SQL Server SQL Server database to a SQL_C_CHAR variable on the client, the SQL Server SQL Server Native Client ODBC driver first converts from character to Unicode using the ACP of the server, then from Unicode back to SQL_C_CHAR using the ACP of the client.

Так как все эти преобразования выполняются с SQL Server SQL Server драйвер ODBC для собственного клиента, выполняемым на клиенте, ACP сервера должен быть одним из кодовых страниц, установленных на клиентском компьютере. Because all of these conversions are done by the SQL Server SQL Server Native Client ODBC driver executing on the client, the server ACP must be one of the code pages installed on the client computer.

Выполнение символьных преобразований с использованием формата Юникод гарантирует правильное преобразование всех символов, существующих на обеих кодовых страницах. Making the character conversions through Unicode ensures the proper conversion of all characters that exist in both code pages. Но если символ имеется на одной кодовой странице и отсутствует на другой, этот символ не может быть представлен на целевой кодовой странице. If a character exists in one code page but not another, however, then the character cannot be represented in the target code page. Например кодовой странице 1252 имеется символ зарегистрированного товарного знака (?), а кодовую страницу 437 — нет. For example, code page 1252 has the registered trademark symbol (??), while code page 437 does not.

Настройка AutoTranslate не оказывает влияния на эти преобразования. The AutoTranslate setting has no effect on these conversions:

Перемещение данных между символьными клиентскими переменными SQL_C_CHAR и Юникода nchar, nvarchar, или ntext столбцов, переменных или параметров в SQL Server SQL Server базы данных. Moving data between character SQL_C_CHAR client variables and Unicode nchar, nvarchar, or ntext columns, variables, or parameters in SQL Server SQL Server databases.

Перемещение данных между клиентскими переменными Юникод SQL_C_WCHAR и символ char, varchar, или текст столбцов, переменных или параметров в SQL Server SQL Server базы данных. Moving data between Unicode SQL_C_WCHAR client variables and character char, varchar, or text columns, variables, or parameters in SQL Server SQL Server databases.

Данные всегда нужно преобразовывать при переходе из символьного формата в Юникод. Data always must be converted when moved from character to Unicode.

Лабораторная работа № 2 Программирование внешних устройств

2.1 Цель работы: Изучить основы разработки и архитектуру Windows – приложений на базе WIN 32 API. Программирование аппаратных устройств : клавиатура, мышь, таймер.

Изучаемые вопросы:

На базе архитектуры WIN 32 Application рассмотреть вопросы:

1. Механизм сообщений от клавиатуры.

2. Коды OEM, ANSI, ASCII, виртуальные коды.

3. Виртуальные клавиши.

4. Символьные сообщения.

5. Системные сообщения.

6. Преобразование кодов.

7. Как отличить нажатия совпадающих клавиш.

8. Как узнать ввод строчных и прописных букв.

1. Захват и освобождение окном мыши.

2. Обработка сообщений от мыши.

3. Координаты x,y.

4. Курсор мыши. Управление курсором.

5. Макроопределения сообщений мыши.

6. Сообщения мыши в клиентской и не клиентской области окна.

1. Установка таймера.

2. Функция таймера.

3. Снятие таймера.

2.2 Постановка задачи:

На базе лабораторной работы №1 разработать WIN 32 Application содержащее все вопросы из пункта изучаемые вопросы.

2.3 Теоретические сведения:


Механизм сообщений от клавиатуры

Когда пользователь нажимает или отпускает клавишу, Windows посылает в программу сообщение ввода с клавиатуры. Ниже.приводится перечень сообщений ввода с клавиатуры и события, их вызывающие:

WM_KEYDOWN Пользователь нажал клавишу;

WM_KEYUP Пользователь отпустил клавишу;

WM_SYSKEYDOWN Пользователь нажал системную клавишу;

WM_SYSKEYUP Пользователь отпустил системную клавишу.

Коды OEM, ANSI, ASCII, виртуальные коды

OEM код храниться в lParamc 16 по 23 бит

Виртуальный код клавиши — это независимое от устройства значение клавиши. Windows использует виртуальные коды клавиш для того, чтобы не зависить от используемой персональной ЭВМ. Виртуальный код передаются в параметре wParam.

Виртуальные клавиши

Когда пользователь нажимает или отпускает клавишу, Windows посылает в программу сообщение ввода с клавиатуры

WM_KEYDOWN Пользователь нажал клавишу;

WM_KEYUP Пользователь отпустил клавишу;

WM_SYSKEYDOWN Пользователь нажал системную клавишу;

WM_SYSKEYUP Пользователь отпустил системную клавишу.

Параметр wParam определяет виртуальный код данной клавиши. Виртуальный код клавиши — это независимое от устройства значение клавиши. Windows использует виртуальные коды клавиш для того, чтобы не завесить от используемой персональной ЭВМ.

Символьные сообщения

Прикладная программа, которая читает символы, вводимые с клавиатуры, должна использовать функцию TranslateMessage в своем цикле обработки сообщений. Эта функция преобразует сообщение ввода с клавиатуры в соответствующее сообщение ввода символа в коде ANSI — WM_CHAR или WM_SYSCHAR. Эти сообщения содержат ANSI-коды символа для данной клавиши в параметре wParam. Параметр lParam аналогичен таковому в сообщении ввода с клавиатуры.

Системные сообщения

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

6. Преобразование кодов

Преобразование ANSI OEM

Чтобы корректно отображались тексты в кодировке DOS, вам, вероятно, потребуется преобразовывать строки из кодировки Windows (ANSI) в кодировку DOS (OEM) и обратно. Функция CharToOem преобразовывает строку из кодировки ANSI в кодировку OEM, а функция OemToChar выполняет обратное преобразование:

Как отличить нажатия совпадающих клавиш

На клавиатуре дублируются некоторые клавиши. Например, левый и правый Shift,CTRL и т.д. Чтобы их отличить проверяют состояние 24 бита в lParam

Как узнать ввод строчных и прописных букв

Можно определить двумя способами проверить был ли до этого нажата клавиша SHIFT или при помощи события WM_CHAR.

Фокус ввода

Клавиатура должна разделяться между всеми приложениями, работающими под Windows. Некоторые приложения могут иметь больше одного окна, и клавиатура должна разделяться между этими окнами в рамках одного и того же приложения. Когда на клавиатуре нажата клавиша, только одна оконная процедура может получить сообщение об этом. Окно, которое получает это сообщение клавиатуры, является окном, имеющем «фокус ввода» (inputfocus).

Концепция фокуса ввода тесно связана с концепцией «активного окна». Окно, имеющее фокус ввода — это либо активное окно, либо дочернее окно активного окна. Определить активное окно обычно достаточно просто. Если у активного окна имеется панель заголовка, то Windows выделяет ее. Если у активного окна вместо панели заголовка имеется рамка диалога (это наиболее часто встречается в окнах диалога), то Windows выделяет ее. Если активное окно минимизировано, то Windows выделяет текст заголовка в панели задач.

Если активное окно минимизировано, то окна с фокусом ввода нет. Windows продолжает слать программе сообщения клавиатуры, но эти сообщения выглядят иначе, чем сообщения, направленные активным и еще не минимизированным окнам.

Обрабатывая сообщения WM_SETFOCUS и WM_KILLFOCUS, оконная процедура может определить, когда окно имеет фокус ввода.WM_SETFOCUS показывает, что окно получило фокус ввода, а WM_KILLFOCUS, что окно потеряло его.

Мышь

Папиллярные узоры пальцев рук — маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни.

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ — конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой.

Как сохранить файл в кодировке cp866 (OEM) ?

Dragokas

Very kind Developer

Блокнот Windows этого не умеет делать.

Следует воспользоваться сторонними редакторами, например AkelPad или Notepad++

Пример для AkelPad4

Файл => Сохранить как. => в поле Кодировка выберите «866 OEM Русская» => Сохранить.

Пример для Notepad ++

Кодировки => Кодировки => Кириллица => OEM 866

Если Вы уже набрали код батника в Notepad++ и Вам его нужно пересохранить в кодировке cp866,
действуйте по такой схеме:

1) Скопируйте весь текст батника (комбинация клавиш Ctrl + A или Правка => Выделить все)

2) Вырежьте выделенный текст в буфер обмена (Ctrl + X или правой кнопкой мыши по выделенному тексту => Вырезать)

3) Сделайте все, как на рисунке выше:
Кодировки => Кодировки => Кириллица => OEM 866

Илон Маск рекомендует:  Атрибут min в HTML

4) Вставьте текст из буфера обмена (Ctrl + V или Shift + Insert или правой кнопкой мыши => Вставить)

5) Сохраните файл (Файл => Сохранить).

Кодировка ANSI сменить на UTF-8

lesssss81

Client

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


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

В настройках есть функция сохранять пустой документ в utf-8 но у меня документ не пустой

Кодировка в файлах DBF

Примерно вот так:

Насколько я знаю, формат OEM мы не используем. Осталось с предыдущих времен.

Только вот что-то мне подсказывает, что проблема ниразу не в кодировке.

Что касается «У тех, кому отправляем, ничего не получается» — предложите детально описать, что конкретно не получается. Это не описание проблемы и за такое пора бы уже заказчиков отстреливать.

(2)да, OEM — это DOS-кодировка. А что-то внятное вынудить бесполезно, я бился с описаниями полей два дня, пришлось с бубном прыгать. Просто уже жалко затраченного времени и сил. А с выбором у меня чуть проще, примерно так:

КодировкаXBase — это системное перечисление в 8-ке.

Вы же не просто строку с формы забираете, так ведь?

(4) да вроде нет, все хорошо должно быть.

(7) Вручную написал
Файл.Кодировка = КодировкаXBase.ANSI;

и все равно, посмотрите пожалуйста этот файл

Что нужно вставить, чтобы текст читался и подставлялся в 1с нормально? Пробовал КодировкаXBase.ANSI и КодировкаXBase.OEM, не помогло, хотя может что не так делал.

(15)
для определения в какой кодировке файл можно использовать:

Для файлов дбф выгруженных из 7.7 для нормального чтения в 8

ФайлДБФ = Новый XBase;
ФайлДБФ.Кодировка = КодировкаXBase.OEM;

Если ФайлДБФ.Открыта() = Ложь Тогда
Сообщить(«Указанный файл не доступен, или неверного формата. «);
Возврат;
КонецЕсли;

ФайлДБФ.Первая(); //Установим курсор на начало файла

Faq преобразование текста oem > ansi

Здраствуйте ещё раз!
Есть таблица
с символьным полем
CODE
» 45″
» 96″
» 99″
«100»

Есть функция результат которой равен » 9:»
так вот результат выполнения DBSEEK(» 9:»)
1. результат, если таблица в OEM кодировки » 99″
2. результат, если таблица в ANSI кодировки » 96″

если я вместо «:» подставляю символ с кодом более 64, т.е. символы
после «@» например А,B,C или даже «ё» то находит то что надо,
напомню что код символа «9» = 57, а код символа «:» вроде как 58
Никто не сталкивался с подобными проблеммами?

Re: OEM ANSI
ssa

Сообщений: 12372
Откуда: Москва

Дата: 26.06.07 12:32:52

Сложный вопрос, особенно с учетом отсутствия в фоксе функции DBSEEK() и, соотвественно, с полным отсутствием понимания у местной публики особенностей ее работы.

Re: OEM ANSI
zmej

Сообщений: 220
Откуда: Томаковка

Дата: 26.06.07 12:49:36
Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 12:59:44
Re: OEM ANSI
ssa

Сообщений: 12372
Откуда: Москва

Дата: 26.06.07 13:29:01

Ну и что из того, что она полный аналог? К тому же только по описанию? Откуда уверенность, что DBSEEK() будет вести себя точно так же, как и SEEK()? И что она будет так же подчиняться и таким же настройкам, как SEEK()?

Re: OEM ANSI
MichaelD

Сообщений: 7578

Дата: 26.06.07 13:55:38

Чтобы понять поведение SEEK Command/function, нужно «внимательно почитать» документацию

— к команде SEEK Command
— также внимательно прочитать все ссылкт в See Also этой команды.
— к изученному выше, я бы ещё добавил описания: SET ANSI Command, SET DATASESSION Command, SET COLLATE Command, . и See Also в этих разделах.

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 15:08:14

Чтобы понять поведение SEEK Command/function, нужно «внимательно почитать» документацию

— к команде SEEK Command
— также внимательно прочитать все ссылкт в See Also этой команды.
— к изученному выше, я бы ещё добавил описания: SET ANSI Command, SET DATASESSION Command, SET COLLATE Command, . и See Also в этих разделах.

Спасибо за инфу почитаю фокс, может пойму почему на XBASE++ теже грабли
п.с. кстати взял просто въювером открыл DBF анси задал поиск » 9:» нашёл 96
тоже произвёл тем же въювером на базе ОЕМ нашёл » 99″
Я думаю многие могут столкнутся с подобными проблеммами особенно при переводе
старых приложений на 32 разрядную платформу и т.д.

Вобщем я думаю тут ваще не в SEEKе дело, понятно что поиск происходит
по кодам символов, в кодировке АНСИ он ищет так как будто код символа «:»
меньше чем код символа «9», что конечно не может быть. т.е. в этом
направлении думаю баг, а не в SEEKe

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 15:10:26
Re: OEM ANSI
ssa

Сообщений: 12372
Откуда: Москва

Дата: 26.06.07 15:31:23

Интересно, и что же было опробОвано? Были перепробованы все сочетания всех, влияющих на эту функцию, SET настроек? И всех вариантов настроек, влияющих на построение индексов? Не верю! (с)

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:01:55

Нет конечно зачем все СЕТы! Я тебе говорю, что проблемма в Коде символов!
А индекс принципиально один и менять его не в коем случае нельзя
потому даже мысли поменять индекс небыло!
Кстати какие ключа индекса ты бы использовал?
CODE(3 char)

индекс по полю CODE т.е. ((CODE))

И это вообще к делу никакого отношения не имеет!
Тут проблемма разницы Кодировок ОЕМ и АНСИ, вот хотелось бы узнать
что такая за разница которая влияет на поиск SEEKом!
Напомню, что при замене «:» на символ код которого больше 64 всё отлично работает.
Ты вообще знаешь как работает SEEK на низком уровне?
Когда узнаешь поймёшь о чём я спрашую!

Так же возможно проблемма с пробелом, так как в ОЕМ он определяет
пробел как код символа 32, а в АНСИ может быть и 10 и 32 и 255 .
ну пробывал в тупую писать CHR(255) и т.д. не помогло
ну это скорее от того, что придумать пока больше нечё не могу.

Исправлено: yurecgod, 26.06.07 16:17


Re: OEM ANSI
ssa

Сообщений: 12372
Откуда: Москва

Дата: 26.06.07 16:16:20

Кстати какие ключа индекса ты бы использовал?
CODE(3 char)

индекс по полю CODE т.е. ((CODE))

И это вообще к делу никакого отношения не имеет!

И наступит мне просветленние и попаду я в нирвану.

И все равно непонятно. Если ты лучше нас все знаешь, чего тогда у нас спрашиваешь? А если не знаешь, то какого . на других наезжаешь?

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:24:19

SSA прости, я не говорил, что Индекс отношения к SEEK никакого не имеет!
Я говорил в общем, что проблемма не в SEEKe как таковой.
Не на кого я не наезжаю.
SEEK работает не с символами которые туда пишешь, а с кодами этих символов
к сожалению очень сейчас занят попозже могу накидать полный алгоритм.

p.s. а наезжаешь как раз ты на меня. Ну я не обижаюсь.

Исправлено: yurecgod, 26.06.07 16:32

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:29:37

Кстати в FOXe есть и ДВseek
SET LIBRARY TO DBSEEK
DO CreateTest

INDEX ON ABC TAG ABC
SET ORDER TO TAG ABC
= DBSEEK(«This is record 3») && seeks ABC = «This is record 3»
LIST NEXT 1
USE

PROCEDURE CreateTest
CREATE TABLE test (ABC C(20))
APPEND BLANK
REPLACE ABC WITH «This is record 1»
APPEND BLANK
REPLACE ABC WITH «This is record 2»
APPEND BLANK
REPLACE ABC WITH «This is record 3»
APPEND BLANK
REPLACE ABC WITH «This is record 4»
GO TOP
RETURN
Взял с Хелпа

Re: OEM ANSI
MichaelD

Сообщений: 7578

Дата: 26.06.07 16:32:36

Пожалуй уточню это:

— т.е. с тем, что было в cdx/idx прописано на момент добавления/изменения данных в dbf
— в то время, как на «механизмы сравениеня» влияют SET-ы, установленные в текущей PDS

Re: OEM ANSI
Владимир Максимов

Сообщений: 13846
Откуда: Москва

Дата: 26.06.07 16:44:22

Как Вы думаете, а что вообще должна найти система, если ей задана не существующая строка для поиска? Вы ведь задали строку «9:», а хотите найти строку «96» или «99». По каким правилам должен осуществляться поиск в этом случае?

Правило поиска в этом случае придумали лично Вы или это некий «стандарт» обязательный для всех без исключения систем? Это не «наезд» и не «подколка». Я серьезно. Просто подумайте в этом направлении.

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:47:18
Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:52:51

К сожалению не я придумал. На самом деле это придумал какой то гений
в середине 90 годов, так как этим он очень сократил и упросил программу.
Я начал с того, что начал менять функцию движения по брауз объекту,
но потом меня осенило и я поставил букву «А», т.е. я смотрю если в конце «:»
то меняю её на «А» мне это очень не нравится напрягает и не даёт спокойно
спать. А почему так сделано, очень просто есть функция которая добавляет
к коду символа ЕДИНИЦУ, этим он сделал очень универсальную функцию которая
работает с различными справочниками (как линейными так и иерархическими).
Конечно я могу всё тупо переписать ну это по моиму не правиль, притом
так и не разобравшись в чём причина.

Исправлено: yurecgod, 26.06.07 16:54

Re: OEM ANSI
Владимир Максимов

Сообщений: 13846
Откуда: Москва

Дата: 26.06.07 16:54:08

Это-то как раз просто.

Re: OEM ANSI
yurecgod
Автор

Сообщений: 23

Дата: 26.06.07 16:55:31

Исправлено: yurecgod, 26.06.07 16:58

Re: OEM ANSI
Владимир Максимов

Сообщений: 13846
Откуда: Москва

Дата: 26.06.07 16:59:25

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

Ну, не нашла система строку, которую ей указали в качестве критерия поиска. Что она должна сделать? Куда установить указатель записи? Оставить там, где был; перейти в конец таблицы; установить на ближайшую похожую? Если на ближайшую похожую, то похожую в большую или в меньшую сторону?

Другими словами, существует довольно большое количество вариантов того, как надо бы было осуществлять поиск в этом случае. Дело вовсе не в кодах символов (хотя и они имеют значение), а именно в настройках среды, которые как раз и опеделяют правила поиска. Куда же в конце концов мы попадем, если не нашли то, что хотели.

Универсальный декодер — конвертер кириллицы

Результат

[Результат перекодировки появится здесь. ]

Поставьте ссылку на наш сайт!
Универсальный декодер кириллицы Custom Work
For a small fee I can help you quickly recode/recover large pieces of data — texts, databases, websites. or write custom functions you can use (invoice available).
FAQ and contact information.

О программе

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

Использование

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

Ограничения

  • Если текст состоит из вопросительных знаков («. ?? . «), то проблема скорее всего на стороне отправителя и восстановить текст не получится. Попросите отправителя послать текст заново, желательно в формате простого текстового файла или в документе LibreOffice/OpenOffice/MSOffice.
  • Не любой текст может быть гарантированно декодирован, даже если есть вы уверены на 100%, что он написан в кириллице.
  • Анализируемый и декодированный тексты ограничены размером в 100 Кб.
  • Программа не всегда дает стопроцентную точность: при перекодировке из одной кодовой страницы в другую могут пропасть некоторые символы, такие как болгарские кавычки, реже отдельные буквы и т.п.
  • Программа проверяет максимум 6776 вариантов из двух и трех перекодировок: если имело место многократное перекодирование вроде koi8(utf(cp1251(utf))), оно не будет распознано или проверено. Обычно возможные и отображаемые верные варианты находятся между 32 и 255.
  • Если части текста закодированы в разных кодировках, программа сможет распознать только одну часть за раз.

Условия использования

Пожалуйста, обратите внимание на то, что данная бесплатная программа создана с надеждой, что она будет полезна, но без каких-либо явных или косвенных гарантий пригодности для любого практического использования. Вы можете пользоваться ей на свой страх и риск.

Если вы используете для перекодировки очень длинный текст, убедитесь, что имеется его резервная копия.

Переводчики

Страница подготовки переводов на другие языки находится тут.

Что нового

October 2013 : I am trying different optimizations for the system which should make the decoder run faster and handle more text. If you notice any problem, please notify me ASAP.

На английской версии страницы доступен changelog программы.

forum.farmanager.com

Far Manager Forum

  • Unanswered topics
  • Active topics
  • Search

Смена кодировки текстового файла: неоднозначности

Смена кодировки текстового файла: неоднозначности

Post by HaRT » Mon 12 Mar, 2012 09:14

Хорошо бы добавить в FAQ вопрос/ответ про смену кодировки файла.

2012-03-14
Выявились неоднозначности, надо сперва самим договориться, чтобы простых пользователей не смущать.

Re: Far 3 FAQ — обсуждение

Post by John Doe » Wed 14 Mar, 2012 11:00

Re: Far 3 FAQ — обсуждение

Post by 2useven10 » Wed 14 Mar, 2012 11:14

Re: Far 3 FAQ — обсуждение

Post by John Doe » Wed 14 Mar, 2012 11:32

Re: Far 3 FAQ — обсуждение

Post by 2useven10 » Wed 14 Mar, 2012 11:59

Re: Far 3 FAQ — обсуждение

Post by John Doe » Wed 14 Mar, 2012 12:04

Всё верно, но именно эта проблема к упомянутому выше Shift-F2 не имеет отношения.

Требуется F2 + Shift-F4 + указание правильной кодировки.
Причём это мог бы делать сам фар, а в т о м а т и ч е с к и, и все вопли пропали бы.

Re: Far 3 FAQ — обсуждение

Post by 2useven10 » Wed 14 Mar, 2012 12:13

1) Shift-F2 — смена кодировки файла который корректно отображается в редакторе. Иначе двойное перекодирование и потенциальная потеря данных.

2) F2 — также может привести к безвозвратной порче данных. Так что — просто Shift-F4 и правильная кодировка. ‘Сам’ может не всегда. Искусственный интеллект с потенциальной потерей данных — не самое лучшее решение.

Re: Far 3 FAQ — обсуждение

Post by John Doe » Wed 14 Mar, 2012 12:18

Re: Far 3 FAQ — обсуждение

Post by Max Rusov » Wed 14 Mar, 2012 12:30

Re: Смена кодировки текстового файла: неоднозначности

Post by John Doe » Wed 14 Mar, 2012 12:32

Re: Far 3 FAQ — обсуждение

Post by John Doe » Wed 14 Mar, 2012 12:38

Вы правы, т.е. всё ещё хуже! Используя Shift-F4 мы сами того не заметив можем потерять важные изменения!
Поэтому вначале нужно F2, а потом уж ShiftF4.

Мой макрос так и делает: если изменений нет — молча ShiftF4.
Если есть — предлагает сохранить, если пользователь соглашается, тогда F2 + ShiftF4.

Re: Смена кодировки текстового файла: неоднозначности

Post by 2useven10 » Wed 14 Mar, 2012 12:48

Re: Смена кодировки текстового файла: неоднозначности

Post by Max Rusov » Wed 14 Mar, 2012 12:56

Моя версия макроса. В принципе — это ответ на вопрос, что должен делать FAR автоматически. Мне кажется, что как-то так и должен.

Re: Смена кодировки текстового файла: неоднозначности

Post by John Doe » Wed 14 Mar, 2012 13:01

«Здесь» это где? Я вообще-то давал ссылки на 1 и 2.
Собственно, ничего суперумного там нет, поэтому можем и с начала:

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

Re: Смена кодировки текстового файла: неоднозначности

Post by Max Rusov » Wed 14 Mar, 2012 13:03

Re: Смена кодировки текстового файла: неоднозначности

Post by Max Rusov » Wed 14 Mar, 2012 13:20

Как то Вы непонятно сформулировали. Я бы сказал так:

Есть 2 пути:
1. Менять кодировку путем перечитывания файла (предварительно предложив сохранить изменения, если были)
2. Менять кодировку уже загруженного файла «на лету», как делает F8/ShiftF8

Второй способ был хорош в эпоху 1-го FAR’а. Сейчас, со зверинцем юникодных кодировок от него больше проблем чем пользы. Я бы предложил полностью перейти на 1-й способ, при этом снимутся все ограничения на переключение кодировок по F8/ShiftF8.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL