/* GUIBEGIN WINDOW , 33, 94, 179, 100, POPUP|CAPTION|SYSMENU|MINBOX|MAXBOX|THICK, , Video Player FONT 8, 400, MS Shell Dlg PUSH 70, 14, 40, 14, TABSTOP, , PlayButton, , Play DEND GUIEND */ LIBRARY rexxgui /* * An example of FUNCDEF'ing some MCI functions to playback * a video clip. */ DO /* Register the Windows OS function MCIWndCreate() */ FUNCDEF("MCIWndCreate", "void, void, void, 32u, str", "msvfw32") /* Register the Windows OS function SendMessage() */ FUNCDEF("SendMessage", "void, void, 32u, void, void", "user32") /* Register the Windows OS function mciGetErrorString(). We * register it to return an error message with a maximum * length of 260 characters. */ FUNCDEF("mciGetErrorString", "32u, 32u, str[260] stor, 32u", "winmm") /* Register the Windows OS function DestroyWindow() */ FUNCDEF("DestroyWindow", "32u, void", "user32") CATCH FAILURE CONDITION("M") RETURN END GuiErr = "SYNTAX" GuiHeading = 1 GuiCreateWindow('NORMAL') /* Initially there is no MCI window open. */ mciHandle = 0 Again: DO FOREVER GuiGetMsg() CATCH SYNTAX CONDITION('M') SIGNAL Again CATCH HALT FINALLY /* Close the device if it's playing */ IF mciHandle \== 0 THEN DO MCIWndStop(mciHandle) MCIWndClose(mciHandle) END GuiDestroyWindow() END RETURN /* =============== WM_CLICK_PlayButton =============== * This handles the CLICK event for my button * associated with the "PlayButton" variable. * * Reginald calls this when the user clicks the button. */ WM_CLICK_PlayButton: /* Are we stopped? If so, put it into play */ IF mciHandle == 0 THEN DO /* Present REXX GUI's File dialog to pick out the file */ /* Store the filename in the variable FN. */ FN = '' /* Present the dialog */ err = GuiFile('FN', 'EXISTING', 'Pick out an AVI file', 'Video files (*.avi) | *.avi | All files (*.*) | *.*') IF err = '' THEN DO /* Register the MCIWnd window class and create an MCIWnd window * for using MCI services. MCIWndCreate can also open an MCI * device or file (such as an AVI file) and associate it with * the MCIWnd window. * * Returns a handle of an MCIWnd window if successful or 0 otherwise. * * The first arg is the handle of the parent window. For example, you * could pass the handle of some open REXX GUI window to embed the * MCI window as a control inside of that window. Omitting this arg * has the MCI window as a separate window. * * The second arg is the module instance (handle) to associate with * the MCIWnd window. You can omit this arg. * * The third arg is various flags. You can add any of the following values * (as well as add any of the values you would pass as flags to CreateWindow): * * 1 = Will not change the dimensions of an MCIWnd window when the image size changes. * 2 = Hides the toolbar from view and prohibits users from accessing it. * 4 = Will not change the dimensions of an MCIWnd window when the size of its contents changes. * 8 = Hides the Menu button from view on the toolbar. * 16 = Shows the name of the open MCI device or data file in the MCIWnd window title bar. * 32 = Shows the current play position in the window title bar. * 64 = Shows the current mode of the MCI device in the window title bar. * 256 = Your parent window is sent an MCIWNDM_NOTIFYMODE (1224) message whenever the * operating mode changes. The fourth arg passed to your window procedure identifies * the new mode, such as MCI_MODE_STOP (525). * 512 = Your parent window is sent an MCIWNDM_NOTIFYPOS (1225) message whenever the * playback or record position changes. The fourth arg passed to your window procedure * is the new position in the content. * 1024 = Your parent window is sent an MCIWNDM_NOTIFYSIZE (1226) message whenever the * MCIWnd window size changes. * 2176 = Your parent window is sent an MCIWNDM_NOTIFYMEDIA (1227) message whenever a * new device is used or a data file is opened or closed. The fourth arg passed to your * is the new filename. * 5096 = Notifies our parent window when an MCI error occurs. * 8192 = Adds a Record button to the toolbar and adds a new file command to the menu * if the MCI device has recording capability. * 16384 = Disables display of MCI error dialogs to users. * 32768 = Hides the open and close commands from the MCIWnd menu. * * If you omit the third arg, then a window is created with default style of * only WS_VISIBLE (268435456) if you don't embed the MCI window * inside of another window, or WS_CHILD, WS_BORDER, WS_VISIBLE * if you do have a parent window. * * The fourth arg is the name of the file to play, or MCI device to open. */ mciHandle = MCIWndCreate(, , 268435456 /* visible */ + 256 /* send me MCIWNDM_NOTIFYMODE */ + 2 /* hide toolbar */, FN) /* Check for an error */ IF mciHandle == 0 THEN GuiSay("Can't create MCI window!") ELSE DO /* Set my REXX GUI window as the owner of this MCI window. * Even though this MCI window isn't physically a control * inside of my REXX window, I'll receive an "EXTRA" event * at this window, with a message number of * (MCIWNDM_NOTIFYMODE). * * If we created the MCI window as a control, then we wouldn't * have to do this, as our REXX GUI window would already be * its owner. */ MCISetOwner(mciHandle, GuiWindow) /* Play the file from the current position. We'll receive an * MCIWNDM_NOTIFYMODE message with an lParam of MCI_MODE_STOP, * when play is done. */ err = MCIWndPlay(mciHandle) IF err \== 0 THEN DO MCIWndClose(mciHandle) mciHandle = 0 mciGetErrorString(err, buf, 260) GuiSay(buf) END /* It's in play now */ ELSE DO GuiAddCtlText("PlayButton", "Stop") END END /* No error with MCIWndCreate */ END /* File dialog */ END /* mciHandle == 0 */ /* We're in play, so stop it */ ELSE DO /* Stop the play */ MCIWndStop(mciHandle) /* Close the device. We wouldn't do this now if the MCI window was * a control inside of our REXX Dialog window. */ MCIWndClose(mciHandle) mciHandle = 0 /* Indicate that we're stopped, and ready to play again */ GuiAddCtlText("PlayButton", "Play") END RETURN /* ===================== WM_EXTRA ======================== * This handles all events for our window which REXX * GUI doesn't know about. REXX GUI doesn't know about * any of the MCI events, so any MCI event causes * Reginald to call this handler. */ WM_EXTRA: /* Figure out what to do based on the message number */ SELECT ARG(3) /* Is it the MCIWNDF_NOTIFYERROR event? MCIWNDF_NOTIFYERROR is not an * event that REXX GUI knows about, so our WM_EXTRA event handler is * called. ARG(3) is the message number, which in this case, happens to * be 1229 for MCIWNDF_NOTIFYERROR. * * The OS gives us this message when MCI is notifying us * of an error. We don't ask for this in our example. * Instead we let the MCI device post error dialogs. So, * this is just for illustration if you *want* to handle * MCI error display yourself. * * ARG(1) is the handle of our MCI window (ie, mciHandle). * ARG(2) is the error number which we could pass to mciGetErrorString(). * * Here we could insert some code to handle an error. If * we created our MCI window with disabling MCI error dialogs, * then we'd probably want to inform the user ourselves now. */ WHEN 1229 THEN DO END /* MCIWNDF_NOTIFYERROR */ /* Is it the MCIWNDM_NOTIFYMODE event? MCIWNDM_NOTIFYMODE is not an * event that REXX GUI knows about, so our WM_EXTRA event handler is * called. ARG(3) is the message number, which in this case, happens to * be 1224 for MCIWNDM_NOTIFYMODE. * * The OS gives us this message when the MCI device is * notifying us of a change in its mode, for example, from * MCI_MODE_STOP to MCI_MODE_PLAY. * * ARG(1) is the handle of our MCI window (ie, mciHandle). * ARG(2) is the new mode. * * Here we could insert some code to handle an error. If * we created our MCI window with disabling MCI error dialogs, * then we'd probably want to inform the user ourselves now. */ WHEN 1224 THEN DO /* Did we just stop? */ IF ARG(2) = '525' & mciHandle \== 0 THEN DO /* Close the device. We wouldn't these two lines now if the MCI window * was a control inside of our REXX Dialog window, and we wanted to keep * it visible. */ MCIWndClose(mciHandle) mciHandle = 0 /* Indicate that we're stopped, and ready to play again */ GuiAddCtlText("PlayButton", "Play") END END /* MCIWNDM_NOTIFYMODE */ OTHERWISE END /* SELECT message number */ /* Don't let Rexx Gui process this event. */ RETURN "" /* ===================== MCI Helper functions ==================== */ /* Each gets passed the handle of an open MCI window */ MCIWndPlay: RETURN SendMessage(ARG(1), 2054 /* MCI_PLAY */, 0, 0) MCIWndClose: /* An MCI_CLOSE message is *supposed* to destroy the MCI * window, but at least under Windows 2000, it still leaves * a titlebar visible. So, we'll work around this bug by * destroying that mciHandle window ourselves after we close it. */ SendMessage(ARG(1), 2052 /* MCI_CLOSE */, 0, 0) DestroyWindow(ARG(1)) RETURN 0 MCIWndStop: RETURN SendMessage(ARG(1), 2056 /* MCI_STOP */, 0, 0) /* This gets passed a second arg too -- the handle of our REXX GUI window */ MCISetOwner: RETURN SendMessage(ARG(1), 1176 /* MCIWNDM_SETOWNER */, ARG(2), 0)