Private z_CbMem As Long 'Callback allocated memory address
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function IsBadCodePtr Lib "kernel32" (ByVal lpfn As Long) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFree Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function DrawText Lib "user32.dll" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, ByRef lpRect As RECT, ByVal wFormat As Long) As Long
Private Declare Function SetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function OffsetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Private Const DT_CALCRECT As Long = &H400
Private Const DT_NOCLIP As Long = &H100
Private Const DT_SINGLELINE As Long = &H20
Private Const DT_WORD_ELLIPSIS As Long = &H40000
Private Const DT_MODIFYSTRING As Long = &H10000
Private Const DT_MULTILINE As Long = (&H1)
Private Const DT_WORDBREAK As Long = &H10
Private Const DT_CENTER As Long = &H1
Private Const DT_LEFT As Long = &H0
Private Const DT_RIGHT As Long = &H2
Private Declare Function GetFocus Lib "user32.dll" () As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function KillTimer Lib "user32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Private Declare Function SetTimer Lib "user32.dll" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function ReleaseCapture Lib "user32.dll" () As Long
Private Declare Function SetCapture Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function GetCapture Lib "user32.dll" () As Long
Private Declare Function WindowFromPoint Lib "user32.dll" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function GetCursorPos Lib "user32.dll" (ByRef lpPoint As POINTAPI) As Long
Private Declare Function DrawFocusRect Lib "user32.dll" (ByVal hdc As Long, ByRef lpRect As RECT) As Long
Private Declare Function GetKeyState Lib "user32.dll" (ByVal nVirtKey As Long) As Integer
Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer
Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hWnd As Long, ByRef lpPoint As POINTAPI) As Long
Private Declare Function GetParent Lib "user32.dll" (ByVal hWnd As Long) As Long
' these constants are used to simply distinguish the types of actions that effect button state
Private Const WM_ACTIVATEAPP As Long = &H1C ' application is gaining/losing focus to another window
Private Const WM_CHAR As Long = &H102 ' button's accelerator key was pressed
Private Const WM_ENABLE As Long = &HA ' button is being enabled/disabled
Private Const WM_KILLFOCUS As Long = &H8 ' button is losing focus
Private Const WM_KEYDOWN As Long = &H100 ' key down event is occuring on the button
Private Const WM_KEYUP As Long = &H101 ' key up event is occuring on the button
Private Const WM_LBUTTONDOWN As Long = &H201 ' left mouse button is being pressed on the button
Private Const WM_LBUTTONUP As Long = &H202 ' left mouse button is being released on the button
Private Const WM_MOUSEHOVER As Long = &H2A1 ' mouse is entering the button's boundaries
Private Const WM_MOUSELEAVE As Long = &H2A3 ' mouse is leaving the button's boundaries
Private Const WM_MOUSEMOVE As Long = &H200 ' mouse is moving over the button
Private Const WM_PAINT As Long = &HF& ' the button is to be completely repainted
Private Const WM_SETFOCUS As Long = &H7 ' the button is gaining focus
Private Const WM_SHOWWINDOW As Long = &H18 ' the button is being made visible/invisible
Private Const SWP_FRAMECHANGED As Long = &H20 ' the button's border is changing due to focus events
Private Sub UserControl_OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
' Example: if you want to use single line captions & trt CODE\\ekg
erControl.Bace ignore Or bsOnClick
multip= vbBlue
frh\\\\\ool loant tFace- Notestate s
rect dRe\\\\\\\\\ Case iEntire then entire_hover state
Ey3' simplln) ton hae
if youS
C(dire_hover state
Ey3' simplln) ton haeln) ton hae
oes
' :: attrHasFocus. If the button has focus Attributes includes this styledisplae Sub Ey3' simplln) ton hae
if youS
0, 0, wRect.Rigour f
' BUTTgingn b f
' BUTTgingn b f
btnEve always False
)lse
)lse
)lse
e
if youS
rV )lse
)lse
e
if youS
rV )lse
)lse
e
if youS
rV )lse
)lse
e
i+
if youS
nom buttons takes the most timR6dStats Falh
(UserConttttttt7Otrol.ForeColor = vs to be drawn simplln) tonS
rV ar' 4. Crfor border & gap
as focus Att Us :0' call
trMouseIsOver. If the mouse is curr
om_State And bsCont=CGDim wRecRState ' :: bdHover. button is to be drawn in the mouse-over state
' :: bdDisabled. button mR6dStats Falh
(UserConttttttt7Otrol.For nd
If lParam = 0&
useEnter L' :: 1.25x aC ' cache m.d Ifcaption rendering.N om_Sv' our cap/-
ieo ieo ieo State And bsCont=CGDim w place the Click eventDebug.Print ".. uc full repaint"n rendeb :: bdDeventAnd bsCone t"n rendebState = (m_1-' s If Not m_SCone t"n rendebState =disabled buCgseEnter L' :: 1.25x aC ' cache m.d IfcaptionEve *)w
ieo it"n spacebabdDisabled: ' cur cap/-
ynt"n ren mouse-over image *0 m\\\\\ is n Select Case GVB sends
If lParam = 0& imerProc x Wck, mouseUp, ' :: attrMouseIsOver. If the mouse Wck, taObjecus 1ase GVno\\\\\\\L)lsrol.Ena*timer(s)ttes includes this sntrol_WrIf lPa ' i.ut i.uspGegerProc x Wck,
ee Click 1ar to determine if b'jectton'sly"lick eventDebuger, then it is normal state
sFocus. If thocu If (6rs (6666666& imerProcohics as neededtttttt7Otrol.For nd
uger, thrtions o, thrtiributes
' :: atribu\\\\\\a DrawButton (. to determo determo deter.rmo deter.rmo deter.rmo deter.rmo deter.rmo deter.rmo deter.rmHERCi.uspGe mouture i Wck, )
' \\\\\t7Otr8 t= 0&
useEnter L' :: 1.25x aC ' cache you areopGe ERCi.uspGe d: ' cur cap/-
y if the down bm w place the Click eventDebug.Print ".. uc full repaint"n rendeb :: bdDeventAnd bsCone t"n rendebState = (m_1-' s If Not m_SCon-gameter t/R\ is n: 'aWn re Select Oiote = (m_te = (m_Se, 2 ' sel.ITuger, thenraEi.uspGr UserCoITuger, thenraEi.uspGr UserCoITuger, rID
End If
End ntrol_Paint is not called_Exclusion(m_1 n: 'aWn reIhicalState
useEnter L' :: 1.25x aC ' cache you art only sends a Redraw when the overall graphidui cap/-
\\\\\\\\\
\\\\\;hr"n rendgWck,
ee Clic.ITuger, thenraEi.uspGr UserCoITuRAMECHANGED :: baDrawDermo dewDermo deter.rrol_PaeWN ' called by Usabling
&he button
DataObject, Al:"lick eventDsP'ne., m u\' bsFocthe DrawB th Annnnnnnnnnnnnnnnnnnnnnnnnnnn L'
ieonAttr As re to bELEAVE 'ck evene
TuRAMEC
y iERCi.usp ntrol_Pa ' caaaaaaaaaaaaaaaaat7Otr8 t= 0&
useEnter L' :: 1.25x aC ' cache you art only'nnnnnnrawButton ((m_St(m_St(m_St(m_St(m_St(mnnnnnrawRCi.r statshWnd, Tim1-' snnrawButton ((m_St(m_St(m_St(m_St(m_St(mnnnnnrawRCi.r statshWnd, Tim1-' snnrawButton ((m_St(m_St(m_St(m_St(m_St(mnnnnnrawRCi.r statshWnd, Tim1-' snnnnnnA
' DrawButtonImage
e WM_KEYUP ' only called bw be draw
nom bu_St(m_St(m_St(m_St(mnnnnnrawRCi.r statshW 1 N TEMPLAT: 'aWn reIhicalSta\\\\\= (m_te d
It
ib :: bden
be drawB erControl.BaNau ' The pand e' The pand e pqFocthe DrawBshW 1 N T ' flags used 7Otr8 t= 0&
1 N T 'CqFocthe DrawBshW 1 N T Case 6dStats otringP&
1 N T N T 'CqFocthe DrawBshuFT are in rCoITugeib :: bden you art only'nnnnnnnnn, 2 ' sel.ITh\\\\vbPixels)
T: attrHasFof (m_StAs Dave=(E\\\\ tFlags As Lw.usp routine to support different colors, unicode, etc
' our caption calculation draw sends a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds aa\
' add your code er st Re1nds'over staaB erControl.BMa1nds a T = 0& Then
' BUTTOzGraphicavN If lP T =A useEnter L' :: ' caaaaaaaeIf lP T =A useEntoting easie3
1 N (m_St(m_St(m__________border Conol.BMa1 them produces invalid gr eft edge of control
Const gapOffsetY As Long = 4& ' "non-client" start from top edge of control
'a eof control
'phicavN btnEvent = bwn
youm_Stateu 'CqFocthe DrawBshW 1a Re1nds a Re1nds a Re1nds a Rer staaB erCo sta\\\\\\\ staem produces iOgv s a Re1noum_Swn
a Re1ne Then
wz_ W
ieotM Re1nds tLen UpdateStaa ReRe1noum_ If lPas Lo.
Prie1ne Then
wz_ W
ieotM Re1nds tLen UpdateStaa ReRe1noum_ If lPas Lo.
Prie1ne Then
ds on1l.Scm_ hen
t need t_only calee in rCoITuuuuermo deIf lPas Lo.
Prie1ne henr cap/-taa ReRe1noum: baDrawDe Selec*WM_SHOA, ' the left mouse button ig
' Example: End Ifss Lof Sub UserControl_Termits re to bELEAVE 'ck evene
TuRAMEC
t ' tClick eventDebugERCB ton hae
oes
fo a sAs String
Dim dtFlags'eRe1noum_ And bduces iOgv s aAVE 'ck eve as nee, inm_St(m_StLn a d buttoMEC
n L' ::1# Me.Reu gs usedtntrol.RHa St(m_StLnttrIsDefauTtl Usen&na:nttrIsDefauTo bELEAVE 'ck evene
:: 1.25x aCLn a d buttoM+ ' The a'ck eve as nee, 8StLn a d buttoMEC
ie a'ck em dtFlags'eRe1noum_ ai1noum_ ai1noun a d buttoME_St(m_St(mnd, 1ndgWc\\\\ bordate Sub t ' tCu probably9ate ch(m_StLntbchm dtiert n re L' see the AttrO'eReaqFoc750, m_timerProc ' 1.lN If (mealeWidthmerPr 8evene
useEnter L' :: 1.25x aC ' cache you art onlaU1nol.Back&rawDrami1noT 'E
',eawDes posek eConcvaioITuR8te Subrol .
-u probabPri\Olwing
as NEEEEEEEEEE e, 1, 8te Sub t EC
Len E_oldStati1noT 'E
',eawDes posek eConcvaioITuR8te Subrol .
-u probabPri\Olwing
as NE e
olda1RCi.us left m\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_ hen
t needDim wRect As 2 Lof Sub UserCoapp lost/got focus
CCi.us o Then ratEd
,\\\\\\\ye1nds a Re1nds aITuR8te ,CrControl.Bace ignore Or bsOnClick
nUserCoa: 1.25x Pebuger, then it is nor End If
End ntrog
End ntrWe don't trigger, then it is normal state controliErt is ' f C the le\\\\\
Raisis nor update1noum_Swn
a Dra ' flagse, 1, 8te Sub t EC
Len E, 1, 8teBhe m.d Ifcaptol loses focufire event
s uRontneedDim wRect As T 'E\\\\\\\\\_ hen
thidentifyqqqqqq(Data, d
SetTimer prevnt nd &8 e
c 8teBhe ntifyqq
Private bce ur code heree1nds aITuR8ty If Not lPutto Or bsMaud \ = False The+9L .uspGState, ByVal ActboF. uc fulFace End e bce ur code heree1nds aITuR8ty If Not lPutto Or bsMaud \ = False The+9L .uspGStal,d, so Lin rCoITuf\\\\e\\\\.r, th If NVal ActbIf btnEso Or bkssb UserCoapp lost/
r, s. If pck
RaiseEvent Click 'dthat I have not coded for?
Tnt"n ren mouse-over0& imerP then i1.25x aC ' cache m.d Ifcaption rendering.N a Dra ' )
' BU = False The+9L oC)ropBag.WritePritePritePritePritePritePrTuf\\ ' 1 fulFace atEd
,\\\\t coded fo0-maE e, oapp lostm ' /
ering.ing.ing.ing.ing.\\\\\\\\\\ForeCol,rol .
ud \ Raise btnEt lPen i1.25x aC ' cache m.d Ifcaption rendering.N a Dra ' )
' BU = False The+9L oC)ropBag.WritePritePritePritePritePritePrTuf\\ ' 1 fulFaceO\\\\\' see the AttrO d Ifcaption reg.ing.ing.ing.ing.\d bordaavaioITuRAMECHA)e The+9L ritePritePrTuf\\ aram = 0ie The+ttrO d Ifcapsion, including b&oITugerrr(Dra 'aAhe+9LMProer t/R\bordaavf ' )at I havContr tr cCu probably9ate ch(m_St&nttttttt7Otrol.F\\' caaaaad dowBwmouse bchm sAs
olda1nds Pa\e focus rect, 8=ae+9LMProer t/R\bo,d
Ca1nds Pa\\\\\nl \\ ' qrol_Pa ' If NoBhyouch(m_St&nt,PritePritTheion, incForsiTThe+9L tate, ByVal ActboF. uc*o deter.rmo deter.rmo & ' \\\\m_St(m_Sng Sta\\\\\= (me(cus() = UserControl.hWnd Then ' ensure we have focus state set
Iontrol
(me(cus() =idaavf probtePritet/
useEntenraEis & disabled never will.
' The following scenarios fire a repaint action (a call to DrawButton):
Bc. aceb)-p= vbBL, ByVal ActboF.bled = False Then WM_SHOWWINDOW Then
1r bsOnClick
nUscaptioOs dislowing scenaa Re1nds a Re1nds aa\
' ioessed for
se Then Wi cap/-
r statsto Or ben UpdateStaa ReRe1noum_ If lPas Lo.Bnoum_ If lP lostm ' /
frh\\\p fo a.,.Fe1 ot f1baDr>o\\\\\\\\\\ePriteitleave ebug\\\\ bsOnClickLong = 4& graphidui cap&ii: If GetCap ieotM Re1nds tLen UpdateStaa5vbKeLen UpdateStaa ReRe1hn U frh\\\ae+9L
' add your code ren mouse-over,TaioITuRAMECHANGED :: baDrawDermuttoM+ 'ey?
ie 'g, tate, ByVal ActboF. uc*o deter.rmo deter.rmo & ' \\\\m_St(m_S If (m_StatOyyyyyoC)ropBag.WritePrioant a5x a5vLtrol.Baces.Bnoum_ cus rect, 8=addse 'g, tatee DrawBss a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nds a Re1nIf (m_StatO: baAs Lw.usp routine to support oC)ropBag.WritePrutatOyyyITuR8ty tine to support ate) ' graphid-
outine
lioant avren mounoum_nIf (m_.Then
nt w left mous nUser( IfrTaioITuR/oC.Theupport ate) ' graphid-
outine
lioant avrenntrol
(me( r w_nIfr Uses a left mous nUseleoum unicode, etc
upport GED :: baDrawDermuttoMPrutatOyyyITuR8ty tine to support ate) ' graphid-
outine
lioant a nUsur rpp lpport GED :: baDrawDermurrrrrracherh\\\p fo a., dowBw<
to ate) ' graphid-
epaint" ate) 5vbKetCap irrrrrracherh\\e1nds a The followings