wxInternetExplorerHelper

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

wxInternetExplorerHelper

Post by PB »

When an application is using the Microsoft Internet Explorer backend for wxWebView, it is almost always necessary to set the appropriate emulation level. While this is generally a job for the installer, sometimes it may be needed to do it from the application’s code, e.g., in a portable installer-less application or just when playing with the code. wxWidgets has recently introduced wxWebView::MSWSetModernEmulationLevel() method but it unfortunately sets the emulation level only to IE8, which is often not high enough.

wxInternetExplorerHelper has two purposes:
1. To obtain the installed version of Internet Explorer.
2. To obtain and set the emulation level for the current application (for a currently logged user).

wxInternetExplorerHelper.h

Code: Select all

////////////////////////////////////////////////////////////////////////////////////
//
//  Name:        wxInternetExplorerHelper.h
//  Purpose:     Implements utility functions for detecting version of
//               Microsoft Internet Explorer and for detecting and setting
//               the emulation level for applications using wxWebViewIE
//  Author:      PB
//  Copyright:   (c) 2017 PB <[email protected]>
//  Licence:     wxWindows licence
//
////////////////////////////////////////////////////////////////////////////////////

#ifndef WX_INTERNET_EXPLORER_HELPER_H_DEFINED
#define WX_INTERNET_EXPLORER_HELPER_H_DEFINED

#include <stddef.h>

class wxInternetExplorerHelper
{
public:
    enum Version
    {
        Version_unknown = 0,
        Version_IE5 = 5,
        Version_IE6,
        Version_IE7,
        Version_IE8,
        Version_IE9,
        Version_IE10,
        Version_IE11
    };

    // Go here to learn more about individual values
    // https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)#browser_emulation
    enum Emulation
    {
        Emulation_none = 0,
        Emulation_unknown = 1,
        Emulation_IE7 = 7000, // default value for wxWebViewIE host
        Emulation_IE8_Default = 8000,
        Emulation_IE8_Standards = 8888,
        Emulation_IE9_Default = 9000,
        Emulation_IE9_Standards = 9999,
        Emulation_IE10_Default = 10000,
        Emulation_IE10_Standards = 10001,
        Emulation_IE11_Default = 11000,
        Emulation_IE11_Standards = 11001
    };

    // Uses the version of MSHTML.dll which may not
    // be exactly the same as the MSIE version but 
    // is exact enough for the purpose.
    static Version GetIEVersion(); 
    static bool IsIEVersionAtLeast(Version version);

    // Retrieves the emulation level for the calling executable
    // for the current user.
    static bool GetEmulation(Emulation& emulation);

    // Sets the emulation level for the calling executable
    // for the current user.
    // Calling with Emulation_none removes the emulation information 
    // for the calling executable for the current user from the registry.
    static bool SetEmulation(Emulation emulation);

private:
    static bool GetMSHTMLDllVersion(unsigned& major, 
                                    unsigned* minor = NULL, 
                                    unsigned* build = NULL, 
                                    unsigned* revision = NULL);
};


#endif // #ifdef WX_INTERNET_EXPLORER_HELPER_H_DEFINED
wxInternetExplorerHelper.cpp

Code: Select all

////////////////////////////////////////////////////////////////////////////////////
//
//  Name:        wxInternetExplorerHelper.cpp
//  Purpose:     Implements utility functions for detecting version of
//               Microsoft Internet Explorer and for detecting and setting
//               the emulation level for applications using wxWebViewIE
//  Author:      PB
//  Copyright:   (c) 2017 PB <[email protected]>
//  Licence:     wxWindows licence
//
////////////////////////////////////////////////////////////////////////////////////


#include "wxInternetExplorerHelper.h"

#ifdef __WXMSW__

#include <wx/buffer.h>
#include <wx/dynlib.h>

#include <wx/msw/registry.h>
#include <wx/msw/private.h>
#include <wx/msw/wrapwin.h>

wxInternetExplorerHelper::Version wxInternetExplorerHelper::GetIEVersion()
{
    unsigned major;

    if ( !GetMSHTMLDllVersion(major) )
        return Version_unknown;

    if ( major >= Version_IE5 && major <= Version_IE11 )
        return static_cast<Version>(major);
    else
        return Version_unknown;
}

bool wxInternetExplorerHelper::IsIEVersionAtLeast(Version version)
{
    wxCHECK(version != Version_unknown, "Invalid version value");
    
    const Version v = GetIEVersion();
    
    return v != Version_unknown && v >= version;        
}

