//==========================================================================; // // 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 - 1998 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------; // // GargProp.cpp // #include // Eliminate two expected level 4 warnings from the Microsoft compiler. // The class does not have an assignment or copy operator, and so cannot // be passed by value. This is normal. This file compiles clean at the // highest (most picky) warning level (-W4). #pragma warning(disable: 4511 4512) #include #include #include #include #include "resource.h" #include "igargle.h" #include "gargprop.h" // // CreateInstance // // Override CClassFactory method. // Set lpUnk to point to an IUnknown interface on a new CGargleProperties object // CUnknown * WINAPI CGargleProperties::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) { CUnknown *punk = new CGargleProperties(lpunk, phr); if (punk == NULL) { *phr = E_OUTOFMEMORY; } return punk; } // CreateInstance // // CGargleProperties constructor // // initialise a CGargleProperties object. // CGargleProperties::CGargleProperties(LPUNKNOWN lpunk, HRESULT *phr) : CBasePropertyPage( NAME("Gargle Property Page") , lpunk, IDD_GARGPROP, IDS_NAME) , m_pGargle(NULL) { } // (constructor) // // SetButtonText // // Utility function to set the text of the button to reflect the curent // waveform being used // void SetButtonText(HWND hwnd, int iShape) { if (iShape==0) { SetDlgItemText(hwnd, IDB_SQUARE_TRIANGLE, "Triangle wave->square"); } else { SetDlgItemText(hwnd, IDB_SQUARE_TRIANGLE, "Square wave->triangle"); } } // SetButtonText // // ConvertToPosition // // Convert a frequency f which is the gargle rate to a slider position. // f runs from 1 to 1000. // p runs from 0 to 300. // f = 10**(p/100) // p = 100*log10(f) // int ConvertToPosition(int f) { // protect against stupidity - should not occur if (f<1) f = 1; if (f>1000) f = 1000; double x = f; x = 100.0*log10(x); // protect against rounding at the ends int p = (int)x; if (p<0) p = 0; if (p>300) p = 300; return p; } // ConvertToPosition // // ConvertToFrequency // // Convert a slider position p to a frequency (gargle rate). // f runs from 1 to 1000. // p runs from 0 to 300. // f = 10**(p/100) // p = 100*log10(f) // int ConvertToFrequency(int p) { // protect against stupidity - should not occur if (p<0) p = 0; if (p>300) p = 300; double x = p; x = pow(10.0, x/100.0); // protect against rounding at the ends int f = (int)x; if (f<1) f = 1; if (f>1000) f = 1000; return f; } // ConvertToFrequency // // OnReceiveMessage // // Override CBasePropertyPage method. // Handle windows messages for the dialog of the property sheet. // BOOL CGargleProperties::OnReceiveMessage (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (uMsg) { case WM_INITDIALOG: m_hwndSlider = CreateSlider(hwnd); SetButtonText(hwnd, m_iGargleShape); ASSERT(m_hwndSlider); return TRUE; // I don't call setfocus... case WM_VSCROLL: ASSERT(m_hwndSlider); OnSliderNotification(wParam); return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDB_SQUARE_TRIANGLE) { // Cycle through shapes. See note below. // int iShape; m_pGargle->get_GargleShape(&iShape); // find what we now have iShape = 1-iShape; // change shapes m_pGargle->put_GargleShape(iShape); // put it back SetButtonText(hwnd, iShape); // reflect in dialog } else if (LOWORD(wParam) == IDB_DEFAULT) { // Restore the default settings. // Set the filter. // m_pGargle->put_DefaultGargleRate(); m_pGargle->put_GargleShape(0); // Set the slider position on the screen to match. // int iPos; m_pGargle->get_GargleRate(&iPos); iPos = ConvertToPosition(iPos); SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, iPos); // Set the button text to match. // int iShape; m_pGargle->get_GargleShape(&iShape); // find out what we now have SetButtonText(hwnd, iShape); } else { // Should not occur - debug! // char Buff[100]; wsprintf(Buff, "wParam=%08x", wParam); #ifdef DEBUG DbgBreakPoint( Buff, TEXT(__FILE__), __LINE__ ); #else ASSERT(!"Should not occur - debug!"); #endif } return TRUE; case WM_DESTROY: DestroyWindow(m_hwndSlider); return TRUE; default: return FALSE; } // switch } // OnReceiveMessage // // OnConnect // // Override CBasePropertyPage method. // Get the interface to the filter. // Set the member variables m_iGargleRate and m_iGargleShape. // HRESULT CGargleProperties::OnConnect(IUnknown * punk) { // Get IGargle interface // if (punk == NULL) { DbgBreak("You can't call me with a NULL pointer!!"); return(E_POINTER); } ASSERT(m_pGargle == NULL); HRESULT hr = punk->QueryInterface(IID_IGargle, (void **) &m_pGargle); if (FAILED(hr)) { DbgBreak("Can't get IGargle interface."); return E_NOINTERFACE; } ASSERT(m_pGargle); m_pGargle->get_GargleRate(&m_iGargleRate); m_pGargle->get_GargleShape(&m_iGargleShape); return NOERROR; } // OnConnect // // OnDisconnect // // Override CBasePropertyPage method. // Release the private interface. // HRESULT CGargleProperties::OnDisconnect() { // // Release the interface // if (m_pGargle == NULL) { return( E_UNEXPECTED); } m_pGargle->Release(); m_pGargle = NULL; return(NOERROR); } // OnDisconnect // // OnDeactivate // // Destroy the dialog. // HRESULT CGargleProperties::OnDeactivate(void) { // // Remember the Gargle Rate and shape for the next Activate() call // m_pGargle->get_GargleRate(&m_iGargleRate); m_pGargle->get_GargleShape(&m_iGargleShape); return NOERROR; } // OnDeactivate // // CreateSlider // // Create the slider (common control) to allow the user to // adjust the gargling rate. // HWND CGargleProperties::CreateSlider(HWND hwndParent) { // Find how to convert dialog units to screen units // LONG XUnit = GetDialogBaseUnits(); LONG YUnit = XUnit>>16; XUnit = XUnit & 0x0000ffff; // Create the slider child window at a position which fits the dialog // HWND hwndSlider = CreateWindow( TRACKBAR_CLASS , TEXT("") , WS_CHILD | WS_VISIBLE | TBS_VERT | TBS_BOTH , 15*XUnit // x , 0 // y , 5*XUnit // width , 5*YUnit // Height , hwndParent , NULL // menu , g_hInst , NULL // CLIENTCREATESTRUCT ); if (hwndSlider == NULL) { DWORD dwErr = GetLastError(); DbgLog((LOG_ERROR, 1 , TEXT("Could not create window. error code: 0x%x"), dwErr)); return NULL; } // Set the range to 0..300 which is converted into Hz as 10**(p/100) // where p is the slider position. SeeConvertToFrequency() above. // SendMessage(hwndSlider, TBM_SETRANGE, TRUE, MAKELONG(0, 300) ); // Set a tick at the default of 10Hz which is 100 on the log scale. // Put another one at 100Hz which corresponds to 200 on the log scale. // SendMessage(hwndSlider, TBM_SETTIC, 0, 100L); SendMessage(hwndSlider, TBM_SETTIC, 0, 200L); // Set the slider position according to the value we obtain from // initialisation or from the last Deactivate() call. // int iPos = ConvertToPosition(m_iGargleRate); SendMessage(hwndSlider, TBM_SETPOS, TRUE, iPos); return hwndSlider; } // CreateSlider // // OnSliderNotification // // Handle the notification meesages from the slider control // void CGargleProperties::OnSliderNotification(WPARAM wParam) { int iPos; switch (wParam) { case TB_BOTTOM: iPos = ConvertToPosition(MinGargleRate); SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, (LPARAM) iPos); break; case TB_TOP: iPos = ConvertToPosition(MaxGargleRate); SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, (LPARAM) iPos); break; case TB_PAGEDOWN: case TB_PAGEUP: break; case TB_THUMBPOSITION: case TB_ENDTRACK: { int iRate = (int) SendMessage(m_hwndSlider, TBM_GETPOS, 0, 0L); iRate = ConvertToFrequency(iRate); m_pGargle->put_GargleRate(iRate); } break; case TB_THUMBTRACK: // default handling of these messages is ok. case TB_LINEDOWN: case TB_LINEUP: break; } } // OnSliderNotification #pragma warning(disable: 4514) // "unreferenced inline function has been removed"