/******************************************************************************

  Source File:  deskmon.cpp

  Main code for the advanced desktop Monitor page

  Copyright (c) 1997-1998 by Microsoft Corporation

  Change History:

  12-16-97 AndreVa - Created It

******************************************************************************/


#include    "deskmon.h"
#define DECL_CRTFREE
#include <crtfree.h>


//
// The function DeviceProperties() is implemented in DevMgr.dll; Since we don't have a devmgr.h, we
// explicitly declare it here.
// 
typedef int (WINAPI  *DEVPROPERTIES)(
    HWND hwndParent,
    LPCTSTR MachineName,
    LPCTSTR DeviceID,
    BOOL ShowDeviceTree
    );


// OLE-Registry magic number
// 42071713-76d4-11d1-8b24-00a0c9068ff3
//
GUID g_CLSID_CplExt = { 0x42071713, 0x76d4, 0x11d1,
                        { 0x8b, 0x24, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}
                      };


DESK_EXTENSION_INTERFACE DeskInterface;

static const DWORD sc_MonitorHelpIds[] =
{
    IDC_MONITOR_GRP,    IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE, 
    IDI_MONITOR,        IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE, 
    IDC_MONITORDESC,    IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE, 
    IDC_MONITORS_LIST,  IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_MONITORTYPE_LISTBOX,
    IDC_PROPERTIES,     IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_PROPERTIES,

    IDC_MONSET_GRP,     IDH_NOHELP, 
    IDC_MONSET_FREQSTR, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_REFRESH, 
    IDC_MONSET_FREQ,    IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_REFRESH, 
    IDC_MONSET_PRUNNING_MODE,       IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_HIDEMODE_CHECKBOX, 
    IDC_MONSET_PRUNNING_MODE_DESC,  IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_HIDEMODE_CHECKBOX, 

    0, 0
};

///////////////////////////////////////////////////////////////////////////////
//
// Messagebox wrapper
//
///////////////////////////////////////////////////////////////////////////////


int
FmtMessageBox(
    HWND hwnd,
    UINT fuStyle,
    DWORD dwTitleID,
    DWORD dwTextID)
{
    TCHAR Title[256];
    TCHAR Text[1700];

    LoadString(g_hInst, dwTextID, Text, ARRAYSIZE(Text));
    LoadString(g_hInst, dwTitleID, Title, ARRAYSIZE(Title));

    return (MessageBox(hwnd, Text, Title, fuStyle));
}


// Constructors / destructor
CMonitorPage::CMonitorPage(HWND hDlg)
    : m_hDlg(hDlg)
    , m_lpdmPrevious(NULL)
    , m_bCanBePruned(FALSE)
    , m_bIsPruningReadOnly(TRUE)
    , m_bIsPruningOn(FALSE)
    , m_cMonitors(0)
    , m_hMonitorsList(NULL)
    , m_lpdmOnCancel(NULL)
    , m_bOnCancelIsPruningOn(FALSE)
{
    // preconditions
    //ASSERT(NULL != hDlg);
}


CMonitorPage::~CMonitorPage()
{
}


void CMonitorPage::OnApply()
{
    long lRet = PSNRET_INVALID_NOCHANGEPAGE;
    HINSTANCE hInst;
    LPDISPLAY_SAVE_SETTINGS lpfnDisplaySaveSettings = NULL;

    hInst = LoadLibrary(TEXT("desk.cpl"));
    if (hInst)
    {
        lpfnDisplaySaveSettings = (LPDISPLAY_SAVE_SETTINGS)
                                  GetProcAddress(hInst, "DisplaySaveSettings");
        if (lpfnDisplaySaveSettings)
        {
            long lSave = lpfnDisplaySaveSettings(DeskInterface.pContext, m_hDlg);
            LPDEVMODEW lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);

            if (lSave == DISP_CHANGE_SUCCESSFUL)
            {
                //
                // Save the current mode - to restore it in case the user cancels the p. sheet
                //
                m_lpdmOnCancel = m_lpdmPrevious = lpdmCurrent;
                m_bOnCancelIsPruningOn = m_bIsPruningOn;
                lRet = PSNRET_NOERROR;
            }
            else if (lSave == DISP_CHANGE_RESTART)
            {
                //
                // User wants to reboot system.
                //
                PropSheet_RestartWindows(GetParent(m_hDlg));
                lRet = PSNRET_NOERROR;
            }
            else
            {
                //
                // Keep the apply button active
                //
                lRet = PSNRET_INVALID_NOCHANGEPAGE;
                
                RefreshFrequenciesList();
                
                BOOL bCanBePruned, bIsPruningReadOnly, bIsPruningOn;
                DeskInterface.lpfnGetPruningMode(DeskInterface.pContext, 
                                                 &bCanBePruned, 
                                                 &bIsPruningReadOnly,
                                                 &bIsPruningOn);
                if(m_bIsPruningOn != bIsPruningOn)
                    InitPruningMode();
            }
        }

        FreeLibrary(hInst);
    }

    SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, lRet);
}

    
void CMonitorPage::OnCancel()
{
    if (m_bCanBePruned && !m_bIsPruningReadOnly && 
        ((m_bOnCancelIsPruningOn != 0) != (m_bIsPruningOn != 0)))
        DeskInterface.lpfnSetPruningMode(DeskInterface.pContext, m_bOnCancelIsPruningOn);

    DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, m_lpdmOnCancel);
};


void CMonitorPage::OnInitDialog()
{
    m_hMonitorsList = GetDlgItem(m_hDlg, IDC_MONITORS_LIST); 
    HWND hSingleMonitor = GetDlgItem(m_hDlg, IDC_MONITORDESC); 
    //ASSERT((NULL != m_hMonitorsList) && (NULL != hSingleMonitor));
    ListBox_ResetContent(m_hMonitorsList);

    //
    // Get the CPL extension interfaces from IDataObject.
    //
    STGMEDIUM stgmExt;
    FORMATETC fmteExt = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_INTERFACE),
                         (DVTARGETDEVICE FAR *) NULL,
                         DVASPECT_CONTENT,
                         -1,
                         TYMED_HGLOBAL};

    HRESULT hres = g_lpdoTarget->GetData(&fmteExt, &stgmExt);

    if (SUCCEEDED(hres) && stgmExt.hGlobal)
    {
        //
        // The storage now contains Display device path (\\.\DisplayX) in UNICODE.
        //
        PDESK_EXTENSION_INTERFACE pInterface =
            (PDESK_EXTENSION_INTERFACE) GlobalLock(stgmExt.hGlobal);

        RtlCopyMemory(&DeskInterface,
                      pInterface,
                      min(pInterface->cbSize,
                      sizeof(DESK_EXTENSION_INTERFACE)));

        GlobalUnlock(stgmExt.hGlobal);
        ReleaseStgMedium(&stgmExt);
    }

    //
    // Get the adapter devnode.
    // The adapter is the parent of all monitors in the device tree.
    //
    DEVINST devInstAdapter;
    BOOL bDevInstAdapter = FALSE;

    STGMEDIUM stgmAdpId;
    FORMATETC fmteAdpId = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_ID),
                           (DVTARGETDEVICE FAR *) NULL,
                           DVASPECT_CONTENT,
                           -1,
                           TYMED_HGLOBAL};

    hres = g_lpdoTarget->GetData(&fmteAdpId, &stgmAdpId);

    if(SUCCEEDED(hres) && stgmAdpId.hGlobal)
    {
        LPWSTR pwDeviceID = (LPWSTR) GlobalLock(stgmAdpId.hGlobal);

        #ifdef UNICODE
            bDevInstAdapter = (CM_Locate_DevNodeW(&devInstAdapter, pwDeviceID, 0) == CR_SUCCESS);
        #else // UNICODE
    	    CHAR szBuffer[MAX_PATH];
            bDevInstAdapter = (BOOL)WideCharToMultiByte(CP_ACP, 0, pwDeviceID, lstrlenW(pwDeviceID) + 1,
                                                        szBuffer, MAX_PATH, NULL, NULL);
            if(bDevInstAdapter)
            {
                bDevInstAdapter = (CM_Locate_DevNodeA(&devInstAdapter, szBuffer, 0) == CR_SUCCESS);
            }
        #endif // UNICODE

        GlobalUnlock(stgmAdpId.hGlobal);
        ReleaseStgMedium(&stgmAdpId);
    }

    //
    // Get the adapter device and enum all monitors
    //
    STGMEDIUM stgmAdpDev;
    FORMATETC fmteAdpDev = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_DEVICE),
                           (DVTARGETDEVICE FAR *) NULL,
                           DVASPECT_CONTENT,
                           -1,
                           TYMED_HGLOBAL};
    hres = g_lpdoTarget->GetData(&fmteAdpDev, &stgmAdpDev);

    if (SUCCEEDED(hres) && stgmAdpDev.hGlobal)
    {
        LPWSTR pwDisplayDevice = (LPWSTR)GlobalLock(stgmAdpDev.hGlobal);
        LPTSTR pBuffer = NULL;

        #ifdef UNICODE
            pBuffer = pwDisplayDevice;
        #else // UNICODE
    	    CHAR szBuffer[MAX_PATH];
            if(WideCharToMultiByte(CP_ACP, 0, pwDisplayDevice, lstrlenW(pwDisplayDevice) + 1,
                                   szBuffer, MAX_PATH, NULL, NULL))
                pBuffer = szBuffer;
        #endif // UNICODE

        if(NULL != pBuffer)
        {
            DISPLAY_DEVICE ddMon;
            BOOL bSuccess = FALSE;
            int cMonitors = 0;

            do 
            {
                ZeroMemory(&ddMon, sizeof(ddMon));
                ddMon.cb = sizeof(DISPLAY_DEVICE);

                bSuccess = EnumDisplayDevices(pBuffer, cMonitors, &ddMon, 0);
                if (bSuccess) 
                {
                    ++cMonitors;

                    if (ddMon.StateFlags & DISPLAY_DEVICE_ATTACHED)
                    {
                        if(0 == m_cMonitors)
                            SendDlgItemMessage(m_hDlg, IDC_MONITORDESC, WM_SETTEXT, 0, (LPARAM)ddMon.DeviceString);
    
                        int nNewItem = ListBox_AddString(m_hMonitorsList, (LPTSTR)ddMon.DeviceString);
                        if(nNewItem >= 0)
                        {
                            ++m_cMonitors;
    
                            ListBox_SetItemData(m_hMonitorsList, nNewItem, NULL);
                            if(bDevInstAdapter)
                                SaveMonitorInstancePath(devInstAdapter, ddMon.DeviceID, nNewItem);
                        }
                    }
                }
            }
            while (bSuccess);
        }
        
        GlobalUnlock(stgmAdpDev.hGlobal);
        ReleaseStgMedium(&stgmAdpDev);
    }

    if(m_cMonitors <= 0)
    {
        TCHAR szDefaultMonitor[MAX_PATH];
        LoadString(g_hInst, IDS_DEFAULT_MONITOR, szDefaultMonitor, ARRAYSIZE(szDefaultMonitor));
        SendDlgItemMessage(m_hDlg, IDC_MONITORDESC, WM_SETTEXT, 0, (LPARAM)szDefaultMonitor);
        EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), FALSE);
    }
    else if(m_cMonitors == 1)
    {
        BOOL bEnable = ((ListBox_GetCount(m_hMonitorsList) >= 1) &&
                        (NULL != (LPTSTR)ListBox_GetItemData(m_hMonitorsList, 0)));
        EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), bEnable);
    }
    else
    {
        ListBox_SetCurSel(m_hMonitorsList, 0);
        OnSelMonitorChanged();
    }

    ShowWindow(((m_cMonitors <= 1) ? m_hMonitorsList : hSingleMonitor), SW_HIDE);

    //
    // Init the pruning mode check box
    //
    InitPruningMode();
    m_bOnCancelIsPruningOn = m_bIsPruningOn;

    //
    // Save the current mode - in case the user cancels the p. sheet    
    //
    m_lpdmOnCancel = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
}


void CMonitorPage::OnDestroy()
{
    //ASSERT(NULL != m_hMonitorsList);
    int cMonitors = ListBox_GetCount(m_hMonitorsList);
    for(int nMonitor = 0; nMonitor < cMonitors; ++nMonitor)
    {
        LPTSTR pMonitorInstancePath = (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nMonitor);
        if(NULL != pMonitorInstancePath)
            LocalFree(pMonitorInstancePath);
    }
}


