home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / ultieyes / ultieyes.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  54KB  |  1,172 lines

  1. /*------------------------------------------------------------------------
  2.  
  3.    SOURCE FILE NAME:  ultieyes.c
  4.  
  5.                    Copyright (c) IBM Corporation 1981, 1993
  6.                              All Rights Reserved
  7.  
  8. --------------------------------------------------------------------------*/
  9.  
  10. #define INCL_DOS
  11. #define INCL_WINSHELLDATA
  12. #define INCL_WIN
  13. #define INCL_GPI
  14. #define INCL_OS2MM                 /* required for MCI and MMIO headers   */
  15. #define INCL_32
  16. #include <os2.h>
  17. #include <os2me.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <malloc.h>
  22. #include <math.h>
  23. #include <dive.h>
  24. #include <fourcc.h>
  25. #include "ultieyes.h"
  26.  
  27. /***********************/
  28. /*  Global Variables   */
  29. /***********************/
  30. POINTL    ptlOldMousePos;               /* save previous mouse position      */
  31. BOOL      fRandomUp = TRUE;             /* random mode: moving up            */
  32. BOOL      fRandomRight = TRUE;          /* random mode: moving right         */
  33. ULONG     ulVideoX = 320;               /* width of video                    */
  34. ULONG     ulVideoY = 240;               /* height of video                   */
  35. UCHAR     szEyeFile[CCHMAXPATH];        /* file with frame table values      */
  36. PSZ       pszMovieFile;                 /* movie file name                   */
  37. ULONG     ulFrameNums[NUMFRAMENUMS];    /* frame table                       */
  38. ULONG     ulCurrentFrame = 0;           /* save last frame displayed         */
  39. double    EyeRatio = 0.125;             /* ratio of eye-nose to video width  */
  40. CHAR      szReturn[CCHMAXPATH];         /* return value from mciSendString   */
  41. HSWITCH   hSwitch;                      /* task list switch entry handle     */
  42. SWCNTRL   switch_control;               /* for task switch entry             */
  43. HWND      hwndFrame;                    /* regular standard frame            */
  44. HWND      hwndNoFrame;                  /* frame-less frame                  */
  45. HWND      hwndClient;                   /* client of hwndFrame               */
  46. HWND      hwndNoFrameClient;            /* client of hwndNoFrame             */
  47. BOOL      fNoFrame;                     /* which frame is visible?           */
  48. BOOL      fRandom = FALSE;              /* random winks/blinks?              */
  49. HPOINTER  vhCurrentPtr;                 /* save current mouse pointer        */
  50. HINI      vhini = 0 ;                   /* profile handle                    */
  51. HWND      hwndSysSubMenu;               /* frame system submenu              */
  52.  
  53. BOOL      fDebug = FALSE;               /* TRUE => display frame num in title*/
  54.  
  55. /************************************************************************/
  56. /*  Name         :  Main                                                */
  57. /*                                                                      */
  58. /*  Description  :  Ultieyes main entry point.                          */
  59. /*                                                                      */
  60. /*  Logic        :  Initialize PM.                                      */
  61. /*                  If frame table file name passed on command line,    */
  62. /*                    open frame table file,                            */
  63. /*                  else open default frame table file.                 */
  64. /*                  Parse frame table file.                             */
  65. /*                  Create two frame windows, one with no border or     */
  66. /*                    title bar.                                        */
  67. /*                  Add a switch entry for the process.                 */
  68. /*                  Open the digitalvideo device.                       */
  69. /*                  Load the .AVI file.                                 */
  70. /*                  Start a timer for the client window.                */
  71. /*                  Service the message queue.                          */
  72. /*                  Destroy windows and terminate.                      */
  73. /*                                                                      */
  74. /*  Parameters   :  argc        - Command line parm count               */
  75. /*                  argv        - Command line parms.  One optional     */
  76. /*                                parameter is the frame table          */
  77. /*                                file name.                            */
  78. /*                                                                      */
  79. /*  Return       :  N/A                                                 */
  80. /************************************************************************/
  81. main( int argc, char * argv[] )
  82.   {
  83.   HMQ       hmq;                        /* message queue handle              */
  84.   HAB       hab;                        /* PM anchor block handle            */
  85.   QMSG      qmsg;                       /* for message queue loop            */
  86.   ULONG     rc;                         /* return code                       */
  87.   ULONG     fSuccess;                   /* return bool                       */
  88.   LONG      cyTitleBar;                 /* title bar height                  */
  89.   ULONG     flCreate = FCF_TITLEBAR |   /* frame creation flags              */
  90.                        FCF_SYSMENU  |
  91.                        FCF_BORDER   |
  92.                        FCF_ICON     |
  93.                        FCF_NOBYTEALIGN;
  94.   ULONG     flNoFrameCreate = FCF_NOBYTEALIGN; /* flag for frameless frame   */
  95.   HFILE     FileHandle;                 /* for frame table file              */
  96.   ULONG     Action;                     /* needed for DosOpen                */
  97.   UCHAR     szMsgBuf[CCHMAXPATH];       /* for error messages                */
  98.   SWP       swp;                        /* for recommended position          */
  99.   LONG      cxWidthBorder;              /* system border width               */
  100.   LONG      cyWidthBorder;              /* system border width               */
  101.   ULONG     uSize;                      /* profile size                      */
  102.   POINTL    ptlSave;                    /* position in profile               */
  103.  
  104.  
  105.  
  106.   /***************************************************************/
  107.   /*  Initialize PM and create a message queue.                  */
  108.   /***************************************************************/
  109.   hab = WinInitialize( 0 );
  110.   hmq = WinCreateMsgQueue( hab, 0 );
  111.  
  112.  
  113.   /******************************************************************/
  114.   /*  Query Video System capabilities to determine direct mode.     */
  115.   /*  On VGA and other subsystems (8514) direct mode is unsupported */
  116.   /*  ultieyes will not run on such systems.                        */
  117.   /******************************************************************/
  118.  
  119.   if (!QueryDirectMode())
  120.     {
  121.        WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  122.                       (PSZ)"Direct software motion video mode is not supported on this system.",
  123.                       (PSZ)"Ultieyes - Direct Mode Support Detection",
  124.                       0,
  125.                       MB_ERROR | MB_OK );
  126.        DosExit( EXIT_PROCESS, 0 );
  127.     }
  128.  
  129.   /***************************************************************/
  130.   /*  Open frame table file.                                     */
  131.   /***************************************************************/
  132.   strcpy( (PCHAR)szEyeFile, DEFAULT_EYE);
  133.   if (argv[1])
  134.     if (argv[1][0])
  135.       strcpy( (PCHAR)szEyeFile, argv[1]);
  136.   if ( DosOpen((PCHAR)szEyeFile,               /* File path name */
  137.                &FileHandle,             /* File handle */
  138.                &Action,                 /* Action taken */
  139.                0,
  140.                0,                       /* no attributes                     */
  141.                OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  142.                OPEN_SHARE_DENYNONE,
  143.                0))                      /* Reserved (must be zero) */
  144.     {
  145.     strcpy( (PCHAR)szMsgBuf, "Cannot open control file: ");
  146.     strcat( (PCHAR)szMsgBuf, (PCHAR)szEyeFile);
  147.     WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  148.                    (PSZ)szMsgBuf, (PSZ)"UltiEyes - Error Opening Control File", 0,
  149.                    MB_ERROR | MB_OK );
  150.     DosExit( EXIT_PROCESS, 0 );
  151.     }
  152.  
  153.   /***************************************************************/
  154.   /*  Parse out movie file name and frame numbers.               */
  155.   /***************************************************************/
  156.   ParseControlFile( FileHandle, (ULONG *) &ulFrameNums);
  157.  
  158.   /***************************************************************/
  159.   /*  Register class and create two standard windows.            */
  160.   /*  fNoFrame is used during window initialization, and must be */
  161.   /*  TRUE for the "frameless" frame and false for the regular   */
  162.   /*  frame.                                                     */
  163.   /***************************************************************/
  164.   fSuccess = WinRegisterClass( hab, (PSZ)"Client",
  165.                                (PFNWP)MainClientWindowProc,
  166.                                CS_SIZEREDRAW | CS_MOVENOTIFY |
  167.                                CS_CLIPCHILDREN, 4);
  168.   fNoFrame = TRUE;                      /* Initialize frameless first        */
  169.   hwndNoFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
  170.                                     &flNoFrameCreate,
  171.                                     (PSZ)"Client", (PSZ)"UltiEyes",
  172.                                     0, 0, 0, &hwndNoFrameClient);
  173.   fNoFrame = FALSE;                     /* Now initialize framed window      */
  174.   hwndFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &flCreate,
  175.                                   (PSZ)"Client", (PSZ)"UltiEyes",
  176.                                   0, 0, ID_ICON, &hwndClient);
  177.   WinGetLastError( hab );
  178.  
  179.   /***************************************************************/
  180.   /*  Add a switch list entry.                                   */
  181.   /***************************************************************/
  182.   switch_control.hwnd = hwndFrame;
  183.   switch_control.hwndIcon = 0;
  184.   switch_control.hprog = 0;
  185.   switch_control.idProcess = 0;
  186.   switch_control.idSession = 0;
  187.   switch_control.uchVisibility = SWL_VISIBLE;
  188.   switch_control.fbJump = SWL_JUMPABLE;
  189.   strcpy( switch_control.szSwtitle, "UltiEyes - ");
  190.   strcat( switch_control.szSwtitle, (PCHAR)szEyeFile);
  191.   hSwitch = WinAddSwitchEntry( &switch_control);
  192.   WinGetLastError( hab );
  193.   WinSetWindowText( hwndFrame, (PCHAR)szEyeFile);
  194.  
  195.   /***************************************************************/
  196.   /*  Open the software motion video device.  If opened          */
  197.   /*  successfully, set the time format to frames and load       */
  198.   /*  the movie file.  If loaded okay, start the timer.          */
  199.   /***************************************************************/
  200.   if (!OpenTheDevice( hwndClient))
  201.     rc = WinPostMsg( hwndClient, WM_CLOSE, 0, 0);
  202.   else
  203.     {
  204.     fSuccess = SendString(hwndClient, (PCHAR)"acquire movie wait", 0);
  205.     fSuccess = SendString(hwndClient, (PCHAR)"set movie time format frames wait", 0);
  206.     if (!LoadTheFile(hwndClient))
  207.       rc = WinPostMsg( hwndClient, WM_CLOSE, 0, 0);
  208.     else
  209.       rc = WinStartTimer( hab, hwndClient, 1, 10);
  210.     fSuccess = SendString(hwndClient, (PCHAR)"release movie wait", 0);
  211.     }                               /* end: opened device okay           */
  212.  
  213.   /***************************************************************/
  214.   /*  Query title bar height.  Get the recommended position      */
  215.   /*  from the system.  Get the size from the movie size plus    */
  216.   /*  the title bar height.                                      */
  217.   /***************************************************************/
  218.   cyTitleBar = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  219.   cxWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
  220.   cyWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
  221.   vhini = PrfOpenProfile (hab, (PSZ)"ultieyes.ini");
  222.   if (!vhini) vhini = HINI_USER;
  223.   if ( PrfQueryProfileSize (vhini, (PSZ)szEyeFile, (PSZ)szMinor, &uSize) &&       /*::*/
  224.        uSize == sizeof(POINTL) &&
  225.        PrfQueryProfileData (vhini, (PSZ)szEyeFile, (PSZ)szMinor,
  226.                             (PVOID) &ptlSave, (PULONG) &uSize) )
  227.     {
  228.     swp.x = ptlSave.x;
  229.     swp.y = ptlSave.y;
  230.     }
  231.   else
  232.     {
  233.     WinQueryTaskSizePos( hab, 0, &swp);
  234.     }
  235.   fSuccess = WinSetWindowPos(hwndFrame, HWND_TOP,
  236.       swp.x,
  237.       swp.y,
  238.       ulVideoX + (2 * cxWidthBorder),
  239.       ulVideoY + cyTitleBar + (2 * cyWidthBorder),
  240.       SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_ACTIVATE);
  241.  
  242.   /***************************************************************/
  243.   /*  Service the message queue.                                 */
  244.   /***************************************************************/
  245.   while( WinGetMsg( hab, &qmsg, 0, 0, 0 ) )
  246.          WinDispatchMsg( hab, &qmsg );
  247.  
  248.   /***************************************************************/
  249.   /*  Destroy windows and terminate PM.                          */
  250.   /***************************************************************/
  251.   if (vhini != HINI_USER) PrfCloseProfile (vhini);
  252.   WinDestroyWindow( hwndFrame);
  253.   WinDestroyWindow( hwndNoFrame);
  254.   WinDestroyMsgQueue( hmq );
  255.   WinTerminate( hab );
  256.   DosExit( EXIT_PROCESS, 0 );
  257.   return( 0 );
  258.   } /* End main() */
  259.  
  260.  
  261. /*****************************************************************/
  262. /*  Name         :  Main                                         */
  263. /*                                                               */
  264. /*  Description  :  Ultieyes main entry point.                   */
  265. /*                                                               */
  266. /*  Logic        :  Switch on message:                           */
  267. /*                    if create:                                 */
  268. /*                      insert separator and NOFRAME into        */
  269. /*                        system menu                            */
  270. /*                    if button 1 click:                         */
  271. /*                      if in left 3/8 of window                 */
  272. /*                        play wink on left side                 */
  273. /*                      else if in right 3/8 of window           */
  274. /*                        play wink on right side                */
  275. /*                      else                                     */
  276. /*                        play blink                             */
  277. /*                    if button 1 doubleclick:                   */
  278. /*                      send NOFRAME command                     */
  279. /*                    if close:                                  */
  280. /*                      close digitalvideo device                */
  281. /*                      post QUIT to message queue               */
  282. /*                    if command NOFRAME:                        */
  283. /*                      if currently showing frame               */
  284. /*                        get current position                   */
  285. /*                        map to desktop                         */
  286. /*                        move frameless frame to same pos       */
  287. /*                        hide frame                             */
  288. /*                        show frameless frame                   */
  289. /*                        start timer for frameless client       */
  290. /*                        send window handle to MCI for          */
  291. /*                          frameless client                     */
  292. /*                        stop timer for frame client            */
  293. /*                      else                                     */
  294. /*                        hide frameless frame                   */
  295. /*                        show frame                             */
  296. /*                        start timer for frame client           */
  297. /*                        send window handle to MCI for          */
  298. /*                          frame client                         */
  299. /*                        stop timer for frameless client        */
  300. /*                    if timer:                                  */
  301. /*                      get mouse position                       */
  302. /*                      if changed since saved pos               */
  303. /*                        save current pos                       */
  304. /*                        map mouse pos to center of video       */
  305. /*                        if in center of video                  */
  306. /*                          select cross-eyed frame              */
  307. /*                        else                                   */
  308. /*                          calculate frame from angle           */
  309. /*                        if calc'd frame has changed            */
  310. /*                          if not doing next sequential frame   */
  311. /*                            seek to calc'd frame               */
  312. /*                          step movie by 1                      */
  313. /*                          if fDebug                            */
  314. /*                            display frame num in titlebar      */
  315. /*                    call default window proc                   */
  316. /*                                                               */
  317. /*  Parameters   :  hwnd        - window handle                  */
  318. /*                  msg         - PM message                     */
  319. /*                  mp1         - parm 1                         */
  320. /*                  mp2         - parm2                          */
  321. /*                                                               */
  322. /*  Return       :  value returned by default window proc        */
  323. /*****************************************************************/
  324.  
  325. MRESULT EXPENTRY MainClientWindowProc( HWND hwnd, ULONG msg,
  326.                                        MPARAM mp1, MPARAM mp2 )
  327.   {
  328.   MRESULT       mr = FALSE;
  329.   ULONG         rc;                     /* return codes                      */
  330.   BOOL          fSuccess;               /* return codes                      */
  331.   POINTL        ptlMouse;               /* mouse pointer position            */
  332.   HWND          hwndTitle;              /* handle of title bar window        */
  333.   UCHAR         szBuf[40];              /* for debug string                  */
  334.   double        Angle;                  /* angle of mouse to center of video */
  335.   ULONG         ulFrame;                /* calculated frame number           */
  336.   CHAR          szSeekString[CCHMAXPATH]; /* for building seek command       */
  337.   CHAR          szSeekPos[10] = "";     /* frame to seek to                  */
  338.   CHAR          szPlayString[CCHMAXPATH]; /* for building play command       */
  339.   CHAR          szFromPos[10] = "";     /* frame to play frome               */
  340.   CHAR          szToPos[10] = "";       /* frame to play to                  */
  341.   SWP           swp;                    /* window position                   */
  342.   HWND          hwndSysMenuMain;        /* frame menu                        */
  343.   USHORT        idSysMenu;              /* menu item id                      */
  344.   MENUITEM      MenuItem;               /* system submenu item               */
  345.   POINTL        ptl;                    /* for coordinate mapping            */
  346.   ULONG         ulRandom;               /* random number                     */
  347.  
  348.   switch( msg )
  349.     {
  350.     case WM_CREATE:
  351.       if (!fNoFrame)
  352.         {
  353.         /*********************************************************/
  354.         /*  If this is the client with a visible frame, get      */
  355.         /*  the system menu and insert a separator and the       */
  356.         /*  No Frame selection.                                  */
  357.         /*********************************************************/
  358.         hwndFrame = WinQueryWindow( hwnd, QW_PARENT);
  359.         hwndSysMenuMain = WinWindowFromID (hwndFrame, FID_SYSMENU);
  360.         idSysMenu = SHORT1FROMMR (WinSendMsg (hwndSysMenuMain,
  361.                                   MM_ITEMIDFROMPOSITION, 0L, 0L));
  362.         WinSendMsg (hwndSysMenuMain, MM_QUERYITEM,
  363.                     MPFROM2SHORT (idSysMenu, FALSE), MPFROMP(&MenuItem));
  364.         hwndSysSubMenu = MenuItem.hwndSubMenu;
  365.         MenuItem.iPosition   = MIT_END;
  366.         MenuItem.afStyle     = MIS_SEPARATOR;
  367.         MenuItem.afAttribute = (ULONG)NULL;
  368.         MenuItem.hwndSubMenu = (HWND)NULL;
  369.         MenuItem.hItem       = (ULONG)NULL;
  370.         MenuItem.id          = 0;
  371.         WinSendMsg (hwndSysSubMenu,
  372.                     MM_INSERTITEM,
  373.                     (MPARAM)&MenuItem,
  374.                     (MPARAM)"");
  375.         WinGetLastError( WinQueryAnchorBlock( hwnd));
  376.         MenuItem.iPosition   = MIT_END;
  377.         MenuItem.afStyle     = MIS_TEXT;
  378.         MenuItem.afAttribute = (ULONG)NULL;
  379.         MenuItem.hwndSubMenu = (HWND)NULL;
  380.         MenuItem.hItem       = (ULONG)NULL;
  381.         MenuItem.id          = (ULONG)IDM_NOFRAME;
  382.         WinSendMsg (hwndSysSubMenu,
  383.                     MM_INSERTITEM,
  384.                     (MPARAM)&MenuItem,
  385.                     (MPARAM)"No ~Frame");
  386.         WinGetLastError( WinQueryAnchorBlock( hwnd));
  387.         MenuItem.iPosition   = MIT_END;
  388.         MenuItem.afStyle     = MIS_TEXT;
  389.         MenuItem.afAttribute = (ULONG)NULL;
  390.         MenuItem.hwndSubMenu = (HWND)NULL;
  391.         MenuItem.hItem       = (ULONG)NULL;
  392.         MenuItem.id          = (ULONG)IDM_RANDOM;
  393.         WinSendMsg (hwndSysSubMenu,
  394.                     MM_INSERTITEM,
  395.                     (MPARAM)&MenuItem,
  396.                     (MPARAM)"R~andom");
  397.         WinGetLastError( WinQueryAnchorBlock( hwnd));
  398.         /***********************************************************/
  399.         /*  Blow away saved mouse position and frame number to     */
  400.         /*  force seek/step of appropriate frame after playing     */
  401.         /*  wink or blink.                                         */
  402.         /***********************************************************/
  403.         ptlOldMousePos.x = ptlOldMousePos.y = -1;
  404.         ulCurrentFrame = 99999;
  405.         }
  406.       break;
  407.  
  408.     case WM_BUTTON1CLICK:
  409.       /***********************************************************/
  410.       /*  Play a wink or a blink.                                */
  411.       /***********************************************************/
  412.       ptl.x = SHORT1FROMMP(mp1);
  413.       ptl.y = SHORT2FROMMP(mp1);
  414.       fSuccess = WinQueryWindowPos( hwnd, &swp);
  415.       if (ptl.x <= swp.cx * 3 / 8)
  416.         {
  417.         _ultoa( ulFrameNums[NUMFRAMENUMS-6], szFromPos, 10);
  418.         _ultoa( ulFrameNums[NUMFRAMENUMS-5], szToPos, 10);
  419.         }
  420.       else if (ptl.x >= swp.cx * 5 / 8)
  421.         {
  422.         _ultoa( ulFrameNums[NUMFRAMENUMS-4], szFromPos, 10);
  423.         _ultoa( ulFrameNums[NUMFRAMENUMS-3], szToPos, 10);
  424.         }
  425.       else
  426.         {
  427.         _ultoa( ulFrameNums[NUMFRAMENUMS-2], szFromPos, 10);
  428.         _ultoa( ulFrameNums[NUMFRAMENUMS-1], szToPos, 10);
  429.         }
  430.       strcpy( szPlayString, "play movie from ");
  431.       strcat( szPlayString, szFromPos);
  432.       strcat( szPlayString, " to ");
  433.       strcat( szPlayString, szToPos);
  434.       strcat( szPlayString, " wait");
  435.       fSuccess = SendString(hwnd, (PCHAR)"acquire movie wait", 0);
  436.       fSuccess = SendString(hwnd, szPlayString, 0);
  437.       fSuccess = SendString(hwnd, (PCHAR)"release movie wait", 0);
  438.  
  439.       if (!fRandom)
  440.         {
  441.         /***********************************************************/
  442.         /*  Blow away saved mouse position and frame number to     */
  443.         /*  force seek/step of appropriate frame after playing     */
  444.         /*  wink or blink.                                         */
  445.         /***********************************************************/
  446.         ptlOldMousePos.x = ptlOldMousePos.y = -1;
  447.         ulCurrentFrame = 99999;
  448.         }
  449.       break;
  450.  
  451.     case WM_BUTTON1DBLCLK:
  452.       /***********************************************************/
  453.       /*  Same as if No Frame selected from system menu.         */
  454.       /***********************************************************/
  455.       WinSendMsg( hwnd, WM_COMMAND, (MPARAM)IDM_NOFRAME, 0);
  456.       break;
  457.  
  458.     case WM_ADJUSTWINDOWPOS:
  459.       /***********************************************************/
  460.       /*  If no frame, keep window on bottom.                    */
  461.       /***********************************************************/
  462.       if (fNoFrame)
  463.         {
  464.         ((PSWP) mp1)->fl |= SWP_ZORDER;
  465.         ((PSWP) mp1)->hwndInsertBehind = HWND_BOTTOM;
  466.         }
  467.       break;
  468.  
  469.     case WM_FOCUSCHANGE:
  470.       /***********************************************************/
  471.       /*  If hwndFrame is gaining focus, put it on top.          */
  472.       /*  If hwndNoFrame is gaining focus, put it on bottom.     */
  473.       /***********************************************************/
  474.       if (SHORT1FROMMP(mp2))            /* if receiving focus                */
  475.         {
  476.         if (!fNoFrame)
  477.           fSuccess = WinSetWindowPos(hwndFrame, HWND_TOP,
  478.                                      0, 0, 0, 0, SWP_ZORDER);
  479.         else
  480.           fSuccess = WinSetWindowPos(hwndNoFrame, HWND_BOTTOM,
  481.                                      0, 0, 0, 0, SWP_ZORDER);
  482.         }
  483.       break;
  484.  
  485.     case WM_CLOSE:
  486.       /***********************************************************/
  487.       /*  Close digitalvideo device and post a quit.             */
  488.       /***********************************************************/
  489.       CloseTheDevice();
  490.       fSuccess = WinQueryWindowPos( hwndFrame, &swp);
  491.       ptl.x = swp.x;
  492.       ptl.y = swp.y;
  493.       PrfWriteProfileData (vhini, (PSZ)szEyeFile, (PSZ)szMinor,
  494.                            (PVOID)&ptl, sizeof(POINTL));
  495.       rc = WinPostMsg( hwnd, WM_QUIT, 0, 0);
  496.       break;
  497.  
  498.     case WM_COMMAND:
  499.       switch(SHORT1FROMMP(mp1))
  500.         {
  501.         case IDM_RANDOM:
  502.           fRandom = !fRandom;
  503.           WinSendMsg(hwndSysSubMenu, MM_SETITEMATTR,
  504.                      MPFROM2SHORT(IDM_RANDOM, TRUE),
  505.                      MPFROM2SHORT(MIA_CHECKED,
  506.                                   (fRandom ? MIA_CHECKED : FALSE)));
  507.           if (fRandom)
  508.             {
  509.             ulRandom = rand() * 10000 / RAND_MAX;
  510.             rc = WinStartTimer( WinQueryAnchorBlock( hwnd),
  511.                                 hwndClient, 2, ulRandom);
  512.             }
  513.           else
  514.             rc = WinStopTimer( WinQueryAnchorBlock( hwnd),
  515.                                hwndClient, 2);
  516.           break;
  517.  
  518.         case IDM_NOFRAME:
  519.           if (!fNoFrame)
  520.             {
  521.             /*****************************************************/
  522.             /*  If switching to frameless frame, set frameless   */
  523.             /*  frame position to our current position.  Hide    */
  524.             /*  visible frame, show frameless frame, stop one    */
  525.             /*  timer, start the other timer, and send new       */
  526.             /*  window handle to digitalvideo device.            */
  527.             /*****************************************************/
  528.             WinQueryWindowPos( hwnd, &swp );
  529.             ptl.x = swp.x;
  530.             ptl.y = swp.y;
  531.             rc = WinMapWindowPoints( hwndFrame, HWND_DESKTOP, &ptl, 1);
  532.             rc = WinSetWindowPos( hwndNoFrame, HWND_BOTTOM,
  533.                              ptl.x, ptl.y, swp.cx, swp.cy,
  534.                              SWP_MOVE | SWP_SIZE | SWP_ZORDER );
  535.             rc = WinShowWindow( hwndFrame, FALSE);
  536.             rc = WinShowWindow( hwndNoFrame, TRUE);
  537.             fNoFrame = TRUE;
  538.             WinGetLastError( WinQueryAnchorBlock( hwnd));
  539.             rc = WinStartTimer( WinQueryAnchorBlock( hwnd),
  540.                                 hwndNoFrameClient, 1, 100);
  541.             rc = SetWindowHandle( hwndNoFrameClient);
  542.             switch_control.hwnd = hwndNoFrame;
  543.             rc = WinChangeSwitchEntry( hSwitch, &switch_control);
  544.             rc = WinStopTimer( WinQueryAnchorBlock( hwnd),
  545.                                hwndClient, 1);
  546.             }
  547.           else
  548.             {
  549.             /*****************************************************/
  550.             /*  If switching to visible frame, hide frameless    */
  551.             /*  frame, show regular frame, stop one timer, start */
  552.             /*  the other timer and send new window handel to    */
  553.             /*  digitalvideo device.                             */
  554.             /*****************************************************/
  555.             fNoFrame = FALSE;
  556.             rc = WinShowWindow( hwndNoFrame, FALSE);
  557.             rc = WinShowWindow( hwndFrame, TRUE);
  558.             rc = WinStartTimer( WinQueryAnchorBlock( hwnd),
  559.                                 hwndClient, 1, 100);
  560.             rc = SetWindowHandle( hwndClient);
  561.             switch_control.hwnd = hwndFrame;
  562.             rc = WinChangeSwitchEntry( hSwitch, &switch_control);
  563.             rc = WinStopTimer( WinQueryAnchorBlock( hwnd),
  564.                                hwndNoFrameClient, 1);
  565.             }
  566.           break;                        /* end: IDM_NOFRAME                  */
  567.         }                               /* end: WM_COMMAND                   */
  568.       break;
  569.  
  570.     case WM_TIMER:
  571.       if (mp1 == (MPARAM)1)
  572.         {
  573.         /*********************************************************/
  574.         /*  If random mode, adjust simulated mouse position,     */
  575.         /*  else see if mouse moved to get new frame.            */
  576.         /*********************************************************/
  577.         if (fRandom)
  578.           {
  579.           /***************************************************/
  580.           /*  If too close to edge of screen, turn around.   */
  581.           /***************************************************/
  582.           fSuccess = WinQueryWindowPos( HWND_DESKTOP, &swp);
  583.           if (fRandomUp && (swp.cy <= ptlOldMousePos.y + RANDOM_SPEED))
  584.             fRandomUp = FALSE;
  585.           else if (!fRandomUp && (RANDOM_SPEED > ptlOldMousePos.y))
  586.             fRandomUp = TRUE;
  587.           if (fRandomRight && (swp.cx <= ptlOldMousePos.x + RANDOM_SPEED))
  588.             fRandomRight = FALSE;
  589.           else if (!fRandomRight && (RANDOM_SPEED > ptlOldMousePos.x))
  590.             fRandomRight = TRUE;
  591.           ptlMouse.x = ptlOldMousePos.x + (fRandomRight ? RANDOM_SPEED :
  592.                                                          -RANDOM_SPEED);
  593.           ptlMouse.y = ptlOldMousePos.y + (fRandomUp ? RANDOM_SPEED :
  594.                                                       -RANDOM_SPEED);
  595.           sprintf( (PCHAR)szBuf, "(%d,%d)", ptlMouse.x, ptlMouse.y);
  596.           }                             /* end: if random mode               */
  597.         else
  598.           rc = WinQueryPointerPos( HWND_DESKTOP, &ptlMouse);
  599.         if ((ptlOldMousePos.x != ptlMouse.x) ||
  600.             (ptlOldMousePos.y != ptlMouse.y))
  601.           {
  602.           memcpy( &ptlOldMousePos, &ptlMouse, sizeof(POINTL));
  603.           fSuccess = WinQueryWindowPos( hwnd, &swp);
  604.           WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptlMouse, 1);
  605.           ptlMouse.x -= swp.cx/2;
  606.           ptlMouse.y -= swp.cy/2;
  607.  
  608.           /*******************************************************/
  609.           /*  If mouse is near middle of video, used special     */
  610.           /*  cross-eyed frame, else calculate frame based       */
  611.           /*  on arc-tangent of mouse position.                  */
  612.           /*******************************************************/
  613.           if (CrossEyed( &ptlMouse, swp.cx))
  614.             ulFrame = ulFrameNums[0];
  615.           else
  616.             {
  617.             Angle = atan2( ptlMouse.y, ptlMouse.x );
  618.             ulFrame = CalcFrame( Angle );
  619.             }
  620.  
  621.           /*******************************************************/
  622.           /*  If calculated frame is not the same as last        */
  623.           /*  calculated frame...                                */
  624.           /*******************************************************/
  625.           if (ulFrame != ulCurrentFrame)
  626.             {
  627.             _ultoa(ulFrame,szSeekPos,10);
  628.             fSuccess = SendString(hwnd, (PCHAR)"acquire movie wait", 0);
  629.  
  630.             /*****************************************************/
  631.             /*  If calculated frame is next sequential frame     */
  632.             /*  after last calculated frame, then we're          */
  633.             /*  already on it and there's no need to seek.       */
  634.             /*****************************************************/
  635.             if (ulFrame != ulCurrentFrame+1)
  636.               {
  637.               strcpy( szSeekString, (PCHAR)"seek movie to ");
  638.               strcat( szSeekString, szSeekPos);
  639.               strcat( szSeekString, " wait");
  640.               fSuccess = SendString(hwnd, szSeekString, 0);
  641.               }
  642.  
  643.             /*****************************************************/
  644.             /*  Step one frame to display video.                 */
  645.             /*****************************************************/
  646.             fSuccess = SendString(hwnd, (PCHAR)"step movie by 1 wait", 0);
  647.             ulCurrentFrame = ulFrame;
  648.             fSuccess = SendString(hwnd, (PCHAR)"release movie wait", 0);
  649.  
  650.             if (fDebug)
  651.               {
  652.               hwndTitle = WinWindowFromID( hwndFrame, FID_TITLEBAR);
  653.               sprintf( (PCHAR)szBuf, "%d (%d,%d)", ulFrame, ptlMouse.x, ptlMouse.y);
  654.               rc = WinSetWindowText( hwndTitle, (PCHAR)szBuf );
  655.               }                         /* end: Debug                        */
  656.             }                           /* end: frame changed                */
  657.           }                             /* end: mouse has moved              */
  658.         }                               /* end: this is our timer            */
  659.       if (mp1 == (MPARAM)2)             /* timer for random blinks           */
  660.         {
  661.         rc = WinStopTimer( WinQueryAnchorBlock( hwnd),
  662.                            hwndClient, 2);
  663.         ulRandom = rand() * 4 / RAND_MAX;
  664.         switch (ulRandom)
  665.           {
  666.           case 0:                       /* wink left side                    */
  667.             WinSendMsg( fNoFrame ? hwndNoFrameClient : hwndClient,
  668.                         WM_BUTTON1CLICK, MPFROM2SHORT( 0, 0), 0);
  669.             break;
  670.           case 1:                       /* wink right side                   */
  671.             WinSendMsg( fNoFrame ? hwndNoFrameClient : hwndClient,
  672.                         WM_BUTTON1CLICK, MPFROM2SHORT( ulVideoX-1, 0), 0);
  673.             break;
  674.           case 2:                       /* blink                             */
  675.             WinSendMsg( fNoFrame ? hwndNoFrameClient : hwndClient,
  676.                         WM_BUTTON1CLICK, MPFROM2SHORT( ulVideoX/2, 0), 0);
  677.             break;
  678.           }
  679.         ulRandom = (rand() * 100000 / RAND_MAX);
  680.         rc = WinStartTimer( WinQueryAnchorBlock( hwnd),
  681.                             hwndClient, 2, ulRandom);
  682.         }
  683.       break;
  684.     }                                   /* end: switch(msg)                  */
  685.  
  686.   mr = WinDefWindowProc( hwnd, msg, mp1, mp2 );
  687.   /**************************************************************/
  688.   /*  Don't allow the no-frame window to activate or get focus. */
  689.   /**************************************************************/
  690.   if (fNoFrame &&
  691.       ((msg == WM_SETFOCUS)      ||
  692.        (msg == WM_ACTIVATE)      ||
  693.        (msg == WM_SINGLESELECT)  ||
  694.        (msg == WM_SETSELECTION)  ||
  695.        (msg == WM_BUTTON1UP)     ||
  696.        (msg == WM_BUTTON1DOWN)   ||
  697.        (msg == WM_BUTTON1CLICK)  ||
  698.        (msg == WM_BUTTON2UP)     ||
  699.        (msg == WM_BUTTON2DOWN)   ||
  700.        (msg == WM_BUTTON2CLICK)))
  701.     {
  702.     fSuccess = WinSetWindowPos(hwndNoFrame, HWND_BOTTOM,
  703.                                0, 0, 0, 0, SWP_ZORDER);
  704.     return FALSE;
  705.     }
  706.   return mr;
  707.   }                                     /* end: MainClientWindowProc         */
  708.  
  709.  
  710. /*****************************************************************/
  711. /*  Name         :  ParseControlFile                             */
  712. /*                                                               */
  713. /*  Description  :  Parse frame table file.                      */
  714. /*                                                               */
  715. /*  Logic        :  Read movie file name and frame number        */
  716. /*                  table from frame table file.                 */
  717. /*                                                               */
  718. /*                  Frame table file contains 25 lines.  First   */
  719. /*                  line contains the filename of the movie      */
  720. /*                  file.  The next 24 lines are the frame       */
  721. /*                  number table (0-23).  The frame numbers      */
  722. /*                  are as follows (symbols refer to points of   */
  723. /*                  the compass):                                */
  724. /*                                                               */
  725. /*                   0      - Cross-eyed frame.                  */
  726. /*                   1      - E                                  */
  727. /*                   2      - ENE                                */
  728. /*                   3      - NE                                 */
  729. /*                   4      - NNE                                */
  730. /*                   5      - N                                  */
  731. /*                   6      - NNW                                */
  732. /*                   7      - NW                                 */
  733. /*                   8      - WNW                                */
  734. /*                   9      - W                                  */
  735. /*                  10      - WSW                                */
  736. /*                  11      - SW                                 */
  737. /*                  12      - SSW                                */
  738. /*                  13      - S                                  */
  739. /*                  14      - SSE                                */
  740. /*                  15      - SE                                 */
  741. /*                  16      - ESE                                */
  742. /*                  17      - E (again)                          */
  743. /*                  18-19   - right-eye wink sequence            */
  744. /*                            (left side of video)               */
  745. /*                  20-21   - left-eye wink sequence             */
  746. /*                            (right side of video)              */
  747. /*                  22-23   - blink sequence                     */
  748. /*                                                               */
  749. /*  Parameters   :  FileHandle  - frame table file handle        */
  750. /*                  ulFrameNums - pointer to frame table         */
  751. /*                                                               */
  752. /*  Return       :  none                                         */
  753. /*****************************************************************/
  754. VOID ParseControlFile( HFILE FileHandle, ULONG * ulFrameNums)
  755.   {
  756.   ULONG   BytesRead;     /* Bytes read (returned) */
  757.   UCHAR   szMsgBuf[CCHMAXPATH];
  758.   PSZ     buffer;
  759.   USHORT  idx;
  760.   PSZ     pszFrameNum;
  761.  
  762.   buffer = calloc( FILE_BUF_SIZE+1, 1);
  763.   if (DosRead(FileHandle, buffer, FILE_BUF_SIZE, &BytesRead))
  764.     {
  765.     strcpy( (PCHAR)szMsgBuf, "Cannot read from control file");
  766.     WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  767.                    (PSZ)szMsgBuf, (PSZ)"UltiEyes - Error Reading Control File", 0,
  768.                    MB_ERROR | MB_OK );
  769.     }
  770.   else
  771.     {
  772.     pszMovieFile = (PSZ) strtok( (PCHAR) buffer, " \r\n");
  773.     for (idx=0; idx < NUMFRAMENUMS; idx++)
  774.       {
  775.       pszFrameNum = (PSZ) strtok( NULL, " \r\n");
  776.       ulFrameNums[idx] = atoi( (PCHAR) pszFrameNum);
  777.       }
  778.     }                                   /* end: read ok                      */
  779.  
  780.   }                                     /* end: ParseControlFile             */
  781.  
  782. /*****************************************************************/
  783. /*  Name         :  CalcFrame                                    */
  784. /*                                                               */
  785. /*  Description  :  Calculate frame number based on mouse        */
  786. /*                  angle.                                       */
  787. /*                                                               */
  788. /*  Logic        :  If angle is >= 0                             */
  789. /*                    interpolate frame number from table        */
  790. /*                      using "northern" frames (1-9)            */
  791. /*                  else                                         */
  792. /*                    interpolate frame number from table        */
  793. /*                      using "southern" frames (9-17)           */
  794. /*                                                               */
  795. /*  Parameters   :  Angle       - angle of mouse to video        */
  796. /*                                center                         */
  797. /*                                                               */
  798. /*  Return       :  frame number                                 */
  799. /*****************************************************************/
  800. ULONG CalcFrame( double Angle)
  801.   {
  802.   double sector;
  803.   ULONG ulBaseFrame;
  804.   ULONG ulNewFrame;
  805.   double remainder;
  806.  
  807.   sector = Angle * 8.0 / PI;
  808.   if ( Angle >= 0.0)
  809.     {
  810.     ulBaseFrame = (ULONG) floor( sector) + 1;
  811.     remainder = fmod( Angle, PI/8.0);
  812.     ulNewFrame = ulFrameNums[ulBaseFrame] +
  813.                  ((ulFrameNums[ulBaseFrame+1] -
  814.                    ulFrameNums[ulBaseFrame]) * remainder * 8.0 / PI);
  815.     }
  816.   else
  817.     {
  818.     ulBaseFrame = (ULONG) floor( sector) + NUMFRAMENUMS-7;
  819.     remainder = -fmod( Angle, PI/8.0);
  820.     ulNewFrame = ulFrameNums[ulBaseFrame+1] -
  821.                  ((ulFrameNums[ulBaseFrame+1] -
  822.                    ulFrameNums[ulBaseFrame]) * remainder * 8.0 / PI);
  823.     }
  824.   return ulNewFrame;
  825.   }                                     /* end: CalcFrame                    */
  826.  
  827. BOOL CrossEyed( PPOINTL pptlMouse, LONG lWidth)
  828.   {
  829.   double distance;
  830.  
  831.   distance = sqrt( (double)((pptlMouse->x * pptlMouse->x) +
  832.                             (pptlMouse->y * pptlMouse->y)));
  833.   if (distance < lWidth * EyeRatio)
  834.     return TRUE;
  835.   else
  836.     return FALSE;
  837.   }                                     /* end: CrossEyed                    */
  838.  
  839. /*************************************************************************
  840.  * Name         :  SendString
  841.  *
  842.  * Description  :  This procedure will send string to MCI.
  843.  *
  844.  * Concepts     :
  845.  *
  846.  * MMPM/2 API's :  mciSendString
  847.  *
  848.  * Parameters   :  hwnd        - window handle.
  849.  *                 pcMCIString - string command.
  850.  *                 usUserParm  - user parameter.
  851.  *
  852.  * Return       :  TRUE  - if the operation was initiated without error.
  853.  *                 FALSE - if an error occurred.
  854.  *
  855.  ******************************************************************************/
  856. BOOL  SendString( HWND hwnd, PCHAR pcMCIString, USHORT usUserParm )
  857. {
  858.    LONG           lmciSendStringRC;    /* return value fromm mciSendString     */
  859.  
  860.  
  861. // printf( "Executing:   %s ....\n", (PCHAR)pcMCIString);
  862.    lmciSendStringRC =
  863.        mciSendString( (PSZ)pcMCIString,
  864.                       (PSZ)szReturn,
  865.                       (USHORT)CCHMAXPATH,
  866.                       (HWND)hwnd,
  867.                       (USHORT)usUserParm );
  868. // printf( "rc=%d\n", lmciSendStringRC);
  869.  
  870.    if (lmciSendStringRC != 0)
  871.    {
  872.       ShowMCIErrorMessage(lmciSendStringRC, hwnd, (PSZ)pcMCIString);
  873.       return( FALSE );
  874.    }
  875.  
  876.    return( TRUE );
  877. }
  878.  
  879. /******************************************************************************
  880.  * Name         :  ShowMCIErrorMessage
  881.  *
  882.  * Description  :  This window procedure displays an MCI error message
  883.  *                 based upon a ulError return code.  The MCI function
  884.  *                 mciGetErrorString is used to convert the error code into
  885.  *                 a text string and the title is pulled from the resource
  886.  *                 based upon a string id.
  887.  *
  888.  * Concepts     :  Using mciGetErrorString to convert an error code into
  889.  *                 a textual message.
  890.  *
  891.  * MMPM/2 API's :  mciGetErrorString
  892.  *
  893.  * Parameters   :  ulError  -  MCI error code.
  894.  *
  895.  * Return       :  nothing
  896.  *
  897.  ******************************************************************************/
  898. VOID  ShowMCIErrorMessage( ULONG ulError, HWND hwnd, PSZ pszCommand)
  899. {
  900.    CHAR  achBuffer[CCHMAXPATH];
  901.  
  902.    switch(mciGetErrorString( ulError, (PSZ)achBuffer,   sizeof( achBuffer)))
  903.    {
  904.       case MCIERR_SUCCESS:
  905.          /*
  906.           * This is what we want.  We were able to use mciGetErrorString to
  907.           * retrieve a textual error message we can show in a message box.
  908.           */
  909.          WinMessageBox( HWND_DESKTOP,
  910.                         hwnd,
  911.                         (PSZ)achBuffer,
  912.                         (PSZ)pszCommand,
  913.                         0,
  914.                         MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  915.          break;
  916.  
  917.       case MCIERR_INVALID_DEVICE_ID:
  918.       case MCIERR_OUTOFRANGE:
  919.       case MCIERR_INVALID_BUFFER:
  920.       default:
  921.          WinMessageBox( HWND_DESKTOP,
  922.                         hwnd,
  923.                         (PSZ)"General MCI Error",
  924.                         (PSZ)pszCommand,
  925.                         0,
  926.                         MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  927.          break;
  928.    }
  929.  
  930.    return;
  931.  
  932. }  /* end of ShowMCIErrorMessage */
  933.  
  934. /*************************************************************************
  935.  * Name         :  CloseTheDevice
  936.  *
  937.  * Description  :  This procedure will close the Movie device.
  938.  *
  939.  * Concepts     :  Closing a device using MCI interface.
  940.  *
  941.  * MMPM/2 API's :  mciSendString
  942.  *                    - close
  943.  *
  944.  * Parameters   :  None.
  945.  *
  946.  * Return       :  nothing.
  947.  *
  948.  ******************************************************************************/
  949. VOID CloseTheDevice( VOID)
  950. {
  951.   BOOL          fSuccess;
  952.  
  953.    /*
  954.     * To stop the device , we will issue a string command using mciSendString.
  955.     * This stop command is done for the alias.
  956.     */
  957.    fSuccess = SendString((HWND)NULL, "close movie", 0 );
  958.  
  959.    return;
  960.  
  961. }  /* end of CloseTheDevice */
  962.  
  963. /*************************************************************************
  964.  * Name         :  OpenTheDevice
  965.  *
  966.  * Description  :  This procedure will open the Movie device.
  967.  *
  968.  * Concepts     :  Opening a device using MCI interface.
  969.  *
  970.  * MMPM/2 API's :  mciSendString
  971.  *                    - open
  972.  *
  973.  * Parameters   :  None.
  974.  *
  975.  * Return       :  nothing.
  976.  *
  977.  ******************************************************************************/
  978. BOOL OpenTheDevice( HWND hwnd)
  979. {
  980.   /******************************************************************/
  981.   /* To open the device, we will issue MCI_OPEN command to the MCI  */
  982.   /* for digital video.                                             */
  983.   /******************************************************************/
  984.   if ( SendString( hwnd,
  985.                    "open digitalvideo alias movie wait shareable",
  986.                    0 ) )
  987.   {
  988.      /* Open success, set the flag and return true */
  989.      return(TRUE);
  990.   }
  991.   else
  992.      return( FALSE );
  993. }  /* end of OpenTheDevice */
  994.  
  995. BOOL LoadTheFile( HWND hwnd )
  996. {
  997.    LONG    lmciSendStringRC;          /* return code from SendString         */
  998.  
  999.    CHAR    szx[5]       = "";         /* string used for x position of window*/
  1000.    CHAR    szy[5]       = "";         /* string used for y position of window*/
  1001.    CHAR    szcx[5]      = "";        /* string used for cx position of window*/
  1002.    CHAR    szcy[5]      = "";        /* string used for cy position of window*/
  1003.  
  1004.  
  1005.    /*******************************************************************/
  1006.    /* The szWindowString and szPutString are used as a foundation     */
  1007.    /* for building a string command to send to sendstring             */
  1008.    /*******************************************************************/
  1009.  
  1010.    CHAR    szPutString[CCHMAXPATH] =
  1011.             "put movie destination at ";  /* string command to mciSendString */
  1012.  
  1013.    CHAR    szLoadString[CCHMAXPATH] =
  1014.             "load movie ";                /* string command to mciSendString */
  1015.  
  1016.    /**********************************************************************/
  1017.    /* Change pointer to a waiting pointer first, since this might take a */
  1018.    /* couple of seconds.                                                 */
  1019.    /**********************************************************************/
  1020.  
  1021.    StartWait( hwnd );
  1022.  
  1023.    lmciSendStringRC = SetWindowHandle( hwnd);
  1024.  
  1025.    /* Load the movie */
  1026.    strcat( szLoadString, (PCHAR)pszMovieFile );
  1027.    strcat (szLoadString, " ");
  1028.    strcat (szLoadString, "wait");
  1029.    if (!(lmciSendStringRC = SendString(hwnd, szLoadString, 0)))
  1030.      {
  1031.        ShowMCIErrorMessage(lmciSendStringRC, hwnd, (PSZ)szLoadString);
  1032.        return( FALSE );
  1033.      }
  1034.  
  1035.    /******************************************************/
  1036.    /* Convert the Frame windows sizes to strings so      */
  1037.    /* we can use the mciSendStringCommand to put the     */
  1038.    /* video in our application Frame window.             */
  1039.    /******************************************************/
  1040.    if (SendString( hwnd, (PCHAR)"status movie horizontal video extent wait", 0))
  1041.      ulVideoX = atoi( (PCHAR) szReturn);
  1042.    if (SendString( hwnd, (PCHAR)"status movie vertical video extent wait", 0))
  1043.      ulVideoY = atoi( (PCHAR) szReturn);
  1044.    WinSetWindowPos( hwnd, 0, 0, 0, ulVideoX, ulVideoY, SWP_SIZE);
  1045.  
  1046.    /******************************************************************/
  1047.    /* Now that we're done here, change the pointer back to the arrow.*/
  1048.    /******************************************************************/
  1049.    StopWait( hwnd );
  1050.  
  1051.    return( TRUE );
  1052.  
  1053. }  /* end of LoadTheFile */
  1054.  
  1055. LONG SetWindowHandle( HWND hwnd)
  1056.   {
  1057.   LONG    lmciSendStringRC;          /* return code from SendString         */
  1058.   CHAR    szHandle[20] = "";         /* string used for window handle       */
  1059.   CHAR    szWindowString[CCHMAXPATH] =
  1060.             "window movie handle ";      /* string command to mciSendString  */
  1061.  
  1062.    /******************************************************/
  1063.    /* Convert the Frame window handle to a string so    */
  1064.    /* we can use the mciSendStringCommand.               */
  1065.    /******************************************************/
  1066.  
  1067.    _ultoa(hwnd,szHandle,10);
  1068.  
  1069.    strcat (szWindowString, szHandle);  /* concatenate the converted handle to*/
  1070.    strcat (szWindowString, " ");     /* the window string so we can issue the*/
  1071.    strcat (szWindowString, "wait");  /* send string command                  */
  1072.  
  1073.    lmciSendStringRC = SendString(hwnd, szWindowString, 0);
  1074.  
  1075.    return( lmciSendStringRC );
  1076.   }                                     /* end: SetWindowHandle              */
  1077.  
  1078.  
  1079. /*****************************************************************
  1080.  * Name : Startwait
  1081.  *
  1082.  * Function: Change mouse pointer to hourglass
  1083.  *
  1084.  ******************************************************************/
  1085. VOID StartWait(HWND hwnd)
  1086. {
  1087.    HPOINTER hptrWait ;
  1088.    POINTL ptlPtr;
  1089.  
  1090.    vhCurrentPtr = WinQueryPointer(HWND_DESKTOP) ;
  1091.  
  1092.    /* If there is mouse pointer,                                */
  1093.    if (vhCurrentPtr)
  1094.    {
  1095.  
  1096.       /* Turn the pointer to an hourglass */
  1097.       hptrWait = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
  1098.       /* Set new mouse pointer                                  */
  1099.       WinSetPointer(HWND_DESKTOP,hptrWait) ;
  1100.  
  1101.       /* Force the pointer NOW to change */
  1102.       WinQueryPointerPos(HWND_DESKTOP, &ptlPtr);
  1103.       WinPostMsg( hwnd, WM_MOUSEMOVE,
  1104.                   MPFROM2SHORT(ptlPtr.x, ptlPtr.y),
  1105.                   MPFROM2SHORT(HT_NORMAL, KC_NONE));
  1106.  
  1107.    }
  1108.  
  1109. }  /* End StartWait() */
  1110.  
  1111.  
  1112. /*****************************************************************
  1113.  * Name : StopWait
  1114.  *
  1115.  * Function: Change mouse pointer from hourglass back to arror
  1116.  *
  1117.  ******************************************************************/
  1118. VOID StopWait(HWND hwnd)
  1119. {
  1120.  
  1121.    POINTL ptlPtr;
  1122.  
  1123.    /* If there is mouse pointer,                                */
  1124.    if (vhCurrentPtr)
  1125.    {
  1126.  
  1127.       /* Set new mouse pointer back to the original             */
  1128.       WinSetPointer(HWND_DESKTOP,vhCurrentPtr) ;
  1129.  
  1130.       /* Force the pointer NOW to change */
  1131.       WinQueryPointerPos(HWND_DESKTOP, &ptlPtr);
  1132.       WinPostMsg( hwnd, WM_MOUSEMOVE,
  1133.                   MPFROM2SHORT(ptlPtr.x, ptlPtr.y),
  1134.                   MPFROM2SHORT(HT_NORMAL, KC_NONE));
  1135.    }
  1136.  
  1137. }  /* End StopWait() */
  1138.  
  1139. /*****************************************************************
  1140.  * Name : QueryDirectMode
  1141.  *
  1142.  * Function: Determine if direct mode is supported.
  1143.  *
  1144.  ******************************************************************/
  1145.  
  1146. BOOL  QueryDirectMode( VOID )
  1147. {
  1148.     DIVE_CAPS    DiveCaps;             /* Dive Query Capabilities */
  1149.     ULONG        rc;                   /* API Return Code         */
  1150.     FOURCC       fccFormats[100] = {0};
  1151.  
  1152.  
  1153.  
  1154.     memset (&DiveCaps,0,sizeof(DiveCaps));
  1155.     DiveCaps.pFormatData = fccFormats;
  1156.     DiveCaps.ulFormatLength = 120;
  1157.     DiveCaps.ulStructLen = sizeof(DIVE_CAPS);
  1158.     rc = DiveQueryCaps( &DiveCaps, DIVE_BUFFER_SCREEN);
  1159.     if (!rc)
  1160.       {
  1161.         if (DiveCaps.fScreenDirect)
  1162.          {
  1163.            if (DiveCaps.ulDepth < 8)
  1164.               return (BOOL)(FALSE);
  1165.          }
  1166.          else
  1167.               return (BOOL)(FALSE);
  1168.  
  1169.       }
  1170.     return (BOOL)(TRUE);
  1171. }
  1172.