home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Pascal / BPASCAL.700 / D12 / PAINT.ZIP / PAINT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-01  |  11.6 KB  |  453 lines

  1. {************************************************}
  2. {                                                }
  3. {   ObjectWindows Paint demo                     }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. program Paint;
  9.  
  10. { The main program file for the paint program.
  11.  
  12.   The paint program is a simple drawing program that demonstrates the
  13.   use of the Object Windows Library (OWL) and of programming with the Windows
  14.   Graphics Device Interface (GDI).
  15. }
  16.  
  17. uses PaintDef, ResDef, PaintDlg, ToolBar, LineBar, Palette, Canvas,
  18.   WinTypes, WinProcs, OWindows, ODialogs, Strings;
  19.  
  20. {$R PAINT}
  21.  
  22. { Global declarations }
  23. const
  24.  
  25.   FileNameMax = 80;        { Max length of file names }
  26.  
  27. type
  28.  
  29.   {
  30.     The main drawing window. Responsible for creating and maintaining
  31.     subwindows for tool, color and line selection, and for menu management.
  32.   }
  33.   PPaintWin = ^TPaintWin;
  34.   TPaintWin = object(TWindow)
  35.     State: TState;        { Drawing state of the program }
  36.     Palette: PPalette;        { Color palette }
  37.     ToolBar: PToolBar;        { Palette of available tools }
  38.     LineBar: PLineBar;        { Palette of available line widths }
  39.     Canvas: PCanvas;        { Window to actually draw on }
  40.     FileName: array [0..FileNameMax] of Char;
  41.                                 { File name associated with current window }
  42.     CBChainNext: HWnd;        { Next window in the clipboard chain }
  43.  
  44.     { Creation }
  45.     constructor Init;
  46.     function GetClassName: PChar; virtual;
  47.     procedure GetWindowClass(var WndClass: TWndClass); virtual;
  48.     procedure SetUpWindow; virtual;
  49.     function CanClose: Boolean; virtual;
  50.  
  51.     { Utility }
  52.     procedure SetNames(NewName: PChar);
  53.     procedure UpdateChildren;
  54.  
  55.     { Window manager interface routines }
  56.     procedure WMSize(var Msg: TMessage);
  57.       virtual wm_First + wm_Size;
  58.     procedure WMChangeCBChain(var Msg: TMessage);
  59.       virtual wm_First + wm_ChangeCBChain;
  60.     procedure WMDrawClipBoard(var Msg: TMessage);
  61.       virtual wm_First + wm_DrawClipBoard;
  62.     procedure WMDestroy(var Msg: TMessage);
  63.       virtual wm_First + wm_Destroy;
  64.  
  65.     { Menu routines }
  66.     procedure CMFileNew(var Msg: TMessage);
  67.       virtual cm_First + cm_FileNew;
  68.     procedure CMFileOpen(var Msg: TMessage);
  69.       virtual cm_First + cm_FileOpen;
  70.     procedure CMFileSave(var Msg: TMessage);
  71.       virtual cm_First + cm_FileSave;
  72.     procedure CMFileSaveAs(var Msg: TMessage);
  73.       virtual cm_First + cm_FileSaveAs;
  74.  
  75.     procedure CMEditUndo(var Msg: TMessage);
  76.       virtual cm_First + cm_EditUndo;
  77.     procedure CMEditCut(var Msg: TMessage);
  78.       virtual cm_First + cm_EditCut;
  79.     procedure CMEditCopy(var Msg: TMessage);
  80.       virtual cm_First + cm_EditCopy;
  81.     procedure CMEditPaste(var Msg: TMessage);
  82.       virtual cm_First + cm_EditPaste;
  83.     procedure CMEditDelete(var Msg: TMessage);
  84.       virtual cm_First + cm_EditDelete;
  85.     procedure CMEditClear(var Msg: TMessage);
  86.       virtual cm_First + cm_EditClear;
  87.  
  88.     procedure CMOptionsSize(var Msg: TMessage);
  89.       virtual cm_First + cm_OptionsSize;
  90.  
  91.     procedure CMHelpAbout(var Msg: TMessage);
  92.       virtual cm_First + cm_HelpAbout;
  93.   end;
  94.  
  95.   {
  96.     A paint application.
  97.   }
  98.   TPaintApp = object(TApplication)
  99.     procedure InitMainWindow; virtual;
  100.   end;
  101.  
  102. { TPaintWin }
  103.  
  104. { Create a drawing window, initializing its drawing state and associated
  105.   windows.
  106. }
  107. constructor TPaintWin.Init;
  108. begin
  109.   TWindow.Init(nil, 'Paint');
  110.  
  111.   { Set up the menu bar }
  112.   Attr.Menu := LoadMenu(HInstance, 'PaintMenu');
  113.  
  114.   { Initialize the drawing state }
  115.   with State do
  116.   begin
  117.     PaintTool := nil;
  118.     MemDC := 0;
  119.     IsDirtyBitmap := False;
  120.     SetRectEmpty(Selection);
  121.     SelectionBM := 0;
  122.     PenSize := 3;
  123.     PenColor := $000000;
  124.     BrushColor := $FFFFFF;
  125.     BitmapSize.X := 640;
  126.     BitmapSize.Y := 480;
  127.   end;
  128.  
  129.   { Create the associated windows }
  130.   Palette := New(PPalette, Init(@Self, @State));
  131.   ToolBar := New(PToolBar, Init(@Self, @State));
  132.   LineBar := New(PLineBar, Init(@Self, @State));
  133.   Canvas := New(PCanvas, Init(@Self, @State));
  134.  
  135.   { Set up the file name }
  136.   FileName[0] := #0;
  137.  
  138.   CBChainNext := 0;
  139. end;
  140.  
  141. function TPaintWin.GetClassName: PChar;
  142. begin
  143.   GetClassName := 'TPaintWin';
  144. end;
  145.  
  146. procedure TPaintWin.GetWindowClass(var WndClass: TWndClass);
  147. begin
  148.   TWindow.GetWindowClass(WndClass);
  149.   WndClass.hbrBackground := color_AppWorkspace + 1;
  150.   WndClass.hIcon := LoadIcon(HInstance, 'PaintIcon');
  151. end;
  152.  
  153. procedure TPaintWin.SetupWindow;
  154. begin
  155.   TWindow.SetupWindow;
  156.   if IsClipboardFormatAvailable(cf_Bitmap) then
  157.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_enabled);
  158.   CBChainNext := SetClipBoardViewer(HWindow);
  159. end;
  160.  
  161. { Set the name of the file associated with the window and display it in the
  162.   title bar.
  163. }
  164. procedure TPaintWin.SetNames(NewName: PChar);
  165. var
  166.   Name: array[0..FileNameMax + 10] of Char;     { Title bar has 'Paint -'
  167.                                                   prepended }
  168. begin
  169.  
  170.   { Create name for title bar }
  171.   StrCopy(Name, 'Paint');
  172.   if StrComp(NewName, '') <> 0 then
  173.   begin
  174.     StrCat(Name, ' - ');
  175.     StrCat(Name, NewName);
  176.   end;
  177.  
  178.   { Set title bar }
  179.   SetCaption(Name);
  180.  
  181.   { Set file name }
  182.   StrCopy(FileName, NewName);
  183. end;
  184.  
  185. procedure TPaintWin.UpdateChildren;
  186. var
  187.   S: Integer;            { Lower coordinates of Palette }
  188.   R: TRect;            { Window client area }
  189.   CX, CY: Integer;
  190. begin
  191.   GetClientRect(HWindow, R);
  192.   S := ((R.bottom - 8) div 17) * 3 + 1;
  193.   MoveWindow(Palette^.HWindow, 4, 4, S, R.bottom - 8, True);
  194.   MoveWindow(ToolBar^.HWindow, S + 8, 4, (Ord(MaxTool) + 1) * 31 + 1,
  195.     32, True);
  196.   MoveWindow(LineBar^.HWindow, S + (Ord(MaxTool) + 1) * 31 + 13, 4,
  197.     LineBarWidth, 32, True);
  198.   Canvas^.MoveSelf(S + 8, 40, R.Right - S - 12, R.Bottom - 44, True);
  199. end;
  200.  
  201. { Window manager interface routines }
  202.  
  203. { Resize the window and resize associated windows proportionately.
  204. }
  205. procedure TPaintWin.WMSize(var Msg: TMessage);
  206. begin
  207.   TWindow.WMSize(Msg);
  208.   UpdateChildren;
  209. end;
  210.  
  211. { Update the clipboard chain link, or pass down the message.
  212. }
  213. procedure TPaintWin.WMChangeCBChain(var Msg: TMessage);
  214. begin
  215.   if Msg.WParam = CBChainNext then
  216.     CBChainNext := Msg.lParamLo
  217.   else
  218.     if CBChainNext <> 0 then
  219.       SendMessage(CBChainNext, Msg.Message, Msg.WParam, Msg.lParam);
  220. end;
  221.  
  222. { Enable/disable menus to reflect a change in the state of the clipboard.
  223. }
  224. procedure TPaintWin.WMDrawClipBoard(var Msg: TMessage);
  225. begin
  226.   if IsClipboardFormatAvailable(cf_Bitmap) then
  227.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_enabled)
  228.   else
  229.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_grayed);
  230.   if CBChainNext <> 0 then
  231.     SendMessage(CBChainNext, Msg.Message, 0, 0);
  232. end;
  233.  
  234. { Notify the clipboard chain before dying.
  235. }
  236. procedure TPaintWin.WMDestroy(var Msg: TMessage);
  237. begin
  238.   ChangeClipboardChain(HWindow, CBChainNext);
  239.   TWindow.WMDestroy(Msg);
  240. end;
  241.  
  242.  
  243. { File menu functions }
  244. { Create a new canvas and destroy the old one.
  245. }
  246. procedure TPaintWin.CMFileNew(var Msg: TMessage);
  247. var
  248.   CurA: TWindowAttr;        { Save the current window attributes }
  249.   aMsg: TMessage;
  250. begin
  251.  
  252.   { Make sure the current image is saved if desired. }
  253.   if State.IsDirtyBitmap then
  254.     case AskCancel('Save current image?') of
  255.       id_Yes: CMFileSave(msg);
  256.       id_Cancel: exit;
  257.     end;
  258.  
  259.   { Mark the bitmap as unmodified }
  260.   State.IsDirtyBitmap := False;
  261.   CurA := Canvas^.Attr;
  262.  
  263.   { Destroy the old canvas }
  264.   Canvas^.Done;
  265.  
  266.   { Create a new one }
  267.   SetNames('');
  268.   Canvas := PCanvas(Application^.MakeWindow(New(PCanvas, Init(@Self,
  269.     @State))));
  270.  
  271.   { Size the window appropriately }
  272.   UpdateChildren;
  273. end;
  274.  
  275. { Read a bitmap from file into the canvas.
  276. }
  277. procedure TPaintWin.CMFileOpen(var msg: TMessage);
  278. var
  279.   FN: array [0..FileNameMax] of Char;        { The file name }
  280.   Curs: HCursor;
  281. begin
  282.  
  283.   { Make sure the current image is saved if desired }
  284.   if State.IsDirtyBitmap then
  285.     case AskCancel('Save current image?') of
  286.       id_Yes: CMFileSave(msg);
  287.       id_Cancel: exit;
  288.     end;
  289.  
  290.   { Create a mask for the file dialog }
  291.   StrCopy(FN, '*.bmp');
  292.  
  293.   { Prompt for the file and load the bitmap }
  294.   if FileOpenDialog(FN) then
  295.   begin
  296.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  297.     if (Canvas^.Load(FN) <> 0) then
  298.     begin
  299.       SetNames(FN);
  300.       UpdateChildren;
  301.     end;
  302.     SetCursor(Curs);
  303.   end;
  304. end;
  305.  
  306. { Save the current bitmap to file.
  307. }
  308. procedure TPaintWin.CMFileSave(var msg: TMessage);
  309. var Curs: HCursor;        { The current cursor }
  310. begin
  311.   
  312.   { Make sure there is a file name to be saved to }
  313.   if StrComp(FileName, '') = 0 then
  314.     CMFileSaveAs(msg)
  315.   else
  316.   begin
  317.     { Set the cursor while the file is being written }
  318.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  319.     Canvas^.Store(FileName);
  320.     SetCursor(Curs);
  321.   end;
  322. end;
  323.  
  324. { Prompt for a file name then save the current bitmap to that file.
  325. }
  326. procedure TPaintWin.CMFileSaveAs(var msg: TMessage);
  327. var
  328.   FN: array[0..FileNameMax] of Char;    { The file name }
  329.   Curs: HCursor;                           { The current cursor }
  330. begin
  331.   { Create a mask for the file dialog }
  332.   StrCopy(FN, '*.bmp');
  333.  
  334.   { Prompt for the file name }
  335.   if FileSaveDialog(FN) then
  336.   begin
  337.     { Set the cursor while the file is being written }
  338.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  339.     if Canvas^.Store(FN) <> 0 then SetNames(FN);
  340.     SetCursor(Curs);
  341.   end;
  342. end;
  343.  
  344. { Make sure the bitmap is saved if desired before dying or cancel if desired.
  345. }
  346. function TPaintWin.CanClose: Boolean;
  347. var Msg: TMessage;            { Bogus to pass on }
  348. begin
  349.   CanClose := True;
  350.   if State.IsDirtyBitmap then
  351.     case AskCancel('Save current image?') of
  352.       id_Yes: CMFileSave(Msg);
  353.       id_Cancel: CanClose := False;
  354.     end;
  355. end;
  356.  
  357.  
  358. { Edit menu functions }
  359.  
  360. { Undo the last change to the bitmap.
  361. }
  362. procedure TPaintWin.CMEditUndo(var Msg: TMessage);
  363. begin
  364.   Canvas^.Undo;
  365. end;
  366.  
  367. { Copy the current selection to the clipboard and clear it from the screen.
  368. }
  369. procedure TPaintWin.CMEditCut(var Msg: TMessage);
  370. begin
  371.   Canvas^.Cut;
  372. end;
  373.  
  374. { Copy the current selection to the clipboard.
  375. }
  376. procedure TPaintWin.CMEditCopy(var Msg: TMessage);
  377. begin
  378.   Canvas^.Copy;
  379. end;
  380.  
  381. { Retrieve the contents of the clipboard and make it the current selection.
  382. }
  383. procedure TPaintWin.CMEditPaste(var Msg: TMessage);
  384. begin
  385.   ToolBar^.ToolSelect(SelectTool);
  386.   Canvas^.Paste;
  387. end;
  388.  
  389. { Clear the current selection from the screen.
  390. }
  391. procedure TPaintWin.CMEditDelete(var Msg: TMessage);
  392. begin
  393.   Canvas^.Delete;
  394. end;
  395.  
  396. { Clear the entire drawing area.
  397. }
  398. procedure TPaintWin.CMEditClear(var Msg: TMessage);
  399. begin
  400.   Canvas^.ClearAll;
  401. end;
  402.  
  403. { Options }
  404. procedure TPaintWin.CMOptionsSize(var Msg: TMessage);
  405. var
  406.   SizeBMInfo: TSizeBMInfo;
  407. begin
  408.   with SizeBMInfo, State do
  409.     begin
  410.       Width := BitmapSize.X;
  411.       Height := BitmapSize.Y;
  412.       CurrentBMFlag := id_PadBM;
  413.     end;
  414.   if Application^.ExecDialog(New(PSizeBMDialog, Init(@Self, 'SizeBMDialog',
  415.     @SizeBMInfo))) = id_OK then
  416.   begin
  417.     with State, SizeBMInfo do
  418.     begin
  419.       BitmapSize.X := Width;
  420.       BitmapSize.Y := Height;
  421.     end;
  422.     Canvas^.Resize(SizeBMInfo.CurrentBMFlag);
  423.     WMSize(Msg);
  424.   end;
  425. end;
  426.   
  427.  
  428. { Help }
  429. { Display the 'About Box'.
  430. }
  431. procedure TPaintWin.CMHelpAbout(var Msg: TMessage);
  432. begin
  433.   Application^.ExecDialog(New(PDialog, Init(@Self, 'AboutDialog')));
  434. end;
  435.  
  436. { TPaintApp }
  437.  
  438. { Create the main window for the paint application.
  439. }
  440. procedure TPaintApp.InitMainWindow;
  441. begin
  442.   MainWindow := New(PPaintWin, Init);
  443. end;
  444.  
  445. var
  446.   PaintApp: TPaintApp;
  447.  
  448. begin
  449.   PaintApp.Init('Paint');
  450.   PaintApp.Run;
  451.   PaintApp.Done;
  452. end.
  453.