void CMonitorPage::SaveMonitorInstancePath(DEVINST devInstAdapter, LPCTSTR pMonitorID, int nNewItem)
{
    //ASSERT(NULL != m_hMonitorsList);

    DEVINST devInstChild, devInstPrevChild;
    TCHAR szBuff[256]; // buffer used to concatenate: HARDWAREID, "\" and DRIVER
                       // this is what EnumDisplayDevice returns in DeviceID in case of a monitor
    ULONG lenBuff; // size of the buffer, in bytes

    if (CM_Get_Child(&devInstChild, devInstAdapter, 0) != CR_SUCCESS) 
        return;

    do 
    {
        devInstPrevChild = devInstChild;

        //CM_DRP_HARDWAREID
        lenBuff = ARRAYSIZE(szBuff) - 2 ; // make sure we have place to append "\"
        if (CM_Get_DevNode_Registry_Property(devInstChild,
                                             CM_DRP_HARDWAREID,
                                             NULL,
                                             szBuff,
                                             &lenBuff,
                                             0) != CR_SUCCESS)
            continue;

        // "\"
        lstrcat(szBuff, TEXT("\\"));

        //CM_DRP_DRIVER
        lenBuff = sizeof(szBuff) - lstrlen(szBuff) * sizeof(TCHAR);
        if (CM_Get_DevNode_Registry_Property(devInstChild,
                                             CM_DRP_DRIVER,
                                             NULL,
                                             szBuff + lstrlen(szBuff),
                                             &lenBuff,
                                             0) != CR_SUCCESS)
            continue;

        if (lstrcmpi(szBuff, pMonitorID) == 0) 
        {
            LPTSTR pMonitorInstancePath = (LPTSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(TCHAR));
            if((NULL != pMonitorInstancePath) &&
               (CM_Get_Device_ID(devInstChild, pMonitorInstancePath, MAX_PATH, 0) == CR_SUCCESS))
                ListBox_SetItemData(m_hMonitorsList, nNewItem, (LPARAM)pMonitorInstancePath);
            break;
        }

    } 
    while(CM_Get_Sibling(&devInstChild, devInstPrevChild, 0) == CR_SUCCESS);
}


void CMonitorPage::OnSelMonitorChanged()
{
    //ASSERT(NULL != m_hMonitorsList);
    //ASSERT(NULL != m_hDlg);
   
    //
    // Enable / Disable the Properties button
    //
    BOOL bEnable = FALSE;
    if(ListBox_GetCount(m_hMonitorsList) >= 1)
    {
        int nCurSel = ListBox_GetCurSel(m_hMonitorsList);
        if(nCurSel >= 0)
            bEnable = (NULL != (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nCurSel));
    }
    EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), bEnable);
}


void CMonitorPage::OnProperties()
{
    int nSelMonitor;

    if(m_cMonitors <= 0)
        nSelMonitor = -1;
    else if(m_cMonitors == 1)
        nSelMonitor = ((ListBox_GetCount(m_hMonitorsList) >= 1) ? 0 : -1);
    else
        nSelMonitor = ListBox_GetCurSel(m_hMonitorsList);

    if(nSelMonitor < 0)
        return;

    //ASSERT(nSelMonitor < ListBox_GetCount(m_hMonitorsList));

    LPTSTR pMonitorInstancePath = (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nSelMonitor);
    if(NULL != pMonitorInstancePath)
    {
        HINSTANCE hinstDevMgr = LoadLibrary(TEXT("DEVMGR.DLL"));

        if (hinstDevMgr)
        {
            DEVPROPERTIES pfnDevProp = NULL;
            #ifdef UNICODE
                pfnDevProp = (DEVPROPERTIES)GetProcAddress(hinstDevMgr, "DevicePropertiesW");
            #else // UNICODE
                pfnDevProp = (DEVPROPERTIES)GetProcAddress(hinstDevMgr, "DevicePropertiesA");
            #endif // UNICODE

            if (pfnDevProp)
            {
                //Display the property sheets for this device.
                (*pfnDevProp)(m_hDlg, NULL, pMonitorInstancePath, FALSE);
            }

            FreeLibrary(hinstDevMgr);
        }
    }
}


