Index: Include/Classes/System/Windows/Forms/Control.ab
===================================================================
--- Include/Classes/System/Windows/Forms/Control.ab	(revision 132)
+++ Include/Classes/System/Windows/Forms/Control.ab	(revision 223)
@@ -4,16 +4,19 @@
 #define __SYSTEM_WINDOWS_FORMS_CONTROL_AB__
 
-#include <windows/WindowHandle.sbp>
-#include <Classes/System/Windows/Forms/misc.ab>
-#include <Classes/System/Windows/Forms/CreateParams.ab>
-#include <Classes/System/Windows/Forms/Message.ab>
-#include <Classes/System/Windows/Forms/PaintEventArgs.ab>
-#include <Classes/System/misc.ab>
-#include <Classes/System/Math.ab>
-#include <Classes/System/Threading/WaitHandle.ab>
-#include <Classes/System/Drawing/Color.ab>
-#include <Classes/System/Drawing/Point.ab>
-#include <Classes/System/Drawing/Size.ab>
-#include <Classes/System/Drawing/Rectangle.ab>
+#require <windows/WindowHandle.sbp>
+#require <Classes/System/Windows/Forms/misc.ab>
+#require <Classes/System/Windows/Forms/CreateParams.ab>
+#require <Classes/System/Windows/Forms/Message.ab>
+#require <Classes/System/Windows/Forms/PaintEventArgs.ab>
+#require <Classes/System/misc.ab>
+#require <Classes/System/Math.ab>
+#require <Classes/System/Threading/WaitHandle.ab>
+#require <Classes/System/Drawing/Color.ab>
+#require <Classes/System/Drawing/Point.ab>
+#require <Classes/System/Drawing/Size.ab>
+#require <Classes/System/Drawing/Rectangle.ab>
+#require <Classes/System/Runtime/InteropServices/GCHandle.ab>
+
+TypeDef InvokeProc = *Function(p As VoidPtr) As VoidPtr
 
 Class AsyncResultForInvoke
@@ -25,10 +28,10 @@
 	End Sub
 
-	Override Function AsyncState() As *IObject
-		Return 0
-	End Function
-
-	Override Function AsyncWaitHandle() As *WaitHandle
-		Return VarPtr(AsyncWaitHandle)
+	Override Function AsyncState() As IObject
+		Return Nothing
+	End Function
+
+	Override Function AsyncWaitHandle() As WaitHandle
+		Return waitHandle
 	End Function
 
@@ -38,5 +41,5 @@
 
 	Override Function IsCompleted() As BOOL
-		Return AsyncWaitHandle()->WaitOne(0, FALSE)
+		Return waitHandle.WaitOne(0, FALSE)
 	End Function
 
@@ -56,31 +59,31 @@
 Class AsyncInvokeData
 Public
-	FuncPtr As *Function(p As VoidPtr) As VoidPtr
+	FuncPtr As InvokeProc
 	Data As *VoidPtr
-	AsyncResult As *AsyncResultForInvoke
+	AsyncResult As AsyncResultForInvoke
 End Class
 
 Class Control
-	Inherits IWin32Window
+'	Inherits IWin32Window
 Public
 	'---------------------------------------------------------------------------
 	' Public Properties
 
-	Function AllowDrop() As BOOL
-	End Function
-
-	Override Function Handle() As HWND
+	Function AllowDrop() As Boolean
+	End Function
+
+	/*Override*/ Function Handle() As HWND
 		Return wnd.HWnd
 	End Function
 
 	' IDropTargetを実装するのでDragAcceptFiles関数は呼ばない。
-	Sub AllowDrop(a As BOOL)
-	End Sub
-
-	Const Function Visible() As BOOL
+	Sub AllowDrop(a As Boolean)
+	End Sub
+
+	Const Function Visible() As Boolean
 		Return wnd.Visible
 	End Function
 
-	Sub Visible(v As BOOL)
+	Sub Visible(v As Boolean)
 		wnd.Visible(v)
 	End Sub
@@ -96,9 +99,9 @@
 	End Sub
 
-	Const Function Enabled() As BOOL
+	Const Function Enabled() As Boolean
 		Return wnd.Enabled
 	End Function
 
-	Sub Enabled(e As BOOL)
+	Sub Enabled(e As Boolean)
 		' OnEnabledChangedはWM_ENABLE経由で呼ばれる
 		wnd.Enabled(e)
