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