BOOL CMonitorPage::OnSetActive()
{
    LPDEVMODEW lpdm;
    DWORD      item;
    LPDEVMODEW lpdmCurrent, lpdmPrevious;
    LPDEVMODEW lpdmTmp;
    DWORD      i = 0;
    TCHAR      achFre[50];
    TCHAR      achText[80];
    DWORD      pos;
    HWND       hFreq;
    
    InitPruningMode();
    
    //
    // Build the list of refresh rates for the currently selected mode.
    //
    lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
    hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
    
    if (lpdmCurrent == NULL)
        return -1;

    if (m_lpdmPrevious) 
    {
        if (lpdmCurrent->dmBitsPerPel != m_lpdmPrevious->dmBitsPerPel ||
            lpdmCurrent->dmPelsWidth  != m_lpdmPrevious->dmPelsWidth  ||
            lpdmCurrent->dmPelsHeight != m_lpdmPrevious->dmPelsHeight) 
        {
            ComboBox_ResetContent(hFreq);
        }
    }
    m_lpdmPrevious = lpdmCurrent;
    
    while (lpdm = DeskInterface.lpfnEnumAllModes(DeskInterface.pContext, i++)) {
    
        //
        // Only show refresh frequencies for current modes.
        //
        if ((lpdmCurrent->dmBitsPerPel != lpdm->dmBitsPerPel)  ||
            (lpdmCurrent->dmPelsWidth  != lpdm->dmPelsWidth)   ||
            (lpdmCurrent->dmPelsHeight != lpdm->dmPelsHeight))
            continue;
    
        //
        // convert bit count to number of colors and make it a string
        //
        // WARNING should this be 0 ?
        if (lpdm->dmDisplayFrequency == 1) {
            LoadString(g_hInst, IDS_DEFFREQ, achText, ARRAYSIZE(achText));
        }
        else {
            DWORD  idFreq = IDS_FREQ;
    
            if (lpdm->dmDisplayFrequency < 50)
            {
                idFreq = IDS_INTERLACED;
            }
    
            LoadString(g_hInst, idFreq, achFre, ARRAYSIZE(achFre));
            wsprintf(achText, TEXT("%d %s"), lpdm->dmDisplayFrequency, achFre);
        }
    
        //
        // Insert the string in the right place
        //
        pos = 0;
    
        while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos))  {
            if ((ULONG_PTR)lpdmTmp != CB_ERR) {
                if (lpdmTmp->dmDisplayFrequency == lpdm->dmDisplayFrequency) {
                    break;
                }
    
                if (lpdmTmp->dmDisplayFrequency < lpdm->dmDisplayFrequency) {
                    pos++;
                    continue;
                }
            }
    
            //
            // Insert it here
            //
            item = ComboBox_InsertString(hFreq, pos, achText);
            ComboBox_SetItemData(hFreq, item, lpdm); 
            break;
        }
    }
    
    //
    // Finally, set the right selection
    //
    pos = 0;
    while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos)) {
    
        if ((ULONG_PTR)lpdmTmp == CB_ERR) {
            FmtMessageBox(m_hDlg,
                          MB_OK | MB_ICONINFORMATION,
                          IDS_BAD_REFRESH,
                          IDS_BAD_REFRESH);
            return -1;
        }
    
        if (lpdmTmp->dmDisplayFrequency == lpdmCurrent->dmDisplayFrequency) {
            ComboBox_SetCurSel(hFreq, pos);
            break;
        }
    
        pos++;
    }
    
    return 0;
}


void CMonitorPage::OnFrequencyChanged()
{
    DWORD       item;
    HWND        hFreq;
    LPDEVMODEW  lpdmSelected = NULL, lpdmCurrent = NULL;

    //
    // Save the mode back
    //
    hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
    item = ComboBox_GetCurSel(hFreq);
    if (item == LB_ERR) 
        return;

    lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
    lpdmSelected = (LPDEVMODEW) ComboBox_GetItemData(hFreq, item);

    if (lpdmSelected && (lpdmSelected != lpdmCurrent))
        DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, lpdmSelected);
}


