本文配套程序下载地址为: http://pan.baidu.com/share/link?shareid=358034&uk=3995556177
因为界面元素很少,所以界面开发很简单。现在讲业务逻辑。
整个逻辑分为下载逻辑和安装逻辑,还有UI逻辑。下载逻辑很麻烦。为什么呢?因为我没有自己的服务器。幸好有百度网盘,可以有共享外链。所以我要先将镜像文件放到百度网盘上,然后分享。在软件里面嵌入一个webbrowser,下载的时候先打开那个百度共享地址,然后在这个页面点击下载链接(直接下载这个地址会失败),最后获取一个下载地址,这个地址才是真正的下载地址。麻烦啊。如果有一个服务器可以直接下载文件多好啊。
问题来了,mfc里有webbrowser控件,但我使用的256版duilib没有。不过在网上找到一个,改来改去,好不容易可用了。又碰到了弹出javascript错误框的问题。前天才知道,原来duilib一直在更新,现在已经有webbrowser控件了。吐血啊... 既然duilib已经有这个控件了,我就不说了,直接贴解决如何消除javascript错误框和获取下载地址的代码
STDMETHODIMP CWebBrowserBase::Exec( const GUID* pguidCmdGroup, DWORD nCmdID,
DWORD nCmdexecopt, VARIANTARG* pvaIn, VARIANTARG* pvaOut )
{
HRESULT hr = S_OK;
if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
{
switch (nCmdID)
{
case OLECMDID_SHOWSCRIPTERROR:
{
IHTMLDocument2* pDoc = NULL;
IHTMLWindow2* pWindow = NULL;
IHTMLEventObj* pEventObj = NULL;
BSTR rgwszNames[5] =
{
SysAllocString(L"errorLine"),
SysAllocString(L"errorCharacter"),
SysAllocString(L"errorCode"),
SysAllocString(L"errorMessage"),
SysAllocString(L"errorUrl")
};
DISPID rgDispIDs[5];
VARIANT rgvaEventInfo[5];
DISPPARAMS params;
BOOL fContinueRunningScripts = true;
int i;
params.cArgs = 0;
params.cNamedArgs = 0;
// Get the document that is currently being viewed.
hr = pvaIn->punkVal->QueryInterface(IID_IHTMLDocument2, (void **) &pDoc);
// Get document.parentWindow.
hr = pDoc->get_parentWindow(&pWindow);
pDoc->Release();
// Get the window.event object.
hr = pWindow->get_event(&pEventObj);
// Get the error info from the window.event object.
for (i = 0; i < 5; i++)
{
// Get the property's dispID.
hr = pEventObj->GetIDsOfNames(IID_NULL, &rgwszNames[i], 1,
LOCALE_SYSTEM_DEFAULT, &rgDispIDs[i]);
// Get the value of the property.
hr = pEventObj->Invoke(rgDispIDs[i], IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET, ¶ms, &rgvaEventInfo[i],
NULL, NULL);
SysFreeString(rgwszNames[i]);
}
// At this point, you would normally alert the user with
// the information about the error, which is now contained
// in rgvaEventInfo[]. Or, you could just exit silently.
(*pvaOut).vt = VT_BOOL;
if (fContinueRunningScripts)
{
// Continue running scripts on the page.
(*pvaOut).boolVal = VARIANT_TRUE;
}
else
{
// Stop running scripts on the page.
(*pvaOut).boolVal = VARIANT_FALSE;
}
hr = S_OK;
break;
}
default:
hr = OLECMDERR_E_NOTSUPPORTED;
break;
}
}
else
{
hr = OLECMDERR_E_UNKNOWNGROUP;
}
return (hr);
}
HRESULT STDMETHODCALLTYPE CWebBrowserBase::Download(IMoniker *pmk,
IBindCtx *pbc,
DWORD dwBindVerb,
LONG grfBINDF,
BINDINFO *pBindInfo,
LPCOLESTR pszHeaders,
LPCOLESTR pszRedir,
UINT uiCP)
{
HRESULT hr = S_FALSE;
LPOLESTR sURL = NULL;
if(pmk)
hr = pmk->GetDisplayName(pbc, NULL, &sURL);
static CString s_url;
CString tmp = sURL;
if (s_url != tmp)
{
g_status = EAZ_DOWNLOAD;
s_url = tmp;
}
//When working with sURL, use CComBSTR strUrl(sURL)
//Otherwise, you may end up with a huge mem leak?
//Free string as stated in MSDN
//Get IMalloc interface
IMalloc *pMalloc;
if(CoGetMalloc((DWORD)1, &pMalloc) == S_OK)
{
pMalloc->Free((LPVOID)sURL);
}
else
CoTaskMemFree((LPVOID)sURL);
return S_OK;
}