Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1233 lines
37 KiB

  1. /****************************************************************************
  2. * @doc INTERNAL AudRecP
  3. *
  4. * @module CaptureP.cpp | Source file for the <c CAudRecProperty>
  5. * class used to implement a property page to test the TAPI control
  6. * interfaces <i ITFormatControl> and <i ITQualityControl>.
  7. ***************************************************************************/
  8. #include "Precomp.h"
  9. extern HINSTANCE ghInst;
  10. /****************************************************************************
  11. * @doc INTERNAL CAUDRECPMETHOD
  12. *
  13. * @mfunc void | CAudRecProperty | CAudRecProperty | This
  14. * method is the constructor for bitrate property object. It
  15. * calls the base class constructor, calls InitCommonControlsEx, and saves
  16. * pointers to the <i ITQualityControl> interfaces.
  17. *
  18. * @parm HWND | hDlg | Specifies a handle to the parent property page.
  19. *
  20. * @parm ULONG | IDLabel | Specifies a label ID for the property.
  21. *
  22. * @parm ULONG | IDMinControl | Specifies a label ID for the associated
  23. * property edit control where the Minimum value of the property appears.
  24. *
  25. * @parm ULONG | IDMaxControl | Specifies a label ID for the associated
  26. * property edit control where the Maximum value of the property appears.
  27. *
  28. * @parm ULONG | IDDefaultControl | Specifies a label ID for the associated
  29. * property edit control where the Default value of the property appears.
  30. *
  31. * @parm ULONG | IDStepControl | Specifies a label ID for the associated
  32. * property edit control where the Stepping Delta value of the property appears.
  33. *
  34. * @parm ULONG | IDEditControl | Specifies a label ID for the associated
  35. * property edit control where the value of the property appears.
  36. *
  37. * @parm ULONG | IDTrackbarControl | Specifies a label ID for the associated
  38. * property slide bar.
  39. *
  40. * @parm ULONG | IDProgressControl | Specifies a label ID for the associated
  41. * property slide bar.
  42. *
  43. * @parm ULONG | IDProperty | Specifies the ID of the Ks property.
  44. *
  45. * @parm ITQualityControl* | pITQualityControl | Specifies a pointer to the
  46. * <i ITQualityControl> interface.
  47. *
  48. * @rdesc Nada.
  49. ***************************************************************************/
  50. CAudRecProperty::CAudRecProperty(
  51. HWND hDlg,
  52. CONTROL_DESCRIPTION &ControlDescription
  53. )
  54. : CPropertyEditor(
  55. hDlg,
  56. ControlDescription.IDLabel,
  57. ControlDescription.IDMinControl,
  58. ControlDescription.IDMaxControl,
  59. ControlDescription.IDDefaultControl,
  60. ControlDescription.IDStepControl,
  61. ControlDescription.IDEditControl,
  62. ControlDescription.IDTrackbarControl,
  63. ControlDescription.IDProgressControl,
  64. ControlDescription.IDProperty,
  65. 0)
  66. {
  67. INITCOMMONCONTROLSEX cc;
  68. FX_ENTRY("CAudRecProperty::CAudRecProperty")
  69. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  70. cc.dwSize = sizeof (INITCOMMONCONTROLSEX);
  71. cc.dwICC = ICC_UPDOWN_CLASS | ICC_BAR_CLASSES;
  72. InitCommonControlsEx(&cc);
  73. // It's fine if the interface pointers are NULL, we'll grey the
  74. // associated items in the property page
  75. m_pITQualityControl = ControlDescription.pITQualityControl;
  76. m_pITAudioSettings = ControlDescription.pITAudioSettings;
  77. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  78. }
  79. /****************************************************************************
  80. * @doc INTERNAL CAUDRECPMETHOD
  81. *
  82. * @mfunc void | CAudRecProperty | ~CAudRecProperty | This
  83. * method is the destructor for capture property objects. It
  84. * simply calls the base class destructor.
  85. *
  86. * @rdesc Nada.
  87. ***************************************************************************/
  88. CAudRecProperty::~CAudRecProperty()
  89. {
  90. FX_ENTRY("CAudRecProperty::~CAudRecProperty")
  91. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  92. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  93. }
  94. /****************************************************************************
  95. * @doc INTERNAL CAUDRECPMETHOD
  96. *
  97. * @mfunc HRESULT | CAudRecProperty | GetValue | This method queries for
  98. * the value of a property.
  99. *
  100. * @rdesc This method returns an HRESULT value that depends on the
  101. * implementation of the interface. HRESULT can include one of the
  102. * following standard constants, or other values not listed:
  103. *
  104. * @flag E_FAIL | Failure
  105. * @flag E_POINTER | Null pointer argument
  106. * @flag E_NOTIMPL | Method is not supported
  107. * @flag NOERROR | No error
  108. ***************************************************************************/
  109. HRESULT CAudRecProperty::GetValue()
  110. {
  111. HRESULT Hr = E_NOTIMPL;
  112. LONG CurrentValue;
  113. TAPIControlFlags CurrentFlag;
  114. LONG Mode;
  115. FX_ENTRY("CAudRecProperty::GetValue")
  116. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  117. switch (m_IDProperty)
  118. {
  119. case IDC_Record_Bitrate:
  120. /*
  121. if (m_pITQualityControl)
  122. {
  123. Hr = m_pITQualityControl->Get(Quality_MaxBitrate, &m_CurrentValue, &CurrentFlag);
  124. }
  125. */
  126. break;
  127. case IDC_Record_Volume:
  128. if (m_pITAudioSettings)
  129. {
  130. Hr = m_pITAudioSettings->Get(AudioSettings_Volume, &m_CurrentValue, (TAPIControlFlags*)&CurrentFlag);
  131. }
  132. break;
  133. case IDC_Record_AudioLevel:
  134. if (m_pITAudioSettings)
  135. {
  136. Hr = m_pITAudioSettings->Get(AudioSettings_SignalLevel, &m_CurrentValue, (TAPIControlFlags*)&CurrentFlag);
  137. }
  138. break;
  139. case IDC_Record_SilenceLevel:
  140. if (m_pITAudioSettings)
  141. {
  142. Hr = m_pITAudioSettings->Get(AudioSettings_SilenceThreshold, &m_CurrentValue, (TAPIControlFlags*)&CurrentFlag);
  143. }
  144. break;
  145. case IDC_Record_SilenceDetection:
  146. m_CurrentValue = 1;
  147. CurrentFlag = TAPIControl_Flags_None;
  148. break;
  149. case IDC_Record_SilenceCompression:
  150. m_CurrentValue = 0;
  151. CurrentFlag = TAPIControl_Flags_None;
  152. break;
  153. default:
  154. Hr = E_UNEXPECTED;
  155. }
  156. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  157. return Hr;
  158. }
  159. /****************************************************************************
  160. * @doc INTERNAL CAUDRECPMETHOD
  161. *
  162. * @mfunc HRESULT | CAudRecProperty | SetValue | This method sets the
  163. * value of a property.
  164. *
  165. * @rdesc This method returns an HRESULT value that depends on the
  166. * implementation of the interface. HRESULT can include one of the
  167. * following standard constants, or other values not listed:
  168. *
  169. * @flag E_FAIL | Failure
  170. * @flag E_POINTER | Null pointer argument
  171. * @flag E_NOTIMPL | Method is not supported
  172. * @flag NOERROR | No error
  173. ***************************************************************************/
  174. HRESULT CAudRecProperty::SetValue()
  175. {
  176. HRESULT Hr = E_NOTIMPL;
  177. LONG CurrentValue;
  178. FX_ENTRY("CAudRecProperty::SetValue")
  179. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  180. switch (m_IDProperty)
  181. {
  182. case IDC_Record_Bitrate:
  183. /*
  184. if (m_pITQualityControl)
  185. {
  186. Hr = m_pITQualityControl->Set(Quality_MaxBitrate, m_CurrentValue, TAPIControl_Flags_None);
  187. }
  188. */
  189. break;
  190. case IDC_Record_Volume:
  191. if (m_pITAudioSettings)
  192. {
  193. Hr = m_pITAudioSettings->Set(AudioSettings_Volume, m_CurrentValue, TAPIControl_Flags_None);
  194. }
  195. break;
  196. case IDC_Record_AudioLevel:
  197. Hr = S_OK;
  198. break;
  199. case IDC_Record_SilenceLevel:
  200. if (m_pITAudioSettings)
  201. {
  202. Hr = m_pITAudioSettings->Set(AudioSettings_SilenceThreshold, m_CurrentValue, TAPIControl_Flags_None);
  203. }
  204. break;
  205. case IDC_Record_SilenceDetection:
  206. // TODO: enable silence suppression.
  207. Hr = S_OK;
  208. break;
  209. case IDC_Record_SilenceCompression:
  210. // TODO: enable silence compression.
  211. Hr = S_OK;
  212. break;
  213. default:
  214. Hr = E_UNEXPECTED;
  215. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Unknown capture property"), _fx_));
  216. }
  217. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  218. return Hr;
  219. }
  220. /****************************************************************************
  221. * @doc INTERNAL CAUDRECPMETHOD
  222. *
  223. * @mfunc HRESULT | CAudRecProperty | GetRange | This method retrieves
  224. * the range information of a property.
  225. *
  226. * @rdesc This method returns an HRESULT value that depends on the
  227. * implementation of the interface. HRESULT can include one of the
  228. * following standard constants, or other values not listed:
  229. *
  230. * @flag E_FAIL | Failure
  231. * @flag E_POINTER | Null pointer argument
  232. * @flag E_NOTIMPL | Method is not supported
  233. * @flag NOERROR | No error
  234. ***************************************************************************/
  235. HRESULT CAudRecProperty::GetRange()
  236. {
  237. HRESULT Hr = E_NOTIMPL;
  238. LONG Min;
  239. LONG Max;
  240. LONG SteppingDelta;
  241. LONG Default;
  242. LONG Flags;
  243. FX_ENTRY("CAudRecProperty::GetRange")
  244. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  245. switch (m_IDProperty)
  246. {
  247. case IDC_Record_Bitrate:
  248. /*
  249. if (m_pITQualityControl)
  250. {
  251. Hr = m_pITQualityControl->GetRange(Quality_MaxBitrate, &m_Min, &m_Max, &m_SteppingDelta, &m_DefaultValue, &m_CapsFlags);
  252. }
  253. */
  254. break;
  255. case IDC_Record_Volume:
  256. if (m_pITAudioSettings)
  257. {
  258. Hr = m_pITAudioSettings->GetRange(AudioSettings_Volume, &m_Min, &m_Max, &m_SteppingDelta, &m_DefaultValue, (TAPIControlFlags *)&m_CapsFlags);
  259. }
  260. break;
  261. case IDC_Record_AudioLevel:
  262. if (m_pITAudioSettings)
  263. {
  264. Hr = m_pITAudioSettings->GetRange(AudioSettings_SignalLevel, &m_Min, &m_Max, &m_SteppingDelta, &m_DefaultValue, (TAPIControlFlags *)&m_CapsFlags);
  265. }
  266. break;
  267. case IDC_Record_SilenceLevel:
  268. if (m_pITAudioSettings)
  269. {
  270. Hr = m_pITAudioSettings->GetRange(AudioSettings_SilenceThreshold, &m_Min, &m_Max, &m_SteppingDelta, &m_DefaultValue, (TAPIControlFlags *)&m_CapsFlags);
  271. }
  272. break;
  273. case IDC_Record_SilenceDetection:
  274. Hr = S_OK;
  275. break;
  276. case IDC_Record_SilenceCompression:
  277. Hr = S_OK;
  278. break;
  279. default:
  280. Hr = E_UNEXPECTED;
  281. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Unknown capture property"), _fx_));
  282. }
  283. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  284. return Hr;
  285. }
  286. /****************************************************************************
  287. * @doc INTERNAL CAUDRECPMETHOD
  288. *
  289. * @mfunc HPROPSHEETPAGE | CAudRecProperties | OnCreate | This
  290. * method creates a new page for a property sheet.
  291. *
  292. * @rdesc Returns the handle to the new property sheet if successful, or
  293. * NULL otherwise.
  294. ***************************************************************************/
  295. HPROPSHEETPAGE CAudRecProperties::OnCreate()
  296. {
  297. PROPSHEETPAGE psp;
  298. psp.dwSize = sizeof(psp);
  299. psp.dwFlags = PSP_USEREFPARENT;
  300. psp.hInstance = ghInst;
  301. psp.pszTemplate = MAKEINTRESOURCE(IDD_RecordFormatProperties);
  302. psp.pfnDlgProc = BaseDlgProc;
  303. psp.pcRefParent = 0;
  304. psp.pfnCallback = (LPFNPSPCALLBACK)NULL;
  305. psp.lParam = (LPARAM)this;
  306. return CreatePropertySheetPage(&psp);
  307. }
  308. /****************************************************************************
  309. * @doc INTERNAL CAUDRECPMETHOD
  310. *
  311. * @mfunc void | CAudRecProperties | CAudRecProperties | This
  312. * method is the constructor for the property page object. It simply
  313. * calls the constructor of the property page base class.
  314. *
  315. * @rdesc Nada.
  316. ***************************************************************************/
  317. CAudRecProperties::CAudRecProperties()
  318. {
  319. FX_ENTRY("CAudRecProperties::CAudRecProperties")
  320. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  321. m_pITQualityControl = NULL;
  322. m_pITQualityControl = NULL;
  323. m_pITFormatControl = NULL;
  324. m_NumProperties = NUM_AUDREC_CONTROLS;
  325. m_hWndFormat = m_hDlg = NULL;
  326. m_RangeCount = 0;
  327. m_SubTypeList = NULL;
  328. m_CurrentMediaType = NULL;
  329. m_CurrentFormat = 0;
  330. m_OriginalFormat = 0;
  331. for (int i = 0; i < m_NumProperties; i++)
  332. m_Controls[i] = NULL;
  333. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  334. }
  335. /****************************************************************************
  336. * @doc INTERNAL CAUDRECPMETHOD
  337. *
  338. * @mfunc void | CAudRecProperties | ~CAudRecProperties | This
  339. * method is the destructor for the capture pin property page. It
  340. * simply calls the base class destructor after deleting all the controls.
  341. *
  342. * @rdesc Nada.
  343. ***************************************************************************/
  344. CAudRecProperties::~CAudRecProperties()
  345. {
  346. int j;
  347. FX_ENTRY("CAudRecProperties::~CAudRecProperties")
  348. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  349. // Free the controls
  350. for (j = 0; j < m_NumProperties; j++)
  351. {
  352. if (m_Controls[j])
  353. {
  354. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: deleting m_Controls[%ld]=0x%08lX"), _fx_, j, m_Controls[j]));
  355. delete m_Controls[j], m_Controls[j] = NULL;
  356. }
  357. else
  358. {
  359. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: control already freed"), _fx_));
  360. }
  361. }
  362. if (m_SubTypeList)
  363. delete[] m_SubTypeList, m_SubTypeList = NULL;
  364. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  365. }
  366. /****************************************************************************
  367. * @doc INTERNAL CAUDRECPMETHOD
  368. *
  369. * @mfunc HRESULT | CAudRecProperties | OnConnect | This
  370. * method is called when the property page is connected to a TAPI object.
  371. *
  372. * @parm ITStream* | pStream | Specifies a pointer to the <i ITStream>
  373. * interface. It is used to QI for the <i ITQualityControl> and
  374. * <i ITFormatControl> interfaces.
  375. *
  376. * @rdesc This method returns an HRESULT value that depends on the
  377. * implementation of the interface. HRESULT can include one of the
  378. * following standard constants, or other values not listed:
  379. *
  380. * @flag E_FAIL | Failure
  381. * @flag E_POINTER | Null pointer argument
  382. * @flag E_NOTIMPL | Method is not supported
  383. * @flag NOERROR | No error
  384. ***************************************************************************/
  385. HRESULT CAudRecProperties::OnConnect(ITStream *pStream)
  386. {
  387. HRESULT Hr = NOERROR;
  388. FX_ENTRY("CAudRecProperties::OnConnect")
  389. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  390. // Validate input parameters
  391. if (!pStream)
  392. {
  393. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: invalid input parameter"), _fx_));
  394. Hr = E_POINTER;
  395. goto MyExit;
  396. }
  397. // Get the quality control interface
  398. if (SUCCEEDED (Hr = pStream->QueryInterface(__uuidof(ITStreamQualityControl), (void **)&m_pITQualityControl)))
  399. {
  400. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: m_pITQualityControl=0x%08lX"), _fx_, m_pITQualityControl));
  401. }
  402. else
  403. {
  404. m_pITQualityControl = NULL;
  405. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Failed Hr=0x%08lX"), _fx_, Hr));
  406. }
  407. // Get the format control interface
  408. if (SUCCEEDED (Hr = pStream->QueryInterface(__uuidof(ITFormatControl), (void **)&m_pITFormatControl)))
  409. {
  410. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: m_pITFormatControl=0x%08lX"), _fx_, m_pITFormatControl));
  411. }
  412. else
  413. {
  414. m_pITFormatControl = NULL;
  415. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Failed Hr=0x%08lX"), _fx_, Hr));
  416. }
  417. // Get the audio settings interface
  418. if (SUCCEEDED (Hr = pStream->QueryInterface(__uuidof(ITAudioSettings), (void **)&m_pITAudioSettings)))
  419. {
  420. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: m_pITAudioSettings=0x%08lX"), _fx_, m_pITAudioSettings));
  421. }
  422. else
  423. {
  424. m_pITAudioSettings = NULL;
  425. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Failed Hr=0x%08lX"), _fx_, Hr));
  426. }
  427. // It's Ok if we couldn't get interface pointers
  428. // We'll just grey the controls in the property page
  429. // to make it clear to the user that they can't
  430. // control those properties on the capture device
  431. Hr = NOERROR;
  432. MyExit:
  433. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  434. return Hr;
  435. }
  436. /****************************************************************************
  437. * @doc INTERNAL CAUDRECPMETHOD
  438. *
  439. * @mfunc HRESULT | CAudRecProperties | OnDisconnect | This
  440. * method is called when the property page is disconnected from the owning
  441. * filter.
  442. *
  443. * @rdesc This method returns an HRESULT value that depends on the
  444. * implementation of the interface. HRESULT can include one of the
  445. * following standard constants, or other values not listed:
  446. *
  447. * @flag NOERROR | No error
  448. ***************************************************************************/
  449. HRESULT CAudRecProperties::OnDisconnect()
  450. {
  451. FX_ENTRY("CAudRecProperties::OnDisconnect")
  452. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  453. // Validate input parameters
  454. if (!m_pITQualityControl)
  455. {
  456. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: already disconnected!"), _fx_));
  457. }
  458. else
  459. {
  460. // Release the interface
  461. m_pITQualityControl->Release();
  462. m_pITQualityControl = NULL;
  463. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: releasing m_pITQualityControl"), _fx_));
  464. }
  465. if (!m_pITFormatControl)
  466. {
  467. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: already disconnected!"), _fx_));
  468. }
  469. else
  470. {
  471. // Release the interface
  472. m_pITFormatControl->Release();
  473. m_pITFormatControl = NULL;
  474. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: releasing m_pITFormatControl"), _fx_));
  475. }
  476. if (!m_pITAudioSettings)
  477. {
  478. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: already disconnected!"), _fx_));
  479. }
  480. else
  481. {
  482. // Release the interface
  483. m_pITAudioSettings->Release();
  484. m_pITAudioSettings = NULL;
  485. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: releasing m_pITFormatControl"), _fx_));
  486. }
  487. // Release format memory
  488. if (m_CurrentMediaType)
  489. {
  490. DeleteAMMediaType(m_CurrentMediaType);
  491. m_CurrentMediaType = NULL;
  492. }
  493. if (m_SubTypeList)
  494. delete[] m_SubTypeList, m_SubTypeList = NULL;
  495. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  496. return NOERROR;
  497. }
  498. /****************************************************************************
  499. * @doc INTERNAL CAUDRECPMETHOD
  500. *
  501. * @mfunc HRESULT | CAudRecProperties | OnActivate | This
  502. * method is called when the property page is activated.
  503. *
  504. * @rdesc This method returns an HRESULT value that depends on the
  505. * implementation of the interface. HRESULT can include one of the
  506. * following standard constants, or other values not listed:
  507. *
  508. * @flag E_FAIL | Failure
  509. * @flag E_POINTER | Null pointer argument
  510. * @flag E_NOTIMPL | Method is not supported
  511. * @flag NOERROR | No error
  512. ***************************************************************************/
  513. HRESULT CAudRecProperties::OnActivate()
  514. {
  515. HRESULT Hr = NOERROR;
  516. DWORD dw;
  517. int j;
  518. FX_ENTRY("CAudRecProperties::OnActivate")
  519. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  520. // Initialize format control structures
  521. m_hWndFormat = GetDlgItem(m_hDlg, IDC_FORMAT_Compression);
  522. // Disable everything if we didn't initialize correctly
  523. if (!m_pITFormatControl || (FAILED (Hr = InitialRangeScan())))
  524. {
  525. EnableWindow(m_hWndFormat, FALSE);
  526. }
  527. else
  528. {
  529. // Update the content of the format combo box
  530. ComboBox_ResetContent(m_hWndFormat);
  531. for (dw = 0; dw < m_RangeCount; dw++)
  532. {
  533. CMediaType *pmt = NULL;
  534. BOOL fEnabled; // Is this format currently enabled (according to the H.245 capability resolver)
  535. Hr = m_pITFormatControl->GetStreamCaps(dw, (AM_MEDIA_TYPE **)&pmt, &m_RangeCaps, &fEnabled);
  536. if (FAILED(Hr))
  537. {
  538. break;
  539. }
  540. DeleteAMMediaType(pmt);
  541. ComboBox_AddString(m_hWndFormat, m_RangeCaps.AudioCap.Description);
  542. if (m_CurrentMediaType->subtype == m_SubTypeList[dw])
  543. {
  544. ComboBox_SetCurSel(m_hWndFormat, dw);
  545. m_SubTypeCurrent = m_SubTypeList[dw];
  546. }
  547. }
  548. // Update current format
  549. OnFormatChanged();
  550. // Remember the original format
  551. m_OriginalFormat = m_CurrentFormat;
  552. }
  553. CONTROL_DESCRIPTION Controls[NUM_AUDREC_CONTROLS] =
  554. {
  555. {
  556. IDC_BitrateControl_Label,
  557. IDC_BitrateControl_Minimum,
  558. IDC_BitrateControl_Maximum,
  559. IDC_BitrateControl_Default,
  560. IDC_BitrateControl_Stepping,
  561. IDC_BitrateControl_Edit,
  562. IDC_BitrateControl_Slider,
  563. 0,
  564. IDC_Record_Bitrate,
  565. m_pITQualityControl,
  566. m_pITAudioSettings,
  567. },
  568. {
  569. IDC_VolumeLevel_Label,
  570. IDC_VolumeLevel_Minimum,
  571. IDC_VolumeLevel_Maximum,
  572. IDC_VolumeLevel_Default,
  573. IDC_VolumeLevel_Stepping,
  574. IDC_VolumeLevel_Edit,
  575. IDC_VolumeLevel_Slider,
  576. IDC_VolumeLevel_Meter,
  577. IDC_Record_Volume,
  578. m_pITQualityControl,
  579. m_pITAudioSettings,
  580. },
  581. {
  582. IDC_AudioLevel_Label,
  583. IDC_AudioLevel_Minimum,
  584. IDC_AudioLevel_Maximum,
  585. IDC_AudioLevel_Default,
  586. IDC_AudioLevel_Stepping,
  587. IDC_AudioLevel_Edit,
  588. IDC_AudioLevel_Slider,
  589. IDC_AudioLevel_Meter,
  590. IDC_Record_AudioLevel,
  591. m_pITQualityControl,
  592. m_pITAudioSettings,
  593. },
  594. {
  595. IDC_SilenceLevel_Label,
  596. IDC_SilenceLevel_Minimum,
  597. IDC_SilenceLevel_Maximum,
  598. IDC_SilenceLevel_Default,
  599. IDC_SilenceLevel_Stepping,
  600. IDC_SilenceLevel_Edit,
  601. IDC_SilenceLevel_Slider,
  602. IDC_SilenceLevel_Meter,
  603. IDC_Record_SilenceLevel,
  604. m_pITQualityControl,
  605. m_pITAudioSettings,
  606. },
  607. {
  608. 0,
  609. 0,
  610. 0,
  611. 0,
  612. 0,
  613. 0,
  614. 0,
  615. 0,
  616. IDC_Record_SilenceDetection,
  617. m_pITQualityControl,
  618. m_pITAudioSettings,
  619. },
  620. {
  621. 0,
  622. 0,
  623. 0,
  624. 0,
  625. 0,
  626. 0,
  627. 0,
  628. 0,
  629. IDC_Record_SilenceCompression,
  630. m_pITQualityControl,
  631. m_pITAudioSettings,
  632. }
  633. };
  634. for (int i = 0; i < NUM_AUDREC_CONTROLS; i ++)
  635. {
  636. m_Controls[i] = new CAudRecProperty(m_hDlg, Controls[i]);
  637. if (m_Controls[i] == NULL)
  638. {
  639. for (int j = 0; j < i; j ++)
  640. {
  641. delete m_Controls[j];
  642. m_Controls[j] = NULL;
  643. }
  644. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: Out of memory"), _fx_));
  645. Hr = E_OUTOFMEMORY;
  646. goto MyExit;
  647. }
  648. }
  649. // Initialize all the controls. If the initialization fails, it's Ok. It just means
  650. // that the TAPI control interface isn't implemented by the device. The dialog item
  651. // in the property page will be greyed, showing this to the user.
  652. for (j = 0; j < m_NumProperties; j++)
  653. {
  654. if (m_Controls[j]->Init())
  655. {
  656. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: m_Controls[%ld]->Init()"), _fx_, j));
  657. }
  658. else
  659. {
  660. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: m_Controls[%ld]->Init() failed"), _fx_, j));
  661. }
  662. }
  663. MyExit:
  664. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  665. return Hr;
  666. }
  667. /****************************************************************************
  668. * @doc INTERNAL CAUDRECPMETHOD
  669. *
  670. * @mfunc HRESULT | CAudRecProperties | OnDeactivate | This
  671. * method is called when the property page is dismissed.
  672. *
  673. * @rdesc This method returns an HRESULT value that depends on the
  674. * implementation of the interface. HRESULT can include one of the
  675. * following standard constants, or other values not listed:
  676. *
  677. * @flag NOERROR | No error
  678. ***************************************************************************/
  679. HRESULT CAudRecProperties::OnDeactivate()
  680. {
  681. int j;
  682. FX_ENTRY("CAudRecProperties::OnDeactivate")
  683. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  684. // Free the controls
  685. for (j = 0; j < m_NumProperties; j++)
  686. {
  687. if (m_Controls[j])
  688. {
  689. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: deleting m_Controls[%ld]=0x%08lX"), _fx_, j, m_Controls[j]));
  690. delete m_Controls[j], m_Controls[j] = NULL;
  691. }
  692. else
  693. {
  694. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: WARNING: control already freed"), _fx_));
  695. }
  696. }
  697. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  698. return NOERROR;
  699. }
  700. /****************************************************************************
  701. * @doc INTERNAL CAUDRECPMETHOD
  702. *
  703. * @mfunc HRESULT | CAudRecProperties | GetCurrentMediaType | This
  704. * method is used to retrieve the current media format used by the pin.
  705. *
  706. * @rdesc This method returns an HRESULT value that depends on the
  707. * implementation of the interface. HRESULT can include one of the
  708. * following standard constants, or other values not listed:
  709. *
  710. * @flag NOERROR | No error
  711. ***************************************************************************/
  712. HRESULT CAudRecProperties::GetCurrentMediaType(void)
  713. {
  714. HRESULT Hr = NOERROR;
  715. FX_ENTRY("CAudRecProperties::GetCurrentMediaType")
  716. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  717. if (m_CurrentMediaType)
  718. {
  719. DeleteAMMediaType(m_CurrentMediaType);
  720. m_CurrentMediaType = NULL;
  721. }
  722. if (FAILED (Hr = m_pITFormatControl->GetCurrentFormat((AM_MEDIA_TYPE **)&m_CurrentMediaType)))
  723. {
  724. // Otherwise, just get the first enumerated media type
  725. TAPI_STREAM_CONFIG_CAPS RangeCaps;
  726. BOOL fEnabled; // Is this format currently enabled (according to the H.245 capability resolver)
  727. if (FAILED (Hr = m_pITFormatControl->GetStreamCaps(0, (AM_MEDIA_TYPE **)&m_CurrentMediaType, &RangeCaps, &fEnabled)))
  728. {
  729. m_CurrentMediaType = NULL;
  730. }
  731. }
  732. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  733. return Hr;
  734. }
  735. /****************************************************************************
  736. * @doc INTERNAL CAUDRECPMETHOD
  737. *
  738. * @mfunc HRESULT | CAudRecProperties | DeleteAMMediaType | This
  739. * method is used to delete a task-allocated AM_MEDIA_TYPE structure.
  740. *
  741. * @rdesc This method returns an HRESULT value that depends on the
  742. * implementation of the interface. HRESULT can include one of the
  743. * following standard constants, or other values not listed:
  744. *
  745. * @flag NOERROR | No error
  746. *
  747. * @comm There is a DShow DeleteMediaType, but it'd be pretty dumb to link to
  748. * strmbase.lib just for this little guy, would it?
  749. ***************************************************************************/
  750. HRESULT CAudRecProperties::DeleteAMMediaType(AM_MEDIA_TYPE *pAMMT)
  751. {
  752. HRESULT Hr = NOERROR;
  753. FX_ENTRY("CAudRecProperties::DeleteAMMediaType")
  754. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  755. if (pAMMT)
  756. {
  757. if (pAMMT->cbFormat != 0 && pAMMT->pbFormat)
  758. {
  759. CoTaskMemFree((PVOID)pAMMT->pbFormat);
  760. }
  761. if (pAMMT->pUnk != NULL)
  762. {
  763. pAMMT->pUnk->Release();
  764. }
  765. }
  766. CoTaskMemFree((PVOID)pAMMT);
  767. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  768. return Hr;
  769. }
  770. /****************************************************************************
  771. * @doc INTERNAL CAUDRECPMETHOD
  772. *
  773. * @mfunc HRESULT | CAudRecProperties | OnFormatChanged | This
  774. * method is used to retrieve the format selected by the user.
  775. *
  776. * @rdesc This method returns an HRESULT value that depends on the
  777. * implementation of the interface. HRESULT can include one of the
  778. * following standard constants, or other values not listed:
  779. *
  780. * @flag NOERROR | No error
  781. ***************************************************************************/
  782. HRESULT CAudRecProperties::OnFormatChanged()
  783. {
  784. HRESULT Hr = E_UNEXPECTED;
  785. DWORD dw;
  786. FX_ENTRY("CAudRecProperties::OnFormatChanged")
  787. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  788. if (!m_pITFormatControl)
  789. {
  790. Hr = E_INVALIDARG;
  791. goto MyExit;
  792. }
  793. // Associate the current compression index with the right range index
  794. m_CurrentFormat = ComboBox_GetCurSel(m_hWndFormat);
  795. if (m_CurrentFormat < m_RangeCount)
  796. {
  797. m_SubTypeCurrent = m_SubTypeList[m_CurrentFormat];
  798. for (dw = 0; dw < m_RangeCount; dw++)
  799. {
  800. if (m_SubTypeList[dw] == m_SubTypeCurrent)
  801. {
  802. CMediaType *pmt = NULL;
  803. BOOL fEnabled; // Is this format currently enabled (according to the H.245 capability resolver)
  804. Hr = m_pITFormatControl->GetStreamCaps(dw, (AM_MEDIA_TYPE **)&pmt, &m_RangeCaps, &fEnabled);
  805. DeleteAMMediaType(pmt);
  806. }
  807. }
  808. }
  809. MyExit:
  810. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  811. return Hr;
  812. }
  813. /****************************************************************************
  814. * @doc INTERNAL CAUDRECPMETHOD
  815. *
  816. * @mfunc HRESULT | CAudRecProperties | InitialRangeScan | This
  817. * method is used to retrieve the list of supported formats on the stream.
  818. *
  819. * @rdesc This method returns an HRESULT value that depends on the
  820. * implementation of the interface. HRESULT can include one of the
  821. * following standard constants, or other values not listed:
  822. *
  823. * @flag NOERROR | No error
  824. ***************************************************************************/
  825. HRESULT CAudRecProperties::InitialRangeScan()
  826. {
  827. HRESULT Hr = NOERROR;
  828. DWORD dw;
  829. AM_MEDIA_TYPE *pmt = NULL;
  830. FX_ENTRY("CAudRecProperties::InitialRangeScan")
  831. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  832. if (!m_pITFormatControl)
  833. {
  834. Hr = E_INVALIDARG;
  835. goto MyExit;
  836. }
  837. Hr = m_pITFormatControl->GetNumberOfCapabilities(&m_RangeCount);
  838. if (!SUCCEEDED(Hr))
  839. {
  840. Hr = E_FAIL;
  841. goto MyExit;
  842. }
  843. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: NumberOfRanges=%d"), _fx_, m_RangeCount));
  844. if (!(m_SubTypeList = new GUID [m_RangeCount]))
  845. {
  846. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: new failed"), _fx_));
  847. Hr = E_OUTOFMEMORY;
  848. goto MyExit;
  849. }
  850. for (dw = 0; dw < m_RangeCount; dw++)
  851. {
  852. pmt = NULL;
  853. BOOL fEnabled; // Is this format currently enabled (according to the H.245 capability resolver)
  854. Hr = m_pITFormatControl->GetStreamCaps(dw, (AM_MEDIA_TYPE **)&pmt, &m_RangeCaps, &fEnabled);
  855. m_SubTypeList[dw] = pmt->subtype;
  856. DeleteAMMediaType(pmt);
  857. }
  858. // Get default format
  859. Hr = GetCurrentMediaType();
  860. MyExit:
  861. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  862. return Hr;
  863. }
  864. /****************************************************************************
  865. * @doc INTERNAL CAUDRECPMETHOD
  866. *
  867. * @mfunc HRESULT | CAudRecProperties | OnApplyChanges | This
  868. * method is called when the user applies changes to the property page.
  869. *
  870. * @rdesc This method returns an HRESULT value that depends on the
  871. * implementation of the interface. HRESULT can include one of the
  872. * following standard constants, or other values not listed:
  873. *
  874. * @flag E_FAIL | Failure
  875. * @flag E_POINTER | Null pointer argument
  876. * @flag E_NOTIMPL | Method is not supported
  877. * @flag NOERROR | No error
  878. ***************************************************************************/
  879. HRESULT CAudRecProperties::OnApplyChanges()
  880. {
  881. HRESULT Hr = NOERROR;
  882. int j;
  883. CMediaType *pmt = NULL;
  884. BOOL fEnabled; // Is this format currently enabled (according to the H.245 capability resolver)
  885. FX_ENTRY("CAudRecProperties::OnApplyChanges")
  886. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: begin"), _fx_));
  887. // Apply format changes on video stream
  888. m_CurrentFormat = ComboBox_GetCurSel(m_hWndFormat);
  889. // Only apply change if the format is different
  890. if (m_CurrentFormat != m_OriginalFormat)
  891. {
  892. if (SUCCEEDED (Hr = m_pITFormatControl->GetStreamCaps(m_CurrentFormat, (AM_MEDIA_TYPE **) &pmt, &m_RangeCaps, &fEnabled)))
  893. {
  894. // if (FAILED(Hr = m_pITFormatControl->SetPreferredFormat(pmt)))
  895. {
  896. // Why did you mess with the format that was returned to you?
  897. }
  898. // Free some memory that was allocated by GetStreamCaps
  899. if (pmt)
  900. DeleteAMMediaType(pmt);
  901. // Update our copy of the current format
  902. GetCurrentMediaType();
  903. }
  904. }
  905. // Apply settings on the stream.
  906. for (j = 0; j < NUM_AUDREC_CONTROLS; j++)
  907. {
  908. if (m_Controls[j])
  909. {
  910. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: SUCCESS: calling m_Controls[%ld]=0x%08lX->OnApply"), _fx_, j, m_Controls[j]));
  911. if (m_Controls[j]->HasChanged())
  912. m_Controls[j]->OnApply();
  913. Hr = NOERROR;
  914. }
  915. else
  916. {
  917. DbgLog((LOG_ERROR, DBG_LEVEL_TRACE_FAILURES, TEXT("%s: ERROR: can't calling m_Controls[%ld]=NULL->OnApply"), _fx_, j));
  918. Hr = E_UNEXPECTED;
  919. }
  920. }
  921. DbgLog((LOG_TRACE, DBG_LEVEL_TRACE_DETAILS, TEXT("%s: end"), _fx_));
  922. return Hr;
  923. }
  924. /****************************************************************************
  925. * @doc INTERNAL CAUDRECPMETHOD
  926. *
  927. * @mfunc BOOL | CAudRecProperties | BaseDlgProc | This
  928. * method is called when a message is sent to the property page dialog box.
  929. *
  930. * @rdesc By default, returns the value returned by the Win32 DefWindowProc function.
  931. ***************************************************************************/
  932. INT_PTR CALLBACK CAudRecProperties::BaseDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  933. {
  934. CAudRecProperties *pSV = (CAudRecProperties*)GetWindowLong(hDlg, DWL_USER);
  935. int iNotify = HIWORD (wParam);
  936. int j;
  937. switch (uMsg)
  938. {
  939. case WM_INITDIALOG:
  940. {
  941. LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE)lParam;
  942. pSV = (CAudRecProperties*)psp->lParam;
  943. pSV->m_hDlg = hDlg;
  944. SetWindowLong(hDlg, DWL_USER, (LPARAM)pSV);
  945. pSV->m_bInit = FALSE;
  946. //pSV->OnActivate();
  947. //pSV->m_bInit = TRUE;
  948. return TRUE;
  949. }
  950. break;
  951. case WM_TIMER:
  952. if (pSV && pSV->m_bInit)
  953. {
  954. // Update the Vu-Meters
  955. for (j = 0; j < pSV->m_NumProperties; j++)
  956. {
  957. if (pSV->m_Controls[j]->GetProgressHWnd())
  958. {
  959. pSV->m_Controls[j]->UpdateProgress();
  960. pSV->SetDirty();
  961. }
  962. }
  963. }
  964. break;
  965. case WM_HSCROLL:
  966. case WM_VSCROLL:
  967. if (pSV && pSV->m_bInit)
  968. {
  969. // Process all of the Trackbar messages
  970. for (j = 0; j < pSV->m_NumProperties; j++)
  971. {
  972. if (pSV->m_Controls[j]->GetTrackbarHWnd() == (HWND)lParam)
  973. {
  974. pSV->m_Controls[j]->OnScroll(uMsg, wParam, lParam);
  975. pSV->SetDirty();
  976. }
  977. }
  978. // pSV->OnApplyChanges();
  979. }
  980. break;
  981. case WM_COMMAND:
  982. if (pSV && pSV->m_bInit)
  983. {
  984. // Process all of the auto checkbox messages
  985. for (j = 0; j < pSV->m_NumProperties; j++)
  986. {
  987. if (pSV->m_Controls[j] && pSV->m_Controls[j]->GetAutoHWnd() == (HWND)lParam)
  988. {
  989. pSV->m_Controls[j]->OnAuto(uMsg, wParam, lParam);
  990. pSV->SetDirty();
  991. break;
  992. }
  993. }
  994. // Process all of the edit box messages
  995. for (j = 0; j < pSV->m_NumProperties; j++)
  996. {
  997. if (pSV->m_Controls[j] && pSV->m_Controls[j]->GetEditHWnd() == (HWND)lParam)
  998. {
  999. pSV->m_Controls[j]->OnEdit(uMsg, wParam, lParam);
  1000. pSV->SetDirty();
  1001. break;
  1002. }
  1003. }
  1004. switch (LOWORD(wParam))
  1005. {
  1006. case IDC_CONTROL_DEFAULT:
  1007. for (j = 0; j < pSV->m_NumProperties; j++)
  1008. {
  1009. if (pSV->m_Controls[j])
  1010. pSV->m_Controls[j]->OnDefault();
  1011. }
  1012. break;
  1013. case IDC_FORMAT_Compression:
  1014. if (HIWORD(wParam) == CBN_SELCHANGE)
  1015. {
  1016. pSV->OnFormatChanged();
  1017. }
  1018. break;
  1019. default:
  1020. break;
  1021. }
  1022. //pSV->OnApplyChanges();
  1023. }
  1024. break;
  1025. case WM_NOTIFY:
  1026. if (pSV)
  1027. {
  1028. switch (((NMHDR FAR *)lParam)->code)
  1029. {
  1030. case PSN_SETACTIVE:
  1031. {
  1032. // We call out here specially so we can mark this page as having been init'd.
  1033. int iRet = pSV->OnActivate();
  1034. pSV->m_bInit = TRUE;
  1035. return iRet;
  1036. }
  1037. break;
  1038. case PSN_APPLY:
  1039. pSV->OnApplyChanges();
  1040. break;
  1041. case PSN_QUERYCANCEL:
  1042. // return pSV->QueryCancel();
  1043. break;
  1044. default:
  1045. break;
  1046. }
  1047. }
  1048. break;
  1049. default:
  1050. return FALSE;
  1051. }
  1052. return TRUE;
  1053. }
  1054. /****************************************************************************
  1055. * @doc INTERNAL CAUDRECPMETHOD
  1056. *
  1057. * @mfunc BOOL | CAudRecProperties | SetDirty | This
  1058. * method notifies the property page site of changes.
  1059. *
  1060. * @rdesc Nada.
  1061. ***************************************************************************/
  1062. void CAudRecProperties::SetDirty()
  1063. {
  1064. PropSheet_Changed(GetParent(m_hDlg), m_hDlg);
  1065. }