// Code for getting/setting emulation is adapted from wxWebViewIE::MSWSetModernEmulationLevel()
// in WXWIN/src/msw/webview_ie.cpp

 // Registry key where emulation level for programs are set.
//  Used by wxInternetExplorerHelper::{Get|Set}Emulation()
static const wxChar* IE_EMULATION_KEY =
    wxS("SOFTWARE\\Microsoft\\Internet Explorer\\Main")
    wxS("\\FeatureControl\\FEATURE_BROWSER_EMULATION");

bool wxInternetExplorerHelper::GetEmulation(wxInternetExplorerHelper::Emulation& emulation)
{
    wxRegKey key(wxRegKey::HKCU, IE_EMULATION_KEY);
    
    if ( !key.Exists() )
    {        
        return false;
    }

    const wxString programName = wxGetFullModuleName().AfterLast('\\');
    
    if ( !key.HasValue(programName) )
    {
        emulation = Emulation_none;
        return true;
    }
    
    long keyValue;

    if ( !key.QueryValue(programName, &keyValue) )
    {
        return false;
    }

    switch ( keyValue )
    {
        case Emulation_IE7:
        case Emulation_IE8_Default: 
        case Emulation_IE8_Standards:
        case Emulation_IE9_Default:
        case Emulation_IE9_Standards:
        case Emulation_IE10_Default:
        case Emulation_IE10_Standards:
        case Emulation_IE11_Default:
        case Emulation_IE11_Standards:
            emulation = static_cast<Emulation>(keyValue);
            break;
        default:
            emulation = Emulation_unknown;
    };

    return true;
}

bool wxInternetExplorerHelper::SetEmulation(wxInternetExplorerHelper::Emulation emulation)
{
    wxCHECK(emulation != Emulation_unknown, wxS("Invalid emulation value"));
        
    wxRegKey key(wxRegKey::HKCU, IE_EMULATION_KEY);

    if ( !key.Exists() )
    {        
        return false;
    }
    
    const wxString programName = wxGetFullModuleName().AfterLast('\\');
    
    if ( emulation == Emulation_none )    
    {
        return key.DeleteValue(programName);
    }
    
    return key.SetValue(programName, static_cast<long>(emulation));
}

// code adapted from private function GetFileVersion(const wxString& filename) 
// in WXWIN/src/msw/dllmsw.cpp
bool wxInternetExplorerHelper::GetMSHTMLDllVersion(unsigned& major, 
                                                   unsigned* minor, 
                                                   unsigned* build, 
                                                   unsigned* revision)
{
    static const wxChar* dllName = wxS("mshtml.dll");	
    const DWORD sizeVerInfo = ::GetFileVersionInfoSize(dllName, NULL);

    if ( sizeVerInfo )
    {
        wxCharBuffer buf(sizeVerInfo);

        if ( ::GetFileVersionInfo(dllName, 0, sizeVerInfo, buf.data()) )
        {
            void *pVer = NULL;
            UINT sizeInfo = 0;
            
            if ( ::VerQueryValue(buf.data(), const_cast<wxChar*>(wxS("\\")),
                &pVer, &sizeInfo) )
            {
                const VS_FIXEDFILEINFO* info = (VS_FIXEDFILEINFO*)pVer;

                major = HIWORD(info->dwFileVersionMS);
                if ( minor )
                    *minor = LOWORD(info->dwFileVersionMS);
                if ( build )
                    *build = HIWORD(info->dwFileVersionLS);
                if ( revision )
                    *revision = LOWORD(info->dwFileVersionLS);

                return true;
            }
        }
    }

    return false;
}

#else // #ifdef __WXMSW__

wxInternetExplorerHelper::Version wxInternetExplorerHelper::GetIEVersion()
{ return Version_Unknown; }

bool wxInternetExplorerHelper::IsIEVersionAtLeast(wxInternetExplorerHelper::Version)
{ return false; }

bool wxInternetExplorerHelper::GetMSHTMLDllVersion(unsigned&, unsigned*, unsigned*, unsigned*)
{ return false; }

bool wxInternetExplorerHelper::GetEmulation(wxInternetExplorerHelper::Emulation&)
{ return false; }

bool wxInternetExplorerHelper::SetEmulation(wxInternetExplorerHelper::Emulation)
{ return false; }

#endif // #ifdef __WXMSW__
Attachments
wxInternetExplorerHelper.zip
(2.62 KiB) Downloaded 268 times
Post Reply