SYNTHPRP.CPP
//==========================================================================; 
// 
//  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) 1992 - 1997  Microsoft Corporation.  All Rights Reserved. 
// 
//--------------------------------------------------------------------------; 
// 
// synthprop.cpp - Synthesizer Property Page 
// 
 
#include <windows.h> 
#include <streams.h> 
#include <commctrl.h> 
#include <memory.h> 
#include <olectl.h> 
 
#include "isynth.h" 
#include "synth.h" 
#include "synthprp.h" 
#include "resource.h" 
 
 
// ------------------------------------------------------------------------- 
// CSynthProperties 
// ------------------------------------------------------------------------- 
 
// 
// CreateInstance 
// 
 
CUnknown * WINAPI CSynthProperties::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) 
{ 
    CUnknown *punk = new CSynthProperties(lpunk, phr); 
    if (punk == NULL) { 
        *phr = E_OUTOFMEMORY; 
    } 
 
    return punk; 
} 
 
 
// 
// Constructor 
// 
// Creaete a Property page object for the synthesizer 
 
CSynthProperties::CSynthProperties(LPUNKNOWN lpunk, HRESULT *phr) 
    : CBasePropertyPage(NAME("Synth Property Page"), lpunk, 
        IDD_SYNTHPROP1,IDS_SYNTHPROPNAME) 
    , m_pSynth(NULL) 
    , m_iSweepStart(DefaultSweepStart) 
    , m_iSweepEnd(DefaultSweepEnd) 
, m_fWindowInActive(TRUE) 
{ 
    ASSERT(phr); 
 
    InitCommonControls(); 
} 
 
// 
// OnConnect 
// 
// Give us the filter to communicate with 
 
HRESULT CSynthProperties::OnConnect(IUnknown *pUnknown) 
{ 
    ASSERT(m_pSynth == NULL); 
 
    // Ask the filter for it's control interface 
 
    HRESULT hr = pUnknown->QueryInterface(IID_ISynth,(void **)&m_pSynth); 
    if (FAILED(hr)) { 
        return E_NOINTERFACE; 
    } 
 
    ASSERT(m_pSynth); 
 
    // Get current filter state 
    m_pSynth->get_BitsPerSample(&m_iBitsPerSampleOriginal); 
    m_pSynth->get_Waveform(&m_iWaveformOriginal); 
    m_pSynth->get_Frequency(&m_iFrequencyOriginal); 
    m_pSynth->get_Channels(&m_iChannelsOriginal); 
    m_pSynth->get_SamplesPerSec(&m_iSamplesPerSecOriginal); 
    m_pSynth->get_Amplitude(&m_iAmplitudeOriginal); 
 
    return NOERROR; 
} 
 
 
// 
// OnDisconnect 
// 
// Release the interface 
 
HRESULT CSynthProperties::OnDisconnect() 
{ 
    // Release the interface 
 
    if (m_pSynth == NULL) { 
        return E_UNEXPECTED; 
    } 
 
    m_pSynth->put_Waveform(m_iWaveformOriginal); 
    m_pSynth->put_Frequency(m_iFrequencyOriginal); 
    m_pSynth->put_Amplitude(m_iAmplitudeOriginal); 
 
    m_pSynth->put_Channels(m_iChannelsOriginal); 
    m_pSynth->put_BitsPerSample(m_iBitsPerSampleOriginal); 
    m_pSynth->put_SamplesPerSec(m_iSamplesPerSecOriginal); 
 
    m_pSynth->Release(); 
    m_pSynth = NULL; 
    return NOERROR; 
} 
 
 
// 
// OnActivate 
// 
// Called on dialog creation 
 
HRESULT CSynthProperties::OnActivate(void) 
{ 
    InitPropertiesDialog(m_hwnd); 
 
    ASSERT(m_hwndFreqSlider); 
 
m_fWindowInActive = FALSE; 
    return NOERROR; 
} 
 
// 
// OnDeactivate 
// 
// Called on dialog destruction 
 
HRESULT 
CSynthProperties::OnDeactivate(void) 
{ 
m_fWindowInActive = TRUE; 
    return NOERROR; 
} 
 
 
// 
// OnApplyChanges 
// 
// User pressed the Apply button, remember the current settings 
 
