source: trunk/ab5.0/ablib/src/Classes/ActiveBasic/Windows/UI/Control.ab@ 698

Last change on this file since 698 was 698, checked in by イグトランス (egtra), 15 years ago

GDI+をコンパイルできるように修正。FontFamily, Penの追加。サンプルとして、Step 32のGDI+版を制作。
(#56)

File size: 18.5 KB
RevLine 
[473]1'Classes/ActiveBasic/Windows/UI/Control.ab
2
[679]3#require <Classes/ActiveBasic/Windows/UI/WindowHandle.ab>
[545]4#require <Classes/ActiveBasic/Windows/UI/EventArgs.ab>
[575]5#require <Classes/ActiveBasic/COM/ComClassBase.ab>
[473]6
7Namespace ActiveBasic
8Namespace Windows
9Namespace UI
10
[564]11Namespace Detail
12 TypeDef PTrackMouseEvent = *Function(ByRef tme As TRACKMOUSEEVENT) As BOOL
13End Namespace
[542]14
[615]15/*
16@brief Windowsのウィンドウを管理する基底クラス
17@auther Egtra
18*/
[473]19Class Control
[547]20 Inherits WindowHandle
[575]21 Implements ActiveBasic.COM.InterfaceQuerable
[473]22Public
[551]23 /*!
24 @brief Destroyイベントよりも後に呼ばれるDestroyイベントデリゲート
25 @date 2008/07/16
26 */
27 finalDestroy As ActiveBasic.Windows.UI.Handler
[547]28
[473]29 Sub Control()
[575]30 comImpl = New COM.ComClassDelegationImpl(This)
[473]31 End Sub
32
[542]33 Function Handle() As HWND
34 Handle = hwnd
[473]35 End Function
36
[575]37 /*!
38 @brief HWNDからControlインスタンスを取得する。
39 @param[in] hwnd 対象のウィンドウハンドル
[646]40 @return 対応するControlインスタンス。存在しなければ作成される。ただし、hwndがNULLならNothing。
[575]41 */
[473]42 Static Function FromHWnd(hwnd As HWND) As Control
43 FromHWnd = Nothing
[646]44 If IsWindow(hwnd) Then
[473]45 FromHWnd = FromHWndCore(hwnd)
[646]46 If ActiveBasic.IsNothing(FromHWnd) Then
47 Dim lock = New ActiveBasic.Windows.CriticalSectionLock(_System_CriticalSection)
48 Try
49 FromHWnd = New Control
50 FromHWnd.registerStandardEvent()
51 FromHWnd.AssociateHWnd(hwnd)
52 Finally
53 lock.Dispose()
54 End Try
55 End If
[473]56 End If
57 End Function
58
[698]59 Function AddRef() As DWord
60 AddRef = comImpl.AddRef()
61 End Function
62
63 Function Release() As DWord
64 Release = comImpl.Release()
65 End Function
66
67 Function QueryInterface(ByRef riid As IID, ByRef pv As Any) As HRESULT
68 QueryInterface = comImpl.QueryInterface(riid, pv)
69 End Function
70
[473]71Private
72 Static Function FromHWndCore(hwnd As HWND) As Control
[575]73 FromHWndCore = _System_PtrObj(GetProp(hwnd, PropertyInstance As ULONG_PTR As PCTSTR) As VoidPtr) As Control
[473]74 End Function
75
76'--------------------------------
[544]77' ウィンドウ作成
[542]78
[473]79Public
[575]80 /*!
81 @brief ウィンドウを作成する(詳細版)。
82 @date 2008/08/02
83 通常はCreateやCreateFormその他を使ってください。
[698]84 ここで渡された引数は、GetCreateStructへ渡して修正の機会を与えた後に、
85 CreateWindowExへ渡される。
[575]86 */
87 Sub CreateEx(parent As Control, style As DWord, exStyle As DWord, hmenu As HMENU)
[473]88 Dim cs As CREATESTRUCT
[551]89 With cs
90 .dwExStyle = exStyle
91 .lpszClass = (atom As ULONG_PTR) As LPCTSTR
92 .lpszName = 0
[575]93 .style = style
[561]94 .x = 0
95 .y = 0
96 .cx = 0
97 .cy = 0
[551]98 If IsNothing(parent) Then
99 .hwndParent = 0
100 Else
101 .hwndParent = parent As HWND
102 End If
103 .hMenu = hmenu
104 .hInstance = hInstance
105 End With
[473]106 GetCreateStruct(cs)
[551]107 createImpl(cs, parent)
[547]108 End Sub
[473]109
[575]110 /*!
111 @brief ウィンドウを作成する(子ウィンドウ以外)。
112 @date 2008/08/02
113 */
114 Sub CreateForm(style As DWord, exStyle As DWord, owner = Nothing As Control, hmenu = 0 As HMENU)
115 CreateEx(owner, style, exStyle, hmenu)
[551]116 End Sub
[575]117
118 Sub CreateForm()
119 CreateEx(Nothing, 0, 0, 0)
120 End Sub
121
122 /*!
123 @brief 子ウィンドウを作成する。
124 @date 2008/08/02
125 */
126 Sub Create(parent As Control, style = 0 As DWord, exStyle = 0 As DWord, id = 0 As Long)
127 CreateEx(parent, style Or WS_CHILD Or WS_VISIBLE, exStyle, id As ULONG_PTR As HMENU)
128 End Sub
[615]129
[473]130Protected
[698]131 /*!
132 @brief ウィンドウ作成前の初期設定確認
133 派生クラスでオーバーライドして、csを書き換えてよい。
134 書き換えられたcsを基にCreateWindowExが呼ばれる。
135 */
[646]136 Virtual Sub GetCreateStruct(ByRef cs As CREATESTRUCT)
137 End Sub
[473]138
[698]139Private
[551]140 Sub createImpl(ByRef cs As CREATESTRUCT, parent As Control)
[615]141 throwIfAlreadyCreated()
[559]142
[542]143 StartWndProc()
144
[473]145 With cs
[561]146 'よそのウィンドウクラスの場合、WndProcFirst内のhwndの代入が行われないため、ここでも行っておく。
[551]147 hwnd = CreateWindowEx(.dwExStyle, .lpszClass, .lpszName, .style,
[473]148 .x, .y, .cx, .cy, .hwndParent, .hMenu, .hInstance, .lpCreateParams)
[547]149 If hwnd = 0 Then
[615]150 ThrowWithLastErrorNT("Control.CreateEx")
[547]151 End If
[551]152
153 If IsNothing(FromHWndCore(hwnd)) <> False Then
[575]154 AssociateHWnd(hwnd)
[551]155 TlsSetValue(tlsIndex, 0)
156 End If
[473]157 End With
[551]158
159 If IsNothing(parent) = False Then
160 RegisterUnassociateHWnd(parent)
161 End If
[547]162 End Sub
[473]163
[615]164Public
[646]165/*
[615]166 Sub Attach(hwndNew As HWND)
167 throwIfAlreadyCreated()
168 If hwndNew = 0 Then
169 Throw New System.ArgumentNullException("Control.Attach")
170 End If
171 registerStandardEvent()
172 AssociateHWnd(hwndNew)
[637]173 End Sub
[646]174*/
[698]175
[637]176 Sub BeginSubclass()
177 throwIfNotCreated()
[646]178 prevWndProc = SetWindowLongPtr(hwnd, GWLP_WNDPROC, AddressOf(WndProcFirst) As LONG_PTR) As WNDPROC
[615]179 End Sub
180
181Private
182 Sub throwIfAlreadyCreated()
183 If hwnd <> 0 Then
[637]184 Throw New System.InvalidOperationException("Window is already created.")
[615]185 End If
186 End Sub
187
[637]188 Sub throwIfNotCreated()
189 If hwnd = 0 Then
190 Throw New System.InvalidOperationException("Window is not already created.")
191 End If
192 End Sub
193
[473]194'--------------------------------
195' ウィンドウプロシージャ
[637]196
197Protected
[473]198 Virtual Function WndProc(msg As DWord, wp As WPARAM, lp As LPARAM) As LRESULT
[637]199 If Not ProcessMessage(msg, wp, lp, WndProc) Then
200 WndProc = DefWndProc(msg, wp, lp)
201 End If
202 End Function
203
204 Virtual Function DefWndProc(msg As DWord, wp As WPARAM, lp As LPARAM) As LRESULT
205 If prevWndProc Then
206 DefWndProc = CallWindowProc(prevWndProc, hwnd, msg, wp, lp)
207 Else
208 DefWndProc = DefWindowProc(hwnd, msg, wp, lp)
209 End If
210 End Function
211Protected
212 Function ProcessMessage(msg As DWord, wp As WPARAM, lp As LPARAM, ByRef lr As LRESULT) As Boolean
[551]213 Dim h = Nothing As MessageHandler
[542]214 Dim b = messageMap.TryGetValue(Hex$(msg), h)
215 If b Then
216 If Not IsNothing(h) Then
[551]217 Dim a = New MessageArgs(hwnd, msg, wp, lp)
[542]218 h(This, a)
[615]219 If a.Handled Then
[637]220 lr = a.LResult
221 ProcessMessage = True
[615]222 Exit Function
223 End If
[542]224 End If
225 End If
[637]226 ProcessMessage = False
[473]227 End Function
228Private
[551]229 Static Function makeKeysFormMsg(e As MessageArgs) As Keys
[698]230 Dim t = (e.WParam As DWord) And Keys.KeyCode
[473]231 t Or= (GetKeyState(VK_SHIFT) As Word And &h8000) << 1
232 t Or= (GetKeyState(VK_CONTROL) As Word And &h8000) << 2
233 t Or= (GetKeyState(VK_MENU) As Word And &h8000) << 3
[544]234 makeKeysFormMsg = t As Keys
[473]235 End Function
236
[551]237 Static Function makeMouseEventFromMsg(e As MessageArgs) As MouseArgs
[544]238 Dim wp = e.WParam
239 Dim lp = e.LParam
[674]240
241 /*************************************************/
242 Dim mb As MouseButtons
243 If LOWORD(wp) = 0 Then mb = MouseButtons.None
244 If LOWORD(wp) and MK_LBUTTON Then mb or = MouseButtons.Left
245 If LOWORD(wp) and MK_RBUTTON Then mb or = MouseButtons.Right
246 If LOWORD(wp) and MK_MBUTTON Then mb or = MouseButtons.Middle
247 If LOWORD(wp) and MK_XBUTTON1 Then mb or = MouseButtons.XButton1
248 If LOWORD(wp) and MK_XBUTTON2 Then mb or = MouseButtons.XButton2
249 If LOWORD(wp) and MK_SHIFT Then mb or = MouseButtons.Shift
250 If LOWORD(wp) and MK_CONTROL Then mb or = MouseButtons.Control
251 makeMouseEventFromMsg = New MouseArgs(mb, 1, GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 0)
252 /*************************************************/
253
254 'makeMouseEventFromMsg = New MouseArgs(LOWORD(wp) As MouseButtons, 1, GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 0)
[542]255 End Function
[473]256
[575]257Protected
[542]258 /*!
[575]259 @brief 最初にウィンドウプロシージャを使うための前処理を行う関数
[542]260 @date 2008/07/11
[575]261 WndProcFirstを使うときは、この関数を呼んでおく必要がある。
[542]262 */
263 Sub StartWndProc()
[575]264 TlsSetValue(tlsIndex, ObjPtr(This))
265 registerStandardEvent()
266 End Sub
267Private
268 /*!
269 @brief 主なメッセージハンドラの登録を行う関数
270 @date 2008/08/02
271 */
272 Sub registerStandardEvent()
[547]273 AddMessageEvent(WM_ERASEBKGND, AddressOf(OnEraseBackground))
[551]274 Dim md = New MessageHandler(AddressOf(OnMouseDownBase))
[542]275 AddMessageEvent(WM_LBUTTONDOWN, md)
276 AddMessageEvent(WM_RBUTTONDOWN, md)
277 AddMessageEvent(WM_MBUTTONDOWN, md)
278 AddMessageEvent(WM_XBUTTONDOWN, md)
[551]279 Dim mu = New MessageHandler(AddressOf(OnMouseUpBase))
[542]280 AddMessageEvent(WM_LBUTTONUP, mu)
281 AddMessageEvent(WM_RBUTTONUP, mu)
282 AddMessageEvent(WM_MBUTTONUP, mu)
283 AddMessageEvent(WM_XBUTTONUP, mu)
[551]284 Dim mb = New MessageHandler(AddressOf(OnMouseDblClkBase))
[564]285 AddMessageEvent(WM_LBUTTONDBLCLK, mb)
286 AddMessageEvent(WM_RBUTTONDBLCLK, mb)
287 AddMessageEvent(WM_MBUTTONDBLCLK, mb)
288 AddMessageEvent(WM_XBUTTONDBLCLK, mb)
[544]289
[547]290 AddMessageEvent(WM_MOUSEMOVE, AddressOf(OnMouseMoveBase))
291 AddMessageEvent(WM_MOUSELEAVE, AddressOf(OnMouseLeaveBase))
[564]292 AddMessageEvent(WM_MOUSEHOVER, AddressOf(OnMouseHoverBase))
[547]293 AddMessageEvent(WM_PAINT, AddressOf(OnPaintBase))
294 AddMessageEvent(WM_KEYDOWN, AddressOf(OnKeyDownBase))
[551]295 AddMessageEvent(WM_CHAR, AddressOf(OnChar))
[547]296 AddMessageEvent(WM_CREATE, AddressOf(OnCreateBase))
[561]297 AddMessageEvent(WM_SIZE, AddressOf(OnSize))
[542]298 End Sub
[473]299
[551]300 Sub OnEraseBackground(sender As Object, e As MessageArgs)
[615]301 Dim a = New PaintBackgroundArgs(e.WParam, e.LParam)
302 e.Handled = e.Handled And OnPaintBackground(a)
303 e.LResult = a.Painted
[542]304 End Sub
[473]305
[551]306 Sub OnMouseDownBase(sender As Object, e As MessageArgs)
[615]307 e.Handled = e.Handled And OnMouseDown(makeMouseEventFromMsg(e))
[542]308 End Sub
309
[551]310 Sub OnMouseUpBase(sender As Object, e As MessageArgs)
[544]311 Dim me = makeMouseEventFromMsg(e)
[542]312 If doubleClickFired = False Then
[561]313 OnClick(Args.Empty)
[542]314 OnMouseClick(me)
[575]315 Else
[542]316 doubleClickFired = False
317 End If
[615]318 e.Handled = e.Handled And OnMouseUp(me)
[542]319 End Sub
320
[551]321 Sub OnMouseDblClkBase(sender As Object, e As MessageArgs)
[544]322 Dim me = makeMouseEventFromMsg(e)
[542]323 doubleClickFired = True
324 OnMouseDown(me)
[561]325 OnDoubleClick(Args.Empty)
[615]326 e.Handled = e.Handled And OnMouseDoubleClick(me)
[542]327 End Sub
328
[551]329 Sub OnMouseMoveBase(sender As Object, e As MessageArgs)
[544]330 Dim me = makeMouseEventFromMsg(e)
[575]331 If mouseEntered = False Then
[542]332 mouseEntered = True
333 OnMouseEnter(me)
[564]334 trackMouseEvent(TME_LEAVE Or TME_HOVER)
[542]335 End If
[615]336 e.Handled = e.Handled And OnMouseMove(me)
[542]337 End Sub
338
[551]339 Sub OnMouseLeaveBase(sender As Object, e As MessageArgs)
[615]340 e.Handled = e.Handled And OnMouseLeave(Args.Empty)
[544]341 mouseEntered = False
342 End Sub
343
[564]344 Sub OnMouseHoverBase(sender As Object, e As MessageArgs)
345 Dim me = makeMouseEventFromMsg(e)
[615]346 e.Handled = e.Handled And OnMouseHover(me)
[564]347 End Sub
348
[551]349 Sub OnPaintBase(sender As Object, e As MessageArgs)
[615]350 If ActiveBasic.IsNothing(paintDC) Then
351 e.Handled = False
352 Else
353 Dim ps As PAINTSTRUCT
[646]354 BeginPaint(hwnd, ps)
[615]355 Try
356 OnPaintDC(New PaintDCArgs(ps.hdc, ps.rcPaint))
357 Finally
[646]358 EndPaint(hwnd, ps)
[615]359 End Try
360 End If
[542]361 End Sub
362
[551]363 Sub OnKeyDownBase(sender As Object, e As MessageArgs)
[615]364 e.Handled = e.Handled And OnKeyDown(New KeyArgs(makeKeysFormMsg(e)))
[544]365 End Sub
[542]366
[551]367 Sub OnKeyUpBase(sender As Object, e As MessageArgs)
[615]368 e.Handled = e.Handled And OnKeyUp(New KeyArgs(makeKeysFormMsg(e)))
[544]369 End Sub
370
[551]371 Sub OnChar(sender As Object, e As MessageArgs)
[615]372 e.Handled = e.Handled And OnKeyPress(New KeyPressArgs(e.WParam As Char))
[551]373 End Sub
[544]374
[551]375 Sub OnCreateBase(sender As Object, e As MessageArgs)
[698]376 Dim c = New CreateArgs(e.LParam As *CREATESTRUCT)
377 If e.LResult = -1 Then
378 c.Cancel = True
379 End If
380 e.Handled = e.Handled And OnCreate(c)
381 If c.Cancel Then
382 e.LResult = -1
383 Else
384 e.LResult = 0
385 End If
[544]386 End Sub
387
[561]388 Sub OnSize(sender As Object, e As MessageArgs)
[615]389 e.Handled = e.Handled And OnResize(New ResizeArgs(e.WParam, e.LParam))
[561]390 End Sub
391
[551]392 messageMap As System.Collections.Generic.Dictionary<Object /*DWord*/, MessageHandler>
[542]393
394Public
[473]395 /*!
[542]396 @biref メッセージイベントハンドラを登録する。
[473]397 @date 2007/12/04
398 */
[551]399 Sub AddMessageEvent(message As DWord, h As MessageHandler)
[542]400 If Not IsNothing(h) Then
401 If IsNothing(messageMap) Then
[551]402 messageMap = New System.Collections.Generic.Dictionary<Object, MessageHandler>
[542]403 End If
404 Dim msg = Hex$(message)
[551]405 Dim m = Nothing As MessageHandler
[542]406 If messageMap.TryGetValue(msg, m) Then
407 messageMap.Item[msg] = m + h
408 Else
409 messageMap.Item[msg] = h
410 End If
411 End If
[473]412 End Sub
413
[542]414 /*!
415 @biref メッセージイベントハンドラ登録を解除する。
416 @date 2007/12/04
417 */
[551]418 Sub RemoveMessageEvent(message As DWord, a As MessageHandler)
[542]419 If Not IsNothing(a) Then
420 If Not IsNothing(messageMap) Then
[545]421 Dim msg = Hex$(message)
[542]422 Dim m = messageMap.Item[msg]
423 If Not IsNothing(m) Then
424 messageMap.Item[msg] = m - a
425 End If
426 End If
427 End If
428 End Sub
429
430'--------------------------------
431' ウィンドウメッセージ処理
432
433
[473]434'--------
435'イベント
436
437#include "ControlEvent.sbp"
438
439'--------------------------------
[544]440' インスタンスメンバ変数
[473]441Private
[542]442 /*!
[615]443 @brief サブクラス化前のウィンドウプロシージャ
444 @date 2008/08/23
445 サブクラス化していなければNULL
446 */
447 prevWndProc As WNDPROC
448 /*!
[542]449 @brief マウスカーソルがクライアント領域に入っているかどうかのフラグ
450 外から中に入ってきたときにMouseEnterイベントを発生させるために用意している。
451 */
452 mouseEntered As Boolean
453 /*!
454 @brief ダブルクリックが起こったかどうかのフラグ
455 Click/MouseClickイベントのために用意している。
456 @date 2008/07/12
457 */
458 doubleClickFired As Boolean
[473]459
460'--------------------------------
[544]461' 初期ウィンドウクラス
[575]462Protected
[473]463 Static Function WndProcFirst(hwnd As HWND, msg As DWord, wp As WPARAM, lp As LPARAM) As LRESULT
464 Imports System.Runtime.InteropServices
465
[547]466 Dim rThis = FromHWndCore(hwnd)
[473]467 If IsNothing(rThis) Then
[575]468 rThis = _System_PtrObj(TlsGetValue(tlsIndex)) As Control
[473]469 TlsSetValue(tlsIndex, 0)
[575]470 If IsNothing(rThis) Then
[473]471 Goto *InstanceIsNotFound
472 End If
473 ' ウィンドウが作られて最初にWndProcFirstが呼ばれたとき
[575]474 rThis.AssociateHWnd(hwnd)
[473]475 End If
476 If msg = WM_NCDESTROY Then
[551]477 rThis.UnassociateHWnd()
[615]478 rThis.hwnd = 0
[473]479 End If
[551]480 If msg = WM_DESTROY And IsNothing(rThis.finalDestroy) = False Then
481 Dim f = rThis.finalDestroy
482 f(rThis, Args.Empty)
483 End If
484 WndProcFirst = rThis.WndProc(msg, wp, lp)
[473]485 Exit Function
486
487 *InstanceIsNotFound
[615]488 Dim err = String.Concat("Control.WndProcFirst: The attached instance is not found. msg = &h",
489 Hex$(msg), Ex"\r\n")
[559]490 OutputDebugString(ToTCStr(err))
[473]491 WndProcFirst = DefWindowProc(hwnd, msg, wp, lp)
492 End Function
[542]493
[551]494 /*!
495 @brief Controlインスタンスとウィンドウハンドルを結び付ける。
[615]496 @param[in] hwndNew 結び付けるウィンドウハンドル
[551]497 @date 2008/07/16
[575]498 これを実行することで、UnassociateHWndされるまでControlがGC対象にならなくなると共に、
499 FromHWndでウィンドウハンドルからControlインスタンスの取得が可能となる。
[551]500 */
[615]501 Sub AssociateHWnd(hwndNew As HWND)
[637]502 SetHWnd(hwndNew)
[615]503 Prop[PropertyInstance] = ObjPtr(This) As HANDLE
[575]504 comImpl.AddRef()
[559]505 End Sub
[551]506
507 /*!
508 @brief オーナーの破棄時にこのControlインスタンスとウィンドウハンドルの結び付けを解除するよう登録する。
509 @param[in] owner 結び付けの解除を連動させるControl
510 @date 2008/07/16
511 ownerのFinalDestoryでこのControlとHWNDとの結び付けを解除する。
512 */
513 Sub RegisterUnassociateHWnd(owner As Control)
514 If IsNothing(owner) = False Then
515 Dim e = New Handler(AddressOf(UnassociateHWndOnEvent))
516 If IsNothing(finalDestroy) Then
517 owner.finalDestroy = e
518 Else
519 owner.finalDestroy += e
520 End If
521 End If
522 End Sub
523
524 Sub UnassociateHWndOnEvent(sender As Object, e As Args)
525 UnassociateHWnd()
[615]526 hwnd = 0
[551]527 End Sub
528
529 Sub UnassociateHWnd()
[575]530 comImpl.Release()
[551]531 End Sub
532
[473]533' Static Const WM_CONTROL_INVOKE = WM_USER + 0 As DWord
534' Static Const WM_CONTROL_BEGININVOKE = WM_USER + 1 As DWord
535
536'--------------------------------
[575]537' インタフェース実装
538
539Public
540 Virtual Function QueryInterfaceImpl(ByRef iid As IID, ByRef pv As VoidPtr) As HRESULT
541 QueryInterfaceImpl = E_NOTIMPL
542 End Function
543
544Private
[615]545 /*!
546 @brief ウィンドウの寿命管理
547 Controlには次のAddRef-Releaseの対がある。
548 @li createImpl - WM_NCDESTROY(ウィンドウプロシージャがWndProcFirstの場合)
549 @li createImpl - UnassociateHWnd←UnassociateHWndOnEvent←RegisterUnassociateHWnd(その他のウィンドウクラスの場合)
550 @li Attach - WM_NCDESTROY(サブクラス化された場合)
551 なお、Control派生クラスをサブクラス化すると、後ろ2つが両方適用される。
552 */
[575]553 comImpl As COM.ComClassDelegationImpl
[615]554
[575]555'--------------------------------
[542]556' その他の補助関数
557Private
[564]558 Function trackMouseEvent(flags As DWord) As BOOL
559 If pTrackMouseEvent <> 0 Then
[542]560 Dim tme As TRACKMOUSEEVENT
561 With tme
562 .cbSize = Len(tme)
[564]563 .dwFlags = flags
564 .hwndTrack = hwnd
[542]565 .dwHoverTime = HOVER_DEFAULT
566 End With
[564]567 trackMouseEvent = pTrackMouseEvent(tme)
[542]568 End If
[564]569 End Function
[542]570
571'--------------------------------
[544]572' 初期化終了関連(特にウィンドウクラス)
[542]573Private
[473]574 'ウィンドウ作成時にウィンドウプロシージャへThisを伝えるためのもの
575 Static tlsIndex As DWord
576
577 Static hInstance As HINSTANCE
578 Static atom As ATOM
[542]579 Static hmodComctl As HMODULE
[564]580 Static pTrackMouseEvent As Detail.PTrackMouseEvent
[473]581
582 Static Const WindowClassName = "ActiveBasic.Windows.UI.Control"
583 Static Const PropertyInstance = 0 As ATOM
584Public
585 Static Sub Initialize(hinst As HINSTANCE)
586 tlsIndex = TlsAlloc()
[637]587 If tlsIndex = TLS_OUT_OF_INDEXES Then
588 ThrowWithLastError("Control.Initialize: TlsAlloc failed.")
589 End If
[473]590 hInstance = hinst
[564]591 hmodComctl = LoadLibrary("comctl32.dll")
592 pTrackMouseEvent = GetProcAddress(hmodComctl, ToMBStr("_TrackMouseEvent")) As Detail.PTrackMouseEvent
[473]593
594 Dim PropertyInstanceString = WindowClassName + " " + Hex$(GetCurrentProcessId())
595 PropertyInstance = GlobalAddAtom(ToTCStr(PropertyInstanceString))
[637]596 If PropertyInstance = 0 Then
597 ThrowWithLastError("Control.Initialize: GlobalAddAtom failed.")
598 End If
[473]599
600 Dim wcx As WNDCLASSEX
601 With wcx
602 .cbSize = Len (wcx)
603 .style = CS_HREDRAW Or CS_VREDRAW Or CS_DBLCLKS
604 .lpfnWndProc = AddressOf (WndProcFirst)
605 .cbClsExtra = 0
606 .cbWndExtra = 0
607 .hInstance = hinst
608 .hIcon = 0
609 .hCursor = LoadImage(0, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE Or LR_SHARED) As HCURSOR
[698]610 .hbrBackground = (COLOR_3DFACE + 1) As HBRUSH
[473]611 .lpszMenuName = 0
612 .lpszClassName = ToTCStr(WindowClassName)
613 .hIconSm = 0
614 End With
615 atom = RegisterClassEx(wcx)
616 If atom = 0 Then
[637]617 ThrowWithLastErrorNT("Control.Initialize: RegisterClasseEx failed.")
[473]618 End If
619 End Sub
620
621 Static Sub Uninitialize()
[542]622 If atom <> 0 Then
623 UnregisterClass(atom As ULONG_PTR As PCSTR, hInstance)
624 End If
625 If tlsIndex <> 0 And tlsIndex <> &hffffffff Then
626 TlsFree(tlsIndex)
627 End If
[564]628 If hmodComctl <> 0 Then
629 FreeLibrary(hmodComctl)
630 End If
[542]631 If PropertyInstance <> 0 Then
632 GlobalDeleteAtom(PropertyInstance)
633 End If
[473]634 End Sub
635End Class
636
[637]637/*!
638@brief WM_COMMANDで通知を行うコントロールの基底クラス
639@date 2008/08/28
640@auther Egtra
641親がWM_COMMANDを受け取ったら、RaiseCommandEventを呼ぶことを意図している。
642(Formで実装済み)
643*/
644Class WmCommandControl
645 Inherits Control
646Public
647 Abstract Function RaiseCommandEvent(notificationCode As Word) As Boolean
648End Class
649
[473]650End Namespace 'UI
651End Namespace 'Widnows
652End Namespace 'ActiveBasic
Note: See TracBrowser for help on using the repository browser.