Win32实现网页本地播放(嵌入IE浏览器WebBrowser)

xingyun86 2018-4-19 1697


#include <io.h>
#include <atlbase.h>

/////////////////////////////////////////////////////////////////////////
//如果使用的是VC6.0,请打开此注释
//CComModule _Module;
//extern CComModule _Module;
//#include <exdisp.h>
#include <atlwin.h>
#include <windows.h>

//////////////////////////////////////////////////////////////////////////
//    全局宏定义声明区域
//////////////////////////////////////////////////////////////////////////
#define ZERO_VALUE 0x00
#define BASE_VALUE 0x100
#define MAXS_VALUE 0x400

#define BASE_STRING BASE_VALUE
#define MAXS_STRING MAXS_VALUE
#define MAX_URL_NUM MAXS_VALUE

#define IDC_TIMER_EVENT BASE_VALUE + 1

#define AX_WINDOWS_CONTAINER_NAME OLESTR("shell.Explorer.2")

#pragma comment(lib,  "atl")
#pragma comment(lib,  "user32")

typedef struct __UrlArrayList{
    long volume; //当前容量
    long size; //当前数量
    long index; //当前播放
    TCHAR ** pszUrlNameList;
}UrlArrayList, *PUrlArrayList;

//////////////////////////////////////////////////////////////////////////
//    全局变量声明区域
//////////////////////////////////////////////////////////////////////////
UrlArrayList * g_pUrlArrayList = 0; //Url名字列表
IWebBrowser2 * g_pIWebBrowser = 0;//IWebBrowser2句柄

//////////////////////////////////////////////////////////////////////////
//    函数声明区域
//////////////////////////////////////////////////////////////////////////
//    查找并替换函数
int FindAndReplace(TCHAR * tFileName, TCHAR * tSrcStr, TCHAR * tDstStr);
//    初始化Url列表    
int InitilizeUrlArrayList(TCHAR * pszFileName, UrlArrayList ** pszUrlArrayList);
//    Url列表内存释放
void FinallizeArrayList(UrlArrayList ** pszUrlArrayList);
//    显示网页内容
void DisplayWebContent(IWebBrowser2 ** ppWebBrowser, TCHAR * szUrlName);
//    主窗口回调函数
LRESULT CALLBACK WindProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//    程序主函数
int WINAPI WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance,  LPSTR lpCmdLine,  int nShowCmd);