HRESULT CSynthProperties::OnApplyChanges(void) 
{ 
    m_pSynth->get_BitsPerSample(&m_iBitsPerSampleOriginal); 
    m_pSynth->get_Waveform(&m_iWaveformOriginal); 
    m_pSynth->get_Frequency(&m_iFrequencyOriginal); 
    m_pSynth->get_Channels(&m_iChannelsOriginal); 
    m_pSynth->get_SamplesPerSec(&m_iSamplesPerSecOriginal); 
    m_pSynth->get_Amplitude(&m_iAmplitudeOriginal); 
 
    return NOERROR; 
} 
 
 
// 
// OnReceiveMessages 
// 
// Handles the messages for our property window 
 
BOOL CSynthProperties::OnReceiveMessage( HWND hwnd 
                                , UINT uMsg 
                                , WPARAM wParam 
                                , LPARAM lParam) 
{ 
 
if(m_fWindowInActive) 
return FALSE; 
 
    switch (uMsg) { 
 
    case WM_PROPERTYPAGE_ENABLE: 
        // Our private message that our owning filter sends us when changing to a Run / Stop / Pause 
        // state.  if lParam, then enable the controls which affect the format; if not lParam, then 
        // disable the controls that affect the format. 
 
        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ11), (BOOL) lParam); 
        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ22), (BOOL) lParam); 
        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ44), (BOOL) lParam); 
 
        EnableWindow (GetDlgItem (hwnd, IDC_BITSPERSAMPLE8),  (BOOL) lParam); 
        EnableWindow (GetDlgItem (hwnd, IDC_BITSPERSAMPLE16), (BOOL) lParam); 
 
        EnableWindow (GetDlgItem (hwnd, IDC_CHANNELS1), (BOOL) lParam); 
        EnableWindow (GetDlgItem (hwnd, IDC_CHANNELS2), (BOOL) lParam); 
        break; 
 
    case WM_VSCROLL: 
        if ((HWND) lParam == m_hwndFreqSlider) 
            OnFreqSliderNotification(LOWORD (wParam), HIWORD (wParam)); 
        else if ((HWND) lParam == m_hwndAmplitudeSlider) 
            OnAmpSliderNotification(LOWORD (wParam), HIWORD (wParam)); 
        SetDirty(); 
        return TRUE; 
 
    case WM_COMMAND: 
 
        switch (LOWORD(wParam)) { 
 
        case IDC_FREQUENCYTEXT: 
        { 
            int iNotify = HIWORD (wParam); 
 
            if (iNotify == EN_KILLFOCUS) { 
                BOOL fOK; 
 
                int iPos = GetDlgItemInt (hwnd, IDC_FREQUENCYTEXT, &fOK, FALSE); 
                int iMaxFreq; 
 
                m_pSynth->get_SamplesPerSec(&iMaxFreq); 
                iMaxFreq /= 2; 
 
                if (!fOK || (iPos > iMaxFreq || iPos < 0)) { 
                    int iCurrentFreq; 
                    m_pSynth->get_Frequency(&iCurrentFreq); 
                    SetDlgItemInt (hwnd, IDC_FREQUENCYTEXT, iCurrentFreq, FALSE); 
                    break; 
                } 
 
   SendMessage(m_hwndFreqSlider, TBM_SETPOS, TRUE, (LPARAM) iMaxFreq - iPos); 
                m_pSynth->put_Frequency(iPos); 
                SetDirty(); 
            } 
        } 
        break; 
 
        case IDC_AMPLITUDETEXT: 
        { 
            int iNotify = HIWORD (wParam); 
 
            if (iNotify == EN_KILLFOCUS) { 
                BOOL fOK; 
 
                int iPos = GetDlgItemInt (hwnd, IDC_AMPLITUDETEXT, &fOK, FALSE); 
 
                if (!fOK || (iPos > MaxAmplitude || iPos < 0)) { 
                    int iCurrentAmplitude; 
 
                    m_pSynth->get_Amplitude(&iCurrentAmplitude); 
                    SetDlgItemInt (hwnd, IDC_AMPLITUDETEXT, iCurrentAmplitude, FALSE); 
                    break; 
                } 
 
    SendMessage(m_hwndAmplitudeSlider, TBM_SETPOS, TRUE, (LPARAM) MaxAmplitude - iPos); 
                m_pSynth->put_Amplitude(iPos); 
                SetDirty(); 
            } 
        } 
        break; 
 
        case IDC_SAMPLINGFREQ11: 
            m_pSynth->put_SamplesPerSec(11025); 
            RecalcFreqSlider(); 
            SetDirty(); 
            break; 
        case IDC_SAMPLINGFREQ22: 
            m_pSynth->put_SamplesPerSec(22050); 
            RecalcFreqSlider(); 
            SetDirty(); 
            break; 
        case IDC_SAMPLINGFREQ44: 
            m_pSynth->put_SamplesPerSec(44100); 
            RecalcFreqSlider(); 
            SetDirty(); 
            break; 
 
 
        case IDC_BITSPERSAMPLE8: 
            m_pSynth->put_BitsPerSample(8); 
            SetDirty(); 
            break; 
        case IDC_BITSPERSAMPLE16: 
            m_pSynth->put_BitsPerSample(16); 
            SetDirty(); 
            break; 
 
 
        case IDC_CHANNELS1: 
            m_pSynth->put_Channels(1); 
            SetDirty(); 
            break; 
        case IDC_CHANNELS2: 
            m_pSynth->put_Channels(2); 
            SetDirty(); 
            break; 
     
 
        case IDC_WAVESINE: 
            m_pSynth->put_Waveform(WAVE_SINE); 
            SetDirty(); 
            break; 
        case IDC_WAVESQUARE: 
            m_pSynth->put_Waveform(WAVE_SQUARE); 
            SetDirty(); 
            break; 
        case IDC_WAVESAWTOOTH: 
            m_pSynth->put_Waveform(WAVE_SAWTOOTH); 
            SetDirty(); 
            break; 
        case IDC_WAVESWEEP: 
            m_pSynth->put_Waveform(WAVE_SINESWEEP); 
            SetDirty(); 
            break; 
 
        default: 
            break; 
 
        } 
        return TRUE; 
 
    case WM_DESTROY: 
        return TRUE; 
 
    default: 
        return FALSE; 
 
    } 
    return TRUE; 
} 
 
 
// 
// InitPropertiesDialog 
// 
 
