Far Manager Encyclopedia

 Programming FAR plugins - Encyclopedia for Developers

Encyclopedia for Developers 1.75 SR2537

FAR Manager - консольный файловый менеджер для операционных систем семейства Windows (базирующихся на Win32 API). Программа предоставляет удобный интерфейс пользователя для работы с файловыми системами (реальными и эмулированными) и файлами.

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

Оболочка FAR Manager настолько тесно слилась со своими плагинами, что говорить о ней и не говорить о плагинах просто бессмысленно. Плагины неимоверно расширяют возможности FAR Manager, дополняя их и модифицируя (см. краткий обзор возможностей).

Энциклопедия «Programming FAR plugins - Encyclopedia for Developers» является наиболее полным справочным руководством по Plugin API FAR Manager последних версий и предназначена в первую очередь для программистов, пишущих (и начинающих писать) плагины. Энциклопедия позволит вам узнать все аспекты написания плагинов, ознакомиться со статьями и заметками авторов, имеющих богатый опыт в данной предметной области.

Мы надеемся, что эта Энциклопедия станет для вас чрезвычайно полезным помощником в работе по программированию плагинов для FAR Manager.

Введение
Что нового?
О проекте
Установка
Лицензия
Авторы
Структуры
Сервисные функции
Экспортируемые функции
Dialog API
Viewer API
Panel API
Editor API
Far Standard Functions
Локализация
Custom API
Макросы
Дополнения
Обзор возможностей
"Правила хорошего тона"
API History
Примеры
Статьи
ЧАВО
Copyright © PlugRinG, 1999-2009.


О проекте Programming FAR plugins - Encyclopedia for Developers

главная | Лицензия | Setup Help

Цель проекта - создание "полнофункционально-избыточного" файла помощи на русском и английском, применительно для языков программирования C/C++ и Pascal. Данная энциклопедия в основном будет интересна разработчикам плагинов для FAR Manager.

Энциклопедия существует в двух вариантах - HTMLHelp (pluginsr.chm/pluginse.chm) и OnlineHelp-версия:

pluginsr.chm/pluginse.chm
Применима в составе MSDN (вариант с CHM/CHI-файлами, например, "MSDN Library - July 2001").
pluginsr online
Online-версия энциклопедии. Всегда можно "пролистать" в Сети по адресу: http://api.farmanager.com/

Энциклопедия, кроме оригинальных тем по Plugins API, содержит множество дополнительных разделов, которые (как мы надеемся) помогут разработчикам плагинов при написании собственных "произведений".

Валентин Скирдин
vskirdin@mail.ru
Координатор проекта


Лицензия

главная | авторы
  1. Все авторские права на Энциклопедию "Programming FAR plugins - Encyclopedia for Developers" принадлежат только авторам.

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

  3. Энциклопедия существует только на русском и английском языках в двух вариантах - HTMLHelp (FarEncyclopedia.ru.chm/FarEncyclopedia.en.chm) и OnlineHelp-версия:
    http://api.farmanager.com/.
    Другие источники считаются нарушением настоящего лицензионного соглашения.

  4. ЭНЦИКЛОПЕДИЯ ПОСТАВЛЯЕТСЯ ПО ПРИНЦИПУ "AS IS". НИКАКИХ ГАРАНТИЙ НЕ ПРИЛАГАЕТСЯ И НЕ ПРЕДУСМАТРИВАЕТСЯ. ВЫ ИСПОЛЬЗУЕТЕ ЭТУ ПРОГРАММНУЮ ДОКУМЕНТАЦИЮ НА СВОЙ РИСК. АВТОРЫ НЕ БУДУТ ОТВЕЧАТЬ НИ ЗА КАКИЕ ПОТЕРИ ИЛИ ИСКАЖЕНИЯ ДАННЫХ, ЛЮБУЮ УПУЩЕННУЮ ВЫГОДУ В ПРОЦЕССЕ ИСПОЛЬЗОВАНИЯ ИЛИ НЕПРАВИЛЬНОГО ИСПОЛЬЗОВАНИЯ ЭТОГО ПРОДУКТА.

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

  6. Установка и использование Энциклопедии означает, что вы понимаете положения настоящего лицензионного соглашения и согласны с ними.

  7. Если почему-либо вы не согласны с этим лицензионным соглашением, Вам необходимо удалить файлы дистрибутива Энциклопедии с ваших устройств хранения информации и прекратить использование Энциклопедии.

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

  9. Авторы оставляет за собой право отменить действие данной лицензии для любой из следующих версий Энциклопедии.

Благодарим за использование Энциклопедии
"Programming FAR plugins - Encyclopedia for Developers".

координатор - Валентин Скирдин

Copyright © PlugRinG, 1999-2009.


Что нового в Far Manager Encyclopedia?

Что нового в Far Manager Encyclopedia 1.75 SR2555?

main

7 Октября 2009

  • Macro: уточнение функции checkhotkey.

8 юиня 2009

  • Начало процесса выхода за рамки "только описания АПИ"...
    Новые имена файлов FarEncyclopedia.en.chm и FarEncyclopedia.ru.chm.

1 апреля 2009

  • Добавлены флаги LIF_HIDDEN, LIF_GRAYED, MIF_HIDDEN, MIF_GRAYED.

  • Цветовая палитра увеличена на 10 цветов.

4 марта 2009

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

3 марта 2009

  • Macro: функция Menu.Select возвращает -1, если вызвана не из контента (не из меню).

2 марта 2009

  • Macro: макросы можно назначать на клавиши мыши. В теле макропоследовательности доступны константы: MsX, MsY, MsButton, MsCtrlState.

24 февраля 2009

  • Macro: новая функция atoi - преобразует число из строкового представления в числовое.

23 января 2009

  • Macro: дополнения и уточнения функционала у функции editor.sel - работает в редакторе, в строках ввода в диалогах, в командной строке.

  • Исправлены ошибки в ECTL_SELECT:
    • отметка блока снимается всегда, даже если были неправильные параметры
    • отметка блока снимается всегда, даже если указанной строки (BlockStartLine) нет (BlockStartLine больше количества строк в редакторе)
    • если BlockHeight превышал количество строк в редакторе (например, пытаемся выделить блок, указывая последнюю строку, а BlockHeight, например, равный 10), то EditorControl возвращал FALSE, хотя блок успешно выделялся.
    • для BlockWidth, равным -1, получалось так, что для BTYPE_COLUMN "транзакция" пометки блока была неполной - это могло приводить к всевозможным проблемам с блоками.

16 января 2009

  • Macro: функция waitkey имеет второй необязательный параметр - тип возвращаемого значения.

  • Macro: новая функция editor.sel позволяет манипулировать блоками в тексте.

  • Macro: новая функция key преобразует значение V в строковый эквивалент названия клавиши.

  • Macro: Именованные клавиши (например, CtrlK) могут участвовать в любых выражениях; в этом случае они считаются как числа.

26 ноября 2008

  • Добавлен новый цвет в палитру - COL_EDITORSCROLLBAR.

6 ноября 2008

  • Диалоги с флагом FDLG_SMALLDIALOG теперь отрисовываются с тенью. Чтобы запретить рисовать тень, укажите флаг FDLG_NODRAWSHADOW.

24 сентября 2008 г.

  • Новые флаги функции MkLink: FLINK_SYMLINKFILE, FLINK_SYMLINKDIR, позволяющие создавать символические ссылки Windows Vista/2008. Флаг FLINK_SYMLINK переименован в FLINK_JUNCTION.

11 августа 2008 г.

  • В цветовую палитру добавлен цвет пользовательского экрана.

06 августа 2008 г.

  • Macro: Комбинация CtrlBreak прерывает выполнение макроса.

  • Macro: Добавлена функция S=trim(S[,Mode]) - удаляет все пробельные символы.

  • Viewer API: Команда VCTL_GETINFO возвращала значение WindowSizeY на 1 меньше реального значения.

19 июня 2008 г.

  • Macro: Теперь Dlg.ItemType "отдает" все то же самое, что возвращает Dlg.GetValue(XXX,1).

17 июня 2008 г.

  • Viewer API: добавлены два события VE_GOTFOCUS и VE_KILLFOCUS.

15 мая 2008 г.

  • В перечисление FarDialogSettings добавлены константы FDIS_DELREMOVESBLOCKS и FDIS_MOUSECLICKOUTSIDECLOSESDIALOG, соответствующие настройкам диалогов "Del удаляет блоки в строках ввода" и "Клик мыши вне диалога закрывает диалог".

3 апреля 2008 г.

  • Macro: добавлены функции для работы со стековыми закладками BM.XXX().

30 марта 2008 г.

  • 6 новых команд EditorControl для управления позициями навигации ("стековыми закладками") в редакторе:
    ECTL_ADDSTACKBOOKMARK, ECTL_CLEARSTACKBOOKMARKS и ECTL_DELETESTACKBOOKMARK - создание и удаление позиций навигации,
    ECTL_GETSTACKBOOKMARKS - получение информации о позициях навигации,
    ECTL_NEXTSTACKBOOKMARK и ECTL_PREVSTACKBOOKMARK - навигация в редакторе

29 марта 2008 г.

  • новый флаг панели: PFLAGS_PANELLEFT.

27 марта 2008 г.

  • Macro: добавлена макрообласть "Consts" для хранения именованных констант.

25 марта 2008 г.

  • В цветовую палитру добавлены цвета для индикаторов длинных строк в меню, списках и комбинированных списках.

  • Macro: Добавлена константа "Editor.RealPos" - текущая позиция курсора в строке в редакторе без привязки к размеру табуляции.

  • Macro: Некоторые функции могут иметь опциональные параметры.

  • Macro: Новая функция prompt - позволяет ввести одну строку текста.

11 марта 2008 г.

  • Macro: Новая функция V=akey(N) - возвращает имя или код клавиши, инициировавшей макрос.

31 декабря 2007 г.

  • API: Новая команда ACTL_REDRAWALL - перерисовка всех окон FAR.

23 декабря 2007 г.

  • Меню плагинов можно вызывать из диалога.

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

14 декабря 2007 г.

  • Macro: Добавлена в коллекцию функция Result=replace(Str,Find,Replace,Cnt).

  • API: Новая команда MCMD_GETSTATE для ACTL_KEYMACRO, возвращает статус работы макродвижка.

  • Macro: функция Menu.Select теперь с двумя параметрами.

6 декабря 2007 г.

  • 2 новых эвента для панельного плагина: FE_GOTFOCUS и FE_KILLFOCUS.

  • 2 новых эвента для редакторного плагина: EE_GOTFOCUS и EE_KILLFOCUS.

  • В диалогах, сразу после DN_INITDIALOG приходит DN_GOTFOCUS для того элемента, который Focus=1.

4 декабря 2007 г.

  • Macro: Добавлена в коллекцию функция n=mod(n1,n2).

  • Macro: добавлена функция N=Menu.Select(S). Позиционирует на первый пункт, содержащий подстроку S.

  • Новый флаг DIF_NOAUTOCOMPLETE для строк редактирования - отключает автодополнение.

12 октября 2007 г.

  • Macro: Добавлена константа "MacroArea" - возвращает имя текущей макрообласти.

  • Macro: Bof/Eof/Empty/Selected в панелях типа QView/Info/Tree возвращают значения для этих типов панелей. Для обычных панелей возвращают значения из командной строки.

13 сентября 2007 г.

  • Теперь при открытом DI_COMBOBOX в диалоговую процедуру посылаются события DN_KEY или DN_MOUSEEVENT. Управлять этим поведением можно с помощью сообщений DM_SETCOMBOBOXEVENT и DM_GETCOMBOBOXEVENT.

30 августа 2007 г.

  • Bug: Macro: Если пункт меню не содержит горячую клавишу, то GetHotkey() возвращает "0" вместо ""

  • Macro: Добавлена команда $SelWord - выделяет слово.

  • Bug: Macro: В панелях быстрого просмотра и информации не работали некоторые переменные: ItemCount, CurPos, Selected, Bof, Eof всегда 0; Empty всегда 1.

7 августа 2007 г.

  • Bug: Если плагин для списка отключал реакцию слежения за курсором мыши (LMRT_NEVER), то в диалоговую процедуру не приходило событие DN_MOUSECLICK для двойного клика мыши (Mantis#0000309)

  • В структуре PluginPanelItem вместо WIN32_FIND_DATA используется структура FAR_FIND_DATA. Вместо макроса _FAR_USE_FARFINDDATA необходимо использовать _FAR_USE_WIN32_FIND_DATA.

23 июля 2007 г.

  • Добавлены команды DM_GETEDITPOSITION и DM_SETEDITPOSITION - управление позицией строки в строках ввода в диалогах.

5 июля 2007 г.

  • Macro: добавлена функция gethotkey.

  • Macro: Не воспринимались переменные начинающиеся с цифр (например, %3DO).

  • Bug: DM_LISTGETCURPOS возвращал неправильное значение после открытия ComboBox`а, навигации по списку с последующим отказом от выбора (нажали Esc).

31 мая 2007 г.

  • Macro: добавлена функция Panel.SetPosIdx - позиционирование на файловой панели по индексу.

10 мая 2007 г.

  • Macro: новые функции asc() и chr.

23 марта 2007 г.

  • Макросы в реестре могут иметь тип REG_MULTI_SZ.

  • Добавлен флаг KSFLAGS_REG_MULTI_SZ.

14 марта 2007 г.

  • После вызова EditorControl(ECTL_SELECT) с установленным значением поля BlockStartLine = -1, последующий вызов ECTL_GETINFO так же возвращал -1 в поле BlockStartLine.

13 марта 2007 г.

  • Macro: новые функции waitkey() и eval.

20 февраля 2007 г.

  • Добавлен флаг DIF_NOTCVTUSERCONTROL для DI_USERCONTROL.

7 февраля 2007 г.

  • Macro: новые слова APanel.ColumnCount и PPanel.ColumnCount.

30 января 2007 г.

  • Новая команда: FCTL_GETUSERSCREEN.

25 января 2007 г.

  • Для элемента DI_VTEXT добавлена обработка флагов: DIF_CENTERGROUP, DIF_SEPARATOR, DIF_SEPARATOR2, DIF_SHOWAMPERSAND.

  • В обработчике DefDlgProc для события DN_BTNCLICK не учитывался флаг DIF_BTNNOCLOSE.

  • Некорректная отрисовка элемента DI_TEXT для сочетания условий: DIF_CENTERTEXT + DIF_SEPARATOR + X1 не равен "-1"

24 января 2007 г.

  • Ужесточение правил, касаемых координат X2 и Y2 в элементах диалогов. Y2 указывать всегда, а не 0.

18 января 2007 г.

  • Не посылался EE_CLOSE для "?New File?".

  • Неправильная цветовая отрисовка диалога сообщения при использование флага FMSG_WARNING в функции Messag без кнопок.

27 декабря 2006 г.

  • Macro: новые слова Help.FileName, Help.Topic и Help.SelTopic.

  • Для окна помощи команда ACTL_GETWINDOWINFO теперь заполняет поле Name - содержит полный путь к просматриваемому HLF-файлу.

01 декабря 2006 г.

  • Viewer API: Член структуры ViewerMode.TypeWrap переименован в ViewerMode.WordWrap

  • Viewer API: Добавлена команда VCTL_SETMODE, позволяющая менять режимы программы просмотра.

23 ноября 2006 г.

  • Macro: $AKey - вставить во входной буфер код клавиши, вызвавшей макрос.

21 ноября 2006 г.

  • Приведение АПИ к 64bit совместимости:
    • DlgProc: long Param2 -> LONG_PTR Param2 и возвращает LONG_PTR вместо long
    • SendDlgMessage: long Param2 -> LONG_PTR Param2 и возвращает LONG_PTR вместо long
    • DefDlgProc: long Param2 -> LONG_PTR Param2 и возвращает LONG_PTR вместо long
    • DialogEx: long Param -> LONG_PTR Param
    • FarMenuItemEx: DWORD UserData -> DWORD_PTR UserData
    • PluginPanelItem: DWORD UserData -> DWORD_PTR UserData
    • AdvControl: возвращает INT_PTR вместо int
    • OpenPlugin: int Item -> INT_PTR Item

20 сентября 2006 г.

  • Macro: fexist() понимает символы маски '*' и '?'

  • Macro: Если имя содержит символы '*' и '?', то fattr() возвращает атрибуты для первого найденного файлового объекта.

  • Macro: fexist() и fattr() теперь не работают с панелями, для работы с панелями добавлены новые функции panel.fexist() и panel.fattr().

25 августа 2006 г.

  • Скорректировано описание работы события DN_BTNCLICK для DI_RADIOBUTTON.

29 июля 2006 г.

  • Добавлена функция FSF.snprintf - осуществляет форматированный вывод в строку с заданным размером.

20 июня 2006 г.

  • Статья Ивана Синтюрина - "Работа с "временной панелью" в своем плагине"

  • Статья от Gigabyte - "Написание плагина на Delphi (ID3 Viewer)"

05 апреля 2006 г.

  • Macro: Новая функция "N=sleep(N)". Организация задержки в макросе.

  • Macro: Константа "Far.Height" - высота консольного окна FAR в строках.

  • Macro: Константа "Far.Title" - текущий заголовок консольного окна FAR (без суффикса " - Far").

  • Macro: Константа "Title" - заголовок текущего объекта.

  • Macro: Константа "Drv.ShowPos" - для левой (1) или правой (2) панели вызвано меню выбора дисков.

  • Macro: Константа "Drv.ShowMode" - флаги отображения меню выбора дисков.

long History, история API


Экспортируемые функции

главная

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

Внимание! Внимание!

  • Все имена файлов, передаваемые FAR, должны быть в кодировке OEM. FAR, в свою очередь, тоже передает имена файлов в OEM. Перед вызовом функций плагина, FAR вызывает функцию SetFileApisToOEM. Если плагин где-либо использует SetFileApisToANSI, то перед возвратом в Far необходимо вызвать SetFileApisToOEM.

Функции общего назначения

Функция | Описание
Configure | конфигурирование плагина
ExitFAR | перед выходом из FAR Manager
GetMinFarVersion | указать минимальную версию FAR Manager
GetPluginInfo | основная информация о плагине
SetStartupInfo | глобальные установки

Специфические функции работы с панелью

Функция | Описание
ClosePlugin | перед закрытием открытого плагина.
Compare | перекрывает алгоритм сортировки
DeleteFiles | удаление файлов
FreeFindData | освобождает память, запрошенную функцией GetFindData
FreeVirtualFindData | освобождает память, выделенную функцией GetVirtualFindData
GetFiles | получить файлы
GetFindData | получить файлы из текущего каталога
GetOpenPluginInfo | информация об открытом плагине
GetVirtualFindData | получить файлы
MakeDirectory | создать каталог
OpenFilePlugin | открыть файл
OpenPlugin | создает новую копию плагина в памяти
ProcessEvent | обработка событий
ProcessHostFile | выполнить архивную команду FAR'a
ProcessKey | обработка событий клавиатуры
PutFiles | поместить файлы на эмулируемую файловую систему
SetDirectory | установить текущий каталог на эмулируемой файловой системе.
SetFindList | Перемещает найденные в Диалоге поиска файлов файлы в эмулируемую файловую панель

Специфические функции редактора

Функция | Описание
ProcessEditorInput | обработка событий клавиатуры
ProcessEditorEvent | обработка событий редактора

Специфические функции программы просмотра

Функция | Описание
ProcessViewerEvent | обработка событий программы просмотра

Специфические функции диалога

Функция | Описание
ProcessDialogEvent | обработка событий диалога
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


Экспортируемые функции

Экспортируемые функции - Функции общего назначения

главная | экспортируемые функции
Функция | Описание
Configure | конфигурирование плагина
ExitFAR | перед выходом из FAR Manager
GetMinFarVersion | указать минимальную версию FAR Manager
GetPluginInfo | основная информация о плагине
SetStartupInfo | глобальные установки
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


Configure

главная | экспортируемые функции
Функция Configure вызывается, когда пользователь выбрал в меню "Plugins configuration" ("Параметры внешних модулей") пункт, добавленный туда данным плагином.
int WINAPI Configure(
  int ItemNumber
);

Параметры

ItemNumber
Номер выбранного элемента в списке пунктов, экспортированном данным плагином в меню "Параметры внешних модулей".

Возвращаемое значение

Если функция завершается успешно, то возвращается TRUE - в этом случае FAR выполняет обновление панелей.
Если пользователь прервал выполнение диалога конфигурации, то верните FALSE.

Замечания

Если ваш плагин содержит только одну функцию, то параметр ItemNumber можно игнорировать.

Пример

int WINAPI _export Configure(int ItemNumber)
{
  switch(ItemNumber)
  {
    case 0:
      return(Config());
  }
  return(FALSE);
}
Смотрите также:
GetPluginInfo


ExitFAR

главная | экспортируемые функции
Функция ExitFAR вызывается перед выходом из FAR. В этой функции плагин может удалить все используемые ресурсы, например, ранее запрошенную память.
void WINAPI ExitFAR( void );

Параметры

Нет.

Возвращаемое значение

Нет.
Смотрите также:
ClosePlugin


GetMinFarVersion

главная | экспортируемые функции
FAR вызывает функцию GetMinFarVersion для получения информации о минимальной версии, с которой согласен работать плагин.
int WINAPI GetMinFarVersion(void);

Параметры

Нет.

Возвращаемое значение

Возвращаемое значение должно быть в формате 0xZZZZXXYY:
Компонента | Описание
ZZZZ | номер билда (FAR 1.70.387 = 0x0183)
XX | major version (FAR 1.70 = 0x01)
YY | minor version (FAR 1.70 = 0x46)

Рекомендуется использовать макрос MAKEFARVERSION.

Замечания

Если возвращаемое функцией значение больше чем текущая версия FAR Manager (включая номер билда) - выводится сообщение об ошибке и плагин выгружается (потом он пропадает из меню плагинов).

Пример

// Укажем, что этот плагин требует 591-й билд FAR Manager 1.70
int WINAPI _export GetMinFarVersion(void)
{
  return MAKEFARVERSION(1,70,591);
}

// А этот плагин будет гарантировано работать FAR Manager начиная
// с версии 1.70 и выше.
int WINAPI _export GetMinFarVersion(void)
{
  return MAKEFARVERSION(1,70,0);
}
Смотрите также:
MAKEFARVERSION, FARMANAGERVERSION, "Плагин для разных версий FAR Manager"


GetPluginInfo

главная | экспортируемые функции
Функция GetPluginInfo вызывается для получения основной информации о плагине.
void WINAPI GetPluginInfo(
  struct PluginInfo *Info
);

Параметры

Info
Указатель на структуру типа PluginInfo. Плагин должен заполнить эту структуру.

Возвращаемое значение

Нет.

Замечания

  1. Функция вызывается для получения информации о плагине перед выполнением следующих действий:
    • перед показом меню конфигурации (Options|Plugins configuration) из функции Configure
    • перед показом меню плагинов (F11)
    • перед показом меню выбора дисков (Alt-F1/Alt-F2)
    • из командной строки по префиксу (например, net:\\share)
  2. Т.к. функция вызывается достаточно часто, то не стоит выполнять в ней длительные по времени операции.
  3. Структура PluginInfo, передаваемая функции GetPluginInfo, уже заполнена 0. Плагин обязательно должен заполнить поле PluginInfo.StructSize
  4. FAR вызывает функцию GetPluginInfo достаточно часто, поэтому при проектировании плагина необходимо минимизировать "расчеты", производимые в этой функции.

Пример

void WINAPI _export GetPluginInfo(struct PluginInfo *Info)
{
  Info->StructSize=sizeof(struct PluginInfo);
  Info->Flags=PF_EDITOR|PF_DISABLEPANELS;

  static char *PluginMenuStrings[1];
  PluginMenuStrings[0]=GetMsg(MBrackets);

  Info->PluginMenuStrings=PluginMenuStrings;
  Info->PluginMenuStringsNumber=sizeof(PluginMenuStrings)/
             sizeof(PluginMenuStrings[0]);
}
Смотрите также:
PluginInfo


SetStartupInfo

главная | экспортируемые функции
Функция SetStartupInfo вызывается один раз, после загрузки DLL-модуля в память. FAR передает плагину информацию, необходимую для дальнейшей работы.
void WINAPI SetStartupInfo(
  const struct PluginStartupInfo *Info
);

Параметры

Info
Указатель на структуру PluginStartupInfo.

Возвращаемое значение

Нет.

Замечания

  1. В FAR Manager 1.65 и ниже эта функция вызывается первой, сразу после загрузки DLL-модуля.
  2. В FAR Manager 1.70 и выше эта функция вызывается после вызова функции GetMinFarVersion.
  3. Указатель Info действителен только в области видимости данной функции (до выхода из функции), так что структура должна копироваться во внутреннюю переменную плагина для дальнейшего использования:
    static struct PluginStartupInfo Info;
...
void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info)
{
  ::Info=*Info;
  ...
}
  4. Если в плагине используются "стандартные функции" из структуры FarStandardFunctions, то член PluginStartupInfo.FSF так же должен быть сохранен в локальное пространство плагина:
    static struct PluginStartupInfo Info;
static struct FarStandardFunctions FSF;

void  _export SetStartupInfo(struct PluginStartupInfo *psInfo)
{
    Info=*psInfo;
    FSF=*psInfo->FSF;
    Info.FSF=&FSF; // скорректируем адрес в локальной структуре
    ...
}


Экспортируемые функции

Экспортируемые функции - Панель

главная | экспортируемые функции

Внимание! Внимание!

  • Все имена файлов, передаваемые FAR, должны быть в кодировке OEM. FAR, в свою очередь, тоже передает имена файлов в OEM. Перед вызовом функций плагина, FAR вызывает функцию SetFileApisToOEM. Если плагин где-либо использует SetFileApisToANSI, то перед возвратом в Far необходимо вызвать SetFileApisToOEM.
Функция | Описание
ClosePlugin | перед закрытием открытого плагина.
Compare | перекрывает алгоритм сортировки
DeleteFiles | удаление файлов
FreeFindData | освобождает память, запрошенную функцией GetFindData
FreeVirtualFindData | освобождает память, выделенную функцией GetVirtualFindData
GetFiles | получить файлы
GetFindData | получить файлы из текущего каталога
GetOpenPluginInfo | информация об открытом плагине
GetVirtualFindData | получить файлы
MakeDirectory | создать каталог
OpenFilePlugin | открыть файл
OpenPlugin | создает новую копию плагина в памяти
ProcessEvent | обработка событий
ProcessHostFile | выполнить архивную команду FAR'a
ProcessKey | обработка событий клавиатуры
PutFiles | поместить файлы на эмулируемую файловую систему
SetDirectory | установить текущий каталог на эмулируемой файловой системе.
SetFindList | Перемещает найденные в Диалоге поиска файлов файлы в эмулируемую файловую панель
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


ClosePlugin

главная | экспортируемые функции
Функция ClosePlugin вызывается перед закрытием открытого плагина.
void WINAPI ClosePlugin(
  HANDLE hPlugin
);

Параметры

hPlugin
Описатель открытого плагина

Возвращаемое значение

Нет
Смотрите также:
ExitFar


Compare

главная | экспортируемые функции
Плагин может экспортировать функцию Compare, чтобы перекрыть используемый по умолчанию алгоритм сортировки файлов.
int WINAPI Compare(
  HANDLE hPlugin,
  const struct PluginPanelItem *Item1,
  const struct PluginPanelItem *Item2,
  unsigned int Mode
);

Параметры

hPlugin
Описатель плагина, возвращаемый функциями OpenPlugin или OpenFilePlugin.
Item1, Item2
Указатели на структуру PluginPanelItem для сравнения.
Mode
См. Методы сортировки

Возвращаемое значение

Эта функция возвращает одно из следующих значение типа int:

-1 если Item1 < Item2
 0 если Item1 == Item2
 1 если Item1 > Item2
-2 если используется внутренняя функция Compare для данного метода сортировки.

Замечания

Для сортировки элементов FAR использует стандартную RTL-функцию qsort, которая реализует нестабильную сортировку. Иными словами, если элементы массива равны с точки зрения функции сравнения, на панели они будут отображаться в произвольном порядке, меняющемся при каждом перечитывании панели.


DeleteFiles

главная | экспортируемые функции
Функция DeleteFiles вызывается для удаления файлов из эмулируемой файловой системы
(FAR плагину: "этот (эти) файлы с твоей панели нужно удалить").
int WINAPI DeleteFiles(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указатель на массив структур типа PluginPanelItem. Каждая структура описывает файл для удаления.
ItemsNumber
Количество элементов в массиве PanelItem.
OpMode
Комбинация флагов operation mode. Эта функция обязана обрабатывать флаг OPM_SILENT.

Возвращаемое значение

Если функция выполнила свои действия успешно, то верните TRUE. В противном случае - FALSE.

Замечания

  1. Плагин должен сам обрабатывать "свои" папки.
  2. Хорошим тоном считается вариант, когда плагин перед удалением "попросит" подтвердить пользователя о своих намерениях (см. так же ACTL_GETCONFIRMATIONS, флаги FCS_DELETE и FCS_DELETENONEMPTYFOLDERS)

Пример

int WINAPI DeleteFiles(HANDLE hPlugin, PluginPanelItem *PanelItem,
           int ItemsNumber,int OpMode)
{
  struct PluginPanelItem * curPI=&PanelItem[0];
  for(int CurItem=0;
      CurItem<ItemsNumber;CurItem++,
      curPI++)
  {
    char* aFile=curPI->FindData.cFileName;
    if(!RemoveFileFromFS(aFile))
    {
      char *MsgItems[]={"Delete failed","","OK"};
      MsgItems[1] = GetErrorStringFS();
      Message(MyNumber,0,NULL,MsgItems,
              sizeof(MsgItems)/sizeof(MsgItems[0]),1);
      return(FALSE);
    }
  }
  return(TRUE);
}


FreeFindData

главная | экспортируемые функции
Функция FreeFindData освобождает память под данные, запрошенную функцией GetFindData
(FAR плагину: "я тут списочек запрашивал, так вот, он мне более не нужен, освободи память").
void WINAPI FreeFindData(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указатель на массив структур типа PluginPanelItem, запрошенных функцией GetFindData.
ItemsNumber
Количество элементов в массиве PanelItem.

Возвращаемое значение

Нет.
Смотрите также:
GetFindData


FreeVirtualFindData

главная | экспортируемые функции
Функция FreeVirtualFindData должна освободить память, выделенную функцией GetVirtualFindData.
void WINAPI FreeVirtualFindData(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указывает на массив структур PluginPanelItem, ранее выделенный функцией GetVirtualFindData.
ItemsNumber
Количество структур PluginPanelItem в массиве PanelItem.

Возвращаемое значение

Нет.
Смотрите также:
GetVirualFindData


GetFiles

главная | экспортируемые функции
Функция GetFiles вызывает для получения файлов из эмулируемой файловой системы
(FAR плагину: "хочу этот/эти файл(ы) с твоей панели, место назначения указано").
int WINAPI GetFiles(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber,
  int Move,
  char *DestPath,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указывает на массив структур PluginPanelItem. Каждая структура описывает файл, получаемый из эмулируемой файловой системы.
ItemsNumber
Количество структур PluginPanelItem в массиве PanelItem.
Move
Если 0, файл должен быть скопирован, иначе - перемещен.
DestPath
Путь назначения (куда получим файлы). Если флаг OpMode OPM_SILENT не установлен, вы можете позволить пользователю изменить его, но в этом случае новый путь должен быть скопирован в DestPath.
OpMode
Комбинация флагов operation mode. Эта функция должна быть готова обработать флаги OPM_SILENT, OPM_FIND, OPM_VIEW, OPM_QUICKVIEW и OPM_EDIT. Также она может обрабатывать OPM_DESCR и OPM_TOPLEVEL для увеличения скорости, если это необходимо.

Возвращаемое значение

В случае успеха возвращаемое значение должно быть равно 1. В случае провала возвращается 0. Если функция была прервана пользователем, то должно возвращаться -1.

Замечания

  1. Плагин должен сам обрабатывать "свои" папки.
  2. Если операция не удалась, но часть файлов была успешно обработана, плагин может снять выделение только с обработанных файлов. Чтобы сделать это, он должен очистить флаг PPIF_SELECTED в обработанных элементах в переданном функции списке структур PluginPanelItem.
  3. Данная функция вызывается только для плагинов, реализующих виртуальные файловые системы. Для этого необходимо при вызове GetOpenPluginInfo снять флаг OPIF_REALNAMES, иначе данная функция никогда не будет вызвана.
Смотрите также:
PutFiles, GetDirList, GetPluginDirList


GetFindData

главная | экспортируемые функции
Функция GetFindData вызывается для получения списка файлов из текущего каталога эмулируемой файловой системы
(FAR плагину: "дай-ка я взгляну на списочек твоих файлов, память сам выдели :-)").
int WINAPI GetFindData(
  HANDLE hPlugin,
  struct PluginPanelItem **pPanelItem,
  int *pItemsNumber,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
pPanelItem
Указывает на переменную, которая получит адрес массива структур PluginPanelItem.
pItemsNumber
Указывает на переменную, которая получит число структур PluginPanelItem.
OpMode
Комбинация флагов operation mode. Эта функция должна быть готова обработать флаг OPM_FIND.

Возвращаемое значение

В случае успеха должно возвращаться TRUE. Иначе FALSE.

Замечания

  1. Плагин сам должен выделять память под запрошенные данные. Если это происходит, то необходимо позаботиться об освобождении памяти, т.е. не забыть бы про экспортирование функции FreeFindData
  2. Если функция вернет FALSE, плагин будет закрыт.
  3. В некоторых случаях (пример: поиск в архивах по Alt-F7) физически панель плагина не создается, поэтому необходимо обязательно проверять код возврата у Control, чтобы не упасть в самый не подходящий момент, выполнив работу для панели, которой нет.
  4. Если вы не хотите, чтобы ваш плагин использовался во время "поиска в архивах" ("[x] Искать в архивах" в диалоге поиска), то возвращайте FALSE в случае, если OpMode содержит флаг OPM_FIND.
Смотрите также:
FreeFindData


GetOpenPluginInfo

главная | экспортируемые функции
Функция GetOpenPluginInfo вызывается для получения информации об открытом плагине.
void WINAPI GetOpenPluginInfo(
  HANDLE hPlugin,
  struct OpenPluginInfo *Info
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
Info
Указатель на структуру типа OpenPluginInfo, которая должна быть заполнена этой функцией.

Возвращаемое значение

Нет.

Замечания

  1. Структура OpenPluginInfo, передаваемая функции GetOpenPluginInfo, уже заполнена 0. Плагин обязательно должен заполнить поле OpenPluginInfo.StructSize
  2. FAR вызывает функцию GetOpenPluginInfo достаточно часто, поэтому при проектировании плагина необходимо минимизировать "расчеты", производимые в этой функции.
Смотрите также:
OpenPluginInfo


GetVirtualFindData

главная | экспортируемые функции
Функция GetVirtualFindData может быть использована для получения списка файлов для показа их на другой панели в дополнение к реальным файлам.
int WINAPI GetVirtualFindData(
  HANDLE hPlugin,
  struct PluginPanelItem **pPanelItem,
  int *pItemsNumber,
  const char *Path
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
pPanelItem
Указывает на переменную, которая получит адрес массива структур PluginPanelItem.
pItemsNumber
Указывает на переменную, которая получит число структур PluginPanelItem.
Path
Путь, для которого запрашивается список файлов (текущий каталог на другой панели). Путь завершен обратным слешем ("\").

Возвращаемое значение

В случае успеха должно возвращаться TRUE. Иначе FALSE.

Замечания

Функция GetVirtualFindData может использоваться для реализации "отложенного копирования" файлов, когда файлы, скопированные с панели плагина на файловую панель, показываются на файловой панели сразу же, а физическое копирование файлов происходит позже, при закрытии плагина или после выполнения специальной команды. Такое "отложенное копирование" может быть полезно, например, в плагине, работающем с Arvid.
Смотрите также:
FreeVirualFindData


MakeDirectory

главная | экспортируемые функции
Функция MakeDirectory вызывается для создания нового каталога в эмулируемой файловой системе.
int WINAPI MakeDirectory (
  HANDLE hPlugin,
  char *Name,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
Name
Имя каталога. Если флаг OpMode OPM_SILENT не установлен, вы можете позволить пользователю изменить его, но в этом случае новое имя должно быть скопировано в Name (максимум NM байт).
OpMode
Комбинация флагов operation mode. Эта функция должна быть готова обработать флаг OPM_SILENT.

Возвращаемое значение

В случае успеха возвращаемое значение должно быть равно 1. В случае провала возвращается 0. Если функция была прервана пользователем, то должно возвращаться -1.
Смотрите также:
OpenPlugin, OpenFilePlugin


OpenFilePlugin

главная | экспортируемые функции
FAR вызывает функцию OpenFilePlugin для открытия плагина, эмулирующего файловую систему на базе переданного этой функции файла (например, архива).
HANDLE WINAPI OpenFilePlugin(
  char *Name,
  const unsigned char *Data,
  int DataSize
);

Параметры

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

Функция OpenFilePlugin также вызывается, когда пользователь собирается создать новый файл (нажали Shift-F1). В этом случае Name равно NULL и другие параметры не определены. Если плагин не поддерживает создание новых файлов, он должен возвратить INVALID_HANDLE_VALUE, иначе он должен вернуть новый экземпляр описателя плагина, который должен быть готов обработать функции GetOpenPluginInfo и PutFiles. Если Name равно NULL, в PutFiles плагин должен запросить Name у пользователя.

Data
Указывает на данные из начала файла. Они могут использоваться для определения типа файла. Плагин не должен их изменять.
DataSize
Размер переданных данных из начала файла. В настоящий момент он может быть от 0 до 128Kb, в зависимости от размера файла, но вы должны быть готовы к любому другому значению.

Возвращаемое значение

  • Если плагин обрабатывает переданный файл, возвращаемое значение должно быть новым описателем плагина.
  • Если тип этого файла не поддерживается, возвращаться должно INVALID_HANDLE_VALUE.
  • Если операция прервана пользователем, должно возвращаться значение -2 (преобразованное в тип HANDLE).

Замечания

  1. FAR Manager при нажатии <Enter> на выбранном файле опрашивает все плагины, экспортирующие эту функцию. Плагины просматриваются в алфавитном порядке (по имени DLL-модуля) и кто первый вернул значение, отличное от INVALID_HANDLE_VALUE - тому и отдается управление.
  2. Параметр Name содержит полный путь к файлу.
  3. Количество читаемых байт можно изменить - TechInfo #63:
    [HKEY_CURRENT_USER\Software\Far\System]
"PluginMaxReadData":REG_DWORD
Параметр "System/PluginMaxReadData" с типом DWORD позволяет задавать
максимальный размер читаемых данных из файла в который попытались
войти из панелей (Enter или Ctrl-PgDn). Считанные данные будут переданы
плагинам для определения плагина поддерживающего файл этого типа.
Диапазон от 0x1000 до 0x80000.
По умолчанию 0x20000.


OpenPlugin

главная | экспортируемые функции
Функция OpenPlugin вызывается при создании новой копии плагина.
HANDLE WINAPI OpenPlugin(
  int OpenFrom,
  INT_PTR Item
);

Параметры

OpenFrom
Идентификатор, определяющий, откуда был вызван плагин. Может принимать одно из следующих значений (перечисление OPENPLUGIN_OPENFROM):
Константа | Описание
OPEN_DISKMENU | Открыт из меню дисков
OPEN_PLUGINSMENU | Открыт из меню плагинов (F11)
OPEN_FINDLIST | Открыт из диалога "поиска файлов" Этот идентификатор плагин получит только в том случае, если он экспортирует функцию SetFindList. Последующий вызов функции SetFindList произойдет только в том случае, если функция OpenPlugin вернет значение отличное от INVALID_HANDLE_VALUE.
OPEN_SHORTCUT | Открыт через ссылку на папку (Меню Commands|Folder shortcuts)
OPEN_COMMANDLINE | Был открыт из командной строки. Этот параметр может использоваться, только если плагин определил вызывающий префикс в функции GetPluginInfo и этот префикс, с двоеточием после него, был указан в командной строке.
OPEN_EDITOR | Открыт из редактора
OPEN_VIEWER | Открыт из встроенной программы просмотра
OPEN_DIALOG | Открыт из диалога
Item
Интерпретация параметра зависит от OpenFrom:
  • Для параметров OPEN_DISKMENU, OPEN_PLUGINSMENU, OPEN_EDITOR и OPEN_VIEWER Item - это номер выбранного пункта в меню из зарегистрированных плагином пунктов. Если плагин экспортирует только один элемент, этот параметр всегда равен нулю.
  • Для OPEN_FINDLIST Item всегда 0.
  • Для OPEN_SHORTCUT Item содержит адрес строки, которая была передана в элемент ShortcutData структуры OpenPluginInfo в момент сохранения горячей клавиши. Плагин может использовать это поле для сохранения дополнительной информации о текущем состоянии. Не обязательно сохранять в нем информацию о текущей директории, так как этим занимается сам FAR.
  • Для OPEN_DIALOG Item содержит адрес структуры OpenDlgPluginData.
  • Для OPEN_COMMANDLINE Item содержит адрес введенного пользователем в командной строке выражения. Если плагин не установил флаг PF_FULLCMDLINE, то командный префикс плагина в командную строку не включается. При установленном флаге PF_FULLCMDLINE плагину передается полная строка (с командным префиксом).
    К примеру, если плагин устанавливает префикс ftp и пользователь вводит ftp://ftp.abc.com, Item будет указывать на строку: "//ftp.abc.com" при НЕустановленном флаге PF_FULLCMDLINE и "ftp://ftp.abc.com" если флаг PF_FULLCMDLINE установили.

Возвращаемое значение

Если функция завершается успешно, то возвращаемое значение - описатель плагина. Этот описатель позже будет передаваться другим функциям плагина для того, чтобы позволить им различать различные копии загруженного плагина. Формат и содержание описателя не важны для FAR'а - они могут быть, к примеру, адресом внутреннего объекта плагина, или адресом структуры с данными плагина или любым другим уникальным идентификатором, отличным от нуля.

В случае неудачного завершения функции, возвращаемое значение должно равняться INVALID_HANDLE_VALUE.

Замечания

  1. Вы можете использовать эту функцию для реализации плагинов, работающих без создания файловых панелей. Просто выполните все необходимые действия и верните INVALID_HANDLE_VALUE.
  2. Если функция вернет ноль, то FAR Manager выгрузит плагин из памяти.


ProcessEvent

главная | экспортируемые функции
ProcessEvent сообщает плагину о разных событиях FAR'a и позволяет обработать некоторые из них.
int WINAPI ProcessEvent(
  HANDLE hPlugin,
  int Event,
  void *Param
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
Event
Тип события. Одно из следующих значений (перечисление FAR_EVENTS):
Событие | Описание
FE_CHANGEVIEWMODE | Сменился режим просмотра панели. Param указывает на строку типов колонок, оканчивающуюся нулем, например N,S,D,T. Возвращаемое значение должно быть FALSE.
FE_REDRAW | Панель должна перерисоваться. Param равен NULL. Верните FALSE, чтобы использовать функцию перерисовки FAR'a, или TRUE, чтобы отключить ее. В последнем случае плагин должен перерисовать панель сам.
FE_IDLE | Посылается с интервалом в несколько секунд. Плагин может использовать это событие, чтобы вызвать обновление панели и ее перерисовку, если это необходимо. Param равен NULL. Возвращаемое значение должно быть FALSE.
FE_CLOSE | Панель закрывается. Param равен NULL. Верните FALSE для закрытия панели или TRUE для отмены этого.
FE_BREAK | Нажатие Ctrl-Break. Param может быть только (int)CTRL_BREAK_EVENT Возвращаемое значение должно быть FALSE. Обработка этого события выполнена в отдельном потоке, поэтому плагин должен быть осторожным при выполнении операций ввода-вывода и не должен использовать сервисные функции FAR'a.
FE_COMMAND | Перед запуском команды в командной строке FAR'a. Param указывает на текст команды. Для разрешения стандартной обработки команды плагин должен вернуть FALSE. Если плагин собирается обработать команду сам, то он должен вернуть TRUE.
FE_KILLFOCUS | Панель потеряла фокус ввода. Param = NULL. Функция должна вернуть FALSE.
FE_GOTFOCUS | Панель получила фокус ввода. Активная панель получает событие FE_GOTFOCUS сразу после создания. Param = NULL. Функция должна вернуть FALSE.
Param
Значение указателя зависит от типа события. Смотрите описание событий для уточнения информации.

Возвращаемое значение

Возвращаемое значение зависит от типа события. Смотрите описание событий для уточнения информации.
Верните FALSE для неизвестных типов событий.


ProcessHostFile

главная | экспортируемые функции | поддержка архивов
Функция ProcessHostFile вызывается, чтобы выполнить архивные команды FAR Manager. Рекомендуется поместить сюда дополнительные операции, которые обрабатывают файл, на основании которого плагин эмулирует файловую систему.
int WINAPI ProcessHostFile(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указывает на массив структур PluginPanelItem. Каждая структура соответствует файлу, выбранному в панели плагина.
ItemsNumber
Количество структур PluginPanelItem в массиве PanelItem.
OpMode
Комбинация флагов operation mode. Для этой функции равна 0 или OPM_TOPLEVEL.

Возвращаемое значение

В случае успеха должно возвращаться TRUE. Иначе - FALSE.

Примечание

Если операция не удалась, но часть файлов была успешно обработана, плагин может удалить выделение только с обработанных файлов. Для этого он должен очистить флаг PPIF_SELECTED у обработанных элементов переданного функции списка PluginPanelItem.


ProcessKey

главная | экспортируемые функции
Функция ProcessKey позволяет перекрывать стандартную обработку клавиш на панели плагина.
int WINAPI ProcessKey(
  HANDLE hPlugin,
  int Key,
  unsigned int ControlState
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
Key
Виртуальный код клавиши.
К параметру Key может применяться флаг PKF_PREPROCESS.
ControlState
Состояние Shift-клавиш. Комбинация флагов из перечисления FAR_PKF_FLAGS (за исключением PKF_PREPROCESS)
Например, при нажатии Shift-F7, Key= VK_F7 и ControlState = PKF_SHIFT.

Возвращаемое значение

FALSE для дальнейшей обработки FAR.
TRUE, если плагин самостоятельно обработал клавишу.

Замечания

  • Для FAR 1.70 build 2051 включительно:
    Из-за особенностей реализации ядра FAR в эту функции не доходят следующие клавиши: Tab, Ctrl-F1, Ctrl-F2, Ctrl-B, Cltr-L, Ctrl-Q, Ctrl-T, Ctrl-O, Ctrl-P, Ctrl-I, Ctrl-U, Alt-F1, Alt-F2, Alt-F7, Ctrl-Down, Ctrl-Up, Ctrl-Left, Ctrl-Right, Ctrl-Num5, F9, Shift-F10, Ctrl-0..9, Alt-Ins, Ctrl-W, F11, Alt-F9, F12, Ctrl-Tab и Ctrl-Shift-Tab.
    Начиная с 1.70 build 2052 эти ограничения сняты (см. замечание для флага PKF_PREPROCESS).


PutFiles

главная | экспортируемые функции
Функция PutFiles вызывается для перемещения файлов на панель эмулируемой файловой системы. (FAR плагину: "этот/эти файл(ы) для тебя, можешь поместить на свою панель").
int WINAPI PutFiles(
  HANDLE hPlugin,
  struct PluginPanelItem *PanelItem,
  int ItemsNumber,
  int Move,
  int OpMode
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указатель на массив из структур PluginPanelItem. Каждая структура описывает файл для передачи.
ItemsNumber
Число элементов в массиве PanelItem.
Move
Ноль, если файл должен быть скопирован, иначе перемещен.
OpMode
Комбинация флагов operation mode. Эта функция должна воспринимать флаг OPM_SILENT. Также она может использовать флаг OPM_DESCR.

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

Возвращаемое значение

В случае удачи, функция должна возвращать 1 или 2. Если плагин возвращает 1, то FAR пытается установить курсор на последний по дате создания файл текущей панели. Если плагин возвращает 2, то FAR никаких перемещений курсора не предпринимает. Если функция завершилась неудачей, должен возвращаться 0. Если же функция была прервана пользователем, то возвращаемое значение должно равняться -1.

Замечания

  1. Если операция была прервана, но часть файлов все же была скопирована, плагин может убрать выделение только с обработанных файлов. Для этого он должен сбросить флаг PPIF_SELECTED у соответствующих структур файлов, передаваемых в функцию через параметр PluginPanelItem.
Смотрите также:
GetFiles, GetDirList, GetPluginDirList


SetDirectory

главная | экспортируемые функции
Функция SetDirectory вызывается для смены каталога в эмулируемой файловой системе.
int WINAPI SetDirectory(
  HANDLE hPlugin,
  const char *Dir,
  int OpMode
);

Параметры

hPlugin
Идентификатор плагина - возвращается функциями OpenPlugin или OpenFilePlugin.
Dir
Имя каталога. Обычно только имя без полного пути. Для предоставления базовых возможностей плагин обязан воспринимать имена '..' и '\'.
Для корректного восстановления каталога после использования "Искать по всему диску" в Диалоге поиска файлов, плагин должен воспринимать полное имя каталога, которое возвращается в функции GetOpenPluginInfo. Это не обязательно для выставленного режима "Искать, начиная с текущей папки" в диалоге поиска файлов .
OpMode
Комбинация флагов режима операции. Эта функция должна быть готова принимать флаг OPM_FIND. Если этот флаг установлен, плагин не должен совершать других действий, кроме смены каталога (так, при установленном OPM_FIND, плагин не должен пытаться обновить или закрыть панели, спрашивать подтверждения у пользователя, выводить сообщения и т.д.).

Возвращаемое значение

В случае удачного завершения возвращаемое значение должно равняться TRUE. Иначе функция должна возвращать FALSE.

Замечания

Если в OpMode выставлен флаг OPM_FIND, то:
  1. это значит, что функция SetDirectory вызывается из диалога поиска файлов (Alt-F7) или другой команды, сканирующей каталоги. Поэтому плагин не должен производить никаких действий кроме смены каталога и возвращения TRUE в случае удачи или FALSE в случае невозможности сменить каталог.
  2. плагин должен аккуратно обрабатывать каталог ".." и при невозможности сменить его - возвращать FALSE. Иначе поиск может зациклиться на панели этого плагина.


SetFindList

главная | экспортируемые функции
Функция SetFindList предназначена для переноса найденных объектов в диалоге Поиска Файлов в эмулируемую файловую систему. Физически файлы не должны копироваться или изменяться.
int WINAPI SetFindList(
  HANDLE hPlugin,
  const struct PluginPanelItem *PanelItem,
  int ItemsNumber
);

Параметры

hPlugin
Описатель плагина, возвращается функциями OpenPlugin или OpenFilePlugin.
PanelItem
Указатель на массив структур PluginPanelItem. Каждая структура описывает файл для помещения в панель.
ItemsNumber
Число элементов в массиве PanelItem.

Возвращаемое значение

В случае удачного завершения возвращаемое значение должно быть TRUE. Иначе функция должна возвращать FALSE.

Замечания

  • Типичный представитель, использующий данную функцию - плагин Temporary panel (TMPCLASS.CPP, функция TmpPanel::SetFindList)
  • Перед вызовом этой функции FAR вызывает функцию OpenPlugin(OPEN_FINDLIST,0) и только после успешного ее завершения вызовет SetFindList.


Экспортируемые функции

Экспортируемые функции - Редактор

главная | экспортируемые функции
Функция | Описание
ProcessEditorInput | обработка событий клавиатуры
ProcessEditorEvent | обработка событий редактора
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


ProcessEditorInput

главная | экспортируемые функции
Функция ProcessEditorInput вызывается всякий раз, когда внутренний редактор FAR обрабатывает событие от клавиатуры или мыши.
int WINAPI ProcessEditorInput(
  const INPUT_RECORD *Rec
);

Параметры

Rec
Указатель на структуру INPUT_RECORD. Эта структура определена в Win32 API и содержит информацию о последнем событии от клавиатуры или мыши.

Возвращаемое значение

Если плагин должен передать управление в редактор FAR`а, то верните 0. Если плагин в полной мере отработал событие или вы хотите, чтобы FAR игнорировал это событие, то верните 1.

Замечания

  1. Плагин должен корректно обрабатывать входные события путем анализа поля INPUT_RECORD.EventType и, в случае если плагин данное событие не обрабатывает, вернуть управление в FAR.
  2. Во время "проигрывания" макроса клавиатурные события (KEY_EVENT) имеют "новый" тип - поле INPUT_RECORD.EventType равно значению 0x8001.
  3. Плагин может вызвать команду EditorControl из этой функции, но будьте осторожны, когда вызываете здесь ECTL_PROCESSINPUT, потому что эта команда вызывает функцию ProcessEditorInput снова. Таким образом, плагин должен сам предотвратить такой самовызов, или он впадет в бесконечный цикл.
  4. Плагину не приходят клавиши: Ctrl-W, F11, Alt-F9, F12, Ctrl-Tab, Ctrl-Shift-Tab, Alt-Ins и Ctrl-Alt-Shift.
  5. Плагину приходят клавиши (с ограничениями):
    • Alt-F5 - если плагин PrintMan не установлен
    • Alt-F11 - если редактор модальный
    • F6 - если есть запрет на переключение в программу просмотра (при вызове функции Editor не указан флаг EF_ENABLE_F6).
Смотрите также:
INPUT_RECORD


ProcessEditorEvent

главная | экспортируемые функции
Функция ProcessEditorEvent сообщает плагину о событиях, происходящих в редакторе FAR.
int WINAPI ProcessEditorEvent(
  int Event,
  void *Param
);

Параметры

Event
Тип события.
Может быть одной из следующих величин (перечисление EDITOR_EVENTS):
Событие Описание
EE_CLOSE Одно из окон редактора закрывается.
Плагин может использовать это сообщение для освобождения внутренних структур данных. Заметьте, что несколько окон редактора могут работать одновременно.
Параметр Param указывает на переменную, содержащую значение EditorID закрываемого редактора. EditorID может быть получен ранее с использованием ECTL_GETINFO команды EditorControl. Но плагин не должен вызывать EditorControl при обработке этого сообщения потому что редактор уже закрыт.
Функция должна вернуть 0.

Замечание для EE_CLOSE Замечание.

  • Начиная с FAR 1.70 build 1989 в EE_CLOSE допускается использовать только ECTL_GETINFO и ECTL_GETBOOKMARKS.
EE_READ Новый файл загружен в редактор. Плагин может использовать команды функции EditorControl для модификации считанных данных.
Param = NULL.
Функция должна вернуть 0.
EE_SAVE Отредактированный файл собираются сохранять. Плагин может использовать команды функции EditorControl для модификации данных перед сохранением.
Param = NULL.
Функция должна вернуть 0.
EE_REDRAW Редактор собирается перерисовать экран. Плагин может использовать команду ECTL_ADDCOLOR функции EditorControl, чтобы установить цвета для строки.
Param может быть одним из следующих значений:
Константа | Описание
EEREDRAW_ALL | Прорисовывается весь экран
EEREDRAW_LINE | Перерисовка только текущей строки
EEREDRAW_CHANGE | Перерисовка вызвана изменением текста. В случае изменения EEREDRAW_CHANGE может быть перерисована как текущая строка, так и весь экран. Поэтому если были изменения раскраски вне текущей строки, настоятельно рекомендуется по окончании раскраски вызвать ECTL_REDRAW. Иначе эти изменения отобразятся только после движения курсора или других вызывающих перерисовку событий. Главное при этом не попасть в рекурсию.
Функция должна вернуть 0.

EE_KILLFOCUS Редактор потерял фокус ввода.
Param указывает на переменную, содержащую значение EditorID редактора, теряющего фокус.
Функция должна вернуть 0.
EE_GOTFOCUS Редактор получил фокус ввода.
Param указывает на переменную, содержащую значение EditorID редактора, получающего фокус.
Функция должна вернуть 0.

Замечание для EE_REDRAW Внимание!

  • При обработке EE_REDRAW НЕЖЕЛАТЕЛЬНО ИСПОЛЬЗОВАТЬ Info.Message, Info.Menu, Info.Dialog и Info.DialogEx. Вызов этих функций приводит к рекурсивному вызову EE_REDRAW.
Param
Указатель на данные, зависящие от типа события Event.

Возвращаемое значение

Возвращаемое значение зависит от типа события Event.
Верните 0 для неизвестного типа события.

Замечания

  • EE_READ вызывается только один раз для файла.
  • EE_SAVE вызывается при каждом нажатии F2 или Shift-F2.
  • EE_REDRAW вызывается при любой перерисовке экрана (в частности, при движении курсора)


Экспортируемые функции

Экспортируемые функции - Программа Просмотра

главная | экспортируемые функции
Функция | Описание
ProcessViewerEvent | обработка событий программы просмотра
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


ProcessViewerEvent

главная | экспортируемые функции
Функция ProcessViewerEvent сообщает плагину о событиях, происходящих во внутренней программе просмотра FAR.
int WINAPI ProcessViewerEvent(
  int Event,
  void *Param
);

Параметры

Event
Тип события.
Может быть одной из следующих величин (перечисление VIEWER_EVENTS):
Событие | Описание
VE_CLOSE | Одно из окон программы просмотра закрывается. Плагин может использовать это сообщение для освобождения внутренних структур данных. Заметьте, что несколько окон программы просмотра могут работать одновременно. Параметр Param указывает на переменную, содержащую значение ViewerID закрываемой программы просмотра. ViewerID может быть получен ранее с использованием VCTL_GETINFO команды ViewerControl. Но плагин не должен вызывать ViewerControl при обработке этого сообщения потому что программа просмотра уже закрыта. Функция должна вернуть 0.
VE_READ | Новый файл загружен в программу просмотра. Param = NULL. Функция должна вернуть 0.
VE_KILLFOCUS | Программа просмотра потеряла фокус ввода. Param указывает на переменную, содержащую значение ViewerID вьювера, теряющего фокус. Функция должна вернуть 0.
VE_GOTFOCUS | Программа просмотра получила фокус ввода. Param указывает на переменную, содержащую значение ViewerID вьювера, получающего фокус. Функция должна вернуть 0.
Param
Указатель на данные, зависящие от типа события Event.

Возвращаемое значение

Возвращаемое значение зависит от типа события Event.
Верните 0 для неизвестного типа события.

Замечания

  • VE_READ вызывается только один раз для файла.
    • Смотрите также:
    ViewerControl


Экспортируемые функции

Экспортируемые функции - Диалог

главная | экспортируемые функции
Функция | Описание
ProcessDialogEvent | обработка событий диалога
Смотрите также:
Сервисные функции, Структуры, Поддержка архивов, Дополнения


ProcessDialogEvent

главная | экспортируемые функции
Функция ProcessDialogEvent сообщает плагину о событиях, происходящих в диалоге FAR.
int WINAPI ProcessDialogEvent(
  int Event,
  void *Param
);

Параметры

Event
Тип события.
Может быть одной из следующих величин (перечисление DIALOG_EVENTS):
Событие | Описание
DE_DLGPROCINIT | Param - указатель на структуру FarDialogEvent. Событие FarDialogEvent.Msg поступает в функцию обработки диалога.
DE_DEFDLGPROCINIT | Param - указатель на структуру FarDialogEvent. Событие FarDialogEvent.Msg поступает в стандартную (внутреннюю) функцию обработки диалога.
DE_DLGPROCEND | Param - указатель на структуру FarDialogEvent. Событие FarDialogEvent.Msg обработано функцией обработки диалога. FarDialogEvent.Result содержит возвращённое обработчиком значение.
Param
Указатель на структуру FarDialogEvent.

Возвращаемое значение

TRUE - плагин самостоятельно обработал событие. Переменная FarDialogEvent.Result будет использована в качестве возвращаемого значения обработчика диалога.
FALSE - продолжить обработку события.

Замечания

Смотрите также:
FarDialogEvent, события, Dialog API


Сервисные функции

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

Внимание! Внимание!

  • Некоторые функции, приведенные ниже, отсутствуют в ранних версиях FAR Manager. Прочитайте замечания по структуре PluginStartupInfo и функции GetMinFarVersion для более подробной информации.

Функции общего назначения

Функция | Описание
AdvControl | дополнительные управляющие функции; работают везде: в панелях/редакторе/вьюере.
CharTable | позволяет получить информацию об установленных таблицах символов
CmpName | сравнивает текстовую строку (например, имя файла) с образцом (маской).
Control | позволяет запрашивать различную информацию и выполнять управляющие действия.
FreeDirList | освобождает память, выделенную для списка файлов функциями GetDirList и GetPluginDirList
GetDirList | возвращает список файлов в указанной директории
GetMsg | получить строку сообщения из языкового файла.
GetPluginDirList | возвращает список файлов в указанной директории эмулируемой файловой системы
Menu | показывает меню
RestoreScreen | восстанавливает предварительно сохраненную область экрана
SaveScreen | сохраняет область экрана
ShowHelp | показывает нужный топик из hlf
Text | выводит текстовую строку на экран

Специфические функции редактора

Функция | Описание
Editor | обеспечивает доступ к внутреннему редактору FAR'a
EditorControl | обеспечивает доступ на низком уровне к API редактора FAR'a

Специфические функции Dialog API

Функция | Описание
DefDlgProc | вызывает стандартный обработчик диалога
Dialog | показывает диалог
DialogEx | расширенный диалог с функцией обработчиком
InputBox | позволяет ввести строку текста
Message | показывает сообщение
SendDlgMessage | послать сообщение обработчику диалога.

Специфические функции программы просмотра

Функция | Описание
Viewer | обеспечивает доступ к внутреннему вьюеру FAR'a
ViewerControl | позволяет запрашивать различную информацию о встроенной программе просмотра FAR и управлять ее состоянием
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


Сервисные функции

Сервисные функции - Функции общего назначения

главная

Функции общего назначения

Функция | Описание
AdvControl | дополнительные управляющие функции; работают везде: в панелях/редакторе/вьюере.
CharTable | позволяет получить информацию об установленных таблицах символов
CmpName | сравнивает текстовую строку (например, имя файла) с образцом (маской).
Control | позволяет запрашивать различную информацию и выполнять управляющие действия.
FreeDirList | освобождает память, выделенную для списка файлов функциями GetDirList и GetPluginDirList
GetDirList | возвращает список файлов в указанной директории
GetMsg | получить строку сообщения из языкового файла.
GetPluginDirList | возвращает список файлов в указанной директории эмулируемой файловой системы
Menu | показывает меню
RestoreScreen | восстанавливает предварительно сохраненную область экрана
SaveScreen | сохраняет область экрана
ShowHelp | показывает нужный топик из hlf
Text | выводит текстовую строку на экран
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


AdvControl

главная | сервисные функции
Функция AdvControl позволяет запрашивать различную информацию и выполнять управляющие действия. Она работает везде: в панелях/редакторе/вьюере.
INT_PTR WINAPI AdvControl(
  int ModuleNumber,
  int Command,
  void *Param
);

Параметры

ModuleNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
Command
Тип команды. Может быть следующим (перечисление ADVANCED_CONTROL_COMMANDS):
Команда Описание
ACTL_COMMIT "Фиксирует" действие последней операции с окнами (например, после ACTL_SETCURRENTWINDOW).
Param = 0 (не используется)
Функция возвращает TRUE в случае успеха и FALSE при неудаче.
ACTL_CONSOLEMODE Программное переключение "FullScreen <-> Windowed".
Param может принимать одно из следующих значений:
Константа | Описание
FAR_CONSOLE_GET_MODE | получить текущее состояние
FAR_CONSOLE_SET_FULLSCREEN | полноэкранный режим
FAR_CONSOLE_SET_WINDOWED | оконный режим
FAR_CONSOLE_TRIGGER | переключить состояние
Возвращается текущее значение режима - одна из констант:
Константа | Описание
FAR_CONSOLE_WINDOWED | оконный режим
FAR_CONSOLE_FULLSCREEN | полноэкранный режим
ACTL_EJECTMEDIA Извлечь диск из съемного накопителя (CD-ROM/USB/SUBST).
Param - указатель на структуру ActlEjectMedia
Функция возвращает TRUE - успешное извлечение, FALSE - ошибка.
ACTL_KEYMACRO Выполнить операции по работе с макрокомандами.
Param - указатель на структуру ActlKeyMacro
Функция возвращает TRUE - успешное выполнение, FALSE - ошибка ("в данный момент идет запись макроса" или "нехватка памяти" или "макрос выполняется").
ACTL_GETARRAYCOLOR Получить все цвета FAR Manager.
Param = указатель на байтовый массив, в который будут скопированы текущие цветовые атрибуты. Один байт на один цветовой атрибут. Старшие 4 бита - цвет фона, младшие 4 бита - цвет символа.
Param = NULL позволяет узнать требуемый размер массива.
Функция всегда возвращает необходимый размер массива в байтах.
ACTL_GETCOLOR Получить цвет FAR Manager по индексу.
Param = одна из констант COL_*, описанных в farcolor.hpp
Функция возвращает атрибут, соответствующий переданному индексу или -1, если индекс указан неверно.
ACTL_GETFARVERSION Узнать версию FAR.
Param указывает на переменную типа DWORD в которую будет помещена информация о версии FAR Manager.
Формат версии:
HIWORD:         = номер билда   (FAR 1.70.387 = 0x0183)
LOWORD:  HIBYTE = major version (FAR 1.70.387 = 0x01)
         LOBYTE = minor version (FAR 1.70.387 = 0x46)
Параметр Param может быть равным NULL.
Функция возвращает информацию о версии FAR Manager.
ACTL_GETFARHWND Возвращает HWND текущего окна FAR Manager.
Param = 0 (не используется)
ACTL_GETCONFIRMATIONS Получить информацию о настройках подтверждений. Возвращается DWORD с выставленными флагами FarConfirmationsSettings (соответствует настройкам диалога "Подтверждения").
Param = 0 (не используется)
ACTL_GETDESCSETTINGS Получить информацию о настройках описаний файлов. Возвращается DWORD с выставленными флагами FarDescriptionSettings (соответствует настройкам диалога "Описания файлов").
Param = 0 (не используется)
ACTL_GETDIALOGSETTINGS Получить информацию о настройках диалогов. Возвращается DWORD с выставленными флагами FarDialogSettings (соответствует настройкам диалога "Настройки диалогов").
Param = 0 (не используется)
ACTL_GETINTERFACESETTINGS Получить информацию о настройках интерфейса. Возвращается DWORD с выставленными флагами FarInterfaceSettings (соответствует настройкам диалога "Настройки интерфейса").
Param = 0 (не используется)
ACTL_GETPANELSETTINGS Получить информацию о настройках панелей. Возвращается DWORD с выставленными флагами FarPanelSettings (соответствует настройкам диалога "Настройки панели").
Param = 0 (не используется)
ACTL_GETPLUGINMAXREADDATA Возвращает максимальный размер данных (DWORD), который FAR может считывать из файла перед передачей управления плагину в функцию OpenFilePlugin. Это значение может быть любым в диапазоне от 4K до 512K.
Param = 0 (не используется)
ACTL_GETSYSTEMSETTINGS Получить информацию о системных настройках. Возвращается DWORD с выставленными флагами FarSystemSettings (соответствует настройкам диалога "Системные параметры").
Param = 0 (не используется)
ACTL_GETSYSWORDDIV Получить строку с символами-разделителями, делящими текст на слова.
Param = указатель на строку-приемник, куда будут скопированы символы-разделители.
Param = NULL - узнать длину строки (без символа конца строки '\0')
Функция возвращает длину переданной строки. Максимальная длина строки - 260 байт (с символом конца строки '\0').
ACTL_GETWCHARMODE Возвращает режим работы консоли FAR manager.
Param = 0 (не используется).
Функция возвращает TRUE, если FAR работает с консолью в Unicode-режиме и FALSE, если в 8-битном режиме.
ACTL_GETWINDOWCOUNT Возвращает число открытых окон в FAR Manager.
Param = 0 (не используется).
Минимальное число окон = 1 (при запуске FAR: в обычном режиме - файловые панели; с ключами -e или -v - редактор или программа просмотра, соответственно).
ACTL_GETWINDOWINFO Получить информацию о конкретном окне FAR Manager.
Param - указатель на структуру WindowInfo.
Функция возвращает TRUE, если окно с номером WindowInfo.Pos существует и FALSE - такого окна нет (поля структуры WindowInfo не заполняются). WindowInfo.Pos надо инициализировать перед вызовом функции.
ACTL_GETSHORTWINDOWINFO Получить информацию о конкретном окне FAR Manager.
Param - указатель на структуру WindowInfo.
Функция возвращает TRUE, если окно с номером WindowInfo.Pos существует и FALSE - такого окна нет (поля структуры WindowInfo не заполняются). WindowInfo.Pos надо инициализировать перед вызовом функции.
В отличии от ACTL_GETWINDOWINFO поля WindowInfo.TypeName и WindowInfo.Name не заполняются и поэтому эту команду можно вызывать из любых тредов.
ACTL_POSTKEYSEQUENCE Передать в FAR последовательность внутренних кодов клавиш.
Param - указатель на структуру KeySequence
Функция возвращает TRUE - клавиши успешно помещены в очередь, FALSE - ошибка.
Последовательность переданных клавиш начнет исполняться тогда, когда FAR получит управление.
ACTL_REDRAWALL Перерисовка всех окон FAR.
Param = 0 (не используется)
ACTL_SETARRAYCOLOR Изменить заданный диапазон цветовой схемы FAR Manager.
Param = указатель на структуру FarSetColors. Функция возвращает TRUE при успешной замене заданного диапазона цветовой схемы и FALSE для неверно заданных параметров в структуре FarSetColors.
ACTL_SETCURRENTWINDOW Позволяет переключиться в конкретное окно FAR Manager Param - целое число типа int, задающее номер активного окна (нумерация начинается с 0).
Функция возвращает TRUE, если переключение состоялось и FALSE при неудаче (не существует требуемого окна).

Замечание для ACTL_COMMIT Внимание!

  • Переключение не произойдет до тех пор, пока не будет вызван ACTL_COMMIT или пока FAR не получит управление.
ACTL_WAITKEY Ожидать клавишу.
Param = -1 или NULL - ждем любую клавишу
Param = (внутренний код клавиши) - ждем конкретную клавишу.
Функция всегда возвращает 0.
Param
Указывает на параметры команды. Смотрите описание Command

Возвращаемое значение

Смотрите описание Command
Смотрите также:
Control, EditorControl


CharTable

главная | сервисные функции
Функция CharTable позволяет получить информацию об установленных таблицах символов.
int WINAPI CharTable(
  int Command,
  char *Buffer,
  int BufferSize
);

Параметры

Command
Или номер требуемой символьной таблицы, или одна из следующих команд (перечисление FARCHARTABLE_COMMAND):
Команда | Описание
FCT_DETECT | Автоматически определить таблицу символов для данного текста
Buffer
Для Command = FCT_DETECT - адрес буфера с текстовыми данными. Иначе - адрес структуры CharTableSet, которая получает информацию о запрошенной таблице символов.
BufferSize
Если Command равна FCT_DETECT,то это должен быть размер буфера с анализируемыми текстовыми данными. Иначе - размер структуры CharTableSet.

Возвращаемое значение

-1, если запрашиваемая таблица отсутствует или не удалось автоопределение. В случае успеха возвращает номер требуемой таблицы и заполняет структуру, указанную Buffer. В режиме FCT_DETECT возвращает номер определенной таблицы и не изменяет данные Buffer.

Примечание

  1. Чтобы перебрать все символьные таблицы, начните с Command равной 0 и увеличивайте ее, пока возвращаемое значение не равно -1.
  2. При неудачном считывании настроек для определенной символьной таблицы структура CharTableSet заполняется данными для OEM (для случая, когда Command не равно FCT_DETECT).


CmpName

главная | сервисные функции | FSF.ProcessName
Функция CmpName сравнивает текстовую строку (например, имя файла) с образцом (маской).
int WINAPI CmpName(
  const char *Pattern,
  const char *String,
  int SkipPath
);

Параметры

Pattern
Адрес образца (маски).
String
Адрес текстовой строки.
SkipPath
Если TRUE, путь к файлу в String игнорируется и только имя файла будет участвовать в сравнении.

Возвращаемое значение

TRUE, если строка удовлетворяет образцу, иначе FALSE.

Замечания

Параметр Pattern может включать обычные допустимые в именах файлов символы, а также специальные выражения:
Метасимвол | Описание
* | любое количество символов
? | любой символ
[c,x-z] | любой символ из находящихся в квадратных скобках; допускаются и отдельные символы, и их диапазоны.
Например, файлы ftp.exe, fc.exe и f.ext совпадают с маской f*.ex?, маска *co* совпадает с color.ini и edit.com, маске [c-ft]*.txt будут соответствовать config.txt, demo.txt, faq.txt и tips.txt.


Control

главная | сервисные функции
Функция Control позволяет запрашивать различную информацию и выполнять управляющие действия над панелями и командной строкой.
int WINAPI Control(
  HANDLE hPlugin,
  int Command,
  void *Param
);

Параметры

hPlugin
Текущий описатель плагина. При запросе информации относительно активной панели установите этот параметр равным INVALID_HANDLE_VALUE. Это позволяет использовать эту функцию в командах плагина без создания новой панели. Так же INVALID_HANDLE_VALUE можно использовать для неплагиновой панели.
Command
Тип команды. Может быть следующим FILE_CONTROL_COMMANDS):
Команда Описание
Панель
FCTL_CHECKPANELSEXIST Проверить доступность панелей.
Param = 0 (не используется).
Функция возвращает FALSE, если FAR запущен с ключами /e или /v (в качестве внешнего редактора или программы просмотра). В этом режиме панели не создаются.

Замечание для FCTL_CHECKPANELSEXIST Внимание!

  • В режиме, когда FAR запущен с ключами /e или /v, функция обрабатывает только одну эту команду - FCTL_CHECKPANELSEXIST.
FCTL_CLOSEPLUGIN Закрыть текущий плагин.
Param указывает на имя каталога, который будет показан в панели после закрытия.
FCTL_GETPANELINFO
FCTL_GETANOTHERPANELINFO 		Получить информацию о активной/пассивной панели плагина.
Param указывает на структуру PanelInfo, которая получит информацию о панели.
PanelInfo.SelectedItemsNumber равно 1, если не выделено никаких элементов. В этом случае PanelInfo.SelectedItems содержит данные для элемента под курсором. Если вы хотите узнать, действительно ли выделен этот файл, то проверьте у него состояние флага PPIF_SELECTED.

В процессе исполнения запроса

Info.Control(INVALID_HANDLE_VALUE,
             FCTL_GETPANELINFO,
             &PInfo);
FAR вызывает экспортируемую функцию GetOpenPluginInfo того плагина, которому принадлежит панель. FAR содержит защиту от бесконечной рекурсии: в случае, когда плагин из обработчика GetOpenPluginInfo() тоже вызывает Info.Control(...,FCTL_GETPANELINFO), повторного вложенного вызова GetOpenPluginInfo() не произойдёт.

В некоторых случаях (пример: поиск в архивах по Alt-F7) физически панель плагина не создается, поэтому необходимо обязательно проверять код возврата у Control, чтобы не упасть в самый не подходящий момент, выполнив работу для панели, которой нет.

Замечание для FCTL_GET[ANOTHER]PANELINFO Внимание!

  • Поля PanelItems и SelectedItems структуры PanelInfo после каждого вызова FCTL_GETPANELINFO или FCTL_GETANOTHERPANELINFO будут иметь разные адреса.
FCTL_GETPANELSHORTINFO
FCTL_GETANOTHERPANELSHORTINFO 		Аналогична FCTL_GETPANELINFO/FCTL_GETANOTHERPANELINFO, но поля PanelItems и SelectedItems структуры PanelInfo не заполнены и равны NULL. Эта команда предназначена для получения общей информации о активной/пассивной панели без конкретных сведений об элементах панели.
FCTL_REDRAWPANEL
FCTL_REDRAWANOTHERPANEL 		Перерисовать активную/пассивную панель плагина.
Param - указатель на структуру PanelRedrawInfo, которой можно задать новые позиции курсора и верхнего элемента панели. Если Param равен NULL, то позиции курсора и верхнего элемента панели при прорисовке не изменяются.
Если hPlugin равен INVALID_HANDLE_VALUE, то перерисуется активная панель независимо от того, какую команду использовал плагин.
Панель прорисуется только в случае, если в данный момент панелей видны.
FCTL_SETNUMERICSORT
FCTL_SETANOTHERNUMERICSORT 		Задает числовой порядок сортировки для активной/пассивной панели.
Param - указатель на целое число, задающий числовую сортировку: 0 (отключить числовую сортировку) или 1 (включить числовую сортировку).
Значение Param равное NULL эквивалентно отключению числовой сортировки.
FCTL_SETPANELDIR
FCTL_SETANOTHERPANELDIR 		Установить текущий каталог в активной/пассивной панели плагина.
Param указывает на имя каталога. Если плагин поддерживает свою собственную панель, он будет закрыт после выполнения этой команды.

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

FCTL_SETSELECTION
FCTL_SETANOTHERSELECTION 		Установить выделение в активной/пассивной панели.
Param указывает на структуру PanelInfo, заполненную предыдущими вызовами FCTL_GETPANELINFO или FCTL_GETANOTHERPANELINFO . Нельзя использовать другие функции Control между FCTL_GETPANELINFO и FCTL_SETSELECTION.

Для изменения выделения установите или очистите флаг PPIF_SELECTED у элементов массива, указатель на которое содержится в поле PanelItems структуры PanelInfo. Обратите внимание, что FCTL_GETPANELINFO и FCTL_GETANOTHERPANELINFO устанавливают значение PPIF_SELECTED для элементов массива, соответствующее состоянию панели.

Нужно вызвать FCTL_REDRAWPANEL для показа изменений.

FCTL_SETSORTMODE
FCTL_SETANOTHERSORTMODE 		Установить режим сортировки для активной/пассивной панели. Param - указатель на целое число, содержащее режим сортировки (см. "Режимы сортировки").
FCTL_SETSORTORDER
FCTL_SETANOTHERSORTORDER 		Задает порядок сортировки для активной/пассивной панели.
Param - указатель на целое число, содержащее порядок сортировки: 0 или 1 (обратная сортировка).
Значение Param равное NULL эквивалентно установки прямого порядка сортировки (0).
FCTL_SETVIEWMODE
FCTL_SETANOTHERVIEWMODE 		Установить режим просмотра активной/пассивной панели.
Param указывает на целое значение, которое содержит номер нового режима, от 0 до 9.
Значение Param равное NULL эквивалентно установки режима 0.
FCTL_UPDATEPANEL
FCTL_UPDATEANOTHERPANEL 		Обновить содержимое активной/пассивной панели плагина.
Если Param равен NULL, текущее выделение файлов будет снято, иначе выделение не изменится.
Командная строка
FCTL_GETCMDLINE Получить содержимое командной строки.
Param указывает на буфер, который получит данные (должен быть не меньше 1 Kb).
FCTL_GETCMDLINEPOS Получить позицию курсора в командной строке.
Param содержит указатель на переменную типа int, в которую будет помещена позиция курсора.
FCTL_GETCMDLINESELECTEDTEXT Получить выделенный текст из командной строки.
Param указывает на буфер, который получит данные (должен быть не меньше 1 Kb).
FCTL_GETCMDLINESELECTION Получить параметры выделенного текста командной строки.
Param указывает на структуру CmdLineSelect.
FCTL_INSERTCMDLINE Вставить текст в командную строку, начиная с текущей позиции курсора.
Param указывает на строку, оканчивающуюся нулем, которая будет вставлена в командную строку.
FCTL_SETCMDLINE Установить содержимое командной строки.
Param указывает на строку, оканчивающуюся нулем, которая будет помещена в командную строку.
FCTL_SETCMDLINEPOS Установить позицию курсора в командной строке.
Param содержит указатель на переменную типа int - позиция курсора.
FCTL_SETCMDLINESELECTION Выделить текст командной строки.
Param указывает на структуру CmdLineSelect.
Прочие
FCTL_SETUSERSCREEN Копиpует текущее содеpжимое экpана в буфеp пользовательского экрана FAR (он показывается, когда панели убpаны).
Param должен быть NULL.
FCTL_GETUSERSCREEN Выводит буфеp пользовательского экрана FAR (он показывается, когда панели убpаны) на экpан.
Param должен быть NULL.
Param
Указывает на параметры команды. Смотрите описание Command

Возвращаемое значение

В случае успеха возвращается TRUE, иначе FALSE.

Замечания

Обычно вы не должны обновлять или перерисовывать панель и директивно закрывать плагин. FAR делает это сам, при выполнении стандартных операций. Эти функции могут быть необходимыми для реализации некоторых нестандартных функциональных возможностей.
Смотрите также:
AdvControl, EditorControl


FreeDirList

главная | сервисные функции
Функция FreeDirList освобождает память, выделенную для списка файлов функциями GetDirList и GetPluginDirList.
void WINAPI FreeDirList(
  const struct PluginPanelItem *PanelItem
);

Параметры

PanelItem
Адрес массива структур PluginPanelItem.

Возвращаемое значение

Нет.


GetDirList

главная | сервисные функции
Функция GetDirList возвращает список файлов в указанной директории (с поддиректориями).
int WINAPI GetDirList(
  const char *Dir,
  struct PluginPanelItem **pPanelItem,
  int *pItemsNumber
);

Параметры

Dir
Имя обрабатываемого подкаталога текущего каталога. Может быть как именем без пути, так и с полным путем.
pPanelItem
Указывает на переменную, которая получит адрес массива структур PluginPanelItem.
Когда этот массив больше не нужен, он должен быть передан функции FreeDirList.
pItemsNumber
Указывает на переменную, которая получит число структур PluginPanelItem.

Возвращаемое значение

Если функция завершилась успешно, она вернет TRUE. Если функция закончилась неудачно или обработка директории была прервана пользователем, то она вернет FALSE.

Замечания

  1. Функция возвращает имена файлов относительно указанного каталога. Например, если Dir есть D:\DIR1\DIR2, имена файлов будут в виде DIR2\file.ext.
  2. Пользователь может прервать выполнение функции, нажав клавишу Esc, при этом функция вернет значение FALSE.
Смотрите также:
GetPluginDirList


GetMsg

главная | сервисные функции
Функция GetMsg возвращает строку сообщения из языкового файла. Настоятельно рекомендуется использовать эту функцию вместо предопределенного текста в ваших программах, поскольку это позволит локализовать ваш плагин и переключать языки в FAR Manager и плагине одновременно.
const char* WINAPI GetMsg(
  int PluginNumber,
  int MsgId
);

Параметры

PluginNumber
Номер плагина. Этот номер вы получаете в функции SetStartupInfo.
MsgId
Номер строки сообщения в файле сообщений.

Возвращаемое значение

Эта функция возвращает адрес запрашиваемой строки сообщения.

Примечание

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

Пример

Во всех примерах, как вы могли заметить, используется следующая функция:
C/C++:
const char *GetMsg(int MsgId)
{
  return(Info.GetMsg(Info.ModuleNumber,MsgId));
}
Delphi:
function GetMsg(MsgId: TMessageStrings): PChar;
begin
  result:= Info.GetMsg(Info.ModuleNumber,integer(MsgId));
end;
Причем, Info определяется как глобальная переменная:
struct PluginStartupInfo Info;
...а инициализируется она в функции SetStartupInfo:
void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info)
{
  ...
  ::Info=*Info;
  ...
}
Смотрите также:
Языки и файлы помощи | LocMsg
"Локализация плагинов второго уровня"


GetPluginDirList

главная | сервисные функции
Функция GetPluginDirList возвращает список файлов в указанной директории (с поддиректориями) эмулируемой файловой системы.
int WINAPI GetPluginDirList(
  int PluginNumber,
  HANDLE hPlugin,
  const char *Dir,
  struct PluginPanelItem **pPanelItem,
  int *pItemsNumber
);

Параметры

PluginNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
hPlugin
Текущий описатель плагина. Если описатель плагина равен INVALID_HANDLE_VALUE, то значение параметра PluginNumber игнорируется и используется номер плагина, которому принадлежит активная панель.
Dir
Имя обрабатываемой директории. Должно быть в форме, приемлемой для функции плагина SetDirectory. Плагинам обычно не требуется обработка полного пути функцией SetDirectory, поэтому чаще всего (нужно в этом убедиться), это просто имя обрабатываемого подкаталога текущего каталога.

Для сохранения текущей директории плагина неизменной после вызова GetPluginDirList, либо Dir должен быть подкаталогом текущего каталога плагина, либо функция SetDirectory плагина должна уметь обрабатывать имя каталога, возвращаемое GetOpenPluginInfo. Иначе текущая директория будет изменена, и вы должны быть готовы восстановить ее.

pPanelItem
Указывает на переменную, которая получит адрес массива структур PluginPanelItem.
Когда этот массив больше не нужен, он должен быть передан функции FreeDirList.
pItemsNumber
Указывает на переменную, которая получит число структур PluginPanelItem.

Возвращаемое значение

Если функция завершилась успешно, она вернет TRUE. Если функция закончилась неудачно или обработка директории была прервана пользователем, то она вернет FALSE.

Замечания

  1. Функция возвращает имена файлов относительно указанного каталога. Например, если Dir есть D:\DIR1\DIR2, имена файлов будут в виде DIR2\file.ext.
  2. Пользователь может прервать выполнение функции, нажав клавишу Esc, при этом функция вернет значение FALSE.
Смотрите также:
GetDirList


Menu

главная | сервисные функции
Функция Menu показывает меню.
int WINAPI Menu(
  int PluginNumber,
  int X,
  int Y,
  int MaxHeight,
  DWORD Flags,
  const char *Title,
  const char *Bottom,
  const char *HelpTopic,
  const int *BreakKeys,
  int *BreakCode,
  const struct FarMenuItem *Item,
  int ItemsNumber
);

Параметры

PluginNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
X,Y
Координаты верхнего левого угла меню
Чтобы назначить их автоматически, приравняйте их -1.
MaxHeight
Максимальное количество видимых на экране пунктов меню. Если высота меню меньше, чем число пунктов, то появится полоса прокрутки.
Чтобы использовать максимально возможное значение, установите этот параметр равным 0.
Flags
Может быть комбинацией из следующих значений (перечисление FARMENUFLAGS):
Константа | Описание
FMENU_AUTOHIGHLIGHT | Если указан, то горячие клавиши будут назначены автоматически, начиная с первого пункта.
FMENU_CHANGECONSOLETITLE | Если указан, то FAR изменит заголовок консоли в значение, указанное в параметре Title (если Title не пуст).
FMENU_SHOWAMPERSAND | При показе меню не использовать амперсанды (&) для определения горячих клавиш.
FMENU_REVERSEAUTOHIGHLIGHT | Если указан, то горячие клавиши будут назначены автоматически, начиная с последнего пункта.
FMENU_USEEXT | Вместо структуры FarMenuItem использовать структуру FarMenuItemEx.
FMENU_WRAPMODE | Если указан, то попытка перемещения курсора выше первого пункта или ниже последнего будет приводить к перемещению соответственно к последнему или к первому пункту. Этот флаг рекомендуется ставить всегда, когда нет специальных причин его не ставить.
Если выставлен флаг FMENU_USEEXT, то необходимо выполнить приведение типов:
struct FarMenuItemEx FooEx[]={
  ...
};
Info.Menu(...,FMENU_USEEXT|...,(const struct FarMenuItem *)FooEx,...)
Title
Заголовок меню. Укажите NULL, если заголовок меню не нужен.
Bottom
Нижняя строка меню. Укажите NULL, если нижняя строка меню не нужна.
HelpTopic
Тема в файле помощи, ассоциированная с меню. Может быть NULL, если подсказка не требуется.
BreakKeys
Адрес массива с кодами виртуальных клавиш (VK_*), которые будут закрывать меню. Последний элемент массива должен быть равным 0. Если вам не нужно определять такие клавиши в дополнение к стандартным (<Enter>, <Esc> и <F10>), установите этот параметр в NULL. Старшее слово (high word) элемента массива может быть или 0, или комбинацией флагов PKF_CONTROL, PKF_ALT и PKF_SHIFT для описания комбинаций клавиш.

Например, в плагине MultiArc реакция на нажатие клавиши F4 в меню "Archive commands" (Shift-F3 на архиве) обрабатывается так:

int BreakCode;
int BreakKeys[2]={VK_F4,0};
ExitCode=Info.Menu(Info.ModuleNumber,-1,-1,0,FMENU_USEEXT|FMENU_WRAPMODE,
     GetMsg(MArcCmdTitle),GetMsg(MSelectF4),"ArcCmd",BreakKeys,&BreakCode,
     (struct FarMenuItem *)MenuItems,Count);
if(ExitCode>=0)
{
  if(BreakCode == 0)  // F4 pressed
  {
    GetFormatName(MenuItems[0].Text.Text);
    ConfigCommands(MenuItems[0].Text.Text,2+MenuData[ExitCode].Cmd*2);
    continue;
  }
}
else
  return FALSE;
BreakCode
Адрес переменной, в которую будет записан номер элемента массива BreakKeys, использованного для закрытия меню, или -1, если меню было закрыто одной из стандартных клавиш. Этот параметр может быть равным NULL.
Item
Адрес массива структур FarMenuItem или, если указан флаг FMENU_USEEXT, то адрес массива структур FarMenuItemEx. Каждая структура описывает элемент меню.
ItemsNumber
Количество структур FarMenuItem.

Возвращаемое значение

Функция возвращает или -1, если пользователь отменил меню, или номер выбранного элемента меню.

Пример

Пример взят из плагина EditCase:
struct FarMenuItem MenuItems[2];
memset(MenuItems,0,sizeof(MenuItems));
strcpy(MenuItems[0].Text,GetMsg(MCaseLower));
strcpy(MenuItems[1].Text,GetMsg(MCaseUpper));
MenuItems[0].Selected=TRUE;
int MenuCode=Info.Menu(Info.ModuleNumber,-1,-
      1,0,FMENU_AUTOHIGHLIGHT|FMENU_WRAPMODE,
      GetMsg(MCaseConversion),NULL,
      "Contents",NULL,NULL,
      MenuItems,
      sizeof(MenuItems)/sizeof(MenuItems[0]));
if (MenuCode<0)
  return(INVALID_HANDLE_VALUE);
. . .
Причем, Info определяется как глобальная переменная:
struct PluginStartupInfo Info;
...а инициализируется она в функции SetStartupInfo:
void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info)
{
  ...
  ::Info=*Info;
  ...
}
Смотрите также:
FarMenuItem


RestoreScreen

главная | сервисные функции
Функция RestoreScreen восстанавливает область экрана предварительно сохраненную функцией SaveScreen.
void WINAPI RestoreScreen(
  HANDLE hScreen,
);

Параметры

hScreen
Описатель, полученный после вызова SaveScreen. После вызова RestoreScreen он больше не может использоваться.

Возвращаемое значение

Нет.

Замечания

Для увеличения скорости RestoreScreen перерисовывает только измененную область экрана. RestoreScreen не может корректно определить эту область, если область экрана была изменена не функцией FAR Manager (например, запущенной из плагина внешней программой). В этом случае сначала вы должны вызвать RestoreScreen с параметром NULL, чтобы показать FAR'у, что экран изменен, а затем вызвать RestoreScreen как обычно - с описателем от SaveScreen.
Смотрите также:
SaveScreen


SaveScreen

главная | сервисные функции
Функция SaveScreen сохраняет область экрана. Для восстановления сохраненной области используйте функцию RestoreScreen.
HANDLE WINAPI SaveScreen(
  int X1,
  int Y1,
  int X2,
  int Y2
);

Параметры

X1,Y1,X2,Y2
Координаты области экрана. Если X2 или Y2 равны -1, то они заменяются соответственно правой или нижней координатой экрана. Таким образом, SaveScreen(0,0,-1,-1) сохранит весь экран.

Возвращаемое значение

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

Смотрите также:
RestoreScreen


ShowHelp

главная | сервисные функции
Функция ShowHelp показывает заданный топик из hlf-файла.
BOOL WINAPI ShowHelp(
  const char *ModuleName,
  const char *HelpTopic,
  int   Flags
);

Параметры

ModuleName
Полное имя плагина. Его вы получаете в функции SetStartupInfo.
HelpTopic
Тема помощи. Если параметр HelpTopic = NULL, то будет показана тема со стандартным именем "Contents".
Flags
Может быть одним из следующий значений (перечисление FarHelpFlags):
Константа | Описание
FHELP_SELFHELP | Трактовать параметр ModuleName как Info.ModuleName и показать тему из файла помощи вызвавшего плагина. Если HelpTopic начинается с символа ':', то будет показана тема из основного файла помощи FAR (в этом случае параметр ModuleName игнорируется).
FHELP_FARHELP | Параметр ModuleName игнорируется и будет показана тема из основного файла помощи FAR. При этом в параметре HelpTopic не надо указывать первым символом ':'.
FHELP_CUSTOMFILE | Трактовать параметр ModuleName как указатель на имя HLF-файла (c:\path\filename).
FHELP_CUSTOMPATH | Трактовать параметр ModuleName как указатель на путь (c:\path), а файл выберется автоматически, исходя из текущих настроек языка.
FHELP_USECONTENTS | Если требуемая тема HelpTopic не найдена, то попытаться отобразить тему "Contents". Флаг может комбинироваться с другими флагами.
FHELP_NOSHOWERROR | Не выводить сообщения об ошибках в случае, если требуемая тема или файл помощи не найдены. Флаг может комбинироваться с другими флагами.

Возвращаемое значение

TRUE - удалось передать параметры в Менеджер Помощи.
FALSE - ошибка:
  • Flags содержит неверное значение,
  • ModuleName = NULL для случаев, отличных от FHELP_FARHELP
  • Менеджер Помощи не нашел заданный файл/тему помощи
  • Менеджер Помощи не нашел файл/тему помощи в процессе навигации по системе помощи.

Пример

Для удобства при частом использовании можно использовать следующую функцию в вашей программе:
void ShowHelp(const char *HelpTopic)
{
  Info.ShowHelp(Info.ModuleName,HelpTopic,0);
}
Причем, Info определяется как глобальная переменная...
struct PluginStartupInfo Info;
...а инициализируется она в функции SetStartupInfo:
void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info)
{
. . .
  ::Info=*Info;
. . .
}
Смотрите также:
Файлы помощи


Text

главная | сервисные функции
Функция Text выводит текстовую строку на экран. FAR использует внутреннюю буферизацию экрана для увеличения производительности, поэтому для совместимости плагин не должен выводить текст на экран напрямую, а только используя функцию Text.
void WINAPI Text(
  int X,
  int Y,
  int Color,
  const char *Str
);

Параметры

X,Y
Координаты вывода текста. Начало системы координат (0,0) - в верхней левой ячейке экрана.
Color
Цветовые атрибуты текста.
Str
Текстовая строка, завершающаяся нулем. После вывода строки, вы можете также вызвать Text с параметром Str равным NULL - эта операция сбросит экранный буфер FAR и ваши изменения вступят в силу немедленно. Но не используйте это слишком часто, чтобы не снизить общую производительность.

Возвращаемое значение

Нет


Сервисные функции

Сервисные функции - Редактор

главная
Функция | Описание
Editor | обеспечивает доступ к внутреннему редактору FAR'a
EditorControl | обеспечивает доступ на низком уровне к API редактора FAR'a
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


Editor

главная | сервисные функции
Функция Editor позволяет открыть внутренний редактор FAR Manager.
int WINAPI Editor(
  const char *FileName,
  const char *Title,
  int X1,
  int Y1,
  int X2,
  int Y2,
  DWORD Flags,
  int StartLine,
  int StartChar
);

Параметры

FileName
Файл для редактирования. Если не указан флаг EF_CREATENEW, то FileName должен содержать имя существующего файла.
Title
Текстовая строка, которая будет показана вверху окна редактора. Если этот параметр равен NULL, то используется имя файла.
X1, Y1, X2, Y2
Координаты окна редактора. Если координата X2 или Y2 равна -1, то она будет замещена соответственно шириной или высотой экрана. Если координата X1 или Y1 меньше нуля, то считается, что она равна нулю.
Flags
Флаги редактора. Может быть комбинацией следующих значений (перечисление EDITOR_FLAGS):
Флаг | Описание
EF_NONMODAL Создать немодальное окно редактора. Если этот флаг присутствует, пользователь сможет переключаться между редактором и другими окнами FAR Manager.

Плагин получит управление только после закрытия или ухода из открытого редактора (например, пользователь нажал Ctrl-Tab). Если вам нужно, чтобы плагин получал управление сразу же после открытия редактора, то используйте флаг EF_IMMEDIATERETURN.

EF_IMMEDIATERETURN | Позволяет плагину получать управление сразу же после открытия редактора. Открываемый редактор становится активным. Выставлять этот флаг имеет смысл только в паре с флагом EF_NONMODAL.
EF_DELETEONCLOSE Поручает FAR'у удалить редактируемый файл после закрытия редактора. Если в директории, содержащей редактируемый файл, нет других файлов, она также будет удалена. Если требуется удаление только файла, то используйте EF_DELETEONLYFILEONCLOSE.
Файл не удаляется:
  1. если было произведено переключение по F6 и если существуют другие открытые вьюеры/редакторы с этим же файлом.
  2. если файл был сохранен из редактора.
EF_DELETEONLYFILEONCLOSE | Аналог EF_DELETEONCLOSE, но удаляется только файл. Этот флаг имеет более низкий приоритет при обработке, чем EF_DELETEONCLOSE.
EF_CREATENEW | Создать новый файл на диске. Вызов редактора с этим флагом аналогичен вызову редактора по Shift+F4 в панелях.
EF_ENABLE_F6 | Разрешает переключение по F6 из редактора во вьюер.
EF_DISABLEHISTORY | Запретить добавление имени файла в историю редактирования (Alt-F11). По умолчанию имя в историю добавляется.
StartLine
Начальная строка, в которую помещаем курсор. Нумерация строк начинается с 0.
StartChar
Позиция курсора в строке. Нумерация позиции начинается с 1.

Возвращаемое значение

Эта функция возвращает следующие значения (перечисление EDITOR_EXITCODE):
Возвращаемое значение | Описание
EEC_OPEN_ERROR Ошибка открытия файла. Ошибка возникает в случаях, если:
  • FAR не смог выделить достаточно памяти при создании редактора (как объекта);
  • в качестве параметра FileName передали пустую строку;
  • в качестве параметра FileName было передано имя каталога;
  • редактируемый файл имеет RO-атрибут и пользователь в диалоге подтверждения открытия такого файла отказался от дальнейшего редактирования.
EEC_MODIFIED | Успешное завершение. Файл был изменен. Функция Editor также возвращает этот код возврата при использовании флага EF_NONMODAL.
EEC_NOT_MODIFIED | Успешное завершение. Файл не был изменен.
EEC_LOADING_INTERRUPTED | Загрузка файла прервана пользователем.

Замечания

Если StartLine и StartChar равны -1, то при открытии редактора будет восстановлена предварительно сохраненная позиция в файле (если это включено в настройках).
Смотрите также:
Viewer


EditorControl

главная | сервисные функции
Функция EditorControl обеспечивает доступ на низком уровне к API редактора FAR'a.
int WINAPI EditorControl(
  int Command,
  void* Param
);

Параметры

Command
Тип команды. Может быть одним из следующих (перечисление EDITOR_CONTROL_COMMANDS):
Команда | Описание
ECTL_ADDCOLOR | Задать цвет части строки. Эта команда может быть вызвана несколько раз для одной и той же строки для задания нескольких цветных областей. Param указывает на структуру EditorColor. Если указанная строка отсутствует, то возвращается FALSE, иначе TRUE.
ECTL_ADDSTACKBOOKMARK | Добавить позицию навигации ("стековую закладку") в текущую позицию редактора. При добавлении удаляются все позиции навигации с индексом выше индекса текущей позиции навигации. Param должен быть равен NULL. Команда возвращает TRUE в случае успешного выполнения.
ECTL_CLEARSTACKBOOKMARKS | Удалить все позиции навигации. Param должен быть равен NULL.
ECTL_DELETEBLOCK | Удалить блок в редакторе. Функция вернет TRUE в случае удачного удаления блока и FALSE, если редактор заблокирован (пользователь нажал Ctrl-L) или нет выделенного блока. Param должен быть равен NULL.
ECTL_DELETECHAR | Удалить символ под курсором. Param должен быть NULL.
ECTL_DELETESTACKBOOKMARK Удалить указанную позицию навигации. Param должен быть равен индексу удаляемой позиции навигации (0 и более) или -1 для удаления текущей позиции навигации. Количество позиций навигации можна получить, вызвав ECTL_GETSTACKBOOKMARKS c Param равным значению NULL.
Команда возвращает TRUE в случае успешного выполнения.
ECTL_DELETESTRING | Удалить текущую строку. Param должен быть NULL.
ECTL_EDITORTOOEM | Конвертировать текст из кодировки редактора в OEM-кодировку. Param указывает на структуру EditorConvertText.
ECTL_EXPANDTABS | Заменить все символы табуляции в строке пробелами. Param указывает на целую переменную, содержащую номер обрабатываемой строки или -1 для обработки текущей строки.
ECTL_GETBOOKMARKS Получить информацию о закладках для текущего редактируемого файла. Param указывает на структуру EditorBookMarks.
Команда возвращает FALSE в случае, если:
  1. файл еще не открыт;
  2. в качестве Param был передано значение NULL;
В случае успеха возвращается TRUE.
ECTL_GETSTACKBOOKMARKS Получить информацию о позициях навигации ("стековых закладках") для текущего редактируемого файла. Param указывает на структуру EditorBookMarks или равен значению NULL.
Команда возвращает количество позиций навигации, информация о которых была передана (или общее количество позиций навигации, если в качестве Param было передано значение NULL).
ECTL_GETCOLOR | Получить цвет части строки. Param указывает на структуру EditorColor. Если указанная строка или часть строки отсутствует, то возвращается FALSE, иначе TRUE.
ECTL_GETINFO | Получить информацию о редакторе. Param указывает на структуру EditorInfo.
ECTL_GETSTRING Получить информацию о строке. Param указывает на структуру EditorGetString. Полученная строка будет в кодировке редактора.
// получить первую строку редактируемого файла
struct EditorGetString egs;
egs.StringNumber=0;
Info.EditorControl(ECTL_GETSTRING,&egs);
ECTL_INSERTSTRING Вставить новую строку (разорвать строку) с текущей позиции курсора и переместить курсор либо на первую позицию новой строки, либо на позицию с учетом отступа. Если Param указывает на целочисленную переменную, равную 1, то при выполнении данной команды будет использоваться отступ. Для его отключения установите Param в NULL или установите целую переменную в 0. Поведение при отступе из плагина точно такое же, как и при нажатии <Enter> пользователем в редакторе, например, в новую строку пробелы (или табуляция) не вставляются, если после нового положения курсора строка не содержит никаких символов.
// вставить пустую строку без отступа
Info.EditorControl(ECTL_INSERTSTRING,0);
ECTL_INSERTTEXT Вставить текст, начиная с позиции курсора. Param указывает на строку в OEM кодировке, оканчивающуюся нулем (ASCIIZ). Команда корректно обрабатывает символ(ы) перевода строки (CR). Команда ECTL_INSERTTEXT работает так, как будто текст вводится с клавиатуры.
// вставить строку "Text" в текущую позицию курсора
Info.EditorControl(ECTL_INSERTTEXT,"Text");
ECTL_NEXTSTACKBOOKMARK Перейти на следующую позицию навигации. Param должен быть равен NULL.
Команда возвращает TRUE в случае успешного выполнения.
ECTL_OEMTOEDITOR | Конвертировать текст из OEM-кодировки в кодировку редактора. Param указывает на структуру EditorConvertText.
ECTL_PREVSTACKBOOKMARK | Перейти на предыдущую позицию навигации. Если после предыдущего вызова команды ECTL_ADDSTACKBOOKMARK не выполнялось операций с позициями навигации, то перед переходом запоминается текущая позиция редактора в качестве новой позиции навигации. Param должен быть равен NULL. Команда возвращает TRUE в случае успешного выполнения.
ECTL_PROCESSINPUT Передает структуру INPUT_RECORD, указатель на которую передается в Param, внутреннему редактору FAR для обработки.
Учтите, что если ваш плагин экспортирует функцию ProcessEditorInput, то данные из Param сразу же будут переданы в ProcessEditorInput. Схема проста:
case ECTL_PROCESSINPUT:
  if (ProcessEditorInput(Param))
    return(TRUE);
  ...
Поэтому используя EditorControl(ECTL_PROCESSINPUT) в функции ProcessEditorInput следите за тем, чтобы не впасть в бесконечную рекурсию.
ECTL_PROCESSKEY Функция позволяющая "нажимать" в редакторе различные клавиши, коды которых передаются в Param.
Используются внутренние коды клавиш FAR Manager (см. farkeys.hpp)
Эта команда всегда возвращает TRUE.
// перейти в конец редактируемого файла
Info.EditorControl(ECTL_PROCESSKEY,(void*)KEY_CTRLEND);
ECTL_QUIT | Закрыть редактор. Любая несохраненная информация будет потеряна. Param должен быть равен NULL. Эта команда всегда возвращает TRUE.
ECTL_READINPUT | Заполняет структуру INPUT_RECORD читая данные со стандартного устройства ввода. Param указывает на структуру INPUT_RECORD (она определена в Win32 API и используется в функции ReadConsoleInput).
ECTL_REALTOTAB | Конвертировать реальную строковую позицию курсора в экранную позицию. Если строка не содержит символов табуляции, входная и получаемая позиция будут равными. Param указывает на структуру EditorConvertPos.
ECTL_REDRAW | Перерисовать окно редактора. Param должен быть NULL.
ECTL_SAVEFILE | Позволяет плагину сохранить редактируемый файл. Param указывает на структуру EditorSaveFile. Если Param равен NULL, то будут использованы имя редактируемого файла и текущий формат сохранения (DOS-формат - перевод строки заменяется на "\r\n", Unix-формат - "\n"). При успешном сохранении файла функция вернет TRUE.
ECTL_SELECT | Выделить или снять выделение с блока. Param указывает на структуру EditorSelect.
ECTL_SETKEYBAR Функция, позволяющая управлять поведением строки функциональных клавиш в редакторе:
Param = NULL - восстановить, предыдущее значение
Param = -1 - обновить полосу (перерисовать)
Param = указатель на структуру KeyBarTitles.

Вызывать данную команду в событии EE_READ не имеет смысла, т.к. строки функциональных клавиш, как объекта, в момент загрузки файла в редактор еще не существует.
Команда возвращает TRUE в случае успешного выполнения или FALSE (когда строка, как объект, не создана).

ECTL_SETPARAM Изменение настроек текущего редактора. Param указывает на структуру EditorSetParameter.
Команда возвращает TRUE в случае успешного изменения параметров.
ECTL_SETPOSITION | Установить позицию курсора. Param указывает на структуру EditorSetPosition.
ECTL_SETSTRING | Поместить текст в строку. Param указывает на структуру EditorSetString. Помещаемая строка должна быть в кодировке редактора.
ECTL_SETTITLE Установить заголовок редактора (верхняя статусная панель). Стандартный заголовок будет восстановлен после отработки плагина. Param указывает на строку, оканчивающуюся нулем, которая содержит текст заголовка.
// DrawLine\DrawLine.cpp: функция SetTitle
Info.EditorControl(ECTL_SETTITLE,(char *)GetMsg(IDTitle));
ECTL_TABTOREAL | Конвертировать экранную позицию курсора в реальную строковую позицию. Если строка не содержит символов табуляции, входная и получаемая позиция будут равными. Param указывает на структуру EditorConvertPos.
ECTL_TURNOFFMARKINGBLOCK Убрать флаг редактора, который устанавливается всегда, когда пользователь осуществляет выделение вертикального или поточного блока. Этот флаг существует только для внутренних нужд FAR Manager и плагинами не используется, но пользователь может заметить негативные (в основном косметические) дефекты, когда он начал выделять блок и запустил (или это произошло автоматически) ваш плагин, который, например, изменил позицию курсора, поэтому вы почти всегда должны использовать данную команды перед передачей управления FAR, если ваш плагин изменил файл в редакторе или положение курсора.
Param должен быть NULL.
Param
Указывает на параметр команды. Смотрите описание Command.

Возвращаемое значение

В случае успеха возвращается TRUE. В случае неудачи - FALSE.

Замечания

FAR обновляет содержимое окна редактора при активных действиях пользователя. Вызовите ECTL_REDRAW, чтобы принудительно обновить окно после любых активных изменений содержимого редактора.
Смотрите также:
AdvControl, Control


Сервисные функции

Сервисные функции - Программа просмотра

главная
Функция | Описание
Viewer | обеспечивает доступ к внутреннему вьюеру FAR'a
ViewerControl | позволяет запрашивать различную информацию о встроенной программе просмотра FAR и управлять ее состоянием
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


Viewer

главная | сервисные функции
Функция Viewer позволяет открыть внутреннюю программу просмотра FAR Manager.
int WINAPI Viewer (
  const char *FileName,
  const char *Title,
  int X1,
  int Y1,
  int X2,
  int Y2,
  DWORD Flags
);

Параметры

FileName
Файл для просмотра
Title
Текстовая строка, которая будет показана вверху окна вьюера. Если этот параметр равен NULL, то используется имя файла.
X1, Y1, X2, Y2
Координаты окна вьюера. Если координата X2 или Y2 равна -1, то она будет замещена соответственно шириной или высотой экрана. Если координата X1 или Y1 меньше нуля, то считается, что она равна нулю.
Flags
Может быть комбинацией следующих значений (перечисление VIEWER_FLAGS):
Флаг | Описание
VF_DELETEONCLOSE | FAR удалит просматриваемый файл после закрытия вьюера. Если в директории, содержащей просматриваемый файл, нет других файлов, она также будет удалена. Если требуется удаление только файла, то используйте VF_DELETEONLYFILEONCLOSE. Файл не удаляется, если было произведено переключение по F6 и если существуют другие открытые вьюеры/редакторы с этим же файлом.
VF_DELETEONLYFILEONCLOSE | Аналог VF_DELETEONCLOSE, но удаляется только файл. Этот флаг имеет более низкий приоритет при обработке, чем VF_DELETEONCLOSE.
VF_DISABLEHISTORY | Запретить добавление имени файла в историю просмотра (Alt-F11). По умолчанию имя в историю добавляется.
VF_ENABLE_F6 | Разрешает переключение по F6 из вьюера в редактор.
VF_IMMEDIATERETURN | Позволяет плагину получать управление сразу же после открытия программы просмотра. Открываемая программа просмотра становится активной. Выставлять этот флаг имеет смысл только в паре с флагом VF_NONMODAL.
VF_NONMODAL | Создать немодальное окно вьюера. Если этот флаг присутствует, пользователь сможет переключаться между программой просмотра и другими окнами FAR Manager. Плагин получит управление только после закрытия или ухода из открытой программы просмотра (например, пользователь нажал Ctrl-Tab). Если вам нужно, чтобы плагин получал управление сразу же после открытия программы просмотра, то используйте флаг VF_IMMEDIATERETURN.

Возвращаемое значение

Если флаг VF_NONMODAL отсутствует, эта функция возвращает TRUE в случае успеха или FALSE, если файл не удалось открыть. Если этот флаг присутствует, то всегда возвращается TRUE.
Смотрите также:
Editor


ViewerControl

главная | сервисные функции
Функция ViewerControl позволяет запрашивать различную информацию о встроенной программе просмотра FAR и управлять ее состоянием.
int WINAPI ViewerControl(
  int Command,
  void *Param
);

Параметры

Command
Тип команды. Может быть одним из следующих (перечисление VIEWER_CONTROL_COMMANDS):
Команда | Описание
VCTL_GETINFO | Получить информацию о программе просмотра. Param указывает на структуру ViewerInfo. Всегда возвращается TRUE.
VCTL_QUIT | Закрыть программу просмотра. Param должен быть NULL. Всегда возвращается TRUE.
VCTL_REDRAW | Перерисовать окно программы просмотра. Param должен быть NULL. Всегда возвращается TRUE.
VCTL_SETKEYBAR | Функция, позволяющая управлять поведением строки функциональных клавиш в программе просмотра: Param = NULL - восстановить предыдущее значение Param = -1 - обновить полосу (перерисовать) Param = указатель на структуру KeyBarTitles. Всегда возвращается TRUE.
VCTL_SELECT | Управление выделением. Param указывает на структуру ViewerSelect. Если Param = NULL, произойдет сброс выделения. В случае успеха возвращается TRUE.
VCTL_SETMODE | Изменить режим работы программы просмотра. Param указывает на структуру ViewerSetMode. В случае успеха возвращается TRUE.
VCTL_SETPOSITION | Установить позицию в файле. Param указывает на структуру ViewerSetPosition. В случае успеха возвращается TRUE.
Param
Смотрите описание конкретной команды.

Возвращаемое значение

Смотрите описание конкретной команды.

Примечание

В FAR 1.70 build 1579 и выше VCTL_QUIT в информационной панели и панели быстрого просмотра не приводит к закрытию программы просмотра.
Смотрите также:
Сервисные функции, ViewerInfo, ViewerSetPosition, ViewerSelect


Сервисные функции

Сервисные функции - Dialog API

главная
Функция | Описание
DefDlgProc | вызывает стандартный обработчик диалога
Dialog | показывает диалог
DialogEx | расширенный диалог с функцией обработчиком
InputBox | позволяет ввести строку текста
Message | показывает сообщение
SendDlgMessage | послать сообщение обработчику диалога.
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


DefDlgProc

главная | Dialog API | События
Функция DefDlgProc позволяет вызвать стандартную (внутреннюю) функцию обработки диалога.
LONG_PTR WINAPI DefDlgProc(
  HANDLE hDlg,
  int    Msg,
  int    Param1,
  LONG_PTR Param2
);

Параметры

hDlg
Указатель на диалог
Msg
Одно из сообщений или событий.
Param1
Параметр 1
Param2
Параметр 2

Возвращаемое значение

Значение, возвращаемое функцией DefDlgProc зависит от параметра Msg.

Замечания

Пример

Фрагмент обработчика диалога игры Reversi:
LONG_PTR WINAPI ReversiDialogProc(HANDLE hDlg, int Msg,int Param1,LONG_PTR Param2)
{
  ...
  return Info.DefDlgProc(hDlg,Msg,Param1,Param2);
}
Смотрите также:


Dialog

главная | Dialog API
Функция Dialog выводит на экран диалог.
int WINAPI Dialog(
  int PluginNumber,
  int X1,
  int Y1,
  int X2,
  int Y2,
  const char *HelpTopic,
  struct FarDialogItem *Item,
  int ItemsNumber
);

Параметры

PluginNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
X1, Y1, X2, Y2
Геометрия диалога. Задайте эти координаты непосредственно или воспользуйтесь формулой "Width x Height" - для этого установите X1 и Y1 в -1, при этом X2 - ширина и Y2 - высота диалога. В последнем случае при выводе на экран диалог будет автоматически центрироваться. Параметры X2 и Y2 не могут быть меньше нуля.
HelpTopic
Тема подсказки связанная с данным диалогом. Если подсказка не используется, то установите этот параметр в NULL.
Item
Указатель на массив структур FarDialogItem. Каждая структура описывает пункт диалога.
ItemsNumber
Количество элементов массива FarDialogItem.

Возвращаемое значение

Эта функция возвращает -1, если пользователь прервал диалог, или номер выбранного диалогового пункта (номер элемента массива Item, в примере этот факт выделен)

Замечания

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

Пример

Пример вывода диалога конфигурирования плагина TempPanel
int Config()
{
  struct InitDialogItem InitItems []={
    DI_DOUBLEBOX,3,1,72,8,0,0,0,0,(char *)MConfigTitle,
    DI_CHECKBOX,5,2,0,2,0,0,0,0,(char *)MConfigAddToDisksMenu,
    DI_FIXEDIT,7,3,7,3,1,0,0,0,"",
    DI_TEXT,9,3,0,3,0,0,0,0,(char *)MConfigDisksMenuDigit,
    DI_TEXT,5,4,0,4,0,0,DIF_BOXCOLOR|DIF_SEPARATOR,0,"",
    DI_CHECKBOX,5,5,0,5,0,0,0,0,(char *)MConfigCommonPanel,
    DI_TEXT,5,6,0,6,0,0,DIF_BOXCOLOR|DIF_SEPARATOR,0,"",
    DI_BUTTON,0,7,0,7,0,0,DIF_CENTERGROUP,1,(char *)MOk,
    DI_BUTTON,0,7,0,7,0,0,DIF_CENTERGROUP,0,(char *)MCancel
  };
  struct FarDialogItem DialogItems[sizeof(InitItems)/sizeof(InitItems[0])];
  . . .
  InitDialogItems(InitItems,DialogItems,
                   sizeof(InitItems)/sizeof(InitItems[0]));
  . . .
  int ExitCode=Info.Dialog(Info.ModuleNumber,
                  -1,-1,76,10,
                  "TempCfg",DialogItems,
                  sizeof(DialogItems)/sizeof(DialogItems[0]));
  if (ExitCode != 7)
    return(FALSE);
. . .
}
Смотрите также:
DialogEx, сервисные функции, Message, InitDialogItems


DialogEx

главная | Dialog API | События и сообщения
Функция DialogEx выводит на экран диалог, для обработки которого можно задать функцию-обработчик.
int WINAPI DialogEx(
  int PluginNumber,
  int X1,
  int Y1,
  int X2,
  int Y2,
  const char *HelpTopic,
  struct FarDialogItem *Item,
  int ItemsNumber,
  DWORD Reserved,
  DWORD Flags,
  FARWINDOWPROC DlgProc,
  LONG_PTR Param
);

Параметры

PluginNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
X1, Y1, X2, Y2
Геометрия диалога. Задайте эти координаты непосредственно или воспользуйтесь формулой "Width x Height" - для этого установите X1 и Y1 в -1, при этом X2 - ширина и Y2 - высота диалога. В последнем случае при выводе на экран диалог будет автоматически центрироваться. Параметры X2 и Y2 не могут быть меньше нуля.
HelpTopic
Тема подсказки связанная с данным диалогом. Если подсказка не используется, то установите этот параметр в NULL.
Item
Указатель на массив структур FarDialogItem. Каждая структура описывает пункт диалога.
ItemsNumber
Количество элементов массива FarDialogItem.
Reserved
Зарезервировано. Должно быть рано 0.
Flags
Набор флагов, уточняющих некоторые параметры диалога. Может быть комбинацией следующих значений (перечисление FARDIALOGFLAGS):
Флаг | Описание
FDLG_WARNING | Задает для диалога цветовую схему "Предупреждение".
FDLG_SMALLDIALOG | Позволяет создавать диалоги с уменьшенным размером рамки. Для таких диалогов при отрисовке разделительных линий (DIF_SEPARATOR) предполагается нулевой отступ между границей диалога и окружающей его двойной рамкой.
FDLG_NODRAWSHADOW | Не рисовать тень диалога.
FDLG_NODRAWPANEL | Не рисовать поле диалога.
DlgProc
Указатель на функцию-обработчик диалогового окна типа FARWINDOWPROC.
Param
Данные, которые обработчик диалога получит в сообщении DN_INITDIALOG

Возвращаемое значение

Эта функция возвращает -1, если пользователь прервал диалог, или номер выбранного диалогового пункта (номер элемента массива Item, в примере этот факт выделен)

Замечания

  1. FAR перед созданием диалога преобразует элементы Item во внутреннее представление. После завершения работы диалога массив элементов Item корректируется с учетом изменений, произошедших в процессе работы пользователя с этим диалогом.
  2. Начиная с версии 1.71 build 2451 "маленькие" диалоги (флаг FDLG_SMALLDIALOG) рисуются с тенью. Чтобы запретить рисовать тень в таких диалогах, укажите флаг FDLG_NODRAWSHADOW.

Пример

  int ExitCode=Info.DialogEx(Info.ModuleNumber,
                  -1,-1,76,10,
                  "TempCfg",DialogItems,
                  sizeof(DialogItems)/sizeof(DialogItems[0]),
                  0,0,
                  DlgProc,0);
  if (ExitCode != 7)
    return(FALSE);
Смотрите также:
Dialog, DefDlgProc, SendDlgMessage, сервисные функции, Message, InitDialogItems


DlgProc

главная | Dialog API | События и сообщения
В плагине обработку событий и посылку сообщений для диалога должна выполнять Функция-Обработчик диалога. Эта функция имеет четыре параметра: дескриптор диалога, описывающий сам диалог, собственно сообщение или событие и пара параметров.

Здесь представлен синтаксис функции обработки диалога, каким он должен быть в плагине.

LONG_PTR WINAPI DlgProc(
  HANDLE hDlg,
  int    Msg,
  int    Param1,
  LONG_PTR Param2
);

Параметры

hDlg
Дескриптор диалога
Msg
Одно из сообщений или событий.
Param1
Параметр 1
Param2
Параметр 2

Возвращаемое значение

Значение, возвращаемое функцией DlgProc зависит от параметра Msg.

Замечания

Иногда информация, содержащаяся в Param1 и Param2, может состоять из двух частей, которые размещаются в двух 16-разрядных словах, составляющих каждый из этих параметров. Для обеспечения доступа к каждой части Param1 и Param2 в Windows определены два макроса - LOWORD и HIWORD . Они возвращают соответственно стершее и младшее слова длинного целого.

Пример

Фрагмент обработчика диалога игры Reversi:
LONG_PTR WINAPI ReversiDialogProc(HANDLE hDlg, int Msg,int Param1,LONG_PTR Param2)
{
  struct FarDialogItem DialogItem;
  struct FarListItem *ListItems;
  int i;

  switch(Msg)
  {
    case DN_INITDIALOG:
      // получим информацию об элементе
      Info.SendDlgMessage(hDlg,DM_GETDLGITEM,75,(LONG_PTR)&DialogItem);
      ListItems=DialogItem.ListItems->Items;
      ...
      NewGame(hDlg);
      return FALSE;

    case DN_HELP:
    {
      // В зависимости от хода игры покажем разные разделы из помощи
      static char *Help[3]={"Contents","Rule","Recommendations"};
      if(NumPl1==2 && NumPl2 == 2)
        i=0;
      else if(NumPl1+NumPl2 > 16)
        i=2;
      else
        i=1;
      return (LONG_PTR)(Help[i]);
    }
    ...

    case DM_CLOSE:
      // проверим, на каком элементе пользователь хочет
      // закрыть диалог
      if(Param1 != 10 && Param1 > 0)
        return FALSE;  // нельзя закрыть
      break;
  }

  // остальными событиями и сообщениями пусть занимается
  // Менеджер Диалогов
  return Info.DefDlgProc(hDlg,Msg,Param1,Param2);
}
Смотрите также:
DefDlgProc, DialogEx, SendDlgMessage


InputBox

главная | сервисные функции
Функция InputBox позволяет ввести одну строку текста.
int WINAPI InputBox(
  const char *Title,
  const char *Prompt,
  const char *HistoryName,
  const char *SrcText,
  char *DestText,
  int   DestLength,
  const char *HelpTopic,
  DWORD Flags
);

Параметры

Title
Заголовок окна ввода. Может быть равен NULL или "".
Prompt
Приглашение на ввод данных. Может быть равен NULL или "".
HistoryName
Адрес строки для "истории". Установите в NULL если "история" ввода не используется.
SrcText
Исходные данные для ввода и редактирования. Может быть равен NULL или "".
DestText
"Приемник" введенных данных. Может указать на ту же область памяти что и SrcText.
DestLength
Размер "приемника"
HelpTopic
Адрес строки с названием темы помощи в формате "<FullPath>Topic", например:
"<D:\\FAR\\Plugins\\Foo\\>FooInfo"

Установите в NULL если подсказка не используется.
Flags
Может быть комбинацией следующих значений (перечисленние INPUTBOXFLAGS):
Константа | Описание
FIB_ENABLEEMPTY | даже если строка ввода пуста функция вернет значение TRUE.
FIB_PASSWORD | используется для ввода пароля - вводимый текст на экране отрисовывается символами '*'.
FIB_EXPANDENV | после успешного ввода, в строке DestText идентификаторы переменных окружения заменяются на их значения, например, если пользователь ввел '%TEMP%', то DestText будет содержать 'C:\TEMP'.
FIB_NOUSELASTHISTORY | не использовать предыдущее значение из истории, оставить строку ввода пустой; актуален, если параметр HistoryName не равен NULL.
FIB_BUTTONS | показать разделительную линию и кнопки [Ok] и [Cancel]. Диалог увеличится на 2 строки.
FIB_NOAMPERSAND | не показывать в приглашении ввода амперсанд, использовать его для определения горячей клавиши.

Возвращаемое значение

Функция возвращает TRUE в случае успешного ввода строки и FALSE, если пользователь прервал ввод.

Замечания

FAR Manager использует данную функцию, когда пользователь пытается создать папку:

Пример

Смотрите также:
Dialog


Message

главная | сервисные функции
Функция Message показывает сообщение.
int WINAPI Message(
  int PluginNumber,
  DWORD Flags,
  const char *HelpTopic,
  const char * const *Items,
  int ItemsNumber,
  int ButtonsNumber
);

Параметры

PluginNumber
Номер плагина. Его вы получаете в функции SetStartupInfo.
Flags
Может быть комбинацией следующих значений (перечисление FARMESSAGEFLAGS):
Флаг | Описание
FMSG_WARNING | Используются цвета "Предупреждения" (обычно белые буквы на красном фоне).
FMSG_ERRORTYPE | Если тип ошибки, возвращаемый функцией GetLastError , известен FAR'у или Windows, то описание ошибки будет показано в первых строках сообщения. При этом строки, переданные плагином в функцию, сдвинутся вниз.
FMSG_KEEPBACKGROUND | Не перерисовывать фон сообщения.
FMSG_DOWN | Показать сообщение двумя строками ниже.
FMSG_LEFTALIGN | Использовать для строк сообщения выравнивание влево (по умолчанию строки выводятся по центру).
FMSG_ALLINONE В этом случае параметра Items не является массивом указателей на строки - это УКАЗАТЕЛЬ на одну строку, в которой разделителем выводимых строк является символ '\n'.

Минимальное количество строк - 2 - заголовок и одна строка сообщения.

При указании флага FMSG_ALLINONE параметр ItemsNumber игнорируется и количество выводимых строк вычисляется автоматически (с учетом флагов-кнопок FMSG_MB_*).

Для подавления вывода заголовка при использовании флага FMSG_ALLINONE начните строку с символа '\n'.

FMSG_MB_OK | Дополнительно выводится кнопка <Ok>
FMSG_MB_OKCANCEL | Дополнительно выводятся кнопки <Ok> и <Cancel>
FMSG_MB_ABORTRETRYIGNORE | Дополнительно выводятся кнопки <Abort>, <Retry> и <Ignore>
FMSG_MB_YESNO | Дополнительно выводятся кнопки <Yes> и <No>
FMSG_MB_YESNOCANCEL | Дополнительно выводятся кнопки <Yes>, <No> и <Cancel>
FMSG_MB_RETRYCANCEL | Дополнительно выводятся кнопки <Retry> и <Cancel>
HelpTopic
Тема подсказки в файле помощи связанная с сообщением. Установите это значение в NULL если подсказка не требуется.
Items
Адрес массива с указателями на ASCIIZ строки. Первая строка - заголовок сообщения, последние ButtonsNumber строк - кнопки, все остальные строки принадлежат телу сообщения.
Для отрисовки одинарной разделительной линии начните строку с символа с кодом 1 (\x001).
Для отрисовки двойной разделительной линии начните строку с символа с кодом 2 (\x002).
Смотрите также описание флага FMSG_ALLINONE.
ItemsNumber
Количество указателей в массиве Items. Минимальное значение - 2 строки.
ButtonsNumber
Количество заключительных строк, которые будут использоваться в качестве кнопок. При указании флагов FMSG_MB_* параметр ButtonsNumber игнорируется.

Возвращаемое значение

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

Замечания

  1. До FAR Manager 1.70 beta 4 суммарное количество элементов сообщения (строк и кнопок) не могло превышать 13.
  2. Если ButtonsNumber равен 0 (флаги FMSG_MB_* не используются) и выведенное сообщение больше не нужно, то плагин должен восстановить экран, используя функцию RestoreScreen или любым другим путем.
  3. Если ButtonsNumber не равен 0, то экран восстанавливает сам FAR.
  4. Диалог не выводится, если в качестве Items указан NULL или количество элементов меньше двух.
  5. При указании флагов-кнопок FMSG_MB_* параметр ButtonsNumber игнорируется.
  6. Кнопки могут иметь горячие клавиши.
  7. При использовании флага FMSG_ALLINONE для корректной компиляции кода необходимо произвести явное преобразование типов:
    Info.Message(Info.ModuleNumber,
  FMSG_ALLINONE|FMSG_MB_OKCANCEL,
  "HelpTopic",
  (const char * const *)"Title\nItem1\nItem2\nItem3",
  0,0);
    или
    const char *Msg="Title\nItem1\nItem2\nItem3\nOk\nCancel";
Info.Message(Info.ModuleNumber,
  FMSG_ALLINONE,
  "HelpTopic",
  (const char * const *)Msg,
  0,2);

Пример

Следующая функция выводит на экран диалог-подтверждение на удаление файла:
диалог-подтверждение на удаление файла
BOOL IsDeleted(char *filename)
{
  const char *Msg[5];

  Msg[0]=GetMsg(MTitle);       // заголовок сообщения
  Msg[1]=GetMsg(MIsDeleted);   // тело сообщения
  Msg[2]=filename;
  Msg[3]=GetMsg(MDelete);      // последние ButtonsNumber (2) строк - кнопки
  Msg[4]=GetMsg(MCancel);

  return Info.Message(Info.ModuleNumber,
               0,
               "DeleteFile",
               Msg,
               sizeof(Msg)/sizeof(Msg[0]),
               2) == 0;
}
Причем, Info определяется как глобальная переменная:
struct PluginStartupInfo Info;
...а инициализируется она в функции SetStartupInfo:
void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info)
{
  ...
  ::Info=*Info;
  ...
}
Смотрите также:
Dialog


SendDlgMessage

главная | Dialog API Сообщения
Функция SendDlgMessage позволяет послать сообщение функции-обработчику диалога.
LONG_PTR WINAPI SendDlgMessage(
  HANDLE hDlg,
  int    Msg,
  int    Param1,
  LONG_PTR Param2
);

Параметры

hDlg
Указатель на диалог
Msg
Одно из сообщений DM_*
Param1
Параметр 1
Param2
Параметр 2

Возвращаемое значение

Значение, возвращаемое функцией SendDlgMessage зависит от параметра Msg.

Замечания

Пример

Фрагмент обработчика диалога игры Reversi:
LONG_PTR WINAPI ReversiDialogProc(HANDLE hDlg, int Msg,int Param1,LONG_PTR Param2)
{
...
    case DN_INITDIALOG:
      // получим информацию об элементе
      Info.SendDlgMessage(hDlg,DM_GETDLGITEM,75,(LONG_PTR)&DialogItem);
      ListItems=DialogItem.ListItems->Items;
      ...
      NewGame(hDlg);
      return FALSE;
...
}
Смотрите также:
DialogEx, DefDlgProc


FarStandardFunctions

главная | структуры | TFarStandardFunctions
Структура FarStandardFunctions содержит указатели на полезные функции используемые в Far.exe
struct FarStandardFunctions
{
  int StructSize;

  FARSTDATOI                 atoi;
  FARSTDATOI64               atoi64;
  FARSTDITOA                 itoa;
  FARSTDITOA64               itoa64;
  FARSTDSPRINTF              sprintf;
  FARSTDSSCANF               sscanf;
  FARSTDQSORT                qsort;
  FARSTDBSEARCH              bsearch;
  FARSTDQSORT                qsortex;
  FARSTDSNPRINTF             snprintf;

  DWORD_PTR                  Reserved[8];

  FARSTDLOCALISLOWER         LIsLower;
  FARSTDLOCALISUPPER         LIsUpper;
  FARSTDLOCALISALPHA         LIsAlpha;
  FARSTDLOCALISALPHANUM      LIsAlphanum;
  FARSTDLOCALUPPER           LUpper;
  FARSTDLOCALLOWER           LLower;
  FARSTDLOCALUPPERBUF        LUpperBuf;
  FARSTDLOCALLOWERBUF        LLowerBuf;
  FARSTDLOCALSTRUPR          LStrupr;
  FARSTDLOCALSTRLWR          LStrlwr;
  FARSTDLOCALSTRICMP         LStricmp;
  FARSTDLOCALSTRNICMP        LStrnicmp;

  FARSTDUNQUOTE              Unquote;
  FARSTDEXPANDENVIRONMENTSTR ExpandEnvironmentStr;
  FARSTDLTRIM                LTrim;
  FARSTDRTRIM                RTrim;
  FARSTDTRIM                 Trim;
  FARSTDTRUNCSTR             TruncStr;
  FARSTDTRUNCPATHSTR         TruncPathStr;
  FARSTDQUOTESPACEONLY       QuoteSpaceOnly;
  FARSTDPOINTTONAME          PointToName;
  FARSTDGETPATHROOT          GetPathRoot;
  FARSTDADDENDSLASH          AddEndSlash;
  FARSTDCOPYTOCLIPBOARD      CopyToClipboard;
  FARSTDPASTEFROMCLIPBOARD   PasteFromClipboard;
  FARSTDKEYTOKEYNAME         FarKeyToName;
  FARSTDKEYNAMETOKEY         FarNameToKey;
  FARSTDINPUTRECORDTOKEY     FarInputRecordToKey;
  FARSTDXLAT                 XLat;
  FARSTDGETFILEOWNER         GetFileOwner;
  FARSTDGETNUMBEROFLINKS     GetNumberOfLinks;
  FARSTDRECURSIVESEARCH      FarRecurseSearch;
  FARSTDMKTEMP               MkTemp;
  FARSTDDELETEBUFFER         DeleteBuffer;
  FARSTDPROCESSNAME          ProcessName;
  FARSTDMKLINK               MkLink;
  FARCONVERTNAMETOREAL       ConvertNameToReal;
  FARGETREPARSEPOINTINFO     GetReparsePointInfo;
};

Элементы

Сообщение | Описание
StructSize | Размер структуры. Если в будущем будут добавлены новые поля в структуре, это поле позволит определить данный факт.
atoi | конвертирует строку в целое число типа int (32-битное целое).
atoi64 | конвертирует строку в целое число типа __int64 (64-битное целое).
itoa | конвертирует целое число типа int (32-битное целое) в строку.
itoa64 | конвертирует целое число типа __int64 (64-битное целое) в строку.
sprintf | осуществляет форматированный вывод в строку.
sscanf | осуществляет форматированный ввод из строки.
qsort | осуществляет сортировку данных с использованием алгоритма QuickSort.
bsearch | осуществляет двоичный поиск в массиве.
qsortex | осуществляет сортировку данных с использованием алгоритма QuickSort.
snprintf | осуществляет форматированный вывод в строку с заданным размером.
LIsLower | проверяет, является ли символ с указанным кодом буквой в нижнем регистре.
LIsUpper | проверяет, является ли символ с указанным кодом буквой в верхнем регистре.
LIsAlpha | проверяет, является ли символ с указанным кодом буквой.
LIsAlphanum | проверяет, является ли символ с указанным кодом буквой или цифрой.
LUpper | преобразует символ в верхний регистр.
LLower | преобразует символ в нижний регистр.
LUpperBuf | преобразует массив символов указанной длины, (который может содержать нулевые символы) в верхнем регистр.
LLowerBuf | преобразует массив символов указанной длины, (который может содержать нулевые символы) в нижний регистр.
LStrupr | преобразует строку, оканчивающуюся нулем, в верхний регистр.
LStrlwr | преобразует строку, оканчивающуюся нулем, в нижний регистр.
LStricmp | сравнивает две строки без учета регистра.
LStrnicmp | сравнивает части двух строк без учета регистра.
Unquote | убирает из строки все двойные кавычки.
ExpandEnvironmentStr | заменяет в строке ссылки на переменные окружения на их значения.
LTrim | удаляет ведущие пробелы в строке.
RTrim | удаляет конечные пробелы в строке.
Trim | удаляет ведущие и конечные пробелы в строке.
TruncStr | усекает указанную строку до требуемой длины и вставляет в начало строки многоточие вместо отрезанной части.
TruncPathStr | усекает указанный путь до требуемого размера и вставляет при надобности многоточие вместо отрезанной части.
QuoteSpaceOnly | заключает строку в кавычки, если она содержит хотя бы один пробел.
PointToName | используется для получения указателя на имя файла в данном имени файла с путем.
GetPathRoot | используется для получения имени корневого каталога из указанного пути.
AddEndSlash | добавляет к строке обратный слеш.
CopyToClipboard | копирует текстовую строку в буфер обмена Windows.
PasteFromClipboard | используется для получения данных из буфера Windows.
FarKeyToName | конвертирует код клавиши во внутреннем формате FAR Manager в строку.
FarNameToKey | преобразует символьное представление клавиши во внутренний формат клавиши FAR Manager.
FarInputRecordToKey | конвертирует код клавиши из INPUT_RECORD во внутренний формат представления клавиш FAR'а.
XLat | используется для конвертирования части строки из одного набора символов (например Русский) в другой (например Латиница).
GetFileOwner | используется для определения владельца указанного файла.
GetNumberOfLinks | возвращает количество жестких связей для заданного файла.
FarRecursiveSearch | осуществляет рекурсивный поиск файлов.
MkTemp | создает имя временного файла на основе шаблона.
DeleteBuffer | используется для освобождения памяти, запрошенной функцией PasteFromClipboard.
ProcessName | позволяет обработать некое имя файла: сравнить с маской, с масками или сгенерировать по маске новое имя.
MkLink | создает жесткие и символические связи, а также монтирует локальные диски на файловую систему.
ConvertNameToReal | преобразует относительное имя файлового объекта в полное с учетом символических связей (т.н. reparse point в Windows 2000) и текущего каталога.
GetReparsePointInfo | позволяет для указанной символической связи получить информацию об источнике - путь к исходному каталогу/диску.

Замечания

Сохраните содержимое структуры в локальное пространство плагина:

static struct PluginStartupInfo Info;
static struct FarStandardFunctions FSF;

void  _export SetStartupInfo(struct PluginStartupInfo *psInfo)
{
    Info=*psInfo;
    FSF=*psInfo->FSF;
    Info.FSF=&FSF; // скорректируем адрес в локальной структуре
    ...
}
Смотрите также:


FSF.AddEndSlash

AddEndSlash

главная | FarStandardFunctions
Функция FSF.AddEndSlash добавляет к строке обратный слеш.
int WINAPI AddEndSlash(
  char *Path
);

Параметры

Path
Указатель на обрабатываемую строку.

Возвращаемое значение

TRUE - при успешном добавлении/преобразовании строки Path.
FALSE - если в качестве параметра Path передали значение NULL.

Примечание

  1. Строка должна иметь достаточный объем, чтобы поместить в нее еще один символ.
  2. Функция работает с обоими видами слешей - прямым и обратным.
  3. Также происходит изменение уже существующего конечного слеша на тот, который чаще встречается в строке Path.
  4. Если в конце строки уже содержится обратный слеш, то еще один слеш в конец не добавляется.

Пример


FSF.atoi

atoi

главная | FarStandardFunctions
Функция FSF.atoi преобразует символьную строку в целое число типа int (32-битное целое).
int WINAPI atoi(
  const char *Str
);

Параметры

Str
Указатель на строку, содержащую строковое представление числа.

Возвращаемое значение

atoi возвращает преобразованное значение входной строки Str. Если строка не может быть преобразована, то функция возвращает 0.

Примечание

Символы в строке Str должны совпадать со следующим форматом:
[ws][sn][ddd] где
ws - табуляция и пробел
sn - знак числа - '+' или '-'
ddd - строка цифр - от '0' до '9'
Преобразование заканчивается, когда функция встречает первый "неправильный" символ. Проверка на переполнение не ведется (результат неопределенный).

Пример

Вы можете в программе описать указатель на функцию, инициализировать и использовать ее:
FARSTDATOI FarAtoi;
...
FarAtoi=Info.FSF->atoi;
...
I=FarAtoi(Str);
...или вызывать непосредственно:
I=Info.FSF->atoi(Str);
Смотрите также:


FSF.atoi64

atoi64

главная | FarStandardFunctions
Функция FSF.atoi64 конвертирует строку в целое число типа __int64 (64-битное целое).
__int64 WINAPI atoi64(
  const char *Str
);

Параметры

Str
Указатель на строку, содержащую строковое представление числа.

Возвращаемое значение

atoi64 возвращает преобразованное значение входной строки Str. Если строка не может быть преобразована, то функция возвращает 0i64.

Примечание

Символы в строке Str должны совпадать со следующим форматом:
[ws][sn][ddd] где
ws - табуляция и пробел
sn - знак числа - '+' или '-'
ddd - строка цифр - от '0' до '9'
Преобразование заканчивается, когда функция встречает первый "неправильный" символ. Проверка на переполнение не ведется (результат неопределенный).

Пример

Вы можете в программе описать указатель на функцию, инициализировать и использовать ее:
FARSTDATOI64 FarAtoi64;
...
FarAtoi64=Info.FSF->atoi64;
...
I_64=FarAtoi64(Str);
...или вызывать непосредственно:
I_64=Info.FSF->atoi64(Str);
Смотрите также:


FSF.bsearch

bsearch

главная | FarStandardFunctions
Функция FSF.bsearch осуществляет двоичный поиск в массиве.
void* WINAPI bsearch(
  const void *key,
  const void *base,
  size_t nelem,
  size_t width,
  int (__cdecl *fcmp)(const void *, const void *)
);

Параметры

key
Указатель на элемент, который хотим найти.
base
Указатель на начало данных для сортировки. Массив данных должен быть отсортирован.
nelem
Количество сортируемых данных.
width
Размер одного элемента сортируемых данных.
fcmp
Функция сравнения двух элементов. В процессе сортировки вызывается каждый раз, когда необходимо сравнить пару элементов данных. Функция сравнения fcmp должна иметь C-декларацию (_USERENTRY или _cdecl).
fcmp получает два аргумента - elem1 и elem2, которые являются указателями на данные, и возвращает результат:
*elem1 < *elem2 | - fcmp возвращает целое меньше 0
*elem1 == *elem2 | - fcmp возвращает 0
*elem1 > *elem2 | - fcmp возвращает целое больше 0

Возвращаемое значение

bsearch возвращает адрес первого вхождения в таблице base, которое соответствует ключу поиска key. Если значение не найдено, то функция возвращает 0.

Примечание

Более подробно о функции см. справочное руководство по языку C/C++.

Пример

Смотрите также:
FSF.qsort


FSF.ConvertNameToReal

ConvertNameToReal

главная | FarStandardFunctions
Функция FSF.ConvertNameToReal преобразует относительное имя файлового объекта в полное с учетом символических связей (т.н. reparse point в Windows 2000) и текущего каталога.
int WINAPI ConvertNameToReal(
  const char *Src,
  char *Dest,
  int DestSize
);

Параметры

Src
Источник данных - полное или относительное имя файла/каталога.
Dest
Строка назначения, сюда будет помещен полный путь. Может быть равна NULL.
DestSize
Размер принимаемых данных. Если Dest=NULL, то параметр DestSize игнорируется.

Возвращаемое значение

Реальный размер полного пути, размещенного в Dest или требуемый размер строки для случая, когда Dest=NULL.
  • Для монтированных дисков, которые не имеют буквы диска, функция поместит в Dest строку, подобную этой: "\\?\Volume{273872e0-5e49-11d5-b614-0080ad70bb9b}\Foo.bar"
  • Если, например, каталог "D:\Foo\Bar" является симлинком для реально существующего "C:\work\Doc", то функция для файла "D:\Foo\Bar\1092\readme.txt" вернет "C:\work\Doc\1092\readme.txt"

Примечание

  1. Функция корректно определяет "реальный" путь только в Windows 2000 и выше. Это связано с тем, что в OS ниже рангом невозможно определить реальное имя симлинка (если таковой присутствует в компоненте пути).
  2. Параметры Src и Dest могут ссылаться на одну и ту же строку.

Пример


FSF.CopyToClipboard

CopyToClipboard

главная | FarStandardFunctions
Функция FSF.CopyToClipboard копирует текстовую строку в буфер обмена Windows.
int WINAPI CopyToClipboard(
  const char *Data
);

Параметры

Data
Указатель на строку, которую нужно поместить в буфер обмена.

Возвращаемое значение

В случае успеха возвращается TRUE, иначе - FALSE.

Примечание

См. ЧАВО:"А что за дупы в клипборде..."

Пример


FSF.DeleteBuffer

DeleteBuffer

главная | FarStandardFunctions
Функция FSF.DeleteBuffer используется для освобождения памяти, запрошенной функцией PasteFromClipboard.
void WINAPI DeleteBuffer(
  void *Buffer
);

Параметры

Buffer
Указатель на освобождаемый буфер.

Возвращаемое значение

Нет.

Примечание

Смысл введения этой функции в следующем: память распределяется ФАРом, соответственно и освобождаться должна ФАРом.

Пример


FSF.ExpandEnvironmentStr

ExpandEnvironmentStr

главная | FarStandardFunctions
Функция FSF.ExpandEnvironmentStr заменяет в строке ссылки на переменные окружения на их значения.
DWORD WINAPI ExpandEnvironmentStr(
  const char *Src,
  char *Dest,
  size_t Size
);

Параметры

Src
Указатель на оканчивающуюся нулем строку, которая может содержать ссылки на переменные окружения в виде %VariableName%.

Для каждой такой ссылки, подстрока %VariableName% заменяется текущим значением соответствующей переменной окружения. Замена производится по тем же правилам, которые использует интерпретатор командной строки (command.com или cmd.exe). Регистр названий переменных окружения игнорируется. Если переменной окружения с таким названием не найдено, строка %VariableName% сохраняется без изменений.

Dest
Указатель на буфер, в который будет записан результат. Может указывать на Src.
Size
Указывает максимально количество символов, которые могут быть записаны в буфер (Dest), включая заключительный нулевой символ.

Возвращаемое значение

Функция возвращает количество символов, которые были записаны в буфер. В случае неудачи расширения переменных среды, в Dest будет скопировано до (Size-1) символов из Src.

Примечание

  1. Данная функция является "оберткой" для функции ExpandEnvironmentStrings из win32 api, поэтому подробности смотрите там.
  2. В отличие от ExpandEnvironmentStrings функция FSF.ExpandEnvironmentStr всегда заполняет буфер Dest.
  3. Функция манипулирует строками (Src и Dest) в OEM-кодировке.


FSF.FarInputRecordToKey

FarInputRecordToKey

главная | FarStandardFunctions
Функция FSF.FarInputRecordToKey конвертирует код клавиши из INPUT_RECORD во внутренний формат представления клавиш FAR'а.
int WINAPI FarInputRecordToKey(
  INPUT_RECORD *Rec
);

Параметры

Rec
Указатель на обрабатываемую структуру INPUT_RECORD.

Возвращаемое значение

Возвращается код клавиши в формате FAR.

Примечание

Пример


FSF.FarKeyToName

FarKeyToName

главная | FarStandardFunctions
Функция FSF.FarKeyToName конвертирует код клавиши, представленной во внутреннем формате FAR Manager, в строку.
BOOL WINAPI FarKeyToName(
  int Key,
  char *KeyText,
  int Size
);

Параметры

Key
Код клавиши во внутреннем формате FAR.
KeyText
Указатель на строку, куда будет помещен результат преобразования.
Size
Максимальное количество символов, которое можно поместить в KeyText, без заключительного нуля, или 0 для копирования всей получаемой строки.

Возвращаемое значение

В случае успеха возвращается TRUE. Если код клавиши (Key) не известен FAR Manager, то возвращается FALSE.

Примечание

Если вы передали 0 в качестве Size, то размер KeyText должен быть не меньше 32 байтов.


FSF.FarNameToKey

FarNameToKey

главная | FarStandardFunctions
Функция FSF.FarNameToKey преобразует символьное представление клавиши во внутренний формат клавиши FAR Manager.
int WINAPI FarNameToKey(
  const char *Name
);

Параметры

Name
Символьное представление клавиши.

Возвращаемое значение

В случае успеха возвращается код клавиши во внутреннем формате FAR Manager, иначе (Name не известно FAR) возвращается -1.

Примечание

  1. Если в комбинации клавиш присутствует Ctrl или Alt и клавиша - "буква", то "буква" принудительно приводится к верхнему регистру. Например, FarNameToKey("CtrlAltz") вернет KEY_CTRLALTZ.
  2. Если в комбинации клавиш присутствует Ctrl или Alt и клавиша - "буква национального алфавита", то "буква" принудительно заменяется на клавиатурный эквивалент и приводится к верхнему регистру. Например, FarNameToKey("CtrlУ") вернет KEY_CTRLE.
  3. Комбинации клавиш Shift-"буква" преобразуется к "БУКВА" (т.е. удаляется компонента Shift и "буква" переводится в верхний регистр).


FSF.FarRecursiveSearch

FarRecursiveSearch

главная | FarStandardFunctions
Функция FSF.FarRecursiveSearch осуществляет рекурсивный поиск файлов.
void WINAPI FarRecursiveSearch(
  const char *InitDir,
  const char *Mask,
  FRSUSERFUNC UserFunc,
  DWORD Flags,
  void *Param
);

Параметры

InitDir
Указывает на каталог, откуда начинается поиск, например "c:\far\plugins"
Mask
Указывает на маску файлов. Маска файла может быть стандартного ФАРовского вида.
UserFunc
Указывает на функцию типа FRSUSERFUNC, которая будет вызываться для каждого найденного файла. Функция должна вернуть TRUE для продолжения поиска файлов, или FALSE для окончания поиска.
Flags
Указывает на необходимое действие. Может быть следующим (перечисление FRSMODE):
Флаг | Описание
FRS_RETUPDIR | По окончании поиска параметр FullName функции UserFunc будет содержать имя каталога, в котором обнаружен заданный файл.
FRS_RECUR | Поиск заданного файла в дереве каталогов.
FRS_SCANSYMLINK | Позволяет искать файлы в символических связях наравне с обычными подкаталогами. Если при помощи символических связей в файловой системе образованы рекурсивные кольца (например, символическая связь указывает на один из собственных родительских каталогов), поиск будет идти до достижения максимально допустимой длины полного пути файлов.
Param
Указатель на данные пользователя, FAR его никак не обрабатывает, просто передает в UserFunc.

Возвращаемое значение

См. описание параметра Flags

Замечания

  1. Если хотите использовать данные, переданные функции UserFunc по окончании поиска, вы должны скопировать эти данные во внутренние переменные.
  2. Для FAR вплоть до 1.70 beta 3: Для перечисления всех файлов задайте маску файла Mask равную "*".
  3. Для FAR вплоть до 1.70 beta 3: При рекурсивном поиске каталоги, в которых производится поиск, тоже определяются на основании параметра Mask. Поэтому в большинстве случаев при рекурсивном поиске следует указывать маску "*" и в callback-функции при помощи функции CmpName определять, соответствует ли файл критериям поиска.
  4. Если флаг FRS_SCANSYMLINK не указан, то независимо от настроек FAR, символические связи обрабатываться не будут.


FSF.GetFileOwner

GetFileOwner

главная | FarStandardFunctions
Функция FSF.GetFileOwner используется для определения владельца указанного файла.
int WINAPI GetFileOwner(
  const char *Computer,
  const char *Name,
  char *Owner
);

Параметры

Computer
Имя компьютера, содержащего обрабатываемый файл. Если этот параметр равен NULL, то используется текущий компьютер.
Name
Имя файла, для которого нужно определить владельца.
Owner
Указатель на буфер, который получит имя владельца файла. Буфер должен иметь достаточный для хранения получаемой строки объем (минимальный размер буфера - NM)

Возвращаемое значение

В случае успеха возвращается TRUE, иначе - FALSE.

Примечание

Пример


FSF.GetNumberOfLinks

GetNumberOfLinks

главная | FarStandardFunctions
Функция FSF.GetNumberOfLinks возвращает количество жестких связей (hard links) для заданного файла.
int WINAPI GetNumberOfLinks(
  const char *Name
);

Параметры

Name
Имя требуемого файла.

Возвращаемое значение

В случае успеха функция возвращает количество жестких связей или 0. Для файловых систем, отличных от NTFS это значение всегда равно 1.
Смотрите также:
MkLink


FSF.GetPathRoot

GetPathRoot

главная | FarStandardFunctions
Функция FSF.GetPathRoot используется для получения имени корневого каталога из указанного пути.
void WINAPI GetPathRoot(
  const char *Path,
  char *Root
);

Параметры

Path
Обрабатываемый путь.
Root
Указатель на буфер, в который будет помещено имя корневого каталога.

Возвращаемое значение

Нет.

Примечание

Помните, что Root должен иметь достаточный размер, чтобы в нем поместилась получаемая строка:
  • Локальные диски - буква диска, двоеточие, слеш - C:\
  • Reparse point (на файловой системе NTFS 5 - Windows 2000) - нечто похожее на
    \\?\Volume{be877ec2-afd6-11d4-b5e3-806d6172696f}\ или
    \??\D:\
  • UNC-путь - имя хоста и имя расшаренного ресурса - \\host\share\

Пример


FSF.GetReparsePointInfo

GetReparsePointInfo

главная | FarStandardFunctions
Функция FSF.GetReparsePointInfo позволяет для указанной символической связи получить информацию об источнике - путь к исходному каталогу/диску.
int WINAPI GetReparsePointInfo(
  const char *Src,
  char *Dest,
  int DestSize
);

Параметры

Src
Источник данных. Строка должна содержать полное имя к символической связи и заканчиваться слешем ('\').
Dest
Строка назначения. Может быть равна NULL.
DestSize
Размер строки назначения Dest. Если Dest=NULL, то параметр DestSize игнорируется.

Возвращаемое значение

Реальный размер строки, размещенной в Dest или требуемый размер строки для случая, когда Dest=NULL.

0 - в случае ошибки:

  • функция не поддерживается (пользователь применил плагин, использующий функцию FSF.GetReparsePointInfo, не в Windows 2000)
  • неверный путь (выставляется системный номер ошибки ERROR_PATH_NOT_FOUND)
  • символическая связь находится на сетевом диске и в большинстве случаев случае реальное имя каталога, на который указывает связь, использовать невозможно.

Примечание

  1. Адреса Src и Dest могут совпадать.
  2. Функция работает только в Windows 2000 и выше.
  3. Возвращаемое функцией значение не несет никакой практической пользы для сетевых дисков.
  4. В отличии от ConvertNameToReal, функция FSF.GetReparsePointInfo применима только для симлинков.
  5. Некоторые замечания относительно понятия "Символическая связь" читайте здесь.

Пример


FSF.itoa

itoa

главная | FarStandardFunctions
Функция FSF.itoa конвертирует целое число типа int (32-битное целое) в строку.
char * WINAPI itoa(
  int Value,
  char *Str,
  int Radix);

Параметры

Value
Значение для конвертирования.
Str
Указатель на строку-приемник. Размер строки Str должен быть достаточно большим чтобы включать преобразованную строку (максимальное значение = 32 символа + символ конца строки '\0').
Radix
Определяет базу, которая должна использоваться при преобразовании числа Value. Допустимые значения от 2 до 36.

Возвращаемое значение

itoa указатель на строку-приемник.

Примечание

Если Value отрицательное число и Radix = 10, то первым символом строки будет знак минус '-'.

Пример

Вы можете в программе описать указатель на функцию, инициализировать и использовать ее:
FARSTDITOA FarItoa;
...
FarItoa=Info.FSF->itoa;
...
FarItoa(Value,Str,10);
...или вызывать непосредственно:
Info.FSF->itoa(Value,Str,10);
Смотрите также:


FSF.itoa64

itoa64

главная | FarStandardFunctions
Функция FSF.itoa64 конвертирует целое число типа __int64 (64-битное целое) в строку. Функция является аналогом стандартной RTL-функции _i64toa.
char * WINAPI itoa64(
  __int64 Value,
  char *Str,
  int Radix);

Параметры

Value
Значение для конвертирования.
Str
Указатель на строку-приемник. Размер строки Str должен быть достаточно большим чтобы включать преобразованную строку (максимальное значение = 64 символа + символ конца строки '\0').
Radix
Определяет базу, которая должна использоваться при преобразовании числа Value. Допустимые значения от 2 до 36.

Возвращаемое значение

itoa64 указатель на строку-приемник.

Примечание

Если Value отрицательное число и Radix = 10, то первым символом строки будет знак минус '-'.

Пример

Вы можете в программе описать указатель на функцию, инициализировать и использовать ее:
FARSTDITOA64 FarItoa64;
...
FarItoa64=Info.FSF->itoa64;
...
FarItoa64(Value64,Str,10);
...или вызывать непосредственно:
Info.FSF->itoa64(Value64,Str,10);
Смотрите также:


FSF.LIsAlpha

LIsAlpha

главная | FarStandardFunctions
Функция FSF.LIsAlpha проверяет, является ли символ с указанным кодом буквой. Функция работает с кодировкой OEM.
int WINAPI LIsAlpha(
  unsigned Ch
);

Параметры

Ch
Код символа для проверки.

Возвращаемое значение

Если указанный символ является буквой, то вернется TRUE, иначе - FALSE.

Примечание

Пример


FSF.LIsAlphanum

LIsAlphanum

главная | FarStandardFunctions
Функция FSF.LIsAlphanum проверяет, является ли символ с указанным кодом буквой или цифрой. Функция работает с кодировкой OEM.
int WINAPI LIsAlphanum(
  unsigned Ch
);

Параметры

Ch
Код символа для проверки.

Возвращаемое значение

Если указанный символ является буквой или цифрой, то вернется TRUE, иначе - FALSE.

Примечание

Пример


FSF.LIsLower

LIsLower

главная | FarStandardFunctions
Функция FSF.LIsLower проверяет, является ли символ с указанным кодом буквой в нижнем регистре. Функция работает с кодировкой OEM.
int WINAPI LIsLower(
  unsigned Ch
);

Параметры

Ch
Код символа для проверки.

Возвращаемое значение

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

Примечание

Пример


FSF.LIsUpper

LIsUpper

главная | FarStandardFunctions
Функция FSF.LIsUpper проверяет, является ли символ с указанным кодом буквой в верхнем регистре. Функция работает с кодировкой OEM.
int WINAPI LIsUpper(
  unsigned Ch
);

Параметры

Ch
Код символа для проверки.

Возвращаемое значение

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

Примечание

Пример


FSF.LLower

LLower

главная | FarStandardFunctions
Функция FSF.LLower преобразует символ в нижний регистр. Функция работает с кодировкой OEM.
unsigned WINAPI LLower(
  unsigned UpperChar
);

Параметры

UpperChar
Код символа для преобразования.

Возвращаемое значение

Возвращается преобразованный символ.

Примечание

Пример


FSF.LLowerBuf

LLowerBuf

главная | FarStandardFunctions
Функция FSF.LLowerBuf преобразует массив символов указанной длины, (который может содержать нулевые символы) в нижний регистр. Функция работает с кодировкой OEM.
void WINAPI LLowerBuf(
  char *Buf,
  int Length
);

Параметры

Buf
Указатель на обрабатываемый массив.
Length
Размер массива в байтах.

Возвращаемое значение

Нет.

Примечание

Пример


FSF.LStricmp

LStricmp

главная | FarStandardFunctions
Функция FSF.LStricmp сравнивает две строки без учета регистра. Функция работает с кодировкой OEM.
int WINAPI LStricmp(
  const char *Str1,
  const char *Str2
);

Параметры

Str1, Str2
Указатели на строки, которые вы хотите сравнить.

Возвращаемое значение

Функция возвращает:
-1 - если s1 < s2
1 - если s1 > s2
0 - если s1 == s2

Примечание

Пример


FSF.LStrlwr

LStrlwr

главная | FarStandardFunctions
Функция FSF.LStrlwr преобразует строку, оканчивающуюся нулем, в нижний регистр. Функция работает с кодировкой OEM.
void WINAPI LStrlwr(
  char *s1
);

Параметры

s1
Указатель на обрабатываемую строку.

Возвращаемое значение

Нет.

Примечание

Пример


FSF.LStrnicmp

LStrnicmp

главная | FarStandardFunctions
Функция FSF.LStrnicmp сравнивает части двух строк без учета регистра. Функция работает с кодировкой OEM.
int WINAPI LStrnicmp(
  const char *Str1,
  const char *Str2,
  int Num
);

Параметры

Str1, Str2
Указатели на строки, которые вы хотите сравнить.
Num
Размер части строки для сравнения.

Возвращаемое значение

Функция возвращает:
-1 - если s1 < s2
1 - если s1 > s2
0 - если s1 == s2

Примечание

Пример


FSF.LStrupr

LStrupr

главная | FarStandardFunctions
Функция FSF.LStrupr преобразует строку, оканчивающуюся нулем, в верхний регистр. Функция работает с кодировкой OEM.
void WINAPI LStrupr(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку.

Возвращаемое значение

Нет.

Примечание

Пример


FSF.LTrim

LTrim

главная | FarStandardFunctions
Функция FSF.LTrim удаляет ведущие пробелы в строке.
char* WINAPI LTrim(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку, которая оканчивается нулем. Результат работы будет помещен в нее же.

Возвращаемое значение

Указатель на результирующую строку.
Смотрите также:


FSF.LUpper

LUpper

главная | FarStandardFunctions
Функция FSF.LUpper преобразует символ в верхний регистр. Функция работает с кодировкой OEM.
unsigned WINAPI LUpper(
  unsigned LowerChar
);

Параметры

LowerChar
Код символа для преобразования.

Возвращаемое значение

Возвращается преобразованный символ.

Примечание

Пример


FSF.LUpperBuf

LUpperBuf

главная | FarStandardFunctions
Функция FSF.LUpperBuf преобразует массив символов указанной длины, (который может содержать нулевые символы) в верхнем регистр. Функция работает с кодировкой OEM.
void WINAPI LUpperBuf(
  char *Buf,
  int Length
);

Параметры

Buf
Указатель на обрабатываемый массив.
Length
Размер массива в байтах.

Возвращаемое значение

Нет.

Примечание

Пример


FSF.MkTemp

MkTemp

главная | FarStandardFunctions
Функция FSF.MkTemp создает имя временного файла на основе шаблона.
char* WINAPI MkTemp(
  char *Dest,
  const char *Prefix
);

Параметры

Dest
Указатель на буфер, который получит полное имя временного файла в верхнем регистре. Размер приемного буфера должен иметь достаточный размер для хранения результирующей строки (путь к каталогу для временных файлов + имя временного файла из 12 символов).
Prefix
Указывает на оканчивающуюся нулем строку-префикс. Максимум первые четыре символа из этой строки будут использованы в качестве префикса имени файла. FAR дополнит символами '0' префикс, если размер Prefix меньше 4.
Если Prefix равен NULL или пустой строке, то будет применен стандартный префикс "FTMP"

Возвращаемое значение

Указатель на Dest, содержащий имя временного файла в верхнем регистре, или NULL, в случае неудачи (не удалось создать уникального имени файла - возможно, что каталог для временных файлов %TEMP% содержит слишком много файлов, попробуйте очистить этот каталог).

Примечание

  1. Имя временного файла формируется объединением пути к временному каталогу (получаемого через вызов функции GetTempPath ), переданного префикса, набора случайных шестнадцатеричных цифр. Формат:

    PrefXXXP.PTT

    здесь
    Pref - 4-х символьный префикс;
    XXX - три 16-ричных цифры;
    PP - две 16-ричных цифры PID (результат функции GetCurrentProcessId );
    TT - две 16-ричных цифры TID (результат функции GetCurrentThreadId ).

  2. Функция, в отличии от FAR 1.70 beta 3, физически не создает файл на диске, только формирует имя.
  3. В FAR 1.70 beta 3 функция работала только с первыми тремя символами префикса.

Пример

char TempName[NM];

FSF.MkTemp(TempName,NULL);        -> "FTMP000D.P50"
FSF.MkTemp(TempName,"");          -> "FTMP000D.P50"
FSF.MkTemp(TempName,"MY");        -> "MY00000D.P50"
FSF.MkTemp(TempName,"BaR");       -> "BAR0000D.P50"
FSF.MkTemp(TempName,"TstPlugin"); -> "TSTP000D.P50"


FSF.MkLink

MkLink

главная | FarStandardFunctions
Функция FSF.MkLink создает жесткие и символические ссылки, связи каталогов, а также монтирует локальные диски на файловую систему. Функция работает только под Windows NT 4 и выше.
int WINAPI MkLink(
  const char *Src,
  const char *Dest,
  DWORD Flags
);

Параметры

Src
Имя файлового объекта, на который создаётся ссылка.
Dest
Имя создаваемой ссылки.
Flags
Тип операции. Одно из (перечисление MKLINKOP):
Операция | Описание
FLINK_HARDLINK | Создать жесткую ссылку (hardlink).
FLINK_JUNCTION | Создать связь каталогов (junction).
FLINK_VOLMOUNT | монтировать локальный диск на файловую систему.
FLINK_SYMLINKFILE | Создать символическую ссылку-файл.
FLINK_SYMLINKDIR | Создать символическую ссылку-каталог.

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

Флаг | Описание
FLINK_SHOWERRMSG | Выводить сообщения об ошибках.
FLINK_DONOTUPDATEPANEL | После создания связи не обновлять панели.

Возвращаемое значение

1 - ссылка создана.

0 - ошибка при создании ссылки:

  • Для жестких ссылок:
    • Src или Dest находятся на разных разделах;
    • раздел не NTFS;
    • раздел не локальный;
    • Src не существует или не является файлом.
    • Dest уже существует;
  • Для связей:
    • Src или Dest находятся не на локальных разделах;
    • раздел не NTFS 5.0;
    • Src не существует или не является каталогом;
    • Dest существует, но не пустой каталог.
  • Для монтирования дисков:
    • Src или Dest находятся не на локальных разделах;
    • раздел для Dest не NTFS 5.0;
    • Src не существует или диск является не локальным;
    • Dest существует, но не пустой каталог.

Примечание

  1. Ссылки создаются по следующим правилам:
    • жесткие ссылки (hardlink) создаются только для файлов в пределах текущего NTFS-раздела (NT4/Win2K/NTFS);
    • связи (junction) создаются только для каталогов в пределах локальных NTFS-разделов (Win2K/NTFS 5.0);
    • монтирование локальных дисков на файловую систему только на NTFS-раздел (Win2K/NTFS 5.0)
  2. Если в качестве Src было передано значение, например "C:", то вместо связи каталогов будет монтирован диск.
  3. Если для монтирования диска Dest оканчивается слешем, то в Dest будет создан каталог "disk_N" (где N - буква диска).
  4. В Windows 2000 напрямую делать связи на папки CD-ROM нельзя, но можно это ограничение обойти, смонтировав CD-ROM диск на папку NTFS-раздела (т.н. Mount Points). И уже из этой папки сделать нужную связь.

Пример

Смотрите также:
GetNumberOfLinks


FSF.PasteFromClipboard

PasteFromClipboard

главная | FarStandardFunctions
Функция FSF.PasteFromClipboard используется для получения данных из буфера Windows.
char* WINAPI PasteFromClipboard(void);

Параметры

Нет

Возвращаемое значение

Указатель на строку или NULL в случае ошибки.

Примечание

FAR сам распределяет необходимое количество памяти под строку. Главное не забыть удалить эту память используя функцию DeleteBuffer

Пример


FSF.PointToName

PointToName

главная | FarStandardFunctions
Функция FSF.PointToName используется для получения указателя на имя файла в данном имени файла с путем.
char *WINAPI PointToName(
  const char *Path
);

Параметры

Path
Обрабатываемое имя файла с путем.

Возвращаемое значение

Указатель на имя файла.

Примечание

Пример


FSF.ProcessName

ProcessName

главная | FarStandardFunctions | CmpName
Функция FSF.ProcessName позволяет обработать некое имя файла: сравнить с маской, с масками или сгенерировать по маске новое имя.
int WINAPI ProcessName(
  const char *Param1,
  char *Param2,
  DWORD Flags
);

Параметры

Param1
зависит от Flags
Param2
зависит от Flags
Flags
указывает на необходимое действие. Может быть следующим (перечисление PROCESSNAME_FLAGS):
Действие | Описание
PN_CMPNAME | сравнить имя файла с маской. Аналог CmpName: Param1 соответствует Pattern, Param2 соответствует String. В случае успеха возвращается TRUE.
PN_CMPNAMELIST | Сравнить имя файла со списком масок, перечисленных через запятую. Аналог предыдущего флага, только Param1 соответствует списку масок. Маски исключения не поддерживаются.
PN_SKIPPATH | Может сочетаться с PN_CMPNAME или PN_CMPNAMELIST - указывает на то, что путь к имени файла при сравнении должен игнорироваться.
PN_GENERATENAME | генерировать имя файла на основе существующего (Param1) и маски (Param2). Результат записывается в Param2. В случае успеха возвращается TRUE, иначе - FALSE. Если нужно преобразовать только часть Param1, то можно указать размер этой части (может быть до 255 байт) в Flags (добавить по принципу OR), например: Param1="dir1\\file1", а нам нужно изменить только "dir1", тогда параметр Flags должен быть равен PN_GENERATENAME|4

Возвращаемое значение

См. описание параметра Flags


FSF.qsort

qsort

главная | FarStandardFunctions
Функция FSF.qsort осуществляет сортировку данных с использованием алгоритма QuickSort.
void WINAPI qsort(
  void *Base,
  size_t NElem,
  size_t Width,
  int (__cdecl *fcmp)(const void *, const void *)
);

Параметры

Base
Указатель на начало данных для сортировки.
NElem
Количество сортируемых данных.
Width
Размер одного элемента сортируемых данных.
fcmp
Функция сравнения двух элементов. В процессе сортировки вызывается каждый раз, когда необходимо сравнить пару элементов данных. Функция сравнения fcmp должна иметь C-декларацию (_USERENTRY или _cdecl).
fcmp получает два аргумента - elem1 и elem2, которые являются указателями на данные, и возвращает результат:
*elem1 < *elem2 | - fcmp возвращает целое меньше 0
*elem1 == *elem2 | - fcmp возвращает 0
*elem1 > *elem2 | - fcmp возвращает целое больше 0

Возвращаемое значение

Нет.

Замечания

  1. Более подробно о функции см. справочное руководство по языку C/C++.
  2. Функция qsort() реализует нестабильную сортировку. Иными словами, порядок элементов, равных с точки зрения функции сравнения, не определён и может меняться при повторных сортировках уже отсортированного массива.

Пример

Смотрите также:
FSF.bsearch, FSF.qsortex


FSF.qsortex

qsortex

главная | FarStandardFunctions
Функция FSF.qsortex осуществляет сортировку данных с использованием алгоритма QuickSort.
void WINAPI qsortex(
  void *Base,
  size_t NElem,
  size_t Width,
  int (__cdecl *fcmp)(const void *, const void *, void *),
  void *User
);

Параметры

Base
Указатель на начало данных для сортировки.
NElem
Количество сортируемых данных.
Width
Размер одного элемента сортируемых данных.
fcmp
Функция сравнения двух элементов. В процессе сортировки вызывается каждый раз, когда необходимо сравнить пару элементов данных. Функция сравнения fcmp должна иметь C-декларацию (_USERENTRY или _cdecl).
fcmp получает три аргумента - elem1, elem2 (которые являются указателями на данные) и user (то, что было передано в функцию в качестве параметра User), и возвращает результат:
*elem1 < *elem2 | - fcmp возвращает целое меньше 0
*elem1 == *elem2 | - fcmp возвращает 0
*elem1 > *elem2 | - fcmp возвращает целое больше 0
User
Указатель на пользовательские данные, которые функция qsortex будет передавать в функцию сравнения fcmp в качестве третьего параметра.

Возвращаемое значение

Нет.

Примечание

Функция qsortex() реализует нестабильную сортировку. Иными словами, порядок элементов, равных с точки зрения функции сравнения, не определён и может меняться при повторных сортировках уже отсортированного массива.
Смотрите также:
FSF.bsearch, FSF.qsort


FSF.QuoteSpaceOnly

QuoteSpaceOnly

главная | FarStandardFunctions
Функция FSF.QuoteSpaceOnly заключает строку в кавычки, если она содержит хотя бы один пробел.
char* WINAPI QuoteSpaceOnly(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку.

Возвращаемое значение

Возвращается указатель на результирующую строку.

Примечание

  1. Помните, что Str должна иметь достаточный размер, чтобы вместить кавычки.
  2. Если строка уже заключена в кавычки - преобразования не происходит.
  3. Функция корректно добавляет недостающие кавычки в начало или в конец строки, если таковых нету.


FSF.RTrim

RTrim

главная | FarStandardFunctions
Функция FSF.RTrim удаляет конечные пробелы в строке.
char* WINAPI RTrim(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку, которая оканчивается нулем. Результат работы будет помещен в нее же.

Возвращаемое значение

Указатель на результирующую строку.
Смотрите также:
FSF.LTrim, FSF.Trim


FSF.snprintf

snprintf

главная | FarStandardFunctions
Функция FSF.snprintf осуществляет форматированный вывод в строку заданного размера.
int WINAPI snprintf(
  char *Buffer,
  size_t Sizebuf,
  const char *Format,
  ...
);

Параметры

Buffer
Приемник форматированных данных.
Sizebuf
Максимально-допустимый размер приемника форматированных данных.
Format
Указатель на строку, содержащую спецификаторы формата
...
Необязательные аргументы.

Возвращаемое значение

В случае успеха функция возвращает количество записанных в Buffer байт (символ конца строки в это количество не входит).
В случае ошибки возвращается EOF (-1)

Примечание

Более подробно о функции см. справочное руководство по языку C/C++.
Смотрите также:
FSF.sprintf


FSF.sprintf

sprintf

главная | FarStandardFunctions
Функция FSF.sprintf осуществляет форматированный вывод в строку.
int WINAPI sprintf(
  char *Buffer,
  const char *Format,
  ...
);

Параметры

Buffer
Приемник форматированных данных.
Format
Указатель на строку, содержащую спецификаторы формата
...
Необязательные аргументы.

Возвращаемое значение

В случае успеха функция возвращает количество записанных в Buffer байт (символ конца строки в это количество не входит).
В случае ошибки возвращается EOF (-1)

Примечание

Более подробно о функции см. справочное руководство по языку C/C++.
Delphi:
Используйте функцию format().
Подробнее смотрите описание функции в справочном руководстве по языку Object Pascal (Delphi).
Смотрите также:
FSF.snprintf


FSF.sscanf

sscanf

главная | FarStandardFunctions
Функция FSF.sscanf осуществляет форматированный ввод из строки.
int WINAPI sscanf(
  const char *Buffer,
  const char *Format,
  [address, ...]
);

Параметры

Buffer
Источник данных для ввода.
Format
Указатель на строку, содержащую спецификаторы формата
address
Адреса перемнных.

Возвращаемое значение

В случае успеха функция возвращает количество записанных полей. (символ конца строки в это количество не входит).
В случае ошибки возвращается 0 - ни одного поля не считано.

Примечание

Более подробно о функции см. справочное руководство по языку C/C++.


FSF.Trim

Trim

главная | FarStandardFunctions
Функция FSF.Trim удаляет ведущие и конечные пробелы в строке.
char* WINAPI Trim(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку, которая оканчивается нулем. Результат работы будет помещен в нее же.

Возвращаемое значение

Указатель на результирующую строку.
Смотрите также:
FSF.LTrim, FSF.RTrim


FSF.TruncPathStr

TruncPathStr

главная | FarStandardFunctions
Функция FSF.TruncPathStr усекает указанный путь до требуемого размера и вставляет при надобности многоточие вместо отрезанной части.
char* WINAPI TruncPathStr(
  char *Str,
  int MaxLength
);

Параметры

Str
Указатель на строку, содержащую путь. Результат работы будет помещен в нее же.
MaxLength
Размер, до которого нужно обрезать путь.

Возвращаемое значение

Указатель на результирующую строку.
Смотрите также:
FSF.TruncStr


FSF.TruncStr

TruncStr

главная | FarStandardFunctions
Функция FSF.TruncStr усекает указанную строку до требуемой длины и вставляет в начало строки многоточие вместо отрезанной части.
char* WINAPI TruncStr(
  char *Str,
  int MaxLength
);

Параметры

Str
Указатель на обрабатываемую строку. Результат работы будет помещен в нее же.
MaxLength
Размер, до которого нужно обрезать строку.

Возвращаемое значение

Указатель на результирующую строку.

Примечание

Пример

Смотрите также:
FSF.TruncPathStr


FSF.Unquote

Unquote

главная | FarStandardFunctions
Функция FSF.Unquote убирает из строки все двойные кавычки.
void WINAPI Unquote(
  char *Str
);

Параметры

Str
Указатель на обрабатываемую строку, которая оканчивается нулем. Результат работы будет помещен в нее же.

Возвращаемое значение

Нет.

Примечание

В версиях FAR с 1.70 beta 1 по beta 3 функция Unquote удаляла только первую и последнюю кавычки.


FSF.XLat

XLat

главная | FarStandardFunctions
Функция FSF.XLat используется для конвертирования части строки из одного набора символов (например, Русский) в другой (например, Латиница).
char* WINAPI XLat(
  char *Line,
  int StartPos,
  int EndPos,
  const struct CharTableSet *TableSet,
  DOWRD Flags
);

Параметры

Line
Указатель на строку, часть которой будет перекодирована.
StartPos
Начальная позиция в строке Line.
EndPos
Конечная позиция в строке Line.
TableSet
Если требуется преобразовать строку в OEM перед транслитерацией, а затем обратно, то это поле может содержать указатель на структуру CharTableSet. Этот параметр может быть равным NULL.
Flags
Может быть комбинацией следующих значений (перечисление XLATMODE):
Флаг | Описание
XLAT_SWITCHKEYBLAYOUT Переключает раскладку клавиатуры после обработки строки.

Внимание! Внимание!

  • Функция не переключает раскладку клавиатуры в Windows 95/98/Me.
XLAT_SWITCHKEYBBEEP | Выдать звуковой сигнал после переключения раскладки (работает если установлен флаг XLAT_SWITCHKEYBLAYOUT).

Возвращаемое значение

Эта функция возвращает указатель на преобразованную строку.


Структуры

главная

Структуры общего назначения:

Структура | Описание
ActlEjectMedia | извлечь диск
ActlKeyMacro | Macro-ориентированные операции
CharTableSet | таблица символов
CmdLineSelect | выделение или сброс выделения блока в командной строке
FarMenuItem | элемент меню
FarSetColors | изменение цветовой схемы FAR Manager
FarStandardFunctions | полезные функции из Far.exe
FARINT64 | используется для хранения 64-битного целого
KeySequence | описание последовательности кодов клавиш
OpenPluginInfo | информация об открытом экземпляре плагина
PluginInfo | информация о модуле плагина
PluginStartupInfo | различная важная информация
WindowInfo | информация об окне FAR Manager

Специфические структуры панели

Структура | Описание
InfoPanelLine | одна линия информационной панели
KeyBarTitles | переопределяет названия функциональных клавиш в полоске клавиш
PanelInfo | информация о панели Far'а
PanelMode | определяет режим просмотра панели
PanelRedrawInfo | используется при перерисовке панели
PluginPanelItem | информация об одном элементе в эмулируемой файловой системе

Специфические структуры редактора

Структура | Описание
EditorBookMarks | информация о закладках текущего редактируемого файла
EditorColor | установить или получить информацию о цветовых областях строк
EditorConvertPos | преобразование между реальным и экранным положением курсора в редакторе
EditorConvertText | преобразование текста между OEM и внутренней кодировкой редактора Far-а
EditorGetString | запрос строки из редактора
EditorInfo | текущее состояние редактора Far`а
EditorSaveFile | сохранение редактируемого файла
EditorSelect | выделение или сброс выделения блока в редакторе
EditorSetParameter | установка параметров редактора
EditorSetPosition | установка позиции в редакторе Far'а
EditorSetString | установка или вставка строки в редакторе

Специфические структуры Dialog API

Структура | Описание
FarDialogEvent | Информация о событии диалога
FarDialogItem | элемент диалога
FarDialogItemData | передача данных элементу диалога
FarList | список DI_LISTBOX
FarListColors | описывает цветовую схему для элементов DI_COMBOBOX и DI_LISTBOX
FarListDelete | параметры удаления элементов из DI_COMBOBOX и DI_LISTBOX
FarListFind | поиск элемента из DI_COMBOBOX и DI_LISTBOX
FarListGetItem | получение одного элемента списка из DI_COMBOBOX и DI_LISTBOX
FarListInfo | получить информацию о списках DI_COMBOBOX и DI_LISTBOX
FarListInsert | вставка элемента в DI_COMBOBOX и DI_LISTBOX
FarListItem | элемент списка
FarListPos | позиционирование в списке
FarListItemData | ассоциация данных с элементом списка
FarListTitles | установка/получение заголовков для списка
FarListUpdate | данные для обновления элемента списка
OpenDlgPluginData | Информация о диалоге, из которого вызван плагин, и выбранном пункте плагина

Специфические структуры программы просмотра

Структура | Описание
ViewerInfo | информации о текущем состоянии программы просмотра
ViewerMode | информация о режимах программы просмотра
ViewerSelect | выделение области в программе просмотра
ViewerSetPosition | изменение текущей позиции в файле
Смотрите также:
Экспортируемые функции, Сервисные функции, Dialog API, Поддержка архивов, Дополнения, Delphi-структуры, Win32 структуры


Структуры

Структуры - Структуры общего назначения

главная | структуры
Структура | Описание
ActlEjectMedia | извлечь диск
ActlKeyMacro | Macro-ориентированные операции
CharTableSet | таблица символов
CmdLineSelect | выделение или сброс выделения блока в командной строке
FARINT64 | используется для хранения 64-битного целого
FarMenuItem | элемент меню
FarSetColors | изменение цветовой схемы FAR Manager
FarStandardFunctions | полезные функции из Far.exe
KeySequence | описание последовательности кодов клавиш
OpenPluginInfo | информация об открытом экземпляре плагина
PluginInfo | информация о модуле плагина
PluginStartupInfo | различная важная информация
WindowInfo | информация об окне FAR Manager
Смотрите также:
Экспортируемые функции, Сервисные функции, Dialog API, Поддержка архивов, Дополнения, Delphi-структуры, Win32 структуры


ActlEjectMedia

главная | структуры
Структура ActlEjectMedia используется в функции AdvControl для извлечения диска из съемного накопителя (CD-ROM/USB/SUBST).
struct ActlEjectMedia {
  DWORD Letter;
  DWORD Flags;
};

Элементы

Letter
Буква диска съемного накопителя
Flags
Набор флагов (перечисление FAREJECTMEDIAFLAGS):
Флаг | Описание
EJECT_NO_MESSAGE | не выдавать сообщения об ошибках на экран
EJECT_LOAD_MEDIA | попытка "загрузить/закрыть" устройство (работает только для CD-ROM, не работает в Windows 95/98/Me)
Смотрите также:


ActlKeyMacro

главная | структуры
Структура ActlKeyMacro используется в функции AdvControl для операций с макрокомандами.
struct ActlKeyMacro {
  int Command;
  union{
    struct {
      char *SequenceText;
      DWORD Flags;
    } PlainText;
    DWORD Reserved[3];
  } Param;
};

Элементы

Command
Одна из команд (перечисление FARMACROCOMMAND):
Команда | Описание
MCMD_LOADALL | Считать из реестра в память FAR все макросы с затиранием предыдущих значений.
MCMD_POSTMACROSTRING Передать в FAR макрос в текстовом виде (в том виде, как их хранит FAR Manager в реестре).
Функция AdvControl возвращает TRUE - макрос проанализирован и помещены в очередь, и FALSE - ошибка (макропоследовательность содержит ошибки). Макропоследовательность начнет исполняться тогда, когда FAR получит управление.
MCMD_SAVEALL | Принудительное сохранение макросов из памяти FAR в реестр.
MCMD_GETSTATE Получить статус работы макродвижка.
Возвращает одно из значений (перечисление FARMACROSTATE):
Значение | Описание
MACROSTATE_NOMACRO | макродвижок не выполняет ни какой макрос в текущий момент
MACROSTATE_EXECUTING | идет исполнение макроса без передачи кодов клавиш в плагин
MACROSTATE_EXECUTING_COMMON | идет исполнение макроса; коды клавиш в плагин передаются
MACROSTATE_RECORDING | идет запись макроса без передачи кодов клавиш в плагин
MACROSTATE_RECORDING_COMMON | идет запись макроса; коды клавиш в плагин передаются
Компонента Param игнорируется. Значение возвращается функцией AdvControl.
Param.PlainText.SequenceText
Указатель на строку, содержащую макрос в текстовом виде. Макропоследовательность должна быть в OEM-кодировке. Этот член структуры используется для команды MCMD_POSTMACROSTRING.
Param.PlainText.Flags
Комбинация флагов исполнения макропоследовательности (перечисление FARKEYSEQUENCEFLAGS):
Флаг | Описание
KSFLAGS_DISABLEOUTPUT | Не отображать на экране результат работы каждой клавиши.
KSFLAGS_NOSENDKEYSTOPLUGINS | Не передавать клавиши редакторным плагинам (плагинам, экспортирующим функцию ProcessEditorInput).
KSFLAGS_REG_MULTI_SZ Параметр Param.PlainText.SequenceText представлен в формате REG_MULTI_SZ.
REG_MULTI_SZ в реестре:
строка 1\x00
строка 2\x00
...
строка N\x00
\x00
Этот член структуры используется для команды MCMD_POSTMACROSTRING.
Reserved
Зарезервировано.

Замечания

  1. Команды MCMD_LOADALL и MCMD_SAVEALL не будут исполняться во время записи или "проигрывания" макроса.
  2. Флаг KSFLAGS_REG_MULTI_SZ можно не указывать, если в Param.PlainText.SequenceText вместо 0x00 будут стоять '\n'.

Пример

Использование MCMD_POSTMACROSTRING в плагине FARCmds:
command.Command=MCMD_POSTMACROSTRING;
command.Param.PlainText.SequenceText=(char *)malloc(strlen(pCmd)+1);
if(command.Param.PlainText.SequenceText)
{
  command.Param.PlainText.Flags=KSFLAGS_DISABLEOUTPUT;
  strcpy(command.Param.PlainText.SequenceText,pCmd);
  Info.AdvControl(Info.ModuleNumber,ACTL_KEYMACRO,&command);
  free(command.Param.PlainText.SequenceText);
}
Использование MCMD_LOADALL в плагине FARCmds:
command.Command=MCMD_LOADALL;
Info.AdvControl(Info.ModuleNumber,ACTL_KEYMACRO,&command);
Использование MCMD_SAVEALL в плагине FARCmds:
command.Command=MCMD_SAVEALL;
Info.AdvControl(Info.ModuleNumber,ACTL_KEYMACRO,&command);
Смотрите также:


CharTableSet

главная | структуры
Структура CharTableSet содержит набор массивов, описывающих таблицы символов FAR. Передается в функцию CharTable.
struct CharTableSet
{
  unsigned char DecodeTable[256];
  unsigned char EncodeTable[256];
  unsigned char UpperTable[256];
  unsigned char LowerTable[256];
  char TableName[128];
};

Элементы

DecodeTable
Таблица для перекодировки из заданной кодовой страницы в OEM (DOS).
EncodeTable
Таблица для перекодировки из кодовой страницы OEM (DOS) в заданную.
UpperTable
Таблица для преобразования из нижнего регистра в верхний.
LowerTable
Таблица для преобразования из верхнего регистра в нижний.
TableName
Название кодовой страницы.
Смотрите также:


FARINT64

главная | Структуры
Тип FARINT64 используется для хранения 64-битного целого.
typedef union
{
  __int64 i64;
  struct
  {
    DWORD LowPart;
    LONG  HighPart;
  } Part;
} FARINT64;
Смотрите также:


CmdLineSelect

главная | структуры
Структура CmdLineSelect используется в функции Control для выделения или снятия выделения с текста в командной строке FAR'а, или для получения информации о выделении.
struct CmdLineSelect
{
  int SelStart;
  int SelEnd;
};

Элементы

SelStart
Начальная позиция выделения текста
SelEnd
Конечная позиция выделения текста

Замечания

Для снятия выделения установите SelStart и SelEnd в значение -1.
Смотрите также:
структуры | TCmdLineSelect | FCTL_GETCMDLINESELECTION | FCTL_SETCMDLINESELECTION.


FarMenuItem

главная | структуры
Структура FarMenuItem описывает один пункт меню. Массив этих структур передается в функцию Menu.
struct FarMenuItem
{
  char Text[128];
  int Selected;
  int Checked;
  int Separator;
};

Элементы

Text
Текст пункта меню.
Selected
Флаг активности пункта меню. Только один пункт может быть активным.
Checked
Если не равно нулю, перед текстом отображается метка выбора. Если Checked равно 1, то отображается стандартная метка, если больше 1 - значение Checked используется как символ метки.
Separator
Если не равно нулю, то пункт меню отображается как разделитель. Остальные компоненты структуры (например, Text) игнорируется.

Замечания

Поскольку переменная FarMenuItem.Text имеет большой размер, прямая инициализация массива FarMenuItem, может заметно увеличить потребление памяти. Для сокращения потребления памяти можно воспользоваться нестандартной структурой InitMenuItem.

Смотрите также:


FarMenuItemEx

главная | структуры | Menu
Структура FarMenuItemEx описывает один пункт меню. Массив этих структур передается в функцию Menu. Для использования структуры FarMenuItemEx необходимо установить флаг FMENU_USEEXT при вызове функции Menu.
struct FarMenuItemEx
{
  DWORD Flags;
  union {
    char  Text[128];
    const char *TextPtr;
  } Text;
  DWORD AccelKey;
  DWORD Reserved;
  DWORD_PTR UserData;
};

Элементы

Flags
Комбинация следующих значений (перечисление FARMENUFLAGS):
Флаг | Описание
MIF_SELECTED | Признак активности пункта меню. Только один пункт может быть активным.
MIF_CHECKED | Признак отмеченного пункта меню. Перед текстом будет отображаться метка выбора.
MIF_SEPARATOR | Пункт меню отображается как разделитель. В отличие от стурктуры FarMenuItem разделитель меню может содержать текст. Текст выравнивается по середине.
MIF_DISABLE | Пункт меню недоступен.
MIF_GRAYED | Если флаг установлен, то пункт меню доступен в навигации, но не доступен для выбора.
MIF_HIDDEN | Если флаг установлен, то пункт меню не выводится на экран.
MIF_USETEXTPTR | Пункт меню использует компоненту Text.TextPtr.
Text.Text
Текст пункта меню.
Text.TextPtr
Указатель на текст пункта меню. Применяется совместно с флагом MIF_USETEXTPTR, если размера компоненты Text.Text не хватает или используется строка из языкового файла, например:
struct FarMenuItemEx Item;
Item.Flags=MIF_USETEXTPTR;
Item.Text.TextPtr=Info.GetMsg(Info.ModuleNumber,MFooItem);
AccelKey
Код клавиши FAR Manager для активизации пункта меню. Пример работы - в меню "Commands" нажатие клавиши Ctrl-O аналогично выбору пункта "Panels On/Off". В отличие от параметра BreakKeys функции Menu компонента AccelKey аналогична клавише быстрого доступа (HotKey).
Reserved
Зарезервировано и должно быть рано 0.
UserData
Пользовательские данные, ассоциированные с пунктом меню. FAR Manager не использует это поле.

Замечания

  1. В младшем слове Flags можно указывать код символа, который будет использоваться для отображения метки выбора. В этом случае система самостоятельно выставит флаг MIF_CHECKED для данного пункта меню.
  2. Если младшее слово Flags равно 0 и выставлен флаг MIF_CHECKED, или если младшее слово Flags равно 1, то будет отображаться стандартная метка выбора - символ с кодом 0FBh (√)
  3. При использовании флага MIF_SEPARATOR без текста компонента Text.Text (или Text.TextPtr) должна быть проинициализирована в 0, например так:
    struct FarMenuItemEx Item;
Item.Flags=MIF_SEPARATOR;
Item.Text.Text[0]=0;
    или так:
    4. struct FarMenuItemEx Item;
Item.Flags=MIF_SEPARATOR|MIF_USETEXTPTR;
Item.Text.TextPtr=NULL;
Смотрите также:


FarSetColors

главная | структуры
Структура FarSetColors используется в функции AdvControl для изменения цветовой схемы FAR Manager.
struct FarSetColors {
  DWORD Flags;
  int StartIndex;
  int ColorItem;
  LPBYTE Colors;
};

Элементы

Flags
Комбинация флагов (перечисление FARCOLORFLAGS):
Флаг | Описание
FCLR_REDRAW | После изменений цветовой схемы обновить экран.
StartIndex
Начальная позиция индекса цветовой схемы для замены.
ColorItem
Количество позиций цветовой для замены.
Colors
Указатель на массив цветовой схемы - байтовый массив цветовых атрибутов.

Замечания

Смотрите также:


InfoPanelLine

главная | структуры
Структура InfoPanelLine описывает одну строку информационной панели. Массив этих структур передается в FAR функцией GetOpenPluginInfo.
struct InfoPanelLine
{
  char Text[80];
  char Data[80];
  int Separator;
};

Элементы

Text
Заголовок параметра - текст, выровненный по левому краю панели и отображаемый цветом обычного текста (COL_PANELTEXT).
Data
Данные параметра - текст, выровненный по правому краю панели и отображаемый цветом выделенной информации (COL_PANELINFOTEXT)
Separator
Если не равно нулю, показывается разделитель. Text используется как заголовок разделителя, Data игнорируется.
Смотрите также:


KeyBarTitles

главная | структуры
Структура KeyBarTitles позволяет переопределять заголовки функциональных клавиш. Массив этих структур передается в FAR функцией GetOpenPluginInfo.
struct KeyBarTitles
{
  char *Titles[12];
  char *CtrlTitles[12];
  char *AltTitles[12];
  char *ShiftTitles[12];

  // FAR Manager >= 1.70
  char *CtrlShiftTitles[12];
  char *AltShiftTitles[12];
  char *CtrlAltTitles[12];
};

Элементы

Titles, CtrlTitles, AltTitles, ShiftTitles
Содержат адреса новых заголовков функциональных клавиш. CtrlTitles, AltTitles и ShiftTitles используются, когда нажаты клавиши <Ctrl>, <Alt> или <Shift> соответственно. Для сохранения стандартного заголовка FAR укажите в соответствующем элементе массива NULL.
CtrlShiftTitles, AltShiftTitles, CtrlAltTitles
Содержат адреса новых заголовков функциональных клавиш. CtrlShiftTitles, AltShiftTitles и CtrlAltTitles используются, когда нажаты клавиши <CtrlShift>, <AltShift> или <CtrlAlt> соответственно. Для сохранения стандартного заголовка FAR укажите в соответствующем элементе массива NULL. Доступно в FAR Manager версии от 1.70
Смотрите также:


KeySequence

главная | структуры
Структура KeySequence используется в функции AdvControl для передачи последовательности внутренних кодов клавиш в FAR Manager.
struct KeySequence {
  DWORD Flags;
  int Count;
  DWORD *Sequence;
};

Элементы

Flags
Комбинация флагов (перечисление FARKEYSEQUENCEFLAGS):
Флаг | Описание
KSFLAGS_DISABLEOUTPUT | Не отображать на экране результат работы каждой клавиши.
KSFLAGS_NOSENDKEYSTOPLUGINS | Не передавать клавиши редакторным плагинам (плагинам, экспортирующим функцию ProcessEditorInput).
Count
Количество кодов клавиш в массиве Sequence.
Sequence
Массив кодов клавиш.

Замечания

Смотрите также:


OpenPluginInfo

главная | структуры
Структура OpenPluginInfo возвращает в FAR информацию об экземпляре плагина.
struct OpenPluginInfo
{
  int StructSize;
  DWORD Flags;
  const char *HostFile;
  const char *CurDir;
  const char *Format;
  const char *PanelTitle;
  const struct InfoPanelLine *InfoLines;
  int InfoLinesNumber;
  const char * const *DescrFiles;
  int DescrFilesNumber;
  const struct PanelMode *PanelModesArray;
  int PanelModesNumber;
  int StartPanelMode;
  int StartSortMode;
  int StartSortOrder;
  const struct KeyBarTitles *KeyBar;
  const char *ShortcutData;
  long Reserverd;
};

Элементы

StructSize
Это поле должно содержать размер структуры OpenPluginInfo:
Си: Opi.StructSize = sizeof (struct OpenPluginInfo);
Pascal: Opi.StructSize := SizeOf(Info);
Flags
Комбинация следующих значений (перечисление OPENPLUGININFO_FLAGS):
Флаг | Описание
OPIF_USEFILTER | Использовать фильтр в панели плагина.
OPIF_USESORTGROUPS | Использовать группы сортировки в панели плагина.
OPIF_USEHIGHLIGHTING | Использовать раскраску файлов в панели плагина.
OPIF_ADDDOTS | Добавить элемент, равный двум точкам (..), если он отсутствует, автоматически.
OPIF_RAWSELECTION | Выбор папок независимо от настроек FAR'а.
OPIF_REALNAMES | Включает использование стандартной обработки файла FAR'ом, если запрошенная операция не поддерживается плагином. Если этот флаг указан, элементы на панели плагина должны быть именами реальных файлов.
OPIF_SHOWNAMESONLY | Показывать по умолчанию имена без путей во всех режимах просмотра.
OPIF_SHOWRIGHTALIGNNAMES | Показывать по умолчанию имена, выровненные по правому краю во всех режимах просмотра.
OPIF_SHOWPRESERVECASE | Показывать имена файлов в оригинальном регистре независимо от настроек FAR'a.
OPIF_FINDFOLDERS | Применить команду "Найти файл" также и для папок. Флаг OPIF_FINDFOLDERS начиная с FAR Manager 1.70 beta 4 не актуален.
OPIF_COMPAREFATTIME | Преобразовывать временные метки в формат FAT при выполнении команды Compare folders. Установите этот флаг, если файловая система плагина не обеспечивает требуемую для стандартного стравнения времени точность.
OPIF_EXTERNALGET OPIF_EXTERNALPUT OPIF_EXTERNALDELETE OPIF_EXTERNALMKDIR | Флаги могут быть использованы только с OPIF_REALNAMES. Вынуждает использование соответствующих функций FAR, даже если требуемая функция экспортируется плагином.
OPIF_USEATTRHIGHLIGHTING | FAR Manager 1.70 build #963 и ниже: использовать раскраску файлов по атрибутам в панели плагина. Все маски раскраски файлов, кроме * или *.* будут проигнорированы. FAR Manager 1.70 build #964 и выше: использовать раскраску файлов в панели плагина только по атрибутам, а имена объектов в раскраске не используются. Выбор цвета происходит только среди тех групп раскраски файлов, у которых маски исключены из анализа, т.е. опция "[ ] Совпадение с маской (масками)" в настройках раскраски файлов отключена.
HostFile
Имя файла на эмулируемой файловой системе. Если плагин не эмулирует файловую систему, основанную на файле, установите эту переменную в NULL.
CurDir
Текущая директория плагина. Если панельный плагин вернет здесь пустую строку, то при нажатии ENTER на ".." FAR закроет плагин автоматически.
Format
Имя формата плагина. Оно показывается в диалоге копирования файла.
PanelTitle
Заголовок панели плагина.
InfoLines
Адрес массива структур InfoPanelLine. Каждая структура описывает одну строку в информационной панели. Если вы не нуждаетесь в показе текста, зависимого от плагина в информационной панели, установите InfoLines в NULL.
InfoLinesNumber
Число структур InfoPanelLine.
DescrFiles
Адрес массива указателей на имена файлов описаний. FAR попытается прочитать эти файлы (функцией GetFiles) при показе описаний и обновить их после обработки файлов, если флаг PPIF_PROCESSDESCR в структуре PluginPanelItem был установлен. В зависимости от типа плагина, обработка описаний может занять значительное время. Если Вам это не нужно, установите DescrFiles в NULL.
DescrFilesNumber
Число имен файлов описаний.
PanelModesArray
Адрес массива структур PanelMode. Используя его, вы можете переопределить настройки режимов просмотра. Первая структура описывает режим просмотра номер 0, вторая - 1 и т.д. Если Вам не нужно определение новых режимов просмотра, установите PanelModesArray в NULL.
PanelModesNumber
Число структур PanelMode.
StartPanelMode
Режим просмотра, который будет установлен после создания панели плагина. Он должен быть в формате '0'+<номер режима просмотра>. Например, '1' или 0x31 будут устанавливать Краткий режим просмотра. Если вы не хотите менять режим просмотра панели после запуска плагина, установите StartPanelMode в 0.
StartSortMode
Режим сортировки, который будет установлен после создания панели плагина. Можно указать здесь одно из следующих значений: SM_UNSORTED, SM_NAME, SM_EXT, SM_MTIME, SM_CTIME, SM_ATIME, SM_SIZE, SM_DESCR, SM_OWNER, SM_COMPRESSEDSIZE, SM_NUMLINKS. Если вы не хотите менять режим сортировки после запуска плагина, установите StartSortMode в SM_DEFAULT или 0.
StartSortOrder
Если вы указали StartSortMode, в поле StartSortOrder вы должны задать направление сортировки, 0 или 1 (обратная сортировка).
KeyBar
Адрес структуры KeyBarTitles. Используя его, вы можете переопределить метки функциональных клавиш в строке функциональных клавиш. Если Вам это не нужно, установите KeyBar в NULL.
ShortcutData
Адрес текстовой строки, оканчивающейся нулем, описывающей текущее состояние плагина. Она должна быть не больше значения MAXSIZE_SHORTCUTDATA. Эта строка передается в OpenPlugin, когда плагин активирован командой ссылки на папку. Например, FTP клиент может поместить сюда текущий хост, логин и пароль. Нет необходимости сохранять здесь текущий каталог, потому что он будет восстановлен самим FAR'ом.
Если вы не нуждаетесь в такой дополнительной информации для обработки ссылки на папку, установите данную строку в NULL.
Reserverd
Зарезервировано. Должно быть = 0.

Замечания

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


PanelInfo

главная | структуры
Структура PanelInfo содержит информацию о панели FAR. Используйте функцию Control для ее заполнения.
struct PanelInfo
{
  int PanelType;
  int Plugin;
  RECT PanelRect;
  struct PluginPanelItem *PanelItems;
  int ItemsNumber;
  struct PluginPanelItem *SelectedItems;
  int SelectedItemsNumber;
  int CurrentItem;
  int TopPanelItem;
  int Visible;
  int Focus;
  int ViewMode;
  char ColumnTypes[80];
  char ColumnWidths[80];
  char CurDir[NM];
  int ShortNames;
  int SortMode;
  DWORD Flags;
  DWORD Reserved;
};

Элементы

PanelType
Может быть (перечисление PANELINFOTYPE)
Тип | Описание
PTYPE_FILEPANEL | Обычная файловая панель
PTYPE_TREEPANEL | Панель, отображающая дерево (Tree)
PTYPE_QVIEWPANEL | Панель быстрого просмотра (Quick View)
PTYPE_INFOPANEL | Панель информации (Information)
Plugin
Если TRUE, панель поддерживается модулем плагина.
PanelRect
Геометрия панели - структура типа RECT.
PanelItems
Адрес массива всех элементов панели (см. PluginPanelItem). Плагин не должен изменять элементы (за исключением флага PPIF_SELECTED) и освобождать память, выделенную для массива. Данные корректны до возврата из экспортируемой функции плагина, которая их получила путём вызова Control(FCTL_GET[ANOTHER]PANELINFO, ...), или до следующего вызова функции Control.
ItemsNumber
Число элементов в массиве PanelItems.
SelectedItems
Адрес массива выделенных элементов панели (см. PluginPanelItem). Плагин не должен изменять элементы (за исключением флага PPIF_SELECTED) и освобождать память, выделенную для массива. Данные корректны до возврата из экспортируемой функции плагина, которая их получила путём вызова Control(FCTL_GET[ANOTHER]PANELINFO, ...), или до следующего вызова функции Control.
SelectedItemsNumber
Число элементов в массиве SelectedItems. Равно 1, даже если нет выделения. Исключение составляет случай, когда нет выделения и курсор стоит на ".." - тогда SelectedItemsNumber равно 0
CurrentItem
Индекс текущего элемента в массиве PanelItems. Перед использованием убедитесь, что ItemsNumber больше 0.
TopPanelItem
Элемент, находящийся в первой видимой позиции панели.
Visible
Если не ноль, панель видимая.
Focus
Если не ноль, панель активна.
ViewMode
Номер режима просмотра панели.
ColumnTypes
Текстовая строка, описывающая типы колонок. Кодируются с помощью одной или нескольких букв, разделенных запятыми, например, так "N,SC,D,T".
ColumnWidths

Текстовая строка, описывающая ширину колонок.

CurDir
Текущий каталог панели. Для Type = PTYPE_TREEPANEL CurDir содержит текущий выбранный каталог в дереве.
ShortNames
Не ноль, если панель в режиме показа коротких имен файлов.
SortMode
Режим сортировки панели. Может быть SM_DEFAULT, SM_UNSORTED, SM_NAME, SM_EXT, SM_MTIME, SM_CTIME, SM_ATIME, SM_SIZE, SM_DESCR, SM_OWNER, SM_COMPRESSEDSIZE, SM_NUMLINKS.
Flags
Дополнительные флаги. Могут быть комбинацией следующих значений (перечисление PANELINFOFLAGS):
Флаг | Описание
PFLAGS_SHOWHIDDEN | Разрешен показ скрытых и системных файлов.
PFLAGS_HIGHLIGHT | Включена раскраска файлов.
PFLAGS_REVERSESORTORDER | Включена обратная сортировка.
PFLAGS_USESORTGROUPS | Используются группы сортировки
PFLAGS_SELECTEDFIRST | Показывать помеченные файлы первыми.
PFLAGS_REALNAMES | Элементы на панели плагина отображают именами реальных файлов (см. также OPIF_REALNAMES)
PFLAGS_NUMERICSORT | Используется числовая сортировка
PFLAGS_PANELLEFT | Левая панель.
Reserved
Зарезервировано для будущего использования.

Замечания

Дополнительную информацию о панели также можно получить, вызвав функцию AdvControl (команда ACTL_GETPANELSETTINGS)
Смотрите также:


PanelMode

главная | структуры
Структура PanelMode описывает один режим панели (view mode). Массив таких структур может быть передан FAR`у в функции GetOpenPluginInfo.
struct PanelMode
{
  char *ColumnTypes;
  char *ColumnWidths;
  char **ColumnTitles;
  int FullScreen;
  int DetailedStatus;
  int AlignExtensions;
  int CaseConversion;
  char *StatusColumnTypes;
  char *StatusColumnWidths;
  DWORD Reserved[2];
};

Элементы

ColumnTypes
Текстовая строка, описывающая типы колонок. Кодируются с помощью одной или нескольких букв, разделенных запятыми, например, так "N,SC,D,T". Если вы используете стандартные режимы, настроенные в FAR`е, то установите ColumnTypes в NULL.
ColumnWidths

Текстовая строка, описывающая ширину колонок.

ColumnTitles
Указатель на массив строк, описывающих заголовки (название) колонок. Если вы будете использовать стандартные названия для колонок, то установите это значение в NULL.
FullScreen
TRUE - показывать панель во весь экран вместо половины экрана.
DetailedStatus
TRUE - в статусной строке будут отображены имя, размер, дата и время файла, для случая StatusColumnTypes=NULL и StatusColumnWidths=NULL. В противном случае в строке статуса будет отображаться только имя файла.
AlignExtensions
TRUE - выравнивать расширения файлов.
CaseConversion
FALSE - для отмены преобразования файлов имен.
StatusColumnTypes
Подобно ColumnTypes, но применительно для строки статуса. Если вы хотите использовать стандартную строку статуса, установите StatusColumnTypes в NULL.
StatusColumnWidths
Подобно ColumnWidths, но применительно для строки статуса.
Reserved
Зарезервировано для будущего использования. Установите в 0.
Смотрите также:


PanelRedrawInfo

главная | структуры
Структура PanelRedrawInfo может быть использована для определения новой позиции при перерисовке панели с помощи функции Control.
struct PanelRedrawInfo
{
  int CurrentItem;
  int TopPanelItem;
};

Элементы

CurrentItem
Текущая позиция на панели (начиная с 0).
TopPanelItem
Позиция верхнего пункта панели (начиная с 0).
Смотрите также:


PluginInfo

главная | структуры
Структура PluginInfo используется для возвращения FAR информации о плагине.
struct PluginInfo
{
  int StructSize;
  DWORD Flags;
  const char * const *DiskMenuStrings;
  int *DiskMenuNumbers;
  int DiskMenuStringsNumber;
  const char * const *PluginMenuStrings;
  int PluginMenuStringsNumber;
  const char * const *PluginConfigStrings;
  int PluginConfigStringsNumber;
  const char *CommandPrefix;
  DWORD Reserved;
};

Элементы

StructSize
Это поле должно содержать размер структуры PluginInfo.
Flags
Комбинация следующих значений (перечисление PLUGIN_FLAGS).
Флаг | Описание
PF_PRELOAD | Отменить кеширование параметров плагина и заставить FAR всегда загружать плагин в память при старте. Должно быть указано, если необходимо изменять строки в меню "Диск", "Команды внешних модулей" или "Конфигурация модулей" динамически. Этот флаг уменьшает эффективность использования памяти.
PF_DISABLEPANELS | Не показывать плагин в меню «Команды внешних модулей», вызываемом из панелей.
PF_EDITOR | Показывать плагин в меню "Команды внешних модулей", вызываемом из редактора FAR'а.
PF_VIEWER | Показывать плагин в меню "Команды внешних модулей", вызываемом из вьюера FAR'а.
PF_DIALOG | Показывать плагин в меню "Команды внешних модулей", вызываемом из диалога FAR'а.
PF_FULLCMDLINE | Заставляет FAR Manager передавать плагину всю командную строку вместе с префиксом CommandPrefix. Обязательно использовать этот флаг, если плагин умеет обрабатывать несколько префиксов CommandPrefix.
DiskMenuStrings
Если плагин добавляет строки в меню Диск, это поле должно быть равным адресу массива указателей на строки меню, в противном случае, установите его в NULL.
DiskMenuNumbers
Задает номера горячих клавиш для экспортированных строк в меню Диск. Если вы хотите позволить FAR'у самому назначить их, установите DiskMenuNumbers в NULL или в 0.
Если указанный номер уже используется другим плагином, FAR изменит его сам.
DiskMenuStringsNumber
Число добавляемых в меню Диск строк.
PluginMenuStrings
То же, что DiskMenuStrings, но строки добавляются в меню "Plugin commands" ("Команды внешних модулей").
PluginMenuStringsNumber
Число строк, добавляемых в меню "Plugin commands" ("Команды внешних модулей").
PluginConfigStrings
То же, что DiskMenuStrings, но строки добавляются в меню "Plugins configuration" ("Параметры внешних модулей").
PluginConfigStringsNumber
Число строк, добавляемых в меню "Plugins configuration" ("Параметры внешних модулей").
CommandPrefix
Плагин может указать в этом поле строку префиксов командной строки, которые будут использоваться для перехвата команд FAR. Например, если плагин передал здесь адрес строки ftp и пользователь ввел в командной строке что-то, начинающееся с ftp:, то функция OpenPlugin будет вызвана с параметром OPEN_COMMANDLINE.
Если предполагается, что плагин будет обрабатывать несколько командных префиксов, то необходимо указать префиксы, разделенные двоеточием. Например, плагин если обрабатывает префиксы edit:, goto: и view:, то строка должна быть такой:
CommandPrefix="edit:view:goto";
Если вы не хотите добавлять команды к FAR'у, установите этот параметр в NULL.
Reserved
Не используется и должно быть равно 0.

Замечания

  1. Все передаваемые в этой структуре данные должны быть правильными после возвращения из GetPluginInfo, таким образом вы не должны использовать автоматически создаваемые адреса переменных. Используйте статические или глобальные переменные.
  2. Структура, передаваемая функции GetPluginInfo, уже заполнена 0.
Смотрите также:


PluginPanelItem

главная | структуры
Структура PluginPanelItem описывает элемент файловой системы в файловой системе эмулируемой плагином. Она используется для возвращения информации о файловой системе плагина и для передачи плагину списка файлов для обработки.

ВНИМАНИЕ! ВНИМАНИЕ!

  • Размер структуры PluginPanelItem должен быть равен 366 байтам. Подробности в статье Игоря Павлова "Как настроить Alignment"
struct PluginPanelItem
{
#ifndef _FAR_USE_WIN32_FIND_DATA
  struct FAR_FIND_DATA   FindData;
#else
  WIN32_FIND_DATA FindData;
#endif
  DWORD PackSizeHigh;
  DWORD PackSize;
  DWORD Flags;
  DWORD NumberOfLinks;
  char *Description;
  char *Owner;
  char **CustomColumnData;
  int CustomColumnNumber;
  DWORD_PTR UserData;
  DWORD CRC32;
  DWORD Reserved[2];
};

Элементы

FindData
Структура FindData содержит много файловых параметров. См. описание структуры WIN32_FIND_DATA для более подробной информации.
PackSizeHigh
Содержит старшие 4 байта упакованного размера файла, в байтах. Сейчас не используется.
PackSize
Содержит младшие 4 байта упакованного размера файла, в байтах.
Flags
Может быть комбинацией следующих значений (перечисление PLUGINPANELITEMFLAGS):
Флаг | Описание
PPIF_PROCESSDESCR | Использовать внутреннюю обработку описаний FAR'а. Этот флаг может быть установлен для обрабатываемых файлов в функциях DeleteFiles, GetFiles и PutFiles. В этом случае FAR будет обновлять файлы описаний с именами, возвращенными в функции GetOpenPluginInfo.
PPIF_SELECTED | Для Control, в функциях FCTL_GETPANELINFO, FCTL_GETANOTHERPANELINFO, FCTL_SETSELECTION и FCTL_SETANOTHERSELECTION этот флаг позволяет проверить и установить выделение элементов. В функциях PutFiles, GetFiles и ProcessHostFile, если операция не удалась, но часть файлов была успешно обработана, плагин может убрать выделение только с обработанных файлов. Для этого плагин должен очистить флаг PPIF_SELECTED у обрабатываемых элементов в переданном функции списке PluginPanelItem.
PPIF_USERDATA | Если этот флаг установлен, FAR считает поле UserData указателем на структуру пользовательских данных. Читайте описание UserData для уточнения информации. Младшее слово параметра Flags может быть использовано плагином для своих собственных флагов.
NumberOfLinks
Количество жестких связей.
Description
Указывает на описание файла. Плагин может использовать это поле для передачи описания файла FAR'у. Если вы не хотите указывать описания, установите Description в NULL. Если плагин использует стандартную обработку описаний FAR'а, и передал имена описаний FAR'у в функции GetOpenPluginInfo, это поле также должно быть NULL.
Owner
Указывает на имя владельца файла. Плагин может использовать это поле для передачи имен владельцев файлов FAR'у. Если Вам это не нужно, установите это поле в NULL.
CustomColumnData
Указывает на массив адресов строк для определенных плагином типов колонок. Первая строка содержит данные для типа колонки C0, вторая - для C1 и т.д. Может быть задано до 10 дополнительных типов колонок от C0 до C9. Если вы не нуждаетесь в дополнительных типах колонок, установите это поле в NULL.
CustomColumnNumber
Число строк с данными о дополнительных типах колонок.
UserData
Это поле может быть использовано плагином для хранения 32-битного значения или указателя на структуру данных. В последнем случае, когда UserData указывает на структуру данных, первое поле этой структуры должно быть 32-битным значением, равным размеру структуры, и плагин должен установить флаг PPIF_USERDATA в поле Flags. Это позволит FAR'у правильно скопировать структуру во внутренний буфер FAR'а и позже передать ее плагину в списках PluginPanelItem. В функции FreeFindData плагин должен освободить память, занятую такими дополнительными структурами.
CRC32
Контрольная сумма. FAR не использует это поле.
Reserved
Зарезервировано для будущего использования. Установите в 0.

Замечания

  1. Все данные, выделенные плагином для членов Description, Owner и CustomColumnData, должны быть освобождены им. FAR создает копии этих данные в своих внутренних структурах. Таким образом они могут быть освобождены в любой момент после передачи FAR'у в функции GetFindData.
  2. Если плагин использует, например, UserData для получения данных о файле, то плагинописатель должен удостовериться в валидности этих данных. Это связано с тем, что при вызове GetFiles из списка найденных файлов FAR передает плагину элементы PluginPanelItem только с одним правильно заполненным членом - FindData, остальные члены установлены в NULL.
Смотрите также:


PluginStartupInfo

главная | структуры
Структура PluginStartupInfo используется в функции SetStartupInfo для передачи плагину различной важной информации.
struct PluginStartupInfo
{
  int StructSize;

  char ModuleName[NM];
  int ModuleNumber;
  const char *RootKey;
  FARAPIMENU             Menu;
  FARAPIDIALOG           Dialog;
  FARAPIMESSAGE          Message;
  FARAPIGETMSG           GetMsg;
  FARAPICONTROL          Control;
  FARAPISAVESCREEN       SaveScreen;
  FARAPIRESTORESCREEN    RestoreScreen;
  FARAPIGETDIRLIST       GetDirList;
  FARAPIGETPLUGINDIRLIST GetPluginDirList;
  FARAPIFREEDIRLIST      FreeDirList;

  // FAR >= 1.50
  FARAPIVIEWER           Viewer;
  FARAPIEDITOR           Editor;
  FARAPICMPNAME          CmpName;

  // FAR >= 1.52
  FARAPICHARTABLE        CharTable;
  FARAPITEXT             Text;

  // FAR >= 1.60
  FARAPIEDITORCONTROL    EditorControl;

  // FAR >= 1.70
  FARSTANDARDFUNCTIONS  *FSF;

  FARAPISHOWHELP         ShowHelp;
  FARAPIADVCONTROL       AdvControl;
  FARAPIINPUTBOX         InputBox;
  FARAPIDIALOGEX         DialogEx;
  FARAPISENDDLGMESSAGE   SendDlgMessage;
  FARAPIDEFDLGPROC       DefDlgProc;
  DWORD_PTR              Reserved;
  FARAPIVIEWERCONTROL    ViewerControl;
};

Элементы

StructSize
Размер структуры. Если в будущем будут добавлены новые поля, это поле позволит определить это.
ModuleName
Полное имя плагина с путем.
ModuleNumber
Номер плагина. Передается как параметр в некоторых функциях.
RootKey
Ключ Реестра, где плагин может сохранять свои параметры. Одинаков и для HKEY_CURRENT_USER и для HKEY_LOCAL_MACHINE. Обычно это "Software\Far\Plugins", но вы не должны указывать эту строку непосредственно, т.к. она может быть изменена или может стать опциональной в будущем. Например, если FAR запущен с ключем '/u user1', то RootKey соответственно будет содержать строку "Software\Far\Users\user1\Plugins".

Не сохраняйте параметры прямо в RootKey, создайте здесь свой собственный подключ.

Menu
Адрес функции Menu.
Dialog
Адрес функции Dialog.
Message
Адрес функции Message.
GetMsg
Адрес функции GetMsg.
Control
Адрес функции Control.
SaveScreen
Адрес функции SaveScreen.
RestoreScreen
Адрес функции RestoreScreen.
GetDirList
Адрес функции GetDirList.
GetPluginDirList
Адрес функции GetPluginDirList.
FreeDirList
Адрес функции FreeDirList.
Viewer
Адрес функции Viewer.
Editor
Адрес функции Editor.
CmpName
Адрес функции CmpName.
CharTable
Адрес функции CharTable.
Text
Адрес функции Text.
EditorControl
Адрес функции EditorControl.
FSF
Указатель на структуру FarStandardFunctions с адресами полезных функций из far.exe.
ShowHelp
Адрес функции ShowHelp.
AdvControl
Адрес функции AdvControl.
InputBox
Адрес функции InputBox.
DialogEx
Адрес функции DialogEx.
SendDlgMessage
Адрес функции SendDlgMessage.
DefDlgProc
Адрес функции DefDlgProc.
DefDlgProc
Адрес функции ViewerControl.

Замечания

Версии FAR Manager:
  • ниже 1.50 (с поддержкой плагинов) - не содержат поля после FreeDirList;
  • ниже 1.52 - не содержат поля после CmpName;
  • ниже 1.60 - не содержат поля после Text;
  • ниже 1.65 - не содержат поля после EditorControl
Таким образом, если вы собираетесь использовать функции Viewer, Editor или любую другую после нее, вы должны сначала проверить поле StructSize, чтобы гарантировать, что эти функции обеспечиваются текущей версией FAR'а.
Смотрите также:


WindowInfo

главная | структуры
Структура WindowInfo содержит информацию о конкретном окне FAR Manager. Плагин может получить информацию, используя команду ACTL_GETWINDOWINFO.
struct WindowInfo{
  int  Pos;
  int  Type;
  int  Modified;
  int  Current;
  char TypeName[64];
  char Name[NM];
};

Элементы

Pos
Номер окна, о котором нужно узнать информацию. Нумерация идет с 0. Pos = -1 вернет информацию о текущем окне.
Type
Тип окна. Может иметь одно из следующих значений (перечисление WINDOWINFO_TYPE):
Тип | Описание
WTYPE_PANELS | Файловые панели.
WTYPE_VIEWER | Окно встроенной программы просмотра.
WTYPE_EDITOR | Окно встроенного редактора.
WTYPE_DIALOG | Диалог.
WTYPE_VMENU | Меню.
WTYPE_HELP | Окно подсказки.
Modified
Признак модификации содержимого файла в окне. Может быть только у WTYPE_EDITOR.
Current
Является ли окно текущим.
TypeName
Имя типа окна (Panels,View,Edit,Help,VMenu), зависит от текущего языка.
Name
Имя окна. Для окон типа WTYPE_VIEWER, WTYPE_EDITOR содержит имя файла. Для панелей - имя текущего файлового объекта. Для окна помощи - полный путь к просматриваемому HLF-файлу. Для диалогов и меню - заголовок.

Пример

void GetFarWindowInfo()
{
  WindowInfo WInfo;
  int CountWindow;
  int I;
  FILE *Fp;

  if((Fp=fopen("window.log","a+t")) == NULL)
      return ;

  // запросили число окон
  CountWindow=(int)Info.AdvControl(Info.ModuleNumber,ACTL_GETWINDOWCOUNT,NULL);
  fprintf(Fp,"WindowCount=%i\n",CountWindow);

  for ( I=0; I < CountWindow; I++ )
  {
    // установили нужный номер
    WInfo.Pos=I;

    // запросили информаци об окне
    Info.AdvControl(Info.ModuleNumber,ACTL_GETWINDOWINFO,(void*)&WInfo);

    // распечатали ее
    fprintf(Fp,"Window[%i], Type=%i (%s), File=[%s] Current=%i, Modified=%i\n",
               I,WInfo.Type,WInfo.TypeName,WInfo.Name,
               WInfo.Current,WInfo.Modified);
  }
  fclose(Fp);

  // установили окно номер 1 (то есть второе)
  Info.AdvControl(Info.ModuleNumber,ACTL_SETCURRENTWINDOW,(void*)1);
}
Смотрите также:


Структуры

Структуры - Редактор

главная | структуры
Структура | Описание
EditorBookMarks | информация о закладках текущего редактируемого файла
EditorColor | установить или получить информацию о цветовых областях строк
EditorConvertPos | преобразование между реальным и экранным положением курсора в редакторе
EditorConvertText | преобразование текста между OEM и внутренней кодировкой редактора Far-а
EditorGetString | запрос строки из редактора
EditorInfo | текущее состояние редактора Far`а
EditorSaveFile | сохранение редактируемого файла
EditorSelect | выделение или сброс выделения блока в редакторе
EditorSetParameter | установка параметров редактора
EditorSetPosition | установка позиции в редакторе Far'а
EditorSetString | установка или вставка строки в редакторе
Смотрите также:
Экспортируемые функции, Сервисные функции, Dialog API, Поддержка архивов, Дополнения, Delphi-структуры, Win32 структуры


EditorBookMarks

главная | структуры
Структура EditorBookMarks используется в функции EditorControl для получения информации о закладках текущего редактируемого файла (команда ECTL_GETBOOKMARKS).
struct EditorBookMarks
{
  long *Line;
  long *Cursor;
  long *ScreenLine;
  long *LeftPos;
  DWORD Reserved[4];
};

Элементы

Line
Указатель на массив номеров строк для каждой закладки.
Cursor
Указатель на массив позиций курсоров в строках Line.
ScreenLine
Указатель на массив номеров строк, соответствующих первой видимой строке текста на экране.
LeftPos
Указатель на массив позиций, соответствующих первому видимому символу текста на экране слева.
Reserved
Зарезервировано, не используется.

Замечания

  1. Перед получением информации о закладках необходимо выяснить размер каждого из массивов Line, Cursor, ScreenLine и LeftPos. Информация о количестве закладок содержится в поле EditorInfo.BookMarkCount.
  2. Если плагину не требуется знать содержимое какого-либо из полей (Line, Cursor, ScreenLine или LeftPos), то установите значение этого поля в NULL.
Смотрите также:


EditorColor

главная | структуры
Структура EditorColor используется в функции EditorControl для того, чтобы установить или получить информацию о цветовых областях строк во внутреннем редакторе.
struct EditorColor
{
  int StringNumber;
  int ColorItem;
  int StartPos;
  int EndPos;
  int Color;
};

Элементы

StringNumber
Номер строки для обработки или -1, если для текущей строки.
ColorItem
Номер цветовой области, о которой вы хотите получить информацию. Строка может содержать несколько цветовых областей. Установите ColorItem равным 0 для получения информации о первой цветовой области, 1 - о второй и т.д.
Это поле не используется в ECTL_ADDCOLOR. Новый цвет всегда применяется ко всей области от StartPos до EndPos, независимо от существовавших там ранее различных цветовых областей.
StartPos, EndPos
Область строки для установки цвета.
Входной параметр для ECTL_ADDCOLOR и выходной для ECTL_GETCOLOR.
Color
Установленный или устанавливаемый цвет.
Входной параметр для ECTL_ADDCOLOR и выходной для ECTL_GETCOLOR.
Если Color равен 0, то ECTL_ADDCOLOR вместо установки новой цветовой области удалит все существующие цветовые области, начиная со StartPos. Если Color равен 0 и StartPos равен -1 все цветовые области данной строки будут удалены.

Начиная с build 1957 FAR раскрашивает символ табуляции на всю длину, на которую расширяется табуляция. Если необходимо, чтобы символ табуляции для цветовой области занимал 1 знакоместо, то для элемента Color, в дополнении к цвету, необходимо выставить флаг ECF_TAB1 (перечисление EDITORCOLORFLAGS):
Флаг | Описание
ECF_TAB1 | Если в диапазоне цветовой области встречается символ табуляции, то раскрасить его как 1 символ.

Замечания

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

Через параметр Color вы можете задать и цвет фона. Более того, вне зависимости от длины строки вы можете установить область начиная с первой видимой позиции и кончая самой правой - при этом вы как бы замените цвет фона в редакторе. Хотя этот метод не сработает на файлах, у которых число строк меньше размера экрана :(

Смотрите также:


EditorConvertPos

главная | структуры
Структура EditorConvertPos используется в функции EditorControl для преобразования реальной строковой позиции курсора в экранную позицию (и наоборот). Это может быть полезно для строк, которые содержат символы табуляции.
struct EditorConvertPos
{
  int StringNumber;
  int SrcPos;
  int DestPos;
};

Элементы

StringNumber
Номер строки для обработки, или -1 для преобразования позиции в текущей строке.
SrcPos
Позиция для конвертирования.
DestPos
Преобразованная позиция.
Смотрите также:


EditorConvertText

главная | структуры
Структура EditorConvertText используется в функции EditorControl для конвертирования текста из OEM-кодировки в кодировку текущей кодовой страницы редактора FAR'а (и наоборот).
struct EditorConvertText
{
  char *Text;
  int TextLength;
};

Элементы

Text
Указывает на текст для конвертирования.
TextLength
Длина текста для конвертирования.
Смотрите также:


EditorGetString

главная | структуры
Структура EditorGetString используется в функции EditorControl для получения строки из редактора FAR'а.
struct EditorGetString
{
  int StringNumber;
  const char *StringText;
  const char *StringEOL;
  int StringLength;
  int SelStart;
  int SelEnd;
};

Элементы

StringNumber
Номер получаемой строки (первая строка имеет индекс 0). Можно установить это поле в -1 для получения текущей строки (замечания, относительно значения -1 читайте здесь)
StringText
Указывает на данные строки. Вы не должны их изменять. Помните, что среди этих данных могут быть нулевые символы.
StringEOL
Последовательность, обозначающая конец строки. Может быть пустой строкой, \r\n или \n
StringLength
Размер данных, на которые указывает StringText.
SelStart
Стартовая позиция выделения в строке. Если строка не содержит выделения, то это поле равно -1.
SelEnd
Конечная позиция выделения в строке. Если область выделения включает в себя последовательность, равную StringEOL, то это поле равно -1.
Смотрите также:


EditorInfo

главная | структуры
Структура EditorInfo используется в функции EditorControl для получения информации о текущем состоянии редактора FAR'а.
struct EditorInfo
{
  int EditorID;
  const char *FileName;
  int WindowSizeX;
  int WindowSizeY;
  int TotalLines;
  int CurLine;
  int CurPos;
  int CurTabPos;
  int TopScreenLine;
  int LeftPos;
  int Overtype;
  int BlockType;
  int BlockStartLine;
  int AnsiMode;
  int TableNum;
  DWORD Options;
  int TabSize;
  int BookMarkCount;
  DWORD CurState;
  DWORD Reserved[6];
};

Элементы

EditorID
Идентификатор экземпляра редактора. Каждый экземпляр редактора имеет уникальный идентификатор, который не повторяется в текущей сессии FAR'а.
FileName
Имя редактируемого файла - полный путь (замечания относительно этого поля читайте для FAR версии ниже 1.65 здесь).
WindowSizeX, WindowSizeY
Ширина и высота окна редактора.
TotalLines
Количество строк в редактируемом тексте.
CurLine
Номер текущей строки.
CurPos
Позиция курсора в текущей строке.
CurTabPos
Экранная позиция курсора в текущей строке. Если строка не содержит символов табуляции, CurTabPos эквивалентна CurPos.
TopScreenLine
Номер строки вверху экрана.
LeftPos
Позиция левой границы окна редактора в редактируемом тексте.
Overtype
0 - режим вставки, 1 - замены.
BlockType
Тип выбранного блока. Одно из следующих значений (перечисление EDITOR_BLOCK_TYPES):
Тип блока | Описание
BTYPE_NONE | снять выделение с блока,
BTYPE_STREAM | выделить строковой блок
BTYPE_COLUMN | выделить вертикальный блок.
BlockStartLine
Номер первой строки блока.
AnsiMode
Состояние текстового режима ANSI. Всегда равно 0, кроме случая, когда не используются таблицы символов и текст в кодировке ANSI.
TableNum
Номер текущей используемой таблицы символов FAR'а или -1, если таковая не используется и текст в кодировке OEM (в этом случае см. AnsiMode). Если это поле не равно -1, вы можете передать его в функции CharTable для получения информации о таблице.
Options
Описывает состояние настроек редактора. Может быть комбинацией следующих флагов (перечисление EDITOR_OPTIONS):
Флаг | Описание
EOPT_EXPANDALLTABS | Включена опция "Преобразовывать все символы табуляции в пробелы" При открытии документа в редакторе все символы Tab заменить на соответствующее количество пробелов. Этот параметр можно изменить используя команду ECTL_SETPARAM (ESPT_EXPANDTABS).
EOPT_EXPANDONLYNEWTABS | Включена опция "Преобразовывать новые символы табуляции в пробелы" При редактировании документа введенный символ Tab заменять на соответствующее количество пробелов. Остальные символы Tab не преобразовывать. Этот параметр можно изменить используя команду ECTL_SETPARAM (ESPT_EXPANDTABS).
EOPT_PERSISTENTBLOCKS | Включена опция "Постоянные блоки"
EOPT_DELREMOVESBLOCKS | Включена опция "Del удаляет блоки"
EOPT_AUTOINDENT | Включена опция "Автоотступ". Этот параметр можно изменить используя команду ECTL_SETPARAM.
EOPT_AUTODETECTTABLE | Включена опция "Автоопределение таблицы символов"
EOPT_CURSORBEYONDEOL | Включена опция "Курсор за пределами строки" Этот параметр можно изменить используя команду ECTL_SETPARAM.
EOPT_SAVEFILEPOSITION | Включена опция "Сохранять позицию файла" Этот параметр можно изменить используя команду ECTL_SETPARAM.
TabSize
Размер табуляции. Этот параметр можно изменить используя команду ECTL_SETPARAM.
BookMarkCount
Количество закладок в редакторе. Для получения информации о закладках используйте команду ECTL_GETBOOKMARKS.
CurState
Текущее состояние редактируемого текста. Может быть набором из следующих значений (перечисление EDITOR_CURRENTSTATE):
Флаг | Описание
ECSTATE_MODIFIED | модифицирован
ECSTATE_SAVED | сохранен
ECSTATE_LOCKED | заблокирован (Ctrl-L)
Reserved
Зарезервировано для будущего использования.

Замечания

Для точного определения текущего набора символов в редакторе можно воспользоваться следующей таблицей:
                    EditorInfo.TableNum        EditorInfo.AnsiMode
DOS                          -1                         0
WIN                          -1                         1
Прочие                  Номер таблицы                   0
Для случая "Прочие" необходимо воспользоваться функцией CharTable, с помощью которой можно узнать имя загруженной таблицы символов.
Смотрите также:


EditorSelect

главная | структуры
Структура EditorSelect используется в функции EditorControl для выделения или снятия выделения с текста в редакторе FAR'а.
struct EditorSelect
{
  int BlockType;
  int BlockStartLine;
  int BlockStartPos;
  int BlockWidth;
  int BlockHeight;
};

Элементы

BlockType
Одно из следующих значений (перечисление EDITOR_BLOCK_TYPES):
Тип блока | Описание
BTYPE_NONE | снять выделение с блока
BTYPE_STREAM | выделить строковой блок
BTYPE_COLUMN | выделить вертикальный блок
Если BlockType равен BTYPE_NONE, другие поля этой структуры не важны.
BlockStartLine
Первая строка блока. Можно установить это поле в -1 - началом блока будет текущая строка.
BlockStartPos
Начальная позиция блока. Если BlockStartPos = -1, то выделение блока снимается.
BlockWidth
Ширина блока. Может быть отрицательной величиной.
BlockHeight
Высота блока. Должна быть >= 1

Замечания

  1. Функция EditorControl вернет FALSE, если:
    • размер передаваемой переменной меньше размера структуры EditorSelect;
    • BlockHeight меньше 1;
    • BlockStartLine больше количества строк в редакторе.

Пример

Программно строковый блок от (X1,Y1) до (X2,Y2) можно выделить так:
es.BlockType=BTYPE_STREAM;
es.BlockStartLine=min(Y2,Y1);
es.BlockStartPos=(Y1 < Y2?X1:X2);

// небольшая коррекция, если позиции равны
if(X1 == X2)
  es.BlockStartPos+=(Y1 < Y2?1:-1);

es.BlockHeight=max(Y1,Y2)-min(Y1,Y2)+1;

if(Y1 < Y2)
  es.BlockWidth=X2-X1+1;
else
  es.BlockWidth=X1-X2+1;

if(X1 == X2)
{
  if(Y1 < Y2)
    es.BlockStartPos--;
  else
    es.BlockStartPos++;
}

Info.EditorControl(ECTL_SELECT,(void*)&es);
Смотрите также:


EditorSetParameter

главная | структуры
Структура EditorSetParameter используется в функции EditorControl для изменения настроек текущего редактора FAR'а.
struct EditorSetParameter
{
  int Type;
  union {
    int iParam;
    char *cParam;
    DWORD Reserved1;
  } Param;
  DWORD Flags;
  DWORD Reserved2;
};

Элементы

Type
Тип настройки. Может быть одним из следующих (перечисление EDITOR_SETPARAMETER_TYPES):
Настройка | Описание
ESPT_AUTOINDENT | Включение/выключение режима "Автоотступ". iParam соответственно должен быть равен TRUE или FALSE.
ESPT_CHARCODEBASE Указать формат показа кода текущего символа в статусной строке редактора. iParam может принимать следующие значения:
  • 0 - восьмеричное значение (3 символа с ведущим нулями)
  • 1 - десятеричное значение (3 символа с ведущими пробелами)
  • 2 - шестнадцатеричное значение (2 символа под цифру + символ 'h')
ESPT_CHARTABLE Изменить текущую кодировку в редакторе. iParam - код устанавливаемой кодировки. Может быть одним из следующих:
  • 1 - OEM
  • 2 - ANSI
  • 3 - таблица с номером 0
  • N - таблица с номером (N-3)
В случае неудачи EditorControl возвращает FALSE, кодировка не изменяется.
ESPT_CURSORBEYONDEOL | Включение/выключение режима "Курсор за пределами строки". iParam соответственно должен быть равен TRUE или FALSE.
ESPT_EXPANDTABS Управление поведением замены пробелов вместо табуляции.
iParam может быть одним из следующих режимов (перечисление EXPAND_TABS):
Флаг | Описание
EXPAND_NOTABS |
EXPAND_ALLTABS |
EXPAND_NEWTABS |

ВНИМАНИЕ! ВНИМАНИЕ!

  • Данная операция необратима, т.е. если в файле были использованы пробелы вместо табуляции, то при переходе к обычным символам табуляции присутствующие в файле идущие подряд пробелы в символы табуляции преобразованы не будут.
ESPT_LOCKMODE | Включение/выключение запрета модификации текста (аналог Ctrl-L). Если iParam равен TRUE, то включается запрет модификации текста, если FALSE - запрет отменяется.
ESPT_SAVEFILEPOSITION | включение/выключение опции "Сохранять позицию файла". iParam соответственно должен быть равен TRUE или FALSE.
ESPT_SETWORDDIV Позволяет изменить строку символов-разделителей слов (параметр cParam) для текущей копии редактора.
Если cParam равен NULL или пустой строке, то в качестве строки разделителей принимается установленное по умолчанию значение - "~!%^&*()+|{}:"<>?`-=\[];',./" Эта строка может содержать не более 255 символов.
ESPT_GETWORDDIV Позволяет получить строку символов-разделителей слов (параметр cParam) для текущей копии редактора.
cParam должен указывать на строку не менее 256 символов.
ESPT_TABSIZE | Изменение размера табуляции. iParam содержит новое значение - от 1 до 512. Значение размера табуляции, выходящее за указанные границы, выставляется равным 8.
iParam
Содержит число, см. описание по конкретному типу настройки.
cParam
Указатель на строку, оканчивающуюся нулем, см. описание по конкретному типу настройки.
Reserved1
Не используется, зарезервировано для будущего использования.
Flags
Содержит дополнительные условия/данные, см. описание по конкретному типу настройки.
Reserved2
Не используется, зарезервировано для будущего использования. Должно быть установлено в 0.

Замечания

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


EditorSetPosition

главная | структуры
Структура EditorSetPosition используется в функции EditorControl для установки позиции и состояния курсора в редакторе FAR'а.
struct EditorSetPosition
{
  int CurLine;
  int CurPos;
  int CurTabPos;
  int TopScreenLine;
  int LeftPos;
  int Overtype;
};

Элементы

CurLine
Новая текущая строка или -1 для сохранения прежнего значения.
CurPos
Новая позиция курсора в текущей строке или -1 для сохранения прежнего значения.
CurTabPos
Новая экранная позиция курсора или -1 для сохранения прежнего значения. Если текущая строка не содержит символы табуляции, CurTabPos дает такой же эффект, как и CurPos. Вы не должны одновременно использовать CurPos и CurTabPos, установите хотя бы одно из этих полей в -1.
TopScreenLine
Новая строка вверху экрана или -1 для сохранения прежнего значения.
LeftPos
Новая позиция левой границы окна редактора в редактируемом тексте или -1 для сохранения прежнего значения.
Overtype
Поместите сюда 0 для установления режима вставки, 1 для установления режима замены или -1 для сохранения прежнего состояния.
Смотрите также:


EditorSetString

главная | структуры
Структура EditorSetString используется в функции EditorControl для изменения значения строки во внутреннем редакторе FAR.
struct EditorSetString
{
  int StringNumber;
  char *StringText;
  char *StringEOL;
  int StringLength;
};

Элементы

StringNumber
Номер изменяемой строки. Можно установить это поле в -1 для обработки текущей строки.
StringText
Указывает на добавляемую строку.
StringEOL
Последовательность, обозначающая конец строки. Может быть пустой строкой, \r\n или \n. Вы можете поместить эту последовательность или в поле StringEOL, или непосредственно в StringText. Также можно установить это поле в NULL для использования значения по умолчанию.
StringLength
Размер данных, на которые указывает StringText.
Смотрите также:


Структуры

Структуры - Dialog API

главная | структуры
Структура | Описание
FarDialogEvent | Информация о событии диалога
FarDialogItem | элемент диалога
FarDialogItemData | передача данных элементу диалога
FarList | список DI_LISTBOX
FarListColors | описывает цветовую схему для элементов DI_COMBOBOX и DI_LISTBOX
FarListDelete | параметры удаления элементов из DI_COMBOBOX и DI_LISTBOX
FarListFind | поиск элемента из DI_COMBOBOX и DI_LISTBOX
FarListGetItem | получение одного элемента списка из DI_COMBOBOX и DI_LISTBOX
FarListInfo | получить информацию о списках DI_COMBOBOX и DI_LISTBOX
FarListInsert | вставка элемента в DI_COMBOBOX и DI_LISTBOX
FarListItem | элемент списка
FarListPos | позиционирование в списке
FarListItemData | ассоциация данных с элементом списка
FarListTitles | установка/получение заголовков для списка
FarListUpdate | данные для обновления элемента списка
OpenDlgPluginData | Информация о диалоге, из которого вызван плагин, и выбранном пункте плагина
Смотрите также:
Экспортируемые функции, Сервисные функции, Dialog API, Поддержка архивов, Дополнения, Delphi-структуры, Win32 структуры


FarDialogEvent

главная | структуры
Структура FarDialogEvent содержит информацию о событии, поступающем в функцию ProcessDialogEvent.
struct FarDialogEvent
{
  HANDLE hDlg;
  int Msg;
  int Param1;
  LONG_PTR Param2;
  LONG_PTR Result;
};

Элементы

hDlg
Указатель на диалог
Msg
Одно из сообщений или событий
Param1
Параметр 1
Param2
Параметр 2
Result
Значение, возвращаемое обработчиком диалога.

Замечания

Смотрите также:
Структуры, ProcessDialogEvent, Dialog API


FarDialogItem

главная | Dialog API | Элементы диалога
Структура FarDialogItem описывает один элемент диалога. Массив этих структур передается в функции Dialog и DialogEx для показа диалога.
struct FarDialogItem
{
  int Type;
  int X1;
  int Y1;
  int X2;
  int Y2;
  int Focus;
  union
  {
    DWORD_PTR Reserved;
    int Selected;
    const char *History;
    const char *Mask;
    struct FarList *ListItems;
    int  ListPos;
    CHAR_INFO *VBuf;
  }
#ifdef _FAR_NO_NAMELESS_UNIONS
  Param
#endif
  ;
  DWORD Flags;
  int DefaultButton;
  union
  {
    char Data[512];
    struct
    {
      DWORD PtrFlags;
      int   PtrLength;
      char *PtrData;
      char  PtrTail[1];
    } Ptr;
  }
#ifdef _FAR_NO_NAMELESS_UNIONS
  Data
#endif
  ;
};

Элементы

Type
Тип элемента диалога. Может принимать одно значений, перечисленных в разделе "Элементы диалога"
X1,Y1,X2,Y2
Координаты, определяющие позицию элемента, относительно диалогового окна (начало отсчета - левый верхний угол диалогового окна, (0,0)). Более подробно о координатах см. описание каждого элемента диалога.
Focus
Определяет имеет ли элемент фокус ввода. Focus одного (одного и только одного!) из элементов диалога должен быть равным TRUE.
Param.Reserved
Размер этого параметра всегда равен размеру объединения Param, что позволяет использовать этот параметр для платформенно-независимой инициализации.
Param.Selected
Определяет состояние элементов DI_CHECKBOX и DI_RADIOBUTTON при показе диалога - включен/выключен. Возвращает их состояние после закрытия окна диалога.
Param.History
Адрес текстовой строки, которая будет использоваться как внутреннее название истории редактирования (см. также флаг DIF_HISTORY)
Param.Mask
Адрес текстовой строки с маской ввода. Используется только с элементом DI_FIXEDIT.
Param.ListItems
Указатель на структуру FarList, описывающую список для элементов DI_COMBOBOX и DI_LISTBOX.
Param.ListPos
Текущая позиция в элементах DI_LISTBOX и DI_COMBOBOX.
Param.VBuf
Указатель на структуру CHAR_INFO, описывающую виртуальный буфер для элемента DI_USERCONTROL.
Flags
Комбинация значений, перечисленных в разделе "Флаги элементов диалога"
DefaultButton
Флаг, означающий, что данный элемент диалога является "элементом по умолчанию". Если при нажатии на <Enter> фокус установлен не на кнопке, то функция Dialog (или DialogEx) вернет номер того элемента, для которого DefaultButton равно 1. Флаг DefaultButton может быть установлен не только для кнопки, но и для любого другого элемента диалога.
Data.Data
Буфер обмена данными с диалогом (без флага DIF_VAREDIT). Подробности использования в описаниях типов элементов диалога.
Data.Ptr.PtrFlags
Дополнительные флаги (в Dialog API 1.0 не используется). Ptr.PtrFlags должен быть равен 0.
Data.Ptr.PtrLength
Размер данных, на которые указывает PtrData.
Data.Ptr.PtrData
Указатель на пользовательский буфер редактирования.
Data.Ptr.PtrTail
"Остаток" - доступ к оставшейся части Data.

Замечания

  1. Вся информация по структуре FarDialogItem изложена с учетом именованных объединений. Более подробно читайте в описании определения _FAR_NO_NAMELESS_UNIONS.
  2. Поскольку содержимое переменной Data.Data имеет большой размер, прямая инициализация массива FarDialogItem, может заметно увеличить потребление памяти. Чтобы избежать этого, можно, например, инициализировать временный массив типов структур с *Data вместо Data[512] и затем преобразовать его в FarDialogItem используя простые функции.
  3. На предмет того, как это сделать смотрите исходные тексты плагинов, входящих в стандартную поставку FAR Manager (функция InitDialogItems и структура InitDialogItem).
  4. Члены Ptr.* используются только для DI_EDIT совместно с флагом DIF_VAREDIT.
Смотрите также:
структуры, _FAR_NO_NAMELESS_UNIONS, InitDialogItem, TFarDialogItem, Флаги элементов диалога
"О пользе и вреде static в диалогах"


FarDialogItemData

главная | Dialog API
Структура FarDialogItemData описывает данные, передаваемые (получаемые) элементу диалога сообщением DM_SETTEXT (DM_GETTEXT) в качестве параметра Param2.
struct FarDialogItemData
{
  int   PtrLength;
  char *PtrData;
};

Элементы

PtrLength
Размер данных в PtrData без завершающего символа конца строки '\0'.
PtrData
Указатель на передаваемые данные.

Замечания

Смотрите также:
DM_GETTEXT, DM_SETTEXT, TFarDialogItemData, структуры


FarList

главная | Dialog API
Структура FarList описывает список элементов FarListItem для элементов диалога DI_LISTBOX и DI_COMBOBOX.
struct FarList
{
  DWORD ItemsNumber;
  struct FarListItem *Items;
};

Элементы

ItemsNumber
Количество элементов списка
Items
Указатель на массив элементов списка FarListItem.

Замечания

Смотрите также:
TFarList, FarListItem, структуры


FarListColors

главная | Dialog API
Структура FarListColors описывает цветовую схему для элементов DI_LISTBOX и DI_COMBOBOX.
struct FarListColors
{
  DWORD  Flags;
  DWORD  Reserved;
  int    ColorCount;
  LPBYTE Colors;
};

Элементы

Flags
Флаги. Поле должно быть равно 0.
Reserved
Зарезервировано для будущего использования. Поле должно быть равно 0.
ColorCount
Количество элементов массива Colors
Colors
Байтовый массив цветовых атрибутов (цвет_фона+цвет_текста). По умолчанию задаются цветовые атрибуты:

для DI_LISTBOX
Индекс | Константа | Описание
0 | COL_DIALOGLISTBOX | подложка
1 | COL_DIALOGLISTBOX | рамка
2 | COL_DIALOGLISTTITLE | заголовок - верхний и нижний
3 | COL_DIALOGLISTTEXT | текст пункта
4 | COL_DIALOGLISTHIGHLIGHT | горячая клавиша
5 | COL_DIALOGLISTBOX | разделительная линия
6 | COL_DIALOGLISTSELECTEDTEXT | текст выбранного пункта
7 | COL_DIALOGLISTSELECTEDHIGHLIGHT | горячая клавиша выбранного пункта
8 | COL_DIALOGLISTSCROLLBAR | полоса прокрутки
9 | COL_DIALOGLISTDISABLED | недоступный пункт (disabled)
10 | COL_DIALOGLISTARROWS | указатели длинных строк
11 | COL_DIALOGLISTARROWSSELECTED | указатели длинных строк выбранного пункта
12 | COL_DIALOGLISTARROWSDISABLED | указатели длинных строк недоступного пункта (disabled)
13 | COL_DIALOGLISTGRAY | Серый текст
14 | COL_DIALOGLISTSELECTEDGRAYTEXT | Выбранный серый текст

для DI_COMBOBOX
Индекс | Константа | Описание
0 | COL_DIALOGCOMBOBOX | подложка
1 | COL_DIALOGCOMBOBOX | рамка
2 | COL_DIALOGCOMBOTITLE | заголовок - верхний и нижний
3 | COL_DIALOGCOMBOTEXT | текст пункта
4 | COL_DIALOGCOMBOHIGHLIGHT | горячая клавиша
5 | COL_DIALOGCOMBOBOX | разделительная линия
6 | COL_DIALOGCOMBOSELECTEDTEXT | текст выбранного пункта
7 | COL_DIALOGCOMBOSELECTEDHIGHLIGHT | горячая клавиша выбранного пункта
8 | COL_DIALOGCOMBOSCROLLBAR | полоса прокрутки
9 | COL_DIALOGCOMBODISABLEDTEXT | недоступный пункт (disabled)
10 | COL_DIALOGCOMBOARROWS | указатели длинных строк
11 | COL_DIALOGCOMBOARROWSSELECTED | указатели длинных строк выбранного пункта
12 | COL_DIALOGCOMBOARROWSDISABLED | указатели длинных строк недоступного пункта (disabled)
13 | COL_DIALOGCOMBOGRAY | Серый текст
14 | COL_DIALOGCOMBOSELECTEDGRAYTEXT | Выбранный серый текст

Замечания

Смотрите также:
DN_CTLCOLORDLGLIST, TFarListColors, структуры


FarListDelete

главная | Dialog API
Структура FarListDelete задает параметры для удаления элементов из DI_LISTBOX и DI_COMBOBOX.
struct FarListDelete
{
  int StartIndex;
  int Count;
};

Элементы

StartIndex
Индекс первого удаляемого элемента списка.
Count
Количество удаляемых элементов списка.

Замечания

Если значение Count меньше или равно 0, то будет удален весь список.
Смотрите также:
DM_LISTDELETE, TFarListDelete, структуры


FarListFind

главная | Dialog API
Структура FarListFind задает параметры для поиска элемента в DI_LISTBOX и DI_COMBOBOX.
struct FarListFind
{
  int StartIndex;
  const char *Pattern;
  DWORD Flags;
  DWORD Reserved;
};

Элементы

StartIndex
Индекс элемента, с которого начинается поиск.
Pattern
Шаблон для поиска по правилам функции CmpName
Flags
Дополнительные флаги. Одно из следующих значений (перечисление FARLISTFINDFLAGS):
Флаг | Описание
LIFIND_EXACTMATCH | Поле Pattern не является шаблоном - рассматривать как обычную подстроку поиска.
Reserved
Резерв.

Замечания

Смотрите также:
DM_LISTFINDSTRING, TFarListFind, структуры


FarListGetItem

главная | Dialog API
Структура FarListGetItem описывает один элемент типа FarListItem для элементов диалога DI_LISTBOX и DI_COMBOBOX.
struct FarListGetItem
{
  int ItemIndex;
  struct FarListItem Item;
};

Элементы

ItemIndex
Индекс элемента из списка.
Item
Элемент списка типа FarListItem.

Замечания

Смотрите также:
TFarListGetItem, FarListItem, DM_LISTGETITEM, структуры


FarListInfo

главная | Dialog API
Структура FarListInfo описывает состояние элементов DI_LISTBOX и DI_COMBOBOX.
struct FarListInfo
{
  DWORD Flags;
  int ItemsNumber;
  int SelectPos;
  int TopPos;
  int MaxHeight;
  int MaxLength;
  DWORD Reserved[6];
};

Элементы

Flags
Набор битовых флагов (перечисление FARLISTINFOFLAGS):
Флаг | Описание
LINFO_SHOWNOBOX | Управляющий элемент DI_LISTBOX с выставленным флагом DIF_LISTNOBOX рисуется без рамки.
LINFO_AUTOHIGHLIGHT | Горячие клавиши будут назначены автоматически, начиная с первого пункта
LINFO_REVERSEHIGHLIGHT | Горячие клавиши будут назначены автоматически, начиная с последнего пункта
LINFO_WRAPMODE | Попытка перемещения курсора выше первого пункта или ниже последнего будет приводить к перемещению соответственно к последнему или к первому пункту списка
LINFO_SHOWAMPERSAND | Показать амперсанды (&). Без этого флага амперсанды используются для определения горячей клавиши пункта.
ItemsNumber
Количество пунктов в списке
SelectPos
Индекс текущего пункта
TopPos
Индекс верхнего видимого пункта списка
MaxHeight
Максимальная видимая высота списка
MaxLength
Максимальный видимый размер строки
Reserved
Резерв.

Замечания

Смотрите также:
DM_LISTINFO, TFarListInfo, структуры


FarListInsert

главная | Dialog API
Структура FarListInsert задает параметры для вставки требуемого элемента в списки DI_LISTBOX и DI_COMBOBOX.
struct FarListInsert
{
  int Index;
  struct FarListItem Item;
};

Элементы

Index
Требуемая позиция элемента в списке. Если Index больше текущего количества элементов списка, то вставляемый пункт будет добавлен в конец списка. Если Index меньше нуля, то вставляемый пункт будет добавлен в начало списка.
Item
Элемент FarListItem.

Замечания

Смотрите также:
FarListItem, DM_LISTINSERT, TFarListInsert, структуры


FarListItem

главная | Dialog API
Структура FarListItem описывает один элемент списка DI_LISTBOX или DI_COMBOBOX.
struct FarListItem
{
  DWORD Flags;
  char Text[128];
  DWORD Reserved[3];
};

Элементы

Flags
Комбинация следующих значений (перечисление LISTITEMFLAGS):
Флаг | Описание
LIF_SELECTED | Флаг активности пункта списка. Только один пункт может быть активным.
LIF_CHECKED | Если флаг установлен, то перед текстом пункта отображается символ пометки (например, символ с кодом 0xFB).
LIF_SEPARATOR | Если флаг установлен, то пункт отображается как разделитель. Разделитель может иметь непустой текст, который будет отображаться поверх разделительной линии.
LIF_DISABLE | Если флаг установлен, то пункт недоступен.
LIF_GRAYED | Если флаг установлен, то пункт доступен в навигации, но не доступен для выбора.
LIF_HIDDEN | Если флаг установлен, то пункт не выводится на экран.
LIF_DELETEUSERDATA | Этот флаг устанавливается в параметре Item соoбщения DM_LISTUPDATE если при обновлении элемента списка необходимо удалить связанные с этим элементом данные.
Text
Текст элемента списка.
Reserved
Зарезервировано, Должно быть равно 0.

Замечания

Смотрите также:
FarList, DM_LISTGETITEM, FarListInsert, FarListUpdate, TFarListItem, структуры


FarListPos

главная | Dialog API
Структура FarListPos задает параметры для позиционирования курсора в DI_LISTBOX и DI_COMBOBOX.
struct FarListPos
{
  int SelectPos;
  int TopPos;
};

Элементы

SelectPos
Позиция текущего элемента.
TopPos
Позиция первого видимого элемента, -1 для автоматической подстройки под значение SelectPos.

Замечания

Смотрите также:
DM_LISTGETCURPOS, DM_LISTSETCURPOS, TFarListPos, структуры


FarListItemData

главная | Dialog API
Структура FarListItemData описывает данные, которые будут ассоциированы с элементом списка DI_LISTBOX или DI_COMBOBOX.
struct FarListItemData
{
  int   Index;
  int   DataSize;
  void *Data;
  DWORD Reserved;
};

Элементы

Index
Индекс элемента списка.
DataSize
Размер данных Data или 0, если предполагается ассоциировать с пунктом списка ASCIIZ строку.
Data
Указатель на данные.
Reserved
Зарезервировано.

Замечания

Менеджер диалогов размещает данные, ассоциируемые с пунктом списка, по следующим правилам:
DataSize | Data
0 | Указатель на ASCIIZ строку. Выделяется память размером strlen(Data)+1 байт. Передаваемые данные копируются в выделенную область памяти.
<= sizeof(DWORD) | Массив символов из 4-х и менее элементов или любой указатель (например, дескриптор окна HWND). Память не выделяется. Данные размещаются в локальной области элемента списка.
> sizeof(DWORD) | Произвольные данные. Выделяется память размером DataSize. Передаваемые данные копируются в выделенную область памяти.
Смотрите также:
FarList, DM_LISTGETDATA, DM_LISTSETDATA, TFarListItemData, структуры


FarListTitles

главная | структуры | Dialog API
Структура FarListTitles описывает заголовки (верхний и нижний) для элемента диалога DI_LISTBOX.
struct FarListTitles
{
  int   TitleLen;
  char *Title;
  int   BottomLen;
  char *Bottom;
};

Элементы

TitleLen
Длина строки верхнего заголовка
Title
Строка, содержащая текст для верхнего заголовка списка. Может быть равна NULL (в этом случае верхний заголовок не выводится).
BottomLen
Длина строки нижнего заголовка
Bottom
Строка, содержащая текст для нижнего заголовка списка. Может быть равна NULL (в этом случае нижний заголовок не выводится).

Замечания

Члены структуры TitleLen и BottomLen обязательны только при получении заголовков списка (см. DM_LISTGETTITLES)
Смотрите также:
TFarListTitles, DM_LISTGETTITLES, DM_LISTSETTITLES


FarListUpdate

главная | Dialog API
Структура FarListUpdate задает параметры операции обновления элемента в списке DI_LISTBOX или DI_COMBOBOX: индекс обновляемого элемента и новые данные элемента.
struct FarListUpdate
{
  int Index;
  struct FarListItem Item;
};

Элементы

Index
Индекс элемента в списке
Items
Элемент FarListItem.

Замечания

Данные ассоциированные с пунктом списка при обновлении не уничтожаются. Для автоматического уничтожения копии данных используйте флаг LIF_DELETEUSERDATA.
Смотрите также:
DM_LISTUPDATE, TFarListUpdate, FarListItem, структуры


OpenDlgPluginData

главная | Dialog API
Указатель на структуру OpenDlgPluginData передается в функцию OpenPlugin плагина при вызове его из диалога.
struct OpenDlgPluginData
{
  int ItemNumber;
  HANDLE hDlg;
};

Элементы

ItemNumber
Номер выбранного пункта в меню из зарегистрированных плагином пунктов.
hDlg
Указатель на диалог, из которого вызван плагин.

Замечания

Смотрите также:
Структуры, OpenPlugin, Dialog API


Структуры

Структуры - Программа просмотра

главная | структуры
Структура | Описание
FARINT64 | используется для хранения 64-битного целого
ViewerInfo | информации о текущем состоянии программы просмотра
ViewerMode | информация о режимах программы просмотра
ViewerSelect | выделение области в программе просмотра
ViewerSetMode | изменение режимов работы программы просмотра
ViewerSetPosition | изменение текущей позиции в файле
Смотрите также:
Экспортируемые функции, Сервисные функции, Delphi-структуры, Win32 структуры


ViewerInfo

главная | структуры
Структура ViewerInfo используется для получения информации о текущем состоянии программы просмотра FAR.
struct ViewerInfo
{
  int  StructSize;
  int  ViewerID;
  const char *FileName;
  FARINT64 FileSize;
  FARINT64 FilePos;
  int  WindowSizeX;
  int  WindowSizeY;
  DWORD Options;
  int  TabSize;
  struct ViewerMode CurMode;
  int  LeftPos;
  DWORD Reserved3;
};

Элементы

StructSize
Размер структуры ViewerInfo. Вы обязательно должны заполнить это поле.
ViewerID
Идентификатор экземпляра программы просмотра. Каждый экземпляр программы просмотра имеет уникальный идентификатор, который не повторяется в текущей сессии FAR.
FileName
Указатель на строку с полным именем просматриваемого файла.
FileSize
Размер файла. Переменная типа FARINT64.
FilePos
Текущая позиция в файле (абсолютное смещение в байтах). Переменная типа FARINT64.
WindowSizeX, WindowSizeY
Ширина и высота окна программы просмотра.
Options
Состояние настроек программы просмотра. Может быть комбинацией из следующих флагов (перечисление VIEWER_OPTIONS):
Флаг | Описание
VOPT_SAVEFILEPOSITION | "Сохранять позицию файла" ("Save file position")
VOPT_AUTODETECTTABLE | "Автоопределение таблицы символов" ("Autodetect character table")
TabSize
Размер табуляции.
CurMode
Переменная типа ViewerMode - дополнительная информация о режиме программы просмотра.
LeftPos
Позиция левой границы просматриваемого текста в окне программы просмотра.
Reserved3
Зарезервировано для будущего использования.
Смотрите также:
Структуры, ViewerControl, ViewerMode


ViewerMode

главная | структуры
Структура ViewerMode используется для получения дополнительной информации о текущем состоянии программы просмотра FAR.
struct ViewerMode
{
   int UseDecodeTable;
   int TableNum;
   int AnsiMode;
   int Unicode;
   int Wrap;
   int WordWrap;
   int Hex;
   DWORD Reserved[4];
};

Элементы

UseDecodeTable
Если 1, то используется таблица перекодировки.
TableNum
Номер пользовательской таблицы перекодировки. Имеет смысл, если UseDecodeTable равно TRUE.
AnsiMode
Если 1, то текущая кодировка в программе просмотра - ANSI.
Unicode
Если 1, то текущая кодировка в программе просмотра - Unicode.
Wrap
Включена (1)/выключена (0) свертка.
WordWrap
Тип свертки: 1 - используется перенос строк по словам, 0 - по буквам.
Hex
Если 1, то программа просмотра в hex-режиме.
Reserved
Зарезервировано для будущего использования.
Смотрите также:
Структуры, ViewerControl, ViewerInfo


ViewerSelect

главная | структуры
Структура ViewerSelect используется для выделения области в программе просмотра FAR.
struct ViewerSelect
{
   FARINT64 BlockStartPos;
   int  BlockLen;
};

Элементы

BlockStartPos
Начало выделения - в символах, а не в байтах. Это означает, что если программа просмотра находится в режиме Unicode, то BlockStartPos будет равно (позиция в файле в байтах / 2).
BlockLen
Длина выделения в символах.
Смотрите также:
Структуры, ViewerControl, FARINT64


ViewerSetMode

главная | структуры
Структура ViewerSetMode используется для изменения режимов работы программы просмотра FAR.
struct ViewerSetMode
{
  int Type;
  union {
    int iParam;
    char *cParam;
  } Param;
  DWORD Flags;
  DWORD Reserved;
};

Элементы

Type
Тип режима. Может быть одним из следующих (перечисление VIEWER_SETMODE_TYPES):
Режим | Описание
VSMT_HEX | Текстовый/16-ричный режим: iParam=1 - включить 16-ричный режим, iParam=0 - текстовый.
VSMT_WRAP | Перенос строк: iParam=1 - перенос включен, iParam=0 - выключен)
VSMT_WORDWRAP | Тип свертки: iParam=1 - используется перенос строк по словам, iParam=0 - по буквам.
iParam
Содержит число, см. описание по конкретному типу режима.
cParam
Указатель на строку, оканчивающуюся нулем, см. описание по конкретному типу режима.
Flags
Дополнительные флаги (перечисление VIEWER_SETMODEFLAGS_TYPES):
Режим | Описание
VSMFL_REDRAW | После применения "режима" перерисовать экран. В противном случае после установки режимов воспользоваться командой VCTL_REDRAW.
Reserved
Не используется, зарезервировано для будущего использования. Должно быть установлено в 0.

Замечания

Смотрите также:


ViewerSetPosition

главная | структуры
Структура ViewerSetPosition используется для изменения текущей позиции в файле, открытом в программе просмотра FAR.
struct ViewerSetPosition
{
   DWORD  Flags;
   FARINT64 StartPos;
   int  LeftPos;
};

Элементы

Flags
Флаги, уточняющие процесс изменения позиции. Может быть комбинация из (перечисление VIEWER_SETPOS_FLAGS):
Флаг | Описание
VSP_NOREDRAW | Не перерисовывать экран.
VSP_PERCENT | Смещение указано не в байтах, а в процентах.
VSP_RELATIVE | Смещение относительное, а не абсолютное.
VSP_NORETNEWPOS | Не возвращать реальную позицию (см. StartPos).
StartPos
Новая позиция в файле (или в байтах, или в процентах - зависит от VSP_PERCENT, может быть отрицательной - если указан флаг VSP_RELATIVE). В программе просмотра в общем случае невозможно установить точную позицию в файле, поэтому новая реальная позиция может и не совпадать со StartPos. Для того, чтобы узнать, чему же равна новая позиция в файле, ее значение записывается в StartPos (если не указан флаг VSP_NORETNEWPOS). Используйте это свойство для контроля, если хотите.
LeftPos
Позиция левой границы просматриваемого текста в окне программы просмотра.
Смотрите также:
Структуры, ViewerControl, FARINT64


Delphi Структуры

главная | структуры

Основные структуры

Структура | Описание
TActlEjectMedia | извлечь диск
TActlKeyMacro | Macro-ориентированные операции
TCharTableSet | таблица символов
TCmdLineSelect | выделение или сброс выделения блока в командной строке
TFarMenuItem | элемент меню
TFarSetColors | изменение цветовой схемы FAR Manager
TFarStandardFunctions | полезные функции из FAR.EXE
TInfoPanelLine | одна линия информационной панели
TKeySequence | описание последовательности кодов клавиш
TKeyBarTitles | переопределяет названия функциональных клавиш в полоске клавиш
TOpenPluginInfo | информация об открытом экземпляре плагина
TPanelInfo | информация о панели Far'а
TPanelMode | определяет режим просмотра панели
TPanelRedrawInfo | используется при перерисовке панели
TPluginInfo | информация о модуле плагина
TPluginPanelItem | информация об одном элементе в эмулируемой файловой системе
TPluginStartupInfo | различная важная информация
TWindowInfo | информация об окне FAR Manager

Специфические структуры редактора

Структура | Описание
TEditorBookMarks | информация о закладках текущего редактируемого файла
TEditorColor | установить или получить информацию о цветовых областях строк
TEditorConvertPos | преобразование между реальным и экранным положением курсора в редакторе
TEditorConvertText | преобразование текста между OEM и внутренней кодировкой редактора FAR Manager
TEditorGetString | запрос строки из редактора
TEditorInfo | текущее состояние редактора Far`а
TEditorSaveFile | сохранение редактируемого файла
TEditorSelect | выделение или сброс выделения блока в редакторе
TEditorSetParameter | установка параметров редактора
TEditorSetPosition | установка позиции в редакторе Far'а
TEditorSetString | установка или вставка строки в редакторе

Специфические структуры Dialog API

Структура | Описание
TFarDialogItem | элемент диалога
TFarDialogItemData | передача данных элементу диалога
TFarList | список элементов для DI_COMBOBOX и DI_LISTBOX
TFarListColors | описывает цветовую палитру для элементов DI_COMBOBOX и DI_LISTBOX
TFarListDelete | параметры удаления элементов из DI_COMBOBOX и DI_LISTBOX
TFarListFind | поиск элемента в DI_COMBOBOX и DI_LISTBOX
TFarListGetItem | получение одного элемента списка из DI_COMBOBOX и DI_LISTBOX
TFarListInfo | получить информацию о списках DI_COMBOBOX и DI_LISTBOX
TFarListInsert | вставка элемента в DI_COMBOBOX и DI_LISTBOX
TFarListItem | элемент списка
FarListPos | позиционирование в списке
TFarListTitles | заголовки списка
TFarListItemData | ассоциация данных с элементом списка
FarListUpdate | данные для обновления элемента списка

Специфические структуры Viewer API

Структура | Описание
TFarInt64 | используется для хранения 64-битного целого
TViewerInfo | информации о текущем состоянии программы просмотра
TViewerMode | информация о режимах программы просмотра
TViewerSelect | выделение области в программе просмотра
TViewerSetMode | изменение режимов работы программы просмотра
TViewerSetPosition | изменение текущей позиции в файле
Смотрите также:
Экспортируемые функции, Сервисные функции, Поддержка архивов, Дополнения


TActlEjectMedia

главная | структуры | ActlEjectMedia
Структура ActlEjectMedia для Delphi:
TActlEjectMedia = packed record
  Letter: DWORD;
  Flags: DWORD;
end;
PActlEjectMedia = ^TActlEjectMedia;


TActlKeyMacro

главная | структуры | ActlKeyMacro
Структура ActlKeyMacro для Delphi:
TActlKeyMacro = packed record
  Command: Integer;
  Reserved: packed array[0..2] of DWORD;
end;
PActlKeyMacro = ^TActlKeyMacro;


TArcInfo

Поддержка архивов | структуры | ArcInfo
Структура ArcInfo для Delphi:
TArcInfo = packed record
  SFXSize: Integer;
  Volume: Integer;
  Comment: Integer;
  Recovery: Integer;
  Lock: Integer;
  Flags: Integer;
end;
PArcInfo = ^TArcInfo;


TArcItemInfo

Поддержка архивов | структуры | TArcItemInfo
Структура ArcItemInfo для Delphi:
TArcItemInfo = packed record
  HostOS: packed array[0..31] of char;
  Description: packed array[0..255] of char;
  Solid: integer;
  Comment: integer;
  Encrypted: integer;
  DictSize: integer;
  UnpVer: integer;
end;
PArcItemInfo = ^TArcItemInfo;


TCharTableSet

главная | структуры | CharTableSet
Структура CharTableSet для Delphi:
TCharTableSet = packed record
  DecodeTable: packed array[0..255] of BYTE;
  EncodeTable: packed array[0..255] of BYTE;
  UpperTable: packed array[0..255] of BYTE;
  LowerTable: packed array[0..255] of BYTE;
  TableName: packed array[0..127] of char;
end;
PCharTableSet = ^TCharTableSet;


TCmdLineSelect

главная | структуры | CmdLineSelect
Структура CmdLineSelect для Delphi:
TCmdLineSelect = packed record
  SelStart: integer;
  SelEnd: integer;
end;
PEditorSelect = ^TCmdLineSelect;


TEditorBookMarks

главная | структуры EditorBookMarks
Структура EditorBookMarks для Delphi:
TEditorBookMarks = packed record
  Line: ^Integer;
  Cursor: ^Integer;
  ScreenLine: ^Integer;
  LeftPos: ^Integer;
  Reserved: packed array[0..3] of DWORD;
end;
PEditorBookMarks = ^TEditorBookMarks;


TEditorColor

главная | структуры
Структура EditorColor для Delphi:
TEditorColor = packed record
  StringNumber: integer;
  ColorItem: integer;
  StartPos: integer;
  EndPos: integer;
  Color: integer;
end;
PEditorColor = ^TEditorColor;


TEditorConvertPos

главная | структуры | EditorConvertPos
Структура EditorConvertPos для Delphi:
TEditorConvertPos = packed record
  StringNumber: integer;
  SrcPos: integer;
  DestPos: integer;
end;
PEditorConvertPos = ^TEditorConvertPos;


TEditorConvertText

главная | структуры | EditorConvertText
Структура EditorConvertText для Delphi:
TEditorConvertText = packed record
  Text: PChar;
  TextLength: integer;
end;
PEditorConvertText = ^TEditorConvertText;


TEditorGetString

главная | структуры | EditorGetString
Структура EditorGetString для Delphi:
TEditorGetString = packed record
  StringNumber: integer;
  StringText: PChar;
  StringEOL: PChar;
  StringLength: integer;
  SelStart: integer;
  SelEnd: integer;
end;
PEditorGetString = ^TEditorGetString;


TEditorInfo

главная | структуры | EditorInfo
Структура EditorInfo для Delphi:
TEditorInfo = packed record
  EditorID: integer;
  FileName: PChar;
  WindowSizeX: integer;
  WindowSizeY: integer;
  TotalLines: integer;
  CurLine: integer;
  CurPos: integer;
  CurTabPos: integer;
  TopScreenLine: integer;
  LeftPos: integer;
  Overtype: integer;
  BlockType: integer;
  BlockStartLine: integer;
  AnsiMode: integer;
  TableNum: integer;
  Options: DWORD;
  TabSize: integer;
  BookMarkCount: integer;
  Reserved: packed array[0..6] of DWORD;
end;
PEditorInfo = ^TEditorInfo;


TEditorSelect

главная | структуры | EditorSelect
Структура EditorSelect для Delphi:
TEditorSelect = packed record
  BlockType: integer;
  BlockStartLine: integer;
  BlockStartPos: integer;
  BlockWidth: integer;
  BlockHeight: integer;
end;
PEditorSelect = ^TEditorSelect;


TEditorSetParameter

главная | структуры | EditorSetParameter
Структура EditorSetParameter для Delphi:
TEditorSetParameter = packed record
  ParamType: integer;
  case integer of
    0: (iParam: integer);
    1: (cParam: PChar);
    2: (Reserved1: DWORD);
  Flags: DWORD;
  Reserved2: DWORD;
end;
PEditorSetParameter = ^TEditorSetParameter;


TEditorSetPosition

главная | структуры | EditorSetPosition
Структура EditorSetPosition для Delphi:
TEditorSetPosition = packed record
  CurLine: integer;
  CurPos: integer;
  CurTabPos: integer;
  TopScreenLine: integer;
  LeftPos: integer;
  Overtype: integer;
end;
PEditorSetPosition = ^TEditorSetPosition;


TEditorSetString

главная | структуры | EditorSetString
Структура EditorSetString для Delphi:
TEditorSetString = packed record
  StringNumber: integer;
  StringText: PChar;
  StringEOL: PChar;
  StringLength: integer;
end;
PEditorSetString = ^TEditorSetString;


TFarSetColors

главная | структуры | FarSetColors
Структура FarSetColors для Delphi:
TFarSetColors = packed record
  Flags: DWORD;
  StartIndex: integer;
  ColorCount: integer;
  Colors: PChar;
end;
PFarSetColors = ^TFarSetColors;


TFarDialogItem

главная | структуры
Структура FarDialogItem для Delphi:

  TFarPtr = packed record
    PtrFlags: DWORD;
    PtrLength: integer;
    PtrData: PChar;
    PtrTail: array[0..0] of char;
  end;

TFarDialogItem = packed record
  ItemType: integer;
  X1: integer;
  Y1: integer;
  X2: integer;
  Y2: integer;
  Focus: integer;
  case integer of
    0: (History: PChar);
    1: (Mask: PChar);
    2: (ListItems: PFarListItemArr);
    3: (VBuf: PCharInfo);
    4: (Selected: integer;
        Flags: DWORD;
        DefaultButton: integer;
        case integer of
          0: (Data: packed array[0..511] of char);
          1: (Ptr: TFarPtr)
       );
end;
PFarDialogItem = ^TFarDialogItem;


TFarDialogItemData

главная | структуры | FarDialogItemData
Структура FarDialogItemData для Delphi:
TFarDialogItemData = packed record
  DataLength: Integer;
  DataPtr: PChar;
end;
PFarDialogItemData = ^TFarDialogItemData;


TFarList

главная | структуры | FarList
Структура FarList для Delphi:
TFarList = packed record
  ItemsNumber: integer;
  Items: PFarListItemArr;
end;
PFarList = ^TFarList;


TFarListColors

главная | структуры | FarListColors
Структура FarListColors для Delphi:
TFarListColors = packed record
  Flags: DWORD;
  Reserved: integer;
  ColorCount: integer;
  Colors: PChar;
end;
PFarListColors = ^TFarListColors;


TFarListDelete

главная | структуры | FarListDelete
Структура FarListDelete для Delphi:
TFarListDelete = packed record
  StartIndex: integer;
  Count: integer;
end;
PFarListDelete = ^TFarListDelete;


TFarListGetItem

главная | структуры | FarListGetItem
Структура FarListGetItem для Delphi:
TFarListGetItem = packed record
  ItemIndex: integer;
  Item: FarListItem;
end;
PFarListGetItem = ^TFarListGetItem;


TFarListItem

главная | структуры FarListItem
Структура FarListItem для Delphi:
TFarListItem = packed record
  Flags: DWORD;
  Text: packed array[0..127] of char;
  Reserved: array[0..2] of DWORD;
end;
PFarListItem = ^TFarListItem;


TFarListPos

главная | структуры FarListPos
Структура FarListPos для Delphi:
TFarListPos = packed record
  SelectPos: Integer;
  TopPos: Integer;
end;
PFarListPos = ^TFarListPos;


TFarListItemData

главная | структуры FarListItemData
Структура FarListItemData для Delphi:
TFarListItemData = packed record
  Index: integer;
  DataSize: integer;
  Data: PChar;
  Reserved: DWORD;
end;
PFarListItemData = ^TFarListItemData;


TFarListTitles

главная | структуры | FarListTitles
Структура FarListTitles для Delphi:
TFarListTitles = packed record
  TitleLen: Integer;
  Title: PChar;
  BottomLen: Integer;
  Bottom: PChar;
end;
PFarListTitles = ^TFarListTitles;


TFarMenuItem

главная | структуры
Структура FarMenuItem для Delphi:
TFarMenuItem = packed record
  Text: packed array[0..127] of char;
  Selected: integer;
  Checked: integer;
  Separator: integer;
end;
PFarMenuItem = ^TFarMenuItem;


TFarMenuItemEx

главная | структуры FarMenuItemEx
Структура FarMenuItemEx для Delphi:
TFarMenuItemEx = packed record
  Flags: DWORD;
  Text: packed array[0..127] of char;
  UserData: DWORD;
end;
PFarMenuItemEx = ^TFarMenuItemEx;


TFarListFind

главная | структуры | FarListFind
Структура FarListFind для Delphi:
TFarListFind = packed record
  StartIndex: integer;
  Pattern: PChar;
  Flags: DWORD;
  Reserved: DWORD;
end;
PFarListFind = ^TFarListFind;


TFarListInfo

главная | структуры | FarListInfo
Структура FarListInfo для Delphi:
TFarListInfo = packed record
  Flags: DWORD;
  ItemsNumber: integer;
  SelectPos: integer;
  TopPos: integer;
  MaxHeight: integer;
  MaxLength: integer;
  Reserved: array[0..5] of DWORD;
end;
PFarListInfo = ^TFarListInfo;


TFarListInsert

главная | структуры | FarListInsert
Структура FarListInsert для Delphi:
TFarListInsert = packed record
  Index: integer;
  Item: TFarListItem;
end;
PFarListInsert = ^TFarListInsert;


TInfoPanelLine

главная | структуры | InfoPanelLine
Структура InfoPanelLine для Delphi:
TInfoPanelLine = packed record
  Text: packed array[0..79] of char;
  Data: packed array[0..79] of char;
  Separator: integer;
end;
PInfoPanelLine = ^TInfoPanelLine;


TKeyBarTitles

главная | структуры | KeyBarTitles
Структура KeyBarTitles для Delphi:
TKeyBarTitles = packed record
  Titles: packed array[0..11] of PChar;
  CtrlTitles: packed array[0..11] of PChar;
  AltTitles: packed array[0..11] of PChar;
  ShiftTitles: packed array[0..11] of PChar;

  CtrlShiftTitles: packed array[0..11] of PChar;
  AltShiftTitles: packed array[0..11] of PChar;
  CtrlAltTitles: packed array[0..11] of PChar;
end;
PKeyBarTitles = ^TKeyBarTitles;


TActlKeyMacro

TKeySequence

главная | структуры | KeySequence
Структура KeySequence для Delphi:
TKeySequence = packed record
  Flags: DWORD;
  Reserved: DWORD;
  Count: Integer;
  Sequence: ^DWORD;
end;
PKeySequence = ^TKeySequence;


TOpenPluginInfo

главная | структуры
Структура OpenPluginInfo для Delphi:
TOpenPluginInfo = packed record
    StructSize: integer;
    Flags: DWORD;
    HostFile: PChar;
    CurDir: PChar;
    Format: PChar;
    PanelTitle: PChar;
    InfoLines: PInfoPanelLineArr;
    InfoLinesNumber: integer;
    DescrFiles: PPCharArray;
    DescrFilesNumber: integer;
    PanelModesArray: PPanelModeArr;
    PanelModesNumber: integer;
    StartPanelMode: integer;
    StartSortMode: integer;
                  (*
                    SM_DEFAULT,
                    SM_UNSORTED,
                    SM_NAME,
                    SM_EXT,
                    SM_MTIME,
                    SM_CTIME,
                    SM_ATIME,
                    SM_SIZE,
                    SM_DESCR,
                    SM_OWNER,
                    SM_COMPRESSEDSIZE,
                    SM_NUMLINKS
                  *)
    StartSortOrder: Integer;
    KeyBar: PKeyBarTitles;
    ShortcutData: PChar;
    Reserved: DWORD;
end;
POpenPluginInfo = ^TOpenPluginInfo;


TPanelInfo

главная | структуры
Структура PanelInfo для Delphi:
TPanelInfo = packed record
    PanelType: integer;
              (*
                PTYPE_FILEPANEL,
                PTYPE_TREEPANEL,
                PTYPE_QVIEWPANEL,
                PTYPE_INFOPANEL
              *)
    Plugin: integer;
    PanelRect: TRect;
    PanelItems: PPluginPanelItemArr;
    ItemsNumber: integer;
    SelectedItems: PPluginPanelItemArr;
    SelectedItemsNumber: integer;
    CurrentItem: integer;
    TopPanelItem: integer;
    Visible: integer;
    Focus: integer;
    ViewMode: inetegr;
    ColumnTypes: packed array[0..79] of char;
    ColumnWidths: packed array[0..79] of char;
    CurDir: packed array[0..Pred(NM)] of char;
    ShortNames: integer;
    SortMode: integer;
             (*
               SM_DEFAULT,
               SM_UNSORTED,
               SM_NAME,
               SM_EXT,
               SM_MTIME,
               SM_CTIME,
               SM_ATIME,
               SM_SIZE,
               SM_DESCR,
               SM_OWNER,
               SM_COMPRESSEDSIZE,
               SM_NUMLINKS
             *)
    Reserved: packed array[0..1] of DWORD;
end;
PPanelInfo = ^TPanelInfo;


TPanelMode

главная | структуры
Структура PanelMode для Delphi:
TPanelMode = packed record
  ColumnTypes: PChar;
  ColumnWidths: PChar;
  ColumnTitles: PPCharArray;
  FullScreen: integer;
  DetailedStatus: integer;
  AlignExtensions: integer;
  CaseConversion: integer;
  StatusColumnTypes: PChar;
  StartusColumnWidths:  PChar;
  Reserved: array[0..1] of DWORD;
end;
PPanelMode = ^TPanelMode;


TPanelRedrawInfo

главная | структуры

Структура PanelRedrawInfo для Delphi:

TPanelRedrawInfo = packed record
    CurrentItem: integer;
    TopPanelItem: integer;
end;
PPanelRedrawInfo = ^TPanelRedrawInfo;


TPluginInfo

главная | структуры
Структура PluginInfo для Delphi:
TPluginInfo = packed record
  StructSize: Integer;
  Flags: DWORD;
  DiskMenuStrings: PPCharArray;
  DiskMenuNumbers: PIntegerArray;
  DiskMenuStringsNumber: integer;
  PluginMenuStrings: PPCharArray;
  PluginMenuStringsNumber: integer;
  PluginConfigStrings: PPCharArray;
  PluginConfigStringsNumber: integer;
  CommandPrefix: PChar;
end;
PPluginInfo = ^TPluginInfo;


TPluginPanelItem

главная | структуры | PluginPanelItem
Структура PluginPanelItem для Delphi:
TPluginPanelItem = packed record
  FindData: TWin32FindDataEx;
  PackSizeHigh: DWORD;
  PackSize: DWORD;
  Flags: DWORD;
  NumberOfLinks: DWORD;
  Description: PChar;
  Owner: PChar;
  CustomColumnData: PPCharArray;
  CustomColumnNumber: integer;
  UserData: DWORD;
  Reserved: array[0..2] of DWORD;
end;
PPluginPanelItem = ^TPluginPanelItem;


TPluginStartupInfo

главная | структуры | PluginStartupInfo
Структура PluginStartupInfo для Delphi:
TPluginStartupInfo = packed record
  StructSize: Integer;
  ModuleName: array[0..Pred(NM)] of char;
  ModuleNumber: integer;
  RootKey: PChar;
  Menu: TFarApiMenu;
  Dialog: TFarApiDialog;
  Message: TFarApiMessage;
  GetMsg: TFarApiGetMsg;
  Control: TFarApiControl;
  SaveScreen: TFarApiSaveScreen;
  RestoreScreen: TFarApiRestoreScreen;
  GetDirList: TFarApiGetDirList;
  GetPluginDirList: TFarApiGetPluginDirList;
  FreeDirList: TFarApiFreeDirList;
  Viewer: TFarApiViewer;
  Editor: TFarApiEditor;
  CmpName: TFarApiCmpName;
  CharTable: TFarApiCharTable;
  Text: TFarApiText;
  EditorControl: TFarApiEditorControl;
  FSF: PFarStandardFunctions;
  ShowHelp: TFarApiShowHelp;
  AdvControl: TFarApiAdvControl;
  InputBox: TFarApiInputBox;
  DialogEx: TFarApiDialogEx;
  SendDlgMessage: TFarApiSendDlgMessage;
  DefDlgProc: TFarApiDefDlgProc;
  Reserved1: DWORD;
  Reserved2: DWORD;
end;
PPluginStartupInfo = ^TPluginStartupInfo;

Где:

TFarApiMenu = function(
  PluginNumber: integer;
  X, Y: integer;
  MaxHeight: integer;
  Flags: DWORD;
  Title: PChar;
  Bottom: PChar;
  HelpTopic: PChar;
  BreakKeys: PIntArr;
  BreakCode: PIntArr;
  Items: PFarMenuItemArr;
  ItemsNumber: integer): integer; stdcall;

TFarApiDialog = function(
  PluginNumber: integer;
  X1, Y1: integer;
  X2, Y2: integer;
  HelpTopic: PChar;
  Items: PFarDialogItemArr;
  ItemsNumber: integer): integer; stdcall;

TFarApiMessage = function(
  PluginNumber: integer;
  Flags: DWORD;
  HelpTopic: PChar;
  Items: PPCharArr;
  ItemsNumber: integer;
  ButtonsNumber: integer): integer; stdcall;

TFarApiGetMsg = function(
  PluginNumber: integer;
  MsgId: integer): PChar; stdcall;

TFarApiControl = function(
  hPlugin: THandle;
  Command: integer;
  Param: pointer): integer; stdcall;

TFarApiSaveScreen = function(
  X1, Y1: integer;
  X2, Y2: integer): THandle; stdcall;

TFarApiRestoreScreen = procedure(
  hScreen: THandle); stdcall;

TFarApiGetDirList = function(
  Dir: PChar;
  var PanelItems: PPluginPanelItemArr;
  var ItemsNumber: integer): integer; stdcall;

TFarApiGetPluginDirList = function(
  PluginNumber: integer;
  hPlugin: THandle;
  Dir: PChar;
  var PanelItems: PPluginPanelItemArr;
  var ItemsNumber: integer): integer; stdcall;

TFarApiFreeDirList = procedure(
  PanelItems: PPluginPanelItemArr); stdcall;

TFarApiViewer = function(
  FileName: PChar;
  Title: PChar;
  X1, Y1: integer;
  X2, Y2: integer;
  Flags: DWORD): integer; stdcall;

TFarApiEditor = function(
  FileName: PChar;
  Title: PChar;
  X1, Y1: integer;
  X2, Y2: integer;
  Flags: DWORD;
  StartLine: integer;
  StartChar: integer): integer; stdcall;

TFarApiCmpName = function(
  Pattern: PChar;
  FileName: PChar;
  SkipPath: integer): integer; stdcall;

TFarApiCharTable = function(
  Command: integer;
  Buffer: PChar;
  BufferSize: integer): integer; stdcall;

TFarApiText = procedure(
  X, Y: integer;
  Color: integer;
  Str: PChar); stdcall;

TFarApiEditorControl = function(
  Command: integer;
  Param: pointer): integer; stdcall;

TFarApiAdvControl = function(
  ModuleNumber: integer;
  Command: integer;
  Param: pointer): integer; stdcall;

TFarApiDialogEx = function(
  PluginNumber: integer;
  X1, Y1: integer;
  X2, Y2: integer;
  HelpTopic: PChar;
  Items: PFarDialogItemArr;
  ItemsNumber: integer;
  Reserved: DWORD;
  Flags: DWORD;
  DlgProc: TFarApiWndProc;
  Param: integer): integer; stdcall;

TFarApiSendDlgMessage = function(
  hDlg: THandle;
  Msg: integer;
  Param1: integer;
  Param2: integer): integer; stdcall;

TFarApiDefDlgProc = function(
  hDlg: THandle;
  Msg: integer;
  Param1: integer;
  Param2: integer): integer; stdcall;

TFarApiInputBox = function(
  Title: PChar;
  SubTitle: PChar;
  HistoryName: PChar;
  SrcText: PChar;
  DstText: PChar;
  DstLength: integer;
  HelpTopic: PChar;
  Flags: DWORD): integer; stdcall;

TFarApiShowHelp = function(
  ModuleName: PChar;
  HelpTopic: PChar;
  Flags: DWORD): BOOL; stdcall;


TWin32FindDataEx

главная | структуры
Структура WIN32_FIND_DATA для Delphi:
TWin32FindDataEx = packed record
  dwFileAttributes: DWORD;
  ftCreationTime: TFileTime;
  ftLastAccessTime: TFileTime;
  ftLastWriteTime: TFileTime;
  nFileSizeHigh: DWORD;
  nFileSizeLow: DWORD;
  dwReserved0: DWORD;
  dwReserved1: DWORD;
  cFileName: packed array[0..MAX_PATH - 1] of AnsiChar;
  cAlternateFileName: packed array[0..13] of AnsiChar;
end;
Смотрите также:
WIN32_FIND_DATA


TWindowInfo

главная | структуры | WindowInfo
Структура WindowInfo для Delphi:
TWindowInfo = packed record
  Pos: Integer;
  Type: Integer;
  Modified: Integer;
  Current: Integer;
  TypeName: array[0..63] of char;
  Name: array[0..Pred(NM)] of char;
end;
PWindowInfo = ^TWindowInfo;


TFarInt64

главная | структуры
Структура FARINT64 для Delphi:
TFarInt64Part = packed record
    LowPart : DWORD;
    HighPart : DWORD;
end;

TFarInt64 = packed record
   case Integer of

{$IFDEF USE_DELPHI4}
         0 : (i64 : Int64);
{$ENDIF}
         1 : (Part : TFarInt64Part);
   end;


TViewerInfo

главная | структуры
Структура ViewerInfo для Delphi:
TViewerInfo = packed record
   StructSize : Integer;
   ViewerID : Integer;
   FileName : PChar;
   FileSize : TFarInt64;
   FilePos : TFarInt64;
   WindowSizeX : Integer;
   WindowSizeY : Integer;
   Options : DWORD;
   TabSize : Integer;
   CurMode : TViewerMode;
   LeftPos : Integer;
   Reserved3 : DWORD;
end;
PViewerInfo = ^TViewerInfo;


TViewerMode

главная | структуры
Структура ViewerMode для Delphi:
TViewerMode = packed record
   UseDecodeTable : Integer;
   TableNum : Integer;
   AnsiMode : Integer;
   Unicode : Integer;
   Wrap : Integer;
   WordWrap : Integer;
   Hex : Integer;
   Reserved : array [0..3] of DWORD;
end;

PViewerMode = ^TViewerMode;


TViewerSelect

главная | структуры
Структура ViewerSelect для Delphi:
TViewerSelect = packed record
    BlockStartPos : TFarInt64;
    BlockLen : Integer;
end;

PViewerSelect = ^TViewerSelect;


TViewerSetMode

главная | структуры
Структура ViewerSetMode для Delphi:
TViewerSetMode = packed record
   ParamType : Integer;

   Param : record case Integer of
      0 : (iParam : Integer);
      1 : (cParam : PChar);
   end;

   Flags : DWORD;
   Reserved : DWORD;
end;

PViewerSetMode = ^TViewerSetMode;


TViewerSetPosition

главная | структуры
Структура ViewerSetPosition для Delphi:
TViewerSetPosition = packed record
   Flags : DWORD;
   StartPos : TFarInt64;
   LeftPos : Integer;
end;

PViewerSetPosition = ^TViewerSetPosition;


Типы и определения

главная

Типы

Тип | Описание
FARWINDOWPROC | функция-обработчик окна диалога.
FRSUSERFUNC | CALLBACK-функция для FSF.FarRecursiveSearch

Макросы

Макрос | Описание
MAKEFARVERSION | генерация требуемой версии FAR Manager.

Константы

Константа | Описание
COL_* | индексы цветов в цветовой схеме (файл farcolor.hpp)
FARMACRO_KEY_EVENT | тип входного события, передаваемого во время исполнения макрокоманды.
FARMANAGERVERSION | номер версии FAR Manager.
_FAR_NO_NAMELESS_UNIONS | "Pure C".
KEY_* | коды клавиш, используемые в FAR Manager (файл farkeys.hpp)
NM | размер буфера под имя файла
OPM_* | дополнительная информация о режиме функции и месте, откуда она была вызвана
FPS__* | информация о настройках панелей
FSS__* | информация о системных настройках
FDS__* | информация о настройках описаний файлов
FCS__* | информация о настройках подтверждений
FIS__* | информация о настройках интерфейса
FDIS__* | информация о настройках диалогов
PKF_* | состояние Shift-клавиш, передаваемых в функцию ProcessKey
SM_* | метод сортировки.
Смотрите также:
Экспортируемые функции, Сервисные функции, Структуры, Поддержка архивов, Дополнения


Индексы цветов

главная | типы и определения

В этой таблице приведены индексы цветов в цветовой схеме FAR Manager, расположенной в реестре HKCU\Software\Far\Colors\CurrentPalette (файл farcolor.hpp, перечисление PaletteColors).

В колонке "Цвет" указаны шестнадцатеричные значения цвета, принятые в цветовой схеме по умолчанию.

Константа | Цвет |  | Описание
COL_DIALOGBOXTITLE | Text | 0x70 | Диалог.Рамка.Заголовок
COL_DIALOGHIGHLIGHTBOXTITLE | Text | 0x7E | Диалог.Рамка.Выделенный заголовок
COL_DIALOGBOX | Text | 0x70 | Диалог.Рамка.Обычный текст
COL_DIALOGTEXT | Text | 0x70 | Диалог.Обычный текст
COL_DIALOGHIGHLIGHTTEXT | Text | 0x7E | Диалог.Выделенный текст
COL_DIALOGDISABLED | Text | 0x78 | Диалог.Блокированный элемент диалога
COL_DIALOGSELECTEDBUTTON | Text | 0x30 | Диалог.Кнопка.Выбранный текст
COL_DIALOGHIGHLIGHTSELECTEDBUTTON | Text | 0x3E | Диалог.Кнопка.Выбранный выделенный текст
COL_DIALOGHIGHLIGHTBUTTON | Text | 0x7E | Диалог.Кнопка.Выделенный текст
COL_DIALOGBUTTON | Text | 0x70 | Диалог.Кнопка.Обычный текст
COL_DIALOGEDITUNCHANGED | Text | 0x38 | Диалог.Поле ввода.Неизмененный текст
COL_DIALOGEDITSELECTED | Text | 0x0F | Диалог.Поле ввода.Выделенного текст
COL_DIALOGEDITDISABLED | Text | 0x38 | Диалог.Поле ввода.Блокированное поле ввода
COL_DIALOGEDIT | Text | 0x30 | Диалог.Поле ввода.Обычный текст
COL_DIALOGLISTTITLE | Text | 0x70 | Диалог.Список.Заголовок
COL_DIALOGLISTSELECTEDTEXT | Text | 0x0F | Диалог.Список.Выбранный элемент
COL_DIALOGLISTSELECTEDHIGHLIGHT | Text | 0x0E | Диалог.Список.Выбранный выделенный элемент
COL_DIALOGLISTHIGHLIGHT | Text | 0x7E | Диалог.Список.Выделенный элемент
COL_DIALOGLISTBOX | Text | 0x70 | Диалог.Список.Рамка
COL_DIALOGLISTDISABLED | Text | 0x78 | Диалог.Список.Блокированный элемент
COL_DIALOGLISTSCROLLBAR | Text | 0x70 | Диалог.Список.Полоса прокрутки
COL_DIALOGLISTTEXT | Text | 0x70 | Диалог.Список.Обычный текст
COL_DIALOGCOMBOTITLE | Text | 0x3F | Диалог.Комбинированный список.Заголовок
COL_DIALOGCOMBOSELECTEDTEXT | Text | 0x0F | Диалог.Комбинированный список.Выбранный элемент
COL_DIALOGCOMBOSELECTEDHIGHLIGHT | Text | 0x0E | Диалог.Комбинированный список.Выбранный выделенный элемент
COL_DIALOGCOMBOHIGHLIGHT | Text | 0x3E | Диалог.Комбинированный список.Выделенный элемент
COL_DIALOGCOMBOBOX | Text | 0x3F | Диалог.Комбинированный список.Рамка
COL_DIALOGCOMBODISABLED | Text | 0x38 | Диалог.Комбинированный список.Блокированный элемент
COL_DIALOGCOMBOSCROLLBAR | Text | 0x3F | Диалог.Комбинированный список.Полоса прокрутки
COL_DIALOGCOMBOTEXT | Text | 0x3F | Диалог.Комбинированный список.Обычный текст элемента
COL_MENUDISABLEDTEXT | Text | 0x38 | Меню.Недоступный пункт
COL_MENUTITLE | Text | 0x3F | Меню.Заголовок
COL_MENUSELECTEDHIGHLIGHT | Text | 0x0E | Меню.Выбранный выделенный текст пункта
COL_MENUSELECTEDTEXT | Text | 0x0F | Меню.Выбранный пункт
COL_MENUHIGHLIGHT | Text | 0x3E | Меню.Выделенный пункт
COL_MENUBOX | Text | 0x3F | Меню.Рамка
COL_MENUSCROLLBAR | Text | 0x3F | Меню.Полоса прокрутки
COL_MENUTEXT | Text | 0x3F | Меню.Обычный текст пункта
COL_HMENUSELECTEDTEXT | Text | 0x0F | Горизонтальное меню.Выбранный текст
COL_HMENUSELECTEDHIGHLIGHT | Text | 0x0E | Горизонтальное меню.Выбранный выделенный текст
COL_HMENUHIGHLIGHT | Text | 0x3E | Горизонтальное меню.Выделенный текст
COL_HMENUTEXT | Text | 0x30 | Горизонтальное меню.Обычный текст
COL_KEYBARTEXT | Text | 0x30 | Линейка клавиш.Названия клавиш
COL_KEYBARNUM | Text | 0x07 | Линейка клавиш.Номера клавиш
COL_KEYBARBACKGROUND | Text | 0x07 | Линейка клавиш.Фон
COL_WARNDIALOGBOXTITLE | Text | 0x4F | Предупреждение.Заголовок рамки
COL_WARNDIALOGHIGHLIGHTTEXT | Text | 0x4E | Предупреждение.Выделенный текст
COL_WARNDIALOGLISTTITLE | Text | 0x4F | Предупреждение.Список.Заголовок
COL_WARNDIALOGLISTSELECTEDTEXT | Text | 0x70 | Предупреждение.Список.Выбранный элемент
COL_WARNDIALOGLISTSELECTEDHIGHLIGHT | Text | 0x7E | Предупреждение.Список.Выбранный выделенный элемент
COL_WARNDIALOGLISTHIGHLIGHT | Text | 0x4E | Предупреждение.Список.Выделенный элемент
COL_WARNDIALOGLISTBOX | Text | 0x4F | Предупреждение.Список.Рамка
COL_WARNDIALOGLISTDISABLED | Text | 0x48 | Предупреждение.Список.Блокированный элемент
COL_WARNDIALOGLISTSCROLLBAR | Text | 0x4F | Предупреждение.Список.Полоса прокрутки
COL_WARNDIALOGLISTTEXT | Text | 0x4F | Предупреждение.Список.Обычный текст
COL_WARNDIALOGHIGHLIGHTBOXTITLE | Text | 0x4E | Предупреждение.Рамка.Выделенный заголовок
COL_WARNDIALOGBOX | Text | 0x4F | Предупреждение.Рамка.Обычный текст
COL_WARNDIALOGDISABLED | Text | 0x48 | Предупреждение.Блокированный элемент диалога
COL_WARNDIALOGSELECTEDBUTTON | Text | 0x70 | Предупреждение.Кнопка.Выбранный текст
COL_WARNDIALOGHIGHLIGHTSELECTEDBUTTON | Text | 0x7E | Предупреждение.Кнопка.Выбранный выделенный текст
COL_WARNDIALOGHIGHLIGHTBUTTON | Text | 0x4E | Предупреждение.Кнопка.Выделенный текст
COL_WARNDIALOGBUTTON | Text | 0x4F | Предупреждение.Кнопка.Обычный текст
COL_WARNDIALOGEDITUNCHANGED | Text | 0x38 | Предупреждение.Поле ввода.Неизмененный текст
COL_WARNDIALOGEDITSELECTED | Text | 0x0F | Предупреждение.Поле ввода.Выделенного текст
COL_WARNDIALOGEDITDISABLED | Text | 0x38 | Предупреждение.Поле ввода.Блокированное поле ввода
COL_WARNDIALOGEDIT | Text | 0x30 | Предупреждение.Поле ввода.Обычный текст
COL_WARNDIALOGCOMBOTITLE | Text | 0x3F | Предупреждение.Комбинированный список.Заголовок
COL_WARNDIALOGCOMBOSELECTEDTEXT | Text | 0x0F | Предупреждение.Комбинированный список.Выбранный элемент
COL_WARNDIALOGCOMBOSELECTEDHIGHLIGHT | Text | 0x0E | Предупреждение.Комбинированный список.Выбранный выделенный элемент
COL_WARNDIALOGCOMBOHIGHLIGHT | Text | 0x3E | Предупреждение.Комбинированный список.Выделенный элемент
COL_WARNDIALOGCOMBOBOX | Text | 0x3F | Предупреждение.Комбинированный список.Рамка
COL_WARNDIALOGCOMBODISABLED | Text | 0x38 | Предупреждение.Комбинированный список.Блокированный элемент
COL_WARNDIALOGCOMBOSCROLLBAR | Text | 0x3F | Предупреждение.Комбинированный список.Полоса прокрутки
COL_WARNDIALOGCOMBOTEXT | Text | 0x3F | Предупреждение.Комбинированный список.Обычный текст элемента
COL_WARNDIALOGTEXT | Text | 0x4F | Предупреждение.Обычный текст
COL_VIEWERSELECTEDTEXT | Text | 0x30 | Просмотрщик.Выбранный текст
COL_VIEWERARROWS | Text | 0x1E | Просмотрщик.Стрелки сдвига экрана
COL_VIEWERSTATUS | Text | 0x30 | Просмотрщик.Статус
COL_VIEWERSCROLLBAR | Text | 0x1B | Просмотрщик.Полоса прокрутки
COL_VIEWERTEXT | Text | 0x1B | Просмотрщик.Обычный текст
COL_PANELHIGHLIGHTTEXT | Text | 0x17 | Панель.(не используется)
COL_PANELCOLUMNTITLE | Text | 0x1E | Панель.Заголовок колонки
COL_PANELSELECTEDTEXT | Text | 0x1E | Панель.Выбранный текст
COL_PANELSELECTEDTITLE | Text | 0x30 | Панель.Выделенный заголовок
COL_PANELSELECTEDCURSOR | Text | 0x3E | Панель.Выделенный курсор
COL_PANELINFOTEXT | Text | 0x1E | Панель.Выделенная информация
COL_PANELBOX | Text | 0x1B | Панель.Рамка
COL_PANELDRAGTEXT | Text | 0x3E | Панель.Перетаскиваемый текст
COL_PANELTOTALINFO | Text | 0x1B | Панель.Количество файлов
COL_PANELSCREENSNUMBER | Text | 0x0B | Панель.Количество фоновых экранов
COL_PANELSELECTEDINFO | Text | 0x3E | Панель.Количество выбранных файлов
COL_PANELSCROLLBAR | Text | 0x1B | Панель.Полоса прокрутки
COL_PANELTEXT | Text | 0x1B | Панель.Обычный текст
COL_PANELTITLE | Text | 0x1B | Панель.Обычный заголовок
COL_PANELCURSOR | Text | 0x30 | Панель.Обычный курсор
COL_EDITORSELECTEDTEXT | Text | 0x30 | Редактор.Выбранный текст
COL_EDITORSTATUS | Text | 0x30 | Редактор.Статус
COL_EDITORTEXT | Text | 0x1B | Редактор.Обычный текст
COL_COMMANDLINESELECTED | Text | 0x70 | Командная строка.Выделенный текст
COL_COMMANDLINEPREFIX | Text | 0x07 | Командная строка.Текст префикса
COL_COMMANDLINE | Text | 0x07 | Командная строка.Обычный текст
COL_HELPBOXTITLE | Text | 0x30 | Помощь.Заголовок рамки
COL_HELPSELECTEDTOPIC | Text | 0x0F | Помощь.Выбранная ссылка
COL_HELPHIGHLIGHTTEXT | Text | 0x3F | Помощь.Выделенный текст
COL_HELPTOPIC | Text | 0x3E | Помощь.Ссылка
COL_HELPBOX | Text | 0x30 | Помощь.Рамка
COL_HELPSCROLLBAR | Text | 0x30 | Помощь.Полоса прокрутки
COL_HELPTEXT | Text | 0x30 | Помощь.Обычный текст
COL_VIEWERCLOCK | Text | 0x30 | Часы.Просмотрщик
COL_EDITORCLOCK | Text | 0x30 | Часы.Редактор
COL_CLOCK | Text | 0x30 | Часы.Панель
COL_DIALOGLISTARROWS | Text | 0x30 | Диалог.Список.Указатели длинных строк
COL_DIALOGLISTARROWSDISABLED | Text | 0x30 | Диалог.Список.Указатели длинных строк.Блокированный элемент
COL_DIALOGLISTARROWSSELECTED | Text | 0x0E | Диалог.Список.Указатели длинных строк.Выбранный элемент
COL_DIALOGCOMBOARROWS | Text | 0x3E | Диалог.Комбинированный список.Указатели длинных строк
COL_DIALOGCOMBOARROWSDISABLED | Text | 0x38 | Диалог.Комбинированный список.Указатели длинных строк.Блокированный элемент
COL_DIALOGCOMBOARROWSSELECTED | Text | 0x0E | Диалог.Комбинированный список.Указатели длинных строк.Выбранный элемент
COL_WARNDIALOGLISTARROWS | Text | 0x4E | Предупреждение.Список.Указатели длинных строк
COL_WARNDIALOGLISTARROWSDISABLED | Text | 0x48 | Предупреждение.Список.Указатели длинных строк.Блокированный элемент
COL_WARNDIALOGLISTARROWSSELECTED | Text | 0x7E | Предупреждение.Список.Указатели длинных строк.Выбранный элемент
COL_WARNDIALOGCOMBOARROWS | Text | 0x3E | Предупреждение.Комбинированный список.Указатели длинных строк
COL_WARNDIALOGCOMBOARROWSDISABLED | Text | 0x38 | Предупреждение.Комбинированный список.Указатели длинных строк.Блокированный элемент
COL_WARNDIALOGCOMBOARROWSSELECTED | Text | 0x0E | Предупреждение.Комбинированный список.Указатели длинных строк.Выбранный элемент
COL_MENUARROWS | Text | 0x3E | Меню.Указатели длинных строк
COL_MENUARROWSDISABLED | Text | 0x38 | Меню.Указатели длинных строк.Недоступный пункт
COL_MENUARROWSSELECTED | Text | 0x0E | Меню.Указатели длинных строк.Выбранный текст пункта
COL_COMMANDLINEUSERSCREEN | Text | 0x07 | Командная строка.Пользовательский экран
COL_EDITORSCROLLBAR | Text | 0x1B | Редактор.Полоса прокрутки
COL_MENUGRAYTEXT | Text | 0x38 | Меню.Серый текст
COL_MENUSELECTEDGRAYTEXT | Text | 0x07 | Меню.Выбранный серый текст
COL_DIALOGCOMBOGRAY | Text | 0x38 | Диалог.Комбинированный список.Серый текст
COL_DIALOGCOMBOSELECTEDGRAYTEXT | Text | 0x07 | Диалог.Комбинированный список.Выбранный серый текст
COL_DIALOGLISTGRAY | Text | 0x78 | Диалог.Список.Серый цвет
COL_DIALOGLISTSELECTEDGRAYTEXT | Text | 0x07 | Диалог.Список.Выбранный серый текст
COL_WARNDIALOGCOMBOGRAY | Text | 0x38 | Предупреждение.Комбинированный список.Серый текст
COL_WARNDIALOGCOMBOSELECTEDGRAYTEXT | Text | 0x07 | Предупреждение.Комбинированный список.Выбранный серый текст
COL_WARNDIALOGLISTGRAY | Text | 0x48 | Предупреждение.Список.Серый текст
COL_WARNDIALOGLISTSELECTEDGRAYTEXT | Text | 0x70 | Предупреждение.Список.Выбранный серый текст
COL_RESERVED0 | Text | 0x00 | (зарезервировано для внутренних нужд)


Коды клавиш FAR Manager

главная | типы и определения | Виртуальные коды клавиш
В этой таблице приведены hex-коды клавиш, используемые в FAR Manager (файл farkeys.hpp, перечисление BaseDefKeyboard).

Базовый набор:

Клавиша | KEY_ | Hex | Замечания
Ctrl | KEY_CTRL | 01000000 | Левый Ctrl
Alt | KEY_ALT | 02000000 | Левый Alt
Shift | KEY_SHIFT | 04000000 |
Right Ctrl | KEY_RCTRL | 10000000 | Правый Ctrl
Right Alt | KEY_RALT | 20000000 | Правый Alt
[ | KEY_BRACKET | 0000005B |
] | KEY_BACKBRACKET | 0000005D |
, | KEY_COMMA | 0000002C |
" | KEY_QUOTE | 00000022 |
. | KEY_DOT | 0000002E |
/ | KEY_SLASH | 0000002F |
: | KEY_COLON | 0000003A |
\ | KEY_BACKSLASH | 0000005C |
Забой | KEY_BS | 00000008 |
Tab | KEY_TAB | 00000009 |
Enter | KEY_ENTER | 0000000D |
Esc | KEY_ESC | 0000001B |
Space | KEY_SPACE | 00000020 |
Break | KEY_BREAK | 00000103 | Ctrl-Pause
Page Up | KEY_PGUP | 00000121 |
Page Down | KEY_PGDN | 00000122 |
End | KEY_END | 00000123 |
Home | KEY_HOME | 00000124 |
Left | KEY_LEFT | 00000125 |
UP | KEY_UP | 00000126 |
Right | KEY_RIGHT | 00000127 |
Down | KEY_DOWN | 00000128 |
Insert | KEY_INS | 0000012D |
Delete | KEY_DEL | 0000012E |
Left Win | KEY_LWIN | 0000015B |
Right Win | KEY_RWIN | 0000015C |
Apps | KEY_APPS | 0000015D |
Numpad 0 | KEY_NUMPAD0 | 00000160 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 1 | KEY_NUMPAD1 | 00000161 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 2 | KEY_NUMPAD2 | 00000162 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 3 | KEY_NUMPAD3 | 00000163 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 4 | KEY_NUMPAD2 | 00000164 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 5 | KEY_NUMPAD5 | 00000165 | На цифровой клавиатуре
Numpad 6 | KEY_NUMPAD6 | 00000166 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 7 | KEY_NUMPAD7 | 00000167 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 8 | KEY_NUMPAD8 | 00000168 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
Numpad 9 | KEY_NUMPAD9 | 00000169 | На цифровой клавиатуре (при включенном правиле "UseNumPad")
 | KEY_CLEAR | 00000165 | Аналогичен KEY_NUMPAD5
Gray * | KEY_MULTIPLY | 0000016A | На цифровой клавиатуре
Gray + | KEY_ADD | 0000016B | На цифровой клавиатуре
Gray - | KEY_SUBTRACT | 0000016D | На цифровой клавиатуре
Gray / | KEY_DIVIDE | 0000016F | На цифровой клавиатуре
F1 | KEY_F1 | 00000170 |
F2 | KEY_F2 | 00000171 |
F3 | KEY_F3 | 00000172 |
F4 | KEY_F4 | 00000173 |
F5 | KEY_F5 | 00000174 |
F6 | KEY_F6 | 00000175 |
F7 | KEY_F7 | 00000176 |
F8 | KEY_F8 | 00000177 |
F9 | KEY_F9 | 00000178 |
F10 | KEY_F10 | 00000179 |
F11 | KEY_F11 | 0000017A |
F12 | KEY_F12 | 0000017B |
F13 | KEY_F13 | 0000017C |
F14 | KEY_F14 | 0000017D |
F15 | KEY_F15 | 0000017E |
F16 | KEY_F16 | 0000017F |
F17 | KEY_F17 | 00000180 |
F18 | KEY_F18 | 00000181 |
F19 | KEY_F19 | 00000182 |
F21 | KEY_F20 | 00000183 |
F22 | KEY_F22 | 00000184 |
F23 | KEY_F23 | 00000185 |
F24 | KEY_F24 | 00000186 |
 | KEY_BROWSER_BACK | 000001A6 | Аналог VK_BROWSER_BACK
 | KEY_BROWSER_FORWARD | 000001A7 | Аналог VK_BROWSER_FORWARD
 | KEY_BROWSER_REFRESH | 000001A8 | Аналог VK_BROWSER_REFRESH
 | KEY_BROWSER_STOP | 000001A9 | Аналог VK_BROWSER_STOP
 | KEY_BROWSER_SEARCH | 000001AA | Аналог VK_BROWSER_SEARCH
 | KEY_BROWSER_FAVORITES | 000001AB | Аналог VK_BROWSER_FAVORITES
 | KEY_BROWSER_HOME | 000001AC | Аналог VK_BROWSER_HOME
 | KEY_VOLUME_MUTE | 000001AD | Аналог VK_VOLUME_MUTE
 | KEY_VOLUME_DOWN | 000001AE | Аналог VK_VOLUME_DOWN
 | KEY_VOLUME_UP | 000001AF | Аналог VK_VOLUME_UP
 | KEY_MEDIA_NEXT_TRACK | 000001B0 | Аналог VK_MEDIA_NEXT_TRACK
 | KEY_MEDIA_PREV_TRACK | 000001B1 | Аналог VK_MEDIA_PREV_TRACK
 | KEY_MEDIA_STOP | 000001B2 | Аналог VK_MEDIA_STOP
 | KEY_MEDIA_PLAY_PAUSE | 000001B3 | Аналог VK_MEDIA_PLAY_PAUSE
 | KEY_LAUNCH_MAIL | 000001B4 | Аналог VK_LAUNCH_MAIL
 | KEY_LAUNCH_MEDIA_SELECT | 000001B5 | Аналог VK_LAUNCH_MEDIA_SELECT
 | KEY_LAUNCH_APP1 | 000001B6 | Аналог VK_LAUNCH_APP1
 | KEY_LAUNCH_APP2 | 000001B7 | Аналог VK_LAUNCH_APP2
 |  | 000001XX | Прочие специфические клавиши, имеющие виртуальный код, отличный от 0xFF, формируются по формуле: "KEY_FKEY_BEGIN" + "Виртуальный код". В макросах такие клавиши хранятся как "OemXXXXX" (здесь XXXXX виртуальный код клавиши).
 | KEY_CTRLALTSHIFTPRESS | 00000201 | Все три клавиши нажаты
 | KEY_CTRLALTSHIFTRELEASE | 00000202 | Любая из трех клавиш отпущена
 | KEY_MSWHEEL_UP | 00000203 | Прокрутка колеса мыши на одно значение вверх
 | KEY_MSWHEEL_DOWN | 00000204 | Прокрутка колеса мыши на одно значение вниз
 | KEY_NUMDEL | 00000209 | Del на цифровой клавиатуре при выключенном NumLock
 | KEY_DECIMAL | 0000020A | Del на цифровой клавиатуре при включенном NumLock
 | KEY_NUMENTER | 0000020B | Enter на цифровой клавиатуре
 | KEY_MSWHEEL_LEFT | 0000020C | Прокрутка колеса мыши на одно значение влево
 | KEY_MSWHEEL_RIGHT | 0000020D | Прокрутка колеса мыши на одно значение вправо
 | KEY_STANDBY | 0000020E | Аналог VK_SLEEP
 | KEY_MSLCLICK | 0000020F | Нажатие левой клавиши мыши (только для макросов - назначенные клавиши и в теле макропоследовательности)
 | KEY_MSRCLICK | 00000210 | Нажатие правой клавиши мыши (только для макросов - назначенные клавиши и в теле макропоследовательности)
 | KEY_MSM1CLICK | 00000211 | Нажатие средней (следующей после левой) клавиши мыши (только для макросов - назначенные клавиши и в теле макропоследовательности)
 | KEY_MSM2CLICK | 00000212 | Нажатие третей после левой клавиши мыши (только для макросов - назначенные клавиши и в теле макропоследовательности)
 | KEY_MSM3CLICK | 00000213 | Нажатие четвертой после левой клавиши мыши (только для макросов - назначенные клавиши и в теле макропоследовательности)
 | KEY_VK_0xFF_BEGIN | 00000300 | Начало определения специфических клавиш, у которых виртуальный код равен 0xFF (например, разнообразные мультимедийные клавиши, которые производители дополнительно встраивают в клавиатуру). Код формируется по формуле: "KEY_VK_0xFF_BEGIN" + ScanCode. В макросах такие клавиши хранятся как "SpecXXXXX" (здесь XXXXX сканкод клавиши).
 | KEY_VK_0xFF_END | 000003FF | Конец определения специфических клавиш.
 | KEY_NONE | 00001001 | "Холостой ход"
 | KEY_IDLE | 00001002 | "Холостой ход"
 | KEY_END_SKEY | 0000FFFF | Конец базовых определений


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

главная | Коды клавиш FAR Manager
В этой таблице приведены символические константы, шестнадцатеричные коды и клавиатурные эквиваленты для кодов виртуальных клавиш, используемых семейством операционных систем Microsoft Windows. Коды перечислены в числовом порядке.
Символическое имя | Значение (hex) | Мышиные, клавиатурные эквиваленты
VK_LBUTTON | 01 | Левая кнопка мыши
VK_RBUTTON | 02 | Правая кнопка мыши
VK_CANCEL | 03 | Обработка Control-break
VK_MBUTTON | 04 | Средняя кнопка мыши
VK_XBUTTON1 | 05 | Windows 2000/XP/2003/Vista/2008/7: кнопка мыши X1
VK_XBUTTON2 | 06 | Windows 2000/XP/2003/Vista/2008/7: кнопка мыши X2
- 07 Не определено
VK_BACK | 08 | BACKSPACE key
VK_TAB | 09 | TAB key
- 0A-0B Зарезервировано
VK_CLEAR | 0C | CLEAR key
VK_RETURN | 0D | ENTER key
- 0E-0F Не определено
VK_SHIFT | 10 | SHIFT key
VK_CONTROL | 11 | CTRL key
VK_MENU | 12 | ALT key
VK_PAUSE | 13 | PAUSE key
VK_CAPITAL | 14 | CAPS LOCK key
VK_KANA | 15 | Input Method Editor (IME) Kana mode
VK_HANGUEL | 15 | IME Hanguel mode (maintained for compatibility; use VK_HANGUL)
VK_HANGUL | 15 | IME Hangul mode
- 16 Не определено
VK_JUNJA | 17 | IME Junja mode
VK_FINAL | 18 | IME final mode
VK_HANJA | 19 | IME Hanja mode
VK_KANJI | 19 | IME Kanji mode
- 1A Не определено
VK_ESCAPE | 1B | ESC key
VK_CONVERT | 1С | IME convert (Reserved for Kanji systems)
VK_NONCONVERT | 1D | IME nonconvert (Reserved for Kanji systems)
VK_ACCEPT | 1E | IME accept (Reserved for Kanji systems)
VK_MODECHANGE | 1F | IME mode change request (Reserved for Kanji systems)
VK_SPACE | 20 | Пробел
VK_PRIOR | 21 | PAGE UP key
VK_NEXT | 22 | PAGE DOWN key
VK_END | 23 | END key
VK_HOME | 24 | HOME key
VK_LEFT | 25 | LEFT ARROW key
VK_UP | 26 | UP ARROW key
VK_RIGHT | 27 | RIGHT ARROW key
VK_DOWN | 28 | DOWN ARROW key
VK_SELECT | 29 | SELECT key
VK_PRINT | 2A | PRINT key
VK_EXECUTE | 2B | EXECUTE key
VK_SNAPSHOT | 2C | PRINT SCREEN key for Windows 3.0 and later
VK_INSERT | 2D | INS key
VK_DELETE | 2E | DEL key
VK_HELP | 2F | HELP key
VK_0 | 30 | 0 key
VK_1 | 31 | 1 key
VK_2 | 32 | 2 key
VK_3 | 33 | 3 key
VK_4 | 34 | 4 key
VK_5 | 35 | 5 key
VK_6 | 36 | 6 key
VK_7 | 37 | 7 key
VK_8 | 38 | 8 key
VK_9 | 39 | 9 key
- 3A-40 Не определено
VK_A | 41 | A key
VK_B | 42 | B key
VK_C | 43 | C key
VK_D | 44 | D key
VK_E | 45 | E key
VK_F | 46 | F key
VK_G | 47 | G key
VK_H | 48 | H key
VK_I | 49 | I key
VK_J | 4A | J key
VK_K | 4B | K key
VK_L | 4C | L key
VK_M | 4D | M key
VK_N | 4E | N key
VK_O | 4F | O key
VK_P | 50 | P key
VK_Q | 51 | Q key
VK_R | 52 | R key
VK_S | 53 | S key
VK_T | 54 | T key
VK_U | 55 | U key
VK_V | 56 | V key
VK_W | 57 | W key
VK_X | 58 | X key
VK_Y | 59 | Y key
VK_Z | 5A | Z key
VK_LWIN | 5B | Left Windows key (Microsoft Natural Keyboard)
VK_RWIN | 5C | Right Windows key (Microsoft Natural Keyboard)
VK_APPS | 5D | Applications key (Microsoft Natural Keyboard)
- 5E Зарезервировано
VK_SLEEP | 5F | Computer Sleep key
VK_NUMPAD0 | 60 | Numeric keypad 0 key
VK_NUMPAD1 | 61 | Numeric keypad 1 key
VK_NUMPAD2 | 62 | Numeric keypad 2 key
VK_NUMPAD3 | 63 | Numeric keypad 3 key
VK_NUMPAD4 | 64 | Numeric keypad 4 key
VK_NUMPAD5 | 65 | Numeric keypad 5 key
VK_NUMPAD6 | 66 | Numeric keypad 6 key
VK_NUMPAD7 | 67 | Numeric keypad 7 key
VK_NUMPAD8 | 68 | Numeric keypad 8 key
VK_NUMPAD9 | 69 | Numeric keypad 9 key
VK_MULTIPLY | 6A | Multiply key (*)
VK_ADD | 6B | Add key (+)
VK_SEPARATOR | 6C | Separator key
VK_SUBTRACT | 6D | Subtract key (-)
VK_DECIMAL | 6E | Decimal key
VK_DIVIDE | 6F | Divide key (/)
VK_F1 | 70 | F1 key
VK_F2 | 71 | F2 key
VK_F3 | 72 | F3 key
VK_F4 | 73 | F4 key
VK_F5 | 74 | F5 key
VK_F6 | 75 | F6 key
VK_F7 | 76 | F7 key
VK_F8 | 77 | F8 key
VK_F9 | 78 | F9 key
VK_F10 | 79 | F10 key
VK_F11 | 7A | F11 key
VK_F12 | 7B | F12 key
VK_F13 | 7C | F13 key
VK_F14 | 7D | F14 key
VK_F15 | 7E | F15 key
VK_F16 | 7F | F16 key
VK_F17 | 80H | F17 key
VK_F18 | 81H | F18 key
VK_F19 | 82H | F19 key
VK_F20 | 83H | F20 key
VK_F21 | 84H | F21 key
VK_F22 | 85H | F22 key
VK_F23 | 86H | F23 key
VK_F24 | 87H | F24 key
- 88-8F Не используются
VK_NUMLOCK | 90 | NUM LOCK key
VK_SCROLL | 91 | SCROLL LOCK key
VK_OEM_NEC_EQUAL | 92 | NEC PC-9800 kbd definitions: '=' key on numpad
VK_OEM_FJ_JISHO | 92 | Fujitsu/OASYS kbd definitions: 'Dictionary' key
VK_OEM_FJ_MASSHOU | 93 | Fujitsu/OASYS kbd definitions: 'Unregister word' key
VK_OEM_FJ_TOUROKU | 94 | Fujitsu/OASYS kbd definitions: 'Register word' key
VK_OEM_FJ_LOYA | 95 | Fujitsu/OASYS kbd definitions: 'Left OYAYUBI' key
VK_OEM_FJ_ROYA | 96 | Fujitsu/OASYS kbd definitions: 'Right OYAYUBI' key
- 97-9F Не используются
VK_LSHIFT | A0 | Left SHIFT key
VK_RSHIFT | A1 | Right SHIFT key
VK_LCONTROL | A2 | Left CONTROL key
VK_RCONTROL | A3 | Right CONTROL key
VK_LMENU | A4 | Left MENU key
VK_RMENU | A5 | Right MENU key
VK_BROWSER_BACK | A6 | Windows 2000/XP/2003/Vista/2008/7: Browser Back key
VK_BROWSER_FORWARD | A7 | Windows 2000/XP/2003/Vista/2008/7: Browser Forward key
VK_BROWSER_REFRESH | A8 | Windows 2000/XP/2003/Vista/2008/7: Browser Refresh key
VK_BROWSER_STOP | A9 | Windows 2000/XP/2003/Vista/2008/7: Browser Stop key
VK_BROWSER_SEARCH | AA | Windows 2000/XP/2003/Vista/2008/7: Browser Search key
VK_BROWSER_FAVORITES | AB | Windows 2000/XP/2003/Vista/2008/7: Browser Favorites key
VK_BROWSER_HOME | AC | Windows 2000/XP/2003/Vista/2008/7: Browser Start and Home key
VK_VOLUME_MUTE | AD | Windows 2000/XP/2003/Vista/2008/7: Volume Mute key
VK_VOLUME_DOWN | AE | Windows 2000/XP/2003/Vista/2008/7: Volume Down key
VK_VOLUME_UP | AF | Windows 2000/XP/2003/Vista/2008/7: Volume Up key
VK_MEDIA_NEXT_TRACK | B0 | Windows 2000/XP/2003/Vista/2008/7: Next Track key
VK_MEDIA_PREV_TRACK | B1 | Windows 2000/XP/2003/Vista/2008/7: Previous Track key
VK_MEDIA_STOP | B2 | Windows 2000/XP/2003/Vista/2008/7: Stop Media key
VK_MEDIA_PLAY_PAUSE | B3 | Windows 2000/XP/2003/Vista/2008/7: Play/Pause Media key
VK_LAUNCH_MAIL | B4 | Windows 2000/XP/2003/Vista/2008/7: Start Mail key
VK_LAUNCH_MEDIA_SELECT | B5 | Windows 2000/XP/2003/Vista/2008/7: Select Media key
VK_LAUNCH_APP1 | B6 | Windows 2000/XP/2003/Vista/2008/7: Start Application 1 key
VK_LAUNCH_APP2 | B7 | Windows 2000/XP/2003/Vista/2008/7: Start Application 2 key
- B8-B9 Зарезервировано
VK_OEM_1 | BA | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the ';:' key
VK_OEM_PLUS | BB | Windows 2000/XP/2003/Vista/2008/7: For any country/region, the '+' key
VK_OEM_COMMA | BC | Windows 2000/XP/2003/Vista/2008/7: For any country/region, the ',' key
VK_OEM_MINUS | BD | Windows 2000/XP/2003/Vista/2008/7: For any country/region, the '-' key
VK_OEM_PERIOD | BE | Windows 2000/XP/2003/Vista/2008/7: For any country/region, the '.' key
VK_OEM_2 | BF | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the '/?' key
VK_OEM_3 | C0 | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the '`~' key
- C1-D7 Зарезервировано
- D8-DA Не используются
VK_OEM_4 | DB | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the '[{' key
VK_OEM_5 | DC | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the '\|' key
VK_OEM_6 | DD | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the ']}' key
VK_OEM_7 | DE | Windows 2000/XP/2003/Vista/2008/7: For the US standard keyboard, the 'single-quote/double-quote' key
VK_OEM_8 | DF | Used for miscellaneous characters; it can vary by keyboard.
- E0 Зарезервировано
E1 | OEM specific
VK_OEM_102 | E2 | Windows 2000/XP/2003/Vista/2008/7: Either the angle bracket key or the backslash key on the RT 102-key keyboard
- E3-E4 OEM specific
VK_PROCESSKEY | E5 | Windows 95/98/Me, Windows 2000/XP/2003/Vista/2008/7: IME PROCESS key
- E6 OEM specific
VK_PACKET | E7 | Windows 2000/XP/2003/Vista/2008/7: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT , SendInput , WM_KEYDOWN , and WM_KEYUP
- E8 Не используется
VK_OEM_RESET | E9 | Only used by Nokia.
VK_OEM_JUMP | EA | Only used by Nokia.
VK_OEM_PA1 | EB | Only used by Nokia.
VK_OEM_PA2 | EC | Only used by Nokia.
VK_OEM_PA3 | ED | Only used by Nokia.
VK_OEM_WSCTRL | EE | Only used by Nokia.
VK_OEM_CUSEL | EF | Only used by Nokia.
VK_OEM_ATTN | F0 | Only used by Nokia.
VK_OEM_FINNISH | F1 | Only used by Nokia.
VK_OEM_COPY | F2 | Only used by Nokia.
VK_OEM_AUTO | F3 | Only used by Nokia.
VK_OEM_ENLW | F4 | Only used by Nokia.
VK_OEM_BACKTAB | F5 | Only used by Nokia.
VK_ATTN | F6 | Attn key
VK_CRSEL | F7 | CrSel key
VK_EXSEL | F8 | ExSel key
VK_EREOF | F9 | Erase EOF key
VK_PLAY | FA | Play key
VK_ZOOM | FB | Zoom key
VK_NONAME | FC | Reserved for future use.
VK_PA1 | FD | PA1 key
VK_OEM_CLEAR | FE | Clear key
FF | Мультимедийные клавиши. См. ScanCode клавиши.


Operation mode

главная | типы и определения
Параметр OpMode передает плагину дополнительную информацию о режиме функции и месте, откуда она была вызвана. OpMode может быть комбинацией следующих констант (перечисление OPERATION_MODES):
Метод | Описание
OPM_SILENT | Плагин должен минимизировать запросы пользователя по возможности, так как вызываемая функция - это часть более комплексной операции.
OPM_FIND | Функция плагина была вызвана из Диалога поиска файлов, или другой команды, сканирующей каталоги. Экранный вывод должен быть минимизирован.
OPM_VIEW | Функция плагина вызвана как часть операции просмотра файла. Если файл просматривается на панели быстрого просмотра, то OPM_VIEW используется совместно с OPM_QUICKVIEW.
OPM_QUICKVIEW | Функция плагина вызвана как часть операции просмотра файла на панели быстрого просмотра (пользователь нажал Ctrl-Q в панелях)
OPM_EDIT | Функция плагина вызвана как часть операции редактирования файла.
OPM_DESCR | Функция была вызвана для запроса или для изменения файла и его описания.
OPM_TOPLEVEL | Все файлы в плагине будут обработаны. Этот флаг устанавливается во время обработки команд Shift-F2 и Shift-F3 вне базового файла плагина. Переданный в функцию плагина список также содержит всю необходимую информацию, поэтому плагин может игнорировать этот флаг, или же повысить скорость операции.
Смотрите также:
SetDirectory, PutFiles, ProcessHostFile, GetFiles, DeleteFiles, GetFindData, MakeDirectory


Метод сортировки

главная | типы и определения

Метод сортировки может принимать одно из следующих значений (перечисление OPENPLUGININFO_SORTMODES):
Метод | Описание
SM_DEFAULT | Сортировка по умолчанию
SM_UNSORTED | Без сортировки
SM_NAME | По имени
SM_EXT | По расширению
SM_MTIME | По дате модификации файла
SM_CTIME | По дате создания файла
SM_ATIME | По дате последнего доступа
SM_SIZE | По размеру
SM_DESCR | По описанию
SM_OWNER | По владельцу
SM_COMPRESSEDSIZE | По сжатому размеру
SM_NUMLINKS | По количеству связей файлов

Смотрите также:


FAR_PKF_FLAGS

главная | типы и определения
Перечисление FAR_PKF_FLAGS описывает состояние Shift-клавиш, передаваемых в функцию ProcessKey.
Флаг | Описание
PKF_CONTROL | Клавиша Ctrl нажата
PKF_ALT | Клавиша Alt нажата
PKF_SHIFT | Клавиша Shift нажата
PKF_PREPROCESS | Идет препроцесс - FAR передает "сырую" клавишу. Этот флаг применяется только к виртуальному коду клавиши (второй параметр функции ProcessKey)

Замечания

  • Начиная с FAR Manager 1.70 build 2052 сняты ограничения на передаваемые плагину клавиши (см. замечание к функции ProcessKey). Если флаг PKF_PREPROCESS выставлен, то плагин может игнорировать вызов функции ProcessKey. В этом случае FAR, по окончании ввода сформирует нужную команду и передаст плагину.
    Например, если пользователь в командной строке вводит "cd ..Enter", то плагин получит последовательность "80043h 80044h 80020h 800BEh 800BEh 8000Dh" (к каждому виртуальному коду добавляется флаг PKF_PREPROCESS).
    В этом случае Здесь 2 варианта развития событий:
    1. плагин сам обрабатывает эту последовательность;
    2. плагин игнорирует вызовы функции ProcessKey с выставленным флагом PKF_PREPROCESS и ждет, когда FAR передаст плагину готовый результат.
Смотрите также:
ProcessKey


_FAR_NO_NAMELESS_UNIONS

главная | типы и определения
Mакроопределение _FAR_NO_NAMELESS_UNIONS определяет, будут ли в структуре FarDialogItem использоваться неименованные объединения (union). Такие конструкции допустимы стандартом C++, но не в ANSI C.

Если не определено макроопределение _FAR_NO_NAMELESS_UNIONS, структура FarDialogItem имеет вид, совместимый с FAR 1.65 и FAR 1.70 beta 3 и более ранними. При этом структура FarDialogItem будет иметь следующий вид:

struct FarDialogItem
{
  ...
  union {
    int Selected;
    char *History;
    char *Mask;
    struct FarList *ListItems;
    CHAR_INFO *VBuf;
  };
  ...
  union {
    char Data[512];

    struct {
      DWORD PtrFlags;
      int   PtrLength;
      char *PtrData;
      char  PtrTail[1];
    } Ptr;
  };
};
Таким образом, для обращения, например, к полю Data структуры FarDialogItem достаточно будет писать Data, а к полю Selected - Selected.

Если определено макроопределение _FAR_NO_NAMELESS_UNIONS, в структуре будут использоваться именованные объединения. При этом структура будет совместима с компиляторами ANSI C, но не будет совместима на уровне исходных текстов с плагинами, написанными для FAR 1.65. Структура будет иметь следующий вид:

struct FarDialogItem
{
  ...
  union {
    int Selected;
    char *History;
    char *Mask;
    struct FarList *ListItems;
    CHAR_INFO *VBuf;
  } Param;
  ...
  union {
    char Data[512];

    struct {
      DWORD PtrFlags;
      int   PtrLength;
      char *PtrData;
      char  PtrTail[1];
    } Ptr;
  } Data;
};

В этом случае для обращения, например, к полю Data структуры необходимо будет писать Data.Data, а к полю Selected - Param.Selected.

То или иное макроопределение должна быть объявлено перед директивой #include "plugin.hpp":

#define _FAR_NO_NAMELESS_UNIONS
#include "plugin.hpp"

Внимание! Внимание!

  • В FAR 1.70 beta 4 умолчанием является вариант, совместимый со старыми плагинами, то есть, _FAR_NO_NAMELESS_UNIONS не определено. Однако в FAR 1.70 release умолчанием станет новый вариант структуры - _FAR_NO_NAMELESS_UNIONS. Поэтому если вы хотите, чтобы ваши плагины были совместимы с версией 1.70 release, вы можете уже сейчас добавить константу _FAR_NO_NAMELESS_UNIONS и внести соответствующие модификации в исходный код ваших плагинов.
Смотрите также:
GetMinFarVersion


FARMANAGERVERSION

главная | типы и определения
Константа FARMANAGERVERSION определяет текущий номер версии FAR Manager и имеет следующий формат - 0xBBBBXXYY:

BBBB = номер билда (343 = 0x0157)
XX = major version (FAR 1.70 = 0x01)
YY = minor version (FAR 1.70 = 0x46)

Т.о. для FAR Manager 1.70 beta 3 build 343 эта константа будет равна: 0x01570146

Константа FARMANAGERVERSION формируется с помощью макроса MAKEFARVERSION

Смотрите также:
GetMinFarVersion


MAKEFARVERSION

главная | типы и определения
Макрос MAKEFARVERSION предназначен для возврата минимально требуемой для плагина версии FAR Manager в функции GetMinFarVersion.
MAKEFARVERSION(major,minor,build)
Смотрите также:
GetMinFarVersion


FarConfirmationsSettings

главная | типы и определения

Информация о настройках подтверждений (перечисление FarConfirmationsSettings). Соответствует настройкам диалога "Подтверждения".
Константа | Описание
FCS_COPYOVERWRITE | "Перезапись файлов при копировании"
FCS_MOVEOVERWRITE | "Перезапись файлов при переносе"
FCS_DRAGANDDROP | "Перетаскивание"
FCS_DELETE | "Удаление"
FCS_DELETENONEMPTYFOLDERS | "Удаление непустых папок"
FCS_INTERRUPTOPERATION | "Прерывание операций (Esc)"
FCS_DISCONNECTNETWORKDRIVE | "Отключение сетевого устройства"
FCS_RELOADEDITEDFILE | "Повторное открытие файла в редакторе"
FCS_CLEARHISTORYLIST | "Очистка списка истории"
FCS_EXIT | "Выход"

Смотрите также:
ACTL_GETCONFIRMATIONS


FarInterfaceSettings

главная | типы и определения

Информация о настройках интерфейса (перечисление FarInterfaceSettings). Соответствует настройкам диалога "Настройки интерфейса".
Константа | Описание
FIS_CLOCKINPANELS | "Часы в панелях"
FIS_CLOCKINVIEWERANDEDITOR | "Часы при редактировании и просмотре"
FIS_MOUSE | "Использовать мышь"
FIS_SHOWKEYBAR | "Показывать линейку клавиш"
FIS_ALWAYSSHOWMENUBAR | "Показывать меню вверху экрана, даже когда оно неактивно"
FIS_USERIGHTALTASALTGR | "Использовать правый Alt как AltGr"
FIS_SHOWTOTALCOPYPROGRESSINDICATOR | "Показывать общий индикатор копирования"
FIS_SHOWCOPYINGTIMEINFO | "Показывать информацию о времени копирования"
FIS_USECTRLPGUPTOCHANGEDRIVE | "Использовать Ctrl-PgUp для выбора диска"

Смотрите также:
ACTL_GETINTERFACESETTINGS


FarDialogSettings

главная | типы и определения

Информация о настройках диалогов (перечисление FarDialogSettings). Соответствует настройкам диалога "Настройки диалогов".
Константа | Описание
FDIS_AUTOCOMPLETEININPUTLINES | "Автозавершение в строках ввода"
FDIS_HISTORYINDIALOGEDITCONTROLS | "История в строках ввода диалогов" (сохранять историю в строках ввода некоторых диалогов FAR.)
FDIS_PERSISTENTBLOCKSINEDITCONTROLS | "Постоянные блоки в строках ввода"
FDIS_BSDELETEUNCHANGEDTEXT | "Backspace удаляет неизмененный текст". Если опция включена, то нажатие клавиши BackSpace в неизмененной текстовой строке удаляет всю строку, как если бы нажали клавишу Del.
FDIS_DELREMOVESBLOCKS | "Del удаляет блоки в строках ввода"
FDIS_MOUSECLICKOUTSIDECLOSESDIALOG | "Клик мыши вне диалога закрывает диалог"

Смотрите также:
ACTL_GETDIALOGSETTINGS


FarDescriptionSettings

главная | типы и определения

Информация о настройках описаний файлов (перечисление FarDescriptionSettings). Соответствует настройкам диалога "Описания файлов".
Константа | Описание
FDS_SETHIDDEN | "Устанавливать атрибут "Hidden" на новые списки описаний"
FDS_UPDATEALWAYS | "Всегда обновлять"
FDS_UPDATEIFDISPLAYED | "Обновлять, если они выводятся на экран"
FDS_UPDATEREADONLY | "Обновлять файл описаний с атрибутом "Только для чтения""

Замечания

Флаги FDS_UPDATEALWAYS и FDS_UPDATEIFDISPLAYED взаимоисключающие.

Смотрите также:
ACTL_GETDESCSETTINGS


FarSystemSettings

главная | типы и определения

Информация о системных настройках (перечисление FarSystemSettings). Соответствует настройкам диалога "Системные параметры".
Константа | Описание
FSS_CLEARROATTRIBUTE | "Снимать атрибут R/O c CD файлов"
FSS_DELETETORECYCLEBIN | "Удалять в Корзину"
FSS_USESYSTEMCOPYROUTINE | "Использовать системную функцию копирования"
FSS_COPYFILESOPENEDFORWRITING | "Копировать открытые для записи файлы"
FSS_SCANSYMLINK | "Сканировать символические связи"
FSS_CREATEFOLDERSINUPPERCASE | "Создавать папки заглавными буквами"
FSS_SAVECOMMANDSHISTORY | "Сохранять историю команд"
FSS_SAVEFOLDERSHISTORY | "Сохранять историю папок"
FSS_SAVEVIEWANDEDITHISTORY | "Сохранять историю просмотра и редактора"
FSS_USEWINDOWSREGISTEREDTYPES | "Использовать стандартные типы файлов"
FSS_AUTOSAVESETUP | "Автозапись конфигурации"

Смотрите также:
ACTL_GETSYSTEMSETTINGS


FarPanelSettings

главная | типы и определения

Информация о настройках панелей (перечисление FarPanelSettings). Соответствует настройкам диалога "Настройки панели".
Константа | Описание
FPS_SHOWHIDDENANDSYSTEMFILES | "Показывать скрытые и системные файлы"
FPS_HIGHLIGHTFILES | "Раскраска файлов"
FPS_AUTOCHANGEFOLDER | "Автосмена папки"
FPS_SELECTFOLDERS | "Пометка папок"
FPS_ALLOWREVERSESORTMODES | "Разрешить обратную сортировку"
FPS_SHOWCOLUMNTITLES | "Показывать заголовки колонок"
FPS_SHOWSTATUSLINE | "Показывать строку статуса"
FPS_SHOWFILESTOTALINFORMATION | "Показывать суммарную информацию"
FPS_SHOWFREESIZE | "Показывать свободное место"
FPS_SHOWSCROLLBAR | "Показывать полосу прокрутки"
FPS_SHOWBACKGROUNDSCREENSNUMBER | "Показывать количество фоновых экранов"
FPS_SHOWSORTMODELETTER | "Показывать букву режима сортировки"

Смотрите также:
ACTL_GETPANELSETTINGS


Маски файлов

главная

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

Метасимвол | Описание
* | Любое количество символов
? | Любой символ
[c,x-z] | Любой символ из находящихся в квадратных скобках. Допускаются и отдельные символы, и их диапазоны.

Например, файлы ftp.exe, fc.exe и f.ext могут быть выбраны с помощью маски f*.ex?, маска *co* выберет и color.ini, и edit.com, маска [c-f,t]*.txt может выбрать config.txt, demo.txt, faq.txt и tips.txt.

Во многих командах FAR можно задать несколько разделенных запятыми или точкой с запятой масок. Например, чтобы выбрать все документы, вы можете ввести *.doc,*.txt,*.wri в команде "Пометить группу".

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

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

Примеры использования масок исключения:

  1. *.cpp
    Все файлы с расширением cpp.
  2. *.*|*.bak,*.tmp
    Все файлы, кроме файлов с расширением bak и tmp.
  3. *.*|
    Ошибка - введен спецсимвол '|', но сама маска исключения не указана.
  4. *.*|*.bak|*.tmp
    Ошибка - спецсимвол '|' не может встречаться более одного раза.
  5. |*.bak
    Обрабатывается как '*|*.bak'


Синтаксис тем помощи

главная | Файлы помощи
Параметр HelpTopic, описывающий тему помощи, может имеет один из следующих форматов:
Формат | Описание
"Topic" | Ссылка на тему в файле помощи плагина.
":Topic" | Ссылка на тему из основного файла помощи FAR.
"<FullPath>Topic" Абсолютная ссылка на тему в файле помощи, находящемся в каталоге FullPath. Путь задается c заключительным слешем. Например, плагин Foo располагается в каталоге 'D:\FAR\Plugins\Foo' и нам надо показать тему помощи 'FooInfo' из хелпа по этому плагину:
"<D:\FAR\Plugins\Foo\>FooInfo"
"<FullModuleName>Topic" Абсолютная ссылка на тему в файле помощи, находящемся в том же каталоге, где находится плагин с именем DLL-модуля FullModuleName. Например, для плагина Foo 'D:\FAR\Plugins\Foo\Foo.dll' необходимо показать тему помощи 'FooInfo' из хелпа по этому плагину:
"<D:\FAR\Plugins\Foo\Foo.dll>FooInfo"
Смотрите также:
ShowHelp, Dialog, DialogEx, DN_HELP, InputBox, Menu, Message


Языки и файлы помощи

главная

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

Все *.lng и *.hlf файлы в каталоге с FAR`ом, во всех подкаталогах папки Plugins считаются как языковые файлы и файлы подсказки. Управляющий элемент .Language задает язык.

Формат | Описание
Управляющие элементы | описание управляющих элементов в языковых файлах и в файлах подсказки
Языковые файлы | описание синтаксиса языковых файлов
Файлы помощи | описание синтаксиса файлов подсказки
Смотрите также:
"Локализация плагинов второго уровня"


Управляющие элементы

главная | языковая поддержка
В начале языковых файлов и в файлах подсказки могут содержаться следующие управляющие элементы, начинающиеся с точки.
Управляющий элемент Описание
.Language
.Language=<Language name>,<Language description>
Этим элементом должен начинаться любой файл помощи или поддержки языка.
<Language name>
описывает файловый язык и должен быть стандартным языковым именем (на английском). Все файлы с тем же языком должны иметь то же значение <Language name>.
<Language description>
может содержать языковое описание в любой форме. Эта строка отобразится в меню Languages (Языки).
.PluginContents
.PluginContents=<Contents topic name>

Это дополнительное утверждение может использоваться для добавления <Contents topic name> в список помощи плагинов (отображается в помощи FAR нажатием Shift-F2). После выбора этого пункта будет показана тема Contents (см. раздел "Файлы помощи" относительно темы Contents).

.Options
.Options <KeyName>=<Value>
Это дополнительное утверждение может использоваться для указания дополнительных опций в файлах помощи. Таких утверждений может быть несколько.
<KeyName>
Одно из следующих значений:
  • CtrlColorChar
    Значение <Value> содержит символ, с помощью которого будет указан цветовой атрибут (см. раздел "Файлы помощи" относительно темы CtrlColorChar). Например, утверждение:
    .Options CtrlColorChar=\
    говорит о том, что для спецсимвола, указывающего на цветовые атрибуты будет использоваться символ \.

  • TabSize
    <Value> указывает на размер табуляции в HLF-файле. Может быть от 1 до 16. По умолчанию равно 8.

  • CtrlStartPosChar
    Значение <Value> содержит символ, с помощью которого будет указано с какой позиции начинать последующие строки. Например, утверждение:
    .Options CtrlStartPosChar=&
    говорит о том, что спецсимволом позиции переноса будет символ '&', тогда
    пункт 1 - &папа у Васи силен в математике, учится папа за Васю весь год.
    выравнивается так:
    _пункт 1 - папа у Васи силен в математике, учится папа
           за Васю весь год.

Пример:

.Language=Russian,Russian (Русский)
.PluginContents=FTP клиент
@Contents
$ #FTP клиент#
   ~Подключение к FTP серверу~@FTPConnect@

   ~Работа с именами серверов~@FTPNames@

   ~Команды FTP клиента~@FTPCmd@

   ~Конфигурация FTP клиента~@FTPCfg@

   ~Режимы панели FTP клиента~@FTPPanel
Смотрите также:
Языковая поддержка, Файлы помощи


Языковые файлы

главная | языковая поддержка | GetMsg

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

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

Все сообщения, не начинающиеся с двойной кавычки или точки считаются комментариями и игнорируются. Ведущие пробелы перед строкой игнорируются.

.Language=Russian,Russian (Русский)
"Пожалуйста зарегистрируйте вашу копию"
"Зарегистрирован"
"Да"
"Нет"
:
//functional keys - 6 characters max
"Помощь"
"ПользМ"
:
"Группы"
"Выбран"
//End of functional keys

Примечание

  1. При использовании кавычек в сообщениях не обязательно ставить обратный слеш и дублировать кавычки. FAR Manager, обрабатывая каждую строку из языкового файла, смотрит только на начальную и заключительную кавычки. Например,
    "Option "Autodetect character table" is off."
"Copy \"%.55s\" to"
    обе строки являются корректными;
  2. длина строки - не более 1000 символов;
  3. строку нельзя разбивать на подстроки;
  4. допускается применение следующих управляющих символов: '\n', '\r', '\\', '\b', '\t'
Смотрите также:
Управляющие элементы, Языковая поддержка, GetMsg


Файлы помощи

главная | языковая поддержка

Синтаксис Help-файла.

В файлах подсказки могут содержаться следующие управляющие элементы.
Управляющий элемент | Описание
@Topic (в начале строки) Начать определение темы Topic. Существуют 4 предопределенных темы:
  1. Тема с именем Contents имеет специальное назначение. Она вызывается при нажатии клавиши F1 из командной строки FAR или при выборе пункта из списка помощи плагинов.
  2. Если плагин "умеет настраиваться", то желательно в качестве имени темы помощи для диалога настройки указать Config. Эта тема будет также вызываться , когда пользователь нажмет клавишу F1 в меню конфигурации плагинов (Options|Plugins configuration)
  3. Если плагин умеет работать и в панелях и в редакторе/программе просмотра, но при этом выполняет разные действия, то имеет смысл в HLF-файлах использовать две предопределенных темы: Editor и Viewer (для редактора и программы просмотра, соответственно). В этом случае Shift-F1 в списке плагинов в редакторе/программе просмотра покажет тему помощи Editor/Viewer.
$Text (в начале строки) | Определяет непрокручиваемую область помощи. Можно указывать несколько идущих подряд строк для не прокручиваемой области, но все эти строки должны идти сразу после определения темы (символа '@').
~Text~@Topic@ Ссылка на тему. Если вы желаете поставить ссылку на тему из основного файла помощи FAR, то перед именем темы поставьте символ ':'.
Ссылка должна располагаться в одной строке.
~Text~@<FullPath>Topic@ Абсолютная или относительная ссылка на тему в файле помощи, находящемся в каталоге FullPath. Путь задается c заключительным слешем.
Ссылка должна располагаться в одной строке.
Например, плагин Foo располагается в каталоге 'D:\FAR\Plugins\Foo' и нам надо показать тему помощи 'FooInfo' из хелпа по этому плагину.
~Информации о плагине Foo~@<D:\FAR\Plugins\Foo\>FooInfo@
~Text~@<FullModuleName>Topic@ Абсолютная или относительная ссылка на тему в файле помощи, находящемся в том же каталоге, где находится плагин FullModuleName.
Ссылка должна располагаться в одной строке.
Например, для плагина Foo 'D:\FAR\Plugins\Foo\Foo.dll' необходимо показать тему помощи 'FooInfo' из хелпа по этому плагину.
~Информации о плагине Foo~@<D:\FAR\Plugins\Foo\Foo.dll>FooInfo@
~Text~@URL@ URL-активатор - запуск приложений, поддерживающих URL-протоколы. Под URL-приложениями понимаются такие приложения, которые поддерживают протоколы, подобные этим:
~доступ к файлам~@file://C:\Program Files\Far\License.xUSSR.txt@
~передача файлов по FTP~@ftp://ftp.kgb.ru/WinUtil/Rar/@
~HTTP~@http://plugring.farmanager.com/@
~MailTo~@mailto:vskirdin@@mail.ru@
~News~@news://fido7.far.support@
~Telnet~@telnet://fido7.far.support@
Должно располагаться в одной строке.
#Text# | Выделенный текст Text.
^ (в начале строки или после $) | Центрирование строки.
@- (в начале строки) | Отключает автоформатирование текста. По умолчанию FAR форматирует все строки, которые в тексте начинаются с первой позиции. Должен находится в отдельной строке.
@+ (в начале строки) | Включает автоформатирование текста. Должен находится в отдельной строке.
<CtrlColorChar>XX Задает цветовые атрибуты, которыми будет отрисован следующий за этой конструкцией текст. Цветовые атрибуты XX - две шестнадцатеричных цифры (0-9A-F).
Например, в качестве управляющего кода <CtrlColorChar> был задан символ '\'. Тогда конструкция \4F заставит менеджер помощи рисовать следующий за приведенной конструкцией текст белыми буквами на темно-красном фоне.
(см. CtrlColorChar)
<CtrlColorChar>- Устанавливает цветовые атрибуты в предустановленный цвет.
(см. CtrlColorChar)

Замечания:

  1. Длина каждой строки в hlf-файле не должна превышать 300 символов.
  2. Если Вам необходимо показать символы ~, # или @, то продублируйте их.
  3. Для URL-активаторов в ссылке (поле <URL>) символы ~ и # могут дублироваться или не дублироваться, символ @ - - всегда дублируется. Если в ссылке должно присутствовать два идущих подряд символа ~ или #, то укажите последовательность из 3 или 4 символов (например, ~~~ или ~~~~ будет восприниматься как ~~)
  4. Не используйте внутри ссылки (если ссылка не URL-активатор!) служебные символы (~, # и @).

Пример:

Данный пример взят из файла FarRus.hlf.
@FolderShortcuts
$ #Ссылки на папки#
    Ссылки на папки позволяют обеспечить быстрый доступ к часто
используемым папкам. Для создания ссылки на текущую папку нужно
нажать Ctrl-Shift-<N>, где N - '0'..'9'. После этого, чтобы перейти
в папку, записанную в ссылке, достаточно нажать ПравыйCtrl-<N>.

    Пункт #Ссылки на папки# в ~Меню команд~@CmdMenu@ позволяет
просматривать, устанавливать, редактировать и удалять ссылки на папки.
Это выглядит так:

Следующие примеры показывают оформление URL-активаторов.
Активизация E-mail клиента:

~vskirdin@@mail.ru~@mailto:vskirdin@@mail.ru@

Активизация браузера:

Активизация браузера:

~http://plugring.farmanager.com/~@plugring.farmanager.com/@
или
~http://www.uic.nnov.ru/~~ruiv/plugring/~@http://www.uic.nnov.ru/~ruiv/plugring/@

Следующие примеры показывают использование цветовых атрибутов:

.Language=Russian,Russian (Русский)
.PluginContents=Игра Реверси
.Options CtrlColorChar=\

...

@-
         Реверси, также известная как Othello, является игрой
 \70 B \-\2F W \-  стратегией, в которую играют два игрока:  Черный и
 \2F W \-\70 B \-  #Белый#.  Игра происходит на поле 8х8 клеток с
         применением 64-х двухцветных фишек.
@+
Это выглядит так:
Смотрите также:
Управляющие элементы, Языковые файлы


Структуры и функции Win32

главная

В данном разделе приведены "вольные" переводы некоторых часто используемых структур и функций из WinAPI.

Функции Win32:

Функция | Описание
GetFileTime | возвращает дату и время создания, модификации и последнего доступа к файлу
PeekConsoleInput | считывает данные из указанного консольного входного буфера без удаления
ReadConsoleInput | считывает данные из входного буфера консоли и удаляет их оттуда
SetFileApisToAnsi | указывает набору файловых функций Win32 использовать кодировку ANSI
SetFileApisToOem | указывает набору файловых функций Win32 использовать кодировку OEM
SetFileTime | устанавливает дату и время создания, модификации и последнего доступа к файлу
WriteConsoleInput | записывает данные непосредственно в консольный входной буфер

Структуры Win32:

Структура | Описание
CHAR_INFO | определяет код символа и цветовые атрибуты экранной символьной ячейки
CONSOLE_CURSOR_INFO | содержит информацию о консольном курсоре
COORD | определяет координаты ячейки символа в консольном буфере экрана
FILETIME | число сто-наносекундных интервалов, прошедших с 1 января 1601 года
FOCUS_EVENT_RECORD | содержит сообщения фокуса; является членом структуры INPUT_RECORD
INPUT_RECORD | информация о входных сообщениях в консольном входном буфере
KEY_EVENT_RECORD | клавиатурные события консоли; является членом структуры INPUT_RECORD
MENU_EVENT_RECORD | сообщения меню; является членом структуры INPUT_RECORD
MOUSE_EVENT_RECORD | информация о сообщениях мыши в консольном окне; является членом структуры INPUT_RECORD
RECT | определяет координаты левого верхнего и правого нижнего углов прямоугольника
SMALL_RECT | определяет координаты левого верхнего и правого нижнего углов прямоугольника
SYSTEMTIME | хранит дату и время, используя отдельные поля для месяца, дня, года, дня недели, часов, минут, секунд и миллисекунд
WIN32_FIND_DATA | описывает файл, найденный функциями FindFirstFile, FindFirstFileEx или FindNextFile
WINDOW_BUFFER_SIZE_RECORD | информация об изменениях размеров экранного буфера консоли; является членом структуры INPUT_RECORD

Константы Win32:

Константа | Описание
Virtualkeycodes | виртуальные коды клавиш
Смотрите также:


Структуры Win32

Структуры и функции Win32

главная
Структура | Описание
CHAR_INFO | определяет код символа и цветовые атрибуты экранной символьной ячейки
CONSOLE_CURSOR_INFO | содержит информацию о консольном курсоре.
COORD | определяет координаты ячейки символа в консольном буфере экрана
FILETIME | число сто-наносекундных интервалов, прошедших с 1 января 1601 года
FOCUS_EVENT_RECORD | содержит сообщения фокуса; является членом структуры INPUT_RECORD
INPUT_RECORD | информация о входных сообщениях в консольном входном буфере
KEY_EVENT_RECORD | клавиатурные события консоли; является членом структуры INPUT_RECORD
MENU_EVENT_RECORD | сообщения меню; является членом структуры INPUT_RECORD
MOUSE_EVENT_RECORD | информация о сообщениях мыши в консольном окне; является членом структуры INPUT_RECORD
RECT | определяет координаты левого верхнего и правого нижнего углов прямоугольника
SMALL_RECT | определяет координаты левого верхнего и правого нижнего углов прямоугольника
SYSTEMTIME | хранит дату и время, используя отдельные поля для месяца, дня, года, дня недели, часов, минут, секунд и миллисекунд.
WIN32_FIND_DATA | описывает файл, найденный функциями FindFirstFile, FindFirstFileEx или FindNextFile
WINDOW_BUFFER_SIZE_RECORD | информация об изменениях размеров экранного буфера консоли; является членом структуры INPUT_RECORD
Смотрите также:


CHAR_INFO

главная | структуры | win32 структуры

Структура CHAR_INFO определяет Unicode- или ANSI-код символа и цветовые атрибуты (передний план и фон) экранной символьной ячейки. Эта структура используется консольными функциями для чтения и записи в консольный экранный буфер.

typedef struct _CHAR_INFO {
  // Unicode or ANSI character
  union {
      WCHAR UnicodeChar;
      CHAR AsciiChar;
  } Char;

  // Text and background colors
  WORD Attributes;
} CHAR_INFO, *PCHAR_INFO;

Элементы

Char
Определяет Unicode- или ANSI-код символа экранной ячейки в зависимости от используемых функций (Unicode или ANSI).
Attributes
Атрибуты можно разделить на два класса: цвет и DBCS. Все константы определены в заголовочном файле Wincon.h:
Атрибут | Описание
FOREGROUND_BLUE | Цвет текста содержит синий.
FOREGROUND_GREEN | Цвет текста содержит зеленый.
FOREGROUND_RED | Цвет текста содержит красный.
FOREGROUND_INTENSITY | Цвет текста усилен.
BACKGROUND_BLUE | Цвет фона содержит синий.
BACKGROUND_GREEN | Цвет фона содержит зеленый.
BACKGROUND_RED | Цвет фона содержит красный.
BACKGROUND_INTENSITY | Цвет фона усилен.
COMMON_LVB_LEADING_BYTE | DBCS: Leading byte.
COMMON_LVB_TRAILING_BYTE | DBCS: Trailing byte.
COMMON_LVB_GRID_HORIZONTAL | DBCS: Grid attribute: top horizontal.
COMMON_LVB_GRID_LVERTICAL | DBCS: Grid attribute: left vertical.
COMMON_LVB_GRID_RVERTICAL | DBCS: Grid attribute: right vertical.
COMMON_LVB_REVERSE_VIDEO | DBCS: Reverse foreground and background attributes.
COMMON_LVB_UNDERSCORE | DBCS: Underscore.
Атрибуты переднего плана (FOREGROUND_*) определяют цвет текста (символов). Атрибуты фона (BACKGROUND_*) определяют цвет, которым будет заполнена текстовая ячейка. Остальные атрибуты (COMMON_LVB_*) используются с DBCS.

Замечания

Смотрите также:
ReadConsoleOutput , ScrollConsoleScreenBuffer , WriteConsoleOutput


CONSOLE_CURSOR_INFO

главная | структуры | win32 структуры
Структура CONSOLE_CURSOR_INFO содержит информацию о консольном курсоре.
typedef struct _CONSOLE_CURSOR_INFO {
  DWORD  dwSize;
  BOOL   bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

Элементы

dwSize
Процент ячейки символа который заполняет курсор. Значение между 0 и 100. Вид курсора меняется, простираясь от полного заполнения ячейки до горизонтальной линии внизу ячейки.

Замечание для Windows 9x/Me Windows 9X/Me

  • Для показа полностью заполненного курсора в Windows 9x/Me укажите значение, равное 99.
bVisible
Видимость курсора. Если курсор виден, этот элемент равен TRUE.
Смотрите также:
GetConsoleCursorInfo , SetConsoleCursorInfo


COORD

главная | структуры | win32 структуры
Структура COORD определяет координаты ячейки символа в консольном буфере экрана. Начало системы координат (0,0) - левая верхняя ячейка экранного буфера.
typedef struct _COORD {
  SHORT X;
  SHORT Y;
} COORD;

Элементы

X
Горизонтальная координата или значение столбца.
Y
Вертикальная координата или значение ряда.

Замечания

Смотрите также:


FILETIME

главная | структуры | win32 структуры
Структура FILETIME - это 64-х разрядное значение, представляющее число сто-наносекундных интервалов, прошедших с первого января 1601 года (UTC).
typedef struct _FILETIME {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME;

Элементы

dwLowDateTime
Младшие 32 бита времени файла
dwHighDateTime
Старшие 32 бита времени файла

Замечания

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

  • Скопировать результирующую структуру в структуру ULARGE_INTEGER
  • Использовать обычную 64-х битную арифметику для значения ULARGE_INTEGER или привести переменную типа FILETIME к типу __int64:
    FILETIME WriteTime1, WriteTime2;

if(*(__int64*) & WriteTime1 == *(__int64*) & WriteTime2)
 ...
Не все файловые системы могут хранить время создания и доступа, и не все они хранят времена одинаковым образом. Например, в FAT время создания задаётся с точностью до 10 миллисекунд, записи - до 2 секунд, а время доступа - 1 день (фактически, дата доступа). У NTFS время доступа имеет точность в 1 час. Таким образом, функция GetFileTime может вернуть время, отличное от установленного функцией SetFileTime. К тому же, FAT хранит времена в локальном часовом поясе, а NTFS - в универсальном синхронизированном времени (UTC).
Смотрите также:
CompareFileTime , GetFileTime, SetFileTime, ULARGE_INTEGER


FOCUS_EVENT_RECORD

главная | структуры | win32 структуры | INPUT_RECORD
Структура FOCUS_EVENT_RECORD используется для информации о сообщениях фокуса в консольной структуре INPUT_RECORD. Эти сообщения используются системой и должны игнорироваться.
typedef struct _FOCUS_EVENT_RECORD {
    BOOL bSetFocus;
} FOCUS_EVENT_RECORD;

Элементы

bSetFocus
Зарезервировано.
Смотрите также:
INPUT_RECORD


INPUT_RECORD

главная | структуры | win32 структуры
Структура INPUT_RECORD используется для возвращения информации о входных сообщениях в консольном входном буфере. Эти записи могут быть считаны из входного буфера используя функции ReadConsoleInput или PeekConsoleInput, или записаны функцией WriteConsoleInput.
typedef struct _INPUT_RECORD {
 WORD EventType;
 union {
    KEY_EVENT_RECORD KeyEvent;
    MOUSE_EVENT_RECORD MouseEvent;
    WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
    MENU_EVENT_RECORD MenuEvent;
    FOCUS_EVENT_RECORD FocusEvent;
 } Event;
} INPUT_RECORD;

Элементы

EventType
Означает тип входного сообщения и запись события, сохраненную в элементе Event.
Этот элемент может иметь одно из следующих значений:
Событие | Описание
KEY_EVENT | Элемент Event содержит структуру KEY_EVENT_RECORD с информацией о сообщении с клавиатуры.
MOUSE_EVENT | Элемент Event содержит структуру MOUSE_EVENT_RECORD с информацией о сообщении мыши - перемещении или нажатии клавиш.
WINDOW_BUFFER_SIZE_EVENT | Элемент Event содержит структуру WINDOW_BUFFER_SIZE_RECORD с информацией о новом размере экрана консоли.
MENU_EVENT | Элемент Event содержит структуру MENU_EVENT_RECORD. Эти сообщения используются системой и должны игнорироваться.
FOCUS_EVENT | Элемент Event содержит структуру FOCUS_EVENT_RECORD. Эти сообщения используются системой и должны игнорироваться.
FARMACRO_KEY_EVENT | Элемент Event содержит структуру KEY_EVENT_RECORD с информацией о сообщении с клавиатуры. Это сообщение, специфичное для FAR manager (начиная с версии 1.70 build 1663), приходит плагину во время "проигрывания" макрокоманды.
Event
Содержит структуры KEY_EVENT_RECORD, MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, FOCUS_EVENT_RECORD или FARMACRO_KEY_EVENT, в зависимости от значения, указанного в EventType.
Смотрите также:
KEY_EVENT_RECORD, MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, FOCUS_EVENT_RECORD, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput


KEY_EVENT_RECORD

главная | структуры | win32 структуры | INPUT_RECORD
Структура KEY_EVENT_RECORD используется для получения входных событий в консольной структуре INPUT_RECORD.
typedef struct _KEY_EVENT_RECORD {
    BOOL bKeyDown;
    WORD wRepeatCount;
    WORD wVirtualKeyCode;
    WORD wVirtualScanCode;
    union {
        WCHAR UnicodeChar;
        CHAR  AsciiChar;
    } uChar;
    DWORD dwControlKeyState;
} KEY_EVENT_RECORD;

Элементы

bKeyDown
Равно TRUE если клавиша нажата, иначе FALSE.
wRepeatCount
Число повторов нажатия клавиши. Например, когда клавиша нажата, вы можете получить пять сообщений с этим членом равным 1, одно сообщение с равным 5, или несколько сообщений с элементом большим, либо равным 1.
wVirtualKeyCode
Виртуальный код клавиши, определяющий данную клавишу в независимой от устройства форме.
wVirtualScanCode
Виртуальный скан-код клавиши. Определяет устройство-зависимое значение, генерируемое аппаратурой клавиатуры.
uChar
Переведенный Unicode или ASCII символ, в зависимости от того, использовалась Wide- или ANSI-версия функции ReadConsoleInput.
dwControlKeyState
Состояние управляющих клавиш. Может быть комбинацией следующих значений:
Клавиша | Значение | Описание
CAPSLOCK_ON | 0x0080 | CAPS LOCK включен.
ENHANCED_KEY | 0x0100 | Клавиша расширенная.
LEFT_ALT_PRESSED | 0x0002 | Левый ALT нажат.
LEFT_CTRL_PRESSED | 0x0008 | Левый CTRL нажат.
NUMLOCK_ON | 0x0020 | NUM LOCK включен.
RIGHT_ALT_PRESSED | 0x0001 | Правый ALT нажат.
RIGHT_CTRL_PRESSED | 0x0004 | Правый CTRL нажат.
SCROLLLOCK_ON | 0x0040 | SCROLL LOCK включен.
SHIFT_PRESSED | 0x0010 | Клавиша SHIFT нажата.

Замечания

Расширенные клавиши для IBM® 101- и 102-х клавишных клавиатур - это INS, DEL, HOME, END, PAGE UP, PAGE DOWN, клавиши курсора, клавиша divide (/) и ENTER на цифровой части.
Сообщения клавиатурного ввода генерируются, когда любая клавиша, включая управляющую, нажата или отпущена. Однако, когда клавиша ALT нажимается и отпускается, это имеет специальное значение в Windows и такое событие не передается приложению. Также сочетание CTRL+C не передается, если хендл входной консоли имеет флаг ENABLE_PROCESSED_INPUT.
Смотрите также:
PeekConsoleInput, ReadConsoleInput, WriteConsoleInput, INPUT_RECORD


MENU_EVENT_RECORD

главная | структуры | win32 структуры | INPUT_RECORD
Структура MENU_EVENT_RECORD содержит сообщения меню в консольной структуре INPUT_RECORD. Эти сообщения используются системой и должны игнорироваться.
typedef struct _MENU_EVENT_RECORD {
    UINT dwCommandId;
} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;

Элементы

dwCommandId
Зарезервировано.
Смотрите также:
INPUT_RECORD


MOUSE_EVENT_RECORD

главная | структуры | win32 структуры | input_record
Структура MOUSE_EVENT_RECORD используется консольной структурой INPUT_RECORD для получения сообщений мыши.
typedef struct _MOUSE_EVENT_RECORD {
    COORD dwMousePosition;
    DWORD dwButtonState;
    DWORD dwControlKeyState;
    DWORD dwEventFlags;
} MOUSE_EVENT_RECORD;

Элементы

dwMousePosition
Положение курсора в координатах экранного буфера (структура COORD).
dwButtonState
Состояние клавиш мыши. Младший бит соответствует самой левой кнопке, следующий - самой правой, Следующий бит - следующая за левой клавиша. Далее биты соответствуют клавишам слева направо. Если бит установлен - клавиша нажата.
Определены следующие константы для первых пяти клавиш мыши:

FROM_LEFT_1ST_BUTTON_PRESSED
RIGHTMOST_BUTTON_PRESSED
FROM_LEFT_2ND_BUTTON_PRESSED
FROM_LEFT_3RD_BUTTON_PRESSED
FROM_LEFT_4TH_BUTTON_PRESSED
dwControlKeyState
Состояние управляющих клавиш. Может быть комбинацией следующих значений:
Клавиша | Описание
CAPSLOCK_ON | CAPS LOCK включен.
ENHANCED_KEY | Клавиша расширенная.
LEFT_ALT_PRESSED | Левый ALT нажат.
LEFT_CTRL_PRESSED | Левый CTRL нажат.
NUMLOCK_ON | NUM LOCK включен.
RIGHT_ALT_PRESSED | Правый ALT нажат.
RIGHT_CTRL_PRESSED | Правый CTRL нажат.
SCROLLLOCK_ON | SCROLL LOCK включен.
SHIFT_PRESSED | Клавиша SHIFT нажата.
dwEventFlags
Тип сообщения мыши. Если ноль, то кнопка мыши была нажата или отпущена. Иначе одно из следующих значений:
Событие | Описание
DOUBLE_CLICK | Второе нажатие при двойном щелчке (первое нажатие приходит как обычное сообщение).
MOUSE_MOVED | Позиция мыши изменилась.
MOUSE_WHEELED | Windows 2000/XP/2003/Vista/2008/7: Устанавливается при вертикальной прокрутке колесика на мышке. Если установлен этот флаг, то в старшем слове dwButtonState содержтся значение, кратное WHEEL_DELTA. По умолчанию это значение равно 120, но может изменяться в зависимости от драйвера мыши.
MOUSE_HWHEELED | Windows Vista/2008/7: Устанавливается при горизонтальной прокрутке колесика на мышке. Если установлен этот флаг, то в старшем слове dwButtonState содержтся значение, кратное WHEEL_DELTA. По умолчанию это значение равно 120, но может изменяться в зависимости от драйвера мыши.

Замечания

Сообщения мыши помещаются во входной буфер, когда консоль имеет установленный флаг ENABLE_MOUSE_INPUT.
Сообщения мыши посылаются в буфер, только если консоль имеет активный клавиатурный фокус и курсор находится в границах консольного окна.
Смотрите также:
COORD, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput, INPUT_RECORD


RECT

главная | структуры | win32 структуры
Структура RECT определяет координаты левого верхнего и правого нижнего углов прямоугольника.
typedef struct _RECT {
  LONG left;
  LONG top;
  LONG right;
  LONG bottom;
} RECT, *PRECT;

Элементы

left
Определяет X-координату левого верхнего угла прямоугольника.
top
Определяет Y-координату левого верхнего угла прямоугольника.
right
Определяет X-координату правого нижнего угла прямоугольника.
bottom
Определяет Y-координату правого нижнего угла прямоугольника.

Замечания

Смотрите также:
SMALL_RECT


SMALL_RECT

главная | структуры | win32 структуры
Структура SMALL_RECT определяет координаты левого верхнего и правого нижнего углов прямоугольника.
typedef struct _SMALL_RECT {
  SHORT Left;
  SHORT Top;
  SHORT Right;
  SHORT Bottom;
} SMALL_RECT;

Элементы

Left
X-координата левого верхнего угла прямоугольника.
Top
Y-координата левого верхнего угла прямоугольника.
Right
X-координата правого нижнего угла прямоугольника.
Bottom
Y-координата правого нижнего угла прямоугольника.

Замечания

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


SYSTEMTIME

главная | структуры | win32 структуры
Структура SYSTEMTIME хранит дату и время, используя отдельные поля для месяца, дня, года, дня недели, часа, минут, секунд и миллисекунд.
typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
} SYSTEMTIME;

Элементы

wYear
Указывает текущий год (1601 - 30827).
wMonth
Текущий месяц; Январь = 1, Февраль = 2, и так далее.
wDayOfWeek
Текущий день недели; Воскресенье = 0, Понедельник = 1, и так далее.
wDay
Текущий день месяца.
wHour
Час (0-23).
wMinute
Минуты (0-59).
wSecond
Секунды (0-59).
wMilliseconds
Миллисекунды (0-999).

Замечания

Не рекомендуется добавлять или вычитать значения из структуры SYSTEMTIME для получения относительного времени. Вместо этого вы должны

  • Конвертировать структуру в FILETIME, используя функцию SystemTimeToFileTime .
  • Скопировать результирующую структуру FILETIME в структуру ULARGE_INTEGER .
  • Использовать обычную 64-х битную арифметику со значениями ULARGE_INTEGER или привести переменную типа FILETIME к типу __int64:
    FILETIME WriteTime1, WriteTime2;

if(*(__int64*) & WriteTime1 == *(__int64*) & WriteTime2)
 ...
Смотрите также:
FILETIME, LARGE_INTEGER , GetSystemTime , SetSystemTime


WIN32_FIND_DATA

главная | структуры | win32 структуры
Структура WIN32_FIND_DATA описывает файл, найденный функциями FindFirstFile , FindFirstFileEx или FindNextFile .
typedef struct _WIN32_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[ MAX_PATH ];
  TCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATA;

Элементы

dwFileAttributes
Указывает атрибуты найденного файла. Этот элемент может быть комбинацией следующих значений:
Атрибут | Описание
FILE_ATTRIBUTE_ARCHIVE | Это архивный файл. Приложения должны использовать этот флаг для копирования, архивирования или удаления.
FILE_ATTRIBUTE_COMPRESSED | Файл или каталог сжат. Для файла это означает, что все данные его сжаты, для каталога - что компрессия по умолчанию применяется ко всем его файлам и подкаталогам.
FILE_ATTRIBUTE_DIRECTORY | Это каталог.
FILE_ATTRIBUTE_ENCRYPTED | Файл или каталог зашифрован. Для файла, это означает, что все данные в файле зашифрованы. Для директория, это означает, что шифрование является умолчанием для вновь созданных файлов и подкаталогов.
FILE_ATTRIBUTE_HIDDEN | Файл скрыт. Такой файл не включается в обычный листинг каталога.
FILE_ATTRIBUTE_NORMAL | У этого файла не установлены другие атрибуты. Это значение корректно только при использовании без остальных флагов.
FILE_ATTRIBUTE_OFFLINE | Данные файла не доступны непосредственно. Означает, что реальные данные файла были физически перемещены на устройства хранения.
FILE_ATTRIBUTE_READONLY | Файл только для чтения. Приложения могут читать такой файл, но не могут записывать или удалять его.
FILE_ATTRIBUTE_REPARSE_POINT | Каталог является символической связью.
FILE_ATTRIBUTE_SPARSE_FILE | Файл является т.н. Sparse file.
FILE_ATTRIBUTE_SYSTEM | Этот файл - часть операционной системы.
FILE_ATTRIBUTE_TEMPORARY | Это временный файл. Приложения должны записывать в такой файл только в крайней необходимости. Большая часть данных файла находится в памяти и не сбрасывается на диск, так как файл будет удален.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | Этот файл или каталог не будут индексироваться службой индексирования.
FILE_ATTRIBUTE_VIRTUAL | Этот файл - виртуальный файл.
ftCreationTime
Время создания - структура FILETIME, содержащая время создания файла. FindFirstFile и FindNextFile возвращают время файла в UTC-формате. Эти функции устанавливают элементы FILETIME в ноль, если файловая система, содержащая файл, не поддерживает этот временной атрибут.
Вы можете использовать функцию FileTimeToLocalFileTime для преобразования из UTC в локальное время и тогда использовать функцию FileTimeToSystemTime для преобразования локального времени в структуру SYSTEMTIME содержащую отдельные элементы для месяца, дня, года и так далее...
ftLastAccessTime
Структура FILETIME с временем последнего доступа к файлу (чтение, запись, исполнение).
Для каталогов в этой компоненте содержится информация о времени создания каталога.
На FAT дата для файлов и каталогов будет правильна, но время дня будет всегда установлено на полночь.
Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
ftLastWriteTime
Структура FILETIME с временем последней записи в файл (с помощью функций WriteFile или SetEndOfFile ). Время последней записи не обновляется для таких операций, как установка атрибутов файла или изменение дескриптора безопасности (security descriptors).
Для каталогов в этой компоненте содержится информация о времени создания каталога.
Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
nFileSizeHigh
Старшее двойное слово 64-х разрядного размера файла в байтах. Размер файла равен (nFileSizeHigh * (1+MAXDWORD)) + nFileSizeLow.
nFileSizeLow
Младшее двойное слово размера файла в байтах.
dwReserved0
Если поле dwFileAttributes содержит атрибут FILE_ATTRIBUTE_REPARSE_POINT, это поле содержит специфическую информацию для символической связи. В противном случае значение этого поля не определено и не должно использоваться.
dwReserved1
Резерв.
cFileName
Строка с именем файла, заканчивающаяся символом конца строки (0x00).
cAlternateFileName
Альтернативное имя файла (классическая 8.3 (filename.ext) форма).

Замечания

  • Если файл имеет длинное имя, полное имя возвращается в элементе cFileName а усеченная версия формата 8.3 сохраняется в cAlternateFileName. Иначе cAlternateFileName пусто. Как альтернативу вы можете использовать функцию GetShortPathName для возвращения 8.3-вида имени файла.
  • Не все файловые системы позволяют хранить время создания файла и последнего доступа к нему, и не все системы хранят их одинаково. Например, в файловой системе FAT под Windows NT время создания файла записывается с разрешением 10 миллисекунд, время последней модификации - 2 секунды, а время доступа - 1 день (то есть, фактически, записывается только дата доступа). На файловой системе NTFS время доступа имеет разрешение 1 час.
Смотрите также:
_FAR_USE_WIN32_FIND_DATA, FAR_FIND_DATA, FILETIME, TWin32FindData


WINDOW_BUFFER_SIZE_RECORD

главная | структуры | win32 структуры
Структура WINDOW_BUFFER_SIZE_RECORD используется консольной структурой INPUT_RECORD для информирования о смене в размере экранного буфера консоли.
typedef struct _WINDOW_BUFFER_SIZE_RECORD {
    COORD dwSize;
} WINDOW_BUFFER_SIZE_RECORD;

Элементы

dwSize
Указывает новый размер экранного буфера в символах (структура COORD).

Замечания

Эти сообщения добавляются во входной буфер, когда консоль находится в режиме window-aware (ENABLE_WINDOW_INPUT).

Смотрите также:
INPUT_RECORD, COORD, ReadConsoleInput


Функции Win32

главная
Функция | Описание
GetFileTime | возвращает дату и время создания, модификации и последнего доступа к файлу
PeekConsoleInput | считывает данные из указанного консольного входного буфера без удаления
ReadConsoleInput | считывает данные из входного буфера консоли и удаляет их оттуда
SetFileApisToAnsi | указывает набору файловых функций Win32 использовать кодировку ANSI
SetFileApisToOem | указывает набору файловых функций Win32 использовать кодировку OEM
SetFileTime | устанавливает дату и время создания, модификации и последнего доступа к файлу
WriteConsoleInput | записывает данные непосредственно в консольный входной буфер
Смотрите также:


GetFileTime

главная | структуры | win32 структуры
Функция GetFileTime возвращает дату и время создания, модификации и последнего доступа к файлу.
BOOL GetFileTime(
  HANDLE hFile,
  CONST FILETIME *lpCreationTime,
  CONST FILETIME *lpLastAccessTime,
  CONST FILETIME *lpLastWriteTime
);

Параметры

hFile
идентифицирует файл, для которого извлекаются дата и время. Файловый дескриптор должен быть создан с доступом GENERIC_READ к файлу.
lpCreationTime
указывает на структуру типа FILETIME, которая получает дату и время создания файла. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.
lpLastAccessTime
указывает на структуру типа FILETIME, которая получает дату и время последнего доступа к файлу. Время последнего доступа включает в себя время, когда в последний раз: в файл записывалась информация, читалась информация из файла, или, в случае исполняемых файлов, файл запускался на исполнение. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.
lpLastWriteTime
указывает на структуру типа FILETIME, указывает на структуру типа FILETIME, которая получает дату и время последней записи в файл. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.

Возвращаемое значение

В случае успеха возвращается ненулевое значение.
Если функция завершается неудачно, возвращается ноль. Для получения дополнительной информации следует вызвать функцию GetLastError .

Замечания

Файловые системы FAT и NTFS поддерживают время создания файла, время последнего доступа к файлу и время последней записи в файл.

Точность хранения времени Точность хранения времени

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

Замечание для Windows NT Семейство Windows NT

  • Когда Windows NT создает список каталогов (Проводник, команда DIR, и т.д.) в разделе NTFS, она модифицирует дату/время последнего доступа на каждом обнаруженном каталоге. Если каталогов очень много, это может повлиять на эффективность.
    Семейство Windows NT на файловой системе NTFS позволяет отключать дату/время последнего доступа (см. Disable the NTFS Last Access Time Stamp)
  • Если вы удалите или переименуете файл, а затем достаточно быстро восстановите его, Windows NT может восстановить из кеша некоторые данные о файле: длинное и короткое имя файла, а также дату его создания.

Пример

Следующий пример показывает как получить дату/время модификации файла в виде строки (Windows NT/2000).
BOOL GetLastWriteTime(HANDLE hFile, LPSTR lpszString)
{
  FILETIME ftCreate, ftAccess, ftWrite;
  SYSTEMTIME stUTC, stLocal;

  // получить файловую дату и время
  if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
      return FALSE;

  // преобразовать время модификации в локальное время.
  FileTimeToSystemTime(&ftWrite, &stUTC);
  SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

  // преобразовать полученное время в строку
  wsprintf(lpszString, "%02d/%02d/%d  %02d:%02d",
      stLocal.wDay, stLocal.wMonth, stLocal.wYear,
      stLocal.wHour, stLocal.wMinute);

  return TRUE;
}
Смотрите также:
FILETIME, GetFileSize , SetFileTime, GetFileType


PeekConsoleInput

главная | структуры | win32 структуры
Функция PeekConsoleInput считывает данные из указанного консольного входного буфера без удаления считанных записей из буфера.
BOOL PeekConsoleInput(
  HANDLE hConsoleInput,
  PINPUT_RECORD lpBuffer,
  DWORD nLength,
  LPDWORD lpNumberOfEventsRead
);

Параметры

hConsoleInput
Дескриптор консольного буфера ввода. Дескриптор должен иметь права GENERIC_READ.
lpBuffer
Указатель на массив структур INPUT_RECORD, который получит данные из входного буфера. Общий размер требуемого массива должен быть меньше чем 64КБ.
nLength
Число элементов в буфере lpBuffer, которое необходимо получить.
lpNumberOfEventsRead
Указатель на 32-х разрядную переменную, которая получит число реально прочитанных элементов.

Возвращаемое значение

В случае успеха возвращается ненулевое значение.
Если функция завершается неудачно, возвращается ноль. Для получения дополнительной информации вызывайте функцию GetLastError .

Замечания

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

Семейство Windows NT Windows NT/2000/XP/2003/Vista/2008/7

  • Эта функция использует либо Unicode, либо 8-битовые символы из текущей кодовой страницы консоли. Кодовая страница консоли по умолчанию равна системной OEM странице.
    Для смены кодовой страницы используйте функции SetConsoleCP или SetConsoleOutputCP , или используйте команды chcp или mode con cp select=.

Замечание для Windows 95/98/Me Windows 95/98/Me

  • Установите Microsoft Layer for Unicode для того, чтобы использовать функцию ReadConsoleInputW (которая позволит использовать Unicode в консольном окне).
Смотрите также:
INPUT_RECORD, ReadConsoleInput, SetConsoleCP , SetConsoleOutputCP , WriteConsoleInput


ReadConsoleInput

главная | структуры | win32 структуры
Функция ReadConsoleInput считывает данные из входного буфера консоли и удаляет их оттуда.
BOOL ReadConsoleInput(
  HANDLE hConsoleInput,
  PINPUT_RECORD lpBuffer,
  DWORD nLength,
  LPDWORD lpNumberOfEventsRead
);

Параметры

hConsoleInput
Дескриптор консольного буфера ввода. Дескриптор должен иметь права GENERIC_READ.
lpBuffer
Указатель на массив структур INPUT_RECORD, который получит данные из входного буфера. Общий размер требуемого массива должен быть меньше чем 64КБ.
nLength
Число элементов в буфере lpBuffer, которое необходимо получить.
lpNumberOfEventsRead
Указатель на 32-х разрядную переменную, которая получит число реально прочитанных элементов.

Возвращаемое значение

В случае успеха возвращается ненулевое значение.
Если функция завершается неудачно, возвращается ноль. Для получения дополнительной информации вызывайте функцию GetLastError .

Замечания

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

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

Для определения числа непрочитанных сообщений во входном буфере используйте функцию GetNumberOfConsoleInputEvents . Для чтения сообщений без их удаления из буфера используйте PeekConsoleInput. Для удаления всех сообщений из входного буфера используйте функцию FlushConsoleInputBuffer .

Семейство Windows NT Windows NT/2000/XP/2003/Vista/2008/7

  • Эта функция использует либо Unicode, либо 8-битовые символы из текущей кодовой страницы консоли. Кодовая страница консоли по умолчанию равна системной OEM странице.
    Для смены кодовой страницы используйте функции SetConsoleCP или SetConsoleOutputCP , или используйте команды chcp или mode con cp select=.

Замечание для Windows 95/98/Me Windows 95/98/Me

  • Установите Microsoft Layer for Unicode для того, чтобы использовать функцию ReadConsoleInputW (которая позволит использовать Unicode в консольном окне).
Смотрите также:
INPUT_RECORD, SetConsoleCP , SetConsoleOutputCP , WriteConsoleInput, PeekConsoleInput, FlushConsoleInputBuffer , GetNumberOfConsoleInputEvents , ReadConsole , ReadFile


SetFileApisToANSI

главная | структуры | win32 структуры
Функция SetFileApisToANSI указывает набору файловых функций Win32 использовать кодировку ANSI. Эта функция полезна для 8-битных консольных операций ввода-вывода.
VOID SetFileApisToANSI(VOID);

Параметры

Отсутствуют.

Возвращаемое значение

Нет.

Замечания

Функция SetFileApisToANSI дополняет функцию SetFileApisToOEM, которая указывает набору файловых функций Win32 использовать кодовую страницу с кодировкой OEM.

8-битные консольные функции используют по умолчанию кодировку OEM. Все остальные функции должны использовать кодовую страницу ANSI по умолчанию. Это означает, что строки, возвращаемые консольными функциями могут быть не корректно обработаны другими функциями, и наоборот. К примеру Если функция FindFirstFileA возвращает строку, содержащую некоторые расширенные символы ANSI, и при этом 8-битные функции установлены для использования кодировки OEM, то функция WriteConsoleA не отобразит строку корректно.

Используйте AreFileApisANSI для обнаружения в какой кодовой странице набор файловых функций работает в данный момент. Используйте SetConsoleCP и SetConsoleOutputCP для установки кодовой страницы для 8-битных консольных функций.

Для разрешения проблемы несовместимости кодовых страниц лучше всего использовать кодировку Unicode. В этом случае приложение будет более гибким. Другой способ — использовать функцию SetFileApisToOEM для указания множеству файловых функций Win32 использовать кодировку OEM. Используйте функцию SetFileApisToANSI для установки кодовой страницы обратно в ANSI.

Функции SetFileApisToANSI и SetFileApisToOEM действуют на следующее множество Win32 функций:

Функция | Описание
_lopen | открыть существующий файл
CopyFile | копировать файл
CreateDirectory | создать каталог
CreateFile | создать/открыть объект (файл, канал, ...)
CreateProcess | создать новый процесс
DeleteFile | удалить файл
FindFirstFile | начать поиск файловых объектов
FindNextFile | продолжить поиск файловых объектов
GetCurrentDirectory | получить текущий каталог
GetDiskFreeSpace | получить информацию о диске
GetDriveType | получить типа диска
GetFileAttributes | получить файловые атрибуты
GetFullPathName | получить полный путь
GetModuleFileName | извлекает полный путь для указанного модуля.
GetModuleHandle | получить хендл запущенного модуля
GetSystemDirectory | возвращает путь к системного каталогу
GetTempFileName | создает имя для временного файла
GetTempPath | возвращает путь к %TEMP% каталогу
GetVolumeInformation | возвращает информацию о файловой системе
GetWindowsDirectory | возвращает путь к каталогу Windows
LoadLibrary | загрузить исполняемый модуль
LoadLibraryEx | загрузить исполняемый модуль
MoveFile | переименовать файл/каталог
MoveFileEx | переименовать файл/каталог
OpenFile | создать/открыть/удалить файл
RemoveDirectory | удалить каталог
SearchPath | поиск файла
SetCurrentDirectory | установить текущий каталог
SetFileAttributes | установить файловые атрибуты

При работе с командной строкой консольное приложение может получить командную строку в Unicode и потом конвертировать ее в OEM, используя соответствующие функции. Заметьте также, что функция argv использует кодовую страницу ANSI.

Смотрите также:
SetFileApisToOEM


SetFileApisToOEM

главная | структуры | win32 структуры
Функция SetFileApisToOEM указывает набору файловых функций Win32 использовать кодировку OEM. Эта функция полезна для 8-битных консольных операций ввода-вывода.
VOID SetFileApisToOEM(VOID);

Параметры

Отсутствуют.

Возвращаемое значение

Нет.

Замечания

Функция SetFileApisToOEM дополняет функцию SetFileApisToANSI, которая указывает набору файловых функций Win32 использовать кодовую страницу с кодировкой ANSI.

8-битные консольные функции используют по умолчанию кодировку OEM. Все остальные функции должны использовать кодовую страницу ANSI по умолчанию. Это означает, что строки, возвращаемые консольными функциями могут быть не корректно обработаны другими функциями, и наоборот. К примеру Если функция FindFirstFileA возвращает строку, содержащую некоторые расширенные символы ANSI, и при этом 8-битные функции установлены для использования кодировки OEM, то функция WriteConsoleA не отобразит строку корректно.

Используйте AreFileApisANSI для обнаружения в какой кодовой странице набор файловых функций работает в данный момент. Используйте SetConsoleCP и SetConsoleOutputCP для установки кодовой страницы для 8-битных консольных функций.

Для разрешения проблемы несовместимости кодовых страниц лучше всего использовать кодировку Unicode. В этом случае приложение будет более гибким. Другой способ — использовать функцию SetFileApisToOEM для указания множеству файловых функций Win32 использовать кодировку OEM. Используйте функцию SetFileApisToANSI для установки кодовой страницы обратно в ANSI.

Функции SetFileApisToANSI и SetFileApisToOEM действуют на следующее множество Win32 функций:

Функция | Описание
_lopen | открыть существующий файл
CopyFile | копировать файл
CreateDirectory | создать каталог
CreateFile | создать/открыть объект (файл, канал, ...)
CreateProcess | создать новый процесс
DeleteFile | удалить файл
FindFirstFile | начать поиск файловых объектов
FindNextFile | продолжить поиск файловых объектов
GetCurrentDirectory | получить текущий каталог
GetDiskFreeSpace | получить информацию о диске
GetDriveType | получить типа диска
GetFileAttributes | получить файловые атрибуты
GetFullPathName | получить полный путь
GetModuleFileName | извлекает полный путь для указанного модуля.
GetModuleHandle | получить хендл запущенного модуля
GetSystemDirectory | возвращает путь к системного каталогу
GetTempFileName | создает имя для временного файла
GetTempPath | возвращает путь к %TEMP% каталогу
GetVolumeInformation | возвращает информацию о файловой системе
GetWindowsDirectory | возвращает путь к каталогу Windows
LoadLibrary | загрузить исполняемый модуль
LoadLibraryEx | загрузить исполняемый модуль
MoveFile | переименовать файл/каталог
MoveFileEx | переименовать файл/каталог
OpenFile | создать/открыть/удалить файл
RemoveDirectory | удалить каталог
SearchPath | поиск файла
SetCurrentDirectory | установить текущий каталог
SetFileAttributes | установить файловые атрибуты

При работе с командной строкой консольное приложение может получить командную строку в Unicode и потом конвертировать ее в OEM, используя соответствующие функции. Заметьте также, что функция argv использует кодовую страницу ANSI.

Смотрите также:
SetFileApisToANSI


SetFileTime

главная | структуры | win32 структуры
Функция SetFileTime устанавливает дату и время создания, модификации и последнего доступа к файлу.
BOOL SetFileTime(
  HANDLE hFile,
  CONST FILETIME *lpCreationTime,
  CONST FILETIME *lpLastAccessTime,
  CONST FILETIME *lpLastWriteTime
);

Параметры

hFile
идентифицирует файл, для которого устанавливаются дата и время. Файловый дескриптор должен быть создан с доступом GENERIC_WRITE к файлу.
lpCreationTime
указывает на структуру типа FILETIME, которая содержит дату и время создания файла. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.
lpLastAccessTime
указывает на структуру типа FILETIME, которая содержит дату и время последнего доступа к файлу. Время последнего доступа включает в себя время, когда в последний раз: в файл записывалась информация, читалась информация из файла, или, в случае исполняемых файлов, файл запускался на исполнение. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.
lpLastWriteTime
указывает на структуру типа FILETIME, которая содержит дату и время последней записи в файл. Значение этого параметра может быть равно NULL, если приложению не требуется эта информация.

Возвращаемое значение

В случае успеха возвращается ненулевое значение.
Если функция завершается неудачно, возвращается ноль. Для получения дополнительной информации вызывайте функцию GetLastError .

Замечания

Файловые системы FAT и NTFS поддерживают время создания файла, время последнего доступа к файлу и время последней записи в файл.

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

Замечание для Windows 95 Windows 95

  • Точность значения времени для файла в файловой системе FAT - 2 секунды. Точность значения времени для файлов в других файловых системах, например, на сетевых дисках, зависит от файловой системы, но также может быть ограничена удаленным устройством.

Пример

Следующий пример показывает, как установить дату/время модификации файла в значение текущего системного времени.
BOOL SetFileToCurrentTime(HANDLE hFile)
{
  FILETIME ft;
  SYSTEMTIME st;

  GetSystemTime(&st);                 // получить текущее время
  SystemTimeToFileTime(&st, &ft);     // преобразовать в файловый формат
  return SetFileTime(hFile,           // установить дату/время модификации файла
              (LPFILETIME) NULL, (LPFILETIME) NULL, &ft);
}
Смотрите также:
FILETIME, GetFileSize , GetFileTime, GetFileType


WriteConsoleInput

главная | структуры | win32 структуры
Функция WriteConsoleInput записывает данные непосредственно в консольный входной буфер.
BOOL WriteConsoleInput(
  HANDLE hConsoleInput,
  CONST INPUT_RECORD *lpBuffer,
  DWORD nLength,
  LPDWORD lpNumberOfEventsWritten
);

Параметры

hConsoleInput
Дескриптор консольного буфера ввода. Дескриптор должен иметь права GENERIC_WRITE.
lpBuffer
Указатель на массив структур INPUT_RECORD, содержащий данные для записи во входной буфер.
nLength
Число элементов для записи во входной буфер.
lpNumberOfEventsWritten
Указатель на 32-х разрядную переменную, которая получит число реально записанных элементов.

Возвращаемое значение

В случае успеха возвращается ненулевое значение.
Если функция завершается неудачно, возвращается ноль. Для получения дополнительной информации вызывайте функцию GetLastError .

Замечания

Функция WriteConsoleInput помещает записи INPUT_RECORD в конец входного буфера. Входной буфер при необходимости растет динамически для хранения необходимого количества записей.

Семейство Windows NT Windows NT/2000/XP/2003/Vista/2008/7

  • Эта функция использует либо Unicode, либо 8-битовые символы из текущей кодовой страницы консоли. Кодовая страница консоли по умолчанию равна системной OEM странице.
    Для смены кодовой страницы используйте функции SetConsoleCP или SetConsoleOutputCP , или используйте команды chcp или mode con cp select=.

Замечание для Windows 95/98/Me Windows 95/98/Me

  • Установите Microsoft Layer for Unicode для того, чтобы использовать функцию WriteConsoleInputW (которая позволит использовать Unicode в консольном окне).
Смотрите также:
INPUT_RECORD, ReadConsoleInput, SetConsoleCP , SetConsoleOutputCP , PeekConsoleInput


Константы Win32

главная
Константа | Описание
Virtualkeycodes | виртуальные коды клавиш
Смотрите также:


Dialog API 1.0

главная

Внимание! Внимание!

  • Все детали по Dialog API написаны с учетом именованных объединений структуры FarDialogItem. Более подробно читайте в описании определения _FAR_NO_NAMELESS_UNIONS.

DialogAPI выделен в отдельное API, начиная с версии FAR Manager 1.70. Что это значит для плагинописателей? Самое главное - максимальный контроль над созданным диалогом.

Различаются два типа диалогов:

  • Диалоги так называемого About стиля (времен FAR 1.65 и ниже)
  • Диалоги Extended стиля - те, которые используют функцию-обработчик диалога.

Независимо от стиля, Менеджер диалогов версии 1.0 поддерживает только так называемые Модальные Диалоги (Modal Dialog). Модальный диалог представляет собой окно, запрещающее пользователю взаимодействовать с любым объектом FAR Manager вне данного диалога. Модальный диалог отсекает поток сообщений, идущих от мыши или клавиатуры к другим объектам FAR Manager.

About стиль

Здесь все просто - НЕУПРАВЛЯЕМЫЕ ДИАЛОГИ! Такие диалоги получаются при вызове функции Dialog или DialogEx с параметром DlgProc, равным NULL.

Данный стиль предполагает следующее поведение диалога:

  • о любых изменениях в состоянии управляющих элементов плагин узнает только после выхода из диалога;
  • выход из диалога происходит, когда пользователь нажал одну из клавиш: Esc, Ctrl-Enter, Enter (нажатие Enter приводит к выходу из диалога на любом элементе, кроме строк редактирования, объединенных флагом DIF_EDITOR), или кликнул кнопкой мыши за пределами диалога;
  • данный стиль предназначен для простых диалогов.

Extended стиль

А вот это... это самое интересное! Плагин полностью управляет поведением диалога:
  • диалог имеет функцию-обработчик, которая реагирует на массу событий, приходящих от Менеджера диалогов;
  • функция-обработчик общается с Менеджером Диалогов путем посылки сообщений, используя функцию SendDlgMessage;
  • функция-обработчик может передать управление Менеджеру Диалогов используя функцию DefDlgProc;
  • если пользователь пытается взаимодействовать с недоступными объектами FAR Manager, нажимая на кнопки мыши вне диалога, то Менеджер Диалогов предупреждает гудком;
  • окончанием обработки диалога управляет плагин.
  • данный стиль предназначен для диалогов со сложной логикой взаимодействия с пользователем.
Если в обработчике диалога просто передать управление ядру посредством функции DefDlgProc, то получим... тот же About-стиль:
// минимальный обработчик диалога
LONG_PTR WINAPI MyDlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2)
{
  return Info.DefDlgProc(hDlg,Msg,Param1,Param2);
}

Критерии выбора стиля диалога просты:

  • создаем диалог для ввода одной строки (типа InputBox) - выбираем простой стиль (About) - проще программа, меньше написанного кода, меньше ошибок;
  • создаем Game-Plugin, Калькулятор или плагин взаимодействующий с базой данных через ODBC - выбираем Extended стиль - сложная логика, динамика, интерактивное взаимодействие с пользователем, от действий которого зависит дальнейшая обработка, etc...

Итак. Dialog API версии 1.0:

Функции
Структуры
Макросы и типы
Элементы диалога
Флаги элементов диалога
События и сообщения
Фокус ввода
Механизмы работы со списками

Примечание

Для ознакомления с Dialog API рекомендуется изучить файл dialog.cpp из плагина "Reversi".
Смотрите также:
Экспортируемые функции, Сервисные функции, Структуры, Поддержка архивов, Дополнения


Функции Dialog API 1.0

Функции Dialog

главная | Dialog API
Следующие функции используются в Dialog API.
Фунция | Описание
Dialog | показывает "неуправляемый" диалог
DialogEx | показывает расширенный диалог
SendDlgMessage | посылка сообщения функции обработки диалога
DefDlgProc | вызов стандартной функции обработки диалога
DlgProc | шаблон функции обработки диалога
Смотрите также:
Структуры, Элементы диалога, Флаги элементов диалога, События и сообщения, Экспортируемые функции, Сервисные функции, Структуры, Поддержка архивов, Дополнения


Структуры - Dialog API 1.0

Структуры Dialog API

Dialog API

Dialog API 1.0 поддерживает следующие структуры.

Структура | Описание
FarDialogItem | элемент диалога
FarDialogItemData | передача данных элементу диалога
FarList | список DI_LISTBOX
FarListColors | описывает цветовую схему для элементов DI_COMBOBOX и DI_LISTBOX
FarListDelete | параметры удаления элементов из DI_COMBOBOX и DI_LISTBOX
FarListFind | поиск элемента из DI_COMBOBOX и DI_LISTBOX
FarListGetItem | получение одного элемента списка из DI_COMBOBOX и DI_LISTBOX
FarListInfo | получить информацию о списках DI_COMBOBOX и DI_LISTBOX
FarListInsert | вставка элемента в DI_COMBOBOX и DI_LISTBOX
FarListItem | элемент списка
FarListPos | позиционирование в списке
FarListItemData | ассоциация данных с элементом списка
FarListTitles | установка/получение заголовков для списка
FarListUpdate | данные для обновления элемента списка
Смотрите также:
Структуры FAR API


Макросы и типы

главная | Dialog API

Типы

Тип | Описание
FARWINDOWPROC | Функция-обработчик окна.

Макросы

Макрос | Описание
Dlg_GetDlgData(Info,hDlg) | Получить 32-битное значение, связанное с диалогом (DM_GETDLGDATA).
Dlg_GetDlgItemData(Info,hDlg,ID) | Получить 32-битное значение, связанное с элементом диалога (DM_GETITEMDATA).
Dlg_RedrawDialog(Info,hDlg) | Перерисовать диалоговое окно (DM_REDRAW).
Dlg_SetDlgData(Info,hDlg,Data) | Устанавить 32-битное значение связанное с диалогом (DM_SETDLGDATA).
Dlg_SetDlgItemData(Info,hDlg,ID,Data) | Устанавить 32-битное значение связанное с элементом диалога (DM_SETITEMDATA).
DlgEdit_AddHistory(Info,hDlg,ID,Str) | Добавить строку в историю поля ввода (DM_ADDHISTORY).
DlgItem_Disable(Info,hDlg,ID) | Установить элемент диалога в состояние Disable (DM_ENABLE).
DlgItem_Enable(Info,hDlg,ID) | Установить элемент диалога в состояние Enable (DM_ENABLE).
DlgItem_GetCheck(Info,hDlg,ID) | Получить состояние элементов DI_CHECKBOX и DI_RADIOBUTTON (DM_GETCHECK).
DlgItem_GetFocus(Info,hDlg) | Получить ID элемента диалога, имеющего клавиатурный фокус ввода (DM_GETFOCUS).
DlgItem_IsEnable(Info,hDlg,ID) | Элемент заблокирован? (DM_ENABLE).
DlgItem_SetCheck(Info,hDlg,ID,State) | Установить состояние элементов DI_CHECKBOX и DI_RADIOBUTTON в одно из трех состояний (DM_SETCHECK).
DlgItem_SetFocus(Info,hDlg,ID) | Установить клавиатурный фокус на заданный элемент диалога (DM_SETFOCUS).
DlgItem_SetText(Info,hDlg,ID,Str) | Установить содержимое строки ввода или заголовка элемента диалога в новое значение (DM_SETTEXTPTR).
DlgList_AddString(Info,hDlg,ID,Str) | Добавить строку в список DI_COMBOBOX или DI_LISTBOX (DM_LISTADDSTR).
DlgList_ClearList(Info,hDlg,ID) | Очистить список DI_COMBOBOX или DI_LISTBOX (DM_LISTDELETE).
DlgList_DeleteItem(Info,hDlg,ID,Index) | Удалить элемент из списка DI_COMBOBOX или DI_LISTBOX (DM_LISTDELETE).
DlgList_GetCurPos(Info,hDlg,ID) | Получить позицию курсора в списке DI_COMBOBOX или DI_LISTBOX (DM_LISTGETCURPOS).
DlgList_GetItemData(Info,hDlg,ID,Index) | Получить данные, ассоциированные с элементом списка DI_COMBOBOX или DI_LISTBOX (DM_LISTGETDATA).
DlgList_SetCurPos(Info,hDlg,ID,NewPos) | Установить новую позицию курсора в списке DI_COMBOBOX или DI_LISTBOX (DM_LISTSETCURPOS).
DlgList_SetItemStrAsData(Info,hDlg,ID,Index,Str) | Ассоциировать строку с элементом списка DI_COMBOBOX или DI_LISTBOX (DM_LISTSETDATA).
DlgList_SortDown(Info,hDlg,ID) | Сортировать элементы списка DI_COMBOBOX или DI_LISTBOX по убыванию (DM_LISTSORT).
DlgList_SortUp(Info,hDlg,ID) | Сортировать элементы списка DI_COMBOBOX или DI_LISTBOX по возрастанию (DM_LISTSORT).
Здесь:
Info
Указатель на структуру PluginStartupInfo.
hDlg
Дескриптор диалога.
ID
Индекс элемента в массиве структур FarDialogItem.
Data
32-битное значение (число типа DWORD или указатель).
Str
ASCIIZ строка.
State
Состояние элемента (одна из констант BSTATE_*, описанная в DM_SETCHECK).
Index
Позиция в списке.
NewPos
Новая позиция в списке.
Смотрите также:
Типы и определения


FARWINDOWPROC

главная | Dialog API | макросы и типы
Тип функции FARWINDOWPROC описывает функцию-обработчик окна.
typedef LONG_PTR (WINAPI *FARWINDOWPROC)(
  HANDLE   hDlg,
  int      Msg,
  int      Param1,
  LONG_PTR Param2
);
Смотрите также:
DialogEx


Элементы диалога

главная | Dialog API | FarDialogItem
DialogAPI поддерживает определенное множество управляющих элементов. Каждый элемент управления описывается структурой FarDialogItem. Массив этих структур передается в функции Dialog и DialogEx для показа диалога.
Элемент | Значение | Описание
DI_BUTTON | 7 | Кнопка (Push Button).
DI_CHECKBOX | 8 | Контрольный переключатель (Check Box).
DI_COMBOBOX | 10 | Комбинированный список.
DI_DOUBLEBOX | 3 | Двойная рамка.
DI_EDIT | 4 | Поле ввода.
DI_FIXEDIT | 6 | Поле ввода фиксированного размера.
DI_LISTBOX | 11 | Окно списка.
DI_PSWEDIT | 5 | Поле ввода пароля.
DI_RADIOBUTTON | 9 | Селекторная кнопка (Radio Button).
DI_SINGLEBOX | 2 | Одиночная рамка.
DI_TEXT | 0 | Текстовая строка.
DI_USERCONTROL | 255 | Элемент управления, определяемый программистом.
DI_VTEXT | 1 | Вертикальная текстовая строка.

Замечания

При описании всех элементов использовалось схематичное представление структуры FarDialogItem.
Смотрите также:
Флаги элементов диалога


DI_BUTTON

главная | Dialog API | Элементы диалога
Элемент диалога DI_BUTTON описывает кнопку (Push Button).
struct FarDialogItem
{
  int Type          = DI_BUTTON
  int X1            = X
  int Y1            = Y
  int X2            = 0 (в Dialog API 1.0 не используется)
  int Y2            = Y (равен значению Y1)
  int Focus         = Focus
  int Selected      = Selected
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512]    = надпись на кнопке
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

Selected

Если кнопка имеет фокус ввода, то при нажатии <Enter> это поле примет значение 1.

Флаги

Для элемента DI_BUTTON имеют значения следующие флаги:
Флаг | Описание
DIF_BTNNOCLOSE | Не завершать работу диалога при нажатии на кнопку.
DIF_CENTERGROUP | центрирование идущих подряд кнопок с одинаковой вертикальной позицией (параметр X игнорируется)
DIF_NOBRACKETS | Показывает заголовок кнопки без скобок.
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать атрибут текста кнопки)
DIF_DISABLE | Элемент является недоступным.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_SHOWAMPERSAND | показывать в заголовке рамки амперсанд не используя его для определения горячей клавиши

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст кнопки
                (COL_WARNDIALOGBUTTON или
                 COL_DIALOGBUTTON)
LoWord HiByte - выделенный текст (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTBUTTON или
                 COL_DIALOGHIGHLIGHTBUTTON)

Param2, когда кнопка в фокусе:

LoWord LoByte - текст кнопки
                (COL_WARNDIALOGSELECTEDBUTTON или
                 COL_DIALOGSELECTEDBUTTON)
LoWord HiByte - выделенный текст
                (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTSELECTEDBUTTON
                или
                 COL_DIALOGHIGHLIGHTSELECTEDBUTTON)
HiWord LoByte - 0
HiWord HiByte - 0
Если используется заказной атрибут (флаг DIF_SETCOLOR), то текст кнопки (LoWord LoByte) будет тем, что указали.
DN_KEY | нажали клавишу.
DN_HOTKEY | горячая клавиша (Alt-Символ)
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_BTNCLICK | нажата кнопка
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Вся информация по структуре FarDialogItem изложена с учетом именованных объединений. Более подробно читайте в описании определения _FAR_NO_NAMELESS_UNIONS.
Смотрите также:
DI_CHECKBOX, DI_RADIOBUTTON, FarDialogItem


DI_CHECKBOX

главная | Dialog API | Элементы диалога
Элемент диалога DI_CHECKBOX описывает контрольный переключатель (Check Box). также он называется кнопкой с независимой фиксацией (переключатель вкл./выкл., который может переключаться пользователем). Переключатель "включен", если у элемента поле Selected отлично от нуля.
struct FarDialogItem
{
  int Type          = DI_CHECKBOX
  int X1            = X
  int Y1            = Y
  int X2            = 0 (в Dialog API 1.0 не используется)
  int Y2            = Y (равен значению Y1)
  int Focus         = Focus
  int Selected      = Selected
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512]    = надпись переключателя
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

Selected

Определяет состояние элемента - отмечен или нет.

Флаги

Для элемента DI_CHECKBOX имеют значения следующие флаги:
Флаг | Описание
DIF_CENTERGROUP | центрирование идущих подряд переключателей с одинаковой вертикальной позицией (параметр X игнорируется)
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать атрибут текста кнопки)
DIF_DISABLE | Элемент является недоступным.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_3STATE | Контрольный переключатель будет иметь 3 состояния: "выключен", "включен", "неопределено".
DIF_SHOWAMPERSAND | показывать в заголовке рамки амперсанд не используя его для определения горячей клавиши

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст кнопки
                (COL_WARNDIALOGBUTTON или
                 COL_DIALOGTEXT)
LoWord HiByte - выделенный текст (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTTEXT или
                 COL_DIALOGHIGHLIGHTTEXT)
HiWord LoByte - 0
HiWord HiByte - 0
Если используется заказной атрибут (флаг DIF_SETCOLOR), то текст кнопки (LoWord LoByte) будет тем, что указали.
DN_HOTKEY | горячая клавиша (Alt-Символ)
DN_BTNCLICK | изменение состояния переключателя
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Хотя координаты X2 и Y2 в Dialog API 1.0 не используется, но для нормальной работы в будущих версиях FAR желательно корректно заполнить значения этих полей.
Смотрите также:
DI_RADIOBUTTON, DI_BUTTON, FarDialogItem


DI_COMBOBOX

главная | Dialog API | Элементы диалога
Элемент диалога DI_COMBOBOX описывает поле ввода со списком (комбинированный список).
struct FarDialogItem
{
  int Type             = DI_COMBOBOX
  int X1               = X1
  int Y1               = Y
  int X2               = X2
  int Y2               = Y (равен значению Y1)
  int Focus            = Focus
  union {
    FarList *ListItems = ListItems  [передается]
    int ListPos        = ListPos    [возвращается]
  };
  DWORD Flags          = Flags
  int DefaultButton    = DefaultButton
  union {
    char Data[512];    = редактируемый текст (без флага DIF_VAREDIT)
    struct {
      DWORD PtrFlags;  = дополнительные флаги (в Dialog API 1.0 не используется)
      int   PtrLength; = размер данных, на которые указывает PtrData
      char *PtrData;   = указатель на пользовательский буфер редактирования
      char  PtrTail[1];= "остаток" - доступ к оставшейся части Data
    } Ptr;             = редактируемый текст (с флагом DIF_VAREDIT)
  };
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

ListItems

Указатель на структуру FarList, описывающую пункты для начальной инициализации комбинированного списка. Редактируемое поле заполняется значением первого пункта списка с установленным флагом LIF_SELECTED при условии, что Data не содержит "редактируемый текст" и есть хотя бы один элемент списка с таким флагом. Если таких пунктов несколько, берется первый.

Если значение = NULL, то список выводится не будет.

ListPos

Текущая позиция в списке ListItems.Items. После закрытия диалога это поле содержит позицию выбранного пользователем элемента списка.

Флаги

Для элемента DI_COMBOBOX имеют значения следующие флаги (про флаги списка см. FarListItem):
Флаг | Описание
DIF_DROPDOWNLIST | Стиль нередактируемого раскрывающегося списка - DropDownList.
DIF_EDITEXPAND | "Расширять" переменные среды.
DIF_LISTAUTOHIGHLIGHT | Горячие клавиши будут назначены автоматически.
DIF_LISTNOAMPERSAND | показывать горячие клавиши в списке.
DIF_LISTWRAPMODE | "Заворачивает" список при навигации по списку.
DIF_DISABLE | Элемент является недоступным.
DIF_READONLY | Переводит строки редактирования в состояние "только для чтения"
DIF_SELECTONENTRY | Выделить редактируемый текст при получении фокуса ввода.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_VAREDIT | Использовать указатель на собственный буфер редактирования (FarDialogItem.Ptr.*) вместо FarDialogItem.Data.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки строки редактирования комбинированного списка; Param2:
LoWord LoByte - редактируемый текст
                (COL_WARNDIALOGEDIT или
                 COL_DIALOGEDIT)
LoWord HiByte - выделенный текст
                (COL_DIALOGEDITSELECTED)
HiWord LoByte - неизмененный текст (UnChanched)
                (COL_DIALOGEDITUNCHANGED)
HiWord HiByte - цвет символа для вызова списка
                (COL_DIALOGTEXT)

Param2 (при флаге DIF_DROPDOWNLIST):

LoWord LoByte - редактируемый текст
                (COL_WARNDIALOGEDIT или
                 COL_DIALOGEDIT)
LoWord HiByte - выделенный текст
                (COL_DIALOGEDIT
                элемент в фокусе
                COL_DIALOGEDITSELECTED)
HiWord LoByte - неизмененный текст (UnChanched)
                (COL_WARNDIALOGEDIT или
                 COL_DIALOGEDIT)
HiWord HiByte - цвет символа для вызова списка
                (COL_DIALOGTEXT)
DN_CTLCOLORDLGLIST | запрос цветовых атрибутов перед отрисовкой открытого комбинированного списка.
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_EDITCHANGE | текст изменен
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Смотрите также:
DI_LISTBOX, FarDialogItem


DI_DOUBLEBOX

главная | Dialog API | Элементы диалога
Элемент диалога DI_DOUBLEBOX описывает двойную рамку.
struct FarDialogItem
{
  int Type          = DI_DOUBLEBOX
  int X1            = X1
  int Y1            = Y1
  int X2            = X2
  int Y2            = Y2
  int Focus         = 0
  int Selected      = 0
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = заголовок рамки
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Флаги

Для элемента DI_DOUBLEBOX имеют значения следующие флаги:
Флаг | Описание
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать цветовой атрибут рамки)
DIF_LEFTTEXT | Выравнивать заголовок рамки по левому краю.
DIF_SHOWAMPERSAND | показывать в текстовой строке амперсанд не используя его для определения горячей клавиши

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки рамки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст заголовка рамки
                (COL_WARNDIALOGBOXTITLE или
                 COL_DIALOGBOXTITLE)
LoWord HiByte - выделенный текст заголовка рамки
                (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTBOXTITLE или
                 COL_DIALOGHIGHLIGHTBOXTITLE)
HiWord LoByte - рамка
                (COL_WARNDIALOGBOX или COL_DIALOGBOX)
HiWord HiByte - 0 (не используется)
DN_HOTKEY | горячая клавиша (Alt-Символ)
DN_MOUSECLICK | "кликнули" клавишей мыши

Замечания

  1. Если элемент в массиве управляющих элементов стоит первым, то консольное окно FAR Manager будет содержать заголовок "заголовок рамки".
  2. Если координаты X1==X2 или Y1==Y2, то рисуется соответствующая линия (вертикальная или горизонтальная)
Смотрите также:
DI_SINGLEBOX, FarDialogItem


DI_EDIT

главная | Dialog API | Элементы диалога
Элемент диалога DI_EDIT описывает поле ввода.
struct FarDialogItem
{
  int Type             = DI_EDIT
  int X1               = X1
  int Y1               = Y
  int X2               = X2
  int Y2               = Y (равен значению Y1)
  int Focus            = Focus
  char *History        = History
  DWORD Flags          = Flags
  int DefaultButton    = DefaultButton
  union {
    char Data[512];    = редактируемый текст (без флага DIF_VAREDIT)
    struct {
      DWORD PtrFlags;  = дополнительные флаги (в Dialog API 1.0 не используется)
      int   PtrLength; = размер данных, на которые указывает PtrData
      char *PtrData;   = указатель на пользовательский буфер редактирования
      char  PtrTail[1];= "остаток" - доступ к оставшейся части Data
    } Ptr;             = редактируемый текст (с флагом DIF_VAREDIT)
  };
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

History

Адрес текстовой строки, которая будет использоваться как внутреннее название истории редактирования (см. также флаг DIF_HISTORY). Если значение = NULL, то поле ввода не имеет истории.

Флаги

Для элемента DI_EDIT имеют значения следующие флаги:
Флаг | Описание
DIF_EDITOR | Последовательно определенные поля ввода группируются в редактор с возможностью вставки и удаления строк.
DIF_HISTORY | Позволяет вести историю редактирования для поля ввода.
DIF_MANUALADDHISTORY | Строка для истории редактирования не будет автоматически добавляться в историю по завершению работы диалога.
DIF_USELASTHISTORY | Начальное значение берется из истории.
DIF_EDITEXPAND | "Расширять" переменные среды.
DIF_DISABLE | Элемент является недоступным.
DIF_READONLY | Переводит строки редактирования в состояние "только для чтения"
DIF_SELECTONENTRY | Выделить редактируемый текст при получении фокуса ввода.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_VAREDIT | Использовать указатель на собственный буфер редактирования (FarDialogItem.Ptr.*) вместо FarDialogItem.Data.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - редактируемый текст
                (COL_WARNDIALOGEDIT или
                 COL_DIALOGEDIT)
LoWord HiByte - выделенный текст
                (COL_DIALOGEDITSELECTED)
HiWord LoByte - неизмененный текст (UnChanched)
                (COL_DIALOGEDITUNCHANGED)
HiWord HiByte - цвет символа для History
                (COL_DIALOGTEXT)
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_EDITCHANGE | текст изменен
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).
Смотрите также:
DI_PSWEDIT, DI_FIXEDIT, FarDialogItem


DI_FIXEDIT

главная | Dialog API | Элементы диалога
Элемент диалога DI_FIXEDIT описывает поле ввода фиксированного размера. То же, что и DI_EDIT, но без возможности прокрутки текста.
struct FarDialogItem
{
  int Type          = DI_FIXEDIT
  int X1            = X1
  int Y1            = Y
  int X2            = X2
  int Y2            = Y (равен значению Y1)
  int Focus         = Focus
  union{
    char *History   = History
    char *Mask;     = Mask
  };
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512]    = редактируемый текст
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

History

Адрес текстовой строки, которая будет использоваться как внутреннее название истории редактирования (см. также флаг DIF_HISTORY). Если значение = NULL, то поле ввода не имеет истории.

Mask

Адрес текстовой строки с маской ввода (см. также флаг DIF_MASKEDIT). Если значение = NULL, то поле ввода не имеет маски.
"История" (флаг DIF_HISTORY) имеет более высокий приоритет, чем "Маска" (флаг DIF_MASKEDIT). Т.е. если указаны оба флага, то элемент редактирования будет иметь историю, а флаг DIF_MASKEDIT будет сброшен.

Флаги

Для элемента DI_FIXEDIT имеют значения следующие флаги:
Флаг | Описание
DIF_HISTORY | Позволяет вести историю редактирования для поля ввода.
DIF_MANUALADDHISTORY | Строка для истории редактирования не будет автоматически добавляться в историю по завершению работы диалога.
DIF_USELASTHISTORY | Начальное значение берется из истории.
DIF_MASKEDIT | Поле ввода позволяет вводить значение по указанной маске.
DIF_DISABLE | Элемент является недоступным.
DIF_READONLY | Переводит строки редактирования в состояние "только для чтения"
DIF_SELECTONENTRY | Выделить редактируемый текст при получении фокуса ввода.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - редактируемый текст
                (COL_WARNDIALOGEDIT или COL_DIALOGEDIT)
LoWord HiByte - выделенный текст
                (COL_DIALOGEDITSELECTED)
HiWord LoByte - неизмененный текст (UnChanched)
                (COL_DIALOGEDITUNCHANGED)
HiWord HiByte - цвет символа для History
                (COL_DIALOGTEXT)
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_EDITCHANGE | текст изменен
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Текстовый курсор после инициализации элемента - в режиме замены.

Смотрите также:
DI_EDIT, DI_PSWEDIT, FarDialogItem


DI_LISTBOX

главная | Dialog API | Элементы диалога
Элемент диалога DI_LISTBOX описывает список.
struct FarDialogItem
{
  int Type          = DI_LISTBOX
  int X1            = X1
  int Y1            = Y1
  int X2            = X2
  int Y2            = Y2
  int Focus         = Focus
  union {
    FarList *ListItems= ListItems  [передается]
    int ListPos       = ListPos    [возвращается]
  };
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512];   = Верхний заголовок списка
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

ListItems

Указатель на структуру FarList, описывающую пункты для начальной инициализации списка.

ListPos

Текущая позиция в списке ListItems.Items. После закрытия диалога это поле содержит позицию выбранного пользователем элемента списка.

Флаги

Для элемента DI_LISTBOX имеют значения следующие флаги (про флаги списка см. FarListItem):
Флаг | Описание
DIF_LISTAUTOHIGHLIGHT | Горячие клавиши будут назначены автоматически.
DIF_LISTNOAMPERSAND | Показывать горячие клавиши в списке.
DIF_LISTWRAPMODE | "Заворачивает" список при навигации по списку.
DIF_DISABLE | Элемент является недоступным.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_LISTNOBOX | Отключает прорисовку рамки вокруг списка. В этом случае Data игнорируется.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки элемента
DN_CTLCOLORDLGLIST | запрос цветовых атрибутов для отрисовки списка.
DN_LISTCHANGE | изменилась позиция в списке
DN_LISTHOTKEY | пользователь для смены пункта в списке воспользовался горячими клавишами.
Смотрите также:
DI_COMBOBOX, FarDialogItem


DI_PSWEDIT

главная | Dialog API | Элементы диалога
Элемент диалога DI_PSWEDIT описывает поле ввода пароля - то же, что и элемент DI_EDIT, но вводимый текст на экране отрисовывается символами '*'.
struct FarDialogItem
{
  int Type          = DI_PSWEDIT
  int X1            = X1
  int Y1            = Y
  int X2            = X2
  int Y2            = Y (равен значению Y1)
  int Focus         = Focus
  int Selected      = 0
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512]    = редактируемый текст
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

Флаги

Для элемента DI_PSWEDIT имеют значения следующие флаги:
Флаг | Описание
DIF_DISABLE | Элемент является недоступным.
DIF_READONLY | Переводит строки редактирования в состояние "только для чтения"
DIF_SELECTONENTRY | Выделить редактируемый текст при получении фокуса ввода.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - редактируемый текст
                (COL_WARNDIALOGEDIT или COL_DIALOGEDIT)
LoWord HiByte - выделенный текст
                (COL_DIALOGEDITSELECTED)
HiWord LoByte - неизмененный текст (UnChanched)
                (COL_DIALOGEDITUNCHANGED)
HiWord HiByte - 0 (не используется)
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_EDITCHANGE | текст изменен
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Элемент DI_PSWEDIT позволяет только вставлять текст в поле редактирования. Копирование текста в буфер обмена (Ctrl-Ins или Ctrl-C) для данного элемента не поддерживаются.

Смотрите также:
DI_EDIT, DI_FIXEDIT, FarDialogItem


DI_RADIOBUTTON

главная | Dialog API | Элементы диалога
Элемент диалога DI_RADIOBUTTON описывает селекторную кнопку (Radio Button). Также он называется кнопкой с зависимой фиксацией. Похож на CheckBox, за исключением того, что, если у первого из несколько идущих подряд подобных элементов установлен флаг DIF_GROUP, то они являются взаимоисключающими: если одна кнопка включена, другие обязательно выключены.
struct FarDialogItem
{
  int Type          = DI_RADIOBUTTON
  int X1            = X
  int Y1            = Y
  int X2            = 0 (в Dialog API 1.0 не используется)
  int Y2            = Y (равен значению Y1)
  int Focus         = Focus
  int Selected      = Selected
  DWORD Flags       = Flags
  int DefaultButton = DefaultButton
  char Data[512]    = надпись кнопки
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Focus

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

Selected

Определяет состояние элемента - отмечен или нет.

Флаги

Для элемента DI_RADIOBUTTON имеют значения следующие флаги:
Флаг | Описание
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать атрибут текста кнопки)
DIF_GROUP | группировка последовательно объявленных селекторных кнопок (укажите этот флаг для первого элемента в группе).
DIF_MOVESELECT | изменить выбор внутри группы при изменении фокуса ввода; также элемент будет отображаться без ограничительных круглых скобок (пример - диалог выбора цвета в FAR Manager - Options|Colors).
DIF_CENTERGROUP | центрирование идущих подряд переключателей с одинаковой вертикальной позицией (параметр X игнорируется)
DIF_DISABLE | Элемент является недоступным.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_SHOWAMPERSAND | показывать в заголовке рамки амперсанд не используя его для определения горячей клавиши

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст кнопки
                (COL_WARNDIALOGBUTTON или
                 COL_DIALOGTEXT)
LoWord HiByte - выделенный текст (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTTEXT или
                 COL_DIALOGHIGHLIGHTTEXT)
HiWord LoByte - 0
HiWord HiByte - 0
Если используется заказной атрибут (флаг DIF_SETCOLOR), то текст кнопки (LoWord LoByte) будет тем, что указали.
DN_HOTKEY | горячая клавиша (Alt-Символ)
DN_BTNCLICK | нажата кнопка
DN_KEY | нажали клавишу.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

Хотя координаты X2 и Y2 в Dialog API 1.0 не используется, но для нормальной работы в будущих версиях FAR желательно корректно заполнить значения этих полей.
Смотрите также:
DI_CHECKBOX, DI_BUTTON, FarDialogItem


DI_SINGLEBOX

главная | Dialog API | Элементы диалога
Элемент диалога DI_SINGLEBOX описывает одинарную рамку.
struct FarDialogItem
{
  int Type          = DI_SINGLEBOX
  int X1            = X1
  int Y1            = Y1
  int X2            = X2
  int Y2            = Y2
  int Focus         = 0
  int Selected      = 0
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = заголовок рамки
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Флаги

Для элемента DI_SINGLEBOX имеют значения следующие флаги:
Флаг | Описание
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать цветовой атрибут рамки)
DIF_LEFTTEXT | Выравнивать заголовок рамки по левому краю.
DIF_SHOWAMPERSAND | показывать в заголовке рамки амперсанд не используя его для определения горячей клавиши

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки рамки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст заголовка рамки
                (COL_WARNDIALOGBOXTITLE или
                 COL_DIALOGBOXTITLE)
LoWord HiByte - выделенный текст заголовка рамки
                (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTBOXTITLE или
                 COL_DIALOGHIGHLIGHTBOXTITLE)
HiWord LoByte - рамка
                (COL_WARNDIALOGBOX или
                 COL_DIALOGBOX)
HiWord HiByte - 0 (не используется)
DN_HOTKEY | горячая клавиша (Alt-Символ)
DN_MOUSECLICK | "кликнули" клавишей мыши

Замечания

  1. Если элемент в массиве управляющих элементов стоит первым, то консольное окно FAR Manager будет содержать заголовок "заголовок рамки".
  2. Если координаты X1==X2 или Y1==Y2, то рисуется соответствующая линия (вертикальная или горизонтальная)
Смотрите также:
DI_DOUBLEBOX, FarDialogItem


DI_TEXT

главная | Dialog API | Элементы диалога
Элемент диалога DI_TEXT описывает статическую текстовую строку. В понятиях WinAPI это управляющий элемент STATIC.
struct FarDialogItem
{
  int Type          = DI_TEXT
  int X1            = X1
  int Y1            = Y
  int X2            = X2
  int Y2            = Y (в Dialog API 1.0 не используется, должно быть равно значению Y1)
  int Focus         = 0
  int Selected      = 0
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = выводимый текст
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Флаги

Для элемента DI_TEXT имеют значения следующие флаги:
Флаг | Описание
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать атрибут выводимого текста)
DIF_BOXCOLOR | текст будет иметь цвет рамок (COL_DIALOGBOX или COL_WARNDIALOGBOX)
DIF_CENTERGROUP | центрирование двух текстовых строк с одинаковой вертикальной позицией (параметр X1 игнорируется)
DIF_SEPARATOR горизонтальный разделитель диалога (одинарная линия); координата X1 не используется для случая, когда Data пустая строка;
если Data не пустая строка, то она также будет отрисована (для вывода строки будет использована координата X1);
DIF_SEPARATOR2 горизонтальный разделитель диалога (двойная линия); координата X1 не используется для случая, когда Data пустая строка;
если Data не пустая строка, то она также будет отрисована (для вывода строки будет использована координата X1);
DIF_SHOWAMPERSAND | показывать в текстовой строке амперсанд не используя его для определения горячей клавиши
DIF_CENTERTEXT | выравнивать текст по центру относительно координат X1 и X2

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст
                (COL_WARNDIALOGTEXT или
                 COL_DIALOGTEXT
                при выставленном флаге DIF_BOXCOLOR:
                COL_WARNDIALOGBOX или
                COL_DIALOGBOX)
LoWord HiByte - выделенный текст
                (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTTEXT или
                 COL_DIALOGHIGHLIGHTTEXT)
HiWord LoByte - 0 (не используется)
HiWord HiByte - 0 (не используется)
Если используется заказной атрибут (флаг DIF_SETCOLOR), то текст (LoWord LoByte) будет тем, что указали.
DN_MOUSECLICK | "кликнули" клавишей мыши
DN_HOTKEY | горячая клавиша (Alt-Символ)

Замечания

  1. Хотя координата Y2 в Dialog API 1.0 не используется, но для нормальной работы в будущих версиях FAR желательно корректно заполнить значение этого поля. Укажите то же значение координаты, что и Y1.
  2. Если указан флаг DIF_CENTERTEXT, то координата X2 должна быть обязательно указана, в противном случае действие флага не будет иметь действия.
  3. Если не указан флаг DIF_CENTERTEXT, то FAR самостоятельно перерасчитает координаты X2 и Y2, исходя из размера строки и размера диалога.
  4. Если элемент в массиве управляющих элементов стоит первым, то консольное окно FAR Manager будет содержать заголовок "выводимый текст".
  5. Если в тексте элемента DI_TEXT имеется "горячая клавиша" (HotKey) и не выставлен флаг DIF_SHOWAMPERSAND, то при нажатии в диалоге Alt-Символ клавиатурный фокус ввода перейдет на следующий элемент, который может иметь фокус ввода
Смотрите также:
DI_VTEXT, FarDialogItem


DI_USERCONTROL

главная | Dialog API | Элементы диалога
Свобода выбора! Элемент диалога DI_USERCONTROL описывает элемент управления, определяемый программистом: отрисовка, реагирование на события и прочие операции с элементом - все это возлагается "на хрупкие плечи" плагина.
struct FarDialogItem
{
  int Type          = DI_USERCONTROL
  int X1            = X1
  int Y1            = Y1
  int X2            = X2
  int Y2            = Y2
  int Focus         = User Defined
  CHAR_INFO *VBuf   = виртуальный буфер отрисовки
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = User Defined
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Виртуальный буфер отрисовки

Параметр VBuf задает адрес виртуального буфера типа CHAR_INFO.

Если значение VBuf = NULL, то это значит, что плагин сам должен отрисовывать элемент DI_USERCONTROL после прихода события DN_DRAWDLGITEM, используя сервисную функцию Text.

Если VBuf не равен NULL, то Менеджер Диалогов считает, что это адрес буфера типа CHAR_INFO. Здесь обработчик диалога, в ответ на событие DN_DRAWDLGITEM, должен отрисовать этот элемент в виртуальный буфер, после чего Менеджер Диалогов выдаст содержимое VBuf на экран.

Типичный сценарий следующий (см. плагин Reversi):

// перед вызовом DialogEx, распределим память под виртуальный буфер
#define DIM(Item) (((Item).X2-(Item).X1+1)*((Item).Y2-(Item).Y1+1))
CHAR_INFO *VBuf=new CHAR_INFO[DIM(DialogItems[11])];
DialogItems[11].VBuf=VBuf;
  .
  .
  .
// в обработчике диалога
struct FarDialogItem DialogItem;

case DN_DRAWDLGITEM:
  if(Param1 == 11)
  {
    char Face[4]="   ";
    SMALL_RECT Rect;
    BYTE AddColor=0x00;

    // получим координаты диалога и описание самого элемента
    Info.SendDlgMessage(hDlg,DM_GETDLGRECT,0,(LONG_PTR)&Rect);
    Info.SendDlgMessage(hDlg,DM_GETDLGITEM,11,(LONG_PTR)&DialogItem);

    // цикл отрисовки игрового поля
    for(Y=0; Y < 8; ++Y)
    {
      for(X=0; X < 8; ++X)
      {
        // подготовим один прямоугольник

        // если ячейка не занята...
        if (GAME[0].Field[Y*8+X]==0)
          Face[1]=' ';
        // для белого игрока
        else if (GAME[0].Field[Y*8+X]==GAME[0].Pl1)
        {
          Face[1]=FaceWhite;
          AddColor=0x00;
        }
        // для черного игрока
        else if (GAME[0].Field[Y*8+X]==GAME[0].Pl2)
        {
          Face[1]=FaceBlack;
          AddColor=0x0F;
        }

        // если не получилось когда-то выделить память
        // то рисуем с использованием Text
        if(!DialogItem.VBuf)
        {
          Info.Text(Rect.Left+DialogItem.X1+X*3,
                   Rect.Top+DialogItem.Y1+Y,
                  ColorsPanel[Y&1][X&1]|AddColor,
                  Face);
        }
        else // рисуем прямо в виртуальный буфер
        {
          CHAR_INFO *VBuf=&DialogItem.VBuf[Y*8*3+X*3];

          VBuf[0].Char.AsciiChar=Face[0];
          VBuf[1].Char.AsciiChar=Face[1];
          VBuf[2].Char.AsciiChar=Face[2];

          VBuf[0].Attributes=
             VBuf[1].Attributes=
             VBuf[2].Attributes=ColorsPanel[Y&1][X&1]|AddColor;
        }
      }
    }
  }
  return TRUE;

Флаги

Для элемента DI_USERCONTROL имеют значения следующие флаги:
Флаг | Описание
DIF_NOFOCUS | управляющий элемент не получает клавиатурный фокус ввода
DIF_DISABLE | элемент является недоступным.
DIF_NOTCVTUSERCONTROL | не конвертировать символы (CHAR_INFO::Char) перед выводом виртуального буфера на экран.

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки элемента
DN_KEY | нажата клавиша.
DN_MOUSECLICK | "кликнули" клавишей мыши; начало координат - левый верхний угол элемента
DN_KILLFOCUS | элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS | элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

  1. Замечания по работе с курсором см. в описании сообщений DM_GETCURSORPOS или DM_SETCURSORPOS.
  2. Элемент не имеет эффекта в случае использования функции Dialog.
Смотрите также:
FarDialogItem


DI_VTEXT

главная | Dialog API | Элементы диалога
Элемент диалога DI_VTEXT описывает статическую вертикальную текстовую строку.
struct FarDialogItem
{
  int Type          = DI_VTEXT
  int X1            = X
  int Y1            = Y1
  int X2            = X (в Dialog API 1.0 не используется, должно быть равно значению X1)
  int Y2            = Y2
  int Focus         = 0
  int Selected      = 0
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = выводимый текст
};

Внимание! Внимание!

  • Приведено схематичное изображение структуры; полное описание структуры см. здесь.

Флаги

Для элемента DI_VTEXT имеют значения следующие флаги:
Флаг | Описание
DIF_SETCOLOR | определить цвет элемента (младший байт параметра Flags должен содержать атрибут выводимого текста)
DIF_BOXCOLOR | текст будет иметь цвет рамок (COL_DIALOGBOX или COL_WARNDIALOGBOX)
DIF_CENTERGROUP | центрирование двух текстовых строк с одинаковой горизонтальной позицией (параметр Y1 игнорируется)
DIF_SEPARATOR вертикальный разделитель диалога (одинарная линия); координата Y1 не используется для случая, когда Data пустая строка;
если Data не пустая строка, то она также будет отрисована (для вывода строки будет использована координата Y1);
DIF_SEPARATOR2 вертикальный разделитель диалога (двойная линия); координата Y1 не используется для случая, когда Data пустая строка;
если Data не пустая строка, то она также будет отрисована (для вывода строки будет использована координата Y1);
DIF_SHOWAMPERSAND | показывать в текстовой строке амперсанд не используя его для определения горячей клавиши
DIF_CENTERTEXT | выравнивать текст по центру (учитываются координаты Y1 и Y2).

События

Событие | Описание
DN_DRAWDLGITEM | начало отрисовки текстовой строки
DN_CTLCOLORDLGITEM запрос цветовых атрибутов для отрисовки; Param2:
LoWord LoByte - текст
                (COL_WARNDIALOGTEXT или
                 COL_DIALOGTEXT
                при выставленном флаге DIF_BOXCOLOR:
                 COL_WARNDIALOGBOX или
                 COL_DIALOGBOX)
LoWord HiByte - выделенный текст
                (highlighting text)
                (COL_WARNDIALOGHIGHLIGHTTEXT или
                 COL_DIALOGHIGHLIGHTTEXT)
HiWord LoByte - 0 (не используется)
HiWord HiByte - 0 (не используется)
Если используется заказной атрибут (флаг DIF_SETCOLOR), то текст (LoWord LoByte) будет тем, что указали.
DN_MOUSECLICK | "кликнули" клавишей мыши

Замечания

  • Хотя координата X2 в Dialog API 1.0 не используется, но для нормальной работы в будущих версиях FAR желательно корректно заполнить значение этого поля. Укажите то же значение координаты, что и X1.
  • Если указан флаг DIF_CENTERTEXT, то координата Y2 должна быть обязательно указаны, в противном случае действие флага не будет иметь действия.
  • Если не указан флаг DIF_CENTERTEXT, то FAR самостоятельно перерасчитает координаты X2 и Y2, исходя из размера строки и размера диалога.
  • Если в тексте элемента DI_TEXT имеется "горячая клавиша" (HotKey) и не выставлен флаг DIF_SHOWAMPERSAND, то при нажатии в диалоге Alt-Символ клавиатурный фокус ввода перейдет на следующий элемент, который может иметь фокус ввода
    • Смотрите также:
    DI_TEXT, FarDialogItem


Флаги элементов диалога

главная | Dialog API | Элементы диалога
Поведением и внешним видом управляющих элементов DialogAPI можно управлять посредством флагов. О том, какие флаги на какие элементы воздействуют читайте в описаниях к элементам управления.
Флаг | Описание
DIF_3STATE | Элемент DI_CHECKBOX будет иметь 3 состояния.
DIF_BOXCOLOR | Текст элемента будет иметь цвет рамок.
DIF_BTNNOCLOSE | Для кнопки - не завершать диалог
DIF_CENTERGROUP | Центрирование группы элементов
DIF_CENTERTEXT | Центрирование текста в статических элементах.
DIF_COLORMASK | Маска для выделения цветовых атрибутов
DIF_DISABLE | Элемент является недоступным.
DIF_DROPDOWNLIST | Задает стиль не редактируемого списка.
DIF_EDITEXPAND | "Расширение" переменных среды в строках ввода.
DIF_EDITOR | Последовательно определенные поля ввода
DIF_GROUP | Группировка RadioButtons
DIF_HISTORY | Позволяет вести историю редактирования для поля ввода.
DIF_HIDDEN | Элемент диалога не виден.
DIF_LEFTTEXT | Выравнивать заголовки рамок по левому краю.
DIF_LISTAUTOHIGHLIGHT | Автоматическое назначение горячих клавиш в списке
DIF_LISTNOAMPERSAND | Позволяет показывать горячие клавиши в списке
DIF_LISTNOBOX | Показывать список без рамки
DIF_LISTNOCLOSE | Не закрывать диалог при выборе элемента из списка.
DIF_LISTWRAPMODE | "Заворачивает" список при навигации по списку.
DIF_MANUALADDHISTORY | Обработчик диалога сам будет добавлять строки в историю
DIF_MASKEDIT | Задает маску в строках ввода
DIF_MOVESELECT | Изменить выбор внутри группы radio-кнопок при изменении фокуса ввода.
DIF_NOAUTOCOMPLETE | Отключить автодополнение для строк редактирования.
DIF_NOBRACKETS | Показывает заголовок кнопки без скобок.
DIF_NOFOCUS | Управляющий элемент не получает клавиатурный фокус ввода.
DIF_NOTCVTUSERCONTROL | не конвертировать символы (CHAR_INFO::Char) перед выводом виртуального буфера на экран.
DIF_READONLY | Переводит строки редактирования в состояние "только для чтения".
DIF_SELECTONENTRY | При получении фокуса ввода содержимое строки редактирования будет выделяться.
DIF_SEPARATOR | Текстовая строка отображается как разделитель диалога (одинарная горизонтальная линия).
DIF_SEPARATOR2 | Текстовая строка отображается как разделитель диалога (двойная горизонтальная линия).
DIF_SETCOLOR | Определение цвета элемента.
DIF_SHOWAMPERSAND | Показывать в текстовой строке амперсанд не используя его для определения горячей клавиши
DIF_USELASTHISTORY | Начальное значение берется из истории.
DIF_VAREDIT | Поле ввода неограниченного размера.
Смотрите также:


DIF_3STATE

главная | Dialog API | Флаги элементов диалога

Флаг DIF_3STATE указывает на то, что элемент DI_CHECKBOX будет иметь 3 состояния:

[ ] - выключено     (FarDialogItem.Selected = 0)
[x] - включено      (FarDialogItem.Selected = 1)
[?] - неопределенно (FarDialogItem.Selected = 2)

Элементы

Флаг DIF_3STATE имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_CHECKBOX | контрольный переключатель (Check Box).

Замечания

Применяя флаг DIF_3STATE, необходимо помнить о том, что ожидает пользователь, работая с таким CheckBox`ом. Т.е. если пользователь выбрал неопределенное состояние чекбокса, то опция, которой управляет этот чекбокс, должна вообще игнорироваться при дальнейшей работе. Ярким примером является диалог работы с файловыми атрибутами:

[ ] - сбросить атрибут
[+] - установить атрибут
[?] - ничего с данным атрибутом не делать

Смотрите также:


DIF_BOXCOLOR

главная | Dialog API | Флаги элементов диалога

Флаг DIF_BOXCOLOR позволяет задавать первоначальный цвет элемента, соответствующего цвету рамки диалога (COL_WARNDIALOGBOX или COL_DIALOGBOX).

Элементы

Флаг имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_TEXT | Текстовая строка.
DI_VTEXT | Вертикальная текстовая строка.

Замечания

При получении события DN_CTLCOLORDLGITEM в функции обработки диалога значение цвета можно изменить.

Смотрите также:
DIF_SETCOLOR, Индексы цветов


DIF_BTNNOCLOSE

главная | Dialog API | Флаги элементов диалога

Флаг DIF_BTNNOCLOSE предписывает кнопке при нажатии не закрывать диалог. Обычное поведение кнопок - завершить обработку диалога. Еще один способ переопределить обычное поведение - вернуть значение FALSE для события DN_CLOSE.

Элементы

Флаг DIF_BTNNOCLOSE имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | Кнопка (Push Button).

Замечания

Для диалога без обработчика флаг DIF_BTNNOCLOSE не имеет значения.
Смотрите также:
DM_CLOSE


DIF_CENTERGROUP

главная | Dialog API | Флаги элементов диалога

Последовательно объявленные элементы с флагом DIF_CENTERGROUP и одинаковой вертикальной позицией будут отцентрированы в диалоге. Горизонтальные координаты элементов (X1 и X2) игнорируются.

Элементы

Флаг DIF_CENTERGROUP имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | Кнопка (Push Button).
DI_CHECKBOX | Контрольный переключатель (Check Box).
DI_RADIOBUTTON | Селекторная кнопка (Radio Button).
DI_TEXT | Текстовая строка.
DI_VTEXT | Вертикальная текстовая строка.

Замечания

  1. Удобно использовать для центрирования групп кнопок.
  2. FAR сам обрабатывает центрирование группы при изменении размеров диалога.
Смотрите также:


DIF_CENTERTEXT

главная | Dialog API | Флаги элементов диалога

Флаг DIF_CENTERTEXT позволяет выравнивать текст в элементах DI_TEXT и DI_VTEXT по центру, относительно геометрии элемента.

Элементы

Флаг DIF_CENTERTEXT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_TEXT | Текстовая строка.
DI_VTEXT | Вертикальная текстовая строка.

Замечания

При указании этого флага вы должны обязательно корректно заполнить координаты X2 (для DI_TEXT) и Y2 (для DI_VTEXT).
Смотрите также:


DIF_SETCOLOR

главная | Dialog API | Флаги элементов диалога

Флаг DIF_SETCOLOR позволяет задавать первоначальный цвет элемента, поместив в младший байт переменной FarDialogItem.Flags необходимый цвет элемента.

Значение DIF_COLORMASK является маской, с помощью которой Менеджер Диалогов выделяет переданную ему составляющую цвета.

Элементы

Флаг DIF_SETCOLOR имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | кнопка (Push Button)
DI_CHECKBOX | контрольный переключатель (Check Box).
DI_RADIOBUTTON | селекторная кнопка (Radio Button).
DI_TEXT | текстовая строка.
DI_VTEXT | вертикальная текстовая строка.
DI_DOUBLEBOX | двойная рамка
DI_SINGLEBOX | одиночная рамка

Замечания

При получении события DN_CTLCOLORDLGITEM в функции обработки диалога значение цвета можно изменить.

Смотрите также:
DIF_BOXCOLOR, Индексы цветов


DIF_DISABLE

главная | Dialog API | Флаги элементов диалога

Флаг DIF_DISABLE указывает Менеджеру Диалогов, что данный элемент недоступен (Disabled). Это значит, что такой элемент диалога не получит фокуса ввода и не будет реагировать на мышь, но в тоже время элемент с этим флагом можно изменить программно.

Элементы

Флаг DIF_DISABLE имеет смысл для следующих элементов диалога:
Элемент | Описание
Все | Все элементы диалога могут иметь состояние "недоступен" (Disabled)

Замечания

  1. Для изменения состояния Enable/Disable элемента пошлите сообщение DM_ENABLE Менеджеру Диалогов (функцией SendDlgMessage).
  2. Дизабленные редактируемые элементы диалога отображаются цветом COL_DIALOGEDITDISABLED. Если вы хотите изменить цвет элемента, то в обработчике диалога необходимо добавить, например, следующий код:
    ...
if(msg == DN_CTLCOLORDLGITEM)
{
  if(Param1 >= 9 && Param1 <= 13)
  {
    int Lo=(int)Info.AdvControl(Info.ModuleNumber,ACTL_GETCOLOR,(void*)COL_DIALOGEDIT);
    int Hi=(int)Info.AdvControl(Info.ModuleNumber,ACTL_GETCOLOR,(void*)COL_DIALOGEDITSELECTED);
    return (LONG_PTR)MAKELONG(MAKEWORD(Lo,Hi),MAKEWORD(Lo,Hi));
  }
}
...
    В данном примере меняются предопределенные цвета для дизабленных элементов на цвета, соответствующие нормальному состоянию элемента редактирования.
Смотрите также:


DIF_DROPDOWNLIST

главная | Dialog API | Флаги элементов диалога

Флаг DIF_DROPDOWNLIST задает для элемента DI_COMBOBOX стиль не редактируемого раскрывающегося списка - DropDownList.

Элементы

Флаг DIF_DROPDOWNLIST имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:


DIF_EDITEXPAND

главная | Dialog API | Флаги элементов диалога

Флаг DIF_EDITEXPAND "расширяет" переменные среды после завершения выполнения диалога (например, %TEMP% будет расширен до C:\TEMP)

Элементы

Флаг DIF_EDITEXPAND имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода

Замечания

Для "расширения" переменных среды используется функция ExpandEnvironmentStrings , так что, если значение %VariableName% отсутствует в окружении, то оно (значение) остается нетронутым.

Смотрите также:


DIF_EDITOR

главная | Dialog API | Флаги элементов диалога

Последовательно определенные поля ввода (DI_EDIT), имеющие флаг DIF_EDITOR группируются в редактор с возможностью вставки и удаления строк.

Элементы

Флаг DIF_EDITOR имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_EDIT | строка ввода

Замечания

Для того, чтобы в диалоге создать область редактирования размером в 5 строк, необходимо разместить 5 элементов редактирования типа DI_EDIT с установленным флагом DIF_EDITOR, как показано в пример:

DI_EDIT,5,3,29,3,1,1,DIF_EDITOR,0,"",
DI_EDIT,5,4,29,4,0,1,DIF_EDITOR,0,"",
DI_EDIT,5,5,29,5,0,1,DIF_EDITOR,0,"",
DI_EDIT,5,6,29,6,0,1,DIF_EDITOR,0,"",
DI_EDIT,5,7,29,7,0,1,DIF_EDITOR,0,"",
Смотрите также:


DIF_GROUP

главная | Dialog API | Флаги элементов диалога
Флаг DIF_GROUP выставленный у первого элемента DI_RADIOBUTTON группирует последовательно объявленные радиокнопки:
// диалог выбора цветов в FAR Manager:
...
// первая группа радиокнопок
DI_RADIOBUTTON,6,3,0,0,0,0,F_LIGHTGRAY|B_BLACK|DIF_GROUP|DIF_SETCOLOR|DIF_MOVESELECT,0,"",
DI_RADIOBUTTON,6,4,0,0,0,0,F_BLACK|B_RED|DIF_SETCOLOR|DIF_MOVESELECT,0,"",
...
// вторая группа радиокнопок
DI_RADIOBUTTON,21,3,0,0,0,0,F_LIGHTGRAY|B_BLACK|DIF_GROUP|DIF_SETCOLOR|DIF_MOVESELECT,0,"",
DI_RADIOBUTTON,21,4,0,0,0,0,F_BLACK|B_RED|DIF_SETCOLOR|DIF_MOVESELECT,0,"",
...

Элементы

Флаг DIF_GROUP имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_RADIOBUTTON | селекторная кнопка (Radio Button)

Замечания

Укажите этот флаг для первого элемента в группе.
Смотрите также:


DIF_HIDDEN

главная | Dialog API | Флаги элементов диалога

Флаг DIF_HIDDEN скрывает элемент диалога.

Элементы

Флаг DIF_HIDDEN имеет смысл для следующих элементов диалога:
Элемент | Описание
Все | Все элементы диалога могут скрыты

Замечания

Смотрите также:


DIF_HISTORY

главная | Dialog API | Флаги элементов диалога

Флаг DIF_HISTORY позволяет вести историю редактирования для полей ввода. Если этот флаг установлен, то поле History должно содержать адрес текстовой строки, которая будет использоваться как внутреннее название истории редактирования. Если для нескольких полей ввода оно одинаково, они используют одну и ту же историю редактирования. Для следующего примера (файл ARCPROC.CPP из MultiArc):

const char *PathHistoryName="ExtrDestPath";
struct InitDialogItem InitItems[]={
 ...
 DI_EDIT,5,3,70,3,1,(DWORD)PathHistoryName,DIF_HISTORY,0,DestPath,
 ...
};
история будет храниться в реестре (ключ HKCU\Software\Far\SavedDialogHistory\ExtrDestPath) по одной строке (имена параметров выглядят как "Line<номер>", тип REG_SZ) для каждого введенного пользователем значения.
Параметры, имена которых выглядят как "Locked<номер>" (REG_DWORD), предназначены для обозначения строк, которые являются неудаляемыми (в списке это состояние можно менять нажатием клавиши <Insert>)

Элементы

Флаг DIF_HISTORY имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

  1. Флаг DIF_HISTORY НЕ РАБОТАЕТ с элементом диалога DI_PSWEDIT!
  2. DIF_HISTORY имеет более высокий приоритет, чем флаг DIF_MASKEDIT.
  3. FAR 1.70 beta 3: Если плагин имеет строку ввода с историей, но при этом выход из диалога предполагается осуществлять по Esc (Enter задействован для других целей), то данные не будут попадать в историю, т.к. Esc означает отказ от дальнейшей обработки диалога. В этом случае плагин может сам добавлять нужную строку в историю редактирования. Для этого необходимо послать Менеджеру Диалогов сообщение DM_ADDHISTORY.
  4. Если у элемента выставлен флаг DIF_MANUALADDHISTORY, то Менеджер Диалогов не будет по завершении работы диалога добавлять строку в историю редактирования.
  5. Плагин может также вести совместные с FAR истории, использовав предопределенные наименования:
    имя | назначение
    "SearchText" | строки поиска
    "ReplaceText" | строки замены
    "PersPath" | пути к персональным плагинам
    "Copy" | строки назначения в диалоге копирования
    "LineNumber" | переходы в редакторе (Alt-F8)
    "ViewerOffset" | переходы в программе просмотра (Alt-F8)
    "NewEdit" | редактируемые файлы (Shift-F4/Shift-F2)
    "Masks" | маски файлов (пометка, ассоциации, фильтры, поиск файлов)
    "UserVarN" | переменные в подстановках
    "ApplyCmd" | "выполнить команду" (Ctrl-G)
    "DizText" | строки ввода описаний файлов
    "NewFolder" | создание каталогов
Смотрите также:
DIF_USELASTHISTORY, DM_ADDHISTORY, DIF_MANUALADDHISTORY.


DIF_LEFTTEXT

главная | Dialog API | Флаги элементов диалога

Флаг DIF_LEFTTEXT позволяет выравнивать заголовки рамок по левому краю. По умолчанию заголовки рамок выровнены по-центру.

Элементы

Флаг DIF_LEFTTEXT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_DOUBLEBOX | двойная рамка
DI_SINGLEBOX | одиночная рамка

Замечания

Смотрите также:


DIF_LISTAUTOHIGHLIGHT

главная | Dialog API | Флаги элементов диалога

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

Элементы

Флаг DIF_LISTAUTOHIGHLIGHT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:


DIF_LISTNOAMPERSAND

главная | Dialog API | Флаги элементов диалога

Флаг DIF_LISTNOAMPERSAND позволяет показывать горячие клавиши в списке. По умолчанию амперсанды в строках списка показываются на экране, а не используются для назначения горячих клавиш.

Элементы

Флаг DIF_LISTNOAMPERSAND имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:


DIF_LISTNOBOX

главная | Dialog API | Флаги элементов диалога

Флаг DIF_LISTNOBOX отключает прорисовку рамки вокруг списка DI_LISTBOX.

Элементы

Флаг DIF_LISTNOBOX имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_LISTBOX | список

Замечания

Смотрите также:


DIF_LISTNOCLOSE

главная | Dialog API | Флаги элементов диалога

Флаг DIF_LISTNOCLOSE предписывает списку при выборе элемента не закрывать диалог. Обычное поведение списка при выборе элемента - завершить обработку диалога. Еще один способ переопределить обычное поведение - вернуть значение FALSE для события DN_CLOSE.

Элементы

Флаг DIF_LISTNOCLOSE имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список


DIF_LISTWRAPMODE

главная | Dialog API | Флаги элементов диалога

Если указан DIF_LISTWRAPMODE, то попытка перемещения курсора в списке выше первого пункта или ниже последнего будет приводить к перемещению соответственно к последнему или к первому пункту.

Элементы

Флаг DIF_LISTWRAPMODE имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:


DIF_MANUALADDHISTORY

главная | Dialog API | Флаги элементов диалога

Флаг DIF_MANUALADDHISTORY указывает Менеджеру Диалогов, что обработчик диалога сам будет добавлять строки в историю.

Элементы

Флаг DIF_MANUALADDHISTORY имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

  1. Добавление строки в историю осуществляется с помощью сообщения DM_ADDHISTORY.
  2. Флаг является дополнением к флагу DIF_HISTORY и сам по себе не несет никакой смысловой нагрузки.
Все это позволяет наиболее полно контролировать процесс добавления строки в историю редактирования.
Смотрите также:
DIF_HISTORY, DM_ADDHISTORY


DIF_MASKEDIT

главная | Dialog API | Флаги элементов диалога

Флаг DIF_MASKEDIT позволяет для элемента диалога DI_FIXEDIT указать маску ввода. Если этот флаг установлен, то поле Mask должно содержать адрес текстовой строки со значением маски ввода.

На данный момент поддерживаются следующие символы маски:
'X' | позволяет вводить в данную позицию строки ввода любой символ;
'#' | позволяет вводить в данную позицию строки ввода цифры, пробел и знак минуса;
'9' | позволяет вводить в данную позицию строки ввода только цифры;
'A' | позволяет вводить в данную позицию строки ввода только буквы.
'H' | позволяет вводить в данную позицию строки ввода только шестнадцатиричные символы.
Можно создавать разнообразнейшие маски ввода, например: "(###) #99-99-99". В этой маске скобки и дефисы между девятками будут статическими (не удаляемыми) элементами строки, внутри скобок можно ввести либо цифры либо пробелы (к примеру телефонный код города), в позициях, где стоят девятки в строке ввода, можно ввести только цифры.
Есть некоторый нюанс по использованию DIF_MASKEDIT. Когда вы задаёте строку маски (к примеру, "99.99.9999") учтите, что работа реализована таким образом, что длина строки ввода принудительно устанавливается равной длине строки маски.

Элементы

Флаг DIF_MASKEDIT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

Флаг DIF_HISTORY имеет более высокий приоритет, чем DIF_MASKEDIT.

Смотрите также:


DIF_MOVESELECT

главная | Dialog API | Флаги элементов диалога

Флаг DIF_MOVESELECT позволяет изменять выбранный элемент внутри группы элементов DI_RADIOBUTTON при изменении фокуса ввода. При этом сам элемент будет иметь другой вид - отрисовка без круглых скобок. Пример работы этого флага см. в диалоге настройки цветов FAR Manager.

Элементы

Флаг DIF_MOVESELECT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_RADIOBUTTON | селекторная кнопка (Radio Button)

Замечания

Смотрите также:


DIF_NOAUTOCOMPLETE

главная | Dialog API | Флаги элементов диалога

Флаг DIF_NOAUTOCOMPLETE отключает автодополнение для строк редактирования.

Элементы

Флаг DIF_NOAUTOCOMPLETE имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Смотрите также:


DIF_NOBRACKETS

главная | Dialog API | Флаги элементов диалога

Флаг DIF_NOBRACKETS заставляет Менеджер Диалогов показывать заголовок кнопки DI_BUTTON без квадратных скобок.

Элементы

Флаг DIF_NOBRACKETS имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | кнопка (Push Button)

Замечания

Смотрите также:


DIF_NOFOCUS

главная | Dialog API | Флаги элементов диалога

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

Элементы

Флаг DIF_NOFOCUS имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | кнопка (Push Button)
DI_CHECKBOX | контрольный переключатель (Check Box).
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_COMBOBOX | комбинированный список
DI_RADIOBUTTON | селекторная кнопка (Radio Button)
DI_PSWEDIT | поле ввода пароля
DI_LISTBOX | список
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

Смотрите также:


DIF_NOTCVTUSERCONTROL

главная | Dialog API | Флаги элементов диалога

Элемент управления с флагом DIF_NOTCVTUSERCONTROL перед выводом виртуального буфера на экран не будет конвертировать символы (CHAR_INFO::Char). Без этого флага FAR использует только компоненту CHAR_INFO::Char.AsciiChar конвертируя её в соответствии с текущим методом вывода на экран (OEM или Unicode).

Элементы

Флаг DIF_NOTCVTUSERCONTROL имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

Смотрите также:


DIF_READONLY

главная | Dialog API | Флаги элементов диалога

Флаг DIF_READONLY переводит строки редактирования в состояние "только для чтения".

Элементы

Флаг DIF_READONLY имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Смотрите также:


DIF_SELECTONENTRY

главная | Dialog API | Флаги элементов диалога
При получении фокуса ввода содержимое строки редактирования с флагом DIF_SELECTONENTRY будет выделяться.

Элементы

Флаг DIF_SELECTONENTRY имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Выделение в строке ввода, имеющей флаг DIF_SELECTONENTRY, будет сниматься при потери фокуса ввода.

Смотрите также:


DIF_SEPARATOR

главная | Dialog API | Флаги элементов диалога

Текстовая строка DI_TEXT с флагом DIF_SEPARATOR отображается как одинарная горизонтальная линия с двойными боковыми линиями.

Элементы

Флаг DIF_SEPARATOR имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_TEXT | Текстовая строка.
DI_VTEXT | Вертикальная текстовая строка.

Замечания

  1. Координаты отрисовки разделительной линии (левый край диалога = 0): X1 = X1_Диалога + 3; X2 = X2_Диалога - 3.
  2. Координата X1 влияет только на позиционирование текстовой строки (отображается поверх разделительной линии) из Data. Если вам нужна разделительная линия с центрированным текстом, то укажите X1 = -1.
  3. Если Data содержит пустую строку, элемент отображается просто как разделительная линия.
Смотрите также:
DIF_SEPARATOR2


DIF_SEPARATOR2

главная | Dialog API | Флаги элементов диалога

Текстовая строка DI_TEXT с флагом DIF_SEPARATOR2 отображается как двойная горизонтальная линия с двойными боковыми линиями.

Элементы

Флаг DIF_SEPARATOR2 имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_TEXT | текстовая строка
DI_VTEXT | Вертикальная текстовая строка.

Замечания

  1. Координаты отрисовки разделительной линии (левый край диалога = 0): X1 = X1_Диалога + 3; X2 = X2_Диалога - 3.
  2. Координата X1 влияет только на позиционирование текстовой строки (отображается поверх разделительной линии) из Data. Если вам нужна разделительная линия с центрированным текстом, то укажите X1 = -1.
  3. Если Data содержит пустую строку, элемент отображается просто как разделительная линия.
Смотрите также:
DIF_SEPARATOR


DIF_SHOWAMPERSAND

главная | Dialog API | Флаги элементов диалога

Флаг DIF_SHOWAMPERSAND заставляет показывать в текстовой строке и рамках амперсанд (&), не используя его для определения горячей клавиши.

Элементы

Флаг DIF_SHOWAMPERSAND имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_BUTTON | кнопка (Push Button)
DI_CHECKBOX | контрольный переключатель (Check Box).
DI_RADIOBUTTON | селекторная кнопка (Radio Button).
DI_TEXT | текстовая строка.
DI_VTEXT | Вертикальная текстовая строка.
DI_DOUBLEBOX | двойная рамка
DI_SINGLEBOX | одиночная рамка

Замечания

Смотрите также:


DIF_USELASTHISTORY

главная | Dialog API | Флаги элементов диалога

Строка ввода с установленными флагами DIF_HISTORY и DIF_USELASTHISTORY получает начальное значение из последнего элемента истории, если начальное значение поля редактирования не задано.

Элементы

Флаг DIF_USELASTHISTORY имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

Смотрите также:
DIF_HISTORY


DIF_VAREDIT

главная | Dialog API | Флаги элементов диалога

Флаг DIF_VAREDIT - это "преодоление барьера в 512 байт для поля ввода". Менеджер диалогов при работе со строкой редактирования или комбинированным списком (с выставленным флагом DIF_VAREDIT) будет учитывать только члены Ptr.* структуры FarDialogItem.

Элементы

Флаг DIF_VAREDIT имеет смысл для следующих элементов диалога:
Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода

Замечания

  1. Плагин должен сам позаботится о выделении памяти для FarDialogItem.Ptr.PtrData и корректно заполнить размер этой памяти (FarDialogItem.Ptr.PtrLength).

  2. Если размер используемых данных не превышает значения 512 байт (или sizeof(FarDialogItem.Data)), то не имеет смысла использовать флаг DIF_VAREDIT.
Смотрите также:


Сообщения Dialog API

главная | Dialog API | События

Сообщение | Описание
DM_ADDHISTORY | добавить строку в историю
DM_CLOSE | сигнал на закрытие диалога
DM_EDITUNCHANGEDFLAG | управление состоянием "неизмененный текст" строки редактирования
DM_ENABLE | переключение/получение состояния Enable/Disable элемента
DM_ENABLEREDRAW | отключение/включение перерисовки всего диалога
DM_GETCHECK | получить состояние элементов DI_CHECKBOX и DI_RADIOBUTTON
DM_GETCOMBOBOXEVENT | получить состояние посылки событий для открытого combo box
DM_GETCURSORPOS | получить позицию курсора
DM_GETCURSORSIZE | получить размеры курсора
DM_GETDLGDATA | получить данные, ассоциированные с диалогом
DM_GETDLGITEM | получение полной информации о элементе
DM_GETDLGRECT | получить координаты диалогового окна
DM_GETDROPDOWNOPENED | определить - есть ли в диалоге раскрытый комбобокс или история
DM_GETEDITPOSITION | получить позицию курсора в строках ввода
DM_GETFOCUS | получить индекс элемента, имеющего фокус ввода
DM_GETITEMDATA | получить данные, ассоциированные с элементом диалога
DM_GETITEMPOSITION | получить позицию и размер элемента
DM_GETSELECTION | получить параметры выделения в строках редактирования диалога
DM_GETTEXT | получение строки ввода или заголовка элементов
DM_GETTEXTLENGTH | получить размер строки
DM_GETTEXTPTR | получение строки ввода или заголовка элементов
DM_KEY | передать массив клавиш обработчику диалога
DM_LISTADD | добавить в список новый элемент
DM_LISTADDSTR | добавить в список строку
DM_LISTDELETE | удалить элементы списка
DM_LISTFINDSTRING | найти элемент списка
DM_LISTGETCURPOS | получить текущую позицию в списке
DM_LISTGETDATA | получить данные, ассоциированные с элементом списка
DM_LISTGETDATASIZE | получить размер данных, ассоциированных с элементом списка
DM_LISTGETITEM | получить один элемент списка
DM_LISTGETTITLES | получить заголовки списка
DM_LISTINFO | получить информацию о списке
DM_LISTINSERT | вставить элемент в список
DM_LISTSET | добавление элементов в список с удалением предыдущих элементов
DM_LISTSETCURPOS | установить позицию в списке
DM_LISTSETDATA | установить данные, ассоциированные с элементом списка
DM_LISTSETMOUSEREACTION | управление реакцией движения мыши в списке DI_LISTBOX
DM_LISTSETTITLES | установить заголовки списка
DM_LISTSORT | сортировать элементы списка
DM_LISTUPDATE | обновить элемент в списке
DM_MOVEDIALOG | переместить диалог
DM_REDRAW | перерисовать весь диалог
DM_RESIZEDIALOG | изменить размеры диалога
DM_SET3STATE | изменить стиль DI_CHECKBOX
DM_SETCHECK | установить состояние элементов DI_CHECKBOX и DI_RADIOBUTTON
DM_SETCOMBOBOXEVENT | включить или отключить посылку сообщений DN_KEY или DN_MOUSEEVENT для открытого combo box
DM_SETCURSORPOS | позиционировать курсор
DM_SETCURSORSIZE | установить размер курсора
DM_SETDLGDATA | ассоциировать данные с диалогом
DM_SETDLGITEM | для изменения информации о заданном элементе
DM_SETDROPDOWNOPENED | программное раскрытие/закрытие комбобокса или истории
DM_SETEDITPOSITION | управление позицией курсора в строках ввода
DM_SETFOCUS | устанавливает клавиатурный фокус на заданный элемент диалога
DM_SETHISTORY | управление наличием истории.
DM_SETITEMDATA | ассоциировать данные с элементом диалога
DM_SETITEMPOSITION | изменить позицию элемента
DM_SETMAXTEXTLENGTH | задать максимальный размер редактируемой строки или заголовка элемента
DM_SETMOUSEEVENTNOTIFY | управление первичным событием мыши
DM_SETSELECTION | выделить блок в строках редактирования диалога
DM_SETTEXT | установить строку ввода или заголовок элемента
DM_SETTEXTPTR | установить строку ввода или заголовок элемента
DM_SHOWDIALOG | показать/спрятать диалоговое окно.
DM_SHOWITEM | показать/спрятать элемент диалога.
DM_USER | отправная точка для пользовательских сообщений
Смотрите также:
События Dialog API


DM_ADDHISTORY

Сообщения | Dialog API
Сообщение DM_ADDHISTORY посылается Менеджеру диалогов для добавления строки в историю.

Param1

ID элемента диалога.

Param2

Указатель на строку, которая будет помещена в историю.

Return

TRUE - данные добавлены в историю.
FALSE - указанный элемент диалога Param1 не поддерживает работу с историей.

Элементы

Элемент | Описание
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

Сообщение работает только для элементов DI_EDIT и DI_FIXEDIT с установленным флагом DIF_HISTORY. Также строки будут автоматически добавляться в историю, если у указанных элементов не выставлен флаг DIF_MANUALADDHISTORY.

Пример

Например, в калькуляторе нажатие клавиши Enter должно приводить к вычислению выражения (Esc - стандартный выход из калькулятора). Для того, чтобы запомнить введенную строку в истории, необходимо после получения сообщения о нажатии клавиши Enter получить эту строку и занести ее в историю:
FarDialogItem dialog[] = {
...
  { DI_EDIT, 10, 3, 49, 0, 1, (int)"foo_history", DIF_HISTORY|DIF_MANUALADDHISTORY, 0, "" },
...
};

LONG_PTR WINAPI FooDlgProc(HANDLE hDlg, int Msg, int Param1, LONG_PTR Param2)
{
...
    if (Msg == DM_KEY && Param2 == KEY_ENTER){
      Info.SendDlgMessage(hDlg, DM_GETTEXTPTR, 2, (LONG_PTR)Text);
      Info.SendDlgMessage(hDlg, DM_ADDHISTORY, 2, (LONG_PTR)Text);
      Res = AData.Parse(Text);
...
}
Смотрите также:
DialogEx, DIF_HISTORY, DIF_MANUALADDHISTORY.


DM_CLOSE

Сообщения | Dialog API
Сообщение DM_CLOSE посылается в обработчик диалога как сигнал, сообщающий, что диалог будет закрыт.

Param1

ID элемента, который будет возвращен из функции DialogEx (или -1 для элемента, имеющего фокус ввода).

Param2

0

Return

Значение, которое обработчик диалога вернет в ответ на событие DN_CLOSE.

Замечания

Событие DN_CLOSE приходит сразу после посылки сообщения DM_CLOSE.

Пример

Смотрите также:
DialogEx, DN_CLOSE


DM_EDITUNCHANGEDFLAG

Сообщения | Dialog API
Команда DM_EDITUNCHANGEDFLAG предназначена для управления состоянием "неизмененный текст" строк редактирования.

Param1

ID элемента управления.

Param2

Одно из трех значений;
-1 - получить текущее состояние строки редактирования;
0 - сбросить состояние "неизмененный текст";
1 - установить состояние "неизмененный текст".

Return

Предыдущее состояние "неизмененный текст" строки редактирования.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список (без флага DIF_DROPDOWNLIST)
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

  1. В начале работы диалога перечисленные элементы, кроме DI_FIXEDIT, уже имеют состояние "неизмененный текст".
  2. После установки состояния "неизмененный текст" выделение блока будет сброшено.
Смотрите также:
DialogEx


DM_ENABLE

Сообщения | Dialog API
Команда DM_ENABLE посылается ядру Dialog API для переключения или получения состояния Enable/Disable конкретного элемента диалога.

Param1

ID элемента диалога

Param2

Состояние элемента:
TRUE - Enable
FALSE - Disable
-1 - получить состояние

Return

Предыдущее состояние элемента:
TRUE - Enabled
FALSE - Disabled

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

Пример

Смотрите также:


DM_ENABLEREDRAW

Сообщения | Dialog API
Команда DM_ENABLEREDRAW посылается Менеджеру диалогов для отключения/включения перерисовки всего диалога.

Param1

TRUE - Включить отрисовку диалога
FALSE - Отключить отрисовку диалога
-1 - Получить текущее значение счетчика блокировки вывода.

Param2

0

Return

Предыдущее значение счетчика блокировки вывода.

Замечания

Эта команда предназначена в основном для того, чтобы исключить перерисовку диалога при изменении нескольких элементов одновременно. Когда посылается это сообщение - счетчик блокировки при Param1 = TRUE увеличивается, при Param1 = FALSE - уменьшается. Диалог отрисовывается, когда значение счетчика равно 0. Это нормальное поведение для вложенных манипуляций. Типичное использование:
Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0);

// изменяем кучу заголовков

Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,TRUE,0);
Смотрите также:
DialogEx


DM_GETCHECK

Сообщения | Dialog API
Сообщение DM_GETCHECK посылается Менеджеру диалогов для получения состояния элементов DI_CHECKBOX и DI_RADIOBUTTON.

Param1

ID требуемого элемента

Param2

0

Return

Состояние элемента: BSTATE_UNCHECKED, BSTATE_CHECKED, BSTATE_3STATE.

Элементы

Элемент | Описание
DI_CHECKBOX | Контрольный переключатель (Check Box).
DI_RADIOBUTTON | Селекторная кнопка (Radio Button).

Замечания

Пример

Смотрите также:
DialogEx | DM_SETCHECK | DM_SET3STATE.


DM_GETCOMBOBOXEVENT

Сообщения | Dialog API
Сообщение DM_GETCOMBOBOXEVENT возвращает режим посылки сообщений DN_KEY и DN_MOUSEEVENT в диалоговую процедуру при навигации в открытом элементе DI_COMBOBOX.

Param1

ID требуемого элемента DI_COMBOBOX.

Param2

0

Return

Состояние режима (перечисление FARCOMBOBOXEVENTTYPE).

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список

Замечания

Пример

Смотрите также:
DM_SETCOMBOBOXEVENT


DM_GETCURSORPOS

Сообщения | DM_SETCURSORPOS| Dialog API
Сообщение DM_GETCURSORPOS посылается обработчику диалога для получения позиции курсора в строках редактирования диалога и в элементе DI_USERCONTROL.

Param1

ID элемента

Param2

Указатель на структуру COORD, в которую Менеджер Диалогов поместит информацию о положении курсора (COORD.Y = 0 для строкового редактора).

Return

FALSE - указанный ID элемента не является строковым редактором или элементом DI_USERCONTROL.
TRUE - структура COORD содержит координаты курсора.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

Пример

Смотрите также:


DM_GETCURSORSIZE

Сообщения | DM_SETCURSORSIZE| Dialog API
Сообщение DM_GETCURSORSIZE посылается обработчику диалога для получения размера курсора в строках редактирования диалога и в элементе DI_USERCONTROL.

Param1

ID элемента

Param2

0

Return

Старшее слово - размер курсора (от 0 до 100, в терминах структуры CONSOLE_CURSOR_INFO), младшее слово - признак видимости курсора (1 - курсор видим, 0 - курсор невидим).

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список (без флага DIF_DROPDOWNLIST)
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

Пример

Смотрите также:


DM_GETDLGDATA

Сообщения | Dialog API
Сообщение DM_GETDLGDATA возвращает 32-битное значение, связанное с диалогом. Каждый диалог имеет соответствующее 32-битное значение, предназначенное для использования плагином, который создавал диалог.

Param1

0

Param2

0

Return

Менеджер Диалогов возвращает 32-битное значение ранее переданное плагином.

Замечания

Первоначально здесь находится то, что передано в параметре Param функции DialogEx.

Пример

Смотрите также:
DialogEx, DM_SETDLGDATA


DM_GETDLGITEM

Сообщения | Dialog API
Сообщение DM_GETDLGITEM посылается Менеджеру диалогов для получения полной информации о заданном элементе.

Param1

ID элемента диалога

Param2

Указатель на структуру FarDialogItem.

Return

TRUE - данные скопированы или FALSE - для неверного ID элемента.

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

Пример

// получить параметры 12-го элемента
struct FarDialogItem DialogItem;

Info.SendDlgMessage(hDlg,DM_GETDLGITEM,12,(LONG_PTR)&DialogItem);
Смотрите также:


DM_GETDLGRECT

Сообщения | Dialog API
Сообщение DM_GETDLGRECT позволяет получить экранные координаты диалогового окна.

Param1

0

Param2

Указатель на структуру SMALL_RECT в которой менеджер диалогов вернет экранные координаты диалога.

Return

TRUE - данные скопированы или FALSE, если в качестве Param2 передано значение NULL.

Пример

struct InitDialogItem InitDlg[]={
...
/*11*/  DI_USERCONTROL,9,4,32,11,0,0,DIF_NOFOCUS,0,"",
...
};

LONG_PTR WINAPI ReversiDialogProc(HANDLE hDlg, int Msg,int Param1,LONG_PTR Param2)
{
...
    case DN_DRAWDLGITEM:
      if(Param1 == 11)
      {
        SMALL_RECT Rect;
        Info.SendDlgMessage(hDlg,DM_GETDLGRECT,0,(LONG_PTR)&Rect);
        ...
              Info.Text(Rect.Left+DialogItem.X1+X*3,
                       Rect.Top+DialogItem.Y1+Y,
                      ColorsPanel[Y&1][X&1]|AddColor,
                      Face);
        ...
...
}
Смотрите также:


DM_GETDROPDOWNOPENED

Сообщения | Dialog API
Сообщение DM_GETDROPDOWNOPENED служит для программного определения: "есть ли в диалоге раскрытый комбобокс или история".

Param1

0

Param2

0

Return

FALSE - в диалоге нет открытого комбобокса или истории.
TRUE - в диалоге есть открытый комбобокс или история.

Элементы

Элемент | Описание
Диалог | сообщение затрагивает только диалог

Замечания

Пример

Смотрите также:


DM_GETEDITPOSITION

Сообщения | DM_SETEDITPOSITION| Dialog API
Сообщение DM_GETEDITPOSITION посылается обработчику диалога для получения позиции и состояния курсора в строках редактирования диалога.

Param1

ID элемента

Param2

Указатель на структуру EditorSetPosition, в которую Менеджер Диалогов поместит информацию о позиции и состоянии курсора.

Return

FALSE - указанный ID элемента не является строковым редактором.
TRUE - структура EditorSetPosition заполнена.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Пример

Смотрите также:


DM_GETFOCUS

Сообщения | Dialog API
Сообщение DM_GETFOCUS посылается Менеджеру Диалогов для получения ID элемента диалога, имеющего клавиатурный фокус ввода.

Param1

0

Param2

0

Return

ID элемента, имеющего клавиатурный фокус ввода.

Элементы

Элемент | Описание
Все | Все элементы, которые могут иметь клавиатурный фокус ввода.

Замечания

Пример

Смотрите также:
DialogEx


DM_GETITEMDATA

Сообщения | Dialog API
Сообщение DM_GETITEMDATA возвращает 32-битное значение, связанное с элементом диалога. Каждый элемент диалога имеет соответствующее 32-битное значение, предназначенное для использования плагином, который создавал диалог.

Param1

ID элемента управления.

Param2

0

Return

Менеджер Диалогов возвращает 32-битное значение, ранее переданное плагином (или 0, если плагин не ассоциировал данные с этим элементом диалога).

Замечания

Пример

Смотрите также:
DialogEx, DM_SETITEMDATA, DM_GETDLGDATA DM_SETDLGDATA,


DM_GETITEMPOSITION

Сообщения | Dialog API
Сообщение DM_GETITEMPOSITION позволяет получить позицию и размеры управляющего элемента.

Param1

ID элемента диалога.

Param2

Указатель на структуру SMALL_RECT в которой менеджер диалогов вернет размеры элемента.

Return

TRUE - данные скопированы или FALSE, если в качестве Param2 передано значение NULL или такого элемента нет.

Пример

Смотрите также:


DM_GETSELECTION

Сообщения | DM_SETSELECTION| Dialog API
Сообщение DM_GETSELECTION посылается обработчику диалога для получения параметров выделения в строках редактирования диалога.

Param1

ID элемента

Param2

Указатель на структуру EditorSelect, в которую Менеджер Диалогов поместит информацию о выделении в сроке редактирования.

Return

FALSE - указанный ID элемента не является строковым редактором.
TRUE - структура EditorSelect содержит параметры выделения.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Пример

Смотрите также:


DM_GETTEXT

Сообщения | Dialog API
Сообщение DM_GETTEXT посылается Менеджеру диалогов для получения содержимого строк ввода или заголовков элементов диалога.

Param1

ID требуемого элемента

Param2

Указатель на структуру FarDialogItemData.
Если Param2 = NULL - это еще один способ получить требуемый размер данных (см. DM_GETTEXTLENGTH):
LenData=SendDlgMessage(hDlg,DM_GETTEXT,1,(LONG_PTR)NULL);
эквивалентно
LenData=SendDlgMessage(hDlg,DM_GETTEXTLENGTH,1,0);

Return

Размер данных без завершающего символа конца строки '\0'.

Элементы

Элемент | Описание
Все | Для строк ввода - содержимое строки, для прочих элементов - заголовки. Все то, что содержится в FarDialogItem.Data или FarDialogItem.PtrData.

Замечания

Сообщение DM_GETTEXT в версиях FAR вплоть до 1.70 beta 3 возвращало размер данных с учетом символа конца строки.

Пример

Смотрите также:


DM_GETTEXTPTR

Сообщения | Dialog API
Сообщение DM_GETTEXTPTR посылается Менеджеру диалогов для получения содержимого строк ввода или заголовков элементов диалога. В отличие от сообщения DM_GETTEXT, это сообщение работает с указателем на строку.

Param1

ID требуемого элемента

Param2

Указатель на строку приемник.
Если Param2 = NULL - это еще один способ получить размер данных (см. DM_GETTEXTLENGTH)

Return

Размер данных без завершающего символа конца строки '\0'.

Элементы

Элемент | Описание
Все | Для строк ввода - содержимое строки, для прочих элементов - заголовки. Все то, что содержится в FarDialogItem.Data или FarDialogItem.PtrData.

Замечания

Сообщение DM_GETTEXTPTR в версиях FAR вплоть до 1.70 beta 3 возвращало размер данных с учетом символа конца строки.

Пример

Смотрите также:


DM_GETTEXTLENGTH

Сообщения | Dialog API
Сообщение DM_GETTEXTLENGTH посылается Менеджеру Диалогов для получения размера данных, содержащихся в FarDialogItem.Data или значения поля FarDialogItem.Ptr.PtrLength.

Param1

ID элемента диалога

Param2

0

Return

Размер данных без завершающего символа конца строки '\0'.

Элементы

Элемент | Описание
Все | Все элементы диалога.

Замечания

Сообщение DM_GETTEXTLENGTH в версиях FAR вплоть до 1.70 beta 3 возвращало размер данных с учетом символа конца строки.

Пример

Смотрите также:
DialogEx


DM_KEY

Сообщения | Dialog API
Используя сообщение DM_KEY плагин передает массив значений кодов клавиш Менеджеру диалогов.

Param1

Количество передаваемых клавиш.

Param2

Указатель на массив (типа DWORD) внутренних кодов клавиш.

Return

0

Замечания

Обработчик диалога не получит события DN_KEY в ответ на посылку Менеджеру диалогов сообщения DM_KEY.

Пример

Пример передачи набора клавиш диалогу (фокусному элементу):

// в конец строки редактирования добавить точку с запятой.
DWORD Keys[2]={KEY_END,';'};

Info.SendDlgMessage(hDlg,DM_KEY,sizeof(Keys)/sizeof(Keys[0]),(LONG_PTR)Keys);
Смотрите также:
DialogEx, DN_KEY


DM_LISTADD

Сообщения | Dialog API
Сообщение DM_LISTADD посылается Менеджеру диалогов для добавления элементов в список DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на добавляемые пункты списка (структуру типа FarList).

Return

TRUE - данные добавлены в список.
FALSE - ошибка при добавлении данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

Смотрите также:

DialogEx


DM_LISTADDSTR

Сообщения | Dialog API
Сообщение DM_LISTADDSTR посылается Менеджеру диалогов для добавления строки в список DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на добавляемую строку.

Return

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

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

Смотрите также:

DialogEx


DM_LISTDELETE

Сообщения | Dialog API
Сообщение DM_LISTDELETE посылается Менеджеру диалогов для удаления элементов из списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру типа FarListDelete, описывающую параметры удаления, или NULL.

Return

TRUE - данные удалены из списка.
FALSE - ошибка при удалении данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Если в качестве Param2 задано значение NULL, то из списка будут удалены все элементы.

Пример

// *** УДАЛИТЬ ПЕРВЫЕ ДВА ЭЛЕМЕНТА СПИСКА ***
struct FarListDelete FLDItem;
FLDItem.StartIndex=0;
FLDItem.Count=2;
Info.SendDlgMessage(hDlg,DM_LISTDELETE,ID,(LONG_PTR)&FLDItem);

// *** ОЧИСТИТЬ ВЕСЬ СПИСОК ***
  //   Способ 1:
  struct FarListDelete FLDItem={0,0};
  Info.SendDlgMessage(hDlg,DM_LISTDELETE,ID,(LONG_PTR)&FLDItem);

  //   Способ 2:
  Info.SendDlgMessage(hDlg,DM_LISTDELETE,ID,(LONG_PTR)NULL);
Смотрите также:
DialogEx, FarListDelete


DM_LISTFINDSTRING

Сообщения | Dialog API
Сообщение DM_LISTFINDSTRING посылается Менеджеру диалогов для поиска элемента списка DI_COMBOBOX или DI_LISTBOX по шаблону.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру, описывающую искомый пункт списка (структуру типа FarListFind).

Return

Позиция найденного элемента в списке (начиная с нуля).
-1 - элемент в списке не найден.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

Смотрите также:


DM_LISTGETCURPOS

Сообщения | Dialog API
Сообщение DM_LISTGETCURPOS посылается Менеджеру диалогов для получения текущей позиции курсора в списке DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру FarListPos, в которую будет записана дополнительная информация о позиции в списке, или NULL, если дополнительная информация не требуется.

Return

Текущая позиция курсора в списке.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

// получить текущую позицию

CurPos=Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,ID,0);
Смотрите также:
DialogEx, DM_LISTSETCURPOS


DM_LISTGETDATA

Сообщения | Dialog API
Сообщение DM_LISTGETDATA посылается Менеджеру диалогов для получения данных, ассоциированных с элементом списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Индекс элемента списка.

Return

Данные, которые плагин ассоциировал с элементом списка с помощью сообщения DM_LISTSETDATA или NULL, если нет данных, ассоциированных с указанным пунктом списка. Более подробно о логике хранения данных см. замечание для структуры FarListItemData.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:
DialogEx, DM_LISTSETDATA


DM_LISTGETDATASIZE

Сообщения | Dialog API
Сообщение DM_LISTGETDATASIZE посылается Менеджеру диалогов для получения размера данных, ассоциированных с элементом списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Индекс элемента списка.

Return

Размер данных, которые плагин ассоциировал с элементом списка с помощью сообщения DM_LISTSETDATA.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:
DialogEx, DM_LISTSETDATA DM_LISTGETDATA


DM_LISTGETITEM

Сообщения | Dialog API
Сообщение DM_LISTGETITEM посылается Менеджеру диалогов для получения одного элемента из списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру типа FarListGetItem, в которую будет помещен результат.

Return

TRUE - данные получены.
FALSE - ошибка при получении данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Перед получением элемента списка необходимо предварительно заполнить структуру FarListGetItem, указав в качестве FarListGetItem.ItemIndex индекс нужного элемента.
struct FarListGetItem List;
List.ItemIndex=Index;
Info.SendDlgMessage(hDlg,DM_LISTGETITEM,ID,(LONG_PTR)&List);
Смотрите также:
DialogEx, FarListGetItem


DM_LISTGETTITLES

Сообщения | Dialog API
Сообщение DM_LISTGETTITLES посылается Менеджеру диалогов для получения заголовков (верхнего и нижнего) у элемента DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру типа FarListTitles, в которую будут помещены заголовки.

Return

TRUE - заголовки получены
FALSE -элемент не является списком

Элементы

Элемент | Описание
DI_LISTBOX | список

Замечания

Для получения заголовков необходимо предварительно заполнить структуру FarListTitles:
char Title[100];
char Bottom[100];
FarListTitles ListTitle;
ListTitle.Title=Title;
ListTitle.TitleLen=sizeof(Title);
ListTitle.Bottom=Bottom;
ListTitle.BottomLen=sizeof(Bottom);
Info.SendDlgMessage(hDlg,DM_LISTGETTITLES,ID,(LONG_PTR)&ListTitle);
Смотрите также:
DialogEx, FarListTitles, DM_LISTSETTITLES


DM_LISTINFO

Сообщения | Dialog API
Сообщение DM_LISTINFO позволяет получить информацию о списке DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру FarListInfo.

Return

TRUE - структура FarListInfo заполнена.
FALSE - ошибка (в качестве Param2 передали значение NULL).

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

// Получить информацию о списке
struct FarListInfo ListInfo;
Info.SendDlgMessage(hDlg,DM_LISTINFO,ID,(LONG_PTR)&ListInfo);
Смотрите также:


DM_LISTINSERT

Сообщения | Dialog API
Сообщение DM_LISTINSERT посылается Менеджеру диалогов для вставки элемента в список DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на добавляемый пункт списка (структуру типа FarListInsert).

Return

Новое количество пунктов в списке.
-1 - ошибка при вставке данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

Смотрите также:
DialogEx


DM_LISTSET

Сообщения | Dialog API
Сообщение DM_LISTSET посылается Менеджеру диалогов для добавления элементов в список DI_COMBOBOX или DI_LISTBOX с удалением уже существующих строк.

Param1

ID требуемого элемента диалога.

Param2

Указатель на добавляемые пункты списка (структуру типа FarList).

Return

TRUE - данные добавлены в список.
FALSE - ошибка при добавлении данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

FarList List;
FarListItem *ListItems;
...

ListItems=new FarListItem[MenuItemsNumber];
List.ItemsNumber=MenuItemsNumber;
List.Items=ListItems;

...
Info.SendDlgMessage(hDlg,DM_LISTSET,0,(LONG_PTR)&List);
Смотрите также:
DialogEx


DM_LISTSETCURPOS

Сообщения | Dialog API
Сообщение DM_LISTSETCURPOS посылается Менеджеру диалогов для позиционирования курсора в списке DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Param2 содержит указатель на FarListPos.

Return

Скорректированная позиция курсора в списке с учетом разделительных линий и недоступных пунктов.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

// Установить текущую позицию

RealPos=Info.SendDlgMessage(hDlg,DM_LISTSETCURPOS,ID,(LONG_PTR)&NewPos);
Смотрите также:
DialogEx, DM_LISTGETCURPOS


DM_LISTSETDATA

Сообщения | Dialog API
Сообщение DM_LISTSETDATA посылается Менеджеру диалогов для ассоциации пользовательских данных с элементом списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру типа FarListItemData, описывающую добавляемые данные.

Return

Размер добавленных данных или 0, если данные некорректны или не удалось выделить достаточно памяти для размещения данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Смотрите также:
DialogEx, DM_LISTGETDATA


DM_LISTSETMOUSEREACTION

Сообщения | Dialog API
Сообщение DM_LISTSETMOUSEREACTION позволяет управлять реакцией на движение мыши в списке DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Может быть одним из следующих значений (перечисление FARLISTMOUSEREACTIONTYPE):
Значение | Описание
LMRT_ONLYFOCUS | Список будет реагировать на движение мыши (перемещать курсор в списке) только если элемент в фокусе
LMRT_ALWAYS | Список будет всегда реагировать на движение мыши (перемещать курсор в списке). Пример такого поведения - список найденных файлов в результатах поиска (Alt-F7)
LMRT_NEVER | Список не будет реагировать на движение мыши

Return

Предыдущее значение.

Элементы

Элемент | Описание
DI_LISTBOX | список

Замечания

  1. По умолчанию список DI_LISTBOX всегда реагирует на движение курсора мыши.
  2. Far Manager 1.70 beta 5 и ниже: Param2 отличный от LMRT_ONLYFOCUS или LMRT_ALWAYS аналогичен значению LMRT_ALWAYS.

Пример

Смотрите также:
DialogEx


DM_LISTSETTITLES

Сообщения | Dialog API
Сообщение DM_LISTSETTITLES посылается Менеджеру диалогов для установки заголовков (верхнего и нижнего) у элемента DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру типа FarListTitles, содержащую заголовки.

Return

TRUE - заголовки установлены
FALSE -элемент не является списком

Элементы

Элемент | Описание
DI_LISTBOX | список

Замечания

Для установки заголовков необходимо предварительно заполнить структуру FarListTitles:
FarListTitles ListTitle;
ListTitle.Title="Some title";
ListTitle.Bottom=NULL; // сбросить нижний заголовок
Info.SendDlgMessage(hDlg,DM_LISTSETTITLES,ID,(LONG_PTR)&ListTitle);
Смотрите также:
DialogEx, FarListTitles, DM_LISTGETTITLES


DM_LISTSORT

Сообщения | Dialog API
Сообщение DM_LISTSORT посылается Менеджеру диалогов для сортировки элементов списка DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Направление сортировки: 0 - по возрастанию, 1 - по убыванию.

Return

TRUE - список отсортирован.
FALSE - ошибка при сортировке списка.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Пример

// Сортировать список по убыванию (от 'Z' до 'A')
Info.SendDlgMessage(hDlg,DM_LISTSORT,ID,1);
Смотрите также:
DialogEx


DM_LISTUPDATE

Сообщения | Dialog API
Сообщение DM_LISTUPDATE посылается Менеджеру диалогов для обновления элемента в списках DI_COMBOBOX или DI_LISTBOX.

Param1

ID требуемого элемента диалога.

Param2

Указатель на обновляемый пункт списка (структуру типа FarListUpdate).

Return

TRUE - пункт в списке успешно обновлен.
FALSE - ошибка при обновлении данных.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список

Замечания

Для обновления строки текущего элемента списка DI_LISTBOX можно также использовать сообщение DM_SETTEXTPTR (или DM_SETTEXT).

Пример

Смотрите также:

DialogEx


DM_MOVEDIALOG

Сообщения | Dialog API
Сообщение DM_MOVEDIALOG посылается менеджеру диалогов для перемещения диалога.

Param1

TRUE - Param2 содержит абсолютные координаты.
FALSE - Param2 содержит относительные координаты.

Param2

Указатель на структуру COORD, в которой указаны новые координаты левого верхнего угла диалогового окна.

Return

Структура COORD, содержащая реальные координаты левого верхнего угла диалогового окна.

Замечания

Для центрирования диалога на экране заполните структуру COORD значениями -1 и установите Param1 = TRUE.

Пример

// центрировать диалог
COORD c={-1,-1};
Info.SendDlgMessage(hDlg,DM_MOVEDIALOG,TRUE,(LONG_PTR)&c);

// переместить диалог в левый верхний угол экрана в координаты 1,1.
COORD c={1,1};
Info.SendDlgMessage(hDlg,DM_MOVEDIALOG,TRUE,(LONG_PTR)&c);

// переместить диалог на 2 позиции вправо.
COORD c={2,0};
Info.SendDlgMessage(hDlg,DM_MOVEDIALOG,FALSE,(LONG_PTR)&c);
Смотрите также:


DM_REDRAW

Сообщения | Dialog API
Плагин посылает сообщение DM_REDRAW Менеджеру диалогов для перерисовки всего диалогового окна.

Param1

0

Param2

0

Return

0

Замечания

В версиях FAR вплоть до 1.70 beta 3 сообщение DM_REDRAW именовалось как DM_SETREDRAW.
Смотрите также:
DialogEx


DM_RESIZEDIALOG

Сообщения | Dialog API
Сообщение DM_RESIZEDIALOG посылается менеджеру диалогов для изменения размеров диалога.

Param1

0

Param2

Указатель на структуру COORD, в которой указаны новые размеры диалогового окна.

Return

Структура COORD, содержащая новые размеры диалогового окна.

Замечания

Пример

Смотрите также:


DM_SET3STATE

Сообщения | Dialog API
Сообщение DM_SET3STATE посылается Менеджеру диалогов для модификации стиля элемента DI_CHECKBOX.

Param1

ID требуемого элемента

Param2

  • TRUE - контрольный переключатель может иметь 3 состояния.
  • FALSE - контрольный переключатель может иметь 2 состояния.

Return

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

Элементы

Элемент | Описание
DI_CHECKBOX | контрольный переключатель (Check Box).

Замечания

Пример

Смотрите также:
DialogEx | DM_GETCHECK | DM_SETCHECK.


DM_SETCHECK

Сообщения | Dialog API
Сообщение DM_SETCHECK посылается Менеджеру диалогов для изменения состояния элементов DI_CHECKBOX и DI_RADIOBUTTON.

Param1

ID требуемого элемента

Param2

Param2 имеет эффект только для элемента DI_CHECKBOX и может принимать одно из следующих значений (перечисление FARCHECKEDSTATE):
Флаг | Описание
BSTATE_UNCHECKED | Выключить - [ ] или ( )
BSTATE_CHECKED | Включить - [x] или (*)
BSTATE_3STATE | Включить неопределенное состояние - [?] (имеет эффект только для элемента с выставленным флагом DIF_3STATE).
BSTATE_TOGGLE | Переключить состояние элемента. (для элемента с выставленным флагом DIF_3STATE состояние будет меняться по кругу: "включено", "выключено", "неопределено").

Return

Предыдущее состояние элемента. Для DI_RADIOBUTTON - ID предыдущего элемента в группе кнопок с зависимой фиксацией (см. описание DIF_GROUP).

Элементы

Элемент | Описание
DI_CHECKBOX | Контрольный переключатель (Check Box).
DI_RADIOBUTTON | Селекторная кнопка (Radio Button).

Замечания

Пример

Смотрите также:
DialogEx | DM_GETCHECK | DM_SET3STATE.


DM_SETCOMBOBOXEVENT

Сообщения | Dialog API
Сообщение DM_SETCOMBOBOXEVENT позволяет управлять механизмом посылки сообщений DN_KEY и DN_MOUSEEVENT в диалоговую процедуру при навигации в открытом элементе DI_COMBOBOX.

Param1

ID требуемого элемента DI_COMBOBOX.

Param2

Param2 комбинация следующих значений (перечисление FARCOMBOBOXEVENTTYPE):
Флаг | Описание
CBET_KEY | Включить приход событий DN_KEY
CBET_MOUSE | Включить приход событий DN_MOUSEEVENT

Return

Предыдущее состояние.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список

Замечания

По умолчанию при открытом DI_COMBOBOX события DN_KEY и DN_MOUSEEVENT в диалоговую процедуру не приходят.

Пример

Смотрите также:
DM_GETCOMBOBOXEVENT


DM_SETCURSORPOS

Сообщения | Dialog API
Сообщение DM_SETCURSORPOS посылается обработчику диалога для позиционирования курсора в строках редактирования диалога и элементах DI_USERCONTROL.

Param1

ID элемента

Param2

Указатель на структуру COORD, содержащей информацию о положении курсора (COORD.Y игнорируется для строкового редактора).

Return

FALSE - указанный ID элемента не является строковым редактором или элементом DI_USERCONTROL.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

Чтобы погасить курсор в элементе DI_USERCONTROL, необходимо заполнить поля структуры COORD значениями -1.

Пример

Смотрите также:
DialogEx


DM_SETCURSORSIZE

Сообщения | Dialog API
Сообщение DM_SETCURSORSIZE посылается обработчику диалога для установки размера курсора и признака его видимости в строках редактирования диалога и в элементе DI_USERCONTROL.

Param1

ID элемента

Param2

Старшее слово - размер курсора (от 0 до 100, в терминах структуры CONSOLE_CURSOR_INFO), младшее слово - признак видимости курсора (1 - курсор видим, 0 - курсор невидим).

Return

Предыдущие значения:
Старшее слово - размер курсора (от 0 до 100, в терминах структуры CONSOLE_CURSOR_INFO), младшее слово - признак видимости курсора (1 - курсор видим, 0 - курсор невидим).

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список (без флага DIF_DROPDOWNLIST)
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля
DI_USERCONTROL | элемент управления, определяемый программистом

Замечания

  1. Для того, чтобы в элементе DI_USERCONTROL курсор стал видим, необходимо также переместить курсор в нужную позицию:
    Coord.X=X;
Coord.Y=Y;
Info.SendDlgMessage(hDlg,DM_SETCURSORPOS,3,(LONG_PTR)&Coord);
    Это связано с тем, что по умолчанию позиция курсора в DI_USERCONTROL равна {-1,-1}.
  2. Для показа полностью заполненного курсора в Windows 9x/Me укажите в старшем слове параметра Param2 значение 99.

Пример

// Установить курсор для элемента 3 полностью заполненной ячейкой.
Info.SendDlgMessage(hDlg,DM_SETCURSORSIZE,3,(LONG_PTR)MAKELONG(1,99));
Смотрите также:


DM_SETDLGDATA

Сообщения | Dialog API
Сообщение DM_SETDLGDATA устанавливает 32-битное значение связанное с диалогом. Каждый экземпляр диалога имеет соответствующее 32-битное значение, предназначенное для использования плагином в его собственных целях.

Param1

0

Param2

Новое 32-битное значение.

Return

Предыдущее значение.

Замечания

Первоначально здесь находится то, что передано в параметре Param функции DialogEx.

Пример

Смотрите также:


DM_SETDLGITEM

Сообщения | Dialog API
Сообщение DM_SETDLGITEM посылается Менеджеру диалогов для изменения информации о заданном элементе.

Param1

ID элемента диалога

Param2

Указатель на структуру FarDialogItem

Return

TRUE - данные обработаны. FALSE - если такого ID элемента не существует или вы поменяли тип элемента.

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

Вы не можете изменить тип элемента.
Смотрите также:
DialogEx


DM_SETDROPDOWNOPENED

Сообщения | Dialog API
Сообщение DM_SETDROPDOWNOPENED используется для программного раскрытия или закрытия комбобокса или истории.

Param1

ID элемента, чей список (DI_COMBOBOX) или историю (DI_EDIT или DI_FIXEDIT с флагом DIF_HISTORY) мы хотим раскрыть.

Param2

TRUE - раскрыть список у элемента ID.
FALSE - закрыть открытый комбобокс или историю. В этом случае параметр Param1 игнорируется.

Return

Если Param2=FALSE, всегда возвращается TRUE.
Если Param2=TRUE, возвращается TRUE в случае удачного открытия комбобокса или истории, FALSE - возвращается, если был указан ID не поддерживаемого типа.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

В диалоге одновременно может быть открыт только один комбо-бокс или список истории. Поэтому посылка сообщения с Param2=TRUE закрывает уже открытый комбо-бокс, а при посылке сообщения с Param2=FALSE указывать ID элемента не требуется.

Пример

Смотрите также:


DM_SETEDITPOSITION

Сообщения | DM_SETEDITPOSITION| Dialog API
Сообщение DM_SETEDITPOSITION посылается обработчику диалога для установки позиции и состояния курсора в строках редактирования диалога.

Param1

ID элемента

Param2

Указатель на структуру EditorSetPosition.

Return

FALSE - указанный ID элемента не является строковым редактором.
TRUE - позиция курсора установлена.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Пример

Пример функции поддержки выделения мышью в строках ввода в плагине "Visual renaming files"
static void MouseSelect(HANDLE hDlg, DWORD idStr, DWORD dwMousePosX)
{
  SMALL_RECT dlgRect, itemRect;
  Info.SendDlgMessage(hDlg, DM_GETDLGRECT, 0, (LONG_PTR)&dlgRect);
  Info.SendDlgMessage(hDlg, DM_GETITEMPOSITION, idStr, (LONG_PTR)&itemRect);

  EditorSetPosition esp;
  Info.SendDlgMessage(hDlg, DM_GETEDITPOSITION, idStr, (LONG_PTR)&esp);

  int length=Info.SendDlgMessage(hDlg, DM_GETTEXTLENGTH, idStr, 0);
  int CurPos=dwMousePosX - ( dlgRect.Left + itemRect.Left );

  if ( dwMousePosX <= ( dlgRect.Left + itemRect.Left ) && esp.LeftPos > 0 )
    esp.LeftPos-=1;
  else if ( dwMousePosX >= ( dlgRect.Left + itemRect.Right ) && CurPos+esp.LeftPos < length )
    esp.LeftPos+=1;

  if (CurPos+esp.LeftPos < 0)
    CurPos=0;
  else if (CurPos+esp.LeftPos > length)
    CurPos=length;
  else
    CurPos+=esp.LeftPos;

  esp.CurPos=esp.CurTabPos=CurPos;

  if (bStartSelect)
  {
    StartPosX=CurPos;
    bStartSelect=false;
  }

  EditorSelect es;
  es.BlockType=BTYPE_COLUMN;
  es.BlockStartLine=es.BlockHeight=0;

  if (CurPos > StartPosX)
  {
    es.BlockStartPos=StartPosX;
    es.BlockWidth=CurPos-StartPosX;
  }
  else
  {
    es.BlockStartPos=CurPos;
    es.BlockWidth=StartPosX-CurPos;
  }

  Info.SendDlgMessage(hDlg, DM_SETSELECTION, idStr, (LONG_PTR)&es);
  Info.SendDlgMessage(hDlg, DM_SETEDITPOSITION, idStr, (LONG_PTR)&esp);
}
Смотрите также:


DM_SETFOCUS

Сообщения | Dialog API
Сообщение DM_SETFOCUS устанавливает клавиатурный фокус на заданный элемент диалога.

Param1

ID элемента, который должен получить фокус ввода.

Param2

0

Return

FALSE - это элемент не может иметь фокус ввода
TRUE - фокус ввода успешно установлен

Элементы

Элемент | Описание
Все | Все элементы, которые могут иметь клавиатурный фокус ввода.

Замечания

Сообщение DM_SETFOCUS порождает цепочку событий: DN_KILLFOCUS для элемента, который теряет фокус ввода и DN_GOTFOCUS - для элемента, который получит фокус ввода. События DN_KILLFOCUS и DN_GOTFOCUS не генерятся в случае, если Param1 совпадает с элементом, уже имеющим фокус ввода.
Смотрите также:
DialogEx


DM_SETHISTORY

Сообщения | Dialog API
Сообщение DM_SETHISTORY позволяет управлять наличием истории в строках ввода.

Param1

ID элемента диалога.

Param2

Указатель на строку, содержащую название истории ввода или NULL, если необходимо отключить историю в строке ввода.

Return

FALSE - указанный элемент диалога Param1 не поддерживает работу с историей.
TRUE - история успешно назначена элементу диалога Param1.

Элементы

Элемент | Описание
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера

Замечания

Если строка ввода пуста и у элемента DI_EDIT выставлен флаг DIF_USELASTHISTORY, то FAR сам подставит первое значение из истории в строку ввода.

Пример

Применение данного сообщения можно увидеть в исходных текстах плагина MultiArc.

Следующий пример выставляет историю и очищает строку ввода:

...
  else if(Msg == MAM_ARCSWITCHES)
  {
    static char SwHistoryName[NM];
    FSF.sprintf(SwHistoryName,"ArcSwitches\\%s",pdd->ArcFormat);
    Info.SendDlgMessage(hDlg,DM_SETHISTORY,4,(LONG_PTR)SwHistoryName);
    Info.SendDlgMessage(hDlg,DM_SETTEXTPTR,4,(LONG_PTR)"");
  }
...

Для того, чтобы FAR сам подставил первую строку из истории ключей, необходимо приведенный выше код переписать так:

...
  else if(Msg == MAM_ARCSWITCHES)
  {
    static char SwHistoryName[NM];
    FSF.sprintf(SwHistoryName,"ArcSwitches\\%s",pdd->ArcFormat);
    Info.SendDlgMessage(hDlg,DM_SETTEXTPTR,4,(LONG_PTR)"");
    Info.SendDlgMessage(hDlg,DM_SETHISTORY,4,(LONG_PTR)SwHistoryName);
  }
...

Т.е. сначала строка ввода очищается, потом происходит назначение истории для элемента.

Смотрите также:
DialogEx, DM_ADDHISTORY, DIF_HISTORY


DM_SETITEMDATA

Сообщения | Dialog API
Сообщение DM_SETITEMDATA устанавливает 32-битное значение, связанное с элементом диалога. Каждый элемент диалога имеет соответствующее 32-битное значение, предназначенное для использования плагином в его собственных целях.

Param1

ID элемента управления.

Param2

Новое 32-битное значение.

Return

Предыдущее значение.

Замечания

Пример

Смотрите также:
DialogEx
DM_GETITEMDATA, DM_GETDLGDATA, DM_SETDLGDATA


DM_SETITEMPOSITION

Сообщения | Dialog API
Сообщение DM_SETITEMPOSITION посылается Менеджеру диалогов для изменения позиции элемента.

Param1

ID элемента диалога

Param2

Указатель на структуру SMALL_RECT с новыми координатами.

Return

TRUE - позиция элемента изменена. FALSE - если такого ID элемента не существует.

Элементы

Элемент | Описание
Все | Все элементы диалога
Смотрите также:


DM_SETMAXTEXTLENGTH

Сообщения | Dialog API
Сообщение DM_SETMAXTEXTLENGTH посылается Менеджеру диалогов для установки максимального размера редактируемой строки.

Param1

ID элемента диалога.

Param2

Требуемый размер

Return

Предыдущее значение размера редактируемой строки или 0 в случае ошибки.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_PSWEDIT | поле ввода пароля

Замечания

  1. Для DI_COMBOBOX влияет только на строку редактирования (не распространяется на DIF_DROPDOWNLIST)
  2. В версиях FAR вплоть до 1.70 beta 3 сообщение DM_SETMAXTEXTLENGTH именовалось как DM_SETTEXTLENGTH.

Пример

Смотрите также:
DialogEx


DM_SETMOUSEEVENTNOTIFY

Сообщения | Dialog API
Сообщение DM_SETMOUSEEVENTNOTIFY позволяет управлять механизмом посылки первичного необработанного сообщения от мыши (DN_MOUSEEVENT) в диалоговую процедуру.

Param1

0 - выключить
1 - включить
-1 - получить состояние

Param2

0

Return

Предыдущее состояние.

Элементы

Элемент | Описание
Диалог | сообщение затрагивает только диалог

Замечания

Пример

Смотрите также:


DM_SETSELECTION

Сообщения | DM_GETSELECTION| Dialog API
Сообщение DM_SETSELECTION посылается обработчику диалога для выделения блока в строках редактирования диалога.

Param1

ID элемента

Param2

Указатель на структуру EditorSelect.

Return

FALSE - указанный ID элемента не является строковым редактором.
TRUE - текст выделен.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

Пример

Смотрите также:


DM_SETTEXT

Сообщения | Dialog API
Сообщение DM_SETTEXT посылается Менеджеру диалогов для установки содержимого строк ввода или заголовков элементов диалога в новое значение.

Param1

ID требуемого элемента диалога.

Param2

Указатель на структуру FarDialogItemData. Значение этого параметра равное NULL игнорируется.

Return

Размер установленных данных без завершающего символа конца строки '\0'.

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

  1. Для DI_COMBOBOX влияет только на строку редактирования (не распространяется на DIF_DROPDOWNLIST)
  2. Сообщение DM_SETTEXT в версиях FAR вплоть до 1.70 beta 3 возвращало размер данных с учетом символа конца строки.

Пример

Смотрите также:


DM_SETTEXTPTR

Сообщения | Dialog API
Сообщение DM_SETTEXTPTR посылается Менеджеру диалогов для установки содержимого строк ввода или заголовков элементов диалога в новое значение. В отличии от сообщения DM_SETTEXT, это сообщение работает с указателем на строку.

Param1

ID требуемого элемента диалога.

Param2

Адрес строки, содержащей текст. Значение этого параметра равное NULL игнорируется.

Return

Размер установленных данных без завершающего символа конца строки '\0'.

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

  1. Для DI_COMBOBOX влияет только на строку редактирования (не распространяется на DIF_DROPDOWNLIST)
  2. Сообщение DM_SETTEXTPTR в версиях FAR вплоть до 1.70 beta 3 возвращало размер данных с учетом символа конца строки.

Пример

Смотрите также:


DM_SHOWDIALOG

Сообщения | Dialog API
Сообщение DM_SHOWDIALOG посылается Менеджеру диалогов для того, чтобы показать или спрятать диалог на экране.

Param1

TRUE - показать диалог
FALSE - скрыть диалог

Param2

0

Return

0
Смотрите также:


DM_SHOWITEM

Сообщения | Dialog API
Сообщение DM_SHOWITEM посылается Менеджеру диалогов для того, чтобы показать или спрятать элемент диалога.

Param1

ID требуемого элемента диалога.

Param2

Одно из трех значений:
  • -1 - получить состояние элемента
  • 0 - погасить элемент
  • 1 - показать элемент

Return

Предыдущее состояние элемента диалога

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

  1. Элемент диалога принудительно перерисовывается, если он видим и Param2=1.
  2. Элемент диалога не перерисовывается для случая Param2=-1.

Пример

Смотрите также:


DM_USER

Сообщения | Dialog API
Сообщение DM_USER предназначено для пользовательских сообщений.

Param1

На усмотрение программиста.

Param2

На усмотрение программиста.

Return

На усмотрение программиста.

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

Пример

#define DMREV_RESULT	DM_USER+1

LONG_PTR WINAPI ReversiDialogProc(HANDLE hDlg, int Msg,int Param1,LONG_PTR Param2)
{
...
    Info.SendDlgMessage(hDlg,DMREV_RESULT,0,0);
...
    case DMREV_RESULT: // пользовательское определение
      ...
      return 0;
...
}
Смотрите также:
DialogEx


События Dialog API

главная | Dialog API | Сообщения

Событие | Описание
DN_CLOSE | сигнал о закрытии диалога
DN_BTNCLICK | изменилось состояние кнопок
DN_CTLCOLORDIALOG | запрос цвета на прорисовку подложки окна диалога
DN_CTLCOLORDLGITEM | запрос цвета для конкретного элемента диалога
DN_CTLCOLORDLGLIST | запрос цвета на отрисовку списка
DN_DRAGGED | информация о перемещениях диалога
DN_DRAWDIALOG | перед прорисовкой всего диалога
DN_DRAWDIALOGDONE | прорисовка диалога закончена
DN_DRAWDLGITEM | перед отрисовкой элемента диалога
DN_EDITCHANGE | изменение состояния элемента редактирования
DN_ENTERIDLE | холостое состояние
DN_GOTFOCUS | элемент диалога получил клавиатурный фокус ввода
DN_HELP | вывод темы помощи
DN_HOTKEY | пользователь нажал Alt-буква
DN_INITDIALOG | инициализация диалога
DN_KEY | пользователь нажал клавишу
DN_KILLFOCUS | перед потерей клавиатурного фокуса элементом диалога
DN_LISTCHANGE | изменение состояния элемента списка
DN_LISTHOTKEY | выбор элемента списка с помощью горячей клавиши
DN_MOUSECLICK | пользователь кликнул клавишей мыши на одном из элементов диалога
DN_MOUSEEVENT | возможность перехватить сообщение мыши до его обработки ядром
DN_RESIZECONSOLE | нотификационное сообщение "Изменились размеры консоли"
Смотрите также:
Сообщения Dialog API


DN_BTNCLICK

События | Dialog API
Сообщение DN_BTNCLICK приходит для элементов DI_BUTTON, DI_CHECKBOX, DI_RADIOBUTTON после того, как пользователь нажал клавиши пробел и Enter (для кнопок), '+', '-' и '*'.

Param1

ID элемента диалога

Param2

Состояние после нажатия:
DI_BUTTON = 0
DI_CHECKBOX =0 (снята пометка), 1 (установлена пометка) и 2 (третье состояние, если установлен флаг DIF_3STATE)
DI_RADIOBUTTON = 0 - для предыдущего элемента в группе, 1 - для активного элемента в группе.

Return

Для DI_BUTTON: TRUE - сообщение обработано, дальше не продолжать обработку этого сообщения ядром.
FALSE - продолжить обработку ядром.

Для остальных элементов: TRUE - разрешить изменение (и соответственно отрисовку того, что пользователь ввёл)
FALSE - запретить изменение.

Элементы

Элемент | Описание
DI_BUTTON | Кнопка (Push Button).
DI_CHECKBOX | Контрольный переключатель (Check Box).
DI_RADIOBUTTON | Селекторная кнопка (Radio Button).

Замечания

Пример

Смотрите также:
DialogEx


DN_CLOSE

События | Dialog API
Событие DN_CLOSE приходит в обработчик диалога как сигнал, сообщающий, что диалог будет закрыт - пользователь пытается завершить работу с диалогом.

Param1

  • ID элемента, который имел фокус ввода в момент нажатия Ctrl-Enter или ID элемента, у которого поле DefaultButton = 1.
  • -2 - нажали KEY_BREAK (комбинация клавиш Ctrl-Pause или Ctrl-ScrollLock)
  • -1 - KEY_ESC или KEY_F10

Param2

0

Return

TRUE - да, согласен с выходом из диалога
FALSE - продолжить работу диалога.

Замечания

  1. Событие DN_CLOSE приходит сразу после посылки сообщения DM_CLOSE обработчиком диалога.

Пример

Смотрите также:
DialogEx, DM_CLOSE


DN_CTLCOLORDIALOG

События | Dialog API
Сообщение DN_CTLCOLORDIALOG посылается в функцию обработки диалога перед прорисовкой подложки окна диалога.

Param1

0

Param2

Атрибуты (цвет_фона+цвет_текста), с использованием которых обработчик диалога хочет отрисовать подложку диалога. По умолчанию это значение равно COL_DIALOGTEXT - для обычных диалогов и COL_WARNDIALOGTEXT для диалогов с флагом FDLG_WARNING.

Return

Атрибуты (цвет_фона+цвет_текста), с использованием которых обработчик диалога должен отрисовать подложку диалога

Замечания

Сообщение приходит сразу после DN_DRAWDIALOG.

Пример

Смотрите также:
DialogEx


DN_CTLCOLORDLGITEM

События | Dialog API
Событие DN_CTLCOLORDLGITEM посылается процедуре обработки диалога перед отрисовкой конкретного элемента диалога.

Param1

ID элемента, который будет отрисован.

Param2

Атрибуты (цвет_фона+цвет_текста), с использованием которых обработчик диалога хочет отрисовать элемент:
DI_SINGLEBOX
DI_DOUBLEBOX
LO(LO=Title,HI=HiText), HI(LO=Box,0)
DI_TEXT
LO(LO=Title,HI=HiText), HI(LO=Box,0)
Цвет для рамки (Box) определен только для флагов DIF_SEPARATOR и DIF_SEPARATOR2.
DI_VTEXT
LO(LO=Title,HI=0), HI(0,0)
DI_EDIT
DI_FIXEDIT
DI_PSWEDIT
DI_COMBOBOX
LO(LO=EditLine,HI=SelectText), HI(LO=UnchangedColor, HI=History&ComboBox указатель)
DI_CHECKBOX
DI_RADIOBUTTON
LO(LO=Title,HI=HiText), HI(0,0)
DI_BUTTON
LO(LO=Title,HI=HiText), HI(0,0)
DI_LISTBOX
Для элемента DI_LISTBOX приходит только событие DN_CTLCOLORDLGLIST.

Return

Атрибуты (цвет_фона+цвет_текста), с использованием которых будет отрисован элемент.

Элементы

Элемент | Описание
Все | Все элементы диалога, кроме DI_LISTBOX и DI_USERCONTROL

Замечания

В ответ на это сообщение процедура обработки диалога может установить свои атрибуты (цвет текста и фона) для заданного элемента.

Пример

Пример того, как диалог назначения макроса на клавишу в FAR Manager меняет цвет поля редактирования:
/* 02 */ DI_EDIT,5,3,28,3,1,0,0,1,"",

case DN_CTLCOLORDLGITEM:
  // Unchanged у нас сидит в младшем байте старшего слова
  Param2&=0xFF00FFFFU;
  Param2|=(Param2&0xFF)<<16;
  return Param2;
Смотрите также:
DialogEx


DN_CTLCOLORDLGLIST

События | Dialog API
Сообщение DN_CTLCOLORDLGLIST посылается процедуре обработки диалога перед отрисовкой списка (DI_COMBOBOX, DI_LISTBOX, DIF_HISTORY).

Param1

ID элемента

Param2

Указатель на структуру FarListColors, описывающую цветовую схему списка.

Return

TRUE - если атрибуты изменены
FALSE - оставить все как есть.

Элементы

Элемент | Описание
DI_LISTBOX | список
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода (с установленным флагом DIF_HISTORY)
DI_FIXEDIT | поле ввода фиксированного размера (с установленным флагом DIF_HISTORY)

Замечания

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

Пример

Смотрите также:


DN_DRAGGED

События | Dialog API
Событие DN_DRAGGED приходит в обработчик диалога как сигнал о начале и конце перемещения диалога.

Начало перемещения диалога

Param1

0

Param2

0

Return

TRUE - разрешить перемещение
FALSE - запретить перемещение

Конец перемещения диалога

Param1

1

Param2

0 - успешное перемещение
1 - отменили перемещение диалога, нажав Esc или правую клавишу мыши.

Return

Не имеет значения.

Замечания

  1. Событие DN_DRAGGED приходит до прорисовки диалога.

Пример

Смотрите также:
DialogEx


DN_DRAWDIALOG

События | Dialog API
Сообщение DN_DRAWDIALOG посылается перед прорисовкой всего диалога.

Param1

0

Param2

0

Return

Если обработчик диалога вернул FALSE, то диалог не будет отрисован на экране.

Замечания

Пример

Смотрите также:
DialogEx, DN_DRAWDIALOGDONE


DN_DRAWDIALOGDONE

События | Dialog API
Сообщение DN_DRAWDIALOGDONE посылается после прорисовкой всего диалога.

Param1

0

Param2

0

Return

Не используется.

Замечания

Хотя это сообщение и посылается последним, но на момент его посылки виртуальный буфер экрана FAR еще не "сброшен". Т.е. если плагин хочет что-то нарисовать поверх диалога, то его изменения могут быть стерты с экрана при возвращении из обработчика этого сообщения.

Чтобы этого не происходило нужно принудительно сбросить виртуальный буфер используя вызов функции Text(0,0,0,NULL), а затем "нарисовать" свое изображение, например:

  case  DN_DRAWDIALOGDONE:
    Info.Text(0,0,0,NULL);
    // здесь рисуем свое
    break;

Пример

Смотрите также:
DialogEx, DN_DRAWDIALOG


DN_DRAWDLGITEM

События | Dialog API
Сообщение DN_DRAWDLGITEM посылается обработчику диалога перед отрисовкой элемента диалога.

Param1

ID элемента диалога, который будет отрисован.

Param2

Указатель на структуру FarDialogItem, описывающую элемент для отрисовки.

Return

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

Элементы

Элемент | Описание
Все | Все элементы диалога

Замечания

Внешний вид DI_USERCONTROL, в отличие от прочих элементов диалога, можно предварительно подготавливать в виртуальном буфере. FAR Manager не копирует во внутренние переменные содержимое этого буфера, поэтому в ответ на событие DN_DRAWDLGITEM достаточно изменить состояние виртуального буфера:
case DN_DRAWDLGITEM:
  CHAR_INFO *VBuf=((struct FarDialogItem*)Param2)->Param.VBuf;
  for (I=0; I < 256; I++)
  {
    VBuf[I].Char.AsciiChar = DecodeTable[I];
    VBuf[I].Attributes = Color;
  }
  return TRUE;

Пример

Смотрите также:
DialogEx


DN_EDITCHANGE

События | Dialog API
Сообщение DN_EDITCHANGE оповещает обработчик об изменении состояния редактируемого элемента диалога - например, ввели символ.

Param1

ID элемента.

Param2

Указатель на структуру FarDialogItem, описывающую измененный элемент.

Return

В Dialog API версии 1.0 результат игнорируется, но для обеспечения работоспособности плагина с будущими версиями Dialog API рекомендуется возвращать:
  • TRUE - "подтверждаю изменения"
  • FALSE - "изменения в окне редактирования не принимаются"

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_EDIT | строка ввода
DI_FIXEDIT | поле ввода фиксированного размера
DI_PSWEDIT | поле ввода пароля

Замечания

  1. В Dialog API версии 1.0 отсутствует возможность принудительно изменять состояние элемента, изменяя элементы структуры FarDialogItem.
  2. Событие DN_EDITCHANGE не приходит в ответ на посылку обработчиком сообщений DM_SETTEXTPTR и DM_SETTEXT.

Пример

...
// отобразить копию введенных данных только для чисел
if (Msg == DN_EDITCHANGE && Param1 == 2)
{
  FarDialogItem *Item=(FarDialogItem *)Param2;
  int Len=strlen(Item->Data);
  for(int I=0; I < Len; ++I)
    if(!isdigit(Item->Data[I]))
      break;
  if(I == Len)
    return FALSE;
  Info.SendDlgMessage(hDlg, DM_SETTEXTPTR, 3, (LONG_PTR)Item->Data);
  return TRUE;
}
...
Смотрите также:
DialogEx


DN_ENTERIDLE

События | Dialog API
Сообщение DN_ENTERIDLE посылается в процедуру обработки диалога, который входит в холостое состояние.

Внимание! Внимание!

  • Это событие ни как не связано с таймером. Диалоговое окно входит в холостое состояние, когда нет никаких событий в системе (клавиши не нажимали, мышью не двигали).

Param1

0

Param2

0

Return

0

Пример

// во время простоя дадим компьютеру подумать над следующим ходом.
case DN_ENTERIDLE:
  Timer(hDlg);
  return 0;
Смотрите также:
DialogEx


DN_GOTFOCUS

События | Dialog API
Сообщение DN_GOTFOCUS посылается процедуре обработки диалога после того, как элемент диалога получил клавиатурный фокус ввода.

Param1

ID элемента получившего фокус ввода.

Param2

0

Return

0

Элементы

Элемент | Описание
Все | Все элементы, которые могут иметь клавиатурный фокус ввода.

Замечания

Событие так же приходит для фокусного элемента сразу после DN_INITDIALOG.

Пример

Смотрите также:
DialogEx


DN_HELP

События | Dialog API
Сообщение DN_HELP передается в обработчик диалога перед выводом темы помощи.

Param1

ID элемента диалога, имеющий фокус ввода (текущий элемент)

Param2

Адрес строки, содержащей название темы, которая будет показана.

Return

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

Элементы

Элемент | Описание
Все | Все элементы, которые могут иметь клавиатурный фокус ввода.

Замечания

Это сообщение позволяет управлять показом темы помощи на уровне отдельного элемента диалога.

Пример

// в зависимости от состояния игры показать тот или иной раздел помощи
// в данном случае текущий элемент диалога нас не интересует
case DN_HELP:
{
  static char *HelpTopics[3]={"Contents","Rule","Recommendations"};
  int i=1;
  if(GAME[0].NumPl1==2 && GAME[0].NumPl2 == 2)
    i=0;
  else if(GAME[0].NumPl1+GAME[0].NumPl2 > 16)
    i=2;
  return (LONG_PTR)(&HelpTopics[i][0]);
}
Смотрите также:
DialogEx


DN_HOTKEY

События | Dialog API
Сообщение DN_HOTKEY посылается в обработчик диалога, когда пользователь нажал Alt-буква.

Param1

ID элемента диалога, который получит фокус ввода.

Param2

Внутренний код клавиши.

Return

TRUE - согласен
FALSE - отменить обработку клавиши.

Элементы

Элемент | Описание
DI_DOUBLEBOX | двойная рамка; если имеет горячую клавишу (флаг DIF_SHOWAMPERSAND не выставлен), то передает управление ближайшему элементу, который может иметь фокус ввода
DI_SINGLEBOX | одиночная рамка; если имеет горячую клавишу (флаг DIF_SHOWAMPERSAND не выставлен), то передает управление ближайшему элементу, который может иметь фокус ввода
DI_TEXT | текстовая строка; если имеет горячую клавишу (флаг DIF_SHOWAMPERSAND не выставлен), то передает управление ближайшему элементу, который может иметь фокус ввода
DI_VTEXT | вертикальная текстовая строка; если имеет горячую клавишу (флаг DIF_SHOWAMPERSAND не выставлен), то передает управление ближайшему элементу, который может иметь фокус ввода
DI_BUTTON | кнопка (Push Button); элемент без выставленного флага DIF_SHOWAMPERSAND сам реагирует на комбинацию Alt-буква
DI_CHECKBOX | контрольный переключатель (Check Box); элемент без выставленного флага DIF_SHOWAMPERSAND сам реагирует на комбинацию Alt-буква
DI_RADIOBUTTON | селекторная кнопка (Radio Button); элемент без выставленного флага DIF_SHOWAMPERSAND сам реагирует на комбинацию Alt-буква

Пример

Смотрите также:
DialogEx


DN_INITDIALOG

События | Dialog API
Сообщение DN_INITDIALOG посылается процедуре обработки диалога после того, как были проинициализированы все управляющие элементы диалога, но до того, как они стали видимы.

Param1

ID элемента, который получит фокус ввода по умолчанию.

Param2

Специфические данные, переданные функции DialogEx - параметр Param

Return

TRUE - если процедура обработки диалога изменила данные.
FALSE - изменений не было.

Замечания

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

Пример

case DN_INITDIALOG:
  struct FarDialogItem DialogItem;

  Info.SendDlgMessage(hDlg,DM_GETDLGITEM,75,(LONG_PTR)&DialogItem);
  if(DialogItem.ListItems->Items[0].Flags&LIF_SELECTED)
    Computer=Pl2;
  else
  ...
  return TRUE;
Смотрите также:
DialogEx


DN_KEY

События | Dialog API
Обработчик диалога получает событие DN_KEY, когда пользователь нажал клавишу.

Param1

ID элемента (обычно элемент, имеющий фокус ввода).

Param2

Внутренний код клавиши.

Return

TRUE - клавишу обработали сами.
FALSE - пусть обрабатывает клавишу стандартный внутренний обработчик диалога

Замечания

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

Пример

Пример обработки сообщения:
// Центрировать диалог, если пользователь нажал Ctrl-Apps
case DN_KEY:
  if(Param2 == KEY_CTRLAPPS)
  {
    COORD c={-1,-1};
    Info.SendDlgMessage(hDlg,DM_MOVEDIALOG,TRUE,(LONG_PTR)&c);
    return TRUE;
  }
Смотрите также:
DialogEx, DM_KEY


DN_KILLFOCUS

События | Dialog API
Сообщение DN_KILLFOCUS передается процедуре обработки диалога непосредственно перед потерей клавиатурного фокуса элементом диалога.

Param1

ID элемента, теряющего фокус ввода.

Param2

0

Return

-1 - "Согласен с потерей фокуса".
>=0 - номер желаемого элемента, которому хотим передать фокус.

Элементы

Элемент | Описание
Все | Все элементы, которые могут иметь клавиатурный фокус ввода.

Замечания

Пример

Смотрите также:
DialogEx


DN_LISTCHANGE

События | Dialog API
Сообщение DN_LISTCHANGE оповещает обработчик об изменении состояния элемента списка (DI_COMBOBOX, DI_LISTBOX, DIF_HISTORY).

Param1

ID элемента

Param2

Текущая позиция в списке.

Return

TRUE - разрешить изменение (и соответственно отрисовку того, что пользователь ввёл)
FALSE - запретить изменение.

Элементы

Элемент | Описание
DI_COMBOBOX | комбинированный список
DI_LISTBOX | список
DI_EDIT | строка ввода (с установленным флагом DIF_HISTORY)
DI_FIXEDIT | поле ввода фиксированного размера (с установленным флагом DIF_HISTORY)

Замечания

Пример

Смотрите также:
DialogEx


DN_LISTHOTKEY

События | Dialog API
Сообщение DN_LISTHOTKEY оповещает обработчик о том, что пользователь для смены пункта в списке (DI_LISTBOX) воспользовался горячими клавишами.

Param1

ID элемента DI_LISTBOX.

Param2

Позиция выбранного элемента в списке.

Return

FALSE - разрешить изменение,
TRUE - плагин сам отработал событие.

Элементы

Элемент | Описание
DI_LISTBOX | список
Смотрите также:
DialogEx


DN_MOUSECLICK

События | Dialog API
Событие DN_MOUSECLICK посылается обработчику после того, как пользователь кликнул клавишей мыши на одном из элементов диалога или вне диалога.

Param1

ID элемента диалога.
Param1 = -1 для случая, если пользователь кликнул клавишей мыши вне диалога.

Param2

Указатель на MOUSE_EVENT_RECORD.

Return

TRUE - обработчик диалога сам обработал событие, дальше ядру не продолжать
FALSE - продолжить обработку этого события ядром.

Элементы

Элемент | Описание
Все | Все элементы диалога, кроме скрытых и недоступных.

Замечания

  1. Для элемента DI_USERCONTROL координаты курсора (0,0) мыши начинаются с левого-верхнего угла этого элемента. Для остальных элементов - относительно левого верхнего угла экрана.
  2. Обработчик диалога может отловить событие DOUBLE_CLICK. Для этого необходимо проверить флаг MouseEvent.dwEventFlags==DOUBLE_CLICK
  3. Если пользователь кликнул клавишей мыши вне диалога, то:
    • левая клавиша рассматривается как нажатие клавиши <Esc>;
    • правая клавиша рассматривается как нажатие клавиши <Enter>;
    • прочие клавиши (для многокнопочной мыши) не имеют никакого эффекта.
    • если функция диалога не обрабатывает событие DN_MOUSECLICK с Param1=-1, то диалог будет закрыт

Пример

Смотрите также:
DialogEx


DN_MOUSEEVENT

События | Dialog API
Событие DN_MOUSEEVENT посылается обработчику диалога до обработки ядром событий мыши.

Param1

0

Param2

Указатель на MOUSE_EVENT_RECORD.

Return

TRUE - разрешить дальнейшую обработку ядром этого события
FALSE - событие обработано плагином.

Элементы

Элемент | Описание
Диалог | сообщение затрагивает только диалог

Замечания

  1. По умолчанию событие DN_MOUSEEVENT не приходит в диалоговую процедуру. Для включения/выключения посылки этого события воспользуйтесь сообщением DM_SETMOUSEEVENTNOTIFY.
  2. Не включайте без нужды данный механизм - события от мыши приходят очень часто.
  3. Плагин может модифицировать поля структуры MOUSE_EVENT_RECORD.
  4. По умолчанию для открытого DI_COMBOBOX событие DN_MOUSEEVENT в диалоговую процедуру не приходит. Воспользуйтесь сообщением DM_SETCOMBOBOXEVENT, чтобы включить режим посылки DN_MOUSEEVENT в диалоговую процедуру.

Пример

Смотрите также:


DN_RESIZECONSOLE

События | Dialog API
Сообщение DN_RESIZECONSOLE передается процедуре обработки диалога после изменения размера консоли (например, после того, как пользователь нажал Alt-F9).

Param1

0

Param2

Указатель на структуру COORD, в которой указаны текущие размеры консоли.

Return

TRUE.

Элементы

Элемент | Описание
Диалог | сообщение затрагивает только диалог

Замечания

Сообщение DN_RESIZECONSOLE полезно в том случае, когда плагин умеет подстраиваться под текущие размеры консоли. Пример работы данного сообщения можно наблюдать в диалоге поиска файлов (Alt-F7).

Пример

Изменение размеров диалога поиска (Alt-F7) при изменении размеров консоли.
case DN_RESIZECONSOLE:
{
  COORD coord=(*(COORD*)Param2);
  SMALL_RECT rect;
  int IncY=coord.Y-DlgHeight-4;

  ...

  Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0);

  Info.SendDlgMessage(hDlg,DM_GETDLGRECT,0,(LONG_PTR)&rect);
  coord.X=rect.Right-rect.Left+1;
  DlgHeight+=IncY;
  coord.Y=DlgHeight;

  if (IncY > 0)
    Info.SendDlgMessage(hDlg,DM_RESIZEDIALOG,0,(LONG_PTR)&coord);

  for (I=0; I < 2; I++)
  {
    Info.SendDlgMessage(hDlg,DM_GETITEMPOSITION,I,(LONG_PTR)&rect);
    rect.Bottom+=(short)IncY;
    Info.SendDlgMessage(hDlg,DM_SETITEMPOSITION,I,(LONG_PTR)&rect);
  }

  for (I=2; I < 10; I++)
  {
    Info.SendDlgMessage(hDlg,DM_GETITEMPOSITION,I,(LONG_PTR)&rect);
    if (I==2)
      rect.Left=-1;
    rect.Top+=(short)IncY;
    Info.SendDlgMessage(hDlg,DM_SETITEMPOSITION,I,(LONG_PTR)&rect);
  }

  if (IncY <= 0)
    Info.SendDlgMessage(hDlg,DM_RESIZEDIALOG,0,(LONG_PTR)&coord);

  Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,TRUE,0);

  ...

  return TRUE;
}
Смотрите также:
DialogEx


Фокус ввода

главная | Dialog API | Элементы диалога

Для распределения сообщений от клавиатуры используется концепция так называемого клавиатурного фокуса ввода. Фокус ввода - это атрибут, который присваивается элементу диалога. Если элемент имеет фокус ввода, то он получает все клавиатурные сообщения (в основном :-) из системной очереди FAR Manager.

Менеджер диалогов может передавать фокус ввода от одного элемента другому. Когда вы нажимаете клавиши Tab, Shift-Tab или Alt-Символ, фокус ввода передается следующему/предыдущему элементу диалога (или элементу диалога, имеющему соответствующую горячую клавишу).

Функция обработки диалога может проследить за получением и потерей фокуса ввода. Когда элемент получает фокус ввода, функции-обработчику передается сообщение DN_GOTFOCUS. Когда элемент теряет фокус ввода, функции-обработчику передается сообщение DN_KILLFOCUS. В ответ на сообщение DN_KILLFOCUS функция обработки диалога может запретить потерю фокуса ввода, вернув значение -1. Сообщение DN_GOTFOCUS носит чисто информативный характер, т.е. вы не можете отменить данное событие, как таковое.

Программный интерфейс Dialog API Far Manager содержит два сообщения, позволяющие узнать или изменить элемент, владеющий фокусом ввода. Эти сообщения имеют соответственно имена DM_GETFOCUS и DM_SETFOCUS.

Ниже перечислены элементы диалога, которые могут иметь клавиатурный фокус ввода (при условии, что для этих элементов не выставлены флаги DIF_NOFOCUS и/или DIF_DISABLE):

Элемент | Описание
DI_BUTTON | Кнопка (Push Button).
DI_CHECKBOX | Контрольный переключатель (Check Box).
DI_COMBOBOX | Комбинированный список.
DI_EDIT | Поле ввода.
DI_FIXEDIT | Поле ввода фиксированного размера.
DI_LISTBOX | Окно списка.
DI_PSWEDIT | Поле ввода пароля.
DI_RADIOBUTTON | Селекторная кнопка (Radio Button).
DI_USERCONTROL | Элемент управления, определяемый программистом.
Смотрите также:
DefDlgProc, DialogEx, SendDlgMessage


Panel API

главная

Экспортируемые функции

Функция | Описание
ClosePlugin | перед закрытием открытого плагина.
Compare | перекрывает алгоритм сортировки
DeleteFiles | удаление файлов
FreeFindData | освобождает память, запрошенную функцией GetFindData
FreeVirtualFindData | освобождает память, выделенную функцией GetVirtualFindData
GetFiles | получить файлы
GetFindData | получить файлы из текущего каталога
GetOpenPluginInfo | информация об открытом плагине
GetVirtualFindData | получить файлы
MakeDirectory | создать каталог
OpenFilePlugin | открыть файл
OpenPlugin | создает новую копию плагина в памяти
ProcessEvent | обработка событий
ProcessHostFile | выполнить архивную команду FAR'a
ProcessKey | обработка событий клавиатуры
PutFiles | поместить файлы на эмулируемую файловую систему
SetDirectory | установить текущий каталог на эмулируемой файловой системе.
SetFindList | Перемещает найденные в Диалоге поиска файлов файлы в эмулируемую файловую панель

Сервисные функции

Функция | Описание
Control | позволяет запрашивать различную информацию и выполнять управляющие действия.
FreeDirList | освобождает память, выделенную для списка файлов функциями GetDirList и GetPluginDirList
GetDirList | возвращает список файлов в указанной директории
GetPluginDirList | возвращает список файлов в указанной директории эмулируемой файловой системы

Структуры

Структура | Описание
InfoPanelLine | одна линия информационной панели
KeyBarTitles | переопределяет названия функциональных клавиш в полоске клавиш
PanelInfo | информация о панели Far'а
PanelMode | определяет режим просмотра панели
PanelRedrawInfo | используется при перерисовке панели
PluginPanelItem | информация об одном элементе в эмулируемой файловой системе

Константы

Константа | Описание
NM | размер буфера под имя файла
OPM_* | дополнительная информация о режиме функции и месте, откуда она была вызвана
SM_* | метод сортировки.
Смотрите также:


Сервисные функции

Сервисные функции - Панели

главная
Функция | Описание
Control | позволяет запрашивать различную информацию и выполнять управляющие действия.
FreeDirList | освобождает память, выделенную для списка файлов функциями GetDirList и GetPluginDirList
GetDirList | возвращает список файлов в указанной директории
GetPluginDirList | возвращает список файлов в указанной директории эмулируемой файловой системы
Смотрите также:
Экспортируемые функции, Структуры, Поддержка архивов, Дополнения, Win32 структуры и функции


Структуры

Структуры - Панель

главная | структуры
Структура | Описание
InfoPanelLine | одна линия информационной панели
KeyBarTitles | переопределяет названия функциональных клавиш в полоске клавиш
PanelInfo | информация о панели Far'а
PanelMode | определяет режим просмотра панели
PanelRedrawInfo | используется при перерисовке панели
PluginPanelItem | информация об одном элементе в эмулируемой файловой системе
Смотрите также:
Экспортируемые функции, Сервисные функции, Dialog API, Поддержка архивов, Дополнения, Delphi-структуры, Win32 структуры


Editor API

главная

Экспортируемые функции

Функция | Описание
ProcessEditorInput | обработка событий клавиатуры
ProcessEditorEvent | обработка событий редактора

Сервисные функции

Функция | Описание
Editor | обеспечивает доступ к внутреннему редактору FAR'a
EditorControl | обеспечивает доступ на низком уровне к API редактора FAR'a

Структуры

Структура | Описание
EditorBookMarks | информация о закладках текущего редактируемого файла
EditorColor | установить или получить информацию о цветовых областях строк
EditorConvertPos | преобразование между реальным и экранным положением курсора в редакторе
EditorConvertText | преобразование текста между OEM и внутренней кодировкой редактора Far-а
EditorGetString | запрос строки из редактора
EditorInfo | текущее состояние редактора Far`а
EditorSaveFile | сохранение редактируемого файла
EditorSelect | выделение или сброс выделения блока в редакторе
EditorSetParameter | установка параметров редактора
EditorSetPosition | установка позиции в редакторе Far'а
EditorSetString | установка или вставка строки в редакторе
Смотрите также:


Viewer API

главная

Экспортируемые функции

Функция | Описание
ProcessViewerEvent | обработка событий программы просмотра

Сервисные функции

Функция | Описание
Viewer | обеспечивает доступ к внутреннему вьюеру FAR'a
ViewerControl | позволяет запрашивать различную информацию о встроенной программе просмотра FAR и управлять ее состоянием

Структуры

Структура | Описание
ViewerInfo | информации о текущем состоянии программы просмотра
ViewerMode | информация о режимах программы просмотра
ViewerSelect | выделение области в программе просмотра
ViewerSetMode | изменение режим работы программы просмотра
ViewerSetPosition | изменение текущей позиции в файле
FARINT64 | используется для хранения 64-битного целого
Смотрите также:


Custom API

главная
В данном разделе представлены API "сторонних производителей", позволяющие писать модули второго уровня для ряда известных плагинов.
API | Описание
API поддержки архивов | API для разработки FMT-модулей для плагина MultiArc.
Интерфейс регулярных выражений библиотеки colorer | Описание регулярных выражений колорера как в исходниках, так и в виде интерфейса внешней DLL.
Search and Replace plugins programming | API для разработки SRP-модулей для плагина Search and Replace.
Mr.Ripper API | API для разработки RIP-модулей для плагина Mr.Ripper.


Дополнения

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

Функции общего назначения

Функции | Описание
InitDialogItems | Преобразование InitDialogItem в FarDialogItem
InitMenuItems | Преобразование InitMenuItem в FarMenuItem
LocMsg | Возвращает указатель на строку в соответствии с языковыми настройками FAR Manager

Структуры

Структура | Описание
InitDialogItem | Описывает один элемент диалога
InitMenuItem | Описывает один пункт меню
Смотрите также:


Дополнения

Дополнения - Функции общего назначения

главная | дополнения
Функции | Описание
InitDialogItems | Преобразование InitDialogItem в FarDialogItem
InitMenuItems | Преобразование InitMenuItem в FarMenuItem
LocMsg | Возвращает указатель на строку в соответствии с языковыми настройками FAR Manager
Смотрите также:


InitDialogItems

главная | дополнения
Функция InitDialogItems предназначена для преобразования массива структур InitDialogItem в FarDialogItem.

Внимание! Внимание!

  • Функция InitDialogItems не входит в стандартное API.
void InitDialogItems(
       const struct InitDialogItem *Init,
       struct FarDialogItem *Item,
       int ItemsNumber
)
{
  int I;
  const struct InitDialogItem *PInit=Init;
  struct FarDialogItem *PItem=Item;
  for (I=0; I < ItemsNumber; I++,PItem++,PInit++)
  {
    PItem->Type=PInit->Type;
    PItem->X1=PInit->X1;
    PItem->Y1=PInit->Y1;
    PItem->X2=PInit->X2;
    PItem->Y2=PInit->Y2;
    PItem->Focus=PInit->Focus;
    PItem->Reserved=PInit->Selected;
    PItem->Flags=PInit->Flags;
    PItem->DefaultButton=PInit->DefaultButton;
    if ((unsigned int)PInit->Data < 2000)
      strcpy(PItem->Data,GetMsg((unsigned int)PInit->Data));
    else
      strcpy(PItem->Data,PInit->Data);
  }
}

Параметры

Init
Указатель на массив структур InitDialogItem. Каждая структура описывает пункт диалога.
Item
Указатель на массив структур FarDialogItem для инициализации. Каждая структура будет описывать пункт диалога.
ItemsNumber
Количество элементов массива Init.

Возвращаемое значение

Нет.

Замечания

Введение функции InitDialogItems обусловлено следующим:
Поскольку переменная FarDialogItem.Data имеет большой размер, прямая инициализация массива FarDialogItem, может заметно увеличить потребление памяти.

В примере (см. ниже) показано как использовать функцию InitDialogItems и структуру InitDialogItem для создания диалога.

Пример

Пример вывода диалога конфигурирования плагина TempPanel:

int Config()
{
  struct InitDialogItem InitItems []={
    DI_DOUBLEBOX,3,1,72,8,0,0,0,0,(char *)MConfigTitle,
    DI_CHECKBOX,5,2,0,0,0,0,0,0,(char *)MConfigAddToDisksMenu,
    . . .
    DI_BUTTON,0,7,0,0,0,0,DIF_CENTERGROUP,1,(char *)MOk,
    DI_BUTTON,0,7,0,0,0,0,DIF_CENTERGROUP,0,(char *)MCancel
  };
  struct FarDialogItem DialogItems[sizeof(InitItems)/sizeof(InitItems[0])];
  . . .
  InitDialogItems(InitItems,DialogItems,sizeof(InitItems)/sizeof(InitItems[0]));
  . . .
  int ExitCode=Info.Dialog(Info.ModuleNumber,
                  -1,-1,76,10,
                  "TempCfg",DialogItems,
                  sizeof(DialogItems)/sizeof(DialogItems[0]));
  if (ExitCode != 7)
    return(FALSE);
. . .
}

Смотрите также:


InitMenuItems

главная | дополнения
Функция InitMenuItems предназначена для преобразования массива структур InitMenuItem в FarMenuItem.

Внимание! Внимание!

  • Функция InitMenuItems не входит в стандартное API.
void InitMenuItems(
         const struct InitMenuItem *Init,
         struct FarMenuItem *Item,
         int ItemsNumber)
{
  int I;
  struct FarMenuItem *PItem=Item;
  const struct InitMenuItem *PInit=Init;
  for (I=0; I < ItemsNumber; I++,PItem++,PInit++)
  {
    PItem->Selected=PInit->Selected;
    PItem->Checked=PInit->Checked;
    PItem->Separator=PInit->Separator;
    if ((unsigned int)PInit->Text < 2000)
      strcpy(PItem->Text,GetMsg((unsigned int)PInit->Text));
    else
      strcpy(PItem->Text,PInit->Text);
  }
}

Параметры

Init
Указатель на массив структур InitMenuItem. Каждая структура описывает пункт меню.
Item
Указатель на массив структур FarMenuItem для инициализации. Каждая структура будет описывать пункт меню.
ItemsNumber
Количество элементов массива Init.

Возвращаемое значение

Нет.

Замечания

Введение функции InitMenuItems обусловлено следующим:
Поскольку переменная FarMenuItem.Text имеет большой размер, прямая инициализация массива FarMenuItem, может заметно увеличить потребление памяти.

В примере (см. ниже) показано как использовать функцию InitMenuItems и структуру InitMenuItem для создания меню.

Смотрите также:


LocMsg

главная | дополнения
Функция LocMsg возвращает указатель на строку в соответствии с языковыми настройками FAR Manager. Является аналогом стандартной функции GetMsg.

Внимание! Внимание!

  • Функция LocMsg не входит в стандартное API. Исходный текст функции см. здесь
char *LocMsg(
  struct PluginStartupInfo *psi,
  char *MsgName,
  char *Var,
  int Len
);

Параметры

psi
Указатель на структуру PluginStartupInfo; из этой структуры берутся переменные RootKey и ModuleNumber.
MsgName
название нужного сообщения
Var
если не NULL, то сюда копируется полученная строка
Len
если = 0, то копируется столько, сколько есть

Возвращаемое значение

Указатель на строку, содержащую данные.

Замечания

  1. В отличии от функции GetMsg, данная функция не кэширует данные, что позволяет динамически (без перезагрузки FAR Manager) менять данные и т.п.
  2. Функция LocMsg позволяет также применять "локализацию" к плагинам "второго уровня", которые "урезаны в своих правах"...
  3. Учитываются настройки конкретных пользователей - фича FAR 1.63
  4. Файл с сообщениями (располагается в каталоге с плагином) должен называться ИмяПлагина.msg и является обыкновенным ini-файлом. Его структура такова:
    [Default]
//Данная секция сообщает из какой секции брать строки, если в
//данном файле не найдено требуемой языковой секции. Данная секция
//может отсутствовать, в этом случае языковой секцией по умолчанию
//считается первая.
Language=Russian

//Далее идет описания языковых секций.
//Названия ДОЛЖНЫ формироваться следующим образом:
//В lng-файлах первая строка такая
//.Language=Russian,Russian (Русский)
//          ^^^^^^^
//А вот так должна называться языковая секция

[Russian]
String1=Текст первого сообщения
String2=Текст второго сообщения
IsSkipNoWord=1

[English]
String1=Text of the first message
String2=Text of the second message
IsSkipNoWord=1
//и т.д.

Пример

  BOOL IsSkipNoWord;
  p=LocMsg("IsSkipNoWord",NULL,1);
  IsSkipNoWord=(*p != '0')?TRUE:FALSE;

  phf=strrchr(LocMsg(temp,"String1",956),".");
Смотрите также:


Дополнения

Дополнения - Структуры

главная | дополнения
Структура | Описание
InitDialogItem | Описывает один элемент диалога
InitMenuItem | Описывает один пункт меню
Смотрите также:


InitDialogItem

главная | структуры | дополнения
Структура InitDialogItem описывает один элемент диалога. Эта структура не является стандартной - это аналог структуры FarDialogItem. Отличие только в члене Data

Внимание! Внимание!

  • Структура InitDialogItem не входит в стандартное API.
struct InitDialogItem
{
  int Type;
  int X1;
  int Y1;
  int X2;
  int Y2;
  int Focus;
  DWORD_PTR Selected;
  unsigned int Flags;
  int DefaultButton;
  char *Data;
};

Замечания

Поведение структуры InitDialogItem, как аналога FarDialogItem обусловлено следующим:
Поскольку переменная FarDialogItem.Data имеет большой размер, прямая инициализация массива FarDialogItem, может заметно увеличить потребление памяти.
Для преобразования InitDialogItem в FarDialogItem можно воспользоваться функцией InitDialogItems
Смотрите также:


InitMenuItem

главная | структуры | дополнения
Структура InitMenuItem описывает один пункт меню. Эта структура не является стандартной - это аналог структуры FarMenuItem. Отличие только в члене Text.

Внимание! Внимание!

  • Структура InitMenuItem не входит в стандартное API.
struct InitMenuItem
{
  char* Text;
  int Selected;
  int Checked;
  int Separator;
};

Замечания

Введение структуры InitMenuItem, как аналога FarMenuItem обусловлено следующим:
Поскольку переменная FarMenuItem.Text имеет большой размер, прямая инициализация массива FarMenuItem, может заметно увеличить потребление памяти.

Для преобразования InitMenuItem в FarMenuItem можно воспользоваться функцией InitMenuItems.

Смотрите также:


Поддержка архивов

главная | Custom API

Замечание Замечание

  • Данная информация актуальна только для плагина MultiArc, входящего в стандартную поставку FAR Manager!
Плагин MultiArc использует для поддержки конкретных форматов архивов плагины второго уровня - FMT-модули. FMT-модулями считаются все файлы *.FMT, находящиеся в подкаталоге Formats каталога MultiArc (но не в подкаталогах каталога Formats).

Экспортируемые функции FMT-модулей

Функция | Описание
CloseArchive | Закрыть архив.
GetArcItem | Получить информацию о следующем элементе архива.
GetDefaultCommands | Получить строки команд архиватора, используемые по умолчанию
GetFormatName | Получить имя формата архива.
GetSFXPos | Получить позицию начала архива.
IsArchive | Проверка, является ли указанный файл архивом.
LoadFormatModule | Вызывается во время загрузки плагина второго уровня.
OpenArchive | Открыть архив и подготовить его к чтению.
SetFarInfo | Передает плагину глобальные установки.

Структуры, используемые FMT-модулями

Структура | Описание
ArcInfo | Общая информация об архиве
ArcItemInfo | Информация о конкретном элементе архива

Замечания

  1. Вы также можете использовать технологию плагинов второго уровня в ваших плагинах. Примеры таких плагинов:
    • Expression Calculator (Alexey Torgashin)
    • Search and Replace (Ivan Sintyurin)
    • Address Book (Pavel Kostromitinov)
    • Mr.Ripper (Vladimir Kubyshev)
Смотрите также:
Экспортируемые функции, Сервисные функции, Структуры, Дополнения, Описание формата файла custom.ini


Поддержка архивов

Экспортируемые функции FMT-модулей

главная | Custom API | поддержка архивов

Замечание Замечание

  • Данная информация актуальна только для плагина MultiArc, входящего в стандартную поставку FAR Manager!
Функция | Описание
CloseArchive | Закрыть архив.
GetArcItem | Получить информацию о следующем элементе архива.
GetDefaultCommands | Получить строки команд архиватора, используемые по умолчанию
GetFormatName | Получить имя формата архива.
GetSFXPos | Получить позицию начала архива.
IsArchive | Проверка, является ли указанный файл архивом.
LoadFormatModule | Вызывается во время загрузки плагина второго уровня.
OpenArchive | Открыть архив и подготовить его к чтению.
SetFarInfo | Передает плагину глобальные установки.
Смотрите также:
Экспортируемые функции, Сервисные функции, Структуры, Дополнения, Описание формата файла custom.ini


LoadFormatModule

главная | Custom API | поддержка архивов
Вызывается, когда модуль плагина второго уровня уже загружен. Эта функция дополнительная и может быть опущена.
DWORD WINAPI LoadFormatModule(
  const char *ModuleName
);

Параметры

ModuleName
имя модуля плагина второго уровня (полный путь к FMT-файлу)

Возвращаемое значение

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

Примечание

Эта функция вызывается один раз, когда MultiArc загружает плагин второго уровня (см. исходные тексты MultiArc - файл ARCPLG.CPP, функция ArcPlugins::LoadFmtModules)

Смотрите также:
поддержка архивов


IsArchive

главная | Custom API | поддержка архивов
Проверка, является ли указанный файл архивом.
BOOL WINAPI IsArchive(
  const char *Name,
  const unsigned char *Data,
  int DataSize
);

Параметры

Name
имя архива
Data
данные из архивного файла (указатель на данные размером DataSize от начала файла).
DataSize
размер переданных данных

Возвращаемое значение

TRUE, если тип архива поддерживается плагином.

Пример

Пример определения архива ZIP (ZIP.CPP)

BOOL WINAPI _export IsArchive(const char *Name,
                      const unsigned char *Data,
                      int DataSize)
{
  for (int I=0;I < DataSize-10;I++)
  {
    const unsigned char *D=Data+I;
    if (D[0]=='P' && D[1]=='K' &&
        D[2]==3   && D[3]==4   &&
        D[8]<15   && D[9]==0)
    {
      SFXSize=I;
      return(TRUE);
    }
  }
  return(FALSE);
}
Смотрите также:
поддержка архивов


GetSFXPos

главная | Custom API | поддержка архивов
Возвращает позицию начала архива в потоке передаваемых функции IsArchive данных.
DWORD WINAPI GetSFXPos(void);

Параметры

Нет.

Возвращаемое значение

Позиция начала архива относительно начала файла.

Замечания

Функция GetSFXPos вызывается сразу после успешного распознавания архива функцией IsArchive. MultiArc выбирает тот FMT-модуль, который вернул наименьшее значение (ближе к началу файла). Это исправляет ситуацию, когда в ZIP-файл с именем, например, "N3gk8v1t.106" помещен ARJ-архив без сжатия. И если в такой архив заглянуть предыдущими версиями MultiArc, то увидим содержимое именно ARJ-архива, а не ZIP.

Смотрите также:
поддержка архивов


OpenArchive

главная | Custom API | поддержка архивов
Открыть архив и подготовить его к чтению. Вызывается после успешного выполнения IsArchive .
BOOL WINAPI OpenArchive(
  const char *Name,
  int *Type
);

Параметры

Name
имя архива
Type
если плагин поддерживает несколько типов архивов, то установите тип здесь, иначе *Type должен быть равен 0

Возвращаемое значение

TRUE при успешном завершении, FALSE в случае ошибки.

Примечание

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

Смотрите также:
поддержка архивов


GetArcItem

главная | Custom API | поддержка архивов
Получить информацию о следующем элементе архива. Вызывается в цикле после вызова функции OpenArchive до тех пор, пока модуль возвращает значение GETARC_SUCCESS.
int WINAPI GetArcItem(
  struct PluginPanelItem *Item,
  struct ArcItemInfo *Info
);

Параметры

Item
эта структура должна быть заполнена. (см. PluginPanelItem для детального описания полей структуры).
Info
Дополнительная информация пункта, которая по возможности должна заполняться (см. ArcItemInfo).

Возвращаемое значение

Возвращаемое значение | Описание
GETARC_EOF | Достигнут конец архива.
GETARC_SUCCESS | Item получен успешно.
GETARC_BROKEN | "Битый" архив
GETARC_UNEXPEOF | Неожиданный конец архива
GETARC_READERROR | Ошибка чтения
Смотрите также:
поддержка архивов


CloseArchive

главная | Custom API | поддержка архивов
Закрыть архив. Вызывается после последнего вызова GetArcItem.
BOOL WINAPI CloseArchive(
  struct ArcInfo *Info
);

Параметры

Info
Дополнительная информация архива, которая по возможности должна заполняться (см. ArcInfo).

Возвращаемое значение

TRUE при успешном выполнении функции.

Смотрите также:
поддержка архивов, ArcInfo, GetArcItem


GetFormatName

главная | Custom API | поддержка архивов
Получить имя формата архива.
BOOL WINAPI GetFormatName(
  int Type,
  char *FormatName,
  char *DefaultExt
);

Параметры

Type
тип архива
FormatName
имя формата; оно будет использовано при сохранении параметров в реестре и при выборе желательного формата архива.
DefaultExt
расширение файла по умолчанию для данного формата (без точки); используется для ускорения распознавания формата.

Возвращаемое значение

В случае успеха возвращается TRUE. Если указанное значение типа архива не поддерживается, то должно возвращаться FALSE.

Пример

Пример получения имени формата ZIP-файла (ZIP.CPP)

BOOL WINAPI _export GetFormatName(int Type,char *FormatName,char *DefaultExt)
{
  if (Type==0)
  {
    strcpy(FormatName,"ZIP");
    strcpy(DefaultExt,"zip");
    return(TRUE);
  }
  return(FALSE);
}
Смотрите также:
поддержка архивов


GetDefaultCommands

главная | Custom API | поддержка архивов
Получить строки команд архиватора, используемые по умолчанию
BOOL WINAPI GetDefaultCommands(
  int Type,
  int Command,
  char *Dest
);

Параметры

Type
Тип архива
Command
Номер команды архиватора:
Номер | Описание
0 | extract (распаковка)
1 | extract without path (распаковка без путей)
2 | test (тестирование)
3 | delete (удаление)
4 | comment (архивный комментарий)
5 | comment files (файловый комментарий)
6 | convert to SFX (преобразование в SFX)
7 | lock (запрет модификации)
8 | add recovery record (защита от повреждений)
9 | recover (восстановление архива)
10 | add files (добавление файлов)
11 | move files (перенос файлов)
12 | add files and folders (добавление файлов и папок)
13 | move files and folders (перенос файлов и папок)
14 | mask to select all files (маска "Все файлы")

В настройках плагина MultiArc это выглядит так:

Dest
Буфер для копирования команд. MultiArc ожидает строку не более 511 байт.

Возвращаемое значение

В случае успеха возвращается TRUE. Если указанный тип архива не поддерживается, то FALSE. Если тип поддерживается, но требуемая команда отсутствует, то верните TRUE и установите Dest в пустую строку.
Смотрите также:
поддержка архивов


SetFarInfo

главная | Custom API | поддержка архивов
Вызывается, когда модуль плагина второго уровня загружен и MultiArc передает плагину указатель на структуру PluginStartupInfo. Эта функция дополнительная и может быть опущена.
void  WINAPI SetFarInfo(
  const struct PluginStartupInfo *Info
);

Параметры

Info
указатель на структуру PluginStartupInfo

Возвращаемое значение

Нет.

Примечание

  1. Функция вызывается один раз сразу после вызова функции LoadFormatModule, после чего плагин второго уровня будет знать о FAR Manager столько же, сколько и сам плагин MultiArc (плюс небольшая добавка от самого MultiArc).
  2. Указатель Info действителен только в области видимости данной функции (до выхода из функции), так что структура должна копироваться во внутреннюю переменную плагина второго уровня для дальнейшего использования:
    static struct PluginStartupInfo Info;
...
void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info)
{
  ::Info=*Info;
  ...
}
  3. Если в плагине используются "стандартные функции" из структуры FarStandardFunctions, то член PluginStartupInfo.FSF так же должен быть сохранен в локальное пространство плагина второго уровня:
    static struct PluginStartupInfo Info;
static struct FarStandardFunctions FSF;

void  _export SetStartupInfo(struct PluginStartupInfo *psInfo)
{
    Info=*psInfo;
    FSF=*psInfo->FSF;
    Info.FSF=&FSF; // скорректируем адрес в локальной структуре
    ...
}
Смотрите также:
поддержка архивов, PluginStartupInfo


Поддержка архивов

Структуры, используемые FMT-модулями

главная | Custom API | поддержка архивов

Замечание Замечание

  • Данная информация актуальна только для плагина MultiArc, входящего в стандартную поставку FAR Manager!
Структура | Описание
ArcInfo | Общая информация об архиве
ArcItemInfo | Информация о конкретном элементе архива
Смотрите также:
Экспортируемые функции, Сервисные функции, Структуры, Дополнения, Описание формата файла custom.ini


ArcItemInfo

главная | Custom API | поддержка архивов
Эта структура передается в функцию GetArcItem (поля уже заполнены 0).
struct ArcItemInfo
{
  char HostOS[32];
  char Description[256];
  int Solid;
  int Comment;
  int Encrypted;
  int DictSize;
  int UnpVer;
  int Chapter;
};

Элементы

HostOS
Операционная система для распаковки или пустая строка, если она неизвестна
Description
Описание элемента или пустая строка
Solid
Флаг, указывающий на непрерывный архив.
Comment
Установите, если присутствует файловый комментарий
Encrypted
Установите, если файл зашифрован
DictSize
Размер словаря или 0, если он неизвестен
UnpVer
Версия, необходимая для распаковки (HighNumber*256+LowNumber) или 0 если неизвестно
Chapter
глава (chapter) в архиве, которой принадлежит файл.
Смотрите также:


ArcInfo

главная | Custom API | поддержка архивов
Эта структура передается CloseArchive.
struct ArcInfo
{
  int SFXSize;
  int Volume;
  int Comment;
  int Recovery;
  int Lock;
  DWORD Flags;
  DWORD Reserved;
  int Chapters;
};

Элементы

SFXSize
размер модуля SFX
Volume
Флаг тома
Comment
Присутствует архивный комментарий
Recovery
Присутствует защита от повреждений
Lock
Архив защищен от изменений
Flags
Дополнительные архивные информационные флаги. Поле Flags может быть комбинацией следующих значений:
Структура | Описание
AF_AVPRESENT | Присутствует электронная подпись (информация о подлинности архива)
AF_IGNOREERRORS | Код завершения архивных команд должен игнорироваться для этого архива.
AF_HDRENCRYPTED | Заголовок архива шифрованный.
Reserved
Зарезервировано.
Chapters
Количество глав (chapter) в архиве.

Замечания

Структура ArcInfo передается в CloseArchive инициализированная нулями.

Смотрите также:
поддержка архивов, структуры


Командные строки архиваторов

главная | Custom API | поддержка архивов
В командных строках внешних архиваторов для различных операций обработки архивов могут использоваться следующие переменные:
Переменные | Описание
%%A | Имя архива
%%a | Короткое имя архива.
%%W | Папка для временных файлов, включая завершающую косую черту.
%%P | Пароль.
%%R | Текущая папка в архиве.
%%L | Имя списка файлов. Список файлов - это файл, содержащий имена файлов, предназначенных для обработки внешним архиватором.
%%l | Имя списка коротких имен файлов.
%%F | Имена одного или нескольких файлов для обработки. Если все имена не помещаются в одну строку, архиватор будет запущен несколько раз до тех пор, пока не исчерпаются все имена файлов. По умолчанию максимальная длина строки равна 127, но вы может указать ее непосредственно после %%F, например %%F512. Переменная %%F должна использоваться только в том случае, если архиватор не поддерживает списки файлов.
%%f | Имя одного файла для обработки. Архиватор будет запускаться, пока не исчерпаются все имена файлов. Эта переменная должна использоваться только в том случае, если архиватор не поддерживает списки файлов или несколько имен файлов в командной строке.
%%E «код завершения» | максимальный допустимый код завершения команды. Например, %%E2 указывает, что допускаются коды 0, 1 и 2. Эта переменная может быть указана в любом месте команды. Если она отсутствует, то как успешный рассматривается только код завершения 0.
%%S | Место для вставки в командную строку дополнительных ключей, указанных во второй строке диалога "Добавить". Если эта переменная отсутствует, ключи будут добавлены в конец командной строки.

Модификаторы переменных Q, S, M, N, *, W могут быть использованы для уточнения деталей формата имен файлов:

Модификаторы | Описание
'Q' | заключать имена с пробелами в кавычки;
'q' | заключать все имена в кавычки;
'S' | использовать '/' вместо '\' в путях файлов;
'M' | передавать имена папок архиваторам как 'имя\*.*';
'N' | передавать имена папок архиваторам как 'имя';
'*' | использовать маску '*' для выбора всех файлов. Этот модификатор перекрывает действие параметра "Маска Все файлы" для отдельной команды архиватора;
'W' | использовать только имя без пути;
'P' | использовать только путь без имени;
'A' | использовать кодировку ANSI.

Эти модификаторы могут быть использованы сразу же после переменных %%F, %%f, %%L или %%l без пробелов. 'P' и 'A' также могут быть указаны после %%A и %%a. Допускается использование нескольких модификаторов, например, %%LMN или %%FQSN128. Если не указаны ни модификатор 'M', ни 'N', то по умолчанию используется 'N'. Если указаны и 'M', и 'N', то архиватору будут переданы и 'имя', и 'имя\*.*'.

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

Если внешний архиватор не поддерживает какую-либо команду, оставьте соответствующую строку пустой.

Смотрите также:
поддержка архивов, GetDefaultCommands


Формат файла custom.ini

главная | Custom API | поддержка архивов
В стандартной поставке MultiArc идет ограниченное количество FMT-модулей, поддерживающих распространенные архиваторы. Среди прочих присутствует модуль CUSTOM.FMT, который позволяет подключать "недостающие" архиваторы путем описания формата выводимого архиватором листинга. Для описания формата предназначен файл CUSTOM.INI.

Каждый добавляемый тип архива описывается в отдельной секции [Имя архива], используемый для имени типа архива. Далее следуют параметры:

TypeName (необязательный параметр)
перекрывает имя формата, определенное в названии секции (оставлен для совместимости)
ID (необязательный параметр)
идентификатор архива - последовательность двузначных шестнадцатеричных чисел, разделенные пробелом (например, запись "ID=1a 4a 61 72 1b" - описывает идентификатор JAR-архива)
IDOnly (необязательный параметр)
"только идентификатор архива". Если равно "1", то расширение файла игнорируется и тип архива определяется только по полю ID. Если равно "0", то для определения типа архива используется расширение файла и поле ID (если присутствует в данной секции).
IDPos (необязательный параметр)
позиция, с которой CUSTOM.FMT начинает искать идентификатор архива (ID). Если поле не определено, то ID ищется начиная с начала файла. По умолчанию FAR "отдает" плагину на анализ первые 128К данных.
Extension
расширение архива (без точки).
List
команда внешнего архиватора для получения листинга. Имя архива будет добавлено после этой строки. Например, для поля List="jar32 v -y" будет сформирована команда: jar32 v -y имя_архива
Errorlevel (необязательный параметр)
анализ листинга производится только если код завершения архиватора будет меньше указанного в параметре Errorlevel числа.
IgnoreErrors (необязательный параметр)
если не равно 0, то код возврата команд архиватора будет игнорироваться. Использовать осторожно!
Start (необязательный параметр)
подстрока, определяющая начало анализа листинга. Если строка начинается с символа '^', то поиск подстроки ведется со второго символа от начала текущей строки листинга.
End (необязательный параметр)
подстрока, определяющая окончание анализа листинга. Если строка начинается с символа '^', то поиск подстроки ведется со второго символа от начала текущей строки листинга.
Format0 ... FormatN
параметры, описывающие запись для одного элемента архива. Каждый параметр описывает очередную строку записи, допускающую следующие коды:
код | Описание
n | имя файла
. | remove trailing spaces from file name and append name with dot
z | размер файла
c | file description
p | упакованный размер файла
d | день
t | месяц
TTT | три буквы имени месяца (Jan, Feb, Mar, ...)
y | год
h | часы
H | hours modifier letter (a - a.m. time, p - p.m. time)
m | минуты
s | секунды
a | атрибуты файла
* | skip until first space or end of line
b | day of last access
v | month of last access
e | year of last access
x | hours of last access
l | minutes of last access
k | seconds of last access
j | day of creation
g | month of creation
f | year of creation
o | hours of creation
i | minutes of creation
u | seconds of creation
r | CRC (hex)
C | поле, описывающее главы (Chapters)
(<число>) | optional digits, some or all digits may be missing
Если строка начинается с символа '^', то поиск подстроки ведется со второго символа от начала текущей строки листинга.
IgnoreString0 ... IgnoreStringN
параметры, задающие строки, которые модуль будет игнорировать при анализе листинга. Если строка начинается с символа '^', то поиск подстроки ведется со второго символа от начала текущей строки листинга.
Extract ... MoveRecurse
параметры, описывающие команды архиватора.
Команда | Описание
Extract | распаковка
ExtractWithoutPath | распаковка без путей
Test | тестирование
Delete | удаление
Comment | архивный комментарий
CommentFiles | файловый комментарий
SFX | преобразование в SFX
Lock | запрет модификации
Protect | защита от повреждений
Recover | восстановление архива
Add | добавление файлов
Move | перенос файлов в архив
AddRecurse | добавление файлов и папок
MoveRecurse | перенос файлов и папок
В командных строках внешних архиваторов для различных операций обработки архивов могут использоваться псевдопеременные, описанные здесь.
AllFilesMask
маска "Все файлы"

Регулярные выражения

В качестве значений параметров FormatX, IgnoreStringX, Start, End можно использовать регулярные выражения с синтаксисом Perl5. Для использования этой возможности необходимо, чтобы соответствующее значение было корректным регулярным выражением, обрамленным прямыми слешами ('/') с необязательными буквенными флагами после заключительного слеша. Допустимы следующие флаги:
Флаг | Описание
i | игнорировать регистр символов
x | использовать расширенный синтаксис (игнорировать пробелы в регулярном выражении)

Для разбора регулярных выражений используется open-source библиотека PCRE (by Philip Hazel, copyright by the University of Cambridge, England).

При использовании регулярных выражений в параметрах FormatX для получения информации из листинга используются именованные подстроки (вида (?P<name>\w+)). Распознаются следующие названия полей:
Поле | Описание
name | имя файла с относительным путем (пробельные символы в начале и конце строки игнорируются)
description | описание файла
size | размер распакованного файла в байтах (нецифровые символы в этом и других числовых полях игнорируются)
packedSize | размер запакованного файла в байтах
attr | атрибуты файла (A - архивный, R - только для чтения, S - системный, C - сжатый, H - спрятанный, D - директория)
cYear, cDay, cMonth, cHour, cMin, cSec | время создания файла
mYear, mDay, mMonth, mHour, mMin, mSec | время последнего изменения файла
mAMPM, mMonthA | расширенные поля для времени изменения файла
aYear, aDay, aMonth, aHour, aMin, aSec | время доступа к файлу
CRC | 32-битная контрольная сумма файла CRC

Например, для разбора листинга:

 Volume in drive D is work
 Volume Serial Number is xxxx-xxxx

 Directory of D:\works\MultiArc\final\Formats

15.11.2004  07:15    <DIR>          .
15.11.2004  07:15    <DIR>          ..
14.11.2004  00:46             5 632 Ace.fmt
14.11.2004  00:46             4 608 Arc.fmt
14.11.2004  00:46             6 656 Arj.fmt
14.11.2004  00:46             6 144 Cab.fmt
15.11.2004  06:07            56 832 Custom.fmt
15.11.2004  07:14             1 551 custom.ini-re
15.11.2004  07:11            54 344 Formats.jkr
14.11.2004  00:46             4 608 Ha.fmt
14.11.2004  00:46             6 144 Lzh.fmt
15.11.2004  07:15                 0 out
14.11.2004  00:46             6 144 Rar.fmt
14.11.2004  00:46             9 216 TarGz.fmt
14.11.2004  00:46             6 656 Zip.fmt
              13 File(s)        168 535 bytes
               2 Dir(s)  37 840 883 712 bytes free

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

Start="/^ Directory of/"
End="/File\(s\)/"
Format0="/^(?P<cDay>\d+).(?P<cMonth>\d+).(?P<cYear>\d+)\s+ (?P<cHour>\d+):(?P<cMin>\d+)\s+(?P<packedSize>[\d\xff]+)\s(?P<name>.*?)\s*$/"

Строки:

Start="/^..reading directory/"
End="/^..listing completed/"
Format0="/^[^\|]*\|(?P<size>[^\|]+)\|(?P<attr>[^\|]+)\|\s+(?P<name>.*?)\s*$/"
IgnoreString0="/^---- ---- ---- ----/"

могут использоваться для разбора листинга:

jkRes utility version 002
  pack/unpack tool to work with jkRes resource bundles

..listing files from resource bundle
..reading directory...12 items found
---- ---- ---- ----
    zlib |     5632 | A.... | Ace.fmt
    zlib |     4608 | A.... | Arc.fmt
    zlib |     6656 | A.... | Arj.fmt
    zlib |     6144 | A.... | Cab.fmt
    zlib |    56832 | A.... | Custom.fmt
    zlib |     4608 | A.... | Ha.fmt
    zlib |     6144 | A.... | Lzh.fmt
    zlib |     6144 | A.... | Rar.fmt
    zlib |     9216 | A.... | TarGz.fmt
    zlib |     6656 | A.... | Zip.fmt
    zlib |    13012 | A.... | Custom.ini
    zlib |     1072 | A.... | custom.ini-re
---- ---- ---- ----
..listing completed
..done

Смотрите также:
поддержка архивов


Регулярные выражения библиотеки colorer

главная | Custom API
Регулярные выражения - довольно прикольная штука, и при желании их можно довольно просто использовать в вашей программе/плагине. Колореровские регэкспы вы можете использовать в наиболее естественном их виде - в исходниках на языке C++ - как отдельный класс. Но, если вы работаете с другими языками или по иным причинам, вы можете использовать их и в виде предварительно скомпилированной DLL.

Исходники непосредственно могут быть найдены в дистрибутиве колорера (начиная с версии freecraze), а DLL вы можете скомпилировать в каталоге icolorer - также в дистрибутиве колорера. В случае подключения исходников вам надо работать с классом CRegExp и его методами, если же вы используете DLL, то просто экспортируете функции-шлюзы для этих методов.

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

Методы

Метод | Описание
CRegExp | Конструктор и деструктор объекта регэкспа.
isok | Результат последней компиляции выражения.
geterror | Расширенная информация об ошибке.
SetNoMoves | Установка возможности движения по целевой строке.
SetBkTrace | Установка ссылок для оператора \yN.
SetExpr | Компиляция выражения.
SetCodePage | Установка таблицы перекодировки для текстов в не-OEM кодировках
Parse | Сопоставление регэкспа целевой строке
Parse | Сопоставление регэкспа целевой строке с расширенными установками

Структуры:

Структура | Описание
SMatches | массив с конечными сопоставлениями скобок
Смотрите также:


CRegExp

главная | Custom API | регэкспы
Инициализация и уничтожение объекта регулярного выражения.

Методы класса:

CRegExp();
CRegExp(char *Text);
~CRegExp();

DLL интерфейс:

PRegExp WINAPI reCreate();
PRegExp WINAPI reCreateCompile(char *text);
BOOL WINAPI reDestroy(PRegExp re);

Элементы

re
Указатель на объект для уничтожения.
Text
указатель на строку с регулярным выражением для компиляции.

Возвращаемое значение

Функции reCreate и reCreateCompile возвращают указатель на созданный объект, который потом будет использовать при вызове всех функций - или NULL в случае неудачи. reDestroy возвращает результат удаления объекта-регулярного выражения.

Замечания

Конструктор с параметром при инициализации компилирует выражение. Результат можно узнать через метод isok или же через метод geterror.
Смотрите также:
isok


CRegExp.isok

главная | Custom API | регэкспы
Возвращает результат последней компиляции.

Метод класса:

bool isok();

DLL интерфейс:

BOOL WINAPI reIsok(PRegExp re);

Элементы

re
Указатель на объект

Возвращаемое значение

Возвращает TRUE или FALSE в зависимости от успеха последней компиляции.

Замечания

Возможно использование расширенного метода geterror для более подробного обнаружения ошибки...
Смотрите также:


CRegExp.geterror

главная | Custom API | регэкспы
[ отсутствует в colorer FreeCraze ]
Расширенная информация об ошибке компиляции

Метод класса:

EError geterror();

DLL интерфейс:

EError WINAPI reGetError(PRegExp re);

Элементы

re
Указатель на объект

Возвращаемое значение

Перечисляемый тип EError - тип ошибки:
enum EError
{
  EOK = 0, EERROR, ESYNTAX, EBRACKETS, EOP
};
думаю тут все понятно.
Смотрите также:
isok


CRegExp.SetNoMoves

главная | Custom API | регэкспы
Устанавливает возможность перемещения по целевой строке.

Метод класса:

bool SetNoMoves(bool Moves);

DLL интерфейс:

BOOL WINAPI reSetNoMoves(PRegExp re, BOOL Moves);

Элементы

re
Указатель на объект
Moves
Если TRUE, то функция сканирования не перемещается по целевой строке. Иначе производится попытка найти совпадение на каждой позиции в строке

Возвращаемое значение

Возвращает успех/неуспех установки параметра.

Замечания

При разрешении перемещений по целевой строке фактически производится вызов функции сканирования для каждой позиции в строке с первой по последнюю и на любой из них ищется совпадение. Если вам не нужна эта возможность, не забудьте установить SetNoMoves(TRUE);
Смотрите также:
CRegExp


CRegExp.SetBkTrace

главная | Custom API | регэкспы
Устанавливает отношения для оператора \yN

Метод класса:

bool SetBkTrace(char *Str, PMatches Trace);

DLL интерфейс:

BOOL WINAPI reSetBkTrace(PRegExp re, char *str, PMatches trace);

Элементы

re
Указатель на объект
Str
Строка для установки отношения
trace
набор совпадений скобок для предыдущего регулярного выражения

Возвращаемое значение

Возвращает TRUE или FALSE в зависимости от успеха операции.

Замечания

Эта функция используется для установки связи между разными регулярными выражениями (используется к примеру плагином колорер) - через оператор \yN где N - номер скобки в первом регулярном выражении для ссылки.
Смотрите также:
CRegExp


CRegExp.SetExpr

главная | Custom API | регэкспы
Устанавливает и компилирует регулярное выражение.

Метод класса:

bool SetExpr(char *Expr);

DLL интерфейс:

BOOL WINAPI reSetExpr(PRegExp re, char *expr)

Элементы

re
Указатель на объект
expr
Строка с регулярным выражением, записанным по правилам колорера. Если вы ищете в кодировке иной, чем OEM (dos866), вы должны во-первых передавать в этот метод преобразованную в вашу кодировку строку, а во-вторых вызвать функцию SetCodePage с адресом таблицы перекодировки из вашей кодировки в OEM.

Возвращаемое значение

Возвращает TRUE или FALSE в зависимости от успеха операции.

Замечания

Возможно использование расширенного метода geterror для более подробного обнаружения ошибки...
Смотрите также:


CRegExp.SetCodePage

главная | Custom API | регэкспы
[ отсутствует в colorer FreeCraze ]
Устанавливает кодовую страницу для работы с отличными от OEM кодировками.

Метод класса:

void SetCodePage(char *Table);

DLL интерфейс:

void WINAPI reSetCodePage(PRegExp re, char *Table);

Элементы

re
Указатель на объект
Table
Таблица для перекодировки из целевой в кодировку OEM

Возвращаемое значение

нет

Замечания

Для полноценной работы регулярных выражений в иной кодировке необходимо устанавливать само регулярное выражение также в целевой кодировке. Заметьте, что вы можете перекомпилировать класс так, чтобы по умолчанию он использовал отличную от OEM кодировку. В этом случае метод setcodepage также будет работать, но перекодировочные таблицы должны быть относительно кодировки, в которой скомпилирован класс CRegExp.
Смотрите также:
CRegExp


CRegExp.Parse

главная | Custom API | регэкспы
Сопоставляет скомпилированное регулярное выражение целевой строке.

Метод класса:

bool Parse(char *Str, PMatches Mtch);

DLL интерфейс:

BOOL WINAPI reParse(PRegExp re, char *str, PMatches mtch);

Элементы

re
Указатель на объект
str
Целевая строка для обработки
mtch
Указатель на структуру для хранения сопоставленных пар скобок

Возвращаемое значение

Возвращает TRUE или FALSE в зависимости от успеха сопоставления.

Замечания

В этом методе некоторые параметры принимаются по умолчанию. Начало строки соответствует реальному началу строки, конец - реальному ээ... концу. Если хотите использовать расширенные параметры - используйте расширенный вариант Parse
Смотрите также:


CRegExp.Parse

главная | Custom API | регэкспы
Сопоставляет скомпилированное регулярное выражение целевой строке, используя расширенные параметры.

Метод класса:

bool Parse(char *Str, char *Sol, char *Eol, PMatches Mtch, int Moves = -1);

DLL интерфейс:

BOOL WINAPI reParseParam(PRegExp re, char *str, char *Sol, char *Eol, PMatches mtch, BOOL moves)

Элементы

re
Указатель на объект
str
Целевая строка для обработки
Sol
Начало строки
Eol
Конец строки
mtch
Указатель на структуру для хранения сопоставленных пар скобок
moves
Принимается -1 по умолчанию - означает, что состояние NoMoves не меняется. Возможно указать иное значение - см. функцию SetNoMoves

Возвращаемое значение

Возвращает TRUE или FALSE в зависимости от успеха сопоставления.

Замечания

Если хотите использовать некоторые параметры по умолчанию - используйте короткий вариант Parse
Смотрите также:


SMatches

главная | Custom API | регэкспы
Возвращает результат последней компиляции.
#define MATCHESNUM 0x10
typedef struct SMatches
{
  int s[MATCHESNUM];
  int e[MATCHESNUM];
  int CurMatch;
} *PMatches;

Элементы

s
массив смещений начал сопоставленных скобок
e
массив смещений концов сопоставленных скобок
CurMatch
Общее количество скобок в регулярном выражении

Замечания

Если скобку сопоставить не удалось (она была пропущена), то и s и e равны -1. Заметьте, что не обязательно CurMatch равен числу совпавших скобок - последние могут выпадать в любом порядке.
Смотрите также:
CRegExp


Search and Replace plugins programming

Custom API

Search and Replace (S&R) - это плагин для FAR, позволяющий производить поиск и замену неких данных как в одном файле, так и во многих, а также работающий в редакторе и программе просмотра.

Информацию по API для разработки SRP-модулей (требуется файл помощи srplugins.chm) можно получить у автора плагина: Иван Синтюрин http://www.moris.ru/~spinoza. On-line версия находится по адресу: http://www.moris.ru/~spinoza/download/s_and_r/srplugins


Mr.Ripper API

Custom API

Mr.Ripper - это плагин для FAR, позволяющий выдирать различные файлы из недр других файлов. Знает более 20 форматов файлов, среди которых WAV, AVI, BMP, JPG, PNG, GIF, DJVU, MP3, MOD, XM, IT, RTF и др. И более 15 пакетных файлов для многих известных игр. Поддержка форматов осуществляется с помощью плагинов второго уровня, как для отдельных форматов, так и для пакетных файлов.

Для разработки RIP-модулей требуется файл помощи ripapi.chm, который содержит информацию по API. Файл можно получить у автора плагина: Владимир Кубышев http://vovan.dankov.net/mrripper/doc_ripapi.html.


Макросы - Файловый и архивный менеджер FAR

Макросы

главная

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

Макросы, чаще всего, используются для:

  1. совершения одинаковых действий несколько раз, используя для вызова последовательности этих действий одно сочетание кнопок;
  2. выполнения специальных функций, которые задаются специальными командами в тексте макроса;
  3. переопределение стандартных сочетаний клавиш, которые использует FAR для совершения тех или иных действий.

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

Подробнее о макросах:


Общие замечания - Макросы

Общие замечания

главная | Макросы

Каждый макрос имеет:

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

ВНИМАНИЕ! ВНИМАНИЕ!

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

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

Замечания

  • FAR не считывает макросы имеющие ошибки в названии макроклавиши и в последовательности "Sequence".
  • Регистр макрокоманд не имеет значения.
  • При старте FAR Manager загружает весь комплект описанных в реестре макрокоманд в память. После создания любая макропоследовательность немедленно заносится в реестр (при включенном автосохранении).
  • Макроклавиша, название которой в реестре начинается с символа '~', считается неактивной.
  • FAR Manager преобразует прокрутку колеса мыши в псевдоклавиши:
    - прокрутка на одно значение вверх - "MsWheelUp"
    - прокрутка на одно значение вниз - "MsWheelDown"
    Эти псевдоклавиши можно применять в сочетании с модификаторами Ctrl, Shift и Alt.
  • Если вы вводите символ при помощи Alt-цифры, то в макросе сохраняется именно эта комбинация, а не введенный символ.
    Например, Alt-151 будет храниться как "Alt00151".
  • Специфические клавиши, у которых виртуальный код отличен от 0xFF, но имена которых FAR не знает, будут хранится как "OemXXXXX" (здесь XXXXX десятичное значение виртуального кода клавиши с ведущими нулями).
  • Специфические клавиши, у которых виртуальный код равен 0xFF, будут хранится как "SpecXXXXX" (здесь XXXXX десятичное значение сканкода клавиши с ведущими нулями).
  • Для манипулирования макрокомандами рекомендуем воспользоваться плагином "Macro browser" Константина Мельникова. Этот модуль обеспечивает просмотр, редактирование, копирование и перемещение макрокоманд в другие группы (области), копирование и перемещение макрокоманд в другие настройки FAR, экспорт в файл, вставку в редактор, ввод новых, удаление и отключение установленных в FAR макрокоманд.
  • Значение параметра "NoSendKeysToPlugins" зависит от способа, которым начиналась запись макропоследовательности.
  • CtrlBreak прерывает выполнение макроса. При этом назначенный на CtrlBreak макрос не срабатывает..

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

Смотрите также:
Работа с макросами, Макроязык, Технические подробности, Примеры


Области действия - Макросы

Области действия

главная | Макросы | Общие сведения

FAR позволяет создавать независимые макросы (макросы, у которых совпадает сочетание клавиш запуска) для различных областей.

ВНИМАНИЕ! ВНИМАНИЕ!

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

В настоящий момент такими независимыми областями являются:

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

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

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

Имеется так же область Common. Макрос из этой области будет работать везде. При этом приоритет отдается перечисленным выше областям. Макрос из этой области нельзя создать интерактивно, но можно удалить.


Работа с макросами - Макросы

Работа с макросами

главная | Макросы

FAR может выполнять макросы в двух основных режимах:

  1. Общий режим: нажимаемые клавиши при записи и воспроизведении будут передаваться плагинам.
  2. Специальный режим: нажимаемые клавиши при записи и воспроизведении не будут передаваться плагинам, перехватывающим события в редакторе.

Например, если какой-то плагин обрабатывает сочетание клавиш Ctrl+A, то при специальном режиме работы макросов этот плагин не получит управления и не выполнит действия, которые он обычно выполняет при реакции на это сочетание клавиш.

Итак, что можно делать с макросами:

Записать
Удалить

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

Смотрите также:
Общие сведения, Макроязык, Технические подробности, Примеры


Запись макроса - Макросы

Запись макроса

главная | Макросы | Работа с макросами

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

  1. Начало записи макроса.
    Клавиша Ctrl-<.> (Ctrl и клавишу с точкой) для записи макроса в общем режиме и Ctrl-Shift-<.> (Ctrl, Shift и клавишу с точкой), для записи макроса в специальном режиме.
    После того как FAR начал запись макроса в левом верхнем углу экрана будет отображаться символ R.
  2. Текст макроса.
    FAR будет сохранять все нажимаемые клавиши со следующими исключениями:
    будут сохранены только клавиши, обрабатываемые FAR. Т.е. если вы в процессе записи макроса из консоли FAR запустите внешнюю программу, то FAR сохранит только клавиши, нажатые до запуска и после завершения внешней программы.
  3. Окончание записи макроса.
    Для завершения записи макроса служат специальные сочетания клавиш. Т.к. макрос может быть дополнительно настроен, то таких сочетаний два: Ctrl-<.> (Ctrl и клавиша с точкой) и Ctrl-Shift-<.> (Ctrl, Shift и клавиша с точкой). Первое сочетание вызывает запись макроса с параметрами воспроизведения, принятыми по умолчанию. Второе сочетание клавиш показывает диалог с параметрами выполнения макроса.
  4. Назначение сочетания клавиш для запуска макроса.
    После окончания ввода текста макроса и назначения параметров его выполнения будет показан диалог назначения клавиши, в котором можно задать горячую клавишу для воспроизведения записанной последовательности.

ВНИМАНИЕ! Примечание:

  • На время записи макроса все остальные макросы отключаются. Таким образом, нельзя записать "многоступенчатый" макрос, вызывающий ранее записанные макропоследовательности.


Удаление макроса - Макросы

Удаление макроса

главная | Макросы | Работа с макросами

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

Эту операцию можно выполнить, осуществив следующие действия:

  1. Начать запись макроса (Ctrl-<.>)
  2. Закончить запись макроса (Ctrl-<.>)
  3. Ввести или выбрать в диалоге назначения горячей клавиши сочетание, макрос для которого вы хотите удалить

ВНИМАНИЕ! ВНИМАНИЕ!

  • После удаления макроса сочетание клавиш, используемое для его выполнения, начнет выполнять свою первоначальную функцию. Т.е. если это сочетание клавиш до записи макроса обрабатывалось FAR или каким-либо плагином, то после удаления макроса оно снова начнёт обрабатываться.


Кнопки назначения - Макросы

Кнопки назначения

главная | Макросы | Работа с макросами

Макрос может быть назначен на:

  1. любую клавишу;
  2. на сочетание клавиши с модификаторами Ctrl, Alt и Shift;
  3. на сочетание клавиши с двумя модификаторами. FAR позволяет использовать следующие двойные модификаторы: Ctrl-Shift-<клавиша>, Ctrl-Alt-<клавиша> и Alt-Shift-<клавиша>

Макрос не может быть назначен на следующие клавиши и сочетания клавиш: Alt-Ins, Ctrl-<.>, Ctrl-Shift-<.>, Ctrl-Alt, Ctrl-Shift, Shift-Alt, Shift-<символ>, Ctrl-Alt-Shift.

Макрос не может быть назначен на следующие клавиши и сочетания клавиш: Alt-Space, Alt-Shift-Space, Alt-Enter, Alt-Shift-Enter. Эти клавиши системные.

Некоторые комбинации клавиш (в частности, Enter, Esc, F1, Ctrl-F5, Ctrl-Down, MsWheelUp и MsWheelDown с комбинацией Ctrl, Shift и Alt) невозможно ввести напрямую в диалоге назначения макроклавиши, поскольку они имеют специальные функции. Для того, чтобы назначить макрос на одну из таких комбинаций клавиш, выберите ее из выпадающего списка.

Смотрите также:
Запись макроса, Удаление макроса


Параметры макрокоманды - Макросы

Параметры макрокоманды

главная | Макросы | Работа с макросами

Параметры макрокоманды определяют условия запуска макроса.

Для задания дополнительных параметров макрокоманды завершите ее запись с помощью Ctrl-Shift-. вместо Ctrl-. и выберите желаемые опции в появившемся диалоге:

Разрешить во время выполнения вывод на экран
Allow screen output while executing macro
Если отключить этот параметр, то во время выполнения макрокоманды FAR Manager отключает перерисовку экрана. Все изменения будут отображены после завершения макрокоманды.
Выполнять после запуска FAR
Execute after FAR start
Позволяет выполнять макрокоманду сразу после запуска FAR Manager.

Для активной и пассивной панелей возможны следующие условия, активизирующие макрокоманду:

На панели плагина
Plugin panel
[x] - выполнять, только если панель плагиновая
[ ] - выполнять только для файловой панели
[?] - игнорировать тип панели
Выполнять для папок
Execute for folders
[x] - выполнять, только если на панели под курсором папка
[ ] - выполнять, только если на панели под курсором файл
[?] - выполнять для папок и файлов
Отмечены файлы
Selection present
[x] - выполнять, только если на панели есть отмеченные файлы/папки
[ ] - выполнять, если нет отмеченных файлов/папок
[?] - игнорировать состояние отметки файлов/папок

Прочие условия активизирующие макрокоманду:

Пустая командная строка
Empty command line
[x] - выполнять, только если командная строка пуста
[ ] - выполнять, только если командная строка не пуста
[?] - игнорировать состояние командной строки
Отмечен блок
Selection block present
[x] - выполнять, только если выделен блок в редакторе,
      программе просмотра, командной строке или в строке
      ввода в диалоге.
[ ] - выполнять, если нет отмеченного блока
[?] - игнорировать состояние отметки блока

ВНИМАНИЕ! Примечание:

  • * FAR, перед активацией макрокоманды, проверяет все описанные выше условия.
  • * Некоторые комбинации клавиш (в частности, Enter, Esc, F1, Ctrl-F5, Ctrl-Down, MsWheelUp и MsWheelDown с комбинацией Ctrl, Shift и Alt) невозможно ввести напрямую, поскольку они имеют специальные функции в диалоге. Для того, чтобы назначить макрос на одну из таких комбинаций клавиш, выберите ее из выпадающего списка в диалоге.
Смотрите также:
Запись макроса, Удаление макроса


Макроязык - Макросы

Макроязык

главная | Макросы

В FAR реализован примитивный макроязык, который позволяет в простую последовательность клавиш ввести логику, что делает макросы (вместе с плагинами) мощным средством, помогающим в работе с FAR Manager. Макроязык узкоспециализированный, привязанный к функционалу FAR Manager, поэтому его нельзя рассматривать как универсальный язык.

Функциональные возможности макроязыка:

  • Макрокоманды
  • Условные операторы
  • Булевые состояния
  • Функции
  • Операции
  • Состояния
  • Переменные
  • Константы

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
  2. Именованные клавиши (например, CtrlK) могут участвовать в любых выражениях; в этом случае они считаются как числа.
Смотрите также:
Общие сведения, Работа с макросами, Технические подробности, Примеры


Макрокоманды - Макросы

Макрокоманды

главная | Макросы | Макроязык

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

Команды, используемые в тексте макросов

Макрокоманда Описание
$Date ["format"] Предназначена для вставки текущей даты/времени.
Подробнее см. раздел "$Date".
$Text "string" Предназначена для вставки произвольного текста.
Подробнее см. раздел "$Text".
$IClip Работа с буфером обмена.
Подробнее см. раздел "$IClip".
$MMode 1 Позволяет изменять режим перерисовки экрана во время проигрывания макропоследовательности.
Подробнее см. раздел "$MMode".
$Exit Прерывает выполнение макропоследовательности.
Подробнее см. раздел "$Exit".
$XLat Вызывает функцию транслитерации.
Подробнее см. раздел "$XLat".
$KbdSwitch Циклическое переключение раскладки клавиатуры.
Подробнее см. раздел "$KbdSwitch".
$If (Expr) TruePart [$Else FalsePart] $End Позволяет организовать в макросах процесс ветвления макропоследовательности.
Подробнее см. раздел "$If".
$While (Expr) Sequence $End Позволяет организовать в макросах циклический процесс - "Пока условие Expr истинно выполнять последовательность Sequence".
Подробнее см. раздел "$While".
$Rep (Expr) Sequence $End Позволяет организовать в макросах циклический процесс - "Выполнить Expr раз последовательность Sequence".
Подробнее см. раздел "$Rep".
$AKey Клавиша вызова макроса.
Подробнее см. раздел "$AKey".
$SelWord Выделить слово под курсором.
Подробнее см. раздел "$SelWord".
%var=value;
%%var=value; 		Использование переменных.
Подробнее см. раздел "Переменные".

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


$AKey - Макросы

$AKey

главная | Макросы | Макроязык | Макрокоманды
Оператор $AKey предназначен для вставки во входной буфер клавиши, вызвавшей макрос.
$AKey

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

Макрос для переключения между экранами. В разделе Common вводятся 10 однотипных макросов AltЦифра:
$If ( Dialog || MainMenu || Menu || UserMenu || Search )
  $AKey
$Else
  %s = AKey ( 1 );
  %c = substr ( %s, len ( %s ) - 1, 1 );
  F12
  $If ( CheckHotkey ( %c ) )
    eval ( %c )
  $Else
    Esc
    $AKey
  $End
$End
Смотрите также:
akey, Примеры


$Date - Макросы

$Date

главная | Макросы | Макроязык | Макрокоманды
Оператор $Date предназначена для вставки текущей даты/времени.
$Date ["format"]

Элементы

format
Текущее время используется для преобразования в строку по формату "format". Этот формат подобен тому, что выдает утилита date (Unix).
$Date поддерживает следующую спецификацию формата даты (подобен формату функции strftime):
Формат | Описание
%% | символ %
%a | Краткое имя дня недели (Sun или Вск)
%A | Полное имя дня недели (Sunday или Воскресенье)
%b | Краткое имя месяца (Jan или Янв)
%B | Полное имя месяца (January или Январь)
%c | Дата и время в формате WDay Mnt Day HH:MM:SS yyyy (Mon Jan 10 04:11:54 2000 или Пнд Янв 10 04:11:54 2000)
%C | Столетие как десятичное число (00 - 99). 1992 => 19
%d | Две цифры дня месяца (01 - 31)
%D | Синоним для %x
%e | Синоним для %d, но вместо ведущего нуля будет стоять пробел.
%h | Синоним для %b
%H | Две цифры часа (00 - 23)
%I | Две цифры часа (01 - 12)
%j | Три цифры дня в году (001 - 366)
%k | Синоним для %H, но вместо ведущего нуля будет стоять пробел.
%l | Синоним для %I, но вместо ведущего нуля будет стоять пробел.
%L | Триггер, переключающий язык названий месяцев и дней недели - английский/локальный. FAR запрашивает у системы 2 набора наименований: 1) английские наименования месяцев и дней недели 2) наименования, соответствующие настройкам текущего пользователя (LOCALE_USER_DEFAULT) По умолчанию выставляются английские наименования.
%m | Месяц, как десятичное число (1 - 12)
%m0 | Подобно %m, но с ведущим нулем (01 - 12)
%mh | Одна цифра месяца, как шестнадцатеричное число (1 - C)
%M | Две цифры минут (00 - 59)
%n | Подобно переводу строки `\\n' Внимание! В редакторе автоотступ не работает.
%p | AM или PM
%r | Подобно %I:%M:%S %p
%R | Подобно %H:%M
%S | Две цифры секунд (00 - 59)
%t | Подобно символу табуляции `\\t'
%T | Синоним %X
%U | Две цифры номера недели, где Воскресенье (Sunday) является первым днем недели (00 - 53)
%v | Дата в формате dd-mmm-yyyy (mmm - в верхнем регистре)
%V | Неделя года в соответствии с ISO 8601: "Если неделя, содержащая 1 Января, имеет >= 4 дней в течение нового года, тогда это неделя 1; в противном случае это самая последняя нумерованная неделя прошлого года (52 или 53)"
%w | День недели где 0 - Воскресенье (Sunday) (0 - 6)
%W | Две цифры номера недели, где Понедельник (Monday) является первым днем недели (00 - 53)
%x | Дата в формате подобно dd<sep>mm<sep>yyyy (разделитель <sep> зависит от локальных настроек; порядок дня, месяца и года зависит от локальных настроек)
%X | Время в формате HH<sep>MM<sep>SS (разделитель <sep> зависит от локальных настроек)
%y | Две цифры года без столетия (00 - 99)
%Y | Год со столетием (19yy-20yy)
%Z | Имя часового пояса или пусто, если часовой пояс не задан

Произвольный текст в форматной строке должен быть только в OEM-кодировке.
В макрокоманде $Date допускается применение следующих escape-последовательностей:
Формат | Описание
\" | Символ '"'
\' | Символ '''
\\ | Символ '\'
\n | Перевод строки `\n'
\t | Символ табуляции `\t'
\a | bell
\b | `\b'
\f | `\f'
\v | `\v'
\N \NN \NNN | 8-ричные символы из OEM кодировки
\xNN | 16-ричные символы из OEM кодировки

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
  2. Если аргумент "format" не указан, то FAR будет использовать форматную строку "%a %b %d %H:%M:%S %Z %Y".

Пример

REGEDIT

;вставка текущей даты

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Common\CtrlD]
"Sequence"="$If (Editor || Dialog || Search) $Date \"%d.%m0.%Y\" Space $Else CtrlD $End"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры, date()


$Text - Макросы

$Text

главная | Макросы | Макроязык | Макрокоманды
Оператор $Text предназначена для вставки произвольного текста.
$Text "string"

Элементы

string
Вставляемый текст 'string' должен быть только в OEM-кодировке.
Допускается применение следующих escape-последовательностей:
Формат | Описание
\" | Символ '"'
\' | Символ '''
\\ | Символ '\'
\n | Переводу строки `\n'
\t | Табуляции `\t'
\a | bell
\b | `\b'
\f | `\f'
\v | `\v'
\N \NN \NNN | 8-ричные символы из OEM кодировки
\xNN | 16-ричные символы из OEM кодировки

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
  2. Макрокоманда '$Text' позволяет сократить расход памяти при хранении длинной макропоследовательности, вставляющей некоторый текст, и сделать её более наглядной.
  3. Фразу "$Text" можно не указывать, т.е. произвольный текст в двойных кавычках макродвижок воспримет как $Text. Исключение составляет ситуация, когда после двойной кавычки идет пробел - в этом случае "$Text" указывать обязательно.

Пример

REGEDIT

;создание папки с именем = текущей дате

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlShiftF7]
"Sequence"="%Folder=date(\"%d.%m0.%Y\"); $If (!panel.fexist(0,%Folder)) F7 $Text %Folder Enter $End"
"DisableOutput"=dword:00000001
"NoPluginPanels"=dword:00000001
Смотрите также:
Примеры


$IClip - Макросы

$IClip

главная | Макросы | Макроязык | Макрокоманды
Оператор $IClip позволяет организовать работу с буфером обмена.

По умолчанию FAR, в операциях запоминания/вставки данных, работает с Буфером Обмена Windows. Макрокоманда '$IClip' позволяет в пределах одного макроса переключать внутренние механизмы FAR для работы с/без использования Буфера Обмена Windows.
Работает как триггер.

$IClip

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

REGEDIT4

;искать тот же файл на другой панели что и на активной
;F5 ShiftEnter CtrlIns - применено чтобы получить имя файла вне зависимости
;пусто/непусто в cmdline и сколько выделено на панели файлов

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlAltLeft]
"Sequence"="$IClip $If (((Bof && APanel.Root) || !Bof) && PPanel.Visible)
$If (fexist(PPanel.Path+\"\\\\\"+APanel.Current) == 1) F5 ShiftEnter
CtrlIns Esc Tab Home Alt< ShiftIns Esc $End $End"
"DisableOutput"=dword:00000001

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlAltRight]
"Sequence"="$IClip $If (((Bof && APanel.Root) || !Bof) && PPanel.Visible)
$If (fexist(PPanel.Path+\"\\\\\"+APanel.Current) == 1) F5 ShiftEnter CtrlIns
Esc Tab Home Alt< ShiftIns Esc $End $End"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры, Clip, IClip


$MMode - Макросы

$MMode

главная | Макросы | Макроязык | Макрокоманды
Оператор $MMode позволяет изменять режим перерисовки экрана во время проигрывания макропоследовательности.
Работает как триггер.
$MMode 1

Параметры

1
Единственный параметр. Всегда = 1.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

REGEDIT4

;вставка текущего времени

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Common\CtrlT]
"Sequence"="$If (Editor || Dialog) $Date \"%H:%M:%S\" CtrlU Space
$Else $MMode 1 CtrlT $End"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры


$Exit - Макросы

$Exit

главная | Макросы | Макроязык | Макрокоманды
Оператор $Exit прерывает выполнение макропоследовательности.
$Exit

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

REGEDIT4

;удаление выделенных символов в командной строке

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Common\ShiftDel]
"Sequence"="$If (Qview || Shell)
$If (!APanel.Visible) ShiftDel $Exit $End CtrlO ShiftDel CtrlO
$Else ShiftDel $End"
"DisableOutput"=dword:00000001
"NotEmptyCommandLine"=dword:00000001
Смотрите также:
Примеры


$XLat - Макросы

$XLat

главная | Макросы | Макроязык | Макрокоманды
Оператор $XLat вызывает функцию транслитерации.
$XLat

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
  2. Работает независимо от того, какие клавиши назначили в TechInfo#10.

Пример

REGEDIT4

;XLAT переконвертация последнего слова

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\ShiftBS]
"Sequence"="CtrlShiftLeft $XLat CtrlRight"
"DisableOutput"=dword:00000001
"NotEmptyCommandLine"=dword:00000001
Смотрите также:
Примеры


$KbdSwitch - Макросы

$KbdSwitch

главная | Макросы | Макроязык | Макрокоманды
Оператор $KbdSwitch циклически переключает раскладку клавиатуры.
$KbdSwitch

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
Смотрите также:
Примеры


$SelWord - Макросы

$SelWord

главная | Макросы | Макроязык | Макрокоманды
Оператор $SelWord позволяет выделить слово под курсором.
$SelWord

Параметры

Нет.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
Смотрите также:
Примеры


$If - Макросы

$If

главная | Макросы | Макроязык | Макрокоманды
Условный оператор $If позволяет организовать в макросах процесс ветвления макропоследовательности.
$If (Expr) TruePart [$Else FalsePart] $End

Элементы

Expr
Выражение
TruePart
Выполняется, если выражение Expr истинно.
FalsePart
Выполняется, если выражение Expr ложно.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
  2. Часть $Else можно не указывать.

Пример

REGEDIT4

;для удобной навигации с нажатым Alt'oм

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Common\AltUp]
"Sequence"="$If (Viewer || Qview) Up $Else AltUp $End"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры


$While - Макросы

$While

главная | Макросы | Макроязык | Макрокоманды
Оператор цикла $While позволяет организовать в макросах циклический процесс - "Пока условие Expr истинно выполнять последовательность Sequence".
$While (Expr) Sequence $End

Элементы

Expr
Выражение
Sequence
Выполняется, пока условие Expr истинно.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

REGEDIT

;для перехода на просмотр файла

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\AltAdd]
"Sequence"="$While (APanel.Folder && !APanel.Eof) Down $End"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры, $Rep


$Rep - Макросы

$Rep

главная | Макросы | Макроязык | Макрокоманды
Оператор цикла $Rep позволяет организовать в макросах циклический процесс - "Выполнить Expr раз последовательность Sequence".
$Rep (Expr) Sequence $End

Элементы

Expr
Выражение, вычисляется однократно при инициализации цикла.
Sequence
Выполняется Expr раз.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

REGEDIT4

;выход из FAR'a

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Common\AltX]
"Sequence"="$If (Editor && (Editor.State & 0x8)) F2 $End
$Rep (2) $If (!Shell) Esc $End $End F10"
"DisableOutput"=dword:00000001
Смотрите также:
Примеры, , $While


Условные операторы - Макросы

Условные операторы

главная | Макросы | Макроязык

В макрокомандах $If и $While в качестве условия Expr могут использоваться операции сравнения:
Оператор | Описание
== | Равно
!= | Не равно
< | Меньше
> | Больше
<= | Меньше или равно
>= | Больше или равно

ВНИМАНИЕ! ВНИМАНИЕ!

  • Операции сравнения для строковых переменных регистрозависимые.

Булевое выражение Expr может быть сложным. В этом случае простые выражения объединяются с помощью следующих операторов:
Оператор | Описание
&& | Логическое И
|| | Логическое ИЛИ

Простые выражения могут заключаться в круглые скобки.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


Булевые состояния - Макросы

Булевые состояния

главная | Макросы | Макроязык

В операторах $If и $While допускается применять следующие ключевые слова в качестве условия (перечислены булевые операторы):
Состояние | Описание
проверка области, в которой исполняется в данный момент макропоследовательность
Shell | файловые панели
Viewer | внутренняя программа просмотра
Editor | редактор
Dialog | диалоги
Search | быстрый поиск в панелях
Disks | меню выбора дисков
MainMenu | основное меню
Menu | прочие меню
Help | система помощи
Info | информационная панель
QView | панель быстрого просмотра
Tree | панель дерева папок
FindFolder | панель поиска папок
UserMenu | пользовательское меню
Other | режим копирования текста с экрана
проверка состояний панели
APanel.Bof PPanel.Bof | текущий элемент панели в начале списка?
APanel.Eof PPanel.Eof | текущий элемент панели в конце списка?
APanel.Empty PPanel.Empty | панель пуста?
APanel.LFN PPanel.LFN | на панели "длинные имена файлов"?
APanel.Selected PPanel.Selected | на панели есть отмеченные файлы/папки?
APanel.Root PPanel.Root | на панели корневой каталог?
APanel.Visible PPanel.Visible | панель видима?
APanel.Plugin PPanel.Plugin | плагиновая панель?
APanel.Folder PPanel.Folder | текущий элемент панели - папка?
APanel.Left PPanel.Left | панель слева?
APanel.FilePanel PPanel.FilePanel | файловая панель?
проверка различных состояний командной строки
CmdLine.Bof | курсор в начале ком.строки
CmdLine.Eof | курсор в конце ком.строки
CmdLine.Empty | командная строка пуста
CmdLine.Selected | выделен блок в командной строке.
проверка различных состояний, в зависимости от контекста исполнения макроса
Bof | достигнуто начало файла в редакторе, программе просмотра; в панелях типа QView/Info/Tree - достигнуто начала файла в области просмотра, в прочих "панелях" - курсор в начале командной строки; в строках ввода в диалогах - в начале строки; в списках/меню - указатель установлен на первом пункте.
Eof | достигнут конец файла в редакторе, программе просмотра; в панелях типа QView/Info/Tree - достигнут конец файла в области просмотра, в прочих "панелях" - курсор в конце командной строки; в строках ввода в диалогах - в конце строки; в списках/меню - указатель установлен на последнем пункте
Empty | в панелях типа QView/Info/Tree - область просмотра пуста, иначе - командная строка пуста; строка ввода пуста; в редакторе/программе просмотра пустой файл; список пуст.
Selected | выделен блок в строках ввода, в редакторе или программе просмотра, в панелях типа QView/Info/Tree - выделен блок в области просмотра, в прочих "панелях" - выделен блок в командной строке (текущая область Shell).
IClip | FAR работает с внутренним буфером обмена? (см. '$IClip')
Windowed | FAR работает в оконном режиме?
проверка флагов макрокоманды
DisableOutput | запрещена перерисовка экрана?

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


Функции - Макросы

Функции

главная | Макросы | Макроязык

В макропоследовательности допускаются следующие функции:
Математические функции
Функция | Описание
N=abs(N) | Возвращает абсолютную величину числового аргумента N.
N=max(N1,N2) | Возвращает максимальное значение между двумя числовыми аргументами N1 и N2.
N=min(N1,N2) | Возвращает минимальное значение между двумя числовыми аргументами N1 и N2.
N=mod(N1,N2) | Деление N1 по модулю N2.
N=int(V) | Приведение значения выражения V к числу.
Строковые функции
Функция | Описание
N=index(S1,S2) | Если подстрока S2 содержится в строке S1, то возвращается ее позиция, иначе -1.
N=rindex(S1,S2) | Если подстрока S2 содержится в строке S1, то возвращается ее позиция, иначе -1. Поиск ведется от конца строки S1.
Result=replace(Str,Find,Replace[,Cnt]) В строке Str заменить подстроку Find на подстроку Replace Cnt раз (укажите Cnt равное 0 или опустите этот параметр для замены всех найденных подстрок).
Возвращается результат замены.
N=asc(S) | Возвращает код символа S.
S=chr(N) | Возвращает символ, заданный кодом N.
S=itoa(N[,Radix]) Конвертирует целое число N в строку. Значение Radix определяет базу, которая должна использоваться при преобразовании числа N. Допустимые значения Radix от 2 до 36.
Если параметр Radix не указан, то подразумевается база 10.
N=atoi(S[,Radix]) Конвертирует строковое представление строки N в число. Значение Radix определяет базу, которая будет использоваться при преобразовании строки S. Допустимые значения Radix от 2 до 36.
Если параметр Radix не указан, то функция попытается сама определить в каком виде представлено строковое представление числа.
N=len(V) | Возвращает длину выражения V. Числовое значение выражения V приводится к строке, после чего вычисляется длина строки).
S=string(V) | Перевод значения выражения V в строку.
S=substr(V,N1[,N2]) Возвращает подстроку из выражения V начиная с позиции N1 длинной N2.
Если параметр N2 не указан или равен -1, то вернется подстрока от позиции N1 до конца строки.
Если параметр N2 равен 0, то вернется пустая строка.
S=trim(V[,N]) | Удаляет все пробельные символы (пробелы, табуляции, переводы строк и возвраты каретки) из строки V снаружи (N=0 или не указан), слева (N=1) или справа (N=2).
S=xlat(S) Возвращает транслитерируемую строку
Функция аналогична макрокоманде $XLat, но используется в выражениях. Строковый аргумент S обязателен.
S=lcase(S) | Преобразует строку S в нижний регистр.
S=ucase(S) | Преобразует строку S в верхний регистр.
S=date(format) Возвращает текущую дату/время по формату format (описание format см. в $Date).
Функция аналогична макрокоманде $Date, но используется в выражениях. Строковый аргумент format в отличии от макрокоманды $Date обязателен.
Файловые функции
Функция | Описание
S=fsplit(path,N) Разбивает путь path на компоненты и возвращает их комбинацию, в зависимости от набора флагов N:
Флаги | Описание
0x00000001 | Текущий диск в формате "C:". Для сетевых каталогов - "\\server\share"
0x00000002 | Путь в формате "\Program Files\Far\"
0x00000004 | Имя
0x00000008 | Расширение в формате ".EXT" или пусто, если расширения нет.
N=fexist(S) Проверяет существование файла/каталога S (возвращает 0 или 1).
В параметр S допускается использование символов '*' и '?'. В этом случае функция проверяет только первое вхождение файла/каталога.
Функция не работает с панелями.
N=fattr(S) Возвращает файловые атрибуты файла/каталога S
Атрибут | Описание
0x00000001 | FILE_ATTRIBUTE_READONLY. Файл только для чтения. Приложения могут читать такой файл, но не могут записывать или удалять его.
0x00000002 | FILE_ATTRIBUTE_HIDDEN. Файл скрыт. Такой файл не включается в обычный листинг каталога.
0x00000004 | FILE_ATTRIBUTE_SYSTEM. Этот файл - часть операционной системы.
0x00000010 | FILE_ATTRIBUTE_DIRECTORY. Это каталог.
0x00000020 | FILE_ATTRIBUTE_ARCHIVE. Это архивный файл. Приложения должны использовать этот флаг для копирования, архивирования или удаления.
0x00000080 | FILE_ATTRIBUTE_NORMAL. У этого файла не установлены другие атрибуты. Это значение корректно только при использовании без остальных флагов.
0x00000100 | FILE_ATTRIBUTE_TEMPORARY. Это временный файл. Приложения должны записывать в такой файл только в крайней необходимости. Большая часть данных файла находится в памяти и не сбрасывается на диск, так как файл будет удален.
0x00000200 | FILE_ATTRIBUTE_SPARSE_FILE. Файл является т.н. "Sparse file".
0x00000400 | FILE_ATTRIBUTE_REPARSE_POINT. Каталог является символической связью.
0x00000800 | FILE_ATTRIBUTE_COMPRESSED. Файл или каталог сжат. Для файла это означает, что все данные его сжаты, для каталога - что компрессия по умолчанию применяется ко всем его файлам и подкаталогам.
0x00001000 | FILE_ATTRIBUTE_OFFLINE. Данные файла не доступны непосредственно. Означает, что реальные данные файла были физически перемещены на устройства хранения.
0x00002000 | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED. Этот файл или каталог не будут индексироваться службой индексирования.
0x00004000 | FILE_ATTRIBUTE_ENCRYPTED. Файл или каталог зашифрован. Для файла, это означает, что все данные в файле зашифрованы. Для директория, это означает, что шифрование является умолчанием для вновь созданных файлов и подкаталогов.
0x00010000 | FILE_ATTRIBUTE_VIRTUAL. Этот файл - виртуальный файл.
если файловый объект не существует, функция возвращает -1.
В параметр S допускается использование символов '*' и '?'. В этом случае функция возвращает атрибуты только для первого найденного файла/каталога.
Функция не работает с панелями.
Панель
Функция | Описание
N=panel.fexist(panelType,S) Проверяет существование файла/каталога S из активной (panelType=0) или пассивной (panelType=1) панели (возвращает 0 или 1).
В параметр S допускается использование символов '*' и '?'. В этом случае функция проверяет только первое вхождение файла/каталога.
Функция работает только с панелями.
N=panel.fattr(panelType,S) Возвращает файловые атрибуты файла/каталога S из активной (panelType=0) или пассивной (panelType=1) панели.
Атрибут | Описание
0x00000001 | FILE_ATTRIBUTE_READONLY. Файл только для чтения. Приложения могут читать такой файл, но не могут записывать или удалять его.
0x00000002 | FILE_ATTRIBUTE_HIDDEN. Файл скрыт. Такой файл не включается в обычный листинг каталога.
0x00000004 | FILE_ATTRIBUTE_SYSTEM. Этот файл - часть операционной системы.
0x00000010 | FILE_ATTRIBUTE_DIRECTORY. Это каталог.
0x00000020 | FILE_ATTRIBUTE_ARCHIVE. Это архивный файл. Приложения должны использовать этот флаг для копирования, архивирования или удаления.
0x00000080 | FILE_ATTRIBUTE_NORMAL. У этого файла не установлены другие атрибуты. Это значение корректно только при использовании без остальных флагов.
0x00000100 | FILE_ATTRIBUTE_TEMPORARY. Это временный файл. Приложения должны записывать в такой файл только в крайней необходимости. Большая часть данных файла находится в памяти и не сбрасывается на диск, так как файл будет удален.
0x00000200 | FILE_ATTRIBUTE_SPARSE_FILE. Файл является т.н. "Sparse file".
0x00000400 | FILE_ATTRIBUTE_REPARSE_POINT. Каталог является символической связью.
0x00000800 | FILE_ATTRIBUTE_COMPRESSED. Файл или каталог сжат. Для файла это означает, что все данные его сжаты, для каталога - что компрессия по умолчанию применяется ко всем его файлам и подкаталогам.
0x00001000 | FILE_ATTRIBUTE_OFFLINE. Данные файла не доступны непосредственно. Означает, что реальные данные файла были физически перемещены на устройства хранения.
0x00002000 | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED. Этот файл или каталог не будут индексироваться службой индексирования.
0x00004000 | FILE_ATTRIBUTE_ENCRYPTED. Файл или каталог зашифрован. Для файла, это означает, что все данные в файле зашифрованы. Для директория, это означает, что шифрование является умолчанием для вновь созданных файлов и подкаталогов.
0x00010000 | FILE_ATTRIBUTE_VIRTUAL. Этот файл - виртуальный файл.
если файловый объект не существует, функция возвращает -1.
В параметр S допускается использование символов '*' и '?'. В этом случае функция возвращает атрибуты только для первого найденного файла/каталога.
Функция работает только с панелями.
V=panelitem(panelType,itemIndex,propIndex) Возвращает различную информацию для элемента панели itemIndex (начиная с 1) из активной (panelType=0) или пассивной (panelType=1) панели. propIndex может быть одним из следующих значений:
Значение | Тип | Описание
0 | String | Имя файла/каталога
1 | String | Короткое имя
2 | Number | Файловые атрибуты
3 | String | Дата/время создания
4 | String | Дата/время последнего доступа
5 | String | Дата/время модификации
6 | Number | Размер
7 | Number | Упакованный размер
8 | Number | "Выделен?"
9 | Number | Количество линков
10 | Number | SortGroup
11 | String | Diz-текст
12 | String | Владелец
13 | Number | CRC32
14 | Number | Позиция элемента в процессе чтения файловой системы
Для панели "Дерево папок" возвращается только имя файла (propIndex=0), остальные значения propIndex игнорируются.
Дата/время возвращается в формате DD.MM.YYYY HH:MM:SS. Разделители и порядок в дате зависят от региональных настроек.
Для получения данных о текущем файле (под курсором) itemIndex должен быть равен 0.
N=panel.setpos(panelType,fileName) Позиционирует курсор на элемент с именем fileName на активной (panelType=0) или пассивной (panelType=1) панели.
Возвращает позицию элемента или 0, если такого элемента на панели нет.
Например, создать каталог с именем, соответствующим текущей дате в формате YYYYMMDD, если каталог существует - позиционировать на него курсор:
%dt=date("%Y%m0%d");
$If (fexist(%dt))
  panel.SetPos(0,%dt)
$Else
  F7 $Text %dt Enter
$End
N=panel.setpath(panelType,pathName[,fileName]) На активной (panelType=0) или пассивной (panelType=1) панели выставляет каталог pathName и позиционирует курсор на элемент с именем fileName (если указан параметр fileName).
Возвращает 1 в случае успешной установки каталога и 0, если каталог не существует.
Например, на активной панели выставить каталог "C:\WINDOWS", на пассивной - "C:\Program Files", активную панель сделать слева и установить курсор на каталог "FAR":
$if(APanel.Left) CtrlU $End
panel.SetPath(1,"C:\\WINDOWS")
panel.SetPath(0,"C:\\Program Files","FAR")
N=panel.setposidx(panelType,indexItem) Позиционирует курсор на элемент с индексом indexItem на активной (panelType=0) или пассивной (panelType=1) панели.
Возвращает позицию элемента или 0, если такого элемента на панели нет.
Управляющие функции
Функция | Описание
V=iif(Cond,True,False) | Условный оператор. Если условие Cond верно, то возвращается True-выражение, иначе False-выражение.
Среда исполнения
Функция | Описание
S=env(V) Возвращает значение переменной среды V, например,
$if (Env("FARLANG") == "English") что-то делаем $end
B=msave(S) Сохраняет значение глобальной переменной с именем S в область Vars. В случае неудачи возвращает 0.
Например,
%%GlobalVars="Foo Bar"; %a=msave("%%GlobalVars");
V=akey(N) Возвращает название или код клавиши, вызвавшей макропоследовательность. N = 0 - возвращается код клавиши, N = 1 - возвращается наименование клавиши.
Пример см. в описании $AKey
V=clip(Cmd[,S]) Позволяет производить разнообразные манипуляции с Clipboard в зависимости от команды Cmd:
Cmd | Описание
0 | Возвращает данные из Clipboard; параметр S игнорируется; в случае ошибки возвращает 0
1 | Поместить строку S в Clipboard; в случае ошибки возвращает 0
2 | Добавить строку S к Clipboard; в случае ошибки возвращает 0
3 | Копировать Windows Clipboard во внутренний буфер обмена; параметр S игнорируется; в случае ошибки возвращает 0
4 | Копировать внутренний буфер обмена в Windows Clipboard; параметр S игнорируется; в случае ошибки возвращает 0
Например, поместить в Clipboard список отмеченных файлов в формате CSV (имя и размер):
Clip(1,"Name;Size\r\n")
Home
$While(!APanel.Eof)
  $If(!APanel.Folder && PanelItem(0,0,8))
     Clip(2,PanelItem(0,0,0)+";"+PanelItem(0,0,6)+"\r\n")
  $End
  Down
$End
См. так же $IClip, IClip.
V=flock(Nkey,NState) Позволяет переключить состояние Lock-клавиш (NumLock, CapsLock и ScrollLock).
Клавиша Nkey:
Nkey | Описание
0 | NumLock
1 | CapsLock
2 | ScrollLock
Состояние NState:
NState | Описание
-1 | получить состояние клавиши
0 | погасить индикатор
1 | включить индикатор
2 | переключить индикатор в противоположное состояние
В Windows 95/98/Me функция может изменять только состояние клавиш CapsLock и ScrollLock. Для линейки NT (NT/2000/XP/...) этого ограничения нет.
Функция капризная (возможно зависание компьютера), поэтому пользоваться ей надо осторожно. Например, макрос, повешенный на CtrlCapsLock (переключение между окнами) должен иметь некую обвязку:
CtrlShiftTab
%a=flock(1,-1)&1;
$while((flock(1,-1)&1)==%a)
  sleep(50)
  flock(1,2)
$end
N=sleep(N) Организация задержки в макросе на N миллисекунд. Отрицательное значение задержки считается ошибкой и функция возвращает 0.
V=waitkey([N, [T]]) Ожидает любую клавишу и возвращает ее название (T=0) или значение (T=1). Если время ожидания N (миллисекунды) истекло, функция возвращает пустую строку (T=0) или 0 (T=1). Если параметр N не указан или равен 0, то функция будет бесконечно ждать нажатия клавиши.
S=key(V) Преобразует параметр V в строковый эквивалент названия клавиши.
Если V строка, то проверяется правильность написания клавиши и она же возвращается, если V число, то происходит попытка преобразовать значение в текстовый эквивалент названия клавиши.
В случае ошибок - возвращается пустая строка.
N=eval(S[,T]) "Проиграть" (T=0) или проверить (T=1) макропоследовательность заданную строкой S. Если S содержит синтаксические ошибки, то макропоследовательность исполняться не будет.
FAR компилирует последовательность S.
Для режима исполнения (T=0): если нет ошибок, то состояние текущего макроса сохраняется и начинает выполняться последовательность S. После исполнения S прерванный макрос продолжает работать.

Функция возвращает 0 в случае успешной компиляции последовательности S или код ошибки:
Error | Описание
1 | Неизвестное ключевое слово 'ключевое слово'
2 | Неизвестная функция 'функция'
3 | Неверное количество параметров у функции 'функция'
4 | Неожиданное появление $Else
5 | Неожиданное появление $End
6 | Неожиданный конец строки
7 | Ожидается 'ключевое слово'
8 | Неизвестный шестнадцатеричный управляющий символ
9 | Неправильный управляющий символ
10 | Переменная 'переменная' не найдена
11 | Ошибка синтаксиса
12 | Пустая макропоследовательность

Локальные переменные - общие для текущего исполняемого макроса и макропоследовательности, исполняемой функцией eval.

Например, необходимо по F10 запускать окно проводника для каталога на активной панели, содержимое командной строки должно сохраняться.
В области Vars задаем 2 строковых переменных макропроцедуры, описывающие сохранение и восстановление содержимое командной строки:

%%CmdSave=$If (!CmdLine.Empty) %Flg_Cmd=1;
          %CmdCurPos=CmdLine.ItemCount-CmdLine.CurPos+1;
          %CmdVal=CmdLine.Value; Esc $End

%%CmdRestore=$If (%Flg_Cmd==1) $Text %CmdVal
          %Flg_Cmd=0; %Num=%CmdCurPos;
          $While (%Num!=0) %Num=%Num-1; CtrlS $End $End
далее на F10 вешаем макрос:
$If (APanel.Visible && (!APanel.Plugin || (!APanel.Bof &&(APanel.OPIFlags & 0x20))))
  Eval(%%CmdSave)
  $If (APanel.Current == "..")
    .
    ShiftEnter
  $Else
    "%SystemRoot%\\explorer.exe /select,"
    $If (Apanel.LFN)
      CtrlN
    $End
    CtrlEnter
    $If (!Apanel.LFN)
      CtrlN
    $End
    Enter
  $End
  Eval(%%CmdRestore)
$End
Взаимодействие с пользователем
Функция | Описание
N=msgbox([Title[,Text[,Flags]]]) Показывает сообщение Text с заголовком Title. В параметре Text строки разбиваются символом '\n'.
Flags может быть набором следующих значений:
Flags | Описание
0x00000001 | Используются цвета "Предупреждения" (обычно белые буквы на красном фоне).
0x00000008 | Показать сообщение двумя строками ниже.
0x00000010 | Использовать для строк сообщения выравнивание влево (по умолчанию строки выводятся по центру).
0x00010000 | Выводится кнопка <Ok>
0x00020000 | Выводятся кнопки <Ok> и <Cancel>
0x00030000 | Выводятся кнопки <Abort>, <Retry> и <Ignore>
0x00040000 | Выводятся кнопки <Yes> и <No>
0x00050000 | Выводятся кнопки <Yes>, <No> и <Cancel>
0x00060000 | Выводятся кнопки <Retry> и <Cancel>
Если параметр Flags равен 0 (или не указан), то выводится стандартный диалог с кнопкой <Ok>
Функция возвращает 0, если пользователь отменил сообщение или выбранный номер кнопки (для первой кнопки - 1, для второй - 2 и так далее).
S=prompt("Title"[,"Prompt"[,flags[, "Src"[, "History"]]]]) Функция позволяет ввести одну строку текста.
Параметры: Title - заголовок диалога, Prompt - приглашения для ввода, Src - начальное значение строки ввода, History - имя истории ввода
Flags может быть набором следующих значений (аналогичным константам FIB_*):
Flags | Описание
0x00000001 | даже если строка ввода пуста функция вернет значение пустое значение.
0x00000002 | используется для ввода пароля - вводимый текст на экране отрисовывается символами '*'.
0x00000004 | после успешного ввода, в результирующем значении S идентификаторы переменных окружения заменяются на их значения, например, если пользователь ввел '%TEMP%', то DestText будет содержать 'C:\TEMP'.
0x00000008 | не использовать предыдущее значение из истории, оставить строку ввода пустой; актуален, если указан непустой параметр History.
0x00000010 | показать разделительную линию и кнопки [Ok] и [Cancel]. Диалог увеличится на 2 строки.
0x00000020 | не показывать в приглашении ввода амперсанд, использовать его для определения горячей клавиши.
Функция возвращает строку - введенное пользователем значение.
Например, запросить пароль и вывести его
%s=prompt("Password","Input password:",0x02); $Text %s
Элементы управления
Функция | Описание
N=checkhotkey(S[,Pos]) Функция позволяет проверить и получить позицию элемента (начиная с Pos), который содержит горячую клавишу S. Если S - пустая строка, то функция вернет позицию элемента, который не содержит ни одной горячей клавиши.
Возвращает: -1 - если функция вызывана не из своей области (MainMenu, Menu, Disks, UserMenu и Dialog), 0 - ничего не найдено, > 0 - если в меню/диалоге/списке присутствует горячая клавиша S.

Например, в меню вызова плагинов (F11) плагину S&R назначена горячая клавиша '7'. Последовательность макрокоманды для редактора:

F11 $if (checkhotkey("7")) 7 1 $else Esc AltF7 $end
вызовет плагин, если хоткей назначен или стандартный диалог поиска, если хоткей не назначен.
S=gethotkey(N) Возвращает хоткей S для пункта N, если в меню присутствует горячая клавиша и текущий "объект" - меню. В противном случае (не меню; нет хоткея; N больше чем количество пунктов меню) возвращает 0.
Здесь N - позиция в списке от 1 (0 - текущая).
N=Menu.Select(S[,N]) В меню позиционирует курсор на первый пункт, содержащий подстроку S. Поиск подстроки ведется в зависимости от указанного режима N:
Режим | Описание
0 | полное совпадение
1 | совпадение с началом строки
2 | совпадение с концом строки
3 | присутствие подстроки S в пункте меню
Поиск регистронезависим. Если такого пункта нет, то ничего не делает.
Возвращает: -1=ошибка - функция вызвана не для меню, 0=ошибка при позиционировании (нет пункта или пункт задисаблен), иначе - позицию пункта меню.
F11 $if(Menu.Select("Advanced compare",0) > 0) Enter $end
Если параметр N не указан, подразумевается полное совпадение.
V=Dlg.GetValue(ID,Type) Получить различные значения текущего диалога.
ID - номер элемента диалога (элементы нумеруются с 1; 0 - само диалоговое окно).
Type - тип получаемой информации, зависит от типа элемента. Для самого диалога (ID=0) допустимы следующие значения:
Type | Тип Var | Описание
0 | Number | Количество элементов диалога
2 | Number | X1
3 | Number | Y1
4 | Number | X2
5 | Number | Y2
6 | Number | ID текущего элемента, имеющего клавиатурный фокус ввода
Для элементов диалога допустимы:
Type | Тип Var | Элемент | Описание
0 | Number | CheckBox | Состояние переключателя
0 | Number | RadioButtons | Состояние переключателя
0 | String | ListBox | Значение текущего элемента списка
0 | String | ComboBox | Значение текущего элемента списка
0 | String | Остальные | Текстовое значение (поле FarDialogItem.Data)
1 | Number | Все | Тип элемента
2 | Number | Все | X1 относительно диалога
3 | Number | Все | Y1 относительно диалога
4 | Number | Все | X2 относительно диалога
5 | Number | Все | Y2 относительно диалога
6 | Number | Все | элемент в фокусе?
7 | Number | CheckBox | Состояние переключателя
7 | Number | RadioButtons | Состояние переключателя
7 | String | ListBox | Текущая позиция в списке (первый пункт списка = 1)
7 | String | ComboBox | Текущая позиция в списке (первый пункт списка = 1)
7 | Number | Остальные | 0
8 | Number | Все | Флаги элемента
9 | Number | Все | Флаг, означающий, что данный элемент диалога является "элементом по умолчанию".
10 | String | Остальные | Текстовое значение (поле FarDialogItem.Data)
Возвращает -1, если ID больше количества элементов диалога или значение Type не поддерживается.
V=Editor.Set(Idx,Var) Для текущей копии редактора изменить настройки.
Index | Тип Var | Описание
0 | Number | Размер табуляции
1 | Number | Преобразование табуляции
2 | Number | Постоянные блоки
3 | Number | Del удаляет блоки
4 | Number | Автоотступ
5 | Number | Автоопределение таблицы символов
6 | Number | AnsiTableForNewFile
7 | Number | Курсор за пределами строки
8 | Number | поведением клавиши BackSpace (TechInfo #13)
9 | Number | Представление кода символа под курсором в статусной строке (TechInfo #32)
10 | Number | Сохранять позицию файла
11 | Number | Сохранять закладки
12 | String | Символы разделители слов (TechInfo #1)
13 | Number | EditorF7Rules (TechInfo #18)
14 | Number | AllowEmptySpaceAfterEof (TechInfo #67)
Значение Var может быть равно -1, в этом случае функция ничего не изменит, а вернет текущее значение настройки.
Возвращает предыдущее значение опций или -1, если данные указаны некорректно.
Например, макрос, перемещающий выделенный фрагмент на одну строку вниз:
$IClip CtrlX %a=Editor.Set(2,1); Down CtrlV %a=Editor.Set(2,%a);
V=Editor.Sel(Action[,Opt]) Функция позволяет производить некоторые операции с блоками в тексте (в редакторе, в строках ввода в диалогах, в командной строке).
Action Описание
0 получить параметры текущего блока
Opt | Описание
0 | вернуть номер строки начала блока
1 | вернуть номер позиции в строке начала блока
2 | вернуть номер строки конца блока
3 | вернуть номер позиции в строке конца блока
4 | вернуть тип выделенного блока: 0 - блок не выделен, 1 - обычный блок, 2 - вертикальный блок (альтернативный вариант - Editor.State)
1 позиционировать курсор внутри текущего блока (при позиционировании курсора состояние блока не изменяется)
Opt | Описание
0 | установить курсор в начало отмеченного блока
1 | установить курсор в конец отмеченного блока
2 установка позиций блока
Opt | Описание
0 | отметить позицию начала блока
1 | отметить позицию конца блока
Позицией начала/конца блока считается текущая позиция курсора. Блок помечается только после указания конечной позиции (Opt=1), с ранее выделенного блока пометка снимается. Если позиция начала и конца блока совпадают, то эта операция равносильна снятию пометки блока.
3 установка позиций вертикального блока
Opt | Описание
0 | отметить позицию начала вертикального блока
1 | отметить позицию конца вертикального блока
Позицией начала/конца блока считается текущая позиция курсора. Блок помечается только после указания конечной позиции (Opt=1), с ранее выделенного блока пометка снимается. Если позиция начала и конца блока совпадают, то эта операция равносильна снятию пометки блока.
4 снять выделение с блока
Параметр Opt игнорируется.
Всегда возвращается 1
В случае ошибки (в т.ч. функция вызвана не из "редактора") возвращаемое значение равно 0, иначе 1. Для Action=0 возвращается запрошенное значение.
Например, повторим некоторые сочетания клавиш из Turbo-сред (макрос на сочетание Ctrl-K):
%k=waitkey(0,1);
$if(%k==B || %k==b || %k==CtrlB)
  editor.sel(2,0)
$else
  $if(%k==K || %k==k || %k==CtrlK)
    editor.sel(2,1)
  $else
    $if((%k==C || %k==c || %k==CtrlC) && Selected)
      CtrlC
    $else
      $if((%k==Y || %k==y || %k==CtrlY) && Selected)
        CtrlD
      $else
        eval("F1")
      $end
    $end
  $end
$end
Работа с закладками
Функция | Описание
N=BM.Add() | Добавить текущие параметры закладки и обрезать хвост
N=BM.Clear() | Очистить все закладки
N=BM.Del([Idx]) | Удалить закладку с указанным индексом Idx (нумерация начинается с 1). Если параметр Idx не указан или равен 0 - удаляется текущая закладка.
N=BM.Get(Idx,M) Получить параметры закладки с индексом Idx (нумерация начинается с 1), Idx=0 - текущая закладка.
Параметр M может быть одним из следующих:
Тип | Описание
0 | координаты строки (начиная с 1)
1 | координаты колонки (начиная с 1)
2 | позиция, соответствующая первому видимому символу текста на экране слева
3 | номер строки, соответствующей первой видимой строке текста на экране
N=BM.Next() | Перейти на следующую закладку
N=BM.Prev() | Перейти на предыдущую закладку
N=BM.Stat([M]) Получить информацию о закладках.
Параметр M может быть одним из следующих:
Тип | Описание
0 | текущее количество закладок
Пример работы с закладками:

Замечания

  1. Функции работы с закладками BM.XXX() доступны только в редакторе.
  2. Параметры функций, обозначенные в квадратных скобках можно не указывать. Значение по умолчанию см. в описаниях функций.
  3. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


Операции - Макросы

Операции

главная | Макросы | Макроязык

Над переменными можно производить следующие операции:
Операция | Описание
+ | Числовое сложение или сцепление строк
- | Числовое вычитание или унарный минус
* | Числовое умножение
/ | Числовое деление. FAR прерывает исполнение макроса, если происходит деление на 0
& | Битовое умножение
^ | Битовое Исключающее ИЛИ (XOR)
| | Битовое сложение
<< | Битовый сдвиг влево
>> | Битовый сдвиг вправо
! | Логическое отрицание
~ | Битовое отрицание

Приоритеты операций в выражениях:
Операция | Описание
! ~ - | Унарные (R->L)
* / | арифметические
+ - | арифметические
<< >> | Битовый сдвиг
< <= > => | Логическое сравнение
== != | Логическое сравнение
& | Битовая (and)
^ | Битовая (xor)
| | Битовая (or)
&& | Логическая
|| | Логическая

Замечания

  1. Именованные клавиши (например, CtrlK) могут участвовать в любых выражениях; в этом случае они считаются как числа.
  2. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


Состояния - Макросы

Состояния

главная | Макросы | Макроязык
Панели
Оператор | Тип | Описание
APanel.ItemCount
PPanel.ItemCount 		Number содержит количество файловых объектов на панели
APanel.SelCount
PPanel.SelCount 		Number содержит количество выделенных файлов на панели (число)
APanel.CurPos
PPanel.CurPos 		Number содержит порядковый номер файлового объекта на панели
APanel.Current
PPanel.Current 		String содержит имя файла под курсором (строка)
APanel.Path
PPanel.Path 		String содержит путь панели (без заключительного '\')
APanel.UNCPath
PPanel.UNCPath 		String содержит UNC-путь панели (без заключительного '\')
APanel.Width
PPanel.Width 		Number содержит ширину панели
APanel.Type
PPanel.Type 		Number содержит тип панели:
Значение | Описание
0 | Файловая панель
1 | Дерево папок
2 | Панель быстрого просмотра
3 | Информационная панель
APanel.DriveType
PPanel.DriveType 		Number содержит тип привода на панели:
Значение | Описание
-1 | Плагиновая панель
0 | Не удалось определить тип привода
2 | Сменный привод
3 | Жесткий диск
4 | Сетевой подмапленный диск
5 | CDROM
6 | Виртуальный диск
15 | SUBST-диск
APanel.OPIFlags
PPanel.OPIFlags 		Number комбинация следующих значений плагиновой панели (если панель не плагиновая, то значение будет = 0):
Значение | Описание
0x00000001 | используется фильтр на панели
0x00000002 | используются группы сортировки на панели
0x00000004 | используется раскраска файлов на панели
0x00000010 | папки на панели плагина выбираются независимо от настроек FAR
0x00000020 | используется стандартная обработка файла FAR'ом, если запрошенная операция не поддерживается плагином; если этот флаг указан, элементы на панели плагина являются именами реальных файлов
0x00000040 | показаны имена без путей
0x00000080 | имена файлов выровнены по правому краю
0x00000100 | имена файлов показаны в оригинальном регистре (независимо от настроек FAR)
APanel.ColumnCount
PPanel.ColumnCount 		Number количество колонок на панели
Диалоги
Dlg.ItemCount | Number | количество элементов диалога
Dlg.CurPos | Number | номер текущего фокусного элемента диалога
Dlg.ItemType Number тип фокусного элемента диалога
Значение | Описание
-1 | ошибка, например, Dlg.ItemType вызван не в диалоге
4 | Поле ввода
5 | Поле ввода пароля
6 | Поле ввода фиксированного размера
7 | Кнопка (Push Button)
8 | Контрольный переключатель (Check Box)
9 | Селекторная кнопка (Radio Button)
10 | Комбинированный список
11 | Окно списка
255 | Элемент управления, определяемый программистом
0x8004 | Выбор из истории поля ввода
0x800A | Выбор из комбинированного списка
Командная строка
CmdLine.ItemCount | Number | количество символов в командной строке
CmdLine.CurPos | Number | текущая позиция курсора в командной строке
CmdLine.Value | String | содержимое командной строки
Редактор
Editor.FileName | String | полное имя редактируемого файла
Editor.CurLine | Number | номер текущей линии в редакторе (первая строка равна 1)
Editor.CurPos | Number | текущая позиция курсора в строке в редакторе (начало строки равно 1); учитывается размер табуляции
Editor.RealPos | Number | текущая позиция курсора в строке в редакторе без привязки к размеру табуляции (начало строки равно 1)
Editor.Value Value содержимое текущей строки в редакторе под курсором.
Например, показать текущий символ под курсором
MsgBox(substr(Editor.Value,Editor.CurPos-1,1),Editor.FileName,0)
Editor.Lines | Number | количество строк в редакторе
Editor.State Number различные состояния текущего редактора - набор битовых флагов:
Значение | Описание
0x00000001 | файл совершенно новый либо его успели удалить
0x00000002 | разрешено переключение на программу просмотра по F6
0x00000004 | после закрытия редактора удалить файл
0x00000008 | редактируемый файл модифицирован (в статусной строке редактора присутствует символ '*')
0x00000010 | в наличии есть выделенный поточный блок (альтернативный вариант Editor.Sel(0,4))
0x00000020 | в наличии есть выделенный вертикальный блок (альтернативный вариант Editor.Sel(0,4))
0x00000040 | редактируемый файл изменялся в сеансе редактирования
0x00000080 | курсор в режиме замены
0x00000100 | позиция курсора была изменена плагином
0x00000200 | редактор заблокирован (ReadOnly)
0x00000400 | используются постоянные блоки
0x00000800 | модальный редактор
0x08000000 | FAR запущен с ключами /e
Например,
$If (Editor.State & 0x8) выполнить действия, если файл модифицирован $End
Программа просмотра
Viewer.FileName | String | полное имя просматриваемого файла
Viewer.State Number различные состояния текущей программы просмотра - набор битовых флагов:
Значение | Описание
0x00000001 | включено автоопределение таблицы символов
0x00000002 | не используются таблицы символов и текст в кодировке ANSI
0x00000004 | режим Unicode
0x00000008 | включен перенос строк
0x00000010 | используется перенос строк по словам, а не по буквам
0x00000020 | выставлен 16-ричный режим
0x00000800 | модальный вьювер
0x08000000 | FAR запущен с ключами /v
Например,
$If (Viewer.State & 0x20) выполнить действия, если выставлен 16-ричный режим $End
Меню выбора дисков
Drv.ShowPos | Number | для левой (AltF1, значение 1) или правой (AltF2, значение 2) панели вызвано меню выбора дисков.
Drv.ShowMode Number флаги отображения меню выбора дисков; набор битовых флагов:
Значение | Описание
0x00000001 | включен показ типа дисков
0x00000002 | включен показ сетевого имени (и путь, ассоциированный с SUBST-диском под NT)
0x00000004 | включен показ метки диска
0x00000008 | включен показ типа файловой системы
0x00000010 | включен показ общего и свободного места на диске
0x00000020 | включен показ параметров сменных дисков
0x00000040 | включен показ имен подключаемых модулей
0x00000080 | включен показ параметров компакт-дисков
0x00000100 | включен показ общего и свободного места на диске в стиле Windows Explorer
0x00000200 | включен показ параметров для сетевых дисков
Прочее
MacroArea | String | наименование текущей макрообласти исполнения
ItemCount | Number | число элементов в текущем объекте; в меню разделительная черта тоже учитывается
CurPos | Number | позиция в текущем объекте
Title | String | заголовок текущего объекта
Far.Width | Number | ширина консоли, в которой работает FAR Manager
Far.Height | Number | высота консоли, в которой работает FAR Manager
Far.Title | String | текущий заголовок консольного окна FAR
Help.FileName | String | полный путь просматриваемого файла помощи; для списка помощи по внешним модулям (Shift-F2) это значение пусто
Help.Topic | String | идентификатор просматриваемой темы (без ведущего символа '@')
Help.SelTopic | String | идентификатор выделенного топика (без ведущего символа '@')
MsX | Number | Координата горизонтального положения курсора мыши с момента последнего поступления мышиного события
MsY | Number | Координата вертикального положения курсора мыши с момента последнего поступления мышиного события
MsButton Number Состояние клавиш мыши. Младший бит соответствует самой левой кнопке, следующий - самой правой, Следующий бит - следующая за левой клавиша. Далее биты соответствуют клавишам слева направо. Если бит установлен - клавиша нажата.
Определены следующие константы для первых пяти клавиш мыши:
Значение | Описание
0x0001 | FROM_LEFT_1ST_BUTTON_PRESSED
0x0002 | RIGHTMOST_BUTTON_PRESSED
0x0004 | FROM_LEFT_2ND_BUTTON_PRESSED
0x0008 | FROM_LEFT_3RD_BUTTON_PRESSED
0x0010 | FROM_LEFT_4TH_BUTTON_PRESSED
MsCtrlState Number Состояние управляющих клавиш. Может быть комбинацией следующих значений:
Значение | Описание
0x0001 | RIGHT_ALT_PRESSED
0x0002 | LEFT_ALT_PRESSED
0x0004 | RIGHT_CTRL_PRESSED
0x0008 | LEFT_CTRL_PRESSED
0x0010 | SHIFT_PRESSED
0x0020 | NUMLOCK_ON
0x0040 | SCROLLLOCK_ON
0x0080 | CAPSLOCK_ON
0x0100 | ENHANCED_KEY

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.


Переменные - Макросы

Переменные

главная | Макросы | Макроязык
Переменные позволяют вам задавать имена значениям и обращаться к ним позже. В макропоследовательности можно применять локальные и глобальные переменные.

Именование

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

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

Имена регистронезависимые: '%myStr' и '%MYstr' - одна и та же переменная.

Присвоение значения переменной должно заканчиваться символом ';'

Типы

Переменные могут быть двух типов - целое число или строка.

Целочисленные константы: NNN - 10-ричная константа, 0NNN - 8-ричная константа, 0xNNN - 16-ричная константа.

Целочисленные константы 64-разрядные.

Область действия

Область действия локальной переменной - текущая макропоследовательность.

Область действия глобальной переменной - текущий сеанс FAR. Глобальные переменные можно записывать в специальную область Vars. Из этой области FAR считывает глобальные переменные при старте.

Представления в реестре

В реестре глобальные переменные располагаются в специальной ветке [HKEY_CURRENT_USER\Software\Far\[Users\USERNAME\]KeyMacros\Vars].

Каждая глобальная переменная имеет имя и может быть трех типов REG_SZ (для строковых переменных) и REG_DWORD или REG_QDWORD (для целочисленных переменных). Если изначально переменная имела тип REG_DWORD, то при сохранении с помощью функции msave тип меняется на REG_QDWORD.

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.
Смотрите также:
msave()


Технические подробности - Макросы

Технические подробности

главная | Макросы

Хранение макросов

Все макрокоманды хранятся в ветке реестра [HKEY_CURRENT_USER\Software\Far\[Users\USERNAME\]KeyMacros] в текстовом виде.

Макрокоманды делятся на 16 областей действий (см. Области действия) и 2 области для хранения глобальных переменных и констант. Имя области соответствует ветке реестра:
Область | Назначение
"Shell" | Файловые панели
"Viewer" | Внутренняя программа просмотра
"Editor" | Редактор
"Dialog" | Диалоги
"Search" | Быстрый поиск в панелях
"Disks" | Меню выбора дисков
"MainMenu" | Основное меню
"Menu" | Прочие меню
"Help" | Система помощи
"Info" | Информационная панель
"QView" | Панель быстрого просмотра
"Tree" | Панель дерева папок
"FindFolder" | Панель поиска папок
"UserMenu" | Пользовательское меню
"Other" | Режим копирования текста с экрана
"Common" | Макросы из этой области работают везде. FAR просматривает эту область последней.
"Vars" | Область для глобальных переменных, которые FAR считывает при старте. Переменные могут быть двух типов - строковые (типа REG_SZ) и числовые (типа REG_QWORD). В эту область можно писать с помощью функции msave()
"Consts" | Область для глобальных констант, которые FAR считывает при старте. Константы могут быть двух типов - строковые (типа REG_SZ) и числовые (типа REG_QWORD).

В областях на каждую макрокоманду в реестре заводится отдельная ветвь с именем назначенной клавиши. Макрокоманда описывается определенным набором значений:
Имя | Тип | Default | Описание
Sequence | REG_SZ REG_MULTI_SZ |  | Последовательность клавиш.
DisableOutput | REG_DWORD | 0 | Запретить на время выполнения вывод на экран. При записи нового макроса значение этого параметра выставляется в 1 (запретить вывод на экран). Если параметр отсутствует, то вывод на экран во время исполнения макроса разрешен.
RunAfterFARStart | REG_DWORD | 0 | Выполнять после запуска FAR. Флаг актуален только для макросов, стартующих в области Shell.
EmptyCommandLine | REG_DWORD | 0 | Выполнять, только если командная строка пуста
NotEmptyCommandLine | REG_DWORD | 0 | Выполнять, только если командная строка не пуста
NoFilePanels | REG_DWORD | 0 | Не выполнять для файловой панели
NoFilePPanels | REG_DWORD | 0 | Не выполнять если пассивная панель - файловая
NoPluginPanels | REG_DWORD | 0 | Не выполнять для плагиновой панели
NoPluginPPanels | REG_DWORD | 0 | Не выполнять если пассивная панель - плагиновая
NoFolders | REG_DWORD | 0 | Не выполнять если текущий элемент - папка
NoPFolders | REG_DWORD | 0 | Не выполнять если текущий элемент - папка (пассивная панель)
NoFiles | REG_DWORD | 0 | Не выполнять если текущий элемент - файл
NoPFiles | REG_DWORD | 0 | Не выполнять если текущий элемент - файл (пассивная панель)
Selection | REG_DWORD | 0 | Выполнять, только если на панели есть отмеченные файлы/папки
PSelection | REG_DWORD | 0 | Выполнять, только если на панели есть отмеченные файлы/папки (пассивная панель)
NoSelection | REG_DWORD | 0 | Выполнять, если нет отмеченных файлов/папок (пассивная панель)
NoPSelection | REG_DWORD | 0 | Выполнять, если нет отмеченных файлов/папок (пассивная панель)
EVSelection | REG_DWORD | 0 | Выполнять, если отмечен блок в редакторе, программе просмотра, в строках ввода в диалогах.
NoEVSelection | REG_DWORD | 0 | Выполнять, если не отмечен блок в редакторе, программе просмотра, в строках ввода в диалогах.
NoSendKeysToPlugins | REG_DWORD | 0 | Специальный режим: нажимаемые клавиши при записи и воспроизведении не будут передаваться плагинам.
Description | REG_SZ |  | Комментарий (не используется)

Обязательным является параметр "Sequence", остальные могут отсутствовать и принимать значение по умолчанию.

Последовательность "Sequence" содержит строковое представление макрокоманды. Каждая клавиша имеет свой строковый эквивалент, разделителем клавиш является пробел или табуляция.

При старте FAR компилирует последовательность "Sequence" во внутренний байткод. Если в процессе компиляции обнаружена ошибка, то макрос "отбрасывается"

Условия запуска макроса

Перед исполнением макроса FAR проверяет условия запуска в следующей последовательности:

  1. NoSendKeysToPlugins
  2. EmptyCommandLine + NotEmptyCommandLine
  3. NoFilePanels + NoPluginPanels
  4. NoFilePPanels + NoPluginPPanels
  5. NoFolders + NoFiles
  6. NoPFolders + NoPFiles
  7. Selection + NoSelection (если не в Viewer, Editor и Dialog)
  8. PSelection + NoPSelection (если не в Viewer, Editor и Dialog)
  9. EVSelection + NoEVSelection (если в Viewer, Editor и Dialog)
Смотрите также:
Общие сведения, Работа с макросами, Макроязык, Примеры


Примеры - Макросы

Примеры

главная | Макросы

REGEDIT4

; переход в меню выбора дисков на противоположной панели
; включение видимости панели в которой будет происходить смена диска, если её не было

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Disks\Tab]
"Sequence"="Esc $If (!PPanel.Visible) $If (APanel.Left) CtrlF2 $Else CtrlF1 $End $End Tab F9 Enter End Enter"
"DisableOutput"=dword:00000001
REGEDIT4

;выделить/(снять выделение) слово(а) под курсором

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Editor\RAlt]
"Sequence"="RCtrl9 CtrlRight CtrlLeft $If (!Selected) CtrlShiftRight $Else CtrlU $End Ctrl9"
"DisableOutput"=dword:00000001
REGEDIT4

;создание папки с именем = текущей дате

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlShiftF7]
"Sequence"="%folder=date(\"%d.%m0.%Y\"); $If (!panel.fexist(0,%folder)) F7 CtrlY $Text %folder Enter $End"
"DisableOutput"=dword:00000001
"NoPluginPanels"=dword:00000001
REGEDIT4

;искать тот же файл на другой панели что и на активной
;F5 ShiftEnter CtrlIns - применено чтобы получить имя файла вне зависимости
;пусто/непусто в cmdline и сколько выделено на панели файлов

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlAltLeft]
"Sequence"="$IClip $If (((Bof && APanel.Root) || !Bof) && PPanel.Visible)
$If (fexist(PPanel.Path+\"\\\\\"+APanel.Current) == 1) F5 ShiftEnter
CtrlIns Esc Tab Home Alt< ShiftIns Esc $End $End"
"DisableOutput"=dword:00000001

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlAltRight]
"Sequence"="$IClip $If (((Bof && APanel.Root) || !Bof) && PPanel.Visible)
$If (fexist(PPanel.Path+\"\\\\\"+APanel.Current) == 1) F5 ShiftEnter CtrlIns
Esc Tab Home Alt< ShiftIns Esc $End $End"
"DisableOutput"=dword:00000001

REGEDIT4

;выделение следующих нижних/верхних 30 файлов

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlDown]
"Sequence"="$If (!Eof) $Rep (30) $If (Eof) Ins $Exit $Else Ins $End $End $End"
"DisableOutput"=dword:00000001

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlUp]
"Sequence"="Up $If (Bof) $If (!APanel.Root) Down $End $Exit $Else Down $End
$If (Eof) Ins $Else Ins Up $End $Rep (29) Up Ins Up $If (Bof)
$If (!APanel.Root) Down $End $Exit $End $End Up"
"DisableOutput"=dword:00000001

REGEDIT4

;сграбить весь экран в текстовый файл far-screen.out
;работает в области Dialog

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Dialog\AltP]
"Sequence"="$IClip AltIns CtrlHome ShiftEnd ShiftPgDn Enter Esc
$If (!Shell) Esc $End $If (Shell && !APanel.Plugin) ShiftF4 CtrlY
\"far-screen.out\" Enter ShiftIns Enter Enter F2 Esc $End"
"DisableOutput"=dword:00000001
REGEDIT4

;удаление файла/папки по клавише Del
;если стояли на элементе .. то пытаемся удалить вышестоящую папку
;если не в конце ком строки то удаляем символы в ней

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\Del]
"Sequence"="$If (!CmdLine.Eof) Del $Exit $Else
$If ((APanel.Bof && !APanel.Selected) &&
(!APanel.Root || APanel.Plugin)) CtrlPgUp $End F8 $End"
"DisableOutput"=dword:00000001

REGEDIT4

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

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlQ]
"Sequence"="Tab $If (QView) Tab Ctrl2 Tab CtrlClear $Else Tab Ctrl6 Tab
$If (APanel.Left) $Rep (APanel.width) CtrlRight $End $Else
$Rep (APanel.width) CtrlLeft $End $End $End Tab CtrlQ"
"DisableOutput"=dword:00000001

Следующий макрос служит для того чтобы помечать вместе с htm-файлом и парную ему папку:

REGEDIT4

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Shell\CtrlShiftIns]
"Sequence"="%Current=APanel.Current; %Ext=substr(%Current,len(%Current)-6);
$If (%Ext==\"_files\") %Name=substr(%Current,0,len(%Current)-6); $Else
%Ext=fsplit(%Current,FSPLIT_EXT); %Name=fsplit(%Current,FSPLIT_NAME); $End
$if (%Ext==\".htm\" || %Ext==\".html\") panel.setpos(ACTIVEPANEL,%Name+\".files\")
panel.setpos(ACTIVEPANEL,%Name+\"_files\") $end $if (%Ext==\".files\" || %Ext==\"_files\")
panel.setpos(ACTIVEPANEL,%Name+\".htm\") panel.setpos(ACTIVEPANEL,%Name+\".html\") $End
$if (APanel.Current!=%Current) $If(!panelitem(ACTIVEPANEL,0,PANELITEM_SELECTED)) Ins $End
panel.setpos(ACTIVEPANEL,%Current) $If(!panelitem(ACTIVEPANEL,0,PANELITEM_SELECTED))
Ins $End $End $MMode 1 $MMode 1"
"DisableOutput"=dword:00000001

;При непустой командной строке макрос не вызывается чтобы можно пользоваться первоначальной
;функцией сочетания CtrlShiftIns - Поместить помеченные имена в Буфер Обмена
"EmptyCommandLine"=dword:00000001


Статьи и заметки

главная
В этом разделе опубликованы статьи и заметки на околопрограммистские темы. Мы будем рады, если материалы из данного раздела помогут Вам найти решение в процессе создания плагина. Собственно для этого и создавалась Энциклопедия!

  • Работа с "временной панелью" в своем плагине
    Иван Синтюрин. 15.04.2006
  • Написание плагина на Delphi (ID3 Viewer)
    Gigabyte, 2004
  • Как компилировать с помощью Borland C++ 5.5 без startup code
    Алексей Ярославский. 02.06.2002
  • Собственные типы колонок на панели плагина
    WARP ItSelf. 02.06.2004
  • Плагин для разных версий FAR Manager
    Eugene Yavorsky. 15.05.2004
  • Как уменьшить размер плагина: Microsoft VC++ 4.2 (замечания к статье Олега Данилова)
    Eugene Yavorsky. 08.05.2004
  • Как настроить Alignment (extended)
    Alex Yaroslavky. 04.12.2001
  • Несколько приемов работы с окнами FAR.
    Александр Назаренко. 13.01.2002
  • Распределение памяти. Скромная попытка расставить все по своим местам в этом вопросе.
    Иван Синтюрин. 28.05.2000 Rev. 20.12.2001
  • Оптимизация размера плагина при использовании gcc.
    Вадим Егоров. 16.07.2001
  • О пользе и вреде static в диалогах.
    Jouri Mamaev. 21.02.2001
  • Как уменьшить размер плагина (на примере Microsoft VC++ 6.0)
    Олег Данилов. 29.01.2001
  • Отладка плагинов в Borland Turbo Debugger
    Вячеслав Печенин. 24.12.2000
  • Упаковщики - ЗА и ПРОТИВ
    Jordan Russell. 21.04.2000
  • Как самому сделать plug-in к FAR на Visual C++ - шаг за шагом
    Руслан Ильгасов. 13.05.2000
  • Распределение памяти в Borland Delphi - проблемы и решения
    Василий Мошнинов. 14.04.2000
  • Приручаем Borland C++ к crtdll.dll
    Eugene Kotlyarov. 04.04.2000, Rev. 24.06.2000
  • Синдром ``Рождественской Ёлки'' или Свобода Безумия
    Игорь Русских. 25.03.2000
  • Написание плагинов на Virtual Pascal 2.0
    Дмитрий Суходоев. 25.03.2000, Rev. 30.04.2000
  • Локализация плагинов второго уровня
    Иван Синтюрин. 07.01.2000
  • Корретировка PLUGIN.HPP
    Валентин Скирдин. 02.01.2000, Rev. 10.09.2000
  • Как настроить Alignment
    Игорь Павлов. 24.12.1999
  • Формат Hrc изнутри.
    Игорь Русских. 14.12.1999
  • Обработка нажатия ESC или "Авторам долгодумающих плагинов посвящается..."
    Иван Синтюрин. 13.12.1999, Rev. 06.09.2000
  • ECTL_GETSTRING работает слишком медленно...
    Stanislav V. Mekhanoshin. 28.11.1999
  • Как уменьшить размер плагина (на примере Watcom v11)
    Эдуард Султанов. 18.10.1999
  • Подсказка в нестандартных диалогах.
    Валентин Скирдин, Игорь Русских. 14.10.1999, Rev. 21.07.2000
  • Как получить полный путь редактируемого файла из плагина в редакторе?
    Валентин Скирдин. 19.08.1999
  • Как уменьшить размер плагина (на примере Borland C++ 5.02)
    Валентин Скирдин. 31.05.1999
Если у вас есть несекретные "маленькие секреты" или, в процессе работы над плагинами, вы сталкивались с некоторыми особенностями, "подводными камнями" и с успехом преодолели эти самыми трудности, то расскажите о них, оформите в виде небольшой статьи, и мы с удовольствием разместим ваш материал в этой Энциклопедии...

Возможно Вам поможет статья "Для авторов" :-)

Смотрите также:
Для авторов


Как компилировать с помощью Borland C++ 5.5 без startup code

главная | статьи
Алексей Ярославский trexinc@yandex.ru

Во время написания Position Saver я столкнулся с небольшой проблемой, размер DLL-а который выдавал мой BCC 5.5 был просто страшным, в районе 80KB. Я почитал статьи из энциклопедии и попытался компилировать без startup code (c0d32.obj). Размер файла уменьшился но плагин перестал загружаться в ФАРе. Оказалось что ilink32.exe при компилирование C++ файлов без startup code неправильно выставлял entry point что и приводило к неработоспособности плагина. Я начал искать на инете информацию о ручном выставление entry point с помощью BCC и нашел что такой возможности он не даёт. Я уже готов был сдаться но в последнюю минуту нашел то что искал.

Так как Борландские компиляторы не дают вручную задавать entry point то нужно линковать с программой, объект который будет содержать уже готовую "entry point". Такой объект можно создать из ниже приведенного ASM файла:

.386p

_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
_TEXT ENDS

_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS

_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS

DGROUP GROUP _DATA, _BSS

ASSUME CS:_TEXT, DS:DGROUP

_TEXT SEGMENT PUBLIC DWORD USE32 'CODE'

PUBLIC EntryPoint
PUBLIC __acrtused

__acrtused label byte

EntryPoint proc near
    mov eax, 1
    ret 12
EntryPoint endp

_TEXT ENDS

END EntryPoint

Объектный модуль полученный после компиляции этого файла (с помощью Turbo Assembler-а) можно линковать вместе с программой для получения работающего DLL-а без startup code с помощью BCC 5.5.

Более подробную информацию можно найти здесь Windows Developer Magazine Online.

02.06.2002
наверх


Собственные типы колонок на панели плагина.

главная | статьи
WARP ItSelf WARP_ItSelf@mail.ru

Введение

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

1. Создание собственных типов колонок и помещение в них ваших данных.

Давайте для начала выполним тривиальную задачу и добавим к панели плагина колонку с собственными строковыми данными (например номерами контактов в ICQ). Far Manager поддерживает до 10 пользовательских колонок на панели плагина. Пусть на панели нашего плагина будет только две колонки: имя контакта в ICQ и его номер. Пусть колонка с номером контакта будет пользовательской. В качестве хранилища имени контакта будем использовать имена файлов на панели. Код функции GetFindData плагина будет следующим:

int WINAPI GetFindData(HANDLE hPlugin,
                       struct PluginPanelItem **pPanelItem,
                       int *pItemsNumber,
                       int OpMode)
{
  PluginPanelItem *pItems = (PluginPanelItem*)malloc (10*sizeof(PluginPanelItem));

  memset (pItems, 0, 10*sizeof(PluginPanelItem));

  // пусть на панели требуется отобразить 10 элементов.
  for (int i = 0; i < 10; i++)
  {
    strcpy (pItems[i].FindData.cFileName, pNames[i]);

    // pNames - массив, в котором хранятся имена контактов.

    // А теперь передадим Far Manager строковые данные, которые он
    // будет отображать в нашей колонке:

    // a) Выделим память для массива, хранящего ссылки на пользовательские
    // данные для каждого нестандартного типа колонки:

    pItems[i].CustomColumnData = (char**)malloc (nCount*4);

    // nCount - число требуемых нестандартных типов колонок. В нашем случае - 1.

    // б) Заполним массив нашими данными. У нас всего одна собственная
    //  колонка на панели, поэтому нам потребуется заполнить только первый элемент
    //      массива:

    pItems[i].CustomColumnData[0] = (char*)malloc (260);
    strcpy (pItems[i].CustomColumnData[0], pContactNumbers[i]);

    // pContactNumbers - массив строк, содержащих номера контактов ICQ.

    // в) Объясним Far Manager, что мы хотим использовать только одну собственную
    // колонку на панели нашего плагина. Для этого надо заполнить поле
    // CustomColumnNumber.

    pItems[i].CustomColumnNumber = 1;
  }

  *pPluginItem = pItems;
  *pItemsNumber = i;

  return TRUE;
}

Теперь необходимо позаботиться об освобождении памяти, которую мы выделили для массива CustomColumnData и его элементов. Это нужно сделать в функции FreeFindData плагина, которую Far Manager вызывает для того, чтобы плагин освободил всю занятую под элементы панели память (все данные Far Manager копирует во внутренние структуры):

void WINAPI FreeFindData (HANDLE hPlugin,
                          struct PluginPanelItem *PanelItem,
                          int ItemsNumber)
{
  for (int i = 0; i < ItemsNumber; i++)
  {
    for (int j = 0; j < PanelItem[i].CustomColumnNumber; j++)
      free (PanelItem[i].CustomColumnData[j]);

    free (PanelItem[i].CustomColumnData);
  }

  free (PanelItem);
}

Можно собирать плагин. После запуска легко будет заметить, что собственная колонка на панели не появилась. Чего же не хватает? Надо объяснить Far Manager, какие типы колонок требуется показывать на нашей панели. Для пользовательских колонок используются идентификаторы C0-C9. Создадим собственный режим панели. Для этого надо изменить поле PanelModesArray параметра *Item, передаваемого в функцию GetOpenPluginInfo плагина:

void WINAPI GetOpenPluginInfo (HANDLE hPlugin,
                               struct OpenPluginInfo *Info)
{
  static PanelMode CustomPanelModes[1] = {
         "C0, N", "15, 0", NULL, FALSE, TRUE, TRUE,
         TRUE, NULL, NULL, {0, 0}};

  memset (Info, 0, sizeof(OpenPluginInfo));

  Info->StructSize = sizeof(OpenPluginInfo);

  Info->PanelModesArray = &CustomPanelModes;
  Info->PanelModesNumber = 1;

  // изменим "нулевой" режим панели (LCtrl-0), так, чтобы в нем
  // на панели отображались 2 колонки: имя файла (а нашем случае
  // имя контакта) и номер контакта (пользовательская колонка "C0").
}

Теперь при выборе "нулевого" режима на панели нашего плагина (LCtrl-0) появятся 2 колонки, вторая из которых будет содержать наши данные.

2. Чего-то не хватает...

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

static const char *CustomColumnTitles[2] = {NULL, "Contact ID"};

Info->PanelModesArray[0].PanelTitles = (char**)&CustomColumnTitles;

// для первой колонки в качестве заголовка используется значение
// NULL (стандартный заголовок), т.к. в первой колонке хранятся
// в нашем случае имена файлов, и заголовок для такого типа
// колонки Far Manager известен ("Имя").

Теперь, казалось бы все в порядке, но...

3. Проблема.

Все работает как надо и у нашей колонки есть даже корректный заголовок. Но что будет, если плагин предоставит пользователю возможность самостоятельно задавать типы и ширину колонок на панели, как это делают многие плагины? На первый взгляд это не должно вызывать проблем, но представим себе следующую ситуацию: в качестве строки, определяющей типы колонок на "нулевом" режиме панели пользователь ввел "C0, N". Заметим, что эта строка отличается, от той строки, что мы использовали выше. Колонки поменялись местами. Но ведь массив, в котором хранятся заголовки панелей остался неизменным. Значит теперь заголовки колонок стали неверны.

4. Решение.

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

// lpUserColumnTypes - строка, содержащая типы колонок,
//                     заданные пользователем
char** ConvertColumnTypes (const char *lpUserColumnTypes)
{
  int nTokens = 0;
  char *lpTokens = (char*)malloc (strlen(lpUserColumnTitles)+1);
  strcpy (lpTokens, lpUserColumnTypes);
  char *lpToken = strtok (lpTokens, ",");

  // посчитаем количество заданных пользователем колонок

  while ( lpToken )
  {
    nTokens++;
    lpToken = strtok (NULL, ",");
  }

  char **pColumnTitles = (char**)malloc (nTokens*4);
  strcpy (lpTokens, lpUserColumnTypes);
  lpToken = strtok (lpTokens, ",");
  nTokens = 0;

  // найдем все колонки, тип которых задан как C0
  // и поместим в соответствующий элемент массива
  // ссылку на нужный заголовок. Для всех остальных
  // типов колонок используем значение NULL,
  // полагая, что остальные типы колонок известны
  // Far Manager.

  while ( lpToken )
  {
    if ( !FSF.LStricmp (lpToken, "C0") )
      pColumnTitles[nTokens] = "Contact ID";
    else
      pColumnTitles[nTokens] = NULL;

    nTokens++;
    lpToken = strtok (NULL, ",");
  }

  free (lpTokens);

  return pColumnTitles;
}

Данная функция возвращает созданный массив заголовков (безусловно, это не самое красивое, но простое решение). Ввиду того, что количество элементов данного массива заранее неизвестно, выделить под него память заранее нельзя, но освободить занятую массивом память все же нужно. Это проще всего сделать в функции ClosePlugin, предварительно сохранив адрес массива в глобальной переменной (или в члене класса). Пусть в нашем случае существует глобальная переменная char **pColumnTitles = NULL. Переменная обязательно должна быть инициализирована. Тогда в функция ClosePlugin будет выглядеть так:

void WINAPI ClosePlugin (HANDLE hPlugin)
{
  free (pColumnTitles);
}

Теперь модифицируем функцию GetOpenPluginInfo, чтобы в нашем режиме панели правильно отображались заголовки.

void WINAPI GetOpenPluginInfo (HANDLE hPlugin,
                struct OpenPluginInfo *Info)
{
  ...

  // если произошел повторный вызов функции GetOpenPluginInfo до вызова
  // фунции ClosePlugin (что в Far Manager совсем не редкость), память
  // занятая под массив pColumnTitles должна быть освобождена.
  if ( pColumnTitles )
    free (pColumnTitles);

  pColumnTitles = ConvertColumnTypes (lpUserColumnTypes);

  // lpUserColumnTypes - глобальная переменная, содержащая пользовательские типы колонок
  // для нашего режима панели.
  CustomPanelModes[0].ColumnTitles = pColumnTitles;

  ...
}

Теперь плагин правильно отображает заголовки нестандартной колонки "Contact ID".

5. Красивости.

Согласитесь, использование идентификаторов C0-C9 для типов колонок собственного режима панели не очень красиво. Тем более, что каждый плагин использует именно эти безликие идентификаторы. И пользователь вынужден каждый раз читать файлы помощи, чтобы вспомнить, что ему нужно написать в строке типов колонок, чтобы на панели плагина появилась нужная ему колонка. Значит нам нужно преобразовывать заданные пользователем осмысленные идентификаторы типов колонок в идентификаторы, понятные Far Manager. Для этого слегка модифицируем функцию ConvertColumnTypes:

// lpUserColumnTypes - строка, содержащая типы колонок,
//                     заданные пользователем
// lpRealColumnTypes - строка, в которую будут помещены
//                     типы колонок, понятные Far Manager.
//                     память под эту строку должна быть
//                     выделена заранее.
char **ConvertColumnTypes (const char *lpUserColumnTypes,
                           char *lpRealColumnTypes)
{
  int nTokens = 0;

  char *lpTokens = (char*)malloc (strlen (lpUserColumnTypes)+1);
  strcpy (lpTokens, lpUserColumnTypes);
  char *lpToken = strtok (lpTokens, ",");

  while ( lpToken )
  {
     nTokens++;
     lpToken = strtok (NULL, ",");
  }

  char **pColumnTitles = (char**)malloc (nTokens*4);
  strcpy (lpTokens, lpUserColumnTypes);
  lpToken = strtok (lpTokens, ",");
  nTokens = 0;

  while ( lpToken )
  {
    // пусть в качестве пользоваетельского идентификатора
    // колонки "Contact ID" выступает строка "ID".

    if ( !FSF.LStricmp (lpToken, "ID") ||
             !FSF.LStricmp (lpToken, "C0") )
    {
      strcat (lpRealColumnTypes, "C0");
      pColumnTitles[nTokens] = "Contact ID";
    }
    else
    {
      pColumnTitles[nTokens] = NULL;
      strcat (lpRealColumnTypes, lpToken);
    }

    strcat (lpRealColumnTypes, ",");
    nTokens++;
    lpToken = strtok (NULL, ",");
  }

  free (lpTokens);

  return pColumnTitles;
}

Теперь в качестве идентификатора для колонки, содержащей номер контакта ICQ пользователь может использовать строку "ID" наравне с "C0". К глобальным переменным требуется добавить переменную char RealColumnTypes[260] (размер этой переменной может быть иным, а в идеальном варианте его должна высчитывать функция ConvertColumnTypes). Осталось только изменить функцию GetOpenPluginInfo:

void WINAPI GetOpenPluginInfo (HANDLE hPlugin,
                struct OpenPluginInfo *Info)
{
  ...

  CustomPanelModes[0].ColumnTitles = pColumnTitles;
  CustomPanelModes[0].ColumnTypes = &RealColumnTypes;

  ...
}

6. Заключение.

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

ПРИМЕЧАНИЕ.

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

02.06.2004
наверх


Как уменьшить размер плагина: Microsoft VC++ 4.2

(замечания к статье Олега Данилова)
главная | статьи
Eugene Yavorsky eugene_yavorsky@mail.ru

В статье "Как уменьшить размер плагина (на примере Microsoft VC++ 6.0)" Олег Данилов пишет:

Шаг 0. Все функции, используемые, в плагине были заменены на аналогичные
из Win API: strcpy на lstrcpy и т.д. К сожалению, история не сохранила
исходный размер плагина, поэтому оценить экономию на этом шаге затруднительно.

В дополнение привожу результаты моих "издевательств" над двумя собственными проектиками в VC 4.2.

Первая подопытная программа - Win32 GDI, RTL - single-threaded (ключ компиляции /ML). До "измывательства" - 26624 байт (исходный код до "обработки" - до 100 строк, после - 101 строка, из которых 3 - инклуды, 30 - форматирование [пробелы и открывающие/закрывающие скобки], 10 - комментарии, 26 - объявления и инициализация переменных. Итого 32 "смысловые" строки).

В таблице приведены результаты рекомендованных Олегом Даниловым замен (естественно, где было что заменять ;-).

Заменяемая функция | Замена | До замены | После | Выигрыш
strlen | lstrlen | 26624 | 26112 | 512
sprintf | strcpy+strcat | 26112 | 18432 | 7680
strcat, strcpy | lstrcat, lstrcpy | 18432 | 17920 | 512
Итого |  | 26624 | 17920 | 8704

Наибольший эффект дала замена

sprintf(lpszMessage, "%s\n\"%s\"\n%s", lpszBegin, lpszExe, lpszError);
на
strcpy(lpszMessage, lpszBegin);
strcat(lpszMessage, "\n\"");
strcat(lpszMessage, lpszExe);
strcat(lpszMessage, "\"\n");
strcat(lpszMessage, lpszError);

(естественно, замена сначала на RTL-функции проводилась исключительно в исследовательских целях).

Т.о., для данного приложения выигрыш от замен составил порядка трети. Естественно, если размер скомпилированного приложения или библиотеки больше двух-трех сотен килограмм, "овчинка" (эти 8 КБ) вряд ли стоит выделки.

Так же стоит внести некоторое возражение относительно "отсутствия эффекта от оптимизации по размеру".

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

В рассматриваемом микро-приложении при отключении оптимизации в "окончательном" варианте размер подскакивает с 17920 до 18432 байт (т.е., на каких-то 32 "смысловых" строках оно таки наоптимизировало 512 байт).

При взятии чуть большего приложения, которому даже далеко до "среднего" по размеру программного прожекта (тестовый проект состоял из 21 исходника на C и CPP суммарным размером около 150 килограмм), получаем такую статистику:

Optimization | размер | выигрыш, %
Disabled (debug) | 404480 (653824) | -
Default | 404480 (653824) | -
Maximize speed | 358912 (636416) | 11,3% (4,5%)
Minimize size | 348160 (624128) | 13,9% (2,7%)

Компилировалась RELEASE-версия. Размер в скобках - это то же, но с включенной "Generate debug info" в релизе.

В качестве вывода - не стоит пренебрежительно относиться к стандартным средствам оптимизации. Просто не всегда им есть где "разгуляться" ;-)

08.05.2004
наверх


Плагин для разных версий FAR Manager.

(замечания к статье FAR Group)
главная | статьи
Eugene Yavorsky eugene_yavorsky@mail.ru

Озаботившись проблемой работы моего плагина в различных версиях ФАРа, от лени не стал изобретать велосипеды и попытался вставить готовую "козу" из упомянутой выше статьи ("Плагин для разных версий FAR Manager" FAR Group), однако код работал как-то странно. Написав по его просьбе тестовый плагин (по приведенному коду - после исправления опечаток) и протестировав его, получил следующие результаты.

Сборка плагина производилась с версиями plugin.hpp из поставки публичных бет:

  • 1.70 beta 1 - Revision: 1.67 04.11.2000
  • 1.70 beta 2 build 312 - Revision: 1.70 16.12.2000
  • 1.70 beta 3 build 591 - Revision: 1.95 19.04.2001
  • 1.70 beta 4 build 1282 - Revision: 1.191 13.03.2002
  • 1.70 beta 5 build 1634 - Revision: 1.226 09.04.2003

А также с plugin.hpp от какой-то 6-й альфы, не помню где взятым:

  • 1.70 beta 6 build 1706 - Revision: 1.234 18.09.2003

Далее эти версии plugin.hpp будут мною для простоты нумероваться как 1701, 1702, 1704, 1705 и 1706.

Тестирование проводилось в следующих публичных версиях ФАРа:

  • 1.60
  • 1.63
  • 1.70 beta 1
  • 1.70 beta 2 build 312
  • 1.70 beta 3 build 591
  • 1.70 beta 4 build 1282
  • 1.70 beta 5 build 1634

И двух 6-х альфах:

  • 1.70 alpha 6 build 1658
  • 1.70 alpha 6 build 1736

Для ФАРов 1.60 и 1.65 поведение всех версий плагина не отличалось:

  1. GetMinFarVersion() не вызывается по причине отсутствия его в этих версиях FAR API
  2. GetPluginInfo() "видит", что
         ::Info.StructSize < sizeof(struct PluginStartupInfo)
    и матерится при каждом вызове (т.е. при каждом F11, вызове меню настроек плагинов, смене языка и т.д.)

Для ФАРов 1.701-1.706 build 1736

На основании логов проверено фунциклирование GetMinFARVersion(). По горизонтали всех таблиц - версия ФАРа, по вертикали - версия plugin.hpp

- ФАР не ругается на "плохую" версию плагина (а надо бы)

+ ФАР ругается на "плохую" версию плагина

. ФАР не ругается на "плохую" версию плагина - и не надо

Версия plugin.hpp | 1701 | 1702 | 1703 | 1704 | 1705 | 1706 build 1658 | 1706 build 1736
1701 | . | . | . | . | . | . | .
1702 | - | . | . | . | . | . | .
1703 | - | - | . | . | . | . | .
1704 | - | - | - | . | . | . | .
1705 | - | - | - | + | . | . | .
1706 | - | - | - | + | + | + | .

При анализе логов для ФАРов 1701-1703 вообще нет свидетельств о вызове GetMinFARVersion().

Т.о., ФАР и GetMinFARVersion() ведет себя документированным и предполагаемым образом только в ФАРах 1704 и выше.

После титанических интеллектуальных усилий код был поправлен следующим образом:

// Ставим тут нужную нам версию
#define HPPVER "1.705"

BOOL bBadFAR = FALSE;
DWORD dwFARVERSION;

void WINAPI SetStartupInfo(struct PluginStartupInfo *PSInfo)
{
  if(PSInfo->StructSize < sizeof(struct PluginStartupInfo))
  {
    memcpy(&Info,PSInfo,PSInfo->StructSize);
    bBadFAR = TRUE;
  }else{
    Info = *PSInfo;
    FSF = *PSInfo->FSF;
    Info.FSF = &FSF;

    Info.AdvControl(Info.ModuleNumber, ACTL_GETFARVERSION, &dwFARVERSION);
    if(dwFARVERSION < FARMANAGERVERSION)
      bBadFAR = TRUE;
  }

  if(bBadFAR)
      Message("Этот плагин требует FAR Manager версии "HPPVER" и выше!");
}

int WINAPI GetMinFarVersion(void)
{
  return FARMANAGERVERSION;
}

void WINAPI GetPluginInfo(struct PluginInfo *Info)
{
  if(bBadFAR)
    return;

  // Далее пошла инициализация PluginInfo
}

После тестирования по той же программе получаем:

Для ФАРов 1.60-1.65:

  1. GetMinFarVersion() не вызывается по причине отсутствия
  2. SetStartupInfo() видит, что
         ::Info.StructSize < sizeof(struct PluginStartupInfo)
    и устанавливает bBadFAR = TRUE и один раз матерится
  3. GetPluginInfo() в ответ на bBadFAR = TRUE сваливает без заполнения PluginInfo и плагин не светится в списке

Для ФАРов 1.701-1.706 build 1736

Обозначения:

+ФАР ругается на "плохую" версию плагина (что достигается корректной работой GetMinFarVersion())

#плагин ругается на "плохую" версию ФАРа (что достигается наличием в SetStartupInfo()):

  Info.AdvControl(Info.ModuleNumber, ACTL_GETFARVERSION, &dwFARVERSION);
  if(dwFARVERSION < FARMANAGERVERSION){
    bBadFAR = TRUE;
    Message("Этот плагин требует FAR Manager версии "HPPVER" и выше!");
  }
При этом GetPluginInfo() в ответ на bBadFAR = TRUE сваливает без заполнения PluginInfo и плагин не светится в списке.

+ GetPluginInfo() заполняет PluginInfo, плагин в списке и работает.

Версия plugin.hpp | 1701 | 1702 | 1703 | 1704 | 1705 | 1706 build 1658 | 1706 build 1736
1701 | . | . | . | . | . | . | .
1702 | # | . | . | . | . | . | .
1703 | # | # | . | . | . | . | .
1704 | # | # | # | . | . | . | .
1705 | # | # | # | + | . | . | .
1706 | # | # | # | + | + | + | .

Т.о., получаем необходимую и логичную функциональность для всех протестированных версий ФАРа и plugin.hpp.

Полные версии тестировочных плугинов (старого - "неправильного" и нового - "поправленного") и соответствующих логов есть на PlugRin`е и будут лежать еще тут.

15.05.2004

Внимание! Внимание!

  • Некорректно делать сравнение типа "if(dwFARVERSION < FARMANAGERVERSION)". Это связано с тем, как FAR хранит версию. Необходимо сравнить старшую и младшую компоненты версии, например:
    if (LOWORD(dwFARVERSION) <  LOWORD(FARMANAGERVERSION) ||
   (LOWORD(dwFARVERSION) == LOWORD(FARMANAGERVERSION) &&
    HIWORD(dwFARVERSION) <  HIWORD(FARMANAGERVERSION)))
{
  bBadFAR = TRUE;
}
наверх


Как настроить Alignment (extended)

главная | статьи
Alex Yaroslavky []

В продолжение статьи "Как настроить Alignment" Игоря Павлова, я пишу здесь объяснения того, как установить правильное выравнивание при компиляции плагинов для FAR, используя LCC-WIN32 или Borland C++ 5.5 (free commandline tool).

LCC-WIN32:

Вы должны найти файл, который называется win.h в каталоге lcc\include\. Затем ищете в нём строку "WIN32_FIND_DATA", вы увидите определение структуры подобно этому:

typedef struct _WIN32_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[MAX_PATH];
  TCHAR cAlternateFileName[14];
  WORD dummy;
} WIN32_FIND_DATA,*LPWIN32_FIND_DATA,*PWIN32_FIND_DATA;

Для правильной компиляции plugin.hpp или для получения размера структуры PluginPanelItem 366 байт нам нужно, чтобы вышеупомянутая структура была равна 318 байтам, единственное что мешает этому, так это поле 'WORD dummy' в конце структуры, которое не нужно в этой структуре и добавлено автором LCC по причине, мне неизвестной (может он тоже был озабочен выраниванием :). Так что оно может быть удалено, просто закомментируйте строчку с фиктивной переменной. Вы всё сделали, теперь вы можете счастливо компилировать ваш плагин, только не забудьте использовать ключ -Zp2, чтобы установить выравнивание в 2 байта.

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

Borland C++ 5.5 (free commandline tool):

Вы должны найти файл, называемый winbase.h в каталоге bcc\include\. Затем в начале файла вы увидите что-то вроде этого:

#ifndef _WINBASE_
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
#define _WINBASE_

Для правильной компиляции plugin.hpp или для получения размера структуры PluginPanelItem 366 байт нам нужно, чтобы вышеупомянутая структура была равна 318 байтам. Чтобы установить этот размер, нужно компилировать winbase.h с выравниванием 2 байта, для чего вы должны изменить "-a8" на "-a2" в описанных выше строках.

Другая проблема - проверка размера структуры PluginPanelItem в plugin.hpp.

Выглядит это так:

#if defined(__BORLANDC__)
#if sizeof(PluginPanelItem) != 366
#if defined(STRICT)
#error Incorrect alignment: sizeof(PluginPanelItem)!=366
#else
#pragma message Incorrect alignment: sizeof(PluginPanelItem)!=366
#endif
#endif
#endif

В Borland C++ 5.5 команда "sizeof(PluginPanelItem)" делает не то, что ожидалось, так что вы всегда будете получать эту ошибку. Что вам нужно сделать, так это изменить строку на "sizeof(struct PluginPanelItem) != 366" чтобы сделать это очевидным. Вы всё сделали, теперь вы можете счастливо компилировать ваш плагин, только не забудьте использовать ключ -a2, чтобы установить выравнивание в 2 байта.

04.12.2001
наверх


Несколько приемов работы с окнами FAR.

главная | статьи
Александр Назаренко corwinnt@yahoo.com

О написании плагинов к редактору написано много, но большинство примеров подобных плагинов работает только с одним окном редактора. А как быть, если нужно переключаться между несколькими открытыми редакторами? Как сохранить все измененные файлы например? Или как перейти на известную позицию в уже открытом на редактирование файле? Поскольку я, похоже, первый наступил на эти «грабли», то мне и приводить рецепты.

FAR Manager до 1.70 beta 3 (включительно)

К сожалению здесь нормально реализовать работу с несколькими окнами редактора не получится потому, что стандартному API не хватает функциональности, а именно нормального способа переключится в нужное окно. Единственный "нормальный" путь - вызов функции Info.Editor(...,EF_NONMODAL,...);. При этом, если файл уже открыт в редакторе, FAR «переспрашивает» у пользователя, хочет ли он использовать уже открытый файл, перегрузить его или отказаться от открытия файла. При использовании плагина, обеспечивающего переход в нужное место исходного текста на основании анализа листинга компилятора, при таком подходе нетрудно предугадать реакцию пользователя. Выхода здесь два:

Первое - просить FAR Group переписать API с поддержкой дополнительных флагов типа Info.Editor(...,EF_USEEXISTING,...);, которые подавляли бы это предупреждение.
Второе - использовать модальный редактор и таким образом просто запретить переключение между окнами.

FAR Manager 1.70 beta 4 (и выше)

Но не о том здесь речь. Третье решение - использовать оконное API от «четверки» с ее расширенным набором функций ACTL_*. Покажу это на примере реализации сохранения всех файлов, открытых на редактирование, и перехода на известную позицию в возможно уже открытом на редактирование файле.

В примере, приведенном ниже, показано как реализовать отсутствующую в стандартном API функцию Info.EditorControl(ECTL_SAVEALL,&rec).

void EditorSaveAll(void)
{
  struct WindowInfo wi;
  // получим информацию о окне текущего файла
  wi.Pos = -1;
  Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWINFO, (void*)&wi);
  int home = wi.Pos;
  int n = Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWCOUNT, NULL);
  for ( int i = 0 ; i < n ; i++ )
  {
    wi.Pos = i;
    Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWINFO, (void*)&wi);
    if ( ( wi.Type == WTYPE_EDITOR ) && wi.Modified )
    {
      // сохраним каждый измененный файл
      Info.AdvControl(Info.ModuleNumber, ACTL_SETCURRENTWINDOW, (void*)i);
      Info.AdvControl(Info.ModuleNumber, ACTL_COMMIT, NULL);
      Info.EditorControl(ECTL_SAVEFILE, NULL);
    }
  }
  // восстановим сохраненное окно редактора
  Info.AdvControl(Info.ModuleNumber, ACTL_SETCURRENTWINDOW, (void*)home);
  Info.AdvControl(Info.ModuleNumber, ACTL_COMMIT, NULL);
}

Все достаточно просто, но эта простота обманчива:

Во первых, при написании этого куска кода я достаточно долго искал причину того, что приведенный кусок не работал. Сохранялся только текущий файл. Причина оказалась в том, что я не использовал Info.AdvControl(Info.ModuleNumber, ACTL_COMMIT, NULL) и фактического переключения в нужное окно не происходило.

Во вторых, вместо использования wi.Pos = -1 я сначала получал имя текущего редактируемого файла через Info.EditorControl(ECTL_GETINFO,&ei); и проверял его совпадение с wi.Name в цикле перебора окон FAR.
Надеюсь, что на эти «грабли» теперь уже никто не наступит.

Теперь о переходе на «нужный» редактор. То есть реализуем отсутствующую в стандартном API функцию Info.Editor(...,EF_NONMODAL|EF_USEEXISTING,...).

Исходные данные, которые мы имеем, это полное имя нужного файла, строка и столбец в нем. Здесь тоже есть тонкие моменты. Нужно отследить два момента.
Во первых, нужно проверить, нужно ли вообще куда-то переходить. То есть, не редактируем ли мы этот файл в данный момент.
Во вторых, нужно проверить, открыт ли этот файл на редактирование вообще или нужно открывать новое окно редактора.

// переход на нужную позицию в текущем редакторе

void EditorSetPos(int line, int col, int topline = -1, int leftcol = -1)
{
  EditorSetPosition sp;
  sp.CurLine = line;
  sp.CurPos = col;
  sp.TopScreenLine = topline;
  sp.LeftPos = leftcol;
  sp.CurTabPos = sp.Overtype = -1;
  Info.EditorControl(ECTL_SETPOSITION, &sp);
}

bool OpenEditor(const char *FileName, int line, int col)
{
  if ( ( FileName != NULL) && ( *FileName != 0 ) )
  {
    struct WindowInfo wi;
    // получим информацию о имени текущего файла
    wi.Pos = -1;
    Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWINFO, (void*)&wi);
    if ( !FSF.LStricmp(wi.Name, FileName) )
      EditorSetPos(line, col);
    else
    {
      // ищем нужный файл среди открытых
      int n = Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWCOUNT, NULL);
      for ( int i = 0 ; i < n ; i++ )
      {
        wi.Pos = i;
        Info.AdvControl(Info.ModuleNumber, ACTL_GETWINDOWINFO, (void*)&wi);
        if ( ( wi.Type == WTYPE_EDITOR ) && ( !FSF.LStricmp(wi.Name, FileName) ) )
        {
          Info.AdvControl(Info.ModuleNumber, ACTL_SETCURRENTWINDOW, (void*)i);
          Info.AdvControl(Info.ModuleNumber, ACTL_COMMIT, NULL);
          EditorSetPos(line, col);
          return true;
        }
      }
      // ничего не поделаешь, придется открывать
      Info.Editor(FileName, NULL, 0, 0, -1, -1, EF_NONMODAL, line, col);
      return true;
    }
  }
  return false;
}

Возможно это многим покажется очевидным, но лично к этому коду я пришел далеко не сразу :)

13.01.2002
наверх


Оптимизация размера плагина при использовании gcc.

главная | статьи
Вадим Егоров zg@matrica.apollo.lv

Введение.

В данной статье рассматривается вопрос об уменьшении размера плагинов, скомпилированных gcc.
Условия, при которых возможен существенный выигрыш в размере:
1. Вы явно или неявно используете в своем плагине оператор new.
2. Вы не используете обработку исключений и механизм rtti.

Для компиляции использовались gcc 2.95.3-4 и ld 2.11.90 (20010704).

Тестовый плагин.

test.cpp:

#include "plugin.hpp"

void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info)
{
  int *a;
  a=new int;
  delete a;
}

test.def:

EXPORTS
SetStartupInfo=SetStartupInfo@4

makefile:

CFLAGS=-c -mcpu=pentiumpro -O3 -Wall
LFLAGS=-s -mdll

RM=rm
CC=gcc
DLLTOOL=dlltool

DEF=test.def
OBJS=test.o
TARGET=test.dll

all: $(TARGET)

$(TARGET): $(OBJS)
    $(CC) $(LFLAGS) -o nul -Xlinker --base-file -Xlinker $@.base $^ $(LIBS)
    $(DLLTOOL) --dllname $@ --base-file $@.base --output-exp $@.exp --def $(DEF)
    $(CC) $(LFLAGS) -o $@ $^ $@.exp $(LIBS)
    $(RM) $@.base
    $(RM) $@.exp

test.o: test.cpp
    $(CC) $(CFLAGS) $< -o $@

Примечание: -mcpu=pentiumpro означает всего лишь оптимизацию для P6+ процессоров, без использования команд отсутствующих в i386.

Оптимизация.

Запускаем make. Получаем test.dll размером 23552 байт. Незаслуженно много для такого простого плагина. Начинаем оптимизацию.

Шаг 1. На этом шаге из плагина исключается код для поддержки исключений и rtti. Добавляем в makefile:

CFLAGS=-c -mcpu=pentiumpro -O3 -Wall -fno-rtti -fno-exceptions

Но этого недостаточно. Дело в том, что в реализации глобальных операторов new и delete используются и исключения и rtti. Поэтому добавим в плагин свои версии этих операторов:

void * operator new(size_t size)
{
  return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
}

void operator delete(void *block)
{
  if(block) HeapFree(GetProcessHeap(),0,block);
}

Запускаем make. Получаем test.dll размером 3584 байт.
Если вы используете операторы new[] и delete[], то их тоже надо переписать:

void * operator new[](size_t size)
{
  return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
}

void operator delete[](void *block)
{
  if(block) HeapFree(GetProcessHeap(),0,block);
}

Шаг 2. Исключение startup code. Его размер в версии gcc, указанной выше, составляет 268 байт. Не так уж много, но все же. Добавляем в makefile:

LFLAGS=-s -mdll -nostartfiles

...и в test.cpp:

#ifdef __cplusplus
extern "C"{
#endif
  BOOL WINAPI DllMainCRTStartup(HANDLE hDll,DWORD dwReason,LPVOID lpReserved);
#ifdef __cplusplus
};
#endif

BOOL WINAPI DllMainCRTStartup(HANDLE hDll,DWORD dwReason,LPVOID lpReserved)
{
  return TRUE;
}

Запускаем make. Получаем test.dll размером 3072 байт.
Для этого плагина на этом можно и остановится. Но для реальных плагинов можно еще сэкономить килобайт, другой.

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

-fomit-frame-pointer - без этого флага для каждой функции генерируется пролог и эпилог примерно следующего вида:

push ebp
mov ebp,esp
...
mov esp,ebp
pop ebp

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

-fstrict-aliasing - включает оптимизацию, основываясь на типе выражения. Считается что указатели разных типов указываю на разные участки памяти. Исключение составляют поля в объединениях.

-funroll-loops - оптимизация по раскрытию циклов с заранее известным количеством итераций. Может приводить к увеличению размера кода.

-funroll-all-loops - оптимизация по раскрытию всех циклов. Может приводить к увеличению размера и увеличению времени выполнения кода.

-fno-builtin - для таких функций, как abort, abs, alloca, cos, exit, fabs, ffs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy и strlen gcc по умолчанию вместо вызова библиотечных функций генерирует inline код. Данный флаг предотвращает это, уменьшая размер кода, но при этом увеличивая время выполнения.

16.07.2001
наверх


О пользе и вреде static в диалогах.

главная | статьи
Jouri Mamaev jourim@usue.ru
Счастливым обладателям С++ посвящается.
Плюс немного о языках.

Введение

Одним из удобных, да и очевидных, способов описания статического, т.е. полностью обрабатываемого ФАРом диалога является следующий:

bool DoConfigure( void )
{
  static FarDialogItem itm[] = {
       {     DI_CHECKBOX, 1, 1, 0, 0,  0, NULL, 0,            0, "&Enabled" },
       {         DI_TEXT, 1, 2, 0, 0,  0, NULL, DIF_LEFTTEXT, 0, "&Activators" },
       {     DI_CHECKBOX, 2, 3, 0, 0,  0, NULL, DIF_GROUP,    0, "Control" },
       {     DI_CHECKBOX, 2, 4, 0, 0,  0, NULL, 0,            0, "Alt" },
       {     DI_CHECKBOX, 2, 5, 0, 0,  0, NULL, 0,            0, "Shift" },
       {     DI_BUTTON,   2, 6, 0, 0,  0, NULL, 0,            0, "&OK" },
       {     DI_BUTTON,  12, 6, 0, 0,  0, NULL, 0,            0, "&Cancel" },
  };
  //Заполнение данных элемента диалога реальными данными плагина
  ...
  //Выполнение диалога
  if ( Info.Dialog( Info.ModuleNumber,-1,-1,25,15,NULL,
                     itm,sizeof(itm)/sizeof(itm[0]) ) == -1)
      return false;
  //В случае успешного завершения диалога получение отредактированных
  //  пользователем данных
  return true;
}

Однако те, кто писал (и закончил) свой плагин, после того как проходит эйфория от выполненной работы, замечают несколько "проблем" такого подхода.

  1. Размер плагина, с количеством используемых в нем диалогов и диалоговых элементов растет как на дрожжах.

    Не помогают ни оптимизация плагина, не подключение динамического RTL-а, ни шаманство с объединением кодовых секций и изменения их выравниваний на этапе линковки.

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

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

    Для "добывания" этих строк нужно использовать функцию АПИ ФАРа

    char *GetMsg( int LanguageStringNumber );

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

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

Рассмотрим проблемы, и способы их решения по очереди.

Размер плагина.

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

Это бы ничего т.к. использование, к примеру:

static char GlobalBuff[ 100000 ];
не должно, и не влияет на размер выполняемого файла, т.к. данные создаются и существуют только в памяти, в момент загрузки программы операционной системой.

Но изменив описание на такое:

static char GlobalBuff[ 100000 ] = "ABC";
ваша программа увеличилась в размере на 100Кб.

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

Посмотрим на размер данных, которые мы заставляем линкер приписывать к программе, инициализируя элементы диалога.

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

#include "plugin.hpp"
printf( "%d\n",sizeof(FarDialogItem) );
Т.к. точные цифры нас интересуют слабо, то поступим проще - нажмем F4 на plugin.hpp и посмотрим на описание структуры FarDialogItem.

В ряду с остальными элементами мы там обнаружим следующее:

char Data[512];
Т.е. любой элемент диалога занимает более 500 байт данных в любом случае.

Легко подсчитать, что если у вас описан диалог из 20 элементов, и плагин занимает 10К, то ровно половину этого объема занимают статические данные массива элементов FarDialogItem, в каждом из которых используется не более десятка букв и несколько цифр.

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

Многоязыковая поддержка.

Задачи, которые хотелось бы уметь решать:

  • иметь эту самую поддержку
  • не иметь с ней проблем в процессе написания и изменения данных, кода и самих строк, которые хочется вынести для возможного перевода на потусторонние языки
  • не проводить (или по возможности минимизировать) дополнительной работы, по вынесению строк в файл языковой поддержки ФАРа

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

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

Рассмотрим более простое, не лишенное минусов, но могущее значительно облегчить описанную проблему, средство.

Реализации

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

Эти средства не являются необходимыми для написания плагинов к ФАРу. Это всего лишь один из способов облегчения процесса написания плагинов.

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

Многоязыковая поддержка.

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

Его можно использовать для реализации механизмов поддержки языков в плагинах.

Для этого нужно написать тройку макросов и одну функцию:

#define FLANGID( v )   ((CONSTSTR)MK_DWORD(0xF5F5,v))
#define FISID( v )     (LO_WORD((DWORD)(v)) == 0xF5F5)
#define FGETID( v )    (HI_WORD((DWORD)(v)))

extern CONSTSTR FGetMsg( CONSTSTR String );
Где:
  • FLANGID( <номер строки из файла языков> )
    создает строку, в которой сохраняет этот номер
  • FISID( <строка> )
    проверяет, является ли данная строка реальной, или она представляет из себя номер, собранный макросом FLANGID
  • FGETID( <строка> )
    получает из строки, собранной макросом FLANGID, номер элемента из файла языков

Для использования нам пригодится только FLANGID, остальные используются самой процедурой FGetMsg.

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

const char *Message = "Not enouth";
на
const char *Message = FLANGID( LNG_NotEnouth );

Использовать этот указатель как обычную строку, не зависимо от того чем это значение реально является - номером или строкой, позволяет функция FGetMsg:

CONSTSTR FGetMsg( CONSTSTR String ) {
  if ( FISID(String) )
   return Info.GetMsg(Info.ModuleNumber,FGETID(String));
  else
   return String;
}

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

Assert( String );
или
if ( !String ) return "";
В зависимости от того, какой реакции от функции вы хотите.

Класс оперирования диалогами.

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

Проанализировав использующиеся у меня диалоги, и рассмотрев необходимые поля, которые она должна содержать, я реализовал ее так:

#define FFDI_FOCUSED   0x00010000UL
#define FFDI_SELECTED  0x00020000UL
#define FFDI_DEFAULT   0x00040000UL

STRUCT( FDialogItem )
  DWORD    Type;
  int      X1;
  int      Y1;
  int      X2;
  int      Y2;
  DWORD    Flags;
  CONSTSTR Text;
};

Где флаги FDI_XXX добавляются к типу объекта и заменяют соответствующие названию поля оригинальной структуры, т.к. во-первых, нужны они далеко не всегда, и, во-вторых, раз уж заниматься минимизацией, то это барство - для хранения одного бита использовать 32.

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

Дополнительно, с целью уменьшить количество текста вида "0,0,0,..." можно использовать макросы для целевого описания типовых элементов диалога.

#define FDI_CONTROL( tp,x,y,x1,y1,fl,txt )    { tp,x,y,x1,y1,fl,txt }
#define FDI_LABEL( x,y,txt )                  FDI_CONTROL( DI_TEXT,x,y,0,0,0,txt )
#define FDI_COLORLABEL( x,y,clr,txt )         FDI_CONTROL( DI_TEXT,x,y,0,0,DIF_SETCOLOR|(clr),txt )
#define FDI_EDIT( x,y,x1 )                    FDI_CONTROL( DI_EDIT,x,y,x1,y,0,NULL )
#define FDI_DISABLEDEDIT( x,y,x1 )            FDI_CONTROL( DI_EDIT,x,y,x1,y,DIF_DISABLE,NULL )
#define FDI_CHECK( x,y,txt )                  FDI_CONTROL( DI_CHECKBOX,x,y,0,0,0,txt )
#define FDI_RADIO( x,y,txt )                  FDI_CONTROL( DI_RADIOBUTTON,x,y,0,0,0,txt )
#define FDI_STARTRADIO( x,y,txt )             FDI_CONTROL( DI_RADIOBUTTON,x,y,0,0,DIF_GROUP,txt )
#define FDI_BUTTON( x,y,txt )                 FDI_CONTROL( DI_BUTTON,x,y,0,0,0,txt )
#define FDI_DEFBUTTON( x,y,txt )              FDI_CONTROL( DI_BUTTON|FFDI_DEFAULT,x,y,0,0,0,txt )

Их назначение:

  • FDI_CONTROL( Тип,x,y,x1,y1,Флаги,Текст )
    описание произвольного объекта диалога
  • FDI_LABEL( x,y,Текст )
    описание метки (неактивного текста)
  • FDI_COLORLABEL( x,y,Цвет,Текст )
    описание цветной метки
  • FDI_EDIT( x,y,x1 )
    описания поля редактирования
  • FDI_DISABLEDEDIT( x,y,x1 )
    описание поля редактирования в ReadOnly режиме
  • FDI_CHECK( x,y,Текст )
    описание переключателя
  • FDI_RADIO( x,y,Текст )
    описание элемента выбора
  • FDI_STARTRADIO( x,y,Текст )
    описание первого элемента выбора
  • FDI_BUTTON( x,y,Текст )
    описание кнопки
  • FDI_DEFBUTTON( x,y,Текст )
    описание кнопки по умолчанию

Пример использования описания диалога, используя эту структуру хранения:

bool DoConfigure( void )
{
  static FDialogItem itm[] = {
      FDI_CONTROL( DI_SINGLEBOX, 0, 0,70,14,  0, "Caption" ),
    FDI_DEFBUTTON( 58,13, "  O&K  " ),
        FDI_LABEL(  2, 1, "&Options" ),
        FDI_CHECK(  3, 2, "Show hidden files" ),
        FDI_LABEL( 10, 5, "Tree &width" ),
         FDI_EDIT(  5, 5, 8 ),
        FDI_LABEL( 38, 1, "&Action functional keys" ),
       FDI_BUTTON( 39, 2, "&Normal" ),
       FDI_BUTTON( 39, 3, "&Control" ),
       FDI_BUTTON( 39, 4, "A&lt" ),
     };
    ...
}

Очень похоже на оригинал за тем исключением, что немного более читабельно, не так ли ?

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

ФАР требует, чтобы элементы которые будут переданы в Dialog были расположены в непрерывном массиве.

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

Для реализации этой организации можно использовать разные методы, от глупостей типа:

static FarDialogItem *LastItems = NULL;
FarDialogItem *AllocFarDialogItems( int Count );
до реализаций массивов из STL.

Первого я боюсь, а второе ненавижу, поэтому остановимся на среднем варианте.

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

template <class T> class RefArray {
  T   *items;
  int  count;
 public:
  MyRefArray( int Count ) { items = new T[ count = Count ]; memset(items,0,sizeof(T)*count); }
  virtual ~MyRefArray()   { delete[] items; }

  T     *Item( int num )       const { return (T*)((num >= 0 && num < count)?(items + num):NULL); }
  T     *operator[]( int num ) const { return Item(num); }
  int    Count( void )         const { return count; }
  T     *Items( void )         const { return (T*)items; }
};

И организуем работу с нашими данными, используя этот шаблон:

class FDialog : public RefArray<FarDialogItem> {
  public:
    FDialog( int NumElemens );
    FDialog( int NumElemens,PFDialogItem Elements,int FNumElements = -1 );

    PFarDialogItem Setup( int num,const FDialogItem& p );
    void           Setup( int From,PFDialogItem p,int count );

    int            Execute( int w,int h,CONSTSTR Help = NULL );
};

который умеет следующее:

  • FDialog( int NumElemens )
    создает массив из NumElemens пустых элементов
  • FDialog( int NumElemens,PFDialogItem Elements,int FNumElements = -1 )
    создает массив из NumElemens пустых элементов, в первые FNumElements или NumElemens которых записывает данные из массива структур FDialogItem
  • PFarDialogItem Setup( int num,const FDialogItem& p );
    Записывает в элемент массива num данные из структуры DialogItem
  • Setup( int From,PFDialogItem p,int count );
    Записывает все элементы количеством count в элементы массива начиная c From
  • Execute( int w,int h,CONSTSTR Help = NULL );
    выполняте центрированный диалог с заданными размерами и возвращает результат выполнения

Реализация методов описана ниже. Обратите внимание на то, что в функции FDialog::Setup используется

StrCpy( p->Data,FGetMsg(it.Text),sizeof(p->Data) );
т.е. строка, которую задали в структуре FDialogItem может быть как реальной константной строкой, так и результатом использования макроса FLANGID. Таким образом, чтобы сделать диалог с поддержкой языков средствами ФАР нужно всего лишь изменить явное использование строки на макрос FLANGID с той константой, которую вы будете использовать для этой строки.
FDialog::FDialog( int NumElemens )
  : RefArray<FarDialogItem>(NumElemens)
{}
FDialog::FDialog( int NumElemens,PFDialogItem Elements,int FNumElements )
  : MyRefArray<FarDialogItem>( NumElements )
 {
   Setup( 0,Elements,(FNumElements==-1)?NumElements:FNumElements );
}
void FDialog::Setup( int From,PFDialogItem p,int ECount )
  {
    for ( int n = 0; n < ECount; n++ )
      Setup( From+n,p[n] );
}
PFarDialogItem FDialog::Setup( int num,const FDialogItem& it )
  {  PFarDialogItem p = Item(num);
     if ( !p ) return NULL;
       p->Type           = (int)(it.Type & 0xFFFF);
       p->X1             = it.X1;
       p->Y1             = it.Y1;
       p->X2             = it.X2;
       p->Y2             = it.Y2;
       p->Focus          = IS_FLAG(it.Type,FFDI_FOCUSED);
       p->Selected       = IS_FLAG(it.Type,FFDI_SELECTED);
       p->Flags          = it.Flags;
       p->DefaultButton  = IS_FLAG(it.Type,FFDI_DEFAULT);
       strcpy( p->Data,FGetMsg(it.Text),sizeof(p->Data) );
 return p;
}
int FDialog::Execute( int w,int h,CONSTSTR Help )
  {
 return Info.Dialog( Info.ModuleNumber,-1,-1,w,h,
                     (char*)Help,
                     (PFarDialogItem)Items(),
                     Count() );
}

Примеры использования

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

Выглядит на экране ФАРа это так:

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

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

bool GetKeyMaskDialog( CONSTSTR KeyName,DWORD& Mask,DWORD Hide )
  {  static FDialogItem itm = FDI_CONTROL( DI_DOUBLEBOX,0,0,50,3,0,NULL );
     static FDialog     dlg( FK_MAX*2+1,&itm,1 );

     int                n;
     PFarDialogItem     it;
     DWORD              dw;

#define IT_CAPTION  0
#define IT_FN       1

//Create FKey labels
     if ( dlg[IT_FN]->Type != DI_RADIOBUTTON )
       for ( n = 0; n < FK_MAX; n++ ) {
        //Labels
         it = dlg[ IT_FN + n*2 ];
         it->Type  = DI_TEXT;
         it->X1    = 2 + n*4;
         it->X2    = 2 + n*4 + 4;
         it->Y1    = it->Y2 = 2;
         if ( n < 9 )
           sprintf( it->Data,"F&%d",n+1 );
          else
           sprintf( it->Data,"F%d",n+1 );
        //Radio
         it = dlg[ IT_FN + n*2 + 1 ];
         it->Type  = DI_CHECKBOX;
         it->X1    = 2 + n*4;
         it->X2    = 2 + n*4 + 4;
         it->Y1    = it->Y2 = 1;
       }
//Setup
     strcpy( dlg[IT_CAPTION]->Data,FGetMsg(KeyName) );
     for ( n = 0; n < FK_MAX; n++ ) {
       it = dlg[IT_FN + n*2 ];
         it->Flags    = IS_FLAG(Hide,1UL<<n)?DIF_DISABLE:0;
       it = dlg[IT_FN + n*2+1 ];
         it->Selected = IS_FLAG(Mask,1UL<<n);
         it->Flags    = IS_FLAG(Hide,1UL<<n)?DIF_DISABLE:0;
     }
//Dialog
     n = dlg.Execute( 50,3,NULL );
     if ( n == -1 ) return false;
//Grab data
     dw = 0;
     for ( n = 0; n < FK_MAX; n++ )
       if ( dlg[IT_FN + n*2+1 ]->Selected ) SET_FLAG( dw,1UL<<n );

     if ( dw != Mask ) {
       Mask = dw;
       return true;
     } else
       return false;
}

Приложения

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

#define MAX_WORD                  ((WORD)0xFFFFU)
#define MK_WORD( lb,hb )          ((WORD)(((((WORD)(hb))&0x00FFU) << 8) |(((BYTE)(lb))&0x00FFU)))
#define MK_DWORD( lw,hw )         (((((DWORD)hw)&0x0000FFFFUL) << 16) |(((WORD)lw)&0x0000FFFFUL))
#define MK_ID( v,v1,v2,v3 )       MK_DWORD( MK_WORD(v,v1),MK_WORD(v2,v3) )
#define PRESTRUCT( cl )           typedef struct cl *P##cl; struct cl
#define PRECLASS( cl )            typedef class cl *P##cl; class cl
#define STRUCT( name )            PRESTRUCT(name) {
#define CLASS( name )             PRECLASS(name) {
#define IS_FLAG( val,flag )       (((val)&(flag))==(flag))
#define SET_FLAG( val,flag )      (val |= (flag))
#define CLR_FLAG( val,flag )      (val &= ~(flag))
#ifndef bool
  #define bool BOOL
  #define true TRUE
  #define false FALSE
#endif
typedef const char *CONSTSTR;

21.02.2001
наверх


Как уменьшить размер плагина: Microsoft VC++ 6.0

Как уменьшить размер плагина

(на примере Microsoft VC++ 6.0)
главная | статьи
Олег Данилов aka DO dosoft@mail.ru
«Mala herba cito crestis»
(Сорная трава быстро растет - лат.)

Введение.

Прошло уже несколько лет с тех пор, когда красивой программой считалась программа маленькая. Канули в лету XT, 286 и 386, процессор 486 можно найти лишь дома у любителей старины, а одних только Pentium'ов сменилось несколько штук. Не модно стало писать маленький код, напротив, чем больше компакт-дисков занимает ваше творение, тем лучше. Тем не менее, в этой статье я хотел бы слегка уделить внимание такой теме, как оптимизация. Очевидно, что оптимизировать мы будем плагин для Far'а. Менее очевидно, но все же это факт — для компиляции будет использоваться Microsoft Visual C++ 6.0. Выбор сделан был не случайно, у данного компилятора есть одно, неоспоримое достоинство — он установлен как на моем домашнем компьютере, так и на рабочем. К тому же VC достаточно подробно описан в MSDN, а я без этой библиотеки и шагу ступить не могу, поскольку ни языка C++ ни Win API абсолютно не знаю ;) Кстати, в связи с последним, сразу уточнение — изложенный ниже материал не претендует на полноту. И даже в некотором роде не претендует на правильность. Сформулируем так — у меня это заработало и позволило уменьшить размер получившегося плагина в несколько раз.

Этапы большого пути.

Шаг 0. Все функции, используемые, в плагине были заменены на аналогичные из Win API: strcpy на lstrcpy и т.д. К сожалению, история не сохранила исходный размер плагина, поэтому оценить экономию на этом шаге затруднительно.

Шаг 1. Документ VCReadme.txt из архива PlugDoc.rar, входящего в поставку Far'а (ред: начиная с FAR 1.70 beta 5 примеры устанавливаются в отдельный каталог PlugDoc), содержал первоначальную информацию, которая помогла мне успешно скомпилировать свой плагин «ScanDir». Оттуда я вынес следующее:

cl /Zp2 /LD ScanDir.cpp /link /def: ScanDir.def kernel32.lib advapi32.lib

Что получилось в результате — dll размером 30 килобайт. По нынешним меркам — не размер для программы, но…

Шаг 2. Включаем оптимизацию по размеру:

cl /O1 /Zp2 /LD ScanDir.cpp /link /def: ScanDir.def kernel32.lib advapi32.lib

Сути дела это не изменило. Будем считать ключ /O1 ритуальным обрядом, вызывающим бога оптимизации. Безуспешно…

Шаг 3. Пришлось взять в руки скальпель, коим выступила программа DUMPBIN и препарировать полученный файл ScanDir.dll. Вот, что меня там заинтересовало:

OPTIONAL HEADER VALUES
…
1000 section alignment
1000 file alignment
…

Summary

1000 .data
1000 .rdata
1000 .reloc
4000 .text

О чем это говорит? Только о том, что в данной программе есть четыре секции (section), каждая из которых выровнена на границу 0x1000. То есть, теряем мы тут в среднем 4*0x800 = 8Кб. Реально же после компиляции

cl /O1 /Zp2 /LD ScanDir.cpp /link /opt:nowin98 /def: ScanDir.def kernel32.lib advapi32.lib

размер ScanDir.dll уменьшился до 19Кбайт. Параметр /opt:nowin98 привел к тому, что выравнивание стало равно 0x200, а плагин существенно «похудел»

Шаг 4. Теперь настала очередь MAP-файла. Из него можно извлечь некоторую полезную информацию:

…
0001:00000a1f __CRT_INIT@12 10001a1f f LIBCMT:dllcrt0.obj
0001:00000af8 __DllMainCRTStartup@12 10001af8 f LIBCMT:dllcrt0.obj
0001:00000b95 __amsg_exit 10001b95 f LIBCMT:dllcrt0.obj
0001:00000bc8 __cinit 10001bc8 f LIBCMT:crt0dat.obj
0001:00000bf5 __exit 10001bf5 f LIBCMT:crt0dat.obj
…
0001:0000342d __seh_longjmp_unwind@4 1000442d f LIBCMT:exsup3.obj
…

Это не что иное, как startup code — код, проводящий инициализацию, необходимую при использовании функций из стандартных библиотек. Но я к этому моменту эти функции не использовал (см. Шаг 0). Потому вполне логичным было следующее:

cl /O1 /Zp2 /LD ScanDir.cpp /link /opt:nowin98 /noentry /def: ScanDir.def kernel32.lib advapi32.lib

Что я получил? ScanDir.dll размером 5120 байт!

Шаг 5. Все вышеперечисленное достаточно универсально и подойдет для любых плагинов. Теперь же начинаем экономить на мелочах, с учетом особенностей конкретной программы. Смотрим в MAP-файле, что из стандартных функций до сих пор используется:

…
0001:00000990 _memset 10001990 f LIBCMT:memset.obj
0001:000009f0 __chkstk 100019f0 f LIBCMT:chkstk.obj
0001:000009f0 __alloca_probe 100019f0 f LIBCMT:chkstk.obj
…

memset на самом деле вызывается всего пару раз, при этом накладные расходы по вызову функции достаточно велики по отношении к ее размеру. Логично было бы воспользоваться ключиком /Oi, который указывает, что вызовы ряда функций (memset, strcpy, abs и др.) надо заменять на ассемблерный код, который очень и очень лаконичен для функций такого рода.

cl /O1 /Zp2 /LD /Oi ScanDir.cpp /link /opt:nowin98 /noentry /def: ScanDir.def kernel32.lib advapi32.lib

Что такое chkstk? Как следует из названия — это проверка стека. Локальные переменные, как известно размещаются на стеке и если в одной из функций, общий размер переменных превышает 4K, то компилятор генерирует вызов chkstk, для того, чтобы гарантировать, что размер стека достаточен для них. Разумеется, это правильно и повышает надежность работы программы. Но моя статья рассказывает об оптимизации, поэтому chkstk — долой! Для этого укажем, чтобы вызов chkstk производился только при достижении 10K, чего заведомо в моей программе случиться не должно.

Ну а чтобы быть уверенным, что при сборке не используются никакие библиотеки, кроме указанных явно, зададим ключ /NODEFAULTLIB:

cl /O1 /Zp2 /LD /Oi /Gs10000 ScanDir.cpp /link /opt:nowin98 /noentry
   /nodefaultlib /def: ScanDir.def kernel32.lib advapi32.lib

Общая экономия на этом шаге — 512 байт.

Шаг 6. (Не надоело? Терпите, осталось чуть-чуть). Разумеется, memset и chkstk не занимали все 512 байт, это — результат выравнивания секций, о котором говорилось выше. А таких секций целых четыре. Попробуем уменьшить их число, ведь чем меньше секций, тем меньше выравниваний и тем меньше будут потери. Ясно, что .reloc лучше не трогать, она используется Windows в своих целях, а остальные можно попытаться объединить в одну:

cl /O1 /Zp2 /LD /Oi /Gs10000 ScanDir.cpp /link /opt:nowin98 /noentry
   /merge:.rdata=.text /merge:.data=.text
   /nodefaultlib /def:ScanDir.def kernel32.lib advapi32.lib

Заключение.

Тут, пожалуй, пока и остановимся. Итоговый размер плагина — 4K. Это не так уж много для программы, которая в процессе работы создает на экране диалог, вызывает внешние программы, работает с реестром, обменивается информацией с Far'ом. Можно ли еще на чем-нибудь сэкономить, и где предел? Попробуем посчитать: 1K ушел на заголовок dll, с ним сделать уже ничего нельзя, 0.5K — на секцию .reloc, и что с ней делать — не очень ясно. Итого остается для дальнейшей оптимизации 2.5 килобайта. А это не так уж мало — целых 2560 байт… Быть может, когда-нибудь…

дополнения от Eugene Yavorsky

29.01.2001
наверх


Отладка плагинов в Borland Turbo Debugger

главная | статьи
Вячеслав Печенин slava@baltica.ru

Borland Turbo Debugger (далее TD) - бесплатная альтернатива встроенным отладчикам из коммерческих сред разработки (e.g., MSVC или BCB). Скачать можно здесь.

Замечания

1. TD поможет отладить только то, что получено компилятором BCC 5.5 (взять можно здесь, патчи здесь).

2. TD - консольное приложение (удивляться этому особенно не нужно; Far, если вы заметили, тоже не особенно GUI) для отладки только Win32 приложений. И тем не менее совсем не дружит с кодовой страницей OEM (см.подробнее). По сему применять этот отладчик сложнее, чем интегрированные в IDE.

Рабочий цикл отладки

1) Сборка .DLL, включая отладочную информацию.

2) Открываете хост-приложение FAR.EXE

3) Обращаете внимание TD на вашу .DLL

4) Ставите breakpoints.

5) На остановках делаете дело.

1) Сборка

Компилятор. Нужно, чтобы BCC поместил в результат debug info и line info. Первое включено по умолчанию (или "-v" для параноиков), второе включается руками "-y".

Редактор связей. Он по умолчанию помещает в результат только самое нужное. Чтобы Debug info попало в эту категорию используйте ключик "-v".

Итого:
bcc32 -c -v -y Hello.cpp
ilink32 -Tpd -v c0d32.obj Hello.obj,Hello.dll,,cw32.lib import32.lib

2) Запускаем хост приложение под TD

Перед тем, как запускать TD, не забудьте, что FAR.EXE должен будет по ходу дела подгрузить вашу .DLL как плагин. Поместите вашу .DLL и .TDS файлик куда нужно. .TDS ссылается на ваши исходники, которые TD найдет там, куда укажет ключик "-sd".

Также неплохо, чтобы TD текущей директорией сделал ту, где лежит .DLL, которую подхватит FAR.EXE. Ключик "-t".

Итого:
td32 -sd"C:\Hello Plugin\Source" -t"C:\Program files\Plugins\Hello" "C:\Program files\Far\Far.exe"

3) Остановка "entry point"

TD остановится с сообщением, что FAR.EXE не содержит debug info. Это - правда. Да и хорошо, что остановится: время предупредить TD, чтобы сделал позже еще одну остановку - тогда проставим breakpoints в HELLO.DLL.

Давим F3 (меню VIEW->MODULE...).

В поле "DLL name" можно ввести: "hello" или "hello.dll" или даже "c:\path\hello.dll" (если ключик "-t" вы не захотели TD указать).

Жмите "Add DLL", не стесняйтесь.

Больше этот диалог не нужен. ESC на него. И продолжим - F9 (Run->Run).

Вопрос: зачем же руками TD сообщать о DLL, которую чуть позже FAR.EXE загрузит?

Ответ: а за тем, что TD выставил флажок "debug startup" (посмотрите сами), и сделает нужную нам остановку, когда FAR.EXE действительно подгрузит HELLO.DLL

4) Breakpoints

TD остановится на входе в HELLO.DLL

Ба-а-а, что же мы видим - дизассемблерованный код. Зачем он нам, какой от него толк? Не все сразу, потерпите.

Давим F3.

HELLO.DLL -> "Symbol load" (вот и пригодился .TDS файлик)

Oops, диалог пропал. А ничего не произошло.

Давим опять F3. И видим, что не зря только что диалог пропадал:

Список "Source modules" пополнился. Выбираешь модуль, давишь "Load" и попадаешь в его исходник, все логично. А попав в исходник, не теряйся, ставь breakpoint.

Замечания.

* Временами попав в исходник, TD не дает поставить breapoint. Тогда нужно сходить в меню VIEW->VARIABLES и найти нужную ф-цию там.

** Все расставленные остановки сохранятся в .TR2, который как-то связывается с .TDS. Так что пересобрав .DLL, а значит получив новый .TDS, или удалив .TR2 - вы потеряете всю информацию об остановках. И все с начала...

5) Отладка

Здесь все делается, как обычно в инструментах от Borland. Единственно, что я для себя с удивлением открыл: неутомимый "Inspect" - можно встать курсором на символьном имени и правой кн. мыши проинспектировать, а там опять же можно проинспектировать и т.д.

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

Будучи консольным приложением TD показывает все строчки в ANSI. Это не значит для плагинописания ничего хорошего, ведь Far и плагины, следуя его правилам, все показывает в OEM. Как победить TD в этом вопросе - я не знаю. Небольшой совет: в диалоге Evaluate/Modify (@F4) введите "lpstr[0],c10" и увидите свою строчку в OEM. Этот же фокус поможет для Watch. А для Inspect не поможет.

Заключение

Самое интересное, что несмотря на рутинную ботву в работе с TD, я им пользуюсь. Потому что:

  • TD - полностью удовл. нужды в отладке.
  • TD - это продукт традиционно высокого качества от Borland.
  • TD - бесплатный.

Дополнительные источники

  • Официальная страница Borland про компилятор BCC
  • Официальная страница Borland про отладчик TD
  • Ньюсгруппа, посвященная BCC 5.5

Rev. 24.12.2000
наверх


Упаковщики - ЗА и ПРОТИВ

главная | статьи
Jordan Russell

Многие посетители моей страницы часто спрашивают следующее:

"Если я хочу уменьшить размер своей программы, то почему бы ни использовать EXE компрессор? Это позволит сделать размер EXE значительно меньше, чем использование StripReloc! Почему вы против этого"

Многие не понимают (или просто не знают), что при использовании Компрессоров типа ASPack и UPX они многое теряют. По моему мнению EXE компрессоры это не то, что следует применять бездумно. Позвольте разъяснить.

В DOS, когда вы запускаете программу, весь ее код загружается с диска В оперативную память и остается в ней до конца. Если не хватает памяти для загрузки всей программы, то вы получите сообщение об ошибке "out of memory".

Современные многозадачные Операционные Системы (ОС), такие как Windows 95/98 и NT используют метод названный "Виртуальная память" (virtual memory). Когда программа загружается, то в память сразу не грузится весь код, как в случае DOS программ. Вместо этого загружается только часть кода, которая требуется для исполнения. Например, ваша программа имеет пункт меню "Print" и код назначенный, который исполняется при выборе этого пункта. Этот код загружается в память только когда пользователь выбирает данный пункт. И если после загрузки кода в память он не используется некоторое время, то код выгружается из памяти, память освобождается и может быть использована другими программами. Данный процесс называется "paging" и полностью прозрачно для программы.

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

Если бы Win32 вели бы себя как DOS программы, то есть загрузка всего кода в память и оставались бы там до завершения и также бы не разделяли память для разных экземпляров программы, вы бы быстро исчерпали всю доступную память.

Вот именно это и делают текущие Win32 EXE компрессоры! Они полностью блокирую работу метода "paging" разжимая весь код в память и сохраняя его там до конца работы программы. И поскольку код в упакованном EXE файле хранится не в обычном "raw" формате (то есть в том виде какой он в памяти), то ОС не в состоянии разделять тот же блок памяти для нескольких экземпляров программы. Многие используют EXE компрессоры как сильное оружие для уменьшения потерь под размер на диске, но я хочу спросить: Что более накладно - мегабайты на диске или мегабайты оперативной памяти? Действительно ли стоит увеличивать требования вашей программы на оперативную память за счет сохранения несколько килобайт дискового пространства?

Тест

Я слышал, что многие сжимаю свои EXE из MS Office, поэтому я решил провести тест по реальному использованию памяти именно на MSACCESS.EXE. Я сжал MSACCESS.EXE из Office 2000 с помощью UPX и сравнил использование памяти с помощью NT 4.0's Task Manager...
Ниже приведены (удивительные) результаты теста.

 | File Size | Process "Mem Usage" 1 instance | "Commit Charge Total" 1 instance difference | "Commit Charge Total" 20 instances difference
uncompressed | 4,677,686 | 2580 KB | 1084 KB | 25396 KB
UPX 0.82 | 2,436,096 | 6852 KB | 6192 KB | 126968 KB

Опираясь на 1 экземпляр результаты показанные выше, показываю что: сжатый MSACCESS.EXE забирает на 5MB больше памяти. Ну не так уж плохо, но уже ощутимо.

Но вот уже для 20 экземпляров результат следующий. Да вы читаете правильно. Это не типографская ошибка!!! Для 20 экземпляров сжатого MSACCESS.EXE требуют на 100 Мб больше, чем не сжатый.

Мой тест был сделан на машине с 256MB оперативной памяти, желаю удачи при проведении теста на машине с 64 Мб память. Для запуска 20 экземпляров MSACCESS.EXE я использовал 20 строчный bat файл, каждая строка которого содержала следующий тест: "START MSACCESS.EXE". Плохая весть: запуск 20 экземпляров MSACCESS.EXE немного больше времени (4 секунды против 1.5), которое я отношу на счет взаимного использования кода между экземплярами и времени требуемым на распаковку программы. Это показывает, что малый размер файла не гарантирует более быструю загрузку.

Поскольку я делал фокус на тестирования кода, я использовал следующие ключи для UPX: --compress-exports=0 --compress-icons=0 --compress-resources=0. Я планировал протестировать и ASPack, но запустить сжатый MSACCESS.EXE не удалось. Но я думаю, что результат был бы сравним с UPX, также я не пробовал тестировать другие упаковщики.

Заключение

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

Дополнение от 20 апреля 2000

  1. Другой недостаток использования EXE компрессоров, не отмеченный выше, это то что многие старые сканеры вирусов считаю, что в эти упакованные файлы заражены вирусом, (некоторые из них докладывают "неизвестный вирус", некоторые "Win32.BackDoor"). Это было основной причиной для отказа использования в моем инсталляторе "Inno Setup", а не по причине расточительного использования памяти. Я был очень огорчен ругательными письмами, которые я стал получать по поводу распространения вирусов. Я даже был обозван лжецом, когда пытался объяснить это. Пришлось даже увидеть предупреждение на некоторых сайтах, о том, что "Inno Setup" может содержать вирус. Как результат, использование EXE компрессоров может привести к потере бизнеса или подрыву репутации.
  2. Я конечно не думаю, что кто то будет запускать 20 экземпляров MS Access одновременно. Это было сделано с целью иллюстрации, что затраты на память возрастаю экспоненциально при запуске нескольких экземпляров. В большинстве случаев не запускают нескольких экземпляров программ, но DLL часто загружаются и используются одновременно несколькими программами. Взаимное использование кода относится и к DLL также, о чем я забыл упомянуть в статье.
  3. Многие люди спрашивают, "а как насчет Shrinker?" Blink, Inc. преподносит, что Shrinker "единственный продукт, который распаковывает EXE блоками по требованию (ON DEMAND), а не при запуске программы", и это объясняет почему распаковщик занимает примерно 30 килобайт для каждой программы. Мои начальные тесты со Shrinker были неполными и проведу дополнительное тестирование Shrinker в будущем.

Примечание переводчика:
Джордан Рассел (Jordan Russell) автор программ и компонент Inno Setup, StripReloc, ToolBar97, ToolBar 2000
Оригинал находится http://www.jordanr.dhs.org/striprlc.htm

Перевод: Анатолий Подгорецкий
anatoly@podgoretsky.com
http://nps.vnet.ee

21.04.2000
См. также статью Криса Касперски "Паковать или не паковать?"
(http://www.programme.ru/index.phtml?arch/102001/102001_1.htm) .

наверх


Плагин для разных версий FAR Manager.

главная | статьи
FAR Group

С выходом в свет FAR manager версии 1.70 произошли некоторые изменения в части инициализации плагина (что ни в коем случае не скажется на работоспособности ранее написанных плагинов), хотя старый метод инициализации также остался работоспособным. После добавления в PluginStartupInfo указателя на структуру FSF, содержащей указатели на стандартные функции FAR, стало возможным уменьшить размер плагинов за счёт использования функций, находящихся в теле Far.exe. Использование новой экспортной функции GetMinFarVersion позволяет осуществлять контроль за версией FAR со стороны плагина. Теперь немного примеров.

Для начала корректно напишем функцию SetStartupInfo:

char PluginRootKey[80];
static struct PluginStartupInfo Info;
static struct FarStandardFunctions FSF;

void WINAPI SetStartupInfo(struct PluginStartupInfo *PSInfo)
{
  if(PSInfo->StructSize >= sizeof(struct PluginStartupInfo))
  {
    Info=*PSInfo;
    FSF=*PSInfo.FSF;
    Info.FSF=&FSF;
    ...
  }
  else
    memcpy(&Info,PSInfo,PSInfo->StructSize);
}

Начиная с FAR 1.70 нужна функция GetMinFarVersion, при этом FAR сам проследит за запуском плагина.

int WINAPI GetMinFarVersion(void)
{
  return FARMANAGERVERSION;
}

Естественно, что пуская плагин в 1.65 (и ниже) FAR не отреагирует на GetMinFarVersion - про эту функцию он просто не знает. Поэтому...

Следующий шаг - GetPluginInfo (или OpenPlugin). Если предполагается, что плагин будет работать только с планируемой версией FAR Manager (и выше), то достаточно выдать об этом сообщение и вывалить, если версия меньше планируемой - сравнить размер структуры PluginStartupInfo с полем PluginStartupInfo.StructSize:

void WINAPI GetPluginInfo(struct PluginInfo *Info)
{
  if(Info.StructSize < sizeof(struct PluginStartupInfo))
  {
    // Выводим сообщение: "Этот плагин требует FAR Manager версии N.NN и выше!"
    return;
  }
  .
  .
  .
}

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

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

дополнения от Eugene Yavorsky

02.11.2000
наверх


Как самому сделать plug-in к FAR на Visual C++
шаг за шагом

главная | статьи
Phoenix aka Руслан Ильгасов phoenixbird@hotmail.ru

Трудно найти человека, которые не знает или не использует Far - IMHO лучший клон NC для Windows. Кроме того, что это просто очень хороший файл менеджер, к нему есть огромное количество plug-in модулей. Plug-in модуль это DLL-файл, который вместо стандартных Windows функций по работе с монитором, клавиатурой и т.д. обращается к функциям Far-а. Far поддерживает весь набор функций для работы в текстовом режиме. Установка plug-in модуля происходит предельно просто - DLL файл и файлы данных копируются в каталог в каталоге Far\Plugins и Far перезапускается.

FAR распространяется с полным набором файлов для написания самим plug-in на любом С компиляторе для Windows. Темой этой статьи является написание этих модулей самим на Visual C++ (я использовал Visual C++ 5.0). При установке в каталог Far копируется PlugDoc.rar, в нем есть примеры plug-in-ов и header файл (ред: начиная с FAR 1.70 beta 5 примеры устанавливаются в отдельный каталог PlugDoc). Все примеры используются Еще там есть VCReadme.txt, в котором описываются тонкости работы с Visual C++. Потом поразбираетесь с примерами.

Мы с вами напишем plug-in, который получает список открытых окон Windows, он может пригодиться как заготовка для своих. И вообще - стоит начать - все это не так сложно, как можно подумать. Вот, а теперь - поехали:

  1. Запускает VC, делаем новый проект типа "Win32 Dynamic-Link Library" по имени SimpleFP. Создает файл simplefp.cpp - здесь, собственно, мы и будем писать. В каталог SimpleFP копируем header файл plugin.hpp из архива PlugDoc.rar (ред: начиная с FAR 1.70 beta 5 примеры устанавливаются в отдельный каталог PlugDoc).
  2. Теперь нам надо сделать .def файл - это файл, в котором описываются функции, которые вызываются из внешних модулей. Мы должны описать функции Far-а, которые мы будем использовать в нашем модуле. Делаем текстовый файл simplefp.def, в котором пишем:
    LIBRARY
EXPORTS
GetPluginInfo=_GetPluginInfo@4
OpenPlugin=_OpenPlugin@8
SetStartupInfo=_SetStartupInfo@4
    Здесь мы описываем 3 функции, которые нам пригодятся. А теперь добавим simpledef.def к файлам проекта (Project - Add to project - Files - simplefp.def).
  3. Теперь пишем сам plug-in - работаем с файлом simplefp.cpp. Я решил дать текст самой программы с комментариями - можно скопировать в С++ и начать с ним возиться. Но сначала о основах.

Far работает по тем же принципам, что и Windows - вы ссылаетесь в программе на те функции, уже имеющиеся в системе, которые хотите использовать. Far предоставляет функции для работы с экранными формами в режиме console application. При запуске plug-in-а Far запускает функцию OpenPlugin, мы будем ее рассматривать как аналог main() или WinMain(). Но кроме этого надо еще сообщить Far-у данные о нашем plug-in-е. Это делает функция GetPluginInfo.

/*
* SimpleFP - простой plug-in к Far-у. (С) 2000 Phoenix, Moscow
*/

#include <stdio.h>    // для вызова sprintf
#include <windows.h>  // для функций Windows
#include "plugin.hpp" // для функций Far

#define PLUGIN_NAME "Open windows"      // Название plug-in-а
#define WINDOW_HEAD "Open windows list" // Заголовок меню, которое мы сделаем

//
// Описываем функции Far, которые с которыми мы работаем.
//

extern "C"
{
void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info);
HANDLE WINAPI _export OpenPlugin(int OpenFrom,int Item);
void WINAPI _export GetPluginInfo(struct PluginInfo *Info);
};

static struct PluginStartupInfo Info; // Информация о нашем plug-in-е

//
// Информация о модуле определена нами в структуре Info
//

void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info)
{
  ::Info=*Info;
}

// Эта функция вызывается для получения информации о plug-in.
// Мы должны заполнить поля структуры Info.
//

void WINAPI _export GetPluginInfo(struct PluginInfo *Info)
{
  Info->StructSize=sizeof(*Info); // Размер структуры Info
  Info->Flags=0; // Это нам не нужно
  Info->DiskMenuStringsNumber=0; // Это нам тоже не нужно

  // Определяем строку с названием модуля
  static char *PluginMenuStrings[1];
  PluginMenuStrings[0]= PLUGIN_NAME;

  // Определяем название plug-in модуля
  Info->PluginMenuStrings=PluginMenuStrings;
  Info->PluginMenuStringsNumber=
    sizeof(PluginMenuStrings)/sizeof(PluginMenuStrings[0]);
  Info->PluginConfigStringsNumber=0; // Это нам не нужно
}

// Эта функция вызывается при запуске plug-in модуля.
//

HANDLE WINAPI _export OpenPlugin(int OpenFrom,int Item)
{
  HWND hwnd; // Используем для получения handle
  char p[128], o[128]; // Для создания строк меню
  int i=0; // Счетчик

  struct FarMenuItem MenuItems[64]; // Описание меню, которое создаст для нас Far
  memset(MenuItems,0,sizeof(MenuItems)); // Инициализируем наше меню
  MenuItems[0].Selected=TRUE;

  hwnd = GetDesktopWindow(); // Получаем handle для desktop
  hwnd = GetWindow(hwnd, GW_CHILD); // Получаем его handle
  while (hwnd !=0) // Пока оно не последнее
  {
    hwnd = GetWindow(hwnd, GW_HWNDNEXT); // получим handle окна
    GetWindowText(hwnd,p,128); // и его заголовок
    if (strlen(p)>0) // если заголовок есть
    {
      sprintf(o,"%0.8xld %s", hwnd, p); // сделаем строчку
      strcpy(MenuItems[i++].Text, o); // скопируем эту строчку в массив MenuItems
    }
  }

  // вызываем созданное нами меню, получаем номер выбранного пункта - MenuCode
  //
  int MenuCode=Info.Menu(Info.ModuleNumber,
                  -1,-1,0,
                  FMENU_AUTOHIGHLIGHT|FMENU_WRAPMODE,
                  WINDOW_HEAD,
                  NULL,
                  "Menu content",
                  NULL,
                  NULL,
                  MenuItems,
                  i);

  return(INVALID_HANDLE_VALUE);
}

Компилируйте, копируйте в Far\Plugin и перезапускайте Far. В Far-е нажмите F11 - это список plug-in модулей. Теперь в нем должна появиться строка Open windows. Посмотрите на результат. Теперь можно развивать, например - обрабатывая результат MenuCode посылать выбранному окну сообщение WM_CLOSE, или сделать еще что-нибудь нетривиальное :) Создание plug-in модулей к Far-у документировано замечательно, разбирайтесь.

В поставку Энциклопедии входит архив simplefp.zip - пример DLL файла (~20Кб)

Phoenix aka Руслан Ильгасов, Москва
E-Mail:phoenixbird@hotmail.ru
FIDO: 2:5020/2637.2

13.05.2000
наверх


Распределение памяти. Скромная попытка расставить все по своим местам в этом вопросе.

главная | статьи
Иван Синтюрин spinoza@mail.ru

В очередной раз подняли вопрос о распределении памяти под win32... У меня по этому поводу кое-что накипело, это можно выразить следующей фразой: "С операционной системой следует говорить на ее родном языке!". Конечно, не надо возводить это правило в абсолют, но на самом деле в некоторых случаях лучше не пользоваться языковыми средствами распределения памяти (new, delete, malloc, free, GetMem, FreeMem и т.д.), т.к. их эффективность зависит от конкретного компилятора и может быть неудовлетворительной, а использовать функции из win32 api, тогда глюков будет меньше (если не считать ваши собственные ;), а скорость работы увеличится. Кроме этого вы можете не просто задействовать сервис из win32 api, но и написать свой собственный менеджер памяти, который в вашем конкретном случае будет обеспечивать максимальную эффективность (последнее не описывается в данной статье, читайте книжки ;-).

В win32 используется три механизма управления памятью:

  • виртуальная память - наиболее подходящая для операций с большими массивами объектов или структур;
  • проецируемые в память файлы - наиболее подходящие для операций с интенсивными потоками данных (обычно из файлов) и для совместного использования данных несколькими процессами;
  • кучи или динамически распределяемы области памяти - для удобны при создании множества небольших блоков данных.
Вот о кучах мы немного и поговорим.

Если вы программировали для 16-разрядной Windows, Вам знакомы два типа куч: локальные и глобальные. У каждого процесса и DLL-модуля в ней собственная локальная куча, а единственная глобальная - доступна всем процессам. В win32 есть принципиальные отличия в схеме управления динамически распределяемой памятью:

  • существует только один тип кучи;
  • кучи всегда являются локальными для процесса;
  • к содержимому кучи не может обратиться поток из другого процесса;
  • процессу разрешается создавать несколько куч, являющихся частью его адресного пространства;
  • DLL-модулю собственная куча не выделяется, он использует кучи являющиеся частью адресного пространства процесса, но DLL может создать в нем кучу и использовать ее для себя.

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

Кучи бывают двух видов:

  • Стандартная куча процесса - ее создает система при инициализации win32-процесса. Ее размер по умолчанию - 1 Mb (не забудьте, что DLL-модулям куча по умолчанию не предоставляется). Эта куча используется многими win32-функциями, доступ к куче разрешается только по очереди. Описатель этой кучи возвращает функция GetProcessHeap .
  • Дополнительные кучи. Для чего они нужны: защита компонентов, более эффективное управление памятью, локальный доступ (кому не понял, про что я говорю, - пишите, я поясню). Эти кучи создаются функцией HeapCreate .
Для выделения блока памяти из кучи используют функцию HeapAlloc , для изменения размера блока памяти - HeapReAlloc . Если вы хотите узнать истинный размер выделенного блока памяти, то используйте HeapSize . Не забывайте ;-) освобождать блоки, для этого есть HeapFree . Функция HeapDestroy используется для уничтожения кучи (созданной HeapCreate , стандартную кучу уничтожает операционная система при завершении процесса) - обращение к этой функции приводит к освобождению всех блоков памяти внутри кучи и возврату системе физической памяти и региона адресного пространства, занятого кучей.

Для удобства при написании программ (или при написании портируемых программ) можно переопределить стандартные операторы в C/C++ (btw, размер плагинов также уменьшается, это очевидно...). Например, можно использовать следующее:

typedef unsigned size_t;

HANDLE heapNew_SR; /*эту кучу я создаю в самом начале работы программы*/

void *malloc(size_t size)
{
  return HeapAlloc(heapNew_SR,HEAP_ZERO_MEMORY,size);
}

void *realloc(void *block, size_t size)
{
  void *p=NULL;
  if(heapNew_SR!=NULL)
  {
   if(!size) HeapFree(heapNew_SR,0,block);
   else
   {
    if(block==NULL) p=HeapAlloc(heapNew_SR,HEAP_ZERO_MEMORY,size);
    else p=HeapReAlloc(heapNew_SR,HEAP_ZERO_MEMORY,block,size);
   }
  }
  return p;
}

void free(void *block)
{
  if(block!=NULL && heapNew_SR) HeapFree(heapNew_SR,0,block);
}

void *operator new(size_t size)
{
  size=size?size:1;
  return malloc(size);
}

void *operator new[](size_t size) {return ::operator new(size);}
void *operator new(size_t size, void *p) {return p;}
void operator delete(void *p)
{
 free(p);
}
void operator delete[](void *ptr) {::operator delete(ptr);}

Многие скажут, а как же GlobalAlloc , GlobalFree , GlobalLock и прочие? Ответ прост - это старье и его лучше не использовать в своих программах (можно, если вы пишете под 16-разрядные винды)! Windows поддерживает эти функции только для совместимости со старыми программами. Они работают хуже и медленнее win32-функций, управляющих кучами, и требуют для своей работы дополнительной памяти.

Приведу пример для тех, кому не достаточно просто утверждения. Для поддержки 16-разрядных функций, управляющих глобальными и локальными кучами, каждому процессу при инициализации предоставляется своя таблица описателей и своя стандартная куча, в которой выделяются участки для глобальной и локальной памяти. Эта таблица описателей нужна win32 для управления выделением глобальной и локальной памяти, она является массивом структур, каждый элемент массива указывает на блок памяти, выделенной из стандартной кучи процесса. При вызове GlobalAlloc система выделяет блок из этой кучи и отыскивает свободный элемент в таблице описателей, принадлежащей процессу. Затем сохраняет адрес выделенного блока в таблице описателей и возвращает адрес элемента этой таблицы. Последнее значение, по сути, описатель блока памяти. И когда вы вызовете GlobalLock , система просмотрит таблицу описателей и просто вернет адрес блока памяти, выделенного в стандартной куче процесса. Первоначально win32 отводит небольшой объем памяти, достаточный для хранения буквально нескольких элементов таблицы описателей. По мере необходимости в нее добавляются новые элементы; при этом win32 может увеличивать объем памяти, занимаемый таблицей описателей. Только из-за одних дополнительных операций с таблицей описателей старые 16-разрядные функции работают медленнее, чем win32-функции, управляющие кучами...

That's all, folks :-)

28.05.2000
Rev. 20.12.2001

P.S. При написании этой статьи кроме личного опыта использовался материал книги Джеффри Рихтера "Windows для профессионалов. 3-е издание." (кстати, по сети гуляет 4-е английское издание этой замечательной книжки, если вам сложно купить ее в магазине, то поищите в любимом поисковике файл Richter_book_withoutIE5.zip).

наверх


Распределение памяти в Borland Delphi - проблемы и решения

главная | статьи
Василий Мошнинов vmoshninov@newmail.ru

Недавно я получил письмо о том, что мой плагин ProxyFtp не может показать каталог, содержащий порядка 4000 файлов. Плагин выдавал сообщение "Out of memory". В памяти при этом ФАР занимал около 64Mb. Я решил проверить этот момент и, к сожалению, все мои опасения подтвердились. После анализа ситуации оказалось, что частый вызов борландовской функции ReallocMem приводил к большому объему расходуемой памяти и в последствии вообще переставал работать. Тогда я решил заменить все функции работы с памятью на соответствующие функции Win32 API , благо их использовалось у меня всего 3 штуки:

  • GetMem - выделить память
  • FreeMem - освободить память
  • ReallocMem - изменить объем выделенной памяти.

Просто отказаться от использования ReallocMem я не мог - она используется для создания списка TPluginPanelItem в функции GetFindData. С первыми двумя функциями проблем не было вообще никаких. Вот как они стали выглядеть у меня (функция RaiseLastWin32Error описана в модуле sysutils.pas):

procedure MemAlloc(var lpMem; Size: integer);
begin
  pointer(lpMem):= pointer(GlobalAlloc

(LPTR, Size));
  if pointer(lpMem) = nil then
    RaiseLastWin32Error;
end; { procedure MemAlloc }

procedure MemFree(var lpMem);
begin
  pointer(lpMem):= pointer(GlobalFree

(HGLOBAL(lpMem)));
  if pointer(lpMem) <> nil then
    RaiseLastWin32Error;
end; { procedure MemFree }

Небольшие затруднения возникли с функцией ReallocMem. Дело в том, что частый вызов GlobalRealloc из Win32 API также приводил к ошибке (что-то про "Insufficient storage...") Тогда я, основываясь на потребностях плагина, сделал эту функцию как вызов двух предыдущих с некоторыми ограничениями.

Функция первый раз возвращает требуемое количество памяти. Во все следующие вызовы память резервируется "с запасом" - кратно константе MEM_DELTA. Это позволило избежать частых распределений памяти при запросах небольшими порциями:

procedure MemRealloc(var lpMem; uSize: integer);
const
  MEM_DELTA = $2000; // 8192 bytes
var
  P: pointer;
  Size: integer;
begin
  if uSize = 0 then
    MemFree(lpMem)
  else if pointer(lpMem) = nil then
// Первый раз вернем столько, сколько запросили
    MemAlloc(lpMem, uSize)
  else
  begin
// Требуемый размер, выровненный на границу MEM_DELTA
    uSize := (uSize + (MEM_DELTA - 1)) and not (MEM_DELTA - 1);
// Текущий размер захваченной памяти
    Size:= GlobalSize(HGLOBAL(lpMem));
    if (uSize  > Size) or ((Size - uSize) > MEM_DELTA) then
// Запросили больше распределенного размера или уменьшили на величину, большую
// MEM_DELTA
    begin
      MemAlloc(P, uSize);
      if Size > uSize then
        Size:= uSize;
      Move(pointer(lpMem)^, P^, Size);
      MemFree(lpMem);
      pointer(lpMem):= P;
    end;
  end; { else }
end; { procedure MemRealloc }

Когда я заменил все вызовы стандартных функций работы с памятью на эти, FAR смог спокойно показать 4600 файлов (раньше падал на 3800), при этом занял в оперативной памяти около 10 Mb (против начальных 64 Mb) и скорость построения списка TPluginPanelItem возросла до ~3 сек (против ~30 сек в начале).

Естественно, в каждом конкретном случае надо смотреть величину MEM_DELTA. Плюс накладывается ограничение на размер в 1 Gb, вместо 2 Gb. Однако, судя по работе плагина - оно того стоило :))

Новые функции работы с памятью задействованы в ProxyFtp 1.6.r3 и в ProxyNews 1.0 Если ваш плагин не может показать каталог, выдавая ошибку "Out of memory" - проверьте его версию и в случае необходимости - обновите:

  • http://proxykit.newmail.ru
  • http://proxykit.narod.ru

14.04.2000
наверх


Приручаем Borland C++ к crtdll.dll

главная | статьи
Eugene Kotlyarov ek@oris.ru

Чтобы скомпилировать программу под Borland C/C++, которая будет использовать crtdll.dll нужно:

  1. создать библиотеку импорта crtdll.dll
    implib crtdll.lib crtdll.dll
  2. скомпилировать основную программу, причем нужно указать опции:
    • /u- не добавлять к внешним функциям символ подчеркивания;
    • /x- отключить исключения, если линковать без startup-кода;
    • /RT- отключить RTTI для уменьшения размера (если ничего из этого в программе не используется)
  3. слинковать dll, чтобы она использовала crtdll
    tlink32 -Tpd -x xxx.obj, xxx.dll,, import32.lib crtdll.lib

Проблемы могут возникнуть, если программа написана на C++, а не на C. В таком случае некоторые функции (например, strchr) объявляются как extern c++, соответственно их имена в obj-файле получаются mangled (типа strchr$qpci) и не могут линковаться. Решается это путем написания своего .h файла и объявления этих функций в нем, как extern "C".

Поскольку даже при #include <windows.h> в BC подключаются все rtl-ные .h-файлы, нужно добавить соответствующий #define, чтобы не подключились стандартные хедеры. Например для string.h - #define __STRING_H. Этот .h-файл нужно подключать перед всеми остальными. Подобный заголовочный файл может выглядеть следующим образом:

// crtdll.h
#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned size_t;

/* stdio.h */
int sprintf(char *buffer, const char *format, ...);

/* stdlib.h (alloc.h) */
void *malloc(size_t size);
void *realloc(void *block, size_t size);
void free(void *block);

/* mem.h */
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);

/* string.h */
int strncmp(const char *s1, const char *s2, size_t maxlen);
char *strchr(char *s, int c);
char *strrchr(char *s, int c);

/* not include standard string.h */
#define __STRING_H

#ifdef __cplusplus
};
#endif

Еще одна проблема в том, что такая функция, как wsprintf в import32.lib объявлена с подчеркиванием и соответственно при компиляции с опцией /u- линковаться не будет. Решение - либо использовать sprintf из crtdll.dll, либо линковать напрямую к user32.lib. Для этого нужно создать аналогично user32.lib -

implib user32.lib user32.dll
и добавить user32.lib в строку запуска tlink32

Более удобный, правильный и совместимый вариант - объявить прототипы нужных RTL функций внутри своего пространства имен, например:

#ifdef __cplusplus
namespace crt {
extern "C" {
#endif

typedef unsigned size_t;
int strncmp(const char *s1, const char *s2, size_t  maxlen);
char *strchr(char *s, int c);
char *strrchr(char *s, int c);

#ifdef __cplusplus
}
}
#endif

В результате исчезают проблемы с совпадением имен, однако для использования функций объявленных extern "C++" нужно непосредственно указывать namespace, т.е. вместо strchr нужно писать crt::strchr.

Если этой информации Вам не хватает, то "типичный" пример использования crtdll.dll можно посмотреть в исходниках плагина QuakePAK.

04.04.2000
Rev. 24.06.2000
наверх


Синдром ``Рождественской Ёлки'' или Свобода Безумия

главная | статьи
Игорь Русских ruiv@uic.nnov.ru

Лирика

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

Последняя на сегодня версия FreeCraze включает в себя помимо привычного вам плагина еще и программу вьювер вместе с генератором цветных HTML-листингов кодов. Но это не главное. Главное то, что почему-то в архиве вместе со всем этим оказались все исходники колорера. Как всегда, что бы я не делал, меня опять начали, мягко выражаясь, обругивать. То у тебя документация левая и неправильная, непонятно в ней ничего, то сам колорер не работает из-за его большой неправильности, то вот теперь вроде как начинаются упреки о том, что исходники недостаточно ``лиричны''. Ну, то бишь непонятно в них ничего. Кто-то сказал, что в хорошем проекте исходники должны состоять из комментариев, слегка разбавленных инструкциями. Ну что-ж, у меня поганый проект. Комментариев там нет вообще.

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

Shared codes

В принципе вся либа колорера состоит из нескольких модулей, которые могут использоваться как вместе, так и по-отдельности. Плагин колорер - это всего лишь интерфейсная оболочка, такая же, как и лежащий вместе с ним colorer.exe (их исходники находятся соответственно в каталогах ( /src/colorer/ и /src/colorlib/ ). Все разделяемые модули находятся в каталоге /src/shared/.

SGML

Первый модуль и самый простой - это модуль парсинга SGML(HTML) подобного текста ( /src/shared/sgml/ ). На самом деле на него можно не обращать внимания, так как он используется колорером для внутренних целей полностью автоматически. Единственно для чего он вам может понадобиться - это для работы с расширенными параметрами в описаниях блоков <type> скриптов HRC. Так, всякие дополнительные параметры навроде цвета текста и фона по умолчанию, подсветки скобок и всей остальной чуши - реализуются модулем плагина. Иными словами сама библиотека по своим структурам никакие эти параметры не поддерживает. Если вам нужна аналогичная функциональность, то использовать SGML-парсер вам придется. Но, повторяю, там ничего сложного - единственный класс, который по методу parse генерирует дерево, преобразуя параметры, названия тэгов, и сохраняя линейный текст и комментарии. Как сгенерированное дерево использовать вы можете понять из описания класса CSgmlEl и из исходников плагина ( /src/colorer/pcolorer.cpp ).

методы и свойства класса CSgmlEl:

  • bool parse(char *src,int sz);
    Парсинг данных из src размером sz. Создает дерево объектов.
  • parent(), next(), prev(), child()
    Возвращают указатели на соответствующий объект в дереве.
  • char *name;
    Имя тэга, если объект - тэг.
  • char *content; int contentsz;
    Линейный текст и его размер - если объект - не тэг, а простой текст.
  • Все остальные методы и данные представляют собой дополнительные атрибуты.

Регэкспы

Немногим более сложным является модуль регэкспов. ( /src/shared/regexp/ ) В принципе его вам вообще можно не понимать (тем более многие люди испытывают какой-то животный страх при одном слове ``регэксп'' и отмахиваются всеми шестью руками с саблями, когда им начинаешь пытаться объяснить что ничего сложного нет, и основы можно понять прямо сейчас). Но очень часто регулярные выражения можно использовать как отдельную возможность по расширению и использовать их в областях никак не связанных с расцветкой (к примеру поиск, замена). На самом деле если вы уже знаете что это такое, то всунуть эти коды в вашу программу не составит никакой сложности. У класса CRegExp фактически два основных метода - SetExpr и Parse. Все остальное - это их вариации. К слову сказать коды моих регэкспов полностью портируемы, и работают даже под DOS :)

public-методы класса CRegExp:

  • bool SetExpr(char *Expr);
    Устанавливает и компилирует регулярное выражение из строки Expr. Может вызываться несколько раз для одного объекта. Возвращает true в случае успеха и false при ошибке разбора.
  • bool SetNoMoves(bool Moves);
    Устанавливает значение перемещения по целевой строке по умолчанию (в случае использования moves=-1). false эквивалентно множественному парсингу регэкспа для каждой позиции строки в отдельности.
  • bool Parse(char *Str,char *Sol, char *Eol, PMatches Mtch, int Moves = -1);
    Пытается сопоставить регулярное выражение строке str и сохранить результат совпадения скобок в структуру, указываемую mtch. Параметры Sol и Eol указывают начало и конец строки (которые в общем случае могут не совпадать со строкой str). mtch - указатель на структуру SMatches, определенную в заголовочном файле. Эта структура хранит совпавшие позиции скобок. Параметр moves - возможность перемещаться по строке в поиске совпадения. Если moves равен -1, то используется установленное по умолчанию значение перемещения. Возвращает результат сопоставления (true/false).
  • bool Parse(char *Str, PMatches Mtch);
    Аналогична предыдущей, но считает некоторые параметры по умолчанию. Sol=str; Eol=str+strlen(str); moves=-1;
  • bool SetBkTrace(char *Str, PMatches Trace);
    Устанавливает связь между двумя объектами регэкспов через оператор \yN. Регэксп re при встрече такого оператора будет сравнивать текущее положение в целевой строке со строкой str по смещению trace.s[N].
  • bool isok();
    Возвращает результат компиляции. Полезна при компиляции из конструктора объекта.

Другое

Несколько файлов в других каталогах - это просто вспомогательные функции. Там же лежит plugins.hpp, дополнительные коды для работы с реестром, числами. Мелочь короче.

Colorer library - CColorData

Ну вот добрались до самого главного. В каталоге /src/shared/colorer/ лежат главные модули библиотеки по парсингу и расцветке кода. Эти коды делятся на два модуля: первый (ccdata.cpp) используется для загрузки и компиляции HRC-базы, второй (ccolorer.cpp) - непосредственно для динамической расцветки текстов. Соответственно в разделяемом файле classes.h (который вы тоже должны подключить в свой проект) описаны два главных класса - CColorData и CColorer.

CColorData - класс, ответственный за загрузку и компиляцию HRC-скриптов. Хочу подчеркнуть, что текущая структура скриптов (имеется в виду дерево каталогов и организация некоторых соглашений по использованию цветов, определений, постановок) совсем не обязательны и не фиксированы. Иными словами, вы можете в вашем проекте взять из HRC-кодов только необходимые вам файлы, скомпоновать их в один большой (с расчетом на то, что пользователь не будет в вашей программе менять конфигурацию колорера) и подавать на парсинг именно этот файл. Замечу также, что значения цветов, используемых для раскраски вовсе не фиксированы. Смысл в том, что вы можете однозначно сопоставить каждой лексеме в расцвечиваемом коде определенный индекс цвета (ведь их может быть больше 16 - максимум 0xFFFF текста и столько же цветов фона - ограничения консоли на цвета не играют для библиотеки никакой роли), а уже в своей программе давать возможность пользователю сопоставлять каждой лексеме любой требуемый цвет. Надеюсь идея дошла. Теперь обзор основных методов:

  • CColorData(char *path, char *ef);
  • CColorData(char *data, int len, char *ef);
    Два варианта конструктора для инициализации базы. Первый - с указанием пути до внешнего файла, второй - непосредственная передача библиотеке данных уже готового файла указанной длины. В первом случае возможно применение в скрипте директивы подключения других файлов (пути считаются относительно базового файла), во втором же случае эта директива не имеет смысла. В обоих конструкторах параметр ef задает имя файла для отладочной информации. При нулевом значении не получите вы лога. Хочу заметить также, что объект CColorData фактически одноразовый объект. То есть если вам вдруг взбрендило заново перечитать и скомпилировать скрипты, вы должны удалить этот объект и создать заново. Ничто не запрещает вам иметь несколько представителей этого класса, хотя толку от этого мало.

    Заметьте, что вся база не загружается - грузится только базовый файл. Реальная компиляция схем из других файлов происходит при вызове метода loadtype. Из всего этого следует, что если вы все схемы и определения поместите в один файл (для компактности к примеру), или вообще будете вызывать второй вариант конструктора, когда никакого файла может и не существовать (данные к примеру могут храниться в ресурсах вашего проекта), все преимущество частичной загрузки баз сходит на нет - так как все схемы начнут компилироваться сразу из конструктора.

    Но, естественно, при небольших размерах базы это оправдано, так как даже полная база (~400Kb в версии FreeCraze), в библиотеке, собранной в VC6.0, грузится около четырех секунд. Хочу кстати заметить, что либа, собранная в BC5.0 при максимуме оптимизации работает при парсинге текста с той же скоростью, а при компиляции баз в пять раз медленнее (~20 секунд). Компилятор GCC дает около 15 секунд. Возможно, я получил не совсем корректные результаты - с удовольствием поспорю относительно иных параметров оптимизации компиляции. Замеры брались из логов загрузки колорера.
  • bool isok();
    Результат компиляции. Сбой может произойти только при грубых ошибках - отсутствие самого файла, окаймляющего блока, и так далее. Все остальные ошибки при компиляции игнорируются и только могут заноситься в лог.
  • unsigned int GetColor(char *name);
    Функция, используется для возвращения значения цвета от символьного имени name с учетом только загруженных цветовых определений.
  • PType enumtypes(PType next);
    Возвращает следующий тип за типом next в списке типов PType. Вообще-то лишняя, так как к соответствующему элементу в типе SType (*PType) можно обратиться напрямую - он открыт.
  • PType seltype(char *fname, char *fstline, int no = 0);
    Выбирает соответствующий файлу тип по имени файла и по первой строке файла. no - если несколько типов попадают под имя файла, номер выбираемого. Стоит наверное устанавливать его в ноль - он же по умолчанию подразумевается.
  • bool loadtype(PType type);
    Физически загружает тип по указанному указателю. Именно этот метод компилирует все необходимые схемы, регэкспы, и обновляет перекрестные ссылки. Уже загруженный тип еще раз не загружается. Использование этого метода позволяет загружать базу только по частям. То есть методы seltype и enumtypes вы можете вызывать и без вызова соответствующего вызова loadtype.

Три последних типа используют открытую структуру SType (*PType). Это связанный список структур, и в каждой из них хранится информация о соответствующем типе, включая указатель на CSgmlEl объект, который можно использовать для получения дополнительных атрибутов. Я бы рекомендовал использовать ее как readonly :)

CColorer

Этот класс является дополнением к классу CColorData, и если тот ничего не знает о нем, то CColorer полагает существование загруженного класса CColorData - из него он черпает информацию о непосредственной расцветке, коей сам и занимается. В отличие от класса CColorData вы можете создавать несколько представителей класса CColorer - к примеру для каждого окна в вашем редакторе. Это необходимо, так как этот класс варится в собственном соку и хранит много информации, зависимой от содержимого расцвечиваемого файла. Сначала маненький обзорчик по сервисам, потом скажу что к чему.

  • bool SetServices(char*(*gl)(PColorer, int, int*), void (*vr)(PColorer));
    Устанавливает сервисы для обработки со стороны программы. char*(*gl)(PColorer, int, int*) - функция, возвращающая строку с запрашиваемым номером для обработки объектом и ее длину. Второй указатель - вообще говоря редко используется - синхронизационное сообщение - необходимо при реализации многопоточного парсинга (в теории - на практике сильно лень пробовать :)
  • bool SetColoringSrc(PType type);
    Устанавливает тип, используемый для расцветки текста. Указатель из параметра может быть получен любым способом, описанным в предыдущем разделе.
  • PLineHL SetMaxLines(int num);
    Устанавливает размер массива для строчек. Программа не может одновременно запрашивать на расцветку число строк, большее установленного сначала здесь. Можно вызывать этот метод несколько раз для изменения размера массива. Возвращает указатель на соответствующий массив структур SLineHL.

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

    Собственно данные начинаются с элемента массива PLines[1]. Каждый элемент - строка, номер которой вы задали при вызове функции парсинга текста. В каждом элементе содержится указатель next на следующую такую структуру в строке. Замечу, что в самих элементах массива информации не содержится - они просто скелет. Вся информация о расцветке(откуда, докуда, и каким цветом) содержится в списках динамических структур, связанных указателем next.

  • bool CompactLines();
    Вспомогательный метод - сжимает цветовые области. Смысл в том, что в полученном массиве вообще говоря цветовые области могут перекрываться и накладываться друг на друга - это не проблема при отображении их к примеру на экран - но вот когда надо сгенерировать с них код (что делает colorer.exe с параметром -h), это может обернуться проблемками. Этот сервис после вызова гарантирует, что цветовые области будут упорядочены без перекрытий.
  • bool ClearCache();
    Чистит внутренний кэш расцветки. Нужно вызывать при смене типа расцветки в объекте.
  • void BreakParse();
    Останавливает процесс расцветки, если он работает в другом потоке. Вызывать естественно стоит из другого потока. Применяется только при использовании многопоточной системы расцветки.
  • int QuickParse(int from, int num);
    Быстрый парсинг num строк текста начиная со строки from. возвращает строку, на которой закончился парсинг. Быстрый парсинг означает, что не строится ни каких дополнительных структур, и текст расцвечивается линейно в указанных пределах. Расцветка будет некорректной, если строка from попадет в середину какой-либо вложенной схемы. Может применяться для полной расцветки текста от начала до конца - в этом случае корректность естественно гарантируется.
  • int FullParse(int from, int fvis, int visnum, int allnum);
    Полный парсинг с заполнением внутренних структур. Текст парсируется cо строки from, анализируется allnum строк. Параметры fvis и visnum определяют соответственно начальную строку для заполнения структур SLineHL и общее число строк, подлежащих цветовому парсингу. Это число не должно превышать размер выделенного функцией SetMaxLines массива. Этот вид парсинга предварительно сохраняет информацию о предыдущих результатах во внутреннем кэше. При новом обращении к функции расцветка начинается с той схемы, которая была сохранена при предыдущем парсинге. При этом необходимо расцветить только лишь один экран (что очень быстро), и все вложенности блочных схем будут соблюдаться. Функция обладает большой гибкостью, и может использоваться в различных вариантах, вплоть до фонового парсинга в отдельном потоке. Возвращает строку, на которой был остановлен (или окончен) разбор.

Ну вот. Примерно значит так. Я думаю элементарный парсинг с использованием QuickParse объяснять не надо - там все линейно и без особых точек. Немного поподробнее надо поговорить о методе FullParse. Не знаю с чего начать объяснять, там любое место связано с другими еще необъясненными. Гмм... Ну первое что надо понять - это соотношения производительности. На примере реализации библиотеки в плагине вы можете видеть, что скорость практически на всех типах файлов приемлема. Ну то-есть жить можно. На некоторых конечно побыстрее, некоторые довольно тормозят - но в общем ничего. И это все на моем стареньком p166mmx. Думаю на любой другой телеге на порядок быстрее. Это зафиксировали. Теперь еще одна вещь - плагин использует наиболее медленный вариант расцветки кода. Конкретнее, при любом нажатии клавиши, даже клавиш курсора, происходит полный парсинг через FullParse текущего экрана. Все это связано с ограничениями ФАРовского внутреннего редактора, и вас не больно должно волновать. Единственно из всего этого хочу до вас донести идею, что при использовании библиотеки целенаправленно в своем проекте вы можете добиться еще больших скоростей. Как минимум вы будете избавлены от работы при каждом перемещении курсора... необходимо контролировать только действия по непосредственной модификации текста (ну или по его прокрутке :))

Теперь что конкретно значит кэширование при работе этот метода. Метод FullParse вы вызываете с двумя парами параметров - фактически внешними границами и внутренними (выраженными в строках). Внутренними границами чаще всего выступают строки, видимые на экране в текущий момент. Это то, на что реально заполняются цветовые структуры. Окаймляющие границы также полностью парсятся - но цветового заполнения не происходит - так как вы их не видите, и вам это просто не надо. После того, как вы первый раз вызвали этот метод, он у себя автоматически сохраняет всю структуру и вложенность схем, которые прошли парсинг. Если в следующий раз этот метод вызовется откуда-нибудь с середины текста, вместо того, чтобы начинать парсинг с нуля - с нулевой схемы (что фактически может быть неправильно - к примеру эта середина попадет внутрь комментария - и это простейший конфликт), функция обратится к кэшу и начнет парсинг с сохраненной в этой позиции схемы - а потом произойдет ``раскрутка'' схем назад - так как они могут быть многократно вложены. В итоге текст раскрасится с учетом блочных комментариев - хотя начинались они где-то раньше, и мы вообще-то не знали где. А расцветка в то же время корректная.

Короче можно сформулировать такое правило: Полученный код гарантированно будет расцвечен, если каждый раз при вызове FullParse происходит зацеп текста - то есть если в прошлый раз вы вызвали

  // параметры распределяются следующим образом:
  //
  // from ------------+
  // ..               |
  // fvis ---------+  +- в этих пределах происходит
  // ..            +--+  заполнение структур с цветовыми
  // fvis+visnum --+  +- областями
  // ..               |
  // from+allnum -----+
  //
  FullParse(from, fvis, visnum, allnum);
То в следующий раз вы должны передать в параметре from значение, не превышающее предыдущие (from+allnum). В этом случае вы гарантированно не сможете пропустить никакой начинающийся блок, и как следствие получите корректную расцветку. Естественно, это правило не всегда удается выполнить - если юзер к примеру находясь в начале файла вдруг захочет проскочить сразу в конец его, то по этому правилу вам придется для корректности провести парсинг всего текста. На первой-второй тысяче строчек это еще не так критично - а вот потом время начинает неприятно увеличиваться.

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

  // fr - это параметр, задающий откуда начнется кэширование и расцветка
  // CurList->endline - это его старое значение.
  fr = (EditInfo.TopScreenLine > CurList->endline)?CurList->endline:EditInfo.TopScreenLine;
  CurList->endline = EditInfo.TopScreenLine;
  // тут есть дополнительная обработка на блочное выделение - нас это не волнует
  // ...
  // а вот тут глядится, превысила ли длина необходимого для парсинга текста
  // некое критическое значение (CurList->typeinfo->backparse)
  // если да - то число линий для парсинга уменьшается...
  if (EditInfo.TopScreenLine - fr > CurList->typeinfo->backparse)
    fr = EditInfo.TopScreenLine - CurList->typeinfo->backparse;
  // А это вызывается сам парсер с соответствующими параметрами номеров строк
  // Заметьте, что начало реального парсинга (fr) не совпадает с началом
  // расцветки текста (EditInfo.TopScreenLine)
  CurList->FullParse->FullParse(fr, EditInfo.TopScreenLine, EditInfo.WindowSizeY,
     EditInfo.TopScreenLine - fr + EditInfo.WindowSizeY);
Я хочу подчеркнуть, что колорер оптимизирован и рассчитан на то, что юзер - нормальный программер. То есть чаще всего он работает только в определенной области файлов, резкие переходы совершает только может быть на начало да на конец файла. Ну, это уже психология. И это правильно. При таких предположениях колорер работает стабильно и сверх-быстро. Некоторые сомнения вызывает только резкий переход на конец файла. Что происходит в этом случае? Чего делать?

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

И в этом случае, и вообще при случайном переходе по тексту(когда пользователю к примеру взбрело подергать мышкой линейку прокрутки туда-сюда), вы можете воспользоваться функцией QuickParse для раскраски только текущего экрана. Естественно может оказаться, что полученная расцветка будет неверна - но зато работать будет сверх-быстро. Дополнительно к этому вы можете попытаться запустить в фоновом потоке функцию FullParse (кстати этого не надо делать для одного и того же объекта - лучше создать два объекта CColorer, ссылающихся на один тип данных). Если юзер успокоился, то через пару мгновений у него на экране появится правильная расцветка вместо показанной сначала некорректной. Если же попался буйный - то вы можете использовать функцию BreakParse для прерывания обработки во втором потоке и возобновлении ее опять с нужного места (так как гипотетически очень наглый юзер может быстро прокручивать текст мышкой да еще и изменять его :-)). Для этого-же предназначен таинственный второй метод vr в функции SetServices. Библиотека вызывает его, когда процесс расцветки закончился либо сам-по-себе либо когда его прервали функцией BreakParse. Короче это синхронизационное сообщение. По идее эта функция должна сообщить первому потоку (который отвечает за ввод пользователя), что расцветка закончилась, можно вызывать парсинг заново (это она может сделать посредством либо Event'ов, либо посредством любой другой синхронизации - не мне вас учить).

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

  // num - количество строк на экране
  cl->SetMaxLines( num * 2 );
  // расцвечивать, только если добрались до строчки,
  // не содержащейся в массиве цветовых областей.
  if (topline+num > from + num*2){
    from = topline;
    cl->FullParse(from, topline, num*2, num*2);
  };

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

Напомни мне если я пел об этом раньше, я все равно не помню ни слова. Напомни мне если я пел об этом раньше - и я спою это снова, я не знаю ничего другого...

Последний раздел

Есть два типа людей. Первые могут воспринимать колорер в стандартном дистрибутивном виде, вторые не могут. Соответственно первые (куда вхожу и я) могут воспринимать гамму цветов колорера, вторые не могут. Проблема вторых известна как синдром Рождественской Ёлки. Думаю, здесь имеют место глубокие инфантильные связи, первично обозначившиеся в домладенческом периоде. Причем физиологию уже не поменять. Я привык теперь (думаю как и многие из вас) к тому, что можно находить простейшие ошибки и опечатки уже на этапе набивки кода. И, вообще говоря, при написании HRC кодов я стремлюсь именно к этому. Основное правило гласит, что главным является не корректно расцвечиваемый правильный код, а ясно видимый и различимый неправильный код. Хотя, конечно, первое тоже важно. Ну и прежде чем хандрить по поводу рождественской гирлянды попробуйте различные варианты настройки цветов. Возможно, что даже какой-то из дистрибутивных вам понравится. Ну а если нет, то никто не мешает вам определить свою цветовую схему - на вкус и, главное, цвет товарищей нет...

Ну вот, думаю выложил все что смог, чего непонятно - спрашивайте.

Cail Lomecb
Sat 25 Mar 2000

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


Написание плагинов на Virtual Pascal 2.0

главная | статьи
Дмитрий Суходоев raven66@mail.ru

Сначала хочу немного рассказать про этот самый Virtual Pascal 2.0. Все таки для пользователей Win32 - это довольно неизвестный компилятор. Первая версия этого компилятора была разработана в Киевском Институте Кибернетики Виталием Мирьяновым (хотя институт тут помог только тем, что предоставлял машины для работы). Большая часть ядро Virtual Pascal была написана на i386 с 4 мегобайтами памяти и поэтому была даже для того времени очень оптимизирована. В июне 1995 была выпущена публичная бета версия Virtual Pascal для OS/2, и тогда с Виталием связалась британская компания fPrint в лице Аллана Мертнера и предложила свою помощью в разработке и поддержке продукта и место жительства в UK. В итоге у них получился Virtual Pascal v1.11 для OS/2. Сейчас уже доступен релиз Virtual Pascal 2.0, который насчитывает всего около 200 пользователей. Здесь я не считаю тех пользователей, которые украли, этот прекрасный компилятор.

Самая главная особенность, которая меня привлекла в Virtual Pascal 2.0 это его почти 100% совместимость с таким достаточно известном компилятором Borland Pascal 7.0, а также одновременная (частичная) совместимость с Borland Delphi 3, с использованием классов. Нельзя не упомянуть то, что в Virtual Pascal вложены скомпиленная библиотека Turbo Vision 2.0, а также патчи для стандартных исходников от Borland и патчи для библиотеки Object Professional 1.30 от Turbo Power Software.

При первых попытках написания простого плагина на Virtual Pascal 2.0 я, естественно, столкнулся с тем, что мне нужен был аналог plugin.hpp, но для паскаля. FarIntf.pas не подходил, по тем причинам, что он был достаточно неплохо заточен под Borland Delphi 4, что вобщем-то и осложнило его компиляцию под Virtual Pascal 2.0. короче говоря - собрать я собрал, а вот работать оно не захотело :-)

Ну немного побездельничав, попросил у Василия Мошнинова исходники аналога plugin.hpp в его варианте и небольшой hello world тоже для его plugin.pas. После небольшой правки все заработало на «ура», что подтолкнуло меня сделать то чего мне так давно в FAR не хватало.

Особых отличий написания плагинов на Virtual Pascal 2.0 от дельфи нет, но все таки есть такая обязательная комбинация директив компилятора, без которых собрать что-либо работающее на Virtual Pascal 2.0 для FAR будет просто невозможным.

  • Huge Strings. В Дельфи они по умолчанию включены. В Virtual Pascal 2.0 для пущей совместимости с bp7 они выключены, поэтому для начала {&H+}. А нужны они в первую очередь для того, чтобы организовать большую совместимость с нуль-терминальными строками pChar, т.е. с ними можно сделать так: pChar(String) - и это будет верным, то есть компилятор на это не будет ругаться.
  • Use32. В дельфи такого понятия как Use32 вроде даже и нет. Попытаюсь объяснить что это такое. Так как Virtual Pascal 2.0 должен быть совместим с bp7, то все данные типы целочисленный переменных у него аналогичны типам bp7, т.е. Word, Integer занимают два байта, ShortInt, Byte занимают один байт, а четыре байта занимает только Longint и Cardinal. Но также Virtual Pascal 2.0 должен обеспечивать совместимость с третьей дельфей, а там типы Integer и Word приравнены в типу Longint, (т.е. занимают четыре байта), что и правильно - какой вин не любит кушать много памяти :-) Ну и соответственно эту директиву выключают для обеспечения совместимости с дельфи и включают для совместимости с bp7. В нашем случае она должна быть включена, т.к. все структуры в стандартном plugin.hpp расписаны тем самым четырехбайтным Integer. Короче говоря вот он этот модуль Use32.pas
    • unit Use32;
{$Use32-}
interface
type
{$IfDef Use32}
 Integer    = System.Longint;
 Word       = System.Longint;
const
 MaxInt     = MaxLongint;
{$Else}
 SmallInt   = System.Integer;
 SmallWord  = System.Word;
{$EndIf}
type
 PByte      = ^Byte;
 PWord      = ^Word;
 PLongint   = ^Longint;
 PSmallInt  = ^SmallInt;
 PSmallWord = ^SmallWord;
implementation
end.
  • Еще в Virtual Pascal 2.0 я лично наткнулся на такие грабли, что перечисляемые типы всегда занимали один байт, а в plugin.hpp - четыре. Василий Мошнинов упорно :) советовал мне {$MINENUMSIZE 4} и {$ALIGN OFF}, не зная, что Virtual Pascal 2.0 на эти директивы матом :-) Я почти три дня думал что в Virtual Pascal 2.0 подобных директив нет, и просто забивал оставшееся пространство массивом из трех символов, пока не почитал документацию. Короче говоря подобное в Virtual Pascal 2.0 будет выглядеть ровно так: {&AlignRec+,Z+}
  • В итоге получаем директиву: {&H+,Use32+,Z+,AlignRec+}
  • Что ставить в начале: begin или initialization? Я, собственно, не хочу пересказывать документацию по Virtual Pascal, но тем не менее расскажу, так как сам наступал на эти грабли. Зарезервированное слово inittialization заставляет компилятор вставлять в dll инициализирующий код, то есть тот код, который идет в implementation секции каждого модуля (unit), подключенного к программе. Вообще для ФАРовского плагина это не нужно (или нужно только для отладки), так как все действия, к которым подготавливает этот код (например вывод текста с помощью WriteLn для модуля Crt, etc..), можно сделать с помощью ФАРовского api. То есть в ФАРовских плагинах надо делать begin, а initialization только для отладки, например для вывода отладочного текста в лоб с помощью процедур Write и WriteLn. При постановке initialization в dll у меня было замечено довольно странное поведение некоторых моих плагинов, в частности, true macro редакторе совершенно от балды выдавал откуда-то макросы, причем там, где их не должно было быть. Когда поставил begin - стало все нормально.

    Что касается использования библиотеки Turbo Vision 2.0 for Win32 в плагинах. Для нее как раз нужно ставить initialization. Почему? Если стандартный модуль drivers.pas не проведет инициализацию, то в лучшем случае у Вас ничего не запустится. В худшем будет просто gpf ;-) Но одного initialization вообще всегда мало. Инициализация, выделение памяти прошло. А кто же будет высвобождать эту память? В обычном exe этим занимается ExitProc - указатель на процедуру деинициализации. В dll он тоже есть, но почему-то при выгрузке он не вызывается. Возможно, это баг Virtual Pascal. Поэтому нужно импортировать ФАРу процедуру ExitFAR и там насильно вызывать ExitProc. Я делаю это так:

    procedure ExitFAR; assembler;
 asm
  call ExitProc;
 end;

Дальше идут необязательные советы, без них работать уже будет, но с ними просто легче.

  • Чем Virtual Pascal 2.0 хорош, по отношению к дельфи, так это тем, что не надо писать для каждой процедуры stdcall. Достаточно в начале модуля поставить директиву компилятора {&StdCall+} и все процедуры и функции, которые будут за ней идти будут подразумеваться как stdcall.
  • Да, ради справедливости надо заметить, что в стандартном windows.pas от Virtual Pascal 2.0 есть такой прикольный баг: значения HKEY_CURRENT_USER и HKEY_LOCAL_MACHINE перепутаны местами, так что если что-то заработало не так, то надо их прописать нормально :)

Кстати сказать, что именно с помощью Virtual Pascal 2.0 намного лучше и экономичней компилять плагины. И не только к ФАРу. Вот я читаю PLUGINSR.HLP и сочувствую наСИльникам: всегда надо как-то извратиться, чтобы получить маленький размер плагина. На дельфи тоже самое, но там уже проще: можно выкинуть модуль SysUtils и спокойно себе скомпилять плагин небольшого размера, другое дело, что без SysUtils в дельфи ничего не сделаешь. А на Virtual Pascal 2.0 самое то! SysUtils в нем тоже есть, но в отличии от дельфи без SysUtils в Virtual Pascal 2.0 можно прожить, да причем прожить припеваючи! Есть все для этого замены: модуль Dos (для работы с диском), модуль Strings (для работы с pChar), а большего от SysUtils никто и не требовал, т.к. исключения (exceptions) плагинам по-моему мнению совсем не нужны. Наконец в Virtual Pascal 2.0 есть Turbo Vision для Win32, что дает более гибкие возможности по сравнению со стандартными ФАРовскими диалогами. Применение его в плагинах уже дает замечательные результаты (смотри плагины rAscii, color selector).

Модуль plugin.pas Василия Мошнинова был несколько переделан мной на лад Virtual Pascal 2.0, туда я добавил функции для работы с реестром, для обработки масок. Смысла здесь их публиковать я не вижу, кому интересно может взять архив с модулем на моей страничке.

Почти там же лежат интерфесы для работы с регулярными выражениями используя плагин Игоря Русских Colorer 3.0. Оно тоже переписано мной для Virtual Pascal 2.0, но при достаточной сноровке это запросто можно собрать с помощью какой-нибудь из семейства дельфей. Лежит тут.

(c) raVen
21.02.2000
Rev 30.04.2000
наверх


Локализация плагинов второго уровня

главная | статьи
Иван Синтюрин spinoza@mail.ru

Одним из самых очевидных достоинств FAR'a является возможность его локализации. Локализация означает то, что сообщения и справка показываются на понятном для пользователя языке, и никто не запрещает ему перевести эти сообщения на любой другой язык (чем я иногда и занимался раньше). Такие же возможности предоставлены подключаемым к FAR'у внешним модулям - т.н. «плагинам». [Почти] все сообщения и вся [полностью] помощь размещаются соответственно в LNG и HLF-файлах, которые можно перевести на нужный язык (было б желание).

Урезаны в своих правах лишь плагины для плагинов, т.н. «плагины второго уровня», «подплагины», "субплагины". Плагинов, поддерживающих субплагины, правда, мало, но кто знает, что будет завтра? В чем проблема? В том, что FAR не подерживает обработку нескольких файлов типа LNG или HLF на одном языке в одном каталоге, каждому языку соответствует только пара файлов - LNG и HLF. Одно дело плагин второго уровня для multiarc'а, ему никаких сообщений выводить не нужно, другое дело плагины типа AddressBook (by Pavel Kostromitinov, рекомендую), для их субплагинов необходима возможность локализации. Как последнюю предусмотреть?

ЧАСТЬ ПЕРВАЯ. ЛОКАЛИЗАЦИЯ СООБЩЕНИЙ

Локализация бывает 3-х видов:

  1. "Отсутствующая" - все сообщения прошиты в теле плагина. Вариант, который нас не устраивает.
  2. Локализация конкретного плагина второго уровня - недостаток - пара подплагинов локализована, остальные на ... языке, хорошо еще, если на английском [в конце концов, для него и словарь можно найти], а если на суахили?
  3. Глобальная локализация - автор плагина предусмотрел локализацию всех плагинов второго уровня.

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

Посидел я минут 10 и написал свою функцию, которая возвращает указатель на запрашиваемую строку в соответствии с настройками FAR'а. Она находится в файле LocMsg.cpp (см. ниже), посмотрите - все просто, «как два пальца об ...». Для 2 вида локализации Вы можете включать данный файл в свою программы директивой препроцессора include, например, так:

#include "LocMsg.cpp"

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

/*
LocMsg - Скажем локализации: «ДА!»
Author - Ivan Sintyurin. Copyright (c) 2000. All Rights Reserved.

  Я буду рад, если данная функция поможет Вам писать программы  с
возможностью локализации. Прошу Вас только об одном -  указывайте
мой copyright (в readme, например).

  Функция LocMsg возвращает указатель на строку в соответствие  с
языковыми  настройками  FAR'а  (учитывает  настройки   конкретных
пользователей - фича FAR 1.63).

  В каталоге с плагином должен быть файл с сообщениями  с  именем
"ИмяПлагина.msg" Описание формата находится в файле template.msg.

Передаваемые параметры:
MsgName - название нужного сообщения
Var     - если не NULL, то сюда копируется полученная строка

Должна также быть определена и заполнена глобальная структура
PluginStartupInfo Info, из нее берутся данные:
Info.RootKey - место, где хранятся данные плагинов
Info.ModuleName - полный путь к плагину
*/
char *LocMsg(char *MsgName, char *Var)
{
        HKEY hKey;
        DWORD Type;
        static char Msg[80];
        char msgfile[NM],       //имя файла с данными
             Lang[80]="Russian",/*Название языковой секции,
                                по умолчанию=Russian*/
             LangKey[80]="";    //Языковые настройки FAR'а

        lstrcpy(msgfile,Info.ModuleName);//Определяем имя файла
        char *ptr=strrchr(msgfile,'.');  //с сообщениями.
        if(ptr) lstrcpy(ptr,".msg");     //У Вас это может
        else lstrcat(msgfile,".msg");    //выглядеть иначе.

        lstrcat(LangKey,Info.RootKey);//Определяем:
        ptr=strrchr(LangKey,'\\');    //откуда читать
        lstrcpy(ptr+1,"Language");    //языковые настройки.

        //Читаем языковые настройки текущего пользователя
        if(RegOpenKeyEx(HKEY_CURRENT_USER,LangKey,0,
        KEY_READ,&hKey)==ERROR_SUCCESS)
        {
               DWORD DataSize=80;
               RegQueryValueEx(hKey,"Main",NULL,&Type,
                               (BYTE *)&Lang,&DataSize);
               RegCloseKey(hKey);
        }

        if(!GetPrivateProfileSection

(Lang,Msg,80,msgfile))
        {
               /*если требуемой секции нет, то прочитать имя
               секции по умолчанию*/
               GetPrivateProfileString

("Default","Language",
                                      "Russian",Lang,80,msgfile);
               if(!GetPrivateProfileSection(Lang,Msg,80,msgfile))
                  /*если нет требуемой секции с именем, равным
                  имя по умолчанию, то читать будем первую
                  попавшуюся секцию*/
                  GetPrivateProfileSectionNames

(Lang,80,msgfile);
        }

        //читаем нужную строку
        GetPrivateProfileString(Lang,MsgName,MsgName,Msg,80,
                                msgfile);

        /*Если раскомментировать следующую строку, то в msg-файле
        будут автоматически создаваться отсутствующие секции*/
        /*if(lstrcmp(MsgName,Msg)==0)
           WritePrivateProfileString

(Lang,MsgName,Msg,msgfile);*/

        //Копируем в Var полученную строку, если надо
        if(Var)lstrcpy(Var,Msg);
        return(Msg);
}

Файл с сообщениями должен называться ИмяПлагина.msg и является обыкновенным ini-файлом. Его структура такова (содержимое упомянутого выше template.msg):

[Default]
//Данная секция сообщает из какой секции брать строки, если в
//данном файле не найдено требуемой языковой секции. Данная секция
//может отсутствовать, в этом случае языковой секцией по умолчанию
//считается первая.
Language=Russian

//Далее идет описания языковых секций.
//Названия ДОЛЖНЫ формироваться следующим образом:
//В lng-файлах первая строка такая
//.Language=Russian,Russian (Русский)
//          ^^^^^^^
//А вот так должна называться языковая секция

[Russian]
String1=Текст первого сообщения
String2=Текст второго сообщения

[English]
String1=Text of the first message
String2=Text of the second message
//и т.д.

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

ЧАСТЬ ВТОРАЯ. ЛОКАЛИЗАЦИЯ СПРАВКИ

К сожалению, Евгений Рошал не предусмотрел в API функции, выводящей определенный топик нужного hlf-файла. Но в данном случае это не страшно.

Статья писалась в то время, когда о FAR 1.70 еще и слышно не было :), поэтому данное заявление уже неверно. В FAR Manager версии 1.70 и выше вы можете для вывода нужного топика нужного hlf-файла функцией ShowHelp.

Допустим, существует плагин с поддержкой субплагинов, и имя ему mainplugin.dll, файлы помощи имеют имена mainpluginR.hlf и mainpluginE.hlf. Пользователь захочет посмотреть справку под названием MainDialog (например) для субплагинов по имени subplugin1 и subplugin2. Для этого нужно просто добавить имена данных топиков в параметры функции Dialog у данных субплагинов, а сами топики дописать к файлам mainpluginR.hlf и mainpluginE.hlf. Для первого субплагина это будет топик с именем subplugin1_MainDialog (рекомендую в качестве префикса к топику писать название субплагина, тогда не будет совпадений/противоречий с другими субплагинами), для второго - subplugin2_MainDialog. В результате нужная справка будет для субплагина показываться также как и для основного плагина.

That's all, folks :-)

07.01.2000
наверх


Корректировка PLUGIN.HPP

главная | статьи
Валентин Скирдин vskirdin@mail.ru

Замечание Замечание

  • Материал данной статьи потерял всякую актуальность с выходом FAR Manager 1.70.1 (указанные HPP-файлы уже входят в дистрибутив в описываемом виде), но оставлен в качестве учебного пособия.

Всем, кто хоть раз пробовал писать плагины для FAR Manager, известен заголовочный файл PLUGIN.HPP (его можно найти здесь: %FAR%\PlugDoc.rar:plugin.hpp - ред: начиная с FAR 1.70 beta 5 примеры устанавливаются в отдельный каталог PlugDoc). Но, к сожалению (с моей точки зрения), это чистой воды полуфабрикат. Здесь я предлагая некоторые "доработки" этого заголовочного файла, т.с. приведение содержимого файла к некоему стандарту. Доработок совсем немного, но эти доработки (IMHO) весьма полезные.

Первое, что мы сделаем - исключим повторную прекомпиляцию PLUGIN.HPP (это тот этап, на котором компилятор наполняет свои внутренние таблицы информацией из C/CPP и H/HPP -файлов - имена, типы, and etc.). Для этого достаточно в начало PLUGIN.HPP следующие строки:

#ifndef __PLUGIN_HPP
#define __PLUGIN_HPP

//#include <windows.h>

...а самой последней строкой поставить:

#endif // __PLUGIN_HPP

На втором этапе внесем некоторые коррекции для директив компиляции, с учетом знаний о компиляторе LCC-Win32...

...
#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) || defined(__LCC__)
  #pragma pack(1)
  #if defined(__LCC__)
    #define _export __declspec(dllexport)
  #endif
#else
...

...в конце необходимо тоже внести изменения:

...
#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) || defined(__LCC__)
  #pragma pack()
#else
...

Третий этап - перечислим прототипы всех экспортируемых API-функций. Но сделаем это несколько необычно - заключим прототипы в "скобки" (выделено), а также учтем "пожелания" компилятора LCC-Win32 (по поводу остальных компиляторов ничего не скажу, т.к. "общался" только с Borland C и LCC-Win32):

#if defined(__BORLANDC__)
#ifdef __cplusplus
extern "C" {
#endif

void WINAPI _export ClosePlugin(HANDLE hPlugin);
.
.
.
int WINAPI _export ProcessEditorEvent(int Event,void *Param);

#ifdef __cplusplus
};
#endif
#endif

Многие компиляторы, встретив файл с расширением CPP, переключаются в режим С++. А в этом режиме, как известно, имена функций "коверкаются" компилятором с тем, чтобы была возможность перегрузки имен функций (более детальную информацию по этому вопросу смотрите в учебниках по С++ - например здесь). Но так, как FAR Manager ожидает от нашего плагина вполне конкретные имена функций, то...

И, напоследок, скопируем полученный файл PLUGIN.HPP в каталог INCLUDE с тем, чтобы не размножать на диске копии этого файла, а просто взять и в исходнике написать:

#include <plugin.hpp>

Кстати, тоже самое проделайте и с FMT.HPP (если, конечно, пишите плагины второго уровня для плагина MultiArc)

02.01.2000
Rev 13.02.2000
наверх


Как настроить Alignment

главная | статьи
Игорь Павлов

Известно, что все структуры, определенные для обмена между FAR'ом и плагинами, должны быть откомпилированы при alignment = 1 (или 2). Чтобы не возникало проблем у авторов плагинов, файл "plugin.hpp" содержит следующие конструкции:

#if defined(__BORLANDC__) && (__BORLANDC <= 0x520)
  #pragma option -a1
#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100))
  #pragma pack(1)
#else
  #pragma pack(push,1)
  #if _MSC_VER
    #define _export
  #endif
#endif

...

#if defined(__BORLANDC__) && (__BORLANDC <= 0x520)
  #pragma option -a.
#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100))
  #pragma pack()
#else
  #pragma pack(pop)
#endif

Они устанавливают значение alignment = 1 для всех структур, определенных в "plugin.hpp". Но структура PluginPanelItem включает в себя структуру WIN32_FIND_DATA из Win32 SDK:

PluginPanelItem
{
  WIN32_FIND_DATA FindData;
...

Т.е. при работе с PluginPanelItem крайне важно, чтобы структура WIN32_FIND_DATA была откомпилирована со значением alignment = 1 (или 2). Но WIN32_FIND_DATA определена в одном из h файлов Win32 SDK. Это означает, что значение alignment для нее не зависит от "plugin.hpp". Здесь и может возникнуть ошибка.

Михаил Юцис в файле "VCReadme.txt", который идет в комплекте с FAR Plugin API, советует компилировать весь проект при alignment = 2 (или 1). Тогда sizeof(WIN32_FIND_DATA) = 318 (OK для FAR'а). Но для нового проекта по умолчанию стоит значение alignment = 8 и sizeof(WIN32_FIND_DATA) = 320 (а FAR считает, что 318). Т.е. нужно изменить значение в Project / Settings / C/C++ / Code Generation / Struct member alignment на 1 или 2. Но тогда возникает другая проблема. В Win32 есть файлы, которые должны быть скомпилированы при alignment = 8. Например, <wincon.h>, который содержит структуры из Console API. Михаил Юцис для решения этой проблемы предлагает следующий трюк:

#define _WINCON_      // предотвратить включение wincon.h
#include <windows.h>
#undef _WINCON_
#include "plugin.hpp" // этот файл хочет 1-byte alignment
#pragma pack(8)
#include <wincon.h>   // этот файл хочет 8-bytes alignment

Но существует другое решение, которое предложил Евгений Рошал. Достаточно лишь определить в файле "plugin.hpp" структуру FarFindData

struct FarFindData
{
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  char cFileName[ MAX_PATH ];
  char cAlternateFileName[ 14 ];
};

и заменить WIN32_FIND_DATA на FarFindData:

PluginPanelItem
{
  FarFindData FindData;
...

А компилировать проект следует при alignment = 8.

Какие преимущества от такого метода:

  • Меньше лишних действий при создании нового проекта.
  • Повышается скорость работы программы.

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

24.12.1999
наверх


Формат Hrc изнутри

главная | статьи
Игорь Русских ruiv@uic.nnov.ru

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

Один человек, помнится мне, обругал меня за то, что в ASP-подсветке плохо был виден текстовый курсор, и совсем не видны комментарии. На основе этого было дано неопровержимое доказательство того, что ASP подсветка введена на халяву только чтобы показать, что есть такое. Для того, чтобы таких мыслей не возникало, я и пишу эту статью. Более того, как раз на примере ASP синтаксиса (как, по моему мнению, наиболее сложного) я и покажу все прелести HRC и все его закоулки.

Итак, как вы уже наверное наслышаны, базовым (и оригинальным :)) понятием в HRC являются схемы (scheme). Штука это довольно простая, и в отличие от различных систем переключения контекста довольно интуитивная. Хотя, практически по всем параметрам между построением расцветки на схемах и на контекстах можно провести параллели. Ну, если давать строгое определение, то схема - это набор неделимых атрибутов расцветки (регулярных выражений, ключевых слов) применительно к однородному содержимому целевого файла.

Так, к примеру, в схеме языка C/C++ таковой является набор ключевых слов языка, регулярных выражений, описывающих однородные области (строки, числа и др.) и некоторых других атрибутов управления (блоков - blocks), которые сами схеме не принадлежат - а принадлежит схеме лишь их управляющая часть. То есть многострочный комментарий сам по себе не является атрибутом схемы (он сам вообще говоря схема), но его параметры (регулярные выражения для переключения и закрытия, цветовые данные) - атрибуты схемы языка C. Соответственно, из этого следует определение вложенных схем - схема, в которой присутствуют параметры, указывающие на переключение на другую схему. Необходимо понимать, что вложенность схем - это не реальный признак наследования - это всего лишь ссылки - на самих схемах это никак не отражается.

Теперь пошло более сложное. На переключение схем не влияет порядок их определения. И это естественно. Одна схема может вызывать из себя другую, а та в свою очередь может вызывать первую. Это нормально (на самом деле :). Из вышесказанного следуют следующие вещи:

  • Схема может быть вызвана сама из себя. Довольно сложно для понимания - но нужно. Позволяет реализовать вложенные блоки, и некоторые виды подсветки текста без изменения общей раскраски.
  • Схема может быть пустой. Таковой, к примеру, является общая схема Comment - зачем вам чего-то выделять внутри комментария?
  • Схема может не представлять конкретный тип файла. Таких схем большинство. В текущей поставке колорера общее число схем - около 130, а типов файлов только 60.

Дополнительно к переключению схем существует возможность включить схему в другую. Это внешне схожее действие на самом деле совершенно иное. Управляется действие тэгом <Include Scheme="">. При этом указанная схема полностью включается в текущую схему (то есть подключаются ее регулярные выражения и список ключевых слов). Это в корне отличное, но также очень мощное средство. С его помощью вы можете реализовать реальное наследование схем, при этом оно же может служить и обычной макроподстановкой - с версии Colorer 2.8 это довольно часто используется. То есть схема включает в себя много маленьких стандартно определенных схем - как то: определение подсветки строк, чисел, адресов и так далее...

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

Ну теперь после разбора базовых понятий попробуем перейти к конкретному примерчику. Разбирать будем на примере общей реализации схемы ASP. Для начала опишу чего за язык такой, так как до того, как писал расцветку сам не знал :) В обсчем основной смысл в том, что в обычный HTML вставляются дополнительные блоки, выделенные символами <% и %>. Внутри этих блоков находится либо код Ява-скрипт, либо Бейсик. Собственно, вот и все из чего она состоит - своих собственных определений у ASP нет. Итак,

  • ASP
    • JScript
    • VBScript
    • HTML
      • CSS
      • JScript
      • VBScript

Это общая схема. На самом деле все сложнее. Дело в том, что в блоки <% и %> могут быть заключены или VB или JS коды - это определяется по первой строке. Еще одна сложность состоит в том, что ASP вставки могут появляться в любых местах Html-кода, включая строки в параметрах и даже в скриптах. Из-за всего этого создается довольно развитая структура схем. Размер всех схем не большой, так как практически все они только лишь наследуются от базовых уже определенных схем Html, VBScript, JScript. Итак, структура взаимодействий состоит из схем:

  • AspJS. Базовая схема ASP для явы-сктипта. Сама по себе наследуется от схемы Html4AspJS, которая определяет обычный Html с некоторыми расширениями (ниже). также включает в себя схему AspJSInclude которая описывает блочное выделение с тэгами <% и %>.
  • AspJSInclude. Определяет единственный блок, который переключает контекст на схему JScript4Asp.
  • JScript4Asp. Обычная ява-скрипт (наследуется от нее) с единственным отличием - однострочный комментарий имеет пониженный приоритет. Это необходимо например для таких конструкций:
    <% return;  // comment %>
    В обычном приоритетном регэкспе строчного комментария закрывающий тэг %> проигнорируется - чего быть не должно.
  • Html4AspJS - обычный Html (наследуется от HtmlBase), но в параметрах тэгов некоторые изменения - схема HtmlTag4AspJS, и во включаемых скриптах яваскрипта или бейсика применяются не стандартные их схемы - а также переопределенные HtmlVBWithAsp и HtmlJSWithAsp.
  • HtmlTag4AspJS. Наследуется от схемы обычного тэга Html, но позволяет ASP-кодам работать в собственных строках. К примеру параметр
    <div align=center style="<% if then ..'vb asp here!! %>;">
    должен выделить ASP-вставку.
  • HtmlJSWithAsp. Эта схема, как и HtmlVBWithAsp, наследуется от стандартной JScript (VBScript), и переопределяет использование строковых регэкспов опять же для возможности вставки ASP-кодов.
Совершенно аналогичные структуры и схемы определяются для набора VB-скриптов, после чего VB-вариант становится по умолчанию, а вариант с явой скриптом подключается следующим образом:
<Switch Match='/language\s*=.*j(ava)?script/i' Scheme="AspJS">

Ну, вот чего я хотел разъяснить вам по схемам - на самом деле все проще простого. Главное захотеть понять все это.

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

То есть к примеру Color="#14" определит красное на черном, если текущий цвет фона - синий. В ином случае это будет красное на синем. Хочу также подчеркнуть, что текущий цвет фона это не только цвет фона FAR по умолчанию, или цвет, задаваемый параметром Color тэга <Files ...> - это и фоновый цвет любого переключения схем. То есть цвет фона изменяется при любом изменении контекста схемы (хотя в большинстве схем цвет тот же, что и в родительской). В связи с такой структурой возможны некоторые побочные эффекты. Так, если схема многократно включается сама в себя и при этом имеет отличающийся от дефолтового цвет фона, у нее начнется чередование цвета фона с черным - что совсем не красиво. Это можно довольно просто обойти путем определения дополнительной схемы, которая наследуется от первой, и включает тот самый блок (но с обычным цветом фона), которым она инициализируется (то есть который порождает переключение на нее).

Вы можете задать вполне резонный вопрос: "на кой черт так извращаться, если все цвета определяются через константы d<name>, между которыми и надо устанавливать соответствия?". Собственно это почти так. Можете считать, что эта структура осталась атавизмом от старых версий, в которых цвета определялись от балды. Возможно, в следующих версиях(если они будут :-), я перекрою это, и сделаю структуру цветов более гибкой - что, к сожалению, вызовет несовместимость версий колорера на уровне программного интерфейса - но это уже совсем другая статья :)

14.12.1999
наверх


Обработка нажатия ESC или "Авторам долгодумающих плагинов посвящается..."

главная | статьи
Иван Синтюрин spinoza@mail.ru

Очередное воззвание к народу:

ДЕЛАЙТЕ ПЛАГИНЫ ИНТЕРАКТИВНЫМИ!

Это в общем, а в частном...

Написали вы свой супер-пупер-мега-плагин. Замечательно! Если он делает свое темное/светлое :-) дело быстро, за доли секунды, то можете дальше не читать. А если некоторые операции, осуществляемые плагином, требуют определенного времени, то следует обязательно обрабатывать в плагине нажатие ESC (или чего-нибудь еще).

Зачем? Пользователь - существо странное, вдруг он запустил ваш плагин по ошибке (или тот самостоятельно запустился, что не меняет сути дела) или сознательно, но резко передумал. Как ему быть в данной ситуации? FAR убивать? А плагин думает, работает, а пользователь волосы на себе рвет и проклинает Вас. Выход прост - плагин должен реагировать (интерактивность!) на нажатие клавиши «ESC» (Escape - бегство, бурж.). Для этого можно использовать, например, следующую функцию (за основу взята функция из файла Examples\MultiArc\ARCMIX.CPP):

bool CheckForEsc(void)
{
 bool EC=false;
 INPUT_RECORD rec;
 static HANDLE hConInp=GetStdHandle(STD_INPUT_HANDLE);
 DWORD ReadCount;
 while (1)
 {
  PeekConsoleInput(hConInp,&rec,1,&ReadCount);
  if (ReadCount==0) break;
  ReadConsoleInput(hConInp,&rec,1,&ReadCount);
  if (rec.EventType==KEY_EVENT)
     if (rec.Event.KeyEvent.wVirtualKeyCode==VK_ESCAPE &&
         rec.Event.KeyEvent.bKeyDown) EC=true;
 }
 return(EC);
}

Дальше, где нужно, пишем что-то типа:

...
if(CheckForEsc()) ... //реакция на нажатие ESC, например, выход из плагина
else ... //работаем дальше
...

That's all, folks :-)

дополнения от Василия Мошнинова

13.12.1999
Rev. 06.09.2000
наверх


ECTL_GETSTRING работает слишком медленно...

главная | статьи
Stanislav V. Mekhanoshin rampitec@tu.spb.ru

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

{
    struct EditorGetString egs;
    struct EditorSetPosition esp;
    struct EditorInfo ei;

    Info.EditorControl(ECTL_GETINFO,&ei);

    for( egs.StringNumber=ei.CurLine;
         egs.StringNumber < ei.TotalLines;
         egs.StringNumber++ )
    {
        Info.EditorControl(ECTL_GETSTRING,&egs);
        if( process( egs.StringText, egs.StringLength ) ){
            esp.CurLine=egs.StringNumber;
            esp.CurPos=-1;
            esp.CurTabPos=-1;
            esp.TopScreenLine=-1;
            esp.LeftPos=-1;
            esp.OverType=-1;
            Info.EditorControl(ECTL_SETPOSITION,&esp);
            return TRUE; // Успех, установили текущую строку.
        }
    }
    return FALSE; // Неуспех, просто вернемся. В редакторе ничего не
                  // изменилось.
}

Однако, написав таким образом, я обнаружил, что код обработки строки (собственно, функция process()), работает на два порядка быстрее, чем весь этот цикл в целом. Т.е. процедура взятия строки по номеру поглощает ~99% времени.

Код был переделан по совету, предложенному ER (не только мне, также поступил в плагине EditCompletition, Андрей Третьяков). Суть совета заключается в том, чтобы брать строку не по номеру, а всегда текущую (-1). Т.е. заменить ECTL_GETSTRING с номером строки на пару ECTL_SETPOSITION с номером строки и ECTL_GETSTRING с -1.

Следует заметить, что этот метод требует запоминания текущей позиции в редакторе и ее восстановления при откате. Но дело того стоит. Итак, код приведенный выше следует переписать следующим образом:

{
    struct EditorGetString egs;
    struct EditorSetPosition esp;
    struct EditorInfo ei;

    Info.EditorControl(ECTL_GETINFO,&ei);
    egs.StringNumber=-1;

    for( esp.CurLine=ei.CurLine;
         esp.CurLine<ei.TotalLines;
         esp.CurLine++ )
    {
        Info.EditorControl(ECTL_SETPOSITION,&esp);
        Info.EditorControl(ECTL_GETSTRING,&egs);
        if( process( egs.StringText, egs.StringLength ) )
            return TRUE; // Успех. Строка уже установлена.
    }

    // восстановим старую позицию:

    esp.CurLine=ei.CurLine;
    esp.CurPos=ei.CurPos;
    esp.TopScreenLine=ei.TopScreenLine;
    esp.LeftPos=ei.LeftPos;
    esp.CurTabPos=-1;
    esp.OverType=-1;
    Info.EditorControl(ECTL_SETPOSITION,&esp);

    return FALSE;
}

Следует отметить, что FAR не отрисовывает изменения немедленно, так что "мельтешения" на экране не будет.

Теперь о приятном: замеры времени на моей машине показали ускорение взятия строки (только взятие, без обработки - чистое время) во втором случае по сравнению с первым в 63 раза. Причем эффект стабилен как для относительно небольших файлов, так и для файлов в половину и более моего RAM. Данные Андрея Третьякова примерно те же - у него соотношение 1/65. Т.е. цифры весьма близкие.

Для замера был использован run-time профилировщик Watcom C 11.0 на основе профилировочной инструкции Pentium rdtsc. IMHO самый правильный профайлер. Но даже на глаз ускорение очень заметно. Моя конфигурация: IP-240, 96M RAM, Windows NT 4.0 SP6. Андрей Третьяков проводил испытания на 486-dx4-100.

Небольшое предостережение: при установке позиции FAR может изменить значения LeftPos, TopScreenLine, CurPos даже если вы использовали для них -1. Например, если курсору запрещено перемещаться за конец строки, а строка короче, чем CurPos, который вы пытаетесь сохранить, устанавливая в -1, то CurPos, тем не менее, изменится. В большинстве случаев такое поведение вполне удовлетворяет пользователя. Однако, при последовательном переборе строк в приведенном цикле, пользователь не видит промежуточных перемещений по тексту и будет удивлен, увидев не совсем ту позицию на экране, на которую он мог бы рассчитывать при перемещении (с его точки зрения), например, с 1-ой на 10-ю строку. В первом приведенном примере такой проблемы возникнуть не может, т.к. реально также осуществляется только одно перемещение. Второй же пример следует модифицировать таким образом, чтобы избежать подобной проблемы.

Вариантов модификации может быть много. Например, если ваш плагин вообще никогда не меняет текущую позицию (т.е. всегда ее восстанавливает), то этой проблемы не будет. Если плагин имеет код вычисления TopScreenLine, LeftPos, CurPos исходя из каких-то своих соображений, возможно вообще не относящихся к предыдущему их состоянию, то он просто вызовет этот код после завершения цикла. В моем случае, я всегда восстанавливаю сохраненную позицию, а уже затем использую ECTL_SETPOSITION, передавая в нее нужную мне строку и -1 для остальных параметров. Вот пример модифицированного кода:

{
    struct EditorGetString egs;
    struct EditorSetPosition esp;
    struct EditorInfo ei;
    int    nFound=-1; // номер найденной строки

    Info.EditorControl(ECTL_GETINFO,&ei);
    egs.StringNumber=-1;

    for( esp.CurLine=ei.CurLine;
         esp.CurLine < ei.TotalLines;
         esp.CurLine++ )
    {
        Info.EditorControl(ECTL_SETPOSITION,&esp);
        Info.EditorControl(ECTL_GETSTRING,&egs);
        if( process( egs.StringText, egs.StringLength ) ){
            nFound=esp.CurLine; // Успех
            break;
        }
    }

    // восстановим старую позицию:

    esp.CurLine=ei.CurLine;
    esp.CurPos=ei.CurPos;
    esp.TopScreenLine=ei.TopScreenLine;
    esp.LeftPos=ei.LeftPos;
    esp.CurTabPos=-1;
    esp.OverType=-1;
    Info.EditorControl(ECTL_SETPOSITION,&esp);

    if( nFound >= 0 )
    {               // А теперь снова установим на найденное место...
        esp.CurLine=nFound;
        esp.CurPos=-1;          // Невзирая на то, что эти поля уже
        esp.TopScreenLine=-1;   // содержат значения - их надо выставить
        esp.LeftPos=-1;         // в -1. Это не одно и то же! Явное число -
        esp.CurTabPos=-1;       // безусловно. -1 лишь _пытается_ сохранить
        esp.OverType=-1;        // старое значение, если это возможно!

        Info.EditorControl(ECTL_SETPOSITION,&esp);
    }

    return nFound >= 0;
}

28.11.1999
Rev. 26.06.2000
наверх


Как уменьшить размер плагина: Watcom v11

Как уменьшить размер плагина

(на примере Watcom v11)
главная | статьи
Эдуард Султанов ed@it.nsc.ru

Ровно такие же проблемы были и у меня. Результат похож, но другой компилятор - другие заморочки. Если у Вас Watcom и Вам неинтересны причины, то найдете в конце примеры makefile и plugin.lnk. Если у Вас другой компилятор - посмотрите все вплоть до конкретной реализации, может Вам это поможет.

Конкретнее:

I. Немного теории.

Залог успешного похудения вашего плагина состоит в контроле того что используете вы сами, а что ваш компилятор:

1. Используемые функции.

Желательно использовать Win API и не пользовать без разбора библиотечные функции типа printf и a2i. Как правило все функции семейства используют одну виртуальную и соответственно донельзя универсальную. Можно привести много причин вредности использовании, но нас интересует одна: размер. Можете мне не верить и попробовать заменить ваш printf на несколько strcat или еще лучше (но не на много) вручную сбить строку. Хитростей тут нет. Это не зависит от компилятора. Просто надо немного думать :-) В конце концов пару простеньких функций сделать несложно.

2. Скрытые функции.

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

3. Подключаемые библиотеки

Я вообще-то приверженец радикального подхода: никаких библиотек. Но это совсем необязательно. Если включить у линкера оптимизацию, то пользовать библиотеки вполне возможно. Но надо помнить главное: используя одну библиотечную функцию вы можете подлинковать половину библиотеки, только потому что используемая функция их все пользует. Естественно это не касается стандартных динамических библиотек.

II. Немного работы ручками.

Если скомпилировать плагин, например так: "wpp386 -bd -d0 -mf Blocks.cpp". Потом получившийся файл отдать на растерзание дизассемблеру: "wdis -a Blocks.obj > Blocks.asm", получиться примерно следующее:

---------------- 'Block.asm' ------------------
.387
.386p
.model flat
                PUBLIC  `_SetStartupInfo@4`
                PUBLIC  `_OpenPlugin@8`
                PUBLIC  `_GetPluginInfo@4`
; Это,понятно, то что мы экспортируем в Far.
; К стати, полезно видеть как это выглядит. Об этом чуть ниже.

                PUBLIC  `W?GetMsg$n(i)pna`
; "Наша" собственная функция. Позаимствовал у ER :-)

                EXTRN   __CHK:BYTE
; Вот !!! Проверка стека вначале функции.

                EXTRN   memset_:BYTE
; Библиотечная функция

                EXTRN   `__imp__RegisterClipboardFormatA@4`:BYTE
; Импорт. Из DLL-ки. Об этом чуть ниже

                EXTRN   __DLLstart_:BYTE
; Вот !!! Так называемый startup.
---------------- !'Block.asm' ------------------

Чтобы не смотреть беспомощно на то что вытворяет линкер с вашим обьектником, к стати обычно не большим, нужно взять все под контроль. Лично я не стал цацкатся и оглядываться на копирайты и просто взял рекомендуемую для Win32 DLL библиотеку CLIB3R.lib и распотрошил. Достал оттуда DLLStart и функции mem* и str*. Оставил от всего DLLStart только

       mov       eax,00000001H
       ret       0000000cH

ну и естественно немного подправленный копирайт :-) Слинковал я все это в библиотеку mindll.lib (входит в поставку энциклопедии). Получилось 5.6K. Я ничего не сказал про __CHK, потому что отключил проверку стека. Но, если Вам это не по душе, можете включить в библиотеку и ее. Только лучше,сначала, маленько прохудить. Лично я не нашел в ней ничего полезного.

Теперь о подключаемых DLL. Каждый компилятор имеет вариант своей статической библиотеки в виде DLL. Для такой динамической линковки есть свой lib-файл. Так что если вы экспериментируете с библиотеками и Вам удалось наконец найти библиотеку с которой dll-ка плагина не ужасающе громадна - посмотрите на вашу dll-ку QuickViewer'ом - что ему надо для работы. Если это что-то помимо user32.dll, kernel32.dll, advapi32.dll то ваш плагин, скорее всего, будет работать только у пользователей такого же компилятора. Так что лучше обрубить линкеру крылья и все библиотеки прописывать самому. Так вернее.

III. Собственно это все. Теперь примеры:

;---------------- 'makefile' ------------------
# Это собственно рабочий кусок.
#Я привык их делать сам, а не из IDE - так понятнее.

Blocks.dll : Blocks.obj
         wlink file Blocks.obj @plugin >err.log

# ну тут наверно все понятно файл plugin.lnk будет чуть позже.

Blocks.obj : Blocks.cpp Blocks.hpp
         wpp386 -3r -bd -d0 -mf -s Blocks.cpp

# ключи:
# -3r оптимизация под 386 и передача параметров через регистр.
# -bd - для DLL.
# -d0 - без информации для дебагера.
# -mf - Модель памяти flat.
# -s - отключить проверку стека.
---------------- !'makefile' ------------------
;---------------- 'plugin.lnk' ------------------
FORMAT
    WINDOWS NT DLL
# Это формат выходного файла

OPTION
    NODEFAULTLIB,
    NOSTDCALL
# Первое - чтобы линкер не подключил что не надо
# Второе - чтобы экспортные функции экспортировались "как есть"
# к стати вот как они декларируются:
# extern "C"
# {
# void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info);
# HANDLE WINAPI _export OpenPlugin(int OpenFrom,int Item);
# void WINAPI _export GetPluginInfo(struct PluginInfo *Info);
# };
# обратите внимание на ключевое слово "_export"

LIBRARY
     mindll.lib,
     USER32.LIB,
     KERNEL32.LIB,
     ADVAPI32.LIB

# Здесь перечисленные сами библиотеки.
# Первое описано выше
# Со второй по четвертую - соответствуют стандартным DLL-кам.

RUNTIME CONSOLE
# Особо ни на что не влияет.
---------------- !'plugin.lnk' ------------------

Вот с этим всем из 4K С++ файла получаем 4K dll. Это конечно не показатель, но все же :-)

18.10.1999
наверх


Подсказка в "нестандартных" диалогах.

главная | статьи
Валентин Скирдин vskirdin@mail.ru
Игорь Русских ruiv@uic.nnov.ru

Что такое «нестандартные» диалоги можно увидеть на примере плагинов "Active Symbol Table" или "Calculator". Их нестандартность заключается в том, что эти плагины не используют Dialog API от FAR...

FAR Manager до 1.65 (включительно)

...А почему? А потому, что стандартному Dialog API не хватает "интерактивности", а именно нормального обработчика диалогов. Тот "куцый" интерфейс, который предоставляет Dialog API, не позволяет сделать нормальный интерактивный диалог. Выхода здесь два:

Первое - просить Евгения Рошала переписать Dialog API с поддержкой пользовательской функции-обработчика диалога.
Второе - "извращаться", путем создания своего оконного интерфейса...

Но не о том здесь речь. Все бы хорошо, да вот только нету в Plugins API еще одной детали - API для вызова Help. Но выход есть, и весьма оригинальный: диалог About на основе стандартного Dialog API (уж этот умеет правильно реагировать на клавишу F1), например такого:

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

HANDLE WINAPI _export OpenPlugin(int OpenFrom,int Item)
{
  INPUT_RECORD rec;
  BOOL done=FALSE;
  ...
  while (!done)
  {
    Info.EditorControl(ECTL_READINPUT,&rec);
    ...
    if (rec.Event.KeyEvent.wVirtualKeyCode == VK_F1 &&
        rec.Event.KeyEvent.bKeyDown)
    {
      // засылаем F1 в очередь...
      WriteConsoleInput(GetStdHandle

(STD_INPUT_HANDLE),
           &rec,1,&lpNumberOfEventsWritten);
      // ... и выводим диалог
      Info.Dialog(Info.ModuleNumber,-1,-1,26,13,
           "Navigate",DialogItems,numItems);

    }
    ...
  }
  ...
}

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

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

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

К слову сказать, автору плагина HexEditor Алексею Пахотину удалось довольно просто разрешить этот конфликт - я (Игорь) в порыве хакерства как-то не обратил на этот момент внимания. Человеку будет не влом закрывать этот диалог, если он сам его открыл, и сам вызвал из него хелп. Таким образом в его HexEditor-е просто-напросто выводится довольно большой диалог с копирайтами (а как же - мы все гордые:)), в котором пользователю предлагается при желании нажать еще и F1. А потом? А сам нажал - сам и убирай. В этом случае вам не надо знать архитектуру консолей виндов, а тем более каких-то там странных функций по записи сообщений, которых никогда и не было.

Будьте проще.

FAR Manager 1.70 и выше

Вот здесь подобных "извращений" делать не нужно. Все уже сделано - сервисная функция ShowHelp. Приведенный выше кусок теперь будет выглядеть так:

HANDLE WINAPI _export OpenPlugin(int OpenFrom,int Item)
{
  INPUT_RECORD rec;
  BOOL done=FALSE;
  ...
  while (!done)
  {
    Info.EditorControl(ECTL_READINPUT,&rec);
    ...
    if (rec.Event.KeyEvent.wVirtualKeyCode == VK_F1 &&
        rec.Event.KeyEvent.bKeyDown)
    {
      // вызываем нужный хелп...
      Info.ShowHelp(Info.ModuleName,"Navigate",0);
    }
    ...
  }
  ...
}

Почувствуйте разницу (естественно About-диалог не создаем)...

Вот теперь действительно - Будьте проще.

14.10.1999
Rev. 21.07.2000
наверх


Как получить полный путь редактируемого файла...

Как получить полный путь редактируемого файла из плагина в редакторе?

главная | статьи
Валентин Скирдин vskirdin@mail.ru

Замечание Замечание

  • Материал данной статьи потерял всякую актуальность с выходом FAR Manager 1.65, но оставлен в качестве учебного пособия.

В FIDO этот вопрос задавали, здесь повторяют...

Решил я поэкспериментировать с этим вопросом, и вот что у меня получилось. Очень кратко, самую суть...

После получения информации о редактируемом файле в EditorInfo->Filename находится имя редактируемого файла. Если имя файла без пути, то файл явно в текущем каталоге. Воспользуемся экспортируемой функцией ProcessEditorEvent (событие EE_READ) и тем фактом, что в полный путь входит имя диска.

char Buffer[250]={0};
char *FilePart;

int WINAPI _export ProcessEditorEvent( int Event, void *Param)
{
  if(Event == EE_READ)
  {
    struct EditorInfo ei;
    Info.EditorControl(ECTL_GETINFO,&ei);
    if(!strrchr(ei.FileName,':'))
    {
      DWORD retlen;
      retlen=GetFullPathName

(ei.FileName,240,Buffer,&FilePart);
    }
    else
      lstrcpy(Buffer,ei.FileName);
  }
  return 0;
}

Событие EE_READ происходит один раз, после того, как редактор загрузил файл на редактирование. На этом и построен весь механизм определения полного пути к файлу. После отработки этого фрагмента у Вас всегда в переменной Buffer будет имя редактируемого файла с полным путем.

19.08.1999
наверх


Как уменьшить размер плагина: Borland C++ 5.02

Как уменьшить размер плагина

(на примере Borland C++ 5.02)
главная | статьи
Валентин Скирдин vskirdin@mail.ru

Основная часть моей сознательной программистской жизни была связана с компиляторами от фирмы Borland: сначала TurboC 2.5, потом Borland C++ 3.1, сейчас это Borland C++ 5.02. Именно как я стремился уменьшить размер плагина "EditSwap" сейчас и опишу...

По началу все как обычно - создаем проект (DLL, Win32 Console, Dinamic), генерим MAK-файл и с этим MAK-файлом и работаем... Можно конечно и из среды все это дело скомпилить, но то, о чем я Вам сейчас расскажу, такого сделать в IDE не получится...

...После компиляции размер DLL`я получился примерно 8K. Попробовал - заработало. Написал письмо Рошалу "о своих достижениях" и приатачил к письму архив со своим "творением"... Вот что я получил в ответ:

Ты его похоже слинковал с dynamic libraries, так что при отсутствии cw3230.dll он не грузится. В принципе можешь закачать его на ftp://rwntug.quarta.msk.ru. Правда там уже лежит аналогичный - qwerty.rar, но он тоже слинкован с dynamic libraries и соответственно почти ни у кого не запускается :-)

...Скомпилил без dynamic libraries - увы, размер DLL`лины увеличился раз в семь :-(. Странно - оригинальный EditCase после компиляции получался либо таким же монстром либо требовал cw3230.dll... У Рошала выяснил, что...

Генерируешь makefile, а потом убираешь из него startup code: это строка с c0d32.obj. Правда после этого некоторые функции сишной библиотеки становятся недоступными (например, распределение памяти), и приходится напрямую обращаться к Win32 API.

Пробую - не получается - линковщик выдает ошибки - чой-то найти не смог... Оказалось, что вместо TLINK стоял ILINK. Заменил ILINK на TLINK и... опять строка cw3230.dll присутствует в файле...

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

# Borland C++ IDE generated makefile
#
.AUTODEPEND

#
# Borland C++ tools
#
IMPLIB  = Implib
BCC32   = Bcc32 +BccW32.cfg
TLINK32 = TLink32
TLIB    = TLib

#
# Dependency List
#
Dep_EditSwap = editswap.lib

EditSwap : BccW32.cfg $(Dep_EditSwap)
  echo MakeNode

editswap.lib : editswap.dll
  $(IMPLIB) $@ editswap.dll

Dep_editswapddll = editswap.obj

editswap.dll : $(Dep_editswapddll)
  $(TLINK32) @&&|
# Если здесь ставить  ILINK32 - то без c0d32.obj ну ни как...
  -Tpd -ap -c -w-dll -LU:\BC5\LIB -x +
# c:\bc5\lib\c0d32.obj - если эту строку оставить, то размерчик...
editswap.obj
$<,$*
C:\BC5\LIB\import32.lib+
C:\BC5\LIB\cw32.lib
# C:\BC5\LIB\cw32i.lib - эта строка приводила к cw3230.dll

|
editswap.obj :  editswap.cpp
  $(BCC32) -c @&&|
  -o$@ editswap.cpp
|

# Compiler configuration file
BccW32.cfg :
   Copy &&|
-w
-v-
...
-a1
-IC:\BC5\INCLUDE
| $@

Вот, собственно и все. Шаманство да и только :-)

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

P.S.
Однажды, 30 Jun 1999, Владимир Тарасов (tsoftgroup@chat.ru) написал, что не использует MAK-файлы для построения плагинов:
ну вобщем, я использовал ручной метод сборки, т.е. у меня bat-ник такого содержания:

@echo off
del qwerty.dll
del qwerty.lib
del qwerty.obj
bcc32 -c -M- qwerty.cpp
tlib qwerty.lib +qwerty.obj
tlink32 -Tpd -aa qwerty.obj, qwerty.dll, , import32 cw32

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

31.05.1999
наверх


Написание плагина на Delphi (ID3 Viewer)

главная | статьи
Gigabyte, 2004
http://www.gigabyte.iatp.org.ua

Замечание Замечание

  • Данная статья с незначительными изменениями (ошибки исправил :-) добавлена в энциклопедию Иваном Синтюриным (IS).
    Оригинал статьи находится по адресу http://www.gigabyte.iatp.org.ua/articles/farplugins.html.

Введение

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

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

Для начала откроем директорию в которой установлен FAR и поищем то, что могло бы нам пригодится при разработке плагинов. Здесь мы обнаружим архив PlugDoc.rar и распакуем его в отдельный каталог.

От IS: здесь и далее по тексту вместо "PlugDoc.rar" следует читать "FarManager17хDevPack".

Теперь можно более детально разобраться с содержимым этого архива:

  • Папка Examples - здесь находятся примеры уже имеющихся расширений (Временная панель, Архиватор, Просмотр сетевого окружения и т.п.)
  • В папке Headers.c, как видно из названия хранятся заголовки и объявления функций необходимых для написания плагинов на С.
  • Папка Headers.pas включает модули с теми же объявлениями для языка Pascal.

Из других полезных вещей, на которые вам следует обратить внимание можно назвать файл справки plugins.chm в котором достаточно подробно описаны все возможности по использованию функций FAR-а, к которым имеет доступ плагин.

Для беглого ознакомления с техникой разработки плагинов для FAR-a нам будет достаточно заглянуть в исходник HelloWorld.pas, расположенный в Examples\HelloWorld. Но его точно будет недостаточно для написания более менее полезных модулей.

И поэтому после HelloWorld мы разберемся с задачей написания просмотрщика ID3 тегов в MP3 файлах.

Здравствуй, Мир!

Как уже говорилось в каталоге Expamples\HelloWorld есть исходник простенького плагина, с которого мы и начнем изучение расширений для FAR-a.

Итак, скомпилировав файл HelloWorld.pas (а это можно сделать написав в командной сроке "dcc32 helloworld.pas") мы получим файл библиотеки HelloWorld.dll. который вместе с дополнительными файлами (*.lng и *.hlf) поместить в отдельную папку каталога Plugins который размещается в директории FAR-a (к примеру C:\Program Files\Far\Plugins\Simple\). Далее, следуя рекомендациям из справки и дополнительных файлов из архива PlugDoc.rar, мы закрываем FAR и открываем его снова (дабы он обнаружил наш вновь созданный плагин). Хотя лично я просто открываю еще одну его копию. Теперь для просмотра результатов наших титанических усилий мы в заново открытом FAR-e жмем F11 и внимательно изучаем список подключенных модулей (рис.1). Наш плагин в этом списке выведен под названием "Здравствуй, Мир!". При нажатии на него появляется следующее предупреждение (рис.2).

Реализация этого модуля довольно проста. Если взглянуть на исходник HelloWorld.pas, то там мы увидим:

  • В самом конце - секцию экспортируемых функций SetStartupInfo, GetPluginInfo, OpenPlugin;
  • Первая из этих функций вызывается один раз при загрузке плагина. Здесь необходимо, как минимум, сохранить передаваемую ей ссылку на внутренние функции FAR-a, при помощи которых и будет создаваться и вызываться сообщение.
  • При вызове второй функции мы возвращаем ей информацию о нашем модуле (название плагина в списке, флаги его присутствия в списке при разных экранных режимах - Viewer, Editor, FilePanel...).
  • Последняя функция отвечает за собственно отображения сообщения при запуске модуля из списка.

Остановимся на каждом пункте более подробно.

Процедура SetStartupInfo.

procedure SetStartupInfo(var psi: TPluginStartupInfo); stdcall;
begin
  Move(psi, FARAPI, SizeOf(FARAPI));
end;

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

TPluginStartupInfo = packed record
    StructSize: integer;
    ModuleName: packed array[0..Pred(NM)] of char;
    ModuleNumber: integer;
    RootKey: PChar;
    Menu: TFarApiMenu;
    Dialog: TFarApiDialog;
    Message: TFarApiMessage;
    GetMsg: TFarApiGetMsg;
    Control: TFarApiControl;
    SaveScreen: TFarApiSaveScreen;
    RestoreScreen: TFarApiRestoreScreen;
    GetDirList: TFarApiGetDirList;
    GetPluginDirList: TFarApiGetPluginDirList;
    FreeDirList: TFarApiFreeDirList;
    Viewer: TFarApiViewer;
    Editor: TFarApiEditor;
    CmpName: TFarApiCmpName;
    CharTable: TFarApiCharTable;
    Text: TFarApiText;
    EditorControl: TFarApiEditorControl;
    FSF: PFarStandardFunctions;
    ShowHelp: TFarApiShowHelp;
    AdvControl: TFarApiAdvControl;
    InputBox: TFarApiInputBox;
    DialogEx: TFarApiDialogEx;
    SendDlgMessage: TFarApiSendDlgMessage;
    DefDlgProc: TFarApiDefDlgProc;
    Reserved: array[0..1] of DWORD;
  end;

Большинство из которых отвечают за вызов тех или иных сервисных функций самого FAR-a. Так функции Menu, Message, Dialog, Control отвечают за вызов соответственно указателей на меню, вывод информационных сообщений, создание диалогов, получение информации об имеющихся в наличии панелях (Файловая, Информационная, Временная:). Другие же функции позволяют выводить текст, справку, открывать редактор и просмотрщик файлов. Кроме этих функций используется также и другой набор из т.н. Стандартных функций (FSF:PFarStandardFunctions), в который включены функции по работе со строками (сравнение, преобразование:), с буфером обмена, с таблицами перекодировок символов и т.п.

Процедура GetPluginInfo. В модуле HelloWorld реализована следующим образом:

procedure GetPluginInfo(var pi: TPluginInfo); stdcall;
begin
  pi.StructSize:= SizeOf(pi);
  pi.Flags:= PF_EDITOR;

  PluginMenuStrings[0]:= GetMsg(MTitle);
  pi.PluginMenuStrings:= @PluginMenuStrings;
  pi.PluginMenuStringsNumber:= 1;
end;

Здесь происходит "заполнение анкеты" нашего плагина (т.е. структуры TPluginInfo) путем указания флага и названия нашего модуля. Кроме этих параметров можно также заполнить параметры:

  • DiskMenuStrings: PPCharArr - указатель на список с названиями пунктов, которые будут добавлены в меню дисков (Alt+F1,Alt+F2).
  • DiskMenuNumbers: PintArr - указатель на список с клавишами быстрого вызова пункта из меню дисков. Если этот параметр равен NULL, то FAR автоматически назначит горячие клавиши для каждого пункта.
  • DiskMenuStringsNumber: integer - количество строк, которые будут добавляться в меню дисков.
  • PluginConfigStrings: PPCharArr - список пунктов, которые будут добавлены в меню конфигурации подключаемых модулей.
  • PluginConfigStringsNumber: integer - количество этих самых пунктов.
  • CommandPrefix: Pchar - префикс команд, используется для перехвата стандартной реакции FAR на командную строку с различными префиксами типа http://www.site.com, ftp://ftp.site.com и т.д.

Функция OpenPlugin вызывается каждый раз при запуске плагина тем или иным образом. Здесь размещается код, который собственно и отвечает за отображение и деятельность нашего модуля:

function OpenPlugin(OpenFrom: integer; Item: integer): THandle; stdcall;
var
  Msg: array[0..6] of PChar;
begin
  Msg[0]:= GetMsg(MTitle);
  Msg[1]:= GetMsg(MMessage1);
  Msg[2]:= GetMsg(MMessage2);
  Msg[3]:= GetMsg(MMessage3);
  Msg[4]:= GetMsg(MMessage4);
  Msg[5]:= #01#00;                   // separator line
  Msg[6]:= GetMsg(MButton);

  FARAPI.Message(FARAPI.ModuleNumber,             // PluginNumber
                 FMSG_WARNING or FMSG_LEFTALIGN,  // Flags
                'Contents',                       // HelpTopic
                 @Msg,                            // Items
                 7,                               // ItemsNumber
                 1);                              // ButtonsNumber

  result:= INVALID_HANDLE_VALUE;
end;

Здесь в первых строках идет заполнение массива строк, из которых будет состоять наше сообщение. Значения этих строк берутся из стандартного языкового файла (т.е. файла с расширением lng расположенного в той же директории, что и модуль и соответствующего используемому в FAR языку). Далее происходит вызов стандартной функции Message, которая и отображает окно сообщения. Присвоение результату функции значения INVALID_HANDLE_VALUE необходимо для того, чтоб потом не возится с освобождением ресурсов, которые выделяет FAR под создание новой панели для нашего плагина. В других же случаях необходимо будет реализовать еще и процедуру ClosePlugin, которая теоретически принимает дескриптор, созданный в функции OpenPlugin, и освобождает соответствующие ему ресурсы.

ID3 Вьювер

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

Для приготовления этого блюда нам понадобится:

  • IDE Delphi 3,4,5,6,7,8 - одна штука
  • Компонент TvID3v1 из набор компонентов JCL/JVCL для чтения id3 тегов, или любой другой компонент с теми же функциями (можно и не компонент, а просто функцию или процедуру).
  • Набор заголовочных файлов из директории Headers.pas
  • Другие приправы по вкусу.

После сбора всех ингредиентов нам следует запустить Delphi и создать в нем новый проект-библиотеку. В эту библиотеку мы будет поочередно носить все функции рассмотренные в предыдущей главе.

Сперва мы сохраним указатель на сервисные функции FAR-a:

library Simple;
uses
  windows,
  plugin,
  DialogDef in 'DialogDef.pas';

procedure SetStartupInfo(var psi: TPluginStartupInfo); stdcall;
begin
  Move(psi, FARAPI, SizeOf(FARAPI));
end;

Далее добавляем название нашего модуля в список модулей вызываемых клавишей F11:

var
  PluginMenuStrings: array[0..0] of PChar;

procedure GetPluginInfo(var pi: TPluginInfo); stdcall;
begin
  pi.StructSize:= SizeOf(pi);
  pi.Flags:= PF_EDITOR;
  PluginMenuStrings[0]:= 'Simple Plugin';
  pi.PluginMenuStrings:= @PluginMenuStrings;
  pi.PluginMenuStringsNumber:= 1;
end;

Теперь реализуем собственно отображение информации на экране:

function OpenPlugin(OpenFrom: integer; Item: integer): THandle; stdcall;
begin
  CreateDialog;
  FARAPI.Dialog(FARAPI.ModuleNumber, -1, -1, 40, 20, nil, @DialogItems, DialogItemsCount);
  result:= INVALID_HANDLE_VALUE;
end;

Здесь главную роль играет объявленная в модуле DialogDef функция, которая создает элементы диалога, который отображается посредством функции Dialog.

Сам вид уже готового диалога показан на рисунке 3. Как видим наш диалог состоит из 7-ми элементов:

  • Панели с названием "Информация MP3"
  • Статического текста с названием "Файл" (Аналог Tlabel в стандартных оконных приложениях)
  • Редактируемого названия файла
  • Трех строк текста, которые отображают соответственно название, исполнителя и альбом
  • Кнопки закрыть

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

  with DialogItems[0] do
   begin
    ItemType:=DI_DOUBLEBOX;
    X1:=0;Y1:=0;
    X2:=39;Y2:=19;
    Focus:=0;
    Flags:=DIF_BOXCOLOR;
    S:=FARAPI.GetMsg(FARAPI.ModuleNumber,0);
    with Data do
  ZeroMemory(@Data,SizeOf(Data));
    with Data do
     Move(Pointer(S)^,Data,Length(S));
   end;

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

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

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

FARAPI.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,@P);

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

     if @P<>nil then
       if (P.PanelType=PTYPE_FILEPANEL) and (P.ItemsNumber>0) then
        begin
         S:=P.PanelItems^[P.CurrentItem].FindData.cFilename;
         with Data do
          ZeroMemory(@Data,SizeOf(Data));
         with Data do
          Move(Pointer(S)^,Data,Min(512,Length(S)));
        end;

Далее, как видно из кода, мы запрашиваем информацию о текущей позиции курсора и считываем информацию о текущем файле. Эти данные (точнее имя текущего файла) мы и передаем в параметр Data нашего элемента, а также используем его для извлечения ID3 тега посредством компонента TvID3v1:

id3:=TJvId3v1.Create(nil);
 try
  id3.FileName:=S;
  with DialogItems[3] do
   begin
    ItemType:=DI_TEXT;
    X1:=2;Y1:=5;X2:=35;
    if id3.TagPresent then S:=FARAPI.GetMsg(FARAPI.ModuleNumber,2)+': '+id3.SongName
    else S:='No mp3 tag found';
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    Move(Pointer(S)^,Data,35);
    S:='';
   end;

Если же данный файл не содержит тегов или это вообще не тот файл, то мы просто записываем на место данных строку "No mp3 tag found".

В конце модуля мы на всякий случай очищаем массив DialogItems:

begin
 ZeroMemory(@DialogItems,SizeOf(DialogItems));
end.

Замечания и предложения

Инсталляция этого плагина реализуется тем же образом, что HelloWorld. Но перед этим следует дополнительно создать языковый файл с указанием названий всех элементов нашего диалога. К счастью программистов и простых пользователей языковый файл FAR - это простой текстовый файл, в котором в отдельных строках размещаются названия отдельных элементов. Первая строка заполняется служебным идентификатором <.Language>, в который записывается название используемого языка. В нашем случае мы создадим языковый файл следующего содержания:

.Langugage = Russian,Russian (Русский)
"Информация MP3"
"Файл"
"Название"
"Исполнитель"
"Альбом"
"Закрыть"

Кроме того тут есть возможность использования комментариев, а также символов табуляции, конца строки и т.п. Которые записываются в стиле C/C++.

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

Листинг - Simple.dpr

{$APPTYPE CONSOLE}
{$MINENUMSIZE 4}
library Simple;
uses
  windows,
  plugin,
  DialogDEf in 'DialogDEf.pas';

procedure SetStartupInfo(var psi: TPluginStartupInfo); stdcall;
begin
  Move(psi, FARAPI, SizeOf(FARAPI));
end;

var
  PluginMenuStrings: array[0..0] of PChar;

procedure GetPluginInfo(var pi: TPluginInfo); stdcall;
begin
  pi.StructSize:= SizeOf(pi);
  pi.Flags:= PF_EDITOR;
  PluginMenuStrings[0]:= 'Simple Plugin';
  pi.PluginMenuStrings:= @PluginMenuStrings;
  pi.PluginMenuStringsNumber:= 1;
end;

function OpenPlugin(OpenFrom: integer; Item: integer): THandle; stdcall;
begin
  CreateDialog;
  FARAPI.Dialog(FARAPI.ModuleNumber,-1,-1,40,20,nil,@DialogItems,DialogItemsCount);
  result:= INVALID_HANDLE_VALUE;
end;

exports
  SetStartupInfo,GetPluginInfo,OpenPlugin;
end.

Листинг - DialogDef.pas

unit DialogDef;

interface
uses plugin,windows;
Const DialogItemsCount = 7;

var FARAPI: TPluginStartupInfo;
var DialogItems: array[0..DialogItemsCount-1] of TFarDialogItem;

procedure CreateDialog;
implementation
uses jvid3v1,DebugUnit;

function Min(A,B:Integer):Integer;
begin
Result:=A;
if A>B then Result:=B;
end;

procedure CreateDialog;
var S:String;Mem:Pointer;
    P:TPanelInfo;
    id3:TJvId3v1;
begin
  with DialogItems[0] do
   begin
    ItemType:=DI_DOUBLEBOX;
    X1:=0;Y1:=0;
    X2:=39;Y2:=19;
    Focus:=0;
    Flags:=DIF_BOXCOLOR;
    S:=FARAPI.GetMsg(FARAPI.ModuleNumber,0);
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    with Data do
     Move(Pointer(S)^,Data,Length(S));
   end;
  with DialogItems[1] do
   begin
    ItemType:=DI_TEXT;
    X1:=2;Y1:=2;
    S:=FARAPI.GetMsg(FARAPI.ModuleNumber,1);
    X2:=Length(S);
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    with Data do
     Move(Pointer(S)^,Data,Length(S));
   end;
  with DialogItems[2] do
   begin
    ItemType:=DI_EDIT;
    X1:=2;Y1:=3;
    X2:=37;
    Focus:=1;
    DefaultButton:=True;
    GetMem(Mem,2048);
    try
    FARAPI.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,@P);
    finally
     if @P<>nil then
       if (P.PanelType=PTYPE_FILEPANEL) and (P.ItemsNumber>0) then
        begin
         S:=P.PanelItems^[P.CurrentItem].FindData.cFilename;
         with Data do
          ZeroMemory(@Data,SizeOf(Data));
         with Data do
          Move(Pointer(S)^,Data,Min(512,Length(S)));
        end;
     FreeMem(Mem,2048);
    end;
   end;
id3:=TJvId3v1.Create(nil);
 try
  id3.FileName:=S;
  with DialogItems[3] do
   begin
    ItemType:=DI_TEXT;
    X1:=2;Y1:=5;X2:=35;
    if id3.TagPresent then S:=FARAPI.GetMsg(FARAPI.ModuleNumber,2)+': '+id3.SongName
    else S:='No mp3 tag found';
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    Move(Pointer(S)^,Data,35);
    S:='';
   end;
  with DialogItems[4] do
   begin
    ItemType:=DI_TEXT;
    X1:=2;Y1:=6;X2:=35;
    if id3.TagPresent then S:=FARAPI.GetMsg(FARAPI.ModuleNumber,3)+': '+id3.Artist
    else S:='No mp3 tag found';
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    Move(Pointer(S)^,Data,35);
    S:='';
   end;
  with DialogItems[5] do
   begin
    ItemType:=DI_TEXT;
    X1:=2;Y1:=7;X2:=35;
    if id3.TagPresent then S:=FARAPI.GetMsg(FARAPI.ModuleNumber,4)+': '+id3.Album
    else S:='No mp3 tag found';
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    Move(Pointer(S)^,Data,35);
    S:='';
   end;
 finally
  id3.free;
 end;
  with DialogItems[6] do
   begin
    ItemType:=DI_BUTTON;
    S:=FARAPI.GetMsg(FARAPI.ModuleNumber,5);
    X1:=15;
    X2:=Length(S);
    Y1:=18;
    Y2:=1;
    Focus:=1;
    DefaultButton:=True;
    with Data do
     ZeroMemory(@Data,SizeOf(Data));
    with Data do
     Move(Pointer(S)^,Data,Length(S));
    S:='';
   end;
end;

begin
ZeroMemory(@DialogItems,SizeOf(DialogItems));
end.

Листинг - Simple.lng

.Langugage = Russian,Russian (Русский)
"Информация MP3"
"Файл"
"Название"
"Исполнитель"
"Альбом"
"Закрыть"
наверх


Работа с "временной панелью" в своем плагине

главная | статьи
Иван Синтюрин spinoza@mail.ru
http://www.moris.ru/~spinoza

Причиной написания данной статьи послужил, как мне кажется, наиболее эффективный на текущий день способ решения проблемы добавления собственным плагином "Поиск и Замена (S&R)" файлов на стандартную "временную панель" FAR, которым я и хочу поделиться с вами.

Немного истории Немного истории (можно абзац пропустить и не читать, тут выстраданное мною, поэтому не могу не написать :-).

  • С временной панелью S&R научился работать пять лет назад (в 2001 г.), функционально решение было оформлено достаточно "топорно" - в виде написания своей собственной "временной панели". Почему я называю это "топорным" - фактически все сведено к copy-and-paste исходного кода стандартной "временной панели", т.е. один и тот же одинаково работающий код загружается в память дважды. Да что там "одинаково работающий"... Со временем приходится периодически тратить время на синхронизацию своего кода с кодом стандартного плагина, чтобы не путать пользователя фактом существования двух "временных панелей" (если код синхронизировать, то пользователь как бы не замечает, что панелей две). В конце концов мне это надоело я с решил научить плагин помещать файлы на стандартную "временную панель", дабы не плодить сущности. Первое, что пришло мне в голову - делать LoadLibrary(стандартный плагин), а потом дергать его функции. Казалось бы, простое решение моментально обнаружило ряд трудностей: мне в своем плагине пришлось бы эмулировать ряд сервисных функций FAR (GetMsg, Message, Dialog, Menu), потому что они требуют в качестве параметра ModuleNumber, который в общем случае мне не известен. Таким образом, избавившись от одного дублирования кода, я автоматически получал другое, еще более сложное в реализации. Кроме того, из-за того, что стандартный плагин "временная панель" загружается FAR'ом в память по мере необходимости, а не тогда, когда нужно моему плагину, мы получали потенциальный глюкодром - в какой-то момент времени функции инициализации/деинициализации стандартной "временной панели" (SetStartupInfo, ExitFAR) могли быть вызваны дважды - моим плагином и FAR'ом, причем в заранее неизвестном порядке. В подобной ситуации в лучшем случае происходило бы "падение" FAR'а или того или иного плагина (проверять я не стал :-). В связи с изложенным, мне пришло в голову решение, излагаемое в следующем абзаце. Причем оно такое простое, что даже обидно, что я не догадался об этом пять лет назад.

Итак, не нужно загружать при помощи LoadLibrary стандартный плагин tmppanel.dll в память самому из своего плагина, нужно попросить сделать это FAR, тогда точно будет известно, что к моменту необходимости работы с "временной панелью" из своего плагина, она будет уже загружена в память и нужным образом проинициализирована. Для этого нужно, чтобы в tmppanel.dll выставлялся флаг PF_PRELOAD. В tmppanel.dll версии 1.70 build 27 (входит в релиз FAR 1.70) этот флаг не выставляется, поэтому я произвел все необходимые изменения в стандартном плагине и его версия 1.71 build 28 (ищите на официальном сайте) делает все, что нам нужно.

Вместо LoadLibrary мы получаем указатель на загруженную "временную панель" при помощи GetModuleHandle:

HMODULE hPluginDll=GetModuleHandle("TmpPanel.dll");

Соответственно, выгружать нам потом тоже ничего вручную не нужно.

Модуль tmppanel.dll экспортирует следующие функции: ClosePlugin, Configure, ExitFAR, GetFindData, GetMinFarVersion, GetOpenPluginInfo, GetPluginInfo, OpenFilePlugin, OpenPlugin, ProcessEvent, ProcessKey, PutFiles, SetDirectory, SetFindList, SetStartupInfo .

Нам потребуется задействовать все из них, за исключением SetStartupInfo, ExitFAR, GetPluginInfo, GetMinFarVersion, Configure, OpenFilePlugin, т.к. они представляют интерес только для самого FAR'а. Для получения адресов указанных функций используется GetProcAddress . У меня это выглядит приблизительно вот так:

typedef HANDLE (WINAPI *PLUGINOPENPLUGIN)(int OpenFrom,int Item);
typedef void (WINAPI *PLUGINCLOSEPLUGIN)(HANDLE hPlugin);
typedef void (WINAPI *PLUGINGETOPENPLUGININFO)(HANDLE hPlugin,
                                               struct OpenPluginInfo *Info);
typedef int (WINAPI *PLUGINPUTFILES)(HANDLE hPlugin,struct PluginPanelItem *PanelItem,
                                     int ItemsNumber,int Move,int OpMode);
typedef int (WINAPI *PLUGINGETFINDDATA)(HANDLE hPlugin,
                                        struct PluginPanelItem **pPanelItem,
                                        int *pItemsNumber,int OpMode);
typedef int (WINAPI *PLUGINSETDIRECTORY)(HANDLE hPlugin,const char *Dir,int OpMode);
typedef int (WINAPI *PLUGINSETFINDLIST)(HANDLE hPlugin,
                                        const struct PluginPanelItem *PanelItem,
                                        int ItemsNumber);
typedef int (WINAPI *PLUGINPROCESSKEY)(HANDLE hPlugin,int Key,
                                       unsigned int ControlState);
typedef int (WINAPI *PLUGINPROCESSEVENT)(HANDLE hPlugin,int Event,void *Param);

struct TEMPPANEL
{
  PLUGINOPENPLUGIN        OpenPlugin;
  PLUGINCLOSEPLUGIN       ClosePlugin;
  PLUGINSETFINDLIST       SetFindList;
  PLUGINPROCESSKEY        ProcessKey;
  PLUGINPROCESSEVENT      ProcessEvent;
  PLUGINGETOPENPLUGININFO GetOpenPluginInfo;
  PLUGINGETFINDDATA       GetFindData;
  PLUGINSETDIRECTORY      SetDirectory;
  PLUGINPUTFILES          PutFiles;
  BOOL Init(HMODULE hDll)
  {
    OpenPlugin=NULL;
    ClosePlugin=NULL;
    SetFindList=NULL;
    ProcessKey=NULL;
    ProcessEvent=NULL;
    GetOpenPluginInfo=NULL;
    GetFindData=NULL;
    SetDirectory=NULL;
    PutFiles=NULL;
    if(hDll)
    {
      OpenPlugin=reinterpret_cast(GetProcAddress(hDll,"OpenPlugin"));
      ClosePlugin=reinterpret_cast(GetProcAddress(hDll,"ClosePlugin"));
      SetFindList=reinterpret_cast(GetProcAddress(hDll,"SetFindList"));
      ProcessKey=reinterpret_cast(GetProcAddress(hDll,"ProcessKey"));
      ProcessEvent=reinterpret_cast(GetProcAddress(hDll, "ProcessEvent"));
      GetOpenPluginInfo=reinterpret_cast(GetProcAddress(hDll, "GetOpenPluginInfo"));
      GetFindData=reinterpret_cast(GetProcAddress(hDll, "GetFindData"));
      SetDirectory=reinterpret_cast(GetProcAddress(hDll, "SetDirectory"));
      PutFiles=reinterpret_cast(GetProcAddress(hDll, "PutFiles"));
    }
    return OpenPlugin && ClosePlugin && SetFindList && ProcessKey && ProcessEvent &&
           GetOpenPluginInfo && GetFindData && SetDirectory && PutFiles;
  }
};
...
HMODULE hPluginDll=GetModuleHandle("TmpPanel.dll");
// тут код проверки hPluginDll, на случай, если вызов GetModuleHandle
// окончился неудачей, вывод соответствующих сообщений и т.п.
TEMPPANEL TmpPanel;
if(TmpPanel.Init(hPluginDll))
{
  // если инициализация указателей на функции успешная
}
else
{
  // ...если облом
}

Чтобы добавить наши файлы на "временную панель" нужно получить указатель на эту самую панель при помощи TmpPanel.OpenPlugin, затем вызвать TmpPanel.SetFindList и, наконец, вернуть FAR'у указатель на созданную временную панель. Схематично выглядеть это будет вот так:

HANDLE WINAPI _export OpenPlugin(int OpenFrom, int Item)
{
  HANDLE retCode=INVALID_HANDLE_VALUE;
  ...
  PluginPanelItem *ppi=NULL; // тут будет перечень файлов, которые
                             // надо поместить на временную панель
  DWORD ppi_total=0;         // количество этих файлов
  ...
  if(ppi_total)
  {
    // TmpPanel мы инициализировали где-то раньше!
    HANDLE hTmp=TmpPanel.OpenPlugin(OPEN_FINDLIST,0);
    if(INVALID_HANDLE_VALUE!=hTmp)
    {
      // временная панель успешно создана,
      // теперь добавим в нее файлы
      if(!TmpPanel.SetFindList(hTmp, ppi, ppi_total))
      {
        // не удалось поместить файлы на панель,
        // закроем ее
        TmpPanel.ClosePlugin(hTmp);
        hTmp=INVALID_HANDLE_VALUE;
      }
      retCode=hTmp;
    }
    else
    {
      // создать временную панель не удалось
    }
  }
  ...
  return retCode;
}

Ну, и наконец, следует экспортировать все прочие функции, которые которые мы цепляем из tmppanel.dll (кроме SetFindList - зачем плодить сущности?!), в противном случае, пользователь не сможет полноценно работать с "временной панелью", открытой путем вызова нашего плагина. Код экспортируемых функций простейший:

void WINAPI ClosePlugin(HANDLE hPlugin)
{
  TmpPanel.ClosePlugin(hPlugin);
}

void WINAPI GetOpenPluginInfo(HANDLE hPlugin, struct OpenPluginInfo *Info)
{
  TmpPanel.GetOpenPluginInfo(hPlugin, Info);
}

int WINAPI GetFindData(HANDLE hPlugin, struct PluginPanelItem **pPanelItem,
                       int *pItemsNumber, int OpMode)
{
  return TmpPanel.GetFindData(hPlugin, pPanelItem, pItemsNumber, OpMode);
}

int WINAPI SetDirectory(HANDLE hPlugin,const char *Dir,int OpMode)
{
  return TmpPanel.SetDirectory(hPlugin, Dir, OpMode);
}

int WINAPI PutFiles(HANDLE hPlugin, struct PluginPanelItem *PanelItem,
                    int ItemsNumber,int Move, int OpMode)
{
  return TmpPanel.PutFiles(hPlugin, PanelItem, ItemsNumber, Move, OpMode);
}

int WINAPI ProcessEvent(HANDLE hPlugin, int Event, void *Param)
{
  return TmpPanel.ProcessEvent(hPlugin, Event, Param);
}

int WINAPI ProcessKey(HANDLE hPlugin, int Key, unsigned int ControlState)
{
  return TmpPanel.ProcessKey(hPlugin, Key, ControlState);
}

Это все, буду рад, если указанная статья поможет кому-то при написании собственного плагина.

15.04.2006

P.S. На момент написания данной статьи соответствующая версия S&R публично не доступна, т.к. находится все еще в стадии разработки. Следите за рекламой! :-)

наверх


Дополнительные разделы

главная
  • Дополнительные структуры и функции
  • Примеры
  • 'Правила хорошего тона'
  • Обзор возможностей подключаемых модулей
  • Лирическое введение в плагины
  • FAR plugins API History
  • Как установить этот файл
  • Вопросы и ответы
  • Авторы


Как установить этот файл

главная

Visual C++ - MSDN

В случае, если у вас установлена библиотека msdn, можно включить Энциклопедию и туда - таким образом можно будет писать в ide, и пользоваться одновременно и нашими и vc-шными хелпами. Помог нам в этом Serg Bormant (2:5027/12.80@fidonet) - здесь же мы и приводим написанный им небольшой «GuideLine» (с моими замечаниями, ruiv).

    Просматривая энциклопедию (FarEncyclopedia.ru.chm), обнаружил раздел,
посвященный ее установке.
...
    Раздельные   .chm   и  .chi  хороши  только  тем,  что  можно
установить  индекс  (.chi)  отдельно,  а текст хранить на сменном
носителе.  Для  энциклопедии,  учитывая ее размер (242641 байт),
это не актуально. "Монолитный" .chm также содержит в себе индекс,
поэтому подключить его не составит труда.

    Для подключения в коллекцию надо учитывать следующие моменты.
*.col описывает представление (логическую структуру) коллекции на
уровне  разделов/подразделов  (Folders).  Сведения  о  физическом
расположении файлов хранятся отдельно в файле hhcolreg.dat.

    Вот  полученный  методом  "научного  тыка" способ подключения
FarEncyclopedia.ru.chm,   не   претендующий  на  абсолютную  идеологическую
правильность :), но тем не менее успешно работающий...

    0. Исходные...
w2k eng, vc6 sp3, msdn jan-2000, HTML Help Control 4.74.8702

Энциклопедия:
D:\Program Files\Far\PlugDoc\
  FarEncyclopedia.ru.chm

Коллекция (этот путь можно "подсмотреть" в ярлыке к MSDN):
D:\Program Files\mvs\MSDN\2000JAN\1033\
  MSDN000.COL

Регистрация коллекций:
D:\Documents and Settings\All Users\Application Data\Microsoft\HTML Help\
  hhcolreg.dat

    1. Действуем:
    1.1. MSDN не загружен...
    1.2.  В  каталоге  с  MSDN ищем файл *.col (в моем случае это
msdn000.col),  делаем  его резервную копию (как и всех изменяемых
нами  файлов).  Идем  в  конец и перед последним тэгом </Folders>
добавим (добавленные строчки помечены ">"):

 <XML>
 <HTMLHelpCollection>
 <collectionnum value=10003/>
 ...
 <Folders>
 <Folder>
   <TitleString value="MSDN Library - January 2000"/>
   <FolderOrder value=1/>
 ...
 </Folder>
>
><Folder>
>  <TitleString value="Far PlugRinG Help Project"/>
><FolderOrder value=2/>
>  <Folder>
>    <TitleString value="=pluginsr"/>
>    <FolderOrder value=1/>
>    <LangId value=1033/>
>  </Folder>
></Folder>
>
 </Folders>
 </HTMLHelpCollection>
 </XML>

    Обратите  внимание  на  тэги  <collectionnum.../> -- номер
коллекции и <FolderOrder.../> -- порядковый номер папки внутри
уровня.
    (collectionnum  вам  будет нужен при изменении следующего
файла,  а  вот  FolderOrder  зависит  от того, куда вы вставляете
кусок.  Его  номер  должен  быть  больше  указанного  в последнем
разделе Folder)

    1.3.   Ищем   файл   регистрации  коллекций  (их  может  быть
несколько,    нас   интересует   тот,   в   котором   в   разделе
<Collections> прописана наша коллекция, и добавим информацию о
файле в раздел <DocCompilations>:
(В моем случае этот файл (hhcolreg.dat) находился в каталоге d:\winnt\help\)

 <XML>
 <HTMLHelpDocInfo>
 ...
 <Collections>
 ...
 <Collection>
   <ColNum value=10003/>
   <ColName value="D:\Program Files\MVS\MSDN\2000JAN\1033\MSDN000.COL"/>
 </Collection>
 </Collections>
 <Locations>
 ...
 </Locations>
 <DocCompilations>
 <DocCompilation>
 ...
 </DocCompilation>
>
><DocCompilation>
><DocCompId value="pluginsr"/>
>  <DocCompLanguage value=1033/>
>  <LocationHistory>
>    <ColNum value=10003/>
>    <TitleLocation value="D:\Program Files\Far\PlugDoc\FarEncyclopedia.ru.chm"/>
>    <IndexLocation value="D:\Program Files\Far\PlugDoc\FarEncyclopedia.ru.chm"/>
>    <QueryLocation value=""/>
>    <LocationRef value=""/>
>    <Version value=0/>
>    <LastPromptedVersion value=0/>
>    <TitleSampleLocation value=""/>
>    <TitleQueryLocation value=""/>
>    <SupportsMerge value=0/>
>  </LocationHistory>
></DocCompilation>
>

 </DocCompilations>
 </HTMLHelpDocInfo>
 </XML>

    Здесь номер коллекции -- <ColNum.../>
(Это именно тот номер, который вы запомнили в первом файле)

    1.4.  Грузим MSDN, в Contents наблюдаем новый раздел, щелкаем
по  вкладке  Index,  дожидаемся,  пока  новый индекс будет создан
(процесс  длителен  !), проверяем работоспособность, набрав любое
ключевое слово, например AF_AVPRESENT.

    2.  Если  не  получилось,  значит где-то допустили ошибку :(,
попробуйте  все  вернуть в исходное состояние и повторить сначала :)

Serg Bormant, 2:5027/12.80@fidonet, bormant@chat.ru, bormant@netcity.ru

С уважением, Serg Bormant                           29 июня 2000

--- GoldED+/W32 1.1.4.5
 * Origin: To be, to be, two beer: without questions... (2:5027/12.80)

Единственным недостатком этого метода является то, что индексы в msdn будут перестраиваться после каждого изменения Энциклопедии - то есть после каждого выпуска новой версии - занимает это 3-5 минут. Зато теперь у вас будут интегрированные хелпы по Plugin API FAR Manager и Win32 API.

Заметьте также, что такая интегрированная энциклопедия поддерживает линки на win32-топики из того же msdn. Соответственно hlp версия энциклопедии активно линкуется с win32.hlp. Так что совсем малина.

И совсем свежее уточнение:

Date: Wed, 26 Sep 2001 21:40:15 +0400
From: Dennis Trachuk <dennis.trachuk@nm.ru>
Subject: MSDN Integration

Hello All!

стататейка по интеграции хтмл-хелп файлов в MSDN
http://codeproject.com/winhelp/msdnintegrator.asp
(локальная копия статьи прилагается)

а самое приятное, что есть утиль для проведения этого безобразия:
http://codeproject.com/winhelp/MSDNIntegrator/MSDNIntegrator.zip
ну и то же самое только с исходниками:
http://codeproject.com/winhelp/MSDNIntegrator/MSDNIntegrator_src.zip

Если есть проблемы с MSDN ("упал", переехал в другое место, etc.), то возможно статья "Восстановление MSDN" (by Sergey Creedence) поможет справиться с некоторыми проблемами.

FAR Manager

Если вы любите "верстать" свои программы, используя редактор FAR`а, то воспользуйтесь плагином "Active-Help". Этот плагин добавляет к редактору возможность вызвать контекстно-зависимую помощь...

А работает он, кстати(!), как с hlp так и с chm файлами. Более того, вы можете указать ему путь к вашей msdn-коллекции (MSDNVS98.COL) - и будет загружаться она!


Лирическое введение в плагины

главная
Вот скажи мне американец, в чём сила?
В деньгах, говоришь?
Вот и брат мне говорит, что в деньгах.
А сила... она в плагинах

Итак, плагины. Многим может показаться пошлым, неповоротливым, зажравшимся - но это факт: к FAR Manager сейчас существует больше сотни плагинов всевозможных мастей - от тетриса до почтовых клиентов. Это на первый взгляд странное явление довольно просто объяснить - каждый хочет того, чего ему надо - и не ждет когда это сделает кто-нибудь со стороны.

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

Сама идея плагинов позволяет настраивать оболочку под себя, добавляя нужное и выкидывая лишнее. Это и есть самое главное преимущество FAR Manager перед монолитными созданиями.

Итак, что же нужно, чтобы воплотить свою гениальную (не сомневаемся) идею? Ответ прост - надо быть программистом. Как не прискорбно для некоторых личностей, но без этого не обойдешься. Сейчас существуют интерфейсы для написания плагинов на C/C++ (сам FAR написан на C++, если интересно), Delphi и "зачатки" к языку Assembler (кстати, есть плагины, написанные на Modula, Ada и C--), но вы можете выбрать и любой другой язык, главное, чтобы ваш компилятор умел создавать dll под windows. В некоторых случаях вы столкнетесь с кучей дополнительных деталей и подробностей - о них вы сможете почитать в специальных разделах.

FAR рассматривает все DLL-модули во всех подкаталогах каталога Plugins как плагины, так что если ваш плагин использует собственные DLL-ки, то они должны иметь другое расширение. Плагин фактически - обычная библиотека, которая выполняется в контексте консольного процесса - так что ваш плагин может делать все (ну или почти все), что может делать обычное консольное Win32 приложение. Хотя, из соображений совместимости плагин не должен выводить текст непосредственно на экран, для этого необходимо использовать функцию Text из сервиса FAR Manager.

Смотрите также:
Обзор возможностей подключаемых модулей, Экспортируемые функции, Сервисные функции, Структуры, Поддержка архивов


Обзор возможностей подключаемых модулей

главная | Интернет

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

Не вдаваясь в подробности и персоналии, можно отметить только некоторые из этих возможностей:

  • управление принтерами, как подключенными к ПК, так и сетевыми
  • подсветка синтаксиса в исходных текстах программ
  • работа с FTP-серверами (с поддержкой доступа через различные типы прокси, автоматической докачкой и прочее)
  • поиск и замена символов одновременно во множестве файлов с применением регулярных выражений.
  • средства переименования групп файлов с возможностью использования сложных составных масок из символов подстановки и шаблонов
  • NNTP/SMTP/POP3/IMAP4 клиенты и отправка сообщений на пейджер
  • работа при нестандартных размерах текстового экрана
  • перекодировка текстов с учетом национальных кодовых таблиц
  • манипуляции с содержимым корзины
  • управление приоритетами процессов на локальном или на сетевом ПК
  • автозавершение слов в редакторе и работа с шаблонами
  • редактирование системного реестра Windows
  • создание и изменение ярлыков Windows
  • всевозможные манипуляции с файлами и текстом, делающие комфортной работу с FIDO
  • кодирование и декодирование файлов в формате UUE
  • управление программой WinAmp и модификация комментариев MP3-файлов
  • обработка Quake PAK файлов
  • Работа с различными серверами через ODBC + работа с серверами ORACLE через OCI.
  • управление службой RAS
  • запуск внешних программ (компиляторов, конверторов и проч.) при редактировании текстов в редакторе FAR
  • отображение содержимого файлов справки Windows (.hlp и .chm)
  • калькуляторы с разными возможностями
  • различные игры :-)
  • функции проверки орфографии при обработке текста в редакторе FAR
  • подготовка каталога сменных накопителей и многое другое...

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

  1. сайт PlugRinG
    http://plugring.farmanager.com

  2. форум
    http://forum.farmanager.com

  3. конференции USENET
    news:fido7.far.support (на Google Groups)
    news:fido7.far.development (на Google Groups)

  4. конференции FidoNet
    far.support
    far.development

  5. листы рассылки
    http://groups.google.com/group/fardev
    http://groups.yahoo.com/group/plugring
    http://groups.yahoo.com/group/farpluginsapi
    http://groups.yahoo.com/group/plugring_announce

  6. использовать плагин PlugRinG viewer - и все самые последние плагины вы сможете посмотреть и скачать к себе на диск прямо из FAR.


"Правила хорошего тона"

Спецификация плагинов...

главная

...или "Правила хорошего тона". Рекомендации. Версия от 30.04.2001

Этот документ является попыткой создания спецификации (а вернее рекомендаций) на плагины к FAR Manager. Пока весь материал будет идти сплошным текстом (впоследствии разгребем по разделам).

Данный документ - для программистов, пишущих плагины для FAR Manager.

Добавляйте, уточняйте, рекомендуйте и...

  1. Дистрибутив плагина рекомендуется упаковывать в архив ZIP (однозначно, т.к. некоторые сервера RAR-архивы "отдают" как text/plain, что в результате приводит к т.н. "битому" архиву).

  2. Обязательно сопровождать дистрибутив файлом file_id.diz, в котором описывать название плагина, версию, дату выпуска, краткое описание для чего предназначен плагин (языки русский, английский) и координаты разработчика. Файл file_id.diz должен быть обязательно в коpне аpхива.

  3. Также имеет смысл сопровождать дистрибутив файлом whatsnew.txt (или history.txt), в котором описывать, что было изменено (с указанием версии и даты).

  4. Одинаковые названия для плагинов в диалогах их вызова и настройки:
    Если плагин добавляет в меню строку "поиск и замена", то и в меню "Параметры внешних модулей" должна быть добавлена строка, начинающаяся с "поиск и замена", но уж никак не "а вот это настройки для поиска и замены" или просто "настройки", тогда пользователю не придется ломать голову над тем, как называются настройки для вашего супер-пупер плагина.

  5. Если вы добавляете в дистрибутив плагина какие-либо макросы в виде reg-файлов, то не забывайте заполнять переменную "Description".

  6. Стоит исключить добавление нескольких строк в меню одним плагином. Лучше плагину показывать свое меню со всеми требуемыми функциями:
    Не надо добавлять в меню строки "поиск", "замена", "поиск в выделенном", не думайте, что ваш плагин - единственный, в этом меню разных строк уже и без вас хватает, в подобном случае лучше добавьте одну строчку "поиск и замена", а при старте плагина показывайте меню со строками "поиск", "замена" и т.д.

  7. Плагин ДОЛЖЕH чистить все временные файлы/каталоги по окончании своей работы.

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

    Пример.

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

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

    Пример.

    Плагин "shell link..." (про версию 1.20!) позволяет юзеру редактировать свойства ярлыка и переходить по нему к конкретному файлу. Это делается из меню плагинов. Это не есть хорошо. Лучше было б, если Оскар (автор) добавил работу с префиксом для командной строки. Тогда, например, можно было бы сделал ассоциацию на *.lnk по f4 - редактирование свойств, enter - переход по ссылке. Это интуитивно понятнее.

  10. Все сообщения, выдаваемые плагином на экран (в диалогах или в меню), должны содержаться в LNG-файлах. Как альтернативный вариант - использовать модуль локализации LocMsg.cpp из бонуса к Энциклопедии (рекомендуется использовать LocMsg.cpp в плагинах второго уровня или для тех случаев, когда необходимо, чтобы ваш плагин реагировал на изменения в файле сообщений без перезапуска FAR). Это позволит сделать плагин языконезависимым.

  11. При длительных операциях дать возможность пользователю прервать процесс. То есть, примерно то, о чем говорится в статье "Обработка нажатия ESC или "Авторам долгодумающих плагинов посвящается...". Это однозначно должно быть. Даже в таких плагинах как colorer. Hельзя, чтоб FAR умирал из-за того что colorer не может провести парсинг строки в 200 кил.

  12. В файлах помощи рекомендуется:
    • размещать всю необходимую для работы информацию: "зачем хранить на винте всякие ридми? Они у меня есть, но лежат в архиве. Какой смысл мне лезть в архив за доп.информацией? Imho, можно и hlf помещать все, что нужно для работы, просто следует отделять обычные сведения от advanced и ставить ссылочки типа "подробнее", "расширенное", "advanced"... Тогда не придется в самый неподходящий момент закрывать плагин и искать этот отдельный текстовый файл. Все это "IMHO", естественно."
    • на главной странице
      1. указывать назначение плагина и версию
      2. ссылки на прочие разделы
    • желательно иметь раздел "Alphabetical list", где перечислены все существующие разделы.
    • в любом разделе помощи предусмотреть линки на главную страницу.
    • обязательно нужно проверить то, как будет выглядеть любая из страниц помощи при размере консоли 80x25. Многие об этом забывают, в результате, помощь показывается нормально только у авторов, а у других строчки "съезжают". Помочь в проверке может плагин HlfViewer.

  13. Вызов плагина на текущем файле через F11 в любом случае нужно сделать из соображений хорошего тона, равно как и дать возможность пользователю отключить в настройках плагина функциональность OpenFilePlugin.

  14. И про вызов из командной строки через префикс не забыть бы :-). Хорошо бы, чтобы этот префикс был настраиваемым в конфигурации плагина, во избежание пересечения с чем-нибудь ещё.

  15. Плагин в своем меню может и не иметь средств изменения порядка элементов меню, но уж если имеет, то это должно делаться по Ctrl-Up/Down.

  16. Старайтесь всегда при показе меню использовать флаг FMENU_WRAPMODE, его отсутствие причиняет лишние неудобства пользователям.

  17. Про меню.
    1. Если его текст заканчивается многоточием ("...") - получу диалоговое окно
    2. Если в тексте, выровненный по правому краю, имеется значок ">" - получу подменю
    3. В противном случае, будет сразу выполнена выбранная мной команда.
    Пример:
    Только что понадобилось отпечатать текст, первый раз решил сделать это из FAR. Через Print Manager. Ставлю курсор на файл, F11 / Print Manager. В полученном меню вижу "Print selected files" и не знаю, что будет, если я этот пункт выберу - сразу печать или что-то еще из настроек. Аналогично дальше то же самое в списке принтеров. В итоге жутко неудобно.

  18. Если Ваш плагин использует компоненты (DLL, OCX, etc), не входящие в состав Windows, не поленитесь указать это в разделе "Инсталляция" своего readme.txt.

    Идеально, если вы протестируете установку своего плагина на "голую" (только что установленную в минимальной конфигурации) Windows 95.

  19. Обрабатывая клавиатурные события редактора, не забывайте о том, что к клавишам перемещения курсора относятся не только общеупотребительные (Left, Right, Up, Down, PgUp, PgDn, Home, End), но и такие сочетания как Ctrl-N, Ctrl-E и Ctrl-S.

  20. Если вы прилагаете к своему плагину для редактора комплект макросов для обеспечения быстрой и удобной работы, а ваш плагин не является универсальным и указанные макросы имеют смысл, например, только при редактировании исходных текстов программ на С++ или только для текстовых файлов, то не следует использовать обычные макросы, хранящиеся в реестре, т.к. они будут действовать на все редакторы и только занимать лишние клавиши в файлах другого типа. Вместо этого можно предлагать пользователю комплект макросов для плагина [ESC] (тут в скобках должно быть имя автора, прямая ссылка на плагин или просто на домашнюю страницу автора, т.к. плагин может меняться и урл будет меняться тоже) или аналогичного другого плагина (на момент написания этих строк таковой не известен), которые практически ничем не отличаются от макросов FAR, но лишены перечисленных недостатков (действуют только на указанные пользователем типы файлов и не занимают место в реестре).


Примеры

главная
В данном разделе перечислены примеры плагинов, входящих в стандартную поставку к FAR Manager (%FAR%\PlugDoc\Examples\)

Работа в редакторе:

Align
Выравнивание блока в редакторе.
Простой плагин из разряда "Вызвали, отработал, завершился" - пример работы с сервисной функцией EditorControl.
Auto wrap
Auto wrap в редакторе - пример установки "хука" для внутреннего редактора FAR Manager.
Во включенном состоянии плагин пропускает через себя все события от клавиатуры и мыши. Используется функция ProcessEditorInput:
int WINAPI _export ProcessEditorInput(const INPUT_RECORD *Rec)
{
  // обработка очередного KEY_EVENT
}
Brackets
Поиск и выделение парных скобок в редакторе.
Плагин из разряда "Вызвали, отработал, завершился".
Поиск ведется с помощью ECTL_GETSTRING, установка курсора на найденную парную скобку - ECTL_SETPOSITION, выделение блока - ECTL_SELECT.
DrawLine
Рисование линий.
Вариант "хука" из разряда "Вызвали, работает, пользователь сам останавливает работу плагина".
Используется "бесконечный цикл" с вызовом команд ECTL_READINPUT и ECTL_PROCESSINPUT:
HANDLE WINAPI _export OpenPlugin(int OpenFrom,INT_PTR Item)
{
  ...
  while (!Done)
  {
    Info.EditorControl(ECTL_READINPUT,&rec);
    ...
    Info.EditorControl(ECTL_PROCESSINPUT,&rec);
  }
  ...
}
EditCase
Изменение начертания символов (верхний/нижний регистр).
Плагин из разряда "Вызвали, отработал, завершился".
Строка берется с помощью команды ECTL_GETSTRING, преобразуется и заменяется в редакторе с помощью команды ECTL_SETSTRING.
HlfViewer
Плагин HlfViewer создан для помощи тем людям, которые создают или изменяют hlf-файлы, а также просто хотят просмотреть тот или иной hlf-файл помощи (обработка клавиши F1 с последующим вызовом редактируемого HLF-файла, обработка перфикса "hlf:").

Прочее:

HelloWorld
"Здравствуй, Мир!" Этот модуль FAR предназначен исключительно для учебных целей.
Как повелось - изучение любого языка программирования начинается с программы "Hello, World!". Именно это и делает данный плагин.
FAR Commands
Плагин FAR Commands (или FARCmd) предоставляет дополнительные возможности, которые можно использовать в меню пользователя, ассоциаций файлов или командной строке. Показана работа с несколькими префиксами.
FileCase
Эта команда позволяет изменить регистр отмеченных имен файлов в соответствии с любым из нескольких доступных форматов. Это - простой плагин, воспользуйтесь им как шаблоном для создания новых команд для FAR.
MultiArc
Этот набор модулей FAR позволяет работать с архивами. Для пользователя файлы в архивах не отличаются от файлов в папках. FAR сам преобразует ваши команды в соответствующие вызовы внешних архиваторов.

Это большой и сложный плагин, поддерживающий плагины второго уровня (можно добавлять поддержку новых архиваторов, написав несколько Kb исходного текста).

Network
С помощью модуля просмотра сети вы можете перемещаться по сети, переходить на сетевые диски, отображать их на локальные диски и отменять такое отображение. Нажмите F5, чтобы отобразить выбранные диски на следующие доступные буквы или F6, если вы хотите выбрать буквы сами. F8 отменяет уже существующее отображение.
TmpPanel
Временная панель поддерживает аналогичный панели файлов интерфейс и предназначена для облегчения одновременной обработки групп файлов из различных папок. Плагин позволяет использовать до 10 временных панелей, каждая из которых содержит отдельный список файлов.


История FAR plugins API

главная
Здесь отмечены ключевые моменты в истории Plugins API

FAR 1.75 01.04.2009

+ LIF_HIDDEN, LIF_GRAYED
+ MIF_HIDDEN, MIF_GRAYED
+ COL_MENUGRAYTEXT
+ COL_MENUSELECTEDGRAYTEXT
+ COL_DIALOGCOMBOGRAY
+ COL_DIALOGCOMBOSELECTEDGRAYTEXT
+ COL_DIALOGLISTGRAY
+ COL_DIALOGLISTSELECTEDGRAYTEXT
+ COL_WARNDIALOGCOMBOGRAY
+ COL_WARNDIALOGCOMBOSELECTEDGRAYTEXT
+ COL_WARNDIALOGLISTGRAY
+ COL_WARNDIALOGLISTSELECTEDGRAYTEXT

FAR 1.71 26.11.2008

+ COL_EDITORSCROLLBAR

FAR 1.71 05.11.2008

+ KEY_SLEEP

FAR 1.71 24.09.2008

* FLINK_SYMLINK переименован в FLINK_JUNCTION
+ FLINK_SYMLINKFILE
+ FLINK_SYMLINKDIR

FAR 1.71 11.08.2008

+ COL_COMMANDLINEUSERSCREEN

FAR 1.71 17.06.2008

+ VE_GOTFOCUS, VE_KILLFOCUS

FAR 1.71 15.05.2008

+ FDIS_DELREMOVESBLOCKS
+ FDIS_MOUSECLICKOUTSIDECLOSESDIALOG

FAR 1.71 30.03.2008

+ ECTL_ADDSTACKBOOKMARK
+ ECTL_CLEARSTACKBOOKMARKS
+ ECTL_DELETESTACKBOOKMARK
+ ECTL_GETSTACKBOOKMARKS
+ ECTL_NEXTSTACKBOOKMARK
+ ECTL_PREVSTACKBOOKMARK

FAR 1.71 29.03.2008

+ PFLAGS_PANELLEFT

FAR 1.71 17.03.2008

+ COL_DIALOGLISTARROWS,
+ COL_DIALOGLISTARROWSDISABLED,
+ COL_DIALOGLISTARROWSSELECTED,
+ COL_DIALOGCOMBOARROWS,
+ COL_DIALOGCOMBOARROWSDISABLED,
+ COL_DIALOGCOMBOARROWSSELECTED,
+ COL_WARNDIALOGLISTARROWS,
+ COL_WARNDIALOGLISTARROWSDISABLED,
+ COL_WARNDIALOGLISTARROWSSELECTED,
+ COL_WARNDIALOGCOMBOARROWS,
+ COL_WARNDIALOGCOMBOARROWSDISABLED,
+ COL_WARNDIALOGCOMBOARROWSSELECTED,
+ COL_MENUARROWS,
+ COL_MENUARROWSDISABLED,
+ COL_MENUARROWSSELECTED,

FAR 1.71 05.01.2008

+ KEY_MSWHEEL_LEFT, KEY_MSWHEEL_RIGHT

FAR 1.71 31.12.2007

+ ACTL_REDRAWALL

FAR 1.71 23.12.2007

+ ProcessDialogEvent
+ FarDialogEvent
+ OpenDlgPluginData
+ PF_DIALOG
+ OPEN_DIALOG
+ DIALOG_EVENTS

FAR 1.71 14.12.2007

+ MCMD_GETSTATE

FAR 1.71 06.12.2007

+ EE_GOTFOCUS, EE_KILLFOCUS
+ FE_GOTFOCUS, FE_KILLFOCUS

FAR 1.71 04.12.2007

+ DIF_NOAUTOCOMPLETE

FAR 1.71 06.08.2007

- _FAR_USE_FARFINDDATA
+ _FAR_USE_WIN32_FIND_DATA

FAR 1.71 20.02.2007

+ DIF_NOTCVTUSERCONTROL

FAR 1.71 30.01.2007

+ FCTL_GETUSERSCREEN

FAR 1.71 07.12.2006

+ VIEWER_SETMODEFLAGS_TYPES

FAR 1.71 01.12.2006

* Член структуры ViewerMode.TypeWrap переименован в ViewerMode.WordWrap
+ VCTL_SETMODE
+ enum VIEWER_SETMODE_TYPES
+ struct ViewerSetMode

FAR 1.70 29.03.2006

! снято ограничение на приходящие в функцию ProcessKey() клавиши.
+ PKF_PREPROCESS
+ ACTL_GETSHORTWINDOWINFO
+ ECF_TAB1
! EOPT_EXPANDTABS -> EOPT_EXPANDALLTABS
+ EOPT_EXPANDONLYNEWTABS, EXPAND_TABS
+ FARINT64
+ ViewerAPI: ViewerInfo, ViewerMode, ViewerSelect, ViewerSetPosition,
             ViewerControl, ProcessViewerEvent,
* Все перечисления в plugin.hpp сделаны именованными
+ FARMACRO_KEY_EVENT
+ DM_GETSELECTION, DM_SETSELECTION
+ DN_LISTHOTKEY
! плагин в ProcessEditorInput получает клавиатурные события
  как при записи, так и при воспроизведении макропоследовательности.
* Частично снято ограничение на приходящие плагину в ProcessEditorInput клавиши.
  Плагину не передаются: Ctrl-W, F11, Alt-F9, F12, Ctrl-Tab,
  Ctrl-Shift-Tab, Alt-Ins и Ctrl-Alt-Shift.
  Следующие сочетания клавиш передаются при условии, что:
   Alt-F5  - плагин PrintMan не установлен;
   Alt-F11 - редактор модальный;
   F6      - есть запрет на переключение в программу просмотра
             (при вызове функции Editor не указан флаг EF_ENABLE_F6).
+ DN_DRAWDIALOGDONE
+ ACTL_GETPLUGINMAXREADDATA, ACTL_GETWCHARMODE
+ ACTL_GETDIALOGSETTINGS
! FIS_PERSISTENTBLOCKSINEDITCONTROLS -> FDIS_PERSISTENTBLOCKSINEDITCONTROLS
! FIS_HISTORYINDIALOGEDITCONTROLS    -> FDIS_HISTORYINDIALOGEDITCONTROLS
! FIS_AUTOCOMPLETEININPUTLINES       -> FDIS_AUTOCOMPLETEININPUTLINES
+ FRS_SCANSYMLINK
+ FSS_SCANSYMLINK
! Теперь GetReparsePointInfo для сетевых каталогов возвращает ошибку,
  т.к. корректную информацию о содержимом символической связи в этом
  случае получить невозможно.
- FAR возвращал мусор в PanelInfo.SelectedItems[0] для случая, когда
  на панели нет выделенных файлов и курсор стоит на элементе ".."
+ MCMD_POSTMACROSTRING
+ ActlKeyMacro.Param
+ KSFLAGS_NOSENDKEYSTOPLUGINS
+ ESPT_SETWORDDIV, ESPT_GETWORDDIV
+ FMENU_CHANGECONSOLETITLE
! DM_LISTSETMOUSEREACTION (изменено поведение)
+ LMRT_*
+ FCTL_SETNUMERICSORT, FCTL_SETANOTHERNUMERICSORT, PFLAGS_NUMERICSORT

FAR 1.70 beta 5 09.04.2003

+ OPM_QUICKVIEW
+ FCTL_GETPANELSHORTINFO, FCTL_GETANOTHERPANELSHORTINFO
+ FIB_NOAMPERSAND
+ ESPT_LOCKMODE
+ ECTL_TURNOFFMARKINGBLOCK
! CONSOLE_* -> FAR_CONSOLE_*
+ MAXSIZE_SHORTCUTDATA
+ FCTL_CHECKPANELSEXIST
+ LIF_DELETEUSERDATA
+ EF_IMMEDIATERETURN, VF_IMMEDIATERETURN
+ FLINK_DONOTUPDATEPANEL
+ ECTL_DELETEBLOCK
+ FDLG_SMALLDIALOG, FDLG_SMALLDIALOG
+ ACTL_SETARRAYCOLOR, FarSetColors, FARCOLORFLAGS.FCLR_REDRAW
+ FarListColors

MultiArc:
+ ArcInfo.Chapters
+ ArcItemInfo.Chapter

FAR 1.70 beta 4 13.03.2002

+ EJECT_LOAD_MEDIA
+ FDLG_WARNING, FDLG_SMALLDIALOG
+ PFLAGS_*
! PanelInfo.Flags
+ KEY_MSWHEEL_UP, KEY_MSWHEEL_DOWN
+ DM_LIST*
+ VF_ENABLE_F6, VF_DISABLEHISTORY
+ EF_ENABLE_F6, EF_DISABLEHISTORY, EF_DELETEONCLOSE
+ FarList*
+ DIF_LISTWRAPMODE, DIF_LISTAUTOHIGHLIGHT, DIF_LISTNOBOX,
  DIF_SEPARATOR2
+ DM_GETCHECK, DM_SETCHECK, DM_SET3STATE, DM_SETITEMPOSITION,
  DM_GETITEMPOSITION, DM_GETDROPDOWNOPENED, DM_SETDROPDOWNOPENED,
  DM_SETHISTORY, DM_SETMOUSEEVENTNOTIFY
+ DM_LISTSETMOUSEREACTION
+ LINFO_*
+ BSTATE_*
+ ACTL_GETWINDOWCOUNT, ACTL_SETCURRENTWINDOW, ACTL_COMMIT,
  ACTL_GETFARHWND, ACTL_POSTKEYSEQUENCE
+ WTYPE_*
+ KeySequenceFlags.KSFLAGS_DISABLEOUTPUT
+ KeySequence
! Unquote
! ExpandEnvironmentStr
+ ECTL_GETBOOKMARKS
+ EditorBookMark
+ DN_LISTCHANGE, DN_MOUSECLICK, DN_DRAGGED, DN_RESIZECONSOLE,
  DN_MOUSEEVENT
+ LIFIND_EXACTMATCH
+ FMENU_USEEXT
+ MIF_*
+ FarMenuItemEx
! FarRecursiveSearch
! DI_RADIOBUTTON
+ ESPT_CHARTABLE, ESPT_SAVEFILEPOSITION
! FarCharTable
+ FCTL_GETCMDLINESELECTEDTEXT, FCTL_SETCMDLINESELECTION,
  FCTL_GETCMDLINESELECTION
+ PluginPanelItem.CRC32
+ ConvertNameToReal
+ GetReparsePointInfo
! AddEndSlash

FAR 1.70 beta 3 20.04.2001

! В plugin.hpp в некоторых экспортируемых и сервисных функциях для
  неизменяемых параметров применен модификатор "const".

+ DIF_VAREDIT - "преодоление барьера в 512 байт" - работает с элементами
  DI_EDIT и DI_COMBOBOX

! Изменена структура FarListItem (возможность работы с "длинными данными")

+ LIF_PTRDATA - для работы с "длинными данными".

! Изменены флаги LISTITEMFLAGS (LIF_*) - значения для LIF_SELECTED,
  LIF_CHECKED и LIF_SEPARATOR перенесены в младший байт старшего слова,
  LIF_DISABLE смещен "вниз".

! Изменены имена полей структуры FarDialogItemData.

+ В сообщении DN_MOUSECLICK теперь можно отловить событие DOUBLE_CLICK.
  (MouseEvent.dwEventFlags==DOUBLE_CLICK)

! Основательная переделка внутренних кодов клавиш (farkeys.hpp).

+ ACTL_EJECTMEDIA

+ DM_GETTEXTPTR, DM_SETTEXTPTR, DM_SHOWITEM, DM_ADDHISTORY

! Ctrl-Break управляемый. Раньше диалог закрывался безусловно,
  независимо от того, что вернул обработчик диалога на DM_CLOSE.

+ DIF_HIDDEN, DIF_MANUALADDHISTORY

+ DIF_SHOWAMPERSAND доступен для элементов DI_SINGLEBOX и DI_DOUBLEBOX

+ ACTL_KEYMACRO:
  struct ActlKeyMacro - интерфейсная часть для ACTL_KEYMACRO
  MCMD_LOADALL     - все макросы из реестра в память FAR`а
  MCMD_SAVEALL     - все макросы из памяти FAR`а в реестр

! Расширен синтаксис функции Message.

+ FSF.qsortex

+ EF_CREATENEW

! FSF.FarRecursiveSearch - добавлен параметр void *param

+ FAR "знает" 4 предопределенных темы в HLF-файлах:
  Contents - стандартная главная тема;
  Config   - тема, вызываемая по Shift-F1 из меню настроек плагинов;
  Editor   - тема, вызываемая по Shift-F1 из меню плагинов в редакторе;
  Viewer   - тема, вызываемая по Shift-F1 из меню плагинов в программе просмотра.

+ FHELP_USECONTENTS

* ACTL_GETFARVERSION возвращает номер версии, а не TRUE/FALSE.

* ACTL_WAITKEY ждет любую клавишу, если в качестве параметра Param передали
  NULL или -1.

+ ECTL_SETPARAM - установка параметров:
  - "Размер табуляции" (ESPT_TABSIZE)
  - "Пробелы вместо табуляции" (ESPT_EXPANDTABS)
  - "Автоотступ" (ESPT_AUTOINDENT)
  - "Курсор за пределами строки" (ESPT_CURSORBEYONDEOL)
  - Формат показа кода текущего символа (ESPT_CHARCODEBASE)

FAR 1.70 beta 2 16.12.2000

! Изменения в Param2 для сообщений DM_SETTEXT & DM_GETTEXT.
  Теперь здесь передается указатель на структуру FarDialogItemData.

+ 6 цветов для DISABLED элементов (в диалогах и предупреждениях)
  см. Headers.c\farcolor.hpp (или Headers.pas\farcolor.pas)

+ DIF_3STATE

! Для DI_PSWEDIT и DI_FIXEDIT исключена обработка флага DIF_EDITEXPAND.

+ ACTL_GETCOLOR, ACTL_GETARRAYCOLOR

! FSF.AddEndSlash работает с обоими видами слешей, также происходит
  изменение уже существующего конечного слеша на такой, который встречается
  чаще.

! Изменен формат версии - константа plugin.hpp::FARMANAGERVERSION имеет
  следующий формат:
     HIWORD:         = NNN - # build
     LOWORD:  HIBYTE =   1 - version Hi
              LOBYTE =  70 - version Lo

FAR 1.70 beta 1 20.11.2000

+ Dialog API 1.0

! Новые/измененные заголовочные файлы:
       farcolor.hpp  - Индексы цветовых атрибут.
       farkeys.hpp   - коды внутренних клавиш FAR Manager
+ FarStandardFunctions: "стандартные функции" - для уменьшения размера плагина
+ GetMinFarVersion().
+ URL-активаторы и цветовые атрибуты в HLF-файлах.

struct PluginStartupInfo:
  + AdvControl
  + InputBox
  + ShowHelp
  + DialogEx
  + SendDlgMessage
  + DefDlgProc

+ PF_FULLCMDLINE
+ FCTL_*SORTMODE, FCTL_*SORTORDER

struct KeyBarTitles:
  + CtrlShiftTitles
  + AltShiftTitles
  + CtrlAltTitles

+ EF_NONMODAL
+ ECTL_SETKEYBAR

+ DI_COMBOBOX, DI_LISTBOX, DI_USERCONTROL
+ DIF_EDITEXPAND, DIF_DROPDOWNLIST, DIF_USELASTHISTORY, DIF_BTNNOCLOSE,
  DIF_MASKEDIT, DIF_DISABLE

+ Поля редактирования с фиксированной длиной могут иметь
  маску ввода.

+ Структуры: FarListItem, FarList
+ Интерфейс для Pascal/Delphi

FAR 1.64 beta 24.05.2000

+ ECTL_SAVEFILE
+ ECTL_QUIT

+ struct EditorSaveFile

FAR 1.63 b 20.08.1999

+ VF_NONMODAL
+ VF_DELETEONCLOSE

FAR 1.62 23.05.1999

+ FCTL_GETCMDLINEPOS

FAR 1.62 b2 10.05.1999

+ EE_CLOSE

FAR 1.62 b 24.04.1999

Плагин "Colorer" "ввел" раскраску в редакторе:
+ EE_REDRAW
+ ECTL_ADDCOLOR
+ ECTL_GETCOLOR

+ struct EditorColor

+ FCTL_SETCMDLINEPOS
+ FE_COMMAND

FAR 1.61 24.02.1999

+ EE_READ
+ EE_SAVE

FAR 1.60 13.10.1998

Бурный прогресс Editor API:
+ FCTL_SETPANELDIR
+ ECTL_*
+ EOPT_*
+ BTYPE_*
+ PF_DISABLEPANELS
+ PF_EDITOR
+ PF_VIEWER
+ OPEN_EDITOR
+ OPEN_VIEWER

+ struct EditorGetString
+ struct EditorSetString
+ struct EditorInfo
+ struct EditorSetPosition
+ struct EditorSelect
+ struct EditorConvertText
+ struct EditorConvertPos

struct PluginStartupInfo:
  + EditorControl

FAR 1.52 26.06.1998

+ FCTL_SETUSERSCREEN
+ FCT_DETECT
+ SM_COMPRESSEDSIZE
+ SM_NUMLINKS
+ FE_BREAK
+ OPM_DESCR

+ struct CharTableSet

struct PanelInfo:
  + ShortNames
  + SortMode

struct PluginStartupInfo:
  + CharTable
  + Text

FAR 1.50 (release version) 09.02.1998

+ PPIF_USERDATA
+ FCTL_SETVIEWMODE
+ FCTL_SETANOTHERVIEWMODE
+ FCTL_INSERTCMDLINE
+ OPIF_USEATTRHIGHLIGHTING

struct PluginPanelItem:
  + UserData

FAR 1.50 beta 03.10.1997

+ DIF_HISTORY
+ FCTL_GETCMDLINE
+ FCTL_SETANOTHERSELECTION
+ FCTL_SETCMDLINE
+ FCTL_SETSELECTION
+ FE_CLOSE
+ FMSG_LEFTALIGN
+ OPEN_COMMANDLINE
+ OPEN_SHORTCUT
+ OPIF_EXTERNALDELETE
+ OPIF_EXTERNALGET
+ OPIF_EXTERNALMKDIR
+ OPIF_EXTERNALPUT
+ OPM_TOPLEVEL
+ PPIF_SELECTED

struct PluginStartupInfo:
  + Viewer
  + Editor
  + CmpName

struct PluginInfo:
  +CommandPrefix

struct PanelMode:
  +StatusColumnTypes
  +StatusColumnWidths

struct KeyBarTitles:
  +ShortcutData

MultiArc:
  Изменено поле структуры ArcInfo:
    - int AuthVer
    + DWORD Flags

  Добавлены флаги...
    enum ARCINFO_FLAGS
    {
      AF_AVPRESENT=1,
      AF_IGNOREERRORS=2
    };

FAR 1.40 beta 27.06.1997

Первое упоминание о FAR Plugins API:
"External DLL modules (plugins) can be used to implement new FAR commands and emulate file systems..."
ER> "Вообще о плагинах я задумался после того, как Лаврентьев попросил меня
ER> сделать версию FAR с поддержкой Арвида. Для нее еще Спасибожко хорошее
ER> название придумал - FARvid ;-) Разрабатывать такую версию мне было неохота,
ER> поэтому я решил предоставить желающим API, достаточное для добавления
ER> такой поддержки без моего участия..."
Для данной версии доступны:
  • Exported functions:
    ClosePlugin, Configure, DeleteFiles, ExitFAR, FreeFindData, FreeVirtualFindData, GetFiles, GetFindData, GetOpenPluginInfo, GetPluginInfo, GetVirtualFindData, MakeDirectory, OpenFilePlugin, OpenPlugin, ProcessEvent, ProcessHostFile, ProcessKey, PutFiles, SetDirectory, SetFindList, SetStartupInfo
  • Service functions:
    Control, Dialog, FreeDirList, GetDirList, GetMsg, GetPluginDirList, Menu, Message, RestoreScreen, SaveScreen
  • Structures
    FarDialogItem, FarMenuItem, InfoPanelLine, KeyBarTitles, OpenPluginInfo, PanelInfo, PanelMode, PanelRedrawInfo, PluginInfo, PluginPanelItem, PluginStartupInfo
  • Language and help files


Programming FAR plugins - Encyclopedia for Developers - Длинная история

главная
Дела давно минувших дней,
Приданья старины глубокой

"Давным-давно, в далекой-далекой...", а может и не совсем далекой, в любом случае это уже история... Наслаждайтесь :-)

29 марта 2006 г.

  • Вернулись обратно к варианту без .CHI-индекса. Если Энциклопедия включена в коллекцию, то не забудьте заменить pluginsr.chi на pluginsr.chm.
  • Изменен дизайн статей Энциклопедии в стиле MSDN (не точная копия, но похоже :-)
  • Bug: Для несколько идущих подряд вызовов ACTL_POSTKEYSEQUENCE срабатывал только первый.
  • Уточнение в InputBox для параметра HelpTopic.
  • MultiArc API: добавлено поле ArcInfo.Chapters - количество глав (chapters) в архиве.
  • MultiArc API: добавлено поле ArcItemInfo.Chapter - глава (chapter) в архиве, которой принадлежит файл.
  • MultiArc API: добавлено описание формата файла custom.ini.
  • Документированы макросы Dlg*.
  • Во время исполнения макросов в ProcessEditorInput передается событие типа FARMACRO_KEY_EVENT.
  • Сообщение DM_LISTSETTITLES не работает, если в листе ни одного элемента.
  • Дублирование курсоров после удаления пунктов списка DI_LISTBOX в случае, если курсор стоит не на удаляемом элементе.
  • Пара новых сообщений DM_GETSELECTION и DM_SETSELECTION, позволяющих управлять выделением блоков в строках редактирования диалога.
  • Новые команды функции AdvControl: ACTL_GETPLUGINMAXREADDATA и ACTL_GETWCHARMODE.
  • Флаг FRS_SCANSYMLINK позволяет функции FSF.FarRecursiveSearch "заходить" в символические связи во время обхода дерева каталогов.
  • Некорректное центрирование элементов DI_RADIOBUTTON и DI_CHECKBOX с выставленным флагом DIF_CENTERGROUP.
  • Теперь FSF.GetReparsePointInfo для сетевых каталогов возвращает ошибку, т.к. корректную информацию о содержимом символической связи в этом случае получить невозможно.
  • В связи с выносом диалоговых настроек отдельным пунктом добавлена команда ACTL_GETDIALOGSETTINGS. Соответственно изменены значения и названия следующих констант:
    Было | Стало
    FIS_PERSISTENTBLOCKSINEDITCONTROLS | FDIS_PERSISTENTBLOCKSINEDITCONTROLS
    FIS_HISTORYINDIALOGEDITCONTROLS | FDIS_HISTORYINDIALOGEDITCONTROLS
    FIS_AUTOCOMPLETEININPUTLINES | FDIS_AUTOCOMPLETEININPUTLINES
  • FAR возвращал мусор в PanelInfo.SelectedItems[0] для случая, когда на панели нет выделенных файлов и курсор стоит на элементе ".."
  • Все перечисления в plugin.hpp сделаны именованными
  • Новая команда MCMD_POSTMACROSTRING - передать в FAR макрос в текстовом виде (в том виде, как их хранит FAR Manager в реестре)
  • Уточнение структуры ActlKeyMacro: добавлен член Param.PlainText - указатель на строку, содержащую макропоследовательность.
  • Новый флаг KSFLAGS_NOSENDKEYSTOPLUGINS - не передавать клавиши редакторным плагинам (плагинам, экспортирующим функцию ProcessEditorInput)
  • Новая команда ESPT_SETWORDDIV - позволяет изменить строку символов-разделителей слов (параметр cParam) для текущей копии редактора.
  • Новая команда ESPT_GETWORDDIV - позволяет получить строку символов-разделителей слов (параметр cParam) для текущей копии редактора.
  • Bug: Если заголовок диалога начинается с числа, то это число отрезается в заголовке окна Фара.
  • Bug: Смена фокуса (нажатие клавиши Tab или Shift-Tab) в диалоге с единственным элементом приводила к зависанию FAR.
  • Поле FarDialogItem.Data для DI_LISTBOX используется как верхний заголовок списка (если не выставлен флаг DIF_LISTNOBOX).
  • В качестве заголовка консоли принимается заголовок списка (DI_LISTBOX), если в диалоге нет рамок и список (DI_LISTBOX) первый элемент.
  • Bug: Преобразование 'Key = FarNameToKey ("AltCtrlБуква") -> FarKeyToName (Key)' работало некорректно (возвращается Alt00000, вместо AltCtrlБуква)
  • Bug: В .lng файле нельзя было ставить пробелы после идентификатора ".Language", например ".Language = foo".
  • Bug: FSF.FarRecursiveSearch, не может найти файл если в качестве маски задано его короткое имя.
  • Новый флаг FMENU_CHANGECONSOLETITLE функции Menu. Если указан, то FAR изменит заголовок консоли в значение, указанное в параметре Title (если Title не пуст).
  • Новый флаг DIF_LISTNOCLOSE - при выборе элемента из списка не закрывать диалог.
  • Сообщение DM_LISTSETMOUSEREACTION теперь позволяет более гибко управлять слежением списка за передвижением курсора мыши (перемещение курсора в списке). С помощью этого сообщения можно задавать одно из трех состояний:
    1. список будет реагировать на движение мыши только если элемент в фокусе,
    2. список будет всегда реагировать на движение мыши
    3. список не будет реагировать на движение мыши
  • При вызове команды ECTL_SAVEFILE FAR не запоминал новое имя файла.
  • Пара новых статей от Eugene Yavorsky: Плагин для разных версий FAR Manager и Как уменьшить размер плагина: Microsoft VC++ 4.2 (замечания к статье Олега Данилова)
  • Новое сообщение DN_LISTHOTKEY. Сообщает обработчику диалога, что пользователь для смены пункта в списке (DI_LISTBOX) воспользовался горячими клавишами.
  • Bug: При движении мышью по листу сообщение DN_LISTCHANGE посылалось даже, если элемент списка не менялся. т.е. если двигать мышью в пределах одного элемента, будут посылаться много DN_LISTCHANGE с номером этого элемента.
  • Логическое дополнение к числовой сортировке: команды FCTL_SETNUMERICSORT и FCTL_SETANOTHERNUMERICSORT флаг PFLAGS_NUMERICSORT (включен NumericSort на панели) к PanelInfo.Flags
  • Bug: Падение FAR, если в функции FSF.PointToName() параметр Path == NULL.
  • Bug: При сохранении файла в редакторе, вызванного из плагина портился пользовательский заголовок, переданный в параметре Title функции Editor.
  • Опубликован Viewer API.
  • Добавлен раздел Panel API.
  • Флаг EOPT_EXPANDTABS переименован в EOPT_EXPANDALLTABS.
  • Добавлен раздел, описывающий макросы.
  • Статья Алексея Ярославского: Как компилировать с помощью Borland C++ 5.5 без startup code
  • Новый флаг ECF_TAB1. Начиная с build 1957 FAR раскрашивает символ табуляции на всю длину, на которую расширяется табуляция. Если необходимо, чтобы символ табуляции для цветовой области занимал 1 знакоместо, то для элемента EditorColor.Color, в дополнении к цвету, необходимо выставить флаг ECF_TAB1.
  • ECTL_GETBOOKMARKS и ECTL_GETINFO можно вызывать в EE_CLOSE.
  • В API поддержки архивов добавился флаг AF_HDRENCRYPTED, показывающий, что у архива шифрованный каталог.
  • Замечания к статье "Плагин для разных версий FAR Manager", по поводу сравнения версий.
  • Начиная с 1.70 build 2052 для панельных плагинов, использующих функцию "ProcessKey", снято ограничение на приходящие в функцию клавиши.
  • Добавлена макрообласть "UserMenu"
  • Новый флаг PKF_PREPROCESS.

09 апреля 2003 г.

  • Теперь Энциклопедия распространяется в виде двух файлов pluginsr.chi (индекс) и pluginsr.chm ("данные")
  • Имена таблиц, возвращаемые плагинам через функцию CharTable, не соответствовали именам, которые показывались в списке по Shift-F8.
  • Bug: FAR изменял переданные плагином данные для панели "Информация" (Ctrl-L).
  • Второй параметр у экспортируемой фунцкии SetFindList является const.
  • Во время вызова ExitFAR плагину недоступны следующие сервисные функции: InputBox, Menu, Dialog, DialogEx GetMsg, Message, Control, SaveScreen, RestoreScreen, GetDirList, Viewer, Editor, CharTable, Text, EditorControl, GetPluginDirList, ShowHelp, AdvControl (частично).
    В AdvControl доступны только следующие команды: ACTL_GETFARVERSION, ACTL_GETSYSWORDDIV, ACTL_GETCOLOR, ACTL_GETARRAYCOLOR, ACTL_GETFARHWND, ACTL_GETSYSTEMSETTINGS, ACTL_GETPANELSETTINGS, ACTL_GETINTERFACESETTINGS, ACTL_GETCONFIRMATIONS, ACTL_GETDESCSETTINGS.
  • Запрещено создание немодального редактора или просмотрщика из модального.
  • Запрещено переключение из модального в другое окно.
  • ESPT_LOCKMODE - плагины могут запретить/отменить запрет изменения файла в редакторе.
  • ECTL_TURNOFFMARKINGBLOCK - сбросить флаг редактора, который устанавливается всегда, когда пользователь осуществляет выделение блока.
  • Некорректное отображение списка DI_LISTBOX с флагом DIF_LISTNOBOX
  • В списке DI_LISTBOX не обрабатывались горячие клавиши.
  • В диалоге при активном фокусном списке DI_LISTBOX не обрабатывались горячие клавиши.
  • При получении фокуса ввода неверно отрисовывался элемент DI_EDIT с выставленным флагом DIF_SELECTONENTRY.
  • Некорректно формировался длинный заголовок диалога.
  • Некорректно обрабатывалось программное переключение (DM_SETCHECK) для группы зависимых кнопок (DI_RADIOBUTTON).
  • Цвет разделительной линии в диалогах не соответствовал цвету рамки.
  • Новый флаг LIF_DELETEUSERDATA, который заставляет FAR удалить ассоциированные данные при обновлении пункта списка командой DM_LISTUPDATE. По умолчанию данные при обновлении не удаляются.
  • DM_LISTADDSTR возвращал некорректное значение позиции добавляемого пункта в списке.
  • При обновлении списка (DM_LISTUPDATE) прикрепленные пользовательские данные (DM_LISTSETDATA) пункта списка удалялись.
  • DM_SETTEXT (DM_SETTEXTPTR) теперь работают с DI_LISTBOX. Происходит обновление текущего элемента списка. Прикрепленные пользовательские данные (DM_LISTSETDATA) пункта списка не изменяются.
  • Новый флаг FIB_NOAMPERSAND - Не показывать в приглашении ввода амперсанд, использовать его для определения горячей клавиши.
  • Константы CONSOLE_* переименованы в FAR_CONSOLE_* (конфликт с константами из WinCon.h)
  • Некорректная отрисовка текущего указателя в меню для случая, когда в переданном массиве пунктов меню первым элементом стоял разделитель и не был задан текущий элемент (или в качестве текущего элемента был сам разделитель).
  • Экспортируемая функция PutFiles может возвращать число 2 (успех, но позиционировать курсор на файл не нужно).
  • Изменилось описание структуры OpenPluginInfo - некоторые члены стали const
  • Конструкция Message(FMSG_ALLINONE,"\nFoobar") приводила к падению FAR (первым символом '\n' пытаемся вывести диалог сообщения без заголовка)
  • FCTL_GETPANELSHORTINFO
    Аналогична FCTL_GETPANELINFO, но поля PanelItems и SelectedItems структуры PanelInfo не заполнены и равны NULL. Эта команда предназначена для получения общей информации о панели без конкретного знания файлового контента.
  • FCTL_GETANOTHERPANELSHORTINFO
    Аналогична FCTL_GETPANELSHORTINFO, но получает информацию о пассивной панели.
  • Новая команда FCTL_CHECKPANELSEXIST. Позволяет проверить доступность панелей. В режиме, когда FAR запущен с ключами /e или /v (в качестве внешнего редактора или программы просмотра), панели не создаются.
  • Некорректное отсечение длинного заголовка (параметр Title) в функции Message.
  • Два новых флага VF_IMMEDIATERETURN и EF_IMMEDIATERETURN, позволяющих плагину получать управление сразу же после открытия редактора/программы просмотра. Реально редактор/программа просмотра начнёт работать после возвращения плагином управления ФАРу. Может быть использовано для открытия нескольких редакторов/программ просмотра мгновенно.
  • Функция FSF.MkLink некорректно работала при создании симолической связи, если в качестве источника был полный путь к каталогу.
  • Функция FSF.MkLink самостоятельно обновляет панели, если не указан флаг FLINK_DONOTUPDATEPANEL.
  • Новый флаг DIF_CENTERTEXT для статических элементов DI_TEXT и DI_VTEXT.
  • VF_DELETEONLYFILEONCLOSE и EF_DELETEONLYFILEONCLOSE - аналоги VF_DELETEONCLOSE и EF_DELETEONCLOSE, но удаляется только файл, а папка, содержащая его, не удаляется, даже если она пуста.
  • Ctrl-Ins в строках ввода сбрасывал состояние UnChanged.
  • Падение в обработчике ECTL_SETSTRING, если поле EditorSetString.StringLength содержало отрицательное значение.
  • Новая команда ECTL_DELETEBLOCK - удалить блок в редакторе.
  • Если у DI_SINGLEBOX (DI_DOUBLEBOX) координаты X1==X2 или Y1==Y2, то рисуется соответствующая линия (вертикальная или горизонтальная)
  • Если у DI_SINGLEBOX (DI_DOUBLEBOX) указан флаг DIF_SETCOLOR, то младший байт позволяет задавать цвет рамки.
  • Два новых флага для DialogEx: FDLG_NODRAWSHADOW - не рисовать тень диалога, FDLG_NODRAWPANEL - не рисовать поле диалога
  • При указании флага FDLG_SMALLDIALOG поле диалога теперь отрисовывается.
  • Новая команда ACTL_SETARRAYCOLOR, позволяющая изменить цветовую схему FAR Manager.
  • Константы COL_DIALOGMENU* заменен на COL_DIALOGLIST*
  • Измененно сообщение DN_CTLCOLORDLGLIST. Теперь Param1 указывает на номер элемента диалога (типа DI_LISTBOX, DI_COMBOBOX или строковый редактор c историей ввода). Param2 - указатель на структуру FarListColors, описывающую цветовую схему списка.
  • Теперь заголовок элемента DI_LISTBOX описывается цветом COL_DIALOGLISTTITLE
  • По умолчанию цвет для индекса COL_DIALOGLISTDISABLED - темносерый на светлосером.
  • Немного добавок в разделе Frequently Asked Questions.
  • Не прорисовывался элемент DI_LISTBOX с флагом DIF_LISTNOBOX высотой в 1 строку..

20 марта 2002 г.

  • Вместо FARMANAGERVERSION в функции GetMinFarVersion() можно воспользоваться макросом MAKEFARVERSION
  • Изменилось определение структуры FarDialogItem для того, чтобы plugin.hpp можно было использовать с pure C компиляторами.
  • Изменена логика возвращаемого значения на сообщение DN_BTNCLICK для элементов DI_BUTTON. Теперь это:
    Для DI_BUTTON:
    1. TRUE - сообщение обработано, дальше не продолжать обработку этого сообщения ядром.
    2. FALSE - продолжить обработку ядром.
    Для остальных элементов:
    1. TRUE - разрешить изменение (и соответственно отрисовку того, что пользователь ввёл)
    2. FALSE - запретить изменение.
  • Новый флаг EJECT_LOAD_MEDIA для ACTL_EJECTMEDIA. Работает только в NT/2000/XP
  • DIF_SHOWAMPERSAND также обрабатывается для DI_BUTTON, DI_CHECKBOX, DI_RADIOBUTTON
  • После выбора строки из истории в функцию обработки диалога не посылалось сообщение DN_EDITCHANGE.
  • Изменена реакция стандартного обработчика диалога на событие DN_MOUSECLICK за пределами диалога. Теперь, если функция диалога не обрабатывает событие DN_MOUSECLICK с Param1=-1, то диалог будет закрыт.
  • Уточнения в структуре PanelInfo - поле Flags. Также добавлены флаги PANELINFOFLAGS.
  • В ProcessHostFile не передавался флаг OPM_TOPLEVEL в том случае, когда это требовалось (нажатие Shift-F3 на архиве в файловой панели).
  • Некорректно работало сообщение DM_SETMAXTEXTLENGTH.
  • Две новых "клавиши" для колеса мыши - KEY_MSWHEEL_UP/KEY_MSWHEEL_DOWN.
  • Сообщения диалога для работы со списками (DI_LISTBOX и DI_COMBOBOX) - DM_LISTSORT, DM_LISTGETITEM, DM_LISTGETCURPOS, DM_LISTSETCURPOS, DM_LISTDELETE, DM_LISTADD, DM_LISTUPDATE, DM_LISTINFO, DM_LISTFINDSTRING, DM_LISTINSERT, DM_LISTSETTITLE, DM_LISTGETTITLE... и соответствующие им структуры.
  • Сообщения DM_GETDROPDOWNOPENED DM_SETDROPDOWNOPENED, DM_SETHISTORY, DM_SETITEMPOSITION.
  • Новые флаги VF_ENABLE_F6 (в функции Viewer) и EF_ENABLE_F6 (в функции Editor), разрешающие переключение по F6 из вьюера и редактора, открытых при помощи соответствующих функций.
  • Флаг DIF_CENTERGROUP имеет смысл только для следующих элементов: DI_BUTTON, DI_CHECKBOX, DI_RADIOBUTTON и DI_TEXT.
  • Новый цвет COL_MENUDISABLEDTEXT - недоступный пункт меню.
  • DM_RESIZEDIALOG - изменить размеры диалога.
  • DM_GETCHECK/DM_SETCHECK/DM_SET3STATE/BSTATE_* - работа с состоянием элементов DI_RADIOBUTTON/DI_CHECKBOX
  • Функция GetMinFarVersion не вызывалась для плагинов с флагом PF_PRELOAD, а также для плагинов, имеющихся в кэше.
  • Теперь функция Viewer возвращает FALSE при ошибке открытия и в том случае, когда вьюер открывается с флагом VF_NONMODAL.
  • Новая FSF-функция MkLink. Умеет создавать хардлинки, символические связи и монтировать диски на файловую систему.
  • Во время исполнения макроса в меню игнорировались значения массива BreakKeys, переданных в функцию Menu.
  • Функция Unquote убирает все двойные кавычки из строки.
  • Плагину в функцию GetFiles в качестве параметра DestPath передавалось имя каталога, усеченного до первой точки. Это по поводу: "Надоело распаковывать some.foo.rar в каталог some\"
  • Функция FSF.ExpandEnvironmentStr манипулирует строками в OEM-кодировке.
  • DN_DRAGGED - информация о процессе перемещения диалога.
  • ACTL_GETWINDOWCOUNT, ACTL_GETWINDOWINFO, ACTL_SETCURRENTWINDOW и ACTL_COMMIT, struct WindowInfo - манипулирование "окнами" FAR Manager
  • ECTL_GETBOOKMARKS, struct EditorBookMarks - информация о закладках в редакторе (EditorInfo.BookMarkCount - количество закладок, поддерживаемых редактором).
  • Удален флаг LIF_PTRDATA - изжил себя как класс (соответственно изменилась структура FarListItem)
  • ACTL_POSTKEYSEQUENCE - поместить последовательность клавиш для последующего выполнения (когда FAR Manager получит управление).
  • ACTL_GETFARHWND - возвращает HWND текущего окна FAR.
  • ACTL_GET*SETTINGS - команды, позволяющие плагину узнать некоторые настройки FAR Manager.
  • DM_EDITUNCHANGEDFLAG - позволяет управлять состоянием "неизменный текст" для полей ввода.
  • ECTL_READINPUT: во время исполнения макроса плагину возвращается корректно заполненная структура INPUT_RECORD.
  • Функция FSF.ConvertNameToReal преобразует относительное имя файлового объекта в полное с учетом символических связей (т.н. reparse point в Windows 2000) и текущего каталога.
  • Все поля структуры CharTableSet кроме TableName имеют тип unsigned char.
  • Дополнительное поле в структуре PluginPanelItem - CRC32.
  • Опциональная посылка DN_MOUSEEVENT в обработчик диалога. По умолчанию отключена (DN_MOUSEEVENT/DM_SETMOUSEEVENTNOTIFY)
  • FCTL_GETCMDLINESELECTION, FCTL_SETCMDLINESELECTION, FCTL_GETCMDLINESELECTEDTEXT.
  • GetPluginDirList: если параметр hPlugin равен INVALID_HANDLE_VALUE, то значение параметра PluginNumber игнорируется (используется номер плагина, которому принадлежит активная панель).
  • DM_GETITEMPOSITION - получить позицию и размеры управляющего элемента.
  • Плагины могут при помощи ECTL_SETPARAM менять текущую кодировку в редакторе.
  • DN_RESIZECONSOLE - уведомляющее сообщение "Изменились размеры консоли".
  • DM_GETTEXTLENGTH возвращает размер строки без учета '\0'
  • Формат HelpTopic для меню, диалогов и сообщений может быть:
    1. ":Topic"
      вызов главной темы (из основного файла помощи FAR)
    2. "Topic"
      вызов локальной темы
    3. "<FullModuleName>Topic"
      вызов темы помощи из каталога, где находится модуль "FullModuleName"
    4. "<FullPath>Topic"
      вызов темы помощи из каталога "FullPath" Здесь "FullPath" путь ДОЛЖЕН заканчиваться символом '\'
    Если для случая 3 и 4 параметр Topic не указан, то будет подставлен "Contents"
  • Усовершенствование FarRecursiveSearch:
    1. Проверяется правильность параметров.
    2. Теперь обработка каталогов не зависит от маски файлов.
    3. Маска может быть стандартного ФАРовского вида (со скобками, перечислением и пр.). Может быть несколько масок файлов, разделенных запятыми или точкой с запятой, можно указывать маски исключения, можно заключать маски в кавычки.
  • Теперь DI_LISTBOX с выставленным флагом DIF_LISTNOBOX и меню с флагом LINFO_SHOWNOBOX рисуются без лишних окантовывающих пробелов вокруг списка, что автоматически позволяет использовать DI_LISTBOX в диалогах, не опасаясь затирания рамки самого диалога пустым местом от списка.
  • FMENU_USEEXT, MIF_*, FarMenuItemEx - "расширение" меню.
  • При создании нового файла также посылается событие EE_READ плагинам.
  • Новая функция FSF.GetReparsePointInfo - позволяет для указанной символической связи получить информацию об источнике - путь к исходному каталогу/диску. Функция работает только в Windows 2000 и выше. В отличие от ConvertNameToReal, применима только для симлинков.
  • FSF.FarInputRecordToKey: Параметр имеет модификатор "const".
  • Элемент диалога DI_USERCONTROL некорректно работал с курсором.
  • Устранено падение FAR Manager, происходившее в случае посылки сообщения DM_SETFOCUS в ответ на событие DN_GOTFOCUS.
  • В HLF-файлах можно указывать размер табуляции, вставив в начало файла помощи конструкцию ".Options TabSize=Размер". "Размер" может быть от 1 до 16, по умолчанию - 8.
  • Неверно рассчитывались координаты элементов DI_TEXT и DI_VTEXT.
  • EditorGetString.StringText и EditorGetString.StringEOL объявлены как const.
  • EditorInfo.CurState - состояние редактора (дополнительные флаги-ECSTATE_*)
  • Флаг EF_DELETEONCLOSE. Аналогичен VF_DELETEONCLOSE.
  • FarListInfo и флаги LINFO_*
  • DIF_SEPARATOR2 - двойная разделительная линия.
  • Неверно обрабатывалась команда ECTL_QUIT.
  • Если указан флаг DIF_LISTWRAPMODE, то попытка перемещения курсора в списке выше первого пункта или ниже последнего будет приводить к перемещению соответственно к последнему или к первому пункту.
  • Флаг EF_DISABLEHISTORY для функции Editor - запретить добавление имени файла в историю редактирования (Alt-F11). По умолчанию имя в историю добавляется.
  • FarListItem: размер текста 128 + DWORD Reserved
  • Флаги диалога DialogEx:
    FDLG_WARNING - задает для диалога цветовую схему "Предупреждение". FDLG_SMALLDIALOG - позволяет создавать диалоги с уменьшенным размером рамки. Для таких диалогов не рисуется поле диалога, тень, а при отрисовке разделительных линий (DIF_SEPARATOR) предполагается нулевой отступ между границей диалога и окружающей его двойной рамкой.
  • Статья: Оптимизация размера плагина при использовании gcc. Вадим Егоров. 16.07.2001
  • Статья: Несколько приемов работы с окнами FAR. Александр Назаренко. 13.01.2002
  • Уточнения в статье: Распределение памяти. Скромная попытка расставить все по своим местам в этом вопросе. Иван Синтюрин. 28.05.2000 Rev. 20.12.2001

20 апреля 2001 г.

  • Выход FAR Manager 1.70 beta 3 - множественные дополнения & изменения в API
  • Начиная с этой версии, Энциклопедия распространяется по Лицензии...
  • Очередное изменение представления Service Release - вместо даты модификации - номер билда FAR Manager ;-)
  • У Вас установлен комплект MSDN-документации? Тогда заметки by Serg Bormant помогут "Приручить" HTML-вариант энциклопедии (файл pluginsr.chm) к MSDN-коллекции (именно на эту коллекцию настроены все ссылки на Win32 API).
  • Новый раздел по Dialog API.
  • Элемент диалога DI_EDIT обзавелся еще одним флагом DIF_EDITEXPAND
  • Флаг DIF_VAREDIT, позволяющий преодолеть барьер в 512 байт для строки ввода в диалогах.
  • О том, как отлаживать плагины в Borland TD32 можно прочитать в статье Вячеслава Печенина "Отладка плагинов в Borland Turbo Debugger".
  • Олег Данилов. Статья про то... "Как уменьшить размер плагина" (на примере Microsoft VC++ 6.0)
  • "Как самому сделать plug-in к FAR на Visual C++" можно прочитать в статье Руслана Ильгасова.
  • Полностью пересмотрен раздел Delphi - спасибЫ слать Василию Мошнинову.
  • Дополнения к статье "Приручаем Borland C++ к crtdll.dll" by Eugene Kotlyarov (Rev. 24.06.2000)
  • Статья про наболевшее... "Упаковщики - ЗА и ПРОТИВ".
  • Иван Синтюрин уточняет "Обработку нажатия ESC..."
  • Stanislav V. Mekhanoshin в своей статье "ECTL_GETSTRING работает слишком медленно" допустил некоторые неточности...
    ...в связи с чем приносим Андрею Третьякову свои извинения! (это ж какие железные нервы у человека :-)
  • Хитрой оказалась команда ECTL_SETTITLE...
  • Изменение параметров редактора "на лету" - ECTL_SETPARAM...
  • Значительные изменения в структуре PluginStartupInfo...
  • Для уменьшения размера плагинов добавлена структура FarStandardFunctions, содержащая в себе адреса ряда полезных функций из FAR.EXE.
  • Новая сервисная функция ShowHelp - позволяет выводить заданный файл помощи на экран...
  • ...и как следствие - уточнение статьи "Подсказка в нестандартных диалогах"...
  • Новая сервисная функция AdvControl - позволяет запрашивать различную информацию и выполнять управляющие действия. Она работает везде: в панелях/редакторе/вьюере.
  • Существенные дополнения к синтаксису HLF-файлов...
  • Статья "О пользе и вреде static в диалогах." от Jouri Mamaev
  • Изменения и дополнения в вопросах и ответах
  • и прочая, прочая, прочая... (см. "История API")

20 июня 2000 г.

  • Исправлена небольшая лажа в PluginInfo по поводу CommandPrefix :-)
  • Все три компоненты Энциклопедии (HLP, CHM, Online) имеют одинаковый интерфейс.
  • Если вы используете CHM-версию Энциклопедии, то теперь открылась возможность переходить на темы помощи из MSDN Library Visual Studio 6.0 (требуется файл WinBase.chm и ShellCC.chm)

28 мая 2000 г.

  • FAQ: "Как можно получить имя каталога, из которого запущен FAR?"
  • Тему "Память" продолжает Иван Синтюрин:
    В очередной раз подняли вопрос о распределении памяти под win32... У меня по этому поводу кое-что накипело, это можно выразить следующей фразой: "С операционной системой следует говорить на ее родном языке!" (далее...)

24 мая 2000 г.

  • Первая бета FAR Manager версии 1.64.
  • В функции EditorControl добавлено пара новых команд: ECTL_SAVEFILE и ECTL_QUIT. Соответственно к команде ECTL_SAVEFILE добавилась структура EditorSaveFile.
  • Раздел "Users API" переименован в "Custom API". В общем-то, как и ожидалось "вторым клиентом" в этот разделе стал Интерфейс регулярных выражений библиотеки colorer by Igor Ruskih.
  • Замечания к статье Ивана Синтюрина - " Обработка нажатия ESC или 'Авторам долгодумающих плагинов посвящается...'"

11 мая 2000 г.

  • Изменено наименование энциклопедии - для краткости :-)
    В наименование энциклопедии входит т.н. Service Release: состоит из пары букв 'SR' и даты выпуска энциклопедии в формате 'YYYYMMDD'.
  • Введен новый раздел - "Users API". Естественно "Работа с архивами" перенесена именно сюда и называется теперь "API поддержки архивов". Видимо "вторым клиентом" в этот раздел будет RegExp API by Igor Ruskih.
  • Новая редакция статьи Дмитрия Суходоева - "Написание плагинов на Virtual Pascal 2.0"...
  • Новая статья от Василия Мошнинова - "Распределение памяти в Borland Delphi - проблемы и решения"...
  • Замечания к статье Ивана Синтюрина - "Обработка нажатия ESC или 'Авторам долгодумающих плагинов посвящается...'"
  • Уточнения для структуры "EditorSelect".
  • Забыли про EE_CLOSE в функции "ProcessEditorEvent" :-).
  • Уточнения для функции "Menu".

04 апреля 2000 г.

  • Вы давно мечтали подружить CRTDLL.DLL с Borland C/C++? Тогда читайте статью Eugene Kotlyarov - «"Приручаем Borland C++ к crtdll.dll»...
  • Новая статья от Игоря Русских - «Синдром ``Рождественской Ёлки'' или Свобода Безумия», посвященная колореру...
  • Новый раздел «Дополнения». Здесь описаны функции и структуры не входящие в стандартный API, но часто используемые при написании плагинов...
  • Добавки и антураж в "ЧаВо".
  • Синтаксис, праваписание и оgечатки... ;-)))

14 марта 2000 г.

  • Собственно - исправления опечаток (в роли DrWeb`а выступает Артем Назаров)
  • Уточнения в статье от Валентина Скирдина - "Корректировка PLUGIN.HPP" с учетом использования компилятора LCC-Win32

23 февраля 2000 г.

  • Некоторые замечания и уточнения в описаниях структур и в разделе "Поддержка архивов"...
  • Энциклопедия содержит "полный комплект" Delphi-структур.
  • Статья от Дмитрия Суходоева - "Написание плагинов на Virtual Pascal 2.0"

12 января 2000 г.

  • Некоторые замечания и уточнения в описаниях экспортируемых функций,
  • Статья от Ивана Синтюрина - "Локализация плагинов второго уровня"
  • Добавлен раздел "Frequently Asked Questions" по программированию плагинов.

02 января 2000 г.

  • Некоторые замечания и уточнения в описаниях структур FarDialogItem и FarMenuItem...
  • Статья от Валентина Скирдина - "Корректировка PLUGIN.HPP"

24 декабря 1999 г.

  • Новая статья от Игоря Павлова - "Как настроить Alignment"

14 декабря 1999 г.

  • Добавилось пара-тройка новых статей:
    • Валентин Скирдин - "Как уменьшить размер плагина Borland C++ 5.02"
    • Игорь Русских - "Формат Hrc изнутри"
    • Ивана Синтюрина - "Обработка нажатия ESC или 'Авторам долгодумающих плагинов посвящается...'"
  • Возможно, когда статей станет больше, энциклопедия будет выходить в виде двух (или более) файлов - собственно сама энциклопедия и журнал(ы) со статьями.

08 декабря 1999 г.

  • Ну что, господа, вот и первый релиз нашей энциклопедии (SR128 1999.12.08)! Бесконечное множество промежуточных версий любой из вас мог скачать из Сети - http://www.uic.nnov.ru/~ruiv/plugring/help/. Но то были ПРОМЕЖУТОЧНЫЕ версии! А это. . . может и "сыроват" продукт, но "читать хэлпы на русском языке чертовски приятно".

    Я, как координатор проекта "Programming FAR plugins - Encyclopedia for Developers", благодарю всех участников, кто "не щадя живота своего" помогал в создании данного произведения, и надеюсь, на дальнейшее сотрудничество. Первый релиз - он и в Африке первый ;-)

    С уважением, Валентин Скирдин

06 декабря 1999 г.

  • Полностью закончен перевод статей, посвященных разделу "Структуры". Добавилась новая статья Валентина Скирдина - "Как получить полный путь редактируемого файла из плагина в редакторе?"

28 ноября 1999 г.

  • Новая статья by Stanislav Mekhanoshin - "ECTL_GETSTRING работает слишком медленно". В остальном - как обычно: переводы, исправления глюков...

21 ноября 1999 г.

  • Полку авторов прибыло. Несколько статей переведено, исправлены небольшие глюки...

10 ноября 1999 г.

  • Как у всех "порядочных" людей версии этой энциклопедии будут вестись в терминах версии FAR Manager с добавкой так называемого Service Release и датой обновления самой энциклопедии. Т.е. сейчас вы читаете Far PlugRinG Russian Help - Encyclopedia of Developer 1.63 SR127 1999.11.19

01 сентября 1999 г.

  • Рождение проекта "Far PlugRinG Russian Help". Приставка "- Encyclopedia for Developer" появится позже :-)
    Из частного (для себя) проект переродился в нечто большее...


ЧАВО - Часто задаваемые вопросы

главная

Общие вопросы

  1. Как мне спрятать курсор?
  2. А как перевести в нужную позицию?
  3. Чтобы плагин работал и в редакторе и в shell (и на панели) что нужно ставить во флагах: Info->Flags=?????;
  4. Возможно динамическое отключение/подключение плагина не перезапуская FAR?
  5. Plug-in`ы в редакторе срабатывают только при активизации? А можно ли сварганить такой, чтобы в фоновом режиме работал?
  6. А можно в одном DLL-модуле держать несколько плагинов...
  7. ... а потом различать что хотел пользователь по параметру Item в функции OpenPlugin - правильно?
  8. Возможно ли при нынешнем API сделать плагин, работающий в фоновом режиме?
  9. Есть файл, который можно открыть плагином. Могy ли я как-то об этом yзнать? Лучше всего отдать командy на cd тyда и получить ответ - смогли/не смогли.
  10. Как бы это из плагинового модуля получить полный путь до него самого?...
  11. Можно ли из плагина управлять переключением фоновых экранов ФАРа?
  12. А как фаp определяет, что в клипборде лежит именно вертикальный блок?
  13. На чем стоит кypсоp в текущей панели?...
  14. Нельзя ли пpи перерисовке любой панели перерисовывать заголовок окна...
  15. Откуда FAR берет процедуры для копирования/удаления/... файлов?
  16. Как можно получить имя каталога, из которого запущен FAR?
  17. А как уменьшить размер DLL?
  18. А что за дупы в клипборде идут, зачем 2 раза одну и ту же в Clipboard помещать?
  19. Как определить что есть "символическая связь"...
  20. ...что скрывается по именем '\\?\Volume{...'
  21. А еще что нить полезного про символические связи можно узнать?
  22. Можно ли получить для редактируемого файла флаг изменен...
  23. Как узнать имя файла, загруженного во вьювер?
  24. Возможно ли каким-то способом в FSF.ProcessName...
  25. Как Windows "сбрасывает" имя файла из Проводника в консольное окно?
  26. Почему-то не работает ProcessKey...
  27. Можно ли из плагина перейти на определённый файл в директории?
  28. Как из плагина запустить что-нибудь? И как показать вывод этой программы под панелями?

Диалоги

  1. Можно как ни будь убрать ограничение в edit окне (512 символов)...
  2. Если я не использую функцию Dialog работы с диалогом, то каким образом обрабатывать ввод данных? Самому писать?
  3. Если я использую Dialog, а в нем строку ввода, то будет ли работать функции ProcessEditorInput и ProcessEditorEvent для этого элемента управления?
  4. Можно ли динамически в Dialog менять элементы типа Static (их заголовки)?
  5. Мне не хватает того набора управляющих элементов, которые обрабатывает FAR...
  6. А что это ListBox и ComboBox полуфабрикатные какие-то?
  7. Почему в диалоге "нового" стиля не срабатывают кнопки на закрытие окна?
  8. И что - мне теперь самому закрывать диалог?
  9. А если я мышкой - оно придет или еще ловить DN_MOUSECLICK?
  10. И DefaultButton самому обрабатывать?
  11. SEPARATOR не желает доходить до правого конца рамки...
  12. А можно как-нибудь выключить автовыбор элемента мышью в листе...

Общие вопросы

  1. Q: Как мне спрятать курсор?
    A: Win32 console API: SetConsoleCursorInfo , только не забудь его потом вернуть на место.

  2. Q: А как перевести в нужную позицию?
    A: Там же: SetConsoleCursorPosition

  3. Q: Чтобы плагин работал и в редакторе и в shell (и на панели) что нужно ставить во флагах: Info->Flags=?????;
    A: PF_EDITOR

  4. Q: Возможно динамическое отключение/подключение плагина не перезапуская FAR?
    A: Отключение невозможно. А зачем тебе его отключать? А подключением FAR сам занимается. Другое дело, что FAR можно попросить не кэшировать настройки для данного плагина, а грузить его в память каждый раз вместе с самим FAR`ом, указав PF_PRELOAD. Но без реальной необходимости это лучше не делать - лишние тормоза и расход памяти.

  5. Q: Плагины в редакторе срабатывают только при активизации? А можно ли сварганить такой, чтобы в фоновом режиме работал?
    A: Можно. Экспортировать ProcessEditorInput и ему будет приходить все нажатия клавиш в редакторе.

  6. Q: А можно в одном DLL-модуле держать несколько плагинов... Несколько функций, так сказать... И чтобы каждый вызывался, как будто бы находился в отдельном DLL-файле (пусть даже с полной загрузкой всего DLL`я)...
    A: Да. В PluginInfo можно указать несколько строк, добавляемых к plugins menu. Но это не является "хорошим тоном".

  7. Q: ...а потом различать что хотел пользователь по параметру Item в функции OpenPlugin?
    A: Правильно.

  8. Q: Возможно ли при нынешнем API сделать плагин, работающий в фоновом режиме?
    A: Разве что в редакторе. В панелях такое не поддерживается.

  9. Q: Есть файл, который можно открыть плагином. Могу ли я как-то об этом узнать? Лучше всего отдать команду на cd туда и получить ответ - смогли/не смогли.
    A: Нет, api для взаимодействия между плагинами в FAR отсутствует. Тут одной проверкой на принадлежность файла не обойтись.

  10. Q: Как бы это из плагинового модуля получить полный путь до него самого?...
    A: В функцию SetStartupInfo far передает указатель на структуру PluginStartupInfo. Полное имя модуля содержится в поле ModuleName оной структуры.

  11. Q: Можно ли из плагина управлять переключением фоновых экранов FAR?
    A: Начиная с FAR Manager 1.70 bata 4 - можно.

  12. Q: А как FAR определяет, что в клипборде лежит именно вертикальный блок?
    A: У вертикального блока clipboard format - "FAR_VerticalBlock"

  13. Q: Скажи, а что - никак нельзя узнать, на чем стоит курсор в текущей панели? Т.е. меня интересует - на каталоге или на файле...
    A:
    Control(FCTL_GETANOTHERPANELINFO);
Control(FCTL_GETPANELINFO);
PanelInfo.PanelItems[PanelInfo.CurrentItem].FindData.dwFileAttributes

  14. Q: Нельзя ли пpи перерисовке любой панели перерисовывать заголовок окна? По моему, это будет проще и быстрее, чем плагину вызывать FCTL_REDRAWPANEL.
    A: Насчет быстрее - не факт. Если заголовок не изменен плагином, как оно обычно и бывает, FAR перерисует его вхолостую.

  15. Q: Откуда FAR берет процедуры для копирования/удаления/... файлов?
    A: Из Win32 API.
    Копирование: CreateFile +ReadFile +WriteFile +CloseHandle или CopyFile (Ex), в зависимости от ОС и опции "Use system copy routine".
    Удаление: DeleteFile или SHFileOperation в зависимости от опции "Delete to Recycle Bin"

  16. Q: Как можно получить имя каталога, из которого запущен FAR?
    A:
    char lpName[_MAX_PATH], lpFullPath[_MAX_PATH];
LPTSTR lpFile;
GetModuleFileName

(NULL,lpName,sizeof(lpName));
GetFullPathName

(lpName,sizeof(lpFullPath),lpFullPath,&lpFile);
*lpFile='\0';

  17. Q: А как уменьшить размер DLL - уж больно "жирный" модуль получается?
    A:
    1. В разделе "Статьи" есть несколько заметок на эту тему.
    2. Плагинописателям, пишущим на Visual C++ и борющимся за уменьшение размера плагинов, настоятельно рекомендуется прочитать: http://msdn.microsoft.com/msdnmag/issues/01/01/hood/default.aspx (локальная копия здесь)

  18. Q: А что за дупы в клипборде идут, зачем 2 раза одну и ту же в Clipboard помещать?
    A: Если поместить текст в clipboard в каком-то одном формате, а программа просит его в другом, то Windows занимается перекодировкой самостоятельно, и очень часто делает это коряво. Псевдографика портится, иногда вместо русских букв остаются одни '?', конкретные глюки зависят от версии Windows и комбинации исходного и запрашиваемого форматов. Если же поместить все форматы сразу, то Windows находит нужный и использует его без всяческих перекодировок.

  19. Q: Как определить что есть "символическая связь" - простая ссылка на каталог или монтированный диск.
    A: Основное правило - символические связи в Win2K - ТОЛЬКО ДЛЯ КАТАЛОГОВ! Значит нам нужно узнать - "А не каталог ли ЭТО?". На это указывает файловый атрибут FA_DIREC (или FILE_ATTRIBUTE_DIRECTORY).
    Едем дальше.
    Нам достоверно известно, что любые символические связи (иначе, reparse point) в Win2K имеют атрибут FILE_ATTRIBUTE_REPARSE_POINT - проверяем его.
    Вызываем
    FSF.GetReparsePointInfo(FullFolderName,DestName,sizeof(DestName))
    Эта функция возвращает нам для некоторого заданного пути "FullFolderName" некий реальный путь "DestName", который имеет суть:
    1. "\??\D:\Junc..."
      симлинк на каталог.
    2. "\\?\Volume{..."
      монтированный диск.

    ПРИЧЕМ! Нас совершенно не интересуют первые 4 символа! Следовательно достаточно сделать проверку 7 символов, начиная с четвертого:
    if(!strncmp(JuncName+4,"Volume{",7))
{
  // это явно монтированный диск!
}
else
{
  // простая ссылка на каталог
}

  20. Q: Да. Но ведь интересно знать, что скрывается по именем '\\?\Volume{...'?
    A: Проще простого. Для этого вызовем функцию
    FSF.GetPathRoot(JuncName,Root);
    которая возвращает реальный корень в одной из двух реинкарнаций:
    1. "D:\"
    2. "\\?\Volume{..."

    второй случай - "тяжелый" :-) - здесь видимо на уровне системы (в менеджере дисков) для данного диска удалили буковку... Ну, что бы не маячила, т.с. ;-)

  21. Q: А еще что нить полезного про символические связи можно узнать?
    A: А как же :-) Правда не совсем про символические связи, но...
    Например, мы можем узнать еще порцию полезностей для монтированных дисков. Здесь все просто - вызываем стандартную GetVolumeInformation()
    Т.е. нам уже известен корень - "GetPathRoot(JuncName,Root);", осталось получить информацию (например, возможности файловой системы по поддержке расширенных атрибутов - сжатие и шифрование и тип файловой системы):
    DWORD FileSystemFlags;
char FSysName[NM];

if (GetVolumeInformation(Root,NULL,0,NULL,NULL,
                        &FileSystemFlags,FSysName,sizeof(FSysName)))
{
  if (FileSystemFlags & FS_FILE_COMPRESSION)
  {
    // файловая система поддерживает компрессию файлов
  }

  if (FileSystemFlags & FS_FILE_ENCRYPTION)
  {
    // файловая система поддерживает шифрование файлов
  }
}

    Типичная функция проверки возможности создания... жестких связей могла бы выглядеть так:
    BOOL CanCreateHardLinks(char *TargetFile,char *HardLinkName)
{
  char RootTarget[NM],RootHardLink[NM],FSysName[NM];
  GetPathRoot(TargetFile,RootTarget);
  GetPathRoot(HardLinkName,RootHardLink);

  if(!strcmp(RootTarget,RootHardLink)) // тот же корень (то же диск)?
  {
    // NTFS drive?
    DWORD FileSystemFlags;

    if(GetVolumeInformation(RootTarget,NULL,0,NULL,NULL,&FileSystemFlags,
                            FSysName,sizeof(FSysName)))
    {
      if(!strcmp(FSysName,"NTFS"))
        return TRUE;
    }
  }
  return FALSE;
}

  22. Q: Можно ли получить для редактируемого файла флаг изменен/неизменен? Я сходу не нашел, а ведь FAR это знает, звездочку в верхней строке показывает.
    A: См. описание структуры EditorInfo, конкретно значения поле EditorInfo.CurState.

  23. Q: Как узнать имя файла, загруженного во вьювер?
    A: Вот такой вот код запросто узнает текущее имя в программе просмотра:
    WindowInfo wi;
wi.Pos=-1;
Info.AdvControl(Info.ModuleNumber,ACTL_GETWINDOWINFO,&wi);
    все. в wi.Name лежит имя файла.

  24. Q: Возможно ли каким-то способом в FSF.ProcessName, при сравнении маски "OUTBOUND\\????????.MO?" и файла "С:\\FILES\\OUTBOUND\\0000ee2c.mod" получить TRUE, а с файлом "C:\\MUSIC\\assol_1.mod" обломаться? PN_SKIPPATH не подходит. При наличии "\\" в маске он, похоже, никогда не вернёт TRUE.
    A: Сравнивай с маской "*\\OUTBOUND\\????????.MO?" без использования PN_SKIPPATH.

  25. Q: Как Windows "сбрасывает" имя файла из Проводника в консольное окно?
    A: Vasily Titsky: "...Если кратко, то когда в консольное приложение идет вставка текста (через системное меню, или кидая ярлык) то добрая ОС делает вот что: если в текущем Keyboard Layout приложения и очередной код символа не пересекаются (текущий язык - english, а вставлять надо символ русского алфавита; или наоборот), то она "эмулирует" ввод этого символа через Alt+цифры. Например, при вставке русской 'А' , будет сгенерировано: нажатие Alt, нажатие '1', отпускание '1', нажатие '2', отпускание '2', нажатие '8', отпускание '8', отпускание Alt. При вставке символов с кодом, меньшим 99 (? - не проверял) имитируется нажатие 2-х цифр. Остается только правильно это обнаружить и обработать..."

  26. Q: Почему-то не работает ProcessKey? Пишу в Delphi:
    function ProcessKey(hPlugin: THandle; Key: Integer; ControlState: Word): integer; stdcall;
begin
  windows.Beep(300,200);
  //возвращаем False для дальнейшей обработки FARом
  result:=0;
end;
    По идее должен выдаваться сигнал при любом нажатии клавиши - этого не происходит. То же самое, если делаю это для какой-то конкретной клавиши.
    A: FAR вызывает функцию ProcessKey для активной плагиновой панели.

  27. Q: Можно ли из плагина перейти на определённый файл в директории?
    A:
    {
  struct PanelInfo PInfo;
  Info.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,&PInfo);

  // установить позицию на элементе панели selectItem

  struct PanelRedrawInfo PRI;
  char Name[NM], Dir[NM*5];
  int pathlen;

  strcpy(Name,Info.FSF->PointToName(selectItem));
  pathlen=Info.FSF->PointToName(selectItem)-selectItem;

  if(pathlen)
    memcpy(Dir,selectItem,pathlen);

  Dir[pathlen]=0;
  Info.FSF->Trim(Name);
  Info.FSF->Trim(Dir);
  Info.FSF->Unquote(Name);
  Info.FSF->Unquote(Dir);

  if(*Dir)
    Info.Control(INVALID_HANDLE_VALUE,FCTL_SETPANELDIR,&Dir);
  Info.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,&PInfo);

  PRI.CurrentItem=PInfo.CurrentItem;
  PRI.TopPanelItem=PInfo.TopPanelItem;

  for(int J=0; J < PInfo.ItemsNumber; J++)
  {
    if(!Info.FSF->LStricmp(Name,Info.FSF->PointToName(PInfo.PanelItems[J].FindData.cFileName)))
    {
      PRI.CurrentItem=J;
      PRI.TopPanelItem=J;
      break;
    }
  }
  Info.Control(INVALID_HANDLE_VALUE,FCTL_REDRAWPANEL,&PRI);
}

  28. Q: Как из плагина запустить что-нибудь? И как показать вывод этой программы под панелями?
    A:
    Info.Control(INVALID_HANDLE_VALUE,FCTL_GETUSERSCREEN,NULL);

if (CreateProcess(NULL,"ls.exe",NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
{
  WaitForSingleObject( pi.hProcess, INFINITE );
  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );
}

Info.Control(INVALID_HANDLE_VALUE,FCTL_SETUSERSCREEN,NULL);

наверх

Диалоги

  1. Q: Можно как ни будь убрать ограничение в edit окне, где последовательность макроса написана в 512 символов?
    A: Это особенность ФАРовских диалогов. В структуре FarDialogItem поле Data имеет размер в 512 символов. (ответ актуален для FAR Manager 1.70 beta 2 и ниже; см. описание флага DIF_VAREDIT)

  2. Q: Если я не использую функцию Dialog работы с диалогом, то каким образом обрабатывать ввод данных? Самому писать?
    A: Можно и самому :-) А можно использовать DialogAPI...

  3. Q: Если я использую функцию Dialog, а в нем строку ввода, то будет ли работать функции ProcessEditorInput и ProcessEditorEvent для этого элемента управления?
    A: Нет. Воспользуйся функцией DialogEx.

  4. Q: Можно ли динамически в Dialog менять элементы типа Static (их заголовки)?
    A: Смотря какой тип диалога использовать. После создания диалога и вызова функции Dialog - нет. Но можно из него (диалога) выйти, заменить заголовок и создать диалог опять. Если это сделать сразу же, одно за другим, то будет достаточно быстро.
    Если воспользоваться функцией DialogEx - то можно - в функции-обработчике диалога послать ядру DialogAPI сообщение DM_SETTEXT.

  5. Q: Ну ладно, воспользовался этим самым DialogAPI, но мне не хватает того набора управляющих элементов, которые обрабатывает FAR. Ась?
    A: Воспользуйся элементом DI_USERCONTROL - отрисовка элемента и управление им - все во власти плагина!

  6. Q: А что это ListBox и ComboBox полуфабрикатные какие-то? Нормально работать с ними ну ни как нельзя - для добавления/удаления приходится изголяться.
    A: А что ты хотел от первой версии DialogAPI?

  7. Q: Почему в диалоге "нового" стиля не срабатывают кнопки на закрытие окна
    A: "Старые" - те которые не имеют обработчика. Вполне естественно, что их поведение должно быть точно таким же, как в FAR 1.65 и ниже.
    "Новые" - которые используют обработчик. Ты сам должен рулить моментом закрытия диалога, исключения: Ctrl-Break - закрывается всегда, Ctrl-Enter - если есть хотя бы одна кнопка с полем DefaultButton=1, то запрос на закрытие с Param1 = номеру текущего элемента, Esc и F10 - здесь можно рулить из обработчика - закрывать или нет.

  8. Q: И что - мне теперь самому закрывать диалог?
    A: Если используешь обработчик диалога - то ДА: поймал событие DN_BTNCLICK, проверил Param1 на нужный номер и заслал ядру диалога сообщение DM_CLOSE.

  9. Q: А если я мышкой - оно придет или еще ловить DN_MOUSECLICK?
    A: На твое усмотрение :-) Сначала мышиное сообщение придет (проигнорируй его), а за ним и DN_BTNCLICK не задержится...

  10. Q: И DefaultButton самому обрабатывать?
    A: Нет. Для DefaultButton получится следующая цепочка событий: [DN_MOUSECLICK -> ] DN_BTNCLICK -> DM_CLOSE.

  11. Q: Каким-то образом у меня получилось, что SEPARATOR, что бы я не делал не желал доходить до правого конца рамки, когда сделал с нуля - исправилось.
    A: См. замечания для флага DIF_SEPARATOR

  12. Q: А можно как-нибудь выключить этот автовыбор элемента мышью в листе (когда мышь над листом выбирает элемент, особенно если лист не текущий).
    A: Частично. См. DM_LISTSETMOUSEREACTION

наверх


Авторы и ссылки

главная

Энциклопедия "Programming FAR plugins - Encyclopedia for Developers" является продуктом коллективного творчества группы авторов (и соавторов). Исходным материалом для энциклопедии послужил файл помощи plugins.hlp из дистрибутива FAR Manager 1.6x.

В этом списке представлены авторы и соавторы данного произведения. Все те, кто принимал участие - словом ли, делом,... (за исключением авторов из радела «Статьи»)

Авторы благодарят Евгения Рошала за санкционирование и поддержку, оказанную при написании этого произведения.

Авторы

Валентин Скирдин
vskirdin@mail.ru
координатор проекта «FAR plugins programing - Encyclopedia of Developer» - сборка и выпуск.
Игорь Русских
cail@nm.ru
http://cail.nm.ru/
сокоординатор / черновая работа, оформление, скрипты, подгонка...
Иван Синтюрин
spinoza@mail.ru
http://www.moris.ru/~spinoza
«главный транслятор» - переводы статей с английского на русский...
Кирилл Кириченко
nectokris@mail.ru
«транслятор» - переводы статей с английского на русский...
Артем Назаров
tema@mail.ru
«DrWeb» - ловчий багов, опечаток, etc...
Василий Мошнинов
vmoshninov@newmail.ru
http://proxykit.narod.ru
Раздел по Delphi, замечания, уточнения, etc...
Дмитрий Жемеров
yole@yole.ru
«Purify» - ловчий багов, опечаток, etc...

Ссылки

Сайт Far PlugRinG
http://plugring.farmanager.com/
Far official site:
http://www.farmanager.com
http://www.rarlab.com


 FAR Manager в Интернете

FAR Manager в Интернете

главная
  • http://www.farmanager.com
    Официальный сайт FAR manager.

  • http://www.rarlab.com
    Официальный сайт поддержки архиватора WinRAR и FAR Manager.

  • http://www.farmanager.com/mantis
    Регистрация и обработка проблем и "хотелок", связанных с FAR Manager и стандартным плагинам к нему.

  • http://api.farmanager.com
    Online версия "Programming FAR plugins - Encyclopedia for Developers".

  • http://forum.farmanager.com
    Официальный форум для пользователей FAR manager.

  • http://plugring.farmanager.com
    Официальный сайт поддержки пользователей оболочки FAR Manager, центральный сайт web-кольца Far PlugRinG - объединенного общества плагинописателей.

  • http://farmanager.com/svn
    Официальный SVN репозитарий исходных текстов FAR Manager и стандартных плагинов.

  • Листы рассылки (с 2000 по 2007 годы):
    • http://groups.yahoo.com/group/plugring
      В группе рассылки "PlugRinG Forum" обсуждаются плагины к FAR Manager

    • http://groups.yahoo.com/group/farpluginsapi
      Список рассылки "FAR Manager Plugins API" предназначен для общения разработчиков плагинов для FAR Manager и обсуждения вопросов возникших в результате написания плагинов FAR Manager, а так же для любых вопросов, затрагивающих тему "API плагинов для FAR Manager" (в т.ч. обсуждение тем и разделов из "Programming FAR plugins - Encyclopedia for Developers").

    • http://groups.yahoo.com/group/plugring_announce
      Анонсы новых поступление на сайт PlugRinG

  • Листы рассылки (с 2007):
    • http://groups.google.com/group/fardev
      Список рассылки "Far Manager Development" предназначен для обсуждения любых вопросов, затрагивающих тему разработки FAR Manager и плагинов к нему.

    • http://groups.google.com/group/farcommits
      Список рассылки "SVN Мониторинг официальных патчей" предназначен для получения информации об изменениях в официальном репозитарии исходных текстов.

  • http://farplugins.sourceforge.net/wiki
    Far Wiki - это место, где собирается информация о Far Manager и его плагинах. Своеобразная народная энциклопедия!

  • news:fido7.far.support
    Конференция USENET FAR.SUPPORT (см. так же на Google Groups)

  • news:fido7.far.development
    Конференция USENET FAR.DEVELOPMENT (см. так же на Google Groups)


Словарь

главная
Часть материалов, описывающих свойства файловой системы взяты с сайта http://www.windowsfaq.ru/. Все ссылки на MSDN, упомянутые в Словаре, открываются в отдельном окне в виде результатов поиска по сайту msdn.microsoft.com (см. так же MSDN по русски).

Plugin - плагин

Программный компонент-добавка к FAR Manager, позволяющая реализовать дополнительные функции. Плагин фактически - обычная библиотека, которая выполняется в контексте консольного процесса - так что ваш плагин может делать все (ну или почти все), что может делать обычное консольное Win32 приложение. Сама идея плагинов позволяет настраивать оболочку под себя, добавляя нужное и выкидывая лишнее.

Reparse Points

Большая часть нововведений в файловой системе Windows 2000 стала возможной благодаря введению концепции Reparse Points, специальных "крючков" в файловой системе, позволяющих подключать дополнительные подсистемы хранения данных без использования дополнительных программ.

Reparse Points в действительности являются специальными объектами файловой системы, обладающими специальными атрибутами, которые позволяют использовать дополнительную функциональность подсистемы хранения данных. Любой файл или папка может иметь Reparse Point, что означает, что по одному и тому же пути при обращении к ресурсу могут быть доступны сразу несколько видов расширенной функциональности.
См. так же: MSDN: Reparse Points

Directory Junctions

Directory Junctions (слияния папок) позволяют соединять папки вместе таким образом, что вы можете привязать любую имеющуюся папку к любой другой локальной папке. Например, если имеются три папки, c:\folder1, c:\folder2 и c:\documents, то можно создать точки перехода к папке c:\documents таким образом, что она будет казаться подпапкой других двух папок, т.е. на диске будут существовать папки c:\folder1\documents и c:\folder2\documents.

Изначально предполагалось, что в поставку будет входить специальная утилита linkd.exe, предназначенная для создания Directory Junctions, однако сейчас эта программа не включена в Win2000 и поставляется в составе Resource Kit. Также Directory Junctions могут быть созданы при помощи API, однако это потребует написания собственной программы.

На первый взгляд, Directory Junctions и Distributed File System выполняют одни и те же задачи, так как оба этих сервиса создают видимость единого дерева папок, в действительности состоящих из множества распределенных папок. Однако между ними есть несколько существенных различий:

  • Система DFS использует службу Active Directory для хранения своей информации
  • Благодаря использованию Active Directory система DFS может обеспечивать защиту от сбоев и выравнивание нагрузки на систему, в то время как Directory Junctions не обеспечивают ни того, ни другого, хотя это и не является необходимым в контексте локального компьютера
  • Система DFS в основном нацелена на объединение сетевых ресурсов в единое пространство имен, в то время как Directory Junctions связывают только локальные ресурсы
  • DFS может работать с использованием нескольких файловых систем, а Directory Junctions основаны только на NTFS 5.0
  • Система DFS требует программы-клиента, а Directory Junctions - нет.

См. так же: MSDN: Directory Junctions, MSDN: Inside Win2K NTFS, Part 1.

Mount Points - точки подключения томов

Mount Points (точки подключения) по сути являются тем же самым, что и Directory Junctions, однако позволяют лишь подключать корневую папку одного раздела к папке на другом разделе диска. Mount Points создаются с использованием Reparse Points, и, следовательно, нуждаются в NTFS 5.0.

Mount Points полезны для увеличения размеров раздела без фактического изменения структуры разделов на диске. Например, можно создать точку подключения диска D: в качестве папки C:\Documents, что приведет в итоге к видимости увеличения доступного на диске C: пространства.
См. так же: MSDN: Volume Mount Points

Hard Links - жесткая связь

Hard Link - это когда один и тот же файл имеет два имени. Допустим, один и тот же файл имеет имена 1.txt и 2.txt: если пользователь сотрет файл 1, останется файл 2. Если сотрет 2 - останется файл 1, то есть оба имени, с момента создания, совершенно равноправны. Файл физически стирается лишь тогда, когда будет удалено его последнее имя. Жесткая связь может быть создана только в пределах одного раздела диска (естественно, файловая система должна поддерживать жесткие связи).
См. так же: MSDN: Hard Links, Q106166 - Windows NT Backup and Hard Links.

Symbolic Links - символическая связь

Гораздо более практичная возможность, позволяющая делать виртуальные каталоги - ровно так же, как и виртуальные диски командой subst в DOSе. Применения достаточно разнообразны: во-первых, упрощение системы каталогов. Если вам не нравится каталог "Documents and settings\Administrator\Documents", вы можете прилинковать его в корневой каталог - система будет по прежнему общаться с каталогом с дремучим путем, а вы - с гораздо более коротким именем, полностью ему эквивалентным.

Символические ссылки (SymLink) на NTFS поддерживаются, начиная с Windows Vista (NT 6.0). Они представляют собой улучшеный вариант связей каталогов - символические ссылки могут указывать как на папки, так и на файлы, как на локальные, так и на сетевые, при этом поддерживаются относительные пути.

См. так же: MSDN: Symbolic Links, Windows 2000 Magazine: Inside Win2K NTFS, Part 1.

Sparse File - разреженный (распределенные) файл

NTFS5 поддерживает разреженные файлы, которые состоят из больших областей последовательных нулевых разрядов. Такой файл можно пометить как разреженный и дать файловой системе возможность выделять место для хранения только значимых разрядов данного файла. NTFS хранит информацию только о том, где размещены значимые данные. Подобный способ позволяет оптимально распределять дисковую память на томах NTFS при хранении разреженных файлов и обработке этих файлов приложениями.
См. так же: MSDN: Sparse Files, Возможности NTFS.

Числовая сортировка

В Windows XP изменен алгоритм сортировки, который операционная система использует при выводе списка файлов. Выполняется не строковая сортировка, а числовая. FAR так же позволяет использовать числовую сортировки в стиле Windows XP - ведущие нули в имени файла не учитываются. Следующий пример показывает как сортируются файлы:
Режим включен (Windows XP) | Режим выключен (Windows 2000)
Ie4_01 | Ie4_01
Ie4_128 | Ie4_128
Ie5 | Ie401sp2
Ie6 | Ie5
Ie401sp2 | Ie501sp2
Ie501sp2 | Ie6
5.txt | 11.txt
11.txt | 5.txt
88.txt | 88.txt

См. так же: Q319827 - The Sort Order for Files and Folders Whose Names....


/*
LocMsg - Скажем локализации: "ДА!"
Author - Ivan Sintyurin. Copyright (c) 2000. All Rights Reserved.

  Я буду рад, если данная функция поможет Вам писать программы  с
возможностью локализации. Прошу Вас только об одном -  указывайте
мой copyright (в readme, например).

  Функция LocMsg возвращает указатель на строку в соответствие  с
языковыми  настройками  FAR'а  (учитывает  настройки   конкретных
пользователей - фича FAR 1.63).

  В каталоге с плагином должен быть файл с сообщениями  с  именем
"ИмяПлагина.msg" Описание формата находится в файле template.msg.

Передаваемые параметры:
MsgName - название нужного сообщения
Var     - если не NULL, то сюда копируется полученная строка
Len     - если = 0, то копируется столько, сколько есть

Должна также быть определена и заполнена глобальная структура
PluginStartupInfo Info, из нее берутся данные:
Info.RootKey - место, где хранятся данные плагинов
Info.ModuleName - полный путь к плагину
*/
char *LocMsg(struct PluginStartupInfo *psi,char *MsgName, char *Var,int Len)
{
  HKEY hKey;
  DWORD Type;
  static char Msg[81];
  char *ppMsg;
  char *sLanguage="Language", *smsg=".msg", *sRussian="Russian";
  char msgfile[NM],       //имя файла с данными
       Lang[80],                //Название языковой секции, по умолчанию=Russian
       LangKey[80]="";    //Языковые настройки FAR'а

  lstrcpy(msgfile,Info.ModuleName);//Определяем имя файла
  lstrcpy(Lang,sRussian);
  char *ptr=strrchr(msgfile,'.');  //с сообщениями.
  if(ptr) lstrcpy(ptr,smsg);     //У Вас это может
  else lstrcat(msgfile,smsg);    //выглядеть иначе.

  lstrcat(LangKey,Info.RootKey);//Определяем:
  ptr=strrchr(LangKey,'\\');    //откуда читать
  lstrcpy(ptr+1,sLanguage);    //языковые настройки.

  //Читаем языковые настройки текущего пользователя
  if(RegOpenKeyEx(HKEY_CURRENT_USER,LangKey,0,KEY_READ,&hKey)==ERROR_SUCCESS)
  {
          DWORD DataSize=80;
          RegQueryValueEx(hKey,"Main",NULL,&Type,(BYTE *)&Lang,&DataSize);
          RegCloseKey(hKey);
  }

  if(!GetPrivateProfileSection(Lang,Msg,80,msgfile))
  {
          //если требуемой секции нет, то прочитать имя секции по умолчанию
          GetPrivateProfileString("Default",sLanguage,sRussian,Lang,80,msgfile);
          if(!GetPrivateProfileSection(Lang,Msg,80,msgfile))
                  //если нет требуемой секции с именем=имя по умолчанию
                  //то читать будем первую попавшуюся секцию
                  GetPrivateProfileSectionNames(Lang,80,msgfile);
  }

  if(!Var)
    ppMsg=Msg;
  else
    ppMsg=Var;

  if(!Len)
    Len=80;
  Len++;
  //читаем нужную строку
  GetPrivateProfileString(Lang,MsgName,MsgName,ppMsg,Len,msgfile);

  //Если раскомментировать следующую строку, то в msg-файле будут
  //автоматически создаваться отсутствующие секции
  //if(lstrcmp(MsgName,Msg)==0)
  //  WritePrivateProfileString(Lang,MsgName,Msg,msgfile);

//  if(Var)
//    lstrcpy(Var,Msg);//Копируем в Var полученную строку, если надо
  return(ppMsg);
}


"Обработка нажатия ESC или . . ."

главная | статьи | статья
Василий Мошнинов vmoshninov@newmail.ru

Я бы предложил переписать функцию проверки на ESC по-другому. В свое время у меня были замечания по поводу того, что плагин ProxyFtp чистит буфер и нельзя делать «упреждающие нажатия» :)) клавиш. Поэтому такая функция была мной переписана вот так:

function CheckForKey(vKey: word): boolean;
const
  DELTA = 16;
Type
  TInputRecArr = array[0..Pred(MaxInt div SizeOf(TInputRecord))] of TInputRecord;
Var
  Console: THandle;
  InputRec: ^TInputRecArr;
  InputSize: DWORD;
  ReadSuccess: boolean;
  ReadCnt,i: DWORD;
Begin
  result:= false;
  Console:= GetStdHandle(STD_INPUT_HANDLE);
  InputSize:= 0;
  InputRec:= nil;

  try
    repeat
      Inc(InputSize, DELTA);
      MemRealloc(InputRec,InputSize*SizeOf(TInputRecord));
      ReadSuccess:= PeekConsoleInput(Console,InputRec^[0],InputSize,ReadCnt);
    until (not ReadSuccess) or (ReadCnt < InputSize);
    if ReadSuccess and (ReadCnt > 0) then
    begin
      for i:= 0 to Pred(ReadCnt) do
        if (InputRec^[i].EventType = KEY_EVENT) and
           (InputRec^[i].Event.KeyEvent.bKeyDown) and
           (InputRec^[i].Event.KeyEvent.wVirtualKeyCode = vKey) then
        begin
         result:= true;
         ReadConsoleInput(Console,InputRec^[0],Succ(i),ReadCnt);
         Break;
        end; { if }
    end; { if }
  finally
    MemRealloc(InputRec,0);
  end;
end;

Эта функция не чистит буфер клавиатуры, если искомого кода там нет.

Вариант функции на C/C++:

BOOL CheckForKey(WORD vKey)
{
  INPUT_RECORD *InputRec;
  DWORD NumberOfEvents, ReadCnt,i;
  BOOL result = FALSE;
  HANDLE Console = GetStdHandle(STD_INPUT_HANDLE);

  if(GetNumberOfConsoleInputEvents(Console,&NumberOfEvents))
  {
    if((InputRec=(INPUT_RECORD *)GlobalAlloc(GPTR,
                             NumberOfEvents*sizeof(INPUT_RECORD))) != NULL)
    {
      if(PeekConsoleInput(Console,InputRec,NumberOfEvents,&ReadCnt))
        if(ReadCnt <= NumberOfEvents)
          for(i=0; i < NumberOfEvents; ++i)
          {
            if (InputRec[i].EventType == KEY_EVENT &&
                InputRec[i].Event.KeyEvent.bKeyDown &&
                InputRec[i].Event.KeyEvent.wVirtualKeyCode == vKey)
            {
              result=TRUE;
              if(i > 0)
                ReadConsoleInput(Console,InputRec,i,&ReadCnt);
              break;
            }
          }
      GlobalFree((HGLOBAL)InputRec);
    }
  }
  return result;
}

15.04.2000
наверх


Для авторов

главная | статьи
Здесь описываются некоторые моменты оформления и организации статей для Энциклопедии.
  1. Ссылка "внутрь" Энциклопедии (например, для структуры PluginStartupInfo):

    <a href="mk:@MSITStore:pluginsr.chm::/html/structures/pluginstartupinfo.html">PluginStartupInfo</a>

    Здесь следует учесть структуры каталогов pluginsr.chm и принципы наименования статей:

    • имена html-файлов в основном соответствуют названиям функций и структур;
    • все html-файлы внутри pluginsr.chm в нижнем регистре;
    • html-файлы раскиданы по подкаталогам в соответствии со своими функциональными назначениями, например, основные структуры располагаются в pluginsr.chm::/html/structures/, структуры Dialog API в pluginsr.chm::/html/dialogapi/structures/ и т.п.

    Для анализа структуры Энциклопедии лучше всего воспользоваться плагином DocFile browser

  2. Ссылка на WinAPI функцию (не описанную в Энциклопедии) для Вашей статьи (например, для функции GetLastError):

    <a href="win32/GetLastError">GetLastError</a>

    специальным скриптом такая ссылка преобразуется в <object>, как указано ниже.

  3. Ссылка на WinAPI функцию (не описанную в Энциклопедии) для самостоятельного CHM-файла (например, для функции GetLastError):

    <a href=JavaScript:linkXXXX.Click()>GetLastError</a>
    <object id=linkXXXX type="application/x-oleobject" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
    <param name="Command" value="KLink">
    <param name="DefaultTopic" value="">
    <param name="Item1" value="">
    <param name="Item2" value="GetLastError">
    </object>

    Здесь linkXXXX - уникальный ID объекта в пределах одной HTML-страницы.

    При этом, если CHM-файл внедрен в MSDN, то выбор ссылки приведет к открытию соответствующей статьи из MSDN. Если MSDN`а поблизости нет, то пользователь получит сообщение:

  4. Ссылка на WinAPI функцию (не описанную в Энциклопедии) для Интернета (например, для функции GetLastError):

    <a href="../notfound.html?GetLastError">GetLastError</a>

    Предполагается, что "notfound.html" располагается в "корне" проекта и браузер пользователя MSIE 4.x и выше.
    Содержимое файла:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>

<head>
<title>Внешняя ссылка</title>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1251">
<link rel="stylesheet" type="text/css" href="../styles/styles.css">
<script language="javascript" type="text/javascript"><!--
var roll = document.images != null;
function DrawNotFound(){
 if (roll && navigator.userAgent.indexOf("Mozilla", 0) != -1){
  var agent = navigator.userAgent.toLowerCase();
  if(agent.indexOf("msie 4")>0 || agent.indexOf("msie 5")>0 || agent.indexOf("msie 6")>0){
   f=document.location.href.indexOf("?");
   if(f > 0){
    qu=document.location.href.substring(f+1);
    str=" по <a href='http://search.microsoft.com/default.asp?boolean=ALL&"
    str=str+"nq=NEW&so=RECCNT&p=1&ig=01&i=00&i=01&i=02&"
    str=str+"i=03&i=04&i=05&i=06&i=07&i=08&i=09&i=10&"
    str=str+"i=11&i=12&i=13&i=14&i=15&i=16&i=17&i=18&"
    str=str+"i=19&i=20&i=21&i=22&i=23&i=24&i=25&i=26&"
    str=str+"i=27&i=28&i=29&i=30&i=31&i=32&i=33&i=34&"
    str=str+"i=35&i=36&i=37&i=38&i=39&i=40&i=41&"
    str=str+"siteid=us/dev&qu=" + qu + "' target='_blank' style='font-weight:bold;'>"
    str=str+ qu+ "</a> ";
    inf.innerHTML=str
   }
  }
 }
}
//--></script>
</head>

<body onload="DrawNotFound()">

<h1>404 - Информация недоступна</h1>
<div class="navbar">
  <a href="index.html">главная</a>
</div>

<div class="descr">
Запрашиваемая информация <span id="inf"></span> находится где-то в дебрях
<b><a href="http://msdn.microsoft.com/library/" target="_blank">MSDN Library</a></b>.

</body>

</html>


Figures

Figure 1 Hello World .MAP File
Address         Publics by Value             Rva+Base     Lib:Object
0001:00000000   _main                        00401000 f   hello.obj
0001:0000000c   _printf                      0040100c f   LIBC:printf.obj
0001:0000003d   _mainCRTStartup              0040103d f   LIBC:crt0.obj
0001:0000011c   __amsg_exit                  0040111c f   LIBC:crt0.obj
0001:00000165   __stbuf                      00401165 f   LIBC:_sftbuf.obj
0001:000001f2   __ftbuf                      004011f2 f   LIBC:_sftbuf.obj
0001:0000022f   __output                     0040122f f   LIBC:output.obj
0001:00000a39   ___initstdio                 00401a39 f   LIBC:_file.obj
0001:00000ade   ___endstdio                  00401ade f   LIBC:_file.obj
0001:00000af2   __cinit                      00401af2 f   LIBC:crt0dat.obj
0001:00000b1f   _exit                        00401b1f f   LIBC:crt0dat.obj
0001:00000b30   __exit                       00401b30 f   LIBC:crt0dat.obj
0001:00000bf4   __XcptFilter                 00401bf4 f   LIBC:winxfltr.obj
0001:00000d78   __setenvp                    00401d78 f   LIBC:stdenvp.obj
0001:00000e31   __setargv                    00401e31 f   LIBC:stdargv.obj
0001:0000107e   ___crtGetEnvironmentStringsA 0040207e f   LIBC:a_env.obj
0001:000011b0   __ioinit                     004021b0 f   LIBC:ioinit.obj
0001:0000135b   __heap_init                  0040235b f   LIBC:heapinit.obj
0001:00001398   __global_unwind2             00402398 f   LIBC:exsup.obj
0001:000013da   __local_unwind2              004023da f   LIBC:exsup.obj
0001:00001432   __NLG_Return2                00402432 f   LIBC:exsup.obj
0001:00001442   __abnormal_termination       00402442 f   LIBC:exsup.obj
0001:00001465   __NLG_Notify1                00402465 f   LIBC:exsup.obj
0001:0000146e   __NLG_Notify                 0040246e f   LIBC:exsup.obj
0001:00001481   __NLG_Dispatch               00402481 f   LIBC:exsup.obj
0001:00001490   __except_handler3            00402490 f   LIBC:exsup3.obj
0001:0000154d   __seh_longjmp_unwind@4       0040254d f   LIBC:exsup3.obj
0001:00001568   __FF_MSGBANNER               00402568 f   LIBC:crt0msg.obj
0001:000015a1   __NMSG_WRITE                 004025a1 f   LIBC:crt0msg.obj
0001:000016f4   _malloc                      004026f4 f   LIBC:malloc.obj
0001:00001706   __nh_malloc                  00402706 f   LIBC:malloc.obj
0001:00001732   __heap_alloc                 00402732 f   LIBC:malloc.obj
0001:00001768   __isatty                     00402768 f   LIBC:isatty.obj
0001:0000178e   _fflush                      0040278e f   LIBC:fflush.obj
0001:000017c9   __flush                      004027c9 f   LIBC:fflush.obj
0001:00001825   __flushall                   00402825 f   LIBC:fflush.obj
0001:000018a0   _strlen                      004028a0 f   LIBC:strlen.obj
0001:0000191b   _wctomb                      0040291b f   LIBC:wctomb.obj
0001:00001990   __aulldiv                    00402990 f   LIBC:ulldiv.obj
0001:00001a00   __aullrem                    00402a00 f   LIBC:ullrem.obj
0001:00001a75   __flsbuf                     00402a75 f   LIBC:_flsbuf.obj
0001:00001b8a   _calloc                      00402b8a f   LIBC:calloc.obj
0001:00001c07   __fcloseall                  00402c07 f   LIBC:closeall.obj
0001:00001c5f   _free                        00402c5f f   LIBC:free.obj
0001:00001c90   _strcpy                      00402c90 f   LIBC:strcat.obj
0001:00001ca0   _strcat                      00402ca0 f   LIBC:strcat.obj
0001:00001d80   __setmbcp                    00402d80 f   LIBC:mbctype.obj
0001:00002144   ___initmbctable              00403144 f   LIBC:mbctype.obj
0001:00002160   _memcpy                      00403160 f   LIBC:memcpy.obj
0001:00002495   ___sbh_heap_init             00403495 f   LIBC:sbheap.obj
0001:000024d3   ___sbh_find_block            004034d3 f   LIBC:sbheap.obj
0001:000024fe   ___sbh_free_block            004034fe f   LIBC:sbheap.obj
0001:00002829   ___sbh_alloc_block           00403829 f   LIBC:sbheap.obj
0001:00002b32   ___sbh_alloc_new_region      00403b32 f   LIBC:sbheap.obj
0001:00002be3   ___sbh_alloc_new_group       00403be3 f   LIBC:sbheap.obj
0001:00002cde   ___crtMessageBoxA            00403cde f   LIBC:crtmbox.obj
0001:00002d70   _strncpy                     00403d70 f   LIBC:strncpy.obj
0001:00002e6e   __callnewh                   00403e6e f   LIBC:handler.obj
0001:00002e89   __commit                     00403e89 f   LIBC:commit.obj
0001:00002ee0   __write                      00403ee0 f   LIBC:write.obj
0001:0000308d   __fptrap                     0040408d f   LIBC:crt0fp.obj
0001:00003096   __lseek                      00404096 f   LIBC:lseek.obj
0001:00003130   __getbuf                     00404130 f   LIBC:_getbuf.obj
0001:00003180   _memset                      00404180 f   LIBC:memset.obj
0001:000031d8   _fclose                      004041d8 f   LIBC:fclose.obj
0001:0000322e   ___crtLCMapStringA           0040422e f   LIBC:a_map.obj
0001:0000347d   ___crtGetStringTypeA         0040447d f   LIBC:a_str.obj
0001:000035d0   _memmove                     004045d0 f   LIBC:memmove.obj
0001:00003905   __free_osfhnd                00404905 f   LIBC:osfinfo.obj
0001:0000397f   __get_osfhandle              0040497f f   LIBC:osfinfo.obj
0001:000039bc   __dosmaperr                  004049bc f   LIBC:dosmap.obj
0001:00003a23   __close                      00404a23 f   LIBC:close.obj
0001:00003ad6   __freebuf                    00404ad6 f   LIBC:_freebuf.obj
0001:00003b10   __alloca_probe               00404b10 f   LIBC:chkstk.obj
0001:00003b10   __chkstk                     00404b10 f   LIBC:chkstk.obj
Figure 2 PRINTF.CPP
//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>

// Force the linker to include USER32.LIB
#pragma comment(linker, "/defaultlib:user32.lib")

extern "C" int __cdecl printf(const char * format, ...)
{
  char szBuff[1024];
  int retValue;
  DWORD cbWritten;
  va_list argptr;

  va_start( argptr, format );
  retValue = wvsprintf( szBuff, format, argptr );
  va_end( argptr );

  WriteFile(  GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue,
              &cbWritten, 0 );

  return retValue;
}
Figure 3 INITTERM
//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================
#include <windows.h>
#include <malloc.h>
#include "initterm.h"

#pragma data_seg(".CRT$XCA")
_PVFV __xc_a[] = { NULL };

#pragma data_seg(".CRT$XCZ")
_PVFV __xc_z[] = { NULL };

#pragma data_seg()  /* reset */

#pragma comment(linker, "/merge:.CRT=.data")

typedef void (__cdecl *_PVFV)(void);

void __cdecl _initterm (
        _PVFV * pfbegin,
        _PVFV * pfend
        )
{
  /*
   * walk the table of function pointers from the bottom up, until
   * the end is encountered.  Do not skip the first entry.  The initial
   * value of pfbegin points to the first valid entry.  Do not try to
   * execute what pfend points to.  Only entries before pfend are
   * valid.
   */
  while ( pfbegin < pfend )
  {
    // if current table entry is non-NULL, call thru it.
    if ( *pfbegin != NULL )
      (**pfbegin)();
    ++pfbegin;
  }
}

static _PVFV * pf_atexitlist = 0;
static unsigned max_atexitlist_entries = 0;
static unsigned cur_atexitlist_entries = 0;

void __cdecl _atexit_init(void)
{
  max_atexitlist_entries = 32;
  pf_atexitlist = (_PVFV *)calloc( max_atexitlist_entries,
                                   sizeof(_PVFV*) );
}

int __cdecl atexit (_PVFV func )
{
  if ( cur_atexitlist_entries < max_atexitlist_entries )
  {
    pf_atexitlist[cur_atexitlist_entries++] = func;
    return 0;
  }

  return -1;
}

void __cdecl _DoExit( void )
{
  if ( cur_atexitlist_entries )
  {
    _initterm( pf_atexitlist,
               // Use ptr math to find the end of the array
               pf_atexitlist + cur_atexitlist_entries );
  }
}
Figure 4 DLLCRTO.CPP
//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
// FILE: DLLCRT0.CPP
//==========================================
#include <windows.h>
#include "initterm.h"

// Force the linker to include KERNEL32.LIB
#pragma comment(linker, "/defaultlib:kernel32.lib")

// Force 512 byte section alignment in the PE file
#pragma comment(linker, "/OPT:NOWIN98")

// #pragma comment(linker, "/nodefaultlib:libc.lib")
// #pragma comment(linker, "/nodefaultlib:libcmt.lib")

// User routine DllMain is called on all notifications

extern BOOL WINAPI DllMain(
                           HANDLE  hDllHandle,
                           DWORD   dwReason,
                           LPVOID  lpreserved
                           ) ;

//
// Modified version of the Visual C++ startup code.  Simplified to
// make it easier to read.  Only supports ANSI programs.
//
extern "C"
BOOL WINAPI _DllMainCRTStartup(
                               HANDLE  hDllHandle,
                               DWORD   dwReason,
                               LPVOID  lpreserved
                               )
{
  if ( dwReason == DLL_PROCESS_ATTACH )
  {
    // set up our minimal cheezy atexit table
    _atexit_init();

    // Call C++ constructors
    _initterm( __xc_a, __xc_z );
  }

  BOOL retcode = DllMain(hDllHandle, dwReason, lpreserved);

  if ( dwReason == DLL_PROCESS_DETACH )
  {
    _DoExit();
  }

  return retcode ;
}
Figure 5 TEST.CPP
// Small test program to exercise TINYCRT.  Does nothing useful
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, char *argv[] )
{
  int i;

  for ( i = 0; i < argc; i++ )
  {
    printf( "argc: %u \'%s\'\n", i, argv[i] );
  }

  char * p = new char[10];
  lstrcpy( p, "Hello" );
  delete p;

  printf( "%s\n", strlwr( "MyLowerCaseString" ) );
  printf ( "strcmpi: %u\n", strcmpi( "Abc", "abc" ) );
  strrchr( "foo", 'o' );

  return 0;
}

// Declare a simple C++ class with a constructor
class TestClass
{
public:
  TestClass(void)
  {
    printf( "In TestClass constructor\n" );
  }
  ~TestClass(void)
  {
    printf( "In TestClass destructor\n" );
  }
};

// Create a global instance of the class
TestClass g_TestClassInstance;


Under the Hood: Reduce EXE and DLL Size with LIBCTINY.LIB -- MSDN Magazine, January 2001

Reduce EXE and DLL Size with LIBCTINY.LIB

главная | статьи
Matt Pietrek
Оригинал: http://msdn.microsoft.com/msdnmag/issues/01/01/hood/default.aspx
Download the code for this article: Hood0101.exe (45KB)

Way back in my October 1996 column in MSJ, I addressed a question concerning the size of executable files. Back then, a simple Hello World program compiled to a 32KB executable. Two compiler versions later, the problem is only slightly better. The same program with the Visual C++о 6.0 compiler is now 28KB.

In that column, I provided a replacement runtime library that lets you create very small executable programs. There were some restrictions on what situations it was useful for, but for a large number of my own programs it worked well. After living with these restrictions for quite a while, I decided it was time to fix some of them. Making these modifications also happens to provide a great opportunity to describe a little-known linker option that can be used to further reduce program size.

EXE and DLL Size

Before jumping into the code for my replacement runtime library, it's worth taking the time to review why simple EXEs and DLLs are bigger than you might expect. Consider the canonical Hello World program:

#include <stdio.h>

void main()
{
    printf ("Hello World!\n" );
}

Let's compile this program for size, and generate a map file. Using the command-line Visual C++ compiler, the syntax would be:

Cl /O1 Hello.CPP /link /MAP

First, look at the .MAP file; a trimmed down version is shown in Figure 1. From looking at the addresses of main (0001:00000000) and of printf (0001:0000000C), you can infer that function main's code is only 0xC bytes in length. Looking at the last line of the file, the __chkstk function at address 0001:00003B10, you can also infer that there's at least 0x3B10 bytes of code in the executable. That's over 14KB of code to send Hello World to the screen.

Now, start looking through some of the other .MAP file lines. Some items make sense, for example, the __initstdio function. After all, printf writes its output to a file, so some amount of underlying runtime library support routines for stdio makes sense. Likewise, it's reasonable to expect that the printf code might call strlen, so its inclusion isn't a surprise.

However, take a look at some of the other functions, for instance __sbh_heap_init. This is the initialization function for the runtime library's small block heap. The Win32о-based operating systems offer up their own heap in the form of the HeapAlloc family of functions. Potential performance gains notwithstanding, the Visual C++ library could choose to use the Win32 heap APIs, but doesn't. Thus, you end up with more code than necessary in your executable.

While some people might not care that the runtime library implements its own heap, there are other less defensible examples. Consider the __crtMessageBoxA function near the bottom of the map file. This function allows the runtime library to call the MessageBox API without forcing the executable to link against USER32.DLL. For a simple Hello World program, it's hard to anticipate the need to call MessageBox.

Consider another example: the __crtLCMapStringA function, which does locale-dependent transformations of strings. While Microsoft is somewhat obligated to provide locale support, it's not really needed for a large number of programs. Why make programs that don't use locales pay the cost for those that do?

I could continue with other examples of unneeded code, but I've made my point. A typical small program contains lots of little nuggets of code that aren't used. By themselves, they don't contribute much to the code size, but add up all the cases and you're into serious amounts of code!

What About the C++ Runtime Library DLL?

Alert readers might say, "Hey Matt! Why don't you just use the DLL version of the runtime library?" In the past, I could make the argument that there was no consistently named version of the C++ runtime library DLL available on Windowsо 95, Windows 98, Windows NT 3.51, Windows NTо 4.0, and so forth. Luckily, we've moved past those days, and in most cases you can rely on MSVCRT.DLL being available on your target machines.

Making this switch and recompiling Hello.CPP, the resulting executable is now only 16KB. Not bad, but you can do better. More importantly, you're just shifting all of this unneeded code to someplace else (that is, to MSVCRT.DLL). In addition, when your program starts up, another DLL will have to be loaded and initialized. This initialization includes items like locale support, which you may not care about. If MSVCRT.DLL suits your needs, then by all means use it. However, I believe that using a stripped-down, statically linked runtime library still has merit.

I may be tilting at windmills here, but my e-mail conversations with readers show that I'm not alone. There are people out there who want the leanest possible code. In this day of writeable CDs, DVDs, and fast Internet connections, it's easy not to worry about code size. However, the best Internet connection I can get at home is only 24Kbps. I hate wasting time downloading bloated controls for a Web page.

As a matter of principle, I want my code to have as small a footprint as possible. I don't want to load any extra DLLs that I don't really need. Even if I might need a DLL, I'll try to delayload it so that I don't incur the cost of loading it until I use the DLL. Delayloading is a topic I've described in previous columns, and I strongly encourage you to become familiar with it. See Under the Hood in the December 1998 issue of MSJ for starters.

Digging Deeper

Now that I've beaten up the unneeded code within the program, let's turn to the executable file itself. If you were to run DUMPBIN /HEADERS on my Hello.EXE, you'd see the following two lines in the output:

1000 section alignment
1000 file alignment

The second line is interesting. It says that every code and data section in the executable is aligned on a 4KB (0x1000) byte boundary. Because sections are stored contiguously in a file, it's not hard to see the potential for wasting up to 4KB between the end of one section and the start of the next.

If I had linked the program with a version of the linker that came before Visual C++ 6.0, I would have seen something different, as you see here:

1000 section alignment
200 file alignment

The key difference is that the alignment between sections is only 512 bytes (0x200). There's much less space available to waste. In Visual C++ 6.0, the linker defaults were changed to make the file alignment of sections equal to the alignment in memory. This provides a slight load-time performance improvement on Windows 9x, but makes executables bigger.

Luckily, the Visual C++ linker has a way to go back to the previous behavior. The magic switch is /OPT:NOWIN98. Rebuilding Hello.CPP as before, but with the addition of this linker switch gets the executable file down to 21KBЧa savings of 7KB. If I switch to linking with MSVCRT.DLL and using /OPT:NOWIN98, the executable size drops to 2560 bytes!

LIBCTINY: A Minimal Runtime Library

Now that you understand the problem of why simple EXEs and DLLs are so large, it's time to introduce my new and improved replacement runtime library. In the October 1996 column (mentioned earlier), I created a small static .LIB file designed to replace or augment the Microsoft LIBC.LIB and LIBCMT.LIB libraries. I called this replacement runtime library LIBCTINY.LIB, since it was a very stripped-down version of Microsoft's own runtime library sources.

LIBCTINY.LIB is intended for simple applications that don't require a huge amount of runtime library support. Thus, it's not suitable for MFC applications or other complicated scenarios that make extensive use of the C++ runtime. LIBCTINY's ideal target is small programs or DLLs that call some Win32 APIs and perhaps display some simple output.

There are two guiding principles behind LIBCTINY.LIB. First, it replaces the standard Visual C++ startup routines with much simpler code. This simpler code doesn't refer to any of the more esoteric runtime library functions like __crtLCMapStringA. Because of this, much less extraneous code is linked into your binary. As I'll show shortly, the LIBCTINY routines perform a bare minimum of tasks before calling your WinMain, main, or DllMain routines.

The second guiding principle of LIBCTINY.LIB is to implement relatively large functions like malloc or printf with code that's already in the Win32 system DLLs. Beyond the minimal startup code, most of the other LIBCTINY source files are simple implementations of standard C++ runtime library functions such as malloc, free, new, delete, printf, strupr, strlwr, and so on. Take a look at the implementation of printf in printf.cpp (see Figure 2) to get an idea of what I'm talking about.

In my original version of LIBCTINY.LIB there were two restrictions that annoyed me. First, the original version did not support DLLs. You could make tiny console and GUI executable programs, but if you wanted to create a tiny DLL, you were out of luck.

Second, the original LIBCTINY did not support static C++ constructors and destructors. By this, I mean constructors and destructors declared at global scope. In the new version, I've added the basic code that implements this support. Along the way, I learned quite a bit about how the compiler and runtime library play a complicated game to make static constructors and destructors work.

The Dark Underbelly of Constructors

When the compiler processes a source file that has a static constructor, it generates two things. The first is a small blob of code with a name like $E2 that calls the constructor. The second thing the compiler emits is a pointer to this blob of code. This pointer is written to a specially named section in the .OBJ called .CRT$XCU.

Why the funny section name? It's a bit complicated. Let me throw another piece of data at you to help explain. If you examine the Visual C++ runtime library sources (for instance, CINITEXE.C), you'll find the following:

#pragma data_seg(".CRT$XCA")
_PVFV __xc_a[] = { NULL };

#pragma data_seg(".CRT$XCZ")
_PVFV __xc_z[] = { NULL };

The previous lines of code create two data segments, .CRT$XCA and .CRT$XCZ. In each segment it places a variable (__xc_a and __xc_z, respectively). Note that the segment names are very similar to the .CRT$XCU segment to which the compiler emits the constructor code pointer.

At this point, a little linker theory is needed. When processing all of the segments to create the final portable executable (PE) file, the linker concatenates all the data from identically named segments. Thus, if A.OBJ has a section called .data, and B.OBJ also has a .data section, all the data from A.OBJ and B.OBJ will be written contiguously into a single .data section in the PE file.

The use of a $ in a segment name puts a new twist on things. When encountering segment names with a $ in them, the linker treats the portion of the name preceding the $ as the final segment name. Thus, the .CRT$XCA, .CRT$XCU, and .CRT$XCZ segments all end up together in the final executable in a segment called .CRT.

What about the part of the segment name following the $? When combining these types of sections, the linker writes out the segments in the order dictated by the string following the $. The ordering is alphabetical, so all the data from .CRT$XCA goes first, followed by all of the data from .CRT$XCU, and finally all of the data from .CRT$XCZ. This is a crucial point to understand.

What's going on here is that the runtime library code has no idea how many static constructor calls are needed for a given EXE or DLL. However, it does know that only pointers to constructor code blobs will be in the .CRT$XCU segment. When the linker concatenates all the .CRT$XCU sections, it has the net effect of creating a function pointer array. By defining .CRT$XCA and .CRT$XCZ segments along with the __xc_a and __xc_z symbols, the runtime library can reliably locate the beginning and end of the function pointer array.

As you might expect, calling all the static constructors in a module is a simple matter of enumerating through the function pointer array, calling each pointer in turn. The routine that does this is _initterm, shown in Figure 3. This routine is identical to the version from the Visual C++ runtime library sources.

All things considered, getting static constructors to work in LIBCTINY was relatively easy. It was mostly a matter of defining the right data segments (specifically, .CRT$XCA and .CRT$XCZ), and calling _initterm from the correct spot in the startup code. Getting static destructors to work was a bit trickier.

Unlike the function pointer array that the compiler and linker conspire to create for static constructors, the list of static destructors to call is built at runtime. To build this list, the compiler generates calls to the atexit function, which is part of the Visual C++ runtime. The atexit function takes a function pointer and adds the pointer to a first-in, last-out list. When the EXE or DLL unloads, the runtime library iterates through the list and calls each function pointer.

LIBCTINY's implementation of the atexit functionality is significantly simpler than what the Visual C++ runtime library does. There are three functions and a handful of static variables for this support, which is also in initterm.cpp. The _atexit_init function simply allocates an array to hold 32 function pointers, and stores the pointer in the pf_atexitlist static variable.

The atexit function checks to see if there's room in the array, and if so, adds the pointer to the end of the list. A more robust version of this code would reallocate the array to a larger size if necessary. Finally, the _DoExit function uses your friend, _initterm, to iterate through the array and call each function pointer. In an ideal world, _DoExit would iterate through the array in reverse order, mimicking the behavior of the Visual C++ runtime library implementation. However, the whole purpose of LIBCTINY is to be simple and small, rather than striving for perfect compatibility.

LIBCTINY's Minimal Startup Routines

Now let's take a look at LIBCTINY's new support for small DLLs. As with EXEs, the trick is to make the DLL's entry point code as small as possible and omit calls to unneeded routines that bring in lots of other code. Figure 4 shows the minimal DLL startup code. When your DLL is loaded, it is this code, not your DllMain routine, that executes first.

The _DllMainCRTStartup is the very first place execution begins in your DLL. In LIBCTINY's implementation, it first checks to see if the DLL is in its DLL_PROCESS_ATTACH call. If so, the code calls _atexit_init (described earlier), and _initterm to invoke any static constructors. The heart of the function is the call to DllMain, which is the routine you supply as part of your DLL's code. This DllMain call is made for all four notification types (process attach/detach, and thread attach/detach).

The last thing DllMainCRTStartup does is to check if the DLL is in its DLL_PROCESS_DETACH code. If so, the code calls _DoExit. As described earlier, this causes any static destructors to be called. If you're curious about the startup code for console and GUI mode EXEs, be sure to check out CRT0TCON.CPP and CRT0TWIN.CPP, respectively. (These modules accompany the code download, found at the link at the top of this article.)

One other thing worth checking out in DLLCRTO.CPP (see Figure 4) is this line near the top:

#pragma comment(linker, "/OPT:NOWIN98")

This puts a linker directive into the DLLCRT0.OBJ file that tells the linker to use the /OPT:NOWIN98 switch. The benefit is that you don't have to manually add /OPT:NOWIN98 to your make files or project files by hand. I figure if you're using LIBCTINY, you'd probably want to use /OPT:NOWIN98 as well.

Using LIBCTINY.LIB

Using LIBCTINY is very simple. All you have to do is add LIBCTINY.LIB to the linker's list of .LIB files to search. If you're using the Visual Studioо IDE, this would be in the Projects | Settings | Link tab. It doesn't matter what type of binary you're building (console EXE, GUI EXE, or DLL), since LIBCTINY.LIB contains appropriate entry point routines for each of them.

Take a look at TEST.CPP in Figure 5. This program simply exercises a few of the routines that LIBCTINY.LIB implements, and includes a static constructor and destructor invocation. When I compile it normally with Visual C++ 6.0,

CL /O1 TEST.CPP
the resulting executable is 32768 bytes. By simply adding LIBCTINY.LIB to the command line

CL /O1 TEST.CPP LIBCTINY.LIB
the resulting executable shrinks to 3072 bytes.

You might be wondering about the runtime library routines that LIBCTINY doesn't implement. For instance, in TEST.CPP, there's a call to strrchr. There's no problem here because that function exists in the regular LIBC.LIB or LIBCMT.LIB that Visual C++ provides. Both LIBCTINY.LIB and LIBC.LIB implement a variety of routines. LIBCTINY's list is obviously smaller than what LIBC.LIB provides. The important thing for your purposes is that the linker finds the LIBCTINY routines first when resolving function calls, and so LIBCTINY's routines are what's used. If something isn't implemented in LIBCTINY, the linker finds it in LIBC.LIB instead.

Finally, it's worth repeating that LIBCTINY isn't suitable for all purposes. For example, if your code makes use of multiple threads and relies on the runtime library's per-thread data support, then LIBCTINY isn't for you. What I do is try LIBCTINY with a prospective program. If it works, great! If not, I simply use the normal runtime library.

Metadata Article Correction

In my October 2000 MSDN Magazine article "Avoiding DLL Hell: Introducing Application Metadata in the Microsoft .NET Framework," I said that using the Visual C++ 6.0 #import directive causes the compiler to read in a COM type library and generate ATL-ready header files for all the interfaces contained within. While header files are generated by #import, it turns out they don't use ATL.

Richard Grimes, author of Professional ATL COM Programming (Wrox Press, 1998), kindly pointed out to me that #import generates what Microsoft calls "compiler COM support classes," which are supported by the COMDEF.H header. Richard goes on to say, "There are many differences between the COM compiler support classes and the equivalent in ATL. The most important is that ATL does not use C++ exceptions. In fact, the ATL classes are more lightweight than the COM compiler support classes and so I would have preferred if Microsoft had decided to generate ATL code."

I have to confess that I should have studied this more before I wrote it. My experience with ATL is limited to the wizards in Visual C++, and tweaking the resulting code. I have used #import on a few occasions, but not enough to have made the connection that the resulting code wasn't ATL. Thanks to Richard for pointing this out to me, and for giving me even more incentive to verify everything before I write about it.

Matt Pietrek does advanced research for the NuMega Labs of Compuware Corporation, and is the author of several books. His Web site, at http://www.wheaty.net/, has a FAQ page and information on previous columns and articles.

From the January 2001 issue of MSDN Magazine.


Восстановление MSDN

главная | статьи
Sergey Creedence csappsupport@mail2k.ru
Оригинал: http://www.sources.ru/msdn/msdn_problems.shtml

Помню, в форуме многих интересовали вопросы типа "как восстановить работоспособность MSDN?", "как мне перенести MSDN на другой комп" или что-то вроде того. Я тоже этим интересовался (один раз перестал запускаться MSDN - начинал орать, что невозможно открыть файл "Msdn010.Col" ;).

Решение такое: все дело в файле "C:\Documents and Settings\All Users\Application Data\Microsoft\HTML Help\HhColreg.Dat". В Вин98 где лежит - не знаю, но можно найти. Он и содержит все прописанные данные о коллекциях. Я даже проверял: переименовывал - появляется "моя любимая ошибка" о невозможности открытия. Восстанавливал - все прекрасно работает.

Еще по поводу MSDN могу сказать, что все подмножества хранятся в файле "C:\Documents and Settings\[username]\Application Data\Microsoft\HTML Help\1033\MSDN010.chs", а избранное - в "C:\Documents and Settings\[username]\Application Data\Microsoft\HTML Help\hh.Dat"

Еще что требуется для MSDN:

  • Зарегистрировать файл "C:\Program Files\Common Files\Microsoft Shared\MSDN\COOKDOC.DLL" с помощью RegSvr32.
  • Прописать в Реестре "коллекцию" (пример для моей установки):
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTML Help Collections]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTML Help Collections\Developer Collections]
"Language"="0x0409"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTML Help Collections\Developer Collections\0x0409]
"Preferred"="0x038b56390"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTML Help Collections\Developer Collections\0x0409\0x038b56390]
"Filename"="C:\\MSDN Library\\2000APR\\1033\\MSDN010.COL"
@="MSDN Library - April 2000"
"Full"=dword:00000001
    Информация о пути к статусу установки хранится в разделе "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MS Setup (ACME)\Table Files"
  • Прописать файлы COLCHNG.EXE в разделе "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools":
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\colchng.exe(1033)]
"Path"="C:\\Program Files\\Common Files\\Microsoft Shared\\MSDN\\1033\\COLCHNG.EXE"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\colchng.exe(1033)\Clients]
"C:\\MSDN Library\\2000APR\\1033\\PID.EXE"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\cookdoc.dll]
"Path"="C:\\Program Files\\Common Files\\Microsoft Shared\\MSDN\\COOKDOC.DLL"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\cookdoc.dll\Clients]
"C:\\MSDN Library\\2000APR\\1033\\PID.EXE"=""
  • Указать об установленном продукте в разделе "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0\Setup\MSDN Library - April 2000"
  • Прописать все файлы в разделе "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs"

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


Паковать или не паковать? - Журнал "Программист"

Паковать или не паковать?

главная | статьи
Крис Касперски kk@sendmail.ru
Оригинал: http://www.programme.ru/index.phtml?arch/102001/102001_1.htm

"Умный человек, - это тот человек, который сознает несовершенство, незакончен-
ность своих знаний, стремится их пополнить и в этом преуспевает"
Братья Стругацкие "Гадкие лебеди"

Введение. Царство MS-DOS

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

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

Вскоре упаковщиков развелось видимо-невидимо (их тогда писали все, кому не лень) - AINEXE, DIET, EXEPACK, LZEXE, PKLITE и масса других - всех не перечислить! И не удивительно: процессоры день ото дня становились все производительнее - уже на "трешке" распаковка занимала столь незначительное время, что им можно было пренебречь. К тому же приятным побочным эффектом оказалась защита от дизассемблирования. Действительно, непосредственно дизассемблировать упакованный файл невозможно - прежде его необходимо распаковать. Конечно, на каждый щит найдется свой меч - из под пера хакеров вышло немало замечательных универсальных распаковщиков (UNP, Intruder, UUP, а вершиной всему стал CPU386 со встроенным эмулятором реального режима процессора 80386), но качество автоматической распаковки оставляло желать лучшего (порой распакованные файлы зависали при запуске или в процессе работы), а ручной трассировкой владели далеко не все.

Словом, при всех своих достоинствах, упаковка исполняемых файлов не имела никаких недостатков и не собиралась сдавать позиций даже с приходом емких (по тем временам) одно-двух гигабайтных жестких дисков и CD-ROM.

Сжатие файлов под Windows 9x\NT

Наступил девяносто пятый год - мир медленно, но неотвратимо пересаживался на новую операционную систему - Windows 95. Пользователи осторожно осваивали мышь и графический интерфейс, а программисты тем временем лихорадочно переносили старое программное обеспечение на новую платформу. Объемы винчестеров к тому времени выросли настолько, что разработчики могли забыть слово "оптимизация", да они, судя по размеру современных приложений, его и забыли. Сто мегабайт - туда, триста сюда - эдак никаких гигабайт не хватит!

Вот тут-то и вспомнили о распаковке исполняемых файлов "на лету". На рынке появилось несколько программ - компрессоров, из которых наибольшую популярность завоевал ASPack, умеющий сжимать и разжимать не только "экзешники", но и динамические библиотеки. А в состав самой Windows 95 вошла динамическая библиотека LZEXPAND.DLL, поддерживающая базовые операции упаковки-распаковки и "прозрачную" работу со сжатыми файлами. Пользователи и программисты не замедлили воспользоваться новыми средствами, но...

...в отличие от старушки MS-DOS, в Windows 9x\NT за автоматическую распаковку приходится платить больше, чем получать взамен. Вспомним, как в MS-DOS происходила загрузка исполняемых модулей. Файл целиком считывался с диска и копировался в оперативную память, причем наиболее узким местом была именно операция чтения с диска. Упаковка даже ускоряла загрузку, ибо физически читался меньший объем данных, а их распаковка занимала пренебрежимо короткое время.

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

Например, если в текстовом редакторе есть модуль работы с таблицами, он не будет загружен с диска до тех пор, пока пользователь не захочет создать (или отобразить) свою таблицу. Причем неважно - находится ли этот модуль в динамической библиотеке или в основном файле! (Вот и попробуйте после этого сказать, что Windows глупые люди писали!) Загрузка таких "монстров", как Microsoft Visual Studio и Word, как бы "размазывается" во времени и к работе с приложением можно приступать практически сразу же после его запуска. А что произойдет, если файл упаковать? Правильно - он будет должен считаться с диска целиком (!) и затем - опять-таки, целиком - распаковаться в оперативную память.

Стоп! Откуда у нас столько оперативной памяти? Ее явно не хватит и распакованные страницы придется вновь скидывать на диск! Как говорится: за что боролись, на то и напоролись. Причем, если при проецировании неупакованного exe-файла оперативная память не выделяется, (во всяком случае, до тех пор, пока в ней не возникнет необходимость), распаковщику без памяти никак не обойтись! А поскольку оперативной памяти никогда не бывает в избытке, она может быть выделена лишь за счет других приложений! Отметим также, что в силу конструктивных особенностей железа и архитектуры операционной системы, операция записи на диск заметно медленнее операции чтения.

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

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

Таким образом, под Windows 9x\NT сжимать исполняемые файлы нецелесообразно - вы платите гораздо больше, чем выручаете. Что же касается защиты от дизассемблирования: Да, когда ASPack только появился, он отвадил от взлома очень многих неквалифицированных хакеров, но - ненадолго! Сегодня в сети только слепой не найдет руководство по ручному снятию ASPack'а. Существует и масса готового инструментария - от автоматических распаковщиков до плагинов к дизассемблеру IDA Pro, позволяющих ему дизассемблировать сжатые файлы. Поэтому, надеяться, что ASPack спасет вашу программу от взлома, несколько наивно.

Точные цифры

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

Первый камень преткновения - что понимать под "временем загрузки"? Если проецирование - так оно выполняется практически мгновенно, и им можно вообще пренебречь. Моментом времени, начиная с которого с приложением можно полноценно работать? Так это от самого приложения зависит больше, чем от его упаковки. К тому же, на время загрузки упакованных файлов очень сильно влияет количество свободной на момент запуска физической оперативной памяти (не путать с общим объемом памяти, установленной на машине). Если перед запуском упакованного файла мы завершим одно-два "монстроузных" приложения, то занятая ими память окажется свободной, и сможет беспрепятственно использоваться распаковщиком. Напротив, если свободной памяти нет, ее придется по крохам отрывать от остальных приложений...

Даже если мы оценим изменение времени загрузки (что, кстати, сделать весьма проблематично - серия замеров на одной и той же машине, с одним и тем же набором приложений дает разброс результатов более чем на порядок), как измерять падение производительности остальных приложений? Ведь, при нехватке памяти Windows в первую очередь избавляется от не модифицированных страниц, которые незачем сохранять на диске! В результате упаковка исполняемого файла может несколько повысить производительность самого этого файла, но значительного ухудшить положение остальных, неупакованных приложений!

Поэтому никаких конкретных цифр в статье не приводится. Приблизительные оценки, выполненные "на глаз", показывают, что при наличии практически неограниченного количества оперативной памяти потери производительности составляют менее 10%, но при ее нехватке скорость всех приложений падает от двух до десяти раз! (Для справки: в эксперименте участвовали исполняемые файлы MS Word 2000, Visual Studio 6.0, Free Pascal 1.04, IDA Pro 4.17, Adobe Acrobat Reader 3.4, машина с процессором CLERION-300A, оснащенная 256 МБ ОЗУ, для имитации нехватки памяти ее объем уменьшался до 64 МБ; использовались операционные системы Windows 2000 и Windows 98).

Выводы:

  1. Исполняемые файлы под Windows лучше не паковать. В крайнем случае - используйте для упаковки/распаковки функции операционной системы (LZInit, LZOpenFile, LZRead, LZSeek, LZClose, LZCopy), динамически распаковывая в специально выделенный буфер только те части файла, которые действительно нужны в данный момент для работы.
  2. Динамические библиотеки вообще не следует паковать, ибо это ведет к чудовищному расходу и физической, и виртуальной памяти и извращает саму концепцию DLL - один модуль - всем процессам.
  3. Кстати, о динамических библиотеках: не стремитесь кромсать свое приложение на множество DLL - страницы исполняемого файла не требуют физической памяти до тех пор, пока к ним не происходит обращений. Поэтому - смело помещайте весь код программы в один файл.


_FAR_USE_FARFINDDATA

главная | типы и определения

Макроопределение _FAR_USE_FARFINDDATA определяет, будет ли структура PluginPanelItem использовать структуру WIN32_FIND_DATA, определенную в заголовках Windows API, или структуру FAR_FIND_DATA с теми же самыми полями, но опреденную в файле plugin.hpp. Поскольку некоторые компиляторы (в частности, Borland C++ 5.5) не позволяют задать выравнивание, отличное от 8-байтного, для структур в системных заголовках, при использовании таких компиляторов и структуры WIN32_FIND_DATA становится невозможным достижение правильного 2-байтного выравнивания для структуры PluginPanelItem в целом.

Если не определено макро _FAR_USE_FARFINDDATA, структура PluginPanelItem будет иметь вид, совместимый с FAR 1.65 и FAR 1.70 beta 3. Однако корректная компиляция плагинов в Borland C++ 5.5 будет невозможна без модификации системных заголовков Windows API.

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

Внимание! Внимание!

  • В FAR 1.70 beta 4 по умолчанию используется вариант, совместимый со старыми плагинами (_FAR_USE_FARFINDDATA не определено). В версии FAR 1.70 release умолчанием станет вариант _FAR_USE_FARFINDDATA. Таким образом, если вы хотите уже сейчас модифицировать свои плагины для совместимости на уровне исходных текстов с FAR 1.70 release, вы можете определить макро _FAR_USE_FARFINDDATA и внести соответствующие изменения в код ваших плагинов.
Смотрите также:


_FAR_USE_WIN32_FIND_DATA

главная | типы и определения

Макроопределение _FAR_USE_WIN32_FIND_DATA определяет, будет ли структура PluginPanelItem использовать структуру WIN32_FIND_DATA, определенную в заголовках Windows API, или структуру FAR_FIND_DATA с теми же самыми полями, но определенную в файле plugin.hpp. Поскольку некоторые компиляторы (в частности, Borland C++ 5.5) не позволяют задать выравнивание, отличное от 8-байтного, для структур в системных заголовках, при использовании таких компиляторов и структуры WIN32_FIND_DATA становится невозможным достижение правильного 2-байтного выравнивания для структуры PluginPanelItem в целом.

Если определено макро _FAR_USE_WIN32_FIND_DATA, структура PluginPanelItem будет иметь вид, совместимый с FAR 1.65 и FAR 1.70. Однако корректная компиляция плагинов в Borland C++ 5.5 будет невозможна без модификации системных заголовков Windows API.

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

Внимание! Внимание!

  • В FAR 1.70 release по умолчанию используется вариант, совместимый со старыми плагинами (_FAR_USE_WIN32_FIND_DATA определено). В версии FAR 1.71 умолчанием станет вариант со структурой FAR_FIND_DATA.
Смотрите также:


Ширина колонок

главная | структуры

Строка ColumnWidths в структурах PanelInfo и PanelMode описывает ширину колонок панели (например, "0,8,0,5").

Формат строки простой - числа (представляющие ширину колонки) разделенные запятой.

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

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

Для показа года в 4-хсимвольном формате нужно увеличить ширину колонки даты на 2.

Смотрите также:


FAR_FIND_DATA

главная | структуры | win32 структуры
Структура FAR_FIND_DATA описывает файловый объект на плагиновой панели FAR.
typedef struct _FAR_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[ MAX_PATH ];
  TCHAR cAlternateFileName[ 14 ];
} FAR_FIND_DATA;

Элементы

dwFileAttributes
Указывает атрибуты найденного файла. Этот элемент может быть комбинацией следующих значений:
Атрибут | Описание
FILE_ATTRIBUTE_ARCHIVE | Это архивный файл. Приложения должны использовать этот флаг для копирования, архивирования или удаления.
FILE_ATTRIBUTE_COMPRESSED | Файл или каталог сжат. Для файла это означает, что все данные его сжаты, для каталога - что компрессия по умолчанию применяется ко всем его файлам и подкаталогам.
FILE_ATTRIBUTE_DIRECTORY | Это каталог.
FILE_ATTRIBUTE_ENCRYPTED | Файл или каталог зашифрован. Для файла, это означает, что все данные в файле зашифрованы. Для директория, это означает, что шифрование является умолчанием для вновь созданных файлов и подкаталогов.
FILE_ATTRIBUTE_HIDDEN | Файл скрыт. Такой файл не включается в обычный листинг каталога.
FILE_ATTRIBUTE_NORMAL | У этого файла не установлены другие атрибуты. Это значение корректно только при использовании без остальных флагов.
FILE_ATTRIBUTE_OFFLINE | Данные файла не доступны непосредственно. Означает, что реальные данные файла были физически перемещены на устройства хранения.
FILE_ATTRIBUTE_READONLY | Файл только для чтения. Приложения могут читать такой файл, но не могут записывать или удалять его.
FILE_ATTRIBUTE_REPARSE_POINT | Каталог является символической связью.
FILE_ATTRIBUTE_SPARSE_FILE | Файл является т.н. "Sparse file".
FILE_ATTRIBUTE_SYSTEM | Этот файл - часть операционной системы.
FILE_ATTRIBUTE_TEMPORARY | Это временный файл. Приложения должны записывать в такой файл только в крайней необходимости. Большая часть данных файла находится в памяти и не сбрасывается на диск, так как файл будет удален.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | Этот файл или каталог не будут индексироваться службой индексирования.
FILE_ATTRIBUTE_VIRTUAL | Этот файл - виртуальный файл.
ftCreationTime
Время создания - структура FILETIME содержащая время создания файла. FindFirstFile и FindNextFile возвращают время файла в UTC-формате. Эти функции устанавливают элементы FILETIME в ноль если файловая система, содержащая файл не поддерживает этот временной атрибут. Вы можете использовать функцию FileTimeToLocalFileTime для преобразования из UTC в локальное время и тогда использовать функцию FileTimeToSystemTime для преобразования локального времени в структуру SYSTEMTIME содержащую отдельные элементы для месяца, дня, года и так далее...
ftLastAccessTime
Структура FILETIME с временем последнего доступа к файлу. Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
ftLastWriteTime
Структура FILETIME с временем последней записи в файл. Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
nFileSizeHigh
Верхнее двойное слово 64-х разрядного размера файла в байтах. Размер файла равен (nFileSizeHigh * MAXDWORD) + nFileSizeLow.
nFileSizeLow
Младшее двойное слово размера файла.
dwReserved0
Если поле dwFileAttributes включает атрибут FILE_ATTRIBUTE_REPARSE_POINT, это поле содержит тэг reparse. В противном случае значение этого поля не определено и не должно использоваться.
dwReserved1
Резерв.
cFileName
Строка с именем файла.
cAlternateFileName
Альтернативное имя файла (классическая 8.3 (filename.ext) форма).

Замечания

  1. Если файл имеет длинное имя, полное имя возвращается в элементе cFileName а усеченная версия формата 8.3 сохраняется в cAlternateFileName. Иначе cAlternateFileName пусто. Как альтернативу вы можете использовать функцию GetShortPathName для возвращения 8.3-вида имени файла.

  2. Не все файловые системы позволяют хранить время создания файла и последнего доступа к нему, и не все системы хранят их одинаково. Например, в файловой системе FAT под Windows NT время создания файла записывается с разрешением 10 миллисекунд, время последней модификации - 2 секунды, а время доступа - 1 день (то есть, фактически, записывается только дата доступа). На файловой системе NTFS время доступа имеет разрешение 1 час.

Смотрите также:


FAR_FIND_DATA

главная | структуры | win32 структуры
Структура FAR_FIND_DATA описывает файловый объект на плагиновой панели FAR. Размер структуры, содержимое и поведение различаются в FAR 1.7x (и ниже) и FAR 2.x.
// FAR 1.7x
typedef struct _FAR_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[ MAX_PATH ];
  TCHAR cAlternateFileName[ 14 ];
} FAR_FIND_DATA;

// FAR 2.x
struct FAR_FIND_DATA
{
  DWORD    dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  unsigned __int64 nFileSize;
  unsigned __int64 nPackSize;
  wchar_t *lpwszFileName;
  wchar_t *lpwszAlternateFileName;
};

Элементы

dwFileAttributes
Указывает атрибуты найденного файла. Этот элемент может быть комбинацией следующих значений:
Атрибут | Описание
FILE_ATTRIBUTE_ARCHIVE | Это архивный файл. Приложения должны использовать этот флаг для копирования, архивирования или удаления.
FILE_ATTRIBUTE_COMPRESSED | Файл или каталог сжат. Для файла это означает, что все данные его сжаты, для каталога - что компрессия по умолчанию применяется ко всем его файлам и подкаталогам.
FILE_ATTRIBUTE_DIRECTORY | Это каталог.
FILE_ATTRIBUTE_ENCRYPTED | Файл или каталог зашифрован. Для файла, это означает, что все данные в файле зашифрованы. Для директория, это означает, что шифрование является умолчанием для вновь созданных файлов и подкаталогов.
FILE_ATTRIBUTE_HIDDEN | Файл скрыт. Такой файл не включается в обычный листинг каталога.
FILE_ATTRIBUTE_NORMAL | У этого файла не установлены другие атрибуты. Это значение корректно только при использовании без остальных флагов.
FILE_ATTRIBUTE_OFFLINE | Данные файла не доступны непосредственно. Означает, что реальные данные файла были физически перемещены на устройства хранения.
FILE_ATTRIBUTE_READONLY | Файл только для чтения. Приложения могут читать такой файл, но не могут записывать или удалять его.
FILE_ATTRIBUTE_REPARSE_POINT | Каталог является символической связью.
FILE_ATTRIBUTE_SPARSE_FILE | Файл является т.н. "Sparse file".
FILE_ATTRIBUTE_SYSTEM | Этот файл - часть операционной системы.
FILE_ATTRIBUTE_TEMPORARY | Это временный файл. Приложения должны записывать в такой файл только в крайней необходимости. Большая часть данных файла находится в памяти и не сбрасывается на диск, так как файл будет удален.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | Этот файл или каталог не будут индексироваться службой индексирования.
FILE_ATTRIBUTE_VIRTUAL | Этот файл - виртуальный файл.
ftCreationTime
Время создания - структура FILETIME содержащая время создания файла. FindFirstFile и FindNextFile возвращают время файла в UTC-формате. Эти функции устанавливают элементы FILETIME в ноль если файловая система, содержащая файл не поддерживает этот временной атрибут. Вы можете использовать функцию FileTimeToLocalFileTime для преобразования из UTC в локальное время и тогда использовать функцию FileTimeToSystemTime для преобразования локального времени в структуру SYSTEMTIME содержащую отдельные элементы для месяца, дня, года и так далее...
ftLastAccessTime
Структура FILETIME с временем последнего доступа к файлу. Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
ftLastWriteTime
Структура FILETIME с временем последней записи в файл. Время хранится в UTC формате; элементы структуры установлены в ноль, если файловая система не поддерживает этого свойства.
nFileSizeHigh 1.x
Верхнее двойное слово 64-х разрядного размера файла в байтах. Размер файла равен (nFileSizeHigh * MAXDWORD) + nFileSizeLow.
nFileSizeLow 1.x
Младшее двойное слово размера файла.
nFileSize 2.x
Размера файла в байтах.
nPackSize 2.x
Размера сжатого файла в байтах.
dwReserved0 1.x
Если поле dwFileAttributes включает атрибут FILE_ATTRIBUTE_REPARSE_POINT, это поле содержит тэг reparse. В противном случае значение этого поля не определено и не должно использоваться.
dwReserved1 1.x
Резерв.
cFileName 1.x
Строка с именем файла.
lpwszFileName 2.x
Указатель на строку с именем файла.
cAlternateFileName 1.x
Альтернативное имя файла (классическая 8.3 (filename.ext) форма).
lpwszAlternateFileName 2.x
Указатель на строку альтернативным имем файла (классическая 8.3 (filename.ext) форма).

Замечания

  1. Если файл имеет длинное имя, полное имя возвращается в элементе cFileName а усеченная версия формата 8.3 сохраняется в cAlternateFileName. Иначе cAlternateFileName пусто. Как альтернативу вы можете использовать функцию GetShortPathName для возвращения 8.3-вида имени файла.

  2. Не все файловые системы позволяют хранить время создания файла и последнего доступа к нему, и не все системы хранят их одинаково. Например, в файловой системе FAT под Windows NT время создания файла записывается с разрешением 10 миллисекунд, время последней модификации - 2 секунды, а время доступа - 1 день (то есть, фактически, записывается только дата доступа). На файловой системе NTFS время доступа имеет разрешение 1 час.
  3. В FAR 2.x плагин должен сам заботиться о выделении и удалении памяти для компонент lpwszFileName и lpwszAlternateFileName.

Смотрите также:


FARMACRO_KEY_EVENT

главная | типы и определения
Константа FARMACRO_KEY_EVENT определяет тип входного сообщения структуры INPUT_RECORD, которое передается в ProcessEditorInput во время исполнения макрокоманды. Элемент Event содержит структуру KEY_EVENT_RECORD с информацией о сообщении с клавиатуры.

Внимание! Внимание!

  • Это сообщение специфичное для FAR manager (начиная с билда 1663) и приходит плагину во время "проигрывания" макрокоманды.


FRSUSERFUNC

главная | типы и определения
Тип FRSUSERFUNC описывает CALLBACK-функцию, вызываемую из функции FSF.FarRecursiveSearch для каждого найденного файла.
typedef int  (WINAPI *FRSUSERFUNC)(
  const WIN32_FIND_DATA *FData,
  const char *FullName,
  void *Param
);

Параметры

FData
Указатель на структуру WIN32_FIND_DATA для очередного найденного файлового объекта.
FullName
Полный путь к найденному файловому объекту.
Param
Указатель на данные пользователя (параметр Param фунции FSF.FarRecursiveSearch).

Возвращаемое значение

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

Замечания

FData и FullName определены только в контексте данной функции, плагин не должен сохранять эти указатели. Для сохранения данных, плагин должен скопировать эти значения в свои стуктуры. Param - те данные, которые плагин передал функции FSF.FarRecursiveSearch.
Смотрите также:
FSF.FarRecursiveSearch


NM

главная | типы и определения
Константа NM определяет размер буфера, содержащего полное имя файла.


ERROR_*

главная | типы и определения
Перечислены типы ошибок, возвращаемые функцией GetLastError , известеные FAR (см. FMSG_ERRORTYPE):

Константа из winerror.h | Строковые константы из Far*.lng
ERROR_INVALID_FUNCTION | "Некорректная функция" "Incorrect function"
ERROR_BAD_COMMAND, ERROR_CALL_NOT_IMPLEMENTED | "Команда не распознана" "Command not recognized"
ERROR_FILE_NOT_FOUND | "Файл не найден" "File not found"
ERROR_PATH_NOT_FOUND | "Путь не найден" "Path not found"
ERROR_TOO_MANY_OPEN_FILES | "Слишком много открытых файлов" "Too many open files"
ERROR_ACCESS_DENIED | "Доступ запрещен" "Access denied"
ERROR_NOT_ENOUGH_MEMORY, ERROR_OUTOFMEMORY | "Недостаточно памяти" "Not enough memory"
ERROR_WRITE_PROTECT | "Попытка записи на защищенный от записи диск" "Cannot write to write protected disk"
ERROR_NOT_READY | "Устройство не готово" "The device is not ready"
ERROR_NOT_DOS_DISK | "Доступ к диску невозможен" "Disk cannot be accessed"
ERROR_SECTOR_NOT_FOUND | "Сектор не найден" "Sector not found"
ERROR_OUT_OF_PAPER | "В принтере нет бумаги" "The printer is out of paper"
ERROR_WRITE_FAULT | "Ошибка записи" "Write fault error"
ERROR_READ_FAULT | "Ошибка чтения" "Read fault error"
ERROR_GEN_FAILURE | "Общая ошибка устройства" "Device general failure"
ERROR_SHARING_VIOLATION, ERROR_LOCK_VIOLATION | "Нарушение совместного доступа к файлу" "File sharing violation"
ERROR_BAD_NETPATH | "Сетевой путь не найден" "The network path was not found"
ERROR_NETWORK_BUSY | "Сеть занята" "The network is busy"
ERROR_NETWORK_ACCESS_DENIED | "Сетевой доступ запрещен" "Network access is denied"
ERROR_NET_WRITE_FAULT | "Ошибка записи в сети" "A write fault occurred on the network"
ERROR_DRIVE_LOCKED | "Диск используется или заблокирован другим процессом" "The disk is in use or locked by another process"
ERROR_ALREADY_EXISTS | "Файл или папка уже существует" "File or folder already exists"
ERROR_BAD_PATHNAME, ERROR_INVALID_NAME | "Указанное имя неверно" "The specified name is invalid"
ERROR_DISK_FULL, ERROR_HANDLE_DISK_FULL | "Нет места на диске" "Insufficient disk space"
ERROR_DIR_NOT_EMPTY | "Папка не пустая" "The folder is not empty"
ERROR_INTERNET_INCORRECT_USER_NAME | "Неверное имя пользователя" "Incorrect user name"
ERROR_INTERNET_INCORRECT_PASSWORD | "Неверный пароль" "Incorrect password"
ERROR_INTERNET_LOGIN_FAILURE | "Ошибка регистрации" "Login failure"
ERROR_INTERNET_CONNECTION_ABORTED | "Соединение разорвано" "Connection aborted"
ERROR_CANCELLED | "Операция отменена" "Operation cancelled"
ERROR_NO_NETWORK | "Сеть отсутствует" "No network present"
ERROR_DEVICE_IN_USE | "Устройство используется и не может быть отсоединено" "Device is in use and cannot be disconnected"
ERROR_OPEN_FILES | "На сетевом диске есть открытые файлы" "This network connection has open files"
ERROR_ALREADY_ASSIGNED | "Имя локального устройства уже использовано" "The local device name is already in use"
ERROR_DEVICE_ALREADY_REMEMBERED | "Имя локального устройства уже находится в профайле пользователя" "The local device is already in the user profile"
ERROR_NOT_LOGGED_ON | "Пользователь не зарегистрирован в сети" "User has not logged on to the network"
ERROR_INVALID_PASSWORD | "Неверный пароль пользователя" "The user password is invalid"
ERROR_NO_RECOVERY_POLICY | "Для этой системы отсутствует политика надежного восстановления шифрования" "There is no valid encryption recovery policy configured for this system"
ERROR_ENCRYPTION_FAILED | "Ошибка при попытке шифрования файла" "The specified file could not be encrypted"
ERROR_DECRYPTION_FAILED | "Ошибка при попытке расшифровки файла" "The specified file could not be decrypted"
ERROR_FILE_NOT_ENCRYPTED | "Указанный файл не зашифрован" "The specified file is not encrypted"
Смотрите также:
Message


TEditorSaveFile

главная | структуры
Структура EditorSaveFile для Delphi.
TEditorSaveFile = packed record
  FileName: packed array[0..Pred(NM)] of char;
  FileEOL: PChar;
end;
PEditorSaveFile = ^TEditorSaveFile;
Смотрите также:


TFarListUpdate

главная | структуры | FarListUpdate
Структура FarListUpdate для Delphi:
TFarListUpdate = packed record
  Index: integer;
  Item: TFarListItem;
end;
PFarListUpdate = ^TFarListUpdate;


TFarStandardFunctions

главная | структуры | FarStandardFunctions
Структура FarStandardFunctions для Delphi:
TFarStandardFunctions = packed record
  StructSize: integer;
  atoi: TFarStdAToI;
  atoi64: TFarStdAToI64;
  itoa: TFarStdIToA;
  itoa64: TFarStdIToA64;

  sprintf: pointer;
  sscanf:  pointer;
  qsort: TFarStdQSort;
  bsearch: TFarStdBSearch;
  qsortex: TFarStdQSortEx;

  Reserved: packed array[0..8] of DWORD;

  LIsLower:    TFarStdLocalIsLower;
  LIsUpper:    TFarStdLocalIsUpper;
  LIsAlpha:    TFarStdLocalIsAlpha;
  LIsAlphanum: TFarStdLocalIsAlphaNum;
  LUpper:      TFarStdLocalUpper;
  LLower:      TFarStdLocalLower;
  LUpperBuf:   TFarStdLocalUpperBuf;
  LLowerBuf:   TFarStdLocalLowerBuf;
  LStrupr:     TFarStdLocalStrUpr;
  LStrlwr:     TFarStdLocalStrLwr;
  LStricmp:    TFarStdLocalStrICmp;
  LStrnicmp:   TFarStdLocalStrNICmp;

  Unquote: TFarStdUnquote;
  ExpandEnvironmentStr: TFarStdExpandEnvironmentStr;
  LTrim: TFarStdLTrim;
  RTrim: TFarStdRTrim;
  Trim: TFarStdTrim;
  TruncStr: TFarStdTruncStr;
  TruncPathStr: TFarStdTruncPathStr;
  QuoteSpaceOnly: TFarStdQuoteSpaceOnly;
  PointToName: TFarStdPointToName;
  GetPathRoot: TFarStdGetPathRoot;
  AddEndSlash: TFarStdAddEndSlash;
  CopyToClipboard: TFarStdCopyToClipboard;
  PasteFromClipboard: TFarStdPasteFromClipboard;
  FarKeyToName: TFarStdKeyToKeyName;
  FarNameToKey: TFarStdKeyNameToKey;
  FarInputRecordToKey: TFarStdInputRecordToKey;
  XLAT: TFarStdXLAT;
  GetFileOwner: TFarStdGetFileOwner;
  GetNumberOfLinks: TFarStdGetNumberOfLinks;
  FarRecurseSearch: TFarRecursiveSearch;
  MkTemp: TFarStdMkTemp;
  DeleteBuffer: TFarStdDeleteBuffer;
  ProcessName: TFarStdProcessName;
  MkLink: TFarStdMkLink;
  ConvertNameToReal: TFarStdConvertNameToReal;
  GetReparsePointInfo: TFarStdGetReparsePointInfo;
end;
PFarStandardFunctions = ^TFarStandardFunctions;

Где:

TFarStdatoi = function(
  S: PChar): integer; stdcall;

TFarStdAToI64 = function(
  S: PChar): int64; stdcall;

TFarStdIToA = function(
  Value: integer;
  Str: PChar;
  Radix: integer): PChar; stdcall;

TFarStdIToA64 = function(
  Value: int64;
  Str: PChar;
  Radix: integer): PChar; stdcall;

  TFarStdQSortFunc = function(
    Param1: pointer;
    Param2: pointer): integer; cdecl;

TFarStdQSort = procedure(
  Base: pointer;
  NElem: size_t;
  Width: size_t;
  fcmp: TFarStdQSortFunc); stdcall;

TFarStdBSearch = procedure(
  Key: pointer;
  Base: pointer;
  NElem: size_t;
  Width: size_t;
  fcmp: TFarStdQSortFunc); stdcall;

TFarStdLocalIsLower = function(
  Ch: integer): integer; stdcall;

TFarStdLocalIsUpper = function(
  Ch: integer): integer; stdcall;

TFarStdLocalIsAlpha = function(
  Ch: integer): integer; stdcall;

TFarStdLocalIsAlphaNum = function(
  Ch: integer): integer; stdcall;

TFarStdLocalUpper = function(
  LowerChar: integer): integer; stdcall;

TFarStdLocalLower = function(
  UpperChar: integer): integer; stdcall;

TFarStdLocalUpperBuf = procedure(
  Buf: PChar;
  Length: integer); stdcall;

TFarStdLocalLowerBuf = procedure(
  Buf: PChar;
  Length: integer); stdcall;

TFarStdLocalStrUpr = procedure(
  s1: PChar); stdcall;

TFarStdLocalStrLwr= procedure(
  s1: PChar); stdcall;

TFarStdLocalStrICmp = function(
  s1: PChar;
  s2: PChar): integer; stdcall;

TFarStdLocalStrNICmp = function(
  s1: PChar;
  s2: PChar;
  n: integer): integer; stdcall;

TFarStdUnquote = procedure(
  Str: PChar); stdcall;

TFarStdExpandEnvironmentStr = function(
  Src: PChar;
  Dst: PChar;
  Size: DWORD): DWORD; stdcall;

TFarStdLTrim = function(
  Str: PChar): PChar; stdcall;

TFarStdRTrim = function(
  Str: PChar): PChar; stdcall;

TFarStdTrim = function(
  Str: PChar): PChar; stdcall;

TFarStdTruncStr = function(
  Str: PChar;
  MaxLength: integer): PChar; stdcall;

TFarStdTruncPathStr = function(
  Str: PChar;
  MaxLength: integer): PChar; stdcall;

TFarStdQuoteSpaceOnly = function(
  Str: PChar): PChar; stdcall;

TFarStdPointToName = function(
  Path: PChar): PChar; stdcall;

TFarStdGetPathRoot = procedure(
  Path: PChar;
  Root: PChar); stdcall;

TFarStdAddEndSlash = function(
  Path: PChar): integer; stdcall;

TFarStdCopyToClipboard = function(
  Data: PChar): integer; stdcall;

TFarStdPasteFromClipboard = function: PChar; stdcall;

TFarStdKeyToKeyName = function(
  Key: integer; KeyName: PChar; Size: integer): BOOL; stdcall;

TFarStdKeyNameToKey = function(
  Name: PChar): integer; stdcall;

TFarStdInputRecordToKey = function(
  var R: INPUT_RECORD): integer; stdcall;

TFarStdXLAT = function(
  Line: PChar;
  StartPos: integer;
  EndPos: integer;
  TableSet: PCharTableSet;
  Flags: DWORD): PChar; stdcall;

TFarStdGetFileOwner = function(
  Computer: PChar;
  Name: PChar;
  Owner: PChar): integer; stdcall;

TFarStdGetNumberOfLinks = function(
  Name: PChar): integer; stdcall;

TFRSFunction = function(
  var FindData: TWin32FindDataEx;
  FullName: PChar): integer; stdcall;

TFarRecursiveSearch = procedure(
  InitDir: PChar;
  Mask: PChar;
  Func: TFRSFunction;
  Flags: DWORD); stdcall;

TFarStdMkTemp = function(
  Dest: PChar;
  Template: PChar): PChar; stdcall;

TFarStdDeleteBuffer = procedure(
  Buffer: PChar); stdcall;

TFarStdProcessName = function(
  Param1: PChar;
  Param2: PChar;
  Flags: DWORD): integer;

TFarStdMkLink = function(
  const Src: PChar;
  const Dest: PChar;
  Flags: DWORD): integer;

TFarStdConvertNameToReal = function(
  const Src: PChar;
  Dest: PChar;
  DestSize: integer): integer;

TFarStdGetReparsePointInfo = function(
  const Src: PChar;
  Dest: PChar;
  DestSize: integer): integer;


Механизмы работы со списками

главная | Dialog API | Элементы диалога
В FAR Manager 1.70 beta 4 работа со списками DI_COMBOBOX и DI_LISTBOX организована по следующей схеме:
  • Запуск Dialog[Ex]
    FarDialogItem.Param.ListItems - только для начальной инициализации.

  • DM_LISTADD
    Добавляет только пункт списка, без ассоциированных данных

  • DM_LISTINSERT
    Вставляет только пункт списка, без ассоциированных данных

  • DM_LISTUPDATE
    Удаляет UserData для обновляемого пункта списка.
    Только обновление данных пункта списка без ассоциированных данных

  • DM_LISTSETDATA
    Перед установкой новых ассоциированных данных предыдущие уничтожаются (если было выделение по памяти)

  • DM_LISTGETDATA
    Возвращается значение, предварительно установленное DM_LISTSETDATA.

  • DM_LISTGETDATASIZE
    Возвращается размер ассоциированных данных.

  • DM_LISTGETITEM
    Возвращает только пункт списка, без ассоциированных данных.

  • DM_GETDLGITEM
    Выставляется переменная FarDialogItem.Param.ListPos.

  • Завершение Dialog[Ex]
    Выставляется переменная FarDialogItem.Param.ListPos
    Ассоциированные данные уничтожаются (если было выделение по памяти)

Смотрите также:
DefDlgProc, DialogEx, SendDlgMessage


События и сообщения Dialog API

главная | Dialog API
Dialog API имеет весьма разнообразный набор событий и сообщений, позволяющий плагину эффективно манипулировать расширенным диалогом.

Смотрите также:


Флаги элементов диалога

главная | Dialog API | Элементы диалога
Поведением и внешним видом управляющих элементов DialogAPI можно управлять посредством флагов. О том, какие флаги на какие элементы воздействуют читайте в описаниях к элементам управления.
 | D I _ B U T T O N | D I _ C H E C K B O X | D I _ C O M B O B O X | D I _ D O U B L E B O X | D I _ E D I T | D I _ F I X E D I T | D I _ L I S T B O X | D I _ P S W E D I T | D I _ R A D I O B U T T O N | D I _ S I N G L E B O X | D I _ T E X T | D I _ U S E R C O N T R O L | D I _ V T E X T
DIF_3STATE |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_BOXCOLOR |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_BTNNOCLOSE |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_CENTERGROUP |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_CENTERTEXT |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_COLORMASK |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_DISABLE |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_DROPDOWNLIST |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_EDITEXPAND |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_EDITOR |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_GROUP |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_HISTORY |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_HIDDEN |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LEFTTEXT |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LISTAUTOHIGHLIGHT |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LISTNOAMPERSAND |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LISTNOBOX |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LISTNOCLOSE |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_LISTWRAPMODE |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_MANUALADDHISTORY |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_MASKEDIT |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_MOVESELECT |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_NOBRACKETS |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_NOFOCUS |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_NOTCVTUSERCONTROL |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_READONLY |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_SELECTONENTRY |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_SEPARATOR |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_SEPARATOR2 |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_SETCOLOR |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_SHOWAMPERSAND |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_USELASTHISTORY |  |  |  |  |  |  |  |  |  |  |  |  |
DIF_VAREDIT |  |  |  |  |  |  |  |  |  |  |  |  |
Смотрите также:


Типы колонок

главная | экспортируемые функции
Допускаются следующие типы колонок:
N - имя файла, допускаются модификаторы (например "NMR"):
M - показывать символы пометки;
O - показывать имена без путей (предназначено в основном для подключаемых модулей);
R - выравнивать имена по правому краю.
S - размер файла.
Для размеров допускаются модификаторы:
C - форматировать размер файла запятыми;
T - использовать 1000 вместо 1024 как делитель, если ширины колонки не хватает для показа полного размера файла.
F - размер файла выводится в стиле Windows Explorer (т.е. 999 байт отображается как 999, а 1000 байт - как 0.97 KB);
E - экономичный режим, между размером и суффиксом пробел не ставится
P - упакованный размер файла.
Для размеров допускаются модификаторы:
C - форматировать размер файла запятыми;
T - использовать 1000 вместо 1024 как делитель, если ширины колонки не хватает для показа полного размера файла.
F - размер файла выводится в стиле Windows Explorer (т.е. 999 байт отображается как 999, а 1000 байт - как 0.97 KB);
E - экономичный режим, между размером и суффиксом пробел не ставится
D - дата модификации файла
T - время модификации файла
DM - дата и время модификации файла
Допускаются модификаторы:
B - краткий (в стиле Unix) формат времени файла;
M - использование текстовых имен месяцев;
DC - дата и время создания файла
Допускаются модификаторы:
B - краткий (в стиле Unix) формат времени файла;
M - использование текстовых имен месяцев;
DA - дата и время последнего доступа к файлу
Допускаются модификаторы:
B - краткий (в стиле Unix) формат времени файла;
M - использование текстовых имен месяцев;
A - атрибуты файла
Z - описание файла
O - владелец файла
LN - количество жестких связей
C0..C9 - пользовательские типы колонок.
Если описание типов колонок содержит более одной колонки имени файла, панель файлов будет отображаться в многоколоночной форме.
Смотрите также:
PanelMode


Inside FAR Manager

главная

Under construction.


"Редактор" (Edit/F4)

содержание
Когда пользователь нажимает F4 на файле, то FAR выполняет следующие действия:

Панель плагина

Выполняется, если плагин при вызове GetOpenPluginInfo заполнил поле HostFile структуры OpenPluginInfo:
  • FAR создает TEMP-каталог.
  • Вызывается GetFiles с параметрами: один элемент PanelItem с требуемым файлом, ItemsNumber=1, DestPath=путь к TEMP-каталогу (без заключительного '\'), OpMode=OPM_SILENT|OPM_EDIT; плагин по указанному пути "выкладывает" требуемый файл и отдает управление FAR. Плагин должен в указанный временный каталог "выложить" файл без подкаталогов.
  • FAR открывает файл из TEMP-каталога в редакторе.
  • После выхода из редактора, если файл был модифицирован, вызывается PutFiles с параметрами: один элемент PanelItem с требуемым файлом, ItemsNumber=1, Move=0, OpMode=OPM_EDIT. Плагин "забирает" файл из временного каталога на свою панель.
  • FAR удаляет временный файл с временным каталогом и обновляет панели.


Алгоритмы работы FAR Manager

содержание
  • "Архивировать" (Add to archive/Shift-F1)
  • "Распаковать" (Extract files/Shift-F2)
  • "Архивные команды" (Archive commands/Shift-F3)
  • "Редактор" (Edit/F4)


"Архивировать" (Add to archive/Shift-F1)

содержание

Когда пользователь нажимает Shift-F1 на файле (группе выделенных файлов), то FAR выполняет следующие действия.

Обычная панель

  • проходит по списку плагинов, поочередно вызывая OpenFilePlugin(NULL,NULL,0) до тех пор, пока один из плагинов не вернет значение, отличное от INVALID_HANDLE_VALUE или -2;
  • FAR формирует временный список выделенных файлов и передает их плагину, вызвав функцию PutFiles(hPlugin,PanelItems,ItemsCount,0,0);
  • если плагин удачно обработал указанные файлы (PutFiles вернул 1 или 2), то FAR сбрасывает выделение с указанных файлов, пытается обновить описания файлов (если плагин при вызове GetOpenPluginInfo укажет OpenPluginInfo.DescrFilesNumber > 0), удаляет временный список, перерисовывает панель и производит позиционирование на созданный/обновленный плагином файл (для случая, если PutFiles вернул 1).

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

Панель плагина

FAR не обрабатывает.


"Распаковать" (Extract files/Shift-F2)

содержание

Когда пользователь нажимает Shift-F2 на файле (группе выделенных файлов), то FAR для каждого из выделенных файлов выполняет следующие действия.

Обычная панель

  • открывает файл, пытается считать максимум 0x20000 байт данных, закрывает файл;
  • проходит по списку плагинов, поочередно вызывая функцию OpenFilePlugin;
  • вызывает GetFindData для того плагина, который первым сказал, что данные его (вернул из OpenFilePlugin значение, отличное от INVALID_HANDLE_VALUE и -2; для значения -2 цикл опроса плагинов прекращается);
  • вызывает GetFiles (для первого обрабатываемого файлы OpMode=OPM_TOPLEVEL, для последующих обрабатываемых файлов добавляется флаг OPM_SILENT), в это время, например, MultiArc показывает диалог "Extract";
  • после успешной отработки функции GetFiles FAR сбрасывает выделения, вызывает функцию FreeFindData для того, чтобы плагин освободил память, выделенную функцией GetFindData.
  • закрывает плагин, вызывая функцию ClosePlugin.

Панель плагина

если плагин при вызове GetOpenPluginInfo заполнил поле HostFile структуры OpenPluginInfo, то действия аналогичны действиям, когда пользователь нажимает F5.


"Архивные команды" (Archive commands/Shift-F3)

содержание

Когда пользователь нажимает Shift-F3 на файле (группе выделенных файлов), то FAR для каждого из выделенных файлов выполняет следующие действия:

Обычная панель

  • открывает файл, пытается считать максимум 0x20000 байт данных, закрывает файл;
  • проходит по списку плагинов, поочередно вызывая функцию OpenFilePlugin;
  • вызывает GetFindData для того плагина, который первым сказал, что данные его (вернул из OpenFilePlugin значение, отличное от INVALID_HANDLE_VALUE и -2; для значения -2 цикл опроса плагинов прекращается);
  • вызывает ProcessHostFile с параметром OpMode равным OPM_TOPLEVEL (если плагин возвращает из функции GetFindData значение TRUE);
  • вызывает функцию FreeFindData для того, чтобы плагин освободил память, выделенную функцией GetFindData.
  • закрывает плагин, вызывая функцию ClosePlugin.

Панель плагина

Выполняется, если плагин при вызове GetOpenPluginInfo заполнил поле HostFile структуры OpenPluginInfo:
  • подготавливает массив структур PluginPanelItem;
  • вызывает ProcessHostFile с параметром OpMode равным 0;
  • если ProcessHostFile возвращает TRUE, то ставится пометка, что HostFile модифицирован (для того, что впоследствии вызвать DeleteFiles или PutFiles);
  • освобождает память, отведенную под массив структур PluginPanelItem.


Константы - Макросы

Константы

главная | Макросы | Макроязык
Константы позволяют вам задавать имена значениям и обращаться к ним позже.

Именование

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

  1. Имя начинается с буквы латинского алфавита, дальше в произвольном порядке идут буквы латинского алфавита, цифры и символ '_'.
  2. Имя константы не должно совпадать с предопределенными булевыми состояниями, именами макрофункций, именами клавиш и прочими макросостояниями.

Типы

Константы могут быть двух типов - целое число или строка.

Целочисленные константы: NNN - 10-ричная константа, 0NNN - 8-ричная константа, 0xNNN - 16-ричная константа.

Целочисленные константы 64-разрядные.

Область действия

Область действия констант - текущий сеанс FAR.

Представления в реестре

В реестре константы располагаются в специальной ветке [HKEY_CURRENT_USER\Software\Far\[Users\USERNAME\]KeyMacros\Consts].

Каждая константа имеет имя и может быть трех типов REG_SZ (для строковых констант) и REG_DWORD или REG_QDWORD (для целочисленных констант).

Замечания

  1. Элементы макроязыка невозможно использовать во время записи макроса стандартным образом. Добавить элементы языка в макрос можно только путем ручной правки реестра или путем применения специальных программ/плагинов.

Пример

Пример применения константы FIB_PASSWORD (0x00000002) для функции prompt
REGEDIT

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Consts]
"FIB_PASSWORD"=dword:00000002

[HKEY_CURRENT_USER\Software\Far\KeyMacros\Editor\CtrlP]
"Sequence"="%s=prompt(\"Password\",\"Input password:\",FIB_PASSWORD); $Text %s"
"DisableOutput"=dword:00000001
Смотрите также:


EditorSaveFile

главная | структуры
Структура EditorSaveFile используется в функции EditorControl для сохранения редактируемого файла (команда ECTL_SAVEFILE).
struct EditorSaveFile
{
  char FileName[NM];
  char *FileEOL;
};

Элементы

FileName
Здесь вы можете определить новое имя для сохраняемого файла. Имейте в виду, что здесь должен быть полный путь к файлу (включая директории). Если вы не желаете изменять имя редактируемого файла, то установите первый байт поля FileName равным нулю.
FileEOL
Последовательность, обозначающая конец строки. Может быть NULL (оставить исходную EOL-последовательность), \r\n или \n
Смотрите также: