home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / wksinst / rwpdemo.pak / RWPWND.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-09-09  |  25.5 KB  |  1,041 lines

  1. {   Copyright (c) 1991 by Borland International }
  2.  
  3. unit RWPWnd;
  4.  
  5. interface
  6.  
  7. {$ifdef BWCC}
  8. uses RWPDlgs, WinProcs, WinTypes, WObjectB, Strings, StdDlgsB, RWPDemoC, WinDOS, bwcc;
  9. {$else}
  10. uses RWPDlgs, WinProcs, WinTypes, WObjects, Strings, StdDlgs, RWPDemoC, WinDOS;
  11. {$endif}
  12.  
  13. type
  14.   PBaseMDIChildWindow = ^TBaseMDIChildWindow;
  15.   TBaseMDIChildWindow = object(TWindow)
  16.     TheMenu: HMenu;
  17.     constructor Init(aParent: PWindowsObject; ATitle: PChar);
  18.     function GetPopupMenu: HMenu; virtual;
  19.     function GetPopupTitle: PChar; virtual;
  20.     procedure SetEditPopup(Style: Word);
  21.     procedure WMMDIActivate(var Msg: TMessage); virtual wm_MDIActivate;
  22.     procedure WMRButtonDown(var Msg: TMessage); virtual wm_RButtonUp;
  23.   end;
  24.  
  25.   { TDocument }
  26.   PDocument = ^TDocument;
  27.   TDocument = object(TBaseMDIChildWindow)
  28.     Changed: Boolean;
  29.     FileName: PChar;
  30.     IsNewFile: Boolean;
  31.  
  32.     constructor Init(AParent: PWindowsObject; AFileName: PChar);
  33.     constructor Load(var S: TStream);
  34.     destructor Done; virtual;
  35.     function CanClear: Boolean; virtual;
  36.     function CanClose: Boolean; virtual;
  37.     procedure ClearModify;
  38.     procedure ClearWindow; virtual;
  39.     procedure CMFileSave(var Msg: TMessage); virtual cm_First + cm_Save;
  40.     procedure CMFileSaveAs(var Msg: TMessage); virtual cm_First + cm_SaveAs;
  41.     function IsModified: Boolean; virtual;
  42.     procedure Read; virtual;
  43.     function Save: Boolean; virtual;
  44.     function SaveAs: Boolean; virtual;
  45.     procedure SetFileName(AFileName: PChar);
  46.     procedure SetupWindow; virtual;
  47.     procedure Store(var S: TStream);
  48.     procedure Write; virtual;
  49.   end;
  50.  
  51.   { TEditWindow  }
  52.   PEditWindow = ^TEditWindow;
  53.   TEditWindow = object(TDocument)
  54.     Editor: PEdit;
  55.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  56.     constructor Load(var S: TStream);
  57.     procedure ClearModify; virtual;
  58.     procedure ClearWindow; virtual;
  59.     function IsModified: Boolean; virtual;
  60.     procedure Read; virtual;
  61.     procedure Store(var S: TStream);
  62.     procedure WMSize(var Msg: TMessage); virtual wm_First + wm_Size;
  63.     procedure WMSetFocus(var Msg: TMessage); virtual wm_First + wm_SetFocus;
  64.     procedure Write; virtual;
  65.   end;
  66.  
  67.  
  68. type
  69.   PGraphObject = ^TGraphObject;
  70.   TGraphObject = object(TObject)
  71.     X1, Y1, X2, Y2: Integer;
  72.     TheColor: TColorRef;
  73.     ThePen: THandle;
  74.     OldPen: THandle;
  75.     constructor Init(R: TRect; AColor: TColorRef);
  76.     constructor Load(var S: TStream);
  77.     procedure Assign(R: TRect);
  78.     procedure Draw(HandleDC: HDC); virtual;
  79.     procedure DrawRect(HandleDC: HDC; R: TRect);
  80.     procedure EndDraw(HandleDC: HDC);
  81.     procedure Store(var S: TStream);
  82.   end;
  83.  
  84.   PRectangle = ^TRectangle;
  85.   TRectangle = object(TGraphObject)
  86.     procedure Draw(HandleDC: HDC); virtual;
  87.   end;
  88.  
  89.   PCircle = ^TCircle;
  90.   TCircle = object(TGraphObject)
  91.     procedure Draw(HandleDC: HDC); virtual;
  92.   end;
  93.  
  94. const
  95.   ShapeCircle = 1;
  96.   ShapeRectangle = 2;
  97.  
  98. type
  99.   PGraphWindow = ^TGraphWindow;
  100.   TGraphWindow = object(TDocument)
  101.     ButtonDown: Boolean;
  102.     CurrentShape: PGraphObject;
  103.     HandleDC: HDC;
  104.     MenuShape: Integer;
  105.     MenuColor: TColorRef;
  106.     OldROP: Word;
  107.     Rect: TRect;
  108.     TheShapes: PCollection;
  109.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  110.     destructor Done; virtual;
  111.     procedure Clear; virtual;
  112.     procedure CMBlue(var Msg: TMessage); virtual cm_First + cm_Blue;
  113.     procedure CMCircle(var Msg: TMessage); virtual cm_First + cm_Circle;
  114.     procedure CMClear(var Msg: TMessage); virtual cm_First + cm_ClearShape;
  115.     procedure CMGreen(var Msg: TMessage); virtual cm_First + cm_Green;
  116.     procedure CMRectangle(var Msg: TMessage); virtual cm_First + cm_Rectangle;
  117.     procedure CMRed(var Msg: TMessage); virtual cm_First + cm_Red;
  118.     function GetPopupMenu: HMenu; virtual;
  119.     function GetPopupTitle: PChar; virtual;
  120.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  121.     procedure Read; virtual;
  122.     procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown;
  123.     procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp;
  124.     procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove;
  125.     procedure Write; virtual;
  126.   end;
  127.  
  128. type
  129.   PPointCollection = ^TPointCollection;
  130.   TPointCollection = object(TCollection)
  131.     destructor Done; virtual;
  132.     function GetItem(var S: TStream): Pointer; virtual;
  133.     procedure PutItem(var S: TStream; Item: Pointer); virtual;
  134.   end;
  135.  
  136. type
  137.   PLine = ^TLine;
  138.   TLine = object(TObject)
  139.     X,Y: Integer;
  140.     LineColor: TColorRef;
  141.     PointCollection: PPointCollection;
  142.     LineThickness: Byte;
  143.     constructor Init(AColor: TColorRef; AThickness: Byte);
  144.     constructor Load(var S: TStream);
  145.     destructor Done; virtual;
  146.     procedure Store(var S: TStream);
  147.   end;
  148.  
  149. type
  150.   PScribbleWindow = ^TScribbleWindow;
  151.   TScribbleWindow = object(TDocument)
  152.     ButtonDown: Boolean;
  153.     CurrentLine: PLine;
  154.     HandleDC: HDC;
  155.     LineCollection: PCollection;
  156.     MenuColor: TColorRef;
  157.     MenuThickness: Byte;
  158.     OldPen: THandle;
  159.  
  160.     constructor Init(aParent: PWindowsObject; ATitle: PChar);
  161.     constructor Load(var S: TStream);
  162.     destructor Done; virtual;
  163.     procedure Clear; virtual;
  164.     procedure CMBlue(var Msg: TMessage); virtual cm_First + cm_Blue;
  165.     procedure CMClear(var Msg: TMessage); virtual cm_First + cm_ClearShape;
  166.     procedure CMGreen(var Msg: TMessage); virtual cm_First + cm_Green;
  167.     procedure CMNormal(var Msg: TMessage); virtual cm_First + cm_Normal;
  168.     procedure CMRed(var Msg: TMessage); virtual cm_First + cm_Red;
  169.     procedure CMThick(var Msg: TMessage); virtual cm_First + cm_Thick;
  170.     procedure CMThin(var Msg: TMessage); virtual cm_First + cm_Thin;
  171.     function GetPopupMenu: HMenu; virtual;
  172.     function GetPopupTitle: PChar; virtual;
  173.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  174.     procedure Read; virtual;
  175.     procedure Store(var S: TStream); virtual;
  176.     procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown;
  177.     procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp;
  178.     procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove;
  179.     procedure Write; virtual;
  180.   end;
  181.  
  182. implementation
  183.  
  184. function Min(a, b: Word): Word;
  185. begin
  186.   if a < b then Min := a
  187.   else Min := b;
  188. end;
  189.  
  190. function Max(a, b: Word): Word;
  191. begin
  192.   if a > b then Max := a
  193.   else Max := b;
  194. end;
  195.  
  196. {---------------- TBaseMDIChildWindow implementation ------------------}
  197.  
  198. constructor TBaseMDIChildWindow.Init(aParent: PWindowsObject; ATitle: PChar);
  199. begin
  200.   TWindow.Init(aParent, ATitle);
  201.   TheMenu := 0;
  202. end;
  203.  
  204. function TBaseMDIChildWindow.GetPopupMenu: HMenu;
  205. begin
  206.   GetPopupMenu := 0;
  207. end;
  208.  
  209. function TBaseMDIChildWindow.GetPopupTitle: PChar;
  210. begin
  211.   GetPopupTitle := nil;
  212. end;
  213.  
  214. procedure TBaseMDIChildWindow.SetEditPopup(Style: Word);
  215. var
  216.   AMenu: HMenu;
  217. begin
  218.   AMenu := GetMenu(Application^.MainWindow^.HWindow);
  219.   EnableMenuItem(AMenu, cm_Undo, mf_ByCommand or Style);
  220.   EnableMenuItem(AMenu, cm_Cut, mf_ByCommand or Style);
  221.   EnableMenuItem(AMenu, cm_Copy, mf_ByCommand or Style);
  222.   EnableMenuItem(AMenu, cm_Paste, mf_ByCommand or Style);
  223.   EnableMenuItem(AMenu, cm_Clear, mf_ByCommand or Style);
  224.   EnableMenuItem(AMenu, cm_Delete, mf_ByCommand or Style);
  225. end;
  226.  
  227. procedure TBaseMDIChildWindow.WMMDIActivate(var Msg: TMessage);
  228. begin
  229.   if Typeof(Self) = TypeOf(TEditWindow) then SetEditPopup(mf_Enabled)
  230.   else SetEditPopup(mf_Grayed);
  231. end;
  232.  
  233. procedure TBaseMDIChildWindow.WMRButtonDown(var Msg: TMessage);
  234. var
  235.   AMenu: HMenu;
  236.   AName: PChar;
  237. begin
  238.   AMenu := CreatePopupMenu;
  239.   AName := GetPopupTitle;
  240.  
  241.   if AName <> nil then
  242.   begin
  243.     AppendMenu(AMenu, mf_Popup, GetPopupMenu, AName);
  244.     ClientToScreen(HWindow, MakePoint(Msg.LParam));
  245.     TrackPopupMenu(AMenu, 0, Msg.LParamLo, Msg.LParamHi, 0, HWindow, nil);
  246.     DestroyMenu(AMenu);
  247.   end;
  248. end;
  249.  
  250. {------------------------- TDocument Implementation ---------------------}
  251. constructor TDocument.Init(AParent: PWindowsObject; AFileName: PChar);
  252. begin
  253.   TBaseMDIChildWindow.Init(AParent, AFileName);
  254.   IsNewFile := True;
  255.   Changed := False;
  256.   FileName := StrNew(AFileName);
  257. end;
  258.  
  259. constructor TDocument.Load(var S: TStream);
  260. begin
  261.   TBaseMDIChildWindow.Load(S);
  262.   FileName := S.StrRead;
  263.   IsNewFile := FileName = nil;
  264. end;
  265.  
  266. destructor TDocument.Done;
  267. begin
  268.   StrDispose(FileName);
  269.   TBaseMDIChildWindow.Done;
  270. end;
  271.  
  272. function TDocument.CanClear: Boolean;
  273. var
  274.   S: array[0..fsPathName+27] of Char;
  275.   P: PChar;
  276.   Rslt: Integer;
  277. begin
  278.   CanClear := True;
  279.   if IsModified then
  280.   begin
  281.     if FileName = nil then StrCopy(S, 'Untitled file has changed. Save?')
  282.     else
  283.     begin
  284.       P := FileName;
  285.       WVSPrintF(S, 'File "%s" has changed.  Save?', P);
  286.     end;
  287. {$ifdef BWCC}
  288.     Rslt := BWCCMessageBox(HWindow, S, 'File Changed', mb_YesNoCancel or
  289.       mb_IconQuestion);
  290. {$else}
  291.     Rslt := MessageBox(HWindow, S, 'File Changed', mb_YesNoCancel or
  292.       mb_IconQuestion);
  293. {$endif}
  294.     if Rslt = id_Yes then CanClear := Save
  295.     else CanClear := Rslt <> id_Cancel;
  296.   end;
  297. end;
  298.  
  299. function TDocument.CanClose: Boolean;
  300. begin
  301.   CanClose := CanClear;
  302. end;
  303.  
  304. procedure TDocument.ClearWindow;
  305. begin
  306. end;
  307.  
  308. procedure TDocument.ClearModify;
  309. begin
  310. end;
  311.  
  312. procedure TDocument.CMFileSave(var Msg: TMessage);
  313. begin
  314.   Save;
  315. end;
  316.  
  317. procedure TDocument.CMFileSaveAs(var Msg: TMessage);
  318. begin
  319.   SaveAs;
  320. end;
  321.  
  322. function TDocument.IsModified: Boolean;
  323. begin
  324.   IsModified := Changed;
  325. end;
  326.  
  327. procedure TDocument.Read;
  328. begin
  329.   IsNewFile := False;
  330. end;
  331.  
  332. function TDocument.Save: Boolean;
  333. begin
  334.   Save := True;
  335.   if IsModified then
  336.     if IsNewFile then Save := SaveAs
  337.     else Write;
  338. end;
  339.  
  340. function TDocument.SaveAs: Boolean;
  341. var
  342.   TmpName: array[0..fsPathName] of Char;
  343. begin
  344.   SaveAs := False;
  345.   if FileName <> nil then StrCopy(TmpName, FileName)
  346.   else TmpName[0] := #0;
  347.   if Application^.ExecDialog(New(PFileDialog,
  348.     Init(@Self, PChar(sd_FileSave), TmpName))) = id_Ok then
  349.   begin
  350.     SetFileName(TmpName);
  351.     Write;
  352.     SaveAs := True;
  353.   end;
  354. end;
  355.  
  356. procedure TDocument.SetFileName(AFileName: PChar);
  357. var
  358.   NewCaption: array[0..80] of Char;
  359. begin
  360.   if FileName <> AFileName then
  361.   begin
  362.     StrDispose(FileName);
  363.     FileName := StrNew(AFileName);
  364.   end;
  365.  
  366.   if FileName = nil then StrCopy(NewCaption,'(Untitled)')
  367.   else StrCopy(NewCaption, AFileName);
  368.   SetWindowText(HWindow, NewCaption);
  369. end;
  370.  
  371. procedure TDocument.SetupWindow;
  372. begin
  373.   TBaseMDIChildWindow.SetupWindow;
  374.   SetFileName(FileName);
  375.   if StrIComp(FileName,'Noname') <> 0 then Read;
  376. end;
  377.  
  378. procedure TDocument.Store(var S: TStream);
  379. begin
  380.   TBaseMDIChildWindow.Store(S);
  381.   S.StrWrite(FileName);
  382. end;
  383.  
  384. procedure TDocument.Write;
  385. begin
  386.   Changed := False;
  387. end;
  388.  
  389. {------------------------- TEditWindow Implementation ---------------------}
  390.  
  391. constructor TEditWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  392. begin
  393.   TDocument.Init(AParent, ATitle);
  394.   Editor := New(PEdit, Init(@Self, 200, nil, 0, 0, 0, 0, 0, True));
  395.   with Editor^.Attr do
  396.     Style := Style or es_NoHideSel;
  397. end;
  398.  
  399. constructor TEditWindow.Load(var S: TStream);
  400. begin
  401.   TDocument.Load(S);
  402.   GetChildPtr(S, Editor);
  403. end;
  404.  
  405. procedure TEditWindow.ClearModify;
  406. begin
  407.   Editor^.ClearModify;
  408. end;
  409.  
  410. procedure TEditWindow.ClearWindow;
  411. begin
  412.   Editor^.Clear;
  413. end;
  414.  
  415. function TEditWindow.IsModified: Boolean;
  416. begin
  417.   IsModified := Editor^.IsModified;
  418. end;
  419.  
  420. procedure TEditWindow.Read;
  421. const
  422.   BufferSize = 1024;
  423. var
  424.   CharsToRead: LongInt;
  425.   BlockSize: Integer;
  426.   AStream: PDosStream;
  427.   ABuffer: PChar;
  428. begin
  429.   TDocument.Read;
  430.   AStream := New(PDosStream, Init(FileName, stOpen));
  431.   ABuffer := MemAlloc(BufferSize + 1);
  432.   CharsToRead := AStream^.GetSize;
  433.   if ABuffer <> nil then
  434.   begin
  435.     Editor^.Clear;
  436.     while CharsToRead > 0 do
  437.     begin
  438.       if CharsToRead > BufferSize then BlockSize := BufferSize
  439.       else BlockSize := CharsToRead;
  440.       AStream^.Read(ABuffer^, BlockSize);
  441.       ABuffer[BlockSize] := Char(0);
  442.       Editor^.Insert(ABuffer);
  443.       CharsToRead := CharsToRead - BlockSize;
  444.     end;
  445.     IsNewFile := False;
  446.     Editor^.ClearModify;
  447.     Editor^.SetSelection(0, 0);
  448.     FreeMem(ABuffer, BufferSize + 1);
  449.   end;
  450.   Dispose(AStream, Done);
  451. end;
  452.  
  453. procedure TEditWindow.Store(var S: TStream);
  454. begin
  455.   TDocument.Store(S);
  456.   PutChildPtr(S, Editor);
  457. end;
  458.  
  459. procedure TEditWindow.WMSetFocus(var Msg: TMessage);
  460. begin
  461.   SetFocus(Editor^.HWindow);
  462. end;
  463.  
  464. procedure TEditWindow.WMSize(var Msg: TMessage);
  465. begin
  466.   TDocument.WMSize(Msg);
  467.   SetWindowPos(Editor^.HWindow, 0, -1, -1, Msg.LParamLo+2, Msg.LParamHi+2,
  468.     swp_NoZOrder);
  469. end;
  470.  
  471. procedure TEditWindow.Write;
  472. const
  473.   BufferSize = 1024;
  474. var
  475.   CharsToWrite, CharsWritten: LongInt;
  476.   BlockSize: Integer;
  477.   AStream: PDosStream;
  478.   ABuffer: pointer;
  479.   NumLines: Integer;
  480. begin
  481.   TDocument.Write;
  482.   NumLines := Editor^.GetNumLines;
  483.   CharsToWrite := Editor^.GetLineIndex(NumLines-1) +
  484.     Editor^.GetLineLength(NumLines-1);
  485.   AStream := New(PDosStream, Init(FileName, stCreate));
  486.   ABuffer := MemAlloc(BufferSize + 1);
  487.   CharsWritten := 0;
  488.   if ABuffer <> nil then
  489.   begin
  490.     while CharsWritten < CharsToWrite do
  491.     begin
  492.       if CharsToWrite - CharsWritten > BufferSize then
  493.         BlockSize := BufferSize
  494.       else BlockSize := CharsToWrite - CharsWritten;
  495.       Editor^.GetSubText(ABuffer, CharsWritten, CharsWritten + BlockSize);
  496.       AStream^.Write(ABuffer^, BlockSize);
  497.       CharsWritten := CharsWritten + BlockSize;
  498.     end;
  499.     Editor^.ClearModify;
  500.     FreeMem(ABuffer, BufferSize + 1);
  501.   end;
  502.  
  503.   Dispose(AStream, Done);
  504. end;
  505.  
  506. {------------------------- TGraphObject Implementation ---------------------}
  507.  
  508. constructor TGraphObject.Init(R: TRect; AColor: TColorRef);
  509. begin
  510.   TObject.Init;
  511.   TheColor := AColor;
  512.   Assign(R);
  513. end;
  514.  
  515. constructor TGraphObject.Load(var S: TStream);
  516. begin
  517.   TObject.Init;
  518.   S.Read(X1, SizeOf(X1));
  519.   S.Read(X2, SizeOf(X2));
  520.   S.Read(Y1, SizeOf(Y1));
  521.   S.Read(Y2, SizeOf(Y2));
  522.   S.Read(TheColor, SizeOf(TheColor));
  523. end;
  524.  
  525. procedure TGraphObject.Assign(R: TRect);
  526. begin
  527.   with R do
  528.   begin
  529.     X1 := Left;
  530.     X2 := Right;
  531.     Y1 := Top;
  532.     Y2 := Bottom;
  533.   end;
  534. end;
  535.  
  536. procedure TGraphObject.Draw(HandleDC: HDC);
  537. begin
  538.   ThePen := CreatePen(ps_Solid, 1, TheColor);
  539.   OldPen := SelectObject(HandleDC, ThePen);
  540. end;
  541.  
  542. procedure TGraphObject.DrawRect(HandleDC: HDC; R: TRect);
  543. begin
  544.   with R do
  545.     SetRect(R, Min(Right, Left), Min(Bottom, Top),
  546.       Max(Right, Left), Max(Top, Bottom));
  547.   Assign(R);
  548.   Draw(HandleDC);
  549. end;
  550.  
  551. procedure TGraphObject.EndDraw(HandleDC: HDC);
  552. begin
  553.   DeleteObject(SelectObject(HandleDC, OldPen));
  554. end;
  555.  
  556.  
  557. procedure TGraphObject.Store(var S: TStream);
  558. begin
  559.   S.Write(X1, SizeOf(X1));
  560.   S.Write(X2, SizeOf(X2));
  561.   S.Write(Y1, SizeOf(Y1));
  562.   S.Write(Y2, SizeOf(Y2));
  563.   S.Write(TheColor, SizeOf(TheColor));
  564. end;
  565.  
  566. {------------------ TRectangle, TCircle Implementations ---------------}
  567.  
  568. procedure TRectangle.Draw(HandleDC: HDC);
  569. begin
  570.   TGraphObject.Draw(HandleDC);
  571.   Rectangle(HandleDC, X1, Y1, X2, Y2);
  572.   EndDraw(HandleDC);
  573. end;
  574.  
  575. procedure TCircle.Draw(HandleDC: HDC);
  576. begin
  577.   TGraphObject.Draw(HandleDC);
  578.   Ellipse(HandleDC, X1, Y1, X2, Y2);
  579.   EndDraw(HandleDC);
  580. end;
  581.  
  582. {------------------------ TGraphWindow Implementation ------------------}
  583.  
  584. constructor TGraphWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  585. begin
  586.   TDocument.Init(AParent, ATitle);
  587.   ButtonDown := False;
  588.   MenuShape := ShapeRectangle;
  589.   MenuColor := RGB(255, 0, 0);
  590.   New(TheShapes, Init(5, 5));
  591. end;
  592.  
  593. destructor TGraphWindow.Done;
  594. begin
  595.   TDocument.Done;
  596.   Dispose(TheShapes, Done);
  597. end;
  598.  
  599. procedure TGraphWindow.Clear;
  600. begin
  601.   TheShapes^.FreeAll;
  602.   InvalidateRect(HWindow, nil, True);
  603.   UpdateWindow(HWindow);
  604. end;
  605.  
  606. procedure TGraphWindow.CMBlue(var Msg: TMessage);
  607. begin
  608.   MenuColor := RGB(0, 0, 255);
  609. end;
  610.  
  611. procedure TGraphWindow.CMCircle(var Msg: TMessage);
  612. begin
  613.   MenuShape := ShapeCircle;
  614. end;
  615.  
  616. procedure TGraphWindow.CMClear(var Msg: TMessage);
  617. begin
  618.   Clear;
  619. end;
  620.  
  621. procedure TGraphWindow.CMGreen(var Msg: TMessage);
  622. begin
  623.   MenuColor := RGB(0, 255, 0);
  624. end;
  625.  
  626. procedure TGraphWindow.CMRectangle(var Msg: TMessage);
  627. begin
  628.   MenuShape := ShapeRectangle;
  629. end;
  630.  
  631. procedure TGraphWindow.CMRed(var Msg: TMessage);
  632. begin
  633.   MenuColor := RGB(255, 0, 0);
  634. end;
  635.  
  636. function TGraphWindow.GetPopupMenu: HMenu;
  637. begin
  638.   GetPopupMenu := LoadMenu(HInstance, MakeIntResource(1001));
  639. end;
  640.  
  641. function TGraphWindow.GetPopupTitle: PChar;
  642. begin
  643.   GetPopupTitle:= 'Graph';
  644. end;
  645.  
  646. procedure TGraphWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  647.  
  648.   procedure DoPaint(GraphObject: PGraphObject); far;
  649.   begin
  650.     GraphObject^.Draw(PaintDC);
  651.   end;
  652.  
  653. begin
  654.   TheShapes^.ForEach(@DoPaint);
  655. end;
  656.  
  657. procedure TGraphWindow.Read;
  658. var
  659.   AStream: PDosStream;
  660. begin
  661.   TDocument.Read;
  662.   AStream := New(PDosStream, Init(FileName, stOpenRead));
  663.   TheShapes := PCollection(AStream^.Get);
  664.   Dispose(AStream, Done);
  665. end;
  666.  
  667. procedure TGraphWindow.WMLButtonDown(var Msg: TMessage);
  668. begin
  669.   if not ButtonDown then
  670.   begin
  671.     ButtonDown := True;
  672.     Changed := True;
  673.     SetCapture(hWindow);
  674.     HandleDC := GetDC(hWindow);
  675.     OldROP := SetROP2(HandleDC, r2_NotXORPen);
  676.     with Msg do
  677.       SetRect(Rect, LParamLo, LParamHi, LParamLo, LParamHi);
  678.     case MenuShape of
  679.       ShapeRectangle:  CurrentShape := New(PRectangle, Init(Rect, MenuColor));
  680.       ShapeCircle: CurrentShape := New(PCircle, Init(Rect, MenuColor));
  681.     end;
  682.   end;
  683. end;
  684.  
  685. procedure TGraphWindow.WMLButtonUp(var Msg: TMessage);
  686. begin
  687.   if ButtonDown then
  688.   begin
  689.     ReleaseCapture;
  690.     with Msg do
  691.     begin
  692.       SetRect(Rect, Min(LParamLo, Rect.Left), Min(LParamHi, Rect.Top),
  693.         Max(LParamLo, Rect.Left), Max(LParamHi, Rect.Top));
  694.       SetROP2(HandleDC, OldROP);
  695.       CurrentShape^.Assign(Rect);
  696.       CurrentShape^.Draw(HandleDC);
  697.     end;
  698.     ReleaseDC(HWindow,HandleDC);
  699.     TheShapes^.Insert(CurrentShape);
  700.     ButtonDown := False;
  701.   end;
  702. end;
  703.  
  704. procedure TGraphWindow.WMMouseMove(var Msg: TMessage);
  705. begin
  706.   if ButtonDown then
  707.   with Msg do
  708.   begin
  709.     CurrentShape^.DrawRect(HandleDC, Rect);
  710.     SetRect(Rect, Rect.Left, Rect.Top,
  711.       LParamLo, LParamHi);
  712.     CurrentShape^.DrawRect(HandleDC, Rect);
  713.   end;
  714. end;
  715.  
  716. procedure TGraphWindow.Write;
  717. var
  718.   AStream: PDosStream;
  719. begin
  720.   TDocument.Write;
  721.   AStream := New(PDosStream, Init(FileName, stCreate));
  722.   AStream^.Put(TheShapes);
  723.   Dispose(AStream, Done);
  724. end;
  725.  
  726. {----------------------- TPointCollection Implementation -----------------}
  727.  
  728. destructor TPointCollection.Done;
  729.  
  730.   procedure GoodBye(Point: PPoint); far;
  731.   begin
  732.     Dispose(Point);
  733.   end;
  734.  
  735. begin
  736.   ForEach(@GoodBye);
  737.   DeleteAll;
  738.   TCollection.Done;
  739. end;
  740.  
  741. function TPointCollection.GetItem(var S: TStream): Pointer;
  742. var
  743.   P: PPoint;
  744. begin
  745.   New(P);
  746.   with P^ do
  747.   begin
  748.     S.Read(X, SizeOf(X));
  749.     S.Read(Y, SizeOf(Y));
  750.   end;
  751.   GetItem := P;
  752. end;
  753.  
  754. procedure TPointCollection.PutItem(var S: TStream; Item: Pointer);
  755. begin
  756.   with PPoint(Item)^ do
  757.   begin
  758.     S.Write(X, SizeOf(X));
  759.     S.Write(Y, SizeOf(Y));
  760.   end;
  761. end;
  762.  
  763. {---------------- TLine Implementation -------------------}
  764.  
  765. constructor TLine.Init(AColor: TColorRef; AThickness: Byte);
  766. begin
  767.   TObject.Init;
  768.   LineColor := AColor;
  769.   LineThickness := AThickness;
  770.   New(PointCollection, Init(100, 50));
  771. end;
  772.  
  773. constructor TLine.Load(var S: TStream);
  774. begin
  775.   S.Read(X, SizeOf(X));
  776.   S.Read(Y, SizeOf(Y));
  777.   S.Read(LineColor, SizeOf(LineColor));
  778.   S.Read(LineThickness, SizeOf(LineThickness));
  779.   PointCollection := PPointCollection(S.Get);
  780. end;
  781.  
  782. destructor TLine.Done;
  783. begin
  784.   TObject.Done;
  785.   Dispose(PointCollection, Done);
  786. end;
  787.  
  788. procedure TLine.Store(var S: TStream);
  789. begin
  790.   S.Write(X, SizeOf(X));
  791.   S.Write(Y, SizeOf(Y));
  792.   S.Write(LineColor, SizeOf(LineColor));
  793.   S.Write(LineThickness, SizeOf(LineThickness));
  794.   S.Put(PointCollection);
  795. end;
  796.  
  797. {---------------------- TScribbleWindow Implementation ---------------}
  798.  
  799. constructor TScribbleWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  800. begin
  801.   TDocument.Init(aParent, ATitle);
  802.   ButtonDown := False;
  803.   MenuColor := RGB(255, 0, 0);
  804.   MenuThickness := 3;
  805.   New(LineCollection, Init(5, 5));
  806. end;
  807.  
  808. constructor TScribbleWindow.Load(var S: TStream);
  809. begin
  810.   TDocument.Load(S);
  811.   LineCollection := PCollection(S.Get);
  812. end;
  813.  
  814. destructor TScribbleWindow.Done;
  815. begin
  816.   TDocument.Done;
  817.   Dispose(LineCollection, Done);
  818. end;
  819.  
  820. procedure TScribbleWindow.Clear;
  821. begin
  822.   LineCollection^.FreeAll;
  823.   InvalidateRect(HWindow, nil, True);
  824.   UpdateWindow(HWindow);
  825. end;
  826.  
  827. procedure TScribbleWindow.CMBlue(var Msg: TMessage);
  828. begin
  829.   MenuColor := RGB(0, 0, 255);
  830. end;
  831.  
  832. procedure TScribbleWindow.CMClear(var Msg: TMessage);
  833. begin
  834.   Clear;
  835. end;
  836.  
  837. procedure TScribbleWindow.CMGreen(var Msg: TMessage);
  838. begin
  839.   MenuColor := RGB(0, 255, 0);
  840. end;
  841.  
  842. procedure TScribbleWindow.CMNormal(var Msg: TMessage);
  843. begin
  844.   MenuThickness := 3;
  845. end;
  846.  
  847. procedure TScribbleWindow.CMRed(var Msg: TMessage);
  848. begin
  849.   MenuColor := RGB(255, 0, 0);
  850. end;
  851.  
  852. procedure TScribbleWindow.CMThick(var Msg: TMessage);
  853. begin
  854.   MenuThickness := 5;
  855. end;
  856.  
  857. procedure TScribbleWindow.CMThin(var Msg: TMessage);
  858. begin
  859.   MenuThickness := 1;
  860. end;
  861.  
  862. function TScribbleWindow.GetPopupMenu: HMenu;
  863. begin
  864.   GetPopupMenu := LoadMenu(HInstance, MakeIntResource(1000));
  865. end;
  866.  
  867. function TScribbleWindow.GetPopupTitle: PChar;
  868. begin
  869.   GetPopupTitle:= 'Scribble';
  870. end;
  871.  
  872. procedure TScribbleWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  873.  
  874.   procedure DrawLine(Line: PLine); far;
  875.  
  876.     procedure DrawSegments(Segment: PPoint); far;
  877.     begin
  878.       LineTo(PaintDC, Segment^.X, Segment^.Y);
  879.     end;
  880.  
  881.   begin
  882.     with Line^ do
  883.     begin
  884.       OldPen := SelectObject(PaintDC, CreatePen(ps_Solid, LineThickness,
  885.         LineColor));
  886.       MoveTo(PaintDC, X, Y);
  887.       PointCollection^.ForEach(@DrawSegments);
  888.       DeleteObject(SelectObject(PaintDC, OldPen));
  889.     end;
  890.   end;
  891.  
  892. begin
  893.   LineCollection^.ForEach(@DrawLine);
  894. end;
  895.  
  896. procedure TScribbleWindow.Read;
  897. var
  898.   AStream: PDosStream;
  899. begin
  900.   TDocument.Read;
  901.   AStream := New(PDosStream, Init(FileName, stOpenRead));
  902.   LineCollection := PCollection(AStream^.Get);
  903.   Dispose(AStream, Done);
  904. end;
  905.  
  906. procedure TScribbleWindow.Store(var S: TStream);
  907. begin
  908.   TDocument.Store(S);
  909.   S.Put(LineCollection);
  910. end;
  911.  
  912. procedure TScribbleWindow.WMLButtonDown(var Msg: TMessage);
  913. begin
  914.   if not ButtonDown then
  915.   begin
  916.     ButtonDown := True;
  917.     Changed := True;
  918.     SetCapture(HWindow);
  919.     HandleDC := GetDC(HWindow);
  920.     OldPen := SelectObject(HandleDC, CreatePen(ps_Solid, MenuThickness,
  921.       MenuColor));
  922.     MoveTo(HandleDC, Msg.LParamLo, Msg.LParamHi);
  923.     New(CurrentLine, Init(MenuColor, MenuThickness));
  924.     CurrentLine^.X := Msg.LParamLo;
  925.     CurrentLine^.Y := Msg.LParamHi;
  926.   end;
  927. end;
  928.  
  929. procedure TScribbleWindow.WMLButtonUp(var Msg: TMessage);
  930. begin
  931.   if ButtonDown then
  932.   begin
  933.     ReleaseCapture;
  934.     DeleteObject(SelectObject(HandleDC, OldPen));
  935.     ReleaseDC(HWindow,HandleDC);
  936.     ButtonDown := False;
  937.     LineCollection^.Insert(CurrentLine);
  938.   end;
  939. end;
  940.  
  941. procedure TScribbleWindow.WMMouseMove(var Msg: TMessage);
  942. var
  943.   APoint: PPoint;
  944. begin
  945.   if ButtonDown then
  946.   begin
  947.     LineTo(HandleDC, Msg.LParamLo, Msg.LParamHi);
  948.     New(APoint);
  949.     APoint^.X := Msg.LParamLo;
  950.     APoint^.Y := Msg.LParamHi;
  951.     CurrentLine^.PointCollection^.Insert(APoint);
  952.   end;
  953. end;
  954.  
  955. procedure TScribbleWindow.Write;
  956. var
  957.   AStream: PDosStream;
  958. begin
  959.   TDocument.Write;
  960.   AStream := New(PDosStream, Init(FileName, stCreate));
  961.   AStream^.Put(LineCollection);
  962.   Dispose(AStream, Done);
  963. end;
  964.  
  965. {------------------ Stream Registration Records -----------------------}
  966. const
  967.   REditWindow: TStreamRec = (
  968.     ObjType: 80;
  969.     VmtLink: Ofs(TypeOf(TEditWindow)^);
  970.     Load:    @TEditWindow.Load;
  971.     Store:   @TEditWindow.Store);
  972.  
  973. const
  974.   RDocument: TStreamRec = (
  975.     ObjType: 81;
  976.     VmtLink: Ofs(TypeOf(TDocument)^);
  977.     Load:    @TDocument.Load;
  978.     Store:   @TDocument.Store);
  979.  
  980. const
  981.   RScribbleWindow: TStreamRec = (
  982.     ObjType: 82;
  983.     VmtLink: Ofs(TypeOf(TScribbleWindow)^);
  984.     Load:    @TScribbleWindow.Load;
  985.     Store:   @TScribbleWindow.Store);
  986.  
  987. const
  988.   RGraphWindow: TStreamRec = (
  989.     ObjType: 83;
  990.     VmtLink: Ofs(TypeOf(TGraphWindow)^);
  991.     Load:    @TGraphWindow.Load;
  992.     Store:   @TGraphWindow.Store);
  993.  
  994. const
  995.   RPointCollection: TStreamRec = (
  996.     ObjType: 84;
  997.     VmtLink: Ofs(TypeOf(TPointCollection)^);
  998.     Load:    @TPointCollection.Load;
  999.     Store:   @TPointCollection.Store);
  1000.  
  1001. const
  1002.   RLine: TStreamRec = (
  1003.     ObjType: 85;
  1004.     VmtLink: Ofs(TypeOf(TLine)^);
  1005.     Load:    @TLine.Load;
  1006.     Store:   @TLine.Store);
  1007.  
  1008. const
  1009.   RGraphObject: TStreamRec = (
  1010.     ObjType: 86;
  1011.     VmtLink: Ofs(TypeOf(TGraphObject)^);
  1012.     Load:    @TGraphObject.Load;
  1013.     Store:   @TGraphObject.Store);
  1014.  
  1015. const
  1016.   RRectangle: TStreamRec = (
  1017.     ObjType: 87;
  1018.     VmtLink: Ofs(TypeOf(TRectangle)^);
  1019.     Load:    @TRectangle.Load;
  1020.     Store:   @TRectangle.Store);
  1021. const
  1022.   RCircle: TStreamRec = (
  1023.     ObjType: 88;
  1024.     VmtLink: Ofs(TypeOf(TCircle)^);
  1025.     Load:    @TCircle.Load;
  1026.     Store:   @TCircle.Store);
  1027.  
  1028. begin
  1029.   RegisterWobjects;
  1030.   RegisterType(REditWindow);
  1031.   RegisterType(RDocument);
  1032.   RegisterType(RScribbleWindow);
  1033.   RegisterType(RGraphWindow);
  1034.   RegisterType(RPointCollection);
  1035.   RegisterType(RLine);
  1036.   RegisterType(RGraphObject);
  1037.   RegisterType(RRectangle);
  1038.   RegisterType(RCircle);
  1039. end.
  1040.  
  1041.