1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
#include "./cddbevnt.h"
#include "cddbinterface.h"
#include <strsafe.h>
#include <ocidl.h>
#include "cddbcontrolwinamp.tlh"
CDBBEventManager::CDBBEventManager(void) : ref(1), cookie(0), user(0),
fnCmdCompleted(NULL), fnCmdProgress(NULL),
fnLogMessage(NULL), fnServerMessage(NULL)
{
}
CDBBEventManager::~CDBBEventManager(void)
{
}
HRESULT CDBBEventManager::Advise(IUnknown *pCDDBCtrl)
{
HRESULT hr;
IConnectionPoint *pcp;
IConnectionPointContainer *pcpc;
if (cookie) return E_FAIL;
if (!pCDDBCtrl) return E_INVALIDARG;
hr = pCDDBCtrl->QueryInterface(IID_IConnectionPointContainer, (PVOID*)&pcpc);
if (SUCCEEDED (hr))
{
hr = pcpc->FindConnectionPoint(DIID_DCDDBEvents, &pcp);
if (SUCCEEDED(hr))
{
hr = pcp->Advise(static_cast<IDispatch*>(this), &cookie);
if (FAILED(hr)) cookie = 0;
pcp->Release();
}
pcpc->Release();
}
return hr;
}
HRESULT CDBBEventManager::Unadvise(IUnknown *pCDDBCtrl)
{
HRESULT hr;
IConnectionPoint *pcp = nullptr;
IConnectionPointContainer *pcpc = nullptr;
if (!cookie) return S_OK;
if (!pCDDBCtrl) return E_INVALIDARG;
hr = pCDDBCtrl->QueryInterface(IID_IConnectionPointContainer, (PVOID*)&pcpc);
if (SUCCEEDED (hr))
{
hr = pcpc->FindConnectionPoint(DIID_DCDDBEvents, &pcp);
if (SUCCEEDED(hr))
{
hr = pcp->Unadvise(cookie);
pcp->Release();
}
pcpc->Release();
}
return hr;
}
HRESULT CDBBEventManager::RegisterCallback(UINT nType, void *fnCallback)
{
switch(nType)
{
case CDDB_CB_CMDCOMPLETED: fnCmdCompleted = (CDDB_CMDCOMPLETED)fnCallback; break;
case CDDB_CB_CMDPROGRESS: fnCmdProgress = (CDDB_CMDPROGRESS)fnCallback; break;
case CDDB_CB_LOGMSG: fnLogMessage = (CDDB_LOGMSG)fnCallback; break;
case CDDB_CB_SRVMSG: fnServerMessage = (CDDB_SRVMSG)fnCallback; break;
default: return E_INVALIDARG;
}
return S_OK;
}
ULONG_PTR CDBBEventManager::SetUserParam(ULONG_PTR userParam)
{
ULONG_PTR tmp = user;
user = userParam;
return tmp;
}
STDMETHODIMP CDBBEventManager::QueryInterface(REFIID riid, PVOID *ppvObject)
{
if (!ppvObject) return E_POINTER;
if (IsEqualIID(riid, DIID_DCDDBEvents))
*ppvObject = dynamic_cast<CDBBEventManager*>(this);
else if (IsEqualIID(riid, IID_IDispatch))
*ppvObject = dynamic_cast<IDispatch*>(this);
else if (IsEqualIID(riid, IID_IUnknown))
*ppvObject = dynamic_cast<IUnknown*>(this);
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG CDBBEventManager::AddRef(void)
{
return InterlockedIncrement(&ref);
}
ULONG CDBBEventManager::Release(void)
{
if (ref && 0 == InterlockedDecrement(&ref))
{
delete this;
return 0;
}
return ref;
}
STDMETHODIMP CDBBEventManager::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
{
return DISP_E_UNKNOWNNAME;
}
STDMETHODIMP CDBBEventManager::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP CDBBEventManager::GetTypeInfoCount(unsigned int FAR * pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP CDBBEventManager::Invoke(DISPID dispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pDispParams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
{
switch(dispId)
{
case EVENT_COMMAND_COMPLETED:
if (3 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
OnCommandCompleted(pDispParams->rgvarg[2].lVal, pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].pvarVal);
return S_OK;
case EVENT_LOG_MESSAGE:
if (1 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
OnLogMessage(pDispParams->rgvarg[0].bstrVal);
return S_OK;
case EVENT_SERVER_MESSAGE:
if (3 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
OnServerMessage(pDispParams->rgvarg[2].lVal, pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].bstrVal);
return S_OK;
case EVENT_COMMAND_PROGRESS:
if (4 != pDispParams->cArgs) return DISP_E_BADPARAMCOUNT;
OnCommandProgress(pDispParams->rgvarg[3].lVal, pDispParams->rgvarg[2].lVal, pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].lVal);
return S_OK;
}
return DISP_E_MEMBERNOTFOUND;
}
void CDBBEventManager::OnCommandCompleted(LONG lCommandCode, HRESULT hCommandResult, VARIANT *pCommandData)
{
if(fnCmdCompleted) fnCmdCompleted(lCommandCode, hCommandResult, pCommandData, user);
}
void CDBBEventManager::OnLogMessage(BSTR bstrMessage)
{
if(fnLogMessage) fnLogMessage(bstrMessage, user);
}
void CDBBEventManager::OnServerMessage(LONG lMessageCode, LONG lMessageAction, BSTR bstrMessageData)
{
if(fnServerMessage) fnServerMessage(lMessageCode, lMessageAction,bstrMessageData, user);
}
void CDBBEventManager::OnCommandProgress(LONG lCommandCode, LONG lProgressCode, LONG lBytesDone, LONG lBytesTotal)
{
if(fnCmdProgress) fnCmdProgress(lCommandCode, lProgressCode, lBytesDone, lBytesTotal, user);
}
|