1617 lines
63 KiB
C++
1617 lines
63 KiB
C++
// 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) Microsoft Corporation. All rights reserved.
|
|
|
|
//------------------------------------------------------------------------------
|
|
// File: DVApp.cpp
|
|
//
|
|
// Desc: DirectShow sample code - DV control/capture example.
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "CDVGraph.h"
|
|
|
|
#include <commdlg.h>
|
|
#include <commctrl.h>
|
|
#include <dbt.h>
|
|
#include "resource.h"
|
|
|
|
|
|
|
|
// ------------ constants-----------------
|
|
#define DV_CAPLIMIT_NONE 10L
|
|
#define DV_CAPLIMIT_TIME 11L
|
|
#define DV_CAPLIMIT_SIZE 12L
|
|
|
|
#define DV_BYTESPERMSEC 352 //DV captures at 3600K per second (3600 / 1024 == ~3.52)
|
|
#define DV_TIMERFREQ 55 //milliseconds between timer ticks
|
|
#define DV_BYTES_IN_MEG 1048576L //(1024 * 1024)
|
|
|
|
// ----------macros-----------------------
|
|
#define MBOX(s) MessageBox(g_hwndApp, s, APPNAME, MB_OK);
|
|
|
|
// ----------function prototypes----------
|
|
BOOL FInitMain(int nCmdShow);
|
|
BOOL DV_InitControls(HWND hwnd, HINSTANCE hInst);
|
|
int NMsgLoop(void);
|
|
|
|
HRESULT DV_AppSetup(void);
|
|
HRESULT SetPreviewWindow(void);
|
|
|
|
// UI help functions
|
|
void Mark_ToolBar_Button(BOOL bEnableRecord, BOOL bEnableOthers);
|
|
void Mark_GraphMode_Menu(HWND hwnd, int idmVal);
|
|
void GetSelectedGraphMode( WPARAM wParam, GRAPH_TYPE* pGraphType);
|
|
|
|
// Message Processing Functions
|
|
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
|
void CALLBACK DV_TransportCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
|
void CALLBACK DV_GraphModeCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
|
|
BOOL CALLBACK DV_CapSizeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
void CALLBACK DV_DroppedFrameProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
|
|
void CALLBACK DV_TimecodeTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
|
|
void CALLBACK DV_StopRecProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
|
|
BOOL CALLBACK DV_AboutDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
void DV_DisplayTimecode();
|
|
BOOL DV_SeekATN(void);
|
|
BOOL DV_UpdateTapeInfo(void);
|
|
BOOL DV_RefreshMode(void);
|
|
|
|
// ------------global data----------------
|
|
|
|
// Handles to the windows
|
|
HINSTANCE g_hinst;
|
|
HWND g_hwndApp = NULL;
|
|
HWND g_hwndTBar = NULL;
|
|
HWND g_hwndStatus = NULL;
|
|
HMENU g_hmenu = 0;
|
|
HWND g_hwndTCCheck = NULL;//checkbox
|
|
|
|
// metrics of the windows
|
|
int g_iAppHeight = DEFAULT_VIDEO_HEIGHT + HEIGHT_EDGE;
|
|
int g_iAppWidth = DEFAULT_VIDEO_WIDTH + WIDTH_EDGE;
|
|
int g_iVWHeight = DEFAULT_VIDEO_HEIGHT;
|
|
int g_iVWWidth = DEFAULT_VIDEO_WIDTH;
|
|
DWORD g_statusHeight = 0;
|
|
|
|
// device notification globals
|
|
PVOID g_hDevNotify = NULL;
|
|
BOOL g_bDeviceFound = FALSE;
|
|
|
|
// capture variables
|
|
DWORD g_dwCaptureLimit = DV_CAPLIMIT_NONE; //track whether we are using time, disk, or no based capture limits
|
|
DWORD g_dwDiskSpace = 120; //roughly the same
|
|
DWORD g_dwTimeLimit = 30; //default to 30 seconds of capture
|
|
|
|
// graph related variables
|
|
CDVGraph* g_pGraph = NULL;
|
|
GRAPH_TYPE g_iGraphType = GRAPH_PREVIEW; //need to track the current graph
|
|
|
|
// file names
|
|
TCHAR g_InputFileName[_MAX_PATH] = {DEFAULT_CAP_FILE_NAME};
|
|
TCHAR g_OutputFileName[_MAX_PATH] = {DEFAULT_CAP_FILE_NAME};
|
|
TCHAR g_FilterGraphFileName[_MAX_PATH] = {DEFAULT_FG_FILE_NAME};
|
|
|
|
DWORD g_CapStartTime = 0;
|
|
BOOL g_bUseAtnTimer = FALSE; //track if we want to constantly update the timer
|
|
BOOL g_bHalfFrameRate = FALSE;
|
|
|
|
|
|
|
|
// ------------inline functions-------------------
|
|
// put the VCR Mode
|
|
inline HRESULT DV_PutVcrMode(long Mode)
|
|
{
|
|
if(!g_pGraph->m_pIAMExtTransport)
|
|
return S_FALSE;
|
|
|
|
return g_pGraph->m_pIAMExtTransport->put_Mode(Mode);
|
|
}
|
|
|
|
// update the status windows with appropriate text
|
|
inline LRESULT DV_StatusText(LPCTSTR statusText, UINT nPart)
|
|
{
|
|
return SendMessage(g_hwndStatus, SB_SETTEXT, (WPARAM) 0 | nPart, (LPARAM)statusText);
|
|
}
|
|
|
|
//divide the status bar into thirds, and give the middle frame an extra 100 pixels.
|
|
inline LRESULT DV_StatusParts(UINT width)
|
|
{
|
|
int rg[3];
|
|
rg[0] = (width / 3) - 50;
|
|
rg[1] = ((rg[0]+50) * 2) + 50;
|
|
rg[2] = -1;
|
|
|
|
return SendMessage(g_hwndStatus, SB_SETPARTS, 3, (LPARAM)(LPINT) rg);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: WinMain
|
|
Purpose: Program entry point
|
|
Arguments: Usual
|
|
Returns: Usual
|
|
Notes: Sets up window capabilities, initializes &
|
|
creates the required DirectShow interface & filters.
|
|
------------------------------------------------------------------------*/
|
|
int WINAPI WinMain( HINSTANCE hinst, // instance handle
|
|
HINSTANCE hinstPrev, // always NULL
|
|
LPSTR pszCmd, // pointer to ANSI command line arguments
|
|
int nCmdShow) // initial app window state
|
|
{
|
|
ASSERT(!hinstPrev);
|
|
g_hinst = hinst;
|
|
if (!FInitMain(nCmdShow))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
// Register for device add/remove notifications.
|
|
DEV_BROADCAST_DEVICEINTERFACE filterData;
|
|
ZeroMemory(&filterData, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
|
|
filterData.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
|
filterData.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
|
filterData.dbcc_classguid = AM_KSCATEGORY_CAPTURE;
|
|
g_hDevNotify = RegisterDeviceNotification(g_hwndApp, &filterData, DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
ASSERT(g_hDevNotify != NULL);
|
|
|
|
// dvapp setup
|
|
DV_AppSetup();
|
|
|
|
return NMsgLoop();
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
Routine: FInitMain
|
|
Purpose: Initialize the main application window.
|
|
Arguments:int initial app window state
|
|
Returns: Return TRUE if successful.
|
|
------------------------------------------------------------------------*/
|
|
BOOL FInitMain( int nCmdShow)
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
INITCOMMONCONTROLSEX icc;
|
|
// register common control classes
|
|
icc.dwSize = sizeof(icc);
|
|
icc.dwICC = ICC_BAR_CLASSES;
|
|
InitCommonControlsEx(&icc);
|
|
|
|
// register the window class
|
|
ZeroMemory(&wc, sizeof(wc));
|
|
wc.cbSize = sizeof(wc);
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = MainWndProc;
|
|
wc.cbClsExtra = 0 ;
|
|
wc.cbWndExtra = 0 ;
|
|
wc.hInstance = g_hinst;
|
|
wc.hIcon = LoadIcon (g_hinst, TEXT("DVICON")) ;
|
|
wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
|
|
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
|
|
wc.lpszMenuName = NULL ;
|
|
wc.lpszClassName = APPNAME ;
|
|
wc.hIconSm = LoadIcon(g_hinst, TEXT("DVICON"));
|
|
if (!RegisterClassEx(&wc))
|
|
{
|
|
MessageBox(NULL, TEXT("cannot register the window class"), TEXT("Error"), 0);
|
|
return FALSE;
|
|
}
|
|
|
|
g_hmenu = LoadMenu(g_hinst, MAKEINTRESOURCE(IDR_MENU));
|
|
|
|
// create the main application window
|
|
g_hwndApp = CreateWindowEx(
|
|
0,
|
|
APPNAME, // window class name
|
|
DV_APPTITLE, // window caption
|
|
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // window style
|
|
CW_USEDEFAULT, // initial x position
|
|
CW_USEDEFAULT, // initial y position
|
|
g_iAppWidth, // initial x size
|
|
g_iAppHeight, // initial y size
|
|
NULL, // parent window handle
|
|
g_hmenu, // window menu handle
|
|
g_hinst, // program instance handle
|
|
0) ; // creation parameters
|
|
|
|
if (!g_hwndApp)
|
|
{
|
|
MBOX(TEXT("Create main window failed"));
|
|
return FALSE;
|
|
}
|
|
|
|
// show the window
|
|
ShowWindow(g_hwndApp, nCmdShow);
|
|
UpdateWindow(g_hwndApp);
|
|
SetWindowText(g_hwndApp, TEXT("Initializing..."));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
Routine: NMsgLoop
|
|
Purpose: Execute the program message loop.
|
|
Arguments:None
|
|
Returns: Return the wParam field of the final WM_QUIT message.
|
|
------------------------------------------------------------------------*/
|
|
int NMsgLoop(void)
|
|
{
|
|
MSG msg;
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return ((int) msg.wParam);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
Routine: MainWndProc
|
|
Purpose: Window procedure for the main application window.
|
|
Arguments:Usual
|
|
Returns: Usual
|
|
------------------------------------------------------------------------*/
|
|
LRESULT CALLBACK MainWndProc(
|
|
HWND hwnd,
|
|
UINT msg,
|
|
WPARAM wparam,
|
|
LPARAM lparam)
|
|
{
|
|
HRESULT hr;
|
|
switch (msg)
|
|
{
|
|
case WM_CREATE:
|
|
if (!DV_InitControls(hwnd, (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HINSTANCE)))
|
|
{
|
|
MBOX(TEXT("DV_InitControls failed to create one of the control windows"));
|
|
}
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
{
|
|
RECT rcAppWin, rcClient, rcTB;
|
|
//re-size the App window
|
|
int cxBorder = GetSystemMetrics(SM_CXBORDER);
|
|
int cyBorder = GetSystemMetrics(SM_CYBORDER);
|
|
GetWindowRect(g_hwndApp, &rcAppWin);
|
|
GetWindowRect(g_hwndTBar, &rcTB);
|
|
MoveWindow(g_hwndApp, rcAppWin.left, rcAppWin.top, g_iAppWidth, g_iAppHeight, TRUE);
|
|
|
|
// Tell the toolbar to resize itself to fill the top of the window.
|
|
SendMessage(g_hwndTBar, TB_AUTOSIZE, 0L, 0L);
|
|
|
|
//handle the status bar height
|
|
GetClientRect(g_hwndApp, &rcClient);
|
|
cxBorder = GetSystemMetrics(SM_CXBORDER);
|
|
cyBorder = GetSystemMetrics(SM_CYBORDER);
|
|
MoveWindow(g_hwndStatus, -cxBorder, rcClient.bottom - (g_statusHeight + cyBorder),
|
|
rcClient.right + (2 * cxBorder), (g_statusHeight + (2 * cyBorder)), TRUE);
|
|
|
|
DV_StatusParts(rcClient.right);
|
|
|
|
//re-size the video window
|
|
GetWindowRect(g_hwndTBar, &rcTB);
|
|
if (g_pGraph )
|
|
{
|
|
if(g_pGraph->m_pVideoWindow)
|
|
{
|
|
g_pGraph->m_pVideoWindow->SetWindowPosition(0, rcTB.bottom - rcTB.top, g_iVWWidth, g_iVWHeight);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_CLOSE:
|
|
return SendMessage(hwnd, WM_DESTROY, 0,0);
|
|
|
|
case WM_DESTROY:
|
|
// Unregister device notifications
|
|
if (g_hDevNotify != NULL)
|
|
{
|
|
UnregisterDeviceNotification(g_hDevNotify);
|
|
g_hDevNotify = NULL;
|
|
}
|
|
|
|
if(g_pGraph != NULL){
|
|
delete g_pGraph;
|
|
g_pGraph = NULL;
|
|
}
|
|
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
case WM_DEVICECHANGE:
|
|
{
|
|
// We are interested in only device arrival events
|
|
if (DBT_DEVICEARRIVAL != wparam)
|
|
break;
|
|
PDEV_BROADCAST_HDR pdbh = (PDEV_BROADCAST_HDR) lparam;
|
|
if (pdbh->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
|
|
break;
|
|
|
|
// Check for capture devices.
|
|
PDEV_BROADCAST_DEVICEINTERFACE pdbi = (PDEV_BROADCAST_DEVICEINTERFACE) lparam;
|
|
if (pdbi->dbcc_classguid != AM_KSCATEGORY_CAPTURE)
|
|
break;
|
|
|
|
// Check for device arrival.
|
|
if (g_bDeviceFound == FALSE)
|
|
{
|
|
MessageBox(g_hwndApp, TEXT("There is a new capture device on this system..."), APPNAME, MB_OK);
|
|
DV_AppSetup();
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_FGNOTIFY : //Filter Graph Events Notify Message handler
|
|
{
|
|
if(g_pGraph == NULL)
|
|
break;
|
|
if(g_pGraph->m_pMediaEvent == NULL)
|
|
break;
|
|
|
|
long event;
|
|
LONG_PTR l1, l2;
|
|
// Get the corresponding filtergraph directshow media event to handle
|
|
while (SUCCEEDED(g_pGraph->m_pMediaEvent->GetEvent(&event, &l1, &l2, 0L)))
|
|
{
|
|
switch (event)
|
|
{
|
|
case EC_USERABORT :
|
|
case EC_COMPLETE :
|
|
// filtergraph is done, time to stop the filtergraph or transport state
|
|
SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);
|
|
break;
|
|
|
|
case EC_ERRORABORT :
|
|
//something bad happened during capture
|
|
MBOX(TEXT("Error during preview, capture or transmit"));
|
|
break;
|
|
|
|
case EC_DEVICE_LOST : // Check if we have lost a capture filter being used.
|
|
if (l2 == 0) //0 indicates device removed;1 indicates removed device added again
|
|
{
|
|
IBaseFilter *pf;
|
|
IUnknown *punk = (IUnknown *) l1;
|
|
hr = punk->QueryInterface(IID_IBaseFilter, (void **) &pf);
|
|
if(FAILED(hr))
|
|
break;
|
|
|
|
if (AreComObjectsEqual(g_pGraph->m_pDeviceFilter, pf))
|
|
{
|
|
MBOX(TEXT("DV Camcorder Device in use was removed"));
|
|
|
|
// handle the timers accordingly
|
|
if (g_bUseAtnTimer)
|
|
KillTimer(hwnd, DV_TIMER_ATN);
|
|
|
|
KillTimer(hwnd, DV_TIMER_CAPLIMIT);
|
|
KillTimer(hwnd, DV_TIMER_FRAMES);
|
|
g_bDeviceFound = FALSE;
|
|
|
|
// should call delete filters....????
|
|
if(g_pGraph != NULL)
|
|
delete g_pGraph; // pf is released
|
|
DV_AppSetup();
|
|
}
|
|
else
|
|
pf->Release();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}// end of switch
|
|
|
|
if(g_pGraph->m_pMediaEvent == NULL)
|
|
break;
|
|
|
|
// Free any memory associated with this event
|
|
g_pGraph->m_pMediaEvent->FreeEventParams(event, l1, l2);
|
|
|
|
} // end of while
|
|
break;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wparam))
|
|
{
|
|
// The File Menu
|
|
/*
|
|
The globals for input file and output file are TCHAR. When compiled ANSI,
|
|
GetOpenFileName (obviously) return ANSI buffers. DirectShow functions use Unicode
|
|
names exclusively, so these are converted to Unicode within the functions
|
|
that need to use these variables (DV_Make...To... functions).
|
|
*/
|
|
case IDM_SETINPUT : //fall through
|
|
case IDM_SETOUTPUT :
|
|
case IDM_OPTIONS_SAVEGRAPH :
|
|
{
|
|
OPENFILENAME ofn = {0};
|
|
OSVERSIONINFO osi = {0};
|
|
//need to adjust the ofn struct size if we are running on win98 vs. nt5
|
|
osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&osi);
|
|
if (osi.dwMajorVersion >=5 && osi.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
ofn.lStructSize = sizeof (OPENFILENAME);
|
|
else
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
|
|
ofn.hwndOwner = g_hwndApp;
|
|
ofn.nMaxFile = _MAX_PATH;
|
|
|
|
if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wparam))
|
|
{
|
|
ofn.lpstrFilter = TEXT("Filter Graph (*.grf)\0*.grf\0\0");
|
|
ofn.lpstrTitle = TEXT("Set FilterGraph File Name...\0");
|
|
ofn.lpstrFile = g_FilterGraphFileName;
|
|
ofn.Flags = OFN_HIDEREADONLY;
|
|
}
|
|
else if (IDM_SETOUTPUT == LOWORD (wparam))
|
|
{
|
|
ofn.lpstrFilter = TEXT("Microsoft AVI (*.avi)\0*.avi\0\0");
|
|
ofn.lpstrTitle = TEXT("Set Output File Name...\0");
|
|
ofn.lpstrFile = g_OutputFileName;
|
|
ofn.Flags = OFN_HIDEREADONLY;
|
|
}
|
|
else
|
|
{
|
|
ofn.lpstrFilter = TEXT("Microsoft AVI (*.avi)\0*.avi\0\0");
|
|
ofn.lpstrTitle = TEXT("Set Input File Name...\0");
|
|
ofn.lpstrFile = g_InputFileName;
|
|
ofn.Flags = OFN_FILEMUSTEXIST | OFN_READONLY;
|
|
}
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wparam))
|
|
{
|
|
hr = StringCchCopy(g_FilterGraphFileName, NUMELMS(g_FilterGraphFileName), ofn.lpstrFile);
|
|
// Save the current built filter graph to a *.grf file
|
|
if(g_pGraph != NULL)
|
|
g_pGraph->SaveGraphToFile(g_FilterGraphFileName);
|
|
|
|
}
|
|
else if (IDM_SETOUTPUT == LOWORD (wparam))
|
|
{
|
|
hr = StringCchCopy(g_FilterGraphFileName, NUMELMS(g_FilterGraphFileName), ofn.lpstrFile);
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchCopy(g_FilterGraphFileName, NUMELMS(g_FilterGraphFileName), ofn.lpstrFile);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case IDM_ABOUT:
|
|
DialogBox((HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_ABOUT), hwnd, (DLGPROC)DV_AboutDlgProc);
|
|
break;
|
|
|
|
// Toolbar Button Commands
|
|
// Transport State & Graph State Control
|
|
case IDM_PLAY :
|
|
case IDM_RECORD :
|
|
case IDM_STOP :
|
|
case IDM_PAUSE :
|
|
case IDM_FF :
|
|
case IDM_REW :
|
|
case IDM_PLAY_FAST_FF :
|
|
case IDM_PLAY_FAST_REV :
|
|
case IDM_STEP_FWD :
|
|
case IDM_STEP_REV :
|
|
case IDM_SEEKTIMECODE :
|
|
DV_TransportCommand_WndProc(hwnd, msg, wparam, lparam);
|
|
break;
|
|
|
|
// The Options Menu
|
|
case IDM_DECODESIZE :
|
|
g_pGraph->StopGraph();
|
|
g_pGraph->GetVideoWindowDimensions(&g_iVWWidth, &g_iVWHeight, TRUE, g_hwndApp);
|
|
SetPreviewWindow();
|
|
|
|
break;
|
|
|
|
case IDM_CHECKTAPE :
|
|
DV_UpdateTapeInfo();
|
|
break;
|
|
|
|
case IDM_REFRESHMODE :
|
|
DV_RefreshMode();
|
|
break;
|
|
|
|
case IDM_FRAMERATE :
|
|
if( g_bHalfFrameRate )
|
|
{
|
|
g_bHalfFrameRate = FALSE;
|
|
CheckMenuItem(g_hmenu, IDM_FRAMERATE, MF_UNCHECKED);
|
|
}
|
|
else
|
|
{
|
|
g_bHalfFrameRate = TRUE;
|
|
CheckMenuItem(g_hmenu, IDM_FRAMERATE, MF_CHECKED);
|
|
}
|
|
g_pGraph->ChangeFrameRate(g_bHalfFrameRate);
|
|
break;
|
|
|
|
case IDM_CAPSIZE:
|
|
DialogBox((HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG_CAPSIZE), hwnd, (DLGPROC)DV_CapSizeDlgProc);
|
|
break;
|
|
|
|
case IDM_EXIT:
|
|
return SendMessage(hwnd, WM_CLOSE, 0, 0);
|
|
|
|
// Graph Mode Menu
|
|
// Change the Current Graph Mode
|
|
case IDM_PREVIEW :
|
|
case IDM_FILETODV :
|
|
case IDM_FILETODV_NOPRE :
|
|
case IDM_DVTOFILE :
|
|
case IDM_DVTOFILE_NOPRE :
|
|
case IDM_FILETODV_TYPE2 :
|
|
case IDM_FILETODV_NOPRE_TYPE2 :
|
|
case IDM_DVTOFILE_TYPE2 :
|
|
case IDM_DVTOFILE_NOPRE_TYPE2 :
|
|
DV_GraphModeCommand_WndProc (hwnd, msg, wparam, lparam);
|
|
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_InitControls
|
|
Purpose: Initializer for app window controls (toolbars, edit controls, etc.)
|
|
Arguments: window handle and hinstance
|
|
Returns: FALSE if creation of any of the controls fails.
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
BOOL DV_InitControls(HWND hwnd, HINSTANCE hInst)
|
|
{
|
|
HWND hwndEdit1 = NULL;
|
|
HWND hwndEdit2 = NULL;
|
|
HWND hwndEdit3 = NULL;
|
|
HWND hwndEdit4 = NULL;
|
|
|
|
RECT rect = {0};
|
|
|
|
// create status bar windows
|
|
g_hwndStatus = CreateWindowEx( 0,
|
|
STATUSCLASSNAME,
|
|
TEXT(""),
|
|
WS_CHILD | WS_BORDER | WS_VISIBLE | WS_CLIPSIBLINGS,
|
|
-100, -100,
|
|
10, 10,
|
|
hwnd,
|
|
HMENU(IDB_STATUS),
|
|
g_hinst,
|
|
NULL);
|
|
|
|
DV_StatusParts(g_iAppWidth);
|
|
g_statusHeight = rect.bottom;
|
|
|
|
// create toolbar window
|
|
g_hwndTBar = CreateToolbarEx( hwnd,
|
|
WS_CHILD | WS_VISIBLE | WS_BORDER | TBSTYLE_TOOLTIPS,
|
|
ID_TOOLBAR,
|
|
10,
|
|
g_hinst,
|
|
IDB_TOOLBAR,
|
|
g_rgTbButtons,
|
|
sizeof(g_rgTbButtons) / sizeof(TBBUTTON),
|
|
16,16,16,16,
|
|
sizeof(TBBUTTON));
|
|
|
|
// create timecode text boxes on the toolbar
|
|
rect.right = 350;
|
|
hwndEdit1 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
|
|
rect.right + 6, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_HOUR, (HINSTANCE) hInst, NULL);
|
|
|
|
hwndEdit2 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
|
|
rect.right + 30, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_MINUTE, (HINSTANCE) hInst, NULL);
|
|
|
|
hwndEdit3 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
|
|
rect.right + 54, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_SECOND, (HINSTANCE) hInst, NULL);
|
|
|
|
hwndEdit4 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
|
|
rect.right + 78, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_FRAME, (HINSTANCE) hInst, NULL);
|
|
|
|
g_hwndTCCheck = CreateWindow(TEXT("button"), TEXT("Display Timecodes"), WS_CHILD | BS_AUTOCHECKBOX | WS_VISIBLE | WS_TABSTOP,
|
|
rect.right + 106, 5, 190, 18, g_hwndTBar, (HMENU)IDC_TCCHECKBOX, (HINSTANCE) hInst, NULL);
|
|
Button_SetCheck (g_hwndTCCheck, BST_CHECKED) ;
|
|
|
|
return (!( !hwndEdit1) || (!hwndEdit2) || (!hwndEdit3) || (!hwndEdit4) ||
|
|
(!g_hwndTCCheck) || (!g_hwndStatus));
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_AppSetup
|
|
Purpose: look for a DV device, initialize it, get its subunit mode,
|
|
Create the filtergraph and instantiate the filters
|
|
Arguments: None
|
|
Returns: None
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
HRESULT DV_AppSetup(void)
|
|
{
|
|
HRESULT hr =S_OK;
|
|
g_pGraph = new CDVGraph();
|
|
if ( !g_pGraph ){
|
|
hr = E_OUTOFMEMORY;
|
|
return hr;
|
|
}
|
|
|
|
//look for a DV device and initialize it, or show an error if one does not exist
|
|
hr = g_pGraph->BuildBasicGraph();
|
|
if (S_OK != hr)
|
|
{
|
|
g_bDeviceFound = FALSE;
|
|
int iOption = MessageBox(g_hwndApp, TEXT("There are no DV camcorder devices on this system.\n\n")
|
|
TEXT("Do you want to exit the app?"), APPNAME, MB_YESNO);
|
|
if(iOption == IDYES)
|
|
SendMessage(g_hwndApp, WM_DESTROY, 0,0);
|
|
else
|
|
{
|
|
ShowWindow(g_hwndTBar, SW_HIDE);
|
|
|
|
EnableMenuItem(g_hmenu, IDM_REFRESHMODE, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_CHECKTAPE, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_DECODESIZE, MF_GRAYED);
|
|
|
|
EnableMenuItem(g_hmenu, IDM_PREVIEW, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_NOPRE, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_TYPE2, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_TYPE2, MF_GRAYED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_bDeviceFound = TRUE;
|
|
ShowWindow(g_hwndTBar, SW_SHOWNORMAL);
|
|
|
|
EnableMenuItem(g_hmenu, IDM_REFRESHMODE, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_CHECKTAPE, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_DECODESIZE, MF_ENABLED);
|
|
|
|
EnableMenuItem(g_hmenu, IDM_PREVIEW, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_NOPRE, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_TYPE2, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_TYPE2, MF_ENABLED);
|
|
EnableMenuItem(g_hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
|
|
|
|
//determine if we are in camera mode or vcr mode and disable unavailable menu items
|
|
DV_RefreshMode();
|
|
DV_StatusText(g_pGraph->m_DeviceName, 0);
|
|
|
|
// make preview graph
|
|
hr= g_pGraph->MakePreviewGraph( );
|
|
if(FAILED(hr))
|
|
{
|
|
delete g_pGraph;
|
|
g_pGraph = NULL;
|
|
|
|
MBOX(TEXT("MakePreviewGraph() failed"));
|
|
return hr;
|
|
}
|
|
|
|
//get and set the display window size
|
|
g_pGraph->GetVideoWindowDimensions(&g_iVWWidth, &g_iVWHeight, FALSE, NULL);
|
|
|
|
// register a window to process event notifications.
|
|
hr = g_pGraph->m_pMediaEvent->SetNotifyWindow((LONG_PTR) g_hwndApp, WM_FGNOTIFY, 0);
|
|
if(FAILED(hr))
|
|
{
|
|
MBOX(TEXT("g_pGraph->m_pMediaEvent->SetNotifyWindow() failed"));
|
|
return hr;
|
|
}
|
|
|
|
// update globals, log, toolbar, menu items for preview mode
|
|
g_iGraphType = GRAPH_PREVIEW;
|
|
Mark_GraphMode_Menu( g_hwndApp, IDM_PREVIEW );
|
|
Mark_ToolBar_Button( FALSE, TRUE );
|
|
SetPreviewWindow();
|
|
|
|
// ready for user
|
|
SetWindowText(g_hwndApp, DV_APPTITLE);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_GraphModeCommand_WndProc
|
|
Purpose: Message Handler for Graph Mode menu items
|
|
Arguments: Usual message processing parameters
|
|
Returns: Usual
|
|
Notes: Builds the various kinds of Graph types preview/capture/transmit
|
|
------------------------------------------------------------------------*/
|
|
void CALLBACK DV_GraphModeCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
GRAPH_TYPE graphType= (GRAPH_TYPE)0;
|
|
GetSelectedGraphMode( wParam, &graphType );
|
|
|
|
// dont rebuild if the required graph already exists
|
|
if( graphType == g_iGraphType )
|
|
return;
|
|
|
|
//stop the graph - this should never fail before rebuilding
|
|
if(FAILED( g_pGraph->m_pMediaControl->Stop()))
|
|
return;
|
|
|
|
//let's look at the former graph
|
|
//Disconnect everything
|
|
if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
|
|
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
|
|
{
|
|
//DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
|
|
g_pGraph->RemoveFilters( g_pGraph->m_pInputFileFilter, TRUE);
|
|
if (g_pGraph->m_pInputFileFilter )
|
|
{
|
|
g_pGraph->m_pGraph->RemoveFilter( g_pGraph->m_pInputFileFilter );
|
|
SAFE_RELEASE( g_pGraph->m_pInputFileFilter );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//DisconnectAll removes only the downstream filters
|
|
g_pGraph->RemoveFilters( g_pGraph->m_pDeviceFilter, TRUE);
|
|
}
|
|
g_iGraphType = graphType;
|
|
|
|
switch (LOWORD (wParam))
|
|
{
|
|
case IDM_PREVIEW :
|
|
if(SUCCEEDED(g_pGraph->MakePreviewGraph( )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
SetPreviewWindow();
|
|
Mark_GraphMode_Menu( hwnd, IDM_PREVIEW );
|
|
Mark_ToolBar_Button( TRUE, TRUE );
|
|
}
|
|
else{
|
|
delete g_pGraph;
|
|
g_pGraph = NULL;
|
|
MBOX(TEXT("MakePreviewGraph() failed"));
|
|
}
|
|
|
|
break;
|
|
|
|
// Type 1 file (transmit & playback)
|
|
case IDM_FILETODV :
|
|
if(SUCCEEDED(g_pGraph->MakeFileToDvGraph_Type1( g_InputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
SetPreviewWindow();
|
|
Mark_GraphMode_Menu( hwnd,IDM_FILETODV );
|
|
Mark_ToolBar_Button( TRUE, FALSE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeFileToDvGraph_Type1() failed. Please set input file."));
|
|
|
|
break;
|
|
|
|
// Type 1 file (transmit)
|
|
case IDM_FILETODV_NOPRE :
|
|
if(SUCCEEDED(g_pGraph->MakeFileToDvGraph_NoPre_Type1( g_InputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
Mark_GraphMode_Menu( hwnd,IDM_FILETODV_NOPRE );
|
|
Mark_ToolBar_Button( TRUE, FALSE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeFileToDvGraph_NoPre_Type1() failed. Please set input file."));
|
|
break;
|
|
|
|
// Type 1 file (capture & preview)
|
|
case IDM_DVTOFILE :
|
|
if(SUCCEEDED(g_pGraph->MakeDvToFileGraph_Type1( g_OutputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
SetPreviewWindow();
|
|
Mark_GraphMode_Menu( hwnd,IDM_DVTOFILE );
|
|
Mark_ToolBar_Button( TRUE, TRUE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeDvToFileGraph_Type1() failed."));
|
|
|
|
break;
|
|
|
|
// Type 1 file (capture)
|
|
case IDM_DVTOFILE_NOPRE :
|
|
if(SUCCEEDED(g_pGraph->MakeDvToFileGraph_NoPre_Type1( g_OutputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
Mark_GraphMode_Menu( hwnd,IDM_DVTOFILE_NOPRE );
|
|
Mark_ToolBar_Button( TRUE, TRUE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeDvToFileGraph_NoPre_Type1() failed."));
|
|
|
|
break;
|
|
|
|
// Type 2 File (transmit & playback)
|
|
case IDM_FILETODV_TYPE2 :
|
|
if(SUCCEEDED(g_pGraph->MakeFileToDvGraph_Type2( g_InputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
SetPreviewWindow();
|
|
Mark_GraphMode_Menu( hwnd,IDM_FILETODV_TYPE2 );
|
|
Mark_ToolBar_Button( TRUE, FALSE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeFileToDvGraph_Type2() failed. Please set input file."));
|
|
|
|
break;
|
|
|
|
// Type 2 File (transmit)
|
|
case IDM_FILETODV_NOPRE_TYPE2 :
|
|
if(SUCCEEDED(g_pGraph->MakeFileToDvGraph_NoPre_Type2( g_InputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
Mark_GraphMode_Menu( hwnd,IDM_FILETODV_NOPRE_TYPE2 );
|
|
Mark_ToolBar_Button( TRUE, FALSE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeFileToDvGraph_NoPre_Type2() failed. Please set input file."));
|
|
|
|
break;
|
|
|
|
// Type 2 File (capture & preview)
|
|
case IDM_DVTOFILE_TYPE2 :
|
|
if(SUCCEEDED(g_pGraph->MakeDvToFileGraph_Type2( g_OutputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
SetPreviewWindow();
|
|
Mark_GraphMode_Menu( hwnd,IDM_DVTOFILE_TYPE2 );
|
|
Mark_ToolBar_Button( TRUE, TRUE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeDvToFileGraph_Type2() failed"));
|
|
|
|
break;
|
|
|
|
// Type 2 File (capture)
|
|
case IDM_DVTOFILE_NOPRE_TYPE2 :
|
|
if(SUCCEEDED(g_pGraph->MakeDvToFileGraph_NoPre_Type2( g_OutputFileName )))
|
|
{
|
|
// update globals, log, toolbar, menu items
|
|
Mark_GraphMode_Menu( hwnd,IDM_DVTOFILE_NOPRE_TYPE2 );
|
|
Mark_ToolBar_Button( TRUE, TRUE );
|
|
}
|
|
else
|
|
MBOX(TEXT("MakeDvToFileGraph_NoPre_Type2() failed"));
|
|
|
|
break;
|
|
|
|
} // switch (LOWORD(wParam))
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_TransportCommand_WndProc
|
|
Purpose: Message Handler to control transport state of the device & the filtergraph state
|
|
Arguments: Usual message processing parameters
|
|
Returns: Usual
|
|
Notes: Handles for the Toolbar button controls
|
|
------------------------------------------------------------------------*/
|
|
void CALLBACK DV_TransportCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (iMsg)
|
|
{
|
|
case WM_COMMAND :
|
|
switch (LOWORD (wParam))
|
|
{
|
|
/*
|
|
The VCR Tool bar commands need to behave differently depending on the
|
|
current graph.
|
|
|
|
In Preview (default) mode, the VCR commands should simply
|
|
control the VCR functions on the vcr device.
|
|
|
|
In DV To File mode, or File To DV mode the commands should start and stop the graph,
|
|
as well as control the vcr mode (although we will disable some buttons to avoid confusion)
|
|
*/
|
|
case IDM_PLAY :
|
|
{
|
|
//check if the current graph is a transmit graph
|
|
if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
|
|
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
|
|
{
|
|
// update the toolbar accordingly
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
|
|
// update the status bar with the dropped frames information
|
|
g_CapStartTime = GetTickCount();
|
|
SetTimer(hwnd, DV_TIMER_FRAMES, DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
|
|
|
|
// run the filter graph & wait for DirectShow events
|
|
g_pGraph->StartGraph();
|
|
}
|
|
else //capture and preview
|
|
{
|
|
// play the tape for the capture or preview graph
|
|
DV_PutVcrMode(ED_MODE_PLAY);
|
|
|
|
if(GRAPH_PREVIEW == g_iGraphType)
|
|
g_pGraph->StartGraph();
|
|
|
|
//do we want to display timecodes?
|
|
if (IsDlgButtonChecked(g_hwndTBar, IDC_TCCHECKBOX))
|
|
{
|
|
SetTimer(hwnd, DV_TIMER_ATN, DV_TIMERFREQ, (TIMERPROC) DV_TimecodeTimerProc);
|
|
g_bUseAtnTimer = TRUE;
|
|
}
|
|
// disable checkbox
|
|
EnableWindow( g_hwndTCCheck, false);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/*
|
|
The record button starts the *entire* graph, so preview (if selected), won't
|
|
start until the recording starts.
|
|
*/
|
|
case IDM_RECORD :
|
|
// update the toolbar accordingly
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
|
|
// check to see if it is a capture graph
|
|
if (GRAPH_DV_TO_FILE == g_iGraphType || GRAPH_DV_TO_FILE_NOPRE == g_iGraphType ||
|
|
GRAPH_DV_TO_FILE_TYPE2 == g_iGraphType || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iGraphType)
|
|
{
|
|
//do something here to record to an avi file on the disk - or to start recording on the vcr.
|
|
switch (g_dwCaptureLimit)
|
|
{
|
|
case DV_CAPLIMIT_NONE :
|
|
break;
|
|
case DV_CAPLIMIT_TIME :
|
|
SetTimer(hwnd, DV_TIMER_CAPLIMIT, g_dwTimeLimit * 1000, (TIMERPROC) DV_StopRecProc);
|
|
break;
|
|
case DV_CAPLIMIT_SIZE :
|
|
//rather than monitor disk usage, we'll just do the math and set a timer
|
|
SetTimer(hwnd, DV_TIMER_CAPLIMIT, ((g_dwDiskSpace * 100000) / DV_BYTESPERMSEC), (TIMERPROC) DV_StopRecProc);
|
|
break;
|
|
default :
|
|
//MBOX(TEXT("Bad value for g_dwCaptureLimit (%d)"), g_dwCaptureLimit);
|
|
break;
|
|
}
|
|
|
|
//update the status bar with the dropped frames information
|
|
g_CapStartTime = GetTickCount();
|
|
SetTimer(hwnd, DV_TIMER_FRAMES, DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
|
|
//run the graph - assume that the camera is already playing if in Vcr mode
|
|
g_pGraph->StartGraph();
|
|
}
|
|
else if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
|
|
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
|
|
{
|
|
// if transmit graph then record on tape of the device
|
|
DV_PutVcrMode(ED_MODE_RECORD);
|
|
}
|
|
else
|
|
{
|
|
//we shouldn't get here
|
|
MBOX( TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) in IDM_RECORD message"));
|
|
}
|
|
break;
|
|
|
|
case IDM_STOP :
|
|
// handle the timers accordingly
|
|
if (g_bUseAtnTimer){
|
|
KillTimer(hwnd, DV_TIMER_ATN);
|
|
|
|
}
|
|
|
|
|
|
//if we're here, these timers were set
|
|
KillTimer(hwnd, DV_TIMER_CAPLIMIT);
|
|
KillTimer(hwnd, DV_TIMER_FRAMES);
|
|
|
|
g_pGraph->StopGraph();
|
|
|
|
// Stop the transport on the device
|
|
DV_PutVcrMode(ED_MODE_STOP);
|
|
// update the toolbar
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
|
|
EnableWindow( g_hwndTCCheck, true);
|
|
break;
|
|
|
|
case IDM_PAUSE :
|
|
if (GRAPH_FILE_TO_DV == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE == g_iGraphType ||
|
|
GRAPH_FILE_TO_DV_TYPE2 == g_iGraphType || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iGraphType)
|
|
{ // transmit graph
|
|
g_pGraph->PauseGraph();
|
|
}
|
|
else
|
|
{ // capture or preview graph
|
|
DV_PutVcrMode(ED_MODE_FREEZE);
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
}
|
|
//SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
break;
|
|
|
|
case IDM_FF :
|
|
// all graphs just forward the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_FF);
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
break;
|
|
|
|
case IDM_REW :
|
|
// all graphs just rewind the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_REW);
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
break;
|
|
|
|
case IDM_PLAY_FAST_FF :
|
|
// all graphs just forward the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_PLAY_FASTEST_FWD);
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
break;
|
|
|
|
case IDM_PLAY_FAST_REV :
|
|
// all graphs just rewind the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_PLAY_FASTEST_REV);
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
break;
|
|
|
|
case IDM_STEP_FWD :
|
|
// all graphs just forward the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_STEP_FWD);
|
|
g_bUseAtnTimer = FALSE;
|
|
DV_DisplayTimecode();
|
|
break;
|
|
|
|
case IDM_STEP_REV :
|
|
// all graphs just rewind the tape & update the toolbar
|
|
DV_PutVcrMode(ED_MODE_STEP_REV);
|
|
g_bUseAtnTimer = FALSE;
|
|
DV_DisplayTimecode();
|
|
break;
|
|
|
|
case IDM_SEEKTIMECODE :
|
|
// ATN Seek & display on the toolbar
|
|
DV_SeekATN();
|
|
DV_DisplayTimecode();
|
|
break;
|
|
|
|
} // switch (LOWORD(wParam))
|
|
} // switch (iMsg)
|
|
}
|
|
|
|
|
|
void Mark_GraphMode_Menu(HWND hwnd, int idmVal)
|
|
{
|
|
//uncheck everything first
|
|
CheckMenuItem(g_hmenu, IDM_PREVIEW, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_FILETODV, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_DVTOFILE, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
|
|
|
|
CheckMenuItem(g_hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
|
|
CheckMenuItem(g_hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
|
|
|
|
// check the selected graph mode
|
|
CheckMenuItem(g_hmenu, idmVal, MF_CHECKED);
|
|
}
|
|
|
|
void Mark_ToolBar_Button(BOOL bEnableRecord, BOOL bEnableOthers)
|
|
{
|
|
if(bEnableRecord == TRUE)
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
else
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
|
|
if(bEnableOthers == TRUE)
|
|
{
|
|
//re-enable everything
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
|
|
}
|
|
else
|
|
{
|
|
//disable everything except for play, pause, and stop
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
|
|
}
|
|
}
|
|
|
|
|
|
void GetSelectedGraphMode( WPARAM wParam, GRAPH_TYPE* pGraphType)
|
|
{
|
|
switch (LOWORD (wParam))
|
|
{
|
|
case IDM_PREVIEW :
|
|
*pGraphType = GRAPH_PREVIEW;
|
|
break;
|
|
case IDM_FILETODV :
|
|
*pGraphType = GRAPH_FILE_TO_DV;
|
|
break;
|
|
case IDM_FILETODV_NOPRE :
|
|
*pGraphType = GRAPH_FILE_TO_DV_NOPRE;
|
|
break;
|
|
case IDM_DVTOFILE :
|
|
*pGraphType = GRAPH_DV_TO_FILE;
|
|
break;
|
|
case IDM_DVTOFILE_NOPRE :
|
|
*pGraphType = GRAPH_DV_TO_FILE_NOPRE;
|
|
break;
|
|
case IDM_FILETODV_TYPE2 :
|
|
*pGraphType = GRAPH_FILE_TO_DV_TYPE2;
|
|
break;
|
|
case IDM_FILETODV_NOPRE_TYPE2 :
|
|
*pGraphType = GRAPH_FILE_TO_DV_NOPRE_TYPE2;
|
|
break;
|
|
case IDM_DVTOFILE_TYPE2 :
|
|
*pGraphType = GRAPH_DV_TO_FILE_TYPE2;
|
|
break;
|
|
case IDM_DVTOFILE_NOPRE_TYPE2 :
|
|
*pGraphType = GRAPH_DV_TO_FILE_NOPRE_TYPE2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: SetPreviewWindow
|
|
Purpose: Hooks up stream *from camera* to preview window
|
|
Note that the preview for the playback from the file is handled within DV_MakeFileToDvGraph() stuff
|
|
Arguments: None
|
|
Returns: HRESULT as appropriate
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
HRESULT SetPreviewWindow(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT(g_pGraph->m_pVideoWindow!= NULL);
|
|
|
|
//Set the video window.
|
|
hr = g_pGraph->m_pVideoWindow->put_Owner((OAHWND)g_hwndApp); // We own the window now
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
// you are now a child
|
|
hr = g_pGraph->m_pVideoWindow->put_WindowStyle(WS_CHILD| WS_CLIPSIBLINGS);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
// give the preview window all our space but where the tool bar and status bar are
|
|
RECT clientRect, toolbarRect;
|
|
GetClientRect(g_hwndApp, &clientRect);
|
|
GetWindowRect(g_hwndTBar, &toolbarRect);
|
|
|
|
g_pGraph->m_pVideoWindow->SetWindowPosition(0, toolbarRect.bottom - toolbarRect.top, g_iVWWidth, g_iVWHeight);
|
|
|
|
hr = g_pGraph->m_pVideoWindow->put_Visible(OATRUE);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_DroppedFrameProc
|
|
Purpose: Callback proc to display dropped frame info
|
|
Arguments: DWORD current time
|
|
Returns: None
|
|
Notes: For both Capture & Transmit graphs
|
|
------------------------------------------------------------------------*/
|
|
void CALLBACK DV_DroppedFrameProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
long dropped = 0, notdropped = 0;
|
|
TCHAR buffer[128];
|
|
DWORD time = dwTime - g_CapStartTime;
|
|
|
|
BOOL bIsModeTransmit = TRUE;
|
|
hr = g_pGraph->getDroppedFrameNum( &bIsModeTransmit, &dropped, ¬dropped);
|
|
if(FAILED(hr))
|
|
{
|
|
DV_StatusText(TEXT("Cannot report dropped frame information"), 1);
|
|
KillTimer(hwnd, DV_TIMER_FRAMES);
|
|
}
|
|
|
|
if( bIsModeTransmit == FALSE)
|
|
hr = StringCchPrintf(buffer, NUMELMS(buffer), TEXT("Captured %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
|
|
else
|
|
hr = StringCchPrintf(buffer, NUMELMS(buffer), TEXT("Transmitted %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
|
|
|
|
DV_StatusText(buffer, 1);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_TimecodeTimerProc
|
|
Purpose: Callback function for the timer proc
|
|
Arguments: Usual Timer Processing Parameters
|
|
Returns: None
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
void CALLBACK DV_TimecodeTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
|
|
{
|
|
DV_DisplayTimecode();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_DisplayTimecode
|
|
Purpose: Routine to display timecodes
|
|
Arguments: None
|
|
Returns: None
|
|
Notes: This is TimeCode Read not Absolute Track Number Read
|
|
------------------------------------------------------------------------*/
|
|
void DV_DisplayTimecode(void)
|
|
{
|
|
TIMECODE_SAMPLE TimecodeSample;
|
|
TimecodeSample.timecode.dwFrames = 0;
|
|
static DWORD i1 = 0, i2 = 0, i3 = 0;
|
|
TCHAR szBuf[4];
|
|
|
|
TimecodeSample.dwFlags = ED_DEVCAP_TIMECODE_READ;
|
|
|
|
// Query the TimeCode sample data
|
|
HRESULT hr = g_pGraph->m_pIAMTCReader->GetTimecode(&TimecodeSample);
|
|
if(FAILED(hr))
|
|
{
|
|
//MBOX(TEXT("DV_DisplayTimecode::g_pGraph->m_pIAMTCReader->GetTimecode() failed"));
|
|
}
|
|
|
|
hr = StringCchPrintf(szBuf, NUMELMS(szBuf), TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0xff000000) >> 24));
|
|
SetDlgItemText(g_hwndTBar, IDC_EDIT_HOUR, szBuf);
|
|
|
|
hr = StringCchPrintf(szBuf, NUMELMS(szBuf), TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16));
|
|
SetDlgItemText(g_hwndTBar, IDC_EDIT_MINUTE, szBuf);
|
|
|
|
hr = StringCchPrintf(szBuf, NUMELMS(szBuf), TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x0000ff00) >> 8));
|
|
SetDlgItemText(g_hwndTBar, IDC_EDIT_SECOND, szBuf);
|
|
|
|
hr = StringCchPrintf(szBuf, NUMELMS(szBuf), TEXT("%.2x"),(TimecodeSample.timecode.dwFrames & 0x000000ff));
|
|
SetDlgItemText(g_hwndTBar, IDC_EDIT_FRAME, szBuf);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_SeekATN
|
|
Purpose: ATN Seek function - uses GetTransportBasicParameters to send RAW AVC command
|
|
Arguments: None
|
|
Returns: TRUE if successful
|
|
Notes: This is Absolute Track Number Seek not TimeCode Seek but uses the timecode display as input
|
|
------------------------------------------------------------------------*/
|
|
BOOL DV_SeekATN(void)
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
HRESULT hr = S_OK;
|
|
int iHr, iMn, iSc, iFr;
|
|
|
|
//get the values from the edit fields
|
|
iHr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_HOUR, &bStatus, FALSE);
|
|
iMn = GetDlgItemInt(g_hwndTBar, IDC_EDIT_MINUTE, &bStatus, FALSE);
|
|
iSc = GetDlgItemInt(g_hwndTBar, IDC_EDIT_SECOND, &bStatus, FALSE);
|
|
iFr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_FRAME, &bStatus, FALSE);
|
|
|
|
hr = g_pGraph->SeekATN( iHr, iMn, iSc, iFr );
|
|
if(FAILED(hr))
|
|
{
|
|
MBOX(TEXT("Invalid Parameter - Time entered should be:\nHour:Minute:Second:Frame"));
|
|
bStatus = FALSE;
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_UpdateTapeInfo
|
|
Purpose: Get Frame rate and availability of dvcr tape
|
|
Arguments: None
|
|
Returns: HRESULT as appropriate
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
BOOL DV_UpdateTapeInfo(void)
|
|
{
|
|
//check information about the tape
|
|
if (S_OK != g_pGraph->GetTapeInfo())
|
|
{
|
|
MBOX(TEXT("Tape is not inserted, or it has an improper format.\nReinsert the tape and select Options - Check Tape"));
|
|
DV_StatusText(TEXT("VCR Mode - No tape, or unknown format"), 2);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
switch(g_pGraph->m_VideoFormat)
|
|
{
|
|
case DVENCODERVIDEOFORMAT_NTSC:
|
|
DV_StatusText(TEXT("VCR Mode - NTSC"), 2);
|
|
break;
|
|
case DVENCODERVIDEOFORMAT_PAL:
|
|
DV_StatusText(TEXT("VCR Mode - PAL"), 2);
|
|
break;
|
|
default:
|
|
MBOX(TEXT("Unsupported or unrecognized tape format type"));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_RefreshMode
|
|
Purpose: Use this to rebuild the necessary stuff to switch between VCR and camera mode
|
|
Arguments: None
|
|
Returns: TRUE if successful
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
BOOL DV_RefreshMode(void)
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
|
|
// Query the current device type
|
|
DV_MODE SubunitMode;
|
|
g_pGraph->GetDVMode( &SubunitMode );
|
|
|
|
switch(SubunitMode)
|
|
{
|
|
case CameraMode :
|
|
// update the Graph Mode menu items & status window
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_GRAYED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_GRAYED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_GRAYED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_GRAYED);
|
|
DV_StatusText(TEXT("Camera Mode"), 2);
|
|
bStatus = TRUE;
|
|
break;
|
|
|
|
case VcrMode :
|
|
// Query the tape info & update the status bar
|
|
DV_UpdateTapeInfo();
|
|
// update the Graph Mode menu items & status window
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_ENABLED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_ENABLED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_ENABLED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
|
|
EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
|
|
bStatus = TRUE;
|
|
break;
|
|
|
|
case UnknownMode :
|
|
MBOX(TEXT("Cannot determine camera / VCR mode"));
|
|
DV_StatusText(TEXT("Unknown Mode"), 2);
|
|
break;
|
|
|
|
default :
|
|
MBOX(TEXT("Bad return value from DV_RefreshMode"));
|
|
break;
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_CapSizeDlgProc
|
|
Purpose: Dialog proc for cap size dialog
|
|
Arguments: Usual Dialog Processing parameters
|
|
Returns: BOOL
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
BOOL CALLBACK DV_CapSizeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch ( msg )
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
TCHAR capDisk[8];
|
|
ULARGE_INTEGER ulFreeBytes;
|
|
ULARGE_INTEGER ulTotalBytes;
|
|
ULARGE_INTEGER ulAvailBytes;
|
|
|
|
// make sure output file name has been input for capture
|
|
if (!g_OutputFileName[0])
|
|
{
|
|
MBOX(TEXT("Please set up an output file name for recording"));
|
|
EndDialog(hwnd, FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//need to determine disk space and init the dialog appropriately
|
|
StringCchCopyN(capDisk, NUMELMS(capDisk), g_OutputFileName, 3);
|
|
capDisk[4] = '\0';
|
|
GetDiskFreeSpaceEx(capDisk, &ulFreeBytes, &ulTotalBytes, &ulAvailBytes);
|
|
|
|
//let's see what our top limits are, and set our limits appropriately
|
|
if ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < 120)
|
|
{
|
|
//less than 120 MB available - subtract 10 MB at a time until we get a usable amount
|
|
UINT i = 110;
|
|
while ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < i)
|
|
{
|
|
i -= 10;
|
|
}
|
|
SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG(i / 4, 1));
|
|
SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG(i, 1));
|
|
}
|
|
else
|
|
{
|
|
SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG( ((ulAvailBytes.QuadPart / (1024 * 1024) ) - 10) / 4, 1));
|
|
SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG( (ulAvailBytes.QuadPart / (1024 * 1024) ) - 10, 1));
|
|
}
|
|
|
|
//enable / disable the controls as appropriate
|
|
switch (g_dwCaptureLimit)
|
|
{
|
|
case DV_CAPLIMIT_NONE :
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
|
|
break;
|
|
|
|
case DV_CAPLIMIT_TIME :
|
|
{
|
|
/*check the radio button, disable the size based controls */
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
|
|
|
|
break;
|
|
}
|
|
case DV_CAPLIMIT_SIZE :
|
|
{
|
|
/*check the radio button, disable the time based controls */
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
|
|
|
|
break;
|
|
}
|
|
}
|
|
SetDlgItemInt(hwnd, IDC_EDIT_TIME, g_dwTimeLimit, FALSE);
|
|
SetDlgItemInt(hwnd, IDC_EDIT_SIZE, g_dwDiskSpace, FALSE);
|
|
break;
|
|
}
|
|
case WM_COMMAND :
|
|
switch LOWORD(wParam)
|
|
{
|
|
// Update the controls ui according to the choices made
|
|
case IDC_RADIO_NOLIMIT :
|
|
{
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
|
|
break;
|
|
}
|
|
|
|
case IDC_RADIO_TIME :
|
|
{
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), TRUE);
|
|
break;
|
|
}
|
|
|
|
case IDC_RADIO_SIZE :
|
|
{
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), TRUE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), TRUE);
|
|
break;
|
|
}
|
|
|
|
case IDOK :
|
|
{
|
|
BOOL bTranslated = FALSE;
|
|
// The selections are made
|
|
// update the new global capture flag
|
|
if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT)))
|
|
{
|
|
g_dwCaptureLimit = DV_CAPLIMIT_NONE;
|
|
//DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("No capture size limit"));
|
|
}
|
|
else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME)))
|
|
{
|
|
g_dwTimeLimit = GetDlgItemInt(hwnd, IDC_EDIT_TIME, &bTranslated, FALSE);
|
|
g_dwCaptureLimit = DV_CAPLIMIT_TIME;
|
|
//DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Time based limit - %d"), g_dwTimeLimit);
|
|
}
|
|
else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE)))
|
|
{
|
|
g_dwDiskSpace = GetDlgItemInt(hwnd, IDC_EDIT_SIZE, &bTranslated, FALSE);
|
|
g_dwCaptureLimit = DV_CAPLIMIT_SIZE;
|
|
//DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Disk based limit - %d MB"), g_dwDiskSpace);
|
|
}
|
|
EndDialog(hwnd, TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
case IDCANCEL :
|
|
// update nothing much
|
|
EndDialog(hwnd, FALSE);
|
|
return FALSE;
|
|
|
|
default :
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_StopRecProc
|
|
Purpose: Callback to stop recording after a specified time
|
|
Arguments: Usual Timer Processing Parameters
|
|
Returns: None
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
void CALLBACK DV_StopRecProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
|
|
{
|
|
SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Routine: DV_AboutDlgProc
|
|
Purpose: simple standard about dialog box proc
|
|
Arguments: Usual Dialog Processing parameters
|
|
Returns: BOOL
|
|
Notes:
|
|
------------------------------------------------------------------------*/
|
|
BOOL CALLBACK DV_AboutDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch ( msg )
|
|
{
|
|
//the only command we process are those that close the dialog
|
|
case WM_COMMAND:
|
|
EndDialog(hwnd, TRUE);
|
|
return TRUE;
|
|
|
|
case WM_INITDIALOG:
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|