📄 httpdownload.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
//---------------------------------------------------------------------------
#pragma hdrstop
#include <windows.h> // needed before wininet.h
#include <wininet.h> // DeleteUrlCacheEntry
#include "HttpDownload.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
// global thread function
DWORD WINAPI gThreadFunc(void* data)
{
((THttpDownload*)data)->ThreadFunc();
return 0;
}
// public
THttpDownload::THttpDownload(HWND CallbackWindow, int CallbackMessage)
: CallbackWnd(CallbackWindow),
CallbackMsg(CallbackMessage),
RefCount(1),
ThreadHandle(NULL),
State(HttpDownloadNew),
Progress(0),
ProgressMax(0)
{
}
bool THttpDownload::Start(string& NUrl, string& NSavePath)
{
if(State == HttpDownloadActive || State == HttpDownloadCancelling)
return false;
if(ThreadHandle) {
// shouldn't happen
TerminateThread(ThreadHandle, 0);
ThreadHandle = NULL;
}
Url = NUrl;
SavePath = NSavePath;
Progress = 0;
ProgressMax = 0;
SetState(HttpDownloadNew);
// start thread
DWORD ThreadId;
if(!(ThreadHandle = CreateThread(NULL,4096,gThreadFunc,(void*)this,0,&ThreadId)))
return false;
return true;
}
bool THttpDownload::Cancel()
{
if(State != HttpDownloadActive)
return false;
SetState(HttpDownloadCancelling);
return true;
}
// private
THttpDownload::~THttpDownload()
{
if(ThreadHandle)
TerminateThread(ThreadHandle, 0);
}
void THttpDownload::ThreadFunc()
{
// make sure we are still around when the download is over
AddRef();
// notify caller that we're starting
SetState(HttpDownloadActive);
// remove fie from cache
DeleteUrlCacheEntry(Url.c_str());
// start blocking download
if(URLDownloadToFile(NULL,Url.c_str(),SavePath.c_str(),0,
(LPBINDSTATUSCALLBACK)this) == S_OK)
{
// download succeeded
SetState(HttpDownloadCompleted);
} else {
// download failed, remove broken file
::DeleteFile(GetSavePath().c_str());
// notify caller
if(GetState() == HttpDownloadCancelling)
SetState(HttpDownloadCancelled);
else
SetState(HttpDownloadFailed);
}
// remove fie from cache
DeleteUrlCacheEntry(Url.c_str());
ThreadHandle = NULL;
// this may free us
Release();
}
void THttpDownload::SetState(THttpDownloadState NState, bool RaiseCallback)
{
State = NState;
// raise callback
if(RaiseCallback && CallbackWnd)
::SendMessage(CallbackWnd,CallbackMsg,(WPARAM)this,0);
}
// IUnknown interface
STDMETHODIMP THttpDownload::QueryInterface(REFIID riid, void **ppvObject)
{
if(ppvObject == NULL)
return E_INVALIDARG;
if (riid == IID_IBindStatusCallback || riid == IID_IUnknown) {
AddRef();
*ppvObject = this;
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) THttpDownload::AddRef()
{
InterlockedIncrement(&RefCount);
return RefCount;
}
STDMETHODIMP_(ULONG) THttpDownload::Release()
{
InterlockedDecrement(&RefCount);
if (RefCount == 0) {
delete this;
return 0;
}
return RefCount;
}
// IBindStatusCallback interface
STDMETHODIMP THttpDownload::OnProgress(ULONG ulProgress, ULONG ulProgressMax,
ULONG ulStatusCode, LPCWSTR wszStatusText)
{
Progress = ulProgress;
ProgressMax = ulProgressMax;
if(State == HttpDownloadActive && CallbackWnd)
::SendMessage(CallbackWnd,CallbackMsg,(WPARAM)this,0);
// abort download if requested
return (State == HttpDownloadCancelling) ? E_ABORT : S_OK;
}
STDMETHODIMP THttpDownload::OnStartBinding(DWORD dwReserved, IBinding *pib)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::GetPriority(LONG *pnPriority)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::OnLowResource(DWORD reserved)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::OnStopBinding(HRESULT hresult, LPCWSTR szError)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::GetBindInfo(DWORD *grfBINDF, BINDINFO *pbindinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::OnDataAvailable(DWORD grfBSCF, DWORD dwSize,
FORMATETC *pformatetc,
STGMEDIUM *pstgmed)
{
return E_NOTIMPL;
}
STDMETHODIMP THttpDownload::OnObjectAvailable(REFIID riid, IUnknown *punk)
{
return E_NOTIMPL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -