标题: 用C语言实现IBindStatusCallback接口
作者: Demon
链接: https://demon.tw/programming/c-ibindstatuscallback.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
昨天在Google关键字“URLDownloadToFile IBindStatusCallback”的时候,看到了看雪论坛上一个名为《在C中怎么使用IBindStatusCallback接口里的方法》的帖子。有人给出了C++的实现,有人留了一句“这样比较麻烦,但是可以实现”,却没有代码。
如果说Linux是C的天下,那么Windows就是C++的天下了。曾经有人问我,在Windows下C++比C方便得多,你为什么偏要用C?我回答,不为什么,因为我喜欢。
和COM开发有关的C语言资料真的很少,但并不是没有,Jeff Glatt的神作《COM in plain C》是最好的资料。把《COM in plain C》看完,实现IBindStatusCallback接口只是小菜一碟。
简单起见,只实现了最常用的OnProgress方法,并且是黑乎乎的控制台程序。只要把原理弄清楚,写一个简单的带进度条的GUI下载器也不是难事。
/*********************************** Author : Demon Website : https://demon.tw E-mail : 380401911@qq.com ***********************************/ #include <stdio.h> #include <urlmon.h> #pragma comment (lib, "urlmon.lib") HRESULT ( STDMETHODCALLTYPE QueryInterface )( IBindStatusCallback * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject) { return E_NOTIMPL; } ULONG ( STDMETHODCALLTYPE AddRef )( IBindStatusCallback * This) { return E_NOTIMPL; } ULONG ( STDMETHODCALLTYPE Release )( IBindStatusCallback * This) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE OnStartBinding )( IBindStatusCallback * This, /* [in] */ DWORD dwReserved, /* [in] */ IBinding *pib) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE GetPriority )( IBindStatusCallback * This, /* [out] */ LONG *pnPriority) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE OnLowResource )( IBindStatusCallback * This, /* [in] */ DWORD reserved) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE OnProgress )( IBindStatusCallback * This, /* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR szStatusText) { if (ulProgress > 0) { printf("Downloaded %d of %d bytes\n", ulProgress, ulProgressMax); fflush(stdout); } return S_OK; } HRESULT ( STDMETHODCALLTYPE OnStopBinding )( IBindStatusCallback * This, /* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE GetBindInfo )( IBindStatusCallback * This, /* [out] */ DWORD *grfBINDF, /* [unique][out][in] */ BINDINFO *pbindinfo) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE OnDataAvailable )( IBindStatusCallback * This, /* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC *pformatetc, /* [in] */ STGMEDIUM *pstgmed) { return E_NOTIMPL; } HRESULT ( STDMETHODCALLTYPE OnObjectAvailable )( IBindStatusCallback * This, /* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown *punk) { return E_NOTIMPL; } static const IBindStatusCallbackVtbl IBindStatusCallback_Vtbl = { QueryInterface, AddRef, Release, OnStartBinding, GetPriority, OnLowResource, OnProgress, OnStopBinding, GetBindInfo, OnDataAvailable, OnObjectAvailable }; int main(int argc, char *argv[]) { HRESULT hr; IBindStatusCallback MyCallback; MyCallback.lpVtbl = (IBindStatusCallbackVtbl *)&IBindStatusCallback_Vtbl; hr = URLDownloadToFile(NULL, "https://demon.tw/download/VbsEdit.zip", "VbsEdit.zip", 0, &MyCallback); if (FAILED(hr)) { printf("Error: %X\n", hr); } return 0; }
两年前的帖子了,不知道发帖那位朋友看不看得到。也许,他现在已经不写代码了吧。两年后的我呢?
赞赏微信赞赏支付宝赞赏
随机文章: