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