wviews.pas 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$I globdir.inc}
  12. unit WViews;
  13. interface
  14. uses Objects,Drivers,Views,Menus,Dialogs;
  15. const
  16. evIdle = $8000;
  17. cmLocalMenu = 54100;
  18. cmUpdate = 54101;
  19. cmListFocusChanged = 54102;
  20. mfUserBtn1 = $00010000;
  21. mfUserBtn2 = $00020000;
  22. mfUserBtn3 = $00040000;
  23. mfUserBtn4 = $00080000;
  24. mfCantCancel = $00100000;
  25. cmUserBtn1 = $fee0;
  26. cmUserBtn2 = $fee1;
  27. cmUserBtn3 = $fee2;
  28. cmUserBtn4 = $fee3;
  29. CPlainCluster = #7#8#9#9;
  30. type
  31. longstring = {$ifdef TP}string{$else}ansistring{$endif};
  32. PCenterDialog = ^TCenterDialog;
  33. TCenterDialog = object(TDialog)
  34. constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  35. end;
  36. PAdvancedMenuBox = ^TAdvancedMenuBox;
  37. TAdvancedMenuBox = object(TMenuBox)
  38. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  39. AParentMenu: PMenuView): PMenuView; virtual;
  40. function Execute: Word; virtual;
  41. end;
  42. PAdvancedMenuPopUp = ^TAdvancedMenuPopup;
  43. TAdvancedMenuPopUp = object(TMenuPopup)
  44. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  45. AParentMenu: PMenuView): PMenuView; virtual;
  46. function Execute: Word; virtual;
  47. end;
  48. PAdvancedMenuBar = ^TAdvancedMenuBar;
  49. TAdvancedMenuBar = object(TMenuBar)
  50. constructor Init(var Bounds: TRect; AMenu: PMenu);
  51. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  52. AParentMenu: PMenuView): PMenuView; virtual;
  53. procedure Update; virtual;
  54. function GetMenuItem(cm : word) : PMenuItem;
  55. procedure HandleEvent(var Event: TEvent); virtual;
  56. function Execute: Word; virtual;
  57. end;
  58. PAdvancedStaticText = ^TAdvancedStaticText;
  59. TAdvancedStaticText = object(TStaticText)
  60. procedure SetText(S: string); virtual;
  61. end;
  62. PAdvancedListBox = ^TAdvancedListBox;
  63. TAdvancedListBox = object(TListBox)
  64. Default: boolean;
  65. procedure FocusItem(Item: sw_integer); virtual;
  66. procedure HandleEvent(var Event: TEvent); virtual;
  67. constructor Load(var S: TStream);
  68. procedure Store(var S: TStream);
  69. end;
  70. PNoUpdateButton = ^TNoUpdateButton;
  71. TNoUpdateButton = object(TButton)
  72. procedure HandleEvent(var Event: TEvent); virtual;
  73. end;
  74. TLocalMenuListBox = object(TAdvancedListBox)
  75. procedure HandleEvent(var Event: TEvent); virtual;
  76. procedure LocalMenu(P: TPoint); virtual;
  77. function GetLocalMenu: PMenu; virtual;
  78. function GetCommandTarget: PView; virtual;
  79. private
  80. LastLocalCmd: word;
  81. end;
  82. PColorStaticText = ^TColorStaticText;
  83. TColorStaticText = object(TAdvancedStaticText)
  84. Color: word;
  85. DontWrap: boolean;
  86. Delta: TPoint;
  87. constructor Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
  88. function GetPalette: PPalette; virtual;
  89. procedure Draw; virtual;
  90. constructor Load(var S: TStream);
  91. procedure Store(var S: TStream);
  92. end;
  93. PHSListBox = ^THSListBox;
  94. THSListBox = object(TLocalMenuListBox)
  95. constructor Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
  96. function SaveToFile(const AFileName: string): boolean; virtual;
  97. function SaveAs: Boolean; virtual;
  98. end;
  99. PDlgWindow = ^TDlgWindow;
  100. TDlgWindow = object(TDialog)
  101. constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
  102. end;
  103. PAdvancedStatusLine = ^TAdvancedStatusLine;
  104. TAdvancedStatusLine = object(TStatusLine)
  105. StatusText: PString;
  106. function GetStatusText: string; virtual;
  107. procedure SetStatusText(const S: string); virtual;
  108. procedure ClearStatusText; virtual;
  109. procedure Draw; virtual;
  110. end;
  111. PDropDownListBox = ^TDropDownListBox;
  112. PDDHelperLB = ^TDDHelperLB;
  113. TDDHelperLB = object(TLocalMenuListBox)
  114. constructor Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
  115. procedure HandleEvent(var Event: TEvent); virtual;
  116. procedure SetState(AState: Word; Enable: Boolean); virtual;
  117. procedure SelectItem(Item: Sw_Integer); virtual;
  118. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  119. function GetLocalMenu: PMenu; virtual;
  120. function GetCommandTarget: PView; virtual;
  121. private
  122. Link : PDropDownListBox;
  123. LastTT: longint;
  124. InClose: boolean;
  125. end;
  126. TDropDownListBox = object(TView)
  127. Text: string;
  128. Focused: sw_integer;
  129. List: PCollection;
  130. constructor Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
  131. procedure HandleEvent(var Event: TEvent); virtual;
  132. function GetText(Item: pointer; MaxLen: sw_integer): string; virtual;
  133. procedure NewList(AList: PCollection); virtual;
  134. procedure CreateListBox(var R: TRect);
  135. procedure DropList(Drop: boolean); virtual;
  136. function GetItemCount: sw_integer; virtual;
  137. procedure FocusItem(Item: sw_integer); virtual;
  138. function LBGetLocalMenu: PMenu; virtual;
  139. function LBGetCommandTarget: PView; virtual;
  140. procedure SetState(AState: Word; Enable: Boolean); virtual;
  141. procedure Draw; virtual;
  142. function GetPalette: PPalette; virtual;
  143. destructor Done; virtual;
  144. private
  145. DropLineCount: Sw_integer;
  146. ListDropped : boolean;
  147. ListBox : PDDHelperLB;
  148. SB : PScrollBar;
  149. end;
  150. PGroupView = ^TGroupView;
  151. TGroupView = object(TLabel)
  152. constructor Init(var Bounds: TRect; AText: String; ALink: PView);
  153. procedure Draw; virtual;
  154. end;
  155. PPlainCheckBoxes = ^TPlainCheckBoxes;
  156. TPlainCheckBoxes = object(TCheckBoxes)
  157. function GetPalette: PPalette; virtual;
  158. end;
  159. PPlainRadioButtons = ^TPlainRadioButtons;
  160. TPlainRadioButtons = object(TRadioButtons)
  161. function GetPalette: PPalette; virtual;
  162. end;
  163. PPanel = ^TPanel;
  164. TPanel = object(TGroup)
  165. constructor Init(var Bounds: TRect);
  166. end;
  167. PAdvMessageBox = ^TAdvMessageBox;
  168. TAdvMessageBox = object(TDialog)
  169. CanCancel: boolean;
  170. procedure HandleEvent(var Event: TEvent); virtual;
  171. end;
  172. procedure InsertOK(ADialog: PDialog);
  173. procedure InsertButtons(ADialog: PDialog);
  174. procedure Bug(const S: string; Params: pointer);
  175. procedure ErrorBox(const S: string; Params: pointer);
  176. procedure WarningBox(const S: string; Params: pointer);
  177. procedure InformationBox(const S: string; Params: pointer);
  178. function OKCancelBox(const S: string; Params: pointer): word;
  179. function ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
  180. function ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
  181. procedure ShowMessage(Msg: string);
  182. procedure HideMessage;
  183. function SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
  184. procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
  185. function IsSubMenu(P: PMenuItem): boolean;
  186. function IsSeparator(P: PMenuItem): boolean;
  187. function UpdateMenu(M: PMenu): boolean;
  188. function SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
  189. procedure AppendMenuItem(M: PMenu; I: PMenuItem);
  190. procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
  191. function GetMenuItemBefore(Menu:PMenu; BeforeOf: PMenuItem): PMenuItem;
  192. procedure NotImplemented;
  193. function ColorIndex(Color: byte): word;
  194. var FormatParams : array[1..20] of longint;
  195. FormatParamCount : integer;
  196. FormatParamStrs : array[1..10] of string;
  197. FormatParamStrCount: integer;
  198. procedure ClearFormatParams;
  199. procedure AddFormatParam(P: pointer);
  200. procedure AddFormatParamInt(L: longint);
  201. procedure AddFormatParamChar(C: char);
  202. procedure AddFormatParamStr(const S: string);
  203. function FormatStrF(const Format: string; var Params): string;
  204. function FormatStrStr(const Format, Param: string): string;
  205. function FormatStrStr2(const Format, Param1,Param2: string): string;
  206. function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
  207. function FormatStrInt(const Format: string; L: longint): string;
  208. const UserButtonName : array[1..4] of string[40] = ('User~1~','User~2~','User~3~','User~4~');
  209. procedure InitAdvMsgBox;
  210. function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
  211. function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
  212. procedure DoneAdvMsgBox;
  213. procedure RegisterWViews;
  214. implementation
  215. uses Mouse,
  216. Resource,
  217. {$ifdef FVISION}
  218. FVConsts,
  219. {$else}
  220. Commands,
  221. {$endif}
  222. App,MsgBox,StdDlg,
  223. WConsts,WUtils;
  224. {$ifndef NOOBJREG}
  225. const
  226. RAdvancedListBox: TStreamRec = (
  227. ObjType: 1120;
  228. VmtLink: Ofs(TypeOf(TAdvancedListBox)^);
  229. Load: @TAdvancedListBox.Load;
  230. Store: @TAdvancedListBox.Store
  231. );
  232. RColorStaticText: TStreamRec = (
  233. ObjType: 1121;
  234. VmtLink: Ofs(TypeOf(TColorStaticText)^);
  235. Load: @TColorStaticText.Load;
  236. Store: @TColorStaticText.Store
  237. );
  238. RHSListBox: TStreamRec = (
  239. ObjType: 1122;
  240. VmtLink: Ofs(TypeOf(THSListBox)^);
  241. Load: @THSListBox.Load;
  242. Store: @THSListBox.Store
  243. );
  244. RDlgWindow: TStreamRec = (
  245. ObjType: 1123;
  246. VmtLink: Ofs(TypeOf(TDlgWindow)^);
  247. Load: @TDlgWindow.Load;
  248. Store: @TDlgWindow.Store
  249. );
  250. {$endif}
  251. const
  252. MessageDialog : PCenterDialog = nil;
  253. UserButtonCmd : array[Low(UserButtonName)..High(UserButtonName)] of word = (cmUserBtn1,cmUserBtn2,cmUserBtn3,cmUserBtn4);
  254. function ColorIndex(Color: byte): word;
  255. begin
  256. ColorIndex:=(Color and $0f)+(Color and $0f) shl 4;
  257. end;
  258. {*****************************************************************************
  259. TCenterDialog
  260. *****************************************************************************}
  261. constructor TCenterDialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  262. begin
  263. inherited Init(Bounds,ATitle);
  264. Options:=Options or ofCentered;
  265. end;
  266. function TAdvancedMenuBox.NewSubView(var Bounds: TRect; AMenu: PMenu;
  267. AParentMenu: PMenuView): PMenuView;
  268. begin
  269. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  270. end;
  271. function TAdvancedMenuBox.Execute: word;
  272. type
  273. MenuAction = (DoNothing, DoSelect, DoReturn);
  274. var
  275. AutoSelect: Boolean;
  276. Action: MenuAction;
  277. Ch: Char;
  278. Result: Word;
  279. ItemShown, P: PMenuItem;
  280. Target: PMenuView;
  281. R: TRect;
  282. E: TEvent;
  283. MouseActive: Boolean;
  284. function IsDisabled(Item: PMenuItem): boolean;
  285. var Found: boolean;
  286. begin
  287. Found:=Item^.Disabled or IsSeparator(Item);
  288. if (Found=false) and (IsSubMenu(Item)=false) then
  289. Found:=CommandEnabled(Item^.Command)=false;
  290. IsDisabled:=Found;
  291. end;
  292. procedure TrackMouse;
  293. var
  294. Mouse: TPoint;
  295. R: TRect;
  296. begin
  297. MakeLocal(E.Where, Mouse);
  298. Current := Menu^.Items;
  299. while Current <> nil do
  300. begin
  301. GetItemRect(Current, R);
  302. if R.Contains(Mouse) then
  303. begin
  304. MouseActive := True;
  305. Break;
  306. end;
  307. Current := Current^.Next;
  308. end;
  309. if (Current<>nil) and IsDisabled(Current) then
  310. begin
  311. Current:=nil;
  312. MouseActive:=false;
  313. end;
  314. end;
  315. procedure TrackKey(FindNext: Boolean);
  316. procedure NextItem;
  317. begin
  318. Current := Current^.Next;
  319. if Current = nil then Current := Menu^.Items;
  320. end;
  321. procedure PrevItem;
  322. var
  323. P: PMenuItem;
  324. begin
  325. P := Current;
  326. if P = Menu^.Items then P := nil;
  327. repeat NextItem until Current^.Next = P;
  328. end;
  329. begin
  330. if Current <> nil then
  331. repeat
  332. if FindNext then NextItem else PrevItem;
  333. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  334. end;
  335. function MouseInOwner: Boolean;
  336. var
  337. Mouse: TPoint;
  338. R: TRect;
  339. begin
  340. MouseInOwner := False;
  341. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  342. begin
  343. ParentMenu^.MakeLocal(E.Where, Mouse);
  344. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  345. MouseInOwner := R.Contains(Mouse);
  346. end;
  347. end;
  348. function MouseInMenus: Boolean;
  349. var
  350. P: PMenuView;
  351. begin
  352. P := ParentMenu;
  353. while (P <> nil) and (P^.MouseInView(E.Where)=false) do
  354. P := P^.ParentMenu;
  355. MouseInMenus := P <> nil;
  356. end;
  357. function TopMenu: PMenuView;
  358. var
  359. P: PMenuView;
  360. begin
  361. P := @Self;
  362. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  363. TopMenu := P;
  364. end;
  365. begin
  366. AutoSelect := False; E.What:=evNothing;
  367. Result := 0;
  368. ItemShown := nil;
  369. Current := Menu^.Default;
  370. MouseActive := False;
  371. if UpdateMenu(Menu) then
  372. begin
  373. if Current<>nil then
  374. if Current^.Disabled then
  375. TrackKey(true);
  376. repeat
  377. Action := DoNothing;
  378. GetEvent(E);
  379. case E.What of
  380. evMouseDown:
  381. if MouseInView(E.Where) or MouseInOwner then
  382. begin
  383. TrackMouse;
  384. if Size.Y = 1 then AutoSelect := True;
  385. end else Action := DoReturn;
  386. evMouseUp:
  387. begin
  388. TrackMouse;
  389. if MouseInOwner then
  390. Current := Menu^.Default
  391. else
  392. if (Current <> nil) and (Current^.Name <> nil) then
  393. Action := DoSelect
  394. else
  395. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  396. else
  397. begin
  398. Current := Menu^.Default;
  399. if Current = nil then Current := Menu^.Items;
  400. Action := DoNothing;
  401. end;
  402. end;
  403. evMouseMove:
  404. if E.Buttons <> 0 then
  405. begin
  406. TrackMouse;
  407. if not (MouseInView(E.Where) or MouseInOwner) and
  408. MouseInMenus then Action := DoReturn;
  409. end;
  410. evKeyDown:
  411. case CtrlToArrow(E.KeyCode) of
  412. kbUp, kbDown:
  413. if Size.Y <> 1 then
  414. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  415. if E.KeyCode = kbDown then AutoSelect := True;
  416. kbLeft, kbRight:
  417. if ParentMenu = nil then
  418. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  419. Action := DoReturn;
  420. kbHome, kbEnd:
  421. if Size.Y <> 1 then
  422. begin
  423. Current := Menu^.Items;
  424. if E.KeyCode = kbEnd then TrackKey(False);
  425. end;
  426. kbEnter:
  427. begin
  428. if Size.Y = 1 then AutoSelect := True;
  429. Action := DoSelect;
  430. end;
  431. kbEsc:
  432. begin
  433. Action := DoReturn;
  434. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  435. ClearEvent(E);
  436. end;
  437. else
  438. Target := @Self;
  439. Ch := GetAltChar(E.KeyCode);
  440. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  441. P := Target^.FindItem(Ch);
  442. if P = nil then
  443. begin
  444. P := TopMenu^.HotKey(E.KeyCode);
  445. if (P <> nil) and CommandEnabled(P^.Command) then
  446. begin
  447. Result := P^.Command;
  448. Action := DoReturn;
  449. end
  450. end else
  451. if Target = @Self then
  452. begin
  453. if Size.Y = 1 then AutoSelect := True;
  454. Action := DoSelect;
  455. Current := P;
  456. end else
  457. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  458. Action := DoReturn;
  459. end;
  460. evCommand:
  461. if E.Command = cmMenu then
  462. begin
  463. AutoSelect := False;
  464. if ParentMenu <> nil then Action := DoReturn;
  465. end else Action := DoReturn;
  466. end;
  467. if ItemShown <> Current then
  468. begin
  469. ItemShown := Current;
  470. DrawView;
  471. end;
  472. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  473. if Current <> nil then with Current^ do if Name <> nil then
  474. if Command = 0 then
  475. begin
  476. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  477. GetItemRect(Current, R);
  478. R.A.X := R.A.X + Origin.X;
  479. R.A.Y := R.B.Y + Origin.Y;
  480. R.B := Owner^.Size;
  481. if Size.Y = 1 then Dec(R.A.X);
  482. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  483. Result := Owner^.ExecView(Target);
  484. Dispose(Target, Done);
  485. end else if Action = DoSelect then Result := Command;
  486. if (Result <> 0) and CommandEnabled(Result) then
  487. begin
  488. Action := DoReturn;
  489. ClearEvent(E);
  490. end
  491. else
  492. Result := 0;
  493. until Action = DoReturn;
  494. end;
  495. if E.What <> evNothing then
  496. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  497. if Current <> nil then
  498. begin
  499. Menu^.Default := Current;
  500. Current := nil;
  501. DrawView;
  502. end;
  503. Execute := Result;
  504. end;
  505. function TAdvancedMenuPopup.NewSubView(var Bounds: TRect; AMenu: PMenu;
  506. AParentMenu: PMenuView): PMenuView;
  507. begin
  508. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  509. end;
  510. function TAdvancedMenuPopup.Execute: word;
  511. type
  512. MenuAction = (DoNothing, DoSelect, DoReturn);
  513. var
  514. AutoSelect: Boolean;
  515. Action: MenuAction;
  516. Ch: Char;
  517. Result: Word;
  518. ItemShown, P: PMenuItem;
  519. Target: PMenuView;
  520. R: TRect;
  521. E: TEvent;
  522. MouseActive: Boolean;
  523. function IsDisabled(Item: PMenuItem): boolean;
  524. var Found: boolean;
  525. begin
  526. Found:=Item^.Disabled or IsSeparator(Item);
  527. if (Found=false) and (IsSubMenu(Item)=false) then
  528. Found:=CommandEnabled(Item^.Command)=false;
  529. IsDisabled:=Found;
  530. end;
  531. procedure TrackMouse;
  532. var
  533. Mouse: TPoint;
  534. R: TRect;
  535. { OldC: PMenuItem;}
  536. begin
  537. MakeLocal(E.Where, Mouse);
  538. { OldC:=Current;}
  539. Current := Menu^.Items;
  540. while Current <> nil do
  541. begin
  542. GetItemRect(Current, R);
  543. if R.Contains(Mouse) then
  544. begin
  545. MouseActive := True;
  546. Break;
  547. end;
  548. Current := Current^.Next;
  549. end;
  550. if (Current<>nil) and IsDisabled(Current) then
  551. begin
  552. Current:={OldC}nil;
  553. MouseActive:=false;
  554. end;
  555. end;
  556. procedure TrackKey(FindNext: Boolean);
  557. procedure NextItem;
  558. begin
  559. Current := Current^.Next;
  560. if Current = nil then Current := Menu^.Items;
  561. end;
  562. procedure PrevItem;
  563. var
  564. P: PMenuItem;
  565. begin
  566. P := Current;
  567. if P = Menu^.Items then P := nil;
  568. repeat NextItem until Current^.Next = P;
  569. end;
  570. begin
  571. if Current <> nil then
  572. repeat
  573. if FindNext then NextItem else PrevItem;
  574. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  575. end;
  576. function MouseInOwner: Boolean;
  577. var
  578. Mouse: TPoint;
  579. R: TRect;
  580. begin
  581. MouseInOwner := False;
  582. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  583. begin
  584. ParentMenu^.MakeLocal(E.Where, Mouse);
  585. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  586. MouseInOwner := R.Contains(Mouse);
  587. end;
  588. end;
  589. function MouseInMenus: Boolean;
  590. var
  591. P: PMenuView;
  592. begin
  593. P := ParentMenu;
  594. while (P <> nil) and (P^.MouseInView(E.Where)=false) do
  595. P := P^.ParentMenu;
  596. MouseInMenus := P <> nil;
  597. end;
  598. function TopMenu: PMenuView;
  599. var
  600. P: PMenuView;
  601. begin
  602. P := @Self;
  603. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  604. TopMenu := P;
  605. end;
  606. begin
  607. AutoSelect := False; E.What:=evNothing;
  608. Result := 0;
  609. ItemShown := nil;
  610. Current := Menu^.Default;
  611. MouseActive := False;
  612. if UpdateMenu(Menu) then
  613. begin
  614. if Current<>nil then
  615. if Current^.Disabled then
  616. TrackKey(true);
  617. repeat
  618. Action := DoNothing;
  619. GetEvent(E);
  620. case E.What of
  621. evMouseDown:
  622. if MouseInView(E.Where) or MouseInOwner then
  623. begin
  624. TrackMouse;
  625. if Size.Y = 1 then AutoSelect := True;
  626. end else Action := DoReturn;
  627. evMouseUp:
  628. begin
  629. TrackMouse;
  630. if MouseInOwner then
  631. Current := Menu^.Default
  632. else
  633. if (Current <> nil) and (Current^.Name <> nil) then
  634. Action := DoSelect
  635. else
  636. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  637. else
  638. begin
  639. Current := Menu^.Default;
  640. if Current = nil then Current := Menu^.Items;
  641. Action := DoNothing;
  642. end;
  643. end;
  644. evMouseMove:
  645. if E.Buttons <> 0 then
  646. begin
  647. TrackMouse;
  648. if not (MouseInView(E.Where) or MouseInOwner) and
  649. MouseInMenus then Action := DoReturn;
  650. end;
  651. evKeyDown:
  652. case CtrlToArrow(E.KeyCode) of
  653. kbUp, kbDown:
  654. if Size.Y <> 1 then
  655. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  656. if E.KeyCode = kbDown then AutoSelect := True;
  657. kbLeft, kbRight:
  658. if ParentMenu = nil then
  659. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  660. Action := DoReturn;
  661. kbHome, kbEnd:
  662. if Size.Y <> 1 then
  663. begin
  664. Current := Menu^.Items;
  665. if E.KeyCode = kbEnd then TrackKey(False);
  666. end;
  667. kbEnter:
  668. begin
  669. if Size.Y = 1 then AutoSelect := True;
  670. Action := DoSelect;
  671. end;
  672. kbEsc:
  673. begin
  674. Action := DoReturn;
  675. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  676. ClearEvent(E);
  677. end;
  678. else
  679. Target := @Self;
  680. Ch := GetAltChar(E.KeyCode);
  681. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  682. P := Target^.FindItem(Ch);
  683. if P = nil then
  684. begin
  685. P := TopMenu^.HotKey(E.KeyCode);
  686. if (P <> nil) and CommandEnabled(P^.Command) then
  687. begin
  688. Result := P^.Command;
  689. Action := DoReturn;
  690. end
  691. end else
  692. if Target = @Self then
  693. begin
  694. if Size.Y = 1 then AutoSelect := True;
  695. Action := DoSelect;
  696. Current := P;
  697. end else
  698. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  699. Action := DoReturn;
  700. end;
  701. evCommand:
  702. if E.Command = cmMenu then
  703. begin
  704. AutoSelect := False;
  705. if ParentMenu <> nil then Action := DoReturn;
  706. end else Action := DoReturn;
  707. end;
  708. if ItemShown <> Current then
  709. begin
  710. ItemShown := Current;
  711. DrawView;
  712. end;
  713. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  714. if Current <> nil then with Current^ do if Name <> nil then
  715. if Command = 0 then
  716. begin
  717. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  718. GetItemRect(Current, R);
  719. R.A.X := R.A.X + Origin.X;
  720. R.A.Y := R.B.Y + Origin.Y;
  721. R.B := Owner^.Size;
  722. if Size.Y = 1 then Dec(R.A.X);
  723. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  724. Result := Owner^.ExecView(Target);
  725. Dispose(Target, Done);
  726. end else if Action = DoSelect then Result := Command;
  727. if (Result <> 0) and CommandEnabled(Result) then
  728. begin
  729. Action := DoReturn;
  730. ClearEvent(E);
  731. end
  732. else
  733. Result := 0;
  734. until Action = DoReturn;
  735. end;
  736. if E.What <> evNothing then
  737. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  738. if Current <> nil then
  739. begin
  740. Menu^.Default := Current;
  741. Current := nil;
  742. DrawView;
  743. end;
  744. Execute := Result;
  745. end;
  746. constructor TAdvancedMenuBar.Init(var Bounds: TRect; AMenu: PMenu);
  747. begin
  748. inherited Init(Bounds, AMenu);
  749. EventMask:=EventMask or evBroadcast;
  750. GrowMode:=gfGrowHiX;
  751. end;
  752. function TAdvancedMenuBar.NewSubView(var Bounds: TRect; AMenu: PMenu;
  753. AParentMenu: PMenuView): PMenuView;
  754. begin
  755. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  756. end;
  757. procedure TAdvancedMenuBar.Update;
  758. begin
  759. UpdateMenu(Menu);
  760. DrawView;
  761. end;
  762. function TAdvancedMenuBar.GetMenuItem(cm : word) : PMenuItem;
  763. type
  764. PItemChain = ^TItemChain;
  765. TItemChain = record
  766. Next : PMenuItem;
  767. Up : PItemChain;
  768. end;
  769. var Cur : PMenuItem;
  770. Up,NUp : PItemChain;
  771. begin
  772. Cur:=Menu^.Items;
  773. Up:=nil;
  774. if cm=0 then
  775. begin
  776. GetMenuItem:=nil;
  777. exit;
  778. end;
  779. while assigned(Cur) and (Cur^.Command<>cm) do
  780. begin
  781. if (Cur^.Command=0) and assigned(Cur^.SubMenu) and
  782. assigned(Cur^.Name) and
  783. assigned(Cur^.SubMenu^.Items) then
  784. {subMenu}
  785. begin
  786. If assigned(Cur^.Next) then
  787. begin
  788. New(Nup);
  789. Nup^.Up:=Up;
  790. Nup^.next:=Cur^.Next;
  791. Up:=Nup;
  792. end;
  793. Cur:=Cur^.SubMenu^.Items;
  794. end
  795. else
  796. { normal item }
  797. begin
  798. if assigned(Cur^.Next) then
  799. Cur:=Cur^.Next
  800. else if assigned(Up) then
  801. begin
  802. Cur:=Up^.next;
  803. NUp:=Up;
  804. Up:=Up^.Up;
  805. Dispose(NUp);
  806. end
  807. else
  808. Cur:=Nil;
  809. end;
  810. end;
  811. GetMenuItem:=Cur;
  812. While assigned(Up) do
  813. begin
  814. NUp:=Up;
  815. Up:=Up^.up;
  816. Dispose(NUp);
  817. end;
  818. end;
  819. procedure TAdvancedMenuBar.HandleEvent(var Event: TEvent);
  820. begin
  821. case Event.What of
  822. evBroadcast :
  823. case Event.Command of
  824. cmCommandSetChanged : Update;
  825. cmUpdate : Update;
  826. end;
  827. end;
  828. inherited HandleEvent(Event);
  829. end;
  830. function TAdvancedMenuBar.Execute: word;
  831. type
  832. MenuAction = (DoNothing, DoSelect, DoReturn);
  833. var
  834. AutoSelect: Boolean;
  835. Action: MenuAction;
  836. Ch: Char;
  837. Result: Word;
  838. ItemShown, P: PMenuItem;
  839. Target: PMenuView;
  840. R: TRect;
  841. E: TEvent;
  842. MouseActive: Boolean;
  843. function IsDisabled(Item: PMenuItem): boolean;
  844. var Dis : boolean;
  845. begin
  846. Dis:=Item^.Disabled or IsSeparator(Item);
  847. if (Dis=false) and (IsSubMenu(Item)=false) then
  848. Dis:=CommandEnabled(Item^.Command)=false;
  849. IsDisabled:=Dis;
  850. end;
  851. procedure TrackMouse;
  852. var
  853. Mouse: TPoint;
  854. R: TRect;
  855. OldC: PMenuItem;
  856. begin
  857. MakeLocal(E.Where, Mouse);
  858. OldC:=Current;
  859. Current := Menu^.Items;
  860. while Current <> nil do
  861. begin
  862. GetItemRect(Current, R);
  863. if R.Contains(Mouse) then
  864. begin
  865. MouseActive := True;
  866. Break;
  867. end;
  868. Current := Current^.Next;
  869. end;
  870. if (Current<>nil) and IsDisabled(Current) then
  871. Current:=nil;
  872. end;
  873. procedure TrackKey(FindNext: Boolean);
  874. procedure NextItem;
  875. begin
  876. Current := Current^.Next;
  877. if Current = nil then Current := Menu^.Items;
  878. end;
  879. procedure PrevItem;
  880. var
  881. P: PMenuItem;
  882. begin
  883. P := Current;
  884. if P = Menu^.Items then P := nil;
  885. repeat NextItem until Current^.Next = P;
  886. end;
  887. begin
  888. if Current <> nil then
  889. repeat
  890. if FindNext then NextItem else PrevItem;
  891. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  892. end;
  893. function MouseInOwner: Boolean;
  894. var
  895. Mouse: TPoint;
  896. R: TRect;
  897. begin
  898. MouseInOwner := False;
  899. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  900. begin
  901. ParentMenu^.MakeLocal(E.Where, Mouse);
  902. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  903. MouseInOwner := R.Contains(Mouse);
  904. end;
  905. end;
  906. function MouseInMenus: Boolean;
  907. var
  908. P: PMenuView;
  909. begin
  910. P := ParentMenu;
  911. while (P <> nil) and not P^.MouseInView(E.Where) do P := P^.ParentMenu;
  912. MouseInMenus := P <> nil;
  913. end;
  914. function TopMenu: PMenuView;
  915. var
  916. P: PMenuView;
  917. begin
  918. P := @Self;
  919. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  920. TopMenu := P;
  921. end;
  922. begin
  923. AutoSelect := False; E.What:=evNothing;
  924. Result := 0;
  925. ItemShown := nil;
  926. Current := Menu^.Default;
  927. MouseActive := False;
  928. if UpdateMenu(Menu) then
  929. begin
  930. if Current<>nil then
  931. if Current^.Disabled then
  932. TrackKey(true);
  933. repeat
  934. Action := DoNothing;
  935. GetEvent(E);
  936. case E.What of
  937. evMouseDown:
  938. if MouseInView(E.Where) or MouseInOwner then
  939. begin
  940. TrackMouse;
  941. if Size.Y = 1 then AutoSelect := True;
  942. end else Action := DoReturn;
  943. evMouseUp:
  944. begin
  945. TrackMouse;
  946. if MouseInOwner then
  947. Current := Menu^.Default
  948. else
  949. if (Current <> nil) and (Current^.Name <> nil) then
  950. Action := DoSelect
  951. else
  952. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  953. else
  954. begin
  955. Current := Menu^.Default;
  956. if Current = nil then Current := Menu^.Items;
  957. Action := DoNothing;
  958. end;
  959. end;
  960. evMouseMove:
  961. if E.Buttons <> 0 then
  962. begin
  963. TrackMouse;
  964. if not (MouseInView(E.Where) or MouseInOwner) and
  965. MouseInMenus then Action := DoReturn;
  966. end;
  967. evKeyDown:
  968. case CtrlToArrow(E.KeyCode) of
  969. kbUp, kbDown:
  970. if Size.Y <> 1 then
  971. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  972. if E.KeyCode = kbDown then AutoSelect := True;
  973. kbLeft, kbRight:
  974. if ParentMenu = nil then
  975. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  976. Action := DoReturn;
  977. kbHome, kbEnd:
  978. if Size.Y <> 1 then
  979. begin
  980. Current := Menu^.Items;
  981. if E.KeyCode = kbEnd then TrackKey(False);
  982. end;
  983. kbEnter:
  984. begin
  985. if Size.Y = 1 then AutoSelect := True;
  986. Action := DoSelect;
  987. end;
  988. kbEsc:
  989. begin
  990. Action := DoReturn;
  991. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  992. ClearEvent(E);
  993. end;
  994. else
  995. Target := @Self;
  996. Ch := GetAltChar(E.KeyCode);
  997. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  998. P := Target^.FindItem(Ch);
  999. if P = nil then
  1000. begin
  1001. P := TopMenu^.HotKey(E.KeyCode);
  1002. if (P <> nil) and CommandEnabled(P^.Command) then
  1003. begin
  1004. Result := P^.Command;
  1005. Action := DoReturn;
  1006. end
  1007. end else
  1008. if Target = @Self then
  1009. begin
  1010. if Size.Y = 1 then AutoSelect := True;
  1011. Action := DoSelect;
  1012. Current := P;
  1013. end else
  1014. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  1015. Action := DoReturn;
  1016. end;
  1017. evCommand:
  1018. if E.Command = cmMenu then
  1019. begin
  1020. AutoSelect := False;
  1021. if ParentMenu <> nil then Action := DoReturn;
  1022. end else Action := DoReturn;
  1023. end;
  1024. if ItemShown <> Current then
  1025. begin
  1026. ItemShown := Current;
  1027. DrawView;
  1028. end;
  1029. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  1030. if Current <> nil then with Current^ do if Name <> nil then
  1031. if Command = 0 then
  1032. begin
  1033. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  1034. GetItemRect(Current, R);
  1035. R.A.X := R.A.X + Origin.X;
  1036. R.A.Y := R.B.Y + Origin.Y;
  1037. R.B := Owner^.Size;
  1038. if Size.Y = 1 then Dec(R.A.X);
  1039. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  1040. Result := Owner^.ExecView(Target);
  1041. Dispose(Target, Done);
  1042. end else if Action = DoSelect then Result := Command;
  1043. if (Result <> 0) and CommandEnabled(Result) then
  1044. begin
  1045. Action := DoReturn;
  1046. ClearEvent(E);
  1047. end
  1048. else
  1049. Result := 0;
  1050. until Action = DoReturn;
  1051. end;
  1052. if E.What <> evNothing then
  1053. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  1054. if Current <> nil then
  1055. begin
  1056. Menu^.Default := Current;
  1057. Current := nil;
  1058. DrawView;
  1059. end;
  1060. Execute := Result;
  1061. end;
  1062. procedure TAdvancedStaticText.SetText(S: string);
  1063. begin
  1064. if Text<>nil then DisposeStr(Text);
  1065. Text:=NewStr(S);
  1066. DrawView;
  1067. end;
  1068. procedure TAdvancedListBox.FocusItem(Item: sw_integer);
  1069. var OFocused: sw_integer;
  1070. begin
  1071. OFocused:=Focused;
  1072. inherited FocusItem(Item);
  1073. if Focused<>OFocused then
  1074. Message(Owner,evBroadcast,cmListFocusChanged,@Self);
  1075. end;
  1076. procedure TAdvancedListBox.HandleEvent(var Event: TEvent);
  1077. begin
  1078. case Event.What of
  1079. evMouseDown :
  1080. if MouseInView(Event.Where) {and (Event.Double)} then
  1081. begin
  1082. inherited HandleEvent(Event);
  1083. if Event.Double then
  1084. if Range>Focused then
  1085. SelectItem(Focused);
  1086. end;
  1087. evBroadcast :
  1088. case Event.Command of
  1089. cmListItemSelected :
  1090. Message(Owner,evBroadcast,cmDefault,nil);
  1091. end;
  1092. end;
  1093. if assigned(VScrollBar) then
  1094. VScrollBar^.HandleEvent(Event);
  1095. if assigned(HScrollBar) then
  1096. HScrollBar^.HandleEvent(Event);
  1097. inherited HandleEvent(Event);
  1098. end;
  1099. constructor TColorStaticText.Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
  1100. begin
  1101. inherited Init(Bounds,AText);
  1102. DontWrap:=not AWrap;
  1103. Color:=AColor;
  1104. end;
  1105. function TColorStaticText.GetPalette: PPalette;
  1106. begin
  1107. GetPalette:=nil;
  1108. end;
  1109. procedure TColorStaticText.Draw;
  1110. procedure MoveColorTxt(var b;const curs:string;c:word);
  1111. var
  1112. p : ^word;
  1113. i : sw_integer;
  1114. col : byte;
  1115. tilde : boolean;
  1116. begin
  1117. tilde:=false;
  1118. col:=lo(c);
  1119. p:=@b;
  1120. i:=0;
  1121. while (i<length(Curs)) do
  1122. begin
  1123. Inc(i);
  1124. case CurS[i] of
  1125. #1 :
  1126. begin
  1127. Inc(i);
  1128. Col:=ord(curS[i]);
  1129. end;
  1130. #2 :
  1131. begin
  1132. if tilde then
  1133. col:=hi(Color)
  1134. else
  1135. col:=lo(Color)
  1136. end;
  1137. '~' :
  1138. begin
  1139. tilde:=not tilde;
  1140. if tilde then
  1141. col:=hi(Color)
  1142. else
  1143. col:=lo(Color)
  1144. end;
  1145. else
  1146. begin
  1147. p^:=(col shl 8) or ord(curs[i]);
  1148. inc(p);
  1149. end;
  1150. end;
  1151. end;
  1152. end;
  1153. var
  1154. C: word;
  1155. Center: Boolean;
  1156. I, J, L, P, Y: Sw_Integer;
  1157. B: TDrawBuffer;
  1158. S: String;
  1159. T: string;
  1160. CurS: string;
  1161. TildeCount,Po: Sw_integer;
  1162. TempS: string;
  1163. begin
  1164. if Size.X=0 then Exit;
  1165. C:=Color;
  1166. if (C and $0f)=((C and $f0) shr 4) then
  1167. C:=GetColor(C and $0f);
  1168. if DontWrap=false then
  1169. begin
  1170. GetText(S);
  1171. L := Length(S);
  1172. P := 1;
  1173. Y := 0;
  1174. Center := False;
  1175. while Y < Size.Y do
  1176. begin
  1177. MoveChar(B, ' ', Lo(C), Size.X);
  1178. if P <= L then
  1179. begin
  1180. if S[P] = #3 then
  1181. begin
  1182. Center := True;
  1183. Inc(P);
  1184. end;
  1185. I := P;
  1186. repeat
  1187. J := P;
  1188. while (P <= L) and (S[P] = ' ') do Inc(P);
  1189. while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
  1190. until (P > L) or (P >= I + Size.X) or (S[P] = #13);
  1191. TildeCount:=0; TempS:=copy(S,I,P-I);
  1192. repeat
  1193. Po:=Pos('~',TempS);
  1194. if Po>0 then begin Inc(TildeCount); Delete(TempS,1,Po); end;
  1195. until Po=0;
  1196. if P > I + Size.X + TildeCount then
  1197. if J > I then P := J else P := I + Size.X;
  1198. T:=copy(S,I,P-I);
  1199. if Center then J := (Size.X - {P + I}CStrLen(T)) div 2 else J := 0;
  1200. MoveColorTxt(B[J],T,C);
  1201. while (P <= L) and (S[P] = ' ') do Inc(P);
  1202. if (P <= L) and (S[P] = #13) then
  1203. begin
  1204. Center := False;
  1205. Inc(P);
  1206. if (P <= L) and (S[P] = #10) then Inc(P);
  1207. end;
  1208. end;
  1209. WriteLine(0, Y, Size.X, 1, B);
  1210. Inc(Y);
  1211. end;
  1212. end { Wrap=false } else
  1213. begin
  1214. GetText(S);
  1215. I:=1;
  1216. for Y:=0 to Size.Y-1 do
  1217. begin
  1218. MoveChar(B, ' ', Lo(C), Size.X);
  1219. CurS:='';
  1220. if S<>'' then
  1221. begin
  1222. P:=Pos(#13,S);
  1223. if P=0 then P:=length(S)+1;
  1224. CurS:=copy(S,1,P-1);
  1225. CurS:=copy(CurS,Delta.X+1,High(CurS));
  1226. CurS:=copy(CurS,1,MaxViewWidth);
  1227. Delete(S,1,P);
  1228. end;
  1229. if CurS<>'' then
  1230. MoveColorTxt(B,CurS,C);
  1231. WriteLine(0,Y,Size.X,1,B);
  1232. end;
  1233. end;
  1234. end;
  1235. constructor TColorStaticText.Load(var S: TStream);
  1236. begin
  1237. inherited Load(S);
  1238. S.Read(Color,SizeOf(Color));
  1239. S.Read(DontWrap,SizeOf(DontWrap));
  1240. S.Read(Delta,SizeOf(Delta));
  1241. end;
  1242. procedure TColorStaticText.Store(var S: TStream);
  1243. begin
  1244. inherited Store(S);
  1245. S.Write(Color,SizeOf(Color));
  1246. S.Write(DontWrap,SizeOf(DontWrap));
  1247. S.Write(Delta,SizeOf(Delta));
  1248. end;
  1249. constructor THSListBox.Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
  1250. begin
  1251. inherited Init(Bounds,ANumCols,AVScrollBar);
  1252. HScrollBar:=AHScrollBar;
  1253. if assigned(VScrollBar) then
  1254. VScrollBar^.SetStep(Bounds.B.Y-Bounds.A.Y-2,1);
  1255. if assigned(HScrollBar) then
  1256. HScrollBar^.SetStep(Bounds.B.X-Bounds.A.X-2,1);
  1257. end;
  1258. function THSListBox.SaveToFile(const AFileName: string): boolean;
  1259. var OK: boolean;
  1260. S: PBufStream;
  1261. i, count : sw_integer;
  1262. st : string;
  1263. begin
  1264. New(S, Init(AFileName,stCreate,4096));
  1265. OK:=Assigned(S) and (S^.Status=stOK);
  1266. if OK then
  1267. begin
  1268. if assigned(List) then
  1269. Count:=List^.Count
  1270. else
  1271. Count:=0;
  1272. for i:=0 to Count-1 do
  1273. begin
  1274. st:=GetText(i,High(st));
  1275. S^.Write(St[1],length(St));
  1276. if i<Count then
  1277. S^.Write(EOL[1],length(EOL));
  1278. OK:=(S^.Status=stOK);
  1279. if not OK then
  1280. break;
  1281. end;
  1282. end;
  1283. if Assigned(S) then Dispose(S, Done);
  1284. SaveToFile:=OK;
  1285. end;
  1286. function THSListBox.SaveAs: Boolean;
  1287. var
  1288. DefExt,Title,Filename : string;
  1289. Re : word;
  1290. begin
  1291. SaveAs := False;
  1292. Filename:='listbox.txt';
  1293. DefExt:='*.txt';
  1294. Title:='Save list box content';
  1295. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  1296. Title, label_name, fdOkButton, FileId)), @FileName);
  1297. if Re <> cmCancel then
  1298. SaveAs := SaveToFile(FileName);
  1299. end;
  1300. constructor TDlgWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
  1301. begin
  1302. inherited Init(Bounds,ATitle);
  1303. Number:=ANumber;
  1304. Flags:=Flags or (wfMove + wfGrow + wfClose + wfZoom);
  1305. end;
  1306. procedure TLocalMenuListBox.LocalMenu(P: TPoint);
  1307. var M: PMenu;
  1308. MV: PAdvancedMenuPopUp;
  1309. R: TRect;
  1310. Re: word;
  1311. begin
  1312. M:=GetLocalMenu;
  1313. if M=nil then Exit;
  1314. if LastLocalCmd<>0 then
  1315. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  1316. Desktop^.GetExtent(R);
  1317. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  1318. New(MV, Init(R, M));
  1319. Re:=Application^.ExecView(MV);
  1320. if M^.Default=nil then LastLocalCmd:=0
  1321. else LastLocalCmd:=M^.Default^.Command;
  1322. Dispose(MV, Done);
  1323. if Re<>0 then
  1324. Message(GetCommandTarget,evCommand,Re,@Self);
  1325. end;
  1326. function TLocalMenuListBox.GetLocalMenu: PMenu;
  1327. begin
  1328. GetLocalMenu:=nil;
  1329. { Abstract;}
  1330. end;
  1331. function TLocalMenuListBox.GetCommandTarget: PView;
  1332. begin
  1333. GetCommandTarget:=@Self;
  1334. end;
  1335. procedure TLocalMenuListBox.HandleEvent(var Event: TEvent);
  1336. var DontClear: boolean;
  1337. P: TPoint;
  1338. begin
  1339. case Event.What of
  1340. evMouseDown :
  1341. if MouseInView(Event.Where) and (Event.Buttons=mbRightButton) then
  1342. begin
  1343. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  1344. LocalMenu(P);
  1345. ClearEvent(Event);
  1346. end;
  1347. evKeyDown :
  1348. begin
  1349. DontClear:=false;
  1350. case Event.KeyCode of
  1351. kbAltF10 : Message(@Self,evCommand,cmLocalMenu,@Self);
  1352. else DontClear:=true;
  1353. end;
  1354. if DontClear=false then ClearEvent(Event);
  1355. end;
  1356. evCommand :
  1357. begin
  1358. DontClear:=false;
  1359. case Event.Command of
  1360. cmLocalMenu :
  1361. begin
  1362. P:=Cursor; Inc(P.X); Inc(P.Y);
  1363. LocalMenu(P);
  1364. end;
  1365. else DontClear:=true;
  1366. end;
  1367. if not DontClear then ClearEvent(Event);
  1368. end;
  1369. end;
  1370. inherited HandleEvent(Event);
  1371. end;
  1372. function TAdvancedStatusLine.GetStatusText: string;
  1373. var S: string;
  1374. begin
  1375. if StatusText=nil then S:='' else S:=StatusText^;
  1376. GetStatusText:=S;
  1377. end;
  1378. procedure TAdvancedStatusLine.SetStatusText(const S: string);
  1379. begin
  1380. if StatusText<>nil then DisposeStr(StatusText);
  1381. StatusText:=NewStr(S);
  1382. DrawView;
  1383. end;
  1384. procedure TAdvancedStatusLine.ClearStatusText;
  1385. begin
  1386. SetStatusText('');
  1387. end;
  1388. procedure TAdvancedStatusLine.Draw;
  1389. var B: TDrawBuffer;
  1390. C: word;
  1391. S: string;
  1392. begin
  1393. S:=GetStatusText;
  1394. if S='' then inherited Draw else
  1395. begin
  1396. C:=GetColor(1);
  1397. MoveChar(B,' ',C,Size.X);
  1398. MoveStr(B[1],S,C);
  1399. WriteLine(0,0,Size.X,Size.Y,B);
  1400. end;
  1401. end;
  1402. procedure Bug(const S: string; Params: pointer);
  1403. begin
  1404. ErrorBox(FormatStrStr(msg_bugcheckfailed,S),Params);
  1405. end;
  1406. procedure ErrorBox(const S: string; Params: pointer);
  1407. begin
  1408. AdvMessageBox(S,Params,mfError+mfInsertInApp+mfOKButton);
  1409. end;
  1410. procedure WarningBox(const S: string; Params: pointer);
  1411. begin
  1412. AdvMessageBox(S,Params,mfWarning+mfInsertInApp+mfOKButton);
  1413. end;
  1414. procedure InformationBox(const S: string; Params: pointer);
  1415. begin
  1416. AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton);
  1417. end;
  1418. function OKCancelBox(const S: string; Params: pointer): word;
  1419. begin
  1420. OKCancelBox:=AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton+mfCancelButton);
  1421. end;
  1422. function b2i(B: boolean): longint;
  1423. begin
  1424. if b then b2i:=1 else b2i:=0;
  1425. end;
  1426. function ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
  1427. begin
  1428. ConfirmBox:=AdvMessageBox(S,Params,mfConfirmation+mfInsertInApp+mfYesButton+mfNoButton+
  1429. b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
  1430. end;
  1431. function ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
  1432. var BtnMask,M: longint;
  1433. I,BtnCount: integer;
  1434. begin
  1435. BtnCount:=Min(High(Buttons)-Low(Buttons)+1,High(UserButtonName)-Low(UserButtonName)+1);
  1436. BtnMask:=0; M:=mfUserBtn1;
  1437. for I:=Low(Buttons) to Low(Buttons)+BtnCount-1 do
  1438. begin
  1439. UserButtonName[Low(UserButtonName)+I-Low(Buttons)]:=Buttons[I];
  1440. BtnMask:=BtnMask or M; M:=M shl 1;
  1441. end;
  1442. ChoiceBox:=AdvMessageBox(S,Params,mfConfirmation+BtnMask+
  1443. b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
  1444. end;
  1445. function IsSeparator(P: PMenuItem): boolean;
  1446. begin
  1447. IsSeparator:=(P<>nil) and (P^.Name=nil) and (P^.HelpCtx=hcNoContext);
  1448. end;
  1449. function IsSubMenu(P: PMenuItem): boolean;
  1450. begin
  1451. IsSubMenu:=(P<>nil) and (P^.Name<>nil) and (P^.Command=0) and (P^.SubMenu<>nil);
  1452. end;
  1453. function SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
  1454. var P,I: PMenuItem;
  1455. begin
  1456. I:=nil;
  1457. if Menu=nil then P:=nil else P:=Menu^.Items;
  1458. while (P<>nil) and (I=nil) do
  1459. begin
  1460. if IsSubMenu(P) then
  1461. I:=SearchMenuItem(P^.SubMenu,Cmd);
  1462. if I=nil then
  1463. if P^.Command=Cmd then I:=P else
  1464. P:=P^.Next;
  1465. end;
  1466. SearchMenuItem:=I;
  1467. end;
  1468. procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
  1469. begin
  1470. if Menu=nil then Exit;
  1471. if Menu^.Param<>nil then DisposeStr(Menu^.Param);
  1472. Menu^.Param:=NewStr(Param);
  1473. end;
  1474. function UpdateMenu(M: PMenu): boolean;
  1475. var P: PMenuItem;
  1476. IsEnabled: boolean;
  1477. begin
  1478. if M=nil then begin UpdateMenu:=false; Exit; end;
  1479. P:=M^.Items; IsEnabled:=false;
  1480. while (P<>nil) do
  1481. begin
  1482. if IsSubMenu(P) then
  1483. begin
  1484. P^.Disabled:=not UpdateMenu(P^.SubMenu);
  1485. if not P^.Disabled then
  1486. IsEnabled:=true;
  1487. end
  1488. else if (IsSeparator(P)=false) {and (P^.Disabled=false)} and
  1489. (Application^.CommandEnabled(P^.Command)=true) then
  1490. begin
  1491. p^.disabled:=not Application^.CommandEnabled(P^.Command);
  1492. if not p^.disabled then
  1493. IsEnabled:=true;
  1494. end;
  1495. P:=P^.Next;
  1496. end;
  1497. UpdateMenu:=IsEnabled;
  1498. end;
  1499. function SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
  1500. var P,C: PMenuItem;
  1501. Count: Sw_integer;
  1502. begin
  1503. P:=nil; Count:=-1;
  1504. if M<>nil then C:=M^.Items else C:=nil;
  1505. while (C<>nil) and (P=nil) do
  1506. begin
  1507. if IsSubMenu(C) then
  1508. begin
  1509. Inc(Count);
  1510. if Count=Index then P:=C;
  1511. end;
  1512. C:=C^.Next;
  1513. end;
  1514. SearchSubMenu:=P;
  1515. end;
  1516. procedure AppendMenuItem(M: PMenu; I: PMenuItem);
  1517. var P: PMenuItem;
  1518. begin
  1519. if (M=nil) or (I=nil) then Exit;
  1520. I^.Next:=nil;
  1521. if M^.Items=nil then M^.Items:=I else
  1522. begin
  1523. P:=M^.Items;
  1524. while (P^.Next<>nil) do P:=P^.Next;
  1525. P^.Next:=I;
  1526. end;
  1527. end;
  1528. procedure DisposeMenuItem(P: PMenuItem);
  1529. begin
  1530. if P<>nil then
  1531. begin
  1532. if IsSubMenu(P) then DisposeMenu(P^.SubMenu) else
  1533. if IsSeparator(P)=false then
  1534. if P^.Param<>nil then DisposeStr(P^.Param);
  1535. if P^.Name<>nil then DisposeStr(P^.Name);
  1536. Dispose(P);
  1537. end;
  1538. end;
  1539. procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
  1540. var P,PrevP: PMenuItem;
  1541. begin
  1542. if (Menu=nil) or (I=nil) then Exit;
  1543. P:=Menu^.Items; PrevP:=nil;
  1544. while (P<>nil) do
  1545. begin
  1546. if P=I then
  1547. begin
  1548. if Menu^.Items<>I then PrevP^.Next:=P^.Next
  1549. else Menu^.Items:=P^.Next;
  1550. DisposeMenuItem(P);
  1551. Break;
  1552. end;
  1553. PrevP:=P; P:=P^.Next;
  1554. end;
  1555. end;
  1556. function GetMenuItemBefore(Menu: PMenu; BeforeOf: PMenuItem): PMenuItem;
  1557. var P,C: PMenuItem;
  1558. begin
  1559. P:=nil;
  1560. if Menu<>nil then C:=Menu^.Items else C:=nil;
  1561. while (C<>nil) do
  1562. begin
  1563. if C^.Next=BeforeOf then begin P:=C; Break; end;
  1564. C:=C^.Next;
  1565. end;
  1566. GetMenuItemBefore:=P;
  1567. end;
  1568. procedure NotImplemented;
  1569. begin
  1570. InformationBox(msg_functionnotimplemented,nil);
  1571. end;
  1572. procedure InsertButtons(ADialog: PDialog);
  1573. var R : TRect;
  1574. W,H : Sw_integer;
  1575. X : Sw_integer;
  1576. X1,X2: Sw_integer;
  1577. begin
  1578. with ADialog^ do
  1579. begin
  1580. GetExtent(R);
  1581. W:=R.B.X-R.A.X; H:=(R.B.Y-R.A.Y);
  1582. R.Assign(0,0,W,H+3); ChangeBounds(R);
  1583. X:=W div 2; X1:=X div 2+1; X2:=X+X1-1;
  1584. R.Assign(X1-3,H,X1+7,H+2);
  1585. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  1586. R.Assign(X2-7,H,X2+3,H+2);
  1587. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  1588. SelectNext(true);
  1589. end;
  1590. end;
  1591. procedure InsertOK(ADialog: PDialog);
  1592. var BW: Sw_integer;
  1593. R: TRect;
  1594. begin
  1595. with ADialog^ do
  1596. begin
  1597. GetBounds(R); R.Grow(0,1); Inc(R.B.Y);
  1598. ChangeBounds(R);
  1599. BW:=10;
  1600. R.A.Y:=R.B.Y-2; R.B.Y:=R.A.Y+2;
  1601. R.A.X:=R.A.X+(R.B.X-R.A.X-BW) div 2; R.B.X:=R.A.X+BW;
  1602. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  1603. SelectNext(true);
  1604. end;
  1605. end;
  1606. procedure ShowMessage(Msg: string);
  1607. var R: TRect;
  1608. Width: Sw_integer;
  1609. begin
  1610. Width:=length(Msg)+4*2;
  1611. if Width<(Desktop^.Size.X div 2) then Width:=(Desktop^.Size.X div 2);
  1612. R.Assign(0,0,Width,5);
  1613. New(MessageDialog, Init(R, ''));
  1614. with MessageDialog^ do
  1615. begin
  1616. Flags:=0;
  1617. GetExtent(R); R.Grow(-4,-2);
  1618. if copy(Msg,1,1)<>^C then Msg:=^C+Msg;
  1619. Insert(New(PStaticText, Init(R, Msg)));
  1620. end;
  1621. Application^.Insert(MessageDialog);
  1622. end;
  1623. procedure HideMessage;
  1624. begin
  1625. if MessageDialog<>nil then
  1626. begin
  1627. Application^.Delete(MessageDialog);
  1628. Dispose(MessageDialog, Done);
  1629. MessageDialog:=nil;
  1630. end;
  1631. end;
  1632. constructor TDDHelperLB.Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
  1633. begin
  1634. inherited Init(Bounds,ANumCols,AScrollBar);
  1635. EventMask:=EventMask or (evMouseMove+evIdle);
  1636. { Options:=Options or ofPreProcess;}
  1637. Link:=ALink;
  1638. end;
  1639. procedure TDDHelperLB.SetState(AState: Word; Enable: Boolean);
  1640. {var OState: longint;}
  1641. begin
  1642. { OState:=State;}
  1643. inherited SetState(AState,Enable);
  1644. { if (((State xor OState) and sfFocused)<>0) and (GetState(sfFocused)=false) then
  1645. Link^.DropList(false);}
  1646. end;
  1647. function TDDHelperLB.GetText(Item,MaxLen: Sw_Integer): String;
  1648. var P: pointer;
  1649. S: string;
  1650. begin
  1651. P:=List^.At(Item);
  1652. if Link=nil then S:='' else
  1653. S:=Link^.GetText(P,MaxLen);
  1654. GetText:=S;
  1655. end;
  1656. function TDDHelperLB.GetLocalMenu: PMenu;
  1657. begin
  1658. GetLocalMenu:=Link^.LBGetLocalMenu;
  1659. end;
  1660. function TDDHelperLB.GetCommandTarget: PView;
  1661. begin
  1662. GetCommandTarget:=Link^.LBGetCommandTarget;
  1663. end;
  1664. procedure TDDHelperLB.HandleEvent(var Event: TEvent);
  1665. const
  1666. MouseAutosToSkip = 4;
  1667. var
  1668. Mouse : TPoint;
  1669. OldItem, NewItem : Sw_Integer;
  1670. ColWidth,Count : Sw_Word;
  1671. GoSelectItem: sw_integer;
  1672. MouseWhere: TPoint;
  1673. begin
  1674. GoSelectItem:=-1;
  1675. TView.HandleEvent(Event);
  1676. case Event.What of
  1677. evMouseDown :
  1678. if MouseInView(Event.Where)=false then
  1679. GoSelectItem:=-2
  1680. else
  1681. begin
  1682. ColWidth := Size.X div NumCols + 1;
  1683. OldItem := Focused;
  1684. MakeLocal(Event.Where, Mouse);
  1685. if MouseInView(Event.Where) then
  1686. NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
  1687. else
  1688. NewItem := OldItem;
  1689. Count := 0;
  1690. repeat
  1691. if NewItem <> OldItem then
  1692. begin
  1693. FocusItemNum(NewItem);
  1694. DrawView;
  1695. end;
  1696. OldItem := NewItem;
  1697. MakeLocal(Event.Where, Mouse);
  1698. if MouseInView(Event.Where) then
  1699. NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
  1700. else
  1701. begin
  1702. if NumCols = 1 then
  1703. begin
  1704. if Event.What = evMouseAuto then Inc(Count);
  1705. if Count = MouseAutosToSkip then
  1706. begin
  1707. Count := 0;
  1708. if Mouse.Y < 0 then NewItem := Focused-1
  1709. else if Mouse.Y >= Size.Y then NewItem := Focused+1;
  1710. end;
  1711. end
  1712. else
  1713. begin
  1714. if Event.What = evMouseAuto then Inc(Count);
  1715. if Count = MouseAutosToSkip then
  1716. begin
  1717. Count := 0;
  1718. if Mouse.X < 0 then NewItem := Focused-Size.Y
  1719. else if Mouse.X >= Size.X then NewItem := Focused+Size.Y
  1720. else if Mouse.Y < 0 then
  1721. NewItem := Focused - Focused mod Size.Y
  1722. else if Mouse.Y > Size.Y then
  1723. NewItem := Focused - Focused mod Size.Y + Size.Y - 1;
  1724. end
  1725. end;
  1726. end;
  1727. until not MouseEvent(Event, evMouseMove + evMouseAuto);
  1728. FocusItemNum(NewItem);
  1729. DrawView;
  1730. if Event.Double and (Range > Focused) then SelectItem(Focused);
  1731. ClearEvent(Event);
  1732. GoSelectItem:=Focused;
  1733. end;
  1734. evMouseMove,evMouseAuto:
  1735. if GetState(sfFocused) then
  1736. if MouseInView(Event.Where) then
  1737. begin
  1738. MakeLocal(Event.Where,Mouse);
  1739. FocusItemNum(TopItem+Mouse.Y);
  1740. ClearEvent(Event);
  1741. end;
  1742. evKeyDown :
  1743. begin
  1744. if (Event.KeyCode=kbEsc) then
  1745. begin
  1746. GoSelectItem:=-2;
  1747. ClearEvent(Event);
  1748. end else
  1749. if (Event.CharCode = ' ') and (Focused < Range) then
  1750. begin
  1751. GoSelectItem:=Focused;
  1752. NewItem := Focused;
  1753. end
  1754. else
  1755. case CtrlToArrow(Event.KeyCode) of
  1756. kbUp : NewItem := Focused - 1;
  1757. kbDown : NewItem := Focused + 1;
  1758. kbRight: if NumCols > 1 then NewItem := Focused + Size.Y else Exit;
  1759. kbLeft : if NumCols > 1 then NewItem := Focused - Size.Y else Exit;
  1760. kbPgDn : NewItem := Focused + Size.Y * NumCols;
  1761. kbPgUp : NewItem := Focused - Size.Y * NumCols;
  1762. kbHome : NewItem := TopItem;
  1763. kbEnd : NewItem := TopItem + (Size.Y * NumCols) - 1;
  1764. kbCtrlPgDn: NewItem := Range - 1;
  1765. kbCtrlPgUp: NewItem := 0;
  1766. else
  1767. Exit;
  1768. end;
  1769. FocusItemNum(NewItem);
  1770. DrawView;
  1771. ClearEvent(Event);
  1772. end;
  1773. evBroadcast :
  1774. case Event.Command of
  1775. cmReceivedFocus :
  1776. if (Event.InfoPtr<>@Self) and (InClose=false) then
  1777. begin
  1778. GoSelectItem:=-2;
  1779. end;
  1780. else
  1781. if Options and ofSelectable <> 0 then
  1782. if (Event.Command = cmScrollBarClicked) and
  1783. ((Event.InfoPtr = HScrollBar) or (Event.InfoPtr = VScrollBar)) then
  1784. Select
  1785. else
  1786. if (Event.Command = cmScrollBarChanged) then
  1787. begin
  1788. if (VScrollBar = Event.InfoPtr) then
  1789. begin
  1790. FocusItemNum(VScrollBar^.Value);
  1791. DrawView;
  1792. end
  1793. else
  1794. if (HScrollBar = Event.InfoPtr) then
  1795. DrawView;
  1796. end;
  1797. end;
  1798. evIdle :
  1799. begin
  1800. MouseWhere.X:=MouseWhereX shr 3; MouseWhere.Y:=MouseWhereY shr 3;
  1801. if MouseInView(MouseWhere)=false then
  1802. if abs(GetDosTicks-LastTT)>=1 then
  1803. begin
  1804. LastTT:=GetDosTicks;
  1805. MakeLocal(MouseWhere,Mouse);
  1806. if ((Mouse.Y<-1) or (Mouse.Y>=Size.Y)) and
  1807. ((0<=Mouse.X) and (Mouse.X<Size.X)) then
  1808. if Range>0 then
  1809. if Mouse.Y<0 then
  1810. FocusItemNum(Focused-(0-Mouse.Y))
  1811. else
  1812. FocusItemNum(Focused+(Mouse.Y-(Size.Y-1)));
  1813. end;
  1814. end;
  1815. end;
  1816. if (Range>0) and (GoSelectItem<>-1) then
  1817. begin
  1818. InClose:=true;
  1819. if GoSelectItem=-2 then
  1820. Link^.DropList(false)
  1821. else
  1822. SelectItem(GoSelectItem);
  1823. end;
  1824. end;
  1825. procedure TDDHelperLB.SelectItem(Item: Sw_Integer);
  1826. begin
  1827. inherited SelectItem(Item);
  1828. Link^.FocusItem(Focused);
  1829. Link^.DropList(false);
  1830. end;
  1831. constructor TDropDownListBox.Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
  1832. begin
  1833. inherited Init(Bounds);
  1834. Options:=Options or (ofSelectable);
  1835. EventMask:=EventMask or (evBroadcast);
  1836. DropLineCount:=ADropLineCount;
  1837. NewList(AList);
  1838. end;
  1839. procedure TDropDownListBox.HandleEvent(var Event: TEvent);
  1840. var DontClear: boolean;
  1841. Count: sw_integer;
  1842. begin
  1843. case Event.What of
  1844. evKeyDown :
  1845. if GetState(sfFocused) then
  1846. begin
  1847. DontClear:=false;
  1848. Count:=GetItemCount;
  1849. if Count>0 then
  1850. case Event.KeyCode of
  1851. kbUp :
  1852. if Focused>0 then
  1853. FocusItem(Focused-1);
  1854. kbDown :
  1855. if Focused<Count-1 then
  1856. FocusItem(Focused+1);
  1857. kbHome :
  1858. FocusItem(0);
  1859. kbEnd :
  1860. FocusItem(Count-1);
  1861. kbPgDn :
  1862. DropList(true);
  1863. else DontClear:=true;
  1864. end;
  1865. if DontClear=false then ClearEvent(Event);
  1866. end;
  1867. evBroadcast :
  1868. case Event.Command of
  1869. { cmReleasedFocus :
  1870. if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
  1871. DropList(false);}
  1872. cmListItemSelected :
  1873. if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
  1874. begin
  1875. FocusItem(ListBox^.Focused);
  1876. Text:=GetText(List^.At(Focused),High(Text));
  1877. DrawView;
  1878. DropList(false);
  1879. end;
  1880. end;
  1881. evMouseDown :
  1882. if MouseInView(Event.Where) then
  1883. begin
  1884. DropList(not ListDropped);
  1885. ClearEvent(Event);
  1886. end;
  1887. end;
  1888. inherited HandleEvent(Event);
  1889. end;
  1890. function TDropDownListBox.GetText(Item: pointer; MaxLen: Sw_integer): string;
  1891. var S: string;
  1892. begin
  1893. S:=GetStr(Item);
  1894. GetText:=copy(S,1,MaxLen);
  1895. end;
  1896. procedure TDropDownListBox.NewList(AList: PCollection);
  1897. begin
  1898. if List<>nil then Dispose(List, Done); List:=nil;
  1899. List:=AList; FocusItem(0);
  1900. end;
  1901. procedure TDropDownListBox.CreateListBox(var R: TRect);
  1902. var R2: TRect;
  1903. begin
  1904. R2.Copy(R); R2.A.X:=R2.B.X-1;
  1905. New(SB, Init(R2));
  1906. Dec(R.B.X);
  1907. New(ListBox, Init(@Self,R,1,SB));
  1908. end;
  1909. procedure TDropDownListBox.DropList(Drop: boolean);
  1910. var R: TRect;
  1911. LB: PListBox;
  1912. begin
  1913. if (ListDropped=Drop) then Exit;
  1914. if Drop then
  1915. begin
  1916. R.Assign(Origin.X+1,Origin.Y+Size.Y,Origin.X+Size.X,Origin.Y+Size.Y+DropLineCount);
  1917. if Owner<>nil then Owner^.Lock;
  1918. CreateListBox(R);
  1919. if SB<>nil then
  1920. Owner^.Insert(SB);
  1921. if ListBox<>nil then
  1922. begin
  1923. ListBox^.NewList(List);
  1924. ListBox^.FocusItem(Focused);
  1925. Owner^.Insert(ListBox);
  1926. end;
  1927. if Owner<>nil then Owner^.UnLock;
  1928. end
  1929. else
  1930. begin
  1931. if Owner<>nil then Owner^.Lock;
  1932. if ListBox<>nil then
  1933. begin
  1934. { ListBox^.List:=nil;}
  1935. LB:=ListBox; ListBox:=nil; { this prevents GPFs while deleting }
  1936. Dispose(LB, Done);
  1937. end;
  1938. if SB<>nil then
  1939. begin
  1940. Dispose(SB, Done);
  1941. SB:=nil;
  1942. end;
  1943. Select;
  1944. if Owner<>nil then Owner^.UnLock;
  1945. end;
  1946. ListDropped:=Drop;
  1947. DrawView;
  1948. end;
  1949. function TDropDownListBox.GetItemCount: sw_integer;
  1950. var Count: sw_integer;
  1951. begin
  1952. if assigned(List)=false then Count:=0 else
  1953. Count:=List^.Count;
  1954. GetItemCount:=Count;
  1955. end;
  1956. procedure TDropDownListBox.FocusItem(Item: sw_integer);
  1957. var P: pointer;
  1958. begin
  1959. Focused:=Item;
  1960. if assigned(ListBox) and (Item>=0) then
  1961. ListBox^.FocusItem(Item);
  1962. if (GetItemCount>0) and (Focused>=0) then
  1963. begin
  1964. P:=List^.At(Focused);
  1965. Text:=GetText(P,Size.X-4);
  1966. end;
  1967. DrawView;
  1968. end;
  1969. function TDropDownListBox.LBGetLocalMenu: PMenu;
  1970. begin
  1971. LBGetLocalMenu:=nil;
  1972. end;
  1973. function TDropDownListBox.LBGetCommandTarget: PView;
  1974. begin
  1975. LBGetCommandTarget:=@Self;
  1976. end;
  1977. procedure TDropDownListBox.SetState(AState: Word; Enable: Boolean);
  1978. begin
  1979. inherited SetState(AState,Enable);
  1980. if (AState and (sfSelected + sfActive + sfFocused)) <> 0 then DrawView;
  1981. end;
  1982. procedure TDropDownListBox.Draw;
  1983. var B: TDrawBuffer;
  1984. C,TextC: word;
  1985. LC: char;
  1986. begin
  1987. if GetState(sfFocused)=false then
  1988. begin
  1989. C:=GetColor(2);
  1990. TextC:=GetColor(2);
  1991. end
  1992. else
  1993. begin
  1994. C:=GetColor(3);
  1995. TextC:=GetColor(3);
  1996. end;
  1997. MoveChar(B,' ',C,Size.X);
  1998. MoveStr(B[1],copy(Text,1,Size.X-2),TextC);
  1999. if ListDropped then LC:=#30 else LC:=#31;
  2000. MoveChar(B[Size.X-2],LC,C,1);
  2001. WriteLine(0,0,Size.X,Size.Y,B);
  2002. end;
  2003. function TDropDownListBox.GetPalette: PPalette;
  2004. const P: string[length(CListViewer)] = CListViewer;
  2005. begin
  2006. GetPalette:=@P;
  2007. end;
  2008. destructor TDropDownListBox.Done;
  2009. begin
  2010. if ListDropped then DropList(false);
  2011. inherited Done;
  2012. end;
  2013. constructor TGroupView.Init(var Bounds: TRect; AText: String; ALink: PView);
  2014. begin
  2015. inherited Init(Bounds,AText,ALink);
  2016. end;
  2017. procedure TGroupView.Draw;
  2018. var B: TDrawBuffer;
  2019. FrameC,LabelC: word;
  2020. begin
  2021. FrameC:=GetColor(1);
  2022. if Light then
  2023. LabelC:=GetColor(2)+GetColor(4) shl 8
  2024. else
  2025. LabelC:=GetColor(1)+GetColor(3) shl 8;
  2026. { First Line }
  2027. MoveChar(B[0],'Ú',FrameC,1);
  2028. MoveChar(B[1],'Ä',FrameC,Size.X-2);
  2029. MoveChar(B[Size.X-1],'¿',FrameC,1);
  2030. if Text<>nil then
  2031. begin
  2032. MoveCStr(B[1],' '+Text^+' ',LabelC);
  2033. end;
  2034. WriteLine(0,0,Size.X,1,B);
  2035. { Mid Lines }
  2036. MoveChar(B[0],'³',FrameC,1);
  2037. MoveChar(B[1],' ',FrameC,Size.X-2);
  2038. MoveChar(B[Size.X-1],'³',FrameC,1);
  2039. WriteLine(0,1,Size.X,Size.Y-2,B);
  2040. { Last Line }
  2041. MoveChar(B[0],'À',FrameC,1);
  2042. MoveChar(B[1],'Ä',FrameC,Size.X-2);
  2043. MoveChar(B[Size.X-1],'Ù',FrameC,1);
  2044. WriteLine(0,Size.Y-1,Size.X,1,B);
  2045. end;
  2046. function TPlainCheckBoxes.GetPalette: PPalette;
  2047. const P: string[length(CPlainCluster)] = CPlainCluster;
  2048. begin
  2049. GetPalette:=@P;
  2050. end;
  2051. function TPlainRadioButtons.GetPalette: PPalette;
  2052. const P: string[length(CPlainCluster)] = CPlainCluster;
  2053. begin
  2054. GetPalette:=@P;
  2055. end;
  2056. constructor TAdvancedListBox.Load(var S: TStream);
  2057. begin
  2058. inherited Load(S);
  2059. S.Read(Default,SizeOf(Default));
  2060. end;
  2061. procedure TAdvancedListBox.Store(var S: TStream);
  2062. begin
  2063. inherited Store(S);
  2064. S.Write(Default,SizeOf(Default));
  2065. end;
  2066. procedure TNoUpdateButton.HandleEvent(var Event: TEvent);
  2067. begin
  2068. if (Event.What<>evBroadcast) or (Event.Command<>cmCommandSetChanged) then
  2069. inherited HandleEvent(Event);
  2070. end;
  2071. constructor TPanel.Init(var Bounds: TRect);
  2072. begin
  2073. inherited Init(Bounds);
  2074. Options:=Options or (ofSelectable+ofTopSelect);
  2075. GrowMode:=gfGrowHiX+gfGrowHiY;
  2076. end;
  2077. procedure TAdvMessageBox.HandleEvent(var Event: TEvent);
  2078. var I: integer;
  2079. begin
  2080. if (not CanCancel) and (Event.What=evCommand) and (Event.Command=cmCancel) then
  2081. ClearEvent(Event);
  2082. inherited HandleEvent(Event);
  2083. case Event.What of
  2084. evCommand:
  2085. begin
  2086. for I:=Low(UserButtonCmd) to High(UserButtonCmd) do
  2087. if Event.Command=UserButtonCmd[I] then
  2088. if State and sfModal <> 0 then
  2089. begin
  2090. EndModal(Event.Command);
  2091. ClearEvent(Event);
  2092. end;
  2093. end;
  2094. end;
  2095. end;
  2096. procedure ClearFormatParams;
  2097. begin
  2098. FormatParamCount:=0; FillChar(FormatParams,sizeof(FormatParams),0);
  2099. FormatParamStrCount:=0;
  2100. end;
  2101. procedure AddFormatParam(P: pointer);
  2102. begin
  2103. AddFormatParamInt(longint(P));
  2104. end;
  2105. procedure AddFormatParamInt(L: longint);
  2106. begin
  2107. Inc(FormatParamCount);
  2108. FormatParams[FormatParamCount]:=L;
  2109. end;
  2110. procedure AddFormatParamChar(C: char);
  2111. begin
  2112. AddFormatParamInt(ord(C));
  2113. end;
  2114. procedure AddFormatParamStr(const S: string);
  2115. begin
  2116. Inc(FormatParamStrCount); FormatParamStrs[FormatParamStrCount]:=S;
  2117. AddFormatParam(@FormatParamStrs[FormatParamStrCount]);
  2118. end;
  2119. function FormatStrF(const Format: string; var Params): string;
  2120. var S: string;
  2121. begin
  2122. S:='';
  2123. FormatStr(S,Format,Params);
  2124. FormatStrF:=S;
  2125. end;
  2126. function FormatStrStr(const Format, Param: string): string;
  2127. var S: string;
  2128. P: pointer;
  2129. begin
  2130. P:=@Param;
  2131. FormatStr(S,Format,P);
  2132. FormatStrStr:=S;
  2133. end;
  2134. function FormatStrStr2(const Format, Param1,Param2: string): string;
  2135. var S: string;
  2136. P: array[1..2] of pointer;
  2137. begin
  2138. P[1]:=@Param1; P[2]:=@Param2;
  2139. FormatStr(S,Format,P);
  2140. FormatStrStr2:=S;
  2141. end;
  2142. function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
  2143. var S: string;
  2144. P: array[1..3] of pointer;
  2145. begin
  2146. P[1]:=@Param1; P[2]:=@Param2; P[3]:=@Param3;
  2147. FormatStr(S,Format,P);
  2148. FormatStrStr3:=S;
  2149. end;
  2150. function FormatStrInt(const Format: string; L: longint): string;
  2151. var S: string;
  2152. begin
  2153. FormatStr(S,Format,L);
  2154. FormatStrInt:=S;
  2155. end;
  2156. const
  2157. Cmds: array[0..3] of word =
  2158. (cmYes, cmNo, cmOK, cmCancel);
  2159. var
  2160. ButtonName: array[0..3] of string;
  2161. Titles: array[0..3] of string;
  2162. function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
  2163. var
  2164. R: TRect;
  2165. begin
  2166. R.Assign(0, 0, 0, 0);
  2167. AdvMessageBox := AdvMessageBoxRect(R, Msg, Params, AOptions);
  2168. end;
  2169. procedure GetStaticTextDimensions(const S: string; ViewWidth: integer; var MaxCols, Rows: integer);
  2170. var
  2171. Color: Byte;
  2172. Center: Boolean;
  2173. I, J, L, P, Y: Sw_Integer;
  2174. CurLine: string;
  2175. begin
  2176. MaxCols:=0;
  2177. L := Length(S);
  2178. P := 1;
  2179. Y := 0;
  2180. Center := False;
  2181. while (Y < 32767) and (P<=length(S)) do
  2182. begin
  2183. CurLine:='';
  2184. if P <= L then
  2185. begin
  2186. if S[P] = #3 then
  2187. begin
  2188. Center := True;
  2189. Inc(P);
  2190. end;
  2191. I := P;
  2192. repeat
  2193. J := P;
  2194. while (P <= L) and (S[P] = ' ') do Inc(P);
  2195. while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
  2196. until (P > L) or (P >= I + ViewWidth) or (S[P] = #13);
  2197. if P > I + ViewWidth then
  2198. if J > I then P := J else P := I + ViewWidth;
  2199. if Center then J := (ViewWidth - P + I) div 2 else J := 0;
  2200. CurLine:=CurLine+copy(S,I,P-I);
  2201. { MoveBuf(B[J], S[I], Color, P - I);}
  2202. while (P <= L) and (S[P] = ' ') do Inc(P);
  2203. if (P <= L) and (S[P] = #13) then
  2204. begin
  2205. Center := False;
  2206. Inc(P);
  2207. if (P <= L) and (S[P] = #10) then Inc(P);
  2208. end;
  2209. end;
  2210. if length(CurLine)>MaxCols then
  2211. MaxCols:=length(CurLine);
  2212. { WriteLine(0, Y, Size.X, 1, B);}
  2213. Inc(Y);
  2214. end;
  2215. Rows:=Y;
  2216. end;
  2217. function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
  2218. var
  2219. I, X, ButtonCount: Sw_Integer;
  2220. Dialog: PAdvMessageBox;
  2221. Control: PView;
  2222. ButtonList: array[0..4] of PView;
  2223. S,BtnName: String;
  2224. Cols,Rows: integer;
  2225. begin
  2226. FormatStr(S, Msg, Params^);
  2227. if R.Empty then
  2228. begin
  2229. GetStaticTextDimensions(S,40,Cols,Rows);
  2230. if Cols<30 then Cols:=30; if Rows=0 then Rows:=1;
  2231. R.Assign(0,0,3+Cols+3,Rows+6);
  2232. if (AOptions and mfInsertInApp)= 0 then
  2233. R.Move((Desktop^.Size.X-(R.B.X-R.A.X)) div 2,(Desktop^.Size.Y-(R.B.Y-R.A.Y)) div 2)
  2234. else
  2235. R.Move((Application^.Size.X-(R.B.X-R.A.X)) div 2,(Application^.Size.Y-(R.B.Y-R.A.Y)) div 2);
  2236. end;
  2237. New(Dialog,Init(R, Titles[AOptions and $3]));
  2238. with Dialog^ do
  2239. begin
  2240. CanCancel:=(Options and mfCantCancel)=0;
  2241. R.Assign(3,2, Size.X-2,Size.Y-3);
  2242. Control := New(PStaticText, Init(R, S));
  2243. Insert(Control);
  2244. X := -2;
  2245. ButtonCount := 0;
  2246. for I := 0 to 3 do
  2247. if AOptions and ($10000 shl I) <> 0 then
  2248. begin
  2249. BtnName:=UserButtonName[I+1];
  2250. R.Assign(0, 0, Max(10,length(BtnName)+2), 2);
  2251. Control := New(PButton, Init(R, BtnName, UserButtonCmd[I+1], bfNormal));
  2252. Inc(X, Control^.Size.X + 2);
  2253. ButtonList[ButtonCount] := Control;
  2254. Inc(ButtonCount);
  2255. end;
  2256. for I := 0 to 3 do
  2257. if AOptions and ($0100 shl I) <> 0 then
  2258. begin
  2259. R.Assign(0, 0, 10, 2);
  2260. Control := New(PButton, Init(R, ButtonName[I], Cmds[i], bfNormal));
  2261. Inc(X, Control^.Size.X + 2);
  2262. ButtonList[ButtonCount] := Control;
  2263. Inc(ButtonCount);
  2264. end;
  2265. X := (Size.X - X) div 2;
  2266. for I := 0 to ButtonCount - 1 do
  2267. begin
  2268. Control := ButtonList[I];
  2269. Insert(Control);
  2270. Control^.MoveTo(X, Size.Y - 3);
  2271. Inc(X, Control^.Size.X + 2);
  2272. end;
  2273. SelectNext(False);
  2274. end;
  2275. if AOptions and mfInsertInApp = 0 then
  2276. AdvMessageBoxRect := DeskTop^.ExecView(Dialog)
  2277. else
  2278. AdvMessageBoxRect := Application^.ExecView(Dialog);
  2279. Dispose(Dialog, Done);
  2280. end;
  2281. procedure InitAdvMsgBox;
  2282. begin
  2283. ButtonName[0] := Labels^.Get(slYes);
  2284. ButtonName[1] := Labels^.Get(slNo);
  2285. ButtonName[2] := Labels^.Get(slOk);
  2286. ButtonName[3] := Labels^.Get(slCancel);
  2287. Titles[0] := Labels^.Get(sWarning);
  2288. Titles[1] := Labels^.Get(sError);
  2289. Titles[2] := Labels^.Get(sInformation);
  2290. Titles[3] := Labels^.Get(sConfirm);
  2291. end;
  2292. procedure DoneAdvMsgBox;
  2293. begin
  2294. end;
  2295. procedure RegisterWViews;
  2296. begin
  2297. {$ifndef NOOBJREG}
  2298. RegisterType(RAdvancedListBox);
  2299. RegisterType(RColorStaticText);
  2300. RegisterType(RHSListBox);
  2301. RegisterType(RDlgWindow);
  2302. {$endif}
  2303. end;
  2304. END.
  2305. {
  2306. $Log$
  2307. Revision 1.5 2002-09-07 15:40:50 peter
  2308. * old logs removed and tabs fixed
  2309. Revision 1.4 2002/08/13 07:12:08 pierre
  2310. * use normal strings for ChoiceBox function
  2311. Revision 1.3 2002/04/12 08:59:00 pierre
  2312. + new function OKCancelBox added
  2313. }