mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Ole moved to archive
git-svn-id: svn://ultimatepp.org/upp/trunk@15668 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
ee6ba69e44
commit
4e60ac4ca3
24 changed files with 3624 additions and 3624 deletions
|
|
@ -11,7 +11,7 @@ file
|
|||
ocx.def;
|
||||
|
||||
custom() "idl",
|
||||
"midl /newtlb $(!/I) /h \"$(DIR)/$(TITLE)_idl.h\" /iid \"$(DIR)/$(TITLE"
|
||||
"midl /newtlb $(!/I) /h \"$(DIR)/$(TITLE)_idl.h\" /iid \"$(DIR)/$(TITLE"
|
||||
")_idl.cpp\" /tlb \"$(DIR)/$(TITLE).tlb\" \"$(PATH)\"\r\n",
|
||||
"$(DIR)/$(TITLE)_idl.h\r\n$(DIR)/$(TITLE).tlb\r\n";
|
||||
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
LIBRARY "test.ocx"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
LIBRARY "test.ocx"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
#include <Ole/Ctrl/OleCtrl.h>
|
||||
|
||||
#ifdef flagMAIN
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
Ctrl::InitWin32(hinstDll);
|
||||
AppInitEnvironment__();
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH: {
|
||||
Ctrl::CloseTopCtrls();
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include <Ole/Ctrl/OleCtrl.h>
|
||||
|
||||
#ifdef flagMAIN
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
Ctrl::InitWin32(hinstDll);
|
||||
AppInitEnvironment__();
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH: {
|
||||
Ctrl::CloseTopCtrls();
|
||||
break;
|
||||
}
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,27 +1,27 @@
|
|||
#ifndef OLE_H
|
||||
#define OLE_H
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE) && defined(COMPILER_MSC)
|
||||
|
||||
#define Ptr Ptr_
|
||||
#define StdFont StdFont_
|
||||
#define Font Font_
|
||||
#define Picture Picture_
|
||||
#define byte win32_byte_ // RpcNdr defines byte -> class with Upp::byte
|
||||
#define CY win32_CY_
|
||||
#include <comdef.h>
|
||||
#include <comip.h>
|
||||
#undef Ptr
|
||||
#undef StdFont
|
||||
#undef Font
|
||||
#undef Picture
|
||||
#undef byte
|
||||
#undef CY
|
||||
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#endif//OLE_H
|
||||
#ifndef OLE_H
|
||||
#define OLE_H
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE) && defined(COMPILER_MSC)
|
||||
|
||||
#define Ptr Ptr_
|
||||
#define StdFont StdFont_
|
||||
#define Font Font_
|
||||
#define Picture Picture_
|
||||
#define byte win32_byte_ // RpcNdr defines byte -> class with Upp::byte
|
||||
#define CY win32_CY_
|
||||
#include <comdef.h>
|
||||
#include <comip.h>
|
||||
#undef Ptr
|
||||
#undef StdFont
|
||||
#undef Font
|
||||
#undef Picture
|
||||
#undef byte
|
||||
#undef CY
|
||||
|
||||
#endif
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#endif//OLE_H
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
TOPIC("ocx_en-us")
|
||||
#include "ocx_en-us.tpp"
|
||||
END_TOPIC
|
||||
TOPIC("ocx_en-us")
|
||||
#include "ocx_en-us.tpp"
|
||||
END_TOPIC
|
||||
|
|
@ -1,455 +1,455 @@
|
|||
#include "Ole.h"
|
||||
|
||||
#if defined(PLATFORM_WIN32) && defined(COMPILER_MSC)
|
||||
|
||||
namespace Upp {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GUID
|
||||
|
||||
GUID GetCoClassGUID(const char *name, bool prog_id)
|
||||
{
|
||||
OleBstr uni = String(name);
|
||||
GUID guid;
|
||||
Zero(guid);
|
||||
if(prog_id && *name != '{')
|
||||
CLSIDFromProgID(~uni, &guid);
|
||||
else
|
||||
CLSIDFromString(~uni, &guid);
|
||||
return guid;
|
||||
}
|
||||
|
||||
hash_t GetHashValue(const GUID& guid) {
|
||||
const dword *p = reinterpret_cast<const dword *>(&guid);
|
||||
return CombineHash(p[0], p[1], p[2], p[3]);
|
||||
}
|
||||
|
||||
String Format(const GUID& guid) {
|
||||
String result;
|
||||
wchar_t buffer[128];
|
||||
int length;
|
||||
if((length = StringFromGUID2(guid, buffer, __countof(buffer))) > 0)
|
||||
result = AsString(buffer, length - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
String CFormat(const GUID& guid) {
|
||||
String value = Format("{ 0x%08x, 0x%04x, 0x%04x, { ", (int)guid.Data1, (int)guid.Data2, (int)guid.Data3);
|
||||
for(int i = 0; i < 8; i++)
|
||||
value << Format("0x%02x, ", guid.Data4[i]);
|
||||
return value << "} }";
|
||||
}
|
||||
|
||||
String GetInterfaceName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "Interface\\" + goo, HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
String GetCoClassName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "CLSID\\" + goo + "\\ProgID", HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
String GetDisplayName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "CLSID\\" + goo, HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
bool Guid::IsNullInstance() const
|
||||
{
|
||||
const dword *p = reinterpret_cast<const dword *>(&guid);
|
||||
return (p[0] | p[1] | p[2] | p[3]) == 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIANT
|
||||
|
||||
Value AsValue(const VARIANT& variant)
|
||||
{
|
||||
switch(variant.vt) {
|
||||
case VT_ERROR: return ErrorValue(GetErrorMessage(variant.scode));
|
||||
case VT_EMPTY: return Value(); // void
|
||||
case VT_NULL: return Null;
|
||||
|
||||
case VT_BOOL:
|
||||
case VT_UI1: return (int)variant.bVal;
|
||||
case VT_I2: return (int)variant.iVal;
|
||||
case VT_I4: return (int)variant.lVal;
|
||||
|
||||
case VT_R4: return variant.fltVal;
|
||||
case VT_R8: return variant.dblVal;
|
||||
|
||||
case VT_CY: return GetCurrency(variant.cyVal);
|
||||
|
||||
case VT_DATE: return FromDATE(variant.date);
|
||||
|
||||
case VT_BSTR: return BSTRToWString(variant.bstrVal);
|
||||
|
||||
case VT_DECIMAL: {
|
||||
const DECIMAL& d = variant.decVal;
|
||||
double h = (d.Lo32 + d.Mid32 * (65536.0 * 65536.0)) * pow(0.1, d.scale);
|
||||
return d.sign ? -h : h;
|
||||
}
|
||||
|
||||
case VT_ARRAY | VT_UI1: {
|
||||
int nelem = variant.parray->rgsabound[0].cElements;
|
||||
void *bits = 0;
|
||||
if(SUCCEEDED(SafeArrayAccessData(variant.parray, &bits)) && bits) {
|
||||
String out((const char *)bits, nelem);
|
||||
SafeArrayUnaccessData(variant.parray);
|
||||
return out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ErrorValue(Format("Unknown variant type %d", variant.vt));
|
||||
}
|
||||
|
||||
OleVariant AsVariant(Value value) {
|
||||
OleVariant out(VT_NULL);
|
||||
if(value.IsNull())
|
||||
return out;
|
||||
switch(value.GetType()) {
|
||||
case BOOL_V: out.vt = VT_UI1; out.bVal = (byte)(int)value; break;
|
||||
case INT_V: out.vt = VT_I4; out.lVal = (int)value; break;
|
||||
case DOUBLE_V: out.vt = VT_R8; out.dblVal = value; break;
|
||||
case STRING_V: out.vt = VT_BSTR; out.bstrVal = StringToBSTR(value); break;
|
||||
case WSTRING_V: out.vt = VT_BSTR; out.bstrVal = WStringToBSTR(value); break;
|
||||
case DATE_V:
|
||||
case TIME_V: out.vt = VT_DATE; out.date = ToDATE((Time)value);
|
||||
// todo: VALUEARRAY_V ??
|
||||
default: break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
double GetCurrency(const win32_CY_& currency) {
|
||||
return (currency.Hi * (65536.0 * 65536.0) + currency.Lo) / 10000.0;
|
||||
}
|
||||
|
||||
OleVariant ValueToVariant(Value v)
|
||||
{
|
||||
if(IsTypeRaw< IRef<IDispatch> >(v))
|
||||
{
|
||||
OleVariant out(VT_DISPATCH);
|
||||
IRef<IDispatch> disp = ValueTo< IRef<IDispatch> >(v);
|
||||
if(!!disp) disp -> AddRef();
|
||||
out.pdispVal = ~disp;
|
||||
return out;
|
||||
}
|
||||
if(IsTypeRaw< IRef<IUnknown> >(v))
|
||||
{
|
||||
OleVariant out(VT_UNKNOWN);
|
||||
IRef<IUnknown> unk = ValueTo< IRef<IUnknown> >(v);
|
||||
if(!!unk) unk -> AddRef();
|
||||
out.punkVal = ~unk;
|
||||
return out;
|
||||
}
|
||||
return AsVariant(v);
|
||||
}
|
||||
|
||||
void ReturnVariant(VARIANT *var, const Value& v)
|
||||
{
|
||||
*var = AsVariant(v);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// BSTR
|
||||
|
||||
String BSTRToString(BSTR bstr)
|
||||
{
|
||||
int l;
|
||||
if(!bstr || !(l = SysStringLen(bstr)))
|
||||
return Null;
|
||||
byte cs = GetDefaultCharset();
|
||||
if(cs == CHARSET_UTF8)
|
||||
return ToUtf8(TWchar(bstr));
|
||||
StringBuffer out(l);
|
||||
FromUnicode(out, TWchar(bstr), l, cs);
|
||||
return out;
|
||||
}
|
||||
|
||||
BSTR StringToBSTR(String s)
|
||||
{
|
||||
int len = s.GetLength();
|
||||
if(len == 0)
|
||||
return NULL;
|
||||
byte cs = GetDefaultCharset();
|
||||
if(cs == CHARSET_UTF8)
|
||||
return WStringToBSTR(FromUtf8(s));
|
||||
BSTR bstr = SysAllocStringLen(NULL, len);
|
||||
ToUnicode(TWchar(bstr), s, len, cs);
|
||||
return bstr;
|
||||
}
|
||||
|
||||
void ReturnString(BSTR *dest, String s)
|
||||
{
|
||||
if(*dest)
|
||||
SysFreeString(*dest);
|
||||
*dest = StringToBSTR(s);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnString(BSTR *bstr, String s)
|
||||
{
|
||||
if(!bstr) return E_INVALIDARG;
|
||||
ReturnString(bstr, s);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void ReturnWString(BSTR *dest, WString s)
|
||||
{
|
||||
if(*dest)
|
||||
SysFreeString(*dest);
|
||||
*dest = WStringToBSTR(s);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnWString(BSTR *bstr, WString s)
|
||||
{
|
||||
if(!bstr) return E_INVALIDARG;
|
||||
ReturnWString(bstr, s);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ValueArray SAFEARRAYToValueArrayPart(SAFEARRAY *array, long *indices, int dim_index)
|
||||
{
|
||||
Vector<Value> dim_array;
|
||||
int nelem = array->rgsabound[dim_index].cElements;
|
||||
dim_array.SetCount(nelem);
|
||||
for(int e = 0; e < nelem; e++) {
|
||||
indices[dim_index] = e;
|
||||
if(dim_index > 0)
|
||||
dim_array[e] = SAFEARRAYToValueArrayPart(array, indices, dim_index - 1);
|
||||
else {
|
||||
OleVariant var;
|
||||
HRESULT hr = SafeArrayGetElement(array, indices, &var);
|
||||
if(SUCCEEDED(hr))
|
||||
dim_array[e] = AsValue(var);
|
||||
else {
|
||||
String dims;
|
||||
for(int i = 0; i < dim_index; i++)
|
||||
dims << (i ? ", " : "") << indices[i];
|
||||
dim_array[e] = ErrorValue(NFormat("SafeArrayGetElement(%s): error %08lx", dims, hr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ValueArray(pick(dim_array));
|
||||
}
|
||||
|
||||
ValueArray SAFEARRAYToValueArray(SAFEARRAY *array)
|
||||
{
|
||||
int ndims = array->cDims;
|
||||
Vector<long> indices;
|
||||
indices.SetCount(ndims, -1);
|
||||
return SAFEARRAYToValueArrayPart(array, indices.Begin(), ndims - 1);
|
||||
}
|
||||
|
||||
Vector<WString> SAFEARRAYToWStringVector(SAFEARRAY *array)
|
||||
{
|
||||
Vector<WString> out;
|
||||
out.SetCount(array->rgsabound[0].cElements);
|
||||
Vector<long> indices;
|
||||
indices.SetCount(array->cDims, 0);
|
||||
for(int i = 0; i < out.GetCount(); i++) {
|
||||
OleBstr s;
|
||||
indices[0] = i;
|
||||
HRESULT hr = SafeArrayGetElement(array, indices.Begin(), s.Set());
|
||||
out[i] = s;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
SAFEARRAY *ToSAFEARRAY(const ValueArray& varray)
|
||||
{
|
||||
SAFEARRAY *a = SafeArrayCreateVector(VT_VARIANT, 0, varray.GetCount());
|
||||
if(!a)
|
||||
return NULL;
|
||||
for(long index = 0; index < varray.GetCount(); index++) {
|
||||
OleVariant var = AsVariant(varray[(int)index]);
|
||||
SafeArrayPutElement(a, &index, &var);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
SAFEARRAY *ToSAFEARRAY(const Vector<WString>& vstr)
|
||||
{
|
||||
SAFEARRAY *a = SafeArrayCreateVector(VT_BSTR, 0, vstr.GetCount());
|
||||
if(!a)
|
||||
return NULL;
|
||||
for(long index = 0; index < vstr.GetCount(); index++) {
|
||||
OleBstr var = vstr[(int)index];
|
||||
SafeArrayPutElement(a, &index, ~var);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// special types
|
||||
|
||||
Color PackColor(long rgb)
|
||||
{
|
||||
if(rgb < 0)
|
||||
return Null;
|
||||
return Color((rgb >> 16) & 255, (rgb >> 8) & 255, (rgb >> 0) & 255);
|
||||
}
|
||||
|
||||
long UnpackColor(Color c)
|
||||
{
|
||||
if(IsNull(c))
|
||||
return -1;
|
||||
return (c.GetR() << 16) | (c.GetG() << 8) | (c.GetB() << 0);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnColor(long *ptr, Color c)
|
||||
{
|
||||
if(!ptr)
|
||||
return E_INVALIDARG;
|
||||
*ptr = UnpackColor(c);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// errors
|
||||
|
||||
OleExc::OleExc(HRESULT hresult)
|
||||
: Exc(NFormat("COM[%08x]: %s", (int)hresult, GetErrorMessage(hresult)))
|
||||
, hresult(hresult)
|
||||
{
|
||||
}
|
||||
|
||||
OleExc::OleExc(HRESULT hresult, const char *text)
|
||||
: Exc(NFormat("COM[%08x]: %s: %s", (int)hresult, GetErrorMessage(hresult), text))
|
||||
, hresult(hresult)
|
||||
{
|
||||
LOG("OleExc::OleExc " << *this);
|
||||
}
|
||||
|
||||
HRESULT LogResult(HRESULT hr)
|
||||
{
|
||||
LOGF("<= return 0x%08x: %s\r\n", hr, GetErrorMessage(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LogError(HRESULT hr)
|
||||
{
|
||||
if(FAILED(hr))
|
||||
LogResult(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// interfaces
|
||||
|
||||
Value DispatchToValue(IDispatch *disp)
|
||||
{
|
||||
return RawPickToValue(IRef<IDispatch>(disp));
|
||||
}
|
||||
|
||||
Value UnknownToValue(IUnknown *unk)
|
||||
{
|
||||
return RawPickToValue(IRef<IUnknown>(unk));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// OleStream::
|
||||
|
||||
OleStream::OleStream(IUnknown *stream)
|
||||
{
|
||||
Open(stream);
|
||||
}
|
||||
|
||||
bool OleStream::Open(IUnknown *stream)
|
||||
{
|
||||
Close();
|
||||
if(!stream)
|
||||
return false;
|
||||
if(FAILED(stream -> QueryInterface(IID_IStream, (void **)&istream)))
|
||||
return false;
|
||||
STATSTG stat;
|
||||
Zero(stat);
|
||||
// HRESULT statres = istream -> Stat(&stat, STATFLAG_NONAME);
|
||||
int mode = READWRITE;
|
||||
// if(SUCCEEDED(statres) && (stat.grfMode & (STGM_READ | STGM_WRITE | STGM_READWRITE)) == STGM_READ)
|
||||
// mode = READ;
|
||||
|
||||
ULARGE_INTEGER pos = AsULarge(0), len;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_CUR, &pos))
|
||||
|| FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_END, &len)))
|
||||
SetError(hr);
|
||||
current_offset = len.QuadPart;
|
||||
OpenInit(mode, len.QuadPart);
|
||||
Seek(pos.QuadPart);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OleStream::Close()
|
||||
{
|
||||
if(!(bool)istream)
|
||||
return;
|
||||
int64 pos = GetPos();
|
||||
Flush();
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(pos), STREAM_SEEK_SET, 0)))
|
||||
SetError(hr);
|
||||
istream = 0;
|
||||
}
|
||||
|
||||
void OleStream::SetStreamSize(dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_WRITE));
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> SetSize(AsULarge(size))))
|
||||
SetError(hr);
|
||||
ULARGE_INTEGER pos = AsULarge(0);
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_CUR, &pos)))
|
||||
SetError(hr);
|
||||
current_offset = pos.LowPart;
|
||||
}
|
||||
|
||||
dword OleStream::Read(int64 at, void *ptr, dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_READ));
|
||||
RawSeek(at);
|
||||
dword done = 0;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Read(ptr, size, &done)))
|
||||
SetError(hr);
|
||||
else
|
||||
current_offset += done;
|
||||
return done;
|
||||
}
|
||||
|
||||
void OleStream::Write(int64 at, const void *data, dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_WRITE));
|
||||
RawSeek(at);
|
||||
dword done = 0;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Write(data, size, &done)) || done != size)
|
||||
SetError(hr);
|
||||
current_offset += done;
|
||||
}
|
||||
|
||||
void OleStream::RawSeek(int64 pos)
|
||||
{
|
||||
if(current_offset == pos)
|
||||
return;
|
||||
ULARGE_INTEGER new_pos = AsULarge(pos);
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(pos), STREAM_SEEK_SET, &new_pos)))
|
||||
SetError(hr);
|
||||
pos = new_pos.LowPart;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "Ole.h"
|
||||
|
||||
#if defined(PLATFORM_WIN32) && defined(COMPILER_MSC)
|
||||
|
||||
namespace Upp {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GUID
|
||||
|
||||
GUID GetCoClassGUID(const char *name, bool prog_id)
|
||||
{
|
||||
OleBstr uni = String(name);
|
||||
GUID guid;
|
||||
Zero(guid);
|
||||
if(prog_id && *name != '{')
|
||||
CLSIDFromProgID(~uni, &guid);
|
||||
else
|
||||
CLSIDFromString(~uni, &guid);
|
||||
return guid;
|
||||
}
|
||||
|
||||
hash_t GetHashValue(const GUID& guid) {
|
||||
const dword *p = reinterpret_cast<const dword *>(&guid);
|
||||
return CombineHash(p[0], p[1], p[2], p[3]);
|
||||
}
|
||||
|
||||
String Format(const GUID& guid) {
|
||||
String result;
|
||||
wchar_t buffer[128];
|
||||
int length;
|
||||
if((length = StringFromGUID2(guid, buffer, __countof(buffer))) > 0)
|
||||
result = AsString(buffer, length - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
String CFormat(const GUID& guid) {
|
||||
String value = Format("{ 0x%08x, 0x%04x, 0x%04x, { ", (int)guid.Data1, (int)guid.Data2, (int)guid.Data3);
|
||||
for(int i = 0; i < 8; i++)
|
||||
value << Format("0x%02x, ", guid.Data4[i]);
|
||||
return value << "} }";
|
||||
}
|
||||
|
||||
String GetInterfaceName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "Interface\\" + goo, HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
String GetCoClassName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "CLSID\\" + goo + "\\ProgID", HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
String GetDisplayName(const GUID& guid) {
|
||||
if(IsNull(Guid(guid)))
|
||||
return Null;
|
||||
String goo = Format(guid);
|
||||
return Nvl(GetWinRegString(NULL, "CLSID\\" + goo, HKEY_CLASSES_ROOT), goo);
|
||||
}
|
||||
|
||||
bool Guid::IsNullInstance() const
|
||||
{
|
||||
const dword *p = reinterpret_cast<const dword *>(&guid);
|
||||
return (p[0] | p[1] | p[2] | p[3]) == 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIANT
|
||||
|
||||
Value AsValue(const VARIANT& variant)
|
||||
{
|
||||
switch(variant.vt) {
|
||||
case VT_ERROR: return ErrorValue(GetErrorMessage(variant.scode));
|
||||
case VT_EMPTY: return Value(); // void
|
||||
case VT_NULL: return Null;
|
||||
|
||||
case VT_BOOL:
|
||||
case VT_UI1: return (int)variant.bVal;
|
||||
case VT_I2: return (int)variant.iVal;
|
||||
case VT_I4: return (int)variant.lVal;
|
||||
|
||||
case VT_R4: return variant.fltVal;
|
||||
case VT_R8: return variant.dblVal;
|
||||
|
||||
case VT_CY: return GetCurrency(variant.cyVal);
|
||||
|
||||
case VT_DATE: return FromDATE(variant.date);
|
||||
|
||||
case VT_BSTR: return BSTRToWString(variant.bstrVal);
|
||||
|
||||
case VT_DECIMAL: {
|
||||
const DECIMAL& d = variant.decVal;
|
||||
double h = (d.Lo32 + d.Mid32 * (65536.0 * 65536.0)) * pow(0.1, d.scale);
|
||||
return d.sign ? -h : h;
|
||||
}
|
||||
|
||||
case VT_ARRAY | VT_UI1: {
|
||||
int nelem = variant.parray->rgsabound[0].cElements;
|
||||
void *bits = 0;
|
||||
if(SUCCEEDED(SafeArrayAccessData(variant.parray, &bits)) && bits) {
|
||||
String out((const char *)bits, nelem);
|
||||
SafeArrayUnaccessData(variant.parray);
|
||||
return out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ErrorValue(Format("Unknown variant type %d", variant.vt));
|
||||
}
|
||||
|
||||
OleVariant AsVariant(Value value) {
|
||||
OleVariant out(VT_NULL);
|
||||
if(value.IsNull())
|
||||
return out;
|
||||
switch(value.GetType()) {
|
||||
case BOOL_V: out.vt = VT_UI1; out.bVal = (byte)(int)value; break;
|
||||
case INT_V: out.vt = VT_I4; out.lVal = (int)value; break;
|
||||
case DOUBLE_V: out.vt = VT_R8; out.dblVal = value; break;
|
||||
case STRING_V: out.vt = VT_BSTR; out.bstrVal = StringToBSTR(value); break;
|
||||
case WSTRING_V: out.vt = VT_BSTR; out.bstrVal = WStringToBSTR(value); break;
|
||||
case DATE_V:
|
||||
case TIME_V: out.vt = VT_DATE; out.date = ToDATE((Time)value);
|
||||
// todo: VALUEARRAY_V ??
|
||||
default: break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
double GetCurrency(const win32_CY_& currency) {
|
||||
return (currency.Hi * (65536.0 * 65536.0) + currency.Lo) / 10000.0;
|
||||
}
|
||||
|
||||
OleVariant ValueToVariant(Value v)
|
||||
{
|
||||
if(IsTypeRaw< IRef<IDispatch> >(v))
|
||||
{
|
||||
OleVariant out(VT_DISPATCH);
|
||||
IRef<IDispatch> disp = ValueTo< IRef<IDispatch> >(v);
|
||||
if(!!disp) disp -> AddRef();
|
||||
out.pdispVal = ~disp;
|
||||
return out;
|
||||
}
|
||||
if(IsTypeRaw< IRef<IUnknown> >(v))
|
||||
{
|
||||
OleVariant out(VT_UNKNOWN);
|
||||
IRef<IUnknown> unk = ValueTo< IRef<IUnknown> >(v);
|
||||
if(!!unk) unk -> AddRef();
|
||||
out.punkVal = ~unk;
|
||||
return out;
|
||||
}
|
||||
return AsVariant(v);
|
||||
}
|
||||
|
||||
void ReturnVariant(VARIANT *var, const Value& v)
|
||||
{
|
||||
*var = AsVariant(v);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// BSTR
|
||||
|
||||
String BSTRToString(BSTR bstr)
|
||||
{
|
||||
int l;
|
||||
if(!bstr || !(l = SysStringLen(bstr)))
|
||||
return Null;
|
||||
byte cs = GetDefaultCharset();
|
||||
if(cs == CHARSET_UTF8)
|
||||
return ToUtf8(TWchar(bstr));
|
||||
StringBuffer out(l);
|
||||
FromUnicode(out, TWchar(bstr), l, cs);
|
||||
return out;
|
||||
}
|
||||
|
||||
BSTR StringToBSTR(String s)
|
||||
{
|
||||
int len = s.GetLength();
|
||||
if(len == 0)
|
||||
return NULL;
|
||||
byte cs = GetDefaultCharset();
|
||||
if(cs == CHARSET_UTF8)
|
||||
return WStringToBSTR(FromUtf8(s));
|
||||
BSTR bstr = SysAllocStringLen(NULL, len);
|
||||
ToUnicode(TWchar(bstr), s, len, cs);
|
||||
return bstr;
|
||||
}
|
||||
|
||||
void ReturnString(BSTR *dest, String s)
|
||||
{
|
||||
if(*dest)
|
||||
SysFreeString(*dest);
|
||||
*dest = StringToBSTR(s);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnString(BSTR *bstr, String s)
|
||||
{
|
||||
if(!bstr) return E_INVALIDARG;
|
||||
ReturnString(bstr, s);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void ReturnWString(BSTR *dest, WString s)
|
||||
{
|
||||
if(*dest)
|
||||
SysFreeString(*dest);
|
||||
*dest = WStringToBSTR(s);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnWString(BSTR *bstr, WString s)
|
||||
{
|
||||
if(!bstr) return E_INVALIDARG;
|
||||
ReturnWString(bstr, s);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ValueArray SAFEARRAYToValueArrayPart(SAFEARRAY *array, long *indices, int dim_index)
|
||||
{
|
||||
Vector<Value> dim_array;
|
||||
int nelem = array->rgsabound[dim_index].cElements;
|
||||
dim_array.SetCount(nelem);
|
||||
for(int e = 0; e < nelem; e++) {
|
||||
indices[dim_index] = e;
|
||||
if(dim_index > 0)
|
||||
dim_array[e] = SAFEARRAYToValueArrayPart(array, indices, dim_index - 1);
|
||||
else {
|
||||
OleVariant var;
|
||||
HRESULT hr = SafeArrayGetElement(array, indices, &var);
|
||||
if(SUCCEEDED(hr))
|
||||
dim_array[e] = AsValue(var);
|
||||
else {
|
||||
String dims;
|
||||
for(int i = 0; i < dim_index; i++)
|
||||
dims << (i ? ", " : "") << indices[i];
|
||||
dim_array[e] = ErrorValue(NFormat("SafeArrayGetElement(%s): error %08lx", dims, hr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ValueArray(pick(dim_array));
|
||||
}
|
||||
|
||||
ValueArray SAFEARRAYToValueArray(SAFEARRAY *array)
|
||||
{
|
||||
int ndims = array->cDims;
|
||||
Vector<long> indices;
|
||||
indices.SetCount(ndims, -1);
|
||||
return SAFEARRAYToValueArrayPart(array, indices.Begin(), ndims - 1);
|
||||
}
|
||||
|
||||
Vector<WString> SAFEARRAYToWStringVector(SAFEARRAY *array)
|
||||
{
|
||||
Vector<WString> out;
|
||||
out.SetCount(array->rgsabound[0].cElements);
|
||||
Vector<long> indices;
|
||||
indices.SetCount(array->cDims, 0);
|
||||
for(int i = 0; i < out.GetCount(); i++) {
|
||||
OleBstr s;
|
||||
indices[0] = i;
|
||||
HRESULT hr = SafeArrayGetElement(array, indices.Begin(), s.Set());
|
||||
out[i] = s;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
SAFEARRAY *ToSAFEARRAY(const ValueArray& varray)
|
||||
{
|
||||
SAFEARRAY *a = SafeArrayCreateVector(VT_VARIANT, 0, varray.GetCount());
|
||||
if(!a)
|
||||
return NULL;
|
||||
for(long index = 0; index < varray.GetCount(); index++) {
|
||||
OleVariant var = AsVariant(varray[(int)index]);
|
||||
SafeArrayPutElement(a, &index, &var);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
SAFEARRAY *ToSAFEARRAY(const Vector<WString>& vstr)
|
||||
{
|
||||
SAFEARRAY *a = SafeArrayCreateVector(VT_BSTR, 0, vstr.GetCount());
|
||||
if(!a)
|
||||
return NULL;
|
||||
for(long index = 0; index < vstr.GetCount(); index++) {
|
||||
OleBstr var = vstr[(int)index];
|
||||
SafeArrayPutElement(a, &index, ~var);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// special types
|
||||
|
||||
Color PackColor(long rgb)
|
||||
{
|
||||
if(rgb < 0)
|
||||
return Null;
|
||||
return Color((rgb >> 16) & 255, (rgb >> 8) & 255, (rgb >> 0) & 255);
|
||||
}
|
||||
|
||||
long UnpackColor(Color c)
|
||||
{
|
||||
if(IsNull(c))
|
||||
return -1;
|
||||
return (c.GetR() << 16) | (c.GetG() << 8) | (c.GetB() << 0);
|
||||
}
|
||||
|
||||
HRESULT CheckReturnColor(long *ptr, Color c)
|
||||
{
|
||||
if(!ptr)
|
||||
return E_INVALIDARG;
|
||||
*ptr = UnpackColor(c);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// errors
|
||||
|
||||
OleExc::OleExc(HRESULT hresult)
|
||||
: Exc(NFormat("COM[%08x]: %s", (int)hresult, GetErrorMessage(hresult)))
|
||||
, hresult(hresult)
|
||||
{
|
||||
}
|
||||
|
||||
OleExc::OleExc(HRESULT hresult, const char *text)
|
||||
: Exc(NFormat("COM[%08x]: %s: %s", (int)hresult, GetErrorMessage(hresult), text))
|
||||
, hresult(hresult)
|
||||
{
|
||||
LOG("OleExc::OleExc " << *this);
|
||||
}
|
||||
|
||||
HRESULT LogResult(HRESULT hr)
|
||||
{
|
||||
LOGF("<= return 0x%08x: %s\r\n", hr, GetErrorMessage(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LogError(HRESULT hr)
|
||||
{
|
||||
if(FAILED(hr))
|
||||
LogResult(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// interfaces
|
||||
|
||||
Value DispatchToValue(IDispatch *disp)
|
||||
{
|
||||
return RawPickToValue(IRef<IDispatch>(disp));
|
||||
}
|
||||
|
||||
Value UnknownToValue(IUnknown *unk)
|
||||
{
|
||||
return RawPickToValue(IRef<IUnknown>(unk));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// OleStream::
|
||||
|
||||
OleStream::OleStream(IUnknown *stream)
|
||||
{
|
||||
Open(stream);
|
||||
}
|
||||
|
||||
bool OleStream::Open(IUnknown *stream)
|
||||
{
|
||||
Close();
|
||||
if(!stream)
|
||||
return false;
|
||||
if(FAILED(stream -> QueryInterface(IID_IStream, (void **)&istream)))
|
||||
return false;
|
||||
STATSTG stat;
|
||||
Zero(stat);
|
||||
// HRESULT statres = istream -> Stat(&stat, STATFLAG_NONAME);
|
||||
int mode = READWRITE;
|
||||
// if(SUCCEEDED(statres) && (stat.grfMode & (STGM_READ | STGM_WRITE | STGM_READWRITE)) == STGM_READ)
|
||||
// mode = READ;
|
||||
|
||||
ULARGE_INTEGER pos = AsULarge(0), len;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_CUR, &pos))
|
||||
|| FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_END, &len)))
|
||||
SetError(hr);
|
||||
current_offset = len.QuadPart;
|
||||
OpenInit(mode, len.QuadPart);
|
||||
Seek(pos.QuadPart);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OleStream::Close()
|
||||
{
|
||||
if(!(bool)istream)
|
||||
return;
|
||||
int64 pos = GetPos();
|
||||
Flush();
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(pos), STREAM_SEEK_SET, 0)))
|
||||
SetError(hr);
|
||||
istream = 0;
|
||||
}
|
||||
|
||||
void OleStream::SetStreamSize(dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_WRITE));
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> SetSize(AsULarge(size))))
|
||||
SetError(hr);
|
||||
ULARGE_INTEGER pos = AsULarge(0);
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(0), STREAM_SEEK_CUR, &pos)))
|
||||
SetError(hr);
|
||||
current_offset = pos.LowPart;
|
||||
}
|
||||
|
||||
dword OleStream::Read(int64 at, void *ptr, dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_READ));
|
||||
RawSeek(at);
|
||||
dword done = 0;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Read(ptr, size, &done)))
|
||||
SetError(hr);
|
||||
else
|
||||
current_offset += done;
|
||||
return done;
|
||||
}
|
||||
|
||||
void OleStream::Write(int64 at, const void *data, dword size)
|
||||
{
|
||||
ASSERT((bool)istream && (GetStyle() & STRM_WRITE));
|
||||
RawSeek(at);
|
||||
dword done = 0;
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Write(data, size, &done)) || done != size)
|
||||
SetError(hr);
|
||||
current_offset += done;
|
||||
}
|
||||
|
||||
void OleStream::RawSeek(int64 pos)
|
||||
{
|
||||
if(current_offset == pos)
|
||||
return;
|
||||
ULARGE_INTEGER new_pos = AsULarge(pos);
|
||||
HRESULT hr;
|
||||
if(FAILED(hr = istream -> Seek(AsLarge(pos), STREAM_SEEK_SET, &new_pos)))
|
||||
SetError(hr);
|
||||
pos = new_pos.LowPart;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,327 +1,327 @@
|
|||
#if defined(PLATFORM_WIN32) && defined(COMPILER_MSC)
|
||||
|
||||
namespace Upp {
|
||||
|
||||
#ifdef COMPILER_MSC
|
||||
typedef __int64 longlong_t;
|
||||
#define LL_(x) COMBINE(x, i64)
|
||||
#else
|
||||
typedef long long longlong_t;
|
||||
#define LL_(x) COMBINE(x, LL)
|
||||
#endif//COMPILER
|
||||
|
||||
inline void OleInit() { CoInitialize(NULL); }
|
||||
|
||||
inline const wchar_t *WcharT(const wchar *w) { return (const wchar_t *)w; }
|
||||
inline wchar_t *WcharT(wchar *w) { return (wchar_t *)w; }
|
||||
inline const wchar *TWchar(const wchar_t *w) { return (const wchar *)w; }
|
||||
inline wchar *TWchar(wchar_t *w) { return (wchar *)w; }
|
||||
|
||||
template <class T>
|
||||
class OleBuffer
|
||||
{
|
||||
public:
|
||||
OleBuffer(T *ptr = 0) : ptr(ptr) {}
|
||||
~OleBuffer() { Clear(); }
|
||||
|
||||
void Clear() { if(ptr) { CoTaskMemFree(ptr); ptr = 0; } }
|
||||
T **Set() { Clear(); return &ptr; }
|
||||
|
||||
operator T * () { return ptr; }
|
||||
operator const T * () const { return ptr; }
|
||||
|
||||
private:
|
||||
T *ptr;
|
||||
};
|
||||
|
||||
hash_t GetHashValue(const GUID& guid);
|
||||
String Format(const GUID& guid);
|
||||
String CFormat(const GUID& guid);
|
||||
inline void Serialize(Stream& stream, GUID& guid) { stream.SerializeRaw((byte *)&guid, sizeof(GUID)); }
|
||||
String GetInterfaceName(const GUID& guid);
|
||||
String GetCoClassName(const GUID& guid);
|
||||
String GetDisplayName(const GUID& guid);
|
||||
GUID GetCoClassGUID(const char *name, bool prog_id = true);
|
||||
|
||||
class Guid : public ValueType<Guid, 70, Moveable<Guid> >
|
||||
{
|
||||
public:
|
||||
Guid(const Nuller& = Null) { Clear(); }
|
||||
Guid(const char *text, bool prid = true) { guid = GetCoClassGUID(text, prid); }
|
||||
Guid(const GUID& guid_) : guid(guid_) {}
|
||||
Guid(const Guid& guid_) : guid(guid_.guid) {}
|
||||
Guid(IDispatchPtr& dispatch); // dynamic GUID of a dispatch object
|
||||
Guid(Value v) { *this = ValueTo<Guid>(v); }
|
||||
|
||||
operator Value () const { return RichValue<Guid>(*this); }
|
||||
operator const GUID& () const { return guid; }
|
||||
operator GUID& () { return guid; }
|
||||
const GUID& operator ~() const { return guid; }
|
||||
|
||||
Guid& operator = (const GUID& _guid) { guid = _guid; return *this; }
|
||||
|
||||
bool IsNullInstance() const;
|
||||
bool IsEmpty() const { return IsNullInstance(); }
|
||||
void Clear() { Zero(guid); }
|
||||
|
||||
operator String () const { return UPP::Format(guid); }
|
||||
String CFormat() const { return UPP::CFormat(guid); }
|
||||
|
||||
void Serialize(Stream& stream) { UPP::Serialize(stream, guid); }
|
||||
|
||||
private:
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline hash_t GetHashValue(const Guid& guid) { return GetHashValue(~guid); }
|
||||
template <>
|
||||
inline String AsString(const GUID& guid) { return Format(guid); }
|
||||
template <>
|
||||
inline String AsString(const Guid& guid) { return Format(~guid); }
|
||||
|
||||
inline bool operator == (const Guid& a, const Guid& b) { return ~a == ~b; }
|
||||
inline bool operator != (const Guid& a, const Guid& b) { return ~a != ~b; }
|
||||
|
||||
class OleExc : public Exc
|
||||
{
|
||||
public:
|
||||
OleExc(HRESULT hresult);
|
||||
OleExc(HRESULT hresult, const char *text);
|
||||
|
||||
public:
|
||||
HRESULT hresult;
|
||||
};
|
||||
|
||||
HRESULT LogResult(HRESULT hr);
|
||||
HRESULT LogError(HRESULT hr);
|
||||
|
||||
inline void OleVerify(HRESULT hr) { if(FAILED(hr)) throw OleExc(hr); }
|
||||
inline void OleVerify(HRESULT hr, const char *text) { if(FAILED(hr)) throw OleExc(hr, text); }
|
||||
|
||||
#define OLE_VERIFY(c) OleVerify(c, #c)
|
||||
|
||||
class OleVariant : public VARIANT
|
||||
{
|
||||
public:
|
||||
OleVariant(int vtype = VT_EMPTY) { VariantInit(this); vt = vtype; }
|
||||
OleVariant(const OleVariant& o) { VariantInit(this); VariantCopy(this, const_cast<OleVariant *>(&o)); }
|
||||
~OleVariant() { VariantClear(this); }
|
||||
OleVariant(const VARIANT& var) { VariantInit(this); VariantCopy(this, const_cast<VARIANT *>(&var)); }
|
||||
|
||||
OleVariant& operator = (const OleVariant& var) { if(this != &var) { VariantClear(this); VariantCopy(this, const_cast<VARIANT *>((VARIANT *)&var)); } return *this; }
|
||||
|
||||
VARIANT operator ~ () const { VARIANT v; VariantInit(&v); VariantCopy(&v, const_cast<OleVariant *>(this)); return v; }
|
||||
};
|
||||
|
||||
Value AsValue(const VARIANT& variant);
|
||||
OleVariant AsVariant(Value value);
|
||||
|
||||
//inline ULARGE_INTEGER AsULarge(dword value) { ULARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
//inline LARGE_INTEGER AsLarge(int value) { LARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
inline ULARGE_INTEGER AsULarge(int64 value) { ULARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
inline LARGE_INTEGER AsLarge(int64 value) { LARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
|
||||
double GetCurrency(const win32_CY_& currency);
|
||||
inline DATE ToDATE(Date date) { return date - Date(1899, 12, 30); }
|
||||
inline DATE ToDATE(Time time) { return (time - Time(1899, 12, 30)) / 86400.0; }
|
||||
inline Time FromDATE(DATE date) { return Time(1899, 12, 30) + (int64)floor(date * 86400.0 + 0.5); }
|
||||
|
||||
OleVariant ValueToVariant(Value v);
|
||||
void ReturnVariant(VARIANT *var, Value v);
|
||||
|
||||
inline WString BSTRToWString(BSTR bstr) { return WString((wchar *)bstr, SysStringLen(bstr)); }
|
||||
inline BSTR WStringToBSTR(WString w) { return SysAllocStringLen((BSTR)~w, w.GetLength()); }
|
||||
String BSTRToString(BSTR bstr);
|
||||
BSTR StringToBSTR(String s);
|
||||
|
||||
void ReturnString(BSTR *dest, String s);
|
||||
HRESULT CheckReturnString(BSTR *bstr, String s);
|
||||
void ReturnWString(BSTR *dest, WString s);
|
||||
HRESULT CheckReturnWString(BSTR *bstr, WString s);
|
||||
|
||||
ValueArray SAFEARRAYToValueArray(SAFEARRAY *array);
|
||||
Vector<WString> SAFEARRAYToWStringVector(SAFEARRAY *array);
|
||||
SAFEARRAY *ToSAFEARRAY(const ValueArray& varray);
|
||||
SAFEARRAY *ToSAFEARRAY(const Vector<WString>& varray);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
|
||||
class OleSafeArray {
|
||||
public:
|
||||
OleSafeArray() : array(NULL) {}
|
||||
OleSafeArray(const ValueArray& va) { array = ToSAFEARRAY(va); }
|
||||
OleSafeArray(const Vector<WString>& vs) { array = ToSAFEARRAY(vs); }
|
||||
OleSafeArray(const OleSafeArray& a) { array = NULL; if(a.array) OleVerify(SafeArrayCopy(a.array, &array)); }
|
||||
~OleSafeArray() { if(array) SafeArrayDestroy(array); }
|
||||
|
||||
operator ValueArray () const { return SAFEARRAYToValueArray(array); }
|
||||
operator Vector<WString> () const { return SAFEARRAYToWStringVector(array); }
|
||||
SAFEARRAY *operator ~ () const { return array; }
|
||||
|
||||
private:
|
||||
SAFEARRAY *array;
|
||||
};
|
||||
|
||||
class OleBstr
|
||||
{
|
||||
public:
|
||||
OleBstr(const Nuller& = Null) : bstr(NULL) {}
|
||||
OleBstr(WString w) : bstr(WStringToBSTR(w)) {}
|
||||
OleBstr(String s) : bstr(StringToBSTR(s)) {}
|
||||
~OleBstr() { if(bstr) SysFreeString(bstr); }
|
||||
|
||||
void Clear() { if(bstr) { SysFreeString(bstr); bstr = NULL; } }
|
||||
BSTR *Set() { Clear(); return &bstr; }
|
||||
|
||||
operator WString () const { return BSTRToWString(bstr); }
|
||||
operator String () const { return BSTRToString(bstr); }
|
||||
String ToString() const { return BSTRToString(bstr); }
|
||||
// operator BSTR () const { return bstr; }
|
||||
BSTR operator ~ () const { return bstr; }
|
||||
int GetLength() const { return SysStringLen(bstr); }
|
||||
|
||||
private:
|
||||
BSTR bstr;
|
||||
};
|
||||
|
||||
inline const RECTL& ToRectL(const Rect& rc) { return reinterpret_cast<const RECTL&>(rc); }
|
||||
inline const Rect& ToRect(const RECTL& rc) { return reinterpret_cast<const Rect&>(rc); }
|
||||
|
||||
Color PackColor(long rgb);
|
||||
long UnpackColor(Color c);
|
||||
HRESULT CheckReturnColor(long *ptr, Color c);
|
||||
|
||||
template <class T>
|
||||
class IRefBase : Moveable< IRefBase<T> >
|
||||
{
|
||||
public:
|
||||
IRefBase(T *ptr = NULL) : ptr(ptr) { if(ptr) ptr->AddRef(); }
|
||||
IRefBase(const IRefBase& i) { if(ptr = i.ptr) ptr->AddRef(); }
|
||||
~IRefBase() { if(ptr) ptr->Release(); }
|
||||
|
||||
static GUID GetIID() { return __uuidof(T); }
|
||||
|
||||
HRESULT Create(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER)
|
||||
{ return CoCreateInstance(clsid, NULL, flags, GetIID(), (void **)Set()); }
|
||||
|
||||
void Clear() { if(ptr) { ptr->Release(); ptr = 0; } }
|
||||
|
||||
T *operator->() const { ASSERT(ptr); return ptr; }
|
||||
T& operator * () const { ASSERT(ptr); return *ptr; }
|
||||
T *operator ~ () const { return ptr; }
|
||||
|
||||
T **Set() { Clear(); return &ptr; }
|
||||
IUnknown **SetUnk() { Clear(); return (IUnknown **)&ptr; }
|
||||
void **SetVoid() { Clear(); return (void **)&ptr; }
|
||||
void Set(T *p) { T *old = ptr; if(ptr = p) ptr->AddRef(); if(old) old->Release(); }
|
||||
|
||||
bool operator !() const { return !ptr; }
|
||||
|
||||
T *AddRef() { if(ptr) ptr->AddRef(); return ptr; }
|
||||
T *Detach() { T *out = ptr; ptr = 0; return out; }
|
||||
T *operator - () { return Detach(); }
|
||||
|
||||
protected:
|
||||
mutable T *ptr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class IRef : public Moveable< IRef<T>, IRefBase<T> >
|
||||
{
|
||||
public:
|
||||
IRef() {}
|
||||
IRef(IUnknown *u) { if(u) OleVerify(u->QueryInterface(__uuidof(T), (void **)&ptr)); }
|
||||
IRef(T *t) { if(ptr = t) ptr->AddRef(); }
|
||||
IRef(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER) { OleVerify(Create(clsid, flags)); }
|
||||
IRef(const IRef<T>& x) : Moveable< IRef<T>, IRefBase<T> >(x) {}
|
||||
explicit IRef(const VARIANT& v)
|
||||
{
|
||||
ptr = NULL;
|
||||
if(v.vt == VT_DISPATCH)
|
||||
OleVerify(v.pdispVal->QueryInterface(__uuidof(T), (void **)&ptr));
|
||||
else if(v.vt == VT_UNKNOWN)
|
||||
OleVerify(v.punkVal->QueryInterface(__uuidof(T), (void **)&ptr));
|
||||
else
|
||||
{
|
||||
ASSERT(v.vt == VT_EMPTY || v.vt == VT_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
IRef& operator = (const IRef<T>& x) { Set(x.ptr); return *this; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class IRef<IUnknown> : public IRefBase<IUnknown>
|
||||
{
|
||||
public:
|
||||
IRef() {}
|
||||
IRef(IUnknown *u) : IRefBase<IUnknown>(u) {}
|
||||
IRef(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER) { OleVerify(Create(clsid, flags)); }
|
||||
IRef(const IRef<IUnknown>& x) : IRefBase<IUnknown>(x.ptr) {}
|
||||
|
||||
IRef& operator = (const IRef<IUnknown>& x) { Set(x.ptr); return *this; }
|
||||
};
|
||||
|
||||
Value DispatchToValue(IDispatch *disp);
|
||||
Value UnknownToValue(IUnknown *unk);
|
||||
|
||||
template <class I>
|
||||
OleVariant DispVar(I& iface)
|
||||
{
|
||||
IRef<IDispatch> disp = iface;
|
||||
OleVariant out(VT_DISPATCH);
|
||||
if(!!disp) disp->AddRef();
|
||||
out.pdispVal = ~disp;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct OleType : Moveable< OleType<T> >
|
||||
{
|
||||
friend T *Ptr(T& t) { return reinterpret_cast<T *>(&reinterpret_cast<char &>(t)); }
|
||||
friend T& Deref(T *t) { return reinterpret_cast<T&>(*reinterpret_cast<char *>(t)); }
|
||||
friend void Destroy(T& t) { t.~T(); }
|
||||
friend T& Construct(T& t) { return Deref(new(Ptr(t)) T); }
|
||||
friend void CopyConstruct(T& t, T& x) { new(Ptr(t)) T(x); }
|
||||
friend void DeepCopyConstruct(T& t, const T& x) { new(Ptr(t)) T(x); }
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
inline HRESULT QueryInterface(T& src, U& dest, const GUID& guid)
|
||||
{
|
||||
return src->QueryInterface(guid, (void **)dest.Set());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline HRESULT QueryInterface(T& src, U& dest)
|
||||
{
|
||||
return QueryInterface(src, dest, dest.GetIID());
|
||||
}
|
||||
|
||||
class OleStream : public BlockStream
|
||||
{
|
||||
public:
|
||||
OleStream(IUnknown *stream = 0);
|
||||
|
||||
bool Open(IUnknown *stream);
|
||||
virtual void Close();
|
||||
virtual bool IsOpen() const { return istream; }
|
||||
|
||||
protected:
|
||||
virtual void SetStreamSize(dword size);
|
||||
virtual dword Read(int64 at, void *ptr, dword size);
|
||||
virtual void Write(int64 at, const void *data, dword size);
|
||||
|
||||
void RawSeek(int64 pos);
|
||||
|
||||
protected:
|
||||
IStreamPtr istream;
|
||||
int64 current_offset;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(PLATFORM_WIN32) && defined(COMPILER_MSC)
|
||||
|
||||
namespace Upp {
|
||||
|
||||
#ifdef COMPILER_MSC
|
||||
typedef __int64 longlong_t;
|
||||
#define LL_(x) COMBINE(x, i64)
|
||||
#else
|
||||
typedef long long longlong_t;
|
||||
#define LL_(x) COMBINE(x, LL)
|
||||
#endif//COMPILER
|
||||
|
||||
inline void OleInit() { CoInitialize(NULL); }
|
||||
|
||||
inline const wchar_t *WcharT(const wchar *w) { return (const wchar_t *)w; }
|
||||
inline wchar_t *WcharT(wchar *w) { return (wchar_t *)w; }
|
||||
inline const wchar *TWchar(const wchar_t *w) { return (const wchar *)w; }
|
||||
inline wchar *TWchar(wchar_t *w) { return (wchar *)w; }
|
||||
|
||||
template <class T>
|
||||
class OleBuffer
|
||||
{
|
||||
public:
|
||||
OleBuffer(T *ptr = 0) : ptr(ptr) {}
|
||||
~OleBuffer() { Clear(); }
|
||||
|
||||
void Clear() { if(ptr) { CoTaskMemFree(ptr); ptr = 0; } }
|
||||
T **Set() { Clear(); return &ptr; }
|
||||
|
||||
operator T * () { return ptr; }
|
||||
operator const T * () const { return ptr; }
|
||||
|
||||
private:
|
||||
T *ptr;
|
||||
};
|
||||
|
||||
hash_t GetHashValue(const GUID& guid);
|
||||
String Format(const GUID& guid);
|
||||
String CFormat(const GUID& guid);
|
||||
inline void Serialize(Stream& stream, GUID& guid) { stream.SerializeRaw((byte *)&guid, sizeof(GUID)); }
|
||||
String GetInterfaceName(const GUID& guid);
|
||||
String GetCoClassName(const GUID& guid);
|
||||
String GetDisplayName(const GUID& guid);
|
||||
GUID GetCoClassGUID(const char *name, bool prog_id = true);
|
||||
|
||||
class Guid : public ValueType<Guid, 70, Moveable<Guid> >
|
||||
{
|
||||
public:
|
||||
Guid(const Nuller& = Null) { Clear(); }
|
||||
Guid(const char *text, bool prid = true) { guid = GetCoClassGUID(text, prid); }
|
||||
Guid(const GUID& guid_) : guid(guid_) {}
|
||||
Guid(const Guid& guid_) : guid(guid_.guid) {}
|
||||
Guid(IDispatchPtr& dispatch); // dynamic GUID of a dispatch object
|
||||
Guid(Value v) { *this = ValueTo<Guid>(v); }
|
||||
|
||||
operator Value () const { return RichValue<Guid>(*this); }
|
||||
operator const GUID& () const { return guid; }
|
||||
operator GUID& () { return guid; }
|
||||
const GUID& operator ~() const { return guid; }
|
||||
|
||||
Guid& operator = (const GUID& _guid) { guid = _guid; return *this; }
|
||||
|
||||
bool IsNullInstance() const;
|
||||
bool IsEmpty() const { return IsNullInstance(); }
|
||||
void Clear() { Zero(guid); }
|
||||
|
||||
operator String () const { return UPP::Format(guid); }
|
||||
String CFormat() const { return UPP::CFormat(guid); }
|
||||
|
||||
void Serialize(Stream& stream) { UPP::Serialize(stream, guid); }
|
||||
|
||||
private:
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline hash_t GetHashValue(const Guid& guid) { return GetHashValue(~guid); }
|
||||
template <>
|
||||
inline String AsString(const GUID& guid) { return Format(guid); }
|
||||
template <>
|
||||
inline String AsString(const Guid& guid) { return Format(~guid); }
|
||||
|
||||
inline bool operator == (const Guid& a, const Guid& b) { return ~a == ~b; }
|
||||
inline bool operator != (const Guid& a, const Guid& b) { return ~a != ~b; }
|
||||
|
||||
class OleExc : public Exc
|
||||
{
|
||||
public:
|
||||
OleExc(HRESULT hresult);
|
||||
OleExc(HRESULT hresult, const char *text);
|
||||
|
||||
public:
|
||||
HRESULT hresult;
|
||||
};
|
||||
|
||||
HRESULT LogResult(HRESULT hr);
|
||||
HRESULT LogError(HRESULT hr);
|
||||
|
||||
inline void OleVerify(HRESULT hr) { if(FAILED(hr)) throw OleExc(hr); }
|
||||
inline void OleVerify(HRESULT hr, const char *text) { if(FAILED(hr)) throw OleExc(hr, text); }
|
||||
|
||||
#define OLE_VERIFY(c) OleVerify(c, #c)
|
||||
|
||||
class OleVariant : public VARIANT
|
||||
{
|
||||
public:
|
||||
OleVariant(int vtype = VT_EMPTY) { VariantInit(this); vt = vtype; }
|
||||
OleVariant(const OleVariant& o) { VariantInit(this); VariantCopy(this, const_cast<OleVariant *>(&o)); }
|
||||
~OleVariant() { VariantClear(this); }
|
||||
OleVariant(const VARIANT& var) { VariantInit(this); VariantCopy(this, const_cast<VARIANT *>(&var)); }
|
||||
|
||||
OleVariant& operator = (const OleVariant& var) { if(this != &var) { VariantClear(this); VariantCopy(this, const_cast<VARIANT *>((VARIANT *)&var)); } return *this; }
|
||||
|
||||
VARIANT operator ~ () const { VARIANT v; VariantInit(&v); VariantCopy(&v, const_cast<OleVariant *>(this)); return v; }
|
||||
};
|
||||
|
||||
Value AsValue(const VARIANT& variant);
|
||||
OleVariant AsVariant(Value value);
|
||||
|
||||
//inline ULARGE_INTEGER AsULarge(dword value) { ULARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
//inline LARGE_INTEGER AsLarge(int value) { LARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
inline ULARGE_INTEGER AsULarge(int64 value) { ULARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
inline LARGE_INTEGER AsLarge(int64 value) { LARGE_INTEGER i; i.QuadPart = value; return i; }
|
||||
|
||||
double GetCurrency(const win32_CY_& currency);
|
||||
inline DATE ToDATE(Date date) { return date - Date(1899, 12, 30); }
|
||||
inline DATE ToDATE(Time time) { return (time - Time(1899, 12, 30)) / 86400.0; }
|
||||
inline Time FromDATE(DATE date) { return Time(1899, 12, 30) + (int64)floor(date * 86400.0 + 0.5); }
|
||||
|
||||
OleVariant ValueToVariant(Value v);
|
||||
void ReturnVariant(VARIANT *var, Value v);
|
||||
|
||||
inline WString BSTRToWString(BSTR bstr) { return WString((wchar *)bstr, SysStringLen(bstr)); }
|
||||
inline BSTR WStringToBSTR(WString w) { return SysAllocStringLen((BSTR)~w, w.GetLength()); }
|
||||
String BSTRToString(BSTR bstr);
|
||||
BSTR StringToBSTR(String s);
|
||||
|
||||
void ReturnString(BSTR *dest, String s);
|
||||
HRESULT CheckReturnString(BSTR *bstr, String s);
|
||||
void ReturnWString(BSTR *dest, WString s);
|
||||
HRESULT CheckReturnWString(BSTR *bstr, WString s);
|
||||
|
||||
ValueArray SAFEARRAYToValueArray(SAFEARRAY *array);
|
||||
Vector<WString> SAFEARRAYToWStringVector(SAFEARRAY *array);
|
||||
SAFEARRAY *ToSAFEARRAY(const ValueArray& varray);
|
||||
SAFEARRAY *ToSAFEARRAY(const Vector<WString>& varray);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
|
||||
class OleSafeArray {
|
||||
public:
|
||||
OleSafeArray() : array(NULL) {}
|
||||
OleSafeArray(const ValueArray& va) { array = ToSAFEARRAY(va); }
|
||||
OleSafeArray(const Vector<WString>& vs) { array = ToSAFEARRAY(vs); }
|
||||
OleSafeArray(const OleSafeArray& a) { array = NULL; if(a.array) OleVerify(SafeArrayCopy(a.array, &array)); }
|
||||
~OleSafeArray() { if(array) SafeArrayDestroy(array); }
|
||||
|
||||
operator ValueArray () const { return SAFEARRAYToValueArray(array); }
|
||||
operator Vector<WString> () const { return SAFEARRAYToWStringVector(array); }
|
||||
SAFEARRAY *operator ~ () const { return array; }
|
||||
|
||||
private:
|
||||
SAFEARRAY *array;
|
||||
};
|
||||
|
||||
class OleBstr
|
||||
{
|
||||
public:
|
||||
OleBstr(const Nuller& = Null) : bstr(NULL) {}
|
||||
OleBstr(WString w) : bstr(WStringToBSTR(w)) {}
|
||||
OleBstr(String s) : bstr(StringToBSTR(s)) {}
|
||||
~OleBstr() { if(bstr) SysFreeString(bstr); }
|
||||
|
||||
void Clear() { if(bstr) { SysFreeString(bstr); bstr = NULL; } }
|
||||
BSTR *Set() { Clear(); return &bstr; }
|
||||
|
||||
operator WString () const { return BSTRToWString(bstr); }
|
||||
operator String () const { return BSTRToString(bstr); }
|
||||
String ToString() const { return BSTRToString(bstr); }
|
||||
// operator BSTR () const { return bstr; }
|
||||
BSTR operator ~ () const { return bstr; }
|
||||
int GetLength() const { return SysStringLen(bstr); }
|
||||
|
||||
private:
|
||||
BSTR bstr;
|
||||
};
|
||||
|
||||
inline const RECTL& ToRectL(const Rect& rc) { return reinterpret_cast<const RECTL&>(rc); }
|
||||
inline const Rect& ToRect(const RECTL& rc) { return reinterpret_cast<const Rect&>(rc); }
|
||||
|
||||
Color PackColor(long rgb);
|
||||
long UnpackColor(Color c);
|
||||
HRESULT CheckReturnColor(long *ptr, Color c);
|
||||
|
||||
template <class T>
|
||||
class IRefBase : Moveable< IRefBase<T> >
|
||||
{
|
||||
public:
|
||||
IRefBase(T *ptr = NULL) : ptr(ptr) { if(ptr) ptr->AddRef(); }
|
||||
IRefBase(const IRefBase& i) { if(ptr = i.ptr) ptr->AddRef(); }
|
||||
~IRefBase() { if(ptr) ptr->Release(); }
|
||||
|
||||
static GUID GetIID() { return __uuidof(T); }
|
||||
|
||||
HRESULT Create(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER)
|
||||
{ return CoCreateInstance(clsid, NULL, flags, GetIID(), (void **)Set()); }
|
||||
|
||||
void Clear() { if(ptr) { ptr->Release(); ptr = 0; } }
|
||||
|
||||
T *operator->() const { ASSERT(ptr); return ptr; }
|
||||
T& operator * () const { ASSERT(ptr); return *ptr; }
|
||||
T *operator ~ () const { return ptr; }
|
||||
|
||||
T **Set() { Clear(); return &ptr; }
|
||||
IUnknown **SetUnk() { Clear(); return (IUnknown **)&ptr; }
|
||||
void **SetVoid() { Clear(); return (void **)&ptr; }
|
||||
void Set(T *p) { T *old = ptr; if(ptr = p) ptr->AddRef(); if(old) old->Release(); }
|
||||
|
||||
bool operator !() const { return !ptr; }
|
||||
|
||||
T *AddRef() { if(ptr) ptr->AddRef(); return ptr; }
|
||||
T *Detach() { T *out = ptr; ptr = 0; return out; }
|
||||
T *operator - () { return Detach(); }
|
||||
|
||||
protected:
|
||||
mutable T *ptr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class IRef : public Moveable< IRef<T>, IRefBase<T> >
|
||||
{
|
||||
public:
|
||||
IRef() {}
|
||||
IRef(IUnknown *u) { if(u) OleVerify(u->QueryInterface(__uuidof(T), (void **)&ptr)); }
|
||||
IRef(T *t) { if(ptr = t) ptr->AddRef(); }
|
||||
IRef(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER) { OleVerify(Create(clsid, flags)); }
|
||||
IRef(const IRef<T>& x) : Moveable< IRef<T>, IRefBase<T> >(x) {}
|
||||
explicit IRef(const VARIANT& v)
|
||||
{
|
||||
ptr = NULL;
|
||||
if(v.vt == VT_DISPATCH)
|
||||
OleVerify(v.pdispVal->QueryInterface(__uuidof(T), (void **)&ptr));
|
||||
else if(v.vt == VT_UNKNOWN)
|
||||
OleVerify(v.punkVal->QueryInterface(__uuidof(T), (void **)&ptr));
|
||||
else
|
||||
{
|
||||
ASSERT(v.vt == VT_EMPTY || v.vt == VT_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
IRef& operator = (const IRef<T>& x) { Set(x.ptr); return *this; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class IRef<IUnknown> : public IRefBase<IUnknown>
|
||||
{
|
||||
public:
|
||||
IRef() {}
|
||||
IRef(IUnknown *u) : IRefBase<IUnknown>(u) {}
|
||||
IRef(const GUID& clsid, dword flags = CLSCTX_INPROC_SERVER) { OleVerify(Create(clsid, flags)); }
|
||||
IRef(const IRef<IUnknown>& x) : IRefBase<IUnknown>(x.ptr) {}
|
||||
|
||||
IRef& operator = (const IRef<IUnknown>& x) { Set(x.ptr); return *this; }
|
||||
};
|
||||
|
||||
Value DispatchToValue(IDispatch *disp);
|
||||
Value UnknownToValue(IUnknown *unk);
|
||||
|
||||
template <class I>
|
||||
OleVariant DispVar(I& iface)
|
||||
{
|
||||
IRef<IDispatch> disp = iface;
|
||||
OleVariant out(VT_DISPATCH);
|
||||
if(!!disp) disp->AddRef();
|
||||
out.pdispVal = ~disp;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct OleType : Moveable< OleType<T> >
|
||||
{
|
||||
friend T *Ptr(T& t) { return reinterpret_cast<T *>(&reinterpret_cast<char &>(t)); }
|
||||
friend T& Deref(T *t) { return reinterpret_cast<T&>(*reinterpret_cast<char *>(t)); }
|
||||
friend void Destroy(T& t) { t.~T(); }
|
||||
friend T& Construct(T& t) { return Deref(new(Ptr(t)) T); }
|
||||
friend void CopyConstruct(T& t, T& x) { new(Ptr(t)) T(x); }
|
||||
friend void DeepCopyConstruct(T& t, const T& x) { new(Ptr(t)) T(x); }
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
inline HRESULT QueryInterface(T& src, U& dest, const GUID& guid)
|
||||
{
|
||||
return src->QueryInterface(guid, (void **)dest.Set());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline HRESULT QueryInterface(T& src, U& dest)
|
||||
{
|
||||
return QueryInterface(src, dest, dest.GetIID());
|
||||
}
|
||||
|
||||
class OleStream : public BlockStream
|
||||
{
|
||||
public:
|
||||
OleStream(IUnknown *stream = 0);
|
||||
|
||||
bool Open(IUnknown *stream);
|
||||
virtual void Close();
|
||||
virtual bool IsOpen() const { return istream; }
|
||||
|
||||
protected:
|
||||
virtual void SetStreamSize(dword size);
|
||||
virtual dword Read(int64 at, void *ptr, dword size);
|
||||
virtual void Write(int64 at, const void *data, dword size);
|
||||
|
||||
void RawSeek(int64 pos);
|
||||
|
||||
protected:
|
||||
IStreamPtr istream;
|
||||
int64 current_offset;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue