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 >
Wrap
C/C++ Source or Header
|
2000-12-15
|
136KB
|
4,549 lines
/* GUI code for the ASFRecorder application */
/* Uses ActiveMovie (DirectShow) for stream preview */
#include "global.h"
#include "CmdLine.h"
#ifdef __MINGW32__
/* we need to rename the main() function for MINGW32 */
/* because otherwise WinMain() will never be called */
#define main(argc,argv) renamed_main(argc,argv)
#endif /* __MINGW32__ */
#define UNTITLED_STRING " - Untitled"
#define nMaxResourceStrSize 128
/*--------------------------------- GLOBALS ---------------------------------*/
/* some application variables */
AppVars appVars;
/* used for inter-process communication */
UINT WM_APPMSG;
#define MAGIC_COOKIE 0x1234
BOOL Idle = TRUE;
/* window and control handles */
HWND hwndAboutBox = NULL;
HWND hwndStatusbar = NULL;
HWND hwndOpenURLDialog = NULL;
// The window for each toolbar button
struct{
HWND hwndPlayButton;
HWND hwndPauseButton;
HWND hwndStopButton;
HWND hwndPreviewButton;
HWND hwndCancelButton;
} toolbar = {NULL, NULL, NULL, NULL, NULL};
HWND hwndTrackbar = NULL;
/* timer for flashing status bar */
#define ID_STATUSTIMER 1
UINT StatusTimer = 0;
UINT StatusTimerCount;
UINT StatusTimerCref;
/* timer for moving trackbar */
#define ID_TRACKBARTIMER 2
UINT TrackbarTimer = 0;
/* some more trackbar stuff */
int positionTrackbar;
BOOL TrackbarDragging = FALSE;
/* flags/names of current stream and media file */
BOOL Batchmode = FALSE;
char StreamURL[512] = "";
char StreamFilename[512] = "";
unsigned int StreamTotalTime;
unsigned int StreamMaxTime;
BOOL Transmitting = FALSE;
BOOL Previewing = FALSE;
/* data obtained from the IMediaPosition interface */
REFTIME IMPTotalTime;
REFTIME IMPCurrentPosition;
REFTIME IMPDownloadTime; /* obtained from gui_progressinfo */
/* data obtained from the IMediaSeeking interface */
LONGLONG IMSTotalTime;
LONGLONG IMSCurrentPosition;
DWORD IMSCapabilities;
LONGLONG IMSDownloadTime; /* obtained from gui_progressinfo */
/* video window positions */
long IVWWindowLeft = 0;
long IVWWindowTop = 0;
long IVWWindowWidth = 0;
long IVWWindowHeight = 0;
/* definition of min/max widths of status bar parts */
int StatusDefinitionArray[] =
{ 6,
50, 80,
30, 40,
80, 120,
50, 80,
160, -1,
16, 16 };
/* enumeration of the status bar parts */
enum
{ STAT_KB = 0,
STAT_PROGRESS,
STAT_TIMECODE,
STAT_SEQNO,
STAT_STATUS, };
/* event for network socket notification */
WSAEVENT NetworkEvent = WSA_INVALID_EVENT;
SOCKET NetworkSocket = INVALID_SOCKET;
/* Winsock error strings/codes */
struct ErrorDef
{
char* ErrorName;
int ErrorVal;
} WinSockErrors[] =
{
"INTR" ,(WSABASEERR+4),
"BADF" ,(WSABASEERR+9),
"ACCES" ,(WSABASEERR+13),
"FAULT" ,(WSABASEERR+14),
"INVAL" ,(WSABASEERR+22),
"MFILE" ,(WSABASEERR+24),
"WOULDBLOCK" ,(WSABASEERR+35),
"INPROGRESS" ,(WSABASEERR+36),
"ALREADY" ,(WSABASEERR+37),
"NOTSOCK" ,(WSABASEERR+38),
"DESTADDRREQ" ,(WSABASEERR+39),
"MSGSIZE" ,(WSABASEERR+40),
"PROTOTYPE" ,(WSABASEERR+41),
"NOPROTOOPT" ,(WSABASEERR+42),
"PROTONOSUPPORT" ,(WSABASEERR+43),
"SOCKTNOSUPPORT" ,(WSABASEERR+44),
"OPNOTSUPP" ,(WSABASEERR+45),
"PFNOSUPPORT" ,(WSABASEERR+46),
"AFNOSUPPORT" ,(WSABASEERR+47),
"ADDRINUSE" ,(WSABASEERR+48),
"ADDRNOTAVAIL" ,(WSABASEERR+49),
"NETDOWN" ,(WSABASEERR+50),
"NETUNREACH" ,(WSABASEERR+51),
"NETRESET" ,(WSABASEERR+52),
"CONNABORTED" ,(WSABASEERR+53),
"CONNRESET" ,(WSABASEERR+54),
"NOBUFS" ,(WSABASEERR+55),
"ISCONN" ,(WSABASEERR+56),
"NOTCONN" ,(WSABASEERR+57),
"SHUTDOWN" ,(WSABASEERR+58),
"TOOMANYREFS" ,(WSABASEERR+59),
"TIMEDOUT" ,(WSABASEERR+60),
"CONNREFUSED" ,(WSABASEERR+61),
"LOOP" ,(WSABASEERR+62),
"NAMETOOLONG" ,(WSABASEERR+63),
"HOSTDOWN" ,(WSABASEERR+64),
"HOSTUNREACH" ,(WSABASEERR+65),
"NOTEMPTY" ,(WSABASEERR+66),
"PROCLIM" ,(WSABASEERR+67),
"USERS" ,(WSABASEERR+68),
"DQUOT" ,(WSABASEERR+69),
"STALE" ,(WSABASEERR+70),
"REMOTE" ,(WSABASEERR+71),
"SYSNOTREADY" ,(WSABASEERR+91),
"VERNOTSUPPORTED" ,(WSABASEERR+92),
"NOTINITIALISED" ,(WSABASEERR+93),
"DISCON" ,(WSABASEERR+101),
"HOST_NOT_FOUND" ,(WSABASEERR+1001),
"TRY_AGAIN" ,(WSABASEERR+1002),
"NO_RECOVERY" ,(WSABASEERR+1003),
"NO_DATA" ,(WSABASEERR+1004),
NULL, -1
};
/*--------------------------- FUNCTION PROTOTYPES ---------------------------*/
/* Function prototypes for externals in asfrecorder.c */
extern int main(int argc, char **argv);
extern int main_function(int argc, char **argv);
extern void gui_abort(void);
extern char *createtimestring(unsigned int timecode);
typedef enum {
ShowUsage,
NoArguments,
BadOption,
} UsageMode;
void Usage(char *progname, UsageMode mode);
UINT DoEnterPasswordDialog( HINSTANCE hInstance, HANDLE hwnd );
UINT DoProxyConfigurationDialog( HINSTANCE hInstance, HANDLE hwnd );
/*--------------------------- WINMAIN ENTRY POINT ---------------------------*/
//
// WinMain
//
// use call custom command line parser and
// give control to main() in asfrecorder.c
//
int PASCAL WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow )
{
UINT nReturn = 0;
HWND win;
DWORD result;
LPTSTR cmdline;
cmdline = GetCommandLine();
/* register an application- and inter-process-global message */
WM_APPMSG = RegisterWindowMessage( APP_NAME );
if (WM_APPMSG != 0)
{
/* loop through all other open ASFRecorder windows */
win = NULL;
while ((win = FindWindowEx(NULL, win, APP_NAME, NULL)) != NULL)
{
/* send an application-specific message to the other windows */
/* to probe if these windows are "idle" (not in a transfer) */
if (SendMessageTimeout( win, WM_APPMSG, 0, 0, SMTO_BLOCK, 250, &result) != 0)
{
if (result == MAGIC_COOKIE)
{
COPYDATASTRUCT cds;
DWORD result2;
/* other windows seems to be idle */
/* so send our command line to this window */
cds.dwData = MAGIC_COOKIE;
cds.cbData = strlen(cmdline)+1;
cds.lpData = cmdline;
result2 = SendMessage( win, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds );
if (result2 == MAGIC_COOKIE)
{
/* other window processed the message */
/* so we can exit this process now */
return nReturn;
}
}
}
}
}
/* seems that no other ASFRecorder window was willing to accept */
/* our command line. So we have to handle it in this process. */
if (ParseCommandLine(cmdline))
{
appVars.szProgramExecutable = argv[0];
main(argc, argv);
}
FreeCommandLine();
return nReturn;
} // WinMain
/*-------------- INTERFACE CODE TO ASFRECORDER NETWORKING CORE --------------*/
int gui_initialize()
{
UINT nReturn;
HINSTANCE hInstance = GetModuleHandleA(NULL);
HINSTANCE hPrevInstance = NULL;
LPSTR lpszCmdParam = NULL;
int nCmdShow = SW_SHOW;
nReturn = PseudoWinMain(hInstance, hPrevInstance, lpszCmdParam, nCmdShow);
return nReturn;
}
void gui_uninitialize(void)
{
EndOfWinMain();
}
void gui_setbatchmode(int flag)
{
Batchmode = flag;
}
int gui_startedfromdesktop(void)
{
int fromdesktop = 0;
/* I don't know if this is correct, but */
/* it works for determining wheter this */
/* programm was started from DOS or from */
/* Windows Explorer, both on Win98 and NT */
LPTSTR lpszVariable;
LPVOID lpvEnv;
// Get a pointer to the environment block.
if ((lpvEnv = GetEnvironmentStrings()) != NULL)
{
// Variable strings are separated by NULL byte, and the block is
// terminated by a NULL byte.
for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++)
{
/* this one is for Windows NT (together with PROMPT=) */
if (!stricmp(lpszVariable, "OS=Windows_NT"))
fromdesktop = 1;
while (*lpszVariable) lpszVariable++;
}
for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++)
{
/* this one for Windows 98 */
if (!stricmp(lpszVariable, "CMDLINE=win"))
fromdesktop = 1;
/* required for Windows NT only */
if (!strnicmp(lpszVariable, "PROMPT=", 7))
fromdesktop = 0;
while (*lpszVariable) lpszVariable++;
}
FreeEnvironmentStrings(lpvEnv);
}
return fromdesktop;
}
void gui_prepareasyncsocket(SOCKET s)
{
int rc;
if (NetworkEvent == WSA_INVALID_EVENT)
{
NetworkEvent = WSACreateEvent();
}
if (NetworkEvent != WSA_INVALID_EVENT)
{
NetworkSocket = s;
rc = WSAEventSelect(s, NetworkEvent, FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE);
if (rc == SOCKET_ERROR)
{
gui_criticalerror("WSAEventSelect() failed! Error code: %d\n", WSAGetLastError());
}
}
}
void gui_restoresyncsocket(SOCKET s)
{
WSAEventSelect(s, NULL, 0);
WSACloseEvent(NetworkEvent);
NetworkSocket = INVALID_SOCKET;
NetworkEvent = WSA_INVALID_EVENT;
}
void gui_return_on_network_activity(void)
{
/* don't enter main loop if the user has already closed the main window */
if (appVars.hwndMainFrame != NULL)
{
DoMainLoop(FD_READ | FD_WRITE | FD_CLOSE);
}
}
void gui_return_on_network_connect(int *returnval)
{
/* don't enter main loop if the user has already closed the main window */
if (appVars.hwndMainFrame != NULL)
{
int ret = DoMainLoop(FD_CONNECT);
if (ret == 0)
*returnval = 0;
else
{
*returnval = SOCKET_ERROR;
WSASetLastError(ret);
}
}
else
{
*returnval = 0;
}
}
int gui_nonblocking_socket_check(int num)
{
if (num == WSAEWOULDBLOCK)
return 1;
else
return 0;
}
void gui_waitforuseraction()
{
/* don't enter main loop if the user has already closed the main window */
if (appVars.hwndMainFrame != NULL)
{
DoMainLoop(0);
}
}
void gui_showtext(char *text, ...)
{
char Buffer[4096];
va_list arglist;
va_start(arglist, text);
vsprintf(Buffer, text, arglist);
MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
MB_APPLMODAL | MB_OK | 0 );
va_end(arglist);
}
void gui_setstatus(char *statustext, ...)
{
va_list arglist;
va_start(arglist, statustext);
SetStatusTextArgs(STAT_STATUS, SBT_POPOUT, CLR_DEFAULT, statustext, arglist);
va_end(arglist);
}
void gui_seterror(char *errortext, ...)
{
va_list arglist;
va_start(arglist, errortext);
SetStatusTextArgs(STAT_STATUS, SBT_POPOUT, RGB(0xff,0xff,0), errortext, arglist);
va_end(arglist);
}
void gui_criticalerror(char *errortext, ...)
{
char Buffer[4096];
va_list arglist;
va_start(arglist, errortext);
vsprintf(Buffer, errortext, arglist);
if (!Batchmode)
{
MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
MB_APPLMODAL | MB_OK | MB_ICONERROR );
}
else
{
/* in batch mode, don't bother the user with blocking requesters */
gui_seterror("%s", Buffer);
}
va_end(arglist);
}
void gui_logtext(char *text, ...)
{
char Buffer[4096];
va_list arglist;
va_start(arglist, text);
vsprintf(Buffer, text, arglist);
// MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
// MB_APPLMODAL | MB_OK | 0 );
va_end(arglist);
}
int gui_start_transmission(char *url, char *filename, int filenamesize, unsigned int totaltime, unsigned int maxtime)
{
int retval = 0;
static char szFileName[ _MAX_PATH ];
static char szTitleName[ _MAX_FNAME + _MAX_EXT ];
LPSTR szTitle;
strcpy(StreamURL, url);
StreamTotalTime = totaltime;
StreamMaxTime = maxtime;
if ( appVars.hwndMainFrame != NULL )
{
SetStatusText(STAT_KB, 0, -1, "");
SetStatusText(STAT_PROGRESS, 0, -1, "");
SetStatusText(STAT_TIMECODE, 0, -1, "");
SetStatusText(STAT_SEQNO, 0, -1, "");
if (!strcmp(filename, ""))
{
strcpy(StreamFilename, filename);
SetTitle( appVars.hwndMainFrame, StreamURL );
Transmitting = TRUE;
}
else
{
// Work out the full path name and the file name from the
// specified file
GetFullPathName( filename, _MAX_PATH, szFileName, &szTitle );
if (Batchmode)
{
/* don't bother the user with a file dialog in batch mode */
Transmitting = TRUE;
}
else
{
strncpy( szTitleName, szTitle, _MAX_FNAME + _MAX_EXT );
szTitleName[ _MAX_FNAME + _MAX_EXT -1 ] = '\0';
if ( DoFileSaveDialog( appVars.hwndMainFrame, szFileName, szTitleName ) )
{
Transmitting = TRUE;
}
}
if (Transmitting)
{
/* keep a local copy of the stream file name (for preview) */
strncpy(StreamFilename, szFileName, sizeof(StreamFilename));
StreamFilename[sizeof(StreamFilename)-1] = '\0';
/* return the new file name to the main function */
strncpy(filename, szFileName, filenamesize);
filename[filenamesize-1] = '\0';
SetTitle( appVars.hwndMainFrame, StreamURL );
retval = 1;
}
else
{
SetTitle( appVars.hwndMainFrame, "Untitled" );
strcpy(filename, "");
retval = 0;
}
}
if (hwndTrackbar != NULL)
{
SendMessage(hwndTrackbar, TBM_CLEARSEL, TRUE, 0 );
}
UpdateToolbar();
}
return retval;
}
void gui_progressinfo(int bytes, char *timecode, int progress, int seqno, int currenttime)
{
/* currenttime is in milliseconds */
IMPDownloadTime = (REFTIME) currenttime / 1000; /* REFTIME is in seconds (64 bit floating pt) */
IMSDownloadTime = (LONGLONG)currenttime * 10000; /* LONGLONG: 10 million units equal 1 second */
if ( appVars.hwndMainFrame != NULL )
{
/* progress is scaled from 0 (=0%) to 10000 (=100%) */
SetStatusText(STAT_KB, 0, -1, "%d kB", bytes /1024 );
SetStatusText(STAT_PROGRESS, 0, -1, "%d%%", progress/100 );
SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecode );
SetStatusText(STAT_SEQNO, 0, -1, "#%d", seqno );
if ((hwndTrackbar != NULL) && (timecode != 0))
{
if (StreamTotalTime != 0)
{
SendMessage(hwndTrackbar, TBM_SETSELSTART, FALSE, 0 );
SendMessage(hwndTrackbar, TBM_SETSELEND, TRUE, (int)((float)10000*currenttime/StreamTotalTime));
}
else
{
if (StreamMaxTime != 0)
{
SendMessage(hwndTrackbar, TBM_SETSELSTART, FALSE, 0 );
SendMessage(hwndTrackbar, TBM_SETSELEND, TRUE, (int)((float)10000*currenttime/StreamMaxTime));
}
else
{
SendMessage(hwndTrackbar, TBM_SETSELSTART, FALSE, 0 );
SendMessage(hwndTrackbar, TBM_SETSELEND, TRUE, 10000 );
}
}
}
}
}
void gui_modify_duration(unsigned int totaltime)
{
/* called only for live recordings */
LONG value;
StreamTotalTime = totaltime;
IMPTotalTime = (REFTIME)totaltime / 1000;
IMSTotalTime = (LONGLONG)totaltime * 10000;
value = (LONG)(10000 * IMPCurrentPosition / IMPTotalTime);
if (hwndTrackbar != NULL)
{
if (!TrackbarDragging)
{
SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, value);
}
}
}
void gui_finished_transmission()
{
Transmitting = FALSE;
Previewing = FALSE;
StreamTotalTime = 0;
StreamMaxTime = 0;
if ( appVars. hwndMainFrame != NULL )
{
SetStatusText(STAT_KB, 0, -1, "");
SetStatusText(STAT_PROGRESS, 0, -1, "");
SetStatusText(STAT_TIMECODE, 0, -1, "");
SetStatusText(STAT_SEQNO, 0, -1, "");
if (hwndTrackbar != NULL)
{
SendMessage(hwndTrackbar, TBM_CLEARSEL, TRUE, 0 );
}
UpdateToolbar();
ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
}
void gui_not_idle(int flag)
{
if (flag)
Idle = FALSE;
else
Idle = TRUE;
}
char *gui_translate_errorcode(int error)
{
static char def[32];
char *result = def;
struct ErrorDef *ed = WinSockErrors;
sprintf(def, "<%d>", error);
for (;;)
{
if (ed->ErrorVal == -1) break;
if (ed->ErrorVal == error)
{
result = ed->ErrorName;
break;
}
ed++;
}
return result;
}
static char username_buffer[256];
static char password_buffer[256];
int gui_getpassword(char **username, char **password)
{
int ret = 0;
if (!Batchmode)
{
if (*username != NULL) strncpy(username_buffer, *username, sizeof(username_buffer)-1);
username[255]=0;
if (*password != NULL) strncpy(password_buffer, *password, sizeof(password_buffer)-1);
password[255]=0;
if (DoEnterPasswordDialog( appVars.hInstance, appVars.hwndMainFrame ) == IDOK)
{
*username = username_buffer;
*password = password_buffer;
ret = 1;
}
}
else
{
/* in batch mode, password must be given on command line */
if (*username == NULL && *password == NULL)
{
/* cancel the authorization of no username/password given */
ret = 0;
}
else
{
ret = 1;
}
}
return ret;
}
static char proxy_buffer[512];
int gui_getproxy(char **proxy)
{
int ret = 0;
/* do not override command line proxy parameter */
if (*proxy == NULL)
{
LONG retval;
HKEY hkeyURLList;
DWORD dwResult;
retval = RegCreateKeyEx(APPREGKEY_ROOT,
APPREGKEY_BASE,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hkeyURLList,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
}
else
{
char buffer[512];
DWORD dwType;
DWORD dwSize;
dwSize = sizeof(buffer);
retval = RegQueryValueEx( hkeyURLList,
"ProxyServer",
0,
&dwType,
buffer,
&dwSize );
if (retval == ERROR_SUCCESS)
{
if (dwType == REG_SZ)
{
strncpy(proxy_buffer, buffer, sizeof(proxy_buffer)-1);
proxy_buffer[sizeof(proxy_buffer)-1] = 0;
/* return proxy only if buffer not empty */
if (strcmp(proxy_buffer, ""))
{
*proxy = proxy_buffer;
ret = 1;
}
}
RegCloseKey(hkeyURLList);
}
}
}
return ret;
}
/*------------------------ COMMON CONTROLS STUFF ----------------------------*/
//
// InitMyControls
//
HRESULT InitMyControls(void)
{
HRESULT hr;
DWORD major;
DWORD minor;
BOOL too_old = FALSE;
#define MIN_MAJOR 4
#define MIN_MINOR 72
GetComCtlVersion(&major, &minor);
if (major < MIN_MAJOR) too_old = TRUE;
else
if (major == MIN_MAJOR && minor < MIN_MINOR) too_old = TRUE;
if (too_old)
{
char Buffer[200];
sprintf(Buffer, "Your commctl32.dll is too old!\n"
"You have version: %d.%d\n"
"Required is at least version %d.%d",
major, minor, MIN_MAJOR, MIN_MINOR);
MessageBox( appVars.hwndMainFrame, Buffer, appVars.szAppName,
MB_APPLMODAL | MB_OK | MB_ICONERROR );
hr = S_FALSE;
}
else
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icex);
hr = S_OK;
}
return hr;
} // InitMyControls
//
// GetComCtlVersion
//
HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
{
HINSTANCE hComCtl;
if( IsBadWritePtr(pdwMajor, sizeof(DWORD)) ||
IsBadWritePtr(pdwMinor, sizeof(DWORD)))
return E_INVALIDARG;
//load the DLL
hComCtl = LoadLibrary(TEXT("comctl32.dll"));
if(hComCtl)
{
HRESULT hr = S_OK;
DLLGETVERSIONPROC pDllGetVersion;
/*
You must get this function explicitly because earlier versions of the DLL
don't implement this function. That makes the lack of implementation of the
function a version marker in itself.
*/
pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hComCtl, TEXT("DllGetVersion"));
if(pDllGetVersion)
{
DLLVERSIONINFO dvi;
ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize = sizeof(dvi);
hr = (*pDllGetVersion)(&dvi);
if(SUCCEEDED(hr))
{
*pdwMajor = dvi.dwMajorVersion;
*pdwMinor = dvi.dwMinorVersion;
}
else
{
hr = E_FAIL;
}
}
else
{
/*
If GetProcAddress failed, then the DLL is a version previous to the one
shipped with IE 3.x.
*/
*pdwMajor = 4;
*pdwMinor = 0;
}
FreeLibrary(hComCtl);
return hr;
}
return E_FAIL;
} // GetComCtlVersion
/*----------------------- STATUS BAR COMMON CONTROL -------------------------*/
//
// InitStatusbar
//
BOOL InitStatusbar( HINSTANCE hInstance, HWND hwndMainFrame )
{
BOOL success = FALSE;
if (hwndStatusbar = DoCreateStatusbar(hwndMainFrame, IDR_STATUSBAR, hInstance, StatusDefinitionArray))
{
ShowWindow( hwndStatusbar, SW_SHOW );
UpdateWindow( hwndStatusbar );
success = TRUE;
}
return success;
} // InitStatusbar
//
// SetStatusText
//
void SetStatusText(int partno, int drawmode, COLORREF cref, LPSTR text,...)
{
va_list arglist;
va_start(arglist, text);
SetStatusTextArgs(partno, drawmode, cref, text, arglist);
va_end(arglist);
} // SetStatusText
//
// StatusTimerFunc
//
void CALLBACK StatusTimerFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
if (uMsg == WM_TIMER && idEvent == StatusTimer)
{
StatusTimerCount--;
if (StatusTimerCount%2 == 0)
SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0, (LPARAM) CLR_DEFAULT);
else
SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0, (LPARAM) StatusTimerCref);
}
if (StatusTimerCount == 0)
KillTimer( appVars.hwndMainFrame, StatusTimer );
} // StatusTimerFunc
//
// SetStatusTextArgs
//
void SetStatusTextArgs(int partno, int drawmode, COLORREF cref, LPSTR text, void *args)
{
if (hwndStatusbar != NULL)
{
char Buffer[1024];
vsprintf(Buffer, text, args);
// Tell the status bar to create the window parts.
if (cref != -1)
{
SendMessage(hwndStatusbar, SB_SETBKCOLOR, (WPARAM) 0, (LPARAM) cref);
if (StatusTimer != 0)
{
KillTimer( appVars.hwndMainFrame, StatusTimer);
StatusTimerCount = 0;
}
if (cref != CLR_DEFAULT)
{
StatusTimerCref = cref;
StatusTimerCount = 5;
StatusTimer = SetTimer( appVars.hwndMainFrame, ID_STATUSTIMER, 200, StatusTimerFunc);
}
}
SendMessage(hwndStatusbar, SB_SETTEXT, (WPARAM) partno | drawmode, (LPARAM) Buffer);
ShowWindow( hwndStatusbar, SW_SHOW );
UpdateWindow( hwndStatusbar );
}
} // SetStatusTextArgs
//
// CalcStatusSize
//
void CalcStatusSize ( SIZE *pSize, int *array )
{
int i;
int nParts;
int *ptr;
int mintotal = 0;
nParts = *array;
ptr = array+1;
for (i = 0; i < nParts; i++)
{
int wmin = *ptr++;
ptr++;
mintotal += wmin;
}
pSize->cx = mintotal;
pSize->cy = 20;
if (hwndStatusbar != NULL)
{
RECT statRect;
GetWindowRect(hwndStatusbar, &statRect);
pSize->cy = statRect.bottom-statRect.top+1;
}
}
//
// AdjustStatusbar
//
void AdjustStatusbar(HWND hwndStatus, HWND hwndParent, int *array)
{
int nParts;
RECT rcClient;
HLOCAL hloc;
LPINT lpParts;
int i, x, nWidth;
int *ptr;
int mintotal = 0;
int maxtotal = 0;
int bendtotal = 0;
int numunlim = 0;
int weight = 0;
int surplus, maxsurplus;
// Get the coordinates of the parent window's client area.
GetClientRect(hwndParent, &rcClient);
nWidth = rcClient.right-rcClient.left+1;
nParts = *array;
ptr = array+1;
for (i = 0; i < nParts; i++)
{
int wmin = *ptr++;
int wmax = *ptr++;
if (wmax!=-1)
{
mintotal += wmin;
maxtotal += wmax;
bendtotal += (wmax-wmin);
}
else
{
mintotal += wmin;
maxtotal += 2*wmin;
bendtotal += wmin;
numunlim++;
}
}
// Allocate an array for holding the right edge coordinates.
hloc = LocalAlloc(LHND, sizeof(int) * nParts);
lpParts = LocalLock(hloc);
// Calculate the right edge coordinate for each part, and
// copy the coordinates to the array.
ptr = array+1;
x = 0;
surplus = nWidth - mintotal;
if (surplus<0) surplus=0;
maxsurplus = nWidth - maxtotal;
if (maxsurplus<0) maxsurplus=0;
for (i = 0; i < nParts; i++)
{
int wmin = *ptr++;
int wmax = *ptr++;
int bend;
int w = 0;
if (wmax!=-1)
bend = wmax-wmin;
else
bend = wmin;
w = wmin + (surplus*bend/bendtotal);
if (w > 2*wmin) w = 2*wmin;
if (wmax==-1)
w += maxsurplus / numunlim;
if (w < wmin) w = wmin;
if (wmax!=-1)
if (w > wmax) w = wmax;
x+= w;
*(lpParts+i) = x;
}
// Tell the status bar to create the window parts.
SendMessage(hwndStatus, SB_SETPARTS, (WPARAM) nParts, (LPARAM) lpParts);
// Free the array, and return.
LocalUnlock(hloc);
LocalFree(hloc);
} // AdjustStatusbar
// DoCreateStatusbar - creates a status bar and divides it into
// the specified number of parts.
// Returns the handle to the status bar.
// hwndParent - parent window for the status bar.
// nStatusID - child window identifier.
// hinst - handle to the application instance.
// nParts - number of parts into which to divide the status bar.
HWND DoCreateStatusbar(HWND hwndParent, int nStatusID,
HINSTANCE hinst, int *array)
{
HWND hwndStatus;
// Create the status bar.
hwndStatus = CreateWindowEx(
0, // no extended styles
STATUSCLASSNAME, // name of status bar class
(LPCTSTR) NULL, // no text when first created
SBARS_SIZEGRIP | // includes a sizing grip
WS_VISIBLE | WS_CHILD, // creates a child window
0, 0, 0, 0, // ignores size and position
hwndParent, // handle to parent window
(HMENU) nStatusID, // child window identifier
hinst, // handle to application instance
NULL); // no window creation data
AdjustStatusbar(hwndStatus, hwndParent, array);
return hwndStatus;
} // DoCreateStatusbar
/*-------------------------- MESSAGE BOX ROUTINES ---------------------------*/
//
// DbgAssert
//
// Displays a message box if the condition evaluated to FALSE
//
void DbgAssert(const char *pCondition, const char *pFileName, int iLine)
{
int MsgId;
char szInfo[1024];
wsprintf(szInfo, TEXT("%s \nAt line %d of %s"),pCondition, iLine, pFileName);
MsgId = MessageBox(NULL, szInfo, TEXT("ASSERT Failed"),
MB_SYSTEMMODAL |
MB_ICONHAND |
MB_ABORTRETRYIGNORE);
switch (MsgId)
{
case IDABORT: // Kill the application
FatalAppExit(FALSE, TEXT("Application terminated"));
break;
case IDRETRY: // Break into the debugger
DebugBreak();
break;
case IDIGNORE: // Ignore assertion continue executing
break;
}
} // DbgAssert
//
// ReallyQuitMessageBox
//
// Ask the user wheter or not to quit
//
UINT ReallyQuitMessageBox( void )
{
UINT retval;
if (Transmitting == FALSE)
{
/* don't ask if there is no transmission in progress */
retval = IDYES;
}
else
{
char szStr[ nMaxResourceStrSize ];
LoadString( appVars.hInstance, IDS_REALLY_QUIT, szStr, nMaxResourceStrSize );
retval = MessageBox( appVars.hwndMainFrame, szStr, appVars.szAppName,
MB_APPLMODAL | MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION );
}
return retval;
} // ReallyQuitMessageBox
//
// PlayerMessageBox
//
// Load and display an error message
//
void PlayerMessageBox( UINT nResource )
{
char szStr[ nMaxResourceStrSize ];
LoadString( appVars.hInstance, nResource, szStr, nMaxResourceStrSize );
MessageBox( appVars.hwndMainFrame, szStr, appVars.szAppName,
MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION );
} // PlayerMessageBox
//
// OnShowReadme
//
void OnShowReadme()
{
char szFileName[ _MAX_PATH ];
char *szTitle;
SHELLEXECUTEINFO sei;
BOOL ret;
// Work out the full path name
if (GetFullPathName( appVars.szProgramExecutable, _MAX_PATH, szFileName, &szTitle ) > 0)
{
strcpy( szTitle, "README.TXT");
memset(&sei, 0, sizeof(sei));
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_FLAG_NO_UI;
sei.hwnd = appVars.hwndMainFrame;
sei.lpVerb = "open";
sei.lpParameters = NULL;
sei.lpDirectory = NULL;
sei.lpFile = szFileName;
sei.nShow = SW_SHOW;
ret = ShellExecuteEx(&sei);
if (ret == FALSE)
{
if ((long)GetLastError() == ERROR_FILE_NOT_FOUND)
gui_criticalerror("Someone deleted the README.TXT\n"
"file from the program directory!\n");
else
gui_criticalerror("Cannot show the README.TXT file for some strange reason!\n");
}
}
}
/*-------------------------- COMMAND HANDLING -------------------------------*/
//
// ProcessCommand
//
// Process a WM_COMMAND message to the main window
//
long ProcessCommand( HWND hwnd, UINT wParam, LONG lParam )
{
switch( wParam ){
case ID_URL_OPEN:
DoOpenURLDialog( appVars.hInstance,hwnd );
break;
case ID_FILE_OPEN:
if (OpenMediaFile( hwnd, NULL ))
OnMediaPlay( );
break;
case ID_FILE_EXIT:
PostMessage( appVars.hwndMainFrame, WM_CLOSE, 0, 0 );
break;
case ID_MEDIA_PLAY:
OnMediaPlay( );
break;
case ID_MEDIA_PAUSE:
OnMediaPause( );
break;
case ID_MEDIA_STOP:
OnMediaStop(FALSE, TRUE);
break;
case ID_MEDIA_EJECT:
DeleteContents();
break;
case ID_STREAM_PREVIEW:
if (strcmp( StreamFilename, "" ))
{
if (OpenMediaFile( hwnd, StreamFilename ))
{
Previewing = TRUE;
OnMediaPlay( );
}
}
break;
case ID_STREAM_CANCEL:
gui_seterror("aborting transfer...");
gui_abort();
PostMessage(hwnd, WM_COMMAND, WM_QUIT, 0);
break;
case ID_SETTINGS_REGISTERFILETYPES:
OnRegisterFileTypes();
break;
case ID_SETTINGS_UNREGISTERFILETYPES:
OnUnregisterFileTypes();
break;
case ID_HELP_ABOUT:
DoAboutDialog( appVars.hInstance,hwnd );
break;
case ID_PROGRAM_ARGUMENTS:
Usage(appVars.szProgramExecutable, ShowUsage);
break;
case ID_SHOW_README:
OnShowReadme();
break;
case ID_PROXY_SERVER:
DoProxyConfigurationDialog( appVars.hInstance, hwnd );
break;
default:
return DefWindowProc( hwnd, WM_COMMAND, wParam, lParam );
}
return (LRESULT) 0;
} // ProcessCommand
/*------------------------- WINDOW SIZE CALCULATIONS ------------------------*/
//
// OnGetMinMaxInfo
//
// Sets the minimum size of the main window and the maximum height
//
void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
RECT rectRequired;
SIZE sizeToolbar;
SIZE sizeStatus;
// Our client area is going to be the toolbar, so find our its size
CalcToolbarSize( &sizeToolbar );
rectRequired.left = rectRequired.top = 0;
rectRequired.right = sizeToolbar.cx;
rectRequired.bottom = sizeToolbar.cy;
CalcStatusSize( &sizeStatus, StatusDefinitionArray );
if (sizeStatus.cx > rectRequired.right)
rectRequired.right = sizeStatus.cx;
rectRequired.bottom += sizeStatus.cy;
// Take into account the menu, caption and thick frame
AdjustWindowRect( &rectRequired, WS_CAPTION|WS_THICKFRAME, TRUE );
// Set the min/max sizes
lpMMI->ptMinTrackSize.x = rectRequired.right - rectRequired.left;
lpMMI->ptMinTrackSize.y = rectRequired.bottom - rectRequired.top;
} // OnGetMinMaxInfo
/*------------------------- MAIN WINDOW PROCEDURE ---------------------------*/
typedef BOOL (FAR WINAPI *GradientFillFunction)(HDC,PTRIVERTEX,ULONG,PVOID,ULONG,ULONG);
GradientFillFunction GradientFillPtr;
//
// MainFrameProc
//
// Handles the message sent to the main window
//
long FAR PASCAL MainFrameProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
DRAWITEMSTRUCT *dis;
/******************************************************/
/* Handle inter-process communications here */
/******************************************************/
/* Answer the probe-message with our current status. */
/* Return MAGIC_COOKIE if we are able to handle */
/* other tasks */
if (message == WM_APPMSG)
{
if (Idle == TRUE)
{
Idle = FALSE;
return (LRESULT) MAGIC_COOKIE;
}
else
{
return (LRESULT) 0;
}
}
/* This message is only received when we just answered */
/* the probe message with a MAGIC_COOKIE */
/* Now we will get the command line from another ASF- */
/* Recorder process */
if (message == WM_COPYDATA)
{
COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
if (cds != NULL)
{
if (cds->dwData == MAGIC_COOKIE)
{
LPTSTR cmdline;
unsigned char buffer[1024];
int argc_bak = argc; /* ParseCommandLine() operates */
char **argv_bak = argv; /* on global variables (backup needed!) */
argc = 0; /* simulate "empty" command line */
argv = NULL;
cmdline = cds->lpData; /* copy the data from the WM_COPYDATA */
strcpy(buffer, cmdline); /* message */
if (ParseCommandLine(buffer))
{
/* tell the other process that we are now */
/* processing its command line */
ReplyMessage((LRESULT) MAGIC_COOKIE);
ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
/* now process this command line */
main_function(argc, argv);
}
FreeCommandLine();
/* restore the previous command line */
/* (needed for FreeCommandLine() in WinMain */
argc = argc_bak;
argv = argv_bak;
}
}
/* return to idle state (can accept other command lines now) */
Idle = TRUE;
return (LRESULT) 0;
}
switch( message )
{
case WM_CLOSE:
if (ReallyQuitMessageBox() == IDYES)
{
if (DestroyWindow ( appVars.hwndMainFrame ))
{
appVars.hwndMainFrame = NULL;
hwndAboutBox = NULL;
hwndOpenURLDialog = NULL;
hwndStatusbar = NULL;
toolbar.hwndPlayButton = NULL;
toolbar.hwndPauseButton = NULL;
toolbar.hwndStopButton = NULL;
toolbar.hwndPreviewButton = NULL;
toolbar.hwndCancelButton = NULL;
hwndTrackbar = NULL;
}
}
break;
case WM_DESTROY:
gui_abort();
PostQuitMessage( 0 );
break;
case WM_GETMINMAXINFO:
OnGetMinMaxInfo( (MINMAXINFO FAR *) lParam );
break;
case WM_ERASEBKGND:
{
RECT rc;
HDC hdc;
SIZE sizeStatus;
HMODULE msimg32;
hdc = (HDC) wParam;
GetClientRect(hwnd, &rc);
/* try to load msimg32.dll (Win98, Win2000) */
if ((msimg32 = LoadLibrary("msimg32.dll")) != NULL)
{
TRIVERTEX vert[4] ;
GRADIENT_TRIANGLE gTri[2];
GradientFillPtr = (GradientFillFunction)GetProcAddress(msimg32, "GradientFill");
CalcStatusSize( &sizeStatus, StatusDefinitionArray );
rc.bottom -= (sizeStatus.cy-1);
vert [0] .x = rc.left;
vert [0] .y = rc.top;
vert [0] .Red = 0xff00;
vert [0] .Green = 0xff00;
vert [0] .Blue = 0x8000;
vert [0] .Alpha = 0x0000;
vert [1] .x = rc.right;
vert [1] .y = rc.top;
vert [1] .Red = 0x6000;
vert [1] .Green = 0x6000;
vert [1] .Blue = 0x6000;
vert [1] .Alpha = 0x0000;
vert [2] .x = rc.right;
vert [2] .y = rc.bottom;
vert [2] .Red = 0x8000;
vert [2] .Green = 0x4000;
vert [2] .Blue = 0x0000;
vert [2] .Alpha = 0x0000;
vert [3] .x = rc.left;
vert [3] .y = rc.bottom;
vert [3] .Red = 0x6000;
vert [3] .Green = 0x6000;
vert [3] .Blue = 0x6000;
vert [3] .Alpha = 0x0000;
gTri[0].Vertex1 = 0;
gTri[0].Vertex2 = 1;
gTri[0].Vertex3 = 2;
gTri[1].Vertex1 = 0;
gTri[1].Vertex2 = 3;
gTri[1].Vertex3 = 2;
(*GradientFillPtr)(hdc, vert,4, gTri, 2, GRADIENT_FILL_TRIANGLE);
FreeLibrary(msimg32);
}
else
{
/* basic backfill functions for users not having the msimg32.dll */
HBRUSH brush = CreateSolidBrush(RGB(0xc0,0x80,0x00));
FillRect(hdc, &rc, brush);
DeleteObject(brush);
}
}
return (LRESULT) 1;
break;
case WM_DRAWITEM:
dis = (DRAWITEMSTRUCT FAR *) lParam;
if (( dis->CtlType == ODT_BUTTON ) &&
( dis->CtlID == ID_MEDIA_PLAY ||
dis->CtlID == ID_MEDIA_PAUSE ||
dis->CtlID == ID_MEDIA_STOP) ||
dis->CtlID == ID_STREAM_PREVIEW ||
dis->CtlID == ID_STREAM_CANCEL )
{
DrawButton( appVars.hInstance, (DRAWITEMSTRUCT FAR *) lParam );
return (LRESULT) 1;
}
break;
case WM_INITMENUPOPUP:
if( lParam == 1 )
{ // Media popup menu
EnableMenuItem( (HMENU) wParam, ID_MEDIA_PLAY, CanPlay() ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( (HMENU) wParam, ID_MEDIA_PAUSE, CanPause() ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( (HMENU) wParam, ID_MEDIA_STOP, CanStop() ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( (HMENU) wParam, ID_MEDIA_EJECT, IsInitialized() ? MF_ENABLED : MF_GRAYED );
}
else
{
if( lParam == 2 )
{ // Stream popup menu
EnableMenuItem( (HMENU) wParam, ID_STREAM_PREVIEW, CanPreview() ? MF_ENABLED : MF_GRAYED );
EnableMenuItem( (HMENU) wParam, ID_STREAM_CANCEL, Transmitting ? MF_ENABLED : MF_GRAYED );
}
else
{
return DefWindowProc( hwnd, message, wParam, lParam );
}
}
break;
case WM_SIZE:
SendMessage(hwndStatusbar, WM_SIZE, wParam, lParam);
AdjustStatusbar(hwndStatusbar, appVars.hwndMainFrame, StatusDefinitionArray);
AdjustTrackbar(hwndTrackbar, appVars.hwndMainFrame );
return DefWindowProc( hwnd, message, wParam, lParam );
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
EndPaint( hwnd, &ps );
}
break;
case WM_COMMAND:
return ProcessCommand( hwnd, wParam, lParam );
break;
case WM_NOTIFY:
{
int id = wParam;
LPNMHDR nmhdr = (LPNMHDR)lParam;
if (nmhdr->hwndFrom == hwndTrackbar)
{
if (nmhdr->code == NM_RELEASEDCAPTURE)
{
int pos;
pos = positionTrackbar;
SendMessage(hwndTrackbar, TBM_SETPOS, TRUE, pos);
SetCurrentPosition((REFTIME)((REFTIME)pos/10000 * IMPTotalTime));
}
}
}
// return DefWindowProc( hwnd, message, wParam, lParam );
break;
case WM_HSCROLL:
{
HWND hwndFrom = (HWND)lParam;
if (hwndFrom == hwndTrackbar)
{
int pos = HIWORD(wParam);
int code = LOWORD(wParam);
switch(code)
{
case TB_THUMBTRACK:
{
unsigned int timecode;
char *timecodestring;
if (Previewing)
{
int prevpos = pos;
int min=SendMessage(hwndTrackbar, TBM_GETSELSTART, 0, 0);
int max=SendMessage(hwndTrackbar, TBM_GETSELEND, 0, 0);
if (pos < min) pos = min;
if (pos > max) pos = max;
if (pos != prevpos) SendMessage(hwndTrackbar, TBM_SETPOS, TRUE, pos);
}
/* save the current position of the trackbar slider */
positionTrackbar = pos;
if (!Transmitting)
{
timecode = (unsigned int)((float)pos/10000 * (1000*IMPTotalTime));
timecodestring = createtimestring(timecode);
SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecodestring);
}
if (TrackbarDragging == FALSE)
OnMediaSeeking(TRUE);
TrackbarDragging = TRUE;
}
break;
case TB_THUMBPOSITION:
{
/* save the position of the trackbar slider /*
/* when we released the mouse button */
positionTrackbar = SendMessage(hwndTrackbar, TBM_GETPOS, 0, 0);
if (TrackbarDragging == TRUE)
OnMediaSeeking(FALSE);
TrackbarDragging = FALSE;
}
break;
default:
break;
}
}
}
// return DefWindowProc( hwnd, message, wParam, lParam );
break;
/* handle drag & drop */
case WM_DROPFILES:
{
HANDLE hDrop = (HANDLE) wParam;
UINT numfiles;
char buffer[512];
unsigned char *dotptr, *tmpptr;
numfiles = DragQueryFile(hDrop, 0xffffffff, buffer, sizeof(buffer));
if (numfiles > 1)
{
PlayerMessageBox( IDS_DROP_ONLY_ONE );
}
if (numfiles > 0)
{
DragQueryFile(hDrop, 0, buffer, sizeof(buffer));
}
DragFinish(hDrop);
/* search for filename extension */
for (dotptr = buffer+strlen(buffer), tmpptr = buffer; (tmpptr = strchr(tmpptr, '.')) != NULL ; dotptr = tmpptr++);
/* search for redirection file name extension */
if ( (!stricmp(dotptr, ".asx")) ||
(!stricmp(dotptr, ".wax")) ||
(!stricmp(dotptr, ".wvx")) ||
(!stricmp(dotptr, ".wmx")) )
{
if (Transmitting)
{
PlayerMessageBox( IDS_TRANSMISSION_RUNNING );
}
else
{
/* call main_function() to process redirection file */
unsigned char *(my_argv[2]);
int my_argc = 2;
my_argv[0] = appVars.szProgramExecutable;
my_argv[1] = buffer;
main_function(my_argc, (char**)my_argv);
}
}
else
{
/* try to play file as media file */
if (OpenMediaFile( hwnd, buffer ))
OnMediaPlay( );
}
}
break;
default:
return DefWindowProc( hwnd, message, wParam, lParam );
}
return (LRESULT) 0;
} // MainFrameProc
/*---------------------- INITIALIZATION/CLEANUP ROUTINES --------------------*/
//
// InitApplication
//
BOOL InitApplication()
{
strcpy( appVars.szAppName, APP_NAME );
// Filter interface initialize?
if( SUCCEEDED( CoInitialize( NULL )))
return TRUE;
return FALSE;
} // InitApplication
//
// UnInitApplication
//
void UnInitApplication()
{
CoUninitialize( );
} // UnInitApplication
//
// InitInstance
//
// Set the specific instance data and register our main
// window class if it has not been registered already
//
BOOL InitInstance( HANDLE hInstance, HANDLE hPrevInstance )
{
appVars.hInstance = hInstance;
if(!hPrevInstance)
{
WNDCLASS wndClass;
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = MainFrameProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = appVars.hInstance;
wndClass.hIcon = LoadIcon( appVars.hInstance, MAKEINTRESOURCE( IDI_APPLICATION_ICON ));
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wndClass.lpszMenuName = MAKEINTRESOURCE( IDM_MAINFRAME );
wndClass.lpszClassName = appVars.szAppName;
RegisterClass( &wndClass );
if ( InitMyControls() == S_OK )
{
return TRUE;
}
return FALSE;
}
return TRUE;
} // InitInstance
//
// InitMainFrame
//
// Create our main window
//
BOOL InitMainFrame( int nCmdShow )
{
const DWORD Styles = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) &~ WS_MAXIMIZEBOX;
char szTitle[ 30 ];
strcpy( szTitle, APP_NAME );
strcat( szTitle, UNTITLED_STRING );
appVars.hwndMainFrame =
CreateWindowEx( WS_EX_ACCEPTFILES,
appVars.szAppName, // Our class name
szTitle, // Window title
Styles, // It's styles
CW_USEDEFAULT, // No x position
CW_USEDEFAULT, // And no y either
0, 65, // Initial sizes
NULL, // No parent window
NULL, // And no menu
appVars.hInstance, // App instance
NULL); // Creation data
DragAcceptFiles( appVars.hwndMainFrame, TRUE);
ShowWindow( appVars.hwndMainFrame, nCmdShow );
UpdateWindow( appVars.hwndMainFrame );
return TRUE;
} // InitMainFrame
/*-------------------------- BUSY POINTER ROUTINE ---------------------------*/
int BusyNest = 0;
//
// SetBusy
//
void SetBusy(BOOL flag)
{
if (flag == TRUE)
{
BusyNest++;
if (BusyNest > 0) SetCursor( LoadCursor( NULL, IDC_WAIT ) );
}
else
{
if (BusyNest > 0) BusyNest--;
if (BusyNest == 0) SetCursor( LoadCursor( NULL, IDC_ARROW ) );
}
} // SetBusy
/*-------------------- MAIN EVENT LOOP/MESSAGE HANDLING ---------------------*/
//
// DoMainLoop
//
// Main message loop
//
int DoMainLoop(int network_mask)
{
MSG msg;
BOOL network_event = FALSE;
int network_retval = 0;
// Message loop lasts until we get a WM_QUIT message
// Upon which we shall return from the function
// Message loop also exits when network activity is
// dectected (only if network is set to TRUE)
for (;;)
{
// Read all of the messages in this next loop
// removing each message as we read it
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == 1)
{
if (msg.message == WM_QUIT)
return msg.wParam;
if (hwndAboutBox != NULL)
if (IsDialogMessage(hwndAboutBox, &msg)) continue;
if (hwndOpenURLDialog != NULL)
if (IsDialogMessage(hwndOpenURLDialog, &msg)) continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// The following code waits for the arrival of new messages, i.e.
// it puts the task to sleep. This is a non-desired behaviour if
// we must react to a network event.
if (network_event == FALSE)
{
HANDLE ahObjects[10]; // Handles that need to be waited on
int cObjects = 0; // Number of objects that we have
int cGraphIndex = -1;
int cNetworkIndex = -1;
ahObjects [cObjects] = GetGraphEventHandle();
if (ahObjects[cObjects] != NULL)
{
cGraphIndex = cObjects;
cObjects++;
}
if (NetworkEvent != WSA_INVALID_EVENT)
{
ahObjects[cObjects] = NetworkEvent;
cNetworkIndex = cObjects;
cObjects++;
}
if( cObjects == 0 )
{
WaitMessage();
}
else
{
DWORD Result;
// Wait for any message or a graph notification
Result = MsgWaitForMultipleObjects( cObjects,
ahObjects,
FALSE,
INFINITE,
QS_ALLINPUT );
// Have we received an event notification
if( Result != (WAIT_OBJECT_0 + cObjects) )
{
if (cGraphIndex != -1)
{
if( Result == WAIT_OBJECT_0 + cGraphIndex)
{
OnGraphNotify();
}
}
if (cNetworkIndex != -1)
{
if( Result == WAIT_OBJECT_0 + cNetworkIndex)
{
WSANETWORKEVENTS wsane;
if (WSAEnumNetworkEvents(NetworkSocket, NetworkEvent, &wsane) == SOCKET_ERROR)
{
gui_criticalerror("WSAEnumNetworkEvents() failed! Error code: %d\n", WSAGetLastError());
}
else
{
if (wsane.lNetworkEvents & FD_CONNECT)
{
network_retval = wsane.iErrorCode[FD_CONNECT_BIT];
}
else
{
network_retval = 0;
}
network_event = TRUE;
}
}
}
}
}
}
if (network_event == TRUE)
break;
}
// if we end up here, we must have received a network event
return network_retval;
} // DoMainLoop
/*--------------------------- PSEUDO WINMAIN CODE ---------------------------*/
//
// PseudoWinMain
//
// former WinMain code. Now called from real WinMain
//
int PASCAL PseudoWinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow )
{
UINT nReturn = 0;
// Initialise COM and the application
if ( InitApplication() == FALSE ) return 0;
if( InitInstance( hInstance, hPrevInstance ) &&
InitMainFrame( nCmdShow ) &&
InitToolbar( hInstance, appVars.hwndMainFrame ) &&
InitStatusbar( hInstance, appVars.hwndMainFrame ) &&
InitTrackbar( hInstance, appVars.hwndMainFrame ) &&
InitMedia( ) &&
InitFileOpenDialog( appVars.hwndMainFrame ) &&
InitFileSaveDialog( appVars.hwndMainFrame ))
{
nReturn = 1;
}
return nReturn;
} // WinMain
//
// EndOfWinMain
//
// former end part of WinMain code. Now called from real WinMain
//
void EndOfWinMain(void)
{
// Stop the graph if we can
if( CanStop() )
OnMediaStop(TRUE, FALSE);
// Release the filter graph
DeleteContents();
UnInitApplication();
} // EndOfWinMain
/*--------------------------- ABOUT DIALOG BOX ------------------------------*/
// Simply handles the Help..About dialog box
//
// AboutDlgProc
//
BOOL FAR PASCAL AboutDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
{
DRAWITEMSTRUCT *dis;
switch( message )
{
case WM_INITDIALOG:
return (LRESULT) 1;
case WM_DRAWITEM:
dis = (DRAWITEMSTRUCT FAR *) lParam;
if (( dis->CtlType == ODT_STATIC ) &&
( dis->CtlID == IDC_ASFRECORDER_BITMAP ))
{
HDC hSourceDC = CreateCompatibleDC( NULL );
HGDIOBJ loadedbitmap;
HGDIOBJ hgdiOldBitmap;
loadedbitmap = (HGDIOBJ) LoadImage( appVars.hInstance, MAKEINTRESOURCE( IDB_ASFRECORDER ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
hgdiOldBitmap = SelectObject( hSourceDC, loadedbitmap );
// ..and blit it
BitBlt( dis->hDC,
dis->rcItem.left,
dis->rcItem.top ,
dis->rcItem.right-dis->rcItem.left+1,
dis->rcItem.bottom-dis->rcItem.top+1,
hSourceDC,
0,
0,
SRCCOPY
);
// Restore the original bitmap
SelectObject( hSourceDC, hgdiOldBitmap );
// this was missing from the Microsoft example code
DeleteObject(loadedbitmap);
DeleteDC(hSourceDC);
return (LRESULT) 1;
}
break;
case WM_COMMAND:
if( wParam==IDOK || wParam==IDCANCEL )
{
if (DestroyWindow( hwndAboutBox ))
hwndAboutBox = NULL;
return (LRESULT) 1;
}
}
return (LRESULT) 0;
} // AboutDlgProc
//
// DoAboutDialog
//
void DoAboutDialog( HINSTANCE hInstance, HANDLE hwnd )
{
if (hwndAboutBox == NULL)
{
hwndAboutBox = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_ABOUTBOX ), hwnd, AboutDlgProc );
}
if (hwndAboutBox != NULL)
{
ShowWindow(hwndAboutBox, SW_SHOW);
BringWindowToTop( hwndAboutBox );
}
} // DoAboutDialog
/*--------------------------- OPEN URL DIALOG BOX ---------------------------*/
// Non-modal Open URL dialog
//
// OpenURLDlgProc
//
BOOL FAR PASCAL OpenURLDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
{
switch( message )
{
case WM_INITDIALOG:
{
HWND combo;
if (combo = GetDlgItem( hwnd, IDC_URLCOMBO ))
{
LONG retval;
HKEY hkeyURLList;
DWORD dwResult;
retval = RegCreateKeyEx(APPREGKEY_ROOT,
APPREGKEY_URLLIST,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hkeyURLList,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
}
else
{
DWORD dwIndex;
char keyname[32];
char buffer[512];
DWORD dwType;
DWORD dwSize;
for (dwIndex = 0 ; dwIndex < URLS_TO_REMEMBER ; dwIndex++)
{
sprintf(keyname, "URL%d", dwIndex);
dwSize = sizeof(buffer);
retval = RegQueryValueEx( hkeyURLList,
keyname,
0,
&dwType,
buffer,
&dwSize );
if (retval != ERROR_SUCCESS)
{
break;
}
else
{
if (dwType == REG_SZ)
{
retval = SendMessage(combo, CB_ADDSTRING, (WPARAM)0, (LPARAM)buffer);
if (dwIndex == 0)
{
retval = SendMessage(combo, CB_SETCURSEL, (WPARAM)dwIndex, 0);
}
}
}
}
RegCloseKey(hkeyURLList);
}
}
return (LRESULT) 1;
}
case WM_COMMAND:
{
int my_argc;
char *(my_argv[2]);
char buffer[512];
strcpy(buffer, "");
if (wParam==IDOK)
{
HWND combo;
int textlength;
if (combo = GetDlgItem( hwndOpenURLDialog, IDC_URLCOMBO ))
{
textlength = SendMessage(combo , WM_GETTEXTLENGTH, 0, 0);
if (textlength > sizeof(buffer)-1) textlength = sizeof(buffer)-1;
SendMessage(combo, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)buffer);
}
if ( strcmp(buffer, "") )
{
HWND combo;
if (combo = GetDlgItem( hwndOpenURLDialog, IDC_URLCOMBO ))
{
LONG retval;
HKEY hkeyURLList;
DWORD dwResult;
retval = RegCreateKeyEx(APPREGKEY_ROOT,
APPREGKEY_URLLIST,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hkeyURLList,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
}
else
{
DWORD dwIndex;
char keyname[32];
char buffer[512];
retval = SendMessage(combo, WM_GETTEXT, (WPARAM)sizeof(buffer), (LPARAM)buffer);
dwIndex = SendMessage(combo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
if (dwIndex != CB_ERR)
{
retval = SendMessage(combo, CB_DELETESTRING, (WPARAM)dwIndex, (LPARAM)0);
}
retval = SendMessage(combo, CB_INSERTSTRING, (WPARAM)0, (LPARAM)buffer);
for (dwIndex = 0 ; dwIndex < URLS_TO_REMEMBER ; dwIndex++)
{
retval = SendMessage(combo, CB_GETLBTEXT, (WPARAM)dwIndex, (LPARAM)buffer);
if (retval == CB_ERR)
{
break;
}
sprintf(keyname, "URL%d", dwIndex);
retval = RegSetValueEx( hkeyURLList,
keyname,
0,
REG_SZ,
buffer,
strlen(buffer)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx failed: %d\n", retval);
}
}
RegCloseKey(hkeyURLList);
}
}
if (DestroyWindow( hwndOpenURLDialog ))
hwndOpenURLDialog = NULL;
my_argc = 2;
my_argv[0] = appVars.szProgramExecutable;
my_argv[1] = buffer;
main_function(my_argc, my_argv);
}
}
if ( wParam==IDOK || wParam==IDCANCEL )
{
if (hwndOpenURLDialog != NULL)
{
if (DestroyWindow( hwndOpenURLDialog ))
hwndOpenURLDialog = NULL;
}
}
return (LRESULT) 1;
}
}
return (LRESULT) 0;
} // OpenURLDlgProc
//
// DoOpenURLDialog
//
void DoOpenURLDialog( HINSTANCE hInstance, HANDLE hwnd )
{
if (Transmitting == FALSE)
{
if (hwndOpenURLDialog == NULL)
{
hwndOpenURLDialog = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_OPEN_URL ), hwnd, OpenURLDlgProc );
}
if (hwndOpenURLDialog != NULL)
{
ShowWindow(hwndOpenURLDialog, SW_SHOW);
BringWindowToTop( hwndOpenURLDialog );
}
}
else
{
PlayerMessageBox( IDS_TRANSMISSION_RUNNING );
}
} // DoOpenURLDialog
/*------------------------ ENTER PASSWORD DIALOG BOX ------------------------*/
// Modal Enter Password dialog
//
// EnterPasswordDlgProc
//
BOOL FAR PASCAL EnterPasswordDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
{
switch( message )
{
case WM_INITDIALOG:
{
HWND edit;
if (edit = GetDlgItem( hwnd, IDC_USERNAME_EDIT ))
{
SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)username_buffer);
}
if (edit = GetDlgItem( hwnd, IDC_PASSWORD_EDIT ))
{
SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)password_buffer);
}
return (LRESULT) 1;
}
case WM_COMMAND:
{
if (wParam==IDOK)
{
HWND edit;
int textlength;
if (edit = GetDlgItem( hwnd, IDC_USERNAME_EDIT ))
{
textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
if (textlength > sizeof(username_buffer)-1) textlength = sizeof(username_buffer)-1;
SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)username_buffer);
}
if (edit = GetDlgItem( hwnd, IDC_PASSWORD_EDIT ))
{
textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
if (textlength > sizeof(password_buffer)-1) textlength = sizeof(password_buffer)-1;
SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)password_buffer);
}
}
if ( wParam==IDOK || wParam==IDCANCEL )
{
EndDialog(hwnd, wParam);
}
return (LRESULT) 1;
}
}
return (LRESULT) 0;
} // EnterPasswordDlgProc
//
// DoEnterPasswordDialog
//
UINT DoEnterPasswordDialog( HINSTANCE hInstance, HANDLE hwnd )
{
UINT ret;
ret = DialogBox( hInstance, MAKEINTRESOURCE( IDD_ENTER_PASSWORD ), hwnd, EnterPasswordDlgProc );
return ret;
} // DoEnterPasswordDialog
/*--------------------- PROXY CONFIGURATION DIALOG BOX ----------------------*/
// Modal Proxy Configuration dialog
//
// ProxyConfigurationDlgProc
//
BOOL FAR PASCAL ProxyConfigurationDlgProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )
{
char serverstring[512];
unsigned int portnum;
char *serverptr, *colonptr;
switch( message )
{
case WM_INITDIALOG:
{
LONG retval;
HKEY hkeyProxyServer;
DWORD dwResult;
HWND edit;
retval = RegCreateKeyEx(APPREGKEY_ROOT,
APPREGKEY_BASE,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hkeyProxyServer,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
}
else
{
char buffer[512];
DWORD dwType;
DWORD dwSize;
dwSize = sizeof(buffer);
retval = RegQueryValueEx( hkeyProxyServer,
"ProxyServer",
0,
&dwType,
buffer,
&dwSize );
if (retval == ERROR_SUCCESS)
{
if (dwType == REG_SZ)
{
strncpy(proxy_buffer, buffer, sizeof(proxy_buffer)-1);
proxy_buffer[sizeof(proxy_buffer)-1] = 0;
}
}
RegCloseKey(hkeyProxyServer);
}
strncpy(serverstring, proxy_buffer, sizeof(serverstring)-1);
serverstring[sizeof(serverstring)-1]=0;
serverptr = serverstring;
if (!strnicmp(serverptr, "http://", 7)) serverptr+=7;
colonptr = strchr(serverptr, ':');
if (colonptr == NULL)
{
colonptr = serverptr+strlen(serverptr);
}
else
{
*colonptr++ = '\0';
}
if (atol(colonptr) == 0) colonptr = "";
if (edit = GetDlgItem( hwnd, IDC_PROXY_SERVER_EDIT ))
{
SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)serverstring);
}
if (edit = GetDlgItem( hwnd, IDC_PROXY_PORT_EDIT ))
{
SendMessage(edit, WM_SETTEXT, (WPARAM)0, (LPARAM)colonptr);
}
return (LRESULT) 1;
}
case WM_COMMAND:
{
if (wParam==IDOK)
{
LONG retval;
HKEY hkeyProxyServer;
DWORD dwResult;
HWND edit;
int textlength;
if (edit = GetDlgItem( hwnd, IDC_PROXY_SERVER_EDIT ))
{
textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
if (textlength > sizeof(serverstring)-1) textlength = sizeof(serverstring)-1;
SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)serverstring);
}
if (edit = GetDlgItem( hwnd, IDC_PROXY_PORT_EDIT ))
{
unsigned char portstring[32];
textlength = SendMessage(edit , WM_GETTEXTLENGTH, 0, 0);
if (textlength > sizeof(portstring)-1) textlength = sizeof(portstring)-1;
SendMessage(edit, WM_GETTEXT, (WPARAM)textlength+1, (LPARAM)portstring);
portnum = atol(portstring);
if (portnum > 65535) portnum = 65535;
if (portnum == 0) portnum = 8080; /* default port number */
}
if (!strcmp(serverstring, ""))
strcpy(proxy_buffer, "");
else
sprintf(proxy_buffer, "%s:%d", serverstring, portnum);
retval = RegCreateKeyEx(APPREGKEY_ROOT,
APPREGKEY_BASE,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hkeyProxyServer,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx failed: %d\n", retval);
}
else
{
retval = RegSetValueEx( hkeyProxyServer,
"ProxyServer",
0,
REG_SZ,
proxy_buffer,
strlen(proxy_buffer)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx failed: %d\n", retval);
}
}
}
if ( wParam==IDOK || wParam==IDCANCEL )
{
EndDialog(hwnd, wParam);
}
return (LRESULT) 1;
}
}
return (LRESULT) 0;
} // ProxyConfigurationDlgProc
//
// DoProxyConfigurationDialog
//
UINT DoProxyConfigurationDialog( HINSTANCE hInstance, HANDLE hwnd )
{
UINT ret;
ret = DialogBox( hInstance, MAKEINTRESOURCE( IDD_PROXY_SERVER ), hwnd, ProxyConfigurationDlgProc );
return ret;
} // DoProxyConfigurationDialog
/*-------------------------- MEDIA STATE ROUTINES ---------------------------*/
// Current multimedia variables
static Media media;
//
// CanPreview
//
// Return true if we can preview the currently downloading stream
//
BOOL CanPreview()
{
return ((!Previewing) && Transmitting && strcmp( StreamFilename, "" ));
} // CanPreview
//
// CanPlay
//
// Return true if we can go to a playing state from our current state
//
BOOL CanPlay()
{
return (media.state == Stopped || media.state == Paused);
} // CanPlay
//
// CanStop
//
// Return true if we can go to a stopped state from our current state
//
BOOL CanStop()
{
return (media.state == Playing || media.state == Paused);
} // CanStop
//
// CanPause
//
// Return true if we can go to a paused state from our current state
//
BOOL CanPause()
{
return (media.state == Playing || media.state == Stopped);
} // CanPause
//
// IsInitialized
//
// Return true if we have loaded and initialized a multimedia file
//
BOOL IsInitialized()
{
return (media.state != Uninitialized);
} // IsInitialized
//
// ChangeStateTo
//
void ChangeStateTo( State newState )
{
if (!Transmitting)
{
switch (newState)
{
case Playing:
gui_setstatus("Playing...");
break;
case Paused:
gui_setstatus("Paused");
break;
case Stopped:
gui_setstatus("Stopped");
break;
case Uninitialized:
gui_setstatus("");
break;
}
}
media.state = newState;
if (TrackbarTimer != 0)
{
KillTimer( appVars.hwndMainFrame, TrackbarTimer); TrackbarTimer = 0;
}
if (newState == Playing)
TrackbarTimer = SetTimer( appVars.hwndMainFrame, ID_TRACKBARTIMER, 100, &TrackbarTimerFunc );
// update the toolbar
UpdateToolbar();
} // ChangeStateTo
//
// InitMedia
//
// Initialization
//
BOOL InitMedia()
{
ChangeStateTo( Uninitialized );
media.hGraphNotifyEvent = NULL;
media.pGraph = NULL;
return TRUE;
} // InitMedia
/*------------------------- GRAPH/MEDIA FUNCTIONS ---------------------------*/
//
// CreateFilterGraph
//
BOOL CreateFilterGraph()
{
BOOL result = FALSE;
IMediaEvent *pME;
HRESULT hr;
ASSERT(media.pGraph == NULL);
SetBusy(TRUE);
hr = CoCreateInstance(&CLSID_FilterGraph, // CLSID of object
NULL, // Outer unknown
CLSCTX_INPROC_SERVER, // Type of server
&IID_IGraphBuilder, // Interface wanted
(void **) &media.pGraph); // Returned object
if (FAILED(hr))
{
media.pGraph = NULL;
}
else
{
// We use this to find out events sent by the filtergraph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaEvent,
(void **) &pME);
if (FAILED(hr))
{
DeleteContents();
}
else
{
hr = pME->lpVtbl->GetEventHandle(pME, (OAEVENT*) &media.hGraphNotifyEvent);
pME->lpVtbl->Release( pME );
if (FAILED(hr))
{
DeleteContents();
}
else
{
result = TRUE;
}
}
}
SetBusy(FALSE);
return result;
} // CreateFilterGraph
// Destruction
//
// DeleteContents
//
void DeleteContents()
{
if (media.pGraph != NULL)
{
HRESULT hr;
IVideoWindow *pVW;
SetBusy(TRUE);
/* check if this graph comes with a video window */
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IVideoWindow, (void**) &pVW);
if (SUCCEEDED(hr))
{
long left, top, width, height;
/* remember video window position */
hr = pVW->lpVtbl->GetRestorePosition(pVW, &left, &top, &width, &height);
if (SUCCEEDED(hr))
{
IVWWindowLeft = left;
IVWWindowTop = top;
IVWWindowWidth = width;
IVWWindowHeight = height;
}
pVW->lpVtbl->Release(pVW);
}
media.pGraph->lpVtbl->Release( media.pGraph );
media.pGraph = NULL;
SetBusy(FALSE);
}
// this event is owned by the filter graph and is thus invalid
media.hGraphNotifyEvent = NULL;
Previewing = FALSE;
IMPTotalTime = 0.0;
IMPCurrentPosition = 0.0;
IMSTotalTime = 0;
IMSCurrentPosition = 0;
IMSCapabilities = 0;
SetStatusText(STAT_TIMECODE, 0, -1, "");
if (hwndTrackbar)
{
SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, 0);
EnableWindow(hwndTrackbar, FALSE);
}
ChangeStateTo( Uninitialized );
} // DeleteContents
//
// RenderFile
//
BOOL RenderFile( LPSTR szFileName )
{
BOOL result = FALSE;
HRESULT hr;
WCHAR wPath[MAX_PATH];
SetBusy(TRUE);
DeleteContents();
if (!Transmitting) gui_setstatus("Preparing to play...");
if ( !CreateFilterGraph() )
{
PlayerMessageBox( IDS_CANT_INIT_QUARTZ );
}
else
{
MultiByteToWideChar( CP_ACP, 0, szFileName, -1, wPath, MAX_PATH );
hr = media.pGraph->lpVtbl->RenderFile(media.pGraph, wPath, NULL);
if (FAILED( hr ))
{
PlayerMessageBox( IDS_CANT_RENDER_FILE );
}
else
{
IMediaPosition *pMP;
IMediaSeeking *pMS;
IVideoWindow *pVW;
IMPTotalTime = 0;
IMPCurrentPosition = 0;
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaPosition,
(void**) &pMP);
if (SUCCEEDED(hr))
{
REFTIME tLength;
hr = pMP->lpVtbl->get_Duration(pMP, &tLength);
if (SUCCEEDED(hr))
{
LONG lBackward;
LONG lForward;
IMPTotalTime = tLength;
hr = pMP->lpVtbl->CanSeekBackward(pMP, &lBackward);
if (SUCCEEDED(hr))
{
hr = pMP->lpVtbl->CanSeekBackward(pMP, &lForward);
if (SUCCEEDED(hr))
{
// if (lBackward == OATRUE && lForward == OATRUE)
{
if (hwndTrackbar)
EnableWindow(hwndTrackbar, TRUE);
}
}
}
}
pMP->lpVtbl->Release(pMP);
}
IMSTotalTime = 0;
IMSCurrentPosition = 0;
IMSCapabilities = 0;
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaSeeking,
(void**) &pMS);
if (SUCCEEDED(hr))
{
LONGLONG llDuration;
hr = pMS->lpVtbl->GetDuration(pMS, &llDuration);
if (SUCCEEDED(hr))
{
DWORD dwCapabilities = 0;
IMSTotalTime = llDuration;
hr = pMS->lpVtbl->GetCapabilities(pMS, &dwCapabilities);
if (SUCCEEDED(hr))
{
//if (dwCapabilities & AM_SEEKING_CanSeekAbsolute) gui_criticalerror("AM_SEEKING_CanSeekAbsolute");
//if (dwCapabilities & AM_SEEKING_CanSeekForwards) gui_criticalerror("AM_SEEKING_CanSeekForwards");
//if (dwCapabilities & AM_SEEKING_CanSeekBackwards) gui_criticalerror("AM_SEEKING_CanSeekBackwards");
//if (dwCapabilities & AM_SEEKING_CanGetCurrentPos) gui_criticalerror("AM_SEEKING_CanGetCurrentPos");
//if (dwCapabilities & AM_SEEKING_CanGetStopPos) gui_criticalerror("AM_SEEKING_CanGetStopPos");
//if (dwCapabilities & AM_SEEKING_CanGetDuration) gui_criticalerror("AM_SEEKING_CanGetDuration");
//if (dwCapabilities & AM_SEEKING_CanPlayBackwards) gui_criticalerror("AM_SEEKING_CanPlayBackwards");
//if (dwCapabilities & AM_SEEKING_CanDoSegments) gui_criticalerror("AM_SEEKING_CanDoSegments");
//if (dwCapabilities & AM_SEEKING_Source) gui_criticalerror("AM_SEEKING_Source");
IMSCapabilities = dwCapabilities;
}
}
pMS->lpVtbl->Release(pMS);
}
/* check if this graph comes with a video window */
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IVideoWindow,
(void**) &pVW);
if (SUCCEEDED(hr))
{
BSTR title;
if ((title = SysAllocString(wPath)) != NULL)
{
hr = pVW->lpVtbl->put_Caption(pVW,title);
SysFreeString(title);
}
if (IVWWindowWidth > 0 && IVWWindowHeight > 0)
{
long left, top, width, height;
left = IVWWindowLeft;
top = IVWWindowTop;
width = IVWWindowWidth;
height = IVWWindowHeight;
hr = pVW->lpVtbl->SetWindowPosition(pVW, left, top, width, height);
}
pVW->lpVtbl->Release(pVW);
}
/* in any case, we got a filter graph, so return TRUE */
result = TRUE;
}
}
SetBusy(FALSE);
return result;
} // RenderFile
//
// SetTitle
//
// Update the title of the video renderer to "Player - szFile"
//
void SetTitle( HWND hwnd, char *szFile )
{
char szNewTitle[ _MAX_FNAME + _MAX_EXT + 20 ];
strcpy( szNewTitle, APP_NAME );
strcat( szNewTitle, " - " );
strcat( szNewTitle, szFile );
// Update the window's title
SetWindowText( hwnd, szNewTitle );
} // SetTitle
//
// OpenMediaFile
//
// File..Open has been selected
//
BOOL OpenMediaFile( HWND hwnd, LPSTR szFile )
{
BOOL result = FALSE;
static char szFileName[ _MAX_PATH ];
static char szTitleName[ _MAX_FNAME + _MAX_EXT ];
if( szFile != NULL )
{
if ( RenderFile( szFile ) )
{
LPSTR szTitle;
// Work out the full path name and the file name from the
// specified file
GetFullPathName( szFile, _MAX_PATH, szFileName, &szTitle );
strncpy( szTitleName, szTitle, _MAX_FNAME + _MAX_EXT );
szTitleName[ _MAX_FNAME + _MAX_EXT -1 ] = '\0';
// Set the main window title and update the state
if (!Transmitting) SetTitle( hwnd, szTitleName );
ChangeStateTo( Stopped );
result = TRUE;
}
else
if (!Transmitting) gui_seterror("Unable to play file!");
}
else
{
if( DoFileOpenDialog( hwnd, szFileName, szTitleName ) )
{
if (RenderFile( szFileName ) )
{
// Set the main window title and update the state
if (!Transmitting) SetTitle( hwnd, szTitleName );
ChangeStateTo( Stopped );
result = TRUE;
}
else
if (!Transmitting) gui_seterror("Unable to play file!");
}
}
return result;
} // OpenMediaFile
//
// GetCurrentPosition
//
BOOL GetCurrentPosition(REFTIME *rtcur)
{
BOOL result = FALSE;
if (IsInitialized())
{
HRESULT hr;
IMediaPosition *pMP;
REFTIME tCurrent;
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaPosition,
(void**) &pMP);
if (SUCCEEDED(hr))
{
hr = pMP->lpVtbl->get_CurrentPosition(pMP, &tCurrent);
if (SUCCEEDED(hr))
{
*rtcur = tCurrent;
result = TRUE;
}
pMP->lpVtbl->Release(pMP);
}
}
return result;
} // GetCurrentPosition
//
// GetStopPosition
//
BOOL GetStopPosition(REFTIME *rtstop, LONGLONG *llstop)
{
BOOL result = FALSE;
if (Previewing)
{
HRESULT hr;
IMediaPosition *pMP;
IMediaSeeking *pMS;
// Obtain the IMediaPosition interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
if( SUCCEEDED(hr) )
{
pMP->lpVtbl->get_StopTime(pMP, rtstop);
if ( SUCCEEDED(hr) )
{
result = TRUE;
}
pMP->lpVtbl->Release(pMP);
}
/* this one works as an alternative to the above */
if (TRUE)
{
// Obtain the IMediaSeeking interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaSeeking, (void **) &pMS);
if( SUCCEEDED(hr) )
{
/* Replay should stop at the current download position */
hr = pMS->lpVtbl->GetStopPosition(pMS, llstop);
if ( SUCCEEDED(hr) )
{
result = TRUE;
}
pMS->lpVtbl->Release(pMS);
}
}
}
return result;
} // GetStopPosition
//
// SetStopPosition
//
BOOL SetStopPosition(int milliseconds)
{
BOOL result = FALSE;
if (Previewing)
{
HRESULT hr;
IMediaPosition *pMP;
IMediaSeeking *pMS;
// Obtain the IMediaPosition interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
if( SUCCEEDED(hr) )
{
pMP->lpVtbl->put_StopTime(pMP, (REFTIME)milliseconds/1000);
if ( SUCCEEDED(hr) )
{
result = TRUE;
}
pMP->lpVtbl->Release(pMP);
}
/* this one works as an alternative to the above */
if (result == FALSE)
{
// Obtain the IMediaSeeking interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaSeeking, (void **) &pMS);
if( SUCCEEDED(hr) )
{
LONGLONG llCurrent = 0;
LONGLONG llStop = 0;
DWORD dwCurrentFlags = AM_SEEKING_NoPositioning;
DWORD dwStopFlags = AM_SEEKING_AbsolutePositioning;
/* Replay should stop at the current download position */
llStop = (LONGLONG)(milliseconds * 10000);
hr = pMS->lpVtbl->SetPositions(pMS,
&llCurrent,
dwCurrentFlags,
&llStop,
dwStopFlags );
if ( hr == NOERROR )
{
result = TRUE;
}
pMS->lpVtbl->Release(pMS);
}
}
}
return result;
} // SetStopPosition
//
// SetCurrentPosition
//
BOOL SetCurrentPosition(REFTIME position)
{
BOOL result = FALSE;
if( IsInitialized() )
{
HRESULT hr;
IMediaPosition *pMP;
SetBusy ( TRUE );
// Obtain the interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IMediaPosition, (void **) &pMP);
if( SUCCEEDED(hr) )
{
pMP->lpVtbl->put_CurrentPosition(pMP, position);
result = TRUE;
pMP->lpVtbl->Release(pMP);
}
if (result == FALSE)
// Inform the user that an error occurred
PlayerMessageBox( IDS_CANT_SEEK );
SetBusy ( FALSE );
}
return result;
} // SetCurrentPosition
//
// OnMediaSeeking
//
BOOL OnMediaSeeking(BOOL Enabled)
{
BOOL result = FALSE;
HRESULT hr;
IMediaControl *pMC;
// Obtain the interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaControl,
(void **) &pMC);
if( SUCCEEDED(hr) )
{
result = TRUE;
if (Enabled)
{
if (!Transmitting) gui_setstatus("Seeking...");
if (media.state == Playing)
{
hr = pMC->lpVtbl->Pause( pMC );
}
}
else
{
if (media.state == Playing)
{
hr = pMC->lpVtbl->Run( pMC );
}
ChangeStateTo(media.state);
}
pMC->lpVtbl->Release( pMC );
}
return result;
} // OnMediaSeeking
//
// OnMediaPlay
//
BOOL OnMediaPlay()
{
BOOL result = FALSE;
if( CanPlay() )
{
HRESULT hr;
IVideoWindow *pVW;
IMediaControl *pMC;
SetBusy ( TRUE );
/* check if this graph comes with a video window */
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph, &IID_IVideoWindow, (void**) &pVW);
if (SUCCEEDED(hr))
{
long windowstate;
/* remember video window position */
hr = pVW->lpVtbl->get_WindowState(pVW, &windowstate);
if (SUCCEEDED(hr))
{
/* show the window if it was hidden/miminized */
if (windowstate == SW_MINIMIZE || windowstate == SW_HIDE ||
windowstate == SW_SHOWMINNOACTIVE )
{
windowstate = SW_SHOWNORMAL;
hr = pVW->lpVtbl->put_WindowState(pVW, windowstate);
}
}
pVW->lpVtbl->Release(pVW);
}
if (Previewing)
{
REFTIME rtstoppos;
LONGLONG llstoppos;
REFTIME rtcurrent;
if (GetStopPosition(&rtstoppos, &llstoppos))
{
if (GetCurrentPosition(&rtcurrent))
{
/* the filter graph thinks it has reached the end of the stream */
/* because it is truncated and we are still downloading it! */
if (rtcurrent == rtstoppos)
{
/* so in this case we have to reposition and try again */
/* otherwise the filter graph won't continue to play */
SetCurrentPosition( IMPCurrentPosition );
}
}
}
}
// Obtain the interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaControl,
(void **) &pMC);
if( SUCCEEDED(hr) )
{
// Ask the filter graph to play and release the interface
hr = pMC->lpVtbl->Run( pMC );
if( SUCCEEDED(hr) )
{
ChangeStateTo( Playing );
result = TRUE;
}
pMC->lpVtbl->Release( pMC );
}
if (result == FALSE)
// Inform the user that an error occurred
PlayerMessageBox( IDS_CANT_PLAY );
SetBusy ( FALSE );
}
return result;
} // OnMediaPlay
//
// OnMediaPause
//
BOOL OnMediaPause()
{
BOOL result = FALSE;
if( CanPause() )
{
HRESULT hr;
IMediaControl *pMC;
SetBusy(TRUE);
// Obtain the interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaControl,
(void **) &pMC);
if( SUCCEEDED(hr) )
{
// Ask the filter graph to pause and release the interface
hr = pMC->lpVtbl->Pause( pMC );
if( SUCCEEDED(hr) )
{
ChangeStateTo( Paused );
result = TRUE;
}
pMC->lpVtbl->Release( pMC );
}
if (result == FALSE)
// Inform the user that an error occurred
PlayerMessageBox( IDS_CANT_PAUSE );
SetBusy(FALSE);
}
return result;
} // OnMediaPause
//
// OnMediaStop
//
BOOL OnMediaStop(BOOL reallystop, BOOL rewind)
{
BOOL result = FALSE;
if( CanStop() )
{
HRESULT hr;
IMediaControl *pMC;
SetBusy(TRUE);
if (!Transmitting) gui_setstatus("Stopping replay...");
// Obtain the interface to our filter graph
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaControl,
(void **) &pMC);
if( SUCCEEDED(hr) )
{
IMediaPosition * pMP;
if (reallystop)
// now really do the stop
pMC->lpVtbl->Stop( pMC );
else
// just simulate a stop using pause (faster)
pMC->lpVtbl->Pause( pMC );
if( SUCCEEDED(hr) )
{
ChangeStateTo( Stopped );
result = TRUE;
}
if (rewind == TRUE)
{
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaPosition,
(void**) &pMP);
if (SUCCEEDED(hr))
{
hr = pMP->lpVtbl->put_CurrentPosition(pMP, 0);
if (SUCCEEDED(hr))
{
SetStatusText(STAT_TIMECODE, 0, -1, "");
if (hwndTrackbar != NULL)
SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, 0);
}
pMP->lpVtbl->Release(pMP);
}
}
pMC->lpVtbl->Release( pMC );
}
if (result == FALSE)
// Inform the user that an error occurred
PlayerMessageBox( IDS_CANT_STOP );
SetBusy(FALSE);
}
return result;
} // OnMediaStop
//
// GetGraphEventHandle
//
// We use this to check for graph events
//
HANDLE GetGraphEventHandle()
{
return media.hGraphNotifyEvent;
} // GetGraphEventHandle
//
// OnGraphNotify
//
// If the event handle is valid, then ask the graph if
// anything has happened (eg the graph has stopped...)
//
void OnGraphNotify()
{
IMediaEvent *pME;
long lEventCode, lParam1, lParam2;
ASSERT( media.hGraphNotifyEvent != NULL );
if( SUCCEEDED(media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaEvent,
(void **) &pME)))
{
if( SUCCEEDED(pME->lpVtbl->GetEvent(pME, &lEventCode, &lParam1, &lParam2, 0)))
{
if (lEventCode == EC_COMPLETE)
{
OnMediaStop(FALSE, FALSE);
if (!Transmitting) gui_setstatus("Replay complete");
}
if (lEventCode == EC_USERABORT)
{
OnMediaStop(TRUE, TRUE);
if (!Transmitting) gui_setstatus("User aborted replay");
}
if (lEventCode == EC_ERRORABORT)
{
OnMediaStop(TRUE, TRUE);
if (!Transmitting) gui_setstatus("Error during replay");
}
}
pME->lpVtbl->Release( pME );
}
} // OnGraphNotify
/*---------------------------- FILE OPEN DIALOG -----------------------------*/
// This handles the file..open dialog box
static OPENFILENAME ofn;
//
// InitFileOpenDialog
//
BOOL InitFileOpenDialog( HWND hwnd )
{
ofn.lStructSize = sizeof( OPENFILENAME );
ofn.hwndOwner = hwnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = "Windows Media files (*.asf,*.wma,*.wmv)\0*.asf; *.wma; *.wmv\0"
"MPEG audio files (*.mp2,*.mp3)\0*.mp2; *.mp3;\0"
"MPEG video files (*.mpg,*.mpe,*.mpeg)\0*.mpg; *.mpe; *.mpeg\0"
"AVI files (*.avi)\0*.avi\0"
"Quick Time files (*.mov)\0*.mov\0"
"Wave audio files (*.wav)\0*.wav\0"
"Filter graph files (*.grf)\0*.grf\0"
"All Files (*.*)\0*.*\0\0";
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = NULL;
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = "asf";
ofn.lCustData = 0;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
return TRUE;
} // InitFileOpenDialog
//
// DoFileOpenDialog
//
BOOL DoFileOpenDialog( HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName )
{
// Called to display the open file dialog
ofn.hwndOwner = hwnd;
ofn.lpstrFile = lpstrFileName;
ofn.lpstrFileTitle = lpstrTitleName;
ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
return GetOpenFileName( &ofn );
} // DoFileOpenDialog
/*---------------------------- FILE SAVE DIALOG -----------------------------*/
// This handles the file..open dialog box
static OPENFILENAME sfn;
//
// InitFileSaveDialog
//
BOOL InitFileSaveDialog( HWND hwnd )
{
sfn.lStructSize = sizeof( OPENFILENAME );
sfn.hwndOwner = hwnd;
sfn.hInstance = NULL;
sfn.lpstrFilter = "Windows Media files (*.asf,*.wma,*.wmv)\0*.asf; *.wma; *.wmv\0"
"All Files (*.*)\0*.*\0\0";
sfn.lpstrCustomFilter = NULL;
sfn.nMaxCustFilter = 0;
sfn.nFilterIndex = 0;
sfn.lpstrFile = NULL;
sfn.nMaxFile = _MAX_PATH;
sfn.lpstrFileTitle = NULL;
sfn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
sfn.lpstrInitialDir = NULL;
sfn.lpstrTitle = NULL;
sfn.Flags = OFN_EXPLORER ;
sfn.nFileOffset = 0;
sfn.nFileExtension = 0;
sfn.lpstrDefExt = "asf";
sfn.lCustData = 0;
sfn.lpfnHook = NULL;
sfn.lpTemplateName = NULL;
return TRUE;
} // InitFileSaveDialog
//
// DoFileSaveDialog
//
BOOL DoFileSaveDialog( HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName )
{
// Called to display the open file dialog
sfn.hwndOwner = hwnd;
sfn.lpstrFile = lpstrFileName;
sfn.lpstrFileTitle = lpstrTitleName;
ShowWindow( appVars.hwndMainFrame, SW_SHOWNORMAL );
SetWindowPos(appVars.hwndMainFrame, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
return GetSaveFileName( &sfn );
} // DoFileSaveDialog
/*----------------------------- TOOL BAR CODE -------------------------------*/
// Constants for the bitmap
const int nButtonImageWidth = 46;
const int nButtonImageHeight = 36;
// Constants for the toolbar implementation
const int nSeperatorGap = 6;
const int nToolbarBorderWidth = 5;
const int nToolbarBorderHeight = 3;
//
// CalcToolbarSize
//
void CalcToolbarSize( SIZE *pSize )
{
// Calculate the area required for this toolbar
// size for 3 buttons, 2 borders and a seperator
// ...but we'll add on a some extra seperators for good measure
pSize->cx = (nButtonImageWidth) * 5 + nSeperatorGap + 2 * nToolbarBorderWidth;
// size for 1 button and 2 borders
pSize->cy = nButtonImageHeight + 2 * nToolbarBorderHeight;
} // CalcToolbarSize
//
// UpdateToolbar
//
// Maintains the enabled/disabled state of the buttons - we should be
// called periodically and/or whenever there is a change of graph state
//
void UpdateToolbar()
{
if (toolbar.hwndPlayButton != NULL)
EnableWindow( toolbar.hwndPlayButton, CanPlay() );
if (toolbar.hwndPauseButton != NULL)
EnableWindow( toolbar.hwndPauseButton, CanPause() );
if (toolbar.hwndStopButton != NULL)
EnableWindow( toolbar.hwndStopButton, CanStop() );
if (toolbar.hwndPreviewButton != NULL)
EnableWindow( toolbar.hwndPreviewButton, CanPreview() );
if (toolbar.hwndCancelButton != NULL)
EnableWindow( toolbar.hwndCancelButton, Transmitting );
} // UpdateToolbar
//
// ToolbarButtonProc
//
// Subclassed window procedure for the toolbar buttons
//
long FAR PASCAL ToolbarButtonProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
WNDPROC oldwndproc = (WNDPROC)GetWindowLong( hwnd, GWL_USERDATA );
switch(message)
{
case WM_ERASEBKGND:
{
/* no nothing */
}
return (LRESULT) 1;
break;
default:
return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
}
return (LRESULT) 0;
} // MainFrameProc
//
// InitToolbar
//
// Create the controls for the buttons
//
BOOL InitToolbar( HINSTANCE hInstance, HWND hwnd )
{
LONG oldwndproc;
int x; // Position of the next button
x = nToolbarBorderWidth;
// The 'Play' button
toolbar.hwndPlayButton = CreateWindow( "BUTTON",
NULL,
BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
x,
nToolbarBorderHeight,
nButtonImageWidth,
nButtonImageHeight,
hwnd,
(HMENU) ID_MEDIA_PLAY,
hInstance,
NULL);
oldwndproc = SetWindowLong( toolbar.hwndPlayButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
SetWindowLong(toolbar.hwndPlayButton, GWL_USERDATA, oldwndproc);
x += nButtonImageWidth;
// The 'Pause' button
toolbar.hwndPauseButton = CreateWindow( "BUTTON",
NULL,
BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
x,
nToolbarBorderHeight,
nButtonImageWidth,
nButtonImageHeight,
hwnd,
(HMENU) ID_MEDIA_PAUSE,
hInstance,
NULL);
oldwndproc = SetWindowLong( toolbar.hwndPauseButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
SetWindowLong(toolbar.hwndPauseButton, GWL_USERDATA, oldwndproc);
x += nButtonImageWidth;
// The 'Stop' button
toolbar.hwndStopButton = CreateWindow( "BUTTON",
NULL,
BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
x,
nToolbarBorderHeight,
nButtonImageWidth,
nButtonImageHeight,
hwnd,
(HMENU) ID_MEDIA_STOP,
hInstance,
NULL);
oldwndproc = SetWindowLong( toolbar.hwndStopButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
SetWindowLong(toolbar.hwndStopButton, GWL_USERDATA, oldwndproc);
x += nButtonImageWidth + nSeperatorGap;
// The 'Preview' button
toolbar.hwndPreviewButton = CreateWindow( "BUTTON",
NULL,
BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
x,
nToolbarBorderHeight,
nButtonImageWidth,
nButtonImageHeight,
hwnd,
(HMENU) ID_STREAM_PREVIEW,
hInstance,
NULL);
oldwndproc = SetWindowLong( toolbar.hwndPreviewButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
SetWindowLong(toolbar.hwndPreviewButton, GWL_USERDATA, oldwndproc);
x += nButtonImageWidth;
// The 'Cancel' button
toolbar.hwndCancelButton = CreateWindow( "BUTTON",
NULL,
BS_OWNERDRAW | WS_VISIBLE | WS_CHILD,
x,
nToolbarBorderHeight,
nButtonImageWidth,
nButtonImageHeight,
hwnd,
(HMENU) ID_STREAM_CANCEL,
hInstance,
NULL);
oldwndproc = SetWindowLong( toolbar.hwndCancelButton, GWL_WNDPROC, (DWORD)&ToolbarButtonProc);
SetWindowLong(toolbar.hwndCancelButton, GWL_USERDATA, oldwndproc);
// We don't call UpdateToolbar to set the button states as
// the multimedia variables may not have been initialized yet
return TRUE;
} // InitToolbar
//
// DrawButton
//
// Called by the main window whenever a button needs to be redrawn
//
void DrawButton( HINSTANCE hInstance, DRAWITEMSTRUCT FAR * lpDrawItem )
{
HDC hSourceDC = CreateCompatibleDC( NULL );
HGDIOBJ loadedbitmap;
HGDIOBJ hgdiOldBitmap;
int nIndex;
// Load the IDR_TOOLBAR_INACTIVE bitmap into our source hDC if the
// button is disabled otherwise load the IDR_TOOLBAR_PRESSED/NOTPRESSED bitmap
if( lpDrawItem->itemState & ODS_DISABLED )
loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_INACTIVE ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
else
{
if( lpDrawItem->itemState & ODS_SELECTED )
loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_PRESSED ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
else
loadedbitmap = (HGDIOBJ) LoadImage( hInstance, MAKEINTRESOURCE( IDB_TOOLBAR_NOTPRESSED ), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR );
}
hgdiOldBitmap = SelectObject( hSourceDC, loadedbitmap );
// Decide which button to blit to the display
switch( lpDrawItem->CtlID ){
case ID_MEDIA_PLAY:
nIndex = 0;
break;
case ID_MEDIA_PAUSE:
nIndex = 1;
break;
case ID_MEDIA_STOP:
nIndex = 2;
break;
case ID_STREAM_PREVIEW:
nIndex = 3;
break;
case ID_STREAM_CANCEL:
nIndex = 4;
break;
}
// ..and blit it
BitBlt( lpDrawItem->hDC,
lpDrawItem->rcItem.left,
lpDrawItem->rcItem.top ,
nButtonImageWidth,
nButtonImageHeight,
hSourceDC,
nIndex * nButtonImageWidth + 2,
0,
SRCCOPY
);
// Restore the original bitmap
SelectObject( hSourceDC, hgdiOldBitmap );
// this was missing from the Microsoft example code
DeleteObject(loadedbitmap);
DeleteDC(hSourceDC);
} // DrawButton
/*---------------------------- TRACK BAR CODE -------------------------------*/
const int nTrackbarBorderWidth = 5;
const int nTrackbarBorderHeight = 11;
//
// CalcTrackbarSize
//
// Calculate the size of the trackbar (including borders)
//
void CalcTrackbarSize ( SIZE *pSize )
{
RECT clientRect;
SIZE sizeToolbar;
GetClientRect( appVars.hwndMainFrame, &clientRect );
CalcToolbarSize( &sizeToolbar );
pSize->cx = (clientRect.right-clientRect.left+1) - sizeToolbar.cx;
pSize->cy = sizeToolbar.cy;
} // CalcTrackbarSize
//
// TrackbarProc
//
// Subclassed window procedure for the trackbar
//
long FAR PASCAL TrackbarProc( HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
WNDPROC oldwndproc = (WNDPROC)GetWindowLong( hwnd, GWL_USERDATA );
switch(message)
{
/* This modifies the default behaviour of the trackbar. */
/* When clicking inside the channel, the click position */
/* is converted to a slider position value and stored in */
/* positionTrackbar */
/* this enables us to move the slider to this position when */
/* we receive a WM_NOTIFY / NM_RELEASEDCAPTURE message */
case WM_LBUTTONDOWN:
{
UINT fwKeys = wParam; // key flags
if (fwKeys == MK_LBUTTON)
{
int xPos = LOWORD(lParam); // horizontal position of cursor
int yPos = HIWORD(lParam); // vertical position of cursor
RECT chanrect;
LONG chanwidth;
SendMessage(hwndTrackbar, TBM_GETCHANNELRECT, 0, (LPARAM) &chanrect);
chanwidth = chanrect.right - chanrect.left + 1;
if (xPos >= chanrect.left && xPos <= chanrect.right)
{
UINT min, max;
min = SendMessage(hwndTrackbar, TBM_GETRANGEMIN, 0, 0);
max = SendMessage(hwndTrackbar, TBM_GETRANGEMAX, 0, 0);
positionTrackbar = min + ((max-min)*(xPos-chanrect.left))/chanwidth;
}
}
return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
}
break;
case WM_ERASEBKGND:
{
/* no nothing */
}
return (LRESULT) 1;
break;
default:
return CallWindowProc(oldwndproc, hwnd, message, wParam, lParam);
}
return (LRESULT) 0;
} // TrackbarProc
//
// AdjustTrackbar
//
// Reposition the trackbar control in the main frame
//
void AdjustTrackbar ( HWND hwndTrack, HWND hwndParent )
{
int x,y,w,h;
SIZE sizeToolbar;
SIZE sizeTrackbar;
CalcToolbarSize( &sizeToolbar );
CalcTrackbarSize ( &sizeTrackbar );
x = sizeToolbar.cx + nTrackbarBorderWidth;
y = (sizeToolbar.cy - sizeTrackbar.cy)/2 + nTrackbarBorderHeight;
w = sizeTrackbar.cx - 2 * nTrackbarBorderWidth;
h = sizeTrackbar.cy - 2 * nTrackbarBorderHeight;
MoveWindow( hwndTrack, x,y,w,h, TRUE );
} // AdjustTrackbar
//
// InitTrackbar
//
// Create and initialize the trackbar control
//
BOOL InitTrackbar( HINSTANCE hInstance, HWND hwnd )
{
LONG oldwndproc;
int x,y,w,h;
SIZE sizeToolbar;
SIZE sizeTrackbar;
CalcToolbarSize( &sizeToolbar );
CalcTrackbarSize ( &sizeTrackbar );
x = sizeToolbar.cx + nTrackbarBorderWidth;
y = (sizeToolbar.cy - sizeTrackbar.cy)/2 + nTrackbarBorderHeight;
w = sizeTrackbar.cx - 2 * nTrackbarBorderWidth;
h = sizeTrackbar.cy - 2 * nTrackbarBorderHeight;
// Create the trackbar
hwndTrackbar = CreateWindow( TRACKBAR_CLASS,
NULL,
WS_DISABLED | WS_VISIBLE | WS_CHILD | TBS_NOTICKS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH,
x,
y,
w,
h,
hwnd,
(HMENU) IDR_TRACKBAR,
hInstance,
NULL );
SendMessage(hwndTrackbar, TBM_SETTHUMBLENGTH, 16, 0);
/* TrackBars range is from 0 to 10000, regardless of the stream length */
SendMessage(hwndTrackbar, TBM_SETRANGEMIN, FALSE, 0 );
SendMessage(hwndTrackbar, TBM_SETRANGEMAX, FALSE, 10000 );
/* disable pageup/down lineup/down using keyboard or mouse */
SendMessage(hwndTrackbar, TBM_SETPAGESIZE, 0 , 0);
SendMessage(hwndTrackbar, TBM_SETLINESIZE, 0, 0);
oldwndproc = SetWindowLong( hwndTrackbar, GWL_WNDPROC, (DWORD)&TrackbarProc);
SetWindowLong(hwndTrackbar, GWL_USERDATA, oldwndproc);
return TRUE;
} // InitTrackbar
//
// TrackbarTimerFunc
//
// Moves the trackbar during media replay. Also prints time stamp.
//
void CALLBACK TrackbarTimerFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
HRESULT hr;
IMediaPosition * pMP;
if (idEvent == TrackbarTimer)
{
if (IMPTotalTime != 0.0)
{
if (IsInitialized())
{
hr = media.pGraph->lpVtbl->QueryInterface(media.pGraph,
&IID_IMediaPosition,
(void**) &pMP);
if (SUCCEEDED(hr))
{
REFTIME tCurrent;
hr = pMP->lpVtbl->get_CurrentPosition(pMP, &tCurrent);
if (SUCCEEDED(hr))
{
LONG value;
if (Previewing)
{
if (tCurrent < IMPDownloadTime)
{
IMPCurrentPosition = tCurrent;
}
}
else
{
IMPCurrentPosition = tCurrent;
}
if (hwndTrackbar != NULL)
{
if (!TrackbarDragging)
{
value = (LONG)(10000 * IMPCurrentPosition / IMPTotalTime);
SendMessage( hwndTrackbar, TBM_SETPOS, TRUE, value);
}
}
if ((!Transmitting) && (!TrackbarDragging))
{
unsigned int timecode = (unsigned int)(1000 * IMPCurrentPosition);
char *timecodestring = createtimestring(timecode);
SetStatusText(STAT_TIMECODE, 0, -1, "T: %s", timecodestring);
}
}
pMP->lpVtbl->Release(pMP);
}
}
}
}
} // TrackbarTimerFunc
/*---------------------- FILE TYPE REGISTRATION CODE ------------------------*/
enum
{
Query,
Register,
Unregister
};
//
// FileTypeRegistration
//
// query for, register or unregister a given file type
//
BOOL FileTypeRegistration(LPTSTR filetype, int mode)
{
BOOL result = FALSE;
LONG retval;
HKEY hkeyFileExtension;
HKEY hkeyFileType;
DWORD dwResult;
unsigned char keyname[32];
unsigned char defaulttypename[32];
unsigned char *src, *dst;
int i;
keyname[0] = '.';
for (src = filetype, dst = &keyname[1]; *dst = tolower(*src) ; dst++, src++ );
for (src = filetype, dst = defaulttypename; *dst = toupper(*src) ; dst++, src++ );
strcat(defaulttypename, "File");
retval = RegCreateKeyEx(HKEY_CLASSES_ROOT,
keyname,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkeyFileExtension,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx (1) for '%s' failed: %d\n", keyname, retval);
}
else
{
unsigned char filetypename[200];
unsigned char filetypenameshellcommand[256];
DWORD dwType;
DWORD dwSize;
strcpy(filetypename, "");
dwSize = sizeof(filetypename);
retval = RegQueryValueEx( hkeyFileExtension,
"",
0,
&dwType,
filetypename,
&dwSize );
if (retval != ERROR_SUCCESS)
{
if (retval != ERROR_FILE_NOT_FOUND)
gui_criticalerror("RegQueryValueEx (1) for '%s' failed: %d\n", "(Default)", retval);
else
{
retval = RegSetValueEx( hkeyFileExtension,
"",
0,
REG_SZ,
defaulttypename,
strlen(defaulttypename)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx (1) for '%s' failed: %d\n", "(Default)", retval);
}
else
strcpy(filetypename, defaulttypename);
}
}
else
{
if (dwType == REG_SZ)
{
if (!strcmp("", filetypename))
{
retval = RegSetValueEx( hkeyFileExtension,
"",
0,
REG_SZ,
defaulttypename,
strlen(defaulttypename)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx (2) for '%s' failed: %d\n", "(Default)", retval);
}
else
strcpy(filetypename, defaulttypename);
}
}
}
if (strcmp(filetypename, ""))
{
if (mode == Query)
result = TRUE;
for (i = 0; i < 2 ; i++)
{
strcpy(filetypenameshellcommand, filetypename);
if (i == 0)
strcat(filetypenameshellcommand, "\\shell\\open\\command");
if (i == 1)
strcat(filetypenameshellcommand, "\\shell\\play\\command");
retval = RegCreateKeyEx(HKEY_CLASSES_ROOT,
filetypenameshellcommand,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkeyFileType,
&dwResult);
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegCreateKeyEx (2) for '%s' failed: %d\n", filetypenameshellcommand, retval);
}
else
{
unsigned char playername[512];
unsigned char playernameuppercase[512];
DWORD dwType = REG_NONE;
DWORD dwSize;
dwSize = sizeof(playername);
retval = RegQueryValueEx( hkeyFileType,
"",
0,
&dwType,
playername,
&dwSize );
if (retval != ERROR_SUCCESS)
{
if (retval != ERROR_FILE_NOT_FOUND)
gui_criticalerror("RegQueryValueEx (2) for '%s' failed: %d\n", "(Default)", retval);
else
strcpy(playername, "");
dwType = REG_SZ;
}
if (dwType == REG_SZ)
{
unsigned char myplayername[512];
unsigned char myplayernameuppercase[512];
sprintf(myplayername, "\42%s\42 \42%%L\42", appVars.szProgramExecutable);
/* make uppercase versions of playername strings */
strcpy(playernameuppercase, playername);
_strupr(playernameuppercase);
strcpy(myplayernameuppercase, myplayername);
_strupr(myplayernameuppercase);
switch (mode)
{
case Query:
/* try to match player name with asfrecorder */
if ( (strstr(playernameuppercase, myplayernameuppercase ) == NULL) &&
(strstr(playernameuppercase, "ASFRECORDER" ) == NULL) &&
(strstr(playernameuppercase, "ASFREC~" ) == NULL) )
{
result = FALSE;
break;
}
break;
case Register:
/* Create backup of old player only if its name */
/* does not contain the string "ASFRecorder" and*/
/* if it is not empty */
if ((strcmp(playernameuppercase, "" ) ) &&
(strstr(playernameuppercase, "ASFRECORDER") == NULL) &&
(strstr(playernameuppercase, "ASFREC~1" ) == NULL) )
{
retval = RegSetValueEx( hkeyFileType,
"ASFRecorder_backup",
0,
REG_SZ,
playername,
strlen(playername)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx (3) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
}
}
retval = RegSetValueEx( hkeyFileType,
"",
0,
REG_SZ,
myplayername,
strlen(myplayername)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx (4) for '%s' failed: %d\n", "(Default)", retval);
}
break;
case Unregister:
dwSize = sizeof(playername);
retval = RegQueryValueEx( hkeyFileType,
"ASFRecorder_backup",
0,
&dwType,
playername,
&dwSize );
if ((retval != ERROR_SUCCESS) && (retval != ERROR_FILE_NOT_FOUND))
{
gui_criticalerror("RegQueryValueEx (3) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
}
else
{
if (retval == ERROR_FILE_NOT_FOUND)
{
dwType = REG_SZ;
strcpy(playername, "");
}
if (dwType == REG_SZ)
{
retval = RegSetValueEx( hkeyFileType,
"",
0,
REG_SZ,
playername,
strlen(playername)+1 );
if (retval != ERROR_SUCCESS)
{
gui_criticalerror("RegSetValueEx (5) for '%s' failed: %d\n", "(Default)", retval);
}
else
{
retval = RegDeleteValue( hkeyFileType,
"ASFRecorder_backup" );
if ((retval != ERROR_SUCCESS) && (retval != ERROR_FILE_NOT_FOUND))
{
gui_criticalerror("RegDeleteValue (1) for '%s' failed: %d\n", "ASFRecorder_backup", retval);
}
}
}
}
break;
}
}
RegCloseKey(hkeyFileType);
}
}
}
RegCloseKey(hkeyFileExtension);
}
return result;
} // FileTypeRegistration
//
// OnRegisterFileTypes
//
// Register redirection file types.
//
void OnRegisterFileTypes()
{
if ( (!FileTypeRegistration("ASX", Query)) ||
(!FileTypeRegistration("WAX", Query)) ||
(!FileTypeRegistration("WVX", Query)) ||
(!FileTypeRegistration("WMX", Query)) )
{
FileTypeRegistration("ASX", Register);
FileTypeRegistration("WAX", Register);
FileTypeRegistration("WVX", Register);
FileTypeRegistration("WMX", Register);
PlayerMessageBox( IDS_REGISTERED );
}
else
{
PlayerMessageBox( IDS_ALREADYREGISTERED );
}
} // OnRegisterFileTypes
//
// OnRegisterFileTypes
//
// Unregister redirection file types.
//
void OnUnregisterFileTypes()
{
if ( FileTypeRegistration("ASX", Query) ||
FileTypeRegistration("WAX", Query) ||
FileTypeRegistration("WVX", Query) ||
FileTypeRegistration("WMX", Query) )
{
FileTypeRegistration("ASX", Unregister);
FileTypeRegistration("WAX", Unregister);
FileTypeRegistration("WVX", Unregister);
FileTypeRegistration("WMX", Unregister);
PlayerMessageBox( IDS_UNREGISTERED );
}
else
{
PlayerMessageBox( IDS_NOTREGISTERED );
}
} // OnUnregisterFileTypes