home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l040 / 13.ddi / RTLOWL.ZIP / OSTDWNDS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-28  |  14.4 KB  |  520 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Turbo Pascal for Windows                        }
  5. {       Standard windows unit for ObjectWindows         }
  6. {                                                       }
  7. {       Copyright (c) 1991 Borland International        }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit OStdWnds;
  12.  
  13. {$R OSTDWNDS.RES}
  14.  
  15. interface
  16.  
  17. uses WinTypes, WinProcs, WinDos, Objects, OWindows, ODialogs,
  18.   OMemory, OStdDlgs, Strings;
  19.  
  20. type
  21.  
  22.   { TSearchRec }
  23.   TSearchRec = record
  24.     SearchText: array[0..80] of Char;
  25.     CaseSensitive: Bool;
  26.     ReplaceText: array[0..80] of Char;
  27.     ReplaceAll: Bool;
  28.     PromptOnReplace: Bool;
  29.     IsReplace: Boolean;
  30.   end;
  31.  
  32.   { TEditWindow  }
  33.   PEditWindow = ^TEditWindow;
  34.   TEditWindow = object(TWindow)
  35.     Editor: PEdit;
  36.     SearchRec: TSearchRec;
  37.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  38.     constructor Load(var S: TStream);
  39.     procedure Store(var S: TStream);
  40.     procedure WMSize(var Msg: TMessage);
  41.       virtual wm_First + wm_Size;
  42.     procedure WMSetFocus(var Msg: TMessage);
  43.       virtual wm_First + wm_SetFocus;
  44.     procedure CMEditFind(var Msg: TMessage);
  45.       virtual cm_First + cm_EditFind;
  46.     procedure CMEditFindNext(var Msg: TMessage);
  47.       virtual cm_First + cm_EditFindNext;
  48.     procedure CMEditReplace(var Msg: TMessage);
  49.       virtual cm_First + cm_EditReplace;
  50.   private
  51.     procedure DoSearch;
  52.   end;
  53.  
  54.   { TFileWindow }
  55.   PFileWindow = ^TFileWindow;
  56.   TFileWindow = object(TEditWindow)
  57.     FileName: PChar;
  58.     IsNewFile: Boolean;
  59.     constructor Init(AParent: PWindowsObject; ATitle, AFileName: PChar);
  60.     destructor Done; virtual;
  61.     constructor Load(var S: TStream);
  62.     procedure Store(var S: TStream);
  63.     function CanClear: Boolean; virtual;
  64.     function CanClose: Boolean; virtual;
  65.     procedure NewFile;
  66.     procedure Open;
  67.     procedure Read;
  68.     procedure SetFileName(AFileName: PChar);
  69.     procedure ReplaceWith(AFileName: PChar);
  70.     function Save: Boolean;
  71.     function SaveAs: Boolean;
  72.     procedure SetupWindow; virtual;
  73.     procedure Write;
  74.     procedure CMFileNew(var Msg: TMessage);
  75.       virtual cm_First + cm_FileNew;
  76.     procedure CMFileOpen(var Msg: TMessage);
  77.       virtual cm_First + cm_FileOpen;
  78.     procedure CMFileSave(var Msg: TMessage);
  79.       virtual cm_First + cm_FileSave;
  80.     procedure CMFileSaveAs(var Msg: TMessage);
  81.       virtual cm_First + cm_FileSaveAs;
  82.   end;
  83.  
  84. const
  85.   REditWindow: TStreamRec = (
  86.     ObjType: 80;
  87.     VmtLink: Ofs(TypeOf(TEditWindow)^);
  88.     Load:    @TEditWindow.Load;
  89.     Store:   @TEditWindow.Store);
  90.  
  91. const
  92.   RFileWindow: TStreamRec = (
  93.     ObjType: 81;
  94.     VmtLink: Ofs(TypeOf(TFileWindow)^);
  95.     Load:    @TFileWindow.Load;
  96.     Store:   @TFileWindow.Store);
  97.  
  98. procedure RegisterStdWnds;
  99.  
  100. implementation
  101.  
  102. { TSearchDialog }
  103.  
  104. const
  105.   sd_Search          = MakeIntResource($7F10);
  106.   sd_Replace         = MakeIntResource($7F11);
  107.   sd_BCSearch        = MakeIntResource($7F12);
  108.   sd_BCReplace       = MakeIntResource($7F13);
  109.   id_SearchText      = 100;
  110.   id_CaseSensitive   = 101;
  111.   id_ReplaceText     = 102;
  112.   id_ReplaceAll      = 103;
  113.   id_PromptOnReplace = 104;
  114.  
  115. type
  116.   PSearchDialog = ^TSearchDialog;
  117.   TSearchDialog = object(TDialog)
  118.     constructor Init(AParent: PWindowsObject; Template: PChar;
  119.       var SearchRec: TSearchRec);
  120.   end;
  121.  
  122. constructor TSearchDialog.Init(AParent: PWindowsObject; Template: PChar;
  123.   var SearchRec: TSearchRec);
  124. var
  125.   C: PWindowsObject;
  126. begin
  127.   TDialog.Init(AParent, Template);
  128.   C := New(PEdit, InitResource(@Self, id_SearchText,
  129.     SizeOf(SearchRec.SearchText)));
  130.   C := New(PCheckBox, InitResource(@Self, id_CaseSensitive));
  131.   if (Template = sd_Replace) or (Template = sd_BCReplace) then
  132.   begin
  133.     C := New(PEdit, InitResource(@Self, id_ReplaceText,
  134.       SizeOf(SearchRec.ReplaceText)));
  135.     C := New(PCheckBox, InitResource(@Self, id_ReplaceAll));
  136.     C := New(PCheckBox, InitResource(@Self, id_PromptOnReplace));
  137.   end;
  138.   TransferBuffer := @SearchRec;
  139. end;
  140.  
  141. { TEditWindow }
  142.  
  143. { Constructor for a TEditWindow.  Initializes its data fields using passed
  144.   parameters and default values.  Constructs its child edit control. }
  145. constructor TEditWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  146. begin
  147.   TWindow.Init(AParent, ATitle);
  148.   Editor := New(PEdit, Init(@Self, 200, nil, 0, 0, 0, 0, 0, True));
  149.   with Editor^.Attr do
  150.     Style := Style or es_NoHideSel;
  151.   FillChar(SearchRec, SizeOf(SearchRec), #0);
  152. end;
  153.  
  154. { Load a TEditWindow from the given stream }
  155. constructor TEditWindow.Load(var S: TStream);
  156. begin
  157.   TWindow.Load(S);
  158.   GetChildPtr(S, Editor);
  159. end;
  160.  
  161. { Store a TEditWindow to the given stream }
  162. procedure TEditWindow.Store(var S: TStream);
  163. begin
  164.   TWindow.Store(S);
  165.   PutChildPtr(S, Editor);
  166. end;
  167.  
  168. { Responds to an incoming wm_Size message by resizing the child edit
  169.   control according to the size of the TEditWindow's client area. }
  170. procedure TEditWindow.WMSize(var Msg: TMessage);
  171. begin
  172.   TWindow.WMSize(Msg);
  173.   SetWindowPos(Editor^.HWindow, 0, -1, -1, Msg.LParamLo+2, Msg.LParamHi+2,
  174.     swp_NoZOrder);
  175. end;
  176.  
  177. { Responds to an incoming wm_SetFocus message by setting the focus to the
  178.   child edit control. }
  179. procedure TEditWindow.WMSetFocus(var Msg: TMessage);
  180. begin
  181.   SetFocus(Editor^.HWindow);
  182. end;
  183.  
  184. procedure TEditWindow.DoSearch;
  185. var
  186.   S: array[0..80] of Char;
  187.   P: Pointer;
  188.   Rslt: Integer;
  189. begin
  190.   Rslt := 0;
  191.   with SearchRec do
  192.     repeat
  193.       Rslt := Editor^.Search(-1, SearchText, CaseSensitive);
  194.       if Rslt = -1 then
  195.       begin
  196.         if not IsReplace or not ReplaceAll then
  197.         begin
  198.           P := @SearchText;
  199.           WVSPrintF(S, '"%0.60s" not found.', P);
  200.           MessageBox(HWindow, S, 'Find error', mb_OK + mb_IconExclamation);
  201.         end;
  202.       end
  203.       else
  204.         if IsReplace then
  205.           if not PromptOnReplace then Editor^.Insert(ReplaceText)
  206.           else
  207.           begin
  208.             Rslt := MessageBox(HWindow, 'Replace this occurrence?',
  209.               'Search/Replace', mb_YesNoCancel + mb_IconQuestion);
  210.             if Rslt = id_Yes then Editor^.Insert(ReplaceText)
  211.             else if Rslt = id_Cancel then Exit;
  212.           end;
  213.     until (Rslt = -1) or not ReplaceAll or not IsReplace;
  214. end;
  215.  
  216. procedure TEditWindow.CMEditFind(var Msg: TMessage);
  217. var
  218.   Dialog: PChar;
  219. begin
  220.   if BWCCClassNames then
  221.     Dialog := sd_BCSearch
  222.   else
  223.     Dialog := sd_Search;
  224.   if Application^.ExecDialog(New(PSearchDialog, Init(@Self,
  225.     Dialog, SearchRec))) = id_OK then
  226.   begin
  227.     SearchRec.IsReplace := False;
  228.     DoSearch;
  229.   end;
  230. end;
  231.  
  232. procedure TEditWindow.CMEditFindNext(var Msg: TMessage);
  233. begin
  234.   DoSearch;
  235. end;
  236.  
  237. procedure TEditWindow.CMEditReplace(var Msg: TMessage);
  238. var
  239.   Dialog: PChar;
  240. begin
  241.   if BWCCClassNames then
  242.     Dialog := sd_BCReplace
  243.   else
  244.     Dialog := sd_Replace;
  245.   if Application^.ExecDialog(New(PSearchDialog, Init(@Self,
  246.     Dialog, SearchRec))) = id_OK then
  247.   begin
  248.     SearchRec.IsReplace := True;
  249.     DoSearch;
  250.   end;
  251. end;
  252.  
  253. { TFileWindow }
  254.  
  255. { Constructor for a TFileWindow.  Initializes its data fields using
  256.   passed parameters and default values. }
  257. constructor TFileWindow.Init(AParent: PWindowsObject; ATitle,
  258.   AFileName: PChar);
  259. begin
  260.   TEditWindow.Init(AParent, ATitle);
  261.   IsNewFile := True;
  262.   FileName := StrNew(AFileName);
  263. end;
  264.  
  265. { Dispose of the file name }
  266. destructor TFileWindow.Done;
  267. begin
  268.   StrDispose(FileName);
  269.   TEditWindow.Done;
  270. end;
  271.  
  272. { Load a TFileWindow from the stream }
  273. constructor TFileWindow.Load(var S: TStream);
  274. begin
  275.   TEditWindow.Load(S);
  276.   FileName := S.StrRead;
  277.   IsNewFile := FileName = nil;
  278. end;
  279.  
  280. { Store a TFileWindow from the stream }
  281. procedure TFileWindow.Store(var S: TStream);
  282. begin
  283.   TEditWindow.Store(S);
  284.   S.StrWrite(FileName);
  285. end;
  286.  
  287. { Performs setup for a TFileWindow, appending 'Untitled' to its caption }
  288. procedure TFileWindow.SetupWindow;
  289. begin
  290.   TEditWindow.SetupWindow;
  291.   SetFileName(FileName);
  292.   if FileName <> nil then Read;
  293. end;
  294.  
  295. { Sets the file name of the window and updates the caption.  Assumes
  296.   that the AFileName parameter and the FileName instance variable were
  297.   allocated by StrNew. }
  298. procedure TFileWindow.SetFileName(AFileName: PChar);
  299. var
  300.   NewCaption: array[0..80] of Char;
  301.   P: array[0..1] of PChar;
  302. begin
  303.   if FileName <> AFileName then
  304.   begin
  305.     StrDispose(FileName);
  306.     FileName := StrNew(AFileName);
  307.   end;
  308.   P[0] := Attr.Title;
  309.   if FileName = nil then P[1] := '(Untitled)'
  310.   else P[1] := AFileName;
  311.   if Attr.Title = nil then SetWindowText(HWindow, P[1])
  312.   else
  313.   begin
  314.     WVSPrintF(NewCaption, '%0.40s - %0.37s', P[0]);
  315.     SetWindowText(HWindow, NewCaption);
  316.   end;
  317. end;
  318.  
  319. { Begins the edit of a new file, after determining that it is Ok to
  320.   clear the TEdit's text. }
  321. procedure TFileWindow.NewFile;
  322. begin
  323.   if CanClear then
  324.   begin
  325.     Editor^.Clear;
  326.     InvalidateRect(Editor^.HWindow, nil, False);
  327.     Editor^.ClearModify;
  328.     IsNewFile := True;
  329.     SetFileName(nil);
  330.   end;
  331. end;
  332.  
  333. { Replaces the current file with the given file. }
  334. procedure TFileWindow.ReplaceWith(AFileName: PChar);
  335. begin
  336.   SetFileName(AFileName);
  337.   Read;
  338.   InvalidateRect(Editor^.HWindow, nil, False);
  339. end;
  340.  
  341. { Brings up a dialog allowing the user to open a file into this
  342.   window.  Save as selecting File|Open from the menus. }
  343. procedure TFileWindow.Open;
  344. var
  345.   TmpName: array[0..fsPathName] of Char;
  346. begin
  347.   if CanClear and (Application^.ExecDialog(New(PFileDialog,
  348.      Init(@Self, PChar(sd_FileOpen), StrCopy(TmpName, '*.*')))) = id_Ok) then
  349.     ReplaceWith(TmpName);
  350. end;
  351.  
  352. { Reads the contents of a previously-specified file into the TEdit
  353.   child control. }
  354. procedure TFileWindow.Read;
  355. const
  356.   BufferSize = 1024;
  357. var
  358.   CharsToRead: LongInt;
  359.   BlockSize: Integer;
  360.   AStream: PDosStream;
  361.   ABuffer: PChar;
  362. begin
  363.   AStream := New(PDosStream, Init(FileName, stOpen));
  364.   ABuffer := MemAlloc(BufferSize + 1);
  365.   CharsToRead := AStream^.GetSize;
  366.   if ABuffer <> nil then
  367.   begin
  368.     Editor^.Clear;
  369.     while CharsToRead > 0 do
  370.     begin
  371.       if CharsToRead > BufferSize then
  372.         BlockSize := BufferSize
  373.       else BlockSize := CharsToRead;
  374.       AStream^.Read(ABuffer^, BlockSize);
  375.       ABuffer[BlockSize] := Char(0);
  376.       Editor^.Insert(ABuffer);
  377.       CharsToRead := CharsToRead - BlockSize;
  378.     end;
  379.     IsNewFile := False;
  380.     Editor^.ClearModify;
  381.     Editor^.SetSelection(0, 0);
  382.     FreeMem(ABuffer, BufferSize + 1);
  383.   end;
  384.   Dispose(AStream, Done);
  385. end;
  386.  
  387. { Saves the contents of the TEdit child control into the file currently
  388.   being editted.  Returns true if the file was saved. }
  389. function TFileWindow.Save: Boolean;
  390. begin
  391.   Save := True;
  392.   if Editor^.IsModified then
  393.     if IsNewFile then Save := SaveAs
  394.     else Write;
  395. end;
  396.  
  397. { Saves the contents of the TEdit child control into a file whose name
  398.   is retrieved from the user, through execution of a "Save" file
  399.   dialog.  Returns true if the file was saved. }
  400. function TFileWindow.SaveAs: Boolean;
  401. var
  402.   TmpName: array[0..fsPathName] of Char;
  403. begin
  404.   SaveAs := False;
  405.   if FileName <> nil then StrCopy(TmpName, FileName)
  406.   else TmpName[0] := #0;
  407.   if Application^.ExecDialog(New(PFileDialog,
  408.       Init(@Self, PChar(sd_FileSave), TmpName))) = id_Ok then
  409.   begin
  410.     SetFileName(TmpName);
  411.     Write;
  412.     SaveAs := True;
  413.   end;
  414. end;
  415.  
  416. { Writes the contents of the TEdit child control to a previously-specified
  417.   file.  If the operation will cause truncation of the text, first confirms
  418.   (through displaying a message box) that it is OK to proceed. }
  419. procedure TFileWindow.Write;
  420. const
  421.   BufferSize = 1024;
  422. var
  423.   CharsToWrite, CharsWritten: LongInt;
  424.   BlockSize: Integer;
  425.   AStream: PDosStream;
  426.   ABuffer: pointer;
  427.   NumLines: Integer;
  428. begin
  429.   NumLines := Editor^.GetNumLines;
  430.   CharsToWrite := Editor^.GetLineIndex(NumLines-1) +
  431.     Editor^.GetLineLength(NumLines-1);
  432.   AStream := New(PDosStream, Init(FileName, stCreate));
  433.   ABuffer := MemAlloc(BufferSize + 1);
  434.   CharsWritten := 0;
  435.   if ABuffer <> nil then
  436.   begin
  437.     while CharsWritten < CharsToWrite do
  438.     begin
  439.       if CharsToWrite - CharsWritten > BufferSize then
  440.         BlockSize := BufferSize
  441.       else BlockSize := CharsToWrite - CharsWritten;
  442.       Editor^.GetSubText(ABuffer, CharsWritten, CharsWritten + BlockSize);
  443.       AStream^.Write(ABuffer^, BlockSize);
  444.       CharsWritten := CharsWritten + BlockSize;
  445.     end;
  446.     IsNewFile := False;
  447.     Editor^.ClearModify;
  448.     FreeMem(ABuffer, BufferSize + 1);
  449.   end;
  450.   Dispose(AStream, Done);
  451. end;
  452.  
  453. { Returns a Boolean value indicating whether or not it is Ok to clear
  454.   the TEdit's text.  Returns True if the text has not been changed, or
  455.   if the user Oks the clearing of the text. }
  456. function TFileWindow.CanClear: Boolean;
  457. var
  458.   S: array[0..fsPathName+27] of Char;
  459.   P: PChar;
  460.   Rslt: Integer;
  461. begin
  462.   CanClear := True;
  463.   if Editor^.IsModified then
  464.   begin
  465.     if FileName = nil then StrCopy(S, 'Untitled file has changed. Save?')
  466.     else
  467.     begin
  468.       P := FileName;
  469.       WVSPrintF(S, 'File "%s" has changed.  Save?', P);
  470.     end;
  471.     Rslt := MessageBox(HWindow, S, 'File Changed', mb_YesNoCancel or
  472.       mb_IconQuestion);
  473.     if Rslt = id_Yes then CanClear := Save
  474.     else CanClear := Rslt <> id_Cancel;
  475.   end;
  476. end;
  477.  
  478. { Returns a Boolean value indicating whether or not it is Ok to close
  479.   the TEdit's text.  Returns the result of a call to Self.CanClear. }
  480. function TFileWindow.CanClose: Boolean;
  481. begin
  482.   CanClose := CanClear;
  483. end;
  484.  
  485. { Responds to an incoming "New" command (with a cm_FileNew command
  486.   identifier) by calling Self.New. }
  487. procedure TFileWindow.CMFileNew(var Msg: TMessage);
  488. begin
  489.   NewFile;
  490. end;
  491.  
  492. { Responds to an incoming "Open" command (with a cm_FileOpen command
  493.   identifier) by calling Self.Open. }
  494. procedure TFileWindow.CMFileOpen(var Msg: TMessage);
  495. begin
  496.   Open;
  497. end;
  498.  
  499. { Responds to an incoming "Save" command (with a cm_FileSave command
  500.   identifier) by calling Self.Save. }
  501. procedure TFileWindow.CMFileSave(var Msg: TMessage);
  502. begin
  503.   Save;
  504. end;
  505.  
  506. { Responds to an incoming "SaveAs" command (with a cm_FileSaveAs command
  507.   identifier) by calling Self.SaveAs. }
  508. procedure TFileWindow.CMFileSaveAs(var Msg: TMessage);
  509. begin
  510.   SaveAs;
  511. end;
  512.  
  513. procedure RegisterStdWnds;
  514. begin
  515.   RegisterType(REditWindow);
  516.   RegisterType(RFileWindow);
  517. end;
  518.  
  519. end.
  520.