//////////////////////////////////////////////////////////////////////////
//    全局函数定义区域
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//    查找并替换函数
int FindAndReplace(TCHAR * tFileName, TCHAR * tSrcStr, TCHAR * tDstStr)
{
    FILE * l_pFile = 0;
    long l_lSrcStrLen = lstrlen(tSrcStr);
    long l_lDstStrlen = lstrlen(tDstStr);
    long l_FileLength = 0;
    TCHAR * l_pWebContent = 0;
    size_t l_stNumberofRead = 0;
    size_t l_stNumberofWrite = 0;
    long l_lIndexId = 0;

    if (l_lSrcStrLen <= 0 || l_lSrcStrLen <= 0)
    {
        ::MessageBox(NULL, __TEXT("源字符串和目标字符串不能为空!"), __TEXT("错误提示"), MB_ICONERROR);
        return (-1);
    }

    //    打开文件, 以读写的模式
    l_pFile = _tfopen(tFileName, __TEXT("r+b"));
    if (!l_pFile)
    {
        //::MessageBox(NULL, __TEXT("文件打开失败!"), __TEXT("错误提示"), MB_ICONERROR);
        return (-1);
    }

    //    获取文件大小
    l_FileLength = _filelength(_fileno(l_pFile));

    //    根据获取的文件长度分配相应的内存(注意所分配的缓冲区长度应该加一)
    l_pWebContent = (TCHAR *)malloc((l_FileLength + 1) * sizeof(TCHAR));
    if (l_pWebContent == 0)
    {
        ::MessageBox(NULL, __TEXT("内存分配失败!"), __TEXT("错误提示"), MB_ICONERROR);
        return (-1);
    }

    //    读取文件内容
    l_stNumberofRead = fread(l_pWebContent, l_FileLength, 1, l_pFile);
    if (l_stNumberofRead <= 0)
    {
        ::MessageBox(NULL, __TEXT("文件内容读取失败!"), __TEXT("错误提示"), MB_ICONERROR);
        return (-1);
    }

    //    查找并替换指定的内容
    do 
    {
        if (_memicmp(l_pWebContent + l_lIndexId, tSrcStr, l_lSrcStrLen) == 0)
        {
            // 源字符串的长度等于目的字符串长度
            if (l_lSrcStrLen == l_lDstStrlen)
            {
                memcpy(l_pWebContent + l_lIndexId, tDstStr, l_lSrcStrLen);
                l_lIndexId += l_lSrcStrLen;
            }
            // 源字符串的长度大于目的字符串长度
            else if (l_lSrcStrLen > l_lDstStrlen)
            {
                memcpy(l_pWebContent + l_lIndexId, tDstStr, l_lDstStrlen);
                memset(l_pWebContent + l_lIndexId + l_lDstStrlen, ZERO_VALUE, (l_lSrcStrLen - l_lDstStrlen));
                l_lIndexId += l_lSrcStrLen;
            }
            // 源字符串的长度小于目的字符串长度
            else if (l_lSrcStrLen < l_lDstStrlen)
            {
                memcpy(l_pWebContent + l_lIndexId, tDstStr, l_lDstStrlen);
                l_lIndexId += l_lDstStrlen;
            }
        }
        else
        {
            l_lIndexId += 1;
        }
    } while (l_lIndexId < l_FileLength);

    //    复位文件指针到文件首部
    fseek(l_pFile, 0, SEEK_SET);

    //    将指定文件内容写入到内存
    l_stNumberofWrite = fwrite(l_pWebContent, l_FileLength, 1, l_pFile);
    if (l_stNumberofWrite <= 0)
    {
        ::MessageBox(NULL, __TEXT("文件内容写入失败!"), __TEXT("错误提示"), MB_ICONERROR);
        return (-1);
    }

    //    刷新内存写入到磁盘
    fflush(l_pFile);

    //    关闭文件句柄
    fclose(l_pFile);

    return (1);
}

//////////////////////////////////////////////////////////////////////////
//    初始化Url列表    
int InitilizeUrlArrayList(TCHAR * pszFileName, UrlArrayList ** pszUrlArrayList)
{
    TCHAR szBuffer[MAXS_STRING];
    FILE * l_pFile = 0;
    
    //    如果(*pszUrlArrayList)不为空,则先做释放与重新初始化操作
    if ((*pszUrlArrayList) != 0)
    {
        //    执行释放操作
        FinallizeArrayList(pszUrlArrayList);
    }
    
    //    初始化(*pszUrlArrayList)
    *pszUrlArrayList = (UrlArrayList *)malloc(sizeof(UrlArrayList));
    if (*pszUrlArrayList == 0)
    {
        MessageBox(NULL, __TEXT("内存分配失败!"), __TEXT("错误"), MB_ICONERROR);
        return (-1);
    }

    //    初始化pszUrlArrayList结构为空
    memset(*pszUrlArrayList, ZERO_VALUE, sizeof(UrlArrayList));
    (*pszUrlArrayList)->volume = MAX_URL_NUM;

    //    为pszUrlArrayList子项分配内存空间
    (*pszUrlArrayList)->pszUrlNameList = (TCHAR **)malloc((*pszUrlArrayList)->volume * sizeof(UrlArrayList *));
    if ((*pszUrlArrayList)->pszUrlNameList == 0)
    {
        MessageBox(NULL, __TEXT("内存分配失败!"), __TEXT("错误"), MB_ICONERROR);
        return (-1);
    }
    
    //    打开Url列表文件
    l_pFile = _tfopen(pszFileName, __TEXT("rb"));
    if (l_pFile == 0)
    {
        MessageBox(NULL, __TEXT("文件打开失败!"), __TEXT("错误"), MB_ICONERROR);
        return (-1);
    }

    //    将文件内容读入到Url列表结构中
    do
    {
        //    每次读取一行数据
        _fgetts(szBuffer, MAXS_STRING, l_pFile);

        //    为该项分配对应的内存空间
        (*pszUrlArrayList)->pszUrlNameList[(*pszUrlArrayList)->size] = (TCHAR *)malloc((_tcslen(szBuffer) + 1) * sizeof(TCHAR));
        if ((*pszUrlArrayList)->pszUrlNameList[(*pszUrlArrayList)->size] == 0)
        {
            MessageBox(NULL, __TEXT("内存分配失败!"), __TEXT("错误"), MB_ICONERROR);
            return (-1);
        }

        //    将读取的一行内容写入指定的内存,同时维护(*pszUrlArrayList)相应的参数变化
        memset((*pszUrlArrayList)->pszUrlNameList[(*pszUrlArrayList)->size], ZERO_VALUE, _tcslen(szBuffer) + 1);
        lstrcpy((*pszUrlArrayList)->pszUrlNameList[(*pszUrlArrayList)->size], szBuffer);
        (*pszUrlArrayList)->size += 1;
    } while(!feof(l_pFile));
    fclose(l_pFile);

    return (1);
}