void 
CSynthProperties::InitPropertiesDialog(HWND hwndParent) 
{ 
    m_hwndFreqSlider = GetDlgItem (hwndParent, IDC_FREQTRACKBAR); 
    m_hwndFreqText  = GetDlgItem (hwndParent, IDC_FREQUENCYTEXT); 
    m_hwndAmplitudeSlider = GetDlgItem (hwndParent, IDC_AMPLITUDETRACKBAR); 
    m_hwndAmplitudeText  = GetDlgItem (hwndParent, IDC_AMPLITUDETEXT); 
 
    // Sampling Frequency 
    int i; 
    switch (m_iSamplesPerSecOriginal) { 
    case 11025: i = IDC_SAMPLINGFREQ11; break; 
    case 22050: i = IDC_SAMPLINGFREQ22; break; 
    case 44100: i = IDC_SAMPLINGFREQ44; break; 
    default: 
        ASSERT(0); 
    } 
    CheckRadioButton(hwndParent, 
        IDC_SAMPLINGFREQ11, 
        IDC_SAMPLINGFREQ44, 
        i); 
 
    // BitsPerSample 
    CheckRadioButton(hwndParent, 
                IDC_BITSPERSAMPLE8, 
                IDC_BITSPERSAMPLE16, 
                IDC_BITSPERSAMPLE8 + m_iBitsPerSampleOriginal / 8 - 1); 
 
    // Waveform 0 == sine, 1 == square, ... 
    CheckRadioButton(hwndParent, 
                IDC_WAVESINE, 
                IDC_WAVESWEEP, 
                IDC_WAVESINE + m_iWaveformOriginal); 
 
    // Channels 
    CheckRadioButton(hwndParent, 
                IDC_CHANNELS1, 
                IDC_CHANNELS2, 
                IDC_CHANNELS1 + m_iChannelsOriginal - 1); 
 
    // 
    // Frequency trackbar 
    // 
 
    RecalcFreqSlider(); 
 
    // 
    //  Amplitude trackbar 
    // 
 
    SendMessage(m_hwndAmplitudeSlider, TBM_SETRANGE, TRUE, 
        MAKELONG(MinAmplitude, MaxAmplitude) ); 
 
    SendMessage(m_hwndAmplitudeSlider, TBM_SETTIC, 0, 
        ((MinAmplitude + MaxAmplitude) / 2)); 
 
    SendMessage(m_hwndAmplitudeSlider, TBM_SETPOS, TRUE, 
        (LPARAM) (MaxAmplitude - m_iAmplitudeOriginal)); 
 
    SetDlgItemInt (hwndParent, IDC_AMPLITUDETEXT, 
        m_iAmplitudeOriginal, TRUE); 
} 
 
 
// 
// RecalcFreqSlider 
// 
// Set the range, current settings for the Freq scrollbar 
 