void CMonitorPage::OnPruningModeChanged()
{
    if (m_bCanBePruned && !m_bIsPruningReadOnly)
    {
        BOOL bNewIsPruningOn = (BST_UNCHECKED != IsDlgButtonChecked(m_hDlg, IDC_MONSET_PRUNNING_MODE));
        if((m_bIsPruningOn != 0) != bNewIsPruningOn)
        {
            m_bIsPruningOn = bNewIsPruningOn;
            DeskInterface.lpfnSetPruningMode(DeskInterface.pContext, m_bIsPruningOn);
            RefreshFrequenciesList();
        }
    }
}


void CMonitorPage::InitPruningMode()
    {
    m_bCanBePruned = FALSE;
    m_bIsPruningReadOnly = TRUE;
    m_bIsPruningOn = FALSE;
    
    DeskInterface.lpfnGetPruningMode(DeskInterface.pContext, 
                                     &m_bCanBePruned, 
                                     &m_bIsPruningReadOnly,
                                     &m_bIsPruningOn);
    
    BOOL bEnable = (m_bCanBePruned && !m_bIsPruningReadOnly);
    EnableWindow(GetDlgItem(m_hDlg, IDC_MONSET_PRUNNING_MODE), bEnable);
    EnableWindow(GetDlgItem(m_hDlg, IDC_MONSET_PRUNNING_MODE_DESC), bEnable);

    BOOL bChecked = (m_bCanBePruned && m_bIsPruningOn);
    CheckDlgButton(m_hDlg, IDC_MONSET_PRUNNING_MODE, bChecked);
    }


void CMonitorPage::RefreshFrequenciesList()
{
    LPDEVMODEW lpdm;
    DWORD      item;
    LPDEVMODEW lpdmCurrent, lpdmPrevious;
    LPDEVMODEW lpdmTmp;
    DWORD      i = 0;
    TCHAR      achFre[50];
    TCHAR      achText[80];
    DWORD      pos;
    HWND       hFreq;

    HWND hwndCurr = GetFocus();
    
    //
    // Build the list of refresh rates for the currently selected mode.
    //
    
    lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
    if (lpdmCurrent == NULL)
        return;

    hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
    ComboBox_ResetContent(hFreq);
    
    while (lpdm = DeskInterface.lpfnEnumAllModes(DeskInterface.pContext, i++))
    {

        //
        // Only show refresh frequencies for current modes.
        //
        if ((lpdmCurrent->dmBitsPerPel != lpdm->dmBitsPerPel)  ||
            (lpdmCurrent->dmPelsWidth  != lpdm->dmPelsWidth)   ||
            (lpdmCurrent->dmPelsHeight != lpdm->dmPelsHeight))
            continue;

        //
        // convert bit count to number of colors and make it a string
        //
        // WARNING should this be 0 ?
        if (lpdm->dmDisplayFrequency == 1)
        {
            LoadString(g_hInst, IDS_DEFFREQ, achText, ARRAYSIZE(achText));
        }
        else
        {
            DWORD  idFreq = IDS_FREQ;

            if (lpdm->dmDisplayFrequency < 50)
            {
                idFreq = IDS_INTERLACED;
            }

            LoadString(g_hInst, idFreq, achFre, ARRAYSIZE(achFre));
            wsprintf(achText, TEXT("%d %s"), lpdm->dmDisplayFrequency, achFre);
        }

        //
        // Insert the string in the right place
        //
        pos = 0;

        while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos))
        {
            if ((ULONG_PTR)lpdmTmp != CB_ERR)
            {
                if (lpdmTmp->dmDisplayFrequency == lpdm->dmDisplayFrequency)
                {
                    break;
                }

                if (lpdmTmp->dmDisplayFrequency < lpdm->dmDisplayFrequency)
                {
                    pos++;
                    continue;
                }
            }

            //
            // Insert it here
            //
            item = ComboBox_InsertString(hFreq, pos, achText);
            ComboBox_SetItemData(hFreq, item, lpdm); 
            break;
        }
    }

    //
    // Finally, set the right selection
    //
    pos = 0;
    while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos))
    {

        if ((ULONG_PTR)lpdmTmp == CB_ERR)
        {
            FmtMessageBox(m_hDlg,
                          MB_OK | MB_ICONINFORMATION,
                          IDS_BAD_REFRESH,
                          IDS_BAD_REFRESH);
            break;
        }

        if (lpdmTmp->dmDisplayFrequency == lpdmCurrent->dmDisplayFrequency)
        {
            ComboBox_SetCurSel(hFreq, pos);
            break;
        }

        pos++;
    }

    if (hwndCurr)
        SetFocus(hwndCurr);

    return;
}


