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

  1. {***************************************************}
  2. {                                                   }
  3. {   Windows 3.1 OLE Server Demonstration Program    }
  4. {   Server Window Unit                              }
  5. {   Copyright (c) 1992 by Borland International     }
  6. {                                                   }
  7. {***************************************************}
  8.  
  9. { This unit implements the main window for the OLE Server
  10.   demo application.  This is the window which manages the
  11.   display and modification of the supported OLE objects.
  12.  
  13.   Note: To compile the OLE Server demo, set Compile|Primary File
  14.   to OLESERVR.PAS
  15. }
  16.  
  17. unit ServrWin;
  18.  
  19. interface
  20.  
  21. uses WinTypes, WinProcs, OWindows, OleTypes;
  22.  
  23. type
  24.  
  25. { Type used to communicate the result of File I/O dialogs.
  26. }
  27.   TFileIoStatus = (fiCancel, fiExecute);
  28.  
  29. { Application Main Window }
  30.  
  31.   PServerWindow = ^TServerWindow;
  32.   TServerWindow = object(TWindow)
  33.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  34.  
  35.     function  CanClose: Boolean; virtual;
  36.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  37.     procedure DefCommandProc(var Msg: TMessage); virtual;
  38.  
  39.     procedure BeginEmbedding; virtual;
  40.     procedure EndEmbedding; virtual;
  41.     function  SaveChangesPrompt: TFileIoStatus; virtual;
  42.     procedure ShapeChange(NewType: TNativeType); virtual;
  43.     procedure UpdateFileMenu(DocName: PChar); virtual;
  44.  
  45.     procedure CMFileNew(var Msg: TMessage);
  46.       virtual cm_First + cm_FileNew;
  47.     procedure CMFileOpen(var Msg: TMessage);
  48.       virtual cm_First + cm_FileOpen;
  49.     procedure CMFileSave(var Msg: TMessage);
  50.       virtual cm_First + cm_FileSave;
  51.     procedure CMFileSaveAs(var Msg: TMessage);
  52.       virtual cm_First + cm_FileSaveAs;
  53.     procedure CMFileUpdate(var Msg: TMessage);
  54.       virtual cm_First + cm_FileUpdate;
  55.     procedure CMEditCopy(var Msg: TMessage);
  56.       virtual cm_First + cm_EditCopy;
  57.     procedure CMHelpAbout(var Msg: TMessage); 
  58.       virtual cm_First + cm_HelpAbout;
  59.   end;
  60.  
  61. implementation
  62.  
  63. uses Ole, Strings, ODialogs, OleApp, Server, OleObj;
  64.  
  65. { Initialized globals }
  66.  
  67. const
  68.   CmToNativeType: array[cm_ShapeEllipse..cm_ShapeTriangle] of TNativeType
  69.                     = (ObjEllipse, ObjRect, ObjTriangle);
  70.  
  71.   NativeTypeToCm: array[TNativeType] of Word
  72.                     = (cm_ShapeEllipse, cm_ShapeRectangle, cm_ShapeTriangle);
  73.  
  74.  
  75. { TServerWindow Methods }
  76.  
  77. constructor TServerWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  78. begin
  79.   TWindow.Init(AParent, ATitle);
  80.   Attr.Menu := LoadMenu(HInstance, PChar(id_Menu));
  81.   Attr.X    := 100;
  82.   Attr.Y    := 100;
  83.   Attr.W    := 250;
  84.   Attr.H    := 250;
  85. end;
  86.  
  87. { Prompts the user to save changes in the document and return,
  88.   and whether the pending operation (new/open/exit) should be
  89.   executed or canceled.  The user has requested File/New,
  90.   File/Open, or File/Exit.
  91. }
  92. function TServerWindow.SaveChangesPrompt: TFileIoStatus;
  93. var
  94.   App     : POleApp;
  95.   Doc     : POleDocument;
  96.   Outcome : Integer;
  97.   Buf     : array [0..127] of Char;
  98. begin
  99.   App := POLEApp(Application);
  100.   Doc := App^.Server^.Document;
  101.   Outcome := IdYes;
  102.  
  103.   if Doc^.IsDirty then
  104.   begin
  105.     if Doc^.DocType = DoctypeEmbedded then
  106.     begin
  107.       StrCopy(Buf, 'Embedded object ');
  108.       StrCat (Buf, Doc^.Name);
  109.       StrCat (Buf, ' has changed. Do you want to update?');
  110.     end
  111.     else
  112.     begin
  113.       StrCopy(Buf, 'Do you want to save changes to ');
  114.       StrCat (Buf, Doc^.Name);
  115.       StrCat (Buf, '?');
  116.     end;
  117.  
  118.     Outcome := MessageBox(HWindow, Buf, App^.Name, mb_IconQuestion or
  119.       mb_YesNoCancel);
  120.  
  121.     if Outcome = IdYes then
  122.       if Doc^.DocType = DoctypeEmbedded then
  123.         OleSavedServerDoc(Doc^.ServerDoc)
  124.       else
  125.         Doc^.SaveDoc;
  126.   end;
  127.  
  128.   if Outcome <> IdCancel then
  129.   begin
  130.     { If the server library is in the process of closing down
  131.       connections to the document, wait until it is finished
  132.       (flag "IsReleased" becomes True) before we re-use the
  133.       document space.
  134.     }
  135.     if OleRevokeServerDoc(Doc^.ServerDoc) = ole_Wait_For_Release then
  136.       App^.Wait(Doc^.IsReleased);
  137.  
  138.     Doc^.ServerDoc := 0;
  139.  
  140.     if Doc^.DocType = DoctypeEmbedded then
  141.       EndEmbedding;
  142.   end;
  143.  
  144.   if Outcome = IdCancel then
  145.     SaveChangesPrompt := fiCancel
  146.   else
  147.     SaveChangesPrompt := fiExecute;
  148. end;
  149.  
  150. { Prompts the user for changes and initiate application shutdown by
  151.   calling OleRevokeServer.  OleRevokeServer automatically revokes any
  152.   documents which revokes any objects.
  153. }
  154. function TServerWindow.CanClose: Boolean;
  155. var
  156.   App   : POLEApp;
  157.   Server: POleServerObj;
  158. begin
  159.   App   := POleApp(Application);
  160.   Server:= App^.Server;
  161.  
  162.   if SaveChangesPrompt = fiExecute then
  163.   begin
  164.     { If the server library is in the process of closing down
  165.       connections to the server, wait until it is finished (flag
  166.       "IsReleased" becomes True) before we terminate
  167.     }
  168.    if OleRevokeServer(Server^.ServerHdl) = ole_Wait_for_Release then
  169.       App^.Wait(Server^.IsReleased);
  170.     CanClose := True;
  171.   end
  172.   else
  173.     CanClose := False;
  174. end;
  175.  
  176. { Rather than have a message response function for each menu item on the
  177.   "Shape" menu we catch the commands here instead.  Other commands are 
  178.   passed to our inherited method.
  179. }
  180. procedure TServerWindow.DefCommandProc(var Msg: TMessage);
  181. begin
  182.   if (Msg.WParam >= cm_ShapeEllipse) and
  183.       (Msg.WParam <= cm_ShapeTriangle) then
  184.     ShapeChange(CmToNativeType[Msg.WParam])
  185.   else
  186.     TWindow.DefCommandProc(Msg);
  187. end;
  188.  
  189. { Responds to selection of the File/New menu item.
  190. }
  191. procedure TServerWindow.CMFileNew(var Msg: TMessage);
  192. begin
  193.   if SaveChangesPrompt = fiExecute then
  194.     POleApp(Application)^.Server^.Document^.Reset(nil);
  195. end;
  196.  
  197. { Responds to selection of the File/Open menu item.
  198. }
  199. procedure TServerWindow.CMFileOpen(var Msg: TMessage);
  200. var
  201.   Path: TFilename;
  202.   Doc : POleDocument;
  203. begin
  204.   Doc := POleApp(Application)^.Server^.Document;
  205.   if SaveChangesPrompt = fiExecute then
  206.   begin
  207.     if Doc^.PromptForOpenFileName(Path) then
  208.       Doc^.Reset(Path)
  209.     else
  210.       Doc^.Reset(nil);
  211.   end;
  212. end;
  213.  
  214. { Responds to selection of the File/Save menu item.
  215.   NOTE: This is only for stand-alone mode, when we're not
  216.   linked.
  217. }
  218. procedure TServerWindow.CMFileSave(var Msg: TMessage);
  219. begin
  220.   POleApp(Application)^.Server^.Document^.SaveDoc;
  221. end;
  222.  
  223. { Responds to selection of the File/SaveAs menu item.
  224. }
  225. procedure TServerWindow.CMFileSaveAs(var Msg: TMessage);
  226. begin
  227.   POleApp(Application)^.Server^.Document^.SaveAs;
  228. end;
  229.  
  230. { Responds to selection of the File/Update menu item.
  231.   NOTE: This is only for embedding mode.
  232. }
  233. procedure TServerWindow.CMFileUpdate(var Msg: TMessage);
  234. var
  235.   Doc: POleDocument;
  236. begin
  237.   Doc := POleApp(Application)^.Server^.Document;
  238.  
  239.   { Notify the server library that the embedded document
  240.     has changed
  241.   }
  242.   OleSavedServerDoc(Doc^.ServerDoc);
  243.   Doc^.IsDirty := False;
  244. end;
  245.  
  246. { Copies the object to the clipoard.  NOTE: since this app only has one
  247.   object we don't support "Cut" and "Delete", but your app might want to.
  248. }
  249. procedure TServerWindow.CMEditCopy(var Msg: TMessage);
  250. var
  251.   App      : POleApp;
  252.   ObjectPtr: POleObjectObj;
  253.   Handle   : THandle;
  254. begin
  255.   App      := POLEApp(Application);
  256.   ObjectPtr:= App^.Server^.Document^.OleObject;
  257.  
  258.   if OpenClipboard(HWindow) then
  259.   begin
  260.     EmptyClipboard;
  261.  
  262.     { Server applications are responsible for placing the data formats
  263.       on the clipboard in most important order first.  Here is the standard
  264.       ordering:
  265.         1. Application-specific data
  266.         2. Native
  267.         3. OwnerLink
  268.         4. cf_MetafilePict
  269.         5. cf_Bitmap
  270.         6. ObjectLink
  271.         7. Any other data
  272.     
  273.      add Native first...
  274.     }
  275.     Handle := ObjectPtr^.GetNativeData;
  276.     if Handle <> 0 then
  277.       SetClipboardData(App^.cfNative, Handle);
  278.  
  279.     { In order for the object to be embedded we must also identify the
  280.       owner of the object using "OwnerLink" data
  281.     }
  282.     Handle := ObjectPtr^.GetLinkData;
  283.     if Handle <> 0 then
  284.       SetClipboardData(App^.cfOwnerLink, Handle);
  285.  
  286.     { Now offer at least one presentation format.  If the server doesn't
  287.       have an object handler DLL then it must provide a metafile.
  288.     }
  289.     Handle := ObjectPtr^.GetMetafilePicture;
  290.     if Handle <> 0 then
  291.       SetClipboardData(cf_MetafilePict, Handle);
  292.  
  293.     { Now offer bitmap format.
  294.     }
  295.     Handle := ObjectPtr^.GetBitmapData;
  296.     if Handle <> 0 then
  297.       SetClipboardData(cf_Bitmap, Handle);
  298.  
  299.     { If the document type is a file then we can offer 'ObjectLink'.
  300.     }
  301.     if (App^.Server^.Document^.DocType = DoctypeFromFile) then
  302.     begin
  303.       Handle := ObjectPtr^.GetLinkData;
  304.       if Handle <> 0 then
  305.         SetClipboardData(App^.cfObjectLink, Handle);
  306.     end;
  307.  
  308.     CloseClipboard;
  309.   end;
  310. end;
  311.  
  312. { Activates the Help dialog.
  313. }
  314. procedure TServerWindow.CMHelpAbout(var Msg: TMessage);
  315. begin
  316.   Application^.ExecDialog(New(PDialog, Init(@Self, PChar(id_About))));
  317. end;
  318.  
  319. { Responds to selection of a menu item from the "Shape" menu.  Checks the
  320.   new menu item, unchecks the previous menu item, changes the selected 
  321.   object's type, repaints the damaged area, and checks the menu items to
  322.   see if they should be enabled/disabled.
  323. }
  324. procedure TServerWindow.ShapeChange(NewType: TNativeType);
  325. var
  326.   DocPtr   : POleDocument;
  327.   ObjectPtr: POleObjectObj;
  328.   OldType  : TNativeType;
  329.   Rect     : TRect;
  330.   MyMenu   : HMenu;
  331. begin
  332.   MyMenu := GetMenu(HWindow);
  333.  
  334.   DocPtr   := POleApp(Application)^.Server^.Document;
  335.   ObjectPtr:= DocPtr^.OleObject;
  336.   OldType  := ObjectPtr^.GetType;
  337.  
  338.   if NewType <> OldType then
  339.   begin
  340.     { Change the object's type which marks the document as 'dirty' and
  341.       notifies each linked object of the change.  Then invalidate
  342.       the window to redraw the object, and update the menu to reflect
  343.       the changes.
  344.     }
  345.     ObjectPtr^.SetType(NewType);
  346.  
  347.     InvalidateRect(HWindow, nil, True);
  348.     CheckMenuItem(MyMenu, NativeTypeToCm[OldType], mf_Unchecked);
  349.     CheckMenuItem(MyMenu, NativeTypeToCm[NewType], mf_Checked);
  350.   end;
  351. end;
  352.  
  353. { Changes the File/Save As... menu item to File/Save Copy As...
  354.   when an embedded document is being edited.
  355. }
  356. procedure TServerWindow.BeginEmbedding;
  357. var
  358.   MyMenu : HMenu;
  359. begin
  360.   MyMenu := GetMenu(HWindow);
  361.   ModifyMenu(MyMenu, cm_FileSaveAs, mf_ByCommand or mf_String, cm_FileSaveAs, 'Save Copy &As...');
  362. end;
  363.  
  364. { Changes File/Save Copy As..., File/Exit & Return, and
  365.   File/Update menu entries to reflect the end of embedded editing.
  366. }
  367. procedure TServerWindow.EndEmbedding;
  368. var
  369.   MyMenu : HMenu;
  370. begin
  371.   MyMenu := GetMenu(HWindow);
  372.   ModifyMenu(MyMenu, cm_FileSaveAs, mf_ByCommand or mf_String,
  373.     cm_FileSaveAs, 'Save &As...');
  374.   ModifyMenu(MyMenu, cm_Exit,       mf_ByCommand or mf_String,
  375.     cm_Exit,       'E&xit');
  376.   ModifyMenu(MyMenu, cm_FileUpdate, mf_ByCommand or mf_String,
  377.     cm_FileSave,   '&Save');
  378. end;
  379.  
  380. { Changes the  File/Save to File/Update <Client Document> and
  381.   File/Exit to File/Exit & Return to <Client Document> in response
  382.   to a SetHostNames callback from the Client.
  383. }
  384. procedure TServerWindow.UpdateFileMenu(DocName: PChar);
  385. var
  386.   MyMenu : HMenu;
  387.   Buf    : array [0..127] of Char;
  388. begin
  389.   MyMenu := GetMenu(HWindow);
  390.  
  391.   StrCopy(Buf, '&Update ');
  392.   StrCat(Buf, DocName);
  393.   ModifyMenu(MyMenu, cm_FileSave, mf_ByCommand or mf_String,
  394.     cm_FileUpdate, Buf);
  395.  
  396.   StrCopy(Buf, '&Exit and Return to ');
  397.   StrCat(Buf, DocName);
  398.   ModifyMenu(MyMenu, cm_Exit, mf_ByCommand or mf_String, cm_Exit, Buf);
  399. end;
  400.  
  401. { Draws the object in Self's client area, by requesting the OLE Server
  402.   to perform the paint with our DC.
  403. }
  404. procedure TServerWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  405. begin
  406.   SetViewportOrg(PaintDC, ObjX, ObjY);
  407.   POleApp(Application)^.Server^.Document^.OleObject^.Draw(PaintDC);
  408. end;
  409.  
  410. end.
  411.  
  412.