dispatch.h

Go to the documentation of this file.
00001 00005 /* 00006 * Copyright © 2001 Sofus Mortensen 00007 * 00008 * This material is provided "as is", with absolutely no warranty 00009 * expressed or implied. Any use is at your own risk. Permission to 00010 * use or copy this software for any purpose is hereby granted without 00011 * fee, provided the above notices are retained on all copies. 00012 * Permission to modify the code and to distribute modified code is 00013 * granted, provided the above notices are retained, and a notice that 00014 * the code was modified is included with the above copyright notice. 00015 * 00016 * This header is part of comet. 00017 * http://www.lambdasoft.dk/comet 00018 */ 00019 00020 #ifndef COMET_DISPATCH_H 00021 #define COMET_DISPATCH_H 00022 00023 #include <comet/ptr.h> 00024 00025 #include <map> 00026 00027 namespace comet { 00031 00042 template<> struct wrap_t<::IDispatch> 00043 { 00046 variant_t get(DISPID id) 00047 { 00048 VARIANT result; 00049 VARIANT* vars = 0; 00050 DISPPARAMS disp = { vars, 0, 0, 0 }; 00051 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0); 00052 if (FAILED(hr)) throw_com_error(raw(this), hr); 00053 return auto_attach(result); 00054 } 00055 00058 variant_t get(const wchar_t* name) 00059 { 00060 DISPID id; 00061 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00062 if (FAILED(hr)) throw_com_error(raw(this), hr); 00063 return get(id); 00064 } 00065 00068 variant_t get(DISPID id, const variant_t& a0) 00069 { 00070 VARIANT result; 00071 VARIANT vars[1]; vars[0] = a0.in(); 00072 DISPPARAMS disp = { vars, 0, 1, 0 }; 00073 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0); 00074 if (FAILED(hr)) throw_com_error(raw(this), hr); 00075 return auto_attach(result); 00076 } 00077 00080 variant_t get(const wchar_t* name, const variant_t& a0) 00081 { 00082 DISPID id; 00083 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00084 if (FAILED(hr)) throw_com_error(raw(this), hr); 00085 return get(id, a0); 00086 } 00087 00090 variant_t get(DISPID id, const variant_t& a1, const variant_t& a0) 00091 { 00092 VARIANT result; 00093 VARIANT vars[2]; vars[0] = a0.in(); vars[1] = a1.in(); 00094 DISPPARAMS disp = { vars, 0, 2, 0 }; 00095 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0); 00096 if (FAILED(hr)) throw_com_error(raw(this), hr); 00097 return auto_attach(result); 00098 } 00099 00102 variant_t get(const wchar_t* name, const variant_t& a1, const variant_t& a0) 00103 { 00104 DISPID id; 00105 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00106 if (FAILED(hr)) throw_com_error(raw(this), hr); 00107 return get(id, a1, a0); 00108 } 00109 00112 variant_t get(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00113 { 00114 VARIANT result; 00115 VARIANT vars[3]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in(); 00116 DISPPARAMS disp = { vars, 0, 3, 0 }; 00117 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0); 00118 if (FAILED(hr)) throw_com_error(raw(this), hr); 00119 return auto_attach(result); 00120 } 00121 00124 variant_t get(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00125 { 00126 DISPID id; 00127 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00128 if (FAILED(hr)) throw_com_error(raw(this), hr); 00129 return get(id, a2, a1, a0); 00130 } 00131 00134 void put(DISPID id, const variant_t& val) 00135 { 00136 VARIANT vars[1]; vars[0] = val.in(); 00137 DISPID did = DISPID_PROPERTYPUT; 00138 DISPPARAMS disp = { vars, &did, 1, 1 }; 00139 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0); 00140 if (FAILED(hr)) throw_com_error(raw(this), hr); 00141 } 00142 00145 void put(const wchar_t* name, const variant_t& val) 00146 { 00147 DISPID id; 00148 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00149 if (FAILED(hr)) throw_com_error(raw(this), hr); 00150 put(id, val); 00151 } 00152 00155 void put(DISPID id, const variant_t& a1, const variant_t& val) 00156 { 00157 VARIANT vars[2]; vars[0] = val.in(); vars[1] = a1.in(); 00158 DISPID did = DISPID_PROPERTYPUT; 00159 DISPPARAMS disp = { vars, &did, 2, 1 }; 00160 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0); 00161 if (FAILED(hr)) throw_com_error(raw(this), hr); 00162 } 00163 00166 void put(const wchar_t* name, const variant_t& a1, const variant_t& val) 00167 { 00168 DISPID id; 00169 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00170 if (FAILED(hr)) throw_com_error(raw(this), hr); 00171 put(id, a1, val); 00172 } 00173 00174 00177 void put(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& val) 00178 { 00179 VARIANT vars[3]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); 00180 DISPID did = DISPID_PROPERTYPUT; 00181 DISPPARAMS disp = { vars, &did, 3, 1 }; 00182 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0); 00183 if (FAILED(hr)) throw_com_error(raw(this), hr); 00184 } 00185 00188 void put(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& val) 00189 { 00190 DISPID id; 00191 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00192 if (FAILED(hr)) throw_com_error(raw(this), hr); 00193 put(id, a2, a1, val); 00194 } 00195 00198 void put(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val) 00199 { 00200 VARIANT vars[4]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in(); 00201 DISPID did = DISPID_PROPERTYPUT; 00202 DISPPARAMS disp = { vars, &did, 4, 1 }; 00203 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0); 00204 if (FAILED(hr)) throw_com_error(raw(this), hr); 00205 } 00206 00209 void put(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val) 00210 { 00211 DISPID id; 00212 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00213 if (FAILED(hr)) throw_com_error(raw(this), hr); 00214 put(id, a3, a2, a1, val); 00215 } 00216 00219 void putref(DISPID id, const variant_t& val) 00220 { 00221 VARIANT vars[1]; vars[0] = val.in(); 00222 DISPID did = DISPID_PROPERTYPUT; 00223 DISPPARAMS disp = { vars, &did, 1, 1 }; 00224 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0); 00225 if (FAILED(hr)) throw_com_error(raw(this), hr); 00226 } 00227 00230 void putref(const wchar_t* name, const variant_t& val) 00231 { 00232 DISPID id; 00233 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00234 if (FAILED(hr)) throw_com_error(raw(this), hr); 00235 putref(id, val); 00236 } 00237 00238 void putref(DISPID id, const variant_t& a1, const variant_t& val) 00239 { 00240 VARIANT vars[2]; vars[0] = val.in(); vars[1] = a1.in(); 00241 DISPID did = DISPID_PROPERTYPUT; 00242 DISPPARAMS disp = { vars, &did, 2, 1 }; 00243 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0); 00244 if (FAILED(hr)) throw_com_error(raw(this), hr); 00245 } 00246 00247 void putref(const wchar_t* name, const variant_t& a1, const variant_t& val) 00248 { 00249 DISPID id; 00250 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00251 if (FAILED(hr)) throw_com_error(raw(this), hr); 00252 putref(id, a1, val); 00253 } 00254 00255 void putref(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& val) 00256 { 00257 VARIANT vars[3]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); 00258 DISPID did = DISPID_PROPERTYPUT; 00259 DISPPARAMS disp = { vars, &did, 3, 1 }; 00260 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0); 00261 if (FAILED(hr)) throw_com_error(raw(this), hr); 00262 } 00263 00264 void putref(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& val) 00265 { 00266 DISPID id; 00267 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00268 if (FAILED(hr)) throw_com_error(raw(this), hr); 00269 putref(id, a2, a1, val); 00270 } 00271 00272 void putref(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val) 00273 { 00274 VARIANT vars[4]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in(); 00275 DISPID did = DISPID_PROPERTYPUT; 00276 DISPPARAMS disp = { vars, &did, 4, 1 }; 00277 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0); 00278 if (FAILED(hr)) throw_com_error(raw(this), hr); 00279 } 00280 00281 void putref(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val) 00282 { 00283 DISPID id; 00284 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00285 if (FAILED(hr)) throw_com_error(raw(this), hr); 00286 putref(id, a3, a2, a1, val); 00287 } 00288 00291 variant_t call(DISPID id) 00292 { 00293 VARIANT result; 00294 VARIANT* vars = 0; 00295 DISPPARAMS disp = { vars, 0, 0, 0 }; 00296 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0); 00297 if (FAILED(hr)) throw_com_error(raw(this), hr); 00298 return auto_attach(result); 00299 } 00300 00303 variant_t call(const wchar_t* name) 00304 { 00305 DISPID id; 00306 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00307 if (FAILED(hr)) throw_com_error(raw(this), hr); 00308 return call(id); 00309 } 00310 00311 variant_t call(DISPID id, const variant_t& a0) 00312 { 00313 VARIANT result; 00314 VARIANT vars[1]; vars[0] = a0.in(); 00315 DISPPARAMS disp = { vars, 0, 1, 0 }; 00316 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0); 00317 if (FAILED(hr)) throw_com_error(raw(this), hr); 00318 return auto_attach(result); 00319 } 00320 00321 variant_t call(const wchar_t* name, const variant_t& a0) 00322 { 00323 DISPID id; 00324 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00325 if (FAILED(hr)) throw_com_error(raw(this), hr); 00326 return call(id, a0); 00327 } 00328 00329 variant_t call(DISPID id, const variant_t& a1, const variant_t& a0) 00330 { 00331 VARIANT result; 00332 VARIANT vars[2]; vars[0] = a0.in(); vars[1] = a1.in(); 00333 DISPPARAMS disp = { vars, 0, 2, 0 }; 00334 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0); 00335 if (FAILED(hr)) throw_com_error(raw(this), hr); 00336 return auto_attach(result); 00337 } 00338 00339 variant_t call(const wchar_t* name, const variant_t& a1, const variant_t& a0) 00340 { 00341 DISPID id; 00342 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00343 if (FAILED(hr)) throw_com_error(raw(this), hr); 00344 return call(id, a1, a0); 00345 } 00346 00347 variant_t call(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00348 { 00349 VARIANT result; 00350 VARIANT vars[3]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in(); 00351 DISPPARAMS disp = { vars, 0, 3, 0 }; 00352 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0); 00353 if (FAILED(hr)) throw_com_error(raw(this), hr); 00354 return auto_attach(result); 00355 } 00356 00357 variant_t call(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00358 { 00359 DISPID id; 00360 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00361 if (FAILED(hr)) throw_com_error(raw(this), hr); 00362 return call(id, a2, a1, a0); 00363 } 00364 00365 variant_t call(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00366 { 00367 VARIANT result; 00368 VARIANT vars[4]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in(); 00369 DISPPARAMS disp = { vars, 0, 4, 0 }; 00370 HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0); 00371 if (FAILED(hr)) throw_com_error(raw(this), hr); 00372 return auto_attach(result); 00373 } 00374 00375 variant_t call(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0) 00376 { 00377 DISPID id; 00378 HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id); 00379 if (FAILED(hr)) throw_com_error(raw(this), hr); 00380 return call(id, a3, a2, a1, a0); 00381 } 00382 }; 00390 template<typename BASE> class ATL_NO_VTABLE dynamic_dispatch : public ::IDispatch { 00391 00392 struct method_ptr { 00393 bool has_retval; 00394 union { 00395 void (BASE::*pm00)(); 00396 void (BASE::*pm01)(const variant_t&); 00397 void (BASE::*pm02)(const variant_t&, const variant_t&); 00398 void (BASE::*pm03)(const variant_t&, const variant_t&, const variant_t&); 00399 void (BASE::*pm04)(const variant_t&, const variant_t&, const variant_t&, const variant_t&); 00400 00401 variant_t (BASE::*pm10)(); 00402 variant_t (BASE::*pm11)(const variant_t&); 00403 variant_t (BASE::*pm12)(const variant_t&, const variant_t&); 00404 variant_t (BASE::*pm13)(const variant_t&, const variant_t&, const variant_t&); 00405 variant_t (BASE::*pm14)(const variant_t&, const variant_t&, const variant_t&, const variant_t&); 00406 }; 00407 }; 00408 00409 typedef std::map<std::wstring, DISPID> NAMEMAP; 00410 NAMEMAP name_map_; 00411 00412 // Workaround VC internal compiler error 00413 struct wrap_map_t { 00414 std::map<unsigned, method_ptr> m; 00415 }; 00416 typedef std::map<DISPID, wrap_map_t > MAP; 00417 MAP map_; 00418 00419 void add_method(const wchar_t* name, method_ptr p, DISPID id, int type) 00420 { 00421 if (id == flag_value) 00422 { 00423 NAMEMAP::const_iterator it = name_map_.find(name); 00424 if (it == name_map_.end()) 00425 { 00426 id = 100000 + map_.size(); 00427 while (map_.find(id) != map_.end()) ++id; 00428 } 00429 else 00430 { 00431 id = it->second; 00432 } 00433 } 00434 00435 name_map_[name] = id; 00436 map_[id].m[type] = p; 00437 } 00438 enum { flag_value = MINLONG }; 00439 public: 00440 typedef ::IDispatch interface_is; 00441 00442 protected: 00443 00444 void remove(const wchar_t* name) 00445 { 00446 NAMEMAP::iterator it = name_map_.find(name); 00447 if (it != name_map_.end()) { 00448 DISPID id = *it; 00449 name_map_.erase(it); 00450 00451 map_.erase(id); 00452 } 00453 } 00454 00455 void add_method(const wchar_t* name, void (BASE::*pm)(), DISPID id = flag_value) 00456 { method_ptr p; p.has_retval = false; p.pm00 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_METHOD ); } 00457 00458 void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value) 00459 { method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_METHOD ); } 00460 00461 void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value) 00462 { method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_METHOD ); } 00463 00464 void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00465 { method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_METHOD ); } 00466 00467 void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00468 { method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_METHOD ); } 00469 00470 void add_method(const wchar_t* name, variant_t (BASE::*pm)(), DISPID id = flag_value) 00471 { method_ptr p; p.has_retval = true; p.pm10 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_METHOD ); } 00472 00473 void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&), DISPID id = flag_value) 00474 { method_ptr p; p.has_retval = true; p.pm11 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_METHOD ); } 00475 00476 void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value) 00477 { method_ptr p; p.has_retval = true; p.pm12 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_METHOD ); } 00478 00479 void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00480 { method_ptr p; p.has_retval = true; p.pm13 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_METHOD ); } 00481 00482 void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00483 { method_ptr p; p.has_retval = true; p.pm14 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_METHOD ); } 00484 00485 void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value) 00486 { method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYPUT ); } 00487 00488 void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value) 00489 { method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYPUT ); } 00490 00491 void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00492 { method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYPUT ); } 00493 00494 void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00495 { method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYPUT ); } 00496 00497 void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value) 00498 { method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYPUTREF ); } 00499 00500 void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value) 00501 { method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYPUTREF ); } 00502 00503 void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00504 { method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYPUTREF ); } 00505 00506 void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00507 { method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYPUTREF ); } 00508 00509 void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(), DISPID id = flag_value) 00510 { method_ptr p; p.has_retval = true; p.pm10 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_PROPERTYGET ); } 00511 00512 void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&), DISPID id = flag_value) 00513 { method_ptr p; p.has_retval = true; p.pm11 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYGET ); } 00514 00515 void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value) 00516 { method_ptr p; p.has_retval = true; p.pm12 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYGET ); } 00517 00518 void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00519 { method_ptr p; p.has_retval = true; p.pm13 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYGET ); } 00520 00521 void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value) 00522 { method_ptr p; p.has_retval = true; p.pm14 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYGET ); } 00523 00524 private: 00525 STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pd, VARIANT* pVarResult, EXCEPINFO* pe, UINT* pu) 00526 { 00527 unsigned type = pd->cArgs << 16 | (wFlags & 15); 00528 MAP::const_iterator it2 = map_.find(id); 00529 if (it2 == map_.end()) return DISP_E_MEMBERNOTFOUND; 00530 00531 std::map<unsigned, method_ptr>::const_iterator it = it2->second.m.find(type); 00532 if (it == it2->second.m.end()) return DISP_E_BADPARAMCOUNT; 00533 00534 try { 00535 00536 if (pd->cNamedArgs > 1) return DISP_E_NONAMEDARGS; 00537 00538 if (pd->cNamedArgs == 1) { 00539 00540 if ((wFlags & 15) != DISPATCH_PROPERTYPUT && (wFlags & 15) != DISPATCH_PROPERTYPUTREF) return DISP_E_NONAMEDARGS; 00541 if (pd->rgdispidNamedArgs[0] != DISPID_PROPERTYPUT) return DISP_E_NONAMEDARGS; 00542 00543 switch (pd->cArgs) 00544 { 00545 case 1: 00546 (static_cast<BASE*>(this)->*it->second.pm01)(variant_t::create_reference(pd->rgvarg[0])); 00547 break; 00548 case 2: 00549 (static_cast<BASE*>(this)->*it->second.pm02)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00550 break; 00551 case 3: 00552 (static_cast<BASE*>(this)->*it->second.pm03)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00553 break; 00554 case 4: 00555 (static_cast<BASE*>(this)->*it->second.pm04)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00556 break; 00557 default: 00558 return DISP_E_MEMBERNOTFOUND; 00559 } 00560 00561 } 00562 else 00563 { 00564 00565 variant_t rv; 00566 if (it->second.has_retval) 00567 { 00568 switch (pd->cArgs) 00569 { 00570 case 0: 00571 rv = (static_cast<BASE*>(this)->*it->second.pm10)(); 00572 break; 00573 case 1: 00574 rv = (static_cast<BASE*>(this)->*it->second.pm11)(variant_t::create_reference(pd->rgvarg[0])); 00575 break; 00576 case 2: 00577 rv = (static_cast<BASE*>(this)->*it->second.pm12)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00578 break; 00579 case 3: 00580 rv = (static_cast<BASE*>(this)->*it->second.pm13)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[1])); 00581 break; 00582 case 4: 00583 rv = (static_cast<BASE*>(this)->*it->second.pm14)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[0])); 00584 break; 00585 default: 00586 return DISP_E_MEMBERNOTFOUND; 00587 } 00588 } 00589 else 00590 { 00591 switch (pd->cArgs) 00592 { 00593 case 0: 00594 (static_cast<BASE*>(this)->*it->second.pm00)(); 00595 break; 00596 case 1: 00597 (static_cast<BASE*>(this)->*it->second.pm01)(variant_t::create_reference(pd->rgvarg[0])); 00598 break; 00599 case 2: 00600 (static_cast<BASE*>(this)->*it->second.pm02)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00601 break; 00602 case 3: 00603 (static_cast<BASE*>(this)->*it->second.pm03)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00604 break; 00605 case 4: 00606 (static_cast<BASE*>(this)->*it->second.pm04)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0])); 00607 break; 00608 default: 00609 return DISP_E_MEMBERNOTFOUND; 00610 } 00611 } 00612 if (pVarResult) *pVarResult = rv.detach(); 00613 } 00614 00615 00616 } catch (com_error& err) { 00617 return impl::return_com_error(err); 00618 } catch (const std::exception& err) { 00619 return impl::return_com_error(err); 00620 } catch (HRESULT hr) { 00621 return hr; 00622 } catch (...) { 00623 return E_FAIL; 00624 } 00625 00626 return S_OK; 00627 00628 } 00629 00630 STDMETHOD(GetIDsOfNames)(REFIID, WCHAR** names, unsigned int c, LCID, DISPID* dispid) 00631 { 00632 bool failed = false; 00633 for (size_t i=0; i<c; ++i) 00634 { 00635 NAMEMAP::const_iterator it = name_map_.find(names[i]); 00636 if (it == name_map_.end()) 00637 { 00638 failed = true; 00639 dispid[i] = DISPID_UNKNOWN; 00640 } 00641 else 00642 { 00643 dispid[i] = it->second; 00644 } 00645 } 00646 return failed ? DISP_E_UNKNOWNNAME : S_OK; 00647 } 00648 00649 STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) 00650 { return E_NOTIMPL; } 00651 00652 STDMETHOD(GetTypeInfoCount)(UINT *it) 00653 { *it = 0; return S_OK; } 00654 00655 }; 00657 } 00658 00659 #endif