Index: trunk/ab5.0/ablib/src/com/bstring.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/bstring.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/bstring.ab	(revision 709)
@@ -5,5 +5,5 @@
 
 Class BString
-	Implements System.IDisposable ', System.ICloneable
+	Implements System.IDisposable, System.ICloneable
 Public
 	Sub BString()
@@ -15,19 +15,11 @@
 	End Sub
 
-	Sub BString(s As BString)
-		If Not IsNothing(s) Then
-			bs = copy(s.bs)
-		End If
-	End Sub
-
 	Sub BString(s As LPCOLESTR, len As DWord)
-		If s <> 0 Then
-			bs = SysAllocStringLen(s, len)
-		End If
+		init(s, len)
 	End Sub
 
 	Sub BString(s As String)
 		If Not IsNothing(s) Then
-			Init(s.StrPtr, s.Length As DWord)
+			init(s.StrPtr, s.Length As DWord)
 		End If
 	End Sub
@@ -73,9 +65,9 @@
 	End Function
 
-	/*Override*/ Function Clone() As BString
-		Return New BString(This)
-	End Function
-
-	/*Override*/ Sub Dispose()
+	Function Clone() As BString
+		Return New BString(bs, Length)
+	End Function
+
+	Sub Dispose()
 		Clear()
 	End Sub
@@ -103,10 +95,10 @@
 
 	Const Function Length() As DWord
-		Length = GetDWord(bs As VoidPtr - SizeOf (DWord)) 'SysStringLen(bs)
+		Length = SysStringLen(bs)
 	End Function
 
 	Const Function Operator [](i As SIZE_T) As OLECHAR
 		If i > Length Then
-			Throw New ArgumentOutOfRangeException("i")
+			Throw New System.ArgumentOutOfRangeException("i - BString.Operator [] (get)")
 		End If
 		Return bs[i]
@@ -115,5 +107,5 @@
 	Sub Operator []=(i As SIZE_T, c As OLECHAR)
 		If i > Length Then
-			Throw New ArgumentOutOfRangeException("i")
+			Throw New System.ArgumentOutOfRangeException("i - BString.Operator [] (set)")
 		End If
 		bs[i] = c
@@ -148,5 +140,5 @@
 			End If
 		Else
-			If IsNullOrEmpty(bsr) Then
+			If IsNullOrEmpty(r) Then
 				Compare = 1
 			Else
@@ -156,5 +148,5 @@
 	End Function
 
-	Static Function IsNullOrEmpty(s As BString)
+	Static Function IsNullOrEmpty(s As BString) As Boolean
 		If IsNothing(s) Then
 			IsNullOrEmpty = True
@@ -196,15 +188,21 @@
 
 	Sub init(s As PCSTR, len As DWord)
-		If <> 0 Then
-			Dim lenBS = MultiByteToWideChar(CP_THREAD_ACP, 0, s, len As Long, 0, 0)
+		If s <> 0 Then
+			Dim lenBS = MultiByteToWideChar(CP_ACP, 0, s, len As Long, 0, 0)
 			bs = SysAllocStringLen(0, lenBS)
 			If bs <> 0 Then
-				MultiByteToWideChar(CP_THREAD_ACP, 0, s, len As Long, bs, lenBS)
-			End If
+				MultiByteToWideChar(CP_ACP, 0, s, len As Long, bs, lenBS)
+			End If
+		End If
+	End Sub
+
+	Sub init(s As PCWSTR, len As DWord)
+		If s <> 0 Then
+			bs = SysAllocStringLen(s, len)
 		End If
 	End Sub
 
 	Sub reset(newBS As BSTR)
-		Dim old = InterlockedExchangePointer(bs, newBS)
+		Dim old = InterlockedExchangePointer(ByVal VarPtr(bs) As *VoidPtr, newBS)
 		SysFreeString(old)
 	End Sub
@@ -215,5 +213,5 @@
 
 	Static Function move(ByRef src As BSTR) As BSTR
-		move = InterlockedExchangePointer(src, 0)
+		move = InterlockedExchangePointer(ByVal VarPtr(src) As *VoidPtr, 0)
 	End Function
 End Class
Index: trunk/ab5.0/ablib/src/com/currency.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/currency.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/currency.ab	(revision 709)
@@ -7,9 +7,9 @@
 
 Class Currency
+	Implements System.ICloneable, System.IEquatable<Currency>', System.IComparable<Currency>
 Public
 	Sub Currency()
 		cy = 0
 	End Sub
-
 /*
 	Sub Currency(x As CY)
@@ -25,34 +25,38 @@
 	End Sub
 */
-/*
-	Const Function Operator +() As Currency
-		Return New Currency(This)
-	End Function
-*/
-	Const Function Operator -() As Currency
-		Dim ret = New Currency
-		VarCyNeg(This.cy, ret.cy)
-		Return ret
-	End Function
-
-	Const Function Operator *(y As Currency) As Currency
-		Dim ret = New Currency
-		VarCyMul(This.cy, y.cy, ret.cy)
-		Return ret
-	End Function
-
-	Const Function Operator *(y As Long) As Currency
-		Dim ret = New Currency
-		VarCyMulI4(This.cy, y, ret.cy)
-		Return ret
-	End Function
-
-	Const Function Operator *(y As Int64) As Currency
-		Dim ret = New Currency
-		VarCyMulI8(This.cy, y, ret.cy)
-		Return ret
-	End Function
-
-	Const Function Operator /(y As Variant) As Double
+	Static Function FromCy(cy As CY) As Currency
+		FromCy = New Currency
+		FromCy.cy = cy
+	End Function
+
+	Function Operator +() As Currency
+		Return FromCy(cy)
+	End Function
+
+	Function Operator -() As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCyNeg(This.cy, ret.cy))
+		Return ret
+	End Function
+
+	Function Operator *(y As Currency) As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCyMul(This.cy, y.cy, ret.cy))
+		Return ret
+	End Function
+
+	Function Operator *(y As Long) As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCyMulI4(This.cy, y, ret.cy))
+		Return ret
+	End Function
+
+	Function Operator *(y As Int64) As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCyMulI8(This.cy, y, ret.cy))
+		Return ret
+	End Function
+
+	Function Operator /(y As Variant) As Double
 		Dim vx = New Variant(This)
 		Dim ret = vx / y
@@ -60,5 +64,5 @@
 	End Function
 
-	Const Function Operator /(y As Currency) As Double
+	Function Operator /(y As Currency) As Double
 		Dim vx = New Variant(This)
 		Dim vy = New Variant(y)
@@ -67,13 +71,13 @@
 	End Function
 
-	Const Function Operator +(y As Currency) As Currency
-		Dim ret = New Currency
-		VarCyAdd(This.cy, y.cy, ret.cy)
-		Return ret
-	End Function
-
-	Const Function Operator -(y As Currency) As Currency
-		Dim ret = New Currency
-		VarCySub(This.cy, y.cy, ret.cy)
+	Function Operator +(y As Currency) As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCyAdd(This.cy, y.cy, ret.cy))
+		Return ret
+	End Function
+
+	Function Operator -(y As Currency) As Currency
+		Dim ret = New Currency
+		Windows.ThrowIfFailed(VarCySub(This.cy, y.cy, ret.cy))
 		Return ret
 	End Function
