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

  1. //---------------------------------------------------------------------------//
  2. // cldemo.c
  3. //
  4. // Copyright (c) Microsoft Corporation, 1990-
  5. //---------------------------------------------------------------------------
  6.  
  7. //---------------------------------------------------------------------------
  8. // include files 
  9. //---------------------------------------------------------------------------
  10.  
  11. #include "windows.h"
  12. #include "ecd.h"
  13. #include "cldemo.h"
  14. #include "client.h"
  15.  
  16. // ----- constants ---------------------------------------------------------
  17. #define szLessonClass  "Lesson1Class"
  18. #define szItemClass    "ItemClass"
  19. #define szMenuName     "Menu"
  20. #define szTitle        "Client - %s"
  21. #define szDefOpen      "test.cl1"
  22. #define szUntitled     "Untitled"
  23. #define szSave         "Save Changes to %s ?"
  24. #define szInvalidFn    "Invalid file name"
  25. #define szNoFile       "No filename specified."
  26. #define szFnError      "File Error"
  27. #define dxCascade      20       
  28. #define dyCascade      20
  29. #define dxInflate      5
  30. #define dyInflate      5
  31. #define cbFnMax        255
  32. #define szMsgMax       100
  33. #define szMaxClassName 20
  34. #define MaxChildWnd         20
  35.  
  36.  
  37. // ----- globals -----------------------------------------------------------
  38.  
  39.  
  40.  
  41. HANDLE  hAccTable;
  42. HWND    hwndMain;
  43. POINT   ptAnchor;                // top-left corner of a new window
  44. char    rgchFilename[cbFnMax]; // file's name
  45. char    rgchOpenName[cbFnMax]; 
  46. BOOL    fDirty = FALSE;   // true if any modification has been made to the file
  47. WORD    cfLink, cfOwnerLink, cfNative;
  48. HWND    hInst;
  49. HWND    hwndEdit = NULL;
  50. HANDLE hEditBuffer = NULL;
  51. FARPROC lpEditWndProc;
  52. BOOL fInsUpdate = FALSE;
  53. char szInsFileName[cbFnMax];
  54. HWND hUndoitem = NULL;
  55.  
  56. HWND rgchChildWnd[MaxChildWnd];
  57. int irgchChild = 0;
  58. int nObjDestroy = 0;
  59.  
  60. // BOOL fObjectClose = FALSE;
  61.  
  62. extern HANDLE            hObjectUndo;
  63. extern LPECDOBJECT     lpObjectUndo;
  64. extern BOOL            fEcdrelease;
  65. extern BOOL            fEcdReleaseError;
  66. extern BOOL            fEcdReleaseStat;
  67.  
  68. // ----- Local functions ---------------------------------------------------
  69. BOOL InitApplication (HANDLE hInstance);
  70. BOOL InitInstance (HANDLE hInstance, int nCmdShow);
  71. void TermInstance (void);
  72. void GetFromClipboard (HWND, WORD);
  73. void PutOnClipboard(HWND, WORD);
  74. void ResetAnchor (PPOINT);
  75. void MoveAnchor (PPOINT, PRECT, PPOINT);
  76. void SetNullFilename (HWND);
  77. void SetFilename (HWND, char*);
  78. BOOL SaveAsNeeded (HWND);
  79. BOOL New (HWND);
  80. BOOL Open (HWND);
  81. BOOL Save (HWND);
  82. BOOL SaveAs (HWND);
  83. BOOL WriteToFile (HWND);
  84. BOOL ReadFromFile (HWND, int);
  85. void CleanHwnd (HWND hwnd);
  86. ECDSTATUS CreateObject(WORD wParam, PITEM pitem);
  87. void CallPrint();
  88. void RemoveObjUndo();
  89. void PrintError(ECDSTATUS stat);
  90. void PrintWindowTitle(PITEM pitem, HWND hwnd);
  91.  
  92. VOID TestEqual(); 
  93.  
  94. void PrepareUndoClear(PITEM pitem);
  95. void GetUndo(PITEM pitem);
  96. ECDSTATUS CopyLink(PITEM pCopy);
  97. VOID WaitForRelease(PITEM pitem);
  98. HWND GetTopChild();
  99. HWND GetNextWnd(LPINT i);
  100.  
  101. long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
  102. long FAR PASCAL ItemWndProc(HWND, unsigned, WORD, LONG);
  103. BOOL FAR PASCAL AboutDlgProc(HWND, unsigned, WORD, LONG);
  104. BOOL FAR PASCAL SaveAsDlgProc(HWND, unsigned, WORD, LONG);
  105. int  FAR PASCAL OpenDlgProc(HWND, unsigned, WORD, LONG);
  106. BOOL FAR PASCAL InsFileProc (HWND, unsigned, WORD, LONG);
  107.  
  108. //---------------------------------------------------------------------------
  109. // WinMain
  110. // Purpose: Wins the Main
  111. //---------------------------------------------------------------------------
  112. int PASCAL
  113. WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  114. {
  115.     MSG msg;
  116.     BOOL fMsg;
  117.      hInst = hInstance;
  118.  
  119.     // initialize the application
  120.     fMsg = SetMessageQueue(32);
  121.  
  122.     if (!hPrevInstance)
  123.         if (!InitApplication(hInstance))
  124.             return (FALSE);
  125.  
  126.     // initialize the instance
  127.     if (!InitInstance(hInstance, nCmdShow))
  128.         return (FALSE);
  129.  
  130.     // initialize the client module
  131.     if (!InitClient (hInstance))
  132.         return FALSE;
  133.  
  134.     // Main message pump
  135.     while (GetMessage(&msg, NULL, NULL, NULL))
  136.         {
  137.         if (!TranslateAccelerator(hwndMain, hAccTable, &msg))
  138.             {
  139.             TranslateMessage(&msg);
  140.             DispatchMessage(&msg); 
  141.             }
  142.         }
  143.  
  144.     // clean up
  145.     TermInstance ();
  146.     TermClient ();
  147.  
  148.     return (msg.wParam);
  149. }
  150.  
  151. //---------------------------------------------------------------------------
  152. // CreateItemWindow
  153. // Purpose: Create a window in which we'll put an object
  154. // Returns: handle to the newly created window
  155. //---------------------------------------------------------------------------
  156. HWND CreateItemWindow (HWND hwndParent, BOOL fIconic, LPRECT lprect)
  157. {
  158.     RECT  rc;
  159.     POINT ptSize;
  160.  
  161.     // Find a window position and size 
  162.     // We do all the previous work even if lprect != NULL
  163.     // create the window
  164.     return (CreateWindow(
  165.         szItemClass,
  166.         "",                  // Window Title
  167.         WS_DLGFRAME | WS_CHILD | WS_CLIPSIBLINGS | 
  168.           WS_THICKFRAME |  WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX |
  169.             (fIconic ? WS_MINIMIZE : 0),
  170. //          WS_THICKFRAME | (fVisible ? WS_VISIBLE : 0),
  171.         NULL,
  172.         NULL,
  173.         200,
  174.         200,
  175.         hwndParent,
  176.         NULL,
  177.         hInst,
  178.         NULL));
  179. }
  180.  
  181.  
  182. //---------------------------------------------------------------------------
  183. // InitApplication
  184. // Purpose: Register windows' classes
  185. // Return: TRUE if successful, FALSE otherwise.
  186. //---------------------------------------------------------------------------
  187. BOOL InitApplication(hInstance)
  188. HANDLE hInstance;
  189. {
  190.     WNDCLASS  wc;
  191.  
  192.     wc.style = NULL;
  193.     wc.lpfnWndProc = MainWndProc;
  194.     wc.cbClsExtra = 0;
  195.     wc.cbWndExtra = 0;
  196.     wc.hInstance = hInstance;
  197.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  198.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  199.     wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
  200.     wc.lpszMenuName =  szMenuName;
  201.     wc.lpszClassName = szLessonClass;
  202.  
  203.     if (!RegisterClass(&wc))
  204.         return FALSE;
  205.  
  206.     wc.style   = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
  207.     wc.hIcon   =  NULL;
  208.     wc.cbWndExtra = sizeof(HANDLE); // used to store a handle to the window's
  209.                                     //  content
  210.     wc.lpszMenuName = NULL;
  211.     wc.lpszClassName = szItemClass;
  212.     wc.lpfnWndProc   = ItemWndProc;
  213.  
  214.     if (!RegisterClass(&wc))
  215.         return FALSE;
  216. }
  217.  
  218.  
  219.  
  220. //---------------------------------------------------------------------------
  221. // InitInstance
  222. // Purpose: Create the main window
  223. // Return: TRUE if successful, FALSE otherwise.
  224. //---------------------------------------------------------------------------
  225. BOOL InitInstance(HANDLE hInstance, int nCmdShow)
  226. {
  227.  
  228.     hAccTable = LoadAccelerators(hInstance, "Accelerators");
  229.  
  230.     ResetAnchor(&ptAnchor);
  231.  
  232.     // register clipboard formats.
  233.     cfLink      = RegisterClipboardFormat("ObjectLink");
  234.     cfOwnerLink = RegisterClipboardFormat("OwnerLink");
  235.     cfNative    = RegisterClipboardFormat("Native");
  236.  
  237.     // Create the main window
  238.     hwndMain = CreateWindow(
  239.         szLessonClass,               // class name
  240.         "",                  // title
  241.         WS_OVERLAPPEDWINDOW,         // style
  242.         CW_USEDEFAULT,               // position: default
  243.         CW_USEDEFAULT,
  244.         CW_USEDEFAULT,               // size: default
  245.         CW_USEDEFAULT,
  246.         NULL,                        // parent: none
  247.         NULL,                        // menu: use the class menu
  248.         hInstance,
  249.         NULL
  250.     );
  251.  
  252.     if (!hwndMain)
  253.         return (FALSE);
  254.  
  255.     // This document is Untitled
  256.     SetNullFilename (hwndMain);
  257.      
  258.     ShowWindow(hwndMain, nCmdShow);
  259.     return (TRUE);
  260. }
  261.  
  262. //---------------------------------------------------------------------------
  263. // TermInstance
  264. // Purpose: 
  265. // Return: void
  266. //---------------------------------------------------------------------------
  267. void TermInstance (void)
  268. {
  269. }
  270.  
  271. //---------------------------------------------------------------------------
  272. // MainWndProc
  273. // Purpose: Handle the main window's events
  274. //---------------------------------------------------------------------------
  275. long FAR PASCAL
  276. MainWndProc(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
  277. {
  278.     PITEM           pitem;
  279.     HANDLE          hitem;
  280.     PAINTSTRUCT     ps;
  281.     ECDCLIPFORMAT   cfFormat;
  282.      FARPROC lpInsProc;
  283.      RECT rc;
  284.     HDC hDC;
  285.     short mm;
  286.     static BOOL object = 0;
  287.    FARPROC lpProc;
  288.     ECDSTATUS EcdStat;
  289.     HWND hwndItem;
  290.  
  291.  
  292.     switch (message)
  293.         {
  294.         case WM_PAINT:
  295.                 BeginPaint(hwnd, &ps);
  296. //                CallWindowProc( lpEditWndProc, hwndEdit, message, ps.hdc, 0L);
  297.  
  298.             EndPaint (hwnd, &ps);
  299.                 break;
  300.  
  301.           case WM_CREATE:    GetClientRect(hwnd, (LPRECT)&rc);
  302.                                                 break;
  303.  
  304.  
  305.       case WM_COMMAND:
  306.             switch (wParam)
  307.                 {
  308.                 case IDM_COPY:
  309.                 case IDM_CUT:
  310.                     PutOnClipboard(hwnd, wParam);
  311.                     if (wParam == IDM_COPY)
  312.                         break;
  313.                             else{
  314.                                 HWND hwndChild;
  315.                                 PITEM pitem;
  316.                                 HANDLE hitem;
  317.  
  318.                                 hwndChild = GetTopChild();
  319.  
  320.                                 hitem = GetWindowWord(hwndChild, 0);
  321.                                 pitem = (PITEM)LocalLock(hitem);
  322.                                 EcdDelete(pitem->lpecdobject);
  323.                                 LocalUnlock(hwndChild);
  324.                                 DestroyWindow(hwndChild);
  325.                                 break;
  326.                                 }
  327.  
  328.                 case IDM_CLEAR:
  329.                     {
  330.                   HWND hwndChild;
  331.                         PITEM pitem, pObjectUndo;
  332.                         HANDLE hitem;
  333.                         hwndChild = GetTopChild();
  334.  
  335.                         
  336.                   hitem = GetWindowWord(hwndChild, 0);
  337.                   pitem = (PITEM) LocalLock(hitem);
  338.                         PrepareUndoClear(pitem);
  339.                         LocalUnlock(hitem);
  340.                   DestroyWindow(hwndChild);
  341.                   fDirty = TRUE;
  342.                   break;
  343.                     }
  344.  
  345.                 case IDM_PASTE:
  346.                 case IDM_LINK:
  347.                     GetFromClipboard(hwnd, wParam);
  348.                           RemoveObjUndo();
  349.                     fDirty = TRUE;
  350.                     break;
  351.                     
  352.                 case IDM_PROPERTIES:
  353.                     {
  354.                     HWND    hwndTop;
  355.                     HANDLE  hitem;
  356.                     PITEM   pitem;
  357.  
  358.                                 hwndTop = GetTopChild();
  359.  
  360.  
  361.                     hitem = GetWindowWord(hwndTop, 0);
  362.                     pitem = (PITEM) LocalLock(hitem);
  363.  
  364.                     lpProc = MakeProcInstance(PropertiesDlgProc, hInst);
  365.                     DialogBox(hInst,
  366.                         (pitem->wType == IDM_LINK) ? "LinkProp" : "EmbProp",
  367.                         hwnd, lpProc);
  368.                     FreeProcInstance(lpProc);
  369.                     LocalUnlock(hitem);
  370.                     break;
  371.                     }
  372.  
  373.                 case IDM_ABOUT:
  374.                     {
  375.                     FARPROC lpProc;
  376.                     HANDLE  hInst;
  377.  
  378.                     hInst = GetWindowWord(hwnd, GWW_HINSTANCE);
  379.                     lpProc = MakeProcInstance(AboutDlgProc, hInst);
  380.                     DialogBox(hInst, "AboutBox", hwnd, lpProc);
  381.                     FreeProcInstance(lpProc);
  382.                     break;
  383.                     }
  384.  
  385.                 case IDM_NEW:
  386.                     New(hwnd);
  387.                         RemoveObjUndo();
  388.                     break;
  389.                      case IDM_INSERTFILE:
  390.                         {
  391.                         int fh;
  392.  
  393.                         fh = Insert(hwndMain);
  394.                         if (fh < 0){
  395.                                 MessageBox(hwndMain, 
  396.                           "Error In Insert File",
  397.                           szAppName, MB_ICONASTERISK | MB_OK);
  398.                                 return FALSE;
  399.                                 }
  400.                        //Fall through
  401.                             }
  402.  
  403.                      case IDM_UNDO:
  404.                      case IDM_COPYLINK:
  405.                      case IDM_INSERT:
  406.                      case IDM_SHAPES:
  407.                      case IDM_PBRUSH:
  408.                      case IDM_EXCEL:
  409.                      case IDM_GRAPH:
  410.                      case IDM_TORUS:
  411.  
  412.                         {
  413.                         PITEM pitem;
  414.                            // Allocate memory for a new item     
  415.                            hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));     
  416.  
  417.                            if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL)){
  418.                                goto errRtn;
  419.                                 }
  420.  
  421.                            if (hwndItem = CreateItemWindow(hwndMain, FALSE, NULL))     
  422.                                {     
  423.                                SetWindowWord (hwndItem, 0, hitem);     
  424.                                BringWindowToTop (hwndItem);
  425.                                }
  426.                             else
  427.                                goto errRtn;
  428.  
  429.                         rgchChildWnd[irgchChild++] = hwndItem;
  430.                             SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0)+1) );
  431.                             if ((wParam == IDM_UNDO) && hObjectUndo){
  432.                                 GetUndo(pitem);
  433.                                 goto Horrible; //dirtiest code 
  434.                             }
  435.                             else
  436.                                 RemoveObjUndo(); // so nothing left of old object
  437.  
  438.                             if (wParam == IDM_INSERTFILE)
  439.                              EcdStat = EcdCreateFromTemplate(PROTOCOL, lpclient, (LPSTR)rgchOpenName, 0, NULL, &(pitem->lpecdobject),
  440.                                ecdrender_draw, 0);
  441.                             else if (wParam == IDM_COPYLINK){
  442.                                 EcdStat = CopyLink(pitem);
  443.                                 }
  444.                             else
  445.                                 EcdStat = CreateObject(wParam, pitem);
  446.                             if (EcdStat == ECD_WAIT_FOR_RELEASE){
  447.                                 WaitForRelease(pitem);
  448.                                 }
  449.                             if (fTestEcdStat(EcdStat)){
  450.                                 MessageBox(hwndMain, 
  451.                           "Error In EcdCreate",
  452.                           szAppName, MB_ICONASTERISK | MB_OK);
  453.                                 goto errRtn;
  454.                                 }
  455.                             else {
  456.                                     cfFormat = EcdEnumObjectFormats (pitem->lpecdobject, NULL);
  457.                                      if (cfFormat == cfNative)
  458.                                          pitem->wType = IDM_PASTE;  
  459.                                      else if (cfFormat == cfLink)
  460.                                          pitem->wType = IDM_LINK;  
  461.     
  462.                                      pitem->wUpdate = IDD_AUTO;
  463. Horrible:
  464.                                     pitem->fOpen = FALSE;
  465.                                     pitem->fClose = FALSE;
  466.         
  467.                                      hDC = GetDC(hwndItem);
  468.                               //         EcdSetHostNames(pitem->lpecdobject, szHostname, szHostobjectname);
  469.                                     mm = SetMapMode(hDC, MM_HIMETRIC);
  470.                                     EcdQueryBounds(pitem->lpecdobject, &rc);
  471.                                     LPtoDP(hDC, (LPPOINT)&rc, 2);
  472.                                     SetMapMode(hDC, mm);
  473.                                     fInsUpdate = TRUE;
  474.                                     if ((rc.right - rc.left == 0) || (rc.bottom - rc.top == 0)){
  475.                                         rc.right = 200;
  476.                                         rc.bottom = 200;
  477.                                         rc.left = 0;
  478.                                         rc.top = 0;
  479.                                         }
  480.                                     MoveWindow(hwndItem, rc.left, rc.top, rc.right - rc.left,
  481.                                         rc.bottom - rc.top, TRUE);
  482.                                    SendMessage (hwndItem, WM_USER, 0, 0L);
  483.                                      ShowWindow(hwndItem, SW_SHOW);
  484.                                     InvalidateRect(hwndItem, NULL, TRUE);
  485.                                      ReleaseDC(hwndItem, hDC);
  486.     
  487.                                     }
  488.                         LocalUnlock(hitem);
  489.                             break;
  490.                             }
  491.  
  492.                 case IDM_OPEN:
  493.                     Open(hwnd);
  494.                             RemoveObjUndo(); // so nothing left of old
  495.                     break;
  496.  
  497.                 case IDM_SAVE:
  498.                     Save(hwnd);
  499.                     break;
  500.  
  501.                 case IDM_SAVEAS:
  502.                     SaveAs(hwnd);
  503.                     break;
  504.  
  505.                     case IDM_EQUAL:
  506.                             TestEqual();
  507.                             break;
  508.  
  509.                 case IDM_EXIT:
  510.                     SendMessage (hwnd, WM_CLOSE, 0, 0L);
  511.                     return(0L);
  512.                     break;
  513.                 case IDM_CLOSE:
  514.                         {
  515.                         HWND hwndTop;
  516.                         /*
  517.                         hwndTop = GetTopWindow(hwndMain);
  518.                         if (hwndTop == hwndEdit)
  519.                             hwndTop = GetWindow(hwndTop, GW_HWNDNEXT);
  520.                         */
  521.                         hwndTop = GetTopChild();
  522.  
  523.                         SendMessage (hwndTop, WM_USER+1, 0, 0L);
  524.                   return(0L);
  525.                         }
  526.                     case IDM_RECONNECT:
  527.                         {
  528.                         HWND hwndTop;
  529.                         hwndTop = GetTopChild();
  530.  
  531.                         SendMessage (hwndTop, WM_USER+2, 0, 0L);
  532.                   break;
  533.                         }
  534.  
  535.                     case IDM_PRINT:
  536.                         CallPrint();
  537.                         break;
  538.             } 
  539.             break;
  540.  
  541.         case WM_CLOSE:
  542.             if (!SaveAsNeeded(hwnd))
  543.                 return(0L);
  544.             break;
  545.  
  546.         case WM_DESTROY:
  547.             {
  548.             int nObjects;
  549.             HWND hwndT;
  550.             int i = 0;
  551.             MSG msg;
  552.  
  553.                 nObjDestroy = GetWindowWord(hwndMain, 0);
  554.                 nObjects = nObjDestroy;
  555.                 while (nObjects--){
  556.                     hwndT = GetNextWnd(&i);
  557.                     DestroyWindow(hwndT);
  558.                     }
  559.                 while (nObjDestroy){
  560.                     GetMessage(&msg, NULL, NULL, NULL);
  561.                 TranslateMessage(&msg);
  562.                 DispatchMessage(&msg); 
  563.                 }
  564.             PostQuitMessage (0);
  565.             return(0L);
  566.                 }
  567.  
  568.         case WM_INITMENU:
  569.             ClientUpdateMenu(hwnd, (HMENU) wParam);
  570.             break;
  571.  
  572.     }
  573.    return (DefWindowProc(hwnd, message, wParam, lParam));
  574.  
  575.     errRtn:
  576.     if (pitem)
  577.         LocalUnlock (hitem);
  578.  
  579.     if (hitem)
  580.         LocalFree (hitem);
  581.  
  582.     if (hwndItem)
  583.         {
  584.         SetWindowWord(hwndItem, 0, NULL);
  585.         DestroyWindow(hwndItem);
  586.         }
  587.  
  588. }
  589.  
  590.  
  591. //---------------------------------------------------------------------------
  592. // ItemWndProc
  593. // Purpose: Handle Item window's messages
  594. //---------------------------------------------------------------------------
  595. long FAR PASCAL
  596. ItemWndProc (HWND hwnd, unsigned message, WORD wParam, LONG lParam)
  597. {
  598.     PITEM           pitem;
  599.     HANDLE          hitem;
  600.      HANDLE                hOldwnd = hwnd;
  601.      static POINT ptOld, ptNew;
  602.      static BOOL bCapture = FALSE;
  603.      static RECT rc;
  604.      int xChange, yChange;
  605.      HWND hNext;
  606.      static int xWnd, yWnd;
  607.  
  608.  
  609.     switch (message)
  610.         {
  611.           case WM_USER:
  612.             {
  613.             HANDLE hitem;
  614.             PITEM pitem;
  615.                 ECDSTATUS EcdStat;
  616.                 HANDLE hWinTitle;
  617.                 LPSTR pTitle, pTitle1;
  618.  
  619.             hitem = GetWindowWord (hwnd, 0);
  620.             pitem = (PITEM) LocalLock (hitem);
  621.                 PrintWIndowTitle(pitem ,hwnd);
  622.  
  623.             LocalUnlock(hitem);
  624.             break;
  625.             }
  626.             case WM_SIZE:
  627.                 {
  628.                 RECT rc;
  629.                 HWND hdc;
  630.                 short mm;
  631.                 ECDSTATUS EcdStat;
  632.     
  633.             hitem = GetWindowWord (hwnd, 0);
  634.                 if (hitem && (pitem = (PITEM) LocalLock (hitem))){
  635.                     if (pitem->fOpen){
  636.                         GetClientRect(hwnd, &rc);
  637.                     hdc = GetDC(hwnd);
  638.                         mm = SetMapMode(hdc, MM_HIMETRIC);
  639.                         DPtoLP(hdc,(LPPOINT)&rc,2);
  640.                         EcdSetBounds(pitem->lpecdobject, (LPRECT)&rc);
  641.                        SetMapMode(hdc, mm);
  642.                        ReleaseDC(hwnd, hdc);
  643.                         }
  644.                         LocalUnlock(hitem);
  645.                     }
  646.                 return (DefWindowProc(hwnd, message, wParam, lParam));
  647.                 }
  648.     
  649.  
  650.         case WM_DESTROY:
  651.             {
  652.                 int i = 0;
  653.             hitem = GetWindowWord (hwnd, 0);
  654.             if (hitem)
  655.                 {
  656.                 pitem = (PITEM) LocalLock (hitem);
  657.                 ClientDelete(pitem);
  658.                 LocalUnlock(hitem);
  659.                 LocalFree(hitem);
  660.                 }
  661.                     while (hwnd != rgchChildWnd[i])
  662.                         i += 1;
  663.                     if (i > MaxChildWnd){
  664.                         MessageBox(hwndMain, "Wrong Child Id",
  665.                          szAppName, MB_ICONASTERISK | MB_OK);
  666.                         return;
  667.                         }
  668.                     rgchChildWnd[i] = 0;
  669.                     nObjDestroy -= 1;
  670.                     SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0) - 1) );
  671.             break;
  672.                 }
  673.  
  674.         case WM_PAINT:
  675.             {
  676.             HDC             hdc;
  677.             PAINTSTRUCT     ps;
  678.  
  679.             BeginPaint (hwnd, (LPPAINTSTRUCT)&ps);
  680.             hitem = GetWindowWord (hwnd, 0);
  681.             pitem = (PITEM) LocalLock (hitem);
  682.  
  683.             if (pitem)
  684.                 ClientPaint(hwnd, ps.hdc, pitem);
  685.             LocalUnlock(hitem);
  686.                 hNext = GetWindow(hwnd, GW_HWNDNEXT);
  687.                 if (hNext && (hNext != hwndEdit))
  688.                     InvalidateRect(hNext, NULL, FALSE);
  689.  
  690.             EndPaint (hwnd, (LPPAINTSTRUCT)&ps);
  691.             break;
  692.             }
  693.  
  694.  
  695.         case WM_LBUTTONDBLCLK:
  696.             {
  697.             HANDLE hitem;
  698.             PITEM pitem;
  699.             
  700.             // edit the object
  701.             hitem = GetWindowWord (hwnd, 0);
  702.             pitem = (PITEM) LocalLock (hitem);
  703.             ClientEdit(hwnd, pitem);
  704.             LocalUnlock(hitem);
  705.             break;
  706.             }
  707.         case WM_LBUTTONDOWN:
  708.             BringWindowToTop (hwnd);
  709.                 SetCapture(hwnd);
  710.                 GetCursorPos((LPPOINT)&ptOld);
  711.                 bCapture = TRUE;
  712.                 break;
  713.  
  714.           case WM_LBUTTONUP:
  715.                 if (bCapture){
  716.                     bCapture = FALSE;
  717.                     ReleaseCapture();
  718.                     GetCursorPos((LPPOINT)&ptNew);
  719.                     xChange = ptNew.x - ptOld.x;
  720.                     yChange = ptNew.y - ptOld.y;
  721.                     GetWindowRect(hwnd, (LPRECT)&rc);
  722.                     ScreenToClient(hwndMain, (LPPOINT) &rc);
  723.                     ScreenToClient(hwndMain, ((LPPOINT) &rc)+1);
  724.                     MoveWindow( hwnd, rc.left + xChange, rc.top + yChange,
  725.                         rc.right - rc.left, rc.bottom - rc.top, TRUE);
  726.                     }
  727.                 break;
  728.             case WM_USER+1: // Asked by user to close the document
  729.             {
  730.             HANDLE hitem;
  731.                 ECDSTATUS EcdStat;
  732.             PITEM pitem;
  733.             
  734.             // edit the object
  735.             hitem = GetWindowWord (hwnd, 0);
  736.             pitem = (PITEM) LocalLock (hitem);
  737.                 pitem->fOpen = FALSE;
  738.                 pitem->fClose = TRUE;
  739.                 if ((EcdStat = EcdClose(pitem->lpecdobject)) == ECD_WAIT_FOR_RELEASE){
  740.                     WaitForRelease(pitem);
  741.                     }
  742.                     if (fTestEcdStat(EcdStat)){
  743.                         MessageBox(hwnd, "Error In Closing Object",
  744.                            szAppName, MB_ICONASTERISK | MB_OK);
  745.                         }
  746.             LocalUnlock(hitem);
  747.                 return (DefWindowProc(hwnd, message, wParam, lParam));
  748.             }
  749.             case WM_USER+2: // Asked by user to Reconnect
  750.             {
  751.             HANDLE hitem;
  752.                 ECDSTATUS EcdStat;
  753.             PITEM pitem;
  754.             
  755.             // edit the object
  756.             hitem = GetWindowWord (hwnd, 0);
  757.             pitem = (PITEM) LocalLock (hitem);
  758.                 pitem->fOpen = TRUE;
  759.                 pitem->fClose = FALSE;
  760.                 if ((EcdStat = EcdReconnect(pitem->lpecdobject)) == ECD_WAIT_FOR_RELEASE){
  761.                     WaitForRelease(pitem);
  762.                     }
  763.                     if (fTestEcdStat(EcdStat)){
  764.                         MessageBox(hwnd, "Error In Reconnecting Object",
  765.                            szAppName, MB_ICONASTERISK | MB_OK);
  766.                         }
  767.             LocalUnlock(hitem);
  768.                 return (DefWindowProc(hwnd, message, wParam, lParam));
  769.             }
  770.  
  771.  
  772.     }
  773.     return (DefWindowProc(hwnd, message, wParam, lParam));
  774. }
  775.  
  776.  
  777. //---------------------------------------------------------------------------
  778. // AboutDlgProc
  779. // Purpose: Handle the About... dialog box events
  780. //---------------------------------------------------------------------------
  781. BOOL FAR PASCAL
  782. AboutDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  783. {
  784.     switch (message)
  785.         {
  786.         case WM_COMMAND:
  787.             if (wParam == IDOK
  788.               || wParam == IDCANCEL)
  789.                 {
  790.                 EndDialog(hDlg, TRUE);
  791.                 return (TRUE);
  792.                 }
  793.             break;
  794.         }
  795.     return (FALSE);
  796. }
  797.  
  798.  
  799. //---------------------------------------------------------------------------
  800. // SaveAsDlgProc
  801. // Purpose: Handle the File Save As... dialog box events
  802. //---------------------------------------------------------------------------
  803. BOOL FAR PASCAL
  804. SaveAsDlgProc (HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  805. {
  806.     switch (message)
  807.         {
  808.         case WM_COMMAND:
  809.             switch (wParam)
  810.                 {
  811.                 case IDOK:
  812.                     GetDlgItemText(hDlg, IDC_EDIT, (LPSTR) rgchFilename, cbFnMax);
  813.                     EndDialog(hDlg, TRUE);
  814.                     return (TRUE);
  815.  
  816.                 case IDCANCEL:
  817.                     EndDialog(hDlg, NULL);
  818.                     return (FALSE);
  819.                 }
  820.             break;
  821.  
  822.         case WM_INITDIALOG:
  823.             SetDlgItemText(hDlg, IDC_EDIT, (LPSTR)rgchFilename);
  824.             SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
  825.                 MAKELONG(0, 32767));
  826.             DlgDirList(hDlg, "", 0, IDC_PATH, 0);
  827.             SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  828.             return (FALSE);
  829.     }
  830.     return FALSE;
  831. }
  832.  
  833. //---------------------------------------------------------------------------
  834. // OpenDlgProc
  835. // Purpose: Handle the File Open... dialog box events
  836. //---------------------------------------------------------------------------
  837. int FAR PASCAL OpenDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  838. {
  839.     int fh; 
  840.  
  841.     switch (message)
  842.         {
  843.         case WM_COMMAND:
  844.             switch (wParam)
  845.                 {
  846.                 case IDC_LISTBOX:
  847.                     switch (HIWORD(lParam))
  848.                         {
  849.                         case LBN_SELCHANGE:
  850.                             DlgDirSelect(hDlg, rgchOpenName, IDC_LISTBOX);
  851.                             SetDlgItemText(hDlg, IDC_EDIT, rgchOpenName);
  852.                             SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL,
  853.                                 NULL, MAKELONG(0, 32767));
  854.                             break;
  855.  
  856.                         case LBN_DBLCLK:
  857.                             goto openfile;
  858.                         }
  859.                     return (TRUE);
  860.  
  861.                 case IDOK:
  862. openfile:
  863.                     GetDlgItemText(hDlg, IDC_EDIT, rgchOpenName, cbFnMax);
  864.  
  865.                     if (!rgchOpenName[0])
  866.                         {
  867.                         MessageBox(hDlg, szNoFile,
  868.                             NULL, MB_OK | MB_ICONHAND);
  869.                         return (TRUE);
  870.                         }
  871.  
  872.                     if ((fh = _lopen(rgchOpenName, OF_READ)) == -1)
  873.                         {
  874.                         MessageBox(hDlg, szInvalidFn,
  875.                             NULL, MB_OK | MB_ICONHAND);
  876.                         return (TRUE);
  877.                         }
  878.                     EndDialog(hDlg, fh);
  879.                     return (TRUE);
  880.  
  881.                 case IDCANCEL:
  882.                     EndDialog(hDlg, -1);
  883.                     return (FALSE);
  884.             }
  885.             break;
  886.  
  887.         case WM_INITDIALOG:                      
  888.             DlgDirList(hDlg, "", IDC_LISTBOX, IDC_PATH, 0); 
  889.             SetDlgItemText(hDlg, IDC_EDIT, szDefOpen);
  890.             SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, NULL, 
  891.                 MAKELONG(0, 32767));              
  892.             SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  893.             return (FALSE); // The focus is already set to a control
  894.     }
  895.     return FALSE;
  896. }
  897.  
  898.  
  899.  
  900. //---------------------------------------------------------------------------
  901. // GetFromClipboard
  902. // Purpose: Paste or Link from the Clipboard
  903. // Returns: void
  904. //---------------------------------------------------------------------------
  905. void GetFromClipboard (HWND hwndMain, WORD w)
  906. {   
  907.     ClientPasteLink(hwndMain, w);
  908. }
  909.  
  910. //---------------------------------------------------------------------------
  911. // PutOnClipboard
  912. // Purpose:  Cut or Copy onto the Clipboard
  913. // Returns: void
  914. //---------------------------------------------------------------------------
  915. void PutOnClipboard(HWND hwndMain, WORD w)
  916. {   
  917.     ClientCutCopy(hwndMain, w);
  918. }
  919.  
  920. //---------------------------------------------------------------------------
  921. // ResetAnchor
  922. // Purpose: Resets the anchor so that new child windows are created at the 
  923. //          top left of the main window
  924. // Returns: void
  925. //---------------------------------------------------------------------------
  926. void ResetAnchor(PPOINT pptAnchor)
  927. {
  928.     pptAnchor->x = dxInflate - dxCascade ;
  929.     pptAnchor->y = dyInflate - dyCascade ;
  930. }
  931.  
  932. //---------------------------------------------------------------------------
  933. // MoveAnchor
  934. // Purpose: Moves the anchor so that the new child window 
  935. //          1) appear in cascade;
  936. //          2) doesn't get created past the edge
  937. // Returns: void
  938. //---------------------------------------------------------------------------
  939. void MoveAnchor(PPOINT pptAnchor, PRECT pclientRect, PPOINT pptSize)
  940. {
  941.     ptAnchor.y += dyCascade;
  942.     if (pptAnchor->y + pptSize->y >= pclientRect->bottom)
  943.         pptAnchor->y = pclientRect->top ;
  944.  
  945.     ptAnchor.x += dxCascade;
  946.     if (pptAnchor->x + pptSize->x >= pclientRect->right)
  947.         pptAnchor->x  = pclientRect->left ;
  948. }
  949.  
  950. //---------------------------------------------------------------------------
  951. // SetNullFilename
  952. // Purpose: This document is untitled...
  953. // Returns: void
  954. //---------------------------------------------------------------------------
  955. void SetNullFilename (HWND hwndMain)
  956. {
  957.     SetFilename (hwndMain, szUntitled);
  958. }
  959.  
  960.  
  961. //---------------------------------------------------------------------------
  962. // SetFilename
  963. // Purpose: Update window title 
  964. //          Keep a copy of the filename
  965. // Returns: FALSE if need to cancel the operation, TRUE otherwise
  966. //---------------------------------------------------------------------------
  967. void SetFilename (HWND hwnd, char* rgch)
  968. {
  969.     char rgchTitle[szMsgMax];
  970.  
  971.     // Keep a copy of the filename handy
  972.     lstrcpy (rgchFilename, rgch);
  973.  
  974.     // Set up the window title
  975.     wsprintf ((LPSTR) rgchTitle, (LPSTR) szTitle, (LPSTR) rgch);
  976.     SetWindowText(hwnd, rgchTitle);
  977. }
  978.  
  979. //---------------------------------------------------------------------------
  980. // SaveAsNeeded
  981. // Purpose: If necessary, ask the user if s/he wants to save the file
  982. // Returns: FALSE if need to cancel the operation, TRUE otherwise
  983. //---------------------------------------------------------------------------
  984. BOOL SaveAsNeeded(HWND hwnd)
  985. {
  986.     int retval;
  987.     char rgch[szMsgMax];
  988.  
  989.     if (!fDirty)
  990.         return TRUE;
  991.     wsprintf ((LPSTR) rgch, (LPSTR) szSave, (LPSTR) rgchFilename);
  992.     retval = MessageBox (hwnd, rgch, szAppName,
  993.         MB_YESNOCANCEL | MB_ICONINFORMATION);
  994.     switch (retval)
  995.         {
  996.         case IDNO:
  997.             return TRUE;
  998.         case IDYES:
  999.             return (Save(hwnd));
  1000.         default:
  1001.             return FALSE;
  1002.         }
  1003. }
  1004.  
  1005. //---------------------------------------------------------------------------
  1006. // New
  1007. // Purpose: Delete old Data
  1008. // Returns: FALSE if the operation was canceled, TRUE otherwise
  1009. //---------------------------------------------------------------------------
  1010. BOOL New (HWND hwnd)
  1011. {
  1012.     // Save the current file if necessary
  1013.     if (!SaveAsNeeded(hwnd))
  1014.         return (FALSE);
  1015.  
  1016.     // delete current objects
  1017.     CleanHwnd (hwnd);
  1018.  
  1019.     fDirty = FALSE;
  1020.  
  1021.     // reset filename
  1022.     SetNullFilename(hwnd);
  1023. }
  1024.  
  1025. //---------------------------------------------------------------------------
  1026. // Open
  1027. // Purpose: Ask for a file name
  1028. //          Open the file
  1029. // Returns: FALSE if the operation was canceled, TRUE otherwise
  1030. //---------------------------------------------------------------------------
  1031. BOOL Open (HWND hwnd)
  1032. {
  1033.     FARPROC lpProc;
  1034.     int     fh;
  1035.  
  1036.     // Save the current file if necessary
  1037.     if (!SaveAsNeeded(hwnd))
  1038.         return (FALSE);
  1039.  
  1040.     // Ask for a file name
  1041.     lpProc = MakeProcInstance(OpenDlgProc, hInst);
  1042.     fh = DialogBox(hInst, "Open", hwnd, lpProc);
  1043.     FreeProcInstance(lpProc);
  1044.     if (fh < 0)
  1045.         return (FALSE); 
  1046.     SetFile(fh);
  1047.     lstrcpy(rgchFilename, rgchOpenName);
  1048.     SetFilename(hwnd, rgchFilename);
  1049.  
  1050.     // delete current objects
  1051.     CleanHwnd (hwnd);
  1052.  
  1053.     // read new objects
  1054.     return(ReadFromFile(hwnd, fh));
  1055. }
  1056.  
  1057.  
  1058. //---------------------------------------------------------------------------
  1059. // Save
  1060. // Purpose: Save the current data to a file 
  1061. //          Ask for a new name if necessary
  1062. // Returns: FALSE if the operation was canceled, TRUE otherwise
  1063. //---------------------------------------------------------------------------
  1064. BOOL Save(HWND hwnd)
  1065. {
  1066.     if (!fDirty)
  1067.         {
  1068.         // The file is already saved.  We are done.
  1069.         return (TRUE);
  1070.         }
  1071.     if (!lstrcmp((LPSTR) rgchFilename, (LPSTR) szUntitled))
  1072.         return (SaveAs(hwnd));
  1073.     return (WriteToFile(hwnd));
  1074. }
  1075.  
  1076.  
  1077. //---------------------------------------------------------------------------
  1078. // SaveAs
  1079. // Purpose: Save the current data to a file 
  1080. //          Ask for a new name
  1081. // Returns: FALSE if the operation was canceled, TRUE otherwise
  1082. //---------------------------------------------------------------------------
  1083. BOOL SaveAs(HWND hwnd)
  1084. {
  1085.     FARPROC lpProc;
  1086.     int     dlg;
  1087.  
  1088.     lpProc = MakeProcInstance(SaveAsDlgProc, hInst);
  1089.     dlg = DialogBox(hInst, "SaveAs", hwnd, lpProc);
  1090.     FreeProcInstance(lpProc);
  1091.     if (!dlg)
  1092.         return (FALSE);
  1093.     SetFilename(hwnd, rgchFilename);
  1094.     return(WriteToFile(hwnd));
  1095. }
  1096.  
  1097.  
  1098. //---------------------------------------------------------------------------
  1099. // WriteToFile
  1100. // Purpose: Write the current data into a file 
  1101. // Returns: FALSE if the operation was aborted, TRUE otherwise
  1102. //---------------------------------------------------------------------------
  1103. BOOL    WriteToFile (HWND hwndMain)
  1104. {
  1105.     int     fh, nObjects;
  1106.     HANDLE  hitem;
  1107.     PITEM   pitem;
  1108.     HWND    hwnd;
  1109.     int i =0;
  1110.     RECT    rc;
  1111.  
  1112.     WORD  wFile, wSize = 0;
  1113.     LPSTR lpEditBuffer;
  1114.                 ECDSTATUS EcdStat;
  1115.  
  1116.  
  1117.  
  1118.             if ((fh =_lcreat (rgchFilename, 0)) <= 0)
  1119.                 {
  1120.                 MessageBox (
  1121.                         GetFocus(),
  1122.                         szInvalidFn,
  1123.                         szAppName,
  1124.                         MB_ICONEXCLAMATION | MB_OK);
  1125.                 return FALSE;
  1126.                 }
  1127.             SetFile(fh);
  1128.  
  1129.             nObjects = GetWindowWord(hwndMain, 0);
  1130.             if (_lwrite (fh, (LPSTR)&nObjects, 2) <= 0){
  1131.                 MessageBox (
  1132.                     GetFocus(),
  1133.                     szFnError,
  1134.                     szAppName,
  1135.                     MB_ICONEXCLAMATION | MB_OK);
  1136.             _lclose(fh);
  1137.             return(FALSE);
  1138.             }
  1139.  
  1140.                                     
  1141.         hwnd = GetNextWnd(&i);
  1142.  
  1143.         while (hwnd && nObjects--){
  1144.             if (hwnd != hwndEdit){
  1145.                 if (IsIconic(hwnd)){
  1146.                     rc.left = 0;
  1147.                     rc.right = 0;
  1148.                     rc.top = 0;
  1149.                     rc.bottom = 0;
  1150.                     }
  1151.                 else { // if normal size window
  1152.                     GetWindowRect(hwnd, &rc);
  1153.                     // Screen coordinates => Parent coordinates
  1154.                     ScreenToClient(hwndMain, (LPPOINT) &rc);
  1155.                     ScreenToClient(hwndMain, ((LPPOINT) &rc)+1);
  1156.                     }
  1157.                 hitem = GetWindowWord (hwnd, 0);
  1158.                 pitem = (PITEM) LocalLock(hitem);
  1159.                 if ( (_lwrite (fh, (LPSTR) &rc, sizeof(RECT)) <= 0)
  1160.                     || (_lwrite (fh, (LPSTR) &(pitem->wType), sizeof(WORD)) <= 0)
  1161.                     || (_lwrite (fh, (LPSTR) &(pitem->wUpdate), sizeof(WORD)) <= 0)
  1162.                     || ((EcdStat = EcdSaveToStream(((PITEM) pitem)->lpecdobject,
  1163.                             (LPECDSTREAM) lpstream)) != ECD_OK))
  1164.                    {
  1165.                     
  1166.                     if (EcdStat == ECD_WAIT_FOR_RELEASE)
  1167.                         WaitForRelease(pitem);
  1168.                     if (fTestEcdStat(EcdStat)){
  1169.                         MessageBox (
  1170.                             GetFocus(),
  1171.                             szFnError,
  1172.                             szAppName,
  1173.                             MB_ICONEXCLAMATION | MB_OK);
  1174.                         LocalUnlock(hitem);
  1175.                         _lclose(fh);
  1176.                         return(FALSE);
  1177.                         }
  1178.                    }
  1179.                 LocalUnlock(hitem);
  1180.                 }
  1181.           
  1182.         hwnd = GetNextWnd(&i);
  1183.         }
  1184.     _lclose (fh);
  1185.     fDirty = FALSE;
  1186.     return TRUE;
  1187. }
  1188.  
  1189. //---------------------------------------------------------------------------
  1190. // ReadFromFile
  1191. // Purpose: Read new data from a file 
  1192. // Returns: FALSE if the operation was aborted, TRUE otherwise
  1193. //---------------------------------------------------------------------------
  1194. BOOL ReadFromFile (HWND hwnd, int fh)
  1195. {
  1196.     char ch;
  1197.     RECT rc;
  1198.     BOOL fRet = TRUE;
  1199.     LPECDOBJECT lpobject;
  1200.     WORD wType, wUpdate;
  1201.      WORD wSize;
  1202.      LPSTR lpEditBuffer;
  1203.      int nObjects;
  1204.                 ECDSTATUS EcdStat;
  1205.  
  1206.         if (_lread (fh, (LPSTR)&nObjects, 2) <= 0)
  1207.            return FALSE; // end of file
  1208.             SetWindowWord(hwndMain, 0, nObjects);
  1209.  
  1210.  
  1211.             while(nObjects--){
  1212.                 if ((_lread (fh, (LPSTR)&rc, sizeof(RECT)) <= 0)
  1213.                     || (_lread (fh, (LPSTR) &wType, sizeof(WORD)) <= 0)
  1214.                     || (_lread (fh, (LPSTR) &wUpdate, sizeof(WORD)) <= 0)
  1215.                     || ((EcdStat = EcdLoadFromStream((LPECDSTREAM) lpstream, PROTOCOL,
  1216.                         lpclient, 0, NULL, &lpobject)) != ECD_OK))
  1217.                     {
  1218.                     // file problem while reading an object description
  1219.                         while(EcdQueryReleaseStatus(lpobject) == ECD_BUSY)
  1220.                             {
  1221.                             MSG msg;
  1222.                             GetMessage(&msg, NULL, NULL, NULL);            
  1223.                           TranslateMessage(&msg);                         
  1224.                           DispatchMessage(&msg);                          
  1225.                            }
  1226.                         if (fEcdReleaseError){
  1227.                                 MessageBox (
  1228.                             GetFocus(),
  1229.                             szFnError,
  1230.                             szAppName,
  1231.                             MB_ICONEXCLAMATION | MB_OK);
  1232.                                 PrintError(fEcdReleaseStat);
  1233.                                 fRet = FALSE;
  1234.                                 break;
  1235.                                 }
  1236.                     }
  1237.         
  1238.                 ClientCreateNewItem (hwnd, TRUE, &rc, lpobject, wType, wUpdate);
  1239.                 }
  1240.         
  1241.     _lclose (fh);
  1242.     return (fRet);
  1243. }
  1244.  
  1245.  
  1246. //---------------------------------------------------------------------------
  1247. // CleanHwnd
  1248. // Purpose: Delete all the children of the main window
  1249. // Returns: void
  1250. //---------------------------------------------------------------------------
  1251. void CleanHwnd (HWND hwndMain)
  1252. {
  1253.     HWND hwnd, hwndT;
  1254.     HANDLE hitem;
  1255.     int nObjects = GetWindowWord(hwndMain, 0);
  1256.     int i = 0;
  1257.  
  1258.     hwnd = GetWindow (hwndMain, GW_CHILD);
  1259.  
  1260.     while (nObjects--){
  1261.         hwndT = GetNextWnd(&i);
  1262.         if (hwndT != hwndEdit)
  1263.         {
  1264.         DestroyWindow(hwndT);
  1265.         }
  1266.         }
  1267.     ResetAnchor(&ptAnchor);
  1268. }
  1269.  
  1270.  
  1271. long far PASCAL EditWndProc(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
  1272. {
  1273.     PAINTSTRUCT ps;
  1274.     PITEM           pitem;
  1275.    HANDLE          hitem;
  1276.     POINT pt;
  1277.     HWND hNext;
  1278.  
  1279.  
  1280.     switch (message) {
  1281.  
  1282.     case WM_PAINT:
  1283.  
  1284.                 BeginPaint(hwnd, &ps);
  1285.                 CallWindowProc( lpEditWndProc, hwndEdit, message, ps.hdc, 0L);
  1286.                 hNext = GetWindow(hwnd, GW_HWNDNEXT);
  1287.                 if (hNext)
  1288.                     InvalidateRect(hNext, NULL, FALSE);
  1289.  
  1290.             EndPaint (hwnd, &ps);
  1291.                 break;
  1292.  
  1293.     default:
  1294.         return CallWindowProc(lpEditWndProc, hwndEdit, message, wParam, lParam);
  1295.             break;
  1296.     }
  1297.     return(0L);
  1298. }
  1299.  
  1300.  
  1301. //*------------------------------------------------------------------------
  1302. //| InsFileProc
  1303. //|     Parameters:
  1304. //|         hWnd    - Handle to Window which message is delivered to.
  1305. //|         msgID   - ID number of message
  1306. //|         wParam  - 16-bit parameter
  1307. //|         lParam  - 32-bit parameter
  1308. //|
  1309. //*------------------------------------------------------------------------
  1310. BOOL FAR PASCAL InsFileProc (HWND     hWnd,
  1311.                             unsigned wMsgID,
  1312.                             WORD     wParam,
  1313.                             LONG     lParam)
  1314. {
  1315.     int nRet;
  1316.  
  1317.     switch(wMsgID)
  1318.     {
  1319.     case WM_INITDIALOG:
  1320.         return TRUE;
  1321.     case WM_COMMAND:
  1322.         switch (wParam)
  1323.         {
  1324.         case IDOK:
  1325.             nRet = GetDlgItemText(hWnd, 101, (LPSTR)szInsFileName, cbFnMax);
  1326.             EndDialog(hWnd,TRUE);
  1327.             return TRUE;
  1328.  
  1329.         case IDCANCEL:
  1330.             EndDialog(hWnd,FALSE);
  1331.             return TRUE;
  1332.         }
  1333.         break;
  1334.     }
  1335.     return FALSE;
  1336. }
  1337.  
  1338. ECDSTATUS CreateObject(WORD wParam, PITEM pitem)
  1339.         {
  1340.         char szClassName[szMaxClassName];
  1341.         switch(wParam){
  1342.             case IDM_SHAPES:
  1343.                 lstrcpy ((LPSTR)szClassName, "Shapes");
  1344.                 break;
  1345.             case IDM_PBRUSH:
  1346.                  lstrcpy ((LPSTR)szClassName, "PBrush");
  1347.                 break;
  1348.             case IDM_EXCEL :
  1349.                 lstrcpy ((LPSTR)szClassName, "ExcelWorksheet");
  1350.                 break;
  1351.             case IDM_GRAPH :
  1352.                 lstrcpy ((LPSTR)szClassName, "Graph");
  1353.                 break;
  1354.             case IDM_TORUS :
  1355.                 lstrcpy ((LPSTR)szClassName, "Torus");
  1356.                 break;
  1357.                 }
  1358.          return(EcdCreate(PROTOCOL, lpclient, (LPSTR)szClassName, 0, NULL, &(pitem->lpecdobject),
  1359.                   ecdrender_draw,  0));
  1360.  
  1361.         }
  1362.  
  1363.  
  1364.  
  1365.     void CallPrint(){
  1366.         static char szPrinter[80];
  1367.         char *szDevice, *szDriver, *szOutput;
  1368.         HWND hPrnDC, hDC;
  1369.         int nObjects;
  1370.        HANDLE  hitem;
  1371.        PITEM   pitem;
  1372.        HWND    hwnd;
  1373.        RECT    rc;
  1374.         short mm;
  1375.         int nRecSize, nRet;
  1376.         HSTR hstr;
  1377.         LPSTR lpstrInfo;
  1378.         int i =0;
  1379.  
  1380.  
  1381.  
  1382.                         
  1383.         nObjects = GetWindowWord(hwndMain, 0);
  1384.         GetProfileString("windows", "device", ",,", szPrinter, 80);                
  1385.         if ((szDevice = strtok(szPrinter, ",")) &&
  1386.             (szDriver = strtok(NULL, ",")) &&                
  1387.             (szOutput = strtok(NULL, ",")))                
  1388.             hPrnDC = CreateIC(szDriver, szDevice, szOutput, NULL);
  1389.         else {
  1390.                MessageBox (GetFocus(), "Not Printed",
  1391.                             szAppName, MB_ICONEXCLAMATION | MB_OK);
  1392.                     return;
  1393.                     }
  1394.  
  1395.         nObjects = GetWindowWord(hwndMain, 0);                
  1396.         hwnd = GetWindow (hwndMain, GW_CHILD);
  1397.         while (hwnd && nObjects--){
  1398.             if (hwnd != hwndEdit){
  1399.                 GetWindowRect(hwnd, &rc);
  1400.                 // Screen coordinates => Parent coordinates
  1401.                 ScreenToClient(hwnd, (LPPOINT) &rc);
  1402.                 ScreenToClient(hwnd, ((LPPOINT) &rc)+1);
  1403.                 mm = SetMapMode(hPrnDC, MM_ISOTROPIC);
  1404.                 LPtoDP(hPrnDC, (LPPOINT)&rc, 2);
  1405.  
  1406.                 hitem = GetWindowWord (hwnd, 0);
  1407.                 pitem = (PITEM) LocalLock(hitem);
  1408.                 if (EcdDraw( pitem->lpecdobject, hPrnDC, (LPRECT)&rc, NULL) != ECD_OK)
  1409.                     {
  1410.                     MessageBox (
  1411.                             GetFocus(),
  1412.                             szFnError,
  1413.                             szAppName,
  1414.                             MB_ICONEXCLAMATION | MB_OK);
  1415.                     LocalUnlock(hitem);
  1416.                     return;
  1417.                     }
  1418.                 else {
  1419.                     LocalUnlock(hitem);
  1420.                     nRecSize = (rc.right-rc.left)*(rc.top - rc.bottom);
  1421.                     if (nRecSize < 0)
  1422.                         nRecSize = - nRecSize;
  1423.                         nRet = Escape(hPrnDC, STARTDOC, 5, "HELLO",   NULL);
  1424.                         nRet = Escape(hPrnDC, NEWFRAME, 0, NULL,  NULL);
  1425.                         nRet = Escape(hPrnDC, ENDDOC, 0, NULL,  NULL);
  1426.                 SetMapMode(hPrnDC, mm);
  1427.  
  1428.                 }
  1429.             }
  1430.         hwnd = GetNextWnd(&i);
  1431.             }
  1432.         DeleteDC(hPrnDC);
  1433.         }
  1434.                 
  1435.                         
  1436. void RemoveObjUndo(){
  1437.  
  1438.             PITEM pitem;
  1439.             if (hObjectUndo){
  1440.                 pitem = (PITEM)LocalLock(hObjectUndo);    
  1441.                 EcdDelete(pitem->lpecdobject);
  1442.                 LocalUnlock(hObjectUndo);
  1443.                   LocalFree(hObjectUndo);                    
  1444.               hObjectUndo = NULL;                  
  1445.             }
  1446.         }
  1447.                           
  1448. void PrintError(ECDSTATUS stat){
  1449.     char szError[szMsgMax];
  1450.  
  1451.     switch(stat){
  1452.         case ECD_ERROR_MEMORY:
  1453.             lstrcpy(szError, "Error ECD_ERROR_MEMORY");
  1454.             break;
  1455.         case ECD_ERROR_FATAL:
  1456.             lstrcpy(szError, "Error ECD_ERROR_FATAL");
  1457.             break;
  1458.         case ECD_ERROR_STREAM:
  1459.             lstrcpy(szError, "Error ECD_ERROR_STREAM");
  1460.             break;
  1461.         case ECD_ERROR_STATIC:
  1462.             lstrcpy(szError, "Error ECD_ERROR_STATIC");
  1463.             break;
  1464.         case ECD_ERROR_BLANK:
  1465.             lstrcpy(szError, "Error ECD_ERROR_BLANK");
  1466.             break;
  1467.         case ECD_ERROR_LAUNCH:
  1468.             lstrcpy(szError, "Error ECD_ERROR_LAUNCH");
  1469.             break;
  1470.         case ECD_ERROR_COMM:
  1471.             lstrcpy(szError, "Error ECD_ERROR_COMM");
  1472.             break;
  1473.         case ECD_ERROR_DRAW:
  1474.             lstrcpy(szError, "Error ECD_ERROR_DRAW");
  1475.             break;
  1476.         case ECD_ERROR_CLIP:
  1477.             lstrcpy(szError, "Error ECD_ERROR_CLIP");
  1478.             break;
  1479.         case ECD_ERROR_FORMAT:
  1480.             lstrcpy(szError, "Error ECD_ERROR_FORMAT");
  1481.             break;
  1482.         case ECD_ERROR_ILLEGALOBJECT:
  1483.             lstrcpy(szError, "Error ECD_ERROR_ILLEGALOBJECT");
  1484.             break;
  1485.         case ECD_ERROR_OPTION:
  1486.             lstrcpy(szError, "Error ECD_ERROR_OPTION");
  1487.             break;
  1488.         case ECD_ERROR_PROTOCOL:
  1489.             lstrcpy(szError, "Error ECD_ERROR_PROTOC");
  1490.             break;
  1491.         case ECD_ERROR_ADDRESS:
  1492.             lstrcpy(szError, "Error ECD_ERROR_ADDRESS");
  1493.             break;
  1494.  
  1495.         case ECD_ERROR_NOT_EQUAL:
  1496.             lstrcpy(szError, "Error ECD_ERROR_NOT_EQUAL");
  1497.             break;
  1498.  
  1499.         case ECD_ERROR_HANDLE:
  1500.             lstrcpy(szError, "Error ECD_ERROR_HANDLE");
  1501.             break;
  1502.         case ECD_ERROR_GENERIC:
  1503.             lstrcpy(szError, "Error ECD_ERROR_GENERIC");
  1504.             break;
  1505.         case ECD_WAIT_FOR_RELEASE:
  1506.             lstrcpy(szError, "Error ECD_WAIT_FOR_RELEASE");
  1507.             break;
  1508.         case ECD_ERROR_MAPPING_MODE:
  1509.             lstrcpy(szError, "Error ECD_ERROR_MAPPING_MODE");
  1510.             break;
  1511.  
  1512.         case ECD_ERROR_INVALIDCLASS:
  1513.             lstrcpy(szError, "Error ECD_ERROR_INVALIDCLASS");
  1514.             break;
  1515.         case ECD_ERROR_SYNTAX:
  1516.             lstrcpy(szError, "Error ECD_ERROR_SYNTAX");
  1517.             break;
  1518.         case ECD_ERROR_NOT_OPEN:
  1519.             lstrcpy(szError, "Error ECD_ERROR_NOTOPEN");
  1520.             break;
  1521.         case ECD_ERROR_PROTECT_ONLY:
  1522.             lstrcpy(szError, "Error ECD_ERROR_PROTECT_ONLY");
  1523.             break;
  1524.         case ECD_ERROR_POKENATIVE:
  1525.             lstrcpy(szError, "Error ECD_ERROR_POKENATIVE");
  1526.             break;
  1527.         case ECD_ERROR_ADVISE_PICT:
  1528.             lstrcpy(szError, "Error ECD_ERROR_ADVISE_PICT");
  1529.             break;
  1530.         case ECD_ERROR_DATATYPE:
  1531.             lstrcpy(szError, "Error ECD_ERROR_DATATYPE");
  1532.             break;
  1533.         case ECD_ERROR_ALREADY_BLOCKED:
  1534.             lstrcpy(szError, "Error ECD_ERROR_ALREADYBLOCKED");
  1535.             break;
  1536.         default:
  1537.             lstrcpy(szError, "Error Other");
  1538.             break;
  1539.             }
  1540.  
  1541.             MessageBox(hwndMain,szError, szAppName, MB_ICONASTERISK | MB_OK);
  1542.             }
  1543.  
  1544.  
  1545.  
  1546.  
  1547. void PrintWindowTitle(PITEM pitem, HWND hwnd){
  1548.  
  1549.     ECDSTATUS EcdStat;
  1550.     HANDLE hWinTitle;
  1551.       LPSTR pTitle, pTitle1;
  1552.    LPSTR lpstrInfo, lpstr1, lpstr2;
  1553.     HSTR hstr;
  1554.  
  1555.             if (((EcdStat = EcdGetData(pitem->lpecdobject,
  1556.                     (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
  1557.                     &hstr))
  1558.                     == ECD_OK)
  1559.                 && hstr)
  1560.                 {
  1561.                 // Both link formats are:  "szClass szDocument szItem 0"
  1562.                 lpstrInfo = GlobalLock(hstr);
  1563.                      lpstr1 = lpstrInfo;
  1564.                      hWinTitle = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 512);
  1565.                      pTitle = pTitle1 = (LPSTR)LocalLock(hWinTitle);
  1566.                     if (pitem->wType == IDM_PASTE){
  1567.                         lstrcpy(pTitle, "Embed!");
  1568.                         pTitle += 6;
  1569.                         }
  1570.                     else{
  1571.                         lstrcat(pTitle, "Link!");
  1572.                         pTitle += 5;
  1573.                         }
  1574.                      while (*lpstr1){
  1575.                         *(pTitle++) = *(lpstr1++);
  1576.                         }
  1577.                      *(pTitle++) = '!';
  1578.                      lpstr1 += 1;
  1579.                      while (*lpstr1)
  1580.                         *(pTitle++) = *(lpstr1++);
  1581.                      *(pTitle++) = '!';
  1582.                      lpstr1 += 1;
  1583.                      while (*lpstr1)
  1584.                         *(pTitle++) = *(lpstr1++);
  1585.                      *pTitle = '!';
  1586.                      lpstr1 += 1;
  1587.                     
  1588.  
  1589.                 SetWindowText(hwnd, (LPSTR)pTitle1);
  1590.                      LocalUnlock(hWinTitle);
  1591.                     LocalFree(hWinTitle);
  1592.                  GlobalUnlock(hstr);
  1593.                 }
  1594.                     }
  1595.  
  1596. void GetUndo(PITEM pitem){
  1597.     PITEM pObjectUndo;
  1598.  
  1599.     pObjectUndo = (PITEM)LocalLock(hObjectUndo);
  1600.     pitem->wType = pObjectUndo->wType ;                        
  1601.     pitem->wUpdate = pObjectUndo->wUpdate ;                        
  1602.     pitem->lpecdobject = pObjectUndo->lpecdobject;                        
  1603.     LocalUnlock(hObjectUndo);                        
  1604.     LocalFree(hObjectUndo);                        
  1605.     hObjectUndo = 0;                        
  1606.     }
  1607.                             
  1608. ECDSTATUS CopyLink(PITEM pCopy){
  1609.      HWND hwnd;
  1610.     HANDLE hitem;
  1611.     PITEM pitem;
  1612.     ECDSTATUS EcdStat;
  1613.     int i = 0;
  1614.  
  1615.     hwnd = GetNextWnd(&i);
  1616.    hitem = GetWindowWord(hwnd, 0);
  1617.    pitem = (PITEM) LocalLock(hitem);
  1618.     EcdStat = EcdCopyFromLink(pitem->lpecdobject, PROTOCOL, lpclient,NULL, NULL, (LPECDOBJECT FAR *) &(pCopy->lpecdobject));
  1619.     LocalUnlock(hitem);
  1620.     return EcdStat;
  1621. }
  1622.  
  1623. VOID WaitForRelease(PITEM pitem){
  1624.    MSG msg;
  1625.  
  1626.     fEcdrelease = FALSE;
  1627.     do  {                                
  1628.     GetMessage(&msg, NULL, NULL, NULL);                                
  1629.    TranslateMessage(&msg);                                
  1630.    DispatchMessage(&msg);                                 
  1631.    }
  1632. while (!fEcdrelease);
  1633. }
  1634.  
  1635.  
  1636. HWND GetTopChild(){
  1637.     HWND  hwnd;
  1638.     int i = 0;
  1639.     
  1640.     hwnd = GetTopWindow(hwndMain);
  1641.  
  1642.     while ((hwnd != rgchChildWnd[i]) && i++ < irgchChild)
  1643.         ;
  1644.     if (i <= irgchChild) // if it was found
  1645.         return hwnd;
  1646.     // else find the first non null guy
  1647.     i = 0;
  1648.     while (!(hwnd = rgchChildWnd[i]) && i++ < irgchChild)
  1649.         ;
  1650.         return hwnd;
  1651. }
  1652.  
  1653. HWND GetNextWnd(LPINT i){
  1654.     HWND hwnd;
  1655.     while (!(hwnd = rgchChildWnd[*i]) && *i < irgchChild)
  1656.       *i += 1;
  1657.     *i += 1;
  1658.     return hwnd;
  1659. }
  1660.  
  1661.  
  1662. BOOL fTestEcdStat(ECDSTATUS EcdStat){
  1663.     // use it for Async conditions
  1664.  
  1665.     switch(EcdStat){
  1666.         case ECD_WAIT_FOR_RELEASE:
  1667.             if (fEcdReleaseError){
  1668.                 PrintError(fEcdReleaseStat);
  1669.                 return TRUE;
  1670.                 }
  1671.             else
  1672.                 return FALSE;
  1673.             break;
  1674.         case ECD_OK:
  1675.             return FALSE;
  1676.         default:
  1677.             PrintError(EcdStat);
  1678.             return TRUE;
  1679.             }
  1680.         }
  1681.  
  1682.  
  1683. BOOL Insert(HWND hwnd)
  1684. {
  1685.     FARPROC lpProc;
  1686.     int     fh;
  1687.  
  1688.  
  1689.     // Ask for a file name
  1690.     lpProc = MakeProcInstance(OpenDlgProc, hInst);
  1691.     fh = DialogBox(hInst, "Open", hwnd, lpProc);
  1692.     FreeProcInstance(lpProc);
  1693.     if (fh > 0)
  1694.         _lclose(fh); // because the file is opened in Open
  1695.     return (fh);
  1696.  
  1697. }
  1698.  
  1699.  
  1700. VOID TestEqual(){ // test the top and next object are equal
  1701.     HWND hTop, hNext;
  1702.     HANDLE hitem1, hitem2;
  1703.     PITEM pitem1, pitem2;
  1704.     ECDSTATUS EcdStat;
  1705.     int i = 0;
  1706.  
  1707.     hTop = GetTopChild();
  1708.     hitem1 = GetWindowWord(hTop, 0);
  1709.     pitem1 = (PITEM)LocalLock(hitem1);
  1710.  
  1711.     hNext = GetNextWnd(&i);
  1712.     hitem2 = GetWindowWord(hNext, 0);
  1713.     pitem2 = (PITEM)LocalLock(hitem2);
  1714.  
  1715.     EcdStat = EcdEqual(pitem1->lpecdobject, pitem2->lpecdobject);
  1716.     if (EcdStat == ECD_WAIT_FOR_RELEASE)
  1717.         WaitForRelease(pitem1);
  1718.     if (fTestEcdStat(EcdStat))
  1719.         PrintError(EcdStat);
  1720. }
  1721.  
  1722.  
  1723.  
  1724.  
  1725.