;---------- [Place in the Application or Include file] ----------
ControlButt    PROTO :DWORD, :DWORD, :DWORD, :DWORD
ButtonType     PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

;---------- [Place in the Application file (.asm)] ----------
.data
ButtClass      db  'BUTTON',0
szRaised       db  'Raised',0
FontName       db  'MS Sans Serif',0

.data?
hButt3         dd  ?
lpButCtrl      dd  ?
hFontB         dd  ?

lf             LOGFONT         <>

.code

start:
.
.
.
      .if wMsg == WM_CREATE
;---------- [Create the Button Control] ----------
         INVOKE     CreateWindowEx, NULL, addr ButtClass, addr szRaised,
                    WS_CHILD or WS_VISIBLE,
                    20, 20, 115, 26, hwnd, 86, hInst, 0
            mov     hButt3, eax

;---------- [Subclass the Control] ----------
         INVOKE     SetWindowLong, hButt3, GWL_WNDPROC, ControlButt
            mov     lpButCtrl, eax

;---------- [Create the Button Font] ----------
         INVOKE     lstrcpy, addr lf.lfFaceName, addr FontName
            mov     lf.lfHeight, 14
            mov     lf.lfWeight, 600
         INVOKE     CreateFontIndirect, ADDR lf
            mov     hFontB, eax
.
.
;---------- [Delete Objects] ----------
      .elseif wmsg == WM_DESTROY
         INVOKE     DeleteObject, hFontB
.
.
.

;=================================================
; Subclass procedure for the Control Buttons
;=================================================
ControlButt  PROC  hwnd:DWORD, wMsg, wParam, lParam
LOCAL     UpDown:DWORD, hBR

      INVOKE     CallWindowProc, lpButCtrl, hwnd, wMsg, wParam, lParam

         mov     UpDown , 1
      .if wMsg == WM_PAINT
PaintEM:
            mov     eax, hwnd
         .if eax == hButt3
            INVOKE     ButtonType, hButt3, hFontB, 000000ffh, 00000000h, addr szRaised, UpDown
         .endif
            mov     UpDown, 1

      .elseif wMsg == WM_LBUTTONDOWN || wMsg == WM_LBUTTONDBLCLK
            mov     UpDown, 2
            jmp     PaintEM

      .elseif wMsg == WM_MOUSEMOVE || wMsg == WM_NCMOUSEMOVE
         .if wParam == MK_LBUTTON
               mov     UpDown, 2
         .else
               mov     UpDown, 1
         .endif
            jmp     PaintEM

      .elseif wMsg == WM_LBUTTONUP
            mov     UpDown, 1
            jmp     PaintEM
      .endif

Ret1:
         mov     eax, TRUE
         ret
ControlButt  ENDP

;=============================================================================
; Creates various appearances of Buttons
;=============================================================================
ButtonType  PROC hButt:DWORD, hFont, BackC, TextC, szText, Bor
LOCAL     rect:RECT
LOCAL     hOldFont:DWORD, hBR, hDC

      INVOKE     GetDC, hButt
         mov     hDC, eax
      .if Bor == 2
            mov     BackC, 00929292h
      .endif
      INVOKE     CreateSolidBrush, BackC
         mov     hBR, eax
      INVOKE     GetClientRect, hButt, addr rect
      INVOKE     FillRect, hDC, addr rect, hBR
      INVOKE     DeleteObject, hBR            ; Delete the brush handle
         mov     eax, hButt
      .if Bor == 1 && eax == hButt3
         INVOKE     DrawEdge, hDC, addr rect, BDR_RAISEDOUTER, BF_TOPLEFT
         INVOKE     DrawEdge, hDC, addr rect, BDR_RAISEDOUTER, BF_BOTTOMRIGHT
      .elseif Bor == 2
         INVOKE     DrawEdge, hDC, addr rect, EDGE_SUNKEN, BF_RECT
      .endif
      INVOKE     SelectObject, hDC, hFont     ; Select the font into the dc
         mov     hOldFont, eax
      INVOKE     SetTextColor, hDC, TextC     ; Set the text color
      INVOKE     SetBkMode, hDC, TRANSPARENT  ; Set the text background to transparent
      INVOKE     DrawText, hDC, szText, -1, addr rect, DT_CENTER or DT_VCENTER or DT_SINGLELINE
      INVOKE     SelectObject, hDC, hOldFont
      INVOKE     ReleaseDC, hButt, hDC        ; Release the control dc

         xor    eax, eax
         ret
ButtonType  ENDP
