⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainwnd.cpp

📁 wince下internet explorer的浏览器的简单实现
💻 CPP
📖 第 1 页 / 共 5 页
字号:


/////////////////
#include "Precomp.h"
#include "commdlg.h"
#include "resource.h"
#include "MainWnd.h"
#include "animthrd.h"
#ifndef NO_FAVORITES
#include "addfavoritesdlg.h"
#include "favlistfulldlg.h"
#include "organizefavoritesdlg.h"
#include "regkeys.h"
#include "debug.h"
#include "RegFavorites.h"
#include <urlmon.h>

DBGPARAM dpCurSettings;
#endif

#define INITGUID
#include "initguid.h"


///////定义接口的GUID
DEFINE_GUID(CLSID_WebBrowser,       0x8856F961L, 0x340A, 0x11D0, 0xA9, 0x6B, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2);
DEFINE_GUID(IID_IWebBrowser,        0xEAB22AC1L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(IID_IWebBrowser2,       0xD30C1661L, 0xCDAF, 0x11D0, 0x8A, 0x3E, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0x6E);
DEFINE_GUID(DIID_DWebBrowserEvents, 0xEAB22AC2L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(DIID_DWebBrowserEvents2, 0x34A715A0L, 0x6587, 0x11D0, 0x92, 0x4A, 0x00, 0x20, 0xAF, 0xC7, 0xAC, 0x4D);
DEFINE_GUID(IID_IWebBrowserApp,     0x0002DF05L, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

const GUID SID_SDocHost = { 0xc6504990, 0xd43e, 0x11cf, { 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a}};


static TBBUTTON tbBtns[] = {    {0, ID_GO_BACK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {1, ID_GO_FORWARD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {2, ID_VIEW_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {3, ID_VIEW_REFRESH, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {4, ID_GO_HOME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {5, ID_GO_SEARCH, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
};

static TCHAR szTypedUrls[] = _T("Software\\Microsoft\\Internet Explorer\\TypedURLs");

#define PROGRESSPANEWIDTH	100			//width of the progressbar,进度条宽度
#define MAX_STATUSMSGLEN	127			//the maximum length for the statusbar message//状态条的最大长度
#define ID_COMBOEDIT		1001		//ID for the edit box of a combo box
#define MAXURLS				10			//maximum number of typed url's.//url的最多个数

#define MAX(a,b)  (a > b) ? a : b
#define MIN(a,b)  (a > b) ? b : a

LONG        glThreadCount	= 0;              /////当前线程数
HWND		ghWndAddressEdit= NULL;           /////地址栏编辑框
HANDLE      ghExitEvent		= NULL;
HINSTANCE   g_hInstance		= NULL;           ////实例句柄            
DWORD      g_dwMainWindowStackSize = 0x20000; //////主窗口栈128KB

typedef struct _ZONESNAMECACHE  // Cache for zone display names
{
    DWORD dwZone;
    WCHAR szZoneName[MAX_ZONE_PATH];
} ZONENAMECACHE, *PZONENAMECACHE;

#ifdef ZONEDISPLAY
PZONENAMECACHE g_pZoneNameCache = NULL;
DWORD g_dwZoneCount = 0;
IInternetSecurityManager * g_pSecMgr = NULL;
#endif

void GetProxyOption();        //得到代理配置函数声明

#ifdef OEMCONTROLS
BOOL RegisterOemControls();
#endif

static HRESULT FindString();  /////查找字符串
HRESULT HandleNewWindow2(LPTSTR lpszUrl, DISPPARAMS FAR* pdparams);  /////处理新窗口
BOOL RegisterMainWnd();  //////注册主窗口

#ifdef ZONEDISPLAY
BOOL GetZoneName(DWORD lZone, LPWSTR pwszName, DWORD cch);
#endif


#ifndef NO_GUIDFROMSTRING

#define InRange(id, idFirst, idLast)      ((UINT)((id)-(idFirst)) <= (UINT)((idLast)-(idFirst)))
#define IsInRange                   InRange

#define ARRAYSIZE(a)    (sizeof(a)/sizeof((a)[0]))


// scan psz for a number of hex digits (at most 8); update psz, return
// value in Value; check for chDelim; return TRUE for success.
//16进制字符串转换到双字
BOOL HexStringToDword(LPCTSTR * ppsz, DWORD * lpValue, int cDigits, TCHAR chDelim)
{
    int ich;
    LPCTSTR psz = *ppsz;
    DWORD Value = 0;
    BOOL fRet = TRUE;

    for (ich = 0; ich < cDigits; ich++)
    {
        TCHAR ch = psz[ich];
        if (InRange(ch, TEXT('0'), TEXT('9')))
        {
            Value = (Value << 4) + ch - TEXT('0');
        }
        else if ( InRange( (ch |= (TEXT('a')-TEXT('A'))), TEXT('a'), TEXT('f')) )
        {
            Value = (Value << 4) + ch - TEXT('a') + 10;
        }
        else
            return(FALSE);
    }

    if (chDelim)
    {
        fRet = (psz[ich++] == chDelim);
    }

    *lpValue = Value;
    *ppsz = psz+ich;

    return fRet;
}


// parse above format; return TRUE if succesful; always writes over *pguid.
//
STDAPI_(BOOL) GUIDFromString(LPCTSTR psz, GUID *pguid)
{
    DWORD dw;
    if (*psz++ != TEXT('{') /*}*/ )
        return FALSE;

    if (!HexStringToDword(&psz, &pguid->Data1, sizeof(DWORD)*2, TEXT('-')))
        return FALSE;

    if (!HexStringToDword(&psz, &dw, sizeof(WORD)*2, TEXT('-')))
        return FALSE;

    pguid->Data2 = (WORD)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(WORD)*2, TEXT('-')))
        return FALSE;

    pguid->Data3 = (WORD)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[0] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, TEXT('-')))
        return FALSE;

    pguid->Data4[1] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[2] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[3] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[4] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[5] = (BYTE)dw;

    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
        return FALSE;

    pguid->Data4[6] = (BYTE)dw;
    if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, /*(*/ TEXT('}')))
        return FALSE;

    pguid->Data4[7] = (BYTE)dw;

    return TRUE;
}
#endif


/////////线程函数
DWORD WINAPI NewWindow(LPVOID pParam)
{

    CMainWnd *pWnd = (CMainWnd *)pParam;
    MSG msg;
    BOOL fRet;

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);//////初始化COM库。多线程

    fRet = pWnd->Create();  ///////创建主窗口

    SetEvent(pWnd->hEvent); //////此时HandleNewWindow2函数结束等待

    if (!fRet)
    {
        pWnd->_pBrowser = NULL;
        return 0;
    }

    while (GetMessage( &msg, NULL, 0, 0 ) )
    {
        if(msg.message == WM_QUIT)
            break;

        if (!pWnd->PreTranslateMessage(&msg) && !(msg.message == WM_CHAR && msg.wParam == VK_TAB))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    pWnd->Release();

    CoUninitialize();

    InterlockedDecrement(&glThreadCount);
    SetEvent(ghExitEvent);

    return msg.wParam;
}


//装载浏览器帮助对象
BOOL CMainWnd::_LoadBrowserHelperObjects(void)
{
    BOOL bRet = FALSE;
    HKEY hkey;
    if (_pBrowser &&
        RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects"),0,0,  &hkey) == ERROR_SUCCESS)
    {
        TCHAR szGUID[64];
        DWORD cb = ARRAYSIZE(szGUID);
        for (int i = 0;
             RegEnumKeyEx(hkey, i, szGUID, &cb, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
             i++)
        {
            CLSID clsid;
            IObjectWithSite *pows;
            if ( GUIDFromString(szGUID, &clsid) && 
                SUCCEEDED(CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IObjectWithSite, (void **)&pows)))
            {
                pows->SetSite(_pBrowser);    // give the poinetr to IWebBrowser2

                BSTR strClsid;
                // now register this object so that it can be found through automation.
                strClsid = SysAllocString(szGUID);
                

                VARIANT varUnknown = {0};
                varUnknown.vt = VT_UNKNOWN;
                varUnknown.punkVal = pows;
                _pBrowser->PutProperty(strClsid, varUnknown);

                pows->Release(); // Instead of calling variantClear() 

                bRet = TRUE;
            }
            cb = ARRAYSIZE(szGUID);
        }
        RegCloseKey(hkey);
    }
    return bRet;
}


////////////////****** 主函数
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nCmdShow)
{
    INITCOMMONCONTROLSEX iccsex;
    HKEY hKey;
    DWORD dwSize = sizeof(DWORD);
    MSG msg;

    // HKCU is where IE\Main settings are
	/////得到注册表中主窗口的栈大小
    if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Main"), 0, 0, &hKey))
    {
            RegQueryValueEx(hKey, TEXT("StackRes"), NULL, NULL, (LPBYTE)&g_dwMainWindowStackSize, &dwSize);
            RegCloseKey(hKey);
    }

    // provide a default stack size if the one given is too small or too large. 
    if(g_dwMainWindowStackSize < 0x10000 || g_dwMainWindowStackSize > 0x80000)
    {
            // default to 128k
            g_dwMainWindowStackSize = 0x20000;
    }
    RETAILMSG(1,(L"IESAMPLE Using Stack size: %x", g_dwMainWindowStackSize));
#ifndef NO_FAVORITES
	// hook in ATL
	_Module.Init(NULL, reinterpret_cast<HINSTANCE>(hInst));
#endif
   
	//////初始化COM库
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (FAILED(hr))
    {
        return FALSE;
    }

#ifdef OEMCONTROLS
    if (!RegisterOemControls())
            return FALSE;
#endif	//OEMCONTROLS
    
	//////注册主窗口
   if (!RegisterMainWnd())
            return FALSE;
    
    ghExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//////创建事件。自动重置
    if (!ghExitEvent)
    {
        return FALSE;
    }

	///////加载rebar控件
    iccsex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    iccsex.dwICC = ICC_COOL_CLASSES
#ifndef NO_FAVORITES
    |ICC_TREEVIEW_CLASSES
#endif
    ;

    InitCommonControlsEx(&iccsex);  //

	////应用程序实例句柄
    g_hInstance = hInst;

    // Create  a message queue on this thread
    PeekMessage(&msg, NULL, 0,0,PM_NOREMOVE);

    if(HandleNewWindow2(lpCmdLine, NULL))   //打开新窗口
    {
        goto Cleanup;
    }


    while (glThreadCount > 0)   //一直循环,直到所有线程都结束
    {
        WaitForSingleObject(ghExitEvent, INFINITE);
    }
    
Cleanup:    
    CoUninitialize();
#ifndef NO_FAVORITES    
    _Module.Term();
#endif
#ifdef ZONEDISPLAY
	if (g_pSecMgr)
		g_pSecMgr->Release();
    if (g_pZoneNameCache)
		LocalFree(g_pZoneNameCache);
#endif
    RETAILMSG(1, (L"IESAMPLE exited. Cmdline was: %s\r\n",lpCmdLine ? lpCmdLine : L""));//

    return TRUE;
}

#ifdef ZONEDISPLAY

//得到地区名称
BOOL GetZoneName(DWORD lZone, LPWSTR pwszName, DWORD cch)
{
	DWORD nIndex;

	if (!pwszName || !cch)
		  return FALSE;

	if (!g_pZoneNameCache)
	{
	  IInternetZoneManager * pizm = NULL;
	  // Create ZoneManager
      CoCreateInstance(CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetZoneManager, (void **)&pizm);
      if (!pizm)
		  return FALSE;

	  DWORD dwZoneEnum, dwZoneCount;

      if (FAILED(pizm->CreateZoneEnumerator(&dwZoneEnum, &dwZoneCount, 0)))
	  {
		 pizm->Release();
		 return FALSE;
	  }
	  
	  g_pZoneNameCache = (PZONENAMECACHE)LocalAlloc(LPTR, dwZoneCount * sizeof(ZONENAMECACHE));
      
	  if (!g_pZoneNameCache)
	  {
		 pizm->Release();
		 return FALSE;
	  }
                
	  g_dwZoneCount = 0;

      for (nIndex=0; nIndex < dwZoneCount; nIndex++)
      {
           DWORD           dwZone;
           ZONEATTRIBUTES  za = {sizeof(ZONEATTRIBUTES)};

           if (SUCCEEDED(pizm->GetZoneAt(dwZoneEnum, nIndex, &dwZone)) &&
			   SUCCEEDED(pizm->GetZoneAttributes(dwZone, &za))) 
			{
				g_pZoneNameCache[nIndex].dwZone = dwZone;
				g_pZoneNameCache[nIndex].szZoneName[MAX_ZONE_PATH - 1] = 0;
				wcsncpy(g_pZoneNameCache[nIndex].szZoneName, za.szDisplayName, MAX_ZONE_PATH - 1);
				g_dwZoneCount++;
			}
	  }
      pizm->DestroyZoneEnumerator(dwZoneEnum);
	  pizm->Release();
    }

	for (nIndex = 0; nIndex < g_dwZoneCount; nIndex++) 
	{
		if (g_pZoneNameCache[nIndex].dwZone == lZone)
		{
			pwszName[cch -1] = 0;
			wcsncpy(pwszName, g_pZoneNameCache[nIndex].szZoneName, cch - 1);
			return TRUE;
		}
	}

    return FALSE;
}
#endif //ZONEDISPLAY

CMainWnd::CMainWnd()  //构造函数
{
    _ulRefs = 1;
    _hWnd = NULL;
    _pBrowser = NULL;
    _pObject = NULL;
    _pCP = NULL;
    _lpszUrl = NULL;
#ifndef NOCOMMANDBAR
    _lpfnAddressEditProc = NULL;
    _hWndMenuBar = NULL;
    _hWndAddrBar = NULL;
    _hWndToolBar = NULL;
    _hWndBrowser = NULL;
    _himlCmdBand = NULL;
#endif	//NOCOMMANDBAR

#ifndef NOSTATUSBAR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -