xref: /third_party/lame/dshow/PropPage.cpp (revision 159b3361)
1/*
2 *  LAME MP3 encoder for DirectShow
3 *  Basic property page
4 *
5 *  Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <streams.h>
24#include <olectl.h>
25#include <commctrl.h>
26#include "iaudioprops.h"
27#include "mpegac.h"
28#include "resource.h"
29#include "PropPage.h"
30#include "Reg.h"
31
32// strings to appear in comboboxes
33const char * szBitRateString[2][14] = {
34    {
35        "32 kbps","40 kbps","48 kbps","56 kbps",
36        "64 kbps","80 kbps","96 kbps","112 kbps",
37        "128 kbps","160 kbps","192 kbps","224 kbps",
38        "256 kbps","320 kbps"
39    },
40    {
41        "8 kbps","16 kbps","24 kbps","32 kbps",
42        "40 kbps","48 kbps","56 kbps","64 kbps",
43        "80 kbps","96 kbps","112 kbps","128 kbps",
44        "144 kbps","160 kbps"
45    }
46};
47
48LPCSTR szQualityDesc[10] = {
49    "High", "High", "High", "High", "High",
50    "Medium", "Medium",
51    "Low", "Low",
52    "Fast mode"
53};
54
55LPCSTR szVBRqDesc[10] = {
56    "0 - ~1:4",
57    "1 - ~1:5",
58    "2 - ~1:6",
59    "3 - ~1:7",
60    "4 - ~1:9",
61    "5 - ~1:9",
62    "6 - ~1:10",
63    "7 - ~1:11",
64    "8 - ~1:12",
65    "9 - ~1:14"
66};
67
68struct SSampleRate {
69    DWORD dwSampleRate;
70    LPCSTR lpSampleRate;
71};
72
73SSampleRate srRates[9] = {
74    // MPEG-1
75    {48000, "48 kHz"},
76    {44100, "44.1 kHz"},
77    {32000, "32 kHz"},
78
79    // MPEG-2
80    {24000, "24 kHz"},
81    {22050, "22.05 kHz"},
82    {16000, "16 kHz"},
83
84    // MPEG-2.5
85    {12000, "12 kHz"},
86    {11025, "11.025 kHz"},
87    { 8000, "8 kHz"}
88};
89
90////////////////////////////////////////////////////////////////
91// CreateInstance
92////////////////////////////////////////////////////////////////
93CUnknown *CMpegAudEncPropertyPage::CreateInstance( LPUNKNOWN punk, HRESULT *phr )
94{
95    CMpegAudEncPropertyPage *pNewObject
96        = new CMpegAudEncPropertyPage( punk, phr );
97
98    if( pNewObject == NULL )
99        *phr = E_OUTOFMEMORY;
100
101    return pNewObject;
102}
103
104////////////////////////////////////////////////////////////////
105// Constructor
106////////////////////////////////////////////////////////////////
107CMpegAudEncPropertyPage::CMpegAudEncPropertyPage(LPUNKNOWN punk, HRESULT *phr)
108 : CBasePropertyPage(NAME("Encoder Property Page"),
109                      punk, IDD_AUDIOENCPROPS, IDS_AUDIO_PROPS_TITLE)
110    , m_pAEProps(NULL)
111{
112    ASSERT(phr);
113
114    m_srIdx = 0;
115
116    InitCommonControls();
117}
118
119//
120// OnConnect
121//
122// Give us the filter to communicate with
123HRESULT CMpegAudEncPropertyPage::OnConnect(IUnknown *pUnknown)
124{
125    ASSERT(m_pAEProps == NULL);
126
127    // Ask the filter for it's control interface
128
129    HRESULT hr = pUnknown->QueryInterface(IID_IAudioEncoderProperties,(void **)&m_pAEProps);
130    if (FAILED(hr))
131        return E_NOINTERFACE;
132
133    ASSERT(m_pAEProps);
134
135    // Get current filter state
136    m_pAEProps->get_Bitrate(&m_dwBitrate);
137    m_pAEProps->get_Variable(&m_dwVariable);
138    m_pAEProps->get_VariableMin(&m_dwMin);
139    m_pAEProps->get_VariableMax(&m_dwMax);
140    m_pAEProps->get_Quality(&m_dwQuality);
141    m_pAEProps->get_VariableQ(&m_dwVBRq);
142    m_pAEProps->get_SampleRate(&m_dwSampleRate);
143    m_pAEProps->get_CRCFlag(&m_dwCRC);
144    m_pAEProps->get_ForceMono(&m_dwForceMono);
145    m_pAEProps->get_CopyrightFlag(&m_dwCopyright);
146    m_pAEProps->get_OriginalFlag(&m_dwOriginal);
147
148    return NOERROR;
149}
150
151//
152// OnDisconnect
153//
154// Release the interface
155
156HRESULT CMpegAudEncPropertyPage::OnDisconnect()
157{
158    // Release the interface
159    if (m_pAEProps == NULL)
160        return E_UNEXPECTED;
161
162    m_pAEProps->set_Bitrate(m_dwBitrate);
163    m_pAEProps->set_Variable(m_dwVariable);
164    m_pAEProps->set_VariableMin(m_dwMin);
165    m_pAEProps->set_VariableMax(m_dwMax);
166    m_pAEProps->set_Quality(m_dwQuality);
167    m_pAEProps->set_VariableQ(m_dwVBRq);
168    m_pAEProps->set_SampleRate(m_dwSampleRate);
169    m_pAEProps->set_CRCFlag(m_dwCRC);
170    m_pAEProps->set_ForceMono(m_dwForceMono);
171    m_pAEProps->set_CopyrightFlag(m_dwCopyright);
172    m_pAEProps->set_OriginalFlag(m_dwOriginal);
173    m_pAEProps->SaveAudioEncoderPropertiesToRegistry();
174
175    m_pAEProps->Release();
176    m_pAEProps = NULL;
177
178    return NOERROR;
179}
180
181//
182// OnActivate
183//
184// Called on dialog creation
185
186HRESULT CMpegAudEncPropertyPage::OnActivate(void)
187{
188    InitPropertiesDialog(m_hwnd);
189
190    return NOERROR;
191}
192
193//
194// OnDeactivate
195//
196// Called on dialog destruction
197
198HRESULT CMpegAudEncPropertyPage::OnDeactivate(void)
199{
200    return NOERROR;
201}
202
203////////////////////////////////////////////////////////////////
204// OnReceiveMessage - message handler function
205////////////////////////////////////////////////////////////////
206BOOL CMpegAudEncPropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
207{
208    switch (uMsg)
209    {
210    case WM_HSCROLL:
211        if ((HWND)lParam == m_hwndQuality)
212        {
213            int pos = SendMessage(m_hwndQuality, TBM_GETPOS, 0, 0);
214            if (pos >= 0 && pos < 10)
215            {
216                SetDlgItemText(hwnd,IDC_TEXT_QUALITY,szQualityDesc[pos]);
217                m_pAEProps->set_Quality(pos);
218                SetDirty();
219            }
220        }
221        break;
222
223    case WM_COMMAND:
224        switch (LOWORD(wParam))
225        {
226        case IDC_COMBO_CBR:
227            if (HIWORD(wParam) == CBN_SELCHANGE)
228            {
229                int nBitrate = SendDlgItemMessage(hwnd, IDC_COMBO_CBR, CB_GETCURSEL, 0, 0L);
230                DWORD dwSampleRate;
231                m_pAEProps->get_SampleRate(&dwSampleRate);
232                DWORD dwBitrate;
233
234                if (dwSampleRate >= 32000)
235                {
236                    // Consider MPEG-1
237                    dwBitrate = dwBitRateValue[0][nBitrate];
238                }
239                else
240                {
241                    // Consider MPEG-2/2.5
242                    dwBitrate = dwBitRateValue[1][nBitrate];
243                }
244
245                m_pAEProps->set_Bitrate(dwBitrate);
246
247                SetDirty();
248            }
249            break;
250
251        case IDC_COMBO_VBRMIN:
252            if (HIWORD(wParam) == CBN_SELCHANGE)
253            {
254                int nVariableMin = SendDlgItemMessage(hwnd, IDC_COMBO_VBRMIN, CB_GETCURSEL, 0, 0L);
255                DWORD dwSampleRate;
256                m_pAEProps->get_SampleRate(&dwSampleRate);
257                DWORD dwMin;
258
259                if (dwSampleRate >= 32000)
260                {
261                    // Consider MPEG-1
262                    dwMin = dwBitRateValue[0][nVariableMin];
263                }
264                else
265                {
266                    // Consider MPEG-2/2.5
267                    dwMin = dwBitRateValue[1][nVariableMin];
268                }
269
270                m_pAEProps->set_VariableMin(dwMin);
271
272                SetDirty();
273            }
274            break;
275
276        case IDC_COMBO_VBRMAX:
277            if (HIWORD(wParam) == CBN_SELCHANGE)
278            {
279                int nVariableMax = SendDlgItemMessage(hwnd, IDC_COMBO_VBRMAX, CB_GETCURSEL, 0, 0L);
280                DWORD dwSampleRate;
281                m_pAEProps->get_SampleRate(&dwSampleRate);
282                DWORD dwMax;
283
284                if (dwSampleRate >= 32000)
285                {
286                    // Consider MPEG-1
287                    dwMax = dwBitRateValue[0][nVariableMax];
288                }
289                else
290                {
291                    // Consider MPEG-2/2.5
292                    dwMax = dwBitRateValue[1][nVariableMax];
293                }
294
295                m_pAEProps->set_VariableMax(dwMax);
296
297                SetDirty();
298            }
299            break;
300
301        case IDC_COMBO_SAMPLE_RATE:
302            if (HIWORD(wParam) == CBN_SELCHANGE)
303            {
304                int nSampleRate = SendDlgItemMessage(hwnd, IDC_COMBO_SAMPLE_RATE, CB_GETCURSEL, 0, 0L);
305
306                if (nSampleRate < 0)
307                    nSampleRate = 0;
308                else if (nSampleRate > 2)
309                    nSampleRate = 2;
310
311                DWORD dwSampleRate = srRates[nSampleRate * 3 + m_srIdx].dwSampleRate;
312
313                m_pAEProps->set_SampleRate(dwSampleRate);
314                InitPropertiesDialog(hwnd);
315                SetDirty();
316            }
317            break;
318
319        case IDC_COMBO_VBRq:
320            if (HIWORD(wParam) == CBN_SELCHANGE)
321            {
322                int nVBRq = SendDlgItemMessage(hwnd, IDC_COMBO_VBRq, CB_GETCURSEL, 0, 0L);
323                if (nVBRq >=0 && nVBRq <=9)
324                    m_pAEProps->set_VariableQ(nVBRq);
325                SetDirty();
326            }
327            break;
328
329        case IDC_RADIO_CBR:
330        case IDC_RADIO_VBR:
331            m_pAEProps->set_Variable(LOWORD(wParam)-IDC_RADIO_CBR);
332            SetDirty();
333            break;
334
335        case IDC_CHECK_PES:
336            m_pAEProps->set_PESOutputEnabled(IsDlgButtonChecked(hwnd, IDC_CHECK_PES));
337            SetDirty();
338            break;
339
340        case IDC_CHECK_COPYRIGHT:
341            m_pAEProps->set_CopyrightFlag(IsDlgButtonChecked(hwnd, IDC_CHECK_COPYRIGHT));
342            SetDirty();
343            break;
344
345        case IDC_CHECK_ORIGINAL:
346            m_pAEProps->set_OriginalFlag(IsDlgButtonChecked(hwnd, IDC_CHECK_ORIGINAL));
347            SetDirty();
348            break;
349
350        case IDC_CHECK_CRC:
351            m_pAEProps->set_CRCFlag(IsDlgButtonChecked(hwnd, IDC_CHECK_CRC));
352            SetDirty();
353            break;
354
355        case IDC_FORCE_MONO:
356            m_pAEProps->set_ForceMono(IsDlgButtonChecked(hwnd, IDC_FORCE_MONO));
357            SetDirty();
358            break;
359        }
360        return TRUE;
361
362    case WM_DESTROY:
363        return TRUE;
364
365    default:
366        return FALSE;
367    }
368
369    return TRUE;
370}
371
372//
373// OnApplyChanges
374//
375HRESULT CMpegAudEncPropertyPage::OnApplyChanges()
376{
377    m_pAEProps->get_Bitrate(&m_dwBitrate);
378    m_pAEProps->get_Variable(&m_dwVariable);
379    m_pAEProps->get_VariableMin(&m_dwMin);
380    m_pAEProps->get_VariableMax(&m_dwMax);
381    m_pAEProps->get_Quality(&m_dwQuality);
382    m_pAEProps->get_VariableQ(&m_dwVBRq);
383    m_pAEProps->get_SampleRate(&m_dwSampleRate);
384    m_pAEProps->get_CRCFlag(&m_dwCRC);
385    m_pAEProps->get_ForceMono(&m_dwForceMono);
386    m_pAEProps->get_CopyrightFlag(&m_dwCopyright);
387    m_pAEProps->get_OriginalFlag(&m_dwOriginal);
388    m_pAEProps->SaveAudioEncoderPropertiesToRegistry();
389
390    m_pAEProps->ApplyChanges();
391
392    return S_OK;
393}
394
395//
396// Initialize dialogbox controls with proper values
397//
398void CMpegAudEncPropertyPage::InitPropertiesDialog(HWND hwndParent)
399{
400    EnableControls(hwndParent, TRUE);
401
402    m_hwndQuality = GetDlgItem(hwndParent,IDC_SLIDER_QUALITY);
403    DWORD dwQuality;
404    m_pAEProps->get_Quality(&dwQuality);
405    SendDlgItemMessage(hwndParent, IDC_SLIDER_QUALITY, TBM_SETRANGE, 1, MAKELONG (2,9));
406    SendDlgItemMessage(hwndParent, IDC_SLIDER_QUALITY, TBM_SETPOS, 1, dwQuality);
407    if (dwQuality>=0 && dwQuality<10)
408        SetDlgItemText(hwndParent,IDC_TEXT_QUALITY,szQualityDesc[dwQuality]);
409
410    //
411    // initialize sample rate selection
412    //
413    DWORD dwSourceSampleRate;
414    m_pAEProps->get_SourceSampleRate(&dwSourceSampleRate);
415
416    SendDlgItemMessage(hwndParent, IDC_COMBO_SAMPLE_RATE, CB_RESETCONTENT, 0, 0L);
417
418    switch (dwSourceSampleRate)
419    {
420    case 48000:
421    case 24000:
422    case 12000:
423        m_srIdx = 0;
424        break;
425
426    case 32000:
427    case 16000:
428    case  8000:
429        m_srIdx = 2;
430        break;
431
432    case 44100:
433    case 22050:
434    case 11025:
435    default:
436        m_srIdx = 1;
437    }
438
439    for (int i = 0; i < 3; i++)
440        SendDlgItemMessage(hwndParent, IDC_COMBO_SAMPLE_RATE, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)srRates[i * 3 + m_srIdx].lpSampleRate);
441
442    DWORD dwSampleRate;
443    m_pAEProps->get_SampleRate(&dwSampleRate);
444    m_pAEProps->set_SampleRate(dwSampleRate);
445
446    int nSR = 0;
447    while (dwSampleRate != srRates[nSR * 3 + m_srIdx].dwSampleRate && nSR < 3)
448    {
449        nSR++;
450    }
451
452    if (nSR >= 3)
453        nSR = 0;
454
455    SendDlgItemMessage(hwndParent, IDC_COMBO_SAMPLE_RATE, CB_SETCURSEL, nSR, 0);
456
457    DWORD dwChannels;
458    m_pAEProps->get_SourceChannels(&dwChannels);
459
460    //
461    //initialize VBRq combo box
462    //
463    int k;
464    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRq, CB_RESETCONTENT, 0, 0);
465    for (k = 0; k < 10; k++)
466        SendDlgItemMessage(hwndParent, IDC_COMBO_VBRq, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szVBRqDesc[k]);
467    DWORD dwVBRq;
468    m_pAEProps->get_VariableQ(&dwVBRq);
469    if (dwVBRq<0)
470        dwVBRq = 0;
471    if (dwVBRq>9)
472        dwVBRq = 9;
473    m_pAEProps->set_VariableQ(dwVBRq);
474    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRq, CB_SETCURSEL, dwVBRq, 0);
475
476//////////////////////////////////////
477// initialize CBR selection
478//////////////////////////////////////
479    int nSt;
480
481    SendDlgItemMessage(hwndParent, IDC_COMBO_CBR, CB_RESETCONTENT, 0, 0);
482    if (dwSampleRate >= 32000)
483    {
484        // If target sampling rate is less than 32000, consider
485        // MPEG 1 audio
486        nSt = 0;
487        for (int i = 0; i < 14; i++)
488            SendDlgItemMessage(hwndParent, IDC_COMBO_CBR, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[0][i]);
489    }
490    else
491    {
492        // Consider MPEG 2 / 2.5 audio
493        nSt = 1;
494        for (int i = 0; i < 14 ; i++)
495            SendDlgItemMessage(hwndParent, IDC_COMBO_CBR, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[1][i]);
496    }
497
498    DWORD dwBitrate;
499    m_pAEProps->get_Bitrate(&dwBitrate);
500
501    int nBitrateSel = 0;
502    // BitRateValue[][i] is in ascending order
503    // We use this fact. We also know there are 14 bitrate values available.
504    // We are going to use the closest possible, so we can limit loop with 13
505    while (nBitrateSel < 13 && dwBitRateValue[nSt][nBitrateSel] < dwBitrate)
506        nBitrateSel++;
507    SendDlgItemMessage(hwndParent, IDC_COMBO_CBR, CB_SETCURSEL, nBitrateSel, 0);
508
509    // check if the specified bitrate is found exactly and correct if not
510    if (dwBitRateValue[nSt][nBitrateSel] != dwBitrate)
511    {
512        dwBitrate = dwBitRateValue[nSt][nBitrateSel];
513        // we can change it, because it is independent of any other parameters
514        // (but depends on some of them!)
515        m_pAEProps->set_Bitrate(dwBitrate);
516    }
517
518    //
519    // Check VBR/CBR radio button
520    //
521    DWORD dwVariable;
522    m_pAEProps->get_Variable(&dwVariable);
523    CheckRadioButton(hwndParent, IDC_RADIO_CBR, IDC_RADIO_VBR, IDC_RADIO_CBR + dwVariable);
524
525//////////////////////////////////////////////////
526// initialize VBR selection
527//////////////////////////////////////////////////
528    //VBRMIN, VBRMAX
529    int j, nST;
530
531    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMIN, CB_RESETCONTENT, 0, 0);
532    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMAX, CB_RESETCONTENT, 0, 0);
533
534    if (dwSampleRate >= 32000)
535    {
536            nST = 0;
537            for (j=0; j<14 ;j++) {
538                SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMIN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[0][j]);
539                SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMAX, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[0][j]);
540            }
541    }
542    else
543    {
544            nST = 1;
545            for (j = 0; j < 14; j++)
546            {
547                SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMIN, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[1][j]);
548                SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMAX, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)szBitRateString[1][j]);
549            }
550    }
551
552    DWORD dwMin,dwMax;
553    m_pAEProps->get_VariableMin(&dwMin);
554    m_pAEProps->get_VariableMax(&dwMax);
555
556    int nVariableMinSel = 0;
557    int nVariableMaxSel = 0;
558
559    // BitRateValue[][i] is in ascending order
560    // We use this fact. We also know there are 14 bitrate values available.
561    // We are going to use the closest possible, so we can limit loop with 13
562    while (nVariableMinSel<13 && dwBitRateValue[nST][nVariableMinSel] < dwMin)
563        nVariableMinSel++;
564    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMIN, CB_SETCURSEL, nVariableMinSel, 0);
565
566    while (nVariableMaxSel<13 && dwBitRateValue[nST][nVariableMaxSel] < dwMax)
567        nVariableMaxSel++;
568    SendDlgItemMessage(hwndParent, IDC_COMBO_VBRMAX, CB_SETCURSEL, nVariableMaxSel, 0);
569
570
571    // check if the specified bitrate is found exactly and correct if not
572    if (dwBitRateValue[nST][nVariableMinSel] != dwMin)
573    {
574        dwMin = dwBitRateValue[nST][nVariableMinSel];
575        // we can change it, because it is independent of any other parameters
576        // (but depends on some of them!)
577        m_pAEProps->set_VariableMin(dwMin);
578    }
579
580    // check if the specified bitrate is found exactly and correct if not
581    if (dwBitRateValue[nST][nVariableMaxSel] != dwMax)
582    {
583        dwMax = dwBitRateValue[nST][nVariableMaxSel];
584        // we can change it, because it is independent of any other parameters
585        // (but depends on some of them!)
586        m_pAEProps->set_VariableMax(dwMax);
587    }
588
589    //
590    // initialize checkboxes
591    //
592    DWORD dwPES;
593    m_pAEProps->get_PESOutputEnabled(&dwPES);
594
595    dwPES = 0;
596    CheckDlgButton(hwndParent, IDC_CHECK_PES, dwPES ? BST_CHECKED : BST_UNCHECKED);
597
598    DWORD dwCRC;
599    m_pAEProps->get_CRCFlag(&dwCRC);
600    CheckDlgButton(hwndParent, IDC_CHECK_CRC, dwCRC ? BST_CHECKED : BST_UNCHECKED);
601
602    DWORD dwForceMono;
603    m_pAEProps->get_ForceMono(&dwForceMono);
604    CheckDlgButton(hwndParent, IDC_FORCE_MONO, dwForceMono ? BST_CHECKED : BST_UNCHECKED);
605
606    DWORD dwCopyright;
607    m_pAEProps->get_CopyrightFlag(&dwCopyright);
608    CheckDlgButton(hwndParent, IDC_CHECK_COPYRIGHT, dwCopyright ? BST_CHECKED : BST_UNCHECKED);
609
610    DWORD dwOriginal;
611    m_pAEProps->get_OriginalFlag(&dwOriginal);
612    CheckDlgButton(hwndParent, IDC_CHECK_ORIGINAL, dwOriginal ? BST_CHECKED : BST_UNCHECKED);
613}
614
615
616////////////////////////////////////////////////////////////////
617// EnableControls
618////////////////////////////////////////////////////////////////
619void CMpegAudEncPropertyPage::EnableControls(HWND hwndParent, bool bEnable)
620{
621    EnableWindow(GetDlgItem(hwndParent, IDC_CHECK_PES), false);//bEnable);
622    EnableWindow(GetDlgItem(hwndParent, IDC_RADIO_CBR), bEnable);
623    EnableWindow(GetDlgItem(hwndParent, IDC_COMBO_CBR), bEnable);
624    EnableWindow(GetDlgItem(hwndParent, IDC_RADIO_VBR), bEnable);
625    EnableWindow(GetDlgItem(hwndParent, IDC_COMBO_VBRMIN), bEnable);
626    EnableWindow(GetDlgItem(hwndParent, IDC_COMBO_VBRMAX), bEnable);
627    EnableWindow(GetDlgItem(hwndParent, IDC_CHECK_COPYRIGHT), bEnable);
628    EnableWindow(GetDlgItem(hwndParent, IDC_CHECK_ORIGINAL), bEnable);
629    EnableWindow(GetDlgItem(hwndParent, IDC_CHECK_CRC), bEnable);
630    EnableWindow(GetDlgItem(hwndParent, IDC_FORCE_MONO), bEnable);
631    EnableWindow(GetDlgItem(hwndParent, IDC_SLIDER_QUALITY), bEnable);
632    EnableWindow(GetDlgItem(hwndParent, IDC_COMBO_SAMPLE_RATE), bEnable);
633}
634
635//
636// SetDirty
637//
638// notifies the property page site of changes
639
640void CMpegAudEncPropertyPage::SetDirty()
641{
642    m_bDirty = TRUE;
643    if (m_pPageSite)
644        m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY);
645}
646
647