|
|
/**************************************************************************
* * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR * PURPOSE. * * Copyright (c) 1992 - 1995 Microsoft Corporation. All Rights Reserved. * **************************************************************************/ /****************************************************************************
* * dialogs.c: Dialog box processing * * Vidcap32 Source code * ***************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <dos.h>
#include <vfw.h>
#include <tchar.h>
#include "arrow.h"
#include "rlmeter.h"
#include "vidcap.h"
#include "vidframe.h"
#include "help.h"
static long GetFreeDiskSpaceInKB(LPTSTR) ; static int CountMCIDevices(UINT) ;
LRESULT FAR PASCAL MCISetupProc(HWND, unsigned, WPARAM, LPARAM);
//--- utility functions ---------------------------------------------------
/*----------------------------------------------------------------------------*\
| SmartWindowPosition (HWND hWndDlg, HWND hWndShow) | | | Description: | | This function attempts to position a dialog box so that it | does not obscure the hWndShow window. This function is | typically called during WM_INITDIALOG processing. | | | Arguments: | | hWndDlg handle of the soon to be displayed dialog | hWndShow handle of the window to keep visible | | | Returns: | | 1 if the windows overlap and positions were adjusted | 0 if the windows don't overlap | | \*----------------------------------------------------------------------------*/ int SmartWindowPosition (HWND hWndDlg, HWND hWndShow) { RECT rc, rcDlg, rcShow; int iHeight, iWidth; int iScreenHeight, iScreenWidth;
GetWindowRect(hWndDlg, &rcDlg); GetWindowRect(hWndShow, &rcShow);
iScreenHeight = GetSystemMetrics(SM_CYSCREEN); iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
InflateRect (&rcShow, 5, 5); // allow a small border
if (IntersectRect(&rc, &rcDlg, &rcShow)){ /* the two do intersect, now figure out where to place */ /* this dialog window. Try to go below the Show window*/ /* first and then to the right, top and left. */
/* get the size of this dialog */ iHeight = rcDlg.bottom - rcDlg.top; iWidth = rcDlg.right - rcDlg.left;
if ((UINT)(rcShow.bottom + iHeight + 1) < (UINT)iScreenHeight){ /* will fit on bottom, go for it */ rc.top = rcShow.bottom + 1; rc.left = (((rcShow.right - rcShow.left)/2) + rcShow.left) - (iWidth/2); } else if ((UINT)(rcShow.right + iWidth + 1) < (UINT)iScreenWidth){ /* will fit to right, go for it */ rc.left = rcShow.right + 1; rc.top = (((rcShow.bottom - rcShow.top)/2) + rcShow.top) - (iHeight/2); } else if ((UINT)(rcShow.top - iHeight - 1) > 0){ /* will fit on top, handle that */ rc.top = rcShow.top - iHeight - 1; rc.left = (((rcShow.right - rcShow.left)/2) + rcShow.left) - (iWidth/2); } else if ((UINT)(rcShow.left - iWidth - 1) > 0){ /* will fit to left, do it */ rc.left = rcShow.left - iWidth - 1; rc.top = (((rcShow.bottom - rcShow.top)/2) + rcShow.top) - (iHeight/2); } else { /* we are hosed, they cannot be placed so that there is */ /* no overlap anywhere. To minimize the damage just put*/ /* the dialog in the lower left corner of the screen */ rc.top = (int)iScreenHeight - iHeight; rc.left = (int)iScreenWidth - iWidth; }
/* make any adjustments necessary to keep it on the screen */ if (rc.left < 0) rc.left = 0; else if ((UINT)(rc.left + iWidth) > (UINT)iScreenWidth) rc.left = (int)(iScreenWidth - iWidth);
if (rc.top < 0) rc.top = 0; else if ((UINT)(rc.top + iHeight) > (UINT)iScreenHeight) rc.top = (int)iScreenHeight - iHeight;
SetWindowPos(hWndDlg, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); return 1; } // if the windows overlap by default
return 0; }
//
// GetFreeDiskSpace: Function to Measure Available Disk Space
//
static long GetFreeDiskSpaceInKB(LPTSTR pFile) { DWORD dwFreeClusters, dwBytesPerSector, dwSectorsPerCluster, dwClusters; TCHAR RootName[MAX_PATH]; LPTSTR ptmp; //required arg
// need to find path for root directory on drive containing
// this file.
GetFullPathName(pFile, sizeof(RootName)/sizeof(RootName[0]), RootName, &ptmp);
// truncate this to the name of the root directory (god how tedious)
if ((RootName[0] == TEXT('\\')) && (RootName[1] == TEXT('\\'))) {
// path begins with \\server\share\path so skip the first
// three backslashes
ptmp = &RootName[2]; while (*ptmp && (*ptmp != TEXT('\\'))) { ptmp++; } if (*ptmp) { // advance past the third backslash
ptmp++; } } else { // path must be drv:\path
ptmp = RootName; }
// find next backslash and put a null after it
while (*ptmp && (*ptmp != TEXT('\\'))) { ptmp++; } // found a backslash ?
if (*ptmp) { // skip it and insert null
ptmp++; *ptmp = TEXT('\0'); }
if (!GetDiskFreeSpace(RootName, &dwSectorsPerCluster, &dwBytesPerSector, &dwFreeClusters, &dwClusters)) { MessageBoxID(IDS_ERR_MEASUREFREEDISK, MB_OK | MB_ICONINFORMATION); return (-1); } return(MulDiv (dwSectorsPerCluster * dwBytesPerSector, dwFreeClusters, 1024)); }
//
// CountMCIDevices: Function to Find the Number of MCI Devices of a Type
//
static int CountMCIDevices(UINT wType) { int nTotal = 0 ; DWORD dwCount ; MCI_SYSINFO_PARMS mciSIP ;
mciSIP.dwCallback = 0 ; mciSIP.lpstrReturn = (LPTSTR)(LPVOID) &dwCount ; mciSIP.dwRetSize = sizeof(DWORD) ; mciSIP.wDeviceType = wType ;
// Use an MCI command to get the info
if (! mciSendCommand(0, MCI_SYSINFO, MCI_SYSINFO_QUANTITY, (DWORD_PTR)(LPVOID) &mciSIP)) nTotal = (int) *((LPDWORD) mciSIP.lpstrReturn) ;
return nTotal ; }
/* lMicroSec = StringRateToMicroSec(szRate)
* * Convert <szRate> (e.g. "3.75" representing 3.75 frames per second) * to microseconds (e.g. 266667L microseconds per frame). * * If the rate is close to zero or negative, then 0L is returned. */ DWORD StringRateToMicroSec(PSTR szRate) { double dRate;
dRate = atof(szRate); if (dRate < 0.0001) { return 0L; } else { return (DWORD) /*floor*/((1e6 / dRate) + 0.5); } }
/* ach = MicroSecToStringRate(achRate, lMicroSec)
* * Convert <lMicroSec> (e.g. 266667L microseconds per frame) to a * string rate (e.g. "3.75" representing 3.75 frames per second). * Returns <achRate>. */ PSTR MicroSecToStringRate(PSTR achRate, DWORD dwMicroSec) { sprintf(achRate, "%.3f", (dwMicroSec == 0L) ? 0.0 : (1e6 / (double) dwMicroSec));
return achRate; }
/*
* update the text of an edit field based on a comarrow up or down change * - write the text in N.NNN format (truncated to an integer) */ LONG FAR PASCAL MilliSecVarArrowEditChange( HWND hwndEdit, UINT uCode, LONG lMin, LONG lMax, UINT uInc ) { TCHAR achTemp[32]; LONG l;
GetWindowText(hwndEdit, achTemp, sizeof(achTemp));
l = atol(achTemp); if(uCode == SB_LINEUP ) {
if(l + (long)uInc <= lMax ) { l += uInc; wsprintf(achTemp, "%ld.000", l ); SetWindowText(hwndEdit, achTemp ); } else { MessageBeep( 0 ); } } else if (uCode == SB_LINEDOWN ) { if( l-(long)uInc >= lMin ) { l -= uInc; wsprintf( achTemp, "%ld.000", l ); SetWindowText( hwndEdit, achTemp ); } else { MessageBeep( 0 ); } } return( l ); }
BOOL MCIGetDeviceNameAndIndex (HWND hwnd, LPINT lpnIndex, LPTSTR lpName) { HWND hwndCB; TCHAR buf[160]; TCHAR *cp;
hwndCB = GetDlgItem( hwnd, IDD_MCI_SOURCE ); *lpnIndex = (int)SendMessage( hwndCB, CB_GETCURSEL, 0, 0L); SendMessage( hwndCB, CB_GETLBTEXT, *lpnIndex, (LONG_PTR)(LPTSTR) buf ); // Point cp to the system name
for (cp = buf + lstrlen(buf); cp > buf; cp--) { if (*cp == ' ' && *(cp-1) == ',') { cp++; break; } } lstrcpy (lpName, cp); return TRUE; }
/*--------------------------------------------------------------+
| TimeMSToHMSString() - change milliseconds into a time string | +--------------------------------------------------------------*/ void FAR PASCAL TimeMSToHMSString (DWORD dwMS, LPTSTR lpTime) { DWORD dwTotalSecs; LONG lHundredths; WORD wSecs; WORD wMins; WORD wHours;
/* convert to number of seconds */ dwTotalSecs = dwMS / 1000; /* keep the remainder part */ lHundredths = (dwMS - (dwTotalSecs * 1000)) / 10; /* break down into other components */ wHours = (WORD)(dwTotalSecs / 3600); // get # Hours
dwTotalSecs -= (wHours * 3600); wMins = (WORD)(dwTotalSecs / 60); // get # Mins
dwTotalSecs -= (wMins * 60); wSecs = (WORD)dwTotalSecs; // what's left is # seconds
/* build the string */ wsprintf((TCHAR far *)lpTime, "%02u:%02u:%02u.%02lu", wHours, wMins, wSecs, lHundredths); }
/*--------------------------------------------------------------+
| TimeHMSStringToMS() - change Time string to milliseconds | | returns dwMilliseconds or -1 if error | +--------------------------------------------------------------*/ LONG NEAR PASCAL TimeHMSStringToMS (LPTSTR lpsz) { TCHAR achTime[12]; // buffer for time string (input)
DWORD dwMSecs; // total MSecs for this thing */
TCHAR *pDelim; // pointer to next delimeter
TCHAR *p; // general pointer
DWORD dwHours = 0; // # of hours
DWORD dwMins = 0; // # of minutes
DWORD dwSecs = 0; // # of seconds
UINT wHundredths = 0; // # hundredths
achTime[sizeof(achTime)-1] = '\0'; _tcsncpy(achTime, lpsz, sizeof (achTime));
if (achTime[0] == '\0' || achTime[sizeof(achTime)-1] != '\0') return -1; // bad TCHAR so error out
/* rip through the whole string and look for illegal TCHARs */ for (p = achTime; *p ; p++){ if (!_istdigit(*p) && *p != '.' && *p != ':') return -1; // bad char so error out
}
/* go find the hundredths portion if it exists */ pDelim = _tcschr(achTime, '.'); if (pDelim && *pDelim){ p = _tcsrchr(achTime, '.'); if (pDelim != p) { return -1; // string has > 1 '.', return error
}
p++; // move up past delim
if (_tcslen(p) > 2) { *(p+2) = '\0'; // knock off all but hundredths
}
wHundredths = _ttoi(p); // get the fractional part
*pDelim = '\0'; // null out this terminator
}
/* try and find seconds */ pDelim = _tcsrchr(achTime, ':'); // get last ':'
if (pDelim) { p = (pDelim+1); } else { // no colon - assume just seconds in string
p = achTime; } dwSecs = _ttoi(p);
if (pDelim) { *pDelim = '\0';
/* go and get the minutes part */ pDelim = _tcsrchr(achTime, ':'); if (pDelim) { p = (pDelim + 1); } else { // no more colons - assume remainder is just minutes
p = achTime; } dwMins = _ttoi(p);
if (pDelim) { *pDelim = '\0';
/* get the hours */ p = achTime; dwHours = _ttoi(p); } }
/* now we've got the hours, minutes, seconds and any */ /* fractional part. Time to build up the total time */
dwSecs += (dwHours * 3600); // add in hours worth of seconds
dwSecs += (dwMins * 60); // add in minutes worth of seconds
dwMSecs = (dwSecs * 1000L); dwMSecs += (wHundredths * 10L);
/* now we've got the total number of milliseconds */ return dwMSecs; }
/*
* MCIDeviceClose * This routine closes the open MCI device. */
void MCIDeviceClose (void) { mciSendString( "close mciframes", NULL, 0, NULL ); }
/*
* MCIDeviceOpen * This routine opens the mci device for use, and sets the * time format to milliseconds. * Return FALSE on error; */
BOOL MCIDeviceOpen (LPTSTR lpDevName) { TCHAR ach[160]; DWORD dwMCIError;
wsprintf( ach, "open %s shareable wait alias mciframes", (LPTSTR) lpDevName); dwMCIError = mciSendString( ach, NULL, 0, NULL ); if( dwMCIError ) { return(FALSE); }
dwMCIError = mciSendString( "set mciframes time format milliseconds", NULL, 0, NULL ); if( dwMCIError ) { MCIDeviceClose(); return(FALSE); } return ( TRUE );
}
/*
* MCIDeviceGetPosition * Stores the current device position in milliseconds in lpdwPos. * Returns TRUE on success, FALSE if error. */ BOOL FAR PASCAL MCIDeviceGetPosition (LPDWORD lpdwPos) { TCHAR ach[80]; DWORD dwMCIError;
dwMCIError = mciSendString( "status mciframes position wait", ach, sizeof(ach), NULL ); if( dwMCIError ) { *lpdwPos = 0L; return FALSE; }
*lpdwPos = _ttol( ach ); return TRUE; }
#ifndef USE_ACM
// --- audio streaming ------------------------------------------------
// the ShowLevel dialog streams data in from the input and
// shows the current volume.
// buffers into which sound data is recorded
#define NUM_LEVEL_BUFFERS 2
// the buffer size is calculated to be about 1/20 sec
#define UPDATES_PER_SEC 20
/*
* we save all our data in one of these, and write a pointer to it * into the dialog DWL_USER field. */
typedef struct _LevelStreamData { LPWAVEHDR alpWave[NUM_LEVEL_BUFFERS]; PCMWAVEFORMAT FAR * pwf; HWAVEIN hwav; int buffersize; } LEVELSTREAMDATA, FAR * PLEVELSTREAMDATA;
//open the wave-device in the given format, queue all the buffers and
//start data streaming. Save the wavein device to the dialog DWL_USER window
//data area so we can close it on dialog dismissal.
BOOL OpenStream(HWND hDlg, PCMWAVEFORMAT FAR * pwf) { PLEVELSTREAMDATA pInfo; int i;
pInfo = (PLEVELSTREAMDATA) GlobalLock(GlobalAlloc(GHND, sizeof(LEVELSTREAMDATA)));
if (pInfo == NULL) { return(FALSE); }
// complete remaining areas of wf
pwf->wf.wFormatTag = WAVE_FORMAT_PCM; pwf->wf.nBlockAlign = pwf->wf.nChannels * pwf->wBitsPerSample / 8; pwf->wf.nAvgBytesPerSec = pwf->wf.nSamplesPerSec * pwf->wf.nBlockAlign;
// save for later use
pInfo->pwf = pwf;
// buffer size a fixed fraction of a second
pInfo->buffersize = pwf->wf.nAvgBytesPerSec/UPDATES_PER_SEC;
pInfo->hwav = NULL;
if (waveInOpen( &pInfo->hwav, WAVE_MAPPER, (LPWAVEFORMATEX)pwf, (DWORD) hDlg, // callback via MM_WIM_ messages to dialogproc
0, CALLBACK_WINDOW)) { SetWindowLong(hDlg, DWL_USER, 0); return(FALSE); }
// store the info structure in the dialog, so that even if we fail
// on this routine we will clean up correctly
SetWindowLong(hDlg, DWL_USER, (long) pInfo);
// set all the wave headers to null (for cleanup if error)
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) { pInfo->alpWave[i] = NULL; }
// alloc, prepare and add all the buffers
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) {
pInfo->alpWave[i] = GlobalLock(GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, sizeof(WAVEHDR) + pInfo->buffersize)); if (pInfo->alpWave[i] == NULL) { return(FALSE); }
pInfo->alpWave[i]->lpData = (LPBYTE) (pInfo->alpWave[i] + 1); pInfo->alpWave[i]->dwBufferLength = pInfo->buffersize; pInfo->alpWave[i]->dwBytesRecorded = 0; pInfo->alpWave[i]->dwUser = 0; pInfo->alpWave[i]->dwFlags = 0; pInfo->alpWave[i]->dwLoops = 0;
if (waveInPrepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) { return(FALSE); }
if (waveInAddBuffer(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) { return(FALSE); } }
waveInStart(pInfo->hwav);
return(TRUE); }
// terminate the data streaming on a wavein device associated with a
// dialog, and clean up the buffers allocated
void CloseStream(HWND hDlg) { PLEVELSTREAMDATA pInfo; int i;
// pick up our info from the dialog
pInfo = (PLEVELSTREAMDATA) GetWindowLong(hDlg, DWL_USER); if ((pInfo == NULL) || (pInfo->hwav == NULL)) { return; }
// stop streaming data
waveInStop(pInfo->hwav);
// release all buffers
waveInReset(pInfo->hwav);
// unlock and free buffers
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) { if (pInfo->alpWave[i]) { waveInUnprepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR)); GlobalFree(GlobalHandle(pInfo->alpWave[i])); pInfo->alpWave[i] = NULL; }
} waveInClose(pInfo->hwav);
GlobalFree(GlobalHandle(pInfo));
SetWindowLong(hDlg, DWL_USER, 0);
}
// we have received a block of data. work out the level(s) and send to
// the appropriate control on the dialog, and then requeue the buffer.
// return FALSE if any error occurs, otherwise TRUE
BOOL StreamData(HWND hDlg, HWAVEIN hwav, LPWAVEHDR pHdr) { PLEVELSTREAMDATA pInfo; int n = 0; int LevelLeft = 0, LevelRight = 0; int i, l;
// pick up our info from the dialog
pInfo = (PLEVELSTREAMDATA) GetWindowLong(hDlg, DWL_USER); if ((pInfo == NULL) || (pInfo->hwav != hwav)) { return FALSE; }
// go through all samples in buffer looking for maximum absolute level
while (n < pInfo->buffersize) {
/*
* volumes go above and below the mean level - we are * interested in the absolute volume * 8 bit samples are in the range 0..255 * 16-bit samples are in the range -32768..+32767 */
// skip the first byte if 16-bit
// and adjust to be in range -127..+128
if (pInfo->pwf->wBitsPerSample == 16) { n++; i = (int) (signed char) pHdr->lpData[n]; } else { i = (int) ((unsigned char) pHdr->lpData[n]) - 128; }
// skip past the byte we've picked up
n++;
// take absolute volume level
if (i < 0) { i = -i; }
// convert to percentage
l = (i*100) / 128;
// compare against current max
if (LevelLeft < l) { LevelLeft = l; }
// if stereo, repeat for right channel
if (pInfo->pwf->wf.nChannels == 2) { // skip the first byte if 16-bit
if (pInfo->pwf->wBitsPerSample == 16) { n++; i = (int) (signed char) pHdr->lpData[n]; } else { i = (int) ((unsigned char) pHdr->lpData[n]) - 128; }
// skip past the byte we've picked up
n++;
// take absolute volume level
if (i < 0) { i = -i; }
// convert to percentage
l = (i*100) / 128;
// compare against current max
if (LevelRight < l) { LevelRight = l; } } }
// put the buffer back on the queue
if (waveInAddBuffer(pInfo->hwav, pHdr, sizeof(WAVEHDR))) { return(FALSE); }
// send new level to dialog control
SendDlgItemMessage(hDlg, IDRL_LEVEL1, WMRL_SETLEVEL, 0, LevelLeft); if (pInfo->pwf->wf.nChannels == 2) { SendDlgItemMessage(hDlg, IDRL_LEVEL2, WMRL_SETLEVEL, 0, LevelRight); }
return(TRUE); }
#endif // ! USE_ACM
// --- dialog procs -----------------------------------------------------
//
// AboutProc: About Dialog Box Procedure
//
LRESULT FAR PASCAL AboutProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_INITDIALOG : return TRUE ;
case WM_COMMAND : switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK : EndDialog(hDlg, TRUE) ; return TRUE ;
case IDCANCEL : EndDialog(hDlg, FALSE) ; return TRUE ; } break ; }
return FALSE ; }
#ifndef USE_ACM
/*
* dialog proc for IDD_RECLVLMONO and IDD_RECLVLSTEREO - show current * volume level */ LRESULT FAR PASCAL ShowLevelProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) {
case WM_INITDIALOG: if (!OpenStream(hDlg, (PCMWAVEFORMAT FAR *) lParam)) { MessageBoxID(IDS_ERR_ACCESS_SOUNDDRIVER, MB_OK|MB_ICONSTOP); EndDialog(hDlg, FALSE); } return(TRUE);
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: case IDCANCEL:
CloseStream(hDlg); EndDialog(hDlg, TRUE); return(TRUE); } break;
case MM_WIM_DATA: if (!StreamData(hDlg, (HWAVEIN)wParam, (LPWAVEHDR)lParam)) { MessageBoxID(IDS_ERR_ACCESS_SOUNDDRIVER, MB_OK|MB_ICONSTOP); CloseStream(hDlg); EndDialog(hDlg, FALSE); } return(TRUE);
} return FALSE; }
//
// AudioFormatProc: Audio Format Setting Dialog Box Procedure
//
LRESULT FAR PASCAL AudioFormatProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { static int nChannels ; static UINT wSample ; static DWORD dwFrequency ;
switch (Message) { case WM_INITDIALOG : nChannels = IDD_ChannelIDs + glpwfex->nChannels ; CheckRadioButton(hDlg, IDD_ChannelMono, IDD_ChannelStereo, nChannels) ; wSample = IDD_SampleIDs + glpwfex->wBitsPerSample / 8 ; CheckRadioButton(hDlg, IDD_Sample8Bit, IDD_Sample16Bit, wSample) ; dwFrequency = IDD_FreqIDs + glpwfex->nSamplesPerSec / 11025 ; CheckRadioButton(hDlg, IDD_Freq11kHz, IDD_Freq44kHz, (UINT)dwFrequency) ; return TRUE ;
case WM_COMMAND : switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDD_SetLevel: { // get the current data into a PCMWAVEFORMAT struct,
// and run the ShowLevel dialog
PCMWAVEFORMAT wf; UINT dlgid;
if (IsDlgButtonChecked(hDlg, IDD_ChannelMono)) { wf.wf.nChannels = 1; dlgid = IDD_RECLVLMONO; } else { wf.wf.nChannels = 2; dlgid = IDD_RECLVLSTEREO; }
if (IsDlgButtonChecked(hDlg, IDD_Sample8Bit)) { wf.wBitsPerSample = 8; } else { wf.wBitsPerSample = 16; }
if (IsDlgButtonChecked(hDlg, IDD_Freq11kHz)) { wf.wf.nSamplesPerSec = 11025 ; } else if (IsDlgButtonChecked(hDlg, IDD_Freq22kHz)) { wf.wf.nSamplesPerSec = 22050 ; } else { wf.wf.nSamplesPerSec = 44100 ; }
DoDialog( hDlg, dlgid, ShowLevelProc, (LPARAM) &wf); break; }
case IDOK : if (IsDlgButtonChecked(hDlg, IDD_ChannelMono)) nChannels = 1 ; else if (IsDlgButtonChecked(hDlg, IDD_ChannelStereo)) nChannels = 2 ; else { MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; }
if (IsDlgButtonChecked(hDlg, IDD_Sample8Bit)) wSample = 8 ; else if (IsDlgButtonChecked(hDlg, IDD_Sample16Bit)) wSample = 16 ; else { MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; }
if (IsDlgButtonChecked(hDlg, IDD_Freq11kHz)) dwFrequency = 11025 ; else if (IsDlgButtonChecked(hDlg, IDD_Freq22kHz)) dwFrequency = 22050 ; else if (IsDlgButtonChecked(hDlg, IDD_Freq44kHz)) dwFrequency = 44100 ; else { MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; }
// All the entries verfied OK -- save them now
glpwfex->nChannels = nChannels ; glpwfex->wBitsPerSample = wSample ; glpwfex->nSamplesPerSec = dwFrequency ; glpwfex->nBlockAlign = glpwfex->nChannels * (glpwfex->wBitsPerSample / 8) ; glpwfex->nAvgBytesPerSec = (long) glpwfex->nSamplesPerSec * glpwfex->nBlockAlign ; glpwfex->cbSize = 0 ; glpwfex->wFormatTag = WAVE_FORMAT_PCM ; EndDialog(hDlg, TRUE) ; return TRUE ;
case IDCANCEL : EndDialog(hDlg, FALSE) ; return TRUE ; } break ; }
return FALSE ; }
#endif // ! USE_ACM
//
// AllocCapFileProc: Capture file Space Allocation Dialog Box Procedure
//
LRESULT FAR PASCAL AllocCapFileProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { static int nFreeMBs = 0 ;
switch (Message) { case WM_INITDIALOG : { int fh ; long lFileSize = 0 ; long lFreeSpaceInKB ; TCHAR achCapFile[_MAX_PATH] ;
// Get current capture file name and measure its size
capFileGetCaptureFile(ghWndCap, achCapFile, sizeof(achCapFile) / sizeof(TCHAR)) ; if ((fh = _open(achCapFile, _O_RDONLY)) != -1) { if ((lFileSize = _lseek(fh, 0L, SEEK_END)) == -1L) { MessageBoxID(IDS_ERR_SIZECAPFILE, #ifdef BIDI
MB_RTL_READING | #endif
MB_OK | MB_ICONEXCLAMATION) ; lFileSize = 0 ; } _close(fh) ; }
// Get free disk space and add current capture file size to that.
// Convert the available space to MBs.
if ((lFreeSpaceInKB = GetFreeDiskSpaceInKB(achCapFile)) != -1L) { lFreeSpaceInKB += lFileSize / 1024 ; nFreeMBs = lFreeSpaceInKB / 1024 ; SetDlgItemInt(hDlg, IDD_SetCapFileFree, nFreeMBs, TRUE) ; } else {
EnableWindow(GetDlgItem(hDlg, IDD_SetCapFileFree), FALSE);
}
gwCapFileSize = (WORD) (lFileSize / ONEMEG);
SetDlgItemInt(hDlg, IDD_SetCapFileSize, gwCapFileSize, TRUE) ; return TRUE ; }
case WM_COMMAND : switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK : { int iCapFileSize ;
iCapFileSize = (int) GetDlgItemInt(hDlg, IDD_SetCapFileSize, NULL, TRUE) ; if (iCapFileSize <= 0 || iCapFileSize > nFreeMBs) { // You are asking for more than we have !! Sorry, ...
SetDlgItemInt(hDlg, IDD_SetCapFileSize, iCapFileSize, TRUE) ; SetFocus(GetDlgItem(hDlg, IDD_SetCapFileSize)) ; MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; } gwCapFileSize = (WORD) iCapFileSize ;
EndDialog(hDlg, TRUE) ; return TRUE ; }
case IDCANCEL : EndDialog(hDlg, FALSE) ; return TRUE ;
case IDD_SetCapFileSize: { long l; BOOL bchanged; TCHAR achBuffer[21];
// check that entered size is a valid number
GetDlgItemText(hDlg, IDD_SetCapFileSize, achBuffer, sizeof(achBuffer)); l = atol(achBuffer); bchanged = FALSE; if (l < 1) { l = 1; bchanged = TRUE; } else if (l > nFreeMBs) { l = nFreeMBs; bchanged = TRUE; } else { // make sure there are no non-digit chars
// atol() will ignore trailing non-digit characters
int c = 0; while (achBuffer[c]) { if (IsCharAlpha(achBuffer[c]) || !IsCharAlphaNumeric(achBuffer[c])) {
// string contains non-digit chars - reset
l = 1; bchanged = TRUE; break; } c++; } } if (bchanged) { wsprintf(achBuffer, "%ld", l); SetDlgItemText(hDlg, IDD_SetCapFileSize, achBuffer); } break; } } break ; }
return FALSE ;
}
#if 0
//
// MakePaletteProc: Palette Details Dialog Box Procedure
//
BOOL CALLBACK MakePaletteProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_INITDIALOG : SetDlgItemInt(hDlg, IDD_MakePalColors, gwPalColors, FALSE) ; SetDlgItemInt(hDlg, IDD_MakePalFrames, gwPalFrames, FALSE) ; return TRUE ;
case WM_COMMAND : switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK : { int iColors ; int iFrames ;
iColors = (int) GetDlgItemInt(hDlg, IDD_MakePalColors, NULL, TRUE) ; if (! (iColors > 0 && iColors <= 236 || iColors == 256)) { // invalid number of palette colors
SetDlgItemInt(hDlg, IDD_MakePalColors, iColors, TRUE) ; SetFocus(GetDlgItem(hDlg, IDD_MakePalColors)) ; MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; } iFrames = (int) GetDlgItemInt(hDlg, IDD_MakePalFrames, NULL, TRUE) ; if (iFrames <= 0 || iFrames > 10000) { // no frame or way t-o-o many frames !!!
SetDlgItemInt(hDlg, IDD_MakePalFrames, iFrames, TRUE) ; SetFocus(GetDlgItem(hDlg, IDD_MakePalFrames)) ; MessageBeep(MB_ICONEXCLAMATION) ; return FALSE ; } gwPalColors = iColors ; gwPalFrames = iFrames ;
EndDialog(hDlg, TRUE) ; return TRUE ; }
case IDCANCEL : EndDialog(hDlg, FALSE) ; return TRUE ; } break ; }
return FALSE ;
}
#endif
#define CAPPAL_TIMER 902
#define CAPTIMER_DELAY 100 // get timers as fast as possible
//
// MakePaletteProc: Palette Details Dialog Box Procedure
//
static int siNumColors = 256;
LRESULT CALLBACK MakePaletteProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static UINT_PTR shTimer; static int siNumFrames; UINT w; TCHAR ach[40]; TCHAR achFormat[40]; int i, k;
switch(msg) { case WM_INITDIALOG: siNumFrames = 0; SetDlgItemInt(hwnd, IDD_MakePalColors, siNumColors, FALSE); SmartWindowPosition (hwnd, ghWndCap); return TRUE; break;
case WM_VSCROLL: /* now handle the scroll */ i = GetDlgItemInt(hwnd, IDD_MakePalColors, NULL, FALSE); ArrowEditChange(GetDlgItem(hwnd, IDD_MakePalColors), GET_WM_VSCROLL_CODE(wParam, lParam), 2, 256); k = GetDlgItemInt(hwnd, IDD_MakePalColors, NULL, FALSE); // Jump over the range 237 to 255
if (k > 236 && k < 256) { if (k > i) w = 256; else w = 236; SetDlgItemInt (hwnd, IDD_MakePalColors, w, TRUE); } break;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: if (siNumFrames) { // The following finishes building the new palette
capPaletteManual (ghWndCap, FALSE, siNumColors); }
if (shTimer){ KillTimer(hwnd, CAPPAL_TIMER); shTimer = 0; } siNumColors = GetDlgItemInt(hwnd, IDD_MakePalColors, (BOOL FAR *)ach, FALSE); siNumColors = max (2, min (256, siNumColors)); EndDialog(hwnd, siNumFrames); break; case IDD_MakePalStart: /* see if we are in START or STOP mode at */ /* this time and handle each one. */ SetFocus (GetDlgItem (hwnd, IDD_MakePalStart)); if (!siNumFrames){ /* this is the first frame, change the CANCEL */ /* button to CLOSE */ LoadString(ghInstApp, IDS_CAPPAL_CLOSE, ach, sizeof(ach)); SetDlgItemText(hwnd, IDCANCEL, ach); } if (!shTimer) {
shTimer = SetTimer(hwnd, CAPPAL_TIMER, CAPTIMER_DELAY, NULL);
if (shTimer == 0) { //!!!error message here.
MessageBeep(0); return TRUE; }
/* button said START, let's set up to */ /* do continuous capture. This involves*/ /* 1 - disabling FRAME button */ /* 2 - turning myself to STOP button */ /* 3 - setting up frame timer */ EnableWindow(GetDlgItem(hwnd, IDD_MakePalSingleFrame), FALSE); LoadString(ghInstApp, IDS_CAPPAL_STOP, ach, sizeof(ach)); SetDlgItemText(hwnd, IDD_MakePalStart, ach); } else { /* button said STOP, turn things around */ /* by: */ /* 1 - killing off timers *
/* 2 - turning back into START button */ /* 3 - re-enabling FRAME button */ // "&Start"
LoadString(ghInstApp, IDS_CAPPAL_START, ach, sizeof(ach)); SetDlgItemText(hwnd, IDD_MakePalStart, ach); EnableWindow(GetDlgItem(hwnd, IDD_MakePalSingleFrame), TRUE); KillTimer(hwnd, CAPPAL_TIMER); shTimer = 0; } return TRUE; break; case IDD_MakePalSingleFrame: if (!siNumFrames){ /* this is the first frame, change the CANCEL */ /* button to CLOSE */ LoadString(ghInstApp, IDS_CAPPAL_CLOSE, ach, sizeof(ach)); SetDlgItemText(hwnd, IDCANCEL, ach); siNumColors = GetDlgItemInt(hwnd, IDD_MakePalColors, (BOOL FAR *)ach, FALSE); siNumColors = max (2, min (256, siNumColors)); } // Get the palette for a single frame
capPaletteManual (ghWndCap, TRUE, siNumColors);
siNumFrames++; LoadString(ghInstApp, IDS_CAPPAL_STATUS, achFormat, sizeof(achFormat)); wsprintf(ach, achFormat, siNumFrames); SetDlgItemText(hwnd, IDD_MakePalNumFrames, ach); return TRUE; break;
case IDD_MakePalColors: if (HIWORD (lParam) == EN_KILLFOCUS) { w = GetDlgItemInt (hwnd, (UINT) wParam, NULL, FALSE); if ( w < 2) { MessageBeep (0); SetDlgItemInt (hwnd, (UINT) wParam, 2, FALSE); } else if (w > 256) { MessageBeep (0); SetDlgItemInt (hwnd, (UINT) wParam, 256, FALSE); } } return TRUE; break;
default: return FALSE; } // switch(wParam) on WM_COMMAND
break; case WM_TIMER: if (wParam == CAPPAL_TIMER){ SendMessage(hwnd, WM_COMMAND, IDD_MakePalSingleFrame, 0L); } break; default: return FALSE; } // switch(msg)
return FALSE; }
//
// CapSetUpProc: Capture SetUp Details Dialog Box Procedure
//
LRESULT FAR PASCAL CapSetUpProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { static TCHAR achBuffer[21] ; UINT fValue;
switch (Message) { case WM_INITDIALOG : {
// Convert from MicroSecPerFrame to FPS -- that's easier !!
MicroSecToStringRate(achBuffer, gCapParms.dwRequestMicroSecPerFrame); SetDlgItemText(hDlg, IDD_FrameRateData, achBuffer);
// If time limit isn't enabled, disable the time data part
CheckDlgButton(hDlg, IDD_TimeLimitFlag, (fValue = gCapParms.fLimitEnabled)) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsText), fValue) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsData), fValue) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsArrow), fValue);
SetDlgItemInt(hDlg, IDD_SecondsData, gCapParms.wTimeLimit, FALSE) ;
// disable audio buttons if no audio hardware
{ CAPSTATUS cs;
capGetStatus(ghWndCap, &cs, sizeof(cs)); EnableWindow(GetDlgItem(hDlg, IDD_CapAudioFlag), cs.fAudioHardware); EnableWindow(GetDlgItem(hDlg, IDD_AudioConfig), cs.fAudioHardware);
CheckDlgButton(hDlg, IDD_CapAudioFlag, gCapParms.fCaptureAudio); }
/*
* Capture To Memory means allocate as many memory buffers * as possible. * Capture To Disk means only allocate enough buffers * to get us through disk seeks and thermal recalibrations. */
// The use of fUsingDOSMemory is now just a means of keeping
// track of whether using lots of buffers. We never actually
// allocate exclusively from memory under 1Meg.
CheckRadioButton(hDlg, IDD_CaptureToDisk, IDD_CaptureToMemory, (gCapParms.fUsingDOSMemory)? IDD_CaptureToDisk : IDD_CaptureToMemory);
// Find out how many MCI devices can source video
if (CountMCIDevices(MCI_DEVTYPE_VCR) + CountMCIDevices(MCI_DEVTYPE_VIDEODISC) == 0) { // if no VCRs or Videodiscs, disable the controls
EnableWindow(GetDlgItem(hDlg, IDD_MCIControlFlag), FALSE); EnableWindow(GetDlgItem(hDlg, IDD_MCISetup), FALSE); } else { EnableWindow(GetDlgItem(hDlg, IDD_MCIControlFlag), TRUE);
// if MCI Control is selected, enable the setup button
CheckDlgButton(hDlg, IDD_MCIControlFlag, gCapParms.fMCIControl); EnableWindow(GetDlgItem(hDlg, IDD_MCISetup), gCapParms.fMCIControl); }
// place the dialog to avoid covering the capture window
SmartWindowPosition(hDlg, ghWndCap); return TRUE ; }
case WM_COMMAND : switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDD_TimeLimitFlag : // If this flag changes, en/dis-able time limit data part
fValue = IsDlgButtonChecked(hDlg, IDD_TimeLimitFlag) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsText), fValue) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsData), fValue) ; EnableWindow(GetDlgItem(hDlg, IDD_SecondsArrow), fValue); return TRUE ;
case IDD_MCIControlFlag : // If this flag changes, en/dis-able MCI Setup button
fValue = IsDlgButtonChecked(hDlg, IDD_MCIControlFlag) ; EnableWindow(GetDlgItem(hDlg, IDD_MCISetup), fValue) ; return TRUE ;
case IDD_CapAudioFlag: fValue = IsDlgButtonChecked(hDlg, IDD_CapAudioFlag) ; EnableWindow(GetDlgItem(hDlg, IDD_AudioConfig), fValue) ; return TRUE ;
case IDD_FrameRateData: // get the requested frame rate and check it against bounds
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS) { long l, new_l;
GetDlgItemText(hDlg, IDD_FrameRateData, achBuffer, sizeof(achBuffer)); new_l = l = StringRateToMicroSec(achBuffer);
// note that the MAX rate is SMALL! hence <max, >min
if (l == 0) { new_l = DEF_CAPTURE_RATE; } else if (l < MAX_CAPTURE_RATE) { new_l = MAX_CAPTURE_RATE; } else if (l > MIN_CAPTURE_RATE) { new_l = MIN_CAPTURE_RATE; } if (l != new_l) { MicroSecToStringRate(achBuffer, new_l); SetDlgItemText(hDlg, IDD_FrameRateData, achBuffer); } } break;
case IDD_SecondsData: { long l, new_l;
// get requested time limit and check validity
GetDlgItemText(hDlg, IDD_SecondsData, achBuffer, sizeof(achBuffer)); new_l = l = atol(achBuffer); if (l < 1) { new_l = 1; } else if (l > 9999) { new_l = 9999; } else { // make sure there are no non-digit chars
// atol() will ignore trailing non-digit characters
int c = 0; while (achBuffer[c]) { if (IsCharAlpha(achBuffer[c]) || !IsCharAlphaNumeric(achBuffer[c])) {
// string contains non-digit chars - reset
new_l = 1; break; } c++; } } if (new_l != l) { wsprintf(achBuffer, "%ld", new_l); SetDlgItemText(hDlg, IDD_SecondsData, achBuffer); // select the changed text so that if you delete the
// '1' and then insert '10' you get 10 not 110
SendDlgItemMessage(hDlg, IDD_SecondsData, EM_SETSEL, 0, -1);
} break; }
// show audio format setup dialog
case IDD_AudioConfig:
// rather than duplicate lots of code from the
// main vidcap winproc, lets just ask it to show the dlg...
SendMessage(ghWndMain, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_O_AUDIOFORMAT, NULL, 0));
break;
// show MCI step control dialog
case IDD_MCISetup: DoDialog(hDlg, IDD_MCISETUP, MCISetupProc, 0); break;
// show video format setup dialog
case IDD_VideoConfig: // rather than duplicate lots of code from the
// main vidcap winproc, lets just ask it to show the dlg...
SendMessage(ghWndMain, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_O_VIDEOFORMAT, NULL, 0)); break;
// show the compressor selector dialog
case IDD_CompConfig: capDlgVideoCompression(ghWndCap); break;
case IDOK : {
gCapParms.fCaptureAudio = IsDlgButtonChecked(hDlg, IDD_CapAudioFlag) ; gCapParms.fMCIControl = IsDlgButtonChecked(hDlg, IDD_MCIControlFlag); gCapParms.fLimitEnabled = IsDlgButtonChecked(hDlg, IDD_TimeLimitFlag) ;
GetDlgItemText(hDlg, IDD_FrameRateData, achBuffer, sizeof(achBuffer)); gCapParms.dwRequestMicroSecPerFrame = StringRateToMicroSec(achBuffer); if (gCapParms.dwRequestMicroSecPerFrame == 0) { gCapParms.dwRequestMicroSecPerFrame = DEF_CAPTURE_RATE; }
GetDlgItemText(hDlg, IDD_SecondsData, achBuffer, sizeof(achBuffer)); if (gCapParms.fLimitEnabled) { gCapParms.wTimeLimit = (UINT) atol(achBuffer); }
// fUsingDOSMemory is archaic and is now just a flag reflecting
// the "CaptureToDisk" selection.
//
gCapParms.fUsingDOSMemory = IsDlgButtonChecked(hDlg, IDD_CaptureToDisk);
EndDialog(hDlg, TRUE) ; return TRUE ; }
case IDCANCEL : EndDialog(hDlg, FALSE) ; return TRUE ; } break ;
case WM_VSCROLL: // message from one of the arrow spinbuttons
{ UINT id;
id = GetDlgCtrlID(GET_WM_COMMAND_HWND(wParam, lParam)); if (id == IDD_FrameRateArrow) { // format n.nnn
MilliSecVarArrowEditChange( GetDlgItem(hDlg, IDD_FrameRateData), GET_WM_VSCROLL_CODE(wParam, lParam), 1, 100, 1); } else { // simple integer format
ArrowEditChange( GetDlgItem(hDlg, IDD_SecondsData), GET_WM_VSCROLL_CODE(wParam, lParam), 1, 30000); } break; }
}
return FALSE ; }
/*
* preferences dialog - sets global options about background colour, * presence of toolbar, status bar etc */ LRESULT FAR PASCAL PrefsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { DWORD indexsz;
switch(message) {
case WM_INITDIALOG: CheckDlgButton(hDlg, IDD_PrefsStatus, gbStatusBar); CheckDlgButton(hDlg, IDD_PrefsToolbar, gbToolBar); CheckDlgButton(hDlg, IDD_PrefsCentre, gbCentre); CheckDlgButton(hDlg, IDD_PrefsSizeFrame, gbAutoSizeFrame); CheckRadioButton(hDlg, IDD_PrefsDefBackground, IDD_PrefsBlack, gBackColour);
CheckRadioButton(hDlg, IDD_PrefsSmallIndex, IDD_PrefsBigIndex, (gCapParms.dwIndexSize == CAP_LARGE_INDEX) ? IDD_PrefsBigIndex : IDD_PrefsSmallIndex);
CheckRadioButton(hDlg, IDD_PrefsMasterAudio, IDD_PrefsMasterNone, gCapParms.AVStreamMaster + IDD_PrefsMasterAudio);
return(TRUE);
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: EndDialog(hDlg, FALSE); return(TRUE);
case IDOK: gbStatusBar = IsDlgButtonChecked(hDlg, IDD_PrefsStatus); gbToolBar = IsDlgButtonChecked(hDlg, IDD_PrefsToolbar); gbCentre = IsDlgButtonChecked(hDlg, IDD_PrefsCentre); gbAutoSizeFrame = IsDlgButtonChecked(hDlg, IDD_PrefsSizeFrame);
if (IsDlgButtonChecked(hDlg, IDD_PrefsDefBackground)) { gBackColour = IDD_PrefsDefBackground; } else if (IsDlgButtonChecked(hDlg, IDD_PrefsLtGrey)) { gBackColour = IDD_PrefsLtGrey; } else if (IsDlgButtonChecked(hDlg, IDD_PrefsDkGrey)) { gBackColour = IDD_PrefsDkGrey; } else { gBackColour = IDD_PrefsBlack; }
if (IsDlgButtonChecked(hDlg, IDD_PrefsSmallIndex)) { indexsz = CAP_SMALL_INDEX;
} else { indexsz = CAP_LARGE_INDEX; } if (indexsz != gCapParms.dwIndexSize) { gCapParms.dwIndexSize = indexsz; }
if (IsDlgButtonChecked(hDlg, IDD_PrefsMasterAudio)) { gCapParms.AVStreamMaster = AVSTREAMMASTER_AUDIO; } else { gCapParms.AVStreamMaster = AVSTREAMMASTER_NONE; }
EndDialog(hDlg, TRUE); return(TRUE); } break; } return FALSE; }
LRESULT FAR PASCAL NoHardwareDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HBRUSH hbr;
switch(message) { case WM_INITDIALOG: // lParam contains the argument to DialogBoxParam which is the
// reason text
SetDlgItemText(hDlg, IDD_FailReason, (LPTSTR) lParam);
hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); return TRUE;
case WM_DESTROY: DeleteObject(hbr);
#ifdef _WIN32
case WM_CTLCOLORSTATIC: #else
case WM_CTLCOLOR: #endif
if (GET_WM_CTLCOLOR_HWND(wParam, lParam, message) == GetDlgItem(hDlg, IDD_FailReason)) {
HDC hdc;
hdc = GET_WM_CTLCOLOR_HDC(wParam, lParam, message);
SetTextColor(hdc, RGB(0xff, 0, 0)); SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
// in order to ensure that the text colour we have chosen for
// this control is used, we need to actually return a brush.
// for win31, we also need to align the brush
#ifndef _WIN32
{ POINT pt;
pt.x = 0; pt.y = 0; ClientToScreen(hDlg, &pt); UnrealizeObject(hbr); SetBrushOrg(hdc, pt.x, pt.y); } #endif
return((INT_PTR) hbr);
} break;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: EndDialog(hDlg, TRUE); return(TRUE); case IDCANCEL: EndDialog(hDlg, FALSE); return(TRUE); } break; }
return(FALSE); }
//capture selected single frames
LRESULT FAR PASCAL CapFramesProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) { TCHAR ach[MAX_PATH*2]; TCHAR achName[MAX_PATH];
static BOOL bFirst; static int iFrames;
switch(Message) { case WM_INITDIALOG:
// write out the prompt message including the capture file name
capFileGetCaptureFile(ghWndCap, achName, sizeof(achName)); wsprintf(ach, tmpString(IDS_PROMPT_CAPFRAMES), achName); SetDlgItemText(hDlg, IDD_CapMessage, ach);
bFirst = TRUE;
//move dialog so it doesn't obscure the capture window
SmartWindowPosition(hDlg, ghWndCap);
return(TRUE);
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case IDCANCEL: if (!bFirst) { capCaptureSingleFrameClose(ghWndCap); EndDialog(hDlg, TRUE); } else { EndDialog(hDlg, FALSE); } return(TRUE);
case IDOK: if (bFirst) { bFirst = FALSE; iFrames = 0; capCaptureSingleFrameOpen(ghWndCap);
SetDlgItemText(hDlg, IDCANCEL, tmpString(IDS_CAP_CLOSE));
} capCaptureSingleFrame(ghWndCap); iFrames++;
wsprintf(ach, tmpString(IDS_STATUS_NUMFRAMES), iFrames); SetDlgItemText(hDlg, IDD_CapNumFrames, ach); return(TRUE);
} break; } return(FALSE); }
// enumerate all the MCI devices of a particular type and add them and
// their descriptions to a combo box list.
//
void AddMCIDeviceNames(UINT wDeviceType, HWND hwndCB) { int nIndex; MCI_OPEN_PARMS mciOp; MCI_INFO_PARMS mciIp; MCI_SYSINFO_PARMS mciSIP; MCI_GENERIC_PARMS mciGp; TCHAR buf[MAXPNAMELEN + 128]; // Contains eg. Name\t\tVideodisc1
TCHAR buf2 [64]; int maxdevs; DWORD dwRet;
// To get the user readable names of the devices, we
// must open all appropriate devices, and then get info.
// MCI Open structure
mciOp.dwCallback = 0; mciOp.lpstrElementName = NULL; mciOp.lpstrAlias = NULL;
// MCI Info structure
mciIp.dwCallback = 0; mciIp.lpstrReturn = (LPTSTR) buf; mciIp.dwRetSize = MAXPNAMELEN - 1;
// MCI SysInfo structure
mciSIP.dwCallback = 0; mciSIP.lpstrReturn = (LPTSTR) buf2; mciSIP.dwRetSize = sizeof (buf2); mciSIP.wDeviceType = wDeviceType;
// MCI Generic structure
mciGp.dwCallback = 0;
// Load the combobox with the product info name, followed by
// a comma, then a space, and then the mci device name. This allows a
// single alphabetized list to be kept.
// eg.
// Pioneer Laserdisc, videodisc1
maxdevs = CountMCIDevices((UINT)mciSIP.wDeviceType); for (nIndex = 0; nIndex < maxdevs; nIndex++) {
// Get the system name eg. Videodisc1
mciSIP.dwNumber = nIndex + 1; dwRet = mciSendCommand (0, MCI_SYSINFO, MCI_SYSINFO_NAME, (DWORD_PTR) (LPVOID) &mciSIP);
mciOp.lpstrDeviceType = (LPTSTR)LongToPtr(MAKELONG (wDeviceType, nIndex));
if (!(dwRet = mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE, (DWORD_PTR) (LPVOID) &mciOp))) { if (!(dwRet = mciSendCommand (mciOp.wDeviceID, MCI_INFO, MCI_WAIT | MCI_INFO_PRODUCT, (DWORD_PTR) (LPVOID) &mciIp))) { lstrcat (buf, ", "); // append the delimiter
lstrcat (buf, buf2); // append the system name
// Whew, finally put it in the listbox
SendMessage( hwndCB, CB_ADDSTRING, 0, (LONG_PTR)(LPTSTR) buf); } //endif got INFO
// Close it now
mciSendCommand (mciOp.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD_PTR) (LPVOID) &mciGp); } // endif OPEN
} // endif for all devices of this type
}
//
// dialog proc to select MCI device and parameters, including start,
// stop times.
LRESULT FAR PASCAL MCISetupProc(HWND hwnd, unsigned msg, WPARAM wParam, LPARAM lParam) { HWND hwndCB; DWORD dw; TCHAR buf[MAXPNAMELEN]; BOOL f; int j; static int nLastCBIndex = 0; static DWORD tdwMCIStartTime; static DWORD tdwMCIStopTime;
switch (msg) { case WM_INITDIALOG:
CheckRadioButton(hwnd, IDD_MCI_PLAY, IDD_MCI_STEP, gCapParms.fStepMCIDevice ? IDD_MCI_STEP : IDD_MCI_PLAY );
// enable averaging options only in step mode
EnableWindow (GetDlgItem (hwnd, IDD_MCI_AVERAGE_2X), gCapParms.fStepMCIDevice); EnableWindow (GetDlgItem (hwnd, IDD_MCI_AVERAGE_FR), gCapParms.fStepMCIDevice); SetDlgItemInt(hwnd, IDD_MCI_AVERAGE_FR, gCapParms.wStepCaptureAverageFrames, FALSE); CheckDlgButton (hwnd, IDD_MCI_AVERAGE_2X, gCapParms.fStepCaptureAt2x);
// save current dialog time settings
tdwMCIStartTime = gCapParms.dwMCIStartTime; tdwMCIStopTime = gCapParms.dwMCIStopTime;
TimeMSToHMSString (gCapParms.dwMCIStartTime, buf); SetDlgItemText (hwnd, IDD_MCI_STARTTIME, buf); TimeMSToHMSString (gCapParms.dwMCIStopTime, buf); SetDlgItemText (hwnd, IDD_MCI_STOPTIME, buf);
// fill combo box with list of MCI devices
hwndCB = GetDlgItem( hwnd, IDD_MCI_SOURCE ); AddMCIDeviceNames(MCI_DEVTYPE_VIDEODISC, hwndCB); AddMCIDeviceNames(MCI_DEVTYPE_VCR, hwndCB);
// set the selection to whatever he chose last time through this dlg
// default is the first entry.
SendMessage( hwndCB, CB_SETCURSEL, nLastCBIndex, 0L); break;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: // i think the point of this is to ensure that
// the KILLFOCUS processing for the edit boxes has been done
// and thus the temp times are the same as the dialog text
SetFocus(GET_WM_COMMAND_HWND(wParam, lParam));
MCIGetDeviceNameAndIndex (hwnd, &nLastCBIndex, gachMCIDeviceName); capSetMCIDeviceName(ghWndCap, gachMCIDeviceName) ; gCapParms.fStepMCIDevice = IsDlgButtonChecked (hwnd, IDD_MCI_STEP);
// pick up the temp times - these were set on KILLFOCUS msgs
// (when we did validation and string->dword conversion
gCapParms.dwMCIStartTime = tdwMCIStartTime; gCapParms.dwMCIStopTime = tdwMCIStopTime;
gCapParms.fStepCaptureAt2x = IsDlgButtonChecked (hwnd, IDD_MCI_AVERAGE_2X); gCapParms.wStepCaptureAverageFrames = GetDlgItemInt (hwnd, IDD_MCI_AVERAGE_FR, NULL, FALSE);
EndDialog(hwnd, TRUE); break; case IDCANCEL: EndDialog(hwnd, 0); break;
case IDD_MCI_STEP: case IDD_MCI_PLAY: //averaging only enabled in play mode
f = IsDlgButtonChecked (hwnd, IDD_MCI_STEP); EnableWindow (GetDlgItem (hwnd, IDD_MCI_AVERAGE_2X), f); EnableWindow (GetDlgItem (hwnd, IDD_MCI_AVERAGE_FR), f); break;
case IDD_MCI_AVERAGE_FR: // validate the count of frames to average 1..100
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS) { j = GetDlgItemInt(hwnd, GET_WM_COMMAND_ID(wParam, lParam), NULL, FALSE); // Limit frames to average between 1 and 100
if (j < 1 || j > 100) { SetDlgItemInt (hwnd, GET_WM_COMMAND_ID(wParam, lParam), 1, FALSE); } } break;
case IDD_MCI_STARTSET: case IDD_MCI_STOPSET: // set the start or stop time to be the time
// on the device right now.
// MCI devices could yield and cause us to re-enter - the
// simplest answer seems to be to disable the dialog
EnableWindow(hwnd, FALSE);
MCIGetDeviceNameAndIndex (hwnd, &nLastCBIndex, buf);
if (MCIDeviceOpen (buf)) { if (GET_WM_COMMAND_ID(wParam, lParam) == IDD_MCI_STARTSET) { if (MCIDeviceGetPosition (&tdwMCIStartTime)) { TimeMSToHMSString (tdwMCIStartTime, buf); SetDlgItemText (hwnd, IDD_MCI_STARTTIME, buf); } else { MessageBoxID(IDS_MCI_CONTROL_ERROR, MB_OK|MB_ICONEXCLAMATION); } } else { if (MCIDeviceGetPosition (&tdwMCIStopTime)) { TimeMSToHMSString (tdwMCIStopTime, buf); SetDlgItemText (hwnd, IDD_MCI_STOPTIME, buf); } else { MessageBoxID(IDS_MCI_CONTROL_ERROR, MB_OK|MB_ICONEXCLAMATION); } } MCIDeviceClose ();
} else { // cant open device
MessageBoxID(IDS_MCI_CONTROL_ERROR, MB_OK|MB_ICONEXCLAMATION); } EnableWindow(hwnd, TRUE); break;
case IDD_MCI_STARTTIME: case IDD_MCI_STOPTIME: if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS) { GetDlgItemText (hwnd, GET_WM_COMMAND_ID(wParam, lParam), buf, sizeof (buf)); if ((dw = TimeHMSStringToMS (buf)) == -1) { // Error in string, reset
MessageBeep (0); if (GET_WM_COMMAND_ID(wParam, lParam) == IDD_MCI_STARTTIME) dw = tdwMCIStartTime; else dw = tdwMCIStopTime; } if (GET_WM_COMMAND_ID(wParam, lParam) == IDD_MCI_STARTTIME) { tdwMCIStartTime = dw; TimeMSToHMSString (tdwMCIStartTime, buf); SetDlgItemText (hwnd, IDD_MCI_STARTTIME, buf); } else { tdwMCIStopTime = dw; TimeMSToHMSString (tdwMCIStopTime, buf); SetDlgItemText (hwnd, IDD_MCI_STOPTIME, buf); } } break; } break;
} return FALSE; }
|