fpusrscr.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. User screen support routines
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPUsrScr;
  13. interface
  14. {$ifdef TP}
  15. {$define DOS}
  16. {$else}
  17. {$ifdef GO32V2}
  18. {$define DOS}
  19. {$endif}
  20. {$endif}
  21. uses
  22. {$ifdef win32}
  23. windows,
  24. {$endif win32}
  25. Objects;
  26. type
  27. PScreen = ^TScreen;
  28. TScreen = object(TObject)
  29. function GetWidth: integer; virtual;
  30. function GetHeight: integer; virtual;
  31. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  32. procedure GetCursorPos(var P: TPoint); virtual;
  33. procedure Capture; virtual;
  34. procedure SwitchTo; virtual;
  35. procedure SwitchBack; virtual;
  36. end;
  37. {$ifdef DOS}
  38. TDOSVideoInfo = record
  39. Mode : word;
  40. ScreenSize: word;
  41. Page : byte;
  42. Rows,Cols : integer;
  43. CurPos : TPoint;
  44. CurShapeT : integer;
  45. CurShapeB : integer;
  46. StateSize : word;
  47. StateBuf : pointer;
  48. end;
  49. PDOSScreen = ^TDOSScreen;
  50. TDOSScreen = object(TScreen)
  51. constructor Init;
  52. destructor Done; virtual;
  53. public
  54. function GetWidth: integer; virtual;
  55. function GetHeight: integer; virtual;
  56. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  57. procedure GetCursorPos(var P: TPoint); virtual;
  58. procedure Capture; virtual;
  59. procedure SwitchTo; virtual;
  60. procedure SwitchBack; virtual;
  61. private
  62. VideoInfo : TDOSVideoInfo;
  63. VBufferSize : word;
  64. VBuffer : PByteArray;
  65. TM : TDOSVideoInfo;
  66. function GetLineStartOfs(Line: integer): word;
  67. procedure GetBuffer(Size: word);
  68. procedure FreeBuffer;
  69. procedure GetVideoMode(var MI: TDOSVideoInfo);
  70. procedure SetVideoMode(MI: TDOSVideoInfo);
  71. end;
  72. {$endif}
  73. {$ifdef Linux}
  74. PLinuxScreen = ^TLinuxScreen;
  75. TLinuxScreen = object(TScreen)
  76. constructor Init;
  77. destructor Done; virtual;
  78. public
  79. function GetWidth: integer; virtual;
  80. function GetHeight: integer; virtual;
  81. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  82. procedure GetCursorPos(var P: TPoint); virtual;
  83. procedure Capture; virtual;
  84. procedure SwitchTo; virtual;
  85. procedure SwitchBack; virtual;
  86. end;
  87. {$endif}
  88. {$ifdef win32}
  89. PWin32Screen = ^TWin32Screen;
  90. TWin32Screen = object(TScreen)
  91. constructor Init;
  92. destructor Done; virtual;
  93. public
  94. function GetWidth: integer; virtual;
  95. function GetHeight: integer; virtual;
  96. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  97. procedure GetCursorPos(var P: TPoint); virtual;
  98. procedure Capture; virtual;
  99. procedure SwitchTo; virtual;
  100. procedure SwitchBack; virtual;
  101. private
  102. DosScreenBufferHandle,
  103. IDEScreenBufferHandle : THandle;
  104. IDEActive : boolean;
  105. procedure BufferCopy(src,dest : THandle);
  106. end;
  107. {$endif}
  108. procedure InitUserScreen;
  109. procedure DoneUserScreen;
  110. const UserScreen : PScreen = nil;
  111. implementation
  112. uses
  113. Dos,Video
  114. (* {$ifdef TP}
  115. {$ifdef DPMI}
  116. ,WinAPI
  117. {$endif}
  118. {$endif}*)
  119. {$ifdef FPC}
  120. {$ifdef GO32V2}
  121. ,Go32
  122. {$endif}
  123. {$endif}
  124. ;
  125. function TScreen.GetWidth: integer;
  126. begin
  127. Getwidth:=0;
  128. Abstract;
  129. end;
  130. function TScreen.GetHeight: integer;
  131. begin
  132. Getheight:=0;
  133. Abstract;
  134. end;
  135. procedure TScreen.GetLine(Line: integer; var Text, Attr: string);
  136. begin
  137. Abstract;
  138. end;
  139. procedure TScreen.GetCursorPos(var P: TPoint);
  140. begin
  141. Abstract;
  142. end;
  143. procedure TScreen.Capture;
  144. begin
  145. Abstract;
  146. end;
  147. procedure TScreen.SwitchTo;
  148. begin
  149. Abstract;
  150. end;
  151. procedure TScreen.SwitchBack;
  152. begin
  153. Abstract;
  154. end;
  155. {****************************************************************************
  156. TDOSScreen
  157. ****************************************************************************}
  158. {$ifdef DOS}
  159. constructor TDOSScreen.Init;
  160. begin
  161. inherited Init;
  162. Capture;
  163. end;
  164. destructor TDOSScreen.Done;
  165. begin
  166. inherited Done;
  167. FreeBuffer;
  168. end;
  169. function TDOSScreen.GetWidth: integer;
  170. begin
  171. GetWidth:=VideoInfo.Cols;
  172. end;
  173. function TDOSScreen.GetHeight: integer;
  174. begin
  175. GetHeight:=VideoInfo.Rows;
  176. end;
  177. procedure TDOSScreen.GetLine(Line: integer; var Text, Attr: string);
  178. var X: integer;
  179. W: word;
  180. begin
  181. Text:=''; Attr:='';
  182. if Line<GetHeight then
  183. begin
  184. W:=GetLineStartOfs(Line);
  185. for X:=0 to GetWidth-1 do
  186. begin
  187. Text:=Text+chr(VBuffer^[W+X*2]);
  188. Attr:=Attr+chr(VBuffer^[W+X*2+1]);
  189. end;
  190. end;
  191. end;
  192. procedure TDOSScreen.GetCursorPos(var P: TPoint);
  193. begin
  194. P:=VideoInfo.CurPos;
  195. end;
  196. procedure TDOSScreen.Capture;
  197. var
  198. VSeg,SOfs: word;
  199. begin
  200. GetVideoMode(VideoInfo);
  201. GetBuffer(VideoInfo.ScreenSize);
  202. if VideoInfo.Mode=7 then
  203. VSeg:=SegB000
  204. else
  205. VSeg:=SegB800;
  206. SOfs:=MemW[Seg0040:$4e];
  207. {$ifdef FPC}
  208. DosmemGet(VSeg,SOfs,VBuffer^,VideoInfo.ScreenSize);
  209. {$else}
  210. Move(ptr(VSeg,SOfs)^,VBuffer^,VideoInfo.ScreenSize);
  211. {$endif}
  212. end;
  213. procedure TDOSScreen.SwitchTo;
  214. var
  215. VSeg,SOfs: word;
  216. begin
  217. GetVideoMode(TM);
  218. SetVideoMode(VideoInfo);
  219. if VideoInfo.Mode=7 then
  220. VSeg:=SegB000
  221. else
  222. VSeg:=SegB800;
  223. SOfs:=MemW[Seg0040:$4e];
  224. {$ifdef FPC}
  225. DosmemPut(VSeg,SOfs,VBuffer^,VideoInfo.ScreenSize);
  226. {$else}
  227. Move(VBuffer^,ptr(VSeg,SOfs)^,VideoInfo.ScreenSize);
  228. {$endif}
  229. end;
  230. procedure TDOSScreen.SwitchBack;
  231. begin
  232. Capture;
  233. SetVideoMode(TM);
  234. end;
  235. function TDOSScreen.GetLineStartOfs(Line: integer): word;
  236. begin
  237. GetLineStartOfs:=(VideoInfo.Cols*Line)*2;
  238. end;
  239. procedure TDOSScreen.GetBuffer(Size: word);
  240. begin
  241. if (VBuffer<>nil) and (VBufferSize=Size) then Exit;
  242. if VBuffer<>nil then FreeBuffer;
  243. VBufferSize:=Size;
  244. GetMem(VBuffer,VBufferSize);
  245. end;
  246. procedure TDOSScreen.FreeBuffer;
  247. begin
  248. if (VBuffer<>nil) and (VBufferSize>0) then FreeMem(VBuffer,VBufferSize);
  249. VBuffer:=nil;
  250. end;
  251. procedure TDOSScreen.GetVideoMode(var MI: TDOSVideoInfo);
  252. var
  253. r: registers;
  254. {$ifdef TP}
  255. P: pointer;
  256. Sel: longint;
  257. (* {$I realintr.inc} *)
  258. {$endif}
  259. begin
  260. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  261. begin FreeMem(MI.StateBuf,MI.StateSize); MI.StateBuf:=nil; end;
  262. MI.ScreenSize:=MemW[Seg0040:$4c];
  263. r.ah:=$0f;
  264. intr($10,r);
  265. MI.Mode:=r.al;
  266. MI.Page:=r.bh;
  267. MI.Cols:=r.ah;
  268. MI.Rows:=MI.ScreenSize div (MI.Cols*2);
  269. r.ah:=$03;
  270. r.bh:=MI.Page;
  271. intr($10,r);
  272. with MI do
  273. begin
  274. CurPos.X:=r.dl; CurPos.Y:=r.dh;
  275. CurShapeT:=r.ch; CurShapeB:=r.cl;
  276. end;
  277. (*
  278. {$ifdef TP}
  279. { check VGA functions }
  280. MI.StateSize:=0;
  281. r.ah:=$1c; r.al:=0; r.cx:=7; intr($10,r);
  282. if (r.al=$1c) and ((r.flags and fCarry)=0) and (r.bx>0) then
  283. begin
  284. MI.StateSize:=r.bx;
  285. GetMem(MI.StateBuf,MI.StateSize); FillChar(MI.StateBuf^,MI.StateSize,0);
  286. P:=MI.StateBuf;
  287. {$ifdef DPMI}
  288. Sel:=GlobalDosAlloc(MI.StateSize);
  289. P:=Ptr(Sel shr 16,0);
  290. {$endif}
  291. r.ah:=$1c; r.al:=1; r.cx:=7;
  292. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  293. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  294. {$ifdef DPMI}
  295. Move(Ptr(Sel and $ffff,0)^,MI.StateBuf^,MI.StateSize);
  296. GlobalDosFree(Sel and $ffff);
  297. {$endif}
  298. end;
  299. {$endif}
  300. *)
  301. end;
  302. procedure TDOSScreen.SetVideoMode(MI: TDOSVideoInfo);
  303. var r: registers;
  304. {$ifdef TP}
  305. P: pointer;
  306. Sel: longint;
  307. {$I realintr.inc}
  308. {$endif}
  309. begin
  310. r.ah:=$0f;
  311. intr($10,r);
  312. if r.al<>MI.Mode then
  313. begin
  314. r.ah:=$00; r.al:=MI.Mode; intr($10,r);
  315. end;
  316. r.ah:=$05; r.al:=MI.Page; intr($10,r);
  317. r.ah:=$02; r.bh:=MI.Page; r.dl:=MI.CurPos.X; r.dh:=MI.CurPos.Y; intr($10,r);
  318. r.ah:=$01; r.ch:=MI.CurShapeT; r.cl:=MI.CurShapeB; intr($10,r);
  319. (*
  320. {$ifdef TP}
  321. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  322. begin
  323. P:=MI.StateBuf;
  324. {$ifdef DPMI}
  325. Sel:=GlobalDosAlloc(MI.StateSize);
  326. Move(MI.StateBuf^,ptr(Sel and $ffff,0)^,MI.StateSize);
  327. P:=Ptr(Sel shr 16,0);
  328. {$endif}
  329. r.ah:=$1c; r.al:=2; r.cx:=7;
  330. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  331. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  332. {$ifdef DPMI}
  333. GlobalDosFree(Sel and $ffff);
  334. {$endif}
  335. end;
  336. {$endif}
  337. *)
  338. end;
  339. {$endif}
  340. {****************************************************************************
  341. TLinuxScreen
  342. ****************************************************************************}
  343. {$ifdef Linux}
  344. constructor TLinuxScreen.Init;
  345. begin
  346. inherited Init;
  347. end;
  348. destructor TLinuxScreen.Done;
  349. begin
  350. inherited Done;
  351. end;
  352. function TLinuxScreen.GetWidth: integer;
  353. begin
  354. GetWidth:=ScreenWidth;
  355. end;
  356. function TLinuxScreen.GetHeight: integer;
  357. begin
  358. GetHeight:=ScreenHeight;
  359. end;
  360. procedure TLinuxScreen.GetLine(Line: integer; var Text, Attr: string);
  361. begin
  362. Text:='';
  363. Attr:='';
  364. end;
  365. procedure TLinuxScreen.GetCursorPos(var P: TPoint);
  366. begin
  367. P.X:=0;
  368. P.Y:=0;
  369. end;
  370. procedure TLinuxScreen.Capture;
  371. begin
  372. end;
  373. procedure TLinuxScreen.SwitchTo;
  374. begin
  375. end;
  376. procedure TLinuxScreen.SwitchBack;
  377. begin
  378. end;
  379. {$endif}
  380. {****************************************************************************
  381. TWin32Screen
  382. ****************************************************************************}
  383. {$ifdef win32}
  384. constructor TWin32Screen.Init;
  385. var
  386. SecurityAttr : Security_attributes;
  387. BigWin : Coord;
  388. res : boolean;
  389. Error : dword;
  390. begin
  391. inherited Init;
  392. SecurityAttr.nLength:=SizeOf(Security_attributes);
  393. SecurityAttr.lpSecurityDescriptor:=nil;
  394. SecurityAttr.bInheritHandle:=false;
  395. DosScreenBufferHandle:=CreateConsoleScreenBuffer(
  396. GENERIC_READ or GENERIC_WRITE,
  397. 0,SecurityAttr,
  398. CONSOLE_TEXTMODE_BUFFER,nil);
  399. IDEScreenBufferHandle:=GetStdHandle(STD_OUTPUT_HANDLE);
  400. {$ifdef win32bigwin}
  401. BigWin.X:=80;
  402. BigWin.Y:=50;
  403. SetConsoleScreenBufferSize(DosScreenBufferHandle,BigWin);
  404. SetConsoleScreenBufferSize(IDEScreenBufferHandle,BigWin);
  405. BigWin.X:=80;
  406. BigWin.Y:=50;
  407. { Try to allow to store more info }
  408. res:=SetConsoleScreenBufferSize(DosScreenBufferHandle,BigWin);
  409. if not res then
  410. error:=GetLastError;
  411. {$endif win32bigwin}
  412. Capture;
  413. SwitchBack;
  414. end;
  415. destructor TWin32Screen.Done;
  416. begin
  417. { copy the Dos buffer content into the original ScreenBuffer
  418. which remains the startup std_output_handle PM }
  419. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
  420. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  421. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  422. CloseHandle(DosScreenBufferHandle);
  423. inherited Done;
  424. end;
  425. function TWin32Screen.GetWidth: integer;
  426. var
  427. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  428. begin
  429. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  430. @ConsoleScreenBufferInfo);
  431. GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
  432. {GetWidth:=ScreenWidth;}
  433. end;
  434. function TWin32Screen.GetHeight: integer;
  435. var
  436. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  437. begin
  438. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  439. @ConsoleScreenBufferInfo);
  440. GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
  441. {GetHeight:=ScreenHeight;}
  442. end;
  443. procedure TWin32Screen.GetLine(Line: integer; var Text, Attr: string);
  444. type
  445. CharInfoArray = Array [0..255] of Char_Info;
  446. var
  447. LineBuf : ^CharInfoArray;
  448. BufSize,BufCoord : Coord;
  449. i,LineSize : longint;
  450. WriteRegion : SMALL_RECT;
  451. begin
  452. GetMem(LineBuf,SizeOf(CharInfoArray));
  453. LineSize:=ScreenWidth;
  454. If LineSize>256 then
  455. LineSize:=256;
  456. BufSize.X:=LineSize;
  457. BufSize.Y:=1;
  458. BufCoord.X:=0;
  459. BufCoord.Y:=0;
  460. with WriteRegion do
  461. begin
  462. Top :=Line;
  463. Left :=0;
  464. Bottom := Line+1;
  465. Right := LineSize-1;
  466. end;
  467. ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
  468. BufSize, BufCoord, @WriteRegion);
  469. for i:=1 to LineSize do
  470. begin
  471. Text[i]:=LineBuf^[i-1].AsciiChar;
  472. Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
  473. end;
  474. FreeMem(LineBuf,SizeOf(CharInfoArray));
  475. Text[0]:=char(byte(LineSize));
  476. Attr[0]:=char(byte(LineSize));
  477. end;
  478. procedure TWin32Screen.GetCursorPos(var P: TPoint);
  479. var
  480. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  481. begin
  482. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  483. @ConsoleScreenBufferInfo);
  484. P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
  485. P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
  486. end;
  487. procedure TWin32Screen.BufferCopy(Src, Dest : THandle);
  488. type
  489. CharInfoArray = Array [0..256*255-1] of Char_Info;
  490. var
  491. LineBuf : ^CharInfoArray;
  492. BufSize,BufCoord : Coord;
  493. LineSize : longint;
  494. WriteRegion : SMALL_RECT;
  495. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  496. begin
  497. GetMem(LineBuf,SizeOf(CharInfoArray));
  498. LineSize:=ScreenWidth;
  499. If LineSize>256 then
  500. LineSize:=256;
  501. BufSize.X:=LineSize;
  502. BufSize.Y:=ScreenHeight;
  503. BufCoord.X:=0;
  504. BufCoord.Y:=0;
  505. with WriteRegion do
  506. begin
  507. Top :=0;
  508. Left :=0;
  509. Bottom := ScreenHeight-1;
  510. Right := LineSize-1;
  511. end;
  512. ReadConsoleOutput(Src, PChar_info(LineBuf),
  513. BufSize, BufCoord, @WriteRegion);
  514. WriteConsoleOutput(Dest, PChar_info(LineBuf)^,
  515. BufSize, BufCoord, @WriteRegion);
  516. FreeMem(LineBuf,SizeOf(CharInfoArray));
  517. GetConsoleScreenBufferInfo(Src,
  518. @ConsoleScreenBufferInfo);
  519. SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
  520. end;
  521. procedure TWin32Screen.Capture;
  522. begin
  523. BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle);
  524. end;
  525. procedure TWin32Screen.SwitchTo;
  526. begin
  527. SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
  528. SetStdHandle(Std_Output_Handle,DosScreenBufferHandle);
  529. IDEActive:=false;
  530. end;
  531. procedure TWin32Screen.SwitchBack;
  532. begin
  533. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  534. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  535. IDEActive:=true;
  536. end;
  537. {$endif}
  538. {****************************************************************************
  539. Initialize
  540. ****************************************************************************}
  541. procedure InitUserScreen;
  542. begin
  543. {$ifdef DOS}
  544. UserScreen:=New(PDOSScreen, Init);
  545. {$else}
  546. {$ifdef LINUX}
  547. UserScreen:=New(PLinuxScreen, Init);
  548. {$else}
  549. {$ifdef Win32}
  550. UserScreen:=New(PWin32Screen, Init);
  551. {$else}
  552. UserScreen:=New(PScreen, Init);
  553. {$endif Win32}
  554. {$endif Linux}
  555. {$endif Dos}
  556. end;
  557. procedure DoneUserScreen;
  558. begin
  559. if UserScreen<>nil then
  560. begin
  561. UserScreen^.SwitchTo;
  562. Dispose(UserScreen, Done);
  563. UserScreen:=nil;
  564. end;
  565. end;
  566. end.
  567. {
  568. $Log$
  569. Revision 1.9 2000-02-04 23:17:25 pierre
  570. * Keep the entry ScreenBuffer at exit
  571. Revision 1.8 1999/12/01 16:17:18 pierre
  572. * Restore std_output_handle correctly at exit for GDB
  573. Revision 1.7 1999/11/10 17:12:00 pierre
  574. * Win32 screen problems solved
  575. Revision 1.6 1999/09/22 13:02:00 pierre
  576. + Twin32Screen added
  577. Revision 1.5 1999/08/16 18:25:24 peter
  578. * Adjusting the selection when the editor didn't contain any line.
  579. * Reserved word recognition redesigned, but this didn't affect the overall
  580. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  581. The syntax scanner loop is a bit slow but the main problem is the
  582. recognition of special symbols. Switching off symbol processing boosts
  583. the performance up to ca. 200%...
  584. * The editor didn't allow copying (for ex to clipboard) of a single character
  585. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  586. * Compiler Messages window (actually the whole desktop) did not act on any
  587. keypress when compilation failed and thus the window remained visible
  588. + Message windows are now closed upon pressing Esc
  589. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  590. only when neccessary
  591. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  592. + LineSelect (Ctrl+K+L) implemented
  593. * The IDE had problems closing help windows before saving the desktop
  594. Revision 1.4 1999/06/28 19:32:25 peter
  595. * fixes from gabor
  596. Revision 1.3 1999/02/02 16:41:42 peter
  597. + automatic .pas/.pp adding by opening of file
  598. * better debuggerscreen changes
  599. Revision 1.2 1999/01/04 11:49:51 peter
  600. * 'Use tab characters' now works correctly
  601. + Syntax highlight now acts on File|Save As...
  602. + Added a new class to syntax highlight: 'hex numbers'.
  603. * There was something very wrong with the palette managment. Now fixed.
  604. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  605. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  606. process revised
  607. Revision 1.1 1998/12/28 15:47:53 peter
  608. + Added user screen support, display & window
  609. + Implemented Editor,Mouse Options dialog
  610. + Added location of .INI and .CFG file
  611. + Option (INI) file managment implemented (see bottom of Options Menu)
  612. + Switches updated
  613. + Run program
  614. Revision 1.0 1998/12/24 09:55:49 gabor
  615. Original implementation
  616. }