443 lines
14 KiB
C++
443 lines
14 KiB
C++
|
|
/****************************************************************************
|
|
* @doc INTERNAL DIALOGS
|
|
*
|
|
* @module WDMDialg.cpp | Source file for <c CWDMDialog> class used to display
|
|
* video settings and camera controls dialog for WDM devices.
|
|
*
|
|
* @comm This code is based on the VfW to WDM mapper code written by
|
|
* FelixA and E-zu Wu. The original code can be found on
|
|
* \\redrum\slmro\proj\wdm10\\src\image\vfw\win9x\raytube.
|
|
*
|
|
* Documentation by George Shaw on kernel streaming can be found in
|
|
* \\popcorn\razzle1\src\spec\ks\ks.doc.
|
|
*
|
|
* WDM streaming capture is discussed by Jay Borseth in
|
|
* \\blues\public\jaybo\WDMVCap.doc.
|
|
***************************************************************************/
|
|
|
|
#include "Precomp.h"
|
|
|
|
// Globals
|
|
extern HINSTANCE g_hInst;
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc HPROPSHEETPAGE | CWDMDialog | Create | This function creates a new
|
|
* page for a property sheet.
|
|
*
|
|
* @rdesc Returns the handle to the new property sheet if successful, or
|
|
* NULL otherwise.
|
|
***************************************************************************/
|
|
HPROPSHEETPAGE CWDMDialog::Create()
|
|
{
|
|
PROPSHEETPAGE psp;
|
|
|
|
psp.dwSize = sizeof(psp);
|
|
psp.dwFlags = PSP_USEREFPARENT;
|
|
psp.hInstance = g_hInst;
|
|
psp.pszTemplate = MAKEINTRESOURCE(m_DlgID);
|
|
psp.pfnDlgProc = (DLGPROC)BaseDlgProc;
|
|
psp.pcRefParent = 0;
|
|
psp.pfnCallback = (LPFNPSPCALLBACK)NULL;
|
|
psp.lParam = (LPARAM)this;
|
|
|
|
return CreatePropertySheetPage(&psp);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc BOOL | CWDMDialog | BaseDlgProc | This function implements
|
|
* the dialog box procedure for the page of a property sheet.
|
|
*
|
|
* @parm HWND | hDlg | Handle to dialog box.
|
|
*
|
|
* @parm UINT | uMessage | Message sent to the dialog box.
|
|
*
|
|
* @parm WPARAM | wParam | First message parameter.
|
|
*
|
|
* @parm LPARAM | lParam | Second message parameter.
|
|
*
|
|
* @rdesc Except in response to the WM_INITDIALOG message, the dialog box
|
|
* procedure returns nonzero if it processes the message, and zero if it
|
|
* does not.
|
|
***************************************************************************/
|
|
BOOL CALLBACK CWDMDialog::BaseDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CWDMDialog * pSV = (CWDMDialog*)GetWindowLong(hDlg,DWL_USER);
|
|
|
|
FX_ENTRY("CWDMDialog::BaseDlgProc");
|
|
|
|
switch (uMessage)
|
|
{
|
|
case WM_HELP:
|
|
if (pSV->m_pdwHelp)
|
|
WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, TEXT("conf.hlp"), HELP_WM_HELP, (DWORD)pSV->m_pdwHelp);
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
if (pSV->m_pdwHelp)
|
|
WinHelp((HWND)wParam, TEXT("conf.hlp"), HELP_CONTEXTMENU, (DWORD)pSV->m_pdwHelp);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)lParam;
|
|
pSV=(CWDMDialog*)psp->lParam;
|
|
pSV->m_hDlg = hDlg;
|
|
SetWindowLong(hDlg,DWL_USER,(LPARAM)pSV);
|
|
pSV->m_bInit = FALSE;
|
|
pSV->m_bChanged = FALSE;
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (pSV)
|
|
{
|
|
int iRet = pSV->DoCommand(LOWORD(wParam), HIWORD(wParam));
|
|
if (!iRet && pSV->m_bInit)
|
|
{
|
|
PropSheet_Changed(GetParent(pSV->m_hDlg), pSV->m_hDlg);
|
|
pSV->m_bChanged = TRUE;
|
|
}
|
|
return iRet;
|
|
}
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
if (pSV && pSV->m_pCWDMPin && pSV->m_pPC)
|
|
{
|
|
HWND hwndControl = (HWND) lParam;
|
|
HWND hwndSlider;
|
|
ULONG i;
|
|
TCHAR szTemp[32];
|
|
|
|
for (i = 0 ; i < pSV->m_dwNumControls ; i++)
|
|
{
|
|
hwndSlider = GetDlgItem(pSV->m_hDlg, pSV->m_pPC[i].uiSlider);
|
|
|
|
// find matching slider
|
|
if (hwndSlider == hwndControl)
|
|
{
|
|
LONG lValue = (LONG)SendMessage(GetDlgItem(pSV->m_hDlg, pSV->m_pPC[i].uiSlider), TBM_GETPOS, 0, 0);
|
|
pSV->m_pCWDMPin->SetPropertyValue(pSV->m_guidPropertySet, pSV->m_pPC[i].uiProperty, lValue, KSPROPERTY_FLAGS_MANUAL, pSV->m_pPC[i].ulCapabilities);
|
|
pSV->m_pPC[i].lCurrentValue = lValue;
|
|
wsprintf(szTemp,"%d", lValue);
|
|
SetWindowText(GetDlgItem(pSV->m_hDlg, pSV->m_pPC[i].uiCurrent), szTemp);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
if (pSV)
|
|
{
|
|
switch (((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
{
|
|
// We call out here specially so we can mark this page as having been init'd.
|
|
int iRet = pSV->SetActive();
|
|
pSV->m_bInit = TRUE;
|
|
return iRet;
|
|
}
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
// Since we apply the changes on the fly when the user moves the slide bars,
|
|
// there isn't much left to do on PSN_APPLY...
|
|
if (pSV->m_bChanged)
|
|
pSV->m_bChanged = FALSE;
|
|
return FALSE;
|
|
break;
|
|
|
|
case PSN_QUERYCANCEL:
|
|
return pSV->QueryCancel();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc void | CWDMDialog | CWDMDialog | Property page class constructor.
|
|
*
|
|
* @parm int | DlgId | Resource ID of the property page dialog.
|
|
*
|
|
* @parm DWORD | dwNumControls | Number of controls to display in the page.
|
|
*
|
|
* @parm GUID | guidPropertySet | GUID of the KS property set we are showing in
|
|
* the property page.
|
|
*
|
|
* @parm PPROPSLIDECONTROL | pPC | Pointer to the list of slider controls
|
|
* to be displayed in the property page.
|
|
*
|
|
* @parm PDWORD | pdwHelp | Pointer to the list of help IDs to be displayed
|
|
* in the property page.
|
|
*
|
|
* @parm CWDMPin * | pCWDMPin | Pointer to the kernel streaming object
|
|
* we will query the property on.
|
|
***************************************************************************/
|
|
CWDMDialog::CWDMDialog(int DlgId, DWORD dwNumControls, GUID guidPropertySet, PPROPSLIDECONTROL pPC, PDWORD pdwHelp, CWDMPin *pCWDMPin)
|
|
{
|
|
FX_ENTRY("CWDMDialog::CWDMDialog");
|
|
|
|
ASSERT(dwNumControls);
|
|
ASSERT(pPC);
|
|
|
|
m_DlgID = DlgId;
|
|
m_pdwHelp = pdwHelp;
|
|
m_pCWDMPin = pCWDMPin;
|
|
m_dwNumControls = dwNumControls;
|
|
m_guidPropertySet = guidPropertySet;
|
|
m_pPC = pPC;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc int | CWDMDialog | SetActive | This function handles
|
|
* PSN_SETACTIVE by intializing all the property page controls.
|
|
*
|
|
* @rdesc Always returns 0.
|
|
***************************************************************************/
|
|
int CWDMDialog::SetActive()
|
|
{
|
|
FX_ENTRY("CWDMDialog::SetActive");
|
|
|
|
DEBUGMSG(ZONE_DIALOGS, ("%s()\n", _fx_));
|
|
|
|
if (!m_pCWDMPin || !m_pPC)
|
|
return 0;
|
|
|
|
// Returns zero to accept the activation or
|
|
// -1 to activate the next or previous page
|
|
// (depending on whether the user chose the Next or Back button)
|
|
LONG i;
|
|
EnableWindow(m_hDlg, TRUE);
|
|
|
|
if (m_bInit)
|
|
return 0;
|
|
|
|
LONG j, lValue, lMin, lMax, lStep;
|
|
ULONG ulCapabilities, ulFlags;
|
|
TCHAR szDisplay[256];
|
|
|
|
for (i = j = 0 ; i < (LONG)m_dwNumControls; i++)
|
|
{
|
|
// Get the current value
|
|
if (m_pCWDMPin->GetPropertyValue(m_guidPropertySet, m_pPC[i].uiProperty, &lValue, &ulFlags, &ulCapabilities))
|
|
{
|
|
LoadString(g_hInst, m_pPC[i].uiString, szDisplay, sizeof(szDisplay));
|
|
DEBUGMSG(ZONE_DIALOGS, ("%s: szDisplay = %s\n", _fx_, szDisplay));
|
|
SetWindowText(GetDlgItem(m_hDlg, m_pPC[i].uiStatic), szDisplay);
|
|
|
|
// Get the Range of Values possible.
|
|
if (m_pCWDMPin->GetRangeValues(m_guidPropertySet, m_pPC[i].uiProperty, &lMin, &lMax, &lStep))
|
|
{
|
|
HWND hTB = GetDlgItem(m_hDlg, m_pPC[i].uiSlider);
|
|
|
|
DEBUGMSG(ZONE_DIALOGS, ("(%d, %d) / %d = %d \n", lMin, lMax, lStep, (lMax-lMin)/lStep));
|
|
|
|
SendMessage(hTB, TBM_SETTICFREQ, (lMax-lMin)/lStep, 0);
|
|
SendMessage(hTB, TBM_SETRANGE, 0, MAKELONG(lMin, lMax));
|
|
}
|
|
else
|
|
{
|
|
ERRORMESSAGE(("%s:Cannot get range values for this property ID = %d\n", _fx_, m_pPC[j].uiProperty));
|
|
}
|
|
|
|
// Save these value for Cancel
|
|
m_pPC[i].lLastValue = m_pPC[i].lCurrentValue = lValue;
|
|
m_pPC[i].lMin = lMin;
|
|
m_pPC[i].lMax = lMax;
|
|
m_pPC[i].ulCapabilities = ulCapabilities;
|
|
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), TRUE);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiStatic), TRUE);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiAuto), TRUE);
|
|
|
|
SendMessage(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), TBM_SETPOS, TRUE, lValue);
|
|
wsprintf(szDisplay,"%d", lValue);
|
|
SetWindowText(GetDlgItem(m_hDlg, m_pPC[i].uiCurrent), szDisplay);
|
|
|
|
DEBUGMSG(ZONE_DIALOGS, ("%s: Capability = 0x%08lX; Flags=0x%08lX; lValue=%d\r\n", _fx_, ulCapabilities, ulFlags, lValue));
|
|
DEBUGMSG(ZONE_DIALOGS, ("%s: switch(%d): \n", _fx_, ulCapabilities & (KSPROPERTY_FLAGS_MANUAL | KSPROPERTY_FLAGS_AUTO)));
|
|
|
|
switch (ulCapabilities & (KSPROPERTY_FLAGS_MANUAL | KSPROPERTY_FLAGS_AUTO))
|
|
{
|
|
case KSPROPERTY_FLAGS_MANUAL:
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiAuto), FALSE); // Disable auto
|
|
break;
|
|
|
|
case KSPROPERTY_FLAGS_AUTO:
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), FALSE); // Disable slider;
|
|
// always auto!
|
|
SendMessage (GetDlgItem(m_hDlg, m_pPC[i].uiAuto),BM_SETCHECK, 1, 0);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiAuto), FALSE); // Disable auto (greyed out)
|
|
break;
|
|
|
|
case (KSPROPERTY_FLAGS_MANUAL | KSPROPERTY_FLAGS_AUTO):
|
|
// Set flags
|
|
if (ulFlags & KSPROPERTY_FLAGS_AUTO)
|
|
{
|
|
DEBUGMSG(ZONE_DIALOGS, ("%s: Auto (checked) and slider disabled\n", _fx_));
|
|
// Set auto check box; greyed out slider
|
|
SendMessage (GetDlgItem(m_hDlg, m_pPC[i].uiAuto),BM_SETCHECK, 1, 0);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), FALSE);
|
|
}
|
|
else
|
|
{
|
|
// Unchecked auto; enable slider
|
|
SendMessage (GetDlgItem(m_hDlg, m_pPC[i].uiAuto),BM_SETCHECK, 0, 0);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), TRUE);
|
|
}
|
|
break;
|
|
|
|
case 0:
|
|
default:
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), FALSE); // Disable slider; always auto!
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiAuto), FALSE); // Disable auto (greyed out)
|
|
break;
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), FALSE);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiStatic), FALSE);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiAuto), FALSE);
|
|
}
|
|
}
|
|
|
|
// Disable the "default" push button;
|
|
// or inform user that no control is enabled.
|
|
if (j == 0)
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_DEFAULT), FALSE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc int | CWDMDialog | DoCommand | This function handles WM_COMMAND. This
|
|
* is where a click on the Default button or one of the Auto checkboxes
|
|
* is handled
|
|
*
|
|
* @parm WORD | wCmdID | Command ID.
|
|
*
|
|
* @parm WORD | hHow | Notification code.
|
|
*
|
|
* @rdesc Always returns 1.
|
|
***************************************************************************/
|
|
int CWDMDialog::DoCommand(WORD wCmdID, WORD hHow)
|
|
{
|
|
// If a user select default settings of the video format
|
|
if (wCmdID == IDC_DEFAULT)
|
|
{
|
|
if (m_pCWDMPin && m_pPC)
|
|
{
|
|
HWND hwndSlider;
|
|
LONG lDefValue;
|
|
TCHAR szTemp[32];
|
|
|
|
for (ULONG i = 0 ; i < m_dwNumControls ; i++)
|
|
{
|
|
hwndSlider = GetDlgItem(m_hDlg, m_pPC[i].uiSlider);
|
|
|
|
if (IsWindowEnabled(hwndSlider))
|
|
{
|
|
if (m_pCWDMPin->GetDefaultValue(m_guidPropertySet, m_pPC[i].uiProperty, &lDefValue))
|
|
{
|
|
if (lDefValue != m_pPC[i].lCurrentValue)
|
|
{
|
|
m_pCWDMPin->SetPropertyValue(m_guidPropertySet,m_pPC[i].uiProperty, lDefValue, KSPROPERTY_FLAGS_MANUAL, m_pPC[i].ulCapabilities);
|
|
SendMessage(hwndSlider, TBM_SETPOS, TRUE, lDefValue);
|
|
wsprintf(szTemp,"%d", lDefValue);
|
|
SetWindowText(GetDlgItem(m_hDlg, m_pPC[i].uiCurrent), szTemp);
|
|
m_pPC[i].lCurrentValue = lDefValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
else if (hHow == BN_CLICKED)
|
|
{
|
|
if (m_pCWDMPin && m_pPC)
|
|
{
|
|
for (ULONG i = 0 ; i < m_dwNumControls ; i++)
|
|
{
|
|
// find matching slider
|
|
if (m_pPC[i].uiAuto == wCmdID)
|
|
{
|
|
if (BST_CHECKED == SendMessage (GetDlgItem(m_hDlg, m_pPC[i].uiAuto),BM_GETCHECK, 1, 0))
|
|
{
|
|
m_pCWDMPin->SetPropertyValue(m_guidPropertySet,m_pPC[i].uiProperty, m_pPC[i].lCurrentValue, KSPROPERTY_FLAGS_AUTO, m_pPC[i].ulCapabilities);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), FALSE);
|
|
}
|
|
else
|
|
{
|
|
m_pCWDMPin->SetPropertyValue(m_guidPropertySet,m_pPC[i].uiProperty, m_pPC[i].lCurrentValue, KSPROPERTY_FLAGS_MANUAL, m_pPC[i].ulCapabilities);
|
|
EnableWindow(GetDlgItem(m_hDlg, m_pPC[i].uiSlider), TRUE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* @doc INTERNAL CWDMDIALOGMETHOD
|
|
*
|
|
* @mfunc int | CWDMDialog | QueryCancel | This function handles
|
|
* PSN_QUERYCANCEL by resetting the values of the controls.
|
|
*
|
|
* @rdesc Always returns 0.
|
|
***************************************************************************/
|
|
int CWDMDialog::QueryCancel()
|
|
{
|
|
if (m_pCWDMPin && m_pPC)
|
|
{
|
|
for (ULONG i = 0 ; i < m_dwNumControls ; i++)
|
|
{
|
|
if (IsWindowEnabled(GetDlgItem(m_hDlg, m_pPC[i].uiSlider)))
|
|
{
|
|
if (m_pPC[i].lLastValue != m_pPC[i].lCurrentValue)
|
|
m_pCWDMPin->SetPropertyValue(m_guidPropertySet,m_pPC[i].uiProperty, m_pPC[i].lLastValue, KSPROPERTY_FLAGS_MANUAL, m_pPC[i].ulCapabilities);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|