| 196 | |
| 197 | |
| 198 | ITypeInfo *GetClassTypeInfo(IUnknown *aUnk) |
| 199 | { |
| 200 | BOOL found = false; |
| 201 | ITypeInfo *ptinfo; |
| 202 | TYPEATTR *typeattr; |
| 203 | |
| 204 | // Find class typeinfo via IProvideClassInfo if available. |
| 205 | // Testing shows this works in some cases where the IDispatch method fails, |
| 206 | // such as for an HTMLDivElement object from an IE11 WebBrowser control. |
| 207 | IProvideClassInfo *ppci; |
| 208 | if (SUCCEEDED(aUnk->QueryInterface<IProvideClassInfo>(&ppci))) |
| 209 | { |
| 210 | found = SUCCEEDED(ppci->GetClassInfo(&ptinfo)); |
| 211 | ppci->Release(); |
| 212 | if (found) |
| 213 | return ptinfo; |
| 214 | } |
| 215 | |
| 216 | // |
| 217 | // Find class typeinfo via IDispatch. |
| 218 | // |
| 219 | IDispatch *pdsp; |
| 220 | ITypeLib *ptlib; |
| 221 | IID iid; |
| 222 | if (SUCCEEDED(aUnk->QueryInterface<IDispatch>(&pdsp))) |
| 223 | { |
| 224 | // Get IID and typelib of this object's IDispatch implementation. |
| 225 | if (SUCCEEDED(pdsp->GetTypeInfo(0, LOCALE_USER_DEFAULT, &ptinfo))) |
| 226 | { |
| 227 | UINT index; |
| 228 | if (SUCCEEDED(ptinfo->GetTypeAttr(&typeattr))) |
| 229 | { |
| 230 | iid = typeattr->guid; |
| 231 | ptinfo->ReleaseTypeAttr(typeattr); |
| 232 | found = SUCCEEDED(ptinfo->GetContainingTypeLib(&ptlib, &index)); |
| 233 | } |
| 234 | ptinfo->Release(); |
| 235 | } |
| 236 | pdsp->Release(); |
| 237 | } |
| 238 | |
| 239 | if (!found) |
| 240 | // No typelib to search through, so give up. |
| 241 | return NULL; |
| 242 | found = false; |
| 243 | |
| 244 | UINT ctinfo = ptlib->GetTypeInfoCount(); |
| 245 | for (UINT i = 0; i < ctinfo; i++) |
| 246 | { |
| 247 | TYPEKIND typekind; |
| 248 | // Consider only classes: |
| 249 | if (FAILED(ptlib->GetTypeInfoType(i, &typekind)) || typekind != TKIND_COCLASS |
| 250 | || FAILED(ptlib->GetTypeInfo(i, &ptinfo))) |
| 251 | continue; |
| 252 | |
| 253 | WORD cImplTypes = 0; |
| 254 | if (SUCCEEDED(ptinfo->GetTypeAttr(&typeattr))) |
| 255 | { |
no test coverage detected