@@ -108,7 +111,7 @@
 		Dim wr As RECT
 		wr = wnd.WindowRect
-		Dim r As Rectangle(wr)
+		Dim r = New Rectangle(wr)
 		Dim parent = Parent
-		If parent <> 0 Then
+		If Object.ReferenceEquals(parent, Nothing) Then
 			Return parent->RectangleToClient(r)
 		Else
@@ -117,5 +120,5 @@
 	End Function
 
-	Sub Bounds(ByRef r As Rectangle)
+	Sub Bounds(r As Rectangle)
 		SetBoundsCore(r.X, r.Y, r.Width, r.Height, BoundsSpecified.All)
 	End Sub
@@ -138,6 +141,5 @@
 
 	Const Function ClientRectangle() As Rectangle
-		Dim r As Rectangle(wnd.ClientRect)
-		Return r
+		Return New Rectangle(wnd.ClientRect)
 	End Function
 
@@ -191,24 +193,31 @@
 
 	Const Function PointToScreen(p As Point) As Point
-		wnd.ClientToScreen(ByVal VarPtr(p) As *POINTAPI)
-		Return r
+		PointToScreen = New Point
+		ret.X = p.X
+		ret.Y = p.Y
+		wnd.ClientToScreen(ByVal VarPtr(PointToScreen) As *POINTAPI)
 	End Function
 
 	Const Function PointToClient(p As Point) As Point
-		wnd.ScreenToClient(ByVal VarPtr(p) As *POINTAPI)
-		Return r
-	End Function
-
-	Const Function RectangleToScreen(p As Rectangle) As Rectangle
-		wnd.ClientToScreen(ByVal VarPtr(p) As *POINTAPI)
-		Return p
-	End Function
-
-	Const Function RectangleToClient(p As Rectangle) As Rectangle
-		wnd.ScreenToClient(ByVal VarPtr(p) As *POINTAPI)
-		Return p
-	End Function
-
-	Const Function InvokeRequired() As BOOL
+		PointToScreen = New Point
+		ret.X = p.X
+		ret.Y = p.Y
+		wnd.ScreenToClient(ByVal VarPtr(PointToScreen) As *POINTAPI)
+	End Function
+
+	Const Function RectangleToScreen(r As Rectangle) As Rectangle
+		Dim rc = r.ToRECT
+		wnd.ClientToScreen(rc)
+		Return New Rectangle(rc)
+	End Function
+
+	Const Function RectangleToClient(r As Rectangle) As Rectangle
+		Dim rc As RECT
+		rc = r.ToRECT()
+		wnd.ScreenToClient(rc)
+		Return New Rectangle(rc)
+	End Function
+
+	Const Function InvokeRequired() As Boolean
 		Return wnd.ThreadID <> GetCurrentThreadId()
 	End Function
@@ -224,6 +233,10 @@
 	End Sub
 
-	Function Parent() As *Control
+	Function Parent() As Control
 		Return parent
+	End Function
+
+	Const Function IsHandleCreated() As Boolean
+		Return wnd.HWnd <> 0
 	End Function
 
@@ -240,15 +253,15 @@
 	End Sub
 
-	Sub Control(ByRef text As String)
+	Sub Control(text As String)
 		Dim sz = DefaultSize()
 		Control(text, 100, 100, sz.Width, sz.Height)
 	End Sub
 
-	Sub Control(ByRef parent As Control, ByRef text As String)
+	Sub Control(parent As Control, text As String)
 		Dim sz = DefaultSize()
 		Control(parent, text, 100, 100, sz.Width, sz.Height)
 	End Sub
 
-	Sub Control(ByRef text As String, left As Long, top As Long, width As Long, height As Long)
+	Sub Control(text As String, left As Long, top As Long, width As Long, height As Long)
 		This.text = text
 		bkColor = DefaultBackColor
@@ -257,5 +270,5 @@
 	End Sub
 
-	Sub Control(ByRef parent As Control, ByRef text As String, left As Long, top As Long, width As Long, height As Long)
+	Sub Control(parent As Control, text As String, left As Long, top As Long, width As Long, height As Long)
 		This.parent = VarPtr(parent)
 		Control(text, left, top, width, height)
@@ -276,5 +289,5 @@
 	' 同期関数呼出、Controlが作成されたスレッドで関数を実行する。
 	' 関数は同期的に呼び出されるので、関数が終わるまでInvokeは制御を戻さない。
