如上

解决方案 »

  1.   

    http://lexx.51.net/text/my/mytextd.htm
    用c实现的,你研究把。
      

  2.   

    其实原理很简单就是利用了 BHO(Browser Helper Object),一种在 IE 组件被启动时会被自动加载的 COM 组件。如果你对 COM 一点不了解可以参看Ash Rofail 和 Yasser Shohoud 著的《COM 与 COM+ 从入门到精通》,这本书入门极佳。 
    简单的说 BHO 就是注册在一个特殊位置(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects 下)的 .DLL,IE 组件启动时会查询注册表相应位置下把需要的 .DLL 装载进来。接着就利用那个 .DLL 被装载的机会,给 IE 加个画面了。 实现
    我采用 VC6.0 的 ATL 来开发这个 BHO 组件。为了不涉及 VC 的特殊性,便没有采用 MFC。
    首先,新建一个 ATL 工程,在其中插入一个 Internet Explorer Object,输入 COM 类名。完成了这步后,就应该已经生成了编译所需的所有文件了。接着就是加代码了。因为增加启动画面不需要很复杂所有的代码加在 DllMain 所在的 .cpp 文件中就可以了(笔者的例子中为 IEStart.cpp)。增加的代码大致可分为两部分:在 DllMain 中识别是否是 IE 装载了自己,接着再作出相应动作;启动画面的实现部分。
     /////////////////////////////////////////////////////////////////////////////
    // 一些要用到的全局申明
    #define WAIT_TIME       2000        // 启动画面停留的时间
    #define PictureH        109         // 启动画面的高
    #define PictureW        405         // 启动画面的宽       
    static UINT iTimeID = 0;            // 用来控制计时器/////////////////////////////////////////////////////////////////////////////
    // 过程的申明
    static int WINAPI ShowSplash(HINSTANCE hInstance, UINT iBgBmpHeight, UINT iBgBmpWidth);  
    static LRESULT CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);/////////////////////////////////////////////////////////////////////////////
    // DLL Entry Point 
    extern "C"
    BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
    {
        TCHAR pszLoader[MAX_PATH];
        LPSTR pstrFileName = NULL;    if (dwReason == DLL_PROCESS_ATTACH) {
            // 得到当前调用者的名字,如:C:\Program Files\Internet Explorer\IEXPLORE.EXE
            GetModuleFileName(NULL, pszLoader, MAX_PATH);
            pstrFileName = strrchr(pszLoader, '\\');
            if (pstrFileName == NULL) {
                // 出错处理
                // 空指针
                return FALSE;
            }
            pstrFileName++;
            
            // 判断是否是 IE,是则加载启动画面
            if (lstrcmpi(pstrFileName, TEXT("IEXPLORE.EXE")) == NULL) {
                // 加载启动画面
                ShowSplash(hInstance, PictureH, PictureW);                        
            }
            
            _Module.Init(ObjectMap, hInstance, &LIBID_IESTARTLib);
            DisableThreadLibraryCalls(hInstance);
        }
        else if (dwReason == DLL_PROCESS_DETACH) {
            _Module.Term();
        }
        return TRUE;    // ok
    }/////////////////////////////////////////////////////////////////////////////
    // IE 启动画面显示int WINAPI ShowSplash(HINSTANCE hInstance, UINT iBgBmpHeight, UINT iBgBmpWidth)
    {
        HWND        hSplashWnd = NULL;
        MSG            stMsg;
        WNDCLASSEX  stWndClassEx;
        TCHAR        szClassName[] = TEXT("LeXX_Splash_Wnd");
        HCURSOR        hMouseCursor =NULL;
        HBRUSH        hBgBrush = NULL;
        HBITMAP        hBgBmp = LoadBitmap(hInstance,    MAKEINTRESOURCE(IDB_SPLASH));    if (hBgBmp == NULL) {
            // 出错处理
            // 导出位图出错
            return 0;        
        }
        
        hBgBrush = CreatePatternBrush(hBgBmp);
        if (hBgBrush == NULL) {
            // 出错处理
            // 创建画刷出错
            return 0;
        }
        hMouseCursor = LoadCursor(NULL, IDC_ARROW);
        if (hMouseCursor == NULL) {
            // 出错处理
            // 导出光标错误
            return 0;        
        }
        
        stWndClassEx.cbSize            =  sizeof(WNDCLASSEX);
        stWndClassEx.style            = CS_HREDRAW | CS_VREDRAW;
        stWndClassEx.lpfnWndProc    = SplashProc;
        stWndClassEx.cbClsExtra        = NULL;
        stWndClassEx.cbWndExtra        = NULL;
        stWndClassEx.hInstance        = hInstance;
        stWndClassEx.hbrBackground    = hBgBrush;
        stWndClassEx.lpszMenuName    = NULL;
        stWndClassEx.lpszClassName    = szClassName;
        stWndClassEx.hIcon            = NULL;
        stWndClassEx.hIconSm        = NULL;
        stWndClassEx.hCursor        = hMouseCursor;    if (!RegisterClassEx(&stWndClassEx)) {
            // 出错处理
            // 无法注册窗口类                
            return 0;
        }
        
        // 使启动画面加载在屏幕正中
        int iWndLeft = (GetSystemMetrics(SM_CXSCREEN) - iBgBmpWidth) / 2;
        int iWndTop = (GetSystemMetrics(SM_CYSCREEN) - iBgBmpHeight) / 2;
        
        hSplashWnd = CreateWindowEx(WS_EX_LEFT, szClassName, TEXT("Loading..."),
                                    WS_POPUP, iWndLeft, iWndTop, iBgBmpWidth, iBgBmpHeight,
                                    NULL,NULL,hInstance,NULL);
        if (hSplashWnd == NULL) {
            // 出错处理
            // 无法创建窗口                
            return 0;
        }
        ShowWindow(hSplashWnd, SW_SHOWNORMAL);
        UpdateWindow(hSplashWnd);
        
        // 消息循环
        while (GetMessage(&stMsg, NULL, 0, 0)) {
            TranslateMessage(&stMsg);
              DispatchMessage(&stMsg);
        }    return stMsg.wParam;
    }LRESULT CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg) {
            case WM_CREATE:
                // 定时器
                iTimeID = SetTimer(hWnd, 1, WAIT_TIME,NULL);
                return 0;        case WM_TIMER:
                KillTimer(hWnd, iTimeID);
                DestroyWindow(hWnd);            
                return 0;        case WM_DESTROY:
                PostQuitMessage(NULL);
                return 0;            
        }
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    最后修改注册表文件,追加 BHO 的注册信息。在工程目录中有一个 .rgs文件是用来保存注册信息的,在里面增加如下代码(注意其中 {EA1EFEA2-1051-4384-A81E-74DE2167EEDF} 只是笔者的 CLSID ,自己写时需做相应的改变):
    HKLM
    {
        SOFTWARE
        {
            Microsoft
            {
                Windows
                {
                    CurrentVersion
                    {
                        Explorer
                        {
                            'Browser Helper Objects'
                            {
                                {EA1EFEA2-1051-4384-A81E-74DE2167EEDF}
                            }
                        }
                    }
                }
            }
        }
    }资源文件比较简单就不列出来了,全部代码在 Win 2K 下编译,并正常运行。
    此例中只用到了 BHO 的一小部分功能,BHO 还可以用来侦测 IE 的一些事件,如用户在地址栏中输了一串字符。想了解的话可以参考一下 MSDN 上的相关文章。