Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Capturing mouse and keyboard messages from a graphic window in PBCC 4.04

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Capturing mouse and keyboard messages from a graphic window in PBCC 4.04

    In PBCC 4.03 and previous versions of PBCC 4, you could subclass the graphic window and capture these messages, there was a change in PBCC 4.04, where you must subclass the static control on the graphic window to capture these messages. A graphic window is a dialog box with one static control on it, the static control is what you actually do the drawing on. All you need to do is get the handle of this static control with hStatic = GetWindow(hGraphicWindow, %GW_CHILD) and subclass hStatic instead of hGraphicWindow. The following example illustrates this:
    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "Win32Api.Inc"
    '
    GLOBAL GraphicWindowChildOldProc AS LONG
    GLOBAL finished AS LONG
    GLOBAL hStatic  AS LONG
    '
    ' Timer callback routines, called every 200ms
    ' Just a little routine to display colored boxes on the graphic window
    SUB DisplayUpdate(BYVAL uID AS LONG, BYVAL uMsg AS LONG, _
                      BYVAL dwUser AS LONG, BYVAL dw1 AS LONG, BYVAL dw2 AS LONG)
      LOCAL r, g, b AS LONG
      LOCAL c AS LONG
      LOCAL x, y AS LONG
      LOCAL w, h AS LONG
      '
      GRAPHIC ATTACH dwUser, 0&, REDRAW
      GRAPHIC GET CLIENT TO w, h
      '
      r = RND(0, 255)
      g = RND(0, 255)
      b = RND(0, 255)
      '
      x = RND(0, w-21)
      y = RND(30, h-21)
      '
      c = RGB(r,g,b)
      '
      GRAPHIC BOX (x,y) - (x+25,y+25), 20, c, c
      '
      GRAPHIC REDRAW
    END SUB
    
    ' This is the function that is called whenever a Key or Mouse click is detected in the Graphics Window
    FUNCTION GraphicWindowChildNewProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
      LOCAL p AS POINTAPI
    
      SELECT CASE wMsg
        CASE %WM_NCHITTEST
        CASE %WM_MOUSEMOVE
          p.x = LO(WORD, lParam)  ' Current Mouse X Position in the graphic window
          p.y = HI(WORD, lParam)  ' Current Mouse Y Position in the graphic window
    
          ' Convert graphic window coordintates to screen (desktop) coordinates
          ClientToScreen(hWnd, p)
          ? "The mouse is at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+") or screen ("+FORMAT$(p.x)+","+FORMAT$(p.y)+")"
    
        CASE %WM_LBUTTONDOWN
          ? "you clicked the left mouse button at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")"
    
        CASE %WM_RBUTTONDOWN
         ? "you clicked the right mouse button at ("+FORMAT$(LO(WORD, lParam))+","+FORMAT$(HI(WORD, lParam))+")"
    
        CASE %WM_KEYDOWN
          IF CHR$(WPARAM) = "X" THEN
            finished = 1
          ELSE
            ? "you pressed the "+CHR$(wparam)+ " key"
          END IF
      END SELECT
      '
      FUNCTION = CallWindowProc(GraphicWindowChildOldProc, hWnd, wMsg, wParam, lParam)
    END FUNCTION
    
    FUNCTION PBMAIN
      LOCAL w              AS LONG
      LOCAL tid            AS LONG
      LOCAL hGraphicWindow AS LONG
      '
      RANDOMIZE
      '
      finished = 0
      '
      GRAPHIC WINDOW "Graphic Window SubClass Example", 0, 0, 320, 240 TO hGraphicWindow
      '
      ' Retreive the handle to the static control (the graphic) on the graphic window (dialog box)
      hStatic = GetWindow(hGraphicWindow, %GW_CHILD)
      '
      ' This function subclasses the Graphic Window
      ' Which means that any key or mouse presses in the Window
      ' Will cause the GraphicWindowChildNewProc Callback function to be called
      GraphicWindowChildOldProc = SetWindowLong(hStatic, %GWL_WNDPROC, CODEPTR(GraphicWindowChildNewProc))
      '
      ' Create an timer that runs the routine DisplayUpdate every 200ms
      tid = TimeSetEvent(200, 10, CODEPTR(DisplayUpdate), BYVAL hGraphicWindow, %TIME_PERIODIC)
      '
      GRAPHIC ATTACH hGraphicWindow, 0&, REDRAW
      GRAPHIC CLEAR %BLACK
      GRAPHIC COLOR %BLUE, %YELLOW
      GRAPHIC FONT "Times New Roman", 18, 1
      GRAPHIC PRINT "press X to quit"
      GRAPHIC REDRAW
      GRAPHIC SET FOCUS
      '
      w = 0
      '
      ' loop until an X is pressed on the graphic window
      WHILE finished = 0
        INCR w
        ' Every third iteration of the loop give back
        ' one time slick to Windows too prevent 100% CPU utilization
        ' See the SLEEP statement in the Help file
        IF w MOD 3 = 0 THEN
          SLEEP 0
        END IF
      WEND
      '
      ' Stop the timer from running
      TimeKillEvent(tid)
      '
      ' Set the graphics window to use the original Callback routine
      SetWindowLong(hStatic, %GWL_WNDPROC, GraphicWindowChildOldProc)
      '
      GRAPHIC ATTACH hGraphicWindow, 0&
      GRAPHIC WINDOW END
    END FUNCTION
    Sincerely,

    Steve Rossell
    PowerBASIC Staff

Working...
X