-	Function Invoke(pfn As *Function(p As VoidPtr) As VoidPtr, p As VoidPtr) As VoidPtr
+	Function Invoke(pfn As InvokeProc, p As VoidPtr) As VoidPtr
 		Return wnd.SendMessage(WM_CONTROL_INVOKE, p As WPARAM, pfn As LPARAM) As VoidPtr
 	End Function
@@ -283,16 +296,16 @@
 	' 関数は非同期的に呼び出されるので、BeginInvokeはすぐに制御を戻す。
 	' 後にEndInvokeを呼び出すことにより、関数の戻り値を受け取れる。
-	' 注意：現状の実装では必ずEndInvokeを呼び出す必要がある。
-	Function BeginInvoke(pfn As *Function(p As VoidPtr) As VoidPtr, p As VoidPtr) As *IAsyncResult
+	Function BeginInvoke(pfn As InvokeProc, p As VoidPtr) As IAsyncResult
 		' EndInvokeがDeleteする
-		Dim pAsyncResult = New AsyncResultForInvoke(CreateEvent(0, FALSE, FALSE, 0))
+		Dim asyncResult = New AsyncResultForInvoke(CreateEvent(0, FALSE, FALSE, 0))
 		' OnControlBeginInvokeがDeleteする
-		Dim pAsyncInvokeData = New AsyncInvokeData
-		With pAsyncInvokeData[0]
+		Dim asyncInvokeData = New AsyncInvokeData
+		With asyncInvokeData
 			.FuncPtr = pfn
 			.Data = p
-			.AsyncResult = pAsyncResult
+			.AsyncResult = asyncResult
 		End With
-		wnd.PostMessage(WM_CONTROL_BEGININVOKE, 0, pAsyncInvokeData As LPARAM)
+		Dim gch = GCHandle.Alloc(asyncInvokeData)
+		wnd.PostMessage(WM_CONTROL_BEGININVOKE, 0, GCHandle.ToIntPtr(gch))
 		Return pAsyncResult
 	End Function
@@ -300,25 +313,22 @@
 	' BeginInvokeで呼び出した関数の戻り値を受け取る。
 	' その関数がまだ終了していない場合、終了するまで待機する。
-	Function EndInvoke(ar As *IAsyncResult) As VoidPtr
-		ar->WaitHandle->WaitOne()
-		Dim arInvoke = ar As *AsyncResultForInvoke
-		Dim result = arInvoke->Result
-		Delete arInvoke
-		Return result
+	Function EndInvoke(ar As IAsyncResult) As VoidPtr
+		ar.WaitHandle.WaitOne()
+		Dim arInvoke = ar As AsyncResultForInvoke
+		Return arInvoke.Result
 	End Function
 
 	' 与えられたウィンドウハンドルがControl（若しくはその派生クラス）の
 	' インスタンスに対応するものであった場合、
-	' 元のインスタンスへのポインタを返す。
-	' そうでなければヌルポインタを返す。
-	Static Function FromHandle(hwnd As HWND) As *Control
+	' 元のインスタンスを返す。
+	' そうでなければNothingを返す。
+	Static Function FromHandle(hwnd As HWND) As Control
 		If IsWindow(hwnd) Then
-			Dim className[19] As Byte 'Len (WindowClassName)
-			GetClassName(hwnd, className, Len (className))
-			If memcmp(className, WindowClassName, Len (WindowClassName)) = 0 Then
-				Return GetWindowLongPtr(hwnd, GWLP_THIS) As *Control
+			If GetClassLongPtr(hwnd, GCW_ATOM) = atom Then
+				Dim gch = GCHandle.FromIntPtr(GetWindowLongPtr(hwnd, GWLP_THIS))
+				Return gch.Target As Control
 			End If
 		End If
-		Return 0 As *Control
+		Return Nothing As Control
 	End Function
 
@@ -327,5 +337,5 @@
 	End Sub
 
-	/*Override*/ Virtual Function ToString() As String
+	Override Function ToString() As String
 		Return text
 	End Function
@@ -351,7 +361,7 @@
 	'---------------------------------------------------------------------------
 	' Protected Properties
-'	Const Virtual Function CanRaiseEvents() As BOOL
-	Virtual Function CreateParams() As *CreateParams
-		Return VarPtr(createParams)
+'	Const Virtual Function CanRaiseEvents() As Boolean
+	Virtual Function CreateParams() As CreateParams
+		Return createParams
 	End Function
 
