Информационный сервер для программистов: Исходники со всего света. Паскальные исходники со всего света
  Powered by Поисковый сервер Яndex: Найдется ВСЁ!
На Главную Pascal Форум Информер Страны мира  
   Турбо Вижн    >>    tv_answ
   
 
 Ряд соображений о Turbo Vision   Виктор Вагнер 17.05.1993

О русификации, Строке Меню и Status Line



3k 
 

Ответы на кое-какие вопросы о Turbo Vision Во-первых, о русификации Turbo Vision. С этим надо быть осторожнее, а то будет как было с Paradox 4.0, русифицированная версия которого несовместима с английской по скриптам, так как требует, чтобы все позиции меню указывались по-русски. Если уж вы делаете что-то такое, то позаботьтесь о том, чтобы горячие клавиши работали независимо от режима клавиатуры. Самый простой способ - поступить как в программе BML, известной всем пользователям Релкома - в начале каждой позиции меню писать латинскую букву:'~M~ - Письмо' или что-нибудь в этом роде. После этого потребуется лишь немного изменить HanleEvent от TMenuBar и TMenuBox, поставив перед вызовом унаследованного HandleEvent такую операцию: if (Event.What=evKeyDown)and(Event.CharCode>=#80 {Русское А}) then Event.CharCode=GetAltChar(Event.ScanCode*256); (GetAltChar - стандартная функция TurboVision, и если вы хотите, чтобы горячей клавишей была русская буква, менять придется именно ее, что нетривиально, ибо она должна возвращать либо русскую, либо латинскую букву в зависимости непонятно от чего). Переписать GetAltCode намного проще, хотя и для этого придется лезть в исходный текст модуля Drivers, но этого мало. Придется также изменить обработку горячих клавиш в объекте TMenuView, т.к. она сделана через GetAltChar, а не GetAltCode. Вообще, если действовать достаточно аккуратно, то это можно сделать и без изменения ядра Turbo Vision - унаследовать объекты TMenuBar и TMenuBox и переписать обоим HandleEvent начисто, а заодно и метод, создающий подменю. Не помню, как он называется, но было дело - переписывал, правда, с совершенно другими целями. Переписывать этот метод надо для того, чтобы при открытии подменю создавался объект вашего типа, а не стандартный TMenuBox. Во-вторых, изменение строки меню. Для того, чтобы сделать это не нужны ни исходные тексты Turbo Vision, ни даже родная документация - вся необходимая информация есть в On-line help. Поскольку пример достаточно компактен, привожу его полностью: {$B-} Function FindMenuItem(Mnu:PMenu,Command:Word):PMenuItem; { Поиск позиции меню, содержащей в поле Command заданный код команды. В качестве первого параметра получает значение поля Menu объекта- наследника TMenuView или поля SubMenu записи TMenuItem Возвращает указатель на позицию меню или nil, если такой позиции нет } var P,Q:PMenuItem; begin P:=Mnu^.Items; While (P<>nil) and (P^.Command<>Command) do if P^.Command=0 {Позиция имеет субменю} then begin Q:=FindMenuItem(P^.Submenu); if Q<>nil then P=Q else P:=P^.Next; end else P:=P^.Next; FindMenuItem:=P; end; Procedure SetMenuParam(Command:Word;AParam:String); { Меняет текст, содержащийся в поле Param позиции меню Заданной кодом команды. Turbo Pascal IDE делает с позициями Complie/Destignation и Complie/Primary File то же самое } var P:PMenuItem; begin P:=FindMenuItem(MenuBar^.Menu,Command); {$IFOPT R+} if P=nil then RunError (213); {$ENDIF} if P^.Param<>nil then DisposeStr(P^.PAram); P^.Param:=NewSTR(AParam); end; Для тех, кто не пользуется файлом ресурсов, можно предложить более простой способ - запомнить указатель на нужную позицию меню непосредственно в процессе его создания: Var PrimaryMenuItem,DestignationMenuItem:PMenuItem; Procedure TIDEApp.InitMenuBar; var R:TRect; begin GetExtent(R); R.B.X:=R.A.X+1; PrimaryMenuItem:=NewItem('~P~rimary file','...',kbNoKey, cmPrimary,hcPrimary,nil); DestignationMenuItem:=NewItem('~D~estignation','Memory',kbNoKey, cmDestignation,hcDeatignation, PrimaryMenuItem); MenuBar:=New(PMenuBar,Init(R,NewMenu( ... NewSubMenu('~C~ompile',hcCompile,NewMenu( ... NewItem('~B~uild','',kbNoKey,cmBuild,hcBuild, DestignationMenuItem)...), ... end; После этого смена текста в позиции меню делается так: DisposeStr(PrimaryMenuItem^.Param); PrimaryMenuItem^.Param:=NewStr(PrimaryFileName); В-третьих, специально для любителей видеть в Status Line имя текущего файла , координаты и другую полезную информацию. Для этого в TStatusLine существует специальный метод Hint, возвражающий строку, которая будет выведена после всех горячих клавиш, отделенная от них вертикальной чертой. Если вы присматривались, IDE пишет имя файла именно там. Наиболее общий способ, который я придумал для этой цели выглядит так: Заведите у себя в программе TStringList, содержащий требуемые строки для всех HelpCtx , встречающихся у вас. Вставьте в некоторые из них спецификаторы формата для функции FormatStr, напиример %-13S для имени файла. Заведите глобальную переменную HintParams:Pointer, в которую любой объект, желающий поместить в StatusLine дополнительную информацию, ,будет записывать адрес требуемых параметров. (Естественно, строка в TStringList, соответствующая HelpCtx этого объекта должна содержать соответствующие спецификаторы. Функция Hint должна выглядеть так: Function TMyStatusLine.Hint(AHelpCtx:Word):String; var S:String; begin S:=HintStrList^.Get(AHelpCtx); Hint:=FormatStr(S,HintParams); end; Учтите, только, что смена изображения в StatusLine происходит при вызове StatusLine^.Update, которая вызывается из Idle. Поэтому, если вам нужно изменить StatusLine из операции сохранения файла или чегонибудь в этом роде, то необходимо вызвать StatusLine^.Update непосредственно, так как иначе изменение HelpCtx не скажется на внешнем виде StatusLine до тех пор, пока программа не начнет ожидать ввод с клавиатуры, а тогда будет поздно. Это может выглядить так: Procedure MyEditor.SaveFile; begin HelpCtx:=hcSaving; HintParams:=@FileName; StatusLine^.Update; TFileEditor.SaveFile; HelpCtx:=hcMyEditor; {Второй раз вызывать Update не надо, т.к. после окончания записи программа начнет ждать ввода с клавиатуры и вызовет Idle} end; Если вы решитесь воспользоваться этим методом, внимательно ознакомьтесь с описанием процедуры FormatStr, чтобы быть уверенным, что вы не предлагаете ей данные тогда, когда она ожидает указатель на них и наоборот. B.Б.Вагнер тел 135-46-61 E-Mail: vitus@agropc.msk.su