home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 February / Chip_2004-02_cd1.bin / tema / stream / download / asfrec / source / wingui / wingui.c < prev    next >
C/C++ Source or Header  |  2000-12-15  |  136KB  |  4,549 lines

  1.  
  2. /*     GUI code for the ASFRecorder application     */
  3. /* Uses ActiveMovie (DirectShow) for stream preview */
  4.  
  5. #include "global.h"
  6. #include "CmdLine.h"
  7.  
  8. #ifdef  __MINGW32__
  9. /* we need to rename the main() function for MINGW32 */
  10. /* because otherwise WinMain() will never be called */
  11. #define main(argc,argv) renamed_main(argc,argv)
  12. #endif /* __MINGW32__ */
  13.  
  14. #define UNTITLED_STRING " - Untitled"
  15. #define nMaxResourceStrSize 128
  16.  
  17. /*--------------------------------- GLOBALS ---------------------------------*/
  18.  
  19. /* some application variables */
  20. AppVars appVars;
  21.  
  22. /* used for inter-process communication */
  23. UINT WM_APPMSG;
  24. #define MAGIC_COOKIE 0x1234
  25. BOOL Idle = TRUE;
  26.  
  27. /* window and control handles */
  28. HWND hwndAboutBox = NULL;
  29. HWND hwndStatusbar = NULL;
  30. HWND hwndOpenURLDialog = NULL;
  31. // The window for each toolbar button
  32. struct{
  33.     HWND hwndPlayButton;
  34.     HWND hwndPauseButton;
  35.     HWND hwndStopButton;
  36.     HWND hwndPreviewButton;
  37.     HWND hwndCancelButton;
  38. } toolbar = {NULL, NULL, NULL, NULL, NULL};
  39. HWND hwndTrackbar = NULL;
  40.  
  41. /* timer for flashing status bar */
  42. #define ID_STATUSTIMER   1
  43. UINT StatusTimer = 0;
  44. UINT StatusTimerCount;
  45. UINT StatusTimerCref;
  46.  
  47. /* timer for moving trackbar */
  48. #define ID_TRACKBARTIMER 2
  49. UINT TrackbarTimer = 0;
  50.  
  51. /* some more trackbar stuff */
  52. int positionTrackbar;
  53. BOOL TrackbarDragging = FALSE;
  54.  
  55. /* flags/names of current stream and media file */
  56. BOOL Batchmode = FALSE;
  57. char StreamURL[512]  = "";
  58. char StreamFilename[512] = "";
  59. unsigned int StreamTotalTime;
  60. unsigned int StreamMaxTime;
  61. BOOL Transmitting = FALSE;
  62. BOOL Previewing = FALSE;
  63.  
  64. /* data obtained from the IMediaPosition interface */
  65. REFTIME IMPTotalTime;
  66. REFTIME IMPCurrentPosition;
  67. REFTIME IMPDownloadTime; /* obtained from gui_progressinfo */
  68.  
  69. /* data obtained from the IMediaSeeking interface */
  70. LONGLONG IMSTotalTime;
  71. LONGLONG IMSCurrentPosition;
  72. DWORD    IMSCapabilities;
  73. LONGLONG IMSDownloadTime; /* obtained from gui_progressinfo */
  74.  
  75. /* video window positions */
  76. long IVWWindowLeft   = 0;
  77. long IVWWindowTop    = 0;
  78. long IVWWindowWidth  = 0;
  79. long IVWWindowHeight = 0;
  80.  
  81. /* definition of min/max widths of status bar parts */
  82. int StatusDefinitionArray[] =
  83. {   6,
  84.     50, 80,
  85.     30, 40,
  86.     80, 120,
  87.     50, 80,
  88.     160, -1,
  89.     16, 16 };
  90.  
  91. /* enumeration of the status bar parts */
  92. enum
  93. {   STAT_KB = 0,
  94.     STAT_PROGRESS,
  95.     STAT_TIMECODE,
  96.     STAT_SEQNO,
  97.     STAT_STATUS, };
  98.  
  99. /* event for network socket notification */
  100. WSAEVENT NetworkEvent = WSA_INVALID_EVENT;
  101. SOCKET NetworkSocket = INVALID_SOCKET;
  102.  
  103. /* Winsock error strings/codes */
  104. struct ErrorDef
  105. {
  106.     char* ErrorName;
  107.     int   ErrorVal;
  108. } WinSockErrors[] =
  109.  
  110. {
  111.     "INTR"                ,(WSABASEERR+4),
  112.     "BADF"                ,(WSABASEERR+9),
  113.     "ACCES"               ,(WSABASEERR+13),
  114.     "FAULT"               ,(WSABASEERR+14),
  115.     "INVAL"               ,(WSABASEERR+22),
  116.     "MFILE"               ,(WSABASEERR+24),
  117.     "WOULDBLOCK"          ,(WSABASEERR+35),
  118.     "INPROGRESS"          ,(WSABASEERR+36),
  119.     "ALREADY"             ,(WSABASEERR+37),
  120.     "NOTSOCK"             ,(WSABASEERR+38),
  121.     "DESTADDRREQ"         ,(WSABASEERR+39),
  122.     "MSGSIZE"             ,(WSABASEERR+40),
  123.     "PROTOTYPE"           ,(WSABASEERR+41),
  124.     "NOPROTOOPT"          ,(WSABASEERR+42),
  125.     "PROTONOSUPPORT"      ,(WSABASEERR+43),
  126.     "SOCKTNOSUPPORT"      ,(WSABASEERR+44),
  127.     "OPNOTSUPP"           ,(WSABASEERR+45),
  128.     "PFNOSUPPORT"         ,(WSABASEERR+46),
  129.     "AFNOSUPPORT"         ,(WSABASEERR+47),
  130.     "ADDRINUSE"           ,(WSABASEERR+48),
  131.     "ADDRNOTAVAIL"        ,(WSABASEERR+49),
  132.     "NETDOWN"             ,(WSABASEERR+50),
  133.     "NETUNREACH"          ,(WSABASEERR+51),
  134.     "NETRESET"            ,(WSABASEERR+52),
  135.     "CONNABORTED"         ,(WSABASEERR+53),
  136.     "CONNRESET"           ,(WSABASEERR+54),
  137.     "NOBUFS"              ,(WSABASEERR+55),
  138.     "ISCONN"              ,(WSABASEERR+56),
  139.     "NOTCONN"             ,(WSABASEERR+57),
  140.     "SHUTDOWN"            ,(WSABASEERR+58),
  141.     "TOOMANYREFS"         ,(WSABASEERR+59),
  142.     "TIMEDOUT"            ,(WSABASEERR+60),
  143.     "CONNREFUSED"         ,(WSABASEERR+61),
  144.     "LOOP"                ,(WSABASEERR+62),
  145.     "NAMETOOLONG"         ,(WSABASEERR+63),
  146.     "HOSTDOWN"            ,(WSABASEERR+64),
  147.     "HOSTUNREACH"         ,(WSABASEERR+65),
  148.     "NOTEMPTY"            ,(WSABASEERR+66),
  149.     "PROCLIM"             ,(WSABASEERR+67),
  150.     "USERS"               ,(WSABASEERR+68),
  151.     "DQUOT"               ,(WSABASEERR+69),
  152.     "STALE"               ,(WSABASEERR+70),
  153.     "REMOTE"              ,(WSABASEERR+71),
  154.     "SYSNOTREADY"         ,(WSABASEERR+91),
  155.     "VERNOTSUPPORTED"     ,(WSABASEERR+92),
  156.     "NOTINITIALISED"      ,(WSABASEERR+93),
  157.     "DISCON"              ,(WSABASEERR+101),
  158.     "HOST_NOT_FOUND"      ,(WSABASEERR+1001),
  159.     "TRY_AGAIN"           ,(WSABASEERR+1002),
  160.     "NO_RECOVERY"         ,(WSABASEERR+1003),
  161.     "NO_DATA"             ,(WSABASEERR+1004),
  162.     NULL,                 -1
  163. };
  164.  
  165.  
  166. /*--------------------------- FUNCTION PROTOTYPES ---------------------------*/
  167.  
  168. /* Function prototypes for externals in asfrecorder.c */
  169. extern int main(int argc, char **argv);
  170. extern int main_function(int argc, char **argv);
  171. extern void gui_abort(void);
  172. extern char *createtimestring(unsigned int timecode);
  173. typedef enum  {
  174.     ShowUsage,
  175.     NoArguments,
  176.     BadOption,
  177. } UsageMode;
  178. void Usage(char *progname, UsageMode mode);
  179. UINT DoEnterPasswordDialog( HINSTANCE hInstance, HANDLE hwnd );
  180. UINT DoProxyConfigurationDialog( HINSTANCE hInstance, HANDLE hwnd );
  181.  
  182.  
  183. /*--------------------------- WINMAIN ENTRY POINT ---------------------------*/
  184.  
  185. //
  186. // WinMain
  187. //
  188. // use call custom command line parser and
  189. // give control to main() in asfrecorder.c
  190. //
  191. int PASCAL WinMain( HINSTANCE hInstance,
  192.                     HINSTANCE hPrevInstance,
  193.                     LPSTR lpszCmdParam,
  194.                     int nCmdShow )
  195. {
  196.     UINT nReturn = 0;
  197.     HWND win;
  198.     DWORD result;
  199.     
  200.     LPTSTR cmdline;
  201.  
  202.     cmdline = GetCommandLine();
  203.  
  204.     /* register an application- and inter-process-global message */
  205.     WM_APPMSG = RegisterWindowMessage( APP_NAME );
  206.  
  207.     if (WM_APPMSG != 0)
  208.     {
  209.         /* loop through all other open ASFRecorder windows */
  210.  
  211.         win = NULL;
  212.         while ((win = FindWindowEx(NULL, win, APP_NAME, NULL)) != NULL)
  213.         {
  214.             /* send an application-specific message to the other windows */
  215.             /* to probe if these windows are "idle" (not in a transfer) */
  216.             if (SendMessageTimeout( win, WM_APPMSG, 0, 0, SMTO_BLOCK, 250, &result) != 0)
  217.             {
  218.                 if (result == MAGIC_COOKIE)
  219.                 {
  220.                     COPYDATASTRUCT cds;
  221.                     DWORD result2;
  222.  
  223.                     /* other windows seems to be idle */
  224.                     /* so send our command line to this window */
  225.  
  226.                     cds.dwData = MAGIC_COOKIE;
  227.                     cds.cbData = strlen(cmdline)+1;
  228.                     cds.lpData = cmdline;
  229.  
  230.                     result2 = SendMessage( win, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds );
  231.  
  232.                     if (result2 == MAGIC_COOKIE)
  233.                     {
  234.                         /* other window processed the message */
  235.                         /* so we can exit this process now */
  236.                         return nReturn;
  237.                     }
  238.                 }
  239.             }
  240.         }
  241.     }
  242.  
  243.     /* seems that no other ASFRecorder window was willing to accept */
  244.     /* our command line. So we have to handle it in this process. */
  245.  
  246.     if (ParseCommandLine(cmdline))
  247.     {
  248.         appVars.szProgramExecutable = argv[0];
  249.  
  250.         main(argc, argv);
  251.     }
  252.     FreeCommandLine();
  253.  
  254.     return nReturn;
  255. } // WinMain
  256.  
  257.  
  258. /*-------------- INTERFACE CODE TO ASFRECORDER NETWORKING CORE --------------*/
  259.  
  260. int gui_initialize()
  261. {
  262.     UINT nReturn;
  263.  
  264.     HINSTANCE hInstance = GetModuleHandleA(NULL);
  265.     HINSTANCE hPrevInstance = NULL;
  266.     LPSTR lpszCmdParam = NULL;
  267.     int nCmdShow = SW_SHOW;
  268.  
  269.     nReturn = PseudoWinMain(hInstance, hPrevInstance, lpszCmdParam, nCmdShow);
  270.  
  271.     return nReturn;
  272. }
  273.  
  274.  
  275. void gui_uninitialize(void)
  276. {
  277.     EndOfWinMain();
  278. }
  279.  
  280.  
  281. void gui_setbatchmode(int flag)
  282. {
  283.     Batchmode = flag;
  284. }
  285.  
  286.  
  287. int  gui_startedfromdesktop(void)
  288. {
  289.     int fromdesktop = 0;
  290.  
  291.     /* I don't know if this is correct, but */
  292.     /* it works for determining wheter this */
  293.     /* programm was started from DOS or from */
  294.     /* Windows Explorer, both on Win98 and NT */
  295.  
  296.     LPTSTR lpszVariable; 
  297.     LPVOID lpvEnv; 
  298.     
  299.     // Get a pointer to the environment block. 
  300.     
  301.     if ((lpvEnv = GetEnvironmentStrings()) != NULL)
  302.     {
  303.         // Variable strings are separated by NULL byte, and the block is 
  304.         // terminated by a NULL byte. 
  305.         
  306.         for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) 
  307.         { 
  308.             /* this one is for Windows NT (together with PROMPT=) */
  309.             if (!stricmp(lpszVariable, "OS=Windows_NT"))
  310.                 fromdesktop = 1;
  311.             while (*lpszVariable) lpszVariable++;
  312.         } 
  313.  
  314.         for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) 
  315.         { 
  316.             /* this one for Windows 98 */
  317.             if (!stricmp(lpszVariable, "CMDLINE=win"))
  318.                 fromdesktop = 1;
  319.             /* required for Windows NT only */
  320.             if (!strnicmp(lpszVariable, "PROMPT=", 7))
  321.                 fromdesktop = 0;
  322.             while (*lpszVariable) lpszVariable++;
  323.         } 
  324.  
  325.         FreeEnvironmentStrings(lpvEnv);
  326.     }
  327.     return fromdesktop;
  328. }
  329.  
  330.  
  331. void gui_prepareasyncsocket(SOCKET s)
  332. {
  333.     int rc;
  334.  
  335.     if (NetworkEvent == WSA_INVALID_EVENT)
  336.     {
  337.         NetworkEvent = WSACreateEvent();
  338.     }
  339.  
  340.     if (NetworkEvent != WSA_INVALID_EVENT)
  341.     {
  342.         NetworkSocket = s;
  343.         rc = WSAEventSelect(s, NetworkEvent, FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE);
  344.         if (rc == SOCKET_ERROR)
  345.         {
  346.             gui_criticalerror("WSAEventSelect() failed! Error code: %d\n", WSAGetLastError());
  347.         }
  348.     }
  349. }
  350.  
  351.  
  352. void gui_restoresyncsocket(SOCKET s)
  353. {
  354.     WSAEventSelect(s, NULL, 0);
  355.     WSACloseEvent(NetworkEvent);
  356.  
  357.     NetworkSocket = INVALID_SOCKET;
  358.     NetworkEvent = WSA_INVALID_EVENT;
  359. }
  360.  
  361.  
  362. void gui_return_on_network_activity(void)
  363. {
  364.     /* don't enter main loop if the user has already closed the main window */
  365.     if (appVars.hwndMainFrame != NULL)
  366.     {
  367.         DoMainLoop(FD_READ | FD_WRITE | FD_CLOSE);
  368.     }
  369. }
  370.  
  371.  
  372. void gui_return_on_network_connect(int *returnval)
  373. {
  374.     /* don't enter main loop if the user has already closed the main window */
  375.     if (appVars.hwndMainFrame != NULL)
  376.     {
  377.         int ret = DoMainLoop(FD_CONNECT);
  378.  
  379.         if (ret == 0)
  380.             *returnval = 0;
  381.         else
  382.         {
  383.             *returnval = SOCKET_ERROR;
  384.             WSASetLastError(ret);
  385.         }
  386.     }
  387.     else
  388.     {
  389.         *returnval = 0;
  390.     }
  391. }
  392.  
  393.  
  394. int gui_nonblocking_socket_check(int num)
  395. {
  396.     if (num == WSAEWOULDBLOCK)
  397.         return 1;
  398.     else
  399.         return 0;
  400. }
  401.  
  402.  
  403. void gui_waitforuseraction()
  404. {
  405.     /* don't enter main loop if the user has already closed the main window */
  406.     if (appVars.hwndMainFrame != NULL)
  407.     {
  408.         DoMainLoop(0);
  409.     }
  410. }
  411.  
  412.  
  413. void gui_showtext(char *text, ...)
  414. {
  415.     char Buffer[4096];
  416.  
  417.     va_list arglist;
  418.     va_start(arglist, text);
  419.  
  420.     vsprintf(Buffer, text, arglist);
  421.  
  422.     MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
  423.                 MB_APPLMODAL | MB_OK | 0 );
  424.  
  425.     va_end(arglist);
  426. }
  427.  
  428.  
  429. void gui_setstatus(char *statustext, ...)
  430. {
  431.     va_list arglist;
  432.     va_start(arglist, statustext);
  433.  
  434.     SetStatusTextArgs(STAT_STATUS, SBT_POPOUT, CLR_DEFAULT, statustext, arglist);
  435.  
  436.     va_end(arglist);
  437. }
  438.  
  439.  
  440. void gui_seterror(char *errortext, ...)
  441. {
  442.     va_list arglist;
  443.     va_start(arglist, errortext);
  444.  
  445.     SetStatusTextArgs(STAT_STATUS, SBT_POPOUT, RGB(0xff,0xff,0), errortext, arglist);
  446.  
  447.     va_end(arglist);
  448. }
  449.  
  450.  
  451. void gui_criticalerror(char *errortext, ...)
  452. {
  453.     char Buffer[4096];
  454.  
  455.     va_list arglist;
  456.     va_start(arglist, errortext);
  457.  
  458.     vsprintf(Buffer, errortext, arglist);
  459.  
  460.     if (!Batchmode)
  461.     {
  462.         MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
  463.                     MB_APPLMODAL | MB_OK | MB_ICONERROR );
  464.     }
  465.     else
  466.     {
  467.         /* in batch mode, don't bother the user with blocking requesters */
  468.         gui_seterror("%s", Buffer);
  469.     }
  470.  
  471.     va_end(arglist);
  472. }
  473.  
  474.  
  475. void gui_logtext(char *text, ...)
  476. {
  477.     char Buffer[4096];
  478.  
  479.     va_list arglist;
  480.     va_start(arglist, text);
  481.  
  482.     vsprintf(Buffer, text, arglist);
  483.  
  484. //    MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
  485. //                MB_APPLMODAL | MB_OK | 0 );
  486.  
  487.     va_end(arglist);
  488. }
  489.  
  490.  
  491. int gui_start_transmission(char *url, char *filename, int filenamesize, unsigned int totaltime, unsigned int maxtime)
  492. {
  493.     int retval = 0;
  494.  
  495.     static char szFileName[ _MAX_PATH ];
  496.     static char szTitleName[ _MAX_FNAME + _MAX_EXT ];
  497.     LPSTR szTitle;
  498.  
  499.     strcpy(StreamURL, url);
  500.  
  501.     StreamTotalTime = totaltime;
  502.     StreamMaxTime = maxtime;
  503.  
  504.     if ( appVars.hwndMainFrame != NULL )
  505.     {
  506.         SetStatusText(STAT_KB,       0, -1, "");
  507.         SetStatusText(STAT_PROGRESS, 0, -1, "");
  508.         SetStatusText(STAT_TIMECODE, 0, -1, "");
  509.         SetStatusText(STAT_SEQNO,    0, -1, "");
  510.  
  511.         if (!strcmp(filename, ""))
  512.         {
  513.             strcpy(StreamFilename, filename);
  514.             
  515.             SetTitle( appVars.hwndMainFrame, StreamURL );
  516.             
  517.             Transmitting = TRUE;
  518.         }
  519.         else
  520.         {
  521.             // Work out the full path name and the file name from the
  522.             // specified file
  523.             GetFullPathName( filename, _MAX_PATH, szFileName, &szTitle );
  524.  
  525.             if (Batchmode)
  526.             {
  527.                 /* don't bother the user with a file dialog in batch mode */
  528.                 Transmitting = TRUE;
  529.             }
  530.             else
  531.             {
  532.                 strncpy( szTitleName, szTitle, _MAX_FNAME + _MAX_EXT );
  533.                 szTitleName[ _MAX_FNAME + _MAX_EXT -1 ] = '\0';
  534.                 
  535.                 if ( DoFileSaveDialog( appVars.hwndMainFrame, szFileName, szTitleName ) )
  536.                 {
  537.                     Transmitting = TRUE;
  538.                 }
  539.             }
  540.             
  541.             if (Transmitting)
  542.             {
  543.                 /* keep a local copy of the stream file name (for preview) */
  544.                 strncpy(StreamFilename, szFileName, sizeof(StreamFilename));
  545.                 StreamFilename[sizeof(StreamFilename)-1] = '\0';
  546.  
  547.                 /* return the new file name to the main function */
  548.                 strncpy(filename, szFileName, filenamesize);
  549.                 filename[filenamesize-1] = '\0';
  550.  
  551.                 SetTitle( appVars.hwndMainFrame, StreamURL );
  552.                 retval = 1;
  553.             }
  554.             else
  555.             {
  556.                 SetTitle( appVars.hwndMainFrame, "Untitled" );
  557.                 strcpy(filename, "");
  558.                 retval = 0;
  559.             }
  560.         }
  561.         
  562.         if (hwndTrackbar != NULL)
  563.         {
  564.             SendMessage(hwndTrackbar, TBM_CLEARSEL,    TRUE,  0     );
  565.         }
  566.         
  567.         UpdateToolbar();
  568.     }
  569.     return retval;
  570. }
  571.  
  572.  
  573. void gui_progressinfo(int bytes, char *timecode, int progress, int seqno, int currenttime)
  574. {
  575.     /* currenttime is in milliseconds */
  576.     IMPDownloadTime = (REFTIME) currenttime / 1000;   /* REFTIME is in seconds (64 bit floating pt) */
  577.     IMSDownloadTime = (LONGLONG)currenttime * 10000;  /* LONGLONG: 10 million units equal 1 second */
  578.  
  579.     if ( appVars.hwndMainFrame != NULL )
  580.     {
  581.         /* progress is scaled from 0 (=0%) to 10000 (=100%) */
  582.         SetStatusText(STAT_KB,       0, -1, "%d kB", bytes   /1024  );
  583.         SetStatusText(STAT_PROGRESS, 0, -1, "%d%%",  progress/100   );
  584.         SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecode       );
  585.         SetStatusText(STAT_SEQNO,    0, -1, "#%d", seqno            );
  586.  
  587.         if ((hwndTrackbar != NULL) && (timecode != 0))
  588.         {
  589.             if (StreamTotalTime != 0)
  590.             {
  591.                 SendMessage(hwndTrackbar, TBM_SETSELSTART,  FALSE,  0                                              );
  592.                 SendMessage(hwndTrackbar, TBM_SETSELEND,    TRUE,   (int)((float)10000*currenttime/StreamTotalTime));
  593.             }
  594.             else
  595.             {
  596.                 if (StreamMaxTime != 0)
  597.                 {
  598.                     SendMessage(hwndTrackbar, TBM_SETSELSTART,  FALSE,  0                                            );
  599.                     SendMessage(hwndTrackbar, TBM_SETSELEND,    TRUE,   (int)((float)10000*currenttime/StreamMaxTime));
  600.                 }
  601.                 else
  602.                 {
  603.                     SendMessage(hwndTrackbar, TBM_SETSELSTART,  FALSE,  0                                            );
  604.                     SendMessage(hwndTrackbar, TBM_SETSELEND,    TRUE,   10000                                        );
  605.                 }
  606.             }
  607.         }
  608.     }
  609. }
  610.  
  611.  
  612. void gui_modify_duration(unsigned int totaltime)
  613. {
  614.     /* called only for live recordings */
  615.  
  616.     LONG value;
  617.  
  618.     StreamTotalTime = totaltime;
  619.  
  620.     IMPTotalTime = (REFTIME)totaltime / 1000;
  621.     IMSTotalTime = (LONGLONG)totaltime * 10000;
  622.  
  623.     value = (LONG)(10000 * IMPCurrentPosition / IMPTotalTime);
  624.  
  625.     if (hwndTrackbar != NULL)
  626.     {
  627.         if (!TrackbarDragging)
  628.         {
  629.             SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, value);
  630.         }
  631.     }
  632. }
  633.  
  634.  
  635. void gui_finished_transmission()
  636. {
  637.     Transmitting = FALSE;
  638.     Previewing = FALSE;
  639.  
  640.     StreamTotalTime = 0;
  641.     StreamMaxTime = 0;
  642.  
  643.     if ( appVars. hwndMainFrame != NULL )
  644.     {
  645.         SetStatusText(STAT_KB,       0, -1, "");
  646.         SetStatusText(STAT_PROGRESS, 0, -1, "");
  647.         SetStatusText(STAT_TIMECODE, 0, -1, "");
  648.         SetStatusText(STAT_SEQNO,    0, -1, "");
  649.         
  650.         if (hwndTrackbar != NULL)
  651.         {
  652.             SendMessage(hwndTrackbar, TBM_CLEARSEL,    TRUE,  0     );
  653.         }
  654.         
  655.         UpdateToolbar();
  656.         
  657.         ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
  658.         SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
  659.                      SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
  660.     }
  661. }
  662.  
  663.  
  664. void gui_not_idle(int flag)
  665. {
  666.     if (flag)
  667.         Idle = FALSE;
  668.     else
  669.         Idle = TRUE;
  670. }
  671.  
  672. char *gui_translate_errorcode(int error)
  673. {
  674.     static char def[32];
  675.     char *result = def;
  676.     struct ErrorDef *ed = WinSockErrors;
  677.  
  678.     sprintf(def, "<%d>", error);
  679.  
  680.     for (;;)
  681.     {
  682.         if (ed->ErrorVal == -1) break;
  683.  
  684.         if (ed->ErrorVal == error)
  685.         {
  686.             result = ed->ErrorName;
  687.             break;
  688.         }
  689.         ed++;
  690.     }
  691.  
  692.     return result;
  693. }
  694.  
  695. static char username_buffer[256];
  696. static char password_buffer[256];
  697.  
  698. int gui_getpassword(char **username, char **password)
  699. {
  700.     int ret = 0;
  701.  
  702.     if (!Batchmode)
  703.     {
  704.         if (*username != NULL) strncpy(username_buffer, *username, sizeof(username_buffer)-1);
  705.         username[255]=0;
  706.         if (*password != NULL) strncpy(password_buffer, *password, sizeof(password_buffer)-1);
  707.         password[255]=0;
  708.     
  709.         if (DoEnterPasswordDialog( appVars.hInstance, appVars.hwndMainFrame ) == IDOK)
  710.         {
  711.             *username = username_buffer;
  712.             *password = password_buffer;
  713.             ret = 1;
  714.         }
  715.     }
  716.     else
  717.     {
  718.         /* in batch mode, password must be given on command line */
  719.         if (*username == NULL && *password == NULL)
  720.         {
  721.             /* cancel the authorization of no username/password given */
  722.             ret = 0;
  723.         }
  724.         else
  725.         {
  726.             ret = 1;
  727.         }
  728.     }
  729.  
  730.     return ret;
  731. }
  732.  
  733. static char proxy_buffer[512];
  734.  
  735. int gui_getproxy(char **proxy)
  736. {
  737.     int ret = 0;
  738.  
  739.     /* do not override command line proxy parameter */
  740.     if (*proxy == NULL)
  741.     {
  742.         LONG retval;
  743.         HKEY hkeyURLList;
  744.         DWORD dwResult;
  745.         
  746.         retval = RegCreateKeyEx(APPREGKEY_ROOT,
  747.             APPREGKEY_BASE,
  748.             0,
  749.             NULL,
  750.             REG_OPTION_NON_VOLATILE,
  751.             KEY_ALL_ACCESS,
  752.             NULL,
  753.             &hkeyURLList,
  754.             &dwResult);
  755.         
  756.         
  757.         if (retval != ERROR_SUCCESS)
  758.         {
  759.             gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
  760.         }
  761.         else
  762.         {
  763.             char buffer[512];
  764.             DWORD dwType;
  765.             DWORD dwSize;
  766.                 
  767.             dwSize = sizeof(buffer);
  768.             retval = RegQueryValueEx( hkeyURLList,
  769.                 "ProxyServer",
  770.                 0,
  771.                 &dwType,
  772.                 buffer,
  773.                 &dwSize );
  774.             
  775.             if (retval == ERROR_SUCCESS)
  776.             {
  777.                 if (dwType == REG_SZ)
  778.                 {
  779.                     strncpy(proxy_buffer, buffer, sizeof(proxy_buffer)-1);
  780.                     proxy_buffer[sizeof(proxy_buffer)-1] = 0;
  781.  
  782.                     /* return proxy only if buffer not empty */
  783.                     if (strcmp(proxy_buffer, ""))
  784.                     {
  785.                         *proxy = proxy_buffer;
  786.                         ret = 1;
  787.                     }
  788.                 }
  789.                 RegCloseKey(hkeyURLList);
  790.             }
  791.         }
  792.     }
  793.     return ret;
  794. }
  795.  
  796. /*------------------------ COMMON CONTROLS STUFF ----------------------------*/
  797.  
  798. //
  799. // InitMyControls
  800. //
  801. HRESULT InitMyControls(void)
  802. {
  803.     HRESULT hr;
  804.     DWORD major;
  805.     DWORD minor;
  806.     BOOL too_old = FALSE;
  807. #define MIN_MAJOR 4
  808. #define MIN_MINOR 72
  809.  
  810.     GetComCtlVersion(&major, &minor);
  811.  
  812.     if (major < MIN_MAJOR) too_old = TRUE;
  813.     else
  814.         if (major == MIN_MAJOR && minor < MIN_MINOR) too_old = TRUE;
  815.  
  816.     if (too_old)
  817.     {
  818.         char Buffer[200];
  819.  
  820.         sprintf(Buffer, "Your commctl32.dll is too old!\n"
  821.                         "You have version: %d.%d\n"
  822.                         "Required is at least version %d.%d",
  823.                         major, minor, MIN_MAJOR, MIN_MINOR);
  824.  
  825.         MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
  826.                     MB_APPLMODAL | MB_OK | MB_ICONERROR );
  827.  
  828.         hr = S_FALSE;
  829.     }
  830.     else
  831.     {
  832.         INITCOMMONCONTROLSEX icex;
  833.  
  834.         icex.dwSize  = sizeof(INITCOMMONCONTROLSEX);
  835.         icex.dwICC = ICC_WIN95_CLASSES;
  836.  
  837.         InitCommonControlsEx(&icex);
  838.  
  839.         hr = S_OK;
  840.     }
  841.     return hr;
  842. } // InitMyControls
  843.  
  844.  
  845. //
  846. // GetComCtlVersion
  847. //
  848. HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
  849. {
  850.     HINSTANCE   hComCtl;
  851.  
  852.     if(   IsBadWritePtr(pdwMajor, sizeof(DWORD)) ||
  853.         IsBadWritePtr(pdwMinor, sizeof(DWORD)))
  854.         return E_INVALIDARG;
  855.  
  856.     //load the DLL
  857.     hComCtl = LoadLibrary(TEXT("comctl32.dll"));
  858.  
  859.     if(hComCtl)
  860.     {
  861.         HRESULT           hr = S_OK;
  862.         DLLGETVERSIONPROC pDllGetVersion;
  863.  
  864.         /*
  865.         You must get this function explicitly because earlier versions of the DLL
  866.         don't implement this function. That makes the lack of implementation of the
  867.         function a version marker in itself.
  868.         */
  869.         pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hComCtl, TEXT("DllGetVersion"));
  870.  
  871.         if(pDllGetVersion)
  872.         {
  873.             DLLVERSIONINFO    dvi;
  874.  
  875.             ZeroMemory(&dvi, sizeof(dvi));
  876.             dvi.cbSize = sizeof(dvi);
  877.  
  878.             hr = (*pDllGetVersion)(&dvi);
  879.  
  880.             if(SUCCEEDED(hr))
  881.             {
  882.                 *pdwMajor = dvi.dwMajorVersion;
  883.                 *pdwMinor = dvi.dwMinorVersion;
  884.             }
  885.             else
  886.             {
  887.                 hr = E_FAIL;
  888.             }
  889.         }
  890.         else
  891.         {
  892.         /*
  893.         If GetProcAddress failed, then the DLL is a version previous to the one
  894.         shipped with IE 3.x.
  895.             */
  896.             *pdwMajor = 4;
  897.             *pdwMinor = 0;
  898.         }
  899.  
  900.         FreeLibrary(hComCtl);
  901.  
  902.         return hr;
  903.     }
  904.  
  905.     return E_FAIL;
  906.  
  907. } // GetComCtlVersion
  908.  
  909.  
  910. /*----------------------- STATUS BAR COMMON CONTROL -------------------------*/
  911.  
  912. //
  913. // InitStatusbar
  914. //
  915. BOOL InitStatusbar( HINSTANCE hInstance, HWND hwndMainFrame )
  916. {
  917.     BOOL success = FALSE;
  918.  
  919.     if (hwndStatusbar = DoCreateStatusbar(hwndMainFrame, IDR_STATUSBAR, hInstance, StatusDefinitionArray))
  920.     {
  921.         ShowWindow( hwndStatusbar, SW_SHOW );
  922.         UpdateWindow( hwndStatusbar );
  923.         success = TRUE;
  924.     }
  925.  
  926.     return success;
  927. } // InitStatusbar
  928.  
  929.  
  930. //
  931. // SetStatusText
  932. //
  933. void SetStatusText(int partno, int drawmode, COLORREF cref, LPSTR text,...)
  934. {
  935.     va_list arglist;
  936.     va_start(arglist, text);
  937.  
  938.     SetStatusTextArgs(partno, drawmode, cref, text, arglist);
  939.  
  940.     va_end(arglist);
  941.  
  942. } // SetStatusText
  943.  
  944.  
  945. //
  946. // StatusTimerFunc
  947. //
  948. void CALLBACK StatusTimerFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  949. {
  950.     if (uMsg == WM_TIMER && idEvent == StatusTimer)
  951.     {
  952.         StatusTimerCount--;
  953.         if (StatusTimerCount%2 == 0)
  954.             SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0,  (LPARAM) CLR_DEFAULT);
  955.         else
  956.             SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0,  (LPARAM) StatusTimerCref);
  957.     }
  958.  
  959.     if (StatusTimerCount == 0)
  960.         KillTimer( appVars.hwndMainFrame, StatusTimer );
  961. } // StatusTimerFunc
  962.  
  963.  
  964. //
  965. // SetStatusTextArgs
  966. //
  967. void SetStatusTextArgs(int partno, int drawmode, COLORREF cref, LPSTR text, void *args)
  968. {
  969.     if (hwndStatusbar != NULL)
  970.     {
  971.         char Buffer[1024];
  972.         vsprintf(Buffer, text, args);
  973.  
  974.         // Tell the status bar to create the window parts.
  975.         if (cref != -1)
  976.         {
  977.             SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0,  (LPARAM) cref);
  978.  
  979.             if (StatusTimer != 0)
  980.             {
  981.                 KillTimer( appVars.hwndMainFrame, StatusTimer);
  982.                 StatusTimerCount = 0;
  983.             }
  984.  
  985.             if (cref != CLR_DEFAULT)
  986.             {
  987.                 StatusTimerCref = cref;
  988.                 StatusTimerCount = 5;
  989.                 StatusTimer = SetTimer( appVars.hwndMainFrame, ID_STATUSTIMER, 200, StatusTimerFunc);
  990.             }
  991.         }
  992.         SendMessage(hwndStatusbar, SB_SETTEXT, (WPARAM) partno | drawmode,  (LPARAM) Buffer);
  993.         ShowWindow( hwndStatusbar, SW_SHOW );
  994.         UpdateWindow( hwndStatusbar );
  995.     }
  996. } // SetStatusTextArgs
  997.  
  998.  
  999. //
  1000. // CalcStatusSize
  1001. //
  1002. void CalcStatusSize ( SIZE *pSize, int *array )
  1003. {
  1004.     int i;
  1005.     int nParts;
  1006.     int *ptr;
  1007.     int mintotal = 0;
  1008.  
  1009.     nParts = *array;
  1010.     ptr = array+1;
  1011.     for (i = 0; i < nParts; i++)
  1012.     {
  1013.         int wmin = *ptr++;
  1014.         ptr++;
  1015.         mintotal += wmin;
  1016.     }
  1017.  
  1018.     pSize->cx = mintotal;
  1019.     pSize->cy = 20;
  1020.  
  1021.     if (hwndStatusbar != NULL)
  1022.     {
  1023.         RECT statRect;
  1024.         GetWindowRect(hwndStatusbar, &statRect);
  1025.         pSize->cy = statRect.bottom-statRect.top+1;
  1026.     }
  1027. }
  1028.  
  1029. //
  1030. // AdjustStatusbar
  1031. //
  1032. void AdjustStatusbar(HWND hwndStatus, HWND hwndParent, int *array)
  1033. {
  1034.     int nParts;
  1035.  
  1036.     RECT rcClient;
  1037.     HLOCAL hloc;
  1038.     LPINT lpParts;
  1039.     int i, x, nWidth;
  1040.     int *ptr;
  1041.     int mintotal = 0;
  1042.     int maxtotal = 0;
  1043.     int bendtotal = 0;
  1044.     int numunlim = 0;
  1045.     int weight = 0;
  1046.     int surplus, maxsurplus;
  1047.  
  1048.     // Get the coordinates of the parent window's client area.
  1049.     GetClientRect(hwndParent, &rcClient);
  1050.  
  1051.     nWidth = rcClient.right-rcClient.left+1;
  1052.  
  1053.     nParts = *array;
  1054.     ptr = array+1;
  1055.     for (i = 0; i < nParts; i++)
  1056.     {
  1057.         int wmin = *ptr++;
  1058.         int wmax = *ptr++;
  1059.  
  1060.         if (wmax!=-1)
  1061.         {
  1062.             mintotal += wmin;
  1063.             maxtotal += wmax;
  1064.             bendtotal += (wmax-wmin);
  1065.         }
  1066.         else
  1067.         {
  1068.             mintotal +=   wmin;
  1069.             maxtotal += 2*wmin;
  1070.             bendtotal +=  wmin;
  1071.             numunlim++;
  1072.         }
  1073.     }
  1074.  
  1075.     // Allocate an array for holding the right edge coordinates.
  1076.     hloc = LocalAlloc(LHND, sizeof(int) * nParts);
  1077.     lpParts = LocalLock(hloc);
  1078.  
  1079.     // Calculate the right edge coordinate for each part, and
  1080.     // copy the coordinates to the array.
  1081.     ptr = array+1;
  1082.     x = 0;
  1083.  
  1084.     surplus    = nWidth - mintotal;
  1085.     if (surplus<0) surplus=0;
  1086.     maxsurplus = nWidth - maxtotal;
  1087.     if (maxsurplus<0) maxsurplus=0;
  1088.  
  1089.     for (i = 0; i < nParts; i++)
  1090.     {
  1091.         int wmin = *ptr++;
  1092.         int wmax = *ptr++;
  1093.         int bend;
  1094.         int w = 0;
  1095.  
  1096.         if (wmax!=-1)
  1097.             bend = wmax-wmin;
  1098.         else
  1099.             bend = wmin;
  1100.  
  1101.         w = wmin + (surplus*bend/bendtotal);
  1102.         if (w > 2*wmin) w = 2*wmin;
  1103.  
  1104.         if (wmax==-1)
  1105.             w += maxsurplus / numunlim;
  1106.  
  1107.         if (w < wmin) w = wmin;
  1108.         if (wmax!=-1)
  1109.             if (w > wmax) w = wmax;
  1110.  
  1111.         x+= w;
  1112.  
  1113.         *(lpParts+i) = x;
  1114.     }
  1115.  
  1116.     // Tell the status bar to create the window parts.
  1117.     SendMessage(hwndStatus, SB_SETPARTS, (WPARAM) nParts, (LPARAM) lpParts);
  1118.  
  1119.     // Free the array, and return.
  1120.     LocalUnlock(hloc);
  1121.     LocalFree(hloc);
  1122.  
  1123. } // AdjustStatusbar
  1124.  
  1125.  
  1126. // DoCreateStatusbar - creates a status bar and divides it into
  1127. //                     the specified number of parts.
  1128. // Returns the handle to the status bar.
  1129. //        hwndParent - parent window for the status bar.
  1130. //         nStatusID - child window identifier.
  1131. //             hinst - handle to the application instance.
  1132. //            nParts - number of parts into which to divide the status bar.
  1133. HWND DoCreateStatusbar(HWND hwndParent, int nStatusID,
  1134.                        HINSTANCE hinst, int *array)
  1135. {
  1136.     HWND hwndStatus;
  1137.  
  1138.     // Create the status bar.
  1139.     hwndStatus = CreateWindowEx(
  1140.         0,                       // no extended styles
  1141.         STATUSCLASSNAME,         // name of status bar class
  1142.         (LPCTSTR) NULL,          // no text when first created
  1143.         SBARS_SIZEGRIP |         // includes a sizing grip
  1144.         WS_VISIBLE | WS_CHILD,   // creates a child window
  1145.         0, 0, 0, 0,              // ignores size and position
  1146.         hwndParent,              // handle to parent window
  1147.         (HMENU) nStatusID,       // child window identifier
  1148.         hinst,                   // handle to application instance
  1149.         NULL);                   // no window creation data
  1150.  
  1151.     AdjustStatusbar(hwndStatus, hwndParent, array);
  1152.     return hwndStatus;
  1153.  
  1154. } // DoCreateStatusbar
  1155.  
  1156.  
  1157.  
  1158. /*-------------------------- MESSAGE BOX ROUTINES ---------------------------*/
  1159.  
  1160. //
  1161. // DbgAssert
  1162. //
  1163. // Displays a message box if the condition evaluated to FALSE
  1164. //
  1165. void DbgAssert(const char *pCondition, const char *pFileName, int iLine)
  1166. {
  1167.     int MsgId;
  1168.     char szInfo[1024];
  1169.  
  1170.     wsprintf(szInfo, TEXT("%s \nAt line %d of %s"),pCondition, iLine, pFileName);
  1171.     MsgId = MessageBox(NULL, szInfo, TEXT("ASSERT Failed"),
  1172.                            MB_SYSTEMMODAL |
  1173.                            MB_ICONHAND |
  1174.                            MB_ABORTRETRYIGNORE);
  1175.     switch (MsgId)
  1176.     {
  1177.         case IDABORT:           // Kill the application
  1178.  
  1179.             FatalAppExit(FALSE, TEXT("Application terminated"));
  1180.             break;
  1181.  
  1182.         case IDRETRY:           // Break into the debugger
  1183.             DebugBreak();
  1184.             break;
  1185.  
  1186.         case IDIGNORE:          // Ignore assertion continue executing
  1187.             break;
  1188.     }
  1189. } // DbgAssert
  1190.  
  1191.  
  1192. //
  1193. // ReallyQuitMessageBox
  1194. //
  1195. // Ask the user wheter or not to quit
  1196. //
  1197. UINT ReallyQuitMessageBox( void )
  1198. {
  1199.     UINT retval;
  1200.  
  1201.     if (Transmitting == FALSE)
  1202.     {
  1203.         /* don't ask if there is no transmission in progress */
  1204.         retval = IDYES;
  1205.     }
  1206.     else
  1207.     {
  1208.         char szStr[ nMaxResourceStrSize ];
  1209.  
  1210.         LoadString( appVars.hInstance, IDS_REALLY_QUIT, szStr, nMaxResourceStrSize );
  1211.         retval = MessageBox( appVars.hwndMainFrame, szStr, appVars.szAppName,
  1212.                              MB_APPLMODAL | MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION );
  1213.     }
  1214.     return retval;
  1215.  
  1216. } // ReallyQuitMessageBox
  1217.  
  1218.  
  1219. //
  1220. // PlayerMessageBox
  1221. //
  1222. // Load and display an error message
  1223. //
  1224. void PlayerMessageBox( UINT nResource )
  1225. {
  1226.     char szStr[ nMaxResourceStrSize ];
  1227.  
  1228.     LoadString( appVars.hInstance, nResource, szStr, nMaxResourceStrSize );
  1229.     MessageBox( appVars.hwndMainFrame, szStr, appVars.szAppName,
  1230.                 MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION );
  1231.  
  1232. } // PlayerMessageBox
  1233.  
  1234.  
  1235. //
  1236. // OnShowReadme
  1237. //
  1238. void OnShowReadme()
  1239. {
  1240.     char szFileName[ _MAX_PATH ];
  1241.     char *szTitle;
  1242.     SHELLEXECUTEINFO sei;
  1243.     BOOL ret;
  1244.     
  1245.     // Work out the full path name
  1246.     if (GetFullPathName( appVars.szProgramExecutable, _MAX_PATH, szFileName, &szTitle ) > 0)
  1247.     {
  1248.         strcpy( szTitle, "README.TXT");
  1249.         
  1250.         memset(&sei, 0, sizeof(sei));
  1251.         sei.cbSize = sizeof(sei);
  1252.  
  1253.         sei.fMask = SEE_MASK_FLAG_NO_UI;
  1254.         sei.hwnd = appVars.hwndMainFrame;
  1255.         sei.lpVerb = "open";
  1256.         sei.lpParameters = NULL;
  1257.         sei.lpDirectory = NULL;
  1258.         sei.lpFile = szFileName;
  1259.         sei.nShow = SW_SHOW;
  1260.         
  1261.         ret = ShellExecuteEx(&sei);
  1262.         
  1263.         if (ret == FALSE)
  1264.         {
  1265.             if ((long)GetLastError() == ERROR_FILE_NOT_FOUND)
  1266.                 gui_criticalerror("Someone deleted the README.TXT\n"
  1267.                                   "file from the program directory!\n");
  1268.             else
  1269.                 gui_criticalerror("Cannot show the README.TXT file for some strange reason!\n");
  1270.         }
  1271.     }
  1272. }
  1273.  
  1274.                 
  1275. /*-------------------------- COMMAND HANDLING -------------------------------*/
  1276.  
  1277. //
  1278. // ProcessCommand
  1279. //
  1280. // Process a WM_COMMAND message to the main window
  1281. //
  1282. long ProcessCommand( HWND hwnd, UINT wParam, LONG lParam )
  1283. {
  1284.     switch( wParam ){
  1285.         case ID_URL_OPEN:
  1286.             DoOpenURLDialog( appVars.hInstance,hwnd );
  1287.             break;
  1288.  
  1289.         case ID_FILE_OPEN:
  1290.             if (OpenMediaFile( hwnd, NULL ))
  1291.                 OnMediaPlay( );
  1292.             break;
  1293.  
  1294.         case ID_FILE_EXIT:
  1295.             PostMessage( appVars.hwndMainFrame, WM_CLOSE, 0, 0 );
  1296.             break;
  1297.  
  1298.         case ID_MEDIA_PLAY:
  1299.             OnMediaPlay( );
  1300.             break;
  1301.  
  1302.         case ID_MEDIA_PAUSE:
  1303.             OnMediaPause( );
  1304.             break;
  1305.  
  1306.         case ID_MEDIA_STOP:
  1307.             OnMediaStop(FALSE, TRUE);
  1308.             break;
  1309.  
  1310.         case ID_MEDIA_EJECT:
  1311.             DeleteContents();
  1312.             break;
  1313.  
  1314.         case ID_STREAM_PREVIEW:
  1315.             if (strcmp( StreamFilename, "" ))
  1316.             {
  1317.                 if (OpenMediaFile( hwnd, StreamFilename ))
  1318.                 {
  1319.                     Previewing = TRUE;
  1320.                     OnMediaPlay( );
  1321.                 }
  1322.             }
  1323.             break;
  1324.  
  1325.         case ID_STREAM_CANCEL:
  1326.             gui_seterror("aborting transfer...");
  1327.             gui_abort();
  1328.             PostMessage(hwnd, WM_COMMAND, WM_QUIT, 0);
  1329.             break;
  1330.  
  1331.         case ID_SETTINGS_REGISTERFILETYPES:
  1332.             OnRegisterFileTypes();
  1333.             break;
  1334.  
  1335.         case ID_SETTINGS_UNREGISTERFILETYPES:
  1336.             OnUnregisterFileTypes();
  1337.             break;
  1338.  
  1339.         case ID_HELP_ABOUT:
  1340.             DoAboutDialog( appVars.hInstance,hwnd );
  1341.             break;
  1342.  
  1343.         case ID_PROGRAM_ARGUMENTS:
  1344.             Usage(appVars.szProgramExecutable, ShowUsage);
  1345.             break;
  1346.  
  1347.         case ID_SHOW_README:
  1348.             OnShowReadme();
  1349.             break;
  1350.  
  1351.         case ID_PROXY_SERVER:
  1352.             DoProxyConfigurationDialog( appVars.hInstance, hwnd );
  1353.             break;
  1354.  
  1355.         default:
  1356.             return DefWindowProc( hwnd, WM_COMMAND, wParam, lParam );
  1357.     }
  1358.     return (LRESULT) 0;
  1359.  
  1360. } // ProcessCommand
  1361.  
  1362. /*------------------------- WINDOW SIZE CALCULATIONS ------------------------*/
  1363.  
  1364. //
  1365. // OnGetMinMaxInfo
  1366. //
  1367. // Sets the minimum size of the main window and the maximum height
  1368. //
  1369. void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  1370. {
  1371.     RECT rectRequired;
  1372.     SIZE sizeToolbar;
  1373.     SIZE sizeStatus;
  1374.  
  1375.     // Our client area is going to be the toolbar, so find our its size
  1376.     CalcToolbarSize( &sizeToolbar );
  1377.  
  1378.     rectRequired.left = rectRequired.top = 0;
  1379.     rectRequired.right = sizeToolbar.cx;
  1380.     rectRequired.bottom = sizeToolbar.cy;
  1381.  
  1382.     CalcStatusSize( &sizeStatus, StatusDefinitionArray );
  1383.  
  1384.     if (sizeStatus.cx > rectRequired.right)
  1385.         rectRequired.right = sizeStatus.cx;
  1386.  
  1387.     rectRequired.bottom += sizeStatus.cy;
  1388.  
  1389.     // Take into account the menu, caption and thick frame
  1390.     AdjustWindowRect( &rectRequired, WS_CAPTION|WS_THICKFRAME, TRUE );
  1391.  
  1392.     // Set the min/max sizes
  1393.     lpMMI->ptMinTrackSize.x = rectRequired.right - rectRequired.left;
  1394.     lpMMI->ptMinTrackSize.y = rectRequired.bottom - rectRequired.top;
  1395.  
  1396. } // OnGetMinMaxInfo
  1397.  
  1398.  
  1399. /*------------------------- MAIN WINDOW PROCEDURE ---------------------------*/
  1400.  
  1401. typedef BOOL (FAR WINAPI *GradientFillFunction)(HDC,PTRIVERTEX,ULONG,PVOID,ULONG,ULONG);
  1402. GradientFillFunction GradientFillPtr;
  1403.  
  1404. //
  1405. // MainFrameProc
  1406. //
  1407. // Handles the message sent to the main window
  1408. //
  1409.  
  1410. long FAR PASCAL MainFrameProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
  1411. {
  1412.     DRAWITEMSTRUCT *dis;
  1413.  
  1414.     /******************************************************/
  1415.     /*      Handle inter-process communications here      */
  1416.     /******************************************************/
  1417.  
  1418.     /* Answer the probe-message with our current status. */
  1419.     /* Return MAGIC_COOKIE if we are able to handle      */
  1420.     /* other tasks                                       */
  1421.     if (message == WM_APPMSG)
  1422.     {
  1423.         if (Idle == TRUE)
  1424.         {
  1425.             Idle = FALSE;
  1426.             return (LRESULT) MAGIC_COOKIE;
  1427.         }
  1428.         else
  1429.         {
  1430.             return (LRESULT) 0;
  1431.         }
  1432.     }
  1433.  
  1434.     /* This message is only received when we just answered */
  1435.     /* the probe message with a MAGIC_COOKIE               */
  1436.     /* Now we will get the command line from another ASF-  */
  1437.     /* Recorder process                                    */
  1438.  
  1439.     if (message == WM_COPYDATA)
  1440.     {
  1441.         COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
  1442.  
  1443.         if (cds != NULL)
  1444.         {            
  1445.             if (cds->dwData == MAGIC_COOKIE)
  1446.             {
  1447.                 LPTSTR cmdline;
  1448.                 unsigned char buffer[1024];
  1449.                 int argc_bak = argc;      /* ParseCommandLine() operates          */
  1450.                 char **argv_bak = argv;   /* on global variables (backup needed!) */
  1451.                 
  1452.                 argc = 0;                 /* simulate "empty" command line */
  1453.                 argv = NULL;   
  1454.  
  1455.                 cmdline = cds->lpData;    /* copy the data from the WM_COPYDATA */
  1456.                 strcpy(buffer, cmdline);  /* message */
  1457.                 
  1458.                 if (ParseCommandLine(buffer))
  1459.                 {
  1460.                     /* tell the other process that we are now */
  1461.                     /* processing its command line */
  1462.                     ReplyMessage((LRESULT) MAGIC_COOKIE);
  1463.  
  1464.                     ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
  1465.                     SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
  1466.                                  SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
  1467.  
  1468.                     /* now process this command line */
  1469.                     main_function(argc, argv);
  1470.                 }
  1471.                 FreeCommandLine();
  1472.                 
  1473.                 /* restore the previous command line        */
  1474.                 /* (needed for FreeCommandLine() in WinMain */
  1475.                 argc = argc_bak;
  1476.                 argv = argv_bak;
  1477.             }
  1478.         }
  1479.  
  1480.         /* return to idle state (can accept other command lines now) */
  1481.         Idle = TRUE;
  1482.         return (LRESULT) 0;
  1483.     }
  1484.  
  1485.     switch( message )
  1486.     {
  1487.     case WM_CLOSE:
  1488.         if (ReallyQuitMessageBox() == IDYES)
  1489.         {
  1490.             if (DestroyWindow ( appVars.hwndMainFrame ))
  1491.             {
  1492.                 appVars.hwndMainFrame = NULL;
  1493.                 hwndAboutBox = NULL;
  1494.                 hwndOpenURLDialog = NULL;
  1495.                 hwndStatusbar = NULL;
  1496.                 toolbar.hwndPlayButton = NULL;
  1497.                 toolbar.hwndPauseButton = NULL;
  1498.                 toolbar.hwndStopButton = NULL;
  1499.                 toolbar.hwndPreviewButton = NULL;
  1500.                 toolbar.hwndCancelButton = NULL;
  1501.                 hwndTrackbar = NULL;
  1502.             }
  1503.         }
  1504.         break;
  1505.  
  1506.     case WM_DESTROY:
  1507.         gui_abort();
  1508.         PostQuitMessage( 0 );
  1509.         break;
  1510.  
  1511.     case WM_GETMINMAXINFO:
  1512.         OnGetMinMaxInfo( (MINMAXINFO FAR *) lParam );
  1513.         break;
  1514.  
  1515.     case WM_ERASEBKGND:
  1516.         {
  1517.             RECT rc;
  1518.             HDC hdc;
  1519.             SIZE sizeStatus;
  1520.  
  1521.             HMODULE msimg32;
  1522.  
  1523.             hdc = (HDC) wParam;
  1524.             GetClientRect(hwnd, &rc);
  1525.  
  1526.             /* try to load msimg32.dll (Win98, Win2000) */
  1527.             if ((msimg32 = LoadLibrary("msimg32.dll")) != NULL)
  1528.             {
  1529.                 TRIVERTEX          vert[4] ;
  1530.                 GRADIENT_TRIANGLE  gTri[2];
  1531.  
  1532.                 GradientFillPtr = (GradientFillFunction)GetProcAddress(msimg32, "GradientFill");
  1533.  
  1534.                 CalcStatusSize( &sizeStatus, StatusDefinitionArray );
  1535.                 rc.bottom -= (sizeStatus.cy-1);
  1536.  
  1537.                 vert [0] .x      = rc.left;
  1538.                 vert [0] .y      = rc.top;
  1539.                 vert [0] .Red    = 0xff00;
  1540.                 vert [0] .Green  = 0xff00;
  1541.                 vert [0] .Blue   = 0x8000;
  1542.                 vert [0] .Alpha  = 0x0000;
  1543.  
  1544.                 vert [1] .x      = rc.right;
  1545.                 vert [1] .y      = rc.top;
  1546.                 vert [1] .Red    = 0x6000;
  1547.                 vert [1] .Green  = 0x6000;
  1548.                 vert [1] .Blue   = 0x6000;
  1549.                 vert [1] .Alpha  = 0x0000;
  1550.  
  1551.                 vert [2] .x      = rc.right;
  1552.                 vert [2] .y      = rc.bottom;
  1553.                 vert [2] .Red    = 0x8000;
  1554.                 vert [2] .Green  = 0x4000;
  1555.                 vert [2] .Blue   = 0x0000;
  1556.                 vert [2] .Alpha  = 0x0000;
  1557.  
  1558.                 vert [3] .x      = rc.left;
  1559.                 vert [3] .y      = rc.bottom;
  1560.                 vert [3] .Red    = 0x6000;
  1561.                 vert [3] .Green  = 0x6000;
  1562.                 vert [3] .Blue   = 0x6000;
  1563.                 vert [3] .Alpha  = 0x0000;
  1564.  
  1565.                 gTri[0].Vertex1 = 0;
  1566.                 gTri[0].Vertex2 = 1;
  1567.                 gTri[0].Vertex3 = 2;
  1568.  
  1569.                 gTri[1].Vertex1 = 0;
  1570.                 gTri[1].Vertex2 = 3;
  1571.                 gTri[1].Vertex3 = 2;
  1572.  
  1573.                 (*GradientFillPtr)(hdc, vert,4, gTri, 2, GRADIENT_FILL_TRIANGLE);
  1574.  
  1575.                 FreeLibrary(msimg32);
  1576.             }
  1577.             else
  1578.             {
  1579.                 /* basic backfill functions for users not having the msimg32.dll */
  1580.                 HBRUSH brush = CreateSolidBrush(RGB(0xc0,0x80,0x00));
  1581.                 FillRect(hdc, &rc, brush);
  1582.                 DeleteObject(brush);
  1583.             }
  1584.         }
  1585.         return (LRESULT) 1;
  1586.         break;
  1587.  
  1588.     case WM_DRAWITEM:
  1589.         dis = (DRAWITEMSTRUCT FAR *) lParam;
  1590.         if (( dis->CtlType == ODT_BUTTON ) &&
  1591.             ( dis->CtlID == ID_MEDIA_PLAY     ||
  1592.               dis->CtlID == ID_MEDIA_PAUSE    ||
  1593.               dis->CtlID == ID_MEDIA_STOP)    ||
  1594.               dis->CtlID == ID_STREAM_PREVIEW ||
  1595.               dis->CtlID == ID_STREAM_CANCEL    )
  1596.         {
  1597.             DrawButton( appVars.hInstance, (DRAWITEMSTRUCT FAR *) lParam );
  1598.             return (LRESULT) 1;
  1599.         }
  1600.         break;
  1601.  
  1602.     case WM_INITMENUPOPUP:
  1603.         if( lParam == 1 )
  1604.         {          // Media popup menu
  1605.             EnableMenuItem( (HMENU) wParam, ID_MEDIA_PLAY,     CanPlay()       ? MF_ENABLED : MF_GRAYED );
  1606.             EnableMenuItem( (HMENU) wParam, ID_MEDIA_PAUSE,    CanPause()      ? MF_ENABLED : MF_GRAYED );
  1607.             EnableMenuItem( (HMENU) wParam, ID_MEDIA_STOP,     CanStop()       ? MF_ENABLED : MF_GRAYED );
  1608.             EnableMenuItem( (HMENU) wParam, ID_MEDIA_EJECT,    IsInitialized() ? MF_ENABLED : MF_GRAYED );
  1609.         }
  1610.         else
  1611.         {
  1612.             if( lParam == 2 )
  1613.             {          // Stream popup menu
  1614.                 EnableMenuItem( (HMENU) wParam, ID_STREAM_PREVIEW,  CanPreview() ? MF_ENABLED : MF_GRAYED );
  1615.                 EnableMenuItem( (HMENU) wParam, ID_STREAM_CANCEL,   Transmitting ? MF_ENABLED : MF_GRAYED );
  1616.             }
  1617.             else
  1618.             {
  1619.                 return DefWindowProc( hwnd, message, wParam, lParam );
  1620.             }
  1621.         }
  1622.         break;
  1623.  
  1624.     case WM_SIZE:
  1625.         SendMessage(hwndStatusbar, WM_SIZE, wParam, lParam);
  1626.         AdjustStatusbar(hwndStatusbar, appVars.hwndMainFrame, StatusDefinitionArray);
  1627.         AdjustTrackbar(hwndTrackbar, appVars.hwndMainFrame );
  1628.         return DefWindowProc( hwnd, message, wParam, lParam );
  1629.         break;
  1630.  
  1631.     case WM_PAINT:
  1632.         {
  1633.             PAINTSTRUCT ps;
  1634.             BeginPaint( hwnd, &ps );
  1635.  
  1636.             EndPaint( hwnd, &ps );
  1637.         }
  1638.         break;
  1639.  
  1640.     case WM_COMMAND:
  1641.         return ProcessCommand( hwnd, wParam, lParam );
  1642.         break;
  1643.  
  1644.     case WM_NOTIFY:
  1645.         {
  1646.             int id = wParam;
  1647.             LPNMHDR nmhdr = (LPNMHDR)lParam;
  1648.  
  1649.             if (nmhdr->hwndFrom == hwndTrackbar)
  1650.             {
  1651.                 if (nmhdr->code == NM_RELEASEDCAPTURE)
  1652.                 {
  1653.                     int pos;
  1654.                     pos = positionTrackbar;
  1655.                     SendMessage(hwndTrackbar, TBM_SETPOS, TRUE, pos);
  1656.                     SetCurrentPosition((REFTIME)((REFTIME)pos/10000 * IMPTotalTime));
  1657.                 }
  1658.             }
  1659.         }
  1660. //        return DefWindowProc( hwnd, message, wParam, lParam );
  1661.         break;
  1662.  
  1663.     case WM_HSCROLL:
  1664.         {
  1665.             HWND hwndFrom = (HWND)lParam;
  1666.             if (hwndFrom == hwndTrackbar)
  1667.             {
  1668.                 int pos  = HIWORD(wParam);
  1669.                 int code = LOWORD(wParam);
  1670.  
  1671.                 switch(code)
  1672.                 {
  1673.                     case TB_THUMBTRACK:
  1674.                         {
  1675.                             unsigned int timecode;
  1676.                             char *timecodestring;
  1677.  
  1678.                             if (Previewing)
  1679.                             {
  1680.                                 int prevpos = pos;
  1681.                                 int min=SendMessage(hwndTrackbar, TBM_GETSELSTART, 0, 0);
  1682.                                 int max=SendMessage(hwndTrackbar, TBM_GETSELEND,   0, 0);
  1683.                                 if (pos < min) pos = min;
  1684.                                 if (pos > max) pos = max;
  1685.                                 if (pos != prevpos) SendMessage(hwndTrackbar, TBM_SETPOS, TRUE, pos);
  1686.                             }
  1687.  
  1688.                             /* save the current position of the trackbar slider */
  1689.                             positionTrackbar = pos;
  1690.  
  1691.                             if (!Transmitting)
  1692.                             {
  1693.                                 timecode = (unsigned int)((float)pos/10000 * (1000*IMPTotalTime));
  1694.                                 timecodestring = createtimestring(timecode);
  1695.                                 SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecodestring);
  1696.                             }
  1697.  
  1698.                             if (TrackbarDragging == FALSE)
  1699.                                 OnMediaSeeking(TRUE);
  1700.  
  1701.                             TrackbarDragging = TRUE;
  1702.                         }
  1703.                         break;
  1704.  
  1705.                     case TB_THUMBPOSITION:
  1706.                         {
  1707.                             /* save the position of the trackbar slider /*
  1708.                             /* when we released the mouse button */
  1709.                             positionTrackbar = SendMessage(hwndTrackbar, TBM_GETPOS, 0, 0);
  1710.  
  1711.                             if (TrackbarDragging == TRUE)
  1712.                                 OnMediaSeeking(FALSE);
  1713.  
  1714.                             TrackbarDragging = FALSE;
  1715.                         }
  1716.                         break;
  1717.  
  1718.                     default:
  1719.                         break;
  1720.                 }
  1721.             }
  1722.         }
  1723. //        return DefWindowProc( hwnd, message, wParam, lParam );
  1724.         break;
  1725.  
  1726.     /* handle drag & drop */
  1727.     case WM_DROPFILES:
  1728.         {
  1729.             HANDLE hDrop = (HANDLE) wParam;
  1730.             UINT numfiles;
  1731.             char buffer[512];
  1732.             unsigned char *dotptr, *tmpptr;
  1733.  
  1734.             numfiles = DragQueryFile(hDrop, 0xffffffff, buffer, sizeof(buffer));
  1735.  
  1736.             if (numfiles > 1)
  1737.             {
  1738.                 PlayerMessageBox( IDS_DROP_ONLY_ONE );
  1739.             }
  1740.  
  1741.             if (numfiles > 0)
  1742.             {
  1743.                 DragQueryFile(hDrop, 0, buffer, sizeof(buffer));
  1744.             }
  1745.  
  1746.             DragFinish(hDrop);
  1747.  
  1748.             /* search for filename extension */
  1749.             for (dotptr = buffer+strlen(buffer), tmpptr = buffer; (tmpptr = strchr(tmpptr, '.')) != NULL ; dotptr = tmpptr++);
  1750.  
  1751.             /* search for redirection file name extension */
  1752.             if ( (!stricmp(dotptr, ".asx")) ||
  1753.                  (!stricmp(dotptr, ".wax")) ||
  1754.                  (!stricmp(dotptr, ".wvx")) ||
  1755.                  (!stricmp(dotptr, ".wmx"))   )
  1756.             {
  1757.                 if (Transmitting)
  1758.                 {
  1759.                     PlayerMessageBox( IDS_TRANSMISSION_RUNNING );
  1760.                 }
  1761.                 else
  1762.                 {
  1763.                     /* call main_function() to process redirection file */
  1764.                     unsigned char *(my_argv[2]);
  1765.  
  1766.                     int my_argc = 2;
  1767.                     my_argv[0] = appVars.szProgramExecutable;
  1768.                     my_argv[1] = buffer;
  1769.  
  1770.                     main_function(my_argc, (char**)my_argv);
  1771.                 }
  1772.             }
  1773.             else
  1774.             {
  1775.                 /* try to play file as media file */
  1776.                 if (OpenMediaFile( hwnd, buffer ))
  1777.                     OnMediaPlay( );
  1778.             }
  1779.         }
  1780.         break;
  1781.  
  1782.     default:
  1783.         return DefWindowProc( hwnd, message, wParam, lParam );
  1784.     }
  1785.  
  1786.     return (LRESULT) 0;
  1787.  
  1788. } // MainFrameProc
  1789.  
  1790.  
  1791. /*---------------------- INITIALIZATION/CLEANUP ROUTINES --------------------*/
  1792.  
  1793. //
  1794. // InitApplication
  1795. //
  1796. BOOL InitApplication()
  1797. {
  1798.     strcpy( appVars.szAppName, APP_NAME );
  1799.  
  1800.     // Filter interface initialize?
  1801.     if( SUCCEEDED( CoInitialize( NULL )))
  1802.         return TRUE;
  1803.  
  1804.     return FALSE;
  1805.  
  1806. } // InitApplication
  1807.  
  1808.  
  1809. //
  1810. // UnInitApplication
  1811. //
  1812. void UnInitApplication()
  1813. {
  1814.     CoUninitialize( );
  1815.  
  1816. } // UnInitApplication
  1817.  
  1818.  
  1819. //
  1820. // InitInstance
  1821. //
  1822. // Set the specific instance data and register our main
  1823. // window class if it has not been registered already
  1824. //
  1825. BOOL InitInstance( HANDLE hInstance, HANDLE hPrevInstance )
  1826. {
  1827.     appVars.hInstance = hInstance;
  1828.  
  1829.     if(!hPrevInstance)
  1830.     {
  1831.         WNDCLASS wndClass;
  1832.  
  1833.         wndClass.style          = CS_HREDRAW | CS_VREDRAW;
  1834.         wndClass.lpfnWndProc    = MainFrameProc;
  1835.         wndClass.cbClsExtra     = 0;
  1836.         wndClass.cbWndExtra     = 0;
  1837.         wndClass.hInstance      = appVars.hInstance;
  1838.         wndClass.hIcon          = LoadIcon( appVars.hInstance, MAKEINTRESOURCE( IDI_APPLICATION_ICON ));
  1839.         wndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  1840.         wndClass.hbrBackground  = (HBRUSH)(COLOR_BACKGROUND + 1);
  1841.         wndClass.lpszMenuName   = MAKEINTRESOURCE( IDM_MAINFRAME );
  1842.         wndClass.lpszClassName  = appVars.szAppName;
  1843.  
  1844.         RegisterClass( &wndClass );
  1845.  
  1846.         if ( InitMyControls() == S_OK )
  1847.         {
  1848.             return TRUE;
  1849.         }
  1850.  
  1851.         return FALSE;
  1852.  
  1853.     }
  1854.  
  1855.     return TRUE;
  1856.  
  1857. } // InitInstance
  1858.  
  1859.  
  1860. //
  1861. // InitMainFrame
  1862. //
  1863. // Create our main window
  1864. //
  1865. BOOL InitMainFrame( int nCmdShow )
  1866. {
  1867.     const DWORD Styles = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) &~ WS_MAXIMIZEBOX;
  1868.     char szTitle[ 30 ];
  1869.  
  1870.     strcpy( szTitle, APP_NAME );
  1871.     strcat( szTitle, UNTITLED_STRING );
  1872.  
  1873.     appVars.hwndMainFrame =
  1874.         CreateWindowEx( WS_EX_ACCEPTFILES,
  1875.                       appVars.szAppName,    // Our class name
  1876.                       szTitle,              // Window title
  1877.                       Styles,               // It's styles
  1878.                       CW_USEDEFAULT,        // No x position
  1879.                       CW_USEDEFAULT,        // And no y either
  1880.                       0, 65,                // Initial sizes
  1881.                       NULL,                 // No parent window
  1882.                       NULL,                 // And no menu
  1883.                       appVars.hInstance,    // App instance
  1884.                       NULL);                // Creation data
  1885.  
  1886.     DragAcceptFiles( appVars.hwndMainFrame, TRUE);
  1887.  
  1888.     ShowWindow( appVars.hwndMainFrame, nCmdShow );
  1889.     UpdateWindow( appVars.hwndMainFrame );
  1890.     return TRUE;
  1891.  
  1892. } // InitMainFrame
  1893.  
  1894. /*-------------------------- BUSY POINTER ROUTINE ---------------------------*/
  1895.  
  1896. int BusyNest = 0;
  1897.  
  1898. //
  1899. // SetBusy
  1900. //
  1901. void SetBusy(BOOL flag)
  1902. {
  1903.     if (flag == TRUE)
  1904.     {
  1905.         BusyNest++;
  1906.         if (BusyNest > 0) SetCursor( LoadCursor( NULL, IDC_WAIT ) );
  1907.     }
  1908.     else
  1909.     {
  1910.         if (BusyNest > 0) BusyNest--;
  1911.  
  1912.         if (BusyNest == 0) SetCursor( LoadCursor( NULL, IDC_ARROW ) );
  1913.     }
  1914.  
  1915. } // SetBusy
  1916.  
  1917.  
  1918. /*-------------------- MAIN EVENT LOOP/MESSAGE HANDLING ---------------------*/
  1919.  
  1920. //
  1921. // DoMainLoop
  1922. //
  1923. // Main message loop
  1924. //
  1925. int DoMainLoop(int network_mask)
  1926. {
  1927.     MSG msg;
  1928.  
  1929.     BOOL network_event = FALSE;
  1930.     int network_retval = 0;
  1931.  
  1932.     // Message loop lasts until we get a WM_QUIT message
  1933.     // Upon which we shall return from the function
  1934.  
  1935.     // Message loop also exits when network activity is
  1936.     // dectected (only if network is set to TRUE)
  1937.  
  1938.     for (;;)
  1939.     {
  1940.         // Read all of the messages in this next loop
  1941.         // removing each message as we read it
  1942.  
  1943.         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == 1)
  1944.         {
  1945.             if (msg.message == WM_QUIT)
  1946.                 return msg.wParam;
  1947.  
  1948.             if (hwndAboutBox != NULL)
  1949.                 if (IsDialogMessage(hwndAboutBox, &msg)) continue;
  1950.  
  1951.             if (hwndOpenURLDialog != NULL)
  1952.                 if (IsDialogMessage(hwndOpenURLDialog, &msg)) continue;
  1953.  
  1954.             TranslateMessage(&msg);
  1955.             DispatchMessage(&msg);
  1956.         }
  1957.  
  1958.  
  1959.         // The following code waits for the arrival of new messages, i.e.
  1960.         // it puts the task to sleep. This is a non-desired behaviour if
  1961.         // we must react to a network event.
  1962.  
  1963.         if (network_event == FALSE)
  1964.         {
  1965.             HANDLE  ahObjects[10];       // Handles that need to be waited on
  1966.             int cObjects = 0;                // Number of objects that we have
  1967.             int cGraphIndex = -1;
  1968.             int cNetworkIndex = -1;
  1969.  
  1970.             ahObjects [cObjects] = GetGraphEventHandle();
  1971.             if (ahObjects[cObjects] != NULL)
  1972.             {
  1973.                 cGraphIndex = cObjects;
  1974.                 cObjects++;
  1975.             }
  1976.  
  1977.             if (NetworkEvent != WSA_INVALID_EVENT)
  1978.             {
  1979.                 ahObjects[cObjects] = NetworkEvent;
  1980.                 cNetworkIndex = cObjects;
  1981.                 cObjects++;
  1982.             }
  1983.  
  1984.             if( cObjects == 0 )
  1985.             {
  1986.                 WaitMessage();
  1987.             }
  1988.             else
  1989.             {
  1990.                 DWORD Result;
  1991.  
  1992.                 // Wait for any message or a graph notification
  1993.  
  1994.                 Result = MsgWaitForMultipleObjects( cObjects,
  1995.                                                     ahObjects,
  1996.                                                     FALSE,
  1997.                                                     INFINITE,
  1998.                                                     QS_ALLINPUT );
  1999.  
  2000.                 // Have we received an event notification
  2001.  
  2002.                 if( Result != (WAIT_OBJECT_0 + cObjects) )
  2003.                 {
  2004.                     if (cGraphIndex != -1)
  2005.                     {
  2006.                         if( Result == WAIT_OBJECT_0 + cGraphIndex)
  2007.                         {
  2008.                             OnGraphNotify();
  2009.                         }
  2010.                     }
  2011.  
  2012.                     if (cNetworkIndex != -1)
  2013.                     {
  2014.                         if( Result == WAIT_OBJECT_0 + cNetworkIndex)
  2015.                         {
  2016.                             WSANETWORKEVENTS wsane;
  2017.                             if (WSAEnumNetworkEvents(NetworkSocket, NetworkEvent, &wsane) == SOCKET_ERROR)
  2018.                             {
  2019.                                 gui_criticalerror("WSAEnumNetworkEvents() failed! Error code: %d\n", WSAGetLastError());
  2020.                             }
  2021.                             else
  2022.                             {
  2023.                                 if (wsane.lNetworkEvents & FD_CONNECT)
  2024.                                 {
  2025.                                     network_retval = wsane.iErrorCode[FD_CONNECT_BIT];
  2026.                                 }
  2027.                                 else
  2028.                                 {
  2029.                                     network_retval = 0;
  2030.                                 }
  2031.                                 network_event = TRUE;
  2032.                             }
  2033.                         }
  2034.                     }
  2035.                 }
  2036.             }
  2037.         }
  2038.  
  2039.         if (network_event == TRUE)
  2040.             break;
  2041.  
  2042.     }
  2043.  
  2044.     // if we end up here, we must have received a network event
  2045.     return network_retval;
  2046.  
  2047. } // DoMainLoop
  2048.  
  2049.  
  2050. /*--------------------------- PSEUDO WINMAIN CODE ---------------------------*/
  2051.  
  2052. //
  2053. // PseudoWinMain
  2054. //
  2055. // former WinMain code. Now called from real WinMain
  2056. //
  2057. int PASCAL PseudoWinMain( HINSTANCE hInstance,
  2058.                           HINSTANCE hPrevInstance,
  2059.                           LPSTR lpszCmdParam,
  2060.                           int nCmdShow )
  2061. {
  2062.     UINT nReturn = 0;
  2063.  
  2064.     // Initialise COM and the application
  2065.     if ( InitApplication() == FALSE ) return 0;
  2066.  
  2067.     if( InitInstance( hInstance, hPrevInstance ) &&
  2068.         InitMainFrame( nCmdShow ) &&
  2069.         InitToolbar( hInstance, appVars.hwndMainFrame ) &&
  2070.         InitStatusbar( hInstance, appVars.hwndMainFrame ) &&
  2071.         InitTrackbar( hInstance, appVars.hwndMainFrame ) &&
  2072.         InitMedia( ) &&
  2073.         InitFileOpenDialog( appVars.hwndMainFrame ) &&
  2074.         InitFileSaveDialog( appVars.hwndMainFrame ))
  2075.     {
  2076.         nReturn = 1;
  2077.     }
  2078.  
  2079.     return nReturn;
  2080.  
  2081. } // WinMain
  2082.  
  2083.  
  2084. //
  2085. // EndOfWinMain
  2086. //
  2087. // former end part of WinMain code. Now called from real WinMain
  2088. //
  2089. void EndOfWinMain(void)
  2090. {
  2091.     // Stop the graph if we can
  2092.     if( CanStop() )
  2093.             OnMediaStop(TRUE, FALSE);
  2094.  
  2095.     // Release the filter graph
  2096.     DeleteContents();
  2097.  
  2098.     UnInitApplication();
  2099.  
  2100. } // EndOfWinMain
  2101.  
  2102.  
  2103. /*--------------------------- ABOUT DIALOG BOX ------------------------------*/
  2104.  
  2105.  
  2106. // Simply handles the Help..About dialog box
  2107.  
  2108. //
  2109. // AboutDlgProc
  2110. //
  2111. BOOL FAR PASCAL AboutDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
  2112. {
  2113.     DRAWITEMSTRUCT *dis;
  2114.  
  2115.     switch( message )
  2116.     {
  2117.         case WM_INITDIALOG:
  2118.            return (LRESULT) 1;
  2119.  
  2120.         case WM_DRAWITEM:
  2121.         dis = (DRAWITEMSTRUCT FAR *) lParam;
  2122.         if (( dis->CtlType == ODT_STATIC ) &&
  2123.             ( dis->CtlID == IDC_ASFRECORDER_BITMAP ))
  2124.         {
  2125.             HDC hSourceDC = CreateCompatibleDC( NULL );
  2126.             HGDIOBJ loadedbitmap;
  2127.             HGDIOBJ hgdiOldBitmap;
  2128.             
  2129.             loadedbitmap = (HGDIOBJ) LoadImage( appVars.hInstance, MAKEINTRESOURCE( IDB_ASFRECORDER ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
  2130.             hgdiOldBitmap = SelectObject( hSourceDC, loadedbitmap );
  2131.             
  2132.             // ..and blit it
  2133.             BitBlt( dis->hDC,
  2134.                 dis->rcItem.left,
  2135.                 dis->rcItem.top ,
  2136.                 dis->rcItem.right-dis->rcItem.left+1,
  2137.                 dis->rcItem.bottom-dis->rcItem.top+1,
  2138.                 hSourceDC,
  2139.                 0,
  2140.                 0,
  2141.                 SRCCOPY
  2142.                 );
  2143.             
  2144.             // Restore the original bitmap
  2145.             SelectObject( hSourceDC, hgdiOldBitmap );
  2146.             
  2147.             // this was missing from the Microsoft example code
  2148.             DeleteObject(loadedbitmap);
  2149.             DeleteDC(hSourceDC);
  2150.             return (LRESULT) 1;
  2151.         }
  2152.         break;
  2153.  
  2154.  
  2155.         case WM_COMMAND:
  2156.             if( wParam==IDOK || wParam==IDCANCEL )
  2157.             {
  2158.                 if (DestroyWindow( hwndAboutBox ))
  2159.                     hwndAboutBox = NULL;
  2160.                 return (LRESULT) 1;
  2161.             }
  2162.     }
  2163.     return (LRESULT) 0;
  2164.  
  2165. } // AboutDlgProc
  2166.  
  2167.  
  2168. //
  2169. // DoAboutDialog
  2170. //
  2171. void DoAboutDialog( HINSTANCE hInstance, HANDLE hwnd )
  2172. {
  2173.     if (hwndAboutBox == NULL)
  2174.     {
  2175.         hwndAboutBox = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_ABOUTBOX ), hwnd, AboutDlgProc );
  2176.     }
  2177.  
  2178.     if (hwndAboutBox != NULL)
  2179.     {
  2180.         ShowWindow(hwndAboutBox, SW_SHOW);
  2181.         BringWindowToTop( hwndAboutBox );
  2182.     }
  2183.  
  2184. } // DoAboutDialog
  2185.  
  2186.  
  2187.  
  2188. /*--------------------------- OPEN URL DIALOG BOX ---------------------------*/
  2189.  
  2190.  
  2191. // Non-modal Open URL dialog
  2192.  
  2193. //
  2194. // OpenURLDlgProc
  2195. //
  2196. BOOL FAR PASCAL OpenURLDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
  2197. {
  2198.     switch( message )
  2199.     {
  2200.         case WM_INITDIALOG:
  2201.         {
  2202.             HWND combo;
  2203.             if (combo = GetDlgItem( hwnd, IDC_URLCOMBO ))
  2204.             {
  2205.                 LONG retval;
  2206.                 HKEY hkeyURLList;
  2207.                 DWORD dwResult;
  2208.  
  2209.                 retval = RegCreateKeyEx(APPREGKEY_ROOT,
  2210.                                         APPREGKEY_URLLIST,
  2211.                                         0,
  2212.                                         NULL,
  2213.                                         REG_OPTION_NON_VOLATILE,
  2214.                                         KEY_ALL_ACCESS,
  2215.                                         NULL,
  2216.                                         &hkeyURLList,
  2217.                                         &dwResult);
  2218.  
  2219.  
  2220.                 if (retval != ERROR_SUCCESS)
  2221.                 {
  2222.                     gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
  2223.                 }
  2224.                 else
  2225.                 {
  2226.                     DWORD dwIndex;
  2227.                     char keyname[32];
  2228.                     char buffer[512];
  2229.                     DWORD dwType;
  2230.                     DWORD dwSize;
  2231.  
  2232.                     for (dwIndex = 0 ; dwIndex < URLS_TO_REMEMBER ; dwIndex++)
  2233.                     {
  2234.                         sprintf(keyname, "URL%d", dwIndex);
  2235.  
  2236.                         dwSize = sizeof(buffer);
  2237.                         retval = RegQueryValueEx( hkeyURLList,
  2238.                                                   keyname,
  2239.                                                   0,
  2240.                                                   &dwType,
  2241.                                                   buffer,
  2242.                                                   &dwSize );
  2243.  
  2244.                         if (retval != ERROR_SUCCESS)
  2245.                         {
  2246.                             break;
  2247.                         }
  2248.                         else
  2249.                         {
  2250.                             if (dwType == REG_SZ)
  2251.                             {
  2252.                                 retval = SendMessage(combo, CB_ADDSTRING, (WPARAM)0, (LPARAM)buffer);
  2253.  
  2254.                                 if (dwIndex == 0)
  2255.                                 {
  2256.                                     retval = SendMessage(combo, CB_SETCURSEL, (WPARAM)dwIndex, 0);
  2257.                                 }
  2258.                             }
  2259.                         }
  2260.                     }
  2261.                     RegCloseKey(hkeyURLList);
  2262.                 }
  2263.             }
  2264.             return (LRESULT) 1;
  2265.         }
  2266.  
  2267.         case WM_COMMAND:
  2268.         {
  2269.             int my_argc;
  2270.             char *(my_argv[2]);
  2271.  
  2272.             char buffer[512];
  2273.             strcpy(buffer, "");
  2274.  
  2275.             if (wParam==IDOK)
  2276.             {
  2277.                 HWND combo;
  2278.                 int textlength;
  2279.                 if (combo = GetDlgItem( hwndOpenURLDialog, IDC_URLCOMBO ))
  2280.                 {
  2281.                     textlength = SendMessage(combo , WM_GETTEXTLENGTH, 0, 0);
  2282.                     if (textlength > sizeof(buffer)-1) textlength = sizeof(buffer)-1;
  2283.                     SendMessage(combo, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)buffer);
  2284.                 }
  2285.  
  2286.                 if ( strcmp(buffer, "") )
  2287.                 {
  2288.                     HWND combo;
  2289.                     if (combo = GetDlgItem( hwndOpenURLDialog, IDC_URLCOMBO ))
  2290.                     {
  2291.                         LONG retval;
  2292.                         HKEY hkeyURLList;
  2293.                         DWORD dwResult;
  2294.  
  2295.                         retval = RegCreateKeyEx(APPREGKEY_ROOT,
  2296.                                                 APPREGKEY_URLLIST,
  2297.                                                 0,
  2298.                                                 NULL,
  2299.                                                 REG_OPTION_NON_VOLATILE,
  2300.                                                 KEY_ALL_ACCESS,
  2301.                                                 NULL,
  2302.                                                 &hkeyURLList,
  2303.                                                 &dwResult);
  2304.  
  2305.                         if (retval != ERROR_SUCCESS)
  2306.                         {
  2307.                             gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
  2308.                         }
  2309.                         else
  2310.                         {
  2311.                             DWORD dwIndex;
  2312.                             char keyname[32];
  2313.                             char buffer[512];
  2314.  
  2315.                             retval = SendMessage(combo, WM_GETTEXT, (WPARAM)sizeof(buffer), (LPARAM)buffer);
  2316.                             dwIndex = SendMessage(combo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
  2317.                             if (dwIndex != CB_ERR)
  2318.                             {
  2319.                                 retval = SendMessage(combo, CB_DELETESTRING, (WPARAM)dwIndex, (LPARAM)0);
  2320.                             }
  2321.                             retval = SendMessage(combo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)buffer);
  2322.  
  2323.                             for (dwIndex = 0 ; dwIndex < URLS_TO_REMEMBER ; dwIndex++)
  2324.                             {
  2325.                                 retval = SendMessage(combo, CB_GETLBTEXT, (WPARAM)dwIndex, (LPARAM)buffer);
  2326.                                 if (retval == CB_ERR)
  2327.                                 {
  2328.                                     break;
  2329.                                 }
  2330.  
  2331.                                 sprintf(keyname, "URL%d", dwIndex);
  2332.  
  2333.                                 retval = RegSetValueEx( hkeyURLList,
  2334.                                                         keyname,
  2335.                                                         0,
  2336.                                                         REG_SZ,
  2337.                                                         buffer,
  2338.                                                         strlen(buffer)+1 );
  2339.  
  2340.                                 if (retval != ERROR_SUCCESS)
  2341.                                 {
  2342.                                     gui_criticalerror("RegSetValueEx failed: %d\n", retval);
  2343.                                 }
  2344.                             }
  2345.                             RegCloseKey(hkeyURLList);
  2346.                         }
  2347.                     }
  2348.  
  2349.                     if (DestroyWindow( hwndOpenURLDialog ))
  2350.                         hwndOpenURLDialog = NULL;
  2351.  
  2352.                     my_argc = 2;
  2353.  
  2354.                     my_argv[0] = appVars.szProgramExecutable;
  2355.                     my_argv[1] = buffer;
  2356.  
  2357.                     main_function(my_argc, my_argv);
  2358.                 }
  2359.             }
  2360.  
  2361.             if ( wParam==IDOK || wParam==IDCANCEL )
  2362.             {
  2363.                 if (hwndOpenURLDialog != NULL)
  2364.                 {
  2365.                     if (DestroyWindow( hwndOpenURLDialog ))
  2366.                         hwndOpenURLDialog = NULL;
  2367.                 }
  2368.             }
  2369.  
  2370.             return (LRESULT) 1;
  2371.         }
  2372.     }
  2373.     return (LRESULT) 0;
  2374.  
  2375. } // OpenURLDlgProc
  2376.  
  2377.  
  2378. //
  2379. // DoOpenURLDialog
  2380. //
  2381. void DoOpenURLDialog( HINSTANCE hInstance, HANDLE hwnd )
  2382. {
  2383.     if (Transmitting == FALSE)
  2384.     {
  2385.         if (hwndOpenURLDialog == NULL)
  2386.         {
  2387.             hwndOpenURLDialog = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_OPEN_URL ), hwnd, OpenURLDlgProc );
  2388.         }
  2389.  
  2390.         if (hwndOpenURLDialog != NULL)
  2391.         {
  2392.             ShowWindow(hwndOpenURLDialog, SW_SHOW);
  2393.             BringWindowToTop( hwndOpenURLDialog );
  2394.         }
  2395.     }
  2396.     else
  2397.     {
  2398.         PlayerMessageBox( IDS_TRANSMISSION_RUNNING );
  2399.     }
  2400.  
  2401. } // DoOpenURLDialog
  2402.  
  2403.  
  2404.  
  2405. /*------------------------ ENTER PASSWORD DIALOG BOX ------------------------*/
  2406.  
  2407.  
  2408. // Modal Enter Password dialog
  2409.  
  2410. //
  2411. // EnterPasswordDlgProc
  2412. //
  2413. BOOL FAR PASCAL EnterPasswordDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
  2414. {
  2415.     switch( message )
  2416.     {
  2417.         case WM_INITDIALOG:
  2418.         {
  2419.             HWND edit;
  2420.             if (edit = GetDlgItem( hwnd, IDC_USERNAME_EDIT ))
  2421.             {
  2422.                 SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)username_buffer);
  2423.             }
  2424.             if (edit = GetDlgItem( hwnd, IDC_PASSWORD_EDIT ))
  2425.             {
  2426.                 SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)password_buffer);
  2427.             }
  2428.             return (LRESULT) 1;
  2429.         }
  2430.  
  2431.         case WM_COMMAND:
  2432.         {
  2433.             if (wParam==IDOK)
  2434.             {
  2435.                 HWND edit;
  2436.                 int textlength;
  2437.                 if (edit = GetDlgItem( hwnd, IDC_USERNAME_EDIT ))
  2438.                 {
  2439.                     textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
  2440.                     if (textlength > sizeof(username_buffer)-1) textlength = sizeof(username_buffer)-1;
  2441.                     SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)username_buffer);
  2442.                 }
  2443.                 if (edit = GetDlgItem( hwnd, IDC_PASSWORD_EDIT ))
  2444.                 {
  2445.                     textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
  2446.                     if (textlength > sizeof(password_buffer)-1) textlength = sizeof(password_buffer)-1;
  2447.                     SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)password_buffer);
  2448.  
  2449.                 }
  2450.             }
  2451.  
  2452.             if ( wParam==IDOK || wParam==IDCANCEL )
  2453.             {
  2454.                 EndDialog(hwnd, wParam);
  2455.             }
  2456.  
  2457.             return (LRESULT) 1;
  2458.         }
  2459.     }
  2460.     return (LRESULT) 0;
  2461.  
  2462. } // EnterPasswordDlgProc
  2463.  
  2464.  
  2465. //
  2466. // DoEnterPasswordDialog
  2467. //
  2468. UINT DoEnterPasswordDialog( HINSTANCE hInstance, HANDLE hwnd )
  2469. {
  2470.     UINT ret;
  2471.  
  2472.     ret = DialogBox( hInstance, MAKEINTRESOURCE( IDD_ENTER_PASSWORD ), hwnd, EnterPasswordDlgProc );
  2473.     
  2474.     return ret;
  2475. } // DoEnterPasswordDialog
  2476.  
  2477.  
  2478.  
  2479. /*--------------------- PROXY CONFIGURATION DIALOG BOX ----------------------*/
  2480.  
  2481.  
  2482. // Modal Proxy Configuration dialog
  2483.  
  2484. //
  2485. // ProxyConfigurationDlgProc
  2486. //
  2487. BOOL FAR PASCAL ProxyConfigurationDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
  2488. {
  2489.     char serverstring[512];
  2490.     unsigned int portnum;
  2491.     char *serverptr, *colonptr;
  2492.             
  2493.     switch( message )
  2494.     {
  2495.         case WM_INITDIALOG:
  2496.         {
  2497.             LONG retval;
  2498.             HKEY hkeyProxyServer;
  2499.             DWORD dwResult;
  2500.             HWND edit;
  2501.  
  2502.             retval = RegCreateKeyEx(APPREGKEY_ROOT,
  2503.                 APPREGKEY_BASE,
  2504.                 0,
  2505.                 NULL,
  2506.                 REG_OPTION_NON_VOLATILE,
  2507.                 KEY_ALL_ACCESS,
  2508.                 NULL,
  2509.                 &hkeyProxyServer,
  2510.                 &dwResult);
  2511.             
  2512.             if (retval != ERROR_SUCCESS)
  2513.             {
  2514.                 gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
  2515.             }
  2516.             else
  2517.             {
  2518.                 char buffer[512];
  2519.                 DWORD dwType;
  2520.                 DWORD dwSize;
  2521.                 
  2522.                 dwSize = sizeof(buffer);
  2523.                 retval = RegQueryValueEx( hkeyProxyServer,
  2524.                     "ProxyServer",
  2525.                     0,
  2526.                     &dwType,
  2527.                     buffer,
  2528.                     &dwSize );
  2529.                 
  2530.                 if (retval == ERROR_SUCCESS)
  2531.                 {
  2532.                     if (dwType == REG_SZ)
  2533.                     {
  2534.                         strncpy(proxy_buffer, buffer, sizeof(proxy_buffer)-1);
  2535.                         proxy_buffer[sizeof(proxy_buffer)-1] = 0;
  2536.                     }
  2537.                 }
  2538.                 RegCloseKey(hkeyProxyServer);
  2539.             }
  2540.  
  2541.             strncpy(serverstring, proxy_buffer, sizeof(serverstring)-1);
  2542.             serverstring[sizeof(serverstring)-1]=0;
  2543.  
  2544.             serverptr = serverstring;
  2545.             if (!strnicmp(serverptr, "http://", 7)) serverptr+=7;
  2546.  
  2547.             colonptr = strchr(serverptr, ':');
  2548.             if (colonptr == NULL)
  2549.             {
  2550.                 colonptr = serverptr+strlen(serverptr);
  2551.             }
  2552.             else
  2553.             {
  2554.                 *colonptr++ = '\0';
  2555.             }
  2556.             if (atol(colonptr) == 0) colonptr = "";
  2557.  
  2558.             if (edit = GetDlgItem( hwnd, IDC_PROXY_SERVER_EDIT ))
  2559.             {
  2560.                 SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)serverstring);
  2561.             }
  2562.             if (edit = GetDlgItem( hwnd, IDC_PROXY_PORT_EDIT ))
  2563.             {
  2564.                SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)colonptr);
  2565.             }
  2566.             return (LRESULT) 1;
  2567.         }
  2568.  
  2569.         case WM_COMMAND:
  2570.         {
  2571.             if (wParam==IDOK)
  2572.             {
  2573.                 LONG retval;
  2574.                 HKEY hkeyProxyServer;
  2575.                 DWORD dwResult;
  2576.                 HWND edit;
  2577.                 int textlength;
  2578.  
  2579.                 if (edit = GetDlgItem( hwnd, IDC_PROXY_SERVER_EDIT ))
  2580.                 {
  2581.                     textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
  2582.                     if (textlength > sizeof(serverstring)-1) textlength = sizeof(serverstring)-1;
  2583.                     SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)serverstring);
  2584.                 }
  2585.                 if (edit = GetDlgItem( hwnd, IDC_PROXY_PORT_EDIT ))
  2586.                 {
  2587.                     unsigned char portstring[32];
  2588.                     textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
  2589.                     if (textlength > sizeof(portstring)-1) textlength = sizeof(portstring)-1;
  2590.                     SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)portstring);
  2591.  
  2592.                     portnum = atol(portstring);
  2593.                     if (portnum > 65535) portnum = 65535;
  2594.                     if (portnum == 0) portnum = 8080; /* default port number */
  2595.                 }
  2596.  
  2597.                 if (!strcmp(serverstring, ""))
  2598.                     strcpy(proxy_buffer, "");
  2599.                 else
  2600.                     sprintf(proxy_buffer, "%s:%d", serverstring, portnum);
  2601.  
  2602.                 retval = RegCreateKeyEx(APPREGKEY_ROOT,
  2603.                     APPREGKEY_BASE,
  2604.                     0,
  2605.                     NULL,
  2606.                     REG_OPTION_NON_VOLATILE,
  2607.                     KEY_ALL_ACCESS,
  2608.                     NULL,
  2609.                     &hkeyProxyServer,
  2610.                     &dwResult);
  2611.                 
  2612.                 if (retval != ERROR_SUCCESS)
  2613.                 {
  2614.                     gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
  2615.                 }
  2616.                 else
  2617.                 {
  2618.                     retval = RegSetValueEx( hkeyProxyServer,
  2619.                         "ProxyServer",
  2620.                         0,
  2621.                         REG_SZ,
  2622.                         proxy_buffer,
  2623.                         strlen(proxy_buffer)+1 );
  2624.                     
  2625.                     if (retval != ERROR_SUCCESS)
  2626.                     {
  2627.                         gui_criticalerror("RegSetValueEx failed: %d\n", retval);
  2628.                     }
  2629.                 }
  2630.             }
  2631.  
  2632.             if ( wParam==IDOK || wParam==IDCANCEL )
  2633.             {
  2634.                 EndDialog(hwnd, wParam);
  2635.             }
  2636.  
  2637.             return (LRESULT) 1;
  2638.         }
  2639.     }
  2640.     return (LRESULT) 0;
  2641.  
  2642. } // ProxyConfigurationDlgProc
  2643.  
  2644.  
  2645. //
  2646. // DoProxyConfigurationDialog
  2647. //
  2648. UINT DoProxyConfigurationDialog( HINSTANCE hInstance, HANDLE hwnd )
  2649. {
  2650.     UINT ret;
  2651.  
  2652.     ret = DialogBox( hInstance, MAKEINTRESOURCE( IDD_PROXY_SERVER ), hwnd, ProxyConfigurationDlgProc );
  2653.     
  2654.     return ret;
  2655. } // DoProxyConfigurationDialog
  2656.  
  2657.  
  2658.  
  2659. /*-------------------------- MEDIA STATE ROUTINES ---------------------------*/
  2660.  
  2661.  
  2662. // Current multimedia variables
  2663. static Media media;
  2664.  
  2665.  
  2666. //
  2667. // CanPreview
  2668. //
  2669. // Return true if we can preview the currently downloading stream
  2670. //
  2671. BOOL CanPreview()
  2672. {
  2673.     return ((!Previewing) && Transmitting && strcmp( StreamFilename, "" ));
  2674. } // CanPreview
  2675.  
  2676.  
  2677. //
  2678. // CanPlay
  2679. //
  2680. // Return true if we can go to a playing state from our current state
  2681. //
  2682. BOOL CanPlay()
  2683. {
  2684.     return (media.state == Stopped || media.state == Paused);
  2685.  
  2686. } // CanPlay
  2687.  
  2688.  
  2689. //
  2690. // CanStop
  2691. //
  2692. // Return true if we can go to a stopped state from our current state
  2693. //
  2694. BOOL CanStop()
  2695. {
  2696.     return (media.state == Playing || media.state == Paused);
  2697.  
  2698. } // CanStop
  2699.  
  2700.  
  2701. //
  2702. // CanPause
  2703. //
  2704. // Return true if we can go to a paused state from our current state
  2705. //
  2706. BOOL CanPause()
  2707. {
  2708.     return (media.state == Playing || media.state == Stopped);
  2709.  
  2710. } // CanPause
  2711.  
  2712.  
  2713. //
  2714. // IsInitialized
  2715. //
  2716. // Return true if we have loaded and initialized a multimedia file
  2717. //
  2718. BOOL IsInitialized()
  2719. {
  2720.     return (media.state != Uninitialized);
  2721.  
  2722. } // IsInitialized
  2723.  
  2724.  
  2725. //
  2726. // ChangeStateTo
  2727. //
  2728. void ChangeStateTo( State newState )
  2729. {
  2730.     if (!Transmitting)
  2731.     {
  2732.         switch (newState)
  2733.         {
  2734.         case Playing:
  2735.                 gui_setstatus("Playing...");
  2736.                 break;
  2737.         case Paused:
  2738.                 gui_setstatus("Paused");
  2739.                 break;
  2740.         case Stopped:
  2741.                 gui_setstatus("Stopped");
  2742.                 break;
  2743.         case Uninitialized:
  2744.                 gui_setstatus("");
  2745.                 break;
  2746.         }
  2747.     }
  2748.  
  2749.     media.state = newState;
  2750.  
  2751.     if (TrackbarTimer != 0)
  2752.     {
  2753.         KillTimer( appVars.hwndMainFrame, TrackbarTimer); TrackbarTimer = 0;
  2754.     }
  2755.  
  2756.     if (newState == Playing)
  2757.         TrackbarTimer = SetTimer( appVars.hwndMainFrame, ID_TRACKBARTIMER, 100, &TrackbarTimerFunc );
  2758.  
  2759.     // update the toolbar
  2760.     UpdateToolbar();
  2761.  
  2762. } // ChangeStateTo
  2763.  
  2764.  
  2765. //
  2766. // InitMedia
  2767. //
  2768. // Initialization
  2769. //
  2770. BOOL InitMedia()
  2771. {
  2772.     ChangeStateTo( Uninitialized );
  2773.  
  2774.     media.hGraphNotifyEvent = NULL;
  2775.     media.pGraph = NULL;
  2776.  
  2777.     return TRUE;
  2778.  
  2779. } // InitMedia
  2780.  
  2781.  
  2782. /*------------------------- GRAPH/MEDIA FUNCTIONS ---------------------------*/
  2783.  
  2784. //
  2785. // CreateFilterGraph
  2786. //
  2787. BOOL CreateFilterGraph()
  2788. {
  2789.     BOOL result = FALSE;
  2790.  
  2791.     IMediaEvent *pME;
  2792.     HRESULT hr;
  2793.  
  2794.     ASSERT(media.pGraph == NULL);
  2795.  
  2796.     SetBusy(TRUE);
  2797.  
  2798.     hr = CoCreateInstance(&CLSID_FilterGraph,           // CLSID of object
  2799.                           NULL,                         // Outer unknown
  2800.                           CLSCTX_INPROC_SERVER,         // Type of server
  2801.                           &IID_IGraphBuilder,           // Interface wanted
  2802.                           (void **) &media.pGraph);     // Returned object
  2803.     if (FAILED(hr))
  2804.     {
  2805.         media.pGraph = NULL;
  2806.     }
  2807.     else
  2808.     {
  2809.         // We use this to find out events sent by the filtergraph
  2810.  
  2811.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  2812.                                                   &IID_IMediaEvent,
  2813.                                                   (void **) &pME);
  2814.         if (FAILED(hr))
  2815.         {
  2816.             DeleteContents();
  2817.         }
  2818.         else
  2819.         {
  2820.             hr = pME->lpVtbl->GetEventHandle(pME, (OAEVENT*) &media.hGraphNotifyEvent);
  2821.             pME->lpVtbl->Release( pME );
  2822.  
  2823.             if (FAILED(hr))
  2824.             {
  2825.                 DeleteContents();
  2826.             }
  2827.             else
  2828.             {
  2829.                 result = TRUE;
  2830.             }
  2831.         }
  2832.     }
  2833.  
  2834.     SetBusy(FALSE);
  2835.  
  2836.     return result;
  2837.  
  2838. } // CreateFilterGraph
  2839.  
  2840.  
  2841. // Destruction
  2842. //
  2843. // DeleteContents
  2844. //
  2845. void DeleteContents()
  2846. {
  2847.     if (media.pGraph != NULL)
  2848.     {
  2849.         HRESULT hr;
  2850.         IVideoWindow   *pVW;
  2851.  
  2852.         SetBusy(TRUE);
  2853.  
  2854.         /* check if this graph comes with a video window */
  2855.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IVideoWindow, (void**) &pVW);
  2856.         if (SUCCEEDED(hr))
  2857.         {
  2858.             long left, top, width, height;
  2859.  
  2860.             /* remember video window position */
  2861.             hr = pVW->lpVtbl->GetRestorePosition(pVW, &left, &top, &width, &height);
  2862.             if (SUCCEEDED(hr))
  2863.             {
  2864.                 IVWWindowLeft   = left;
  2865.                 IVWWindowTop    = top;
  2866.                 IVWWindowWidth  = width;
  2867.                 IVWWindowHeight = height;
  2868.             }
  2869.             pVW->lpVtbl->Release(pVW);
  2870.         }
  2871.  
  2872.         media.pGraph->lpVtbl->Release( media.pGraph );
  2873.         media.pGraph = NULL;
  2874.  
  2875.         SetBusy(FALSE);
  2876.     }
  2877.  
  2878.     // this event is owned by the filter graph and is thus invalid
  2879.     media.hGraphNotifyEvent = NULL;
  2880.  
  2881.     Previewing = FALSE;
  2882.  
  2883.     IMPTotalTime = 0.0;
  2884.     IMPCurrentPosition = 0.0;
  2885.  
  2886.     IMSTotalTime = 0;
  2887.     IMSCurrentPosition = 0;
  2888.     IMSCapabilities = 0;
  2889.  
  2890.     SetStatusText(STAT_TIMECODE, 0, -1, "");
  2891.  
  2892.     if (hwndTrackbar)
  2893.     {
  2894.         SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, 0);
  2895.         EnableWindow(hwndTrackbar, FALSE);
  2896.     }
  2897.  
  2898.     ChangeStateTo( Uninitialized );
  2899.  
  2900. } // DeleteContents
  2901.  
  2902.  
  2903. //
  2904. // RenderFile
  2905. //
  2906. BOOL RenderFile( LPSTR szFileName )
  2907. {
  2908.     BOOL result = FALSE;
  2909.  
  2910.     HRESULT hr;
  2911.     WCHAR wPath[MAX_PATH];
  2912.  
  2913.     SetBusy(TRUE);
  2914.  
  2915.     DeleteContents();
  2916.  
  2917.     if (!Transmitting) gui_setstatus("Preparing to play...");
  2918.  
  2919.     if ( !CreateFilterGraph() )
  2920.     {
  2921.         PlayerMessageBox( IDS_CANT_INIT_QUARTZ );
  2922.     }
  2923.     else
  2924.     {
  2925.         MultiByteToWideChar( CP_ACP, 0, szFileName, -1, wPath, MAX_PATH );
  2926.  
  2927.         hr = media.pGraph->lpVtbl->RenderFile(media.pGraph, wPath, NULL);
  2928.  
  2929.         if (FAILED( hr ))
  2930.         {
  2931.             PlayerMessageBox( IDS_CANT_RENDER_FILE );
  2932.         }
  2933.         else
  2934.         {
  2935.             IMediaPosition *pMP;
  2936.             IMediaSeeking  *pMS;
  2937.             IVideoWindow   *pVW;
  2938.  
  2939.             IMPTotalTime = 0;
  2940.             IMPCurrentPosition = 0;
  2941.  
  2942.             hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  2943.                                                       &IID_IMediaPosition,
  2944.                                                       (void**) &pMP);
  2945.             if (SUCCEEDED(hr))
  2946.             {
  2947.                 REFTIME tLength;
  2948.                 hr = pMP->lpVtbl->get_Duration(pMP, &tLength);
  2949.                 if (SUCCEEDED(hr))
  2950.                 {
  2951.                     LONG lBackward;
  2952.                     LONG lForward;
  2953.  
  2954.                     IMPTotalTime = tLength;
  2955.  
  2956.                     hr = pMP->lpVtbl->CanSeekBackward(pMP, &lBackward);
  2957.                     if (SUCCEEDED(hr))
  2958.                     {
  2959.                         hr = pMP->lpVtbl->CanSeekBackward(pMP, &lForward);
  2960.                         if (SUCCEEDED(hr))
  2961.                         {
  2962. //                            if (lBackward == OATRUE && lForward == OATRUE)
  2963.                             {
  2964.                                 if (hwndTrackbar)
  2965.                                     EnableWindow(hwndTrackbar, TRUE);
  2966.                             }
  2967.                         }
  2968.                     }
  2969.                 }
  2970.                 pMP->lpVtbl->Release(pMP);
  2971.             }
  2972.  
  2973.             IMSTotalTime = 0;
  2974.             IMSCurrentPosition = 0;
  2975.             IMSCapabilities = 0;
  2976.  
  2977.             hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  2978.                                                       &IID_IMediaSeeking,
  2979.                                                       (void**) &pMS);
  2980.             if (SUCCEEDED(hr))
  2981.             {
  2982.                 LONGLONG llDuration;
  2983.  
  2984.                 hr = pMS->lpVtbl->GetDuration(pMS, &llDuration);
  2985.                 if (SUCCEEDED(hr))
  2986.                 {
  2987.                     DWORD dwCapabilities = 0;
  2988.  
  2989.                     IMSTotalTime = llDuration;
  2990.  
  2991.                     hr = pMS->lpVtbl->GetCapabilities(pMS, &dwCapabilities);
  2992.                     if (SUCCEEDED(hr))
  2993.                     {
  2994.                       //if (dwCapabilities & AM_SEEKING_CanSeekAbsolute)  gui_criticalerror("AM_SEEKING_CanSeekAbsolute");
  2995.                       //if (dwCapabilities & AM_SEEKING_CanSeekForwards)  gui_criticalerror("AM_SEEKING_CanSeekForwards");
  2996.                       //if (dwCapabilities & AM_SEEKING_CanSeekBackwards) gui_criticalerror("AM_SEEKING_CanSeekBackwards");
  2997.                       //if (dwCapabilities & AM_SEEKING_CanGetCurrentPos) gui_criticalerror("AM_SEEKING_CanGetCurrentPos");
  2998.                       //if (dwCapabilities & AM_SEEKING_CanGetStopPos)    gui_criticalerror("AM_SEEKING_CanGetStopPos");
  2999.                       //if (dwCapabilities & AM_SEEKING_CanGetDuration)   gui_criticalerror("AM_SEEKING_CanGetDuration");
  3000.                       //if (dwCapabilities & AM_SEEKING_CanPlayBackwards) gui_criticalerror("AM_SEEKING_CanPlayBackwards");
  3001.                       //if (dwCapabilities & AM_SEEKING_CanDoSegments)    gui_criticalerror("AM_SEEKING_CanDoSegments");
  3002.                       //if (dwCapabilities & AM_SEEKING_Source)           gui_criticalerror("AM_SEEKING_Source");
  3003.  
  3004.                         IMSCapabilities = dwCapabilities;
  3005.                     }
  3006.                 }
  3007.  
  3008.                 pMS->lpVtbl->Release(pMS);
  3009.             }
  3010.  
  3011.             /* check if this graph comes with a video window */
  3012.             hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3013.                                                       &IID_IVideoWindow,
  3014.                                                       (void**) &pVW);
  3015.             if (SUCCEEDED(hr))
  3016.             {
  3017.                 BSTR title;
  3018.                 
  3019.                 if ((title = SysAllocString(wPath)) != NULL)
  3020.                 {
  3021.                     hr = pVW->lpVtbl->put_Caption(pVW,title);
  3022.  
  3023.                     SysFreeString(title);
  3024.                 }
  3025.  
  3026.                 if (IVWWindowWidth > 0 && IVWWindowHeight > 0)
  3027.                 {
  3028.                     long left, top, width, height;
  3029.                     left   = IVWWindowLeft;
  3030.                     top    = IVWWindowTop;
  3031.                     width  = IVWWindowWidth;
  3032.                     height = IVWWindowHeight;
  3033.  
  3034.                     hr = pVW->lpVtbl->SetWindowPosition(pVW, left, top, width, height);
  3035.                 }
  3036.  
  3037.                 pVW->lpVtbl->Release(pVW);
  3038.             }
  3039.  
  3040.             /* in any case, we got a filter graph, so return TRUE */
  3041.             result = TRUE;
  3042.  
  3043.         }
  3044.     }
  3045.  
  3046.     SetBusy(FALSE);
  3047.  
  3048.     return result;
  3049.  
  3050. } // RenderFile
  3051.  
  3052.  
  3053. //
  3054. // SetTitle
  3055. //
  3056. // Update the title of the video renderer to "Player - szFile"
  3057. //
  3058. void SetTitle( HWND hwnd, char *szFile )
  3059. {
  3060.     char szNewTitle[ _MAX_FNAME + _MAX_EXT  + 20 ];
  3061.  
  3062.     strcpy( szNewTitle, APP_NAME );
  3063.     strcat( szNewTitle, " - " );
  3064.     strcat( szNewTitle, szFile );
  3065.  
  3066.     // Update the window's title
  3067.     SetWindowText( hwnd, szNewTitle );
  3068.  
  3069. } // SetTitle
  3070.  
  3071.  
  3072. //
  3073. // OpenMediaFile
  3074. //
  3075. // File..Open has been selected
  3076. //
  3077. BOOL OpenMediaFile( HWND hwnd, LPSTR szFile )
  3078. {
  3079.     BOOL result = FALSE;
  3080.  
  3081.     static char szFileName[ _MAX_PATH ];
  3082.     static char szTitleName[ _MAX_FNAME + _MAX_EXT ];
  3083.  
  3084.     if( szFile != NULL )
  3085.     {
  3086.         if ( RenderFile( szFile ) )
  3087.         {
  3088.             LPSTR szTitle;
  3089.  
  3090.             // Work out the full path name and the file name from the
  3091.             // specified file
  3092.             GetFullPathName( szFile, _MAX_PATH, szFileName, &szTitle );
  3093.             strncpy( szTitleName, szTitle, _MAX_FNAME + _MAX_EXT );
  3094.             szTitleName[ _MAX_FNAME + _MAX_EXT -1 ] = '\0';
  3095.  
  3096.             // Set the main window title and update the state
  3097.             if (!Transmitting) SetTitle( hwnd, szTitleName );
  3098.             ChangeStateTo( Stopped );
  3099.             result = TRUE;
  3100.         }
  3101.         else
  3102.             if (!Transmitting) gui_seterror("Unable to play file!");
  3103.     }
  3104.     else
  3105.     {
  3106.         if( DoFileOpenDialog( hwnd, szFileName, szTitleName ) )
  3107.         {
  3108.             if (RenderFile( szFileName ) )
  3109.             {
  3110.                 // Set the main window title and update the state
  3111.                 if (!Transmitting) SetTitle( hwnd, szTitleName );
  3112.                 ChangeStateTo( Stopped );
  3113.                 result = TRUE;
  3114.             }
  3115.             else
  3116.                 if (!Transmitting) gui_seterror("Unable to play file!");
  3117.  
  3118.         }
  3119.     }
  3120.     return result;
  3121.  
  3122. } // OpenMediaFile
  3123.  
  3124.  
  3125. //
  3126. // GetCurrentPosition
  3127. //
  3128.  
  3129. BOOL GetCurrentPosition(REFTIME *rtcur)
  3130. {
  3131.     BOOL result = FALSE;
  3132.  
  3133.     if (IsInitialized())
  3134.     {
  3135.         HRESULT hr;
  3136.         IMediaPosition *pMP;
  3137.         REFTIME tCurrent;
  3138.  
  3139.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3140.             &IID_IMediaPosition,
  3141.             (void**) &pMP);
  3142.         if (SUCCEEDED(hr))
  3143.         {
  3144.             hr = pMP->lpVtbl->get_CurrentPosition(pMP, &tCurrent);
  3145.             if (SUCCEEDED(hr))
  3146.             {
  3147.                 *rtcur = tCurrent;
  3148.                 result = TRUE;
  3149.             }
  3150.             pMP->lpVtbl->Release(pMP);
  3151.         }
  3152.     }
  3153.  
  3154.     return result;
  3155. } // GetCurrentPosition
  3156.  
  3157.  
  3158. //
  3159. // GetStopPosition
  3160. //
  3161.  
  3162. BOOL GetStopPosition(REFTIME *rtstop, LONGLONG *llstop)
  3163. {
  3164.     BOOL result = FALSE;
  3165.  
  3166.     if (Previewing)
  3167.     {
  3168.         HRESULT hr;
  3169.         IMediaPosition *pMP;
  3170.         IMediaSeeking *pMS;
  3171.  
  3172.         // Obtain the IMediaPosition interface to our filter graph
  3173.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
  3174.         if( SUCCEEDED(hr) )
  3175.         {
  3176.             pMP->lpVtbl->get_StopTime(pMP, rtstop);
  3177.             if ( SUCCEEDED(hr) )
  3178.             {
  3179.                 result = TRUE;
  3180.             }
  3181.             pMP->lpVtbl->Release(pMP);
  3182.         }
  3183.  
  3184.         /* this one works as an alternative to the above */
  3185.         if (TRUE)
  3186.         {
  3187.             // Obtain the IMediaSeeking interface to our filter graph
  3188.             hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaSeeking, (void **) &pMS);
  3189.             if( SUCCEEDED(hr) )
  3190.             {
  3191.                 /* Replay should stop at the current download position */
  3192.                 hr = pMS->lpVtbl->GetStopPosition(pMS, llstop);
  3193.                 if ( SUCCEEDED(hr) )
  3194.                 {
  3195.                     result = TRUE;
  3196.                 }
  3197.  
  3198.                 pMS->lpVtbl->Release(pMS);
  3199.             }
  3200.  
  3201.         }
  3202.     }
  3203.  
  3204.     return result;
  3205.  
  3206. } // GetStopPosition
  3207.  
  3208.  
  3209. //
  3210. // SetStopPosition
  3211. //
  3212.  
  3213. BOOL SetStopPosition(int milliseconds)
  3214. {
  3215.     BOOL result = FALSE;
  3216.  
  3217.     if (Previewing)
  3218.     {
  3219.         HRESULT hr;
  3220.         IMediaPosition *pMP;
  3221.         IMediaSeeking *pMS;
  3222.  
  3223.         // Obtain the IMediaPosition interface to our filter graph
  3224.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
  3225.         if( SUCCEEDED(hr) )
  3226.         {
  3227.             pMP->lpVtbl->put_StopTime(pMP, (REFTIME)milliseconds/1000);
  3228.             if ( SUCCEEDED(hr) )
  3229.             {
  3230.                 result = TRUE;
  3231.             }
  3232.             pMP->lpVtbl->Release(pMP);
  3233.         }
  3234.  
  3235.         /* this one works as an alternative to the above */
  3236.         if (result == FALSE)
  3237.         {
  3238.             // Obtain the IMediaSeeking interface to our filter graph
  3239.             hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaSeeking, (void **) &pMS);
  3240.             if( SUCCEEDED(hr) )
  3241.             {
  3242.                 LONGLONG llCurrent = 0;
  3243.                 LONGLONG llStop = 0;
  3244.                 DWORD dwCurrentFlags = AM_SEEKING_NoPositioning;
  3245.                 DWORD dwStopFlags = AM_SEEKING_AbsolutePositioning;
  3246.  
  3247.                 /* Replay should stop at the current download position */
  3248.                 llStop = (LONGLONG)(milliseconds * 10000);
  3249.                 hr = pMS->lpVtbl->SetPositions(pMS,
  3250.                     &llCurrent,
  3251.                     dwCurrentFlags,
  3252.                     &llStop,
  3253.                     dwStopFlags );
  3254.                 if ( hr == NOERROR )
  3255.                 {
  3256.                     result = TRUE;
  3257.                 }
  3258.  
  3259.                 pMS->lpVtbl->Release(pMS);
  3260.             }
  3261.  
  3262.         }
  3263.     }
  3264.  
  3265.     return result;
  3266.  
  3267. } // SetStopPosition
  3268.  
  3269.  
  3270. //
  3271. // SetCurrentPosition
  3272. //
  3273.  
  3274. BOOL SetCurrentPosition(REFTIME position)
  3275. {
  3276.     BOOL result = FALSE;
  3277.  
  3278.     if( IsInitialized() )
  3279.     {
  3280.         HRESULT hr;
  3281.         IMediaPosition *pMP;
  3282.  
  3283.         SetBusy ( TRUE );
  3284.  
  3285.         // Obtain the interface to our filter graph
  3286.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
  3287.         if( SUCCEEDED(hr) )
  3288.         {
  3289.             pMP->lpVtbl->put_CurrentPosition(pMP, position);
  3290.             result = TRUE;
  3291.             pMP->lpVtbl->Release(pMP);
  3292.         }
  3293.  
  3294.         if (result == FALSE)
  3295.             // Inform the user that an error occurred
  3296.             PlayerMessageBox( IDS_CANT_SEEK );
  3297.  
  3298.         SetBusy ( FALSE );
  3299.     }
  3300.  
  3301.     return result;
  3302.  
  3303. } // SetCurrentPosition
  3304.  
  3305.  
  3306. //
  3307. // OnMediaSeeking
  3308. //
  3309. BOOL OnMediaSeeking(BOOL Enabled)
  3310. {
  3311.     BOOL result = FALSE;
  3312.  
  3313.     HRESULT hr;
  3314.     IMediaControl *pMC;
  3315.  
  3316.     // Obtain the interface to our filter graph
  3317.     hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3318.         &IID_IMediaControl,
  3319.         (void **) &pMC);
  3320.  
  3321.     if( SUCCEEDED(hr) )
  3322.     {
  3323.         result = TRUE;
  3324.  
  3325.         if (Enabled)
  3326.         {
  3327.             if (!Transmitting) gui_setstatus("Seeking...");
  3328.  
  3329.             if (media.state == Playing)
  3330.             {
  3331.                 hr = pMC->lpVtbl->Pause( pMC );
  3332.             }
  3333.         }
  3334.         else
  3335.         {
  3336.             if (media.state == Playing)
  3337.             {
  3338.                 hr = pMC->lpVtbl->Run( pMC );
  3339.             }
  3340.  
  3341.             ChangeStateTo(media.state);
  3342.  
  3343.         }
  3344.  
  3345.         pMC->lpVtbl->Release( pMC );
  3346.  
  3347.     }
  3348.  
  3349.     return result;
  3350.  
  3351. } // OnMediaSeeking
  3352.  
  3353.  
  3354. //
  3355. // OnMediaPlay
  3356. //
  3357.  
  3358. BOOL OnMediaPlay()
  3359. {
  3360.     BOOL result = FALSE;
  3361.  
  3362.     if( CanPlay() )
  3363.     {
  3364.         HRESULT hr;
  3365.         IVideoWindow  *pVW;
  3366.         IMediaControl *pMC;
  3367.  
  3368.         SetBusy ( TRUE );
  3369.  
  3370.         /* check if this graph comes with a video window */
  3371.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IVideoWindow, (void**) &pVW);
  3372.         if (SUCCEEDED(hr))
  3373.         {
  3374.             long windowstate;
  3375.  
  3376.             /* remember video window position */
  3377.             hr = pVW->lpVtbl->get_WindowState(pVW, &windowstate);
  3378.             if (SUCCEEDED(hr))
  3379.             {
  3380.                 /* show the window if it was hidden/miminized */
  3381.                 if (windowstate == SW_MINIMIZE || windowstate == SW_HIDE ||
  3382.                     windowstate == SW_SHOWMINNOACTIVE                     )
  3383.                 {
  3384.                     windowstate = SW_SHOWNORMAL;
  3385.                     hr = pVW->lpVtbl->put_WindowState(pVW, windowstate);
  3386.                 }
  3387.                 
  3388.             }
  3389.             pVW->lpVtbl->Release(pVW);
  3390.         }
  3391.  
  3392.         if (Previewing)
  3393.         {
  3394.             REFTIME rtstoppos;
  3395.             LONGLONG llstoppos;
  3396.             REFTIME rtcurrent;
  3397.  
  3398.             if (GetStopPosition(&rtstoppos, &llstoppos))
  3399.             {
  3400.                 if (GetCurrentPosition(&rtcurrent))
  3401.                 {
  3402.                     /* the filter graph thinks it has reached the end of the stream */
  3403.                     /* because it is truncated and we are still downloading it!     */
  3404.                     if (rtcurrent == rtstoppos)
  3405.                     {
  3406.                         /* so in this case we have to reposition and try again */
  3407.                         /* otherwise the filter graph won't continue to play   */
  3408.                         SetCurrentPosition( IMPCurrentPosition );
  3409.                     }
  3410.                 }
  3411.             }
  3412.         }
  3413.  
  3414.         // Obtain the interface to our filter graph
  3415.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3416.                                                   &IID_IMediaControl,
  3417.                                                   (void **) &pMC);
  3418.  
  3419.         if( SUCCEEDED(hr) )
  3420.         {
  3421.             // Ask the filter graph to play and release the interface
  3422.             hr = pMC->lpVtbl->Run( pMC );
  3423.             if( SUCCEEDED(hr) )
  3424.             {
  3425.                 ChangeStateTo( Playing );
  3426.                 result = TRUE;
  3427.             }
  3428.             pMC->lpVtbl->Release( pMC );
  3429.         }
  3430.  
  3431.         if (result == FALSE)
  3432.             // Inform the user that an error occurred
  3433.             PlayerMessageBox( IDS_CANT_PLAY );
  3434.  
  3435.         SetBusy ( FALSE );
  3436.     }
  3437.  
  3438.     return result;
  3439.  
  3440. } // OnMediaPlay
  3441.  
  3442.  
  3443. //
  3444. // OnMediaPause
  3445. //
  3446. BOOL OnMediaPause()
  3447. {
  3448.     BOOL result = FALSE;
  3449.  
  3450.     if( CanPause() )
  3451.     {
  3452.         HRESULT hr;
  3453.         IMediaControl *pMC;
  3454.  
  3455.         SetBusy(TRUE);
  3456.  
  3457.         // Obtain the interface to our filter graph
  3458.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3459.                                                   &IID_IMediaControl,
  3460.                                                   (void **) &pMC);
  3461.  
  3462.         if( SUCCEEDED(hr) )
  3463.         {
  3464.             // Ask the filter graph to pause and release the interface
  3465.             hr = pMC->lpVtbl->Pause( pMC );
  3466.             if( SUCCEEDED(hr) )
  3467.             {
  3468.                 ChangeStateTo( Paused );
  3469.                 result = TRUE;
  3470.             }
  3471.  
  3472.             pMC->lpVtbl->Release( pMC );
  3473.  
  3474.         }
  3475.  
  3476.         if (result == FALSE)
  3477.             // Inform the user that an error occurred
  3478.             PlayerMessageBox( IDS_CANT_PAUSE );
  3479.  
  3480.         SetBusy(FALSE);
  3481.     }
  3482.  
  3483.     return result;
  3484.  
  3485. } // OnMediaPause
  3486.  
  3487.  
  3488. //
  3489. // OnMediaStop
  3490. //
  3491. BOOL OnMediaStop(BOOL reallystop, BOOL rewind)
  3492. {
  3493.     BOOL result = FALSE;
  3494.  
  3495.     if( CanStop() )
  3496.     {
  3497.         HRESULT hr;
  3498.         IMediaControl *pMC;
  3499.  
  3500.         SetBusy(TRUE);
  3501.  
  3502.         if (!Transmitting) gui_setstatus("Stopping replay...");
  3503.  
  3504.         // Obtain the interface to our filter graph
  3505.         hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3506.                                                   &IID_IMediaControl,
  3507.                                                   (void **) &pMC);
  3508.         if( SUCCEEDED(hr) )
  3509.         {
  3510.             IMediaPosition * pMP;
  3511.  
  3512.             if (reallystop)
  3513.                 // now really do the stop
  3514.                 pMC->lpVtbl->Stop( pMC );
  3515.             else
  3516.                 // just simulate a stop using pause (faster)
  3517.                 pMC->lpVtbl->Pause( pMC );
  3518.  
  3519.             if( SUCCEEDED(hr) )
  3520.             {
  3521.                 ChangeStateTo( Stopped );
  3522.                 result = TRUE;
  3523.             }
  3524.  
  3525.             if (rewind == TRUE)
  3526.             {
  3527.                 hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3528.                                                           &IID_IMediaPosition,
  3529.                                                           (void**) &pMP);
  3530.                 if (SUCCEEDED(hr))
  3531.                 {
  3532.                     hr = pMP->lpVtbl->put_CurrentPosition(pMP, 0);
  3533.                     if (SUCCEEDED(hr))
  3534.                     {
  3535.                         SetStatusText(STAT_TIMECODE, 0, -1, "");
  3536.  
  3537.                         if (hwndTrackbar != NULL)
  3538.                             SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, 0);
  3539.                     }
  3540.  
  3541.                     pMP->lpVtbl->Release(pMP);
  3542.                 }
  3543.             }
  3544.             pMC->lpVtbl->Release( pMC );
  3545.         }
  3546.  
  3547.         if (result == FALSE)
  3548.             // Inform the user that an error occurred
  3549.             PlayerMessageBox( IDS_CANT_STOP );
  3550.  
  3551.         SetBusy(FALSE);
  3552.     }
  3553.  
  3554.     return result;
  3555.  
  3556. } // OnMediaStop
  3557.  
  3558.  
  3559. //
  3560. // GetGraphEventHandle
  3561. //
  3562. // We use this to check for graph events
  3563. //
  3564. HANDLE GetGraphEventHandle()
  3565. {
  3566.     return media.hGraphNotifyEvent;
  3567.  
  3568. } // GetGraphEventHandle
  3569.  
  3570.  
  3571. //
  3572. // OnGraphNotify
  3573. //
  3574. // If the event handle is valid, then ask the graph if
  3575. // anything has happened (eg the graph has stopped...)
  3576. //
  3577. void OnGraphNotify()
  3578. {
  3579.     IMediaEvent *pME;
  3580.     long lEventCode, lParam1, lParam2;
  3581.  
  3582.     ASSERT( media.hGraphNotifyEvent != NULL );
  3583.  
  3584.     if( SUCCEEDED(media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  3585.                                                        &IID_IMediaEvent,
  3586.                                                        (void **) &pME)))
  3587.     {
  3588.         if( SUCCEEDED(pME->lpVtbl->GetEvent(pME, &lEventCode, &lParam1, &lParam2, 0)))
  3589.         {
  3590.             if (lEventCode == EC_COMPLETE)
  3591.             {
  3592.                 OnMediaStop(FALSE, FALSE);
  3593.                 if (!Transmitting) gui_setstatus("Replay complete");
  3594.             }
  3595.             if (lEventCode == EC_USERABORT)
  3596.             {
  3597.                 OnMediaStop(TRUE, TRUE);
  3598.                 if (!Transmitting) gui_setstatus("User aborted replay");
  3599.             }
  3600.             if (lEventCode == EC_ERRORABORT)
  3601.             {
  3602.                 OnMediaStop(TRUE, TRUE);
  3603.                 if (!Transmitting) gui_setstatus("Error during replay");
  3604.             }
  3605.         }
  3606.         pME->lpVtbl->Release( pME );
  3607.     }
  3608.  
  3609. } // OnGraphNotify
  3610.  
  3611.  
  3612. /*---------------------------- FILE OPEN DIALOG -----------------------------*/
  3613.  
  3614.  
  3615. // This handles the file..open dialog box
  3616.  
  3617. static OPENFILENAME ofn;
  3618.  
  3619. //
  3620. // InitFileOpenDialog
  3621. //
  3622. BOOL InitFileOpenDialog( HWND hwnd )
  3623. {
  3624.     ofn.lStructSize         = sizeof( OPENFILENAME );
  3625.     ofn.hwndOwner           = hwnd;
  3626.     ofn.hInstance           = NULL;
  3627.     ofn.lpstrFilter         = "Windows Media files (*.asf,*.wma,*.wmv)\0*.asf; *.wma; *.wmv\0"
  3628.                               "MPEG audio files (*.mp2,*.mp3)\0*.mp2; *.mp3;\0"
  3629.                               "MPEG video files (*.mpg,*.mpe,*.mpeg)\0*.mpg; *.mpe; *.mpeg\0"
  3630.                               "AVI files (*.avi)\0*.avi\0"
  3631.                               "Quick Time files (*.mov)\0*.mov\0"
  3632.                               "Wave audio files (*.wav)\0*.wav\0"
  3633.                               "Filter graph files (*.grf)\0*.grf\0"
  3634.                               "All Files (*.*)\0*.*\0\0";
  3635.     ofn.lpstrCustomFilter   = NULL;
  3636.     ofn.nMaxCustFilter      = 0;
  3637.     ofn.nFilterIndex        = 0;
  3638.     ofn.lpstrFile           = NULL;
  3639.     ofn.nMaxFile            = _MAX_PATH;
  3640.     ofn.lpstrFileTitle      = NULL;
  3641.     ofn.nMaxFileTitle       = _MAX_FNAME + _MAX_EXT;
  3642.     ofn.lpstrInitialDir     = NULL;
  3643.     ofn.lpstrTitle          = NULL;
  3644.     ofn.Flags               = OFN_EXPLORER | OFN_FILEMUSTEXIST;
  3645.     ofn.nFileOffset         = 0;
  3646.     ofn.nFileExtension      = 0;
  3647.     ofn.lpstrDefExt         = "asf";
  3648.     ofn.lCustData           = 0;
  3649.     ofn.lpfnHook            = NULL;
  3650.     ofn.lpTemplateName      = NULL;
  3651.  
  3652.     return TRUE;
  3653.  
  3654. } // InitFileOpenDialog
  3655.  
  3656.  
  3657. //
  3658. // DoFileOpenDialog
  3659. //
  3660. BOOL DoFileOpenDialog( HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName )
  3661. {
  3662.     // Called to display the open file dialog
  3663.     ofn.hwndOwner = hwnd;
  3664.     ofn.lpstrFile = lpstrFileName;
  3665.     ofn.lpstrFileTitle = lpstrTitleName;
  3666.  
  3667.     ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
  3668.     SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
  3669.                  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
  3670.  
  3671.     return GetOpenFileName( &ofn );
  3672.  
  3673. } // DoFileOpenDialog
  3674.  
  3675.  
  3676.  
  3677. /*---------------------------- FILE SAVE DIALOG -----------------------------*/
  3678.  
  3679.  
  3680. // This handles the file..open dialog box
  3681.  
  3682. static OPENFILENAME sfn;
  3683.  
  3684. //
  3685. // InitFileSaveDialog
  3686. //
  3687. BOOL InitFileSaveDialog( HWND hwnd )
  3688. {
  3689.     sfn.lStructSize         = sizeof( OPENFILENAME );
  3690.     sfn.hwndOwner           = hwnd;
  3691.     sfn.hInstance           = NULL;
  3692.     sfn.lpstrFilter         = "Windows Media files (*.asf,*.wma,*.wmv)\0*.asf; *.wma; *.wmv\0"
  3693.                               "All Files (*.*)\0*.*\0\0";
  3694.     sfn.lpstrCustomFilter   = NULL;
  3695.     sfn.nMaxCustFilter      = 0;
  3696.     sfn.nFilterIndex        = 0;
  3697.     sfn.lpstrFile           = NULL;
  3698.     sfn.nMaxFile            = _MAX_PATH;
  3699.     sfn.lpstrFileTitle      = NULL;
  3700.     sfn.nMaxFileTitle       = _MAX_FNAME + _MAX_EXT;
  3701.     sfn.lpstrInitialDir     = NULL;
  3702.     sfn.lpstrTitle          = NULL;
  3703.     sfn.Flags               = OFN_EXPLORER ;
  3704.     sfn.nFileOffset         = 0;
  3705.     sfn.nFileExtension      = 0;
  3706.     sfn.lpstrDefExt         = "asf";
  3707.     sfn.lCustData           = 0;
  3708.     sfn.lpfnHook            = NULL;
  3709.     sfn.lpTemplateName      = NULL;
  3710.  
  3711.     return TRUE;
  3712.  
  3713. } // InitFileSaveDialog
  3714.  
  3715.  
  3716. //
  3717. // DoFileSaveDialog
  3718. //
  3719. BOOL DoFileSaveDialog( HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName )
  3720. {
  3721.     // Called to display the open file dialog
  3722.     sfn.hwndOwner = hwnd;
  3723.     sfn.lpstrFile = lpstrFileName;
  3724.     sfn.lpstrFileTitle = lpstrTitleName;
  3725.  
  3726.     ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
  3727.     SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
  3728.                  SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
  3729.  
  3730.     return GetSaveFileName( &sfn );
  3731.  
  3732. } // DoFileSaveDialog
  3733.  
  3734.  
  3735.  
  3736. /*----------------------------- TOOL BAR CODE -------------------------------*/
  3737.  
  3738.  
  3739. // Constants for the bitmap
  3740. const int nButtonImageWidth = 46;
  3741. const int nButtonImageHeight = 36;
  3742.  
  3743. // Constants for the toolbar implementation
  3744. const int nSeperatorGap = 6;
  3745. const int nToolbarBorderWidth = 5;
  3746. const int nToolbarBorderHeight = 3;
  3747.  
  3748. //
  3749. // CalcToolbarSize
  3750. //
  3751. void CalcToolbarSize( SIZE *pSize )
  3752. {
  3753.     // Calculate the area required for this toolbar
  3754.  
  3755.     // size for 3 buttons, 2 borders and a seperator
  3756.     // ...but we'll add on a some extra seperators for good measure
  3757.     pSize->cx = (nButtonImageWidth) * 5 + nSeperatorGap + 2 * nToolbarBorderWidth;
  3758.  
  3759.     // size for 1 button and 2 borders
  3760.     pSize->cy = nButtonImageHeight + 2 * nToolbarBorderHeight;
  3761.  
  3762. } // CalcToolbarSize
  3763.  
  3764.  
  3765. //
  3766. // UpdateToolbar
  3767. //
  3768. // Maintains the enabled/disabled state of the buttons - we should be
  3769. // called periodically and/or whenever there is a change of graph state
  3770. //
  3771. void UpdateToolbar()
  3772. {
  3773.     if (toolbar.hwndPlayButton != NULL)
  3774.         EnableWindow( toolbar.hwndPlayButton, CanPlay() );
  3775.     if (toolbar.hwndPauseButton != NULL)
  3776.         EnableWindow( toolbar.hwndPauseButton, CanPause() );
  3777.     if (toolbar.hwndStopButton != NULL)
  3778.         EnableWindow( toolbar.hwndStopButton, CanStop() );
  3779.     if (toolbar.hwndPreviewButton != NULL)
  3780.         EnableWindow( toolbar.hwndPreviewButton, CanPreview() );
  3781.     if (toolbar.hwndCancelButton != NULL)
  3782.         EnableWindow( toolbar.hwndCancelButton, Transmitting );
  3783.  
  3784. } // UpdateToolbar
  3785.  
  3786.  
  3787. //
  3788. // ToolbarButtonProc
  3789. //
  3790. // Subclassed window procedure for the toolbar buttons
  3791. //
  3792.  
  3793. long FAR PASCAL ToolbarButtonProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
  3794. {
  3795.     WNDPROC oldwndproc = (WNDPROC)GetWindowLong( hwnd, GWL_USERDATA );
  3796.  
  3797.     switch(message)
  3798.     {
  3799.         case WM_ERASEBKGND:
  3800.         {
  3801.             /* no nothing */
  3802.         }
  3803.         return (LRESULT) 1;
  3804.         break;
  3805.  
  3806.         default:
  3807.             return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
  3808.     }
  3809.     return (LRESULT) 0;
  3810.  
  3811. } // MainFrameProc
  3812.  
  3813. //
  3814. // InitToolbar
  3815. //
  3816. // Create the controls for the buttons
  3817. //
  3818. BOOL InitToolbar( HINSTANCE hInstance, HWND hwnd )
  3819. {
  3820.     LONG oldwndproc;
  3821.     int x;      // Position of the next button
  3822.  
  3823.     x = nToolbarBorderWidth;
  3824.  
  3825.     // The 'Play' button
  3826.     toolbar.hwndPlayButton = CreateWindow( "BUTTON",
  3827.                                            NULL,
  3828.                                            BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
  3829.                                            x,
  3830.                                            nToolbarBorderHeight,
  3831.                                            nButtonImageWidth,
  3832.                                            nButtonImageHeight,
  3833.                                            hwnd,
  3834.                                            (HMENU) ID_MEDIA_PLAY,
  3835.                                            hInstance,
  3836.                                            NULL);
  3837.  
  3838.     oldwndproc = SetWindowLong( toolbar.hwndPlayButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
  3839.     SetWindowLong(toolbar.hwndPlayButton, GWL_USERDATA, oldwndproc);
  3840.  
  3841.     x += nButtonImageWidth;
  3842.  
  3843.     // The 'Pause' button
  3844.     toolbar.hwndPauseButton = CreateWindow( "BUTTON",
  3845.                                             NULL,
  3846.                                             BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
  3847.                                             x,
  3848.                                             nToolbarBorderHeight,
  3849.                                             nButtonImageWidth,
  3850.                                             nButtonImageHeight,
  3851.                                             hwnd,
  3852.                                             (HMENU) ID_MEDIA_PAUSE,
  3853.                                             hInstance,
  3854.                                             NULL);
  3855.  
  3856.     oldwndproc = SetWindowLong( toolbar.hwndPauseButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
  3857.     SetWindowLong(toolbar.hwndPauseButton, GWL_USERDATA, oldwndproc);
  3858.  
  3859.     x += nButtonImageWidth;
  3860.  
  3861.     // The 'Stop' button
  3862.     toolbar.hwndStopButton = CreateWindow( "BUTTON",
  3863.                                            NULL,
  3864.                                            BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
  3865.                                            x,
  3866.                                            nToolbarBorderHeight,
  3867.                                            nButtonImageWidth,
  3868.                                            nButtonImageHeight,
  3869.                                            hwnd,
  3870.                                            (HMENU) ID_MEDIA_STOP,
  3871.                                            hInstance,
  3872.                                            NULL);
  3873.  
  3874.     oldwndproc = SetWindowLong( toolbar.hwndStopButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
  3875.     SetWindowLong(toolbar.hwndStopButton, GWL_USERDATA, oldwndproc);
  3876.  
  3877.     x += nButtonImageWidth + nSeperatorGap;
  3878.  
  3879.     // The 'Preview' button
  3880.     toolbar.hwndPreviewButton = CreateWindow( "BUTTON",
  3881.                                            NULL,
  3882.                                            BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
  3883.                                            x,
  3884.                                            nToolbarBorderHeight,
  3885.                                            nButtonImageWidth,
  3886.                                            nButtonImageHeight,
  3887.                                            hwnd,
  3888.                                            (HMENU) ID_STREAM_PREVIEW,
  3889.                                            hInstance,
  3890.                                            NULL);
  3891.  
  3892.     oldwndproc = SetWindowLong( toolbar.hwndPreviewButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
  3893.     SetWindowLong(toolbar.hwndPreviewButton, GWL_USERDATA, oldwndproc);
  3894.  
  3895.     x += nButtonImageWidth;
  3896.  
  3897.     // The 'Cancel' button
  3898.     toolbar.hwndCancelButton = CreateWindow( "BUTTON",
  3899.                                            NULL,
  3900.                                            BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
  3901.                                            x,
  3902.                                            nToolbarBorderHeight,
  3903.                                            nButtonImageWidth,
  3904.                                            nButtonImageHeight,
  3905.                                            hwnd,
  3906.                                            (HMENU) ID_STREAM_CANCEL,
  3907.                                            hInstance,
  3908.                                            NULL);
  3909.  
  3910.     oldwndproc = SetWindowLong( toolbar.hwndCancelButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
  3911.     SetWindowLong(toolbar.hwndCancelButton, GWL_USERDATA, oldwndproc);
  3912.  
  3913.     // We don't call UpdateToolbar to set the button states as
  3914.     // the multimedia variables may not have been initialized yet
  3915.     return TRUE;
  3916.  
  3917. } // InitToolbar
  3918.  
  3919.  
  3920. //
  3921. // DrawButton
  3922. //
  3923. // Called by the main window whenever a button needs to be redrawn
  3924. //
  3925. void DrawButton( HINSTANCE hInstance, DRAWITEMSTRUCT FAR * lpDrawItem )
  3926. {
  3927.     HDC hSourceDC = CreateCompatibleDC( NULL );
  3928.     HGDIOBJ loadedbitmap;
  3929.     HGDIOBJ hgdiOldBitmap;
  3930.     int nIndex;
  3931.  
  3932.     // Load the IDR_TOOLBAR_INACTIVE bitmap into our source hDC if the
  3933.     // button is disabled otherwise load the IDR_TOOLBAR_PRESSED/NOTPRESSED bitmap
  3934.     if( lpDrawItem->itemState & ODS_DISABLED )
  3935.         loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_INACTIVE ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
  3936.     else
  3937.     {
  3938.         if( lpDrawItem->itemState & ODS_SELECTED )
  3939.             loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_PRESSED ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
  3940.         else
  3941.             loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_NOTPRESSED ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
  3942.     }
  3943.     hgdiOldBitmap = SelectObject( hSourceDC, loadedbitmap );
  3944.  
  3945.     // Decide which button to blit to the display
  3946.     switch( lpDrawItem->CtlID ){
  3947.         case ID_MEDIA_PLAY:
  3948.             nIndex = 0;
  3949.             break;
  3950.  
  3951.         case ID_MEDIA_PAUSE:
  3952.             nIndex = 1;
  3953.             break;
  3954.  
  3955.         case ID_MEDIA_STOP:
  3956.             nIndex = 2;
  3957.             break;
  3958.  
  3959.         case ID_STREAM_PREVIEW:
  3960.             nIndex = 3;
  3961.             break;
  3962.  
  3963.         case ID_STREAM_CANCEL:
  3964.             nIndex = 4;
  3965.             break;
  3966.     }
  3967.  
  3968.     // ..and blit it
  3969.     BitBlt( lpDrawItem->hDC,
  3970.             lpDrawItem->rcItem.left,
  3971.             lpDrawItem->rcItem.top ,
  3972.             nButtonImageWidth,
  3973.             nButtonImageHeight,
  3974.             hSourceDC,
  3975.             nIndex * nButtonImageWidth + 2,
  3976.             0,
  3977.             SRCCOPY
  3978.           );
  3979.  
  3980.     // Restore the original bitmap
  3981.     SelectObject( hSourceDC, hgdiOldBitmap );
  3982.  
  3983.     // this was missing from the Microsoft example code
  3984.     DeleteObject(loadedbitmap);
  3985.     DeleteDC(hSourceDC);
  3986. } // DrawButton
  3987.  
  3988.  
  3989. /*---------------------------- TRACK BAR CODE -------------------------------*/
  3990.  
  3991. const int nTrackbarBorderWidth = 5;
  3992. const int nTrackbarBorderHeight = 11;
  3993.  
  3994. //
  3995. // CalcTrackbarSize
  3996. //
  3997. // Calculate the size of the trackbar (including borders)
  3998. //
  3999.  
  4000. void CalcTrackbarSize ( SIZE *pSize )
  4001. {
  4002.     RECT clientRect;
  4003.  
  4004.     SIZE sizeToolbar;
  4005.  
  4006.     GetClientRect( appVars.hwndMainFrame, &clientRect );
  4007.     CalcToolbarSize( &sizeToolbar );
  4008.  
  4009.     pSize->cx = (clientRect.right-clientRect.left+1) - sizeToolbar.cx;
  4010.     pSize->cy = sizeToolbar.cy;
  4011.  
  4012. } // CalcTrackbarSize
  4013.  
  4014.  
  4015. //
  4016. // TrackbarProc
  4017. //
  4018. // Subclassed window procedure for the trackbar
  4019. //
  4020.  
  4021. long FAR PASCAL TrackbarProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
  4022. {
  4023.     WNDPROC oldwndproc = (WNDPROC)GetWindowLong( hwnd, GWL_USERDATA );
  4024.  
  4025.     switch(message)
  4026.     {
  4027.         /* This modifies the default behaviour of the trackbar.     */
  4028.         /* When clicking inside the channel, the click position     */
  4029.         /* is converted to a slider position value and stored in    */
  4030.         /* positionTrackbar                                         */
  4031.  
  4032.         /* this enables us to move the slider to this position when */
  4033.         /* we receive a WM_NOTIFY / NM_RELEASEDCAPTURE message      */
  4034.  
  4035.     case WM_LBUTTONDOWN:
  4036.         {
  4037.             UINT fwKeys = wParam;        // key flags
  4038.             if (fwKeys == MK_LBUTTON)
  4039.             {
  4040.                 int xPos = LOWORD(lParam);  // horizontal position of cursor
  4041.                 int yPos = HIWORD(lParam);  // vertical position of cursor
  4042.                 RECT chanrect;
  4043.                 LONG chanwidth;
  4044.  
  4045.                 SendMessage(hwndTrackbar, TBM_GETCHANNELRECT, 0, (LPARAM) &chanrect);
  4046.                 chanwidth = chanrect.right - chanrect.left + 1;
  4047.  
  4048.                 if (xPos >= chanrect.left && xPos <= chanrect.right)
  4049.                 {
  4050.                     UINT min, max;
  4051.                     min = SendMessage(hwndTrackbar, TBM_GETRANGEMIN, 0, 0);
  4052.                     max = SendMessage(hwndTrackbar, TBM_GETRANGEMAX, 0, 0);
  4053.  
  4054.                     positionTrackbar = min + ((max-min)*(xPos-chanrect.left))/chanwidth;
  4055.                 }
  4056.             }
  4057.             return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
  4058.         }
  4059.         break;
  4060.  
  4061.     case WM_ERASEBKGND:
  4062.         {
  4063.             /* no nothing */
  4064.         }
  4065.         return (LRESULT) 1;
  4066.         break;
  4067.  
  4068.         default:
  4069.             return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
  4070.     }
  4071.     return (LRESULT) 0;
  4072.  
  4073. } // TrackbarProc
  4074.  
  4075.  
  4076. //
  4077. // AdjustTrackbar
  4078. //
  4079. // Reposition the trackbar control in the main frame
  4080. //
  4081.  
  4082. void AdjustTrackbar ( HWND hwndTrack, HWND hwndParent )
  4083. {
  4084.     int x,y,w,h;
  4085.  
  4086.     SIZE sizeToolbar;
  4087.     SIZE sizeTrackbar;
  4088.  
  4089.     CalcToolbarSize( &sizeToolbar );
  4090.     CalcTrackbarSize ( &sizeTrackbar );
  4091.  
  4092.     x = sizeToolbar.cx + nTrackbarBorderWidth;
  4093.     y = (sizeToolbar.cy - sizeTrackbar.cy)/2 + nTrackbarBorderHeight;
  4094.     w = sizeTrackbar.cx - 2 * nTrackbarBorderWidth;
  4095.     h = sizeTrackbar.cy - 2 * nTrackbarBorderHeight;
  4096.  
  4097.     MoveWindow( hwndTrack, x,y,w,h, TRUE );
  4098.  
  4099. } // AdjustTrackbar
  4100.  
  4101.  
  4102. //
  4103. // InitTrackbar
  4104. //
  4105. // Create and initialize the trackbar control
  4106. //
  4107.  
  4108. BOOL InitTrackbar( HINSTANCE hInstance, HWND hwnd )
  4109. {
  4110.     LONG oldwndproc;
  4111.     int x,y,w,h;
  4112.  
  4113.     SIZE sizeToolbar;
  4114.     SIZE sizeTrackbar;
  4115.  
  4116.     CalcToolbarSize( &sizeToolbar );
  4117.     CalcTrackbarSize ( &sizeTrackbar );
  4118.  
  4119.     x = sizeToolbar.cx + nTrackbarBorderWidth;
  4120.     y = (sizeToolbar.cy - sizeTrackbar.cy)/2 + nTrackbarBorderHeight;
  4121.     w = sizeTrackbar.cx - 2 * nTrackbarBorderWidth;
  4122.     h = sizeTrackbar.cy - 2 * nTrackbarBorderHeight;
  4123.  
  4124.     // Create the trackbar
  4125.     hwndTrackbar = CreateWindow( TRACKBAR_CLASS,
  4126.                                  NULL,
  4127.                                  WS_DISABLED | WS_VISIBLE | WS_CHILD | TBS_NOTICKS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH,
  4128.                                  x,
  4129.                                  y,
  4130.                                  w,
  4131.                                  h,
  4132.                                  hwnd,
  4133.                                  (HMENU) IDR_TRACKBAR,
  4134.                                  hInstance,
  4135.                                  NULL );
  4136.  
  4137.     SendMessage(hwndTrackbar, TBM_SETTHUMBLENGTH, 16, 0);
  4138.  
  4139.     /* TrackBars range is from 0 to 10000, regardless of the stream length */
  4140.     SendMessage(hwndTrackbar, TBM_SETRANGEMIN, FALSE, 0     );
  4141.     SendMessage(hwndTrackbar, TBM_SETRANGEMAX, FALSE, 10000 );
  4142.  
  4143.     /* disable pageup/down lineup/down using keyboard or mouse */
  4144.     SendMessage(hwndTrackbar, TBM_SETPAGESIZE,    0 , 0);
  4145.     SendMessage(hwndTrackbar, TBM_SETLINESIZE,    0,  0);
  4146.  
  4147.     oldwndproc = SetWindowLong( hwndTrackbar, GWL_WNDPROC, (DWORD)&TrackbarProc);
  4148.     SetWindowLong(hwndTrackbar, GWL_USERDATA, oldwndproc);
  4149.  
  4150.     return TRUE;
  4151.  
  4152. } // InitTrackbar
  4153.  
  4154.  
  4155. //
  4156. // TrackbarTimerFunc
  4157. //
  4158. // Moves the trackbar during media replay. Also prints time stamp.
  4159. //
  4160.  
  4161. void CALLBACK TrackbarTimerFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  4162. {
  4163.     HRESULT hr;
  4164.     IMediaPosition * pMP;
  4165.  
  4166.     if (idEvent == TrackbarTimer)
  4167.     {
  4168.         if (IMPTotalTime != 0.0)
  4169.         {
  4170.             if (IsInitialized())
  4171.             {
  4172.                 hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
  4173.                                                           &IID_IMediaPosition,
  4174.                                                           (void**) &pMP);
  4175.                 if (SUCCEEDED(hr))
  4176.                 {
  4177.                     REFTIME tCurrent;
  4178.                     hr = pMP->lpVtbl->get_CurrentPosition(pMP, &tCurrent);
  4179.                     if (SUCCEEDED(hr))
  4180.                     {
  4181.                         LONG value;
  4182.  
  4183.                         if (Previewing)
  4184.                         {
  4185.                             if (tCurrent < IMPDownloadTime)
  4186.                             {
  4187.                                 IMPCurrentPosition = tCurrent;
  4188.                             }
  4189.                         }
  4190.                         else
  4191.                         {
  4192.                             IMPCurrentPosition = tCurrent;
  4193.                         }
  4194.  
  4195.                         if (hwndTrackbar != NULL)
  4196.                         {
  4197.                             if (!TrackbarDragging)
  4198.                             {
  4199.                                 value = (LONG)(10000 * IMPCurrentPosition / IMPTotalTime);
  4200.                                 SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, value);
  4201.                             }
  4202.                         }
  4203.  
  4204.  
  4205.                         if ((!Transmitting) && (!TrackbarDragging))
  4206.                         {
  4207.                             unsigned int timecode = (unsigned int)(1000 * IMPCurrentPosition);
  4208.                             char *timecodestring = createtimestring(timecode);
  4209.                             SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecodestring);
  4210.                         }
  4211.                     }
  4212.                     pMP->lpVtbl->Release(pMP);
  4213.                 }
  4214.             }
  4215.         }
  4216.     }
  4217.  
  4218. } // TrackbarTimerFunc
  4219.  
  4220.  
  4221. /*---------------------- FILE TYPE REGISTRATION CODE ------------------------*/
  4222.  
  4223. enum
  4224. {
  4225.     Query,
  4226.     Register,
  4227.     Unregister
  4228. };
  4229.  
  4230. //
  4231. // FileTypeRegistration
  4232. //
  4233. // query for, register or unregister a given file type
  4234. //
  4235.  
  4236. BOOL FileTypeRegistration(LPTSTR filetype, int mode)
  4237. {
  4238.     BOOL result = FALSE;
  4239.  
  4240.     LONG retval;
  4241.     HKEY hkeyFileExtension;
  4242.     HKEY hkeyFileType;
  4243.     DWORD dwResult;
  4244.  
  4245.     unsigned char keyname[32];
  4246.     unsigned char defaulttypename[32];
  4247.     unsigned char *src, *dst;
  4248.  
  4249.     int i;
  4250.  
  4251.     keyname[0] = '.';
  4252.     for (src = filetype, dst = &keyname[1]; *dst = tolower(*src) ; dst++, src++ );
  4253.     for (src = filetype, dst = defaulttypename; *dst = toupper(*src) ; dst++, src++ );
  4254.     strcat(defaulttypename, "File");
  4255.  
  4256.     retval = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  4257.                             keyname,
  4258.                             0,
  4259.                             NULL,
  4260.                             REG_OPTION_NON_VOLATILE,
  4261.                             KEY_READ | KEY_WRITE,
  4262.                             NULL,
  4263.                             &hkeyFileExtension,
  4264.                             &dwResult);
  4265.  
  4266.     if (retval != ERROR_SUCCESS)
  4267.     {
  4268.         gui_criticalerror("RegCreateKeyEx (1) for '%s' failed: %d\n", keyname, retval);
  4269.     }
  4270.     else
  4271.     {
  4272.         unsigned char filetypename[200];
  4273.         unsigned char filetypenameshellcommand[256];
  4274.         DWORD dwType;
  4275.         DWORD dwSize;
  4276.  
  4277.         strcpy(filetypename, "");
  4278.  
  4279.         dwSize = sizeof(filetypename);
  4280.         retval = RegQueryValueEx( hkeyFileExtension,
  4281.                                   "",
  4282.                                   0,
  4283.                                   &dwType,
  4284.                                   filetypename,
  4285.                                   &dwSize );
  4286.  
  4287.         if (retval != ERROR_SUCCESS)
  4288.         {
  4289.             if (retval != ERROR_FILE_NOT_FOUND)
  4290.                 gui_criticalerror("RegQueryValueEx (1) for '%s' failed: %d\n", "(Default)", retval);
  4291.             else
  4292.             {
  4293.                 retval = RegSetValueEx( hkeyFileExtension,
  4294.                                         "",
  4295.                                         0,
  4296.                                         REG_SZ,
  4297.                                         defaulttypename,
  4298.                                         strlen(defaulttypename)+1 );
  4299.                 if (retval != ERROR_SUCCESS)
  4300.                 {
  4301.                     gui_criticalerror("RegSetValueEx (1) for '%s' failed: %d\n", "(Default)", retval);
  4302.                 }
  4303.                 else
  4304.                     strcpy(filetypename, defaulttypename);
  4305.             }
  4306.         }
  4307.         else
  4308.         {
  4309.             if (dwType == REG_SZ)
  4310.             {
  4311.                 if (!strcmp("", filetypename))
  4312.                 {
  4313.                     retval = RegSetValueEx( hkeyFileExtension,
  4314.                                             "",
  4315.                                             0,
  4316.                                             REG_SZ,
  4317.                                             defaulttypename,
  4318.                                             strlen(defaulttypename)+1 );
  4319.                     if (retval != ERROR_SUCCESS)
  4320.                     {
  4321.                         gui_criticalerror("RegSetValueEx (2) for '%s' failed: %d\n", "(Default)", retval);
  4322.                     }
  4323.                     else
  4324.                         strcpy(filetypename, defaulttypename);
  4325.                 }
  4326.             }
  4327.         }
  4328.             
  4329.  
  4330.         if (strcmp(filetypename, ""))
  4331.         {
  4332.             if (mode == Query)
  4333.                 result = TRUE;
  4334.  
  4335.             for (i = 0; i < 2 ; i++)
  4336.             {
  4337.                 strcpy(filetypenameshellcommand, filetypename);
  4338.                 if (i == 0)
  4339.                     strcat(filetypenameshellcommand, "\\shell\\open\\command");
  4340.                 if (i == 1)
  4341.                     strcat(filetypenameshellcommand, "\\shell\\play\\command");
  4342.  
  4343.                 retval = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  4344.                                         filetypenameshellcommand,
  4345.                                         0,
  4346.                                         NULL,
  4347.                                         REG_OPTION_NON_VOLATILE,
  4348.                                         KEY_READ | KEY_WRITE,
  4349.                                         NULL,
  4350.                                         &hkeyFileType,
  4351.                                         &dwResult);
  4352.  
  4353.                 if (retval != ERROR_SUCCESS)
  4354.                 {
  4355.                     gui_criticalerror("RegCreateKeyEx (2) for '%s' failed: %d\n", filetypenameshellcommand, retval);
  4356.                 }
  4357.                 else
  4358.                 {
  4359.                     unsigned char playername[512];
  4360.                     unsigned char playernameuppercase[512];
  4361.                     DWORD dwType = REG_NONE;
  4362.                     DWORD dwSize;
  4363.                     
  4364.                     dwSize = sizeof(playername);
  4365.                     retval = RegQueryValueEx( hkeyFileType,
  4366.                                               "",
  4367.                                               0,
  4368.                                               &dwType,
  4369.                                               playername,
  4370.                                               &dwSize );
  4371.  
  4372.                     if (retval != ERROR_SUCCESS)
  4373.                     {
  4374.                         if (retval != ERROR_FILE_NOT_FOUND)
  4375.                             gui_criticalerror("RegQueryValueEx (2) for '%s' failed: %d\n", "(Default)", retval);
  4376.                         else
  4377.                             strcpy(playername, "");
  4378.                         dwType = REG_SZ;
  4379.                     }
  4380.                         
  4381.                     if (dwType == REG_SZ)
  4382.                     {
  4383.                         unsigned char myplayername[512];
  4384.                         unsigned char myplayernameuppercase[512];
  4385.                         sprintf(myplayername, "\42%s\42 \42%%L\42", appVars.szProgramExecutable);
  4386.                         
  4387.                         /* make uppercase versions of playername strings */
  4388.                         strcpy(playernameuppercase, playername);
  4389.                         _strupr(playernameuppercase);
  4390.                         
  4391.                         strcpy(myplayernameuppercase, myplayername);
  4392.                         _strupr(myplayernameuppercase);
  4393.  
  4394.                         switch (mode)
  4395.                         {
  4396.                         case Query:
  4397.                             
  4398.                             /* try to match player name with asfrecorder */
  4399.                             if ( (strstr(playernameuppercase, myplayernameuppercase ) == NULL) &&
  4400.                                  (strstr(playernameuppercase, "ASFRECORDER"         ) == NULL) &&
  4401.                                  (strstr(playernameuppercase, "ASFREC~"             ) == NULL)    )
  4402.                             {
  4403.                                 result = FALSE;
  4404.                                 break;
  4405.                             }
  4406.                             break;
  4407.                             
  4408.                         case Register:
  4409.                             /* Create backup of old player only if its name */
  4410.                             /* does not contain the string "ASFRecorder" and*/
  4411.                             /* if it is not empty */
  4412.                             if ((strcmp(playernameuppercase, ""           )        ) &&
  4413.                                 (strstr(playernameuppercase, "ASFRECORDER") == NULL) &&
  4414.                                 (strstr(playernameuppercase, "ASFREC~1"   ) == NULL)    )
  4415.                             {
  4416.                                 retval = RegSetValueEx( hkeyFileType,
  4417.                                                         "ASFRecorder_backup",
  4418.                                                         0,
  4419.                                                         REG_SZ,
  4420.                                                         playername,
  4421.                                                         strlen(playername)+1 );
  4422.                                 if (retval != ERROR_SUCCESS)
  4423.                                 {
  4424.                                     gui_criticalerror("RegSetValueEx (3) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
  4425.                                 }
  4426.                             }
  4427.                             
  4428.                             retval = RegSetValueEx( hkeyFileType,
  4429.                                                     "",
  4430.                                                     0,
  4431.                                                     REG_SZ,
  4432.                                                     myplayername,
  4433.                                                     strlen(myplayername)+1 );
  4434.                             if (retval != ERROR_SUCCESS)
  4435.                             {
  4436.                                 gui_criticalerror("RegSetValueEx (4) for '%s' failed: %d\n", "(Default)", retval);
  4437.                             }
  4438.                             break;
  4439.                             
  4440.                         case Unregister:
  4441.                             dwSize = sizeof(playername);
  4442.                             retval = RegQueryValueEx( hkeyFileType,
  4443.                                                       "ASFRecorder_backup",
  4444.                                                       0,
  4445.                                                       &dwType,
  4446.                                                       playername,
  4447.                                                       &dwSize );
  4448.                             if ((retval != ERROR_SUCCESS) && (retval != ERROR_FILE_NOT_FOUND))
  4449.                             {
  4450.                                 gui_criticalerror("RegQueryValueEx (3) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
  4451.                             }
  4452.                             else
  4453.                             {
  4454.                                 if (retval == ERROR_FILE_NOT_FOUND)
  4455.                                 {
  4456.                                     dwType = REG_SZ;
  4457.                                     strcpy(playername, "");
  4458.                                 }
  4459.                                 
  4460.                                 if (dwType == REG_SZ)
  4461.                                 {
  4462.                                     retval = RegSetValueEx( hkeyFileType,
  4463.                                                             "",
  4464.                                                             0,
  4465.                                                             REG_SZ,
  4466.                                                             playername,
  4467.                                                             strlen(playername)+1 );
  4468.                                     if (retval != ERROR_SUCCESS)
  4469.                                     {
  4470.                                         gui_criticalerror("RegSetValueEx (5) for '%s' failed: %d\n", "(Default)", retval);
  4471.                                     }
  4472.                                     else
  4473.                                     {
  4474.                                         retval = RegDeleteValue( hkeyFileType,
  4475.                                             "ASFRecorder_backup" );
  4476.                                         if ((retval != ERROR_SUCCESS) && (retval != ERROR_FILE_NOT_FOUND))
  4477.                                         {
  4478.                                             gui_criticalerror("RegDeleteValue (1) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
  4479.                                         }
  4480.                                     }
  4481.                                 }
  4482.                             }
  4483.                             break;
  4484.                         }
  4485.                     }
  4486.                     RegCloseKey(hkeyFileType);
  4487.                 }
  4488.             }
  4489.         }
  4490.         RegCloseKey(hkeyFileExtension);
  4491.     }
  4492.     return result;
  4493.  
  4494. } // FileTypeRegistration
  4495.  
  4496.  
  4497. //
  4498. // OnRegisterFileTypes
  4499. //
  4500. // Register redirection file types.
  4501. //
  4502.  
  4503. void OnRegisterFileTypes()
  4504. {
  4505.     if ( (!FileTypeRegistration("ASX", Query)) ||
  4506.          (!FileTypeRegistration("WAX", Query)) ||
  4507.          (!FileTypeRegistration("WVX", Query)) ||
  4508.          (!FileTypeRegistration("WMX", Query))   )
  4509.     {
  4510.         FileTypeRegistration("ASX", Register);
  4511.         FileTypeRegistration("WAX", Register);
  4512.         FileTypeRegistration("WVX", Register);
  4513.         FileTypeRegistration("WMX", Register);
  4514.         PlayerMessageBox( IDS_REGISTERED );
  4515.     }
  4516.     else
  4517.     {
  4518.         PlayerMessageBox( IDS_ALREADYREGISTERED );
  4519.     }
  4520.  
  4521. } // OnRegisterFileTypes
  4522.  
  4523.  
  4524. //
  4525. // OnRegisterFileTypes
  4526. //
  4527. // Unregister redirection file types.
  4528. //
  4529.  
  4530. void OnUnregisterFileTypes()
  4531. {
  4532.     if ( FileTypeRegistration("ASX", Query) ||
  4533.          FileTypeRegistration("WAX", Query) ||
  4534.          FileTypeRegistration("WVX", Query) ||
  4535.          FileTypeRegistration("WMX", Query)   )
  4536.     {
  4537.         FileTypeRegistration("ASX", Unregister);
  4538.         FileTypeRegistration("WAX", Unregister);
  4539.         FileTypeRegistration("WVX", Unregister);
  4540.         FileTypeRegistration("WMX", Unregister);
  4541.         PlayerMessageBox( IDS_UNREGISTERED );
  4542.     }
  4543.     else
  4544.     {
  4545.         PlayerMessageBox( IDS_NOTREGISTERED );
  4546.     }
  4547.  
  4548. } // OnUnregisterFileTypes
  4549.