@@ -373,9 +383,10 @@
 	Virtual Sub CreateHandle()
 		Dim createParams = CreateParams()
-		TlsSetValue(tlsIndex, VarPtr(This))
+		Dim gch = GCHandle.Alloc(This)
+		TlsSetValue(tlsIndex, GCHandle.ToIntPtr(gch) As VoidPtr)
 		With createParams[0]
 			Dim hwndParent = 0 As HWND
-			If parent <> 0 Then
-				hwndParent = parent->Handle
+			If Not Object.ReferenceEquals(parent, Nothing) Then
+				hwndParent = parent.Handle
 			End If
 			If CreateWindowEx(.ExStyle, atom As ULONG_PTR As PCSTR, text, .Style, _
@@ -383,6 +394,6 @@
 				hwndParent, 0, hInstance, 0) = 0 Then
 				' Error
-				Dim buf[1023] As Byte
-				wsprintf(buf, Ex"Control: CreateWindowEx failed. Error code: &h%08X\r\n", GetLastError())
+				Dim buf[1023] As TCHAR
+				wsprintf(buf, ToTCStr(Ex"Control: CreateWindowEx failed. Error code: &h%08X\r\n"), GetLastError())
 				OutputDebugString(buf)
 '				Debug
@@ -390,11 +401,12 @@
 			End If
 		End With
-	End Sub
-
-	Virtual Sub DefWndProc(ByRef m As Message)
+		gch.Free()
+	End Sub
+
+	Virtual Sub DefWndProc(m As Message)
 		m.Result = DefWindowProc(m.HWnd, m.Msg, m.WParam, m.LParam)
 	End Sub
 
-	Virtual Sub WndProc(ByRef m As Message)
+	Virtual Sub WndProc(m As Message)
 		With m
 			Select Case .Msg
@@ -402,12 +414,11 @@
 					.Result = text.Length
 				Case WM_GETTEXT
-					Dim size = Math.Min(.WParam As ULONG_PTR, text.Length As ULONG_PTR + 1)
-					memcpy(.LParam As *Byte, text.StrPtr, size)
+					Dim size = Math.Min(.WParam As ULONG_PTR, (text.Length + 1) As ULONG_PTR)
+					memcpy(.LParam As PCTSTR, ToTCStr(text), size * SizeOf (TCHAR))
 					.Result = size
 				Case WM_SETTEXT
-					text = .LParam As *Byte
+					text = New String(.LParam As PCTSTR)
 				Case WM_ENABLE
-					Dim e As EventArgs
-					OnEnabledChanged(e)
+					OnEnabledChanged(EventArgs.Empty)
 				Case WM_ERASEBKGND
 					' OnPaintBackgroundに移すべき
@@ -420,9 +431,10 @@
 					DeleteObject(hbr)
 				Case WM_CONTROL_INVOKE
-					Dim pfn As *Function(p As VoidPtr) As VoidPtr
-					pfn = .LParam As *Function(p As VoidPtr) As VoidPtr
+					Dim pfn = .LParam As InvokeProc
 					.Result = pfn(m.WParam As VoidPtr) As LRESULT
 				Case WM_CONTROL_BEGININVOKE
 					OnControlBeginInvoke(m)
+				Case WM_CREATE
+					OnHandleCreated(EventArgs.Empty)
 				Case Else
 					DefWndProc(m)
@@ -450,16 +462,16 @@
 
 	Virtual Sub SetBoundsCore(x As Long, y As Long, width As Long, height As Long, bs As BoundsSpecified)
-		If Not (bs As DWord And BoundsSpecified.X As DWord) Then
+'		If Not (bs As DWord And BoundsSpecified.X As DWord) Then
 			x = Left
-		End If
-		If Not (bs As DWord And BoundsSpecified.Y As DWord) Then
+'		End If
+'		If Not (bs As DWord And BoundsSpecified.Y As DWord) Then
 			y = Right
-		End If
-		If Not (bs As DWord And BoundsSpecified.Width As DWord) Then
+'		End If
+'		If Not (bs As DWord And BoundsSpecified.Width As DWord) Then
 			width = Width
-		End If
-		If Not (bs As DWord And BoundsSpecified.Height As DWord) Then
+'		End If
+'		If Not (bs As DWord And BoundsSpecified.Height As DWord) Then
 			height = Height
-		End If
+'		End If
 		wnd.Move(x, y, width, height)
 	End Sub
@@ -471,9 +483,10 @@
 	End Sub
 
