Index: trunk/ab5.0/ablib/src/com/variant.ab
===================================================================
--- trunk/ab5.0/ablib/src/com/variant.ab	(revision 506)
+++ 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
