home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / AutoPC / apcsdk10.exe / data1.cab / Win32_Samples / win32 / tuneit / tuneit.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-13  |  39.6 KB  |  1,430 lines

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2.  
  3. Copyright (c) 1998 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     tuneit.cpp
  8.  
  9. Abstract:
  10.  
  11.     TuneIt AutoPC Sample main application implementation.
  12.     This application highlights the use of Tuner API and the 
  13.     Audio Manager API, as well as constraint based resource scripts
  14.     and advanced UI elements.
  15.  
  16. Environment:
  17.  
  18.     AutoPC
  19.  
  20. -------------------------------------------------------------------*/
  21.  
  22. // Auto PC specific includes
  23. #include <windows.h>
  24. #include <olectl.h>
  25. #include <asfc.h>           // AutoPC Forms Manager
  26. #include <ascmnctl.h>       // AutoPC Common Controls
  27. #include <keypad.h>            // Defs for VK_*, WM_REMOTE_KEYDOWN, etc.
  28. #include <tunerapi.h>        // Tuner API
  29. #include <apcaudio.h>        // Audio Manager API
  30.  
  31. #define APCDBG_INIT "tuner"
  32. #include <apcdebug.h>
  33.  
  34. // Application specific includes
  35. #include "resource.h"
  36. #include "tunesink.h"
  37. #include "tuneit.h"
  38.  
  39.  
  40. //global
  41. extern CTuneitApp * g_pApp;
  42.  
  43. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  44. Class:
  45.     CTuneitApp
  46.  
  47. Description:
  48.     Main App class. Creates main form and manager, initializes and 
  49.     works with Tuner and Audio APIs.
  50. -------------------------------------------------------------------*/
  51.  
  52. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  53. Function:
  54.     CTuneitApp::CTuneitApp
  55.  
  56. Description:
  57.     Constructor.  Initializes all member variables.
  58.  
  59. Parameters:
  60.     HINSTANCE - Instance handle of application. (Constructor saves
  61.                 this to a member variable)
  62.  
  63. Returns:
  64.     Nothing.
  65. -------------------------------------------------------------------*/
  66. CTuneitApp::CTuneitApp(HINSTANCE hInst)
  67. {
  68.     //Forms, sinks, and managers
  69.     m_pManage            = NULL;            // Forms manager
  70.     m_pFormRadio        = NULL;            // Main Form (only form)
  71.     m_pEventSink        = NULL;            // Event Sink (attached to Form
  72.     m_pClassMsgSink        = NULL;            // ClassMsgSink attached to forms manager
  73.  
  74.     //Controls
  75.     m_pVolume            = NULL;            // Label showing Volume
  76.     m_pBand                = NULL;            // Label showing Band (AM/FM)
  77.     m_pFrequency        = NULL;            // Label showing current Frequency
  78.     m_pEditPreset        = NULL;            // Edit Control.  Displays preset name and edits it
  79.     m_pHertz            = NULL;            // Label showing Mhz or Khz
  80.     m_pMenuSettings        = NULL;            // Settings PowerListBox
  81.  
  82.     //Menu items
  83.     m_pItemBand            = NULL;            // StringSpinner - Band
  84.     m_pItemBass            = NULL;            // IntSpinner - Bass level
  85.     m_pItemTreble        = NULL;            // IntSpinner - Treble level
  86.     m_pItemFade            = NULL;            // IntSpinner - Fade setting
  87.     m_pItemBalance        = NULL;            // IntSpinner - Balance setting
  88.  
  89.     //handles
  90.     m_oh                = NULL;            // Forms context handle
  91.     m_hInst                = hInst;        // Application instance handle
  92.     m_hTuner            = NULL;            // Tuner handle
  93.     m_idThread            = NULL;            // Process thread ID
  94.     
  95.     //Strings (BSTR)
  96.     m_bstrAppName        = NULL;            // Application Name (used to register)
  97.     m_bstrTuneitMain    = NULL;            // Caption text "Tuneit - Main"
  98.     m_bstrTuneitSettings= NULL;            // Caption text "Tuneit - Settings"
  99.     m_bstrBandFM        = NULL;            // Text "FM"
  100.     m_bstrBandAM        = NULL;            // Text "AM"
  101.     m_bstrFrequency        = NULL;            // Text Buffer used to store current frequency
  102.     m_bstrVolume        = NULL;            // Text Buffer used to store current volume
  103.     m_bstrMhz            = NULL;            // Text "Mhz"
  104.     m_bstrKhz            = NULL;            // Text "Khz"
  105.  
  106.     //Tuner info    
  107.     m_iCurrentPreset[FM]= NO_PRESET;    // Current Preset on FM band (NO_PRESET means not set yet)
  108.     m_iCurrentPreset[AM]= NO_PRESET;    // Current Preset on AM band (NO_PRESET means not set yet)
  109.     m_dwCurrentFreq[FM]    = 107700;        // Current Freq on FM band
  110.     m_dwCurrentFreq[AM]    = 950;            // Current Freq on AM band
  111.     m_dwCurrentBand        = FM;            // Current Band
  112.     m_dwFreqFloor        = NULL;            // Floor (lowest) freq on current band
  113.     m_dwFreqCeiling        = NULL;            // Ceiling (max) freq on current band
  114.     m_dwFreqSteps        = NULL;            // Freq Step on current band
  115.     m_dwfAudioCaps        = NULL;            // Capabilities of audio system (flags used are in resource.h)
  116.  
  117.     //State info
  118.     m_State                = PRIMARY;        // Current state (enumeration in tuneit.h)
  119. }
  120.  
  121. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  122. Function:
  123.     CTuneitApp::~CTuneitApp
  124.  
  125. Description:
  126.     Destructor.  Does nothing.  All clean done in the CleanUp function.
  127.  
  128. Parameters:
  129.     Nothing.
  130.  
  131. Returns:
  132.     Nothing.
  133. -------------------------------------------------------------------*/
  134. CTuneitApp::~CTuneitApp()
  135. {
  136.  
  137. }
  138.  
  139. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  140. Function:
  141.     CTuneitApp::LoadBSTR
  142.  
  143. Description:
  144.     Loads a string resource and allocates a BSTR for it.  Strings can't
  145.     be longer than 255 chars.
  146.  
  147. Parameters:
  148.     UINT - Resource ID to load.
  149.  
  150. Returns:
  151.     BSTR - String allocated.
  152. -------------------------------------------------------------------*/
  153. BSTR
  154. CTuneitApp::LoadBSTR(UINT uID)
  155. {
  156.     WCHAR wszTemp[256];        // Buffer (we only hand 255 chars)
  157.     int iStringLen = 255;
  158.  
  159.     if((iStringLen = LoadStringW(m_hInst, uID, wszTemp, iStringLen)) == 0 ) 
  160.     {
  161.         return NULL;
  162.     }
  163.  
  164.     return SysAllocString(wszTemp);
  165. }
  166.  
  167. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  168. Function:
  169.     CTuneitApp::Init
  170.  
  171. Description:
  172.     Loads all strings, initializes tuner and audio manager.
  173.  
  174. Parameters:
  175.     Nothing.
  176.  
  177. Returns:
  178.     HRESULT - NOERROR on success.  E_FAIL on failure.
  179. -------------------------------------------------------------------*/
  180. HRESULT
  181. CTuneitApp::Init()
  182. {
  183.     m_idThread = GetCurrentThreadId();    // Save the Thread ID (used to send WM_QUIT message
  184.                                         // to application with PostThreadMsg)
  185.     
  186.     //Allocate all the strings we are going to use.
  187.     m_bstrAppName = LoadBSTR(STR_APP_SHELL_NAME);
  188.     if(!m_bstrAppName) return E_FAIL;
  189.  
  190.     m_bstrTuneitMain = LoadBSTR(IDS_TUNEIT_MAIN);
  191.     if(!m_bstrTuneitMain) return E_FAIL;
  192.  
  193.     m_bstrTuneitSettings = LoadBSTR(IDS_TUNEIT_SETTINGS);
  194.     if(!m_bstrTuneitSettings) return E_FAIL;
  195.  
  196.     m_bstrBandFM = LoadBSTR(IDS_BAND_FM);
  197.     if(!m_bstrBandFM) return E_FAIL;
  198.  
  199.     m_bstrBandAM = LoadBSTR(IDS_BAND_AM);
  200.     if(!m_bstrBandAM) return E_FAIL;
  201.  
  202.     m_bstrMhz = LoadBSTR(IDS_MHZ);
  203.     if(!m_bstrMhz) return E_FAIL;
  204.  
  205.     m_bstrKhz = LoadBSTR(IDS_KHZ);
  206.     if(!m_bstrKhz) return E_FAIL;
  207.  
  208.     m_bstrNoPreset = LoadBSTR(IDS_NOPRESET);
  209.     if(!m_bstrNoPreset) return E_FAIL;
  210.  
  211.     m_bstrStatus = SysAllocStringLen(NULL, 100);
  212.     if(!m_bstrStatus) return E_FAIL;
  213.  
  214.     m_bstrFrequency = SysAllocStringLen(NULL, 15);
  215.     if(!m_bstrFrequency) return E_FAIL;
  216.  
  217.     m_bstrVolume = SysAllocStringLen(NULL, 15);
  218.     if(!m_bstrVolume) return E_FAIL;
  219.  
  220.  
  221.     if(FAILED(InitAudioManager())) return E_FAIL;    // Call AudioManager init
  222.     if(FAILED(CreateEventSink())) return E_FAIL;    // Creates IASEventSink and IASClassMsgSink from CAppEventSink
  223.     if(FAILED(GetFormsManager())) return E_FAIL;    // Creates IfmManage
  224.     if(FAILED(CreateFormRadio())) return E_FAIL;    // Creates Main (only) form
  225.     if(FAILED(InitTuner())) return E_FAIL;            // Call Tuner init
  226.     if(FAILED(BuildSettingsMenu())) return E_FAIL;    // Create the Settings menu from resource
  227.                                                     // and set its item bounds
  228.  
  229.     // If application isn't started from shell, it won't be visible.  So we move it
  230.     // to the foreground.
  231.     HRESULT hr = m_pManage->MoveAppToForeground(GetCurrentProcessId(), 0, 0);
  232.     if(FAILED(hr)) return E_FAIL;
  233.     
  234.     return NOERROR;
  235. }
  236.  
  237. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  238. Function:
  239.     CTuneitApp::CleanUp
  240.  
  241. Description:
  242.     Frees all strings and releases all interfaces.
  243.  
  244. Parameters:
  245.     Nothing.
  246.  
  247. Returns:
  248.     Nothing.
  249. -------------------------------------------------------------------*/
  250. void
  251. CTuneitApp::CleanUp()
  252. {
  253.     // Free any non-null string pointers
  254.     
  255.     if(m_bstrTuneitMain) SysFreeString(m_bstrTuneitMain);
  256.     if(m_bstrTuneitSettings) SysFreeString(m_bstrTuneitSettings);
  257.     if(m_bstrBandFM) SysFreeString(m_bstrBandFM);
  258.     if(m_bstrBandAM) SysFreeString(m_bstrBandAM);
  259.     if(m_bstrFrequency) SysFreeString(m_bstrFrequency);
  260.     if(m_bstrVolume) SysFreeString(m_bstrVolume);
  261.     if(m_bstrMhz) SysFreeString(m_bstrMhz);
  262.     if(m_bstrKhz) SysFreeString(m_bstrKhz);
  263.     if(m_bstrNoPreset) SysFreeString(m_bstrNoPreset);
  264.  
  265.     // Release all Conrol interfaces
  266.     if(m_pBand) m_pBand->Release();
  267.     if(m_pFrequency) m_pFrequency->Release();
  268.     if(m_pEditPreset) m_pEditPreset->Release();
  269.     if(m_pVolume) m_pVolume->Release();
  270.     if(m_pHertz) m_pHertz->Release();
  271.     if(m_pMenuSettings) m_pMenuSettings->Release();
  272.  
  273.     // Release all the Settings menu items
  274.     if(m_pItemBand) m_pItemBand->Release();
  275.     if(m_pItemBass) m_pItemBass->Release();
  276.     if(m_pItemTreble) m_pItemTreble->Release();
  277.     if(m_pItemFade) m_pItemFade->Release();
  278.     if(m_pItemBalance) m_pItemBalance->Release();
  279.  
  280.     // Release Forms, sinks, Manager (DeRegisterApp as well)
  281.     if(m_pFormRadio) m_pFormRadio->Close();
  282.     if(m_pFormRadio) m_pFormRadio->Release();
  283.     if(m_pEventSink) m_pEventSink->Release();
  284.     if(m_pClassMsgSink) m_pClassMsgSink->Release();
  285.     if(m_pManage) m_pManage->DeregisterStartedApplication(m_oh, m_bstrAppName);
  286.     if(m_bstrAppName) SysFreeString(m_bstrAppName);
  287.     
  288.     if(m_pManage) m_pManage->Release();
  289. }
  290.  
  291. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  292. Function:
  293.     CTuneitApp::CreateFormRadio
  294.  
  295. Description:
  296.     Creates the one and only form.  Loads it from a form resource, then
  297.     gets all the interfaces that we will need during the Apps lifetime.
  298.  
  299. Parameters:
  300.     Nothing.
  301.  
  302. Returns:
  303.     HRESULT - NOERROR on success.  E_FAIL on failure.
  304. -------------------------------------------------------------------*/
  305. HRESULT 
  306. CTuneitApp::CreateFormRadio()
  307. {
  308.     HRESULT hr;
  309.  
  310.     IDispatch* pDispForm = NULL;
  311.     //LoadFormResource() creates the form for us as long as m_pFormRadio is NULL
  312.     hr = m_pManage->LoadFormResource(
  313.                 (OLE_HANDLE)m_hInst,            // Application instance handle
  314.                 IDF_MAIN,                       // Resource ID of form resource
  315.                 (IDispatch **)&pDispForm,    // Target to put interface
  316.                 m_pEventSink );                 // EventSink to attached to form
  317.     if(FAILED(hr)) return E_FAIL;
  318.  
  319.     hr = pDispForm->QueryInterface(IID_ASFORM, (PVOID *)&m_pFormRadio);
  320.     if(FAILED(hr)) return E_FAIL;
  321.  
  322.     pDispForm->Release();
  323.  
  324.     IDispatch* pDisp;
  325.     //Get Interface Pointers to controls we will need to access
  326.     hr = m_pFormRadio->ItemFromID(IDC_BAND, (IDispatch **)&pDisp);
  327.     if(FAILED(hr)) return E_FAIL;
  328.     hr = pDisp->QueryInterface(IID_ASLABEL, (PVOID *)&m_pBand);
  329.     if(FAILED(hr)) return E_FAIL;
  330.     pDisp->Release();
  331.  
  332.     hr = m_pFormRadio->ItemFromID(IDC_FREQUENCY, (IDispatch **)&pDisp);
  333.     if(FAILED(hr)) return E_FAIL;
  334.     hr = pDisp->QueryInterface(IID_ASLABEL, (PVOID *)&m_pFrequency);
  335.     if(FAILED(hr)) return E_FAIL;
  336.     pDisp->Release();
  337.  
  338.     hr = m_pFormRadio->ItemFromID(IDC_VOLUME, (IDispatch **)&pDisp);
  339.     if(FAILED(hr)) return E_FAIL;
  340.     hr = pDisp->QueryInterface(IID_ASLABEL, (PVOID *)&m_pVolume);
  341.     if(FAILED(hr)) return E_FAIL;
  342.     pDisp->Release();
  343.  
  344.     hr = m_pFormRadio->ItemFromID(IDC_HERTZ, (IDispatch **)&pDisp);
  345.     if(FAILED(hr)) return E_FAIL;
  346.     hr = pDisp->QueryInterface(IID_ASLABEL, (PVOID *)&m_pHertz);
  347.     if(FAILED(hr)) return E_FAIL;
  348.     pDisp->Release();
  349.  
  350.     hr = m_pFormRadio->ItemFromID(IDC_EDIT_PRESET, (IDispatch **)&pDisp);
  351.     if(FAILED(hr)) return E_FAIL;
  352.     hr = pDisp->QueryInterface(IID_ASEDITBOX, (PVOID *)&m_pEditPreset);
  353.     if(FAILED(hr)) return E_FAIL;
  354.     pDisp->Release();
  355.  
  356.     hr = m_pFormRadio->ItemFromID(IDC_SETTINGS, (IDispatch **)&pDisp);
  357.     if(FAILED(hr)) return E_FAIL;
  358.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOX, (PVOID *)&m_pMenuSettings);
  359.     if(FAILED(hr)) return E_FAIL;
  360.     pDisp->Release();
  361.  
  362.     // now we have to start it
  363.     hr = m_pManage->Start(m_pFormRadio);
  364.     if(FAILED(hr)) return E_FAIL;
  365.  
  366.     // Hide the Menu settings PowerListBox
  367.     m_pMenuSettings->put_Visible(FALSE);
  368.     m_pEditPreset->put_MaxChars(20);
  369.  
  370.     // Put focus on Preset Edit control, so when enter pressed, this control handles
  371.     // it and allows the user to edit the name
  372.     m_pFormRadio->SetFocus(m_pEditPreset);
  373.  
  374.  
  375.     return NOERROR;
  376. }
  377.  
  378. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  379. Function:
  380.     CTuneitApp::BuildSettingsMenu
  381.  
  382. Description:
  383.     Loads menu from resource.  Gets an interface to each item and
  384.     sets its Min,Max, and current Value from variables populated
  385.     by InitAudioManager.
  386.  
  387. Parameters:
  388.     Nothing.
  389.  
  390. Returns:
  391.     HRESULT - NOERROR on success.  E_FAIL on failure.
  392. -------------------------------------------------------------------*/
  393. HRESULT
  394. CTuneitApp::BuildSettingsMenu()
  395. {
  396.     HRESULT hr;
  397.  
  398.     // Set up menu
  399.     hr = m_pMenuSettings->AddItemsFromResource(
  400.         m_hInst,                        // Application instance handle (required for all resource loads)
  401.         MAKEINTRESOURCE(IDM_SETTINGS),    // Menu Name (converted using MAKEINTRESOURCE macro)
  402.         m_dwfAudioCaps);                // Menu State.  Audio Capabilities flags tell which menu options are valid
  403.     if(FAILED(hr)) return E_FAIL;
  404.  
  405.     IDispatch* pDisp;
  406.  
  407.     // Get an interface to each of the items in the menu
  408.     hr = m_pMenuSettings->Item(ID_BAND, &pDisp);
  409.     if(FAILED(hr)) return E_FAIL;
  410.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOXSTRINGSPINNER, (PVOID *)&m_pItemBand);
  411.     if(FAILED(hr)) return E_FAIL;
  412.     pDisp->Release();
  413.  
  414.     hr = m_pMenuSettings->Item(ID_BASS, &pDisp);
  415.     if(FAILED(hr)) return E_FAIL;
  416.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOXINTSPINNER, (PVOID *)&m_pItemBass);
  417.     if(FAILED(hr)) return E_FAIL;
  418.     pDisp->Release();
  419.  
  420.     hr = m_pMenuSettings->Item(ID_TREBLE, &pDisp);
  421.     if(FAILED(hr)) return E_FAIL;
  422.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOXINTSPINNER, (PVOID *)&m_pItemTreble);
  423.     if(FAILED(hr)) return E_FAIL;
  424.     pDisp->Release();
  425.     
  426.     hr = m_pMenuSettings->Item(ID_FADE, &pDisp);
  427.     if(FAILED(hr)) return E_FAIL;
  428.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOXINTSPINNER, (PVOID *)&m_pItemFade);
  429.     if(FAILED(hr)) return E_FAIL;
  430.     pDisp->Release();
  431.  
  432.     hr = m_pMenuSettings->Item(ID_BALANCE, &pDisp);
  433.     if(FAILED(hr)) return E_FAIL;
  434.     hr = pDisp->QueryInterface(IID_ASPOWERLISTBOXINTSPINNER, (PVOID *)&m_pItemBalance);
  435.     if(FAILED(hr)) return E_FAIL;
  436.     pDisp->Release();
  437.  
  438.     // Set bounds for all the valid intspinners
  439.     // BASS
  440.     if(m_dwfAudioCaps & FLAG_BASS)
  441.     {
  442.         m_pItemBass->put_Min(m_lSettingMin[BASS]);
  443.         m_pItemBass->put_Max(m_lSettingMax[BASS]);
  444.         m_pItemBass->put_Value(m_lSetting[BASS]);
  445.     }
  446.  
  447.     // BALANCE
  448.     if(m_dwfAudioCaps & FLAG_BALANCE)
  449.     {
  450.         m_pItemBalance->put_Min(m_lSettingMin[BALANCE]);
  451.         m_pItemBalance->put_Max(m_lSettingMax[BALANCE]);
  452.         m_pItemBalance->put_Value(m_lSetting[BALANCE]);
  453.     }
  454.  
  455.     // FADE
  456.     if(m_dwfAudioCaps & FLAG_FADE)
  457.     {
  458.         m_pItemFade->put_Min(m_lSettingMin[FADE]);
  459.         m_pItemFade->put_Max(m_lSettingMax[FADE]);
  460.         m_pItemFade->put_Value(m_lSetting[FADE]);
  461.     }
  462.  
  463.     // TREBLE
  464.     if(m_dwfAudioCaps & FLAG_TREBLE)
  465.     {
  466.         m_pItemTreble->put_Min(m_lSettingMin[TREBLE]);
  467.         m_pItemTreble->put_Max(m_lSettingMax[TREBLE]);
  468.         m_pItemTreble->put_Value(m_lSetting[TREBLE]);
  469.     }
  470.  
  471.     return NOERROR;
  472. }
  473.  
  474. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  475. Function:
  476.     CTuneitApp::CreateEventSink
  477.  
  478. Description:
  479.     Creates a new CAppEventSink object, then requests IASEventSink
  480.     and IASClassMsgSink interfaces from it. 
  481.  
  482. Parameters:
  483.     Nothing.
  484.  
  485. Returns:
  486.     HRESULT - NOERROR on success.  E_FAIL on failure.
  487. -------------------------------------------------------------------*/
  488. HRESULT 
  489. CTuneitApp::CreateEventSink()
  490. {
  491.     HRESULT hr;
  492.     CAppEventSink * pSink;
  493.     pSink = new CAppEventSink;
  494.  
  495.     // Get the IASEventSink interface to attach to form
  496.     hr = pSink->QueryInterface(IID_ASEVENTSINK, (PVOID *) &m_pEventSink);
  497.     if(FAILED(hr)) return E_FAIL;
  498.  
  499.     // Get the IASClassMsgSink interface to attach to forms manager
  500.     hr = pSink->QueryInterface(IID_ASCLASSMSGSINK, (PVOID *) &m_pClassMsgSink);
  501.     if(FAILED(hr)) return E_FAIL;
  502.  
  503.     return NOERROR;
  504. }
  505.  
  506. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  507. Function:
  508.     CTuneitApp::GetFormsManager
  509.  
  510. Description:
  511.     Gets a forms manager interface and registers our application.
  512.  
  513. Parameters:
  514.     Nothing.
  515.  
  516. Returns:
  517.     HRESULT - NOERROR on success.  E_FAIL on failure.
  518. -------------------------------------------------------------------*/
  519. HRESULT 
  520. CTuneitApp::GetFormsManager()
  521. {
  522.     HRESULT hr;
  523.                 
  524.     hr = CoCreateInstance(
  525.         CLSID_FMMANAGE,            // Create a fmManage Class COM object
  526.         NULL,                    // Not aggregate from anything
  527.         CLSCTX_INPROC_SERVER,    // Runs in our process
  528.         IID_FMMANAGE,            // Return the IfmManage interface
  529.         (PVOID *) &m_pManage);    // Interface Target
  530.     if(FAILED(hr)) return E_FAIL;
  531.  
  532.     // Get form context handle.  Required to RegisterStartedApplication
  533.     hr = m_pManage->GetFormsContextHandle(&m_oh);
  534.     if(FAILED(hr)) return E_FAIL;
  535.  
  536.     // Attach a class message sink to the forms manager
  537.     hr = m_pManage->put_ClassMsgSink(m_pClassMsgSink);
  538.     if(FAILED(hr)) return E_FAIL;
  539.     
  540.     // Register our application as started with the forms manager
  541.     hr = m_pManage->RegisterStartedApplication(m_oh, m_bstrAppName, 0, 0);
  542.     if(FAILED(hr)) return E_FAIL;
  543.  
  544.     return NOERROR;
  545. }
  546.  
  547. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  548. Function:
  549.     CTuneitApp::InitTuner
  550.  
  551. Description:
  552.     Initializes tuner.  Allocates memory for and clears preset-related variables.
  553.     Opens tuner and makes sure it can handle AM and FM.
  554.  
  555. Parameters:
  556.     Nothing.
  557.  
  558. Returns:
  559.     HRESULT - NOERROR on success.  E_FAIL on failure.
  560. -------------------------------------------------------------------*/
  561. HRESULT
  562. CTuneitApp::InitTuner()
  563. {
  564.     HRESULT            hr;
  565.     TUNERDEVCAPS    CapTuner;
  566.  
  567.     // Set up the presets
  568.     for(int i=0; i<10; i++)
  569.     {
  570.         m_Presets[FM][i].dwFreqValue = NO_PRESET;
  571.         m_bstrPresets[FM][i] = SysAllocStringLen(NULL, 30);
  572.         if(!m_bstrPresets[FM][i]) return E_FAIL;
  573.  
  574.         m_Presets[AM][i].dwFreqValue = NO_PRESET;
  575.         m_bstrPresets[AM][i] = SysAllocStringLen(NULL, 30);
  576.         if(!m_bstrPresets[AM][i]) return E_FAIL;
  577.     }
  578.  
  579.     // Get tuner's Device capabilities.  We are using Tuner Device 1
  580.     if(!TunerGetDevCaps(1, &CapTuner))
  581.     {
  582.         return    FALSE;
  583.     }
  584.  
  585.     // Make sure it supports both AM and FM
  586.     if((CapTuner.dwTunerCaps&(BAND_AM|BAND_FM)) != (BAND_AM|BAND_FM))
  587.     {
  588.         return    FALSE;
  589.     }
  590.  
  591.     // Open the Tuner.  We are using Tuner Device 1
  592.     m_hTuner = TunerOpen(1);
  593.     if(m_hTuner == INVALID_HANDLE_VALUE) return E_FAIL; //No tuner I guess
  594.  
  595.     hr = SetBand(m_dwCurrentBand);
  596.     if(FAILED(hr)) return E_FAIL;
  597.     
  598.     return NOERROR;
  599. }
  600.  
  601. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  602. Function:
  603.     CTuneitApp::SetBand
  604.  
  605. Description:
  606.     Sets the current Band.  
  607.  
  608. Parameters:
  609.     DWORD - Band (AM or FM, defined in tuneit.h)
  610.  
  611. Returns:
  612.     HRESULT - NOERROR on success.  E_FAIL on failure.
  613. -------------------------------------------------------------------*/
  614. HRESULT
  615. CTuneitApp::SetBand(DWORD dwBand)
  616. {
  617.     TUNERBANDINFO    tbInfo;
  618.     TUNERCONFIG        tc;
  619.     DWORD            dwBufSize;
  620.     DWORD            band;
  621.  
  622.     // We convert our application specific dwBand parameter to tuner API
  623.     // friendly BAND_FM or BAND_AM
  624.     if(dwBand == FM) band = BAND_FM;
  625.     else band = BAND_AM;
  626.  
  627.     m_dwCurrentBand = dwBand;
  628.     
  629.     // Use TunerGetBandInfo to get the frequency range of our new band
  630.     if(!TunerGetBandInfo(1, band, &tbInfo, sizeof(tbInfo), &dwBufSize))
  631.         return E_FAIL;
  632.     m_dwFreqFloor = tbInfo.RangeLow.dwFreqValue;
  633.     m_dwFreqCeiling = tbInfo.RangeHigh.dwFreqValue;
  634.  
  635.     // Set frequency steps.  If FM, also check to make sure our floor and ceiling frequencies
  636.     // land on things like 89.1, 107.9, and not 108.0 or 90.0
  637.     if(m_dwCurrentBand == FM)
  638.     {
  639.         m_dwFreqSteps = 200;
  640.         if(!(m_dwFreqFloor%200)) m_dwFreqFloor += 100;
  641.         if(!(m_dwFreqCeiling%200)) m_dwFreqCeiling -= 100;
  642.     }
  643.     else // Band is AM
  644.     {
  645.         m_dwFreqSteps = 10;
  646.     }
  647.  
  648.     //Set the Band by getting the current tuner config;
  649.     if(!TunerGetConfig(m_hTuner, &tc))
  650.         return E_FAIL;
  651.     //Changing a couple things;
  652.     tc.dwBand = band;
  653.     tc.CurrentFreq.dwFreqValue = m_dwCurrentFreq[m_dwCurrentBand];
  654.     tc.SeekStep.dwFreqValue = m_dwFreqSteps;
  655.     tc.dwState = STEREO_ON;
  656.     //And setting the new tuner config.
  657.     if(!TunerSetConfig(m_hTuner, &tc))
  658.         return E_FAIL;
  659.  
  660.     // update the radio's display
  661.     UpdateRadio();
  662.  
  663.     return NOERROR;
  664. }
  665.  
  666. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  667. Function:
  668.     CTuneitApp::SetBass
  669.  
  670. Description:
  671.     Sets the Bass level.  
  672.  
  673. Parameters:
  674.     long - Bass level
  675.  
  676. Returns:
  677.     Nothing.
  678. -------------------------------------------------------------------*/
  679. void
  680. CTuneitApp::SetBass(long lBass)
  681. {
  682.     AAM_EQPreset(AAM_FLAG_BASS | AAM_FLAG_SET, &lBass);
  683. }
  684.  
  685. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  686. Function:
  687.     CTuneitApp::SetTreble
  688.  
  689. Description:
  690.     Sets the Treble level.  
  691.  
  692. Parameters:
  693.     long - Treble level
  694.  
  695. Returns:
  696.     Nothing.
  697. -------------------------------------------------------------------*/
  698. void 
  699. CTuneitApp::SetTreble(long lTreble)
  700. {
  701.     AAM_EQPreset(AAM_FLAG_TREBLE | AAM_FLAG_SET, &lTreble);
  702. }
  703.  
  704. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  705. Function:
  706.     CTuneitApp::SetFade
  707.  
  708. Description:
  709.     Sets the Fade level.  
  710.  
  711. Parameters:
  712.     long - Fade level
  713.  
  714. Returns:
  715.     Nothing.
  716. -------------------------------------------------------------------*/
  717. void
  718. CTuneitApp::SetFade(long lFade)
  719. {
  720.     AAM_VolumeControl(AAM_FLAG_FADE | AAM_FLAG_SET, &lFade);
  721. }
  722.  
  723. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  724. Function:
  725.     CTuneitApp::SetBalance
  726.  
  727. Description:
  728.     Sets the Balance level.  
  729.  
  730. Parameters:
  731.     long - Balance level
  732.  
  733. Returns:
  734.     Nothing.
  735. -------------------------------------------------------------------*/
  736. void 
  737. CTuneitApp::SetBalance(long lBalance)
  738. {
  739.     AAM_VolumeControl(AAM_FLAG_BALANCE | AAM_FLAG_SET, &lBalance);
  740. }
  741.  
  742. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  743. Function:
  744.     CTuneitApp::InitAudioManager
  745.  
  746. Description:
  747.     Initializes the audio manager.  Gets EQ Capabilities and saves 
  748.     them in m_dwfAudioCaps using application defined flags (in resource.h)
  749.     Also gets the min/max/current level of the Balance, Fade, Bass, and Treble 
  750.     settings.
  751.  
  752. Parameters:
  753.     Nothing.
  754.  
  755. Returns:
  756.     HRESULT - NOERROR on success.  E_FAIL on failure.
  757. -------------------------------------------------------------------*/
  758. HRESULT
  759. CTuneitApp::InitAudioManager()
  760. {
  761.     long lRet;
  762.     long bMute = FALSE;
  763.     DWORD dwEQCaps = NULL;
  764.  
  765.     // Check support for Bass/Treble
  766.     if(AAM_GetEQCaps(&dwEQCaps))
  767.     {
  768.         return E_FAIL;
  769.     }
  770.     // Set our local audio manager capability storage variables using
  771.     // our local flags that are understood by the resource script 
  772.     // menu loading function
  773.     if(dwEQCaps & AAM_FLAG_BASS) m_dwfAudioCaps |= FLAG_BASS;
  774.     if(dwEQCaps & AAM_FLAG_TREBLE) m_dwfAudioCaps |= FLAG_TREBLE;
  775.  
  776.     // Check if we can get the fade/balance values,
  777.     // set our local 
  778.     if(!AAM_VolumeControl(AAM_FLAG_BALANCE | AAM_FLAG_GET, &lRet))
  779.         m_dwfAudioCaps |= FLAG_BALANCE;
  780.  
  781.     if(!AAM_VolumeControl(AAM_FLAG_FADE | AAM_FLAG_GET, &lRet))
  782.         m_dwfAudioCaps |= FLAG_FADE;
  783.  
  784.     //Get Vol min/max/current
  785.     if(!AAM_VolumeControl(AAM_FLAG_VOLUME | AAM_FLAG_RANGE | AAM_FLAG_GET, &lRet))
  786.     {
  787.         m_lVolMin = HIWORD(lRet);
  788.         m_lVolMax = LOWORD(lRet);
  789.     
  790.         //get current volume
  791.         AAM_VolumeControl(AAM_FLAG_VOLUME | AAM_FLAG_GET, &lRet);
  792.         m_lVolume = lRet;
  793.     }
  794.  
  795.     // Get Balance min/max/current    
  796.     if(!AAM_VolumeControl(AAM_FLAG_BALANCE | AAM_FLAG_GET, &lRet))
  797.     {
  798.         m_lSetting[BALANCE] = lRet;
  799.         AAM_VolumeControl(AAM_FLAG_BALANCE | AAM_FLAG_GET | AAM_FLAG_RANGE, &lRet);
  800.         m_lSettingMin[BALANCE] = -LOWORD(lRet);
  801.         m_lSettingMax[BALANCE] = LOWORD(lRet);
  802.     }
  803.  
  804.     // Get Fade min/max/current
  805.     if(!AAM_VolumeControl(AAM_FLAG_FADE | AAM_FLAG_GET, &lRet))
  806.     {
  807.         m_lSetting[FADE] = lRet;
  808.         AAM_VolumeControl(AAM_FLAG_FADE | AAM_FLAG_GET | AAM_FLAG_RANGE, &lRet);
  809.         m_lSettingMin[FADE] = -LOWORD(lRet);
  810.         m_lSettingMax[FADE] = LOWORD(lRet);
  811.     }
  812.  
  813.     // Get Bass min/max/current
  814.     if(!AAM_EQPreset(AAM_FLAG_BASS | AAM_FLAG_GET, &lRet))
  815.     {
  816.         m_lSetting[BASS] = lRet;
  817.         AAM_EQPreset(AAM_FLAG_BASS | AAM_FLAG_GET | AAM_FLAG_RANGE, &lRet);
  818.         m_lSettingMin[BASS] = -LOWORD(lRet);
  819.         m_lSettingMax[BASS] = LOWORD(lRet);
  820.     }
  821.  
  822.     // Get Treble min/max/current
  823.     if(!AAM_EQPreset(AAM_FLAG_TREBLE | AAM_FLAG_GET, &lRet))
  824.     {
  825.         m_lSetting[TREBLE] = lRet;
  826.         AAM_EQPreset(AAM_FLAG_TREBLE | AAM_FLAG_GET | AAM_FLAG_RANGE, &lRet);
  827.         m_lSettingMin[TREBLE] = -LOWORD(lRet);
  828.         m_lSettingMax[TREBLE] = LOWORD(lRet);
  829.     }
  830.  
  831.     //Turn mute off
  832.     AAM_VolumeControl(AAM_FLAG_MUTE | AAM_FLAG_SET, &bMute);
  833.  
  834.     //Set the source to radio
  835.     AAM_SelectSource(AAM_SRC_TUNER);
  836.  
  837.     return NOERROR;
  838. }
  839.  
  840. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  841. Function:
  842.     CTuneitApp::UpdateRadio
  843.  
  844. Description:
  845.     Updates all labels on the radio form.
  846.  
  847. Parameters:
  848.     Nothing.
  849.  
  850. Returns:
  851.     Nothing.
  852. -------------------------------------------------------------------*/
  853. void
  854. CTuneitApp::UpdateRadio()
  855. {
  856.     // If the we are on a preset, put that presets text into the edit
  857.     // box.  If we aren't on a preset, put No Preset text into edit box.
  858.     if(m_iCurrentPreset[m_dwCurrentBand] != NO_PRESET)
  859.     {
  860.         m_pEditPreset->put_Text(m_bstrPresets[m_dwCurrentBand][m_iCurrentPreset[m_dwCurrentBand]]);
  861.     }
  862.     else m_pEditPreset->put_Text(m_bstrNoPreset);
  863.     
  864.     // Update band, freq, and khz/mhz
  865.     if(m_dwCurrentBand == FM)
  866.     {
  867.         m_pBand->put_Caption(m_bstrBandFM);    // Set BAND text to "FM"
  868.  
  869.         // Print the frequency to a string in the right format. 
  870.         swprintf(m_bstrFrequency, L"%.1f", ((float)m_dwCurrentFreq[m_dwCurrentBand])/1000);
  871.         m_pFrequency->put_Caption(m_bstrFrequency);    // Set text on frequency label control
  872.         m_pHertz->put_Caption(m_bstrMhz);            // Set text on Mhz/Khz label control
  873.     }
  874.     else 
  875.     {
  876.         m_pBand->put_Caption(m_bstrBandAM);    // Set BAND text to "AM"
  877.  
  878.         // Print the frequency to a string.  Weird formatting necessary.
  879.         swprintf(m_bstrFrequency, L"%d", m_dwCurrentFreq[m_dwCurrentBand]);
  880.         m_pFrequency->put_Caption(m_bstrFrequency);    // Set text on frequency label control
  881.         m_pHertz->put_Caption(m_bstrKhz);            // Set text on Mhz/Khz lavel control
  882.     }
  883.  
  884.     // Update Volume (PrintF to a string, then set text on volume label control.
  885.     // The volume displayed is actually volume max - current volume, becuase
  886.     // volume actually means volume attenuation, so lower is louder
  887.     swprintf(m_bstrVolume, L"%d", (m_lVolMax - m_lVolume) );
  888.     m_pVolume->put_Caption(m_bstrVolume);
  889.     
  890. }
  891.  
  892. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  893. Function:
  894.     CTuneitApp::TuneToPreset
  895.  
  896. Description:
  897.     Tunes the radio to the preset in the current band.  Uses
  898.     TunerGetConfig and TunerSetConfig, not any of the Seek functions.
  899.  
  900. Parameters:
  901.     Nothing.
  902.  
  903. Returns:
  904.     Nothing.
  905. -------------------------------------------------------------------*/
  906. void
  907. CTuneitApp::TuneToPreset()
  908. {
  909.     // Set our local storage of the current frequency to the current
  910.     // presets frequency
  911.     m_dwCurrentFreq[m_dwCurrentBand] = 
  912.         m_Presets[m_dwCurrentBand][m_iCurrentPreset[m_dwCurrentBand]].dwFreqValue;    
  913.  
  914.     TUNERCONFIG tc;
  915.  
  916.     // Get initial configuration (since we only want to change the frequency
  917.     TunerGetConfig(m_hTuner, &tc);
  918.  
  919.     // Update the frequency the tuner was configured on
  920.     tc.CurrentFreq.dwFreqValue = m_dwCurrentFreq[m_dwCurrentBand];
  921.  
  922.     // Set the new tuner config
  923.     TunerSetConfig(m_hTuner, &tc);
  924.  
  925.     // Update the radios visual display to reflect the new information
  926.     UpdateRadio();
  927. }
  928.  
  929. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  930. Function:
  931.     CTuneitApp::TuneUp
  932.  
  933. Description:
  934.     Tunes the radio up one frequency step.  Uses TunerGetConfig and 
  935.     TunerSetConfig, not any of the Seek functions.
  936.  
  937. Parameters:
  938.     Nothing.
  939.  
  940. Returns:
  941.     Nothing.
  942. -------------------------------------------------------------------*/
  943. void
  944. CTuneitApp::TuneUp()
  945. {
  946.     TUNERCONFIG tc;
  947.  
  948.     m_dwCurrentFreq[m_dwCurrentBand] += m_dwFreqSteps;    // Increase Freq by a step
  949.  
  950.     // Make sure the step is within bounds, if not, flip around to the 
  951.     // floor (lowest) frequency in this band.
  952.     if(m_dwCurrentFreq[m_dwCurrentBand] > m_dwFreqCeiling) 
  953.     {
  954.         m_dwCurrentFreq[m_dwCurrentBand] = m_dwFreqFloor;
  955.     }
  956.  
  957.     // Check to see if the new freq is a preset.  Go through each preset and
  958.     // see if it is equal to the new current freq.
  959.     m_iCurrentPreset[m_dwCurrentBand] = NO_PRESET;
  960.     for(int i=0; i<10; i++)
  961.     {
  962.         if(m_Presets[m_dwCurrentBand][i].dwFreqValue == m_dwCurrentFreq[m_dwCurrentBand])
  963.         {
  964.             // If new frequency is a preset, save the preset number in a variable
  965.             m_iCurrentPreset[m_dwCurrentBand] = i;
  966.             break;
  967.         }
  968.     }
  969.  
  970.     // Tune to the new freq now!
  971.     // Get Current config
  972.     TunerGetConfig(m_hTuner, &tc);
  973.  
  974.     // Change the frequency tuner is configured to
  975.     tc.CurrentFreq.dwFreqValue = m_dwCurrentFreq[m_dwCurrentBand];
  976.  
  977.     // Send the new configuration to the tuner
  978.     TunerSetConfig(m_hTuner, &tc);
  979.  
  980.     // Update the radio form to reflect new frequency and/or new preset
  981.     UpdateRadio();
  982. }
  983.  
  984. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  985. Function:
  986.     CTuneitApp::TuneDown
  987.  
  988. Description:
  989.     Tunes the radio down one frequency step.  Uses TunerGetConfig and 
  990.     TunerSetConfig, not any of the Seek functions.
  991.  
  992. Parameters:
  993.     Nothing.
  994.  
  995. Returns:
  996.     Nothing.
  997. -------------------------------------------------------------------*/
  998. void
  999. CTuneitApp::TuneDown()
  1000. {
  1001.     TUNERCONFIG tc;
  1002.  
  1003.     // Decrease the current frequency by one step
  1004.     m_dwCurrentFreq[m_dwCurrentBand] -= m_dwFreqSteps;
  1005.  
  1006.     // Make sure we didn't fall below the minimum frequency for the band.
  1007.     // If we did, wrap around by setting current frequency to max freq.
  1008.     if(m_dwCurrentFreq[m_dwCurrentBand] < m_dwFreqFloor) 
  1009.     {
  1010.         m_dwCurrentFreq[m_dwCurrentBand] = m_dwFreqCeiling;
  1011.     }
  1012.  
  1013.     // Check to see if the new freq is a preset.  Go through each preset and
  1014.     // see if it is equal to the new current freq.
  1015.     m_iCurrentPreset[m_dwCurrentBand] = NO_PRESET;
  1016.     for(int i=0; i<10; i++)
  1017.     {
  1018.         if(m_Presets[m_dwCurrentBand][i].dwFreqValue == m_dwCurrentFreq[m_dwCurrentBand])
  1019.         {
  1020.             // If new frequency is a preset, save the preset number in a variable
  1021.             m_iCurrentPreset[m_dwCurrentBand] = i;
  1022.             break;
  1023.         }
  1024.     }
  1025.  
  1026.     // Tune to the new freq now!
  1027.     // Get current configuration
  1028.     TunerGetConfig(m_hTuner, &tc);
  1029.  
  1030.     // Change just the frequency configured to
  1031.     tc.CurrentFreq.dwFreqValue = m_dwCurrentFreq[m_dwCurrentBand];
  1032.  
  1033.     // Set the tuner to the new configuration
  1034.     TunerSetConfig(m_hTuner, &tc);
  1035.  
  1036.     // Update the radio form's display
  1037.     UpdateRadio();
  1038. }
  1039.  
  1040. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1041. Function:
  1042.     CTuneitApp::PreviousPreset
  1043.  
  1044. Description:
  1045.     Moves to the previous preset in the list.  If we aren't currently on a 
  1046.     valid preset frequency, it goes to the last preset in the list.  If we
  1047.     are on the first preset in the list, we go to the last preset.
  1048.  
  1049. Parameters:
  1050.     Nothing.
  1051.  
  1052. Returns:
  1053.     Nothing.
  1054. -------------------------------------------------------------------*/
  1055. void
  1056. CTuneitApp::PreviousPreset()
  1057. {
  1058.     // If the lowest preset in the preset list is not valid, then
  1059.     // none of the other presets in the list are valid, so we just return
  1060.     // without doing anything.
  1061.     if(m_Presets[m_dwCurrentBand][0].dwFreqValue == NO_PRESET)
  1062.     {
  1063.         return;
  1064.     }
  1065.  
  1066.     // If we are currently not on a preset, we start at the top
  1067.     // of the preset list and work down till we find the last valid preset
  1068.     // in the list, then we tune to that.
  1069.     if(m_iCurrentPreset[m_dwCurrentBand] == NO_PRESET)
  1070.     {
  1071.         for(int i=9; i >= 0; i--)
  1072.         { // Find last
  1073.             if(m_Presets[m_dwCurrentBand][i].dwFreqValue != NO_PRESET)
  1074.             { 
  1075.                 // Found a filled preset, set CurrentPreset to it and call
  1076.                 // TuneToPreset which tunes to whatever preset is set in CurrentPreset
  1077.                 m_iCurrentPreset[m_dwCurrentBand] = i;
  1078.                 TuneToPreset();
  1079.                 return;
  1080.             }
  1081.         }
  1082.     }
  1083.     else
  1084.     {
  1085.         // In the normal case, we are on a preset, and hit back, we go to the 
  1086.         // Previous preset
  1087.         m_iCurrentPreset[m_dwCurrentBand]--;
  1088.  
  1089.         // If we are at the beginning of the preset list, we loop and find the
  1090.         // last preset in the list
  1091.         if(m_iCurrentPreset[m_dwCurrentBand] < 0)
  1092.         { // Find last 
  1093.             for(int i=9; i >= 0; i--)
  1094.             {
  1095.                 if(m_Presets[m_dwCurrentBand][i].dwFreqValue != NO_PRESET)
  1096.                 { 
  1097.                     // Found a filled preset, Tune to it
  1098.                     m_iCurrentPreset[m_dwCurrentBand] = i;
  1099.                     TuneToPreset();
  1100.                     return;
  1101.                 }
  1102.             }
  1103.         }
  1104.  
  1105.         // If we didn't have to search through the list, we just Tune to the 
  1106.         // new preset
  1107.         else TuneToPreset();
  1108.     }
  1109. }
  1110.  
  1111. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1112. Function:
  1113.     CTuneitApp::NextPreset
  1114.  
  1115. Description:
  1116.     Moves to the next preset in the preset list.  If we are currently not
  1117.     on any preset, we go to the first preset in the list.  If we go
  1118.     to the end of the list, we loop back to the first preset.
  1119.  
  1120. Parameters:
  1121.     Nothing.
  1122.  
  1123. Returns:
  1124.     Nothing.
  1125. -------------------------------------------------------------------*/
  1126. void
  1127. CTuneitApp::NextPreset()
  1128. {
  1129.  
  1130.     // If the lowest preset in the preset list is not valid, then
  1131.     // none of the other presets in the list are valid, so we just return
  1132.     // without doing anything.
  1133.     if(m_Presets[m_dwCurrentBand][0].dwFreqValue == NO_PRESET)
  1134.     {
  1135.         return;
  1136.     }
  1137.  
  1138.     // Move to next preset
  1139.     m_iCurrentPreset[m_dwCurrentBand]++;
  1140.  
  1141.     // If the new preset we are on isn't valid (meaning we are at the end of the list),
  1142.     // we go back to the first preset in the list. (preset 0)
  1143.     if(m_Presets[m_dwCurrentBand][m_iCurrentPreset[m_dwCurrentBand]].dwFreqValue == NO_PRESET)
  1144.     {
  1145.         m_iCurrentPreset[m_dwCurrentBand] = 0;
  1146.     }
  1147.  
  1148.     // Tune to the new preset we are on
  1149.     TuneToPreset();
  1150. }
  1151.  
  1152. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1153. Function:
  1154.     CTuneitApp::PreSetPreset
  1155.  
  1156. Description:
  1157.     This function gets called before the edit box turns into editing
  1158.     mode.  We set the new state we are going to be in, and set blank 
  1159.     the    text in the edit box to null if we aren't on a preset.
  1160.  
  1161. Parameters:
  1162.     Nothing.
  1163.  
  1164. Returns:
  1165.     Nothing.
  1166. -------------------------------------------------------------------*/
  1167. void
  1168. CTuneitApp::PreSetPreset()
  1169. {
  1170.     m_State = SET_PRESET;
  1171.  
  1172.     if(m_iCurrentPreset[m_dwCurrentBand] == NO_PRESET)
  1173.     {
  1174.         m_pEditPreset->put_Text(NULL);
  1175.     }
  1176. }
  1177.  
  1178. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1179. Function:
  1180.     CTuneitApp::DoneSetPreset
  1181.  
  1182. Description:
  1183.     This function gets called after we commit a change to the preset
  1184.     name, or if we exit from the edit box editing mode.  
  1185.  
  1186. Parameters:
  1187.     BOOL - TRUE saves into a preset slot, FALSE just sets things back
  1188.         to our primary state.
  1189.  
  1190. Returns:
  1191.     Nothing.
  1192. -------------------------------------------------------------------*/
  1193. void
  1194. CTuneitApp::DoneSetPreset(BOOL bSave)
  1195. {
  1196.     // Sets our state variable telling that we are in the main view
  1197.     m_State = PRIMARY;
  1198.  
  1199.     // If we aren't going to save into a preset slot set text to "No Preset"
  1200.     // if we weren't on a preset and update radio display.
  1201.     if(bSave == FALSE) 
  1202.     {
  1203.         if(m_iCurrentPreset[m_dwCurrentBand] == NO_PRESET)
  1204.         {
  1205.             m_pEditPreset->put_Text(m_bstrNoPreset);
  1206.         }
  1207.         UpdateRadio();
  1208.         return; 
  1209.     }
  1210.  
  1211.     // Make sure they didn't enter something of length 0
  1212.     short nc;
  1213.     m_pEditPreset->get_NumChars(&nc);
  1214.     if(nc == 0)    // If they entered something of 0 length
  1215.     {
  1216.         UpdateRadio();
  1217.         return;
  1218.     }
  1219.  
  1220.     int i;
  1221.  
  1222.     // If we aren't currently on a preset, save it in the next available preset slot.
  1223.     if(m_iCurrentPreset[m_dwCurrentBand] == NO_PRESET) 
  1224.     { // New preset
  1225.         for(i=0; i<10; i++)
  1226.         {
  1227.             if(wcslen(m_bstrPresets[m_dwCurrentBand][i]) == 0) 
  1228.             {
  1229.                 m_pEditPreset->get_Text(&m_bstrPresets[m_dwCurrentBand][i]);
  1230.                 m_Presets[m_dwCurrentBand][i].dwFreqValue = m_dwCurrentFreq[m_dwCurrentBand];
  1231.                 m_iCurrentPreset[m_dwCurrentBand] = i;
  1232.                 break;
  1233.             }
  1234.         }
  1235.     }
  1236.     else    
  1237.     { // We were already on a preset just save the name
  1238.         m_pEditPreset->get_Text(&m_bstrPresets[m_dwCurrentBand][m_iCurrentPreset[m_dwCurrentBand]]);
  1239.     }
  1240.     UpdateRadio();
  1241. }
  1242.  
  1243. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1244. Function:
  1245.     CTuneitApp::DoneSettings
  1246.  
  1247. Description:
  1248.     This function gets called after the settings menu is exited.
  1249.     It sets everything back to the primary state's normals.
  1250.  
  1251. Parameters:
  1252.     Nothing.
  1253.  
  1254. Returns:
  1255.     Nothing.
  1256. -------------------------------------------------------------------*/
  1257. void 
  1258. CTuneitApp::DoneSettings()
  1259. {
  1260.     // Keep track of state change
  1261.     m_State = PRIMARY;
  1262.  
  1263.     // Hide the menu settings PowerListBox
  1264.     m_pMenuSettings->put_Visible(FALSE);
  1265.  
  1266.     // Change the form caption (titlebar) to show we're now in main view
  1267.     m_pFormRadio->put_Caption(m_bstrTuneitMain);
  1268.  
  1269.     // Set focus on Edit control
  1270.     m_pFormRadio->SetFocus(m_pEditPreset);
  1271.  
  1272.     // Update the radio view
  1273.     UpdateRadio();
  1274. }
  1275.  
  1276. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1277. Function:
  1278.     CTuneitApp::VolumeUp
  1279.  
  1280. Description:
  1281.     Increase the audio volume one step.  Actually lowers the volume variable,
  1282.     becuase on the Auto PC we speak of volume attenuation, so lower volume
  1283.     level is actually louder.
  1284.  
  1285. Parameters:
  1286.     Nothing.
  1287.  
  1288. Returns:
  1289.     Nothing.
  1290. -------------------------------------------------------------------*/
  1291. void CTuneitApp::VolumeUp()
  1292. {
  1293.     if (m_lVolume > m_lVolMin) m_lVolume--;
  1294.     AAM_VolumeControl(AAM_FLAG_VOLUME | AAM_FLAG_SET, &m_lVolume);
  1295.  
  1296.     // Update view
  1297.     UpdateRadio();
  1298. }
  1299.  
  1300. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1301. Function:
  1302.     CTuneitApp::VolumeUp
  1303.  
  1304. Description:
  1305.     Decreases the audio volume one step.  Actually increases the volume variable,
  1306.     becuase on the Auto PC we speak of volume attenuation, so the higher the
  1307.     volume level set, the quiter the audio actually is.
  1308.  
  1309. Parameters:
  1310.     Nothing.
  1311.  
  1312. Returns:
  1313.     Nothing.
  1314. -------------------------------------------------------------------*/
  1315. void CTuneitApp::VolumeDown()
  1316. {
  1317.     if (m_lVolume < m_lVolMax) m_lVolume++;
  1318.     AAM_VolumeControl(AAM_FLAG_VOLUME | AAM_FLAG_SET, &m_lVolume);
  1319.     
  1320.     UpdateRadio();
  1321. }
  1322.  
  1323. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1324. Function:
  1325.     CTuneitApp::Is*
  1326.  
  1327. Description:
  1328.     State functions just return TRUE/FALSE if they are in that state
  1329.     or not.  Used by message sinks since same message needs to be handled 
  1330.     differently in different states.  The states are PRIMARY (main view),
  1331.     SET_PRESET (edit box in editing mode), and SETTINGS (Settings menu up).
  1332.  
  1333. Parameters:
  1334.     Nothing.
  1335.  
  1336. Returns:
  1337.     BOOL - TRUE, in that state.  FLASE, not in that state.
  1338. -------------------------------------------------------------------*/
  1339.  
  1340. BOOL
  1341. CTuneitApp::IsPrimary()
  1342. {
  1343.     if(m_State == PRIMARY) return TRUE;
  1344.     else return FALSE;
  1345. }
  1346.  
  1347. BOOL
  1348. CTuneitApp::IsSetPreset()
  1349. {
  1350.     if(m_State == SET_PRESET) return TRUE;
  1351.     else return FALSE;
  1352. }
  1353.  
  1354. BOOL
  1355. CTuneitApp::IsSettings()
  1356. {
  1357.     if(m_State == SETTINGS) return TRUE;
  1358.     else return FALSE;
  1359. }
  1360.  
  1361. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1362. Function:
  1363.     CTuneitApp::OnMenu
  1364.  
  1365. Description:
  1366.     Function called when menu key pressed.  Sets the Settings Menu to 
  1367.     visible and changes the caption on the titlebar.
  1368.  
  1369. Parameters:
  1370.     Nothing.
  1371.  
  1372. Returns:
  1373.     Nothing.
  1374. -------------------------------------------------------------------*/
  1375. void
  1376. CTuneitApp::OnMenu()
  1377. {
  1378.     m_State = SETTINGS;
  1379.  
  1380.     m_pFormRadio->put_Caption(m_bstrTuneitSettings);
  1381.  
  1382.     m_pMenuSettings->put_Visible(TRUE);
  1383.     m_pFormRadio->SetFocus(m_pMenuSettings);
  1384. }
  1385.  
  1386. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1387. Function:
  1388.     WinMain
  1389.  
  1390. Description:
  1391.     Standard Windows entry point.  
  1392.  
  1393. Parameters:
  1394.     Standard Win32 CE parameters
  1395. -------------------------------------------------------------------*/
  1396. int APIENTRY WinMain(HINSTANCE hInst, 
  1397.                      HINSTANCE hPrevInst, 
  1398.                      LPWSTR wszCmd, 
  1399.                      int nCmdShow)
  1400. {
  1401.     MSG         msg;
  1402.  
  1403.     g_pApp = new CTuneitApp(hInst);            // Allocate our new App Class object
  1404.  
  1405.     CoInitializeEx( NULL, COINIT_MULTITHREADED );    // Initialize COM
  1406.     HRESULT hr = InitASFormsManager();                // Initialize the forms manager
  1407.     if(FAILED(hr))
  1408.     {
  1409.         CoUninitialize();
  1410.         return FALSE;
  1411.     }
  1412.  
  1413.     if(SUCCEEDED(g_pApp->Init()))
  1414.     {
  1415.         while (GetMessage(&msg, NULL, 0, 0))  // loop until the application quits
  1416.         {
  1417.             if(msg.hwnd) DispatchMessage(&msg);
  1418.             else g_pApp->m_pEventSink->ReceiveMsg(msg.message, msg.wParam, msg.lParam);
  1419.         }
  1420.     }
  1421.     g_pApp->CleanUp();
  1422.     delete g_pApp;
  1423.  
  1424.     UnInitASFormsManager(); // uninitialize the forms manager
  1425.     CoUninitialize();       // uninitialize COM
  1426.  
  1427.     return TRUE; 
  1428. }
  1429.  
  1430.