@@ -99,115 +103,119 @@
 	End Function
 
-	Const Function Operator ==(y As Currency) As Boolean
+	Function Operator ==(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_EQ
 	End Function
 
-	Const Function Operator ==(y As Double) As Boolean
+	Function Operator ==(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_EQ
 	End Function
 
-	Const Function Operator <>(y As Currency) As Boolean
+	Function Operator <>(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c <> VARCMP_EQ
 	End Function
 
-	Const Function Operator <>(y As Double) As Boolean
+	Function Operator <>(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c <> VARCMP_EQ
 	End Function
 
-	Const Function Operator <(y As Currency) As Boolean
+	Function Operator <(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT
 	End Function
 
-	Const Function Operator <(y As Double) As Boolean
+	Function Operator <(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT
 	End Function
 
-	Const Function Operator >(y As Currency) As Boolean
+	Function Operator >(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT
 	End Function
 
-	Const Function Operator >(y As Double) As Boolean
+	Function Operator >(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT
 	End Function
 
-	Const Function Operator <=(y As Currency) As Boolean
+	Function Operator <=(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT Or c = VARCMP_EQ
 	End Function
 
-	Const Function Operator <=(y As Double) As Boolean
+	Function Operator <=(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT Or c = VARCMP_EQ
 	End Function
 
-	Const Function Operator >=(y As Currency) As Boolean
+	Function Operator >=(y As Currency) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT Or c = VARCMP_EQ
 	End Function
 
-	Const Function Operator >=(y As Double) As Boolean
+	Function Operator >=(y As Double) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT Or c = VARCMP_EQ
 	End Function
 
-	Const Function Abs() As Currency
+	Function Abs() As Currency
 		Abs = New Currency
-		VarCyAbs(This.cy, Abs.cy)
-	End Function
-
-	Const Function Fix() As Currency
+		Windows.ThrowIfFailed(VarCyAbs(This.cy, Abs.cy))
+	End Function
+
+	Function Fix() As Currency
 		Fix = New Currency
-		VarCyFix(This.cy, Fix.cy)
-	End Function
-
-	Const Function Int() As Currency
+		Windows.ThrowIfFailed(VarCyFix(This.cy, Fix.cy))
+	End Function
+
+	Function Int() As Currency
 		Int = New Currency
-		VarCyInt(This.cy, Int.cy)
-	End Function
-
-	Const Function Round(c = 0 As Long) As Currency
+		Windows.ThrowIfFailed(VarCyInt(This.cy, Int.cy))
+	End Function
+
+	Function Round(c = 0 As Long) As Currency
 		Round = New Currency
-		VarCyRound(This.cy, c, Round.cy)
-	End Function
-
-	Const Function Cy() As CY
+		Windows.ThrowIfFailed(VarCyRound(This.cy, c, Round.cy))
+	End Function
+
+	Function Cy() As CY
 		Cy = cy
 	End Function
 
-	Sub Cy(c As CY)
-		cy = c
-	End Sub
-
-	Const Function ToDouble() As Double
+	Function ToDouble() As Double
 		VarR8FromCy(cy, ToDouble)
 	End Function
 
-	Const Function ToInt64() As Int64
+	Function ToInt64() As Int64
 		VarI8FromCy(cy, ToInt64)
 	End Function
 
-	Const Function ToVariant() As Variant
+	Function ToVariant() As Variant
 		Return New Variant(This)
 	End Function
 
 	Override Function ToString() As String
-		/*Using*/ Dim bstr = New BString
+		Using bstr = New BString
 			Dim bs As BSTR
 			VarBstrFromCy(cy, LOCALE_USER_DEFAULT, LOCALE_USE_NLS, bs)
 			bstr.Attach(bs)
-			ToString = bstr.ToString
-		bstr.Dispose() 'End Using
+			ToString = bstr.ToString()
+		End Using
 	End Function
 
 	Override Function GetHashCode() As Long
-		Return HIDWORD(cy) Xor LODWORD(cy)
+		Return (HIDWORD(cy) Xor LODWORD(cy)) As Long
+	End Function
+
+	Override Function Equals(y As Object) As Boolean
+		If This.GetType().Equals(y.GetType()) Then
+			Equals = Equals(y As Currency)
+		Else
+			Equals = False
+		End If
 	End Function
 
@@ -215,4 +223,19 @@
 		Dim c = Compare(This, y)
 		Return c = VARCMP_EQ
+	End Function
+
+	Function CompareTo(y As Currency) As Long
+		Dim c = Compare(This, y)
+		If c = VARCMP_GT Then
+			CompareTo = 1
+		ElseIf c = VARCMP_LT Then
+			CompareTo = -1
+		Else
+			CompareTo = 0
+		End If
+	End Function
+
+	Function Clone() As Currency
+		Clone = This
 	End Function
 Private
Index: trunk/ab5.0/ablib/src/com/decimal.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/decimal.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/decimal.ab	(revision 709)
@@ -8,5 +8,7 @@
 
 Class Decimal
+	Implements System.ICloneable, System.IEquatable<Decimal>', System.IComparable<Decimal>
 Public
+
 	Sub Decimal()
 	End Sub
@@ -22,5 +24,5 @@
 	Sub Decimal(lo As Long, mid As Long, hi As Long, isNegative As Boolean, scale As Byte)
 		If scale > 28 Then
-			Throw New ArgumentOutOfRangeException("scale")
+			Throw New System.ArgumentOutOfRangeException("scale - Decimal constructor")
 		End If
 		Dim sign As Byte
@@ -36,27 +38,27 @@
 
 	Sub Decimal(x As Long)
-		VarDecFromI4(x, dec)
+		Windows.ThrowIfFailed(VarDecFromI4(x, dec))
 	End Sub
 
 	Sub Decimal(x As DWord)
-		VarDecFromUI4(x, dec)
+		Windows.ThrowIfFailed(VarDecFromUI4(x, dec))
 	End Sub
 
 	Sub Decimal(x As Int64)
-		VarDecFromI8(x, dec)
+		Windows.ThrowIfFailed(VarDecFromI8(x, dec))
 	End Sub
 
 	Sub Decimal(x As QWord)
-		VarDecFromUI8(x, dec)
+		Windows.ThrowIfFailed(VarDecFromUI8(x, dec))
 	End Sub
 
 	Sub Decimal(x As Single)
-		VarDecFromR4(x, dec)
+		Windows.ThrowIfFailed(VarDecFromR4(x, dec))
 	End Sub
 
 	Sub Decimal(x As Double)
-		VarDecFromR8(x, dec)
-	End Sub
-/*
+		Windows.ThrowIfFailed(VarDecFromR8(x, dec))
+	End Sub
+
 	Const Function Operator() As Variant
 		Return New Variant(This)
@@ -197,12 +199,12 @@
 	End Function
 */
-/*
+
 	Const Function Operator +() As Decimal
 		Return New Decimal(dec)
 	End Function
-*/
+
 	Const Function Operator -() As Decimal
 		Dim ret = New Decimal
-		VarDecNeg(This.dec, ret.dec)
+		Windows.ThrowIfFailed(VarDecNeg(This.dec, ret.dec))
 		Return ret
 	End Function
@@ -210,5 +212,5 @@
 	Const Function Operator *(y As Decimal) As Decimal
 		Dim ret = New Decimal
-		VarDecMul(This.dec, y.dec, ret.dec)
+		Windows.ThrowIfFailed(VarDecMul(This.dec, y.dec, ret.dec))
 		Return ret
 	End Function
@@ -216,5 +218,5 @@
 	Const Function Operator /(y As Decimal) As Decimal
 		Dim ret = New Decimal
-		VarDecDiv(This.dec, y.dec, ret.dec)
+		Windows.ThrowIfFailed(VarDecDiv(This.dec, y.dec, ret.dec))
 		Return ret
 	End Function
@@ -222,5 +224,5 @@
 	Const Function Operator +(y As Decimal) As Decimal
 		Dim ret = New Decimal
-		VarDecAdd(This.dec, y.dec, ret.dec)
+		Windows.ThrowIfFailed(VarDecAdd(This.dec, y.dec, ret.dec))
 		Return ret
 	End Function
@@ -228,12 +230,14 @@
 	Const Function Operator -(y As Decimal) As Decimal
 		Dim ret = New Decimal
-		VarDecSub(This.dec, y.dec, ret.dec)
-		Return ret
-	End Function
-
+		Windows.ThrowIfFailed(VarDecSub(This.dec, y.dec, ret.dec))
+		Return ret
+	End Function
+
+	' ThrowIfFailedしていないことに注意
 	Static Function Compare(x As Decimal, y As Decimal) As HRESULT
-		Return VarDecCmp(x.dec, y.dec)
-	End Function
-
+		Compare = VarDecCmp(x.dec, y.dec)
+	End Function
+
+	' ThrowIfFailedしていないことに注意
 	Static Function Compare(x As Decimal, y As Double) As HRESULT
 		Return VarDecCmpR8(x.dec, y)
@@ -314,20 +318,20 @@
 	Const Function Abs() As Decimal
 		Abs = New Decimal
-		VarDecAbs(This.dec, Abs.dec)
+		Windows.ThrowIfFailed(VarDecAbs(This.dec, Abs.dec))
 	End Function
 
 	Const Function Fix() As Decimal
 		Fix = New Decimal
-		VarDecFix(This.dec, Fix.dec)
+		Windows.ThrowIfFailed(VarDecFix(This.dec, Fix.dec))
 	End Function
 
 	Const Function Int() As Decimal
 		Int = New Decimal
-		VarDecInt(This.dec, Int.dec)
+		Windows.ThrowIfFailed(VarDecInt(This.dec, Int.dec))
 	End Function
 
 	Const Function Round(c = 0 As Long) As Decimal
 		Round = New Decimal
-		VarDecRound(This.dec, c, Round.dec)
+		Windows.ThrowIfFailed(VarDecRound(This.dec, c, Round.dec))
 	End Function
 
@@ -336,19 +340,19 @@
 	End Function
 
-	Sub Dec(ByRef d As DECIMAL)
-		dec = d
-	End Sub
-
 	Const Function ToVariant() As Variant
 		Return New Variant(This)
 	End Function
 
+	Function ToBString() As BString
+		ToBString = New BString
+		Dim bs As BSTR
+		VarBstrFromDec(dec, LOCALE_USER_DEFAULT, LOCALE_USE_NLS, bs)
+		ToBString.Attach(bs)
+	End Function
+
 	Override Function ToString() As String
-		/*Using*/ Dim bstr = New BString
-			Dim bs As BSTR
-			VarBstrFromDec(dec, LOCALE_USER_DEFAULT, LOCALE_USE_NLS, bs)
-			bstr.Attach(bs)
+		Using bstr = ToBString()
 			ToString = bstr.ToString
-		bstr.Dispose() 'End Using
+		End Using
 	End Function
 
@@ -362,4 +366,15 @@
 		Return c = VARCMP_EQ
 	End Function
+
+	Override Function Equals(y As Object) As Boolean
+		If This.GetType().Equals(y.GetType()) Then
+			Equals = Equals(y As Decimal)
+		End If
+	End Function
+
+	Function Clone() As Decimal
+		Clone = New Decimal(This)
+	End Function
+
 Private
 	dec As DECIMAL
Index: trunk/ab5.0/ablib/src/com/index.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/index.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/index.ab	(revision 709)
@@ -1,5 +1,5 @@
 #require <com/bstring.ab>
 #require <com/variant.ab>
-'#require <com/vbobject.ab>
+#require <com/vbobject.ab>
 #require <com/currency.ab>
 #require <com/decimal.ab>
Index: trunk/ab5.0/ablib/src/com/variant.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/variant.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/variant.ab	(revision 709)
@@ -7,4 +7,5 @@
 
 Class Variant
+	Implements System.IDisposable, System.ICloneable
 Public
 	Sub Variant()
@@ -12,4 +13,10 @@
 	End Sub
 
+	Sub Variant(ByRef y As VARIANT)
+		VariantInit(v)
+		VariantCopy(v, y)
+	End Sub
+
+	' 仮
 	Sub Variant(y As Variant)
 		VariantInit(v)
@@ -17,9 +24,4 @@
 	End Sub
 
-	Sub Variant(ByRef y As VARIANT)
-		VariantInit(v)
-		VariantCopy(v, y)
-	End Sub
-
 	Sub Variant(n As SByte)
 		v.vt = VT_I1
@@ -74,9 +76,9 @@
 	Sub Variant(bs As BString)
 		v.vt = VT_BSTR
-		SetPointer(VarPtr(v.val), bs.Copy))
+		SetPointer(VarPtr(v.val), bs.Copy())
 	End Sub
 
 	Sub Variant(unk As IUnknown)
-		If Not IsNothing(unk) Then unk.AddRef()
+		If ObjPtr(unk) <> 0 Then unk.AddRef()
 		v.vt = VT_UNKNOWN
 		SetPointer(VarPtr(v.val), ObjPtr(unk))
@@ -84,5 +86,5 @@
 
 	Sub Variant(disp As IDispatch)
-		If Not IsNothing(disp) Then disp.AddRef()
+		If ObjPtr(disp) <> 0 Then disp.AddRef()
 		v.vt = VT_DISPATCH
 		SetPointer(VarPtr(v.val), ObjPtr(disp))
@@ -104,6 +106,26 @@
 
 	Sub Variant(s As String)
-		ValStr = New BString(s)
-	End Sub
+		v.vt = VT_BSTR
+		If IsNothing(s) Then
+			initWithStr(0)
+		Else
+			initWithStr(0)
+		End If
+	End Sub
+
+	Sub Variant(s As BSTR)
+		initWithStr(s)
+	End Sub
+Private
+	Sub initWithStr(bs As BSTR)
+		v.vt = VT_BSTR
+		If bs = NULL Then
+			SetPointer(VarPtr(v.val), SysAllocStringLen(0, 0))
+		Else
+			SetPointer(VarPtr(v.val), SysAllocStringByteLen(bs As PCSTR, SysStringByteLen(bs)))
+		End If
+	End Sub
+
+Public
 
 	Sub Variant(n As Currency)
@@ -118,31 +140,22 @@
 	End Sub
 
-
 	Sub ~Variant()
-		Clear()
-	End Sub
-
-	Sub Clear()
+		Dispose()
+	End Sub
+
+	Sub Dispose()
 		VariantClear(v)
 		v.vt = VT_EMPTY
 	End Sub
 
-	Sub Assign(from As Variant)
-		Assign(from.v)
-	End Sub
-
-	Sub Assign(ByRef from As VARIANT)
-		Variant.Copy(v, from)
-	End Sub
-
-	Sub AssignInd(ByRef from As VARIANT)
-		VariantCopyInd(v, from)
-	End Sub
-
-	Sub Attach(ByRef from As VARIANT)
-		Variant.Move(v, from)
-	End Sub
-
-	Const Function Copy() As VARIANT
+	Sub Clear()
+		Dispose()
+	End Sub
+
+	Virtual Function Clone() As Variant
+		Clone = New Variant(This)
+	End Function
+
+	Function Copy() As VARIANT
 		Variant.Copy(Copy, v)
 	End Function
@@ -151,96 +164,101 @@
 		Variant.Move(Detach, v)
 	End Function
-/*
-	Static Function Assgin(ByRef from As VARIANT) As Variant
-		Assign = New Variant
-		Assgin.Assign(from)
+
+	Static Function CopyFrom(ByRef from As VARIANT) As Variant
+		CopyFrom = New Variant
+		Variant.Copy(CopyFrom.v, from)
 	End Function
 
 	Static Function Attach(ByRef from As VARIANT) As Variant
 		Attach = New Variant
-		Attach.Attach(from)
-	End Function
-*/
+		Variant.Move(Attach.v, from)
+	End Function
+
+	Static Function CopyIndirectFrom(ByRef from As VARIANT) As Variant
+		CopyIndirectFrom = New Variant
+		VariantCopyInd(CopyIndirectFrom.v, from)
+	End Function
+
 	'Operators
 /*
-	Const Function Operator ^(y As Variant) As Variant
-		Dim ret = New Variant
-		VarPow(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator +() As Variant
-		Return New Variant(This)
-	End Function
-
-	Const Function Operator -() As Variant
-		Dim ret = New Variant
-		VarNeg(This.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator *(y As Variant) As Variant
-		Dim ret = New Variant
-		VarMul(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator /(y As Variant) As Variant
-		Dim ret = New Variant
-		VarDiv(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator \(y As Variant) As Variant
-		Dim ret = New Variant
-		VarIdiv(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator Mod(y As Variant) As Variant
-		Dim ret = New Variant
-		VarMod(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator +(y As Variant) As Variant
-		Dim ret = New Variant
-		VarAdd(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator -(y As Variant) As Variant
-		Dim ret = New Variant
-		VarSub(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator &(y As Variant) As Variant
-		Dim ret = New Variant
-		VarCat(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator And(y As Variant) As Variant
-		Dim ret = New Variant
-		VarAnd(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator Or(y As Variant) As Variant
-		Dim ret = New Variant
-		VarOr(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator Xor(y As Variant) As Variant
-		Dim ret = New Variant
-		VarXor(This.v, y.v, ret.v)
-		Return ret
-	End Function
-
-	Const Function Operator Not() As Variant
-		Dim ret = New Variant
-		VarNot(This.v, ret.v)
+	Function Operator ^(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarPow(This.v, y.v, ret.v))
+		Return ret
+	End Function
+*/
+	Function Operator +() As Variant
+'		Return Clone()
+	End Function
+
+	Function Operator -() As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarNeg(This.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator *(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarMul(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator /(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarDiv(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator \(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarIdiv(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator Mod(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarMod(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator +(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarAdd(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator -(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarSub(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator &(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarCat(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator And(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarAnd(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator Or(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarOr(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator Xor(y As Variant) As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarXor(This.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Operator Not() As Variant
+		Dim ret = New Variant
+		Windows.ThrowIfFailed(VarNot(This.v, ret.v))
 		Return ret
 	End Function
@@ -248,5 +266,5 @@
 	Static Function Imp(x As Variant, y As Variant) As Variant
 		Dim ret = New Variant
-		VarImp(x.v, y.v, ret.v)
+		Windows.ThrowIfFailed(VarImp(x.v, y.v, ret.v))
 		Return ret
 	End Function
@@ -254,28 +272,29 @@
 	Static Function Eqv(x As Variant, y As Variant) As Variant
 		Dim ret = New Variant
-		VarEqv(x.v, y.v, ret.v)
-		Return ret
-	End Function
-*/
-	Const Function Abs() As Variant
+		Windows.ThrowIfFailed(VarEqv(x.v, y.v, ret.v))
+		Return ret
+	End Function
+
+	Function Abs() As Variant
 		Abs = New Variant
-		VarAbs(This.v, Abs.v)
-	End Function
-
-	Const Function Fix() As Variant
+		Windows.ThrowIfFailed(VarAbs(This.v, Abs.v))
+	End Function
+
+	Function Fix() As Variant
 		Fix = New Variant
-		VarFix(This.v, Fix.v)
-	End Function
-
-	Const Function Int() As Variant
+		Windows.ThrowIfFailed(VarFix(This.v, Fix.v))
+	End Function
+
+	Function Int() As Variant
 		Int = New Variant
-		VarInt(This.v, Int.v)
-	End Function
-
-	Const Function Round(cDecimals = 0 As Long) As Variant
+		Windows.ThrowIfFailed(VarInt(This.v, Int.v))
+	End Function
+
+	Function Round(cDecimals = 0 As Long) As Variant
 		Round = New Variant
-		VarRound(This.v, cDecimals, Round.v)
-	End Function
-
+		Windows.ThrowIfFailed(VarRound(This.v, cDecimals, Round.v))
+	End Function
+
+	' ThrowIfFailedを使っていないことに注意
 	Static Function Compare(x As Variant, y As Variant, lcid As LCID, flags As DWord) As HRESULT
 		Return VarCmp(removeNull(x).v, removeNull(y).v, lcid, flags)
@@ -286,59 +305,52 @@
 	End Function
 
-	Const Function Operator ==(y As Variant) As Boolean
+	Function Operator ==(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_EQ
 	End Function
 
-	Const Function Operator <>(y As Variant) As Boolean
+	Function Operator <>(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c <> VARCMP_EQ
 	End Function
 
-	Const Function Operator <(y As Variant) As Boolean
+	Function Operator <(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT
 	End Function
 
-	Const Function Operator >(y As Variant) As Boolean
+	Function Operator >(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT
 	End Function
 
-	Const Function Operator <=(y As Variant) As Boolean
+	Function Operator <=(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_LT Or c = VARCMP_EQ
 	End Function
 
-	Const Function Operator >=(y As Variant) As Boolean
+	Function Operator >=(y As Variant) As Boolean
 		Dim c = Compare(This, y)
 		Return c = VARCMP_GT Or c = VARCMP_EQ
 	End Function
 
-	Const Function ChangeType(vt As VARTYPE, flags As Word) As Variant
+	Function ChangeType(vt As VARTYPE, flags = 0 As Word) As Variant
 		ChangeType = New Variant
-		ChangeType(ChangeType, flags, vt)
-	End Function
-
-	Const Function ChangeType(vt As VARTYPE) As Variant
-		Return ChangeType(vt, 0)
-	End Function
-
-	Const Function ChangeType(ByRef ret As VARIANT, flags As Word, vt As VARTYPE) As HRESULT
-		Return VariantChangeType(ret, v, flags, vt)
-	End Function
-
-	Const Function ChangeType(ByRef ret As Variant, flags As Word, vt As VARTYPE) As HRESULT
-		Return ChangeType(ret.v, flags, vt)
-	End Function
-
-	Const Function VarType() As VARTYPE
+		changeType(ChangeType.v, vt, flags)
+	End Function
+Private
+	Sub changeType(ByRef ret As VARIANT, vt As VARTYPE, flags = 0 As Word)
+		Windows.ThrowIfFailed(VariantChangeType(ret, v, flags, vt))
+	End Sub
+Public
+
+	Function VarType() As VARTYPE
 		Return v.vt
 	End Function
 
 	Override Function ToString() As String
-		/*Using*/ Dim bs = ValStr
-		ToString = bs.ToString
-		bstr.Dispose() 'End Using
+		Using bs = ValStr
+			ToString = bs.ToString()
+		End Using
 	End Function
 
@@ -348,202 +360,95 @@
 	End Function
 
-	Const Function ValUI1() As Byte
+	Function ValUI1() As Byte
 		Dim r = ChangeType(VT_UI1)
 		Return GetByte(VarPtr(r.v.val))
 	End Function
 
-	Sub ValUI1(x As Byte)
-		Clear()
-		SetByte(VarPtr(v.val), x)
-		v.vt = VT_UI1
-	End Sub
-
-	Const Function ValUI2() As Word
+	Function ValUI2() As Word
 		Dim r = ChangeType(VT_UI2)
 		Return GetWord(VarPtr(r.v.val))
 	End Function
 
-	Sub ValUI2(x As Word)
-		Clear()
-		SetWord(VarPtr(v.val), x)
-		v.vt = VT_UI2
-	End Sub
-
-	Const Function ValUI4() As DWord
+	Function ValUI4() As DWord
 		Dim r = ChangeType(VT_UI4)
 		Return GetDWord(VarPtr(r.v.val))
 	End Function
 
-	Sub ValUI4(x As DWord)
-		Clear()
-		SetDWord(VarPtr(v.val), x)
-		v.vt = VT_UI4
-	End Sub
-
-	Const Function ValUI8() As QWord
+	Function ValUI8() As QWord
 		Dim r = ChangeType(VT_UI8)
 		Return GetQWord(VarPtr(r.v.val))
 	End Function
 
-	Sub ValUI8(x As QWord)
-		Clear()
-		SetQWord(VarPtr(v.val), x)
-		v.vt = VT_UI8
-	End Sub
-
-	Const Function ValI1() As SByte
+	Function ValI1() As SByte
 		Dim r = ChangeType(VT_I1)
 		Return GetByte(VarPtr(r.v.val)) As SByte
 	End Function
 
-	Sub ValI1(x As SByte)
-		Clear()
-		SetByte(VarPtr(v.val), x As Byte)
-		v.vt = VT_I1
-	End Sub
-
-	Const Function ValI2() As Integer
+	Function ValI2() As Integer
 		Dim r = ChangeType(VT_I2)
 		Return GetWord(VarPtr(r.v.val)) As Integer
 	End Function
 
-	Sub ValI2(x As Integer)
-		Clear()
-		SetWord(VarPtr(v.val), x As Word)
-		v.vt = VT_I2
-	End Sub
-
-	Const Function ValI4() As Long
+	Function ValI4() As Long
 		Dim r = ChangeType(VT_I4)
 		Return GetDWord(VarPtr(r.v.val)) As Long
 	End Function
 
-	Sub ValI4(x As Long)
-		Clear()
-		SetDWord(VarPtr(v.val), x As DWord)
-		v.vt = VT_I4
-	End Sub
-
-	Const Function ValI8() As Int64
+	Function ValI8() As Int64
 		Dim r = ChangeType(VT_I8)
 		Return GetQWord(VarPtr(r.v.val)) As Int64
 	End Function
 
-	Sub ValI8(x As Int64)
-		Clear()
-		SetQWord(VarPtr(v.val), x As QWord)
-		v.vt = VT_I8
-	End Sub
-
-	Const Function ValR4() As Single
+	Function ValR4() As Single
 		Dim r = ChangeType(VT_R4)
 		Return GetSingle(VarPtr(r.v.val))
 	End Function
 
-	Sub ValR4(x As Single)
-		Clear()
-		SetDWord(VarPtr(v.val), x)
-		v.vt = VT_R4
-	End Sub
-
-	Const Function ValR8() As Double
+	Function ValR8() As Double
 		Dim r = ChangeType(VT_UI8)
 		Return GetDouble(VarPtr(r.v.val))
 	End Function
 
-	Sub ValR8(x As Double)
-		Clear()
-		SetDouble(VarPtr(v.val), x)
-		v.vt = VT_R8
-	End Sub
-
-	Const Function ValBool() As VARIANT_BOOL
+	Function ValBool() As VARIANT_BOOL
 		Dim r = ChangeType(VT_BOOL)
 		Return GetWord(VarPtr(r.v.val))
 	End Function
 
-	Sub ValBool(x As VARIANT_BOOL)
-		Clear()
-		SetWord(VarPtr(v.val), x)
-		v.vt = VT_BOOL
-	End Sub
-
-	Const Function ValError() As SCODE
+	Function ValError() As SCODE
 		Dim r = ChangeType(VT_ERROR)
 		Return GetDWord(VarPtr(r.v.val))
 	End Function
 
-	Sub ValError(x As SCODE)
-		Clear()
-		SetDWord(VarPtr(v.val), x)
-		v.vt = VT_ERROR
-	End Sub
-
-	Const Function ValCy() As Currency
+	Function ValCy() As Currency
 		Dim r = ChangeType(VT_CY)
-		ValCy = New Currency
-		ValCy.Cy = GetQWord(VarPtr(r.v.val))
-	End Function
-
-	Sub ValCy(x As Currency)
-		Clear()
-		SetQWord(VarPtr(v.val), x.Cy)
-		v.vt = VT_CY
-	End Sub
-	
+		ValCy = Currency.FromCy(GetQWord(VarPtr(r.v.val)))
+	End Function
+
 	'ValDate
 
-	Const Function ValStr() As BString
+	Function ValStr() As BString
 		ValStr = New BString
 		Dim r As VARIANT
-		ChangeType(r, VARIANT_ALPHABOOL, VT_BSTR)
+		changeType(r, VT_BSTR, VARIANT_ALPHABOOL)
 		ValStr.Attach(GetPointer(VarPtr(r.val)) As BSTR)
 	End Function
 
-	Sub ValStr(x As BString)
-		Clear()
-		v.vt = VT_BSTR
-		If IsNothing(x) Then
-			SetPointer(VarPtr(v.val), SysAllocStringLen(0))
-		Else
-			SetPointer(VarPtr(v.val), x.Copy())
-		End If
-	End Sub
-
-	Const Function ValUnknown() As IUnknown
+	Function ValUnknown() As IUnknown
 		Dim r As VARIANT
-		ChangeType(r, 0, VT_UNKNOWN)
+		changeType(r, VT_UNKNOWN)
 		Return _System_PtrUnknown(r.val As ULONG_PTR As VoidPtr)
 	End Function
 
-	Sub ValUnknown(x As IUnknown)
-		Clear()
-		SetPointer(VarPtr(v.val), ObjPtr(x))
-		If Not IsNothing(x) Then
-			x.AddRef()
-		End If
-		v.vt = VT_UNKNOWN
-	End Sub
-/*
-	Const Function ValObject() As VBObject
+	Function ValObject() As VBObject
 		Dim r As VARIANT
-		ChangeType(r, 0, VT_DISPATCH)
-		Dim o As VBObject
-		o.Attach(GetPointer(VarPtr(r.val)) As *IDispatch)
-		Return o
-	End Function
-
-	Sub ValObject(x As VBObject)
-		Clear()
-		SetPointer(VarPtr(v.val), x.Copy())
-		x->AddRef()
-		v.vt = VT_DISPATH
-	End Sub
-*/
+		changeType(r, VT_DISPATCH)
+		ValObject = VBObject.Attach(_System_PtrUnknown(r.val As ULONG_PTR As VoidPtr) As IDispatch)
+	End Function
+
 	'ValArray
 
-	Const Function ValDecimal() As Decimal
-		Dim p = VarPtr(v) As *Decimal
-		Return New Deciaml(ByVal p)
+	Function ValDecimal() As Decimal
+		Dim p = VarPtr(v) As *DECIMAL
+		Return New Decimal(ByVal p)
 	End Function
 
@@ -554,5 +459,4 @@
 		v.vt = VT_DECIMAL '念の為
 	End Sub
-	
 
 	Function PtrToVariant() As *VARIANT
@@ -562,7 +466,13 @@
 	Static Function OptionalParam() As Variant
 		If IsNothing(optionalParam) Then
-			Dim t = New Variant
-			t.ValError = DISP_E_PARAMNOTFOUND
-			InterlockedCompareExchangePointer(ByVal VarPtr(optionalParam), ObjPtr(t), 0)
+			Using lock = New ActiveBasic.Windows.CriticalSectionLock(_System_CriticalSection)
+				If IsNothing(optionalParam) Then
+					Dim t = New Variant
+					Dim p = t.PtrToVariant
+					p->vt = VT_ERROR
+					p->val = DISP_E_PARAMNOTFOUND
+					optionalParam = t
+				End If
+			End Using
 		End If
 		Return optionalParam
@@ -570,12 +480,17 @@
 
 	Static Function Null() As Variant
-		If IsNothing(optionalParam) Then
-			Dim t = New Variant
-			Dim p = t.PtrToVariant
-			p->vt = VT_NULL
-			InterlockedCompareExchangePointer(ByVal VarPtr(optionalParam), ObjPtr(t), 0)
+		If IsNothing(null) Then
+			Using lock = New ActiveBasic.Windows.CriticalSectionLock(_System_CriticalSection)
+				If IsNothing(null) Then
+					Dim t = New Variant
+					Dim p = t.PtrToVariant
+					p->vt = VT_NULL
+					null = t
+				End If
+			End Using
 		End If
-		Return optionalParam
-	End Function
+		Return null
+	End Function
+
 Private
 	v As VARIANT
@@ -587,8 +502,8 @@
 	Static Sub Move(ByRef dst As VARIANT, ByRef src As VARIANT)
 		dst = src
-'		src.vt = VT_EMPTY
-	End Sub
-
-	Static Function removeNull(v As Variant) As Varinat
+		src.vt = VT_EMPTY
+	End Sub
+
+	Static Function removeNull(v As Variant) As Variant
 		If IsNothing(v) Then
 			removeNull = Null
@@ -600,7 +515,8 @@
 	Static optionalParam = Nothing As Variant
 	Static null = Nothing As Variant
+
 End Class
 
-/*
+
 Function Abs(v As Variant) As Variant
 	Return v.Abs()
@@ -618,5 +534,76 @@
 	Return v.VarType()
 End Function
-*/
+
+Namespace Detail
+
+Sub CopyFromVariant(ByRef x As Byte, v As Variant)
+	x = v.ValUI1
+End Sub
+
+Sub CopyFromVariant(ByRef x As Word, v As Variant)
+	x = v.ValUI2
+End Sub
+
+Sub CopyFromVariant(ByRef x As DWord, v As Variant)
+	x = v.ValUI4
+End Sub
+
+Sub CopyFromVariant(ByRef x As QWord, v As Variant)
+	x = v.ValUI8
+End Sub
+
+Sub CopyFromVariant(ByRef x As SByte, v As Variant)
+	x = v.ValI1
+End Sub
+
+Sub CopyFromVariant(ByRef x As Integer, v As Variant)
+	x = v.ValI2
+End Sub
+
+Sub CopyFromVariant(ByRef x As Long, v As Variant)
+	x = v.ValI4
+End Sub
+
+Sub CopyFromVariant(ByRef x As Int64, v As Variant)
+	x = v.ValI8
+End Sub
+
+Sub CopyFromVariant(ByRef x As Single, v As Variant)
+	x = v.ValR4
+End Sub
+
+Sub CopyFromVariant(ByRef x As Double, v As Variant)
+	x = v.ValR8
+End Sub
+
+Sub CopyFromVariant(ByRef x As Boolean, v As Variant)
+	x = v.ValBool As Boolean
+End Sub
+
+Sub CopyFromVariant(ByRef x As ActiveBasic.COM.Currency, v As Variant)
+	x = v.ValCy
+End Sub
+
+Sub CopyFromVariant(ByRef x As String, v As Variant)
+	x = v.ValStr.ToString()
+End Sub
+
+Sub CopyFromVariant(ByRef x As ActiveBasic.COM.VBObject, v As Variant)
+	x = v.ValObject
+End Sub
+
+Sub CopyFromVariant(ByRef x As ActiveBasic.COM.Decimal, v As Variant)
+	x = v.ValDecimal
+End Sub
+
+Sub CopyFromVariant(ByRef x As IUnknown, v As Variant)
+	x = v.ValUnknown
+End Sub
+
+Sub CopyFromVariant(ByRef x As Variant, v As Variant)
+	x = v.Clone()
+End Sub
+
+End Namespace
 
 End Namespace 'COM
Index: trunk/ab5.0/ablib/src/com/vbobject.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/vbobject.ab	(revision 664)
+++ trunk/ab5.0/ablib/src/com/vbobject.ab	(revision 709)
@@ -6,55 +6,35 @@
 Namespace COM
 
-Class VBObject
+Class VBObjectBase
+	Implements System.IDisposable, System.IEquatable<VBObjectBase>
 Public
-	Sub VBObject()
-		pdisp = 0
-	End Sub
-
-	Sub VBObject(className As String, pOuter As *IUnknown, clsContext As DWord)
-		VBObject(ToWCStr(className), pOuter, clsContext)
-	End Sub
-
-	Sub VBObject(className As PCSTR, pOuter As *IUnknown, clsContext As DWord)
-		VBObject(ToWCStr(className), pOuter, clsContext)
-	End Sub
-
-	Sub VBObject(className As PCWSTR, pOuter As *IUnknown, clsContext As DWord)
-		pdisp = 0
-		Dim clsid As CLSID
-		Dim hr = _System_CLSIDFromString(className, clsid)
-		VBObject(clsid, pOuter, clsContext)
-	End Sub
-
-	Sub VBObject(ByRef clsid As CLSID, pOuter As *IUnknown, clsContext As DWord)
-		Dim hr = CoCreateInstance(clsid, pOuter, clsContext, IID_IDispatch, pdisp)
-	End Sub
-
-	Sub VBObject(ByRef obj As VBObject)
-		pdisp = obj.pdisp
-		pdisp->AddRef()
-	End Sub
-
-	Sub ~VBObject()
-		Clear()
+	Sub VBObjectBase()
+		disp = Nothing
+	End Sub
+
+	Sub VBObjectBase(dispObj As IDispatch)
+		copy(disp, dispObj)
+	End Sub
+
+	Sub ~VBObjectBase()
+		Dispose()
 	End Sub
 
 	Sub Clear()
-		If pdisp <> 0 Then
-			pdisp->Release()
-			pdisp = 0
+		Dispose()
+	End Sub
+
+	Virtual Sub Dispose()
+		If ObjPtr(disp) <> 0 Then
+			disp.Release()
+			disp = Nothing
 		End If
 	End Sub
 
-	Function Operator [](name As PCWSTR) As DispatchCaller
-		Return GetCaller(name)
-	End Function
-
-	Function Operator [](name As String) As DispatchCaller
-		Return GetCaller(ToWCStr(name))
-	End Function
-
-	Function Equals(y As VBObject) As Boolean
-		Return _System_COMReferenceEquals(pdisp, y.pdisp)
+'	Override Function Equals(y As Object) As Boolean
+'	End Function
+
+	Virtual Function Equals(y As VBObjectBase) As Boolean
+		Return Detail.COMReferenceEquals(This.Dispatch, y.Dispatch)
 	End Function
 /*
@@ -65,78 +45,108 @@
 	End Function
 */
-	Function Operator ==(y As VBObject) As Boolean
-		Return Equals(y)
-	End Function
-
-	Function Operator <>(y As VBObject) As Boolean
-		Return Not Equals(y)
-	End Function
-
-	Sub Assign(p As *IDispatch)
+
+	Function Copy() As IDispatch
+		copy(Copy, disp)
+	End Function
+
+	Sub Attach(ByRef y As IDispatch)
+'		Clear()
+'		move(pdisp, y)
+	End Sub
+
+	Function Detach() As IDispatch
+		move(Detach, disp)
+	End Function
+
+	Function Dispatch() As IDispatch
+		Dispatch = disp
+	End Function
+Protected
+
+	Sub attach(ByRef y As IDispatch)
 		Clear()
-		VBObject.Copy(pdisp, p)
-	End Sub
-
-	Function Copy() As *IDispatch
-		VBObject.Copy(GetDispatch, pdisp)
-	End Function
-
-	Sub Attach(ByRef p As *IDispatch)
-		Clear()
-		VBObject.Move(pdisp, p)
-	End Sub
-
-	Function Detach() As *IDispatch
-		VBObject.Move(Detach, pdisp)
-	End Function
-
-	Function Dispatch() As *IDispatch
-		Dispatch = pdisp
-	End Function
+		move(disp, y)
+	End Sub
+
+Private
+	disp As IDispatch
+
+	Static Sub copy(ByRef dst As IDispatch, ByVal src As IDispatch)
+		dst = src
+		If ObjPtr(src) <> 0 Then
+			src.AddRef()
+		End If
+	End Sub
+
+	Static Sub move(ByRef dst As IDispatch, ByRef src As IDispatch)
+		dst = src
+		src = Nothing
+	End Sub
+
+End Class
+
+Class VBObject
+	Inherits VBObjectBase
+Public
+	Static Function Attach(y As IDispatch) As VBObject
+		Attach = New VBObject
+		Attach.attach(y)
+	End Function
+
+	Sub VBObject()
+		disp = Nothing
+	End Sub
+
+	Sub VBObject(className As String, outer = Nothing As IUnknown, clsContext = CLSCTX_ALL As DWord)
+		VBObjectBase(createInstance(className, outer, clsContext))
+	End Sub
+
+	Sub VBObject(ByRef clsid As CLSID, outer = Nothing As IUnknown, clsContext = CLSCTX_ALL As DWord)
+		VBObjectBase(createInstance(clsid, outer, clsContext))
+	End Sub
+Private
+	Function createInstance(className As String, outer As IUnknown, clsContext As DWord) As IDispatch
+		Dim clsid = Detail.StringToCLSID(ToWCStr(className))
+		createInstance = createInstance(clsid, outer, clsContext)
+	End Function
+
+	Function createInstance(ByRef clsid As CLSID, outer As IUnknown, clsContext As DWord) As IDispatch
+		Dim hr = CoCreateInstance(clsid, ObjPtr(outer), clsContext, IID_IDispatch, createInstance)
+		Windows.ThrowIfFailed(hr)
+	End Function
+Public
+
+	Function Operator [](name As PCWSTR) As DispatchCaller
+		Return GetCaller(name)
+	End Function
+
+	Function Operator [](name As String) As DispatchCaller
+		Return GetCaller(ToWCStr(name))
+	End Function
+
 Private
 	Function GetCaller(name As PCWSTR) As DispatchCaller
 		Dim dispid As DISPID
-		Dim hr = pdisp->GetIDsOfNames(GUID_NULL, VarPtr(name), 1, LOCALE_USER_DEFAULT, VarPtr(dispid))
-		Return New DispatchCaller(pdisp, dispid)
-	End Function
-
-	pdisp As *IDispatch
-
-	Static Sub Copy(ByRef dst As *IDispatch, ByVal src As *IDispatch)
-		dst = src
-		dst->AddRef()
-	End Sub
-
-	Static Sub Move(ByRef dst As *IDispatch, ByRef src As *IDispatch)
-		dst = src
-		src = 0
-	End Sub
+		Dim hr = Dispatch.GetIDsOfNames(GUID_NULL, VarPtr(name), 1, LOCALE_USER_DEFAULT, VarPtr(dispid))
+		Windows.ThrowIfFailed(hr)
+		Return New DispatchCaller(disp, dispid)
+	End Function
 End Class
 
 Class DispatchCaller
+	Implements System.IDisposable
 Public
 	Sub DispatchCaller()
 	End Sub
-	Sub DispatchCaller(pDispatch As *IDispatch, dispatchId As DISPID)
-		pdisp = pDispatch
-		pdisp->AddRef()
+	Sub DispatchCaller(dispObj As IDispatch, dispatchId As DISPID)
+		disp = dispObj
+		disp.AddRef()
 		dispid = dispatchId
 	End Sub
 
-	Sub DispatchCaller(ByRef dc As DispatchCaller)
-		pdisp = dc.pdisp
-		pdisp->AddRef()
-		dispid = dc.dispid
-	End Sub
-
-	Sub Operator =(ByRef dc As DispatchCaller)
-		Dispose()
-		DispatchCaller(dc)
-	End Sub
-
 	Sub Dispose()
-		If pdisp <> 0 Then
-			pdisp->Release()
-			pdisp = 0
+		If ObjPtr(disp) <> NULL Then
+			disp.Release()
+			disp = Nothing
 		End If
 	End Sub
@@ -154,10 +164,8 @@
 			.cNamedArgs = 0
 		End With
-		Dim ret As VARIANT
-		Dim hr = pdisp->Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, dispParams, ret, 0, 0)
-		Dispose()
-		Prop = New Variant
-		v.Attach(ret)
-		Return v
+		Call = New Variant
+		Dim hr = disp.Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, dispParams, ByVal Call.PtrToVariant, ByVal 0, 0)
+		Windows.ThrowIfFailed(hr)
+		Dispose()
 	End Function
 
@@ -186,10 +194,8 @@
 			.cNamedArgs = 0
 		End With
-		Dim ret As VARIANT
-		Dim hr = pdisp->Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispParams, ret, ByVal 0, 0)
-		Dispose()
-		Dim v = New Variant
-		v.Attach(ret)
-		Return v
+		Call = New Variant
+		Dim hr = disp.Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispParams, ByVal Call.PtrToVariant, ByVal 0, 0)
+		Windows.ThrowIfFailed(hr)
+		Dispose()
 	End Function
 
@@ -259,10 +265,10 @@
 			.cNamedArgs = 1
 		End With
-		Dim hr = pdisp->Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, callType, dispParams, ByVal 0, ByVal 0, 0)
-		Dispose()
-	End Sub
-
-
-	pdisp As *IDispatch
+		Dim hr = disp.Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, callType, dispParams, ByVal 0, ByVal 0, 0)
+		Windows.ThrowIfFailed(hr)
+		Dispose()
+	End Sub
+
+	disp As IDispatch
 	dispid As DISPID
 End Class
@@ -276,7 +282,8 @@
 End Function
 
-Function CallByName(obj As *IDispatch, name As PCWSTR, callType As Word, cArgs As Long, args As *VARIANT) As Variant
+Function CallByName(obj As IDispatch, name As PCWSTR, callType As Word, cArgs As Long, args As *VARIANT) As Variant
 	Dim dispid As DISPID
-	Dim hr = obj->GetIDsOfNames(GUID_NULL, VarPtr(name), 1, LOCALE_USER_DEFAULT, VarPtr(dispid))
+	Dim hr = obj.GetIDsOfNames(GUID_NULL, VarPtr(name), 1, LOCALE_USER_DEFAULT, VarPtr(dispid))
+	Windows.ThrowIfFailed(hr)
 	Dim dispParams As DISPPARAMS
 	With dispParams
@@ -286,9 +293,7 @@
 		.cNamedArgs = 0
 	End With
-	Dim ret As VARIANT
-	hr = obj->Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispParams, ret, ByVal 0, 0)
 	CallByName = New Variant
-	CallByName.Attach(ret)
-	Return CallByName
+	hr = obj.Invoke(dispid, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispParams, ByVal CallByName.PtrToVariant, ByVal 0, 0)
+	Windows.ThrowIfFailed(hr)
 End Function
 /*
@@ -300,5 +305,5 @@
 	Return New VBObject(ToWCStr(className), 0, CLSCTX_ALL)
 End Function
-/*
+*/
 #ifdef _WIN32_DCOM
 Function CreateObject(className As PCWSTR, serverName As PCWSTR) As VBObject
@@ -306,5 +311,5 @@
 	Dim si As COSERVERINFO
 	Dim context As DWord
-	If /*Server = 0 OrElse* / Server[0] = 0 Then
+	If /*Server = 0 OrElse*/ Server[0] = 0 Then
 		context = CLSCTX_SERVER
 	Else
@@ -332,37 +337,40 @@
 End Function
 #endif
-*/
-Function _System_CLSIDFromString(pwString As PCWSTR, ByRef guid As GUID) As HRESULT
+
+
+Namespace Detail
+Function StringToCLSID(pwString As PCWSTR) As CLSID
 	If pwString[0] = &h007b As WCHAR Then
 		' 1文字目が { ならクラスIDの文字列表現と見なしCLSIDFromStringで変換。
-		_System_CLSIDFromString = CLSIDFromString(pwString, guid)
+		Windows.ThrowIfFailed(CLSIDFromString(pwString, StringToCLSID))
 	Else
-		_System_CLSIDFromString = CLSIDFromProgID(pwString, guid)
-	End If
-End Function
-
-Function _System_COMReferenceEquals(p As *IUnknown, q As *IUnknown) As Boolean
-	If p = q Then
+		Windows.ThrowIfFailed(CLSIDFromProgID(pwString, StringToCLSID))
+	End If
+End Function
+
+Function COMReferenceEquals(p As IUnknown, q As IUnknown) As Boolean
+	If ObjPtr(p) = ObjPtr(q) Then
 		Return True
-	Else If p = 0 Or q = 0 Then
+	Else If ObjPtr(p) = 0 Or ObjPtr(q) = 0 Then
 		Return False
 	End If
 
-	Dim punkX = _System_GetUnknown(p)
-	Dim punkY = _System_GetUnknown(q)
-	If punkX = punkY Then
-		_System_COMReferenceEquals = True
+	Dim punkX = GetUnknown(p)
+	Dim punkY = GetUnknown(q)
+	If ObjPtr(punkX) = ObjPtr(punkY) Then
+		COMReferenceEquals = True
 	Else
-		_System_COMReferenceEquals = False
-	End If
-	punkX->Release()
-	punkY->Release()
-End Function
-
-Function _System_GetUnknown(p As *IUnknown) As *IUnknown 'pは任意のCOMインタフェース
-	If FAILDED(pdisp->QueryInterface(IID_Unknown, _System_GetUnknown)) Then
-		GetUnknown = 0
-	End If
-End Function
+		COMReferenceEquals = False
+	End If
+	punkX.Release()
+	punkY.Release()
+End Function
+
+Function GetUnknown(p As IUnknown) As IUnknown 'pは任意のCOMインタフェース
+	If FAILED(p.QueryInterface(IID_IUnknown, GetUnknown)) Then
+		GetUnknown = Nothing
+	End If
+End Function
+End Namespace 'Detail
 
 End Namespace 'COM
