home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / ole / shapes / server.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-17  |  28.7 KB  |  1,247 lines

  1. #define SERVERONLY
  2. #include "windows.h"
  3. #include "ecd.h"
  4. #include "shapes.h"
  5.  
  6. //////////////////////////////////////////////////////////////////////////
  7. //
  8. // (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
  9. //
  10. /////////////////////////////////////////////////////////////////////////
  11.  
  12.  
  13. // We alis the null item with the very first item in the file.
  14. // Since we never copy more than one item to clip board, there
  15. // is no problem for the objects being edited. If they are created
  16. // from template, we give the first child window back.
  17.  
  18.  
  19. extern      HANDLE  hInst;
  20.  
  21. extern      char    *pcolors[];
  22. extern      char    *pshapes[];
  23. extern      HBRUSH  hbrColor [5];
  24.  
  25. extern      WORD    cfLink;
  26. extern      WORD    cfOwnerLink;
  27. extern      WORD    cfNative;
  28.  
  29. extern      WORD    cShapes;
  30.  
  31. ECDDOCUMENTVTBL     docVTbl;
  32. ECDOBJECTVTBL       itemVTbl;
  33. ECDSERVERVTBL       srvrVTbl;
  34.  
  35.  
  36. void FreeVTbls ()
  37. {
  38.  
  39.     FreeProcInstance(srvrVTbl.Open);
  40.     FreeProcInstance(srvrVTbl.Create);
  41.     FreeProcInstance(srvrVTbl.CreateFromTemplate);
  42.     FreeProcInstance(srvrVTbl.Edit);
  43.     FreeProcInstance(srvrVTbl.Exit);
  44.     FreeProcInstance(srvrVTbl.Release);
  45.  
  46.     FreeProcInstance (docVTbl.Save);
  47.     FreeProcInstance (docVTbl.Close);
  48.     FreeProcInstance (docVTbl.GetObject);
  49.     FreeProcInstance (docVTbl.Release);
  50.  
  51.     FreeProcInstance (docVTbl.SetHostNames);
  52.     FreeProcInstance (docVTbl.SetDocDimensions);
  53.  
  54.  
  55.     FreeProcInstance (itemVTbl.Show);
  56.     FreeProcInstance (itemVTbl.GetData);
  57.     FreeProcInstance (itemVTbl.SetData);
  58.     FreeProcInstance (itemVTbl.Delete);
  59.     FreeProcInstance (itemVTbl.SetTargetDevice);
  60.     FreeProcInstance (itemVTbl.EnumFormats);
  61.  
  62. }
  63.  
  64. void InitVTbls ()
  65. {
  66.  
  67.     // srvr vtable.
  68.  
  69.     srvrVTbl.Open    = MakeProcInstance(SrvrOpen, hInst);
  70.     srvrVTbl.Create  = MakeProcInstance(SrvrCreate, hInst);
  71.     srvrVTbl.CreateFromTemplate = MakeProcInstance(SrvrCreateFromTemplate, hInst);
  72.     srvrVTbl.Edit    = MakeProcInstance(SrvrEdit, hInst);
  73.     srvrVTbl.Exit    = MakeProcInstance(SrvrExit, hInst);
  74.     srvrVTbl.Release = MakeProcInstance(SrvrRelease, hInst);
  75.  
  76.     // doc table
  77.     docVTbl.Save       = MakeProcInstance(DocSave, hInst);
  78.     docVTbl.Close      = MakeProcInstance(DocClose, hInst);
  79.     docVTbl.GetObject  = MakeProcInstance(DocGetObject, hInst);
  80.     docVTbl.Release    = MakeProcInstance(DocRelease, hInst);
  81.  
  82.     docVTbl.SetHostNames        = MakeProcInstance(DocSetHostNames, hInst);
  83.     docVTbl.SetDocDimensions    = MakeProcInstance(DocSetDocDimensions, hInst);
  84.  
  85.     // item table.
  86.  
  87.     itemVTbl.Show      = MakeProcInstance (ItemOpen, hInst);
  88.     itemVTbl.GetData   = MakeProcInstance (ItemGetData, hInst);
  89.     itemVTbl.SetData   = MakeProcInstance (ItemSetData, hInst);
  90.     itemVTbl.Delete    = MakeProcInstance (ItemDelete, hInst);
  91.  
  92.     itemVTbl.SetTargetDevice =  MakeProcInstance (ItemSetTargetDevice, hInst);
  93.     itemVTbl.EnumFormats =  MakeProcInstance (ItemEnumFormats, hInst);
  94.  
  95. }
  96.  
  97. BOOL ProcessCmdLine (hwnd, lpcmdline)
  98. LPSTR   lpcmdline;
  99. HWND    hwnd;
  100. {
  101.  
  102.     // Look for any file name on the command line.
  103.     char    buf[100];
  104.     int      i;
  105.  
  106.     while (*lpcmdline){
  107.         // skip blanks
  108.         while ( *lpcmdline && *lpcmdline == ' ')
  109.             lpcmdline++;
  110.  
  111.         if (*lpcmdline == '-' || *lpcmdline == '/'){
  112.             // skip the options.
  113.             while ( *lpcmdline && *lpcmdline != ' ')
  114.                 lpcmdline++;
  115.  
  116.  
  117.         } else {
  118.             // looks like we found the file name. terminate with NULL and
  119.             // open the document.
  120.  
  121.             // !!! check for the buffer limits.
  122.  
  123.             i = 0;
  124.             while ( *lpcmdline && *lpcmdline != ' ')
  125.                 buf[i++] =*lpcmdline++;
  126.  
  127.             buf[i] = 0;
  128.  
  129.            // now open the document.
  130.            if(CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0),
  131.                 (LPSTR)buf, NULL))
  132.                 return TRUE;
  133.             else
  134.                 return FALSE;
  135.         }
  136.     }
  137.     return TRUE;
  138.  
  139.  
  140. }
  141.  
  142. BOOL InitServer (hwnd, hInst)
  143. HWND    hwnd;
  144. HANDLE  hInst;
  145. {
  146.  
  147.  
  148.     HANDLE      hsrvr = NULL;
  149.     PSRVR       psrvr = NULL;
  150.     int         retval;
  151.  
  152.     hsrvr = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (SRVR));
  153.  
  154.     if (hsrvr == NULL || (psrvr = (PSRVR) LocalLock (hsrvr)) == NULL)
  155.         goto errRtn;
  156.  
  157.     psrvr->hsrvr = hsrvr;
  158.  
  159.     psrvr->ecdsrvr.lpvtbl = &srvrVTbl;
  160.  
  161.     retval = EcdRegisterServer ((LPSTR)"Shapes", (LPECDSERVER)psrvr,
  162.                 (LONG FAR *) &psrvr->lhsrvr, hInst, ECD_SRVR_SINGLE);
  163.  
  164.  
  165.     if (retval != ECD_OK)
  166.         goto errRtn;
  167.  
  168.     psrvr->hwnd = hwnd;        // corresponding main window
  169.     SetWindowLong (hwnd, 0, (LONG)(LPSRVR)psrvr);
  170.     return TRUE;
  171.  
  172. errRtn:
  173.     if (psrvr)
  174.         LocalUnlock (hsrvr);
  175.  
  176.     if (hsrvr)
  177.         LocalFree (hsrvr);
  178.  
  179.     return FALSE;
  180.  
  181. }
  182.  
  183. int     FAR     PASCAL SrvrRelease (lpecdsrvr)
  184. LPECDSERVER   lpecdsrvr;
  185. {
  186.  
  187.     PSRVR   psrvr;
  188.     HANDLE  hsrvr;
  189.     HWND    hwnd;
  190.  
  191.  
  192.     psrvr = (PSRVR)((LPSRVR)lpecdsrvr);
  193.     if (psrvr->lhsrvr)
  194.         DeleteServer (psrvr);
  195.  
  196.     else {
  197.         // This delete server should release the server immediately
  198.         hwnd = psrvr->hwnd;
  199.         LocalUnlock (hsrvr = psrvr->hsrvr);
  200.         LocalFree (hsrvr);
  201.         DestroyWindow(hwnd);
  202.     }
  203.     return TRUE;    // return something
  204. }
  205.  
  206. void DeleteServer (psrvr)
  207. PSRVR   psrvr;
  208. {
  209.      LHSERVER lhsrvr;
  210.  
  211.  
  212. #ifdef TEST
  213.      EcdRevokeServer ((LHSERVER)psrvr);
  214. #else
  215.  
  216.      lhsrvr = psrvr->lhsrvr;
  217.      psrvr->lhsrvr = NULL;
  218.      if (lhsrvr){
  219.         ShowWindow (psrvr->hwnd, FALSE);
  220.         EcdRevokeServer (lhsrvr);
  221.      }
  222. #endif
  223. }
  224.  
  225. int     FAR     PASCAL SrvrOpen (lpecdsrvr, lhdoc, lpdocname, lplpecddoc)
  226. LHDOCUMENT     lhdoc;
  227. LPECDSERVER    lpecdsrvr;
  228. LPSTR          lpdocname;
  229. LPECDDOCUMENT FAR *lplpecddoc;
  230. {
  231.     PDOC    pdoc;
  232.  
  233.  
  234.     PROBE_BUSY(bBusy);
  235.  
  236.     // errors are not taken care properly
  237.     if(!(pdoc = CreateDocFromFile ((PSRVR)((LPSRVR)lpecdsrvr), lpdocname, lhdoc)))
  238.         return ECD_ERROR_MEMORY;
  239.  
  240.     *lplpecddoc = (LPECDDOCUMENT)pdoc;
  241.     return ECD_OK;
  242.  
  243. }
  244.  
  245.  
  246. int     FAR     PASCAL SrvrCreate (lpecdsrvr, lhdoc, lpclassname, lpdocname, lplpecddoc)
  247. LHDOCUMENT         lhdoc;
  248. LPECDSERVER   lpecdsrvr;
  249. LPSTR         lpclassname;
  250. LPSTR         lpdocname;
  251. LPECDDOCUMENT  FAR *lplpecddoc;
  252. {
  253.  
  254.    PDOC pdoc;
  255.    // errors are not taken care properly
  256.  
  257.    PROBE_BUSY(bBusy);
  258.  
  259.    if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
  260.         return ECD_ERROR_MEMORY;
  261.  
  262.    CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
  263.    *lplpecddoc = (LPECDDOCUMENT)pdoc;
  264.  
  265.    return ECD_OK;
  266.  
  267. }
  268.  
  269. int     FAR     PASCAL SrvrCreateFromTemplate (lpecdsrvr, lhdoc, lpclassname, lpdocname, lptemplatename, lplpecddoc)
  270. LHDOCUMENT    lhdoc;
  271. LPECDSERVER   lpecdsrvr;
  272. LPSTR         lpclassname;
  273. LPSTR         lpdocname;
  274. LPSTR         lptemplatename;
  275. LPECDDOCUMENT  FAR *lplpecddoc;
  276. {
  277.  
  278.     PDOC    pdoc;
  279.  
  280.     PROBE_BUSY(bBusy);
  281.  
  282.     if(!(pdoc = CreateDocFromFile ((PSRVR)lpecdsrvr, lptemplatename, lhdoc)))
  283.         return ECD_ERROR_MEMORY;
  284.  
  285.     ChangeDocName (pdoc, (LPSTR)lptemplatename);
  286.     *lplpecddoc = (LPECDDOCUMENT)pdoc;
  287.     return ECD_OK;
  288.  
  289. }
  290.  
  291. int     FAR     PASCAL SrvrEdit (lpecdsrvr, lhdoc, lpclassname, lpdocname, lplpecddoc)
  292. LHDOCUMENT    lhdoc;
  293. LPECDSERVER   lpecdsrvr;
  294. LPSTR         lpclassname;
  295. LPSTR         lpdocname;
  296. LPECDDOCUMENT  FAR *lplpecddoc;
  297. {
  298.  
  299.    PDOC pdoc;
  300.  
  301.    PROBE_BUSY(bBusy);
  302.  
  303.    // errors are not taken care properly
  304.  
  305.    if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
  306.         return ECD_ERROR_MEMORY;
  307.  
  308.    *lplpecddoc = (LPECDDOCUMENT)pdoc;
  309.  
  310.    return ECD_OK;
  311.  
  312.  
  313. }
  314.  
  315. int     FAR     PASCAL SrvrExit (lpecdsrvr)
  316. LPECDSERVER   lpecdsrvr;
  317. {
  318.  
  319.     // Server lib is calling us to exit.
  320.     // Let us hide the main window.
  321.     // But let us not delete the window.
  322.     PSRVR   psrvr;
  323.  
  324.     PROBE_BUSY(bBusy);
  325.  
  326.     psrvr = (PSRVR)lpecdsrvr;
  327.  
  328.     ShowWindow (psrvr->hwnd, FALSE);
  329.     EcdRevokeServer (psrvr->lhsrvr);
  330.     return ECD_OK;
  331.  
  332.  
  333.  
  334. }
  335.  
  336. // doucment functions.
  337.  
  338. PDOC    InitDoc (hwnd, lhdoc)
  339. HWND        hwnd;
  340. LHDOCUMENT  lhdoc;
  341. {
  342.     HANDLE      hdoc = NULL;
  343.     PDOC        pdoc = NULL;
  344.     char        buf[128];
  345.     PSRVR       psrvr;
  346.  
  347.  
  348.  
  349.     hdoc = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (DOC));
  350.  
  351.     if (hdoc == NULL || (pdoc = (PDOC) LocalLock (hdoc)) == NULL)
  352.         goto errRtn;
  353.  
  354.     pdoc->hdoc = hdoc;
  355.     pdoc->hwnd = hwnd;        // corresponding main window
  356.  
  357.     psrvr = (PSRVR)GetWindowLong (GetParent (hwnd), 0);
  358.     GetWindowText (hwnd, (LPSTR)buf, 128);
  359.     if (lhdoc == NULL){
  360.         if (EcdRegisterDocument (psrvr->lhsrvr, (LPSTR)buf, (LPECDDOCUMENT)pdoc,
  361.             (LHDOCUMENT FAR *)&pdoc->lhdoc) != ECD_OK)
  362.             goto errRtn;
  363.     } else
  364.         pdoc->lhdoc = lhdoc;
  365.  
  366.     pdoc->aName = GlobalAddAtom ((LPSTR)buf);
  367.     SetWindowLong (hwnd, 0, (LONG)pdoc);
  368.  
  369.     pdoc->ecddoc.lpvtbl = &docVTbl;
  370.  
  371.     // set the anchor point for children
  372.     pdoc->ptAnchor.x = 0;
  373.     pdoc->ptAnchor.y = 0;
  374.  
  375.     return pdoc;
  376.  
  377. errRtn:
  378.  
  379.     if (pdoc)
  380.         LocalUnlock (hdoc);
  381.  
  382.     if (hdoc)
  383.         LocalFree;
  384.  
  385.     return (PDOC)NULL;
  386.  
  387. }
  388.  
  389.  
  390. int FAR PASCAL  DocSave (lpecddoc)
  391. LPECDDOCUMENT    lpecddoc;
  392. {
  393.  
  394.     PROBE_BUSY(bBusy);
  395.     // not yet implemented
  396.     return ECD_OK;
  397.  
  398.  
  399. }
  400.  
  401. void DeleteDoc (pdoc)
  402. PDOC    pdoc;
  403. {
  404.     LHDOCUMENT   lhdoc;
  405.  
  406. #ifdef TEST
  407.     EcdRevokeDocument ((LHDOCUMENT)pdoc);
  408.  
  409. #else
  410.     lhdoc = pdoc->lhdoc;
  411.     pdoc->lhdoc = NULL;
  412.     if (lhdoc) {
  413.         ShowWindow (pdoc->hwnd, FALSE);
  414.         EcdRevokeDocument (lhdoc);
  415.     }
  416. #endif
  417.  
  418. }
  419.  
  420.  
  421. int FAR PASCAL  DocClose (lpecddoc)
  422. LPECDDOCUMENT    lpecddoc;
  423. {
  424.     PDOC    pdoc;
  425.  
  426.     PROBE_BUSY(bBusy);
  427.     pdoc = (PDOC)lpecddoc;
  428.  
  429.     SendDocChangeMsg (pdoc, ECD_CLOSED);
  430.     DeleteDoc (pdoc);
  431.     return ECD_OK;
  432.  
  433. }
  434.  
  435. int FAR PASCAL DocSetHostNames(lpecddoc, lpclientName, lpdocName)
  436. LPECDDOCUMENT    lpecddoc;
  437. LPSTR            lpclientName;
  438. LPSTR            lpdocName;
  439. {
  440.  
  441.  
  442.     PDOC    pdoc;
  443.     char    buf[200];
  444.     int     len;
  445.     HWND    hwnd;
  446.  
  447.     PROBE_BUSY(bBusy);
  448.  
  449.     // Do something to show that the titiel are chaning
  450.     pdoc = (PDOC)lpecddoc;
  451.     hwnd = pdoc->hwnd;
  452.  
  453.     SetWindowText (hwnd, lpdocName);;
  454.  
  455.     hwnd = GetParent (hwnd);
  456.     lstrcpy ((LPSTR)buf, lpclientName);
  457.     lstrcat ((LPSTR)buf, (LPSTR)":");
  458.     lstrcat ((LPSTR)buf, (LPSTR)"Sample Server Application");
  459.     len = lstrlen ((LPSTR)buf);
  460.     SetWindowText (hwnd, (LPSTR)buf);
  461.  
  462.     return ECD_OK;
  463.  
  464. }
  465. int FAR PASCAL DocSetDocDimensions(lpecddoc, lprc)
  466. LPECDDOCUMENT   lpecddoc;
  467. LPRECT  lprc;
  468. {
  469.     PROBE_BUSY(bBusy);
  470.     return ECD_OK;
  471.  
  472.  
  473. }
  474.  
  475. int FAR PASCAL  DocRelease (lpecddoc)
  476. LPECDDOCUMENT    lpecddoc;
  477. {
  478.  
  479.     // !!! what is this supposed to do?
  480.     // Revoke document calls DocRelease.
  481.  
  482.     PDOC    pdoc;
  483.     HANDLE  hdoc;
  484.     HWND    hwnd;
  485.  
  486.  
  487.     PROBE_BUSY(bBusy);
  488.  
  489.     pdoc = (PDOC)lpecddoc;
  490.     GlobalDeleteAtom (pdoc->aName);
  491.     hwnd = pdoc->hwnd;
  492.     LocalUnlock (hdoc = pdoc->hdoc);
  493.     LocalFree (hdoc);
  494.     DestroyWindow(hwnd);
  495.     return TRUE;        // return something
  496.  
  497. }
  498.  
  499. int ChangeDocName (pdoc, lpname)
  500. PDOC    pdoc;
  501. LPSTR   lpname;
  502. {
  503.  
  504.     GlobalDeleteAtom (pdoc->aName);
  505.     pdoc->aName = GlobalAddAtom (lpname);
  506.     SetWindowText (pdoc->hwnd, lpname);
  507.     return TRUE;        // return something
  508.  
  509. }
  510.  
  511.  
  512. int FAR PASCAL  DocGetObject (lpecddoc, lpitemname, lplpecdobject, lpecdclient)
  513. LPECDDOCUMENT       lpecddoc;
  514. LPSTR               lpitemname;
  515. LPECDOBJECT FAR *   lplpecdobject;
  516. LPECDCLIENT         lpecdclient;
  517. {
  518.     PDOC    pdoc;
  519.     HWND    hwnd;
  520.     ATOM    aName;
  521.     PITEM   pitem;
  522.  
  523.  
  524.     PROBE_BUSY(bBusy);
  525.  
  526.     pdoc  = (PDOC)lpecddoc;
  527.     aName = GlobalFindAtom (lpitemname);
  528.     hwnd = GetWindow ((hwnd = pdoc->hwnd), GW_CHILD);
  529.  
  530.     // go thru all the child window list and find the window which is
  531.     // matching the given item name.
  532.  
  533.     while (hwnd){
  534.  
  535.        // !!! We are trying to match the doc item with any item
  536.        // OK only if there is only one item in a doc. Otherwise
  537.        // we will be in troubles. Should work without any problems.
  538.        // for embedded objects.
  539.  
  540.         pitem = (PITEM)GetWindowLong (hwnd, 0);
  541.  
  542.         // Alias the null with the very first item
  543.         if (pitem->aName == aName || pitem->aName == NULL || aName == NULL)
  544.             goto rtn;
  545.  
  546.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  547.     }
  548.     // we did not find the item we wanted. So, create one
  549.  
  550.     // create a window with empty native data.
  551.  
  552.     if (CreateNewItem (pdoc, IDM_RECT, IDM_RED, FALSE)) {
  553.         // newly created window is always the first child
  554.         pitem = (PITEM)GetWindowLong (GetWindow (pdoc->hwnd, GW_CHILD), 0);
  555.         BringWindowToTop (pitem->hwnd);
  556.     } else
  557.         return ECD_ERROR_MEMORY;
  558. rtn:
  559.     pitem->aName = GlobalAddAtom (lpitemname);
  560.     // If the item is not null, then do not show the window.
  561.     *lplpecdobject = (LPECDOBJECT)pitem;
  562.     pitem->lpecdclient = lpecdclient;
  563.     return ECD_OK;
  564.  
  565. }
  566.  
  567.  
  568. // item related routines
  569.  
  570. void SetNewItemName (pitem)
  571. PITEM   pitem;
  572. {
  573.     char    buf[3];
  574.  
  575.     lstrcpy ((LPSTR)pitem->name, (LPSTR)"Shape #");
  576.  
  577.  
  578.     if (cShapes++ > 100)
  579.         cShapes = 1;
  580.  
  581.     buf[0] = (char)((cShapes / 10)  + (int)'0');
  582.     buf[1] = (char)((cShapes % 10)  + (int)'0');
  583.     buf[2] = 0;
  584.  
  585.     lstrcat ((LPSTR)pitem->name, (LPSTR)buf);
  586.     pitem->aName = GlobalAddAtom ((LPSTR)pitem->name);
  587. }
  588.  
  589. void SetItemName (pitem, lpname)
  590. PITEM   pitem;
  591. LPSTR   lpname;
  592. {
  593.     pitem->aName = GlobalAddAtom (lpname);
  594.     lstrcpy ((LPSTR)pitem->name, lpname);
  595. }
  596.  
  597. void CutCopyItem (hwnd)
  598. HWND    hwnd;
  599. {
  600.     PITEM       pitem;
  601.  
  602.     if (OpenClipboard (hwnd)){
  603.  
  604.         EmptyClipboard ();
  605.  
  606.         // firt set the clipboard
  607.  
  608.         pitem = (PITEM) GetWindowLong (GetWindow(
  609.                 GetWindow (hwnd, GW_CHILD), GW_CHILD), 0);
  610.  
  611.         // Check for null handles from the render routines.
  612.         SetClipboardData (CF_METAFILEPICT, GetPicture (pitem));
  613.         SetClipboardData (CF_BITMAP, GetBitmap (pitem));
  614.         SetClipboardData (cfNative, GetNative (pitem));
  615.         SetClipboardData (cfLink, GetLink (pitem));
  616.         SetClipboardData (cfOwnerLink, GetLink (pitem));
  617.         CloseClipboard ();
  618.     }
  619.  
  620.  
  621. }
  622.  
  623. HANDLE  GetNative (pitem)
  624. PITEM   pitem;
  625. {
  626.  
  627.  
  628.     LPSTR       lpsrc;
  629.     LPSTR       lplink = NULL;
  630.     HANDLE      hlink = NULL;
  631.     int         i;
  632.  
  633.  
  634.  
  635.     hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof (ITEM));
  636.     if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
  637.         goto errRtn;
  638.  
  639.     lpsrc = (LPSTR)pitem;
  640.     for (i = 0; i <  sizeof(ITEM); i++)
  641.         *lplink++ = *lpsrc++;
  642.  
  643.     GlobalUnlock (hlink);
  644.     return hlink;
  645.  
  646. errRtn:
  647.     if (lplink)
  648.         GlobalUnlock (hlink);
  649.  
  650.     if (hlink)
  651.         GlobalFree (hlink);
  652.  
  653. }
  654.  
  655. HANDLE  GetLink (pitem)
  656. PITEM   pitem;
  657. {
  658.  
  659.     char        buf[128];
  660.     LPSTR       lpsrc;
  661.     LPSTR       lplink = NULL;
  662.     HANDLE      hlink = NULL;
  663.     int         len;
  664.     int         i;
  665.  
  666.     // make the link
  667.     lstrcpy ((LPSTR)buf, (LPSTR)"Shapes");
  668.     len = lstrlen ((LPSTR)buf) + 1;
  669.     len += GetWindowText (GetParent (pitem->hwnd), (LPSTR)buf + len , 128 - len) + 1;
  670.     len += GlobalGetAtomName (pitem->aName, (LPSTR)buf + len, 128 - len) + 1;
  671.     buf[len++] = 0;       // throw in another null at the end.
  672.  
  673.  
  674.     hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, len);
  675.     if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
  676.         goto errRtn;
  677.  
  678.     lpsrc = (LPSTR)buf;
  679.     for (i = 0; i <  len; i++)
  680.         *lplink++ = *lpsrc++;
  681.  
  682.     GlobalUnlock (hlink);
  683.  
  684.     return hlink;
  685. errRtn:
  686.     if (lplink)
  687.         GlobalUnlock (hlink);
  688.  
  689.     GlobalFree (hlink);
  690.     return NULL;
  691. }
  692.  
  693. HANDLE     GetPicture (pitem)
  694. PITEM       pitem;
  695. {
  696.  
  697.     LPMETAFILEPICT  lppict = NULL;
  698.     HANDLE          hpict = NULL;
  699.     HANDLE          hMF = NULL;
  700.     HANDLE          hdc;
  701.     RECT            rc;
  702.     HPEN            hpen;
  703.     HPEN            holdpen;
  704.     int             mm;
  705.  
  706.  
  707.     // Now set the bitmap data.
  708.  
  709.     hdc = CreateMetaFile(NULL);
  710.  
  711.     GetClientRect (pitem->hwnd, (LPRECT)&rc);
  712.  
  713.     // paint directly into the bitmap
  714.     SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
  715.     PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
  716.     SetWindowOrg (hdc, 0, 0);
  717.     SetWindowExt (hdc, rc.right, rc.bottom);
  718.  
  719.  
  720.     hpen = CreatePen (PS_SOLID, 9, 0x00808080);
  721.     holdpen = SelectObject (hdc, hpen);
  722.  
  723.     switch (pitem->cmdShape){
  724.         case IDM_ROUNDRECT:
  725.             RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
  726.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  727.             break;
  728.  
  729.         case IDM_RECT:
  730.             Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
  731.             break;
  732.  
  733.         case IDM_HALLOWRECT:
  734.             SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
  735.             Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
  736.             break;
  737.  
  738.         case IDM_HALLOWROUNDRECT:
  739.             SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
  740.             RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
  741.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  742.             break;
  743.  
  744.     }
  745.  
  746.     hMF = CloseMetaFile (hdc);
  747.  
  748.     if(!(hpict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT))))
  749.         goto errRtn;
  750.  
  751.     if ((lppict = (LPMETAFILEPICT)GlobalLock (hpict)) == NULL)
  752.         goto errRtn;
  753.  
  754.     lppict->mm = MM_ANISOTROPIC;
  755.     lppict->hMF = hMF;
  756.  
  757.  
  758.     hdc = GetDC (pitem->hwnd);
  759.     mm = SetMapMode(hdc, MM_HIMETRIC);
  760.     DPtoLP(hdc, (LPPOINT)&rc, 2);
  761.     SetMapMode(hdc, mm);
  762.     ReleaseDC (pitem->hwnd, hdc);
  763.  
  764.     lppict->xExt =  rc.right - rc.left;
  765.     lppict->yExt =  rc.top - rc.bottom;
  766.     GlobalUnlock (hpict);
  767.     return hpict;
  768.  
  769. errRtn:
  770.     if (lppict)
  771.         GlobalUnlock (hpict);
  772.  
  773.     if (hpict)
  774.         GlobalFree (hpict);
  775.  
  776.     if (hMF)
  777.         DeleteMetaFile (hMF);
  778.     return NULL;
  779.  
  780. }
  781.  
  782.  
  783. HBITMAP     GetBitmap (pitem)
  784. PITEM       pitem;
  785. {
  786.  
  787.     HDC         hdc;
  788.     HDC         hdcmem;
  789.     RECT        rc;
  790.     HBITMAP     hbitmap;
  791.     HBITMAP     holdbitmap;
  792.     HPEN        hpen;
  793.     HPEN        holdpen;
  794.  
  795.  
  796.     // Now set the bitmap data.
  797.  
  798.     hdc = GetDC (pitem->hwnd);
  799.     hdcmem = CreateCompatibleDC (hdc);
  800.     GetClientRect (pitem->hwnd, (LPRECT)&rc);
  801.     hbitmap = CreateCompatibleBitmap (hdc, rc.right - rc.left, rc.bottom - rc.top);
  802.     holdbitmap = SelectObject (hdcmem, hbitmap);
  803.  
  804.     // paimt directly into the bitmap
  805.     SelectObject (hdcmem, hbrColor [ pitem->cmdColor - IDM_RED]);
  806.     PatBlt (hdcmem, 0,0, rc.right, rc.bottom, WHITENESS);
  807.  
  808.     hpen = CreatePen (PS_SOLID, 9, 0x00808080);
  809.     holdpen = SelectObject (hdcmem, hpen);
  810.  
  811.     switch (pitem->cmdShape){
  812.         case IDM_ROUNDRECT:
  813.             RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
  814.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  815.             break;
  816.  
  817.         case IDM_RECT:
  818.             Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
  819.             break;
  820.  
  821.         case IDM_HALLOWRECT:
  822.             SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
  823.             Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
  824.             break;
  825.  
  826.         case IDM_HALLOWROUNDRECT:
  827.             SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
  828.             RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
  829.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  830.             break;
  831.  
  832.     }
  833.  
  834.  
  835.  
  836.     hbitmap = SelectObject (hdcmem, holdbitmap);
  837.     hpen = SelectObject (hdcmem, holdpen);
  838.     DeleteObject (hpen);
  839.     DeleteDC (hdcmem);
  840.     ReleaseDC (pitem->hwnd, hdc);
  841.     return hbitmap;
  842.  
  843. }
  844.  
  845. PITEM   CreateNewItem (pdoc, cmdShape, cmdColor, bVisible)
  846. PDOC    pdoc;
  847. int     cmdShape;
  848. int     cmdColor;
  849. BOOL    bVisible;
  850. {
  851.  
  852.     RECT        rc;
  853.     HANDLE      hitem = NULL;
  854.     PITEM       pitem = NULL;
  855.     HWND        hwnd;
  856.  
  857.  
  858.  
  859.     GetClientRect (pdoc->hwnd, (LPRECT)&rc);
  860.  
  861.     hwnd = CreateWindow(
  862.         "ItemClass",
  863.         "Item",
  864.  
  865.         WS_DLGFRAME| WS_CHILD | WS_CLIPSIBLINGS |
  866.                     (bVisible ? WS_VISIBLE : 0),
  867.         pdoc->ptAnchor.x,
  868.         pdoc->ptAnchor.y,
  869.         (rc.right - rc.left) >> 1,
  870.         (rc.bottom - rc.top)>> 1,
  871.         pdoc->hwnd,
  872.         NULL,
  873.         hInst,
  874.         NULL
  875.     );
  876.  
  877.  
  878.     if (!hwnd)
  879.         return (FALSE);
  880.  
  881.     pdoc->ptAnchor.x += 20;
  882.     pdoc->ptAnchor.y += 20;
  883.  
  884.  
  885.     // Now create the item info;
  886.     hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
  887.  
  888.     if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
  889.         goto  errRtn;
  890.  
  891.     pitem->cmdShape = cmdShape;;
  892.     pitem->cmdColor = cmdColor;
  893.     pitem->hitem    = hitem;
  894.     pitem->aName    = NULL;
  895.     pitem->hwnd     = hwnd;
  896.     pitem->ecdobject.lpvtbl = &itemVTbl;
  897.     
  898.     pitem->width    = (rc.right - rc.left) >> 1;
  899.     pitem->height   = (rc.bottom - rc.top) >> 1;
  900.  
  901.     SetWindowLong (hwnd, 0, (LONG)pitem);
  902.     return pitem;
  903.  
  904.  errRtn:
  905.     if (pitem)
  906.         LocalUnlock (hitem);
  907.  
  908.     if (hitem)
  909.         LocalFree (hitem);
  910.  
  911.     return (PITEM)NULL;
  912.  
  913. }
  914.  
  915. int FAR PASCAL  ItemOpen (lpecdobject)
  916. LPECDOBJECT     lpecdobject;
  917. {
  918.  
  919.     // !!! This routine should activate the app
  920.     // and prepare it ready for the editing. Activation
  921.     // should bring on to the top and restore
  922.  
  923.  
  924.     PITEM   pitem;
  925.     HWND    hwnd;
  926.  
  927.     PROBE_BUSY(bBusy);
  928.     pitem = (PITEM)lpecdobject;
  929.     BringWindowToTop (pitem->hwnd);
  930.     BringWindowToTop (GetParent (pitem->hwnd));
  931.     SetActiveWindow ((hwnd = GetParent (GetParent (pitem->hwnd))));
  932.     SendMessage (hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
  933.     return ECD_OK;
  934.  
  935.  
  936. }
  937.  
  938.  
  939. int FAR PASCAL  ItemDelete (lpecdobject)
  940. LPECDOBJECT     lpecdobject;
  941. {
  942.  
  943.     PITEM   pitem;
  944.  
  945.     PROBE_BUSY(bBusy);
  946.     pitem = (PITEM)lpecdobject;
  947.     if (--pitem->ref)
  948.         return ECD_OK;
  949.  
  950.     if (IsWindow(pitem->hwnd))
  951.         DestroyWindow (pitem->hwnd);
  952.     return ECD_OK;
  953. }
  954.  
  955.  
  956. int FAR PASCAL  ItemGetData (lpecdobject, cfFormat, lphandle)
  957. LPECDOBJECT     lpecdobject;
  958. WORD            cfFormat;
  959. LPHANDLE        lphandle;
  960. {
  961.  
  962.     PITEM   pitem;
  963.  
  964.     // PROBE_BUSY(bBusy);
  965.  
  966.     // asking data for emtyp object.
  967.     pitem = (PITEM)lpecdobject;
  968.  
  969.     if (pitem->cmdShape  == NULL||
  970.         pitem->cmdColor == NULL)
  971.         return ECD_ERROR_MEMORY;
  972.  
  973.     if (cfFormat == cfNative){
  974.  
  975.         if (!(*lphandle = GetNative (pitem)))
  976.             return ECD_ERROR_MEMORY;
  977.  
  978.         return ECD_OK;
  979.     }
  980.  
  981.  
  982.     if (cfFormat == CF_BITMAP){
  983.  
  984.         if (!(*lphandle = (HANDLE)GetBitmap (pitem)))
  985.             return ECD_ERROR_MEMORY;
  986.  
  987.         return ECD_OK;
  988.     }
  989.  
  990.     if (cfFormat == CF_METAFILEPICT){
  991.  
  992.         if (!(*lphandle = GetPicture (pitem)))
  993.             return ECD_ERROR_MEMORY;
  994.  
  995.         return ECD_OK;
  996.     }
  997.  
  998.     if (cfFormat == cfLink || cfFormat == cfOwnerLink){
  999.  
  1000.         if (!(*lphandle = GetLink (pitem)))
  1001.             return ECD_ERROR_MEMORY;
  1002.  
  1003.         return ECD_OK;
  1004.     }
  1005.     return ECD_ERROR_MEMORY;          // this is actually unknow format.
  1006.  
  1007. }
  1008.  
  1009.  
  1010. int FAR PASCAL   ItemSetTargetDevice (lpecdobject, hdata)
  1011. LPECDOBJECT     lpecdobject;
  1012. HANDLE          hdata;
  1013. {
  1014.     LPSTR   lpdata;
  1015.  
  1016.     lpdata = (LPSTR)GlobalLock (hdata);
  1017.     // Print the lpdata here.
  1018.     GlobalUnlock (hdata);
  1019.     GlobalFree (hdata);
  1020.     return ECD_OK;
  1021.  
  1022. }
  1023.  
  1024. int FAR PASCAL  ItemSetData (lpecdobject, cfFormat, hdata)
  1025. LPECDOBJECT     lpecdobject;
  1026. WORD            cfFormat;
  1027. HANDLE          hdata;
  1028. {
  1029.  
  1030.     LPITEM   lpitem;
  1031.     PITEM    pitem;
  1032.  
  1033.     PROBE_BUSY(bBusy);
  1034.     pitem = (PITEM)lpecdobject;
  1035.  
  1036.     if (cfFormat != cfNative)
  1037.         return ECD_ERROR_MEMORY;
  1038.  
  1039.  
  1040.     lpitem = (LPITEM)GlobalLock (hdata);
  1041.     if (lpitem){
  1042.         pitem->cmdShape = lpitem->cmdShape;
  1043.         pitem->cmdColor = lpitem->cmdColor;
  1044.         SetItemName (pitem, (LPSTR)pitem->name);
  1045.         // This is not necessary.
  1046.         ShowWindow (pitem->hwnd, TRUE);
  1047.         InvalidateRect (pitem->hwnd, (LPRECT)NULL, TRUE);
  1048.         GlobalUnlock (hdata);
  1049.     }
  1050.  
  1051.     GlobalFree (hdata);
  1052.     return ECD_OK;
  1053. }
  1054.  
  1055. ECDCLIPFORMAT   FAR PASCAL ItemEnumFormats (lpecdobject, cfFormat)
  1056. LPECDOBJECT     lpecdobject;
  1057. ECDCLIPFORMAT   cfFormat;
  1058. {
  1059.     if (cfFormat == 0)
  1060.         return cfLink;
  1061.  
  1062.     if (cfFormat == cfLink)
  1063.         return cfOwnerLink;
  1064.  
  1065.     if (cfFormat == cfOwnerLink)
  1066.         return CF_BITMAP;
  1067.  
  1068.     if (cfFormat == CF_BITMAP)
  1069.         return CF_METAFILEPICT;
  1070.  
  1071.     if (cfFormat == CF_METAFILEPICT)
  1072.         return cfNative;
  1073.  
  1074.     //if (cfFormat == cfNative)
  1075.     //    return NULL;
  1076.  
  1077.     return NULL;
  1078. }
  1079.  
  1080. BOOL DestroyItem (hwnd)
  1081. HWND    hwnd;
  1082. {
  1083.     PITEM   pitem;
  1084.     HANDLE  hitem;
  1085.  
  1086.  
  1087.     pitem = (PITEM)GetWindowLong (hwnd, 0);
  1088.     if (pitem->aName)
  1089.         GlobalDeleteAtom (pitem->aName);
  1090.  
  1091.     LocalUnlock (hitem = pitem->hitem);
  1092.     LocalFree (hitem);
  1093.     return TRUE;        // return something
  1094.  
  1095. }
  1096.  
  1097. void    PaintItem (hwnd)
  1098. HWND    hwnd;
  1099. {
  1100.  
  1101.     HDC             hdc;
  1102.     PITEM           pitem;
  1103.     RECT            rc;
  1104.     PAINTSTRUCT     ptSt;
  1105.     HPEN            hpen;
  1106.     HPEN            holdpen;
  1107.  
  1108.  
  1109.     BeginPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
  1110.     hdc = GetDC (hwnd);
  1111.  
  1112.     // Do not paint anything for the whole document item
  1113.     // For document item the name is null.
  1114.  
  1115.     pitem = (PITEM)GetWindowLong (hwnd, 0);
  1116.  
  1117.     GetClientRect (hwnd, (LPRECT)&rc);
  1118.     PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
  1119.     SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
  1120.     hpen = CreatePen (PS_SOLID, 9, 0x00808080);
  1121.     holdpen = SelectObject (hdc, hpen);
  1122.  
  1123.     switch (pitem->cmdShape){
  1124.         case IDM_ROUNDRECT:
  1125.             RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
  1126.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  1127.             break;
  1128.  
  1129.         case IDM_RECT:
  1130.             Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
  1131.             break;
  1132.  
  1133.         case IDM_HALLOWRECT:
  1134.             SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
  1135.             Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
  1136.             break;
  1137.  
  1138.         case IDM_HALLOWROUNDRECT:
  1139.             SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
  1140.             RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
  1141.                     (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
  1142.             break;
  1143.  
  1144.     }
  1145.  
  1146.     hpen = SelectObject (hdc, holdpen);
  1147.     DeleteObject (hpen);
  1148.  
  1149.     ReleaseDC (hwnd, hdc);
  1150.     EndPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
  1151. }
  1152.  
  1153.  
  1154.  
  1155. void    SendSrvrChangeMsg (psrvr, options)
  1156. PSRVR   psrvr;
  1157. WORD    options;
  1158. {
  1159.  
  1160.     HWND    hwnd;
  1161.  
  1162.     // if we are releasing the document, do not do anything
  1163.     if (psrvr->lhsrvr == NULL)
  1164.         return;
  1165.  
  1166.     hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
  1167.     while (hwnd){
  1168.         SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), options);
  1169.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  1170.  
  1171.     }
  1172.  
  1173. }
  1174.  
  1175. void    SendDocRenameMsg (psrvr, options)
  1176. PSRVR   psrvr;
  1177. WORD    options;
  1178. {
  1179.  
  1180.     HWND    hwnd;
  1181.     PITEM   pitem;
  1182.     PDOC    pdoc;
  1183.     char    buf[128];
  1184.  
  1185.     // if we are releasing the document, do not do anything
  1186.     if (psrvr->lhsrvr == NULL)
  1187.         return;
  1188.  
  1189.     hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
  1190.     pdoc = (PDOC)GetWindowLong (hwnd, 0);
  1191.  
  1192.     // if we are releasing the document, do not do anything
  1193.     if (pdoc->lhdoc == NULL)
  1194.         return;
  1195.  
  1196.     hwnd = GetWindow (pdoc->hwnd, GW_CHILD);
  1197.  
  1198.     while (hwnd){
  1199.         pitem = (PITEM)GetWindowLong (hwnd, 0);
  1200.         // Sending rename to obe item is sufficient
  1201.         if (pitem->lpecdclient){
  1202.             (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, options,
  1203.                     (LPECDOBJECT)pitem);
  1204.  
  1205.             return;
  1206.         }
  1207.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  1208.     }
  1209.  
  1210.     // reregister the document if there are no callbacks.
  1211.     GetWindowText (pdoc->hwnd, (LPSTR)buf, 128);
  1212.     DeleteDoc (pdoc);
  1213.     CreateDocFromFile (psrvr, (LPSTR)buf, NULL);
  1214.     return;
  1215. }
  1216.  
  1217. void    SendDocChangeMsg (pdoc, options)
  1218. PDOC    pdoc;
  1219. WORD    options;
  1220. {
  1221.  
  1222.     HWND    hwnd;
  1223.  
  1224.     // if we are releasing the document, do not do anything
  1225.     if (pdoc->lhdoc == NULL)
  1226.         return;
  1227.  
  1228.     hwnd = GetWindow (pdoc->hwnd, GW_CHILD);
  1229.     while (hwnd){
  1230.         SendItemChangeMsg ((PITEM)GetWindowLong (hwnd, 0), options);
  1231.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  1232.  
  1233.     }
  1234.  
  1235. }
  1236.  
  1237.  
  1238. void    SendItemChangeMsg (pitem, options)
  1239. PITEM   pitem;
  1240. WORD    options;
  1241. {
  1242.  
  1243.     if (pitem->lpecdclient)
  1244.         (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, options,
  1245.                 (LPECDOBJECT)pitem);
  1246. }
  1247.