wxDisplayFactoryMSW::wxDisplayFactoryMSW() { if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL || gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL ) { // First initialization, or last initialization failed. wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET); wxDL_INIT_FUNC(gs_, MonitorFromPoint, dllDisplay); wxDL_INIT_FUNC(gs_, MonitorFromWindow, dllDisplay); wxDL_INIT_FUNC_AW(gs_, GetMonitorInfo, dllDisplay); wxDL_INIT_FUNC(gs_, EnumDisplayMonitors, dllDisplay); // we can safely let dllDisplay go out of scope, the DLL itself will // still remain loaded as all programs link to it statically anyhow } if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL || gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL ) return; // enumerate all displays if ( !gs_EnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) ) { wxLogLastError(wxT("EnumDisplayMonitors")); } }
wxDisplayFactoryDirectDraw::wxDisplayFactoryDirectDraw() { if ( !ms_supportsMultimon ) return; m_dllDDraw.Load(wxT("ddraw.dll"), wxDL_VERBATIM | wxDL_QUIET); if ( !m_dllDDraw.IsLoaded() ) return; DirectDrawEnumerateEx_t wxDL_INIT_FUNC_AW(pfn, DirectDrawEnumerateEx, m_dllDDraw); if ( !pfnDirectDrawEnumerateEx ) return; // we can't continue without DirectDrawCreate() later, so resolve it right // now and fail the initialization if it's not available if ( !wxDL_INIT_FUNC(m_pfn, DirectDrawCreate, m_dllDDraw) ) return; if ( (*pfnDirectDrawEnumerateEx)(DDEnumExCallback, this, DDENUM_ATTACHEDSECONDARYDEVICES) != DD_OK ) { wxLogLastError(wxT("DirectDrawEnumerateEx")); } }
// wrapper around Shell_NotifyIcon(): this function is not present in Win95 // shell32.dll so load it dynamically to allow programs using wxTaskBarIcon to // start under this OS static BOOL wxShellNotifyIcon(DWORD dwMessage, NOTIFYICONDATA *pData) { #if wxUSE_DYNLIB_CLASS typedef BOOL (WINAPI *Shell_NotifyIcon_t)(DWORD, NOTIFYICONDATA *); static Shell_NotifyIcon_t s_pfnShell_NotifyIcon = NULL; static bool s_initialized = false; if ( !s_initialized ) { s_initialized = true; wxLogNull noLog; wxDynamicLibrary dllShell("shell32.dll"); if ( dllShell.IsLoaded() ) { wxDL_INIT_FUNC_AW(s_pfn, Shell_NotifyIcon, dllShell); } // NB: it's ok to destroy dllShell here, we link to shell32.dll // implicitly so it won't be unloaded } return s_pfnShell_NotifyIcon ? (*s_pfnShell_NotifyIcon)(dwMessage, pData) : FALSE; #else // !wxUSE_DYNLIB_CLASS return Shell_NotifyIcon(dwMessage, pData); #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS }
// Helper wrapping AssocQueryString() Win32 function: returns the value of the // given associated string for the specified extension (which may or not have // the leading period). // // Returns empty string if the association is not found. static wxString wxAssocQueryString(ASSOCSTR assoc, wxString ext, const wxString& verb = wxString()) { typedef HRESULT (WINAPI *AssocQueryString_t)(ASSOCF, ASSOCSTR, LPCTSTR, LPCTSTR, LPTSTR, DWORD *); static AssocQueryString_t s_pfnAssocQueryString = (AssocQueryString_t)-1; static wxDynamicLibrary s_dllShlwapi; if ( s_pfnAssocQueryString == (AssocQueryString_t)-1 ) { if ( !s_dllShlwapi.Load(wxT("shlwapi.dll"), wxDL_VERBATIM | wxDL_QUIET) ) s_pfnAssocQueryString = NULL; else wxDL_INIT_FUNC_AW(s_pfn, AssocQueryString, s_dllShlwapi); } if ( !s_pfnAssocQueryString ) return wxString(); DWORD dwSize = MAX_PATH; TCHAR bufOut[MAX_PATH] = { 0 }; if ( ext.empty() || ext[0] != '.' ) ext.Prepend('.'); HRESULT hr = s_pfnAssocQueryString ( wxASSOCF_NOTRUNCATE,// Fail if buffer is too small. assoc, // The association to retrieve. ext.t_str(), // The extension to retrieve it for. verb.empty() ? NULL : static_cast<const TCHAR*>(verb.t_str()), bufOut, // The buffer for output value. &dwSize // And its size ); // Do not use SUCCEEDED() here as S_FALSE could, in principle, be returned // but would still be an error in this context. if ( hr != S_OK ) { // The only really expected error here is that no association is // defined, anything else is not expected. The confusing thing is that // different errors are returned for this expected error under // different Windows versions: XP returns ERROR_FILE_NOT_FOUND while 7 // returns ERROR_NO_ASSOCIATION. Just check for both to be sure. if ( hr != HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) && hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ) { wxLogApiError("AssocQueryString", hr); } return wxString(); } return wxString(bufOut); }
wxDisplayFactoryWin32Base::wxDisplayFactoryWin32Base() { if ( ms_supportsMultimon == -1 ) { ms_supportsMultimon = 0; wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET); if ( (wxDL_INIT_FUNC(gs_, MonitorFromPoint, dllDisplay)) == NULL || (wxDL_INIT_FUNC(gs_, MonitorFromWindow, dllDisplay)) == NULL || (wxDL_INIT_FUNC_AW(gs_, GetMonitorInfo, dllDisplay)) == NULL ) return; ms_supportsMultimon = 1; // we can safely let dllDisplay go out of scope, the DLL itself will // still remain loaded as all programs link to it statically anyhow } }
wxDisplayFactoryMSW::wxDisplayFactoryMSW() { // This is not supposed to happen with the current code, the factory is // implicitly a singleton. wxASSERT_MSG( !ms_factory, wxS("Using more than one factory?") ); ms_factory = this; m_hiddenHwnd = NULL; m_hiddenClass = NULL; if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL || gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL ) { // First initialization, or last initialization failed. wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET); wxDL_INIT_FUNC(gs_, MonitorFromPoint, dllDisplay); wxDL_INIT_FUNC(gs_, MonitorFromWindow, dllDisplay); wxDL_INIT_FUNC_AW(gs_, GetMonitorInfo, dllDisplay); wxDL_INIT_FUNC(gs_, EnumDisplayMonitors, dllDisplay); // we can safely let dllDisplay go out of scope, the DLL itself will // still remain loaded as all programs link to it statically anyhow } if ( gs_MonitorFromPoint==NULL || gs_MonitorFromWindow==NULL || gs_GetMonitorInfo==NULL || gs_EnumDisplayMonitors==NULL ) return; DoRefreshMonitors(); // Also create a hidden window to listen for WM_SETTINGCHANGE that we // receive when a monitor is added to or removed from the system as we must // refresh our monitor handles information then. m_hiddenHwnd = wxCreateHiddenWindow ( &m_hiddenClass, wxT("wxDisplayHiddenWindow"), wxDisplayWndProc ); }
bool wxDisplayImplMultimon::ChangeMode(const wxVideoMode& mode) { // prepare ChangeDisplaySettingsEx() parameters DEVMODE dm; DEVMODE *pDevMode; int flags; if ( mode == wxDefaultVideoMode ) { // reset the video mode to default pDevMode = NULL; flags = 0; } else // change to the given mode { wxCHECK_MSG( mode.GetWidth() && mode.GetHeight(), false, wxT("at least the width and height must be specified") ); wxZeroMemory(dm); dm.dmSize = sizeof(dm); dm.dmDriverExtra = 0; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; dm.dmPelsWidth = mode.GetWidth(); dm.dmPelsHeight = mode.GetHeight(); if ( mode.GetDepth() ) { dm.dmFields |= DM_BITSPERPEL; dm.dmBitsPerPel = mode.GetDepth(); } if ( mode.GetRefresh() ) { dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = mode.GetRefresh(); } pDevMode = &dm; #ifdef __WXWINCE__ flags = 0; #else // !__WXWINCE__ flags = CDS_FULLSCREEN; #endif // __WXWINCE__/!__WXWINCE__ } // get pointer to the function dynamically // // we're only called from the main thread, so it's ok to use static // variable static ChangeDisplaySettingsEx_t pfnChangeDisplaySettingsEx = NULL; if ( !pfnChangeDisplaySettingsEx ) { wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET); if ( dllDisplay.IsLoaded() ) { wxDL_INIT_FUNC_AW(pfn, ChangeDisplaySettingsEx, dllDisplay); } //else: huh, no this DLL must always be present, what's going on?? #ifndef __WXWINCE__ if ( !pfnChangeDisplaySettingsEx ) { // we must be under Win95 and so there is no multiple monitors // support anyhow pfnChangeDisplaySettingsEx = ChangeDisplaySettingsExForWin95; } #endif // !__WXWINCE__ } // do change the mode switch ( pfnChangeDisplaySettingsEx ( GetName().wx_str(), // display name pDevMode, // dev mode or NULL to reset NULL, // reserved flags, NULL // pointer to video parameters (not used) ) ) { case DISP_CHANGE_SUCCESSFUL: // ok { // If we have a top-level, full-screen frame, emulate // the DirectX behavior and resize it. This makes this // API quite a bit easier to use. wxWindow *winTop = wxTheApp->GetTopWindow(); wxFrame *frameTop = wxDynamicCast(winTop, wxFrame); if (frameTop && frameTop->IsFullScreen()) { wxVideoMode current = GetCurrentMode(); frameTop->SetClientSize(current.GetWidth(), current.GetHeight()); } } return true; case DISP_CHANGE_BADMODE: // don't complain about this, this is the only "expected" error break; default: wxFAIL_MSG( wxT("unexpected ChangeDisplaySettingsEx() return value") ); } return false; }