home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Multimedia Jumpstart 1.1a / CD_ROM.BIN / develpmt / source / hotspot / editor / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-03  |  25.9 KB  |  687 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (c) 1993  Microsoft Corporation.  All Rights Reserved.
  9.  * 
  10.  **************************************************************************/
  11.  
  12. /****************************************************************************
  13.  
  14.     PROGRAM: AVIHED
  15.  
  16.     PURPOSE:    AVI Hotspot Editor
  17.                 Copyright (c) 1993 Microsoft Corp.
  18.                 Written by David Feinleib: August, 1993
  19.     
  20.     MODIFIED    September/October 1993 by Wayne Radinsky:
  21.                 Separated source from hotspot app, hotspot viewer DLL,
  22.                 and hotspot VBX.  Converted hotspot data from INI file
  23.                 to binary HOT file.
  24.  
  25. ****************************************************************************/
  26.  
  27. /*
  28.     main.c:
  29.         WinMain -- Calls initialization function, processes message loop
  30.         InitApplication -- Initializes window data and registers
  31.             window class
  32.         InitInstance -- Saves instance handle and creates main window
  33.         MainWndProc -- Processes messages
  34.         SaveWindowRect -- Write specified rect to win.ini 
  35.         RestoreWindowRect -- Retreives main window position from win.ini
  36.         RestoreDlgRect -- same thing but with dialogs...
  37.         RestoreSelectDlgRect
  38. */        
  39.         
  40.  
  41. #include <windows.h>
  42. #include <mmsystem.h>
  43. #include <digitalv.h>
  44. #include <viewer.h>
  45. #include <string.h>
  46. #include <commdlg.h>
  47. #include <stdlib.h>
  48.  
  49. #include "hotspot.h"
  50. #include "avihed.h"            /* specific to this program          */
  51.  
  52. PMOVIEINFO pMovieInfo;
  53. HANDLE  hInst;               /* current instance              */
  54. UINT    uDoubleClickTime = 0;
  55. BOOL    bShowValidRectsOnly = TRUE;
  56. BOOL    bModified = FALSE;
  57. BOOL    bFileLoaded = FALSE;
  58. char    szBaseWindowTitle[] = "AVI Hotspot Editor";
  59. char    szWindowTitle[80];
  60. int     PixelVary = 3;
  61. HWND    hwndDlg;               // handle of FrameDlg
  62. HWND    hwndSelectDlg;         // handle of SelectDlg
  63. RECT    rcwndDlg;
  64. RECT    rcwndSelectDlg;
  65.  
  66.  
  67. /*
  68.     WinMain -- calls InitApplication() and initAVI(), initializes
  69.         some global variables, then translates and dispatches messages
  70.         until WM_QUIT message breaks the loop.        
  71. */
  72.  
  73. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  74. HANDLE hInstance;                /* current instance         */
  75. HANDLE hPrevInstance;            /* previous instance        */
  76. LPSTR lpCmdLine;                 /* command line             */
  77. int nCmdShow;                    /* show-window type (open/icon) */
  78. {
  79.     MSG msg;                     /* message              */
  80.  
  81.     if (!hPrevInstance)          /* Other instances of app running? */
  82.     if (!InitApplication(hInstance)) /* Initialize shared things */
  83.         return (FALSE);      /* Exits if unable to initialize     */
  84.  
  85.     /* Perform initializations that apply to a specific instance */
  86.  
  87.     if (!InitInstance(hInstance, nCmdShow))
  88.         return (FALSE);
  89.  
  90.     /* Acquire and dispatch messages until a WM_QUIT message is received. */
  91.     
  92.     uDoubleClickTime = GetDoubleClickTime();
  93.     PixelVary = GetProfileInt(szBaseWindowTitle, "PixelVary", 3);
  94.     
  95.     initAVI();
  96.     
  97.     while (GetMessage(&msg,    /* message structure              */
  98.         NULL,          /* handle of window receiving the message */
  99.         NULL,          /* lowest message to examine          */
  100.         NULL))         /* highest message to examine         */
  101.     {
  102.         TranslateMessage(&msg);    /* Translates virtual key codes       */
  103.         DispatchMessage(&msg);     /* Dispatches message to window       */
  104.     }
  105.     
  106.     termAVI();
  107.     
  108.     return (msg.wParam);       /* Returns the value from PostQuitMessage */
  109. }
  110.  
  111.  
  112. /* 
  113.     InitApplication -- registers window class.  This gives Windows a
  114.         pointer to MainWndProc.
  115. */
  116. BOOL InitApplication(hInstance)
  117. HANDLE hInstance;                  /* current instance       */
  118. {
  119.     WNDCLASS  wc;
  120.  
  121.     /* Fill in window class structure with parameters that describe the       */
  122.     /* main window.                                                           */
  123.  
  124.     wc.style = CS_DBLCLKS;                    /* Class style(s).                    */
  125.     wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for  */
  126.                                         /* windows of this class.             */
  127.     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
  128.     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
  129.     wc.hInstance = hInstance;           /* Application that owns the class.   */
  130.     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  131.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  132.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  133.     wc.lpszMenuName =  "AvihedMenu";   /* Name of menu resource in .RC file. */
  134.     wc.lpszClassName = "AvihedWClass"; /* Name used in call to CreateWindow. */
  135.  
  136.     /* Register the window class and return success/failure code. */
  137.  
  138.     return (RegisterClass(&wc));
  139.  
  140. }
  141.  
  142.  
  143. /*
  144.     InitInstance() -- creates main application window, putting it at
  145.         the same coordiantes (via RestoreWindowRect()) if possible.
  146. */
  147.  
  148. BOOL InitInstance(hInstance, nCmdShow)
  149.     HANDLE          hInstance;          /* Current instance identifier.       */
  150.     int             nCmdShow;           /* Param for first ShowWindow() call. */
  151. {
  152.     HWND            hWnd;               /* Main window handle.                */
  153.     RECT            rc;
  154.  
  155.     /* Save the instance handle in static variable, which will be used in  */
  156.     /* many subsequence calls from this application to Windows.            */
  157.     hInst = hInstance;
  158.  
  159.     /* Create a main window for this application instance.  */
  160.     
  161.     if (RestoreWindowRect(&rc))
  162.         hWnd = CreateWindow(
  163.         "AvihedWClass",                 /* See RegisterClass() call.          */
  164.         szBaseWindowTitle,              /* Text for window title bar.         */
  165.         WS_OVERLAPPEDWINDOW,
  166.         rc.left,
  167.         rc.top,
  168.         rc.right - rc.left,
  169.         rc.bottom - rc.top,
  170.         NULL,                           /* Overlapped windows have no parent. */
  171.         NULL,                           /* Use the window class menu.         */
  172.         hInstance,                      /* This instance owns this window.    */
  173.         NULL                            /* Pointer not needed.                */
  174.         );
  175.     
  176.     else    
  177.         hWnd = CreateWindow(
  178.             "AvihedWClass",                 /* See RegisterClass() call.          */
  179.             szBaseWindowTitle,              /* Text for window title bar.         */
  180.             WS_OVERLAPPEDWINDOW,
  181.             CW_USEDEFAULT,                  /* Default horizontal position.       */
  182.             CW_USEDEFAULT,                  /* Default vertical position.         */
  183.             CW_USEDEFAULT,                  /* Default width.                     */
  184.             CW_USEDEFAULT,                  /* Default height.                    */
  185.             NULL,                           /* Overlapped windows have no parent. */
  186.             NULL,                           /* Use the window class menu.         */
  187.             hInstance,                      /* This instance owns this window.    */
  188.             NULL                            /* Pointer not needed.                */
  189.             );
  190.  
  191.     /* If window could not be created, return "failure" */
  192.  
  193.     if (!hWnd)
  194.         return (FALSE);
  195.  
  196.     /* Make the window visible; update its client area; and return "success" */
  197.  
  198.     if (GetProfileInt(szBaseWindowTitle, "Maximized", 0))
  199.         ShowWindow(hWnd, SW_SHOWMAXIMIZED);
  200.     else
  201.         ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
  202.     UpdateWindow(hWnd);          /* Sends WM_PAINT message                 */
  203.     return (TRUE);               /* Returns the value from PostQuitMessage */
  204.  
  205. }
  206.  
  207. /*
  208.     MainWndProc --
  209.         processes messages.  see comments by message handlers
  210. */
  211.  
  212. long CALLBACK __export MainWndProc(hWnd, message, wParam, lParam)
  213. HWND hWnd;                      /* window handle                 */
  214. UINT message;                   /* type of message               */
  215. WPARAM wParam;                  /* additional information        */
  216. LPARAM lParam;                  /* additional information        */
  217. {
  218.     
  219.     static DLGPROC dlgproc;    
  220.     static DLGPROC dlgproc2;    
  221.     static RECT rcMain;
  222.     static RECT rcDlg;
  223.     POINT pt;
  224.     BOOL fFlag = FALSE;
  225.     int xDlg;
  226.     static POINT ptOld;
  227.     
  228.     switch (message)
  229.     {
  230.         // WM_CREATE -- makes two dialog boxes, using coordiantes from the
  231.         // app's INI file if possible, otherwise computing some, and
  232.         // uses MoveWindow to put them where they go.
  233.         case WM_CREATE:
  234.             dlgproc = (DLGPROC) MakeProcInstance(FrameDlg, hInst);
  235.             hwndDlg = CreateDialog(hInst, MAKEINTRESOURCE(FRAMEDLG), hWnd, dlgproc);
  236.             
  237.             dlgproc2 = (DLGPROC) MakeProcInstance(SelectDlg, hInst);
  238.             hwndSelectDlg = CreateDialog(hInst, MAKEINTRESOURCE(SELECTDLG), hWnd, dlgproc2);
  239.             
  240.             if (!RestoreDlgRect(&rcwndDlg))
  241.             {                
  242.                 // move the frame dlg            
  243.                 GetClientRect(hWnd, &rcMain);
  244.                 pt.x = rcMain.left;
  245.                 pt.y = rcMain.top;
  246.                 ClientToScreen(hWnd, &pt);
  247.                 rcMain.left = pt.x;
  248.                 rcMain.top = pt.y;
  249.             
  250.                 pt.x = rcMain.right;
  251.                 pt.y = rcMain.bottom;
  252.                 ClientToScreen(hWnd, &pt);
  253.                 rcMain.right = pt.x;
  254.                 rcMain.bottom = pt.y;
  255.                         
  256.                 GetWindowRect(hwndDlg, &rcDlg);                
  257.                 MoveWindow(hwndDlg, rcMain.right - (rcDlg.right - rcDlg.left),
  258.                              rcMain.top, 
  259.                              rcDlg.right - rcDlg.left,
  260.                              rcDlg.bottom - rcDlg.top, TRUE);
  261.             }
  262.             else
  263.                 MoveWindow(hwndDlg, rcwndDlg.left, rcwndDlg.top, rcwndDlg.right - rcwndDlg.left,
  264.                                          rcwndDlg.bottom - rcwndDlg.top, TRUE);
  265.  
  266.             if (!RestoreSelectDlgRect(&rcwndSelectDlg))
  267.             {
  268.                              
  269.                 xDlg = rcMain.right - (rcDlg.right - rcDlg.left);
  270.  
  271.                 // move the select dlg                             
  272.                 GetClientRect(hWnd, &rcMain);
  273.                 pt.x = rcMain.left;
  274.                 pt.y = rcMain.top;
  275.                 ClientToScreen(hWnd, &pt);
  276.                 rcMain.left = pt.x;
  277.                 rcMain.top = pt.y;
  278.             
  279.                 pt.x = rcMain.right;
  280.                 pt.y = rcMain.bottom;
  281.                 ClientToScreen(hWnd, &pt);
  282.                 rcMain.right = pt.x;
  283.                 rcMain.bottom = pt.y;
  284.                         
  285.                 GetWindowRect(hwndSelectDlg, &rcDlg);
  286.                 MoveWindow(hwndSelectDlg, xDlg - 2 - (rcDlg.right - rcDlg.left),
  287.                              rcMain.top, 
  288.                              rcDlg.right - rcDlg.left,
  289.                              rcDlg.bottom - rcDlg.top, TRUE);                                         
  290.             }
  291.             else
  292.                 MoveWindow(hwndSelectDlg, rcwndSelectDlg.left, 
  293.                                             rcwndSelectDlg.top, 
  294.                                                 rcwndSelectDlg.right - rcwndSelectDlg.left, 
  295.                                                     rcwndSelectDlg.bottom - rcwndSelectDlg.top,
  296.                                                      TRUE);
  297.             return TRUE;
  298.  
  299.         // WM_LBUTTONDOWN -- if they clicked in a hotspot, remember the
  300.         // coordinate in ptOld, otherwise set ptOld to -1's.
  301.         case WM_LBUTTONDOWN:
  302.             if (!pMovieInfo)
  303.                 break;            
  304.                 
  305.             if (2 == (OnButtonDown(pMovieInfo, message, wParam, lParam)))
  306.             {
  307.                 ptOld = MAKEPOINT(lParam);
  308.             }                                
  309.             else 
  310.                 ptOld.y = ptOld.x = -1;                                
  311.             break;            
  312.  
  313.         // WM_LBUTTONDBLCLK -- if they dbl clicked, OnButtonDblClk will
  314.         // do the work...
  315.         case WM_LBUTTONDBLCLK:
  316.             if (!pMovieInfo)
  317.                 break;            
  318.             OnButtonDblClk(pMovieInfo, message, wParam, lParam);
  319.             break;
  320.             
  321.         // WM_KEYUP --  if they hit delete, delete current ptOld's hotspot.
  322.         case WM_KEYUP:
  323.             if (!pMovieInfo)
  324.                 break;            
  325.             if (wParam == VK_DELETE)
  326.             {
  327.                 RECT rc;
  328.                 if (ptOld.x != -1 && ptOld.y != -1)
  329.                 {
  330.                     CopyRect(&rc, &HotspotFromPoint(pMovieInfo, ptOld)->rc);
  331.                     DeleteHotspot(pMovieInfo, 
  332.                             HotspotFromPoint(pMovieInfo, ptOld));                                                                                        
  333.                     ptOld.x = ptOld.y = -1;
  334.                     bModified = TRUE;
  335.                     InvalidateRect(hWnd, &rc, TRUE);
  336.                     UpdateWindow(hWnd);                    
  337.                     ShowSelectInfo((RECT FAR *)NULL);
  338.                 }
  339.             }
  340.             break;
  341.  
  342.         // WM_SIZE -- if they minimize, remember our coordinates in
  343.         // rcMain, rcwndDlg and rcwndSelectDlg
  344.         case WM_SIZE:            
  345.             if (wParam != SIZE_MINIMIZED)
  346.             {                                    
  347.                 GetWindowRect(hWnd, &rcMain);
  348.                 if (hwndDlg)
  349.                     GetWindowRect(hwndDlg, &rcwndDlg);
  350.                 if (hwndSelectDlg)                    
  351.                     GetWindowRect(hwndSelectDlg, &rcwndSelectDlg);
  352.             }                            
  353.             return 0L;
  354.  
  355.         // WM_PAINT -- use MCI_UPDATE to refresh the AVI window, then
  356.         // call DrawRects to draw the hotspots on the picture.
  357.         case WM_PAINT:
  358.             {
  359.             HDC hDC;
  360.             PAINTSTRUCT ps;
  361.             MCI_DGV_UPDATE_PARMS mciUpdate;
  362.             
  363.             hDC = BeginPaint(hWnd, &ps);
  364.             if (pMovieInfo)
  365.             {
  366.                 mciUpdate.hDC = hDC;
  367.                 mciUpdate.rc = ps.rcPaint;
  368.                 mciUpdate.wReserved0 = 0;
  369.                 mciUpdate.dwCallback = NULL;
  370.                 mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_UPDATE, 
  371.                             MCI_WAIT | MCI_DGV_RECT | MCI_DGV_UPDATE_PAINT | MCI_DGV_UPDATE_HDC,
  372.                             (DWORD)(LPMCI_DGV_UPDATE_PARMS)&mciUpdate);
  373.                                             
  374.                 if (pMovieInfo->pHotspotList && pMovieInfo->hwndMovie
  375.                                 && !pMovieInfo->fPlaying)
  376.                     DrawRects(hDC, pMovieInfo);            
  377.             }
  378.             EndPaint(hWnd, &ps);                            
  379.             }
  380.             return TRUE;
  381.                             
  382.         // WM_MOVE -- If not minimized, remember where we got moved to,
  383.         case WM_MOVE:                        
  384.             if (!IsIconic(hWnd))
  385.                 {                                    
  386.                 GetWindowRect(hWnd, &rcMain);
  387.                 if (hwndDlg)
  388.                     GetWindowRect(hwndDlg, &rcwndDlg);
  389.                 if (hwndSelectDlg)                    
  390.                     GetWindowRect(hwndSelectDlg, &rcwndSelectDlg);                                    
  391.                 }            
  392.             return 0L;
  393.             
  394.         // check/uncheck menu items depending on state  of related flags
  395.         case WM_INITMENU:
  396.             CheckMenuItem(wParam, IDM_SHOWFRAMEHOTSPOTS,
  397.                 (bShowValidRectsOnly ? MF_CHECKED : MF_UNCHECKED));
  398.  
  399.             if (pMovieInfo)
  400.                 {
  401.                 EnableMenuItem(wParam, IDM_PRINT,
  402.                     pMovieInfo->pHotspotList ? MF_ENABLED : MF_GRAYED);
  403.                 EnableMenuItem(wParam, IDM_SAVE,
  404.                     (pMovieInfo->pHotspotList && bModified) ? MF_ENABLED : MF_GRAYED);
  405.                 EnableMenuItem(wParam, IDM_SAVEAS,
  406.                     pMovieInfo->pHotspotList ? MF_ENABLED : MF_GRAYED);
  407.                 EnableMenuItem(wParam, IDM_DELETE,
  408.                     pMovieInfo->pHotspotList ? MF_ENABLED : MF_GRAYED);                    
  409.                 }
  410.             else
  411.                 {
  412.                 EnableMenuItem(wParam, IDM_PRINT, MF_GRAYED);
  413.                 EnableMenuItem(wParam, IDM_SAVE, MF_GRAYED);
  414.                 EnableMenuItem(wParam, IDM_SAVEAS, MF_GRAYED);
  415.                 EnableMenuItem(wParam, IDM_DELETE, MF_GRAYED);                
  416.                 }
  417.             break;
  418.  
  419.         case WM_COMMAND:       /* message: command from application menu */
  420.             switch (wParam)
  421.                 {
  422.                 case IDM_ABOUT:
  423.                     DialogBox(hInst,        /* current instance          */
  424.                         "AboutBox",         /* resource to use           */
  425.                         hWnd,               /* parent handle             */
  426.                         About);             /* About() instance address  */                
  427.                     break;
  428.                         
  429.                 case IDM_OPEN:
  430.                     FileOpen(hWnd);
  431.                     break;
  432.                     
  433.                 case IDM_SAVEAS:
  434.                     fFlag = TRUE;
  435.                 case IDM_SAVE:
  436.                     if (pMovieInfo)
  437.                         {
  438.                         if (pMovieInfo->pHotspotList)
  439.                             FileSave(hWnd, fFlag);
  440.                         }
  441.                     break;
  442.                     
  443.                 case IDM_EXIT:                    
  444.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  445.                     break;
  446.                     
  447.                 case IDM_SHOWFRAMEHOTSPOTS:
  448.                     bShowValidRectsOnly ^= 1;
  449.                     if (pMovieInfo)
  450.                         {
  451.                         if (pMovieInfo->hwndMovie)
  452.                             {
  453.                             InvalidateRect(pMovieInfo->hwndMovie, NULL, TRUE);
  454.                             UpdateWindow(pMovieInfo->hwndMovie);
  455.                             }
  456.                         }
  457.                     break;
  458.                     
  459.                 case IDM_REDRAW:
  460.                     if (pMovieInfo)
  461.                         {
  462.                         if (pMovieInfo->hwndMovie)
  463.                             {
  464.                             InvalidateRect(hWnd, NULL, TRUE);
  465.                             UpdateWindow(hWnd);
  466.                             }
  467.                         }                    
  468.                     break;                    
  469.                     
  470.                 case IDM_DELETE:
  471.                     if (pMovieInfo)
  472.                         {
  473.                         if (pMovieInfo->hwndMovie)
  474.                             {
  475.                             PostMessage(pMovieInfo->hwndMovie, WM_KEYUP, VK_DELETE, 0L);
  476.                             }
  477.                         }
  478.                     break;                    
  479.                     
  480.                 default:
  481.                     return (DefWindowProc(hWnd, message, wParam, lParam));                
  482.                 }
  483.             break;            
  484.  
  485.         // WM_CLOSE -- prompt user to save if necessary.            
  486.         case WM_CLOSE:
  487.             if (bModified)
  488.                 {
  489.                 int fSave = IDNO;
  490.                 fSave = MessageBox(hWnd, "Save Changes?",                                    
  491.                                    szBaseWindowTitle, MB_YESNOCANCEL | MB_ICONQUESTION);
  492.                 if (fSave == IDCANCEL)
  493.                     return 0L;
  494.                 if (fSave == IDYES)
  495.                     {
  496.                     if (pMovieInfo)
  497.                         {
  498.                         if (pMovieInfo->pHotspotList)
  499.                             FileSave(hWnd, FALSE);
  500.                         }                
  501.                     }
  502.                 if (fSave == IDNO)
  503.                     ;                                                               
  504.                 }
  505.             DestroyWindow(hWnd);        
  506.             return 0L;            
  507.             
  508.         case MM_MCINOTIFY:
  509.              /* This is where we check the status of an AVI  */
  510.             /* movie that might have been playing.  We do   */
  511.             /* the play with MCI_NOTIFY on so we should get */
  512.             /* a MCI_NOTIFY_SUCCESSFUL if the play      */
  513.             /* completes on it's own.           */
  514.             switch(wParam){         
  515.                 case MCI_NOTIFY_FAILURE:
  516.                 case MCI_NOTIFY_ABORTED:
  517.                 case MCI_NOTIFY_SUPERSEDED:
  518.                 case MCI_NOTIFY_SUCCESSFUL:
  519.                     {
  520.                     char szBuf[129];
  521.                     
  522.                     pMovieInfo->fPlaying = FALSE;
  523.                     pMovieInfo->dwCurrentFrame = GetMovieFrame(pMovieInfo);
  524.                     wsprintf(szBuf, "%ld of %ld", pMovieInfo->dwCurrentFrame,
  525.                                                       pMovieInfo->dwMovieLength);
  526.                     SetDlgItemText(hwndDlg, ID_CURRENTFRAME, szBuf);                        
  527.                     SetDlgItemText(hwndDlg, ID_PLAY, "Play");
  528.                     EnableWindow(GetDlgItem(hwndDlg, ID_FORWARD), TRUE);
  529.                     EnableWindow(GetDlgItem(hwndDlg, ID_REVERSE), TRUE);                    
  530.                     InvalidateRect(hWnd, NULL, FALSE);
  531.                     UpdateWindow(hWnd);
  532.                     }
  533.                     return 0;
  534.             }
  535.             break;
  536.  
  537.         // we're going to die!
  538.         case WM_DESTROY:          /* message: window being destroyed */            
  539.             SaveWindowRect(hWnd, rcMain);            
  540.             DestroyWindow(hwndDlg);             // get rid of modeless dialog
  541.             FreeProcInstance(dlgproc);
  542.             DestroyWindow(hwndSelectDlg);             // get rid of modeless dialog
  543.             FreeProcInstance(dlgproc2);
  544.             if (pMovieInfo)
  545.                 {
  546.                 fileCloseMovie(pMovieInfo, FALSE);
  547.                 DeleteHotspotList(pMovieInfo);            
  548.                 FREE(pMovieInfo);
  549.                 }
  550.             termAVI();            
  551.             PostQuitMessage(0);
  552.             break;
  553.  
  554.         default:                  /* Passes it on if unproccessed    */
  555.             return (DefWindowProc(hWnd, message, wParam, lParam));
  556.     }
  557.     return (NULL);
  558. }
  559.  
  560.  
  561. /*
  562.  
  563.     SaveWindowRect -- Write specified rect to win.ini.  Uses hWnd
  564.         to determine minimize/maximize status of window, and saves
  565.         that as well
  566. */
  567.  
  568. void SaveWindowRect(HWND hWnd, RECT rc)
  569. {
  570.     char szBuf[129];
  571.     
  572.     if (rc.left < 0)
  573.         rc.left = 0;
  574.     if (rc.top < 0)
  575.         rc.top = 0;            
  576.     wsprintf(szBuf, "%d,%d,%d,%d", rc.left, rc.top, rc.right, rc.bottom);    
  577.     WriteProfileString(szBaseWindowTitle, "Window", szBuf);
  578.     
  579.     if (IsZoomed(hWnd))
  580.         WriteProfileString(szBaseWindowTitle, "Maximized", "1");
  581.     else
  582.         WriteProfileString(szBaseWindowTitle, "Maximized", "0");        
  583.  
  584.     wsprintf(szBuf, "%d,%d,%d,%d", rcwndDlg.left, rcwndDlg.top, rcwndDlg.right, rcwndDlg.bottom);    
  585.     WriteProfileString(szBaseWindowTitle, "wndDlg", szBuf);
  586.     
  587.     wsprintf(szBuf, "%d,%d,%d,%d", rcwndSelectDlg.left, rcwndSelectDlg.top, 
  588.                                     rcwndSelectDlg.right, rcwndSelectDlg.bottom);
  589.     WriteProfileString(szBaseWindowTitle, "wndSelectDlg", szBuf);
  590.  
  591.     wsprintf(szBuf, "%d", PixelVary);    
  592.     WriteProfileString(szBaseWindowTitle, "PixelVary", szBuf);
  593.     
  594. }
  595.  
  596. /*
  597.     RestoreWindowRect -- Retreives main window position from win.ini
  598.         (note this doesn't actually change the window position)
  599. */
  600. BOOL RestoreWindowRect(RECT FAR *pRect)
  601. {
  602.     char szBuf[129];
  603.     LPSTR token;
  604.  
  605.     if (!pRect)
  606.         return FALSE;
  607.  
  608.     if (GetProfileString(szBaseWindowTitle, "Window", "", szBuf, 128))
  609.         {
  610.         token = FindToken(szBuf, ',');        
  611.         pRect->left = StrToInt(token);
  612.         
  613.         token = FindToken(NULL, ',');        
  614.         pRect->top = StrToInt(token);
  615.         
  616.         token = FindToken(NULL, ',');        
  617.         pRect->right = StrToInt(token);
  618.         
  619.         token = FindToken(NULL, ',');        
  620.         pRect->bottom = StrToInt(token);            
  621.         return TRUE;
  622.         }
  623.     else
  624.         return FALSE;
  625. }        
  626.  
  627.  
  628. BOOL RestoreDlgRect(RECT FAR *pRect)
  629. {
  630.     char szBuf[129];
  631.     LPSTR token;
  632.  
  633.     if (!pRect)
  634.         return FALSE;
  635.  
  636.     if (GetProfileString(szBaseWindowTitle, "wndDlg", "", szBuf, 128))
  637.         {
  638.         token = FindToken(szBuf, ',');        
  639.         pRect->left = StrToInt(token);
  640.         
  641.         token = FindToken(NULL, ',');        
  642.         pRect->top = StrToInt(token);
  643.         
  644.         token = FindToken(NULL, ',');        
  645.         pRect->right = StrToInt(token);
  646.         
  647.         token = FindToken(NULL, ',');        
  648.         pRect->bottom = StrToInt(token);            
  649.         return TRUE;
  650.         }
  651.     else
  652.         return FALSE;
  653.  
  654. }
  655.  
  656.         
  657. // Same as RestoreRect, basically...
  658. BOOL RestoreSelectDlgRect(RECT FAR *pRect)
  659. {
  660.     char szBuf[129];
  661.     LPSTR token;
  662.  
  663.     if (!pRect)
  664.         return FALSE;
  665.  
  666.     if (GetProfileString(szBaseWindowTitle, "wndSelectDlg", "", szBuf, 128))
  667.         {
  668.         token = FindToken(szBuf, ',');        
  669.         pRect->left = StrToInt(token);
  670.         
  671.         token = FindToken(NULL, ',');        
  672.         pRect->top = StrToInt(token);
  673.         
  674.         token = FindToken(NULL, ',');        
  675.         pRect->right = StrToInt(token);
  676.         
  677.         token = FindToken(NULL, ',');        
  678.         pRect->bottom = StrToInt(token);            
  679.         return TRUE;
  680.         }
  681.     else
  682.         return FALSE;
  683. }
  684.         
  685.  
  686.  
  687.