-	Virtual Sub OnPaintBackground(ByRef e As PaintEventArgs) : End Sub
-	Virtual Sub OnEnabledChanged(ByRef e As EventArgs) : End Sub
-	Virtual Sub OnBackColorChanged(ByRef e As EventArgs) : End Sub
-	Virtual Sub OnTextChanged(ByRef e As EventArgs)
-		wnd.SetText(text.StrPtr)
+	Virtual Sub OnPaintBackground(e As PaintEventArgs) : End Sub
+	Virtual Sub OnEnabledChanged(e As EventArgs) : End Sub
+	Virtual Sub OnBackColorChanged(e As EventArgs) : End Sub
+	Virtual Sub OnHandleCreated(e As EventArgs) : End Sub
+	Virtual Sub OnTextChanged(e As EventArgs)
+		wnd.SetText(ToTCStr(text))
 	End Sub
 
@@ -482,5 +495,5 @@
 	wnd As WindowHandle
 	text As String
-	parent As *Control
+	parent As Control
 	bkColor As Color
 
@@ -496,5 +509,5 @@
 	Static Const WM_CONTROL_BEGININVOKE = WM_USER + 1 As DWord
 
-	Static Const WindowClassName = "ActiveBasic Control" As *Byte
+	Static Const WindowClassName = "ActiveBasic Control"
 Public
 	Static Sub Initialize(hinst As HINSTANCE)
@@ -519,6 +532,6 @@
 		atom = RegisterClassEx(wcx)
 		If atom = 0 Then
-			Dim buf[1023] As Byte
-			wsprintf(buf, Ex"Control: RegisterClasseEx failed. Error code: &h%08X\r\n", GetLastError())
+			Dim buf[1023] As TCHAR
+			wsprintf(buf, ToTCStr(Ex"Control: RegisterClasseEx failed. Error code: &h%08X\r\n"), GetLastError())
 			OutputDebugString(buf)
 			Debug
@@ -543,10 +556,11 @@
 	' Windowsから呼ばれるウィンドウプロシージャ。WndProc
 	Static Function WndProcFirst(hwnd As HWND, msg As DWord, wp As WPARAM, lp As LPARAM) As LRESULT
-		Dim pThis = Control.FromHandle(hwnd) As *Control
-		If pThis = 0 Then
-			pThis = TlsGetValue(tlsIndex)
+		Dim rThis = Control.FromHandle(hwnd) As Control
+		If Object.ReferenceEquals(rThis As Object, Nothing) Then
+			Dim gchValue = TlsGetValue(tlsIndex) As LONG_PTR
+			Dim gch = GCHandle.FromIntPtr(gchValue)
+			rThis = gch.Target As Control
 			' ウィンドウが作られて最初にWndProcFirstが呼ばれたとき
-			TlsSetValue(tlsIndex, 0)
-			If pThis = 0 Then
+			If Object.ReferenceEquals(rThis, Nothing) Then
 				' あってはならない事態
 				Debug
@@ -554,22 +568,22 @@
 			End If
 '			Debug
-			pThis->wnd = hwnd
-			SetWindowLongPtr(hwnd, GWLP_THIS, pThis As LONG_PTR)
+			rThis.wnd = New WindowHandle(hwnd)
+			SetWindowLongPtr(hwnd, GWLP_THIS, gchValue)
 		End If
 		Dim m As Message
 		m = Message.Create(hwnd, msg, wp, lp)
-		pThis->WndProc(m)
+		rThis.WndProc(m)
 		Return m.Result
 	End Function
 
 	' BeginInvokeが呼ばれたときの処理
-	Sub OnControlBeginInvoke(ByRef m As Message)
-		Dim data As *AsyncInvokeData
-		data = m.LParam As *AsyncInvokeData
-		Dim asyncResult As *AsyncResultForInvoke
-		asyncResult->Result = data->FuncPtr(data->Data)
-		Dim wh = asyncResult->AsyncWaitHandle
-		SetEvent(wh->Handle)
-		Delete data
+	Sub OnControlBeginInvoke(m As Message)
+		Dim gch = GCHandle.FromIntPtr(m.LParam)
+		Dim data = gch.Target As AsyncInvokeData
+		With data
+			Dim pfn = .FuncPtr
+			.AsyncResult.Result = pfn(.Data)
+			SetEvent(.AsyncResult.AsyncWaitHandle.Handle)
+		End With
 	End Sub
 End Class