//////////////////////////////////////////////////////////////////////////
//    Url列表内存释放
void FinallizeArrayList(UrlArrayList ** pszUrlArrayList)
{
    //    若(*pszUrlArrayList), 则继续执行释放操作
    if ((*pszUrlArrayList) != 0)
    {
        for (int i = 0; i < (*pszUrlArrayList)->size; i++)
        {
            //    若该项不为空,则执行释放操作
            if((*pszUrlArrayList)->pszUrlNameList[i] != 0)
            {
                free((*pszUrlArrayList)->pszUrlNameList[i]);
            }
        }
        free((*pszUrlArrayList));
        (*pszUrlArrayList) = 0;
    }
}

//////////////////////////////////////////////////////////////////////////
//    显示网页内容
void DisplayWebContent(IWebBrowser2 ** ppWebBrowser, TCHAR * szUrlName)
{
    DWORD l_dwResult = 0;
    VARIANT l_varMyURL;
    OLECHAR szOleFullPathName[BASE_STRING];
    TCHAR szFullPathName[BASE_STRING];

    //    获取文件的绝对路径名
    l_dwResult = GetFullPathName(szUrlName, BASE_STRING, szFullPathName, 0);
    if (l_dwResult != 0)
    {

        //    查找替换指定的字符串
        FindAndReplace(szFullPathName, __TEXT("<script"), __TEXT("<!--     "));
        FindAndReplace(szFullPathName, __TEXT("</script>"), __TEXT("      -->"));

#if !defined(UNICODE) || !defined(_UNICODE)
        memset(szOleFullPathName, ZERO_VALUE, BASE_STRING * sizeof(OLECHAR));
        MultiByteToWideChar(CP_ACP, 0, szFullPathName, -1, szOleFullPathName, lstrlen(szFullPathName));
#else
        _tcscpy(szOleFullPathName, szFullPathName);
#endif

        VariantInit(&l_varMyURL);
        l_varMyURL.vt  =  VT_BSTR;
        l_varMyURL.bstrVal  =  SysAllocString(szOleFullPathName);
        (*ppWebBrowser)->Navigate2(&l_varMyURL, 0, 0, 0, 0);
        VariantClear(&l_varMyURL);
    }
}

