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

  1. #define SERVERONLY
  2. #include "windows.h"
  3. #include "ecd.h"
  4. #include "shapes.h"
  5. #include <string.h>
  6.  
  7.  
  8. char FileName[128];
  9. char PathName[128];
  10. char OpenName[128];
  11. char DefPath[128];
  12. char DefSpec[13] = "*.shax104";
  13. char DefExt[] = ".txt";
  14. char str[255];
  15.  
  16. RECT    dragRect;
  17. POINT   dragPt;
  18. HWND    hwndMain;
  19. BOOL    fCapture = FALSE;
  20.  
  21. HBRUSH  hbrColor [5];
  22.  
  23. char    *pcolors [5]  ={"RED",
  24.                         "GREEN",
  25.                         "BLUE",
  26.                         "BLACK",
  27.                         "YELLOW"
  28.                        };
  29. char    *pshapes [4] = {
  30.                         ":RECTANGLE",
  31.                         ":ROUNDRECT"
  32.                         ":HOLLOWRECT",
  33.                         ":HOLLOWROUNDRECT"
  34.                        };
  35.  
  36.  
  37. WORD        cfLink;
  38. WORD        cfOwnerLink;
  39. WORD        cfNative;
  40. WORD        cShapes = 0;
  41. BOOL        bBusy   = FALSE;
  42.  
  43.  
  44. HANDLE hInst;
  45. HANDLE hAccTable;
  46.  
  47.  
  48. //////////////////////////////////////////////////////////////////////////
  49. //
  50. // Right thing to do is to wait till the termination came from the client side.
  51. // This is lot more cleaner.
  52. //
  53. // (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
  54. //
  55. /////////////////////////////////////////////////////////////////////////
  56.  
  57.  
  58. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  59. HANDLE  hInstance;
  60. HANDLE  hPrevInstance;
  61. LPSTR   lpCmdLine;
  62. int nCmdShow;
  63. {
  64.     MSG msg;
  65.  
  66.  
  67.  
  68.     if (!hPrevInstance)
  69.         if (!InitApplication(hInstance))
  70.             return (FALSE);
  71.  
  72.  
  73.  
  74.  
  75.     if (!InitInstance(hInstance, nCmdShow))
  76.         return (FALSE);
  77.  
  78.     if (!InitServer (hwndMain, hInstance))
  79.         return FALSE;
  80.  
  81.     if (!ProcessCmdLine (hwndMain, lpCmdLine))
  82.         return FALSE;
  83.  
  84.     while (GetMessage(&msg, NULL, NULL, NULL)) {
  85.  
  86.     /* Only translate message if it is not an accelerator message */
  87.  
  88.         if (!TranslateAccelerator(hwndMain, hAccTable, &msg)) {
  89.             TranslateMessage(&msg);
  90.             DispatchMessage(&msg); 
  91.         }
  92.     }
  93.  
  94.     DeleteInstance ();
  95.     return (msg.wParam);
  96. }
  97.  
  98.  
  99.  
  100. BOOL InitApplication(hInstance)
  101. HANDLE hInstance;
  102. {
  103.     WNDCLASS  wc;
  104.  
  105.     wc.style = NULL;
  106.     wc.lpfnWndProc = MainWndProc;
  107.     wc.cbClsExtra = 4;
  108.     wc.cbWndExtra = 4;
  109.     wc.hInstance = hInstance;
  110.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  111.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  112.     wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
  113.     wc.lpszMenuName =  "InitMenu";
  114.  
  115.     wc.lpszClassName = "SampleClass";
  116.     wc.lpfnWndProc = MainWndProc;
  117.  
  118.     if (!RegisterClass(&wc))
  119.         return NULL;
  120.  
  121.  
  122.     wc.hIcon   = NULL;
  123.     wc.hCursor = NULL;
  124.     wc.lpszMenuName  = NULL;
  125.     wc.lpszClassName = "DocClass";
  126.     wc.lpfnWndProc   = DocWndProc;
  127.  
  128.     if (!RegisterClass(&wc))
  129.         return NULL;
  130.  
  131.  
  132.  
  133.     wc.hIcon   = NULL;
  134.     wc.hCursor = NULL;
  135.     wc.lpszMenuName = NULL;
  136.     wc.lpszClassName = "ItemClass";
  137.     wc.lpfnWndProc   = ItemWndProc;
  138.  
  139.     if (!RegisterClass(&wc))
  140.         return NULL;
  141.  
  142. }
  143.  
  144.  
  145.  
  146. BOOL InitInstance(hInstance, nCmdShow)
  147. HANDLE          hInstance;
  148. int             nCmdShow;
  149. {
  150.  
  151.     // initialse the proc tables.
  152.     InitVTbls ();
  153.  
  154.     hbrColor [0] = CreateSolidBrush (0x000000ff);
  155.     hbrColor [1] = CreateSolidBrush (0x0000ff00);
  156.     hbrColor [2] = CreateSolidBrush (0x00ff0000);
  157.     hbrColor [3] = CreateSolidBrush (0x00000000);
  158.     hbrColor [4] = CreateSolidBrush (0x00ff00ff);
  159.  
  160.     // register clipboard formats.
  161.     cfLink      = RegisterClipboardFormat("ObjectLink");
  162.     cfOwnerLink = RegisterClipboardFormat("OwnerLink");
  163.     cfNative    = RegisterClipboardFormat("Native");
  164.  
  165.  
  166.     hInst = hInstance;
  167.     hAccTable = LoadAccelerators(hInst, "SampleAcc");
  168.  
  169.     hwndMain = CreateWindow(
  170.         "SampleClass",
  171.         "Sample miServer Application",
  172.         WS_OVERLAPPEDWINDOW,
  173.         CW_USEDEFAULT,
  174.         CW_USEDEFAULT,
  175.         CW_USEDEFAULT,
  176.         CW_USEDEFAULT,
  177.         NULL,
  178.         NULL,
  179.         hInstance,
  180.         NULL
  181.     );
  182.  
  183.  
  184.     if (!hwndMain)
  185.         return (FALSE);
  186.  
  187.     ShowWindow(hwndMain, nCmdShow);
  188.     UpdateWindow(hwndMain);
  189.     return (TRUE);
  190.  
  191. }
  192.  
  193. void    DeleteInstance ()
  194. {
  195.  
  196.     // Free the proc table instances.
  197.     FreeVTbls ();
  198.  
  199.     DeleteObject (hbrColor [0]);
  200.     DeleteObject (hbrColor [1]);
  201.     DeleteObject (hbrColor [2]);
  202.     DeleteObject (hbrColor [3]);
  203.     DeleteObject (hbrColor [4]);
  204.  
  205. }
  206.  
  207. // main window or server related routiens
  208.  
  209. long FAR PASCAL MainWndProc(hwnd, message, wParam, lParam)
  210. HWND hwnd;
  211. unsigned message;
  212. WORD wParam;
  213. LONG lParam;
  214. {
  215.     FARPROC lpProcAbout, lpOpenDlg, lpSaveDlg;
  216.  
  217.     int     Return;
  218.     PITEM   pitem;
  219.     PDOC    pdoc;
  220.  
  221.  
  222.  
  223.     switch (message) {
  224.         case WM_COMMAND:
  225.             switch (wParam) {
  226.  
  227.  
  228.                 case IDM_NEWITEM:
  229.                     pdoc = (PDOC)GetWindowLong (GetWindow (hwnd, GW_CHILD), 0);
  230.                     pitem = CreateNewItem  (pdoc, IDM_RECT, IDM_RED, TRUE);
  231.                     SetNewItemName (pitem);
  232.                     BringWindowToTop (pitem->hwnd);
  233.                     break;
  234.  
  235.                 case IDM_RED:
  236.                 case IDM_GREEN:
  237.                 case IDM_BLUE:
  238.                 case IDM_BLACK:
  239.                 case IDM_YELLOW:
  240.  
  241.                     pitem = (PITEM)GetWindowLong (
  242.                             GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD), 0);
  243.                     pitem->cmdColor = wParam;
  244.                     InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
  245.                     // make sure that we have the right bits on the screen
  246.                     UpdateWindow (pitem->hwnd);
  247.                     SendItemChangeMsg (pitem, ECD_CHANGED);
  248.                     break;
  249.  
  250.  
  251.                 case IDM_RECT:
  252.                 case IDM_ROUNDRECT:
  253.                 case IDM_HALLOWRECT:
  254.                 case IDM_HALLOWROUNDRECT:
  255.  
  256.                     pitem = (PITEM)GetWindowLong (
  257.                             GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD), 0);
  258.                     pitem->cmdShape = wParam;
  259.                     InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
  260.                     UpdateWindow (pitem->hwnd);
  261.                     SendItemChangeMsg (pitem, ECD_CHANGED);
  262.                     break;
  263.  
  264.                 case IDM_NEW:
  265.  
  266.                     // create another document widnwo.
  267.                     pdoc = CreateNewDoc ((PSRVR)GetWindowLong (hwnd, 0), NULL, (LPSTR)"New");
  268.                     if (pdoc == NULL)
  269.                         break;
  270.                     pitem = CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
  271.                     SetNewItemName (pitem);
  272.                     BringWindowToTop (pdoc->hwnd);
  273.                     break;
  274.  
  275.  
  276.                 case IDM_ABOUT:
  277.                     lpProcAbout = MakeProcInstance(About, hInst);
  278.                     DialogBox(hInst, "AboutBox", hwnd, lpProcAbout);
  279.                     FreeProcInstance(lpProcAbout);
  280.                     break;
  281.  
  282.                 case IDM_OPEN:
  283.                     /* Call OpenDlg() to get the filename */
  284.  
  285.                     lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
  286.                     Return = DialogBox(hInst, "Open", hwnd, lpOpenDlg);
  287.                     FreeProcInstance(lpOpenDlg);
  288.  
  289.                     if (!CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0), (LPSTR)OpenName, NULL))
  290.                         MessageBox (
  291.                               hwndMain,
  292.                               "reading from file failed",
  293.                               "Server Sample Sample Application",
  294.                                MB_OK);
  295.  
  296.  
  297.                     break;
  298.  
  299.                 case IDM_SAVE:
  300.  
  301.                     lpSaveDlg = MakeProcInstance((FARPROC) SaveDlg, hInst);
  302.                     Return = DialogBox(hInst, "Save", hwnd, lpSaveDlg);
  303.                     FreeProcInstance(lpSaveDlg);
  304.  
  305.                     SaveDocIntoFile (pdoc = (PDOC) (GetWindowLong (GetWindow (hwnd, GW_CHILD), 0)),
  306.                         (LPSTR)OpenName);
  307.  
  308.                     // send message for save
  309.                     SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_SAVED);
  310.                     SendDocRenameMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_RENAMED);
  311.                     break;
  312.  
  313.  
  314.                 case IDM_SAVEAS:
  315.                 case IDM_PRINT:
  316.                     MessageBox (
  317.                           GetFocus(),
  318.                           "Command not implemented",
  319.                           "Server Sample Sample Application",
  320.                           MB_ICONASTERISK | MB_OK);
  321.                     break;  
  322.  
  323.  
  324.  
  325.                 case IDM_EXIT:
  326.                     SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CLOSED);
  327.                     DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
  328.                     break;
  329.     
  330.                 /* edit menu commands */
  331.  
  332.                 case IDM_UNDO:
  333.                 case IDM_CUT:
  334.                 case IDM_COPY:
  335.  
  336.                     CutCopyItem (hwnd);
  337.                     break;
  338.  
  339.                 case IDM_PASTE:
  340.                 case IDM_CLEAR:
  341.                     MessageBox (
  342.                           GetFocus(),
  343.                           "Command not implemented",
  344.                           "Server Sample  Sample Application",
  345.                           MB_ICONASTERISK | MB_OK);
  346.                     break;  
  347.  
  348.                 case IDC_EDIT:
  349.                     if (HIWORD (lParam) == EN_ERRSPACE) {
  350.                         MessageBox (
  351.                               GetFocus ()
  352.                             , "Out of memory."
  353.                             , "server Sample  Sample Application"
  354.                             , MB_ICONHAND | MB_OK
  355.                         );
  356.                     }
  357.                     break;
  358.  
  359.             } 
  360.             break;
  361.  
  362.         case WM_SIZE:
  363.             if (wParam == SIZENORMAL)
  364.                 ReSizeAllDocs (hwnd, LOWORD (lParam), HIWORD (lParam));
  365.  
  366.             break;
  367.  
  368.         case WM_CLOSE:
  369.             SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CLOSED);
  370.             DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
  371.             break;
  372.  
  373.         case WM_DESTROY:
  374.             PostQuitMessage (0);
  375.             break;
  376.  
  377.         default:
  378.             return (DefWindowProc(hwnd, message, wParam, lParam));
  379.     }
  380.     return (NULL);
  381. }
  382.  
  383.  
  384.  
  385.  
  386.  
  387. HANDLE FAR PASCAL SaveDlg (hDlg, message, wParam, lParam)
  388. HWND     hDlg;
  389. unsigned message;
  390. WORD     wParam;
  391. LONG     lParam;
  392. {
  393.  
  394.     switch (message) {
  395.         case WM_COMMAND:
  396.             switch (wParam) {
  397.  
  398.                 case IDOK:
  399.                     GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
  400.  
  401.                     AddExt(OpenName, DefExt);
  402.                     EndDialog(hDlg, TRUE);
  403.                     return (TRUE);
  404.  
  405.                 case IDCANCEL:
  406.                     EndDialog(hDlg, NULL);
  407.                     return (FALSE);
  408.             }
  409.             break;
  410.  
  411.         case WM_INITDIALOG:                        /* message: initialize    */
  412.             SetDlgItemText(hDlg, IDC_EDIT, (LPSTR)"shape1.sha");
  413.             SendDlgItemMessage(hDlg,               /* dialog handle      */
  414.                 IDC_EDIT,                          /* where to send message  */
  415.                 EM_SETSEL,                         /* select characters      */
  416.                 NULL,                              /* additional information */
  417.                 MAKELONG(0, 0x7fff));              /* entire contents      */
  418.             SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  419.             return (FALSE); /* Indicates the focus is set to a control */
  420.     }
  421.     return FALSE;
  422. }
  423.  
  424.  
  425.  
  426.  
  427. HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
  428. HWND     hDlg;
  429. unsigned message;
  430. WORD     wParam;
  431. LONG     lParam;
  432. {
  433.     HANDLE hFile=1;     /* Temp value for return */
  434.  
  435.     switch (message) {
  436.         case WM_COMMAND:
  437.             switch (wParam) {
  438.  
  439.                 case IDC_LISTBOX:
  440.                     switch (HIWORD(lParam)) {
  441.  
  442.                         case LBN_SELCHANGE:
  443.                             /* If item is a directory name, append "*.*" */
  444.                             if (DlgDirSelect(hDlg, str, IDC_LISTBOX)) 
  445.                                 strcat(str, DefSpec);
  446.  
  447.                             SetDlgItemText(hDlg, IDC_EDIT, str);
  448.                             SendDlgItemMessage(hDlg,
  449.                                 IDC_EDIT,
  450.                                 EM_SETSEL,
  451.                                 NULL,
  452.                                 MAKELONG(0, 0x7fff));
  453.                             break;
  454.  
  455.                         case LBN_DBLCLK:
  456.                             goto openfile;
  457.                     }
  458.                     return (TRUE);
  459.  
  460.                 case IDOK:
  461. openfile:
  462.                     GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
  463.                     if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
  464.                         SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
  465.                             (LPSTR) OpenName);
  466.                         if (str[0])
  467.                             strcpy(DefPath, str);
  468.                         ChangeDefExt(DefExt, DefSpec);
  469.                         UpdateListBox(hDlg);
  470.                         return (TRUE);
  471.                     }
  472.  
  473.                     if (!OpenName[0]) {
  474.                         MessageBox(hDlg, "No filename specified.",
  475.                             NULL, MB_OK | MB_ICONHAND);
  476.                         return (TRUE);
  477.                     }
  478.  
  479.                     AddExt(OpenName, DefExt);
  480.  
  481.                     /* The routine to open the file would go here, and the */
  482.                     /* file handle would be returned instead of NULL.           */
  483.                     EndDialog(hDlg, hFile);
  484.                     return (TRUE);
  485.  
  486.                 case IDCANCEL:
  487.                     EndDialog(hDlg, NULL);
  488.                     return (FALSE);
  489.             }
  490.             break;
  491.  
  492.         case WM_INITDIALOG:                        /* message: initialize    */
  493.             UpdateListBox(hDlg);
  494.             SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  495.             SendDlgItemMessage(hDlg,               /* dialog handle      */
  496.                 IDC_EDIT,                          /* where to send message  */
  497.                 EM_SETSEL,                         /* select characters      */
  498.                 NULL,                              /* additional information */
  499.                 MAKELONG(0, 0x7fff));              /* entire contents      */
  500.             SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  501.             return (FALSE); /* Indicates the focus is set to a control */
  502.     }
  503.     return FALSE;
  504. }
  505.  
  506.  
  507.  
  508. void UpdateListBox(hDlg)
  509. HWND hDlg;
  510. {
  511.     strcpy(str, DefPath);
  512.     strcat(str, DefSpec);
  513.     DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);
  514.  
  515.     /* To ensure that the listing is made for a subdir. of
  516.      * current drive dir...
  517.      */
  518.     if (!strchr (DefPath, ':'))
  519.     DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);
  520.  
  521.     /* Remove the '..' character from path if it exists, since this
  522.      * will make DlgDirList move us up an additional level in the tree
  523.      * when UpdateListBox() is called again.
  524.      */
  525.     if (strstr (DefPath, ".."))
  526.     DefPath[0] = '\0';
  527.  
  528.     SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  529. }
  530.  
  531.  
  532. void ChangeDefExt(Ext, Name)
  533. PSTR Ext, Name;
  534. {
  535.     PSTR pTptr;
  536.  
  537.     pTptr = Name;
  538.     while (*pTptr && *pTptr != '.')
  539.         pTptr++;
  540.     if (*pTptr)
  541.         if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
  542.             strcpy(Ext, pTptr);
  543. }
  544.  
  545.  
  546. void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
  547. HWND hDlg;
  548. LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
  549. {
  550.     LPSTR lpTmp;
  551.     char  cTmp;
  552.  
  553.     lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
  554.     while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
  555.         lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
  556.     if (*lpTmp != ':' && *lpTmp != '\\') {
  557.         lstrcpy(lpDestFileName, lpSrcFileName);
  558.         lpDestPath[0] = 0;
  559.         return;
  560.     }
  561.     lstrcpy(lpDestFileName, lpTmp + 1);
  562.     cTmp = *(lpTmp + 1);
  563.     lstrcpy(lpDestPath, lpSrcFileName);
  564.      *(lpTmp + 1) = cTmp;
  565.     lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
  566. }
  567.  
  568.  
  569.  
  570. void AddExt(Name, Ext)
  571. PSTR Name, Ext;
  572. {
  573.     PSTR pTptr;
  574.  
  575.     pTptr = Name;
  576.     while (*pTptr && *pTptr != '.')
  577.         pTptr++;
  578.     if (*pTptr != '.')
  579.         strcat(Name, Ext);
  580. }
  581.  
  582.  
  583. BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
  584. HWND hDlg;
  585. unsigned message;
  586. WORD wParam;
  587. LONG lParam;
  588. {
  589.     switch (message) {
  590.         case WM_INITDIALOG:
  591.             return (TRUE);
  592.  
  593.         case WM_COMMAND:
  594.         if (wParam == IDOK
  595.                 || wParam == IDCANCEL) {
  596.                 EndDialog(hDlg, TRUE);
  597.                 return (TRUE);
  598.             }
  599.             break;
  600.     }
  601.     return (FALSE);
  602. }
  603.  
  604.  
  605. void   DrawDragRect (hwnd)
  606. HWND    hwnd;
  607. {
  608.  
  609.         HDC hdc;
  610.  
  611.         hdc = GetDC(hwnd);
  612.         InvertRect (hdc, (LPRECT)&dragRect);
  613.         ReleaseDC (hwnd, hdc);
  614.  
  615. }
  616.  
  617. void    ReSizeAllDocs (hwndSrvr, width, height)
  618. HWND    hwndSrvr;
  619. int     width;
  620. int     height;
  621. {
  622.     HWND    hwnd;
  623.     RECT    rc;
  624.  
  625.  
  626.     hwnd = GetWindow (hwndSrvr, GW_CHILD);
  627.     while (hwnd){
  628.         GetWindowRect (hwnd, (LPRECT)&rc);
  629.         ScreenToClient (hwndSrvr, (LPPOINT)&rc);
  630.         MoveWindow (hwnd, rc.left, rc.top,
  631.             width , height, TRUE);
  632.  
  633.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  634.     }
  635.  
  636. }
  637. void    ReSizeAllItems (hwndDoc, width, height)
  638. HWND    hwndDoc;
  639. int     width;
  640. int     height;
  641. {
  642.     HWND    hwnd;
  643.     RECT    rc;
  644.  
  645.  
  646.     hwnd = GetWindow (hwndDoc, GW_CHILD);
  647.     while (hwnd){
  648.         GetWindowRect (hwnd, (LPRECT)&rc);
  649.         ScreenToClient (hwndDoc, (LPPOINT)&rc);
  650.         MoveWindow (hwnd, rc.left, rc.top,
  651.             width >> 1, height >> 1, TRUE);
  652.  
  653.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  654.     }
  655.  
  656. }
  657.  
  658. long FAR PASCAL ItemWndProc (hwnd, message, wParam, lParam)
  659. HWND hwnd;
  660. unsigned message;
  661. WORD wParam;
  662. LONG lParam;
  663. {
  664.         POINT   pt;
  665.         HWND    hwndParent;
  666.  
  667.  
  668.     switch (message) {
  669.         case WM_PAINT:
  670.             PaintItem (hwnd);
  671.             break;
  672.  
  673.  
  674.         case WM_SIZE:
  675.             break;
  676.  
  677.         case WM_DESTROY:
  678.             DestroyItem (hwnd);
  679.             break;
  680.  
  681.         case WM_RBUTTONDOWN:
  682.  
  683.  
  684.             hwndParent = GetParent (hwnd);
  685.             GetWindowRect (hwnd, (LPRECT) &dragRect);
  686.             ScreenToClient (hwndParent, (LPPOINT)&dragRect);
  687.             ScreenToClient (hwndParent, (LPPOINT)&dragRect.right);
  688.  
  689.             DrawDragRect (hwndParent);
  690.  
  691.             dragPt.x = LOWORD(lParam);
  692.             dragPt.y = HIWORD(lParam);
  693.  
  694.             ClientToScreen (hwnd, (LPPOINT)&dragPt);
  695.             ScreenToClient (hwndParent, (LPPOINT)&dragPt);
  696.  
  697.             SetCapture (hwnd);
  698.             fCapture = TRUE;
  699.             break;
  700.  
  701.         case WM_MOUSEMOVE:
  702.             if (!fCapture)
  703.                 break;
  704.  
  705.             hwndParent = GetParent (hwnd);
  706.             DrawDragRect (hwndParent);
  707.             pt.x = LOWORD(lParam);
  708.             pt.y = HIWORD(lParam);
  709.  
  710.             ClientToScreen (hwnd, (LPPOINT)&pt);
  711.             ScreenToClient (hwndParent, (LPPOINT)&pt);
  712.  
  713.             OffsetRect ((LPRECT)&dragRect, pt.x - dragPt.x,
  714.                                         pt.y - dragPt.y);
  715.  
  716.             dragPt.x = pt.x;
  717.             dragPt.y = pt.y;
  718.  
  719.  
  720.             DrawDragRect (hwndParent);
  721.             break;
  722.  
  723.  
  724.         case WM_RBUTTONUP:
  725.             if (!fCapture)
  726.                 return TRUE;
  727.  
  728.             hwndParent = GetParent (hwnd);
  729.             fCapture = FALSE;
  730.             ReleaseCapture ();
  731.             DrawDragRect (hwndParent);
  732.  
  733.             MoveWindow (hwnd, dragRect.left, dragRect.top,
  734.                         dragRect.right - dragRect.left,
  735.                         dragRect.bottom - dragRect.top, TRUE);
  736.  
  737.              // fall thru
  738.  
  739.         case WM_LBUTTONDOWN:
  740.              BringWindowToTop (hwnd);
  741.              break;
  742.  
  743.         default:
  744.             return (DefWindowProc(hwnd, message, wParam, lParam));
  745.     }
  746.     return (NULL);
  747. }
  748.  
  749.  
  750. BOOL    SaveDocIntoFile (pdoc, lpstr)
  751. PDOC    pdoc;
  752. LPSTR   lpstr;
  753. {
  754.  
  755.  
  756.     HWND    hwnd;
  757.     int     fh;
  758.     PITEM   pitem;
  759.  
  760.  
  761.     if ((fh =_lcreat (lpstr, 0)) <= 0)
  762.         return FALSE;
  763.  
  764.     hwnd = GetWindow (pdoc->hwnd, GW_CHILD);
  765.  
  766.     while (hwnd) {
  767.         pitem = (PITEM) GetWindowLong (hwnd, 0);
  768.         if (!pitem->aName)
  769.             SetNewItemName (pitem);
  770.  
  771.         if (_lwrite (fh, (LPSTR)pitem, sizeof (ITEM)) <= 0)
  772.             break;
  773.  
  774.         hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  775.     }
  776.     _lclose (fh);
  777.  
  778.     SetWindowText (pdoc->hwnd, (LPSTR)lpstr);
  779.     return TRUE;
  780. }
  781.  
  782.  
  783. PDOC    CreateDocFromFile (psrvr, lpstr, lhdoc)
  784. PSRVR       psrvr;
  785. LPSTR       lpstr;
  786. LHDOCUMENT  lhdoc;
  787. {
  788.  
  789.     int     fh;
  790.     ITEM    item;
  791.     PITEM   pitem;
  792.     PDOC    pdoc;
  793.  
  794.  
  795.     if ((fh =_lopen (lpstr, OF_READ)) <= 0)
  796.         return FALSE;
  797.  
  798.     if (!(pdoc = CreateNewDoc (psrvr, lhdoc, lpstr)))
  799.         return FALSE;
  800.  
  801.     cShapes = 0;
  802.     while (TRUE) {
  803.         if (_lread (fh, (LPSTR)&item, sizeof (ITEM)) <= 0)
  804.             break;
  805.  
  806.         pitem = CreateNewItem (pdoc, item.cmdShape, item.cmdColor, TRUE);
  807.         SetItemName (pitem, (LPSTR)item.name);
  808.         cShapes++;
  809.     }
  810.     _lclose (fh);
  811.  
  812.  
  813.     return pdoc;
  814. }
  815.  
  816. // doc related routines
  817.  
  818. PDOC    CreateNewDoc (psrvr, lhdoc, lptitle)
  819. PSRVR   psrvr;
  820. LONG    lhdoc;
  821. LPSTR   lptitle;
  822. {
  823.  
  824.     RECT        rc;
  825.     HMENU       hMenu;
  826.     HWND        hwnd;
  827.  
  828.     hwnd = psrvr->hwnd;
  829.  
  830.     // first set the menu.
  831.     hMenu = GetMenu (hwnd);
  832.     DestroyMenu (hMenu);
  833.  
  834.     hMenu = LoadMenu (hInst, (LPSTR)"SampleMenu");
  835.     SetMenu (hwnd, hMenu);
  836.     DrawMenuBar (hwnd);
  837.  
  838.     GetClientRect (hwnd, (LPRECT)&rc);
  839.     if (IsIconic (psrvr->hwnd)){
  840.         // create some reasonale height/wdith for satisfying the
  841.         // data request in iconic mode
  842.         rc.right = GetSystemMetrics (SM_CXSCREEN) >> 1;
  843.         rc.bottom   = GetSystemMetrics (SM_CYSCREEN) >> 1;
  844.     }
  845.     InflateRect ((LPRECT)&rc, -5, -5);
  846.  
  847.     hwnd = CreateWindow(
  848.         "DocClass",
  849.         "New",
  850.         WS_SYSMENU | WS_CAPTION | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
  851.  
  852.         rc.left,
  853.         rc.top,
  854.         (rc.right - rc.left),
  855.         (rc.bottom - rc.top),
  856.         psrvr->hwnd,
  857.         NULL,
  858.         hInst,
  859.         NULL
  860.     );
  861.  
  862.     SetWindowText (hwnd, lptitle);
  863.     return InitDoc (hwnd, lhdoc);
  864. }
  865.  
  866. long FAR PASCAL DocWndProc(hwnd, message, wParam, lParam)
  867. HWND hwnd;
  868. unsigned message;
  869. WORD wParam;
  870. LONG lParam;
  871. {
  872.     HWND    hwndChild;
  873.     HWND    hwndParent;
  874.     HMENU   hMenu;
  875.  
  876.     switch (message) {
  877.  
  878.         case WM_SIZE:
  879.             if (wParam == SIZENORMAL)
  880.                 ReSizeAllItems (hwnd, LOWORD (lParam), HIWORD (lParam));
  881.             break;
  882.  
  883.         case WM_CLOSE:
  884.             SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), ECD_CLOSED);
  885.             DeleteDoc ((PDOC)GetWindowLong (hwnd, 0));
  886.             break;
  887.  
  888.         case WM_DESTROY:
  889.  
  890.             hwndParent = GetParent (hwnd);
  891.             hwndChild = GetWindow(hwndParent, GW_CHILD);
  892.  
  893.             if (GetWindow (hwndChild, GW_HWNDNEXT))
  894.                 break;          // some more doc windows.
  895.  
  896.             // first set the menu.
  897.             hMenu  = GetMenu (hwndMain);
  898.             DestroyMenu (hMenu);
  899.  
  900.             // we do not ahve any more doc windows.
  901.             hMenu = LoadMenu (hInst, (LPSTR)"InitMenu");
  902.             SetMenu (hwndMain, hMenu);
  903.             DrawMenuBar (hwndMain);
  904.             break;
  905.  
  906.  
  907.  
  908.         case WM_LBUTTONDOWN:
  909.             BringWindowToTop (hwnd);
  910.             break;
  911.  
  912.         default:
  913.             return (DefWindowProc(hwnd, message, wParam, lParam));
  914.     }
  915.     return (NULL);
  916. }
  917.