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

  1. //---------------------------------------------------------------------------
  2. // client.c
  3. //
  4. // Copyright (c) Microsoft Corporation, 1990-
  5. //---------------------------------------------------------------------------
  6.  
  7. #include "windows.h"
  8. #include "ecd.h"
  9. #include "cldemo.h"
  10. #include "client.h"
  11.  
  12. //--- Globals --------------------------------------------------------------
  13. extern HWND    hwndEdit;
  14. extern BOOL fInsUpdate;
  15. extern HWND rgchChildWnd[];
  16. extern int irgchChild;
  17. // extern BOOL fObjectClose;
  18.  
  19. LPECDCLIENT     lpclient;
  20. ECDCLIENTVTBL   clientTbl;
  21. ECDSTREAMVTBL   streamTbl;
  22. LPAPPSTREAM     lpstream;
  23. HANDLE            hObjectUndo = NULL;
  24. LPECDOBJECT     lpObjectUndo;
  25. WORD            wUpdateUndo, wTypeUndo;
  26. BOOL            fEcdrelease;
  27. BOOL            fEcdReleaseError;
  28. BOOL            fEcdReleaseStat;
  29. HANDLE          hobjStream = NULL;
  30. HANDLE          hobjClient = NULL;
  31. // HANDLE             hobjPrn = NULL;
  32. HANDLE hWinTitle = 0;
  33. int    nOffDocNm, nOffItemNm;
  34.  
  35.  
  36. //--- Local Functions Declaration -------------------------------------------
  37. void GetUpdateStatus(HWND hDlg);
  38. void PrepareUndo(PITEM pitem);
  39. void PrepareUndoClear(PITEM pitem);
  40. void PrintWindowTitle(PITEM pitem, HWND hwnd);
  41. VOID SetRectSize(HWND hwnd, PITEM pitem);
  42. void PrintLinkName(PITEM pitem, HWND hwnd);
  43. void SetData(PITEM pitem, HWND hDlg);
  44.  
  45.  
  46. extern HWND GetTopChild();
  47. extern HWND GetNextWnd(LPINT i);
  48.  
  49. //---------------------------------------------------------------------------
  50. // InitClient
  51. // Purpose: Set up this application as a client
  52. // Returns: TRUE if successful
  53. //---------------------------------------------------------------------------
  54. BOOL InitClient (HANDLE hInstance)
  55.     {
  56.     
  57.     // Set up the client structure
  58.  
  59.     if (!(hobjClient = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  60.                                    sizeof(ECDCLIENT))))
  61.             return FALSE;
  62.  
  63.     if (!(lpclient = (LPECDCLIENT)(GlobalLock(hobjClient))))
  64.         {
  65.         GlobalFree(hobjClient);
  66.         hobjClient = NULL;
  67.         return FALSE;
  68.         }
  69.  
  70.     lpclient->lpvtbl = (LPECDCLIENTVTBL)&clientTbl;
  71.  
  72.     lpclient->lpvtbl->CallBack = MakeProcInstance(CallBack, hInstance);
  73.  
  74.     // Set up the stream structure
  75.  
  76.     if (!(hobjStream = GlobalAlloc (GMEM_MOVEABLE, sizeof(APPSTREAM))))
  77.         {
  78.         GlobalUnlock(hobjClient);
  79.         GlobalFree(hobjClient);
  80.         hobjClient = NULL;
  81.         return FALSE;
  82.         }
  83.  
  84.     if(lpstream = (LPAPPSTREAM)(GlobalLock(hobjStream)))
  85.         {
  86.         lpstream->lpstbl = (LPECDSTREAMVTBL)&streamTbl;
  87.         streamTbl.Get =
  88.             (LONG  (pascal far *) (LPECDSTREAM, LPSTR, LONG))
  89.             MakeProcInstance((FARPROC) ReadStream, hInstance);
  90.         streamTbl.Put =
  91.             (LONG  (pascal far *) (LPECDSTREAM, LPSTR, LONG))
  92.             MakeProcInstance((FARPROC) WriteStream, hInstance);
  93.         streamTbl.Seek =
  94.             (LONG  (pascal far *) (LPECDSTREAM, LONG))
  95.             MakeProcInstance((FARPROC) PosStream, hInstance);
  96.         streamTbl.Status =  MakeProcInstance((FARPROC) StatusStream, hInstance);
  97.         lpstream->hobjStream = hobjStream;
  98.         }
  99.     else
  100.         {
  101.         GlobalUnlock(hobjClient);
  102.         GlobalFree(hobjClient);
  103.         hobjClient = NULL;
  104.         GlobalFree(hobjStream);
  105.         hobjStream = NULL;
  106.         return FALSE;
  107.         }
  108.     return TRUE;
  109. }
  110.  
  111. //---------------------------------------------------------------------------
  112. // TermClient
  113. // Purpose: To clean up after termination
  114. // Returns: void
  115. //---------------------------------------------------------------------------
  116. void TermClient (void)
  117. {
  118.     // Get rid of the client structure
  119.     if (hobjClient)
  120.         {
  121.         GlobalUnlock(hobjClient);
  122.         GlobalFree(hobjClient);
  123.         }
  124.  
  125.     // Get rid of the stream structure
  126.     if (hobjStream)
  127.         {
  128.         GlobalUnlock(hobjStream);
  129.         GlobalFree(hobjStream);
  130.         }
  131. }
  132.  
  133. //---------------------------------------------------------------------------
  134. // CallBack
  135. // Purpose: Client Callback Function
  136. //---------------------------------------------------------------------------
  137. int FAR PASCAL
  138. CallBack(LPECDCLIENT lpclient, int flags, LPECDOBJECT lpObject)
  139. {
  140.     RECT rc;
  141.     HWND hDC;
  142.     ECDSTATUS EcdStat;
  143.     switch(flags)
  144.         {
  145.         case ECD_SAVED:
  146.         case ECD_CHANGED:
  147.         case ECD_CLOSED:
  148.             {
  149.             HANDLE hitem;
  150.             PITEM  pitem;
  151.             HWND   hwnd, hNext;
  152.                 short mm;
  153.           
  154.             // The file needs to be saved
  155.             fDirty = TRUE;
  156.  
  157.             // Find out if we need to update our visuals immediately
  158.                 if (fInsUpdate){ // it is for case when object created by EcdCreate
  159.                     fInsUpdate = FALSE;
  160.                     }
  161.  
  162.             hwnd = GetTopWindow(hwndMain);
  163.                 while(hwnd){
  164.                     if (hwnd != hwndEdit){
  165.                         hitem = GetWindowWord(hwnd, 0);
  166.                         pitem = (PITEM) LocalLock(hitem);
  167.                     if (pitem->lpecdobject == lpObject && (flags == ECD_CLOSED)){
  168.                             pitem->fOpen = FALSE;
  169.                             }
  170.                     if (pitem->lpecdobject == lpObject){
  171.                             SetRectSize(hwnd, pitem);
  172.                         InvalidateRect(hwnd, NULL, TRUE);
  173.                             }
  174.                     LocalUnlock(hitem);
  175.                         }
  176.                     hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  177.                     }
  178.             
  179.             }
  180.                 break;
  181.  
  182.         case ECD_RELEASE:
  183.             fEcdrelease = TRUE;
  184.                 if ((fEcdReleaseStat = EcdQueryReleaseError(lpObject)) != ECD_OK){
  185.                     fEcdReleaseError = TRUE;
  186.                     }
  187.                 else
  188.                     fEcdReleaseError = FALSE;
  189.  
  190.             break;
  191.  
  192.         case ECD_QUERY_PAINT:
  193.             // Yes, paint!
  194.             return TRUE; 
  195.             break;
  196.  
  197.         case ECD_RENAMED:
  198.             // The file needs to be saved
  199.             fDirty = TRUE;
  200.             break;
  201.  
  202.         default:
  203.             break;
  204.     }
  205.     return 0;
  206. }
  207.  
  208. //---------------------------------------------------------------------------
  209. // ClientUpdateMenu
  210. // Purpose: Update the Edit menu
  211. // Returns: void
  212. //---------------------------------------------------------------------------
  213. void ClientUpdateMenu(HWND hwnd, HMENU hMenu)
  214. {
  215.     HWND    hwndChild;
  216.     HANDLE  hitem;
  217.     PITEM   pitem;
  218.     int     mfPaste = MF_GRAYED;
  219.     int     mfPasteLink = MF_GRAYED;
  220.     int     mfProperties = MF_GRAYED;
  221.     int     mfClear = MF_GRAYED;
  222.     int     mfCut   = MF_GRAYED;
  223.     int     mfCopy  = MF_GRAYED;
  224.     int     mfUndo  = MF_GRAYED;
  225.     int     mfClose  = MF_GRAYED;
  226.     int     mfCopyLink  = MF_GRAYED;
  227.     int     mfReconnect  = MF_GRAYED;
  228.  
  229.     // Enable "Paste" if there is a paste-able object in the clipboard */
  230.      if (hObjectUndo)
  231.         mfUndo = MF_ENABLED;
  232.     if (EcdQueryCreateFromClip(PROTOCOL, ecdrender_draw, 0) == ECD_OK)
  233.         mfPaste = MF_ENABLED;
  234.     
  235.     // Enable "Paste Link" if there is a link-able object in the clipboard 
  236.     if (EcdQueryLinkFromClip(PROTOCOL, ecdrender_draw, 0) == ECD_OK)
  237.         mfPasteLink = MF_ENABLED;
  238.     
  239.     // Enable "Clear", "Cut", "Copy" and maybe "Properties..." 
  240.     // if we have a child window
  241.         if (GetWindowWord(hwndMain, 0)) // if there is any window
  242.         {
  243.         mfClear = MF_ENABLED;
  244.         mfCut   = MF_ENABLED;
  245.         mfCopy  = MF_ENABLED;
  246.         mfCopyLink  = MF_ENABLED;
  247.              hwndChild = GetTopWindow(hwnd);
  248.             if (hwndChild == hwndEdit)
  249.             hwndChild = GetTopWindow(hwnd);
  250.         hitem = GetWindowWord(hwndChild, 0);
  251.         pitem = (PITEM) LocalLock(hitem);
  252.         if (pitem->wType != IDM_STATIC)
  253.             mfProperties = MF_ENABLED;
  254.           if (pitem->fOpen)
  255.             mfClose  = MF_ENABLED;
  256.           if (pitem->fClose)
  257.             mfReconnect = MF_ENABLED;
  258.         LocalUnlock(hitem);
  259.         }
  260.  
  261.     EnableMenuItem(hMenu, IDM_UNDO,       mfUndo);
  262.     EnableMenuItem(hMenu, IDM_CUT,        mfCut);
  263.     EnableMenuItem(hMenu, IDM_COPY,       mfCopy);
  264.     EnableMenuItem(hMenu, IDM_CLOSE,      mfClose);
  265.     EnableMenuItem(hMenu, IDM_COPYLINK,   mfCopyLink);
  266.     EnableMenuItem(hMenu, IDM_LINK,       mfPasteLink);
  267.     EnableMenuItem(hMenu, IDM_PASTE,      mfPaste);
  268.     EnableMenuItem(hMenu, IDM_CLEAR,      mfClear);
  269.     EnableMenuItem(hMenu, IDM_PROPERTIES, mfProperties);
  270.     EnableMenuItem(hMenu, IDM_RECONNECT,  mfReconnect);
  271. }
  272.  
  273. //---------------------------------------------------------------------------
  274. // ClientCutCopy
  275. // Purpose: Does "Cut" and "Copy"
  276. // Returns: void
  277. //---------------------------------------------------------------------------
  278. void ClientCutCopy(HWND hwndMain, WORD w)
  279. {
  280.     HWND hwnd;
  281.     HANDLE hitem;
  282.     PITEM pitem;
  283.  
  284.     hwnd = GetTopWindow(hwndMain);
  285.     hitem = GetWindowWord(hwnd, 0);
  286.     pitem = (PITEM) LocalLock(hitem);
  287.     if (pitem->lpecdobject && OpenClipboard(hwndMain))
  288.         {
  289.         EmptyClipboard();
  290.         if (w = IDM_COPY)
  291.             {
  292.             EcdCopyToClipboard(pitem->lpecdobject);
  293.             }
  294.         else
  295.             {
  296.             EcdCutToClipboard(pitem->lpecdobject);
  297.             pitem->lpecdobject = NULL;
  298.             }
  299.         CloseClipboard();
  300.         }
  301.     LocalUnlock(hitem);
  302. }
  303.  
  304.  
  305. //---------------------------------------------------------------------------
  306. // ClientPasteLink
  307. // Purpose: Does "Paste" and "Paste Link"
  308. // Returns: void
  309. //---------------------------------------------------------------------------
  310. void ClientPasteLink(HWND hwndMain, WORD w)
  311. {
  312.     HWND hwnd = NULL;
  313.     HANDLE hitem;
  314.     PITEM pitem = NULL;
  315.     ECDCLIPFORMAT   cfFormat;
  316.  
  317.     RECT rc;
  318.     HDC hdc;
  319.     short mm;
  320.     POINT pt;
  321.     ECDSTATUS EcdStat;
  322.  
  323.     // Allocate memory for a new item
  324.     hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
  325.     if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
  326.         goto  errRtn;
  327.  
  328.     if (hwnd = CreateItemWindow(hwndMain, FALSE, NULL))
  329.         {
  330.         SetWindowWord (hwnd, 0, hitem);
  331.         BringWindowToTop (hwnd);
  332.         }
  333.     else goto errRtn;
  334.  
  335.         rgchChildWnd[irgchChild++] = hwnd;
  336.         SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0)+1) );
  337.  
  338.     // Grab the item from the clipboard
  339.     switch (w)
  340.         {
  341.         case IDM_PASTE:
  342.             if (!OpenClipboard(hwndMain))
  343.                 goto errRtn;
  344.             else if( (EcdStat = EcdCreateFromClip(PROTOCOL, lpclient, 0, NULL, &(pitem->lpecdobject),
  345.                 ecdrender_draw,  0)) != ECD_OK)
  346.                 {
  347.                     if (EcdStat == ECD_WAIT_FOR_RELEASE)
  348.                         WaitForRelease(pitem);
  349.                     if (fTestEcdStat(EcdStat)){
  350.                          CloseClipboard();
  351.                          goto errRtn;
  352.                    }
  353.                 }
  354.             CloseClipboard();
  355.             break;
  356.         case IDM_LINK:
  357.             if (!OpenClipboard(hwndMain))
  358.                 goto errRtn;
  359.             else if ( (EcdStat = EcdCreateLinkFromClip(PROTOCOL, lpclient, 0, NULL, &(pitem->lpecdobject),
  360.                     ecdrender_draw, 0)) != ECD_OK)
  361.                 {
  362.                       if (EcdStat == ECD_WAIT_FOR_RELEASE)
  363.                         WaitForRelease(pitem);
  364.                     if (fTestEcdStat(EcdStat)){
  365.                              CloseClipboard();
  366.                              goto errRtn;
  367.                        }
  368.                 }
  369.             CloseClipboard();
  370.             break;
  371.         }
  372.                                     
  373.         pitem->fOpen = FALSE;
  374.         pitem->fClose = FALSE;
  375.     cfFormat = EcdEnumObjectFormats (pitem->lpecdobject, NULL);
  376.     if (cfFormat == cfNative)
  377.         {
  378.         pitem->wType = IDM_PASTE;  
  379.         }
  380.     else if (cfFormat == cfLink)
  381.         pitem->wType = IDM_LINK;  
  382.  
  383.     pitem->wUpdate = IDD_AUTO;
  384.      
  385.     EcdSetHostNames(pitem->lpecdobject, szHostname, szHostobjectname);
  386.  
  387.     GetCaretPos((LPPOINT)&pt);
  388.     pt.y += 15;
  389.     hdc = GetDC(hwnd);
  390.     mm = SetMapMode(hdc, MM_HIMETRIC);
  391.     DPtoLP(hdc, (LPPOINT)&pt, 1); 
  392.  
  393.     EcdQueryBounds(pitem->lpecdobject, &rc);
  394.     rc.top = pt.y ;
  395.     rc.bottom += pt.y ;
  396.     LPtoDP(hdc, (LPPOINT)&rc, 2);
  397.  
  398.  
  399.     SetMapMode(hdc, mm);
  400.     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top +
  401.         GetSystemMetrics(SM_CYCAPTION), TRUE);
  402.     ReleaseDC(hwnd, hdc);
  403.    SendMessage (hwnd, WM_USER, 0, 0L);
  404.  
  405.     ShowWindow(hwnd, SW_SHOW);
  406.      InvalidateRect(hwnd, NULL, TRUE);
  407.  
  408.     LocalUnlock(hitem);
  409.  
  410.     return;
  411.  
  412.  errRtn:
  413.     if (pitem)
  414.         LocalUnlock (hitem);
  415.  
  416.     if (hitem)
  417.         LocalFree (hitem);
  418.  
  419.     if (hwnd)
  420.         {
  421.         SetWindowWord(hwnd, 0, NULL);
  422.         DestroyWindow(hwnd);
  423.         }
  424.  
  425. }
  426.  
  427. //---------------------------------------------------------------------------
  428. // ClientCreateNewItem
  429. // Purpose: Creates a new window and associates a new item
  430. // Returns: void
  431. //---------------------------------------------------------------------------
  432. void ClientCreateNewItem (HWND hwndMain, BOOL fVisible,
  433.     LPRECT lprect, LPECDOBJECT lpobject, WORD wType, WORD wUpdate)
  434. {
  435.     HWND   hwndItem;
  436.     HANDLE hitem;
  437.     PITEM  pitem = NULL;
  438.     BOOL fIconic = FALSE;
  439.  
  440.     // Allocate memory for a new item
  441.     hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
  442.  
  443.     if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
  444.         goto  errRtn;
  445.  
  446.     pitem->wType = wType;    
  447.     pitem->wUpdate = wUpdate;
  448.     pitem->lpecdobject = lpobject;
  449.  
  450.     pitem->fOpen = FALSE;
  451.     pitem->fClose = FALSE;
  452.  
  453.     // Create a window in which to put the new item
  454.     if ((lprect->left == 0) && (lprect->top == 0) && (lprect->right == 0) && (
  455.         lprect->bottom == 0)) // i.e. iconic window
  456.         fIconic = TRUE;
  457.     if (hwndItem = CreateItemWindow(hwndMain, fIconic, lprect))
  458.         {
  459.             if (!fIconic)
  460.                 MoveWindow(hwndItem, lprect->left, lprect->top,
  461.                     lprect->right - lprect->left, lprect->bottom - lprect->top, TRUE);
  462.         EcdSetHostNames(pitem->lpecdobject, szHostname, szHostobjectname);
  463.         SetWindowWord (hwndItem, 0, hitem);
  464.             rgchChildWnd[irgchChild++] = hwndItem;
  465.          SendMessage (hwndItem, WM_USER, 0, 0L);
  466.         if (fVisible)
  467.             ShowWindow(hwndItem, SW_SHOW);
  468.                 InvalidateRect(hwndItem, NULL, TRUE);
  469.         }
  470.     else goto errRtn;
  471.     LocalUnlock(hitem);
  472.     return;
  473.  
  474.  errRtn:
  475.     if (pitem)
  476.         LocalUnlock (hitem);
  477.  
  478.     if (hitem)
  479.         LocalFree (hitem);
  480. }
  481.  
  482. //---------------------------------------------------------------------------
  483. // ClientPaint
  484. // Purpose: Ask the server to paint for us
  485. // Returns: void
  486. //---------------------------------------------------------------------------
  487. void ClientPaint(HWND hwnd, HDC hdc, PITEM pitem)
  488. {
  489.     RECT rc;
  490.     HDC saveDC;
  491.     short mm;
  492.     POINT pt;
  493.     int bot;
  494.  
  495.     // Find the coordinates of the "display" area
  496.  
  497.  
  498.     GetClientRect (hwnd, (LPRECT)&rc);
  499.     
  500.     // Convert the rectangle's coordinates to MM_HIMETRIC 
  501.     SetMapMode(hdc, MM_HIMETRIC);
  502.     DPtoLP(hdc,(LPPOINT)&rc,2);
  503.  
  504.     // Ask the server to draw the object 
  505.     EcdDraw (pitem->lpecdobject, hdc, (LPRECT)&rc, hdc);
  506. }
  507.  
  508. //---------------------------------------------------------------------------
  509. // ClientEdit
  510. // Purpose: Ask the server to edit the object
  511. // Returns: void
  512. //---------------------------------------------------------------------------
  513. void ClientEdit(HWND hwnd, PITEM pitem)
  514. {
  515.     RECT rc;
  516.     HWND hdc;
  517.     short mm;
  518.     ECDSTATUS EcdStat;
  519.  
  520.     GetClientRect(hwnd,&rc);
  521.      if (EcdQueryOpen(pitem->lpecdobject) != ECD_OK) //
  522.         EcdStat = EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
  523.      else{
  524.         EcdStat = EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
  525.         /* should be following code
  526.         if (EcdReconnect(pitem->lpecdobject) != ECD_OK){
  527.             MessageBox(hwndMain, "Error Reconnecting ",
  528.                           szAppName, MB_ICONASTERISK | MB_OK);
  529.             EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
  530.             }
  531.         */
  532.         }
  533.         pitem->fOpen = TRUE;
  534.         if (EcdStat != ECD_OK){
  535.             if (EcdStat == ECD_WAIT_FOR_RELEASE)
  536.                 WaitForRelease(pitem);
  537.                 if (fTestEcdStat(EcdStat)){
  538.                 }
  539.             }
  540.             
  541.     hdc = GetDC(hwnd);
  542.     mm = SetMapMode(hdc, MM_HIMETRIC);
  543.     DPtoLP(hdc,(LPPOINT)&rc,2);
  544.     EcdSetBounds(pitem->lpecdobject, (LPRECT)&rc);
  545.     SetMapMode(hdc, mm);
  546.     ReleaseDC(hwnd, hdc);
  547.  
  548. }
  549.  
  550. //---------------------------------------------------------------------------
  551. // ClientDelete
  552. // Purpose: Ask the server to delete the object
  553. // Returns: void
  554. //---------------------------------------------------------------------------
  555. void ClientDelete(PITEM pitem)
  556. {
  557.     MSG msg;
  558.  
  559.     if (EcdDelete (pitem->lpecdobject) == ECD_WAIT_FOR_RELEASE)
  560.         {
  561.             fEcdrelease = FALSE;
  562.             do
  563.             {
  564.             GetMessage(&msg, NULL, NULL, NULL);
  565.             TranslateMessage(&msg);
  566.             DispatchMessage(&msg); 
  567.             }
  568.         while (!fEcdrelease);
  569.         }
  570. }
  571.  
  572. //---------------------------------------------------------------------------
  573. // SetFile
  574. // Purpose: Set up the stream structure
  575. // Returns: void
  576. //---------------------------------------------------------------------------
  577. void SetFile (int fh)
  578. {
  579.     lpstream->fh = fh;
  580. }
  581.  
  582. //---------------------------------------------------------------------------
  583. // PropertiesDlgProc
  584. // Purpose: Handles the Properties... dialog box events
  585. //---------------------------------------------------------------------------
  586. BOOL FAR PASCAL
  587. PropertiesDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  588. {
  589.     HWND hwnd;
  590.     HANDLE hitem;
  591.     PITEM pitem;
  592.     LPECDOBJECT lpobject;
  593.     HSTR hstr;
  594.     LPSTR lpstrInfo, lpstr1, lpstr2;
  595.  
  596.     switch (message)
  597.         {
  598.         case WM_INITDIALOG:
  599.             lpObjectUndo = NULL;
  600.             wUpdateUndo = 0;
  601.                 hwnd = GetTopChild();
  602.             hitem = GetWindowWord(hwnd, 0);
  603.             pitem = (PITEM) LocalLock(hitem);
  604.             PrepareUndo(pitem);
  605.             CheckDlgButton(hDlg, pitem->wUpdate, TRUE);
  606.             if (pitem->wType == IDM_PASTE)
  607.                 EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
  608.                     if (pitem->wType != IDM_PASTE)
  609.                         PrintLinkName(pitem, hDlg);
  610.                  //        PrintWindowTitle(pitem, GetDlgItem(hDlg, IDD_LINKINFO));
  611.                     else
  612.                          PrintWindowTitle(pitem, GetDlgItem(hDlg, IDD_WHICH));
  613.             
  614.             LocalUnlock(hitem);
  615.             return (TRUE);
  616.  
  617.         case WM_COMMAND:
  618.             switch (wParam)
  619.                 {
  620.                 case IDD_FREEZE:
  621.                 case IDD_UPDATE:
  622.                         /*
  623.                     hwnd = GetTopWindow(hwndMain);
  624.                             if (hwnd == hwndEdit)
  625.                                 hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  626.                             */
  627.                             hwnd = GetTopChild();
  628.                     hitem = GetWindowWord(hwnd,0);
  629.                     pitem = (PITEM) LocalLock(hitem);
  630.                     if (wParam == IDD_FREEZE)
  631.                         {
  632.                         if (pitem->wType == IDM_PASTE)
  633.                             EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
  634.                         else
  635.                             EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE);
  636.                         EnableWindow(GetDlgItem(hDlg, IDD_EDIT), FALSE);
  637.                         EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE);
  638.                         if (EcdObjectConvert(pitem->lpecdobject, SPROTOCOL,
  639.                             lpclient, NULL, NULL, &lpobject) == ECD_OK)
  640.                             {
  641.                             ClientDelete (pitem);
  642.                             pitem->lpecdobject = lpobject;
  643.                             pitem->wType = IDM_STATIC;
  644.                             }
  645.                         }
  646.                     else // (wParam == IDD_UPDATE)
  647.                         {
  648.                         EcdUpdate(pitem->lpecdobject);
  649.                         }
  650.                     fDirty = TRUE;
  651.                     InvalidateRect(hwnd, NULL, TRUE);
  652.                     LocalUnlock(hitem);
  653.                     break;
  654.  
  655.                 case IDD_EDIT:
  656.                     {
  657.                     RECT rc;
  658.  
  659.                     GetUpdateStatus(hDlg);
  660.                             hwnd = GetTopChild();
  661.  
  662.                     hitem = GetWindowWord(hwnd, 0);
  663.                     pitem = (PITEM) LocalLock(hitem);
  664.                     EcdDelete(lpObjectUndo);
  665.                             lpObjectUndo = NULL;
  666.                     GetClientRect(hwnd,&rc);
  667.                     EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
  668.                     LocalUnlock(hitem);
  669.                     fDirty = TRUE;
  670.                     InvalidateRect(hwnd, NULL, TRUE);
  671.                     }
  672.                     /* Fall through */
  673.  
  674.                 case IDOK:
  675.                     GetUpdateStatus(hDlg);
  676.                     EcdDelete(lpObjectUndo);
  677.                             lpObjectUndo = NULL;
  678.                             hwnd = GetTopChild();
  679.                         hitem = GetWindowWord(hwnd, 0);
  680.                         pitem = (PITEM) LocalLock(hitem);
  681.                             if (pitem->wType != IDM_PASTE)
  682.                                 SetData(pitem, hDlg);
  683.                             LocalUnlock(hitem);
  684.                             GlobalFree(hWinTitle);
  685.                     EndDialog(hDlg, TRUE);
  686.                     return TRUE;
  687.  
  688.                 case IDCANCEL:
  689.                             hwnd = GetTopChild();
  690.  
  691.                     hitem = GetWindowWord(hwnd, 0);
  692.                     pitem = (PITEM) LocalLock(hitem);
  693.                     if (lpObjectUndo)
  694.                         {
  695.                         EcdDelete(pitem->lpecdobject);
  696.                         pitem->lpecdobject = lpObjectUndo;
  697.                         pitem->wType = wTypeUndo;
  698.                         pitem->wUpdate  = wUpdateUndo;
  699.                         }
  700.                     LocalUnlock(hitem);
  701.                         InvalidateRect(hwnd, NULL, TRUE);
  702.                             GlobalFree(hWinTitle);
  703.                     EndDialog(hDlg, TRUE);
  704.                     return TRUE;
  705.                 }
  706.             break;
  707.         }
  708.     return (FALSE);
  709. }
  710.  
  711.  
  712. //---------------------------------------------------------------------------
  713. // GetUpdateStatus
  714. // Purpose: Read the status of the update buttons in the Properties Dialog
  715. //          associate to a linked object.  
  716. //          Updates the internal data structures and inform the dll.
  717. // Return: void
  718. //---------------------------------------------------------------------------
  719. void GetUpdateStatus(HWND hDlg)
  720. {
  721.     WORD wUpdate;
  722.     HWND hwnd;
  723.     HANDLE hitem;
  724.     PITEM pitem;
  725.      ECDSTATUS EcdRet;
  726.      ECDOPT_UPDATE EcdOpt;
  727.  
  728.       
  729.     hwnd = GetTopChild();
  730.     hitem = GetWindowWord(hwnd, 0);
  731.     pitem = (PITEM) LocalLock(hitem);
  732.     if (pitem->wType == IDM_LINK)
  733.         {
  734.         wUpdate = (IsDlgButtonChecked(hDlg, IDD_AUTO) ?
  735.             IDD_AUTO : IDD_MANUAL);
  736.         if (wUpdate != pitem->wUpdate)
  737.             {
  738.             pitem->wUpdate = wUpdate;
  739.                 EcdRet = EcdGetLinkUpdateOptions(pitem->lpecdobject,
  740.                     (ECDOPT_UPDATE FAR *)&EcdOpt);
  741.                 if ((wUpdate == IDD_AUTO )&& (EcdOpt != ecdupdate_always))
  742.                     EcdSetLinkUpdateOptions(pitem->lpecdobject, ecdupdate_always);
  743.                 else if ((wUpdate == IDD_MANUAL) && (EcdOpt != ecdupdate_oncall))
  744.                     EcdSetLinkUpdateOptions(pitem->lpecdobject, ecdupdate_oncall);
  745.             }
  746.         }
  747.     LocalUnlock(hitem);
  748. }
  749.  
  750. //---------------------------------------------------------------------------
  751. // PrepareUndo
  752. // Purpose: Keep track of the current object to be able to Undo later
  753. // Return: void
  754. //---------------------------------------------------------------------------
  755. void PrepareUndo(PITEM pitem)
  756. {
  757.     // Delete the old copy of the object if necessary
  758.     if (lpObjectUndo)
  759.         EcdDelete(lpObjectUndo);
  760.  
  761.     // Create a copy of the current object
  762.     if (EcdClone(pitem->lpecdobject, lpclient,
  763.         NULL, NULL, (LPECDOBJECT FAR *)&lpObjectUndo) != ECD_OK) 
  764.         lpObjectUndo = NULL;
  765.     else
  766.         {
  767.         wUpdateUndo = pitem->wUpdate;
  768.         wTypeUndo = pitem->wType;
  769.         }
  770. }
  771.  
  772.  
  773. //---------------------------------------------------------------------------
  774. // PrepareUndoClear
  775. // Purpose: Keep track of the current object to be able to Undo later
  776. // Return: void
  777. //---------------------------------------------------------------------------
  778. void PrepareUndoClear(PITEM pitem)
  779. {
  780.     PITEM pObjectUndo;
  781.     // Delete the old copy of the object if necessary
  782.     if (hObjectUndo){
  783.         pObjectUndo = (PITEM)LocalLock(hObjectUndo);
  784.         EcdDelete(pObjectUndo->lpecdobject);
  785.         }
  786.     else {
  787.         hObjectUndo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
  788.         pObjectUndo = (PITEM) LocalLock(hObjectUndo);                
  789.       }            
  790.     // Create a copy of the current object
  791.     if (EcdClone(pitem->lpecdobject, lpclient,
  792.         NULL, NULL, (LPECDOBJECT FAR *)&pObjectUndo->lpecdobject) != ECD_OK) {
  793.         LocalUnlock(hObjectUndo);
  794.         LocalFree(hObjectUndo);
  795.       hObjectUndo = NULL;
  796.         }
  797.     else{
  798.         pObjectUndo->wType = pitem->wType;                
  799.         pObjectUndo->wUpdate = pitem->wUpdate;
  800.         LocalUnlock(hObjectUndo);
  801.         }
  802. }
  803.  
  804. //---------------------------------------------------------------------------
  805. // ReadStream
  806. // Purpose: Read from an open file
  807. //---------------------------------------------------------------------------
  808. LONG FAR PASCAL ReadStream(LPAPPSTREAM lpStream, LPSTR lpstr, LONG cb)
  809. {
  810.     return _lread(lpStream->fh, lpstr, (WORD)cb);
  811. }
  812.  
  813. //---------------------------------------------------------------------------
  814. // WriteStream
  815. // Purpose: Write to an open file
  816. //---------------------------------------------------------------------------
  817. LONG FAR PASCAL WriteStream(LPAPPSTREAM lpStream, LPSTR lpstr, LONG cb)
  818. {
  819.     return _lwrite(lpStream->fh, lpstr, (WORD)cb);
  820. }
  821.  
  822. //---------------------------------------------------------------------------
  823. // PosStream
  824. // Purpose: Reposition file pointer
  825. //---------------------------------------------------------------------------
  826. LONG FAR PASCAL PosStream(LPAPPSTREAM lpStream, LONG pos)
  827. {
  828.     return  _llseek(lpStream->fh, (LONG)pos, 0);
  829. }
  830.  
  831. //---------------------------------------------------------------------------
  832. // StatusStream
  833. // Purpose: Returns the status of a file operation
  834. // Returns: NULL (Not implemented)
  835. //---------------------------------------------------------------------------
  836. WORD FAR PASCAL StatusStream(LPAPPSTREAM lpStream)
  837. {
  838.     return NULL;
  839. }
  840.  
  841.  
  842. VOID SetRectSize(HWND hwnd, PITEM pitem){
  843.     RECT rc, rc1;
  844.     HDC hDC;
  845.     short mm;
  846.     
  847.     if (!IsIconic(hwnd)){
  848.         GetWindowRect(hwnd, &rc1);
  849.       ScreenToClient(hwndMain, (LPPOINT) &rc1);
  850.         hDC = GetDC(hwnd);
  851.         mm = SetMapMode(hDC, MM_HIMETRIC);                                
  852.         EcdQueryBounds(pitem->lpecdobject, &rc);                                
  853.         LPtoDP(hDC, (LPPOINT)&rc, 2);                                
  854.         SetMapMode(hDC, mm);                                
  855.         if ((rc.right - rc.left == 0) || (rc.bottom - rc.top == 0)){    
  856.             rc.right = 200 ;                                                        
  857.             rc.bottom = 200;                                
  858.             rc.left = 0;                                
  859.             rc.top = 0;                                
  860.             }                                
  861.         MoveWindow(hwnd, rc1.left, rc1.top, rc.right - rc.left,
  862.             rc.bottom - rc.top + GetSystemMetrics(SM_CYCAPTION), TRUE);            
  863.         ReleaseDC(hwnd, hDC);
  864.         }
  865.  
  866. }
  867.  
  868.  
  869.  
  870. /* Combine This function with PrintWindowTitle, lots of problems */
  871.  
  872. void PrintLinkName(PITEM pitem, HWND hwnd){
  873.  
  874.     ECDSTATUS EcdStat;
  875.       LPSTR pTitle, pTitle1;
  876.    LPSTR lpstrInfo, lpstr1, lpstr2;
  877.     HSTR hstr;
  878.  
  879.             if (((EcdStat = EcdGetData(pitem->lpecdobject,
  880.                     (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
  881.                     &hstr))
  882.                     == ECD_OK)
  883.                 && hstr)
  884.                 {
  885.                 // Both link formats are:  "szClass szDocument szItem 0"
  886.                 lpstrInfo = GlobalLock(hstr);
  887.                      lpstr1 = lpstrInfo;
  888.                      hWinTitle = GlobalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 512);
  889.                      pTitle = pTitle1 = (LPSTR)GlobalLock(hWinTitle);
  890.                      while (*lpstr1){
  891.                         *(pTitle++) = *(lpstr1++);
  892.                         }
  893.                      *(pTitle++) = '\0';
  894.                      lpstr1 += 1;
  895.                 SetWindowText(GetDlgItem(hwnd, IDD_LINKINFO), (LPSTR)pTitle1);
  896.                      nOffDocNm = pTitle - pTitle1;
  897.                     pTitle1 = pTitle;
  898.                      while (*lpstr1){
  899.                         *(pTitle++) = *(lpstr1++);
  900.                         }
  901.                      *(pTitle++) = '\0';
  902.                      lpstr1 += 1;
  903.                 SetWindowText(GetDlgItem(hwnd, IDD_DOCNM), (LPSTR)pTitle1);
  904.  
  905.                     nOffItemNm = pTitle - pTitle1 + nOffDocNm;
  906.                     pTitle1 = pTitle;
  907.                      while (*lpstr1){
  908.                         *(pTitle++) = *(lpstr1++);
  909.                         }
  910.                      *(pTitle++) = '\0';
  911.                      lpstr1 += 1;
  912.                 SetWindowText(GetDlgItem(hwnd, IDD_ITEMNM), (LPSTR)pTitle1);
  913.  
  914.                      GlobalUnlock(hWinTitle);
  915. //                    LocalFree(hWinTitle);
  916.                  GlobalUnlock(hstr);
  917.                 }
  918.                     }
  919.  
  920. void SetData(PITEM pitem, HWND hDlg){
  921.         char szObj[128];
  922.         BOOL fSet = FALSE;
  923.         LPSTR lpWinTitle;
  924.         ECDSTATUS EcdStat;
  925.  
  926.         lpWinTitle = GlobalLock(hWinTitle);
  927.         GetDlgItemText(hDlg, IDD_DOCNM, (LPSTR)szObj, 128);
  928.         if (lstrcmpi((LPSTR)szObj, (LPSTR)(lpWinTitle + nOffDocNm))){
  929.             lstrcpy((LPSTR)(lpWinTitle + nOffDocNm), (LPSTR)szObj);
  930.             fSet = TRUE;
  931.             }
  932.         GetDlgItemText(hDlg, IDD_ITEMNM, (LPSTR)szObj, 128);
  933.         if (lstrcmp((LPSTR)szObj, (LPSTR)(lpWinTitle + nOffItemNm))){
  934.             lstrcpy((LPSTR)(lpWinTitle + nOffItemNm), (LPSTR)szObj);
  935.             fSet = TRUE;
  936.             }
  937.         GlobalUnlock(hWinTitle);
  938.         if (fSet){
  939.             EcdStat = EcdSetData(pitem->lpecdobject,
  940.                     (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
  941.                             hWinTitle);
  942.             PrintError(EcdStat);
  943.             }
  944.         }
  945.  
  946.  
  947.  
  948.