Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
multimon.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 152k
Category:
Windows Kernel
Development Platform:
Visual C++
- /**************************************************************************
- * Module Name: multimon.cpp
- *
- * Contains all the code to manage multiple devices
- *
- * Copyright (c) Microsoft Corp. 1995-1998 All Rights Reserved
- *
- * NOTES:
- *
- **************************************************************************/
- #include "precomp.h"
- #include "shlobjp.h"
- #include "shlwapi.h"
- #include "settings.hxx"
- #include "ntreg.hxx"
- #include <tchar.h>
- #include <dbt.h>
- #include <oleacc.h>
- #if DEBUG
- #define new DBG_NEW
- #endif
- extern "C" {
- LRESULT CALLBACK MonitorWindowProc(HWND hwnd, UINT msg,WPARAM wParam,LPARAM lParam);
- LRESULT CALLBACK SliderSubWndProc (HWND hwndSlider, UINT uMsg, WPARAM wParam, LPARAM lParam, WPARAM uID, ULONG_PTR dwRefData);
- int ComputeNumberOfDisplayDevices();
- //The following are defined in lookdlg.c
- extern int g_iNewDPI;
- extern int g_iAppliedNewDPI;
- extern HWND g_hDlg;
- extern void UpdateUIfontsDueToDPIchange(int iOldDPI, int iNewDPI);
- extern void Look_InitDPIglobals();
- }
- BOOL MakeMonitorBitmap(int w, int h, LPCTSTR sz, HBITMAP *pBitmap, HBITMAP *pMaskBitmap, int cx, int cy, BOOL fSelected);
- #define SELECTION_THICKNESS 4
- #define MONITOR_BORDER 1
- #define REGSTR_VAL_SAFEBOOT TEXT("System\CurrentControlSet\Control\SafeBoot\Option")
- // Maximum number of monitors supported.
- #define MONITORS_MAX 10
- #define PREVIEWAREARATIO 2
- #define MM_REDRAWPREVIEW (WM_USER + 1)
- #define MM_MONITORMOVED (WM_USER + 2)
- #define RECTWIDTH(rc) ((rc).right-(rc).left)
- #define RECTHEIGHT(rc) ((rc).bottom-(rc).top)
- #define ToolTip_Activate(hTT, activate)
- SendMessage(hTT, TTM_ACTIVATE, (WPARAM) activate, (LPARAM) 0)
- #define ToolTip_AddTool(hTT, lpti)
- SendMessage(hTT, TTM_ADDTOOL, (WPARAM) 0, (LPARAM) (lpti))
- #define ToolTip_DelTool(hTT, lpti)
- SendMessage(hTT, TTM_DELTOOL, (WPARAM) 0, (LPARAM) (lpti))
- #define ToolTip_GetCurrentTool(hTT, lpti)
- SendMessage(hTT, TTM_GETCURRENTTOOL, (WPARAM) 0, (LPARAM) (lpti))
- #define ToolTip_RelayEvent(hTT, _msg, h, m, wp, lp)
- _msg.hwnd = h; _msg.message = m; _msg.wParam = wp; _msg.lParam = lp;
- SendMessage(hTT, TTM_RELAYEVENT, (WPARAM) 0, (LPARAM) &_msg);
- #define ToolTip_SetDelayTime(hTT, d, t)
- SendMessage(hTT, TTM_SETDELAYTIME, (WPARAM) d, (LPARAM)MAKELONG((t), 0))
- #define ToolTip_SetToolInfo(hTT, lpti)
- SendMessage(hTT, TTM_SETTOOLINFO, (WPARAM) 0, (LPARAM) (lpti))
- #define ToolTip_TrackActivate(hTT, bActivate, lpti)
- SendMessage(hTT, TTM_TRACKACTIVATE, (WPARAM) (bActivate), (LPARAM) (lpti))
- #define ToolTip_TrackPosition(hTT, x, y)
- SendMessage(hTT, TTM_TRACKPOSITION, (WPARAM) 0, (LPARAM) MAKELONG((x), (y)))
- #define ToolTip_Update(hTT)
- SendMessage(hTT, TTM_UPDATE, (WPARAM) 0, (LPARAM) 0)
- VOID
- CDECL
- TRACE(
- PCTSTR pszMsg,
- ...
- )
- /*++
- Outputs a message to the setup log. Prepends "desk.cpl " to the strings and
- appends the correct newline chars (rn)==
- --*/
- {
- TCHAR ach[1024+40]; // Largest path plus extra
- va_list vArgs;
- va_start(vArgs, pszMsg);
- wvsprintf(ach, pszMsg, vArgs);
- va_end(vArgs);
- OutputDebugString(ach);
- }
- #ifdef _WIN64
- //
- // GetDlgItem and GetDlgCtrlID don't support INT_PTR's,
- // so we have to do it manually.
- // Fortunately, GetWindowLongPtr(GWLP_ID) actually returns a full 64-bit
- // value instead of truncating at 32-bits.
- //
- #define GetDlgCtrlIDP(hwnd) GetWindowLongPtr(hwnd, GWLP_ID)
- HWND GetDlgItemP(HWND hDlg, INT_PTR id)
- {
- HWND hwndChild = GetWindow(hDlg, GW_CHILD);
- while (hwndChild && GetDlgCtrlIDP(hwndChild) != id)
- hwndChild = GetWindow(hwndChild, GW_HWNDNEXT);
- return hwndChild;
- }
- #else
- #define GetDlgItemP GetDlgItem
- #define GetDlgCtrlIDP GetDlgCtrlID
- #endif
- //
- // display devices
- //
- typedef struct _multimon_device {
- //
- // Main class for settings
- //
- CDeviceSettings * pds;
- //
- // Color and resolution information cache
- // Rebuild when modes are enumerated.
- //
- int cColors;
- PLONGLONG ColorList;
- int cResolutions;
- PPOINT ResolutionList;
- ULONG ComboBoxItem;
- DISPLAY_DEVICE DisplayDevice;
- ULONG DisplayIndex;
- POINT Snap;
- HDC hdc;
- //
- // Image information.
- //
- int w,h;
- HIMAGELIST himl;
- int iImage;
- BOOLEAN bTracking;
- HWND hwndFlash; //Flash window.
- } MULTIMON_DEVICE, *PMULTIMON_DEVICE;
- #define GetDlgCtrlDevice(hwnd) ((PMULTIMON_DEVICE)GetDlgCtrlIDP(hwnd))
- BOOL gfFlashWindowRegistered = FALSE;
- HWND ghwndToolTipTracking;
- HWND ghwndToolTipPopup;
- HWND ghwndPropSheet;
- void AddTrackingToolTip(PMULTIMON_DEVICE pDevice, HWND hwnd);
- void RemoveTrackingToolTip(HWND hwnd);
- void AddPopupToolTip(HWND hwndC);
- void RemovePopupToolTip(HWND hwndC);
- #if QUICK_REFRESH
- #define IDC_FREQUENCY_START 2000
- HMENU CreateFrequencyMenu(PMULTIMON_DEVICE pDevice);
- #endif
- extern int AskDynaCDS(HWND hDlg);
- extern int GetDisplayCPLPreference(LPCTSTR szRegVal);
- extern void SetDisplayCPLPreference(LPCTSTR szRegVal, int val);
- // Prototype for CreateStdAccessibleProxy.
- // A and W versions are available - pClassName can be ANSI or UNICODE
- // string. This is a TCHAR-style prototype, but you can do a A or W
- // specific one if desired.
- typedef HRESULT (WINAPI *PFNCREATESTDACCESSIBLEPROXY) (
- HWND hWnd,
- LPTSTR pClassName,
- LONG idObject,
- REFIID riid,
- void ** ppvObject
- );
- // Same for LresultFromObject...
- typedef LRESULT (WINAPI *PFNLRESULTFROMOBJECT)(
- REFIID riid,
- WPARAM wParam,
- LPUNKNOWN punk
- );
- PRIVATE PFNCREATESTDACCESSIBLEPROXY s_pfnCreateStdAccessibleProxy = NULL;
- PRIVATE PFNLRESULTFROMOBJECT s_pfnLresultFromObject = NULL;
- BOOL g_fAttemptedOleAccLoad ;
- HMODULE g_hOleAcc;
- //-----------------------------------------------------------------------------
- static const DWORD sc_MultiMonitorHelpIds[] =
- {
- IDC_SCREENSAMPLE, IDH_DISPLAY_SETTINGS_MONITOR_GRAPHIC,
- IDC_MULTIMONHELP, IDH_DISPLAY_SETTINGS_MONITOR_GRAPHIC,
- IDC_DISPLAYDESK, IDH_DISPLAY_SETTINGS_MONITOR_GRAPHIC,
- IDC_DISPLAYLABEL, IDH_DISPLAY_SETTINGS_DISPLAY_LIST,
- IDC_DISPLAYLIST, IDH_DISPLAY_SETTINGS_DISPLAY_LIST,
- IDC_DISPLAYTEXT, IDH_DISPLAY_SETTINGS_DISPLAY_LIST,
- IDC_COLORGROUPBOX, IDH_DISPLAY_SETTINGS_COLORBOX,
- IDC_COLORBOX, IDH_DISPLAY_SETTINGS_COLORBOX,
- IDC_COLORSAMPLE, IDH_DISPLAY_SETTINGS_COLORBOX,
- IDC_RESGROUPBOX, IDH_DISPLAY_SETTINGS_SCREENAREA,
- IDC_SCREENSIZE, IDH_DISPLAY_SETTINGS_SCREENAREA,
- IDC_RES_LESS, IDH_DISPLAY_SETTINGS_SCREENAREA,
- IDC_RES_MORE, IDH_DISPLAY_SETTINGS_SCREENAREA,
- IDC_RESXY, IDH_DISPLAY_SETTINGS_SCREENAREA,
- IDC_DISPLAYUSEME, IDH_DISPLAY_SETTINGS_EXTEND_DESKTOP_CHECKBOX,
- IDC_DISPLAYPRIME, IDH_DISPLAY_SETTINGS_USE_PRIMARY_CHECKBOX,
- IDC_IDENTIFY, IDH_DISPLAY_SETTINGS_IDENTIFY_BUTTON,
- IDC_TROUBLESHOOT, IDH_DISPLAY_SETTINGS_TROUBLE_BUTTON,
- IDC_DISPLAYPROPERTIES, IDH_DISPLAY_SETTINGS_ADVANCED_BUTTON,
- 0, 0
- };
- class CAccessibleWrapper: public IAccessible
- {
- // We need to do our own refcounting for this wrapper object
- ULONG m_ref;
- // Need ptr to the IAccessible
- IAccessible * m_pAcc;
- HWND m_hwnd;
- public:
- CAccessibleWrapper( HWND hwnd, IAccessible * pAcc );
- virtual ~CAccessibleWrapper();
- // IUnknown
- // (We do our own ref counting)
- virtual STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
- virtual STDMETHODIMP_(ULONG) AddRef();
- virtual STDMETHODIMP_(ULONG) Release();
- // IDispatch
- virtual STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
- virtual STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
- virtual STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames,
- LCID lcid, DISPID* rgdispid);
- virtual STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
- DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo,
- UINT* puArgErr);
- // IAccessible
- virtual STDMETHODIMP get_accParent(IDispatch ** ppdispParent);
- virtual STDMETHODIMP get_accChildCount(long* pChildCount);
- virtual STDMETHODIMP get_accChild(VARIANT varChild, IDispatch ** ppdispChild);
- virtual STDMETHODIMP get_accName(VARIANT varChild, BSTR* pszName);
- virtual STDMETHODIMP get_accValue(VARIANT varChild, BSTR* pszValue);
- virtual STDMETHODIMP get_accDescription(VARIANT varChild, BSTR* pszDescription);
- virtual STDMETHODIMP get_accRole(VARIANT varChild, VARIANT *pvarRole);
- virtual STDMETHODIMP get_accState(VARIANT varChild, VARIANT *pvarState);
- virtual STDMETHODIMP get_accHelp(VARIANT varChild, BSTR* pszHelp);
- virtual STDMETHODIMP get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild, long* pidTopic);
- virtual STDMETHODIMP get_accKeyboardShortcut(VARIANT varChild, BSTR* pszKeyboardShortcut);
- virtual STDMETHODIMP get_accFocus(VARIANT * pvarFocusChild);
- virtual STDMETHODIMP get_accSelection(VARIANT * pvarSelectedChildren);
- virtual STDMETHODIMP get_accDefaultAction(VARIANT varChild, BSTR* pszDefaultAction);
- virtual STDMETHODIMP accSelect(long flagsSel, VARIANT varChild);
- virtual STDMETHODIMP accLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild);
- virtual STDMETHODIMP accNavigate(long navDir, VARIANT varStart, VARIANT * pvarEndUpAt);
- virtual STDMETHODIMP accHitTest(long xLeft, long yTop, VARIANT * pvarChildAtPoint);
- virtual STDMETHODIMP accDoDefaultAction(VARIANT varChild);
- virtual STDMETHODIMP put_accName(VARIANT varChild, BSTR szName);
- virtual STDMETHODIMP put_accValue(VARIANT varChild, BSTR pszValue);
- };
- CAccessibleWrapper::CAccessibleWrapper( HWND hwnd, IAccessible * pAcc )
- : m_ref( 1 ),
- m_pAcc( pAcc ),
- m_hwnd( hwnd )
- {
- ASSERT( m_pAcc );
- m_pAcc->AddRef();
- }
- CAccessibleWrapper::~CAccessibleWrapper()
- {
- m_pAcc->Release();
- }
- // IUnknown
- // Implement refcounting ourselves
- // Also implement QI ourselves, so that we return a ptr back to the wrapper.
- STDMETHODIMP CAccessibleWrapper::QueryInterface(REFIID riid, void** ppv)
- {
- *ppv = NULL;
- if ((riid == IID_IUnknown) ||
- (riid == IID_IDispatch) ||
- (riid == IID_IAccessible))
- {
- *ppv = (IAccessible *) this;
- }
- else
- return(E_NOINTERFACE);
- AddRef();
- return(NOERROR);
- }
- STDMETHODIMP_(ULONG) CAccessibleWrapper::AddRef()
- {
- return ++m_ref;
- }
- STDMETHODIMP_(ULONG) CAccessibleWrapper::Release()
- {
- ULONG ulRet = --m_ref;
- if( ulRet == 0 )
- delete this;
- return ulRet;
- }
- // IDispatch
- // - pass all through m_pAcc
- STDMETHODIMP CAccessibleWrapper::GetTypeInfoCount(UINT* pctinfo)
- {
- return m_pAcc->GetTypeInfoCount(pctinfo);
- }
- STDMETHODIMP CAccessibleWrapper::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
- {
- return m_pAcc->GetTypeInfo(itinfo, lcid, pptinfo);
- }
- STDMETHODIMP CAccessibleWrapper::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames,
- LCID lcid, DISPID* rgdispid)
- {
- return m_pAcc->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
- }
- STDMETHODIMP CAccessibleWrapper::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
- DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo,
- UINT* puArgErr)
- {
- return m_pAcc->Invoke(dispidMember, riid, lcid, wFlags,
- pdispparams, pvarResult, pexcepinfo,
- puArgErr);
- }
- // IAccessible
- // - pass all through m_pAcc
- STDMETHODIMP CAccessibleWrapper::get_accParent(IDispatch ** ppdispParent)
- {
- return m_pAcc->get_accParent(ppdispParent);
- }
- STDMETHODIMP CAccessibleWrapper::get_accChildCount(long* pChildCount)
- {
- return m_pAcc->get_accChildCount(pChildCount);
- }
- STDMETHODIMP CAccessibleWrapper::get_accChild(VARIANT varChild, IDispatch ** ppdispChild)
- {
- return m_pAcc->get_accChild(varChild, ppdispChild);
- }
- STDMETHODIMP CAccessibleWrapper::get_accName(VARIANT varChild, BSTR* pszName)
- {
- return m_pAcc->get_accName(varChild, pszName);
- }
- STDMETHODIMP CAccessibleWrapper::get_accValue(VARIANT varChild, BSTR* pszValue)
- {
- // varChild.lVal specifies which sub-part of the component
- // is being queried.
- // CHILDID_SELF (0) specifies the overall component - other
- // non-0 values specify a child.
- // In a trackbar, CHILDID_SELF refers to the overall trackbar
- // (which is what we want), whereas other values refer to the
- // sub-components - the actual slider 'thumb', and the 'page
- // up/page down' areas to the left/right of it.
- if( varChild.vt == VT_I4 && varChild.lVal == CHILDID_SELF )
- {
- HWND hDlg;
- TCHAR achRes[120];
- #ifndef UNICODE
- WCHAR wszRes[120];
- #endif
- hDlg = GetParent( m_hwnd );
- SendDlgItemMessage(hDlg, IDC_RESXY, WM_GETTEXT, 120, (LPARAM)achRes);
- #ifdef UNICODE
- *pszValue = SysAllocString( achRes );
- #else
- MultiByteToWideChar( CP_ACP, 0, achRes, -1, wszRes, 120 );
- *pszValue = SysAllocString( wszRes );
- #endif
- return S_OK;
- }
- else
- {
- // Pass requests about the sub-components to the
- // 'original' IAccessible for us).
- return m_pAcc->get_accValue(varChild, pszValue);
- }
- }
- STDMETHODIMP CAccessibleWrapper::get_accDescription(VARIANT varChild, BSTR* pszDescription)
- {
- return m_pAcc->get_accDescription(varChild, pszDescription);
- }
- STDMETHODIMP CAccessibleWrapper::get_accRole(VARIANT varChild, VARIANT *pvarRole)
- {
- return m_pAcc->get_accRole(varChild, pvarRole);
- }
- STDMETHODIMP CAccessibleWrapper::get_accState(VARIANT varChild, VARIANT *pvarState)
- {
- return m_pAcc->get_accState(varChild, pvarState);
- }
- STDMETHODIMP CAccessibleWrapper::get_accHelp(VARIANT varChild, BSTR* pszHelp)
- {
- return m_pAcc->get_accHelp(varChild, pszHelp);
- }
- STDMETHODIMP CAccessibleWrapper::get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild, long* pidTopic)
- {
- return m_pAcc->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
- }
- STDMETHODIMP CAccessibleWrapper::get_accKeyboardShortcut(VARIANT varChild, BSTR* pszKeyboardShortcut)
- {
- return m_pAcc->get_accKeyboardShortcut(varChild, pszKeyboardShortcut);
- }
- STDMETHODIMP CAccessibleWrapper::get_accFocus(VARIANT * pvarFocusChild)
- {
- return m_pAcc->get_accFocus(pvarFocusChild);
- }
- STDMETHODIMP CAccessibleWrapper::get_accSelection(VARIANT * pvarSelectedChildren)
- {
- return m_pAcc->get_accSelection(pvarSelectedChildren);
- }
- STDMETHODIMP CAccessibleWrapper::get_accDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
- {
- return m_pAcc->get_accDefaultAction(varChild, pszDefaultAction);
- }
- STDMETHODIMP CAccessibleWrapper::accSelect(long flagsSel, VARIANT varChild)
- {
- return m_pAcc->accSelect(flagsSel, varChild);
- }
- STDMETHODIMP CAccessibleWrapper::accLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
- {
- return m_pAcc->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varChild);
- }
- STDMETHODIMP CAccessibleWrapper::accNavigate(long navDir, VARIANT varStart, VARIANT * pvarEndUpAt)
- {
- return m_pAcc->accNavigate(navDir, varStart, pvarEndUpAt);
- }
- STDMETHODIMP CAccessibleWrapper::accHitTest(long xLeft, long yTop, VARIANT * pvarChildAtPoint)
- {
- return m_pAcc->accHitTest(xLeft, yTop, pvarChildAtPoint);
- }
- STDMETHODIMP CAccessibleWrapper::accDoDefaultAction(VARIANT varChild)
- {
- return m_pAcc->accDoDefaultAction(varChild);
- }
- STDMETHODIMP CAccessibleWrapper::put_accName(VARIANT varChild, BSTR szName)
- {
- return m_pAcc->put_accName(varChild, szName);
- }
- STDMETHODIMP CAccessibleWrapper::put_accValue(VARIANT varChild, BSTR pszValue)
- {
- return m_pAcc->put_accValue(varChild, pszValue);
- }
- class CMultiMon : public IMultiMonConfig
- {
- friend int ComputeNumberOfDisplayDevices();
- friend int DisplaySaveSettings(PVOID pContext, HWND hwnd);
- private:
- // Data Section
- PMULTIMON_DEVICE _pCurDevice;
- PMULTIMON_DEVICE _pPrimaryDevice;
- // HWND for the main window
- HWND _hDlg;
- HWND _hwndDesk;
- HWND _hwndList;
- // union of all monitor RECTs
- RECT _rcDesk;
- // ref count
- UINT _cRef;
- // how to translate to preview size
- int _DeskScale;
- POINT _DeskOff;
- UINT _InSetInfo;
- ULONG _NumDevices;
- HBITMAP _hbmScrSample;
- HBITMAP _hbmMonitor;
- HIMAGELIST _himl;
- // UI variables
- int _iColor;
- int _iResolution;
- BOOL _bBadDriver : 1;
- BOOL _bNoAttach : 1;
- BOOL _bDirty : 1;
- MULTIMON_DEVICE _Devices[MONITORS_MAX];
- // Private functions
- void _DeskToPreview(LPRECT in, LPRECT out);
- void _OffsetPreviewToDesk(LPRECT in, LPRECT out);
- BOOL _QueryForceSmallFont();
- void _SetPreviewScreenSize(int HRes, int VRes, int iOrgXRes, int iOrgYRes);
- void _CleanupRects(HWND hwndP);
- void _ConfirmPositions();
- void _DoAdvancedSettingsSheet();
- int _HandleApply();
- BOOL _HandleHScroll(HWND hwndSB, int iCode, int iPos);
- void _RedrawDeskPreviews();
- void _OnAdvancedClicked();
- BOOL _InitDisplaySettings(BOOL bExport);
- int _EnumerateAllDisplayDevices(); //Enumerates and returns the number of devices.
- void _DestroyMultimonDevice(PMULTIMON_DEVICE pDevice);
- void _DestroyDisplaySettings();
- void _InitUI();
- void _UpdateUI(int FocusToCtrlID = 0);
- LPTSTR _FormatMessageInvoke(LPCTSTR pcszFormat, va_list *argList);
- LPTSTR _FormatMessageWrap(LPCTSTR pcszFormat, ...);
- void _GetDisplayName(PMULTIMON_DEVICE pDevice, LPTSTR pszDisplay, DWORD cchSize);
- int _SaveDisplaySettings(DWORD dwSet);
- BOOL _RebuildDisplaySettings(BOOL bComplete);
- void _ForwardToChildren(UINT message, WPARAM wParam, LPARAM lParam);
- static BOOL _AnyChange(CDeviceSettings *rgpds[], ULONG numDevices);
- static BOOL _AnyColorChange(CDeviceSettings *rgpds[], ULONG numDevices);
- static BOOL _IsSingleToMultimonChange(CDeviceSettings *rgpds[],
- ULONG numDevices);
- static int _DisplaySaveSettings(CDeviceSettings* rgpds[],
- ULONG numDevices,
- HWND hDlg);
- static int _SaveSettings(CDeviceSettings *rgpds[],
- ULONG numDevices,
- HWND hDlg,
- DWORD dwSet);
- // NT specific stuff
- #ifdef WINNT
- BOOL _InitMessage();
- void _vPreExecMode();
- void _vPostExecMode();
- #endif
- public:
- CMultiMon();
- static BOOL RegisterPreviewWindowClass(WNDPROC pfnWndProc);
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
- // *** IMultiMonConfig methods ***
- STDMETHOD ( Initialize ) ( HWND hwndHost, WNDPROC pfnWndProc, DWORD dwReserved);
- STDMETHOD ( GetNumberOfMonitors ) (int * pCMon, DWORD dwReserved);
- STDMETHOD ( GetMonitorData) (int iMonitor, MonitorData * pmd, DWORD dwReserved);
- STDMETHOD ( Paint) (THIS_ int iMonitor, DWORD dwReserved);
- void InitMultiMonitorDlg(HWND hDlg);
- PMULTIMON_DEVICE GetCurDevice(){return _pCurDevice;};
- int GetNumberOfAttachedDisplays();
- void UpdateActiveDisplay(PMULTIMON_DEVICE pDevice, BOOL bRepaint = TRUE);
- BOOL HandleMonitorChange(HWND hwndP, BOOL bMainDlg, BOOL bRepaint = TRUE);
- void SetDirty(BOOL bDirty=TRUE);
- BOOL SetPrimary(PMULTIMON_DEVICE pDevice);
- BOOL SetMonAttached(PMULTIMON_DEVICE pDevice, BOOL bSetAttached,
- BOOL bForce, HWND hwnd);
- HWND GetCurDeviceHwnd() { return GetDlgItemP(_hwndDesk, (INT_PTR) _pCurDevice);};
- ULONG GetNumDevices() { return _NumDevices;};
- BOOL QueryNoAttach() { return _bNoAttach;};
- BOOL IsDirty() { return _bDirty;};
- void GetMonitorPosition(PMULTIMON_DEVICE pDevice, HWND hwndP, PPOINT ptPos);
- LRESULT CALLBACK WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- #if 0
- TraceMsg(TF_DUMP_CSETTINGS,"t cb = %d", _DisplayDevice.cb );
- TraceMsg(TF_DUMP_CSETTINGS,"t DeviceName = %s", _pstrDisplayDevice );
- TraceMsg(TF_DUMP_CSETTINGS,"t DeviceString= %s", _DisplayDevice.DeviceString );
- TraceMsg(TF_DUMP_CSETTINGS,"t StateFlags = %08lx", _DisplayDevice.StateFlags );
- #endif
- CMultiMon::CMultiMon() : _cRef(1) {
- ASSERT(_pCurDevice == NULL);
- ASSERT(_pPrimaryDevice == NULL);
- ASSERT(_DeskScale == 0);
- ASSERT(_InSetInfo == 0);
- ASSERT(_NumDevices == 0);
- ASSERT(IsRectEmpty(&_rcDesk));
- ASSERT(_bNoAttach == FALSE);
- ASSERT(_bDirty == FALSE);
- };
- void CMultiMon::_DestroyMultimonDevice(PMULTIMON_DEVICE pDevice)
- {
- ASSERT(pDevice->pds);
- delete pDevice->pds;
- pDevice->pds = NULL;
- if(pDevice->hwndFlash)
- {
- DestroyWindow(pDevice->hwndFlash);
- pDevice->hwndFlash = NULL;
- }
- if (pDevice->hdc) {
- DeleteDC(pDevice->hdc);
- pDevice->hdc = NULL;
- }
- if (pDevice->ResolutionList) {
- LocalFree(pDevice->ResolutionList);
- pDevice->ResolutionList = NULL;
- }
- if (pDevice->ColorList) {
- LocalFree(pDevice->ColorList);
- pDevice->ColorList = NULL;
- }
- }
- void CMultiMon::_DestroyDisplaySettings()
- {
- ULONG iDevice;
- HWND hwndC;
- ASSERT(_NumDevices);
- TraceMsg(TF_GENERAL, "DestroyDisplaySettings: %d devices", _NumDevices);
- // We are about to destroy the _Devices below. Pointerts to these devices are used as the
- // CtrlIDs for the monitor windows. So, we need destroy the monitor windows first;
- // otherwise, if the monitor windows are destroyed later, they try to use these invalid
- // pDevice in FlashText. (pDevice->hwndFlash will fault).
- while (hwndC = GetWindow(_hwndDesk, GW_CHILD))
- {
- RemoveTrackingToolTip(hwndC);
- RemovePopupToolTip(hwndC);
- DestroyWindow(hwndC);
- }
- // Now, we can destroy the _Devices safely.
- for (iDevice = 0; iDevice < _NumDevices; iDevice++) {
- _DestroyMultimonDevice(_Devices + iDevice);
- // Note: pds is destroyed and set to zero already in the above call.
- //delete _Devices[iDevice].pds;
- //_Devices[iDevice].pds = 0;
- }
- if (_himl) {
- ImageList_Destroy(_himl);
- _himl = NULL;
- }
- DestroyWindow(ghwndToolTipTracking);
- DestroyWindow(ghwndToolTipPopup);
- ghwndToolTipTracking = NULL;
- ghwndToolTipPopup = NULL;
- TraceMsg(TF_GENERAL, "DestroyDisplaySettings: Finished destroying all devices");
- }
- #ifdef WINNT
- //
- // deterines if the applet is in detect mode.
- //
- //
- // Called to put up initial messages that need to appear above the dialog
- // box
- //
- BOOL CMultiMon::_InitMessage()
- {
- {
- //
- // _bBadDriver will be set when we fail to build the list of modes,
- // or something else failed during initialization.
- //
- // In almost every case, we should already know about this situation
- // based on our boot code.
- // However, if this is a new situation, just report a "bad driver"
- //
- if (_bBadDriver)
- {
- ASSERT(gbExecMode == EXEC_INVALID_MODE);
- gbExecMode = EXEC_INVALID_MODE;
- gbInvalidMode = EXEC_INVALID_DISPLAY_DRIVER;
- }
- if (gbExecMode == EXEC_INVALID_MODE)
- {
- DWORD Mesg;
- switch(gbInvalidMode) {
- case EXEC_INVALID_NEW_DRIVER:
- Mesg = MSG_INVALID_NEW_DRIVER;
- break;
- case EXEC_INVALID_DEFAULT_DISPLAY_MODE:
- Mesg = MSG_INVALID_DEFAULT_DISPLAY_MODE;
- break;
- case EXEC_INVALID_DISPLAY_DRIVER:
- Mesg = MSG_INVALID_DISPLAY_DRIVER;
- break;
- case EXEC_INVALID_OLD_DISPLAY_DRIVER:
- Mesg = MSG_INVALID_OLD_DISPLAY_DRIVER;
- break;
- case EXEC_INVALID_16COLOR_DISPLAY_MODE:
- Mesg = MSG_INVALID_16COLOR_DISPLAY_MODE;
- break;
- case EXEC_INVALID_DISPLAY_MODE:
- Mesg = MSG_INVALID_DISPLAY_MODE;
- {
- //
- // If we are in safe mode, then we will get to here when
- // we initially log in. We are in forced VGA mode, so there
- // is no real error here. Emulate a click on the OK button
- // and everybody is happy.
- //
- HKEY hSafe;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- REGSTR_VAL_SAFEBOOT,
- 0,
- KEY_READ,
- &hSafe) == ERROR_SUCCESS) {
- //
- // If we ever care about the actual safe mode, the value
- // is nameed "OptionValue"
- //
- RegCloseKey(hSafe);
- PropSheet_PressButton(GetParent(_hDlg), PSBTN_OK);
- return TRUE;
- }
- }
- break;
- case EXEC_INVALID_CONFIGURATION:
- default:
- Mesg = MSG_INVALID_CONFIGURATION;
- break;
- }
- FmtMessageBox(_hDlg,
- MB_ICONEXCLAMATION,
- MSG_CONFIGURATION_PROBLEM,
- Mesg);
- //
- // For a bad display driver or old display driver, let's send the
- // user straight to the installation dialog.
- //
- if ((gbInvalidMode == EXEC_INVALID_OLD_DISPLAY_DRIVER) ||
- (gbInvalidMode == EXEC_INVALID_DISPLAY_DRIVER))
- {
- ASSERT(FALSE);
- }
- }
- }
- return TRUE;
- }
- VOID CMultiMon::_vPreExecMode()
- {
- HKEY hkey;
- // DWORD data;
- //
- // This function sets up the execution mode of the applet.
- // There are four vlid modes.
- //
- // EXEC_NORMAL - When the apple is launched from the control panel
- //
- // EXEC_INVALID_MODE is exactly the same as for NORMAL except we will
- // not mark the current mode as tested so the user has
- // to at least test a mode
- //
- // EXEC_DETECT - When the applet is launched normally, but a detect was
- // done on the previous boot (the key in the registry is
- // set)
- //
- // EXEC_SETUP - When we launch the applet in setup mode from setup (Both
- // the registry key is set and the setup flag is passed in).
- //
- //
- // These two keys should only be checked deleted if the machine has been
- // rebooted and the detect new display has actually happened.
- // So we will look for the RebootNecessary key (a volatile key) and if
- // it is not present, then we can delete the key. Otherwise, the reboot
- // has not happened, and we keep the key
- //
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- SZ_REBOOT_NECESSARY,
- 0,
- KEY_READ | KEY_WRITE,
- &hkey) != ERROR_SUCCESS) {
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- SZ_DETECT_DISPLAY,
- 0,
- KEY_READ | KEY_WRITE,
- &hkey) == ERROR_SUCCESS) {
- //
- // NOTE: This key is also set when EXEC_SETUP is being run.
- //
- if (gbExecMode == EXEC_NORMAL) {
- gbExecMode = EXEC_DETECT;
- } else {
- //
- // If we are in setup mode, we also check the extra values
- // under DetectDisplay that control the unattended installation.
- //
- ASSERT(gbExecMode == EXEC_SETUP);
- }
- RegCloseKey(hkey);
- }
- //
- // Check for a new driver being installed
- //
- if ( (gbExecMode == EXEC_NORMAL) &&
- (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- SZ_NEW_DISPLAY,
- 0,
- KEY_READ | KEY_WRITE,
- &hkey) == ERROR_SUCCESS) ) {
- gbExecMode = EXEC_INVALID_MODE;
- gbInvalidMode = EXEC_INVALID_NEW_DRIVER;
- RegCloseKey(hkey);
- }
- RegDeleteKey(HKEY_LOCAL_MACHINE,
- SZ_DETECT_DISPLAY);
- RegDeleteKey(HKEY_LOCAL_MACHINE,
- SZ_NEW_DISPLAY);
- }
- {
- LPTSTR psz;
- LPTSTR pszInv;
- switch(gbExecMode) {
- case EXEC_NORMAL:
- psz = TEXT("Normal Execution mode");
- break;
- case EXEC_DETECT:
- psz = TEXT("Detection Execution mode");
- break;
- case EXEC_SETUP:
- psz = TEXT("Setup Execution mode");
- break;
- case EXEC_INVALID_MODE:
- psz = TEXT("Invalid Mode Execution mode");
- switch(gbInvalidMode) {
- case EXEC_INVALID_NEW_DRIVER:
- pszInv = TEXT("Invalid new driver");
- break;
- default:
- pszInv = TEXT("*** Invalid *** Invalid mode");
- break;
- }
- break;
- default:
- psz = TEXT("*** Invalid *** Execution mode");
- break;
- }
- KdPrint(("n nDisplay.cpl: The display applet is in : %wsn", psz));
- if (gbExecMode == EXEC_INVALID_MODE)
- {
- KdPrint(("tt sub invalid mode : %ws", pszInv));
- }
- KdPrint(("nn", psz));
- }
- }
- VOID CMultiMon::_vPostExecMode() {
- HKEY hkey;
- DWORD cb;
- DWORD data;
- //
- // Check for various invalid configurations
- //
- if ( (gbExecMode == EXEC_NORMAL) &&
- (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- SZ_INVALID_DISPLAY,
- 0,
- KEY_READ | KEY_WRITE,
- &hkey) == ERROR_SUCCESS) ) {
- gbExecMode = EXEC_INVALID_MODE;
- //
- // Check for these fields in increasing order of "badness" or
- // "detail" so that the *worst* error is the one remaining in the
- // gbInvalidMode variable once all the checks are done.
- //
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("DefaultMode"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_DEFAULT_DISPLAY_MODE;
- }
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("BadMode"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_DISPLAY_MODE;
- }
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("16ColorMode"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_16COLOR_DISPLAY_MODE;
- }
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("InvalidConfiguration"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_CONFIGURATION;
- }
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("MissingDisplayDriver"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_DISPLAY_DRIVER;
- }
- //
- // This last case will be set in addition to the previous one in the
- // case where the driver was an old driver linking to winsvr.dll
- // and we can not load it.
- //
- cb = 4;
- if (RegQueryValueEx(hkey,
- TEXT("OldDisplayDriver"),
- NULL,
- NULL,
- (LPBYTE)(&data),
- &cb) == ERROR_SUCCESS)
- {
- gbInvalidMode = EXEC_INVALID_OLD_DISPLAY_DRIVER;
- }
- RegCloseKey(hkey);
- }
- //
- // Delete all of these bad configuration keys since we only want the
- // user to see the message once.
- //
- RegDeleteKey(HKEY_LOCAL_MACHINE,
- SZ_INVALID_DISPLAY);
- {
- LPTSTR psz;
- LPTSTR pszInv;
- if (gbExecMode == EXEC_INVALID_MODE)
- {
- switch (gbInvalidMode)
- {
- case EXEC_INVALID_DEFAULT_DISPLAY_MODE:
- pszInv = TEXT("Default mode being used");
- break;
- case EXEC_INVALID_DISPLAY_DRIVER:
- pszInv = TEXT("Invalid Display Driver");
- break;
- case EXEC_INVALID_OLD_DISPLAY_DRIVER:
- pszInv = TEXT("Old Display Driver");
- break;
- case EXEC_INVALID_16COLOR_DISPLAY_MODE:
- pszInv = TEXT("16 color mode not supported");
- break;
- case EXEC_INVALID_DISPLAY_MODE:
- pszInv = TEXT("Invalid display mode");
- break;
- case EXEC_INVALID_CONFIGURATION:
- pszInv = TEXT("Invalid configuration");
- break;
- default:
- psz = TEXT("*** Invalid *** Invalid mode");
- break;
- }
- KdPrint(("tt sub invlid mode : %ws", pszInv));
- KdPrint(("nn", psz));
- }
- }
- }
- #endif
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- void CMultiMon::_DeskToPreview(LPRECT in, LPRECT out)
- {
- out->left = _DeskOff.x + MulDiv(in->left - _rcDesk.left,_DeskScale,1000);
- out->top = _DeskOff.y + MulDiv(in->top - _rcDesk.top, _DeskScale,1000);
- out->right = _DeskOff.x + MulDiv(in->right - _rcDesk.left,_DeskScale,1000);
- out->bottom = _DeskOff.y + MulDiv(in->bottom - _rcDesk.top, _DeskScale,1000);
- }
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- void CMultiMon::_OffsetPreviewToDesk(LPRECT in, LPRECT out)
- {
- int x, y;
- // Scale preview rects back to desk size
- x = _rcDesk.left + MulDiv(in->left - _DeskOff.x,1000,_DeskScale);
- y = _rcDesk.top + MulDiv(in->top - _DeskOff.y,1000,_DeskScale);
- // Figure out how much to offset
- x = x - out->left;
- y = y - out->top;
- OffsetRect(out, x, y);
- }
- //-----------------------------------------------------------------------------
- int CMultiMon::_SaveSettings(CDeviceSettings *rgpds[], ULONG numDevices, HWND hDlg, DWORD dwSet)
- {
- int iRet = 0;
- ULONG iDevice;
- for (iDevice = 0; iDevice < numDevices; iDevice++)
- {
- // BUGBUG - we should only save the settings for devices that have
- // changed.
- int iResult = rgpds[iDevice]->SaveSettings(dwSet);
- if (iResult != DISP_CHANGE_SUCCESSFUL)
- {
- if (iResult == DISP_CHANGE_RESTART)
- {
- iRet = iResult;
- continue;
- }
- else
- {
- FmtMessageBox(hDlg,
- MB_ICONEXCLAMATION,
- IDS_CHANGE_SETTINGS,
- IDS_CHANGESETTINGS_FAILED);
- ASSERT(iResult < 0);
- return iResult;
- }
- }
- }
- return iRet;
- }
- INT_PTR CALLBACK KeepNewDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
- {
- UINT_PTR idTimer = 0;
- HICON hicon;
- TCHAR szRevert[100];
- TCHAR szString[120];
- switch(message)
- {
- case WM_INITDIALOG:
- hicon = LoadIcon(NULL, IDI_QUESTION);
- if (hicon)
- SendDlgItemMessage(hDlg, IDC_BIGICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon);
- LoadString(hInstance, IDS_REVERTBACK, szRevert, SIZEOF(szRevert));
- wsprintf(szString, szRevert, 15);
- SetDlgItemText(hDlg, IDC_COUNTDOWN, szString);
- idTimer = SetTimer(hDlg, 15, 1000, NULL);
- SetFocus(GetDlgItem(hDlg, IDNO));
- // FALSE so that the focus set above is kept
- return FALSE;
- case WM_DESTROY:
- // raymondc - this code is dead; idTimer is initialized to zero
- // fortunately, timers are automatically killed at window destruction
- // if (idTimer)
- // KillTimer(hDlg, idTimer);
- hicon = (HICON)SendDlgItemMessage(hDlg, IDC_BIGICON, STM_GETIMAGE, IMAGE_ICON, 0);
- if (hicon)
- DestroyIcon(hicon);
- break;
- case WM_TIMER:
- KillTimer(hDlg, wParam);
- LoadString(hInstance, IDS_REVERTBACK, szRevert, SIZEOF(szRevert));
- wsprintf(szString, szRevert, wParam - 1);
- SetDlgItemText(hDlg, IDC_COUNTDOWN, szString);
- idTimer = SetTimer(hDlg, wParam - 1, 1000, NULL);
- if (wParam == 1)
- EndDialog(hDlg, IDNO);
- break;
- case WM_COMMAND:
- EndDialog(hDlg, wParam);
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- BOOL CMultiMon::_RebuildDisplaySettings(BOOL bComplete)
- {
- BOOL result = TRUE;
- HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- delete _Devices[iDevice].pds;
- _Devices[iDevice].pds = new CDeviceSettings();
- }
- RedrawWindow(_hDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
- SetCursor(hcur);
- return result;
- }
- int CMultiMon::GetNumberOfAttachedDisplays()
- {
- int nDisplays = 0;
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- if (_Devices[iDevice].pds->IsAttached())
- nDisplays++;
- }
- return nDisplays;
- }
- BOOL CMultiMon::_AnyColorChange(CDeviceSettings *rgpds[], ULONG numDevices)
- {
- for (ULONG iDevice = 0; iDevice < numDevices; iDevice++)
- {
- if (rgpds[iDevice]->IsAttached() && rgpds[iDevice]->IsColorChanged())
- return TRUE;
- }
- return FALSE;
- }
- /* static */ BOOL CMultiMon::_IsSingleToMultimonChange(CDeviceSettings *rgpds[],
- ULONG numDevices)
- {
- int nAttached = 0;
- int nOrgAttached = 0;
- for (ULONG iDevice = 0;
- (iDevice < numDevices) && (nOrgAttached <= 1);
- iDevice++)
- {
- if (rgpds[iDevice]->IsOrgAttached())
- nOrgAttached++;
- if (rgpds[iDevice]->IsAttached())
- nAttached++;
- }
- return ((nOrgAttached <= 1) && (nAttached > 1));
- }
- BOOL CMultiMon::_AnyChange(CDeviceSettings *rgpds[], ULONG numDevices)
- {
- for (ULONG iDevice = 0; iDevice < numDevices; iDevice++)
- {
- if (rgpds[iDevice]->IsAttached() && rgpds[iDevice]->bIsModeChanged())
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL CMultiMon::_QueryForceSmallFont()
- {
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- if ((_Devices[iDevice].pds->IsAttached()) &&
- (!_Devices[iDevice].pds->IsSmallFontNecessary()))
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- LPTSTR CMultiMon::_FormatMessageInvoke(LPCTSTR pcszFormat, va_list *argList)
- {
- LPTSTR pszOutput;
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
- pcszFormat,
- 0, 0,
- reinterpret_cast<LPTSTR>(&pszOutput), 0,
- argList) == 0)
- {
- pszOutput = NULL;
- }
- return(pszOutput);
- }
- LPTSTR CMultiMon::_FormatMessageWrap(LPCTSTR pcszFormat, ...)
- {
- LPTSTR pszOutput;
- va_list argList;
- va_start(argList, pcszFormat);
- pszOutput = _FormatMessageInvoke(pcszFormat, &argList);
- va_end(argList);
- return(pszOutput);
- }
- void CMultiMon::_GetDisplayName(PMULTIMON_DEVICE pDevice, LPTSTR pszDisplay, DWORD cchSize)
- {
- LPTSTR pszFormattedOutput;
- TCHAR szMonitor[140];
- TCHAR szDisplayFormat[40];
- LoadString(hInstance, IDS_DISPLAYFORMAT, szDisplayFormat, SIZEOF(szDisplayFormat));
- pDevice->pds->GetMonitorName(szMonitor);
- pszFormattedOutput = _FormatMessageWrap(szDisplayFormat,
- pDevice->DisplayIndex,
- szMonitor,
- pDevice->DisplayDevice.DeviceString);
- lstrcpyn(pszDisplay, pszFormattedOutput, cchSize);
- DirectLocalFree(pszFormattedOutput);
- }
- void CMultiMon::_OnAdvancedClicked()
- {
- BOOL bCanBePruned, bIsPruningReadOnly;
- BOOL bBeforeIsPruningOn, bAfterIsPruningOn;
- _pCurDevice->pds->GetPruningMode(&bCanBePruned,
- &bIsPruningReadOnly,
- &bBeforeIsPruningOn);
- _DoAdvancedSettingsSheet();
- if (bCanBePruned && !bIsPruningReadOnly)
- {
- _pCurDevice->pds->GetPruningMode(&bCanBePruned,
- &bIsPruningReadOnly,
- &bAfterIsPruningOn);
- if (bBeforeIsPruningOn != bAfterIsPruningOn)
- {
- //
- // pruning mode has changed - update the UI
- //
- _InitUI();
- _UpdateUI();
- }
- }
- }
- //-----------------------------------------------------------------------------
- void CMultiMon::_DoAdvancedSettingsSheet()
- {
- #ifndef WINNT
- HINSTANCE hDesk16 = LoadLibrary16( "DeskCp16.Dll" );
- FARPROC16 pDesk16 = (FARPROC16)( hDesk16?
- GetProcAddress16( hDesk16, "CplApplet" ) : NULL );
- #endif
- PROPSHEETHEADER psh;
- HPROPSHEETPAGE rPages[MAX_PAGES];
- PROPSHEETPAGE psp;
- HPSXA hpsxa = NULL;
- HPSXA hpsxaOEM = NULL;
- INT_PTR iResult = 0;
- TCHAR szDisplay[140 + 256 + 20]; //Monitor-name and Adapter Properties.
- TCHAR szMonitor[140];
- TCHAR szDisplayFormat[35];
- // Create the "Monitor-name and Adapter-name properties" string to be used as the title for these
- // property sheets.
- LoadString(hInstance, IDS_ADVDIALOGTITLE, szDisplayFormat, SIZEOF(szDisplayFormat));
- _pCurDevice->pds->GetMonitorName(szMonitor);
- wsprintf(szDisplay,
- szDisplayFormat,
- szMonitor,
- _pCurDevice->DisplayDevice.DeviceString);
- psh.dwSize = sizeof(psh);
- psh.dwFlags = PSH_PROPTITLE;
- psh.hwndParent = GetParent(_hDlg);
- psh.hInstance = hInstance;
- psh.pszCaption = szDisplay;
- psh.nPages = 0;
- psh.nStartPage = 0;
- psh.phpage = rPages;
- psp.dwSize = sizeof(psp);
- psp.dwFlags = PSP_DEFAULT;
- psp.hInstance = hInstance;
- psp.pfnDlgProc = GeneralPageProc;
- psp.pszTemplate = MAKEINTRESOURCE(DLG_GENERAL);
- psp.lParam = (LPARAM)_QueryForceSmallFont();
- if (rPages[psh.nPages] = CreatePropertySheetPage(&psp))
- psh.nPages++;
- #ifndef WINNT
- ATOM AtomDevice = GlobalAddAtom((char *)&_pCurDevice->DisplayDevice.DeviceName);
- if( pDesk16 && CallCPLEntry16( hDesk16, pDesk16, NULL, CPL_INIT, (LPARAM)AtomDevice, 0 ) )
- {
- // or just add the default page
- SHAddPages16( NULL, "DESKCP16.DLL,GetAdapterPage",
- _AddDisplayPropSheetPage, (LPARAM)&psh );
- //
- // only add the monitor tab iff a monitor exists
- //
- if (_pCurDevice->DisplayDevice.DeviceName[0])
- {
- TCHAR szMonitor[140];
- if (_pCurDevice->pds->GetMonitorName(szMonitor))
- {
- SHAddPages16( NULL, "DESKCP16.DLL,GetMonitorPage",
- _AddDisplayPropSheetPage, (LPARAM)&psh );
- }
- }
- SHAddPages16( NULL, "DESKCP16.DLL,GetPerformancePage",
- _AddDisplayPropSheetPage, (LPARAM)&psh );
- }
- #endif
- IDataObject * pdo = NULL;
- _pCurDevice->pds->QueryInterface(IID_IDataObject, (LPVOID *) &pdo);
- //
- // load any extensions from the registry
- //
- //
- // load the generic (non hardware specific) extensions
- //
- if( ( hpsxa = SHCreatePropSheetExtArrayEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\Device"), 8, pdo) ) != NULL )
- {
- SHAddFromPropSheetExtArray( hpsxa, _AddDisplayPropSheetPage, (LPARAM)&psh );
- }
- //
- // load the hardware-specific extensions
- //
- // NOTE it is very important to load the OEM extensions *after* the
- // generic extensions some HW extensions expect to be the last tabs
- // in the propsheet (right before the settings tab)
- //
- // BUGBUG - we may need a way to NOT load the vendor extensions in case
- // they break our applet.
- //
- #ifdef WINNT
- if( ( hpsxaOEM = SHCreatePropSheetExtArrayEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\Display"), 8, pdo) ) != NULL )
- {
- SHAddFromPropSheetExtArray( hpsxaOEM, _AddDisplayPropSheetPage, (LPARAM)&psh );
- }
- #else
- if( ( hpsxaOEM = SHCreatePropSheetExtArrayEx( HKEY_LOCAL_MACHINE, _pCurDevice->DisplayDevice.DeviceKey, 8, pdo) ) != NULL )
- {
- SHAddFromPropSheetExtArray( hpsxaOEM, _AddDisplayPropSheetPage, (LPARAM)&psh );
- }
- #endif
- //
- // add a fake settings page to fool OEM extensions (must be last)
- //
- if (hpsxa || hpsxaOEM)
- {
- AddFakeSettingsPage(&psh);
- }
- if (psh.nPages)
- {
- iResult = PropertySheet(&psh);
- }
- _GetDisplayName(_pCurDevice, szDisplay, ARRAYSIZE(szDisplay));
- if (_NumDevices == 1)
- {
- //Set the name of the primary in the static text
- //strip the first token off (this is the number we dont want it)
- TCHAR *pch;
- for (pch=szDisplay; *pch && *pch != TEXT(' '); pch++);
- for (;*pch && *pch == TEXT(' '); pch++);
- SetDlgItemText(_hDlg, IDC_DISPLAYTEXT, pch);
- }
- else
- {
- ComboBox_DeleteString(_hwndList, _pCurDevice->ComboBoxItem);
- ComboBox_InsertString(_hwndList, _pCurDevice->ComboBoxItem, szDisplay);
- ComboBox_SetItemData(_hwndList, _pCurDevice->ComboBoxItem, (DWORD_PTR)_pCurDevice);
- ComboBox_SetCurSel(_hwndList, _pCurDevice->ComboBoxItem);
- }
- if( hpsxa )
- SHDestroyPropSheetExtArray( hpsxa );
- if( hpsxaOEM )
- SHDestroyPropSheetExtArray( hpsxaOEM );
- if (pdo)
- pdo->Release();
- #ifndef WINNT
- if (pDesk16)
- CallCPLEntry16( hDesk16, pDesk16, NULL, CPL_EXIT, 0, 0 );
- if (AtomDevice)
- GlobalDeleteAtom(AtomDevice);
- if( hDesk16 )
- FreeLibrary16( hDesk16 );
- #endif
- if ((iResult == ID_PSRESTARTWINDOWS) || (iResult == ID_PSREBOOTSYSTEM))
- {
- PropSheet_CancelToClose(GetParent(_hDlg));
- if (iResult == ID_PSREBOOTSYSTEM)
- PropSheet_RebootSystem(ghwndPropSheet);
- else
- PropSheet_RestartWindows(ghwndPropSheet);
- }
- //
- // BUGBUG
- // Reset the dirty flag based on what the extensions did.
- //
- //
- // Reset the controls in case someone changed the selected mode.
- //
- UpdateActiveDisplay(NULL);
- }
- //-----------------------------------------------------------------------------
- void CMultiMon::UpdateActiveDisplay(PMULTIMON_DEVICE pDevice, BOOL bRepaint /*=TRUE*/)
- {
- HWND hwndC;
- _InSetInfo++;
- if (pDevice == NULL)
- pDevice = (PMULTIMON_DEVICE)ComboBox_GetItemData(_hwndList, ComboBox_GetCurSel(_hwndList));
- else
- ComboBox_SetCurSel(_hwndList, pDevice->ComboBoxItem);
- if (pDevice && pDevice != (PMULTIMON_DEVICE)CB_ERR)
- {
- hwndC = GetCurDeviceHwnd();
- // The Current Device has changed, so, force recreating the bitmap the next time
- // we paint the monitor on the preview window.
- _pCurDevice->w = pDevice->w = 0;
- _pCurDevice = pDevice;
- if (hwndC)
- RedrawWindow(hwndC, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
- hwndC = GetCurDeviceHwnd();
- if (hwndC)
- RedrawWindow(hwndC, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
- if(_NumDevices > 1)
- {
- //
- // Update the two check box windows
- //
- #ifdef WINNT
- CheckDlgButton(_hDlg, IDC_DISPLAYPRIME, _pCurDevice->pds->IsPrimary());
- EnableWindow(GetDlgItem(_hDlg, IDC_DISPLAYPRIME),
- _pCurDevice->pds->IsAttached() &&
- !_pCurDevice->pds->IsPrimary());
- #endif
- CheckDlgButton(_hDlg, IDC_DISPLAYUSEME, _pCurDevice->pds->IsAttached());
- EnableWindow(GetDlgItem(_hDlg, IDC_DISPLAYUSEME),
- !_bNoAttach && !_pCurDevice->pds->IsPrimary());
- }
- //
- // Reset the values for the list boxes, and then repaint it
- //
- if(bRepaint)
- {
- _InitUI();
- _UpdateUI();
- }
- }
- else
- {
- //
- // No display device !
- //
- TraceMsg(TF_WARNING, "**** UpdateActiveDisplay: No display device!!!!");
- ASSERT(FALSE);
- }
- _InSetInfo--;
- }
- // ---------------------------------------------------------------------------
- // Initialize the resolution and color UI widgets
- //
- void CMultiMon::_InitUI()
- {
- int i;
- int Color;
- //
- // Update the Color list
- //
- TraceMsg(TF_FUNC, "_InitUI() -- Color list");
- SendDlgItemMessage(_hDlg, IDC_COLORBOX, CB_RESETCONTENT, 0, 0);
- if (_pCurDevice->ColorList)
- {
- LocalFree(_pCurDevice->ColorList);
- _pCurDevice->ColorList = NULL;
- }
- _pCurDevice->cColors = _pCurDevice->pds->GetColorList(NULL, &_pCurDevice->ColorList);
- for (i = 0; i < _pCurDevice->cColors; i++)
- {
- TCHAR achColor[50];
- DWORD idColor;
- Color = (int) *(_pCurDevice->ColorList + i);
- //
- // convert bit count to number of colors and make it a string
- //
- switch (Color)
- {
- case 32: idColor = ID_DSP_TXT_TRUECOLOR32; break;
- case 24: idColor = ID_DSP_TXT_TRUECOLOR24; break;
- case 16: idColor = ID_DSP_TXT_16BIT_COLOR; break;
- case 15: idColor = ID_DSP_TXT_15BIT_COLOR; break;
- case 8: idColor = ID_DSP_TXT_8BIT_COLOR; break;
- case 4: idColor = ID_DSP_TXT_4BIT_COLOR; break;
- default:
- ASSERT(FALSE);
- }
- LoadString(hInstance, idColor, achColor, SIZEOF(achColor));
- SendDlgItemMessage(_hDlg, IDC_COLORBOX, CB_INSERTSTRING, i, (LPARAM)achColor);
- }
- //
- // Update the screen Size List
- //
- TraceMsg(TF_FUNC, "_InitUI() -- Screen Size list");
- if (_pCurDevice->ResolutionList)
- {
- LocalFree(_pCurDevice->ResolutionList);
- _pCurDevice->ResolutionList = NULL;
- }
- _pCurDevice->cResolutions =
- _pCurDevice->pds->GetResolutionList(-1, &_pCurDevice->ResolutionList);
- SendDlgItemMessage(_hDlg, IDC_SCREENSIZE, TBM_SETRANGE, TRUE,
- MAKELONG(0, _pCurDevice->cResolutions - 1));
- TraceMsg(TF_FUNC, "_InitUI() -- Res MaxRange = %d", _pCurDevice->cResolutions - 1);
- //
- // Reset the indices since they are no longer valid
- //
- _iResolution = -1;
- _iColor = -1;
- //EnableWindow(GetDlgItem(_hDlg, IDC_COLORBOX), _fOrgAttached);
- //EnableWindow(GetDlgItem(_hDlg, IDC_SCREENSIZE), _fOrgAttached);
- }
- // ---------------------------------------------------------------------------
- // Update the resolution and color UI widgets
- //
- void CMultiMon::_UpdateUI(int FocusToCtrlID)
- {
- int i;
- POINT Res;
- int Color;
- BOOL bRepaint;
- //
- // Get the current values
- //
- _pCurDevice->pds->GetCurResolution(&Res);
- Color = _pCurDevice->pds->GetCurColor();
- //
- // Update the color listbox
- //
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Color %d", Color);
- for (i=0; i<_pCurDevice->cColors; i++)
- {
- if (Color == (int) *(_pCurDevice->ColorList + i))
- {
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Color index %d", i);
- if (_iColor == i)
- {
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Color index %d - is current", i);
- break;
- }
- HBITMAP hbm, hbmOld;
- int iBitmap = IDB_COLOR4DITHER;
- HDC hdc = GetDC(NULL);
- int bpp = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
- SendDlgItemMessage(_hDlg, IDC_COLORBOX, CB_SETCURSEL, i, 0);
- if (Color <= 4)
- iBitmap = IDB_COLOR4;
- else if (bpp >= 16)
- {
- if (Color <= 8)
- iBitmap = IDB_COLOR8;
- else if (Color <= 16)
- iBitmap = IDB_COLOR16;
- else
- iBitmap = IDB_COLOR24;
- }
- ReleaseDC(NULL, hdc);
- hbm = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(iBitmap), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
- if (hbm)
- {
- hbmOld = (HBITMAP) SendDlgItemMessage(_hDlg, IDC_COLORSAMPLE, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbm);
- if (hbmOld)
- {
- DeleteObject(hbmOld);
- }
- }
- _iColor = i;
- break;
- }
- }
- if (i == _pCurDevice->cColors)
- {
- TraceMsg(TF_ERROR, "_UpdateUI -- !!! inconsistent color list !!!");
- }
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Resolution %d %d", Res.x, Res.y);
- //
- // Update the resolution string
- //
- {
- TCHAR achStr[80];
- TCHAR achRes[120];
- LoadString(hInstance, ID_DSP_TXT_XBYY, achStr, SIZEOF(achStr));
- wsprintf(achRes, achStr, Res.x, Res.y);
- SendDlgItemMessage(_hDlg, IDC_RESXY, WM_SETTEXT, 0, (LPARAM)achRes);
- }
- //
- // Update the resolution slider
- //
- for (i=0; i<_pCurDevice->cResolutions; i++)
- {
- if ( (Res.x == (*(_pCurDevice->ResolutionList + i)).x) &&
- (Res.y == (*(_pCurDevice->ResolutionList + i)).y) )
- {
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Resolution index %d", i);
- if (_iResolution == i)
- {
- TraceMsg(TF_FUNC, "_UpdateUI() -- Set Resolution index %d - is current", i);
- break;
- }
- SendDlgItemMessage(_hDlg, IDC_SCREENSIZE, TBM_SETPOS, TRUE, i);
- break;
- }
- }
- if (i == _pCurDevice->cResolutions)
- {
- TraceMsg(TF_ERROR, "_UpdateUI -- !!! inconsistent color list !!!");
- }
- bRepaint = (i != _iResolution);
- _iResolution = i;
- //
- // If the resolution has changed, we have to repaint the preview window
- // Set the focus back to the trackbar after the repaint so any further
- // kb events will be send to it rather than the preview window
- //
- if (bRepaint) {
- SendMessage(_hDlg, MM_REDRAWPREVIEW, 0, 0);
- }
- if (FocusToCtrlID != 0) {
- SetFocus(GetDlgItem(_hDlg, FocusToCtrlID));
- }
- }
- //----------------------------------------------------------------------------
- //
- // SetPrimary()
- //
- //----------------------------------------------------------------------------
- BOOL
- CMultiMon::SetPrimary(
- PMULTIMON_DEVICE pDevice)
- {
- //
- // Check if state is already set.
- //
- if (pDevice == _pPrimaryDevice)
- {
- pDevice->pds->SetPrimary(TRUE);
- return TRUE;
- }
- ASSERT(pDevice->pds->IsAttached());
- //
- // make sure the primary is in a valid mode
- //
- // BUGBUG
- //_VerifyPrimaryMode(FALSE);
- //
- // make sure the primary is in a mode >= 256 color
- //
- if (pDevice->pds->GetCurColor() < 8)
- {
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- _Devices[iDevice].pds->SetAttached(FALSE);
- }
- pDevice->pds->SetAttached(TRUE);
- RedrawWindow(GetDlgItem(_hDlg, IDC_DISPLAYDESK), NULL, NULL,
- RDW_ALLCHILDREN | RDW_ERASE | RDW_INVALIDATE);
- }
- _pPrimaryDevice->pds->SetPrimary(FALSE);
- pDevice->pds->SetPrimary(TRUE);
- _pPrimaryDevice = pDevice;
- SetDirty();
- return TRUE;
- }
- //----------------------------------------------------------------------------
- //
- // SetMonAttached()
- //
- //----------------------------------------------------------------------------
- BOOL
- CMultiMon::SetMonAttached(
- PMULTIMON_DEVICE pDevice,
- BOOL bSetAttached,
- BOOL bForce,
- HWND hwnd)
- {
- if (pDevice->pds->IsAttached() == bSetAttached)
- {
- return TRUE;
- }
- if (bSetAttached)
- {
- //
- // Make sure this device actually has a rectangle.
- // If it does not (not configured in the registry, then we need
- // to put up a popup and ask the user to configure the device.
- //
- // BUGBUG
- // RECT rcPos;
- // pDevice->pds->GetCurPosition(&rcPos);
- // if (IsRectEmpty(&rcPos))
- // return FALSE;
- if (hwnd)
- {
- //
- // Check to see if we should ask the user about enabling this device
- //
- if (bForce == FALSE)
- {
- TCHAR szTurnItOn[400];
- TCHAR szTurnOnTitleFormat[30];
- TCHAR szTurnOnTitle[110];
- LPTSTR pstr = szTurnItOn;
- LoadString(hInstance, IDS_TURNONTITLE, szTurnOnTitleFormat, SIZEOF(szTurnOnTitleFormat));
- wsprintf(szTurnOnTitle, szTurnOnTitleFormat, pDevice->DisplayIndex);
- if (GetNumberOfAttachedDisplays() == 1)
- {
- LoadString(hInstance, IDS_TURNONMSG, szTurnItOn, SIZEOF(szTurnItOn));
- pstr += lstrlen(szTurnItOn);
- }
- LoadString(hInstance, IDS_TURNITON, pstr, SIZEOF(szTurnItOn));
- if (ShellMessageBox(hInstance, hwnd, szTurnItOn, szTurnOnTitle,
- MB_YESNO | MB_ICONINFORMATION) != IDYES)
- {
- return FALSE;
- }
- }
- }
- pDevice->pds->SetAttached(TRUE);
- }
- else // (bSetAttached == FALSE)
- {
- //
- // Can't detach if we have only one device or it's the primary.
- // The UI should disable this situation
- //
- if ((GetNumberOfAttachedDisplays() == 1) ||
- pDevice->pds->IsPrimary())
- {
- ASSERT(FALSE);
- }
- pDevice->pds->SetAttached(FALSE);
- }
- SetDirty();
- return TRUE;
- #if 0
- #ifndef WINNT
- // BUGBUG Memphis stuff
- //else
- //{
- // _pPrimaryDevice->pds->SetMode(640,480,8);
- //}
- #endif
- #endif
- }
- //----------------------------------------------------------------------------
- //
- // SetDirty
- //
- //----------------------------------------------------------------------------
- void CMultiMon::SetDirty(BOOL bDirty)
- {
- _bDirty = bDirty;
- if (_bDirty)
- {
- PostMessage(GetParent(_hDlg), PSM_CHANGED, (WPARAM)_hDlg, 0L);
- }
- }
- //-----------------------------------------------------------------------------
- void CMultiMon::_CleanupRects(HWND hwndP)
- {
- int n;
- HWND hwndC;
- DWORD arcDev[MONITORS_MAX];
- RECT arc[MONITORS_MAX];
- DWORD iArcPrimary = 0;
- RECT rc;
- RECT rcU;
- int i;
- RECT rcPrev;
- int sx,sy;
- int x,y;
- //
- // get the positions of all the windows
- //
- n = 0;
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- PMULTIMON_DEVICE pDevice = &_Devices[iDevice];
- hwndC = GetDlgItemP(hwndP, (INT_PTR) pDevice);
- if (hwndC != NULL)
- {
- RECT rcPos;
- TraceMsg(TF_GENERAL, "_CleanupRects start Device %08lx, Dev = %d, hwnd = %08lx",
- pDevice, iDevice, hwndC);
- ShowWindow(hwndC, SW_SHOW);
- GetWindowRect(hwndC, &arc[n]);
- MapWindowPoints(NULL, hwndP, (POINT FAR*)&arc[n], 2);
- pDevice->pds->GetCurPosition(&rcPos);
- _OffsetPreviewToDesk(&arc[n], &rcPos);
- arc[n] = rcPos;
- arcDev[n] = iDevice;
- // TEMP
- // For non-atached devices, make sure they end up to the right
- // Eventually, non-attached devices should be showed aligned on the
- // right hand side of the window.
- if (!pDevice->pds->IsAttached())
- {
- OffsetRect(&arc[n], 10000, 0);
- }
- if (pDevice->pds->IsPrimary())
- {
- TraceMsg(TF_GENERAL, "_CleanupRects primary Device %08lx", pDevice);
- iArcPrimary = n;
- }
- n++;
- }
- }
- //
- // cleanup the rects
- //
- AlignRects(arc, n, iArcPrimary, CUDR_NORMAL);
- //
- // Get the union.
- //
- SetRectEmpty(&rcU);
- for (i=0; i<n; i++)
- UnionRect(&rcU, &rcU, &arc[i]);
- GetClientRect(hwndP, &rcPrev);
- //
- // only rescale if the new desk hangs outside the preview area.
- // or is too small
- //
- _DeskToPreview(&rcU, &rc);
- x = ((rcPrev.right - rcPrev.left)-(rc.right - rc.left))/2;
- y = ((rcPrev.bottom - rcPrev.top) -(rc.bottom - rc.top))/2;
- if (rcU.left < 0 || rcU.top < 0 || x < 0 || y < 0 ||
- rcU.right > rcPrev.right || rcU.bottom > rcPrev.bottom ||
- (x > (rcPrev.right-rcPrev.left)/8 &&
- y > (rcPrev.bottom-rcPrev.top)/8))
- {
- _rcDesk = rcU;
- sx = MulDiv(rcPrev.right - rcPrev.left - 16,1000,_rcDesk.right - _rcDesk.left);
- sy = MulDiv(rcPrev.bottom - rcPrev.top - 16,1000,_rcDesk.bottom - _rcDesk.top);
- _DeskScale = min(sx,sy) * 2 / 3;
- _DeskToPreview(&_rcDesk, &rc);
- _DeskOff.x = ((rcPrev.right - rcPrev.left)-(rc.right - rc.left))/2;
- _DeskOff.y = ((rcPrev.bottom - rcPrev.top) -(rc.bottom - rc.top))/2;
- }
- //
- // Show all the windows and save them all to the devmode.
- //
- for (i=0; i < n; i++)
- {
- RECT rcPos;
- POINT ptPos;
- _Devices[arcDev[i]].pds->GetCurPosition(&rcPos);
- hwndC = GetDlgItemP(hwndP, (INT_PTR) &_Devices[arcDev[i]]);
- _DeskToPreview(&arc[i], &rc);
- rc.right = MulDiv(RECTWIDTH(rcPos), _DeskScale, 1000);
- rc.bottom = MulDiv(RECTHEIGHT(rcPos), _DeskScale, 1000);
- TraceMsg(TF_GENERAL, "_CleanupRects set Dev = %d, hwnd = %08lx", arcDev[i], hwndC);
- TraceMsg(TF_GENERAL, "_CleanupRects window pos %d,%d,%d,%d", rc.left, rc.top, rc.right, rc.bottom);
- SetWindowPos(hwndC,
- NULL,
- rc.left,
- rc.top,
- rc.right,
- rc.bottom,
- SWP_NOZORDER);
- ptPos.x = arc[i].left;
- ptPos.y = arc[i].top;
- _Devices[arcDev[i]].pds->SetCurPosition(&ptPos);
- }
- TraceMsg(TF_GENERAL, "");
- }
- void CMultiMon::_ConfirmPositions()
- {
- ASSERT (_NumDevices > 1);
- PMULTIMON_DEVICE pDevice;
- ULONG iDevice;
- for (iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- pDevice = &_Devices[iDevice];
- if (pDevice->pds->IsOrgAttached())
- {
- RECT rcOrg, rcCur;
- pDevice->pds->GetCurPosition(&rcCur);
- pDevice->pds->GetOrgPosition(&rcOrg);
- if ((rcCur.left != rcOrg.left) ||
- (rcCur.top != rcOrg.top))
- {
- POINT ptOrg;
- ptOrg.x = rcCur.left;
- ptOrg.y = rcCur.top;
- pDevice->pds->SetOrgPosition(&ptOrg);
- SetDirty(TRUE);
- }
- }
- }
- }
- void CMultiMon::GetMonitorPosition(PMULTIMON_DEVICE pDevice, HWND hwndP, PPOINT ptPos)
- {
- int iPrimary;
- HWND hwndC;
- RECT rcPos;
- RECT arc[MONITORS_MAX];
- int i;
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- PMULTIMON_DEVICE pDevice = &_Devices[iDevice];
- hwndC = GetDlgItemP(hwndP, (INT_PTR) pDevice);
- ASSERT(hwndC);
- GetWindowRect(hwndC, &arc[iDevice]);
- MapWindowPoints(NULL, hwndP, (POINT FAR*)&arc[iDevice], 2);
- pDevice->pds->GetCurPosition(&rcPos);
- _OffsetPreviewToDesk(&arc[iDevice], &rcPos);
- arc[iDevice] = rcPos;
- if (pDevice->pds->IsPrimary()) {
- iPrimary = iDevice;
- }
- }
- AlignRects(arc, iDevice, iPrimary, CUDR_NORMAL);
- i = (int)(pDevice - _Devices);
- ptPos->x = arc[i].left;
- ptPos->y = arc[i].top;
- }
- BOOL CMultiMon::HandleMonitorChange(HWND hwndP, BOOL bMainDlg, BOOL bRepaint /*=TRUE*/)
- {
- if (!bMainDlg && _InSetInfo)
- return FALSE;
- SetDirty();
- if (bMainDlg)
- BringWindowToTop(hwndP);
- _CleanupRects(GetParent(hwndP));
- UpdateActiveDisplay(_pCurDevice, bRepaint);
- return TRUE;
- }
- BOOL CMultiMon::RegisterPreviewWindowClass(WNDPROC pfnWndProc)
- {
- TraceMsg(TF_GENERAL, "InitMultiMonitorDlgn");
- WNDCLASS cls;
- cls.hCursor = LoadCursor(NULL,IDC_ARROW);
- cls.hIcon = NULL;
- cls.lpszMenuName = NULL;
- cls.lpszClassName = TEXT("Monitor32");
- cls.hbrBackground = (HBRUSH)(COLOR_DESKTOP + 1);
- cls.hInstance = hInstance;
- cls.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
- cls.lpfnWndProc = pfnWndProc;
- cls.cbWndExtra = SIZEOF(LPVOID);
- cls.cbClsExtra = 0;
- return RegisterClass(&cls);
- }
- LRESULT CALLBACK DeskWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uID, DWORD_PTR dwRefData);
- // This function is called from desk.c; Hence extern "C".
- // This function is needed to determine if we need to use the single monitor's dialog
- // or multi-monitor's dialog template at the time of starting the control panel applet.
- int ComputeNumberOfDisplayDevices()
- {
- int iNumberOfDevices = 0;
- CMultiMon *pMultiMon = new CMultiMon;
- int iDevice;
- // Enumerate all display devices to count the number of valid devices.
- iNumberOfDevices = pMultiMon->_EnumerateAllDisplayDevices();
- // Now that we have the number of devices, let's cleanup the device settings we
- // created in the process of enumerating above.
- for (iDevice = 0; iDevice < iNumberOfDevices; iDevice++)
- pMultiMon->_DestroyMultimonDevice(&pMultiMon->_Devices[iDevice]);
- // Let's clean up the MultiMon we allocated earlier.
- delete pMultiMon;
- return iNumberOfDevices;
- }
- BOOL CMultiMon::_InitDisplaySettings(BOOL bExport)
- {
- HWND hwndC;
- int iItem;
- LONG iPrimeDevice;
- TCHAR ach[128];
- PMULTIMON_DEVICE pDevice;
- RECT rcPrimary;
- HCURSOR hcur;
- _InSetInfo = 1;
- hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
- //
- // Reset all the data so we can reinitialize the applet.
- //
- {
- ComboBox_ResetContent(_hwndList);
- SetRectEmpty(&_rcDesk);
- while (hwndC = GetWindow(_hwndDesk, GW_CHILD))
- {
- RemoveTrackingToolTip(hwndC);
- RemovePopupToolTip(hwndC);
- DestroyWindow(hwndC);
- }
- ShowWindow(_hwndDesk, SW_HIDE);
- if (_himl != NULL)
- {
- ImageList_Destroy(_himl);
- _himl = NULL;
- }
- //
- // Clear out all the devices.
- //
- for (ULONG iDevice = 0; iDevice < _NumDevices; iDevice++) {
- pDevice = _Devices + iDevice;
- _DestroyMultimonDevice(pDevice);
- ZeroMemory(pDevice, sizeof(MULTIMON_DEVICE));
- }
- ZeroMemory(_Devices + _NumDevices,
- sizeof(_Devices) - sizeof(MULTIMON_DEVICE) * _NumDevices);
- _NumDevices = 0;
- }
- //
- // Enumerate all the devices in the system.
- //
- // Note: This function computes the _NumDevices.
- _EnumerateAllDisplayDevices();
- if (_NumDevices == 0)
- {
- ASSERT(0);
- return FALSE;
- }
- //
- // Because we are getting the registry values, the current state of
- // the registry may be inconsistent with that of the system:
- //
- // EmumDisplayDevices will return the active primary in the
- // system, which may be different than the actual primary marked in the
- // registry
- //
- BOOL bTmpDevicePrimary = FALSE;
- BOOL bBestDevicePrimary = FALSE;
- ULONG iDevice;
- _pPrimaryDevice = NULL;
- for (iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- //
- // First, we can pick any monitor that is attached as the primary.
- //
- if (_Devices[iDevice].pds->IsAttached())
- {
- if (_pPrimaryDevice == NULL)
- {
- _pPrimaryDevice = &_Devices[iDevice];
- TraceMsg(TF_GENERAL, "InitDisplaySettings: primary found %dn", iDevice);
- }
- //
- // If the DISPLAY_DEVICE structure tells us this is the primary,
- // Pick this one.
- //
- if (_Devices[iDevice].DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
- {
- if (bTmpDevicePrimary)
- {
- ASSERT(FALSE);
- }
- else
- {
- _pPrimaryDevice = &_Devices[iDevice];
- bTmpDevicePrimary = TRUE;
- TraceMsg(TF_GENERAL, "InitDisplaySettings: Tmp DEVICE_PRIMARY found %d", iDevice);
- }
- //
- // Check that the position should really be 0,0
- //
- RECT pos;
- _Devices[iDevice].pds->GetCurPosition(&pos);
- if ((pos.left == 0) &&
- (pos.top == 0))
- {
- _pPrimaryDevice = &_Devices[iDevice];
- TraceMsg(TF_GENERAL, "InitDisplaySettings: Best DEVICE_PRIMARY found %d", iDevice);
- }
- else
- {
- ASSERT(FALSE);
- TraceMsg(TF_GENERAL, "InitDisplaySettings: PRIMARY is not at 0,0");
- }
- }
- }
- }
- if (_pPrimaryDevice == NULL)
- {
- ASSERT(FALSE);
- TraceMsg(TF_GENERAL, "InitDisplaySettings: NO Attached devices !!!");
- //
- // We must be running setup - pick the first device as the primary.
- //
- _pPrimaryDevice = &_Devices[0];
- }
- _pCurDevice = _pPrimaryDevice;
- //
- // Reset the primary's variables to make sure it is a properly formated
- // primary entry.
- //
- SetMonAttached(_pPrimaryDevice, TRUE, TRUE, NULL);
- SetPrimary(_pPrimaryDevice);
- _pPrimaryDevice->pds->GetCurPosition(&rcPrimary);
- #ifndef WINNT
- if (!lstrcmpi((LPTSTR)_pPrimaryDevice->DisplayDevice.DeviceString,TEXT("Standard VGA")))
- _bNoAttach = TRUE;
- #endif
- //
- // compute the max image size needed for a monitor bitmap
- //
- // NOTE this must be the max size the images will *ever*
- // be we cant just take the current max size.
- // we use the client window size, a child monitor cant be larger than this.
- //
- RECT rcDesk;
- GetClientRect(_hwndDesk, &rcDesk);
- int cxImage = rcDesk.right;
- int cyImage = rcDesk.bottom;
- //
- // Create a temporary monitor bitmap
- //
- HBITMAP hbm = NULL;
- MakeMonitorBitmap(cxImage, cyImage, NULL, &hbm, NULL, cxImage, cyImage, FALSE);
- //
- // Go through all the devices one last time to create the windows
- //
- for (iDevice = 0; iDevice < _NumDevices; iDevice++)
- {
- TCHAR szDisplay[256];
- pDevice = &_Devices[iDevice];
- MonitorData md = {0};
- RECT rcPos;
- LPVOID pWindowData = (LPVOID)this;
- pDevice->DisplayIndex = iDevice + 1;
- _GetDisplayName(pDevice, szDisplay, ARRAYSIZE(szDisplay));
- iItem = ComboBox_AddString(_hwndList, szDisplay);
- pDevice->ComboBoxItem = iItem;
- ComboBox_SetItemData(_hwndList,
- iItem,
- (DWORD_PTR)pDevice);
- //
- // If the monitor is part of the desktop, show it on the screen
- // otherwise keep it invisible.
- //
- wsprintf(ach, TEXT("%d"), iDevice + 1);