/**************************************************************************** * @doc INTERNAL DIALOGS * * @module WDMDialg.cpp | Source file for 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*)GetWindowLongPtr(hDlg,DWLP_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_PTR)pSV->m_pdwHelp); break; case WM_CONTEXTMENU: if (pSV->m_pdwHelp) WinHelp((HWND)wParam, TEXT("conf.hlp"), HELP_CONTEXTMENU, (DWORD_PTR)pSV->m_pdwHelp); break; case WM_INITDIALOG: { LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)lParam; pSV=(CWDMDialog*)psp->lParam; pSV->m_hDlg = hDlg; SetWindowLongPtr(hDlg,DWLP_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; }