void 
CSynthProperties::RecalcFreqSlider(void) 
{ 
    int iPos, iMaxFreq; 
 
    // Limit the frequency to one half the sampling frequency 
 
    m_pSynth->get_SamplesPerSec(&iMaxFreq); 
    iMaxFreq /= 2; 
    m_pSynth->get_Frequency(&iPos); 
    if (iPos > iMaxFreq) 
        iPos = iMaxFreq; 
 
    SendMessage(m_hwndFreqSlider, TBM_SETRANGE, TRUE, 
        MAKELONG(0, iMaxFreq)); 
 
    SendMessage(m_hwndFreqSlider, TBM_SETTIC, 0, 
        iMaxFreq / 2); 
 
    SendMessage(m_hwndFreqSlider, TBM_SETPOS, TRUE, 
        (LPARAM) (iMaxFreq - iPos)); 
 
    SendMessage(m_hwndFreqSlider, TBM_SETPAGESIZE, 0, 10); 
 
    SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE, 
        MAKELONG (iMaxFreq - m_iSweepEnd, iMaxFreq - m_iSweepStart)); 
 
    SetDlgItemInt (m_hwnd, IDC_FREQUENCYTEXT, 
        iPos, TRUE); 
 
} 
 
// 
// OnFreqSliderNotification 
// 
// Handle the notification meesages from the slider control 
 
void 
CSynthProperties::OnFreqSliderNotification(WPARAM wParam, WORD wPosition) 
{ 
    int MaxFreq; 
    int Freq; 
    int SliderPos; 
 
    switch (wParam) { 
 
    case TB_ENDTRACK: 
    case TB_THUMBTRACK: 
    case TB_LINEDOWN: 
    case TB_LINEUP: { 
        // max frequency of slider is half the sampling frequency 
        m_pSynth->get_SamplesPerSec (&MaxFreq); 
        MaxFreq /= 2; 
        SliderPos = (int) SendMessage(m_hwndFreqSlider, TBM_GETPOS, 0, 0L); 
        Freq = MaxFreq - SliderPos; 
        m_pSynth->put_Frequency (Freq); 
 
        // Set the end of sweep to the current slider pos 
        if (!(GetKeyState (VK_SHIFT) & 0x8000)) { 
            m_iSweepEnd = Freq; 
        } 
 
        // Set the start of the sweep range if SHIFT key is pressed 
        if (GetKeyState (VK_SHIFT) & 0x8000) { 
            m_iSweepStart = Freq; 
        } 
        m_pSynth->put_SweepRange (m_iSweepStart, m_iSweepEnd); 
 
        if (m_iSweepEnd > m_iSweepStart) 
            SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE, 
                MAKELONG (MaxFreq - m_iSweepEnd, MaxFreq - m_iSweepStart)); 
        else 
            SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE, 
                MAKELONG (MaxFreq - m_iSweepStart, MaxFreq - m_iSweepEnd)); 
 
        SetDlgItemInt (m_hwnd, IDC_FREQUENCYTEXT, Freq, TRUE); 
 
    } 
    break; 
 
    } 
} 
 
// 
// OnAmpSliderNotification 
// 
// Handle the notification meesages from the slider control 
 
void 
CSynthProperties::OnAmpSliderNotification(WPARAM wParam, WORD wPosition) 
{ 
    switch (wParam) { 
 
    case TB_ENDTRACK: 
    case TB_THUMBTRACK: 
    case TB_LINEDOWN: 
    case TB_LINEUP: { 
        int Level = (int) SendMessage(m_hwndAmplitudeSlider, TBM_GETPOS, 0, 0L); 
        m_pSynth->put_Amplitude (MaxAmplitude - Level); 
        SetDlgItemInt (m_hwnd, IDC_AMPLITUDETEXT, MaxAmplitude - Level, TRUE); 
    } 
    break; 
 
    } 
} 
 
// 
// SetDirty 
// 
// notifies the property page site of changes 
 
void 
CSynthProperties::SetDirty() 
{ 
    m_bDirty = TRUE; 
    if (m_pPageSite) 
        m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY); 
}