Why am I not getting a #WM_PAINT event on button press?

Windows specific forum
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Why am I not getting a #WM_PAINT event on button press?

Post by Mistrel »

I want to draw directly onto a button instead of using a ButtonImageGadget(). I can draw on it just fine with #WM_PAINT but I don't get a message to update it when it's clicked.

See this example. The button borders aren't drawn so it just looks like a black square. Click on it somewhere around the middle to see it update and fail to send an updated paint message:

Code: Select all

#ButtonGadget=1

Structure G_State
  *oldWndProc
EndStructure

Global g_State.G_State

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  Protected paint.PAINTSTRUCT
  Protected fill.RECT
 
  Select uMsg
  Case #WM_PAINT
    If hWnd=GadgetID(#ButtonGadget)
        hDC=BeginPaint_(hWnd,@paint)
       
        SetRect_(@fill.RECT,10,10,70,70)
        FillRect_(hDC,@fill,GetStockObject_(#BLACK_BRUSH))
       
        EndPaint_(hWnd,@paint)
     
      ProcedureReturn 0
    EndIf
  EndSelect
 
  ProcedureReturn CallWindowProc_(g_State\oldWndProc,hWnd,uMsg,wParam,lParam)
EndProcedure

OpenWindow(0,10,10,132,103,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ButtonGadget(#ButtonGadget,10,10,60,60,"")

g_State\oldWndProc=GetWindowLongPtr_(GadgetID(#ButtonGadget),#GWL_WNDPROC)
SetWindowLongPtr_(GadgetID(#ButtonGadget),#GWL_WNDPROC,@WinCallback())

Repeat
Until WaitWindowEvent(1)=#PB_Event_CloseWindow
User avatar
chi
Addict
Addict
Posts: 1034
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Why am I not getting a #WM_PAINT event on button press?

Post by chi »

You could do something like this...

Code: Select all

Global oldProc

Procedure BtnCallback(hWnd, Msg, wParam, lParam)
  Select Msg
      
    Case #WM_NCPAINT
      InvalidateRect_(hWnd, 0, 0)
      ProcedureReturn 0
      
    Case #WM_PAINT
      BeginPaint_(hWnd, ps.PAINTSTRUCT)
      Select SendMessage_(hWnd, #BM_GETSTATE, 0, 0)
        Case 0, 8
          FillRect_(ps\hdc, ps\rcPaint, GetStockObject_(#GRAY_BRUSH))  
        Case 512, 520, 616
          FillRect_(ps\hdc, ps\rcPaint, GetStockObject_(#LTGRAY_BRUSH))  
        Case 620
          FillRect_(ps\hdc, ps\rcPaint, GetStockObject_(#DKGRAY_BRUSH))           
      EndSelect  
      FrameRect_(ps\hdc, ps\rcPaint, GetStockObject_(#BLACK_BRUSH))   
      EndPaint_(hWnd, ps)
      ProcedureReturn 0 
      
    Case #WM_NCDESTROY
      SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @oldProc)
      ProcedureReturn 0
      
  EndSelect
  ProcedureReturn CallWindowProc_(oldProc, hWnd, Msg, wParam, lParam)
EndProcedure

OpenWindow(0, 0, 0, 320, 200, "", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)

ButtonGadget(0, 10, 10, 100, 30, "Button")
oldProc = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @BtnCallback())

HideWindow(0, #False)

Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          Beep_(800,50)
          
      EndSelect
  EndSelect
Until event = #PB_Event_CloseWindow
[/size]but in reality you should use #BS_OWNERDRAW
Et cetera is my worst enemy
Post Reply