#ifdef DBG

void CMonitorPage::AssertValid() const
{
    //ASSERT(m_hDlg != NULL);
    //ASSERT(!m_bIsPruningOn || m_bCanBePruned);
}

#endif


//---------------------------------------------------------------------------
//
// PropertySheeDlgProc()
//
//  The dialog procedure for the "Monitor" property sheet page.
//
//---------------------------------------------------------------------------
INT_PTR
CALLBACK
PropertySheeDlgProc(
    HWND hDlg,
    UINT uMessage,
    WPARAM wParam,
    LPARAM lParam
    )
{
    NMHDR FAR *lpnm;
    CMonitorPage * pMonitorPage = (CMonitorPage*)GetWindowLongPtr(hDlg, DWLP_USER);

    switch (uMessage)
    {
    case WM_INITDIALOG:

        if (!g_lpdoTarget)
        {
            return FALSE;
        }
        else
        {
            //ASSERT(!pMonitorPage);
            pMonitorPage = new CMonitorPage(hDlg);
            if(!pMonitorPage)
                return FALSE;
            SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pMonitorPage);
            pMonitorPage->OnInitDialog();
        }

        break;

    case WM_DESTROY:

        if (pMonitorPage)
        {
            pMonitorPage->OnDestroy();
            SetWindowLongPtr(hDlg, DWLP_USER, NULL);
            delete pMonitorPage;
        }

        break;

    case WM_COMMAND:

        switch (GET_WM_COMMAND_ID(wParam, lParam))
        {
        case IDC_MONSET_FREQ:

            switch(GET_WM_COMMAND_CMD(wParam, lParam))
            {
            case CBN_SELCHANGE:
                PropSheet_Changed(GetParent(hDlg), hDlg);
                if(pMonitorPage)
                   pMonitorPage->OnFrequencyChanged();
                break;

            default:
                break;
            }
            break;
            
        case IDC_PROPERTIES:
            if(pMonitorPage)
                pMonitorPage->OnProperties();
            break;

        case IDC_MONSET_PRUNNING_MODE:
            PropSheet_Changed(GetParent(hDlg), hDlg);
            if(pMonitorPage)
                pMonitorPage->OnPruningModeChanged();
            break;

        case IDC_MONITORS_LIST:

            switch(GET_WM_COMMAND_CMD(wParam, lParam))
            {
            case LBN_SELCHANGE:
                if(pMonitorPage)
                    pMonitorPage->OnSelMonitorChanged();
                break;

            default:
                return FALSE;
            }
            break;

        default:
            return FALSE;
        }

        break;

    case WM_NOTIFY:

        switch (((NMHDR FAR *)lParam)->code)
        {
        case PSN_SETACTIVE:
            return (pMonitorPage && pMonitorPage->OnSetActive());

        case PSN_APPLY: 
            if(pMonitorPage)
                pMonitorPage->OnApply();
            break;

        case PSN_RESET: 
            if(pMonitorPage)
                pMonitorPage->OnCancel();
            break;
        
        default:
            return FALSE;
        }

        break;


    case WM_HELP:

        WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
                TEXT("display.hlp"),
                HELP_WM_HELP,
                (DWORD_PTR)(LPTSTR)sc_MonitorHelpIds);

        break;


    case WM_CONTEXTMENU:

        WinHelp((HWND)wParam,
                TEXT("display.hlp"),
                HELP_CONTEXTMENU,
                (DWORD_PTR)(LPTSTR)sc_MonitorHelpIds);

        break;


    default:

        return FALSE;
    }

    return TRUE;
}