//////////////////////////////////////////////////////////////////////////
//    主窗口回调函数
LRESULT CALLBACK WindProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    CComModule * _pModule = 0;
    int l_nResult = 0;
    HRESULT hResult = 0;
    CAxWindow WinContainer;
    RECT l_rcClientRect;
    hResult = GetClientRect(hWnd,  &l_rcClientRect);
    if(hResult == 0)
    {
        //MessageBox(NULL, __TEXT("获取客户端区域失败!"), __TEXT("错误"), MB_ICONERROR);
        return    hResult;
    }
    switch(message)
    {
    case WM_CREATE:
        {
            if (_pModule != 0)
            {
                delete _pModule;
                _pModule = 0;
            }
            _pModule = new CComModule();
            if (_pModule != 0)
            {
        //    初始化
//AtlAxWinInit();//VC6.0要添加此初始化
                //    创建容器
                WinContainer.Create(hWnd,  l_rcClientRect,  0, WS_CHILD | WS_VISIBLE);

                //    创建容器控件
                hResult = WinContainer.CreateControl(AX_WINDOWS_CONTAINER_NAME);
                if (hResult != 0)
                {
                    MessageBox(NULL, __TEXT("创建容器控件失败!"), __TEXT("错误"), MB_ICONERROR);
                    return hResult;
                }
                //    获取容器控件可用句柄
                hResult = WinContainer.QueryControl(__uuidof(IWebBrowser2), (void**)&g_pIWebBrowser);
                if (hResult != 0)
                {
                    MessageBox(NULL, __TEXT("获取容器控件可用句柄失败!"), __TEXT("错误"), MB_ICONERROR);
                    return hResult;
                }
                g_pIWebBrowser->put_Silent(TRUE);
                    
                SetTimer(hWnd,             // handle to main window
                    IDC_TIMER_EVENT,            // timer identifier
                    1000,                 // 1.5-second interval
                    (TIMERPROC) NULL);     // no timer callback
            }
        }
        break;
    case WM_TIMER:
        {
            switch (wParam)
            {
            case IDC_TIMER_EVENT:
                {
                    // process the 1.5-second timer
                    DisplayWebContent(&g_pIWebBrowser, g_pUrlArrayList->pszUrlNameList[(g_pUrlArrayList->index ++) % (g_pUrlArrayList->size)]);
                    
                    // 显示到最后一个, 关闭timer事件
                    if (g_pUrlArrayList->size == g_pUrlArrayList->index)
                    {
                        int a = KillTimer(hWnd, IDC_TIMER_EVENT);
                        g_pUrlArrayList->index = 0;
                    }
                }
            }
        }
        break;
    case WM_CLOSE:
        {
            //    对全局变量进行析构释放操作
            
            g_pIWebBrowser->Release();
            if (_pModule != 0)
            {
                delete _pModule;
                _pModule = 0;
            }
            DestroyWindow(hWnd);
            FinallizeArrayList(&g_pUrlArrayList);
        }
        break;
    case WM_DESTROY:
        {
            PostQuitMessage(0);
        }
        break;
    default:
        return (int)DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

//////////////////////////////////////////////////////////////////////////
//    程序主函数
int WINAPI WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance,  LPSTR lpCmdLine,  int nShowCmd)
{

    HWND hWnd;
    MSG msg;
    WNDCLASS wndclass;
    TCHAR szAppName[] = __TEXT("InternetWebExplorer");
    TCHAR szClassName[] = __TEXT("InternetWebExplorer");
//     此处本人意欲获取命令行参数信息,暂时未实现
//     TCHAR ** Argv;
//     int Argc;
//     Argv = CommandLineToArgvW(GetCommandLine(), &Argc);
//     if (Argv == 0)
//     {
//         MessageBox(NULL, __TEXT("Unable to parse command line"), __TEXT("Error"), MB_OK);
//         return 10;
//     }

//     for(int i = 0; i < Argc; i++)
//     {
//         MessageBox(NULL, Argv[i], __TEXT("Arglist contents"), MB_OK);
//     }
//    LocalFree(Argv);

    if(InitilizeUrlArrayList(__TEXT(".\\url.conf"), &g_pUrlArrayList) < 0)
    {
        MessageBox(NULL, __TEXT("Url列表初始化失败!"), __TEXT("错误"), MB_ICONERROR);
        return (-1);
    }

    wndclass.style = CS_HREDRAW |  CS_VREDRAW;
    wndclass.lpfnWndProc = WindProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance,  IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szClassName;

    if(!RegisterClass(&wndclass) && UnregisterClass(szClassName, hInstance) && !RegisterClass(&wndclass))
    {
        MessageBox(NULL, __TEXT("Error!"), szAppName, MB_ICONERROR);
        return (0);
    }

    hWnd = CreateWindow(szClassName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nShowCmd);
    UpdateWindow(hWnd);

    while(GetMessage(&msg,  NULL,  0,  0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)(msg.wParam);
}
运行结果如下:


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回