Announcement

Collapse
No announcement yet.

Problems subclassing a graphics window

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

  • Richard Angell
    replied
    The GW has always AFAIK been a container for the actual child window where the drawing takes place. Sub-classing the child to trap the mouse moves was in all my examples. Sub-classing the child has been used and posted by many since 8.00 was first released. PBWin 9.00 and PBCC 5.00 introduced mouse and keyboard commands for GW's, possibly affecting the approach you were using before ... only PB could comment on that.

    Leave a comment:


  • allen hirsh
    replied
    Thank you! The answer was that in pb 9 I have to access the child of the graphic window, not the graphic window itself-as you clearly saw. In my code I don't appear to have to change the position of the getwindowlong, just switch the handle to the child. Thanks again.

    ALLEN HIRSH PhD
    VP, INFORMATION TECHNOLOGY
    CRYOBIOPHYSICA INC.
    12111 PARKLAWN DRIVE
    ROCKVILLE, MD 20852
    [email protected]
    301-881-3300 X 63 OR 62 SUPPORT
    301-881-2193 SALES
    301-881-0607 FAX

    Leave a comment:


  • Steven Pringels 3
    replied
    Hi Allen,

    I changed the following. Note hte SetWindowLong after the Graphic commands.
    Just for clarity.

    Code:
    GRAPHIC PAINT (50, 50),RGB(200, 200, 200)
    GRAPHIC COLOR -1, RGB(200, 200, 200)
    GRAPHIC LINE (50!, 40!) - (50!, CSNG(ART_Y_POS&-140)) ' pH
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), CSNG(ART_Y_POS&-140)) ' Column Volumes
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), 40!) '%ACIDIC BUFFER
    
    Local hGWChild As Long
    hGWChild        = GetWindow (hWndg, %GW_CHILD)
    hWndg = hGwChild
    SS1&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_USERDATA, BYVAL GetWindowLong(BYVAL HWNDG,BYVAL %GWL_WNDPROC)) ' Store the previous procedure in the user data area
    SS2&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_WNDPROC, BYVAL CODEPTR(pIsep_GRAPHICAL_WINDOW_SUBCLASSPROC)) ' Change to the new procedure address
    and then in the callback function (the subclassed callback)

    Code:
    Select Case cb.msg
    Case %wm_mousemove
        MsgBox "move"
    Case %wm_lbuttondown
        MsgBox "here"
    End select

    Leave a comment:


  • allen hirsh
    replied
    I am sorry it took me this long to reply. The subclassed callback in question in the commercial code is 2500 lines long and the drawing callback and winmain are also in the 500-1000 line category, so it took me a little time to reduce the code to bare bones.

    The following is the PB 9 code:

    $COMPILE EXE
    #REGISTER NONE
    #DEBUG ERROR ON
    DEFEXT A-Z
    #INCLUDE "pbforms.inc"
    $INCLUDE "C:\PBWin90\WinAPI\WIN32API.INC"
    GLOBAL HWND AS LONG
    GLOBAL HWNDG AS DWORD
    GLOBAL HWNDG_DC AS DWORD
    GLOBAL X&,Y&
    GLOBAL WINRECT AS RECT
    GLOBAL ID_ACTIVATE_GRAPHICS AS LONG
    GLOBAL END_DRAW&
    GLOBAL MESSAGE_STRING$
    GLOBAL FE&

    CALLBACK FUNCTION EXITButton()
    PRINT #FE&,MESSAGE_STRING$
    CLOSE
    GRAPHIC WINDOW END
    DIALOG END CB.HNDL, 0
    'RGB(70,90,250),RGB(230,90,50)
    END FUNCTION

    CALLBACK FUNCTION pIsep_GRAPHICAL_WINDOW_SUBCLASSPROC() AS LONG 'SUBCLASS THE GRAPHICS WINDOW

    STATIC PIX_COUNT&

    INCR PIX_COUNT& ' count how many times the callback is entered
    IF END_DRAW&>0 THEN 'IF ALL DRAWING IS DONE IN THE NEWLY FORMED GRAPHIC WINDOW, BEGIN RECORDING INCOMING MESSAGES
    MESSAGE_STRING$=MESSAGE_STRING$+STR$(PIX_COUNT&)& "," & HEX$(CB.MSG) & "," & HEX$(CB.CTLMSG) & "," & HEX$(%WM_MOUSEMOVE) & $CRLF
    END IF


    FUNCTION=CallWindowProc(BYVAL GetWindowLong(BYVAL HWNDG,BYVAL %GWL_USERDATA), BYVAL CB.HNDL, BYVAL CB.MSG, BYVAL CB.WPARAM, BYVAL CB.LPARAM)


    END FUNCTION


    CALLBACK FUNCTION ACTIVATE_PLOT_Button 'PLOT two simple axes in a graphic window



    IF CB.MSG=%WM_COMMAND THEN


    CtlMsg&=CB.CTLMSG

    SELECT CASE CtlMsg&
    CASE %BN_CLICKED


    ART_X_POS&=(X&\2)'SET AXIS SCALE LENGTHS
    ART_Y_POS&=(Y&\2)-50





    WIN_EXISTENCE&=IsWindow (BYVAL HWNDG) 'KILL any existing WINDOW
    IF WIN_EXISTENCE&<>0 THEN
    GRAPHIC ATTACH HWNDG, 0
    GRAPHIC WINDOW END
    DIALOG DOEVENTS
    DIALOG DOEVENTS
    END IF


    IF WIN_EXISTENCE&=0 THEN

    WINDOW_STRING$="TEST WINDOW"
    GRAPHIC WINDOW WINDOW_STRING$, ART_X_POS&, ART_Y_POS&, ART_X_POS&-50, ART_Y_POS&-50 TO HWNDG
    GRAPHIC ATTACH HWNDG, 0

    SS1&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_USERDATA, BYVAL GetWindowLong(BYVAL HWNDG,BYVAL %GWL_WNDPROC)) ' Store the previous procedure in the user data area
    SS2&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_WNDPROC, BYVAL CODEPTR(pIsep_GRAPHICAL_WINDOW_SUBCLASSPROC)) ' Change to the new procedure address

    GRAPHIC PAINT (50, 50),RGB(200, 200, 200) 'draw the two axes when plot button is pushed
    GRAPHIC COLOR -1, RGB(200, 200, 200)
    GRAPHIC LINE (50!, 40!) - (50!, CSNG(ART_Y_POS&-140)) ' pH
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), CSNG(ART_Y_POS&-140)) ' Column Volumes
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), 40!) '%ACIDIC BUFFER

    END IF

    END SELECT

    END IF
    END_DRAW&=1
    FUNCTION=1

    END FUNCTION





    FUNCTION PBMAIN () AS LONG
    #REGISTER NONE
    xyz%=0 'FORCE ACTUAL EXTENDED PRECISION CALCULATIONS
    ASM fstcw xyz%
    ASM OR xyz%, &B0000001100000000%
    ASM fldcw xyz%
    ID_ACTIVATE_GRAPHICS=122

    LOCAL Rresult AS LONG
    LOCAL hDlg2 AS LONG

    HWND=GetDesktopWindow ()
    WRECT_FIND&=GetWindowRect (BYVAL HWND, WINRECT)
    X&=ABS(WINRECT.nRight-WINRECT.nLeft)
    Y&=ABS(WINRECT.nBottom-WINRECT.nTop)
    FE&=FREEFILE 'STOP
    OPEN "MESSAGE ERROR CHECK PB 9.CSV" FOR OUTPUT AS FE&
    SS$="COUNT" & "," & "CB.MSG IN HEX" & "," & "CB.CTLMSG IN HEX" & "," & "%WM_MOUSE IN HEX
    PRINT #FE&,SS$
    PRINT #FE&,



    STYLE&=%DS_CENTERMOUSE OR %WS_SYSMENU OR %WS_CAPTION OR %DS_SETFOREGROUND OR %WS_MAXIMIZEBOX OR %WS_MINIMIZEBOX OR %WS_MAXIMIZE OR %WS_THICKFRAME
    exstyle&=%WS_EX_CLIENTEDGE OR %WS_EX_STATICEDGE


    TITLE$="MESSAGE TEST"
    DIALOG NEW %HWND_DESKTOP, TITLE$, , , 100, 100 , STYLE&, TO hDlg&

    DIALOG GET SIZE hDlg& TO DIA_x&, DIA_y&

    DIALOG UNITS hDlg&, DIA_x&, DIA_y& TO PIXELS DIA_xx&, DIA_yy&



    CONTROL ADD BUTTON, hDlg&, %IDCANCEL, "EXIT PROGRAM", 4, 4, 60, 30, 0 CALL EXITButton

    STYLE&=%BS_MULTILINE OR %BS_NOTIFY
    CONTROL ADD BUTTON, hDlg&, ID_ACTIVATE_GRAPHICS, "PLOT LINEAR GRAPH", 65, 4, 50, 30, STYLE&, CALL ACTIVATE_PLOT_Button


    DIALOG SHOW MODAL hDlg& TO Rresult

    END FUNCTION





    The PB 8 code is as follows:


    $COMPILE EXE
    #REGISTER NONE
    #DEBUG ERROR ON
    DEFEXT A-Z
    #INCLUDE "pbforms.inc"
    $INCLUDE "C:\PBWin80\WinAPI\WIN32API.INC"
    GLOBAL HWND AS LONG
    GLOBAL HWNDG AS DWORD
    GLOBAL HWNDG_DC AS DWORD
    GLOBAL X&,Y&
    GLOBAL WINRECT AS RECT
    GLOBAL ID_ACTIVATE_GRAPHICS AS LONG
    GLOBAL END_DRAW&
    GLOBAL MESSAGE_STRING$
    GLOBAL FE&

    CALLBACK FUNCTION EXITButton()
    PRINT #FE&,MESSAGE_STRING$
    CLOSE
    GRAPHIC WINDOW END
    DIALOG END CBHNDL, 0
    'RGB(70,90,250),RGB(230,90,50)
    END FUNCTION

    CALLBACK FUNCTION pIsep_GRAPHICAL_WINDOW_SUBCLASSPROC() AS LONG 'SUBCLASS THE GRAPHICS WINDOW

    STATIC PIX_COUNT&


    INCR PIX_COUNT&
    IF END_DRAW&>0 THEN 'IF ALL DRAWING IS DONE IN THE NEWLY FORMED GRAPHIC WINDOW, BEGIN RECORDING INCOMING MESSAGES
    MESSAGE_STRING$=MESSAGE_STRING$+STR$(PIX_COUNT&)& "," & HEX$(CBMSG) & "," & HEX$(CBCTLMSG) & "," & HEX$(%WM_MOUSEMOVE) & $CRLF
    END IF




    FUNCTION=CallWindowProc(BYVAL GetWindowLong(BYVAL HWNDG,BYVAL %GWL_USERDATA), BYVAL CBHNDL, BYVAL CBMSG, BYVAL CBWPARAM, BYVAL CBLPARAM)


    END FUNCTION


    CALLBACK FUNCTION ACTIVATE_PLOT_Button 'PLOT LINEAR ANALYSIS

    IF CBMSG=%WM_COMMAND THEN


    CtlMsg&=CBCTLMSG

    SELECT CASE CtlMsg&
    CASE %BN_CLICKED

    ART_X_POS&=(X&\2)'SET AXIS SCALE LENGTHS
    ART_Y_POS&=(Y&\2)-50





    WIN_EXISTENCE&=IsWindow (BYVAL HWNDG) 'KILL existing WINDOW
    IF WIN_EXISTENCE&<>0 THEN
    GRAPHIC ATTACH HWNDG, 0
    GRAPHIC WINDOW END
    DIALOG DOEVENTS
    DIALOG DOEVENTS
    END IF



    IF WIN_EXISTENCE&=0 THEN

    WINDOW_STRING$="TEST WINDOW"
    GRAPHIC WINDOW WINDOW_STRING$, ART_X_POS&, ART_Y_POS&, ART_X_POS&-50, ART_Y_POS&-50 TO HWNDG
    GRAPHIC ATTACH HWNDG, 0

    SS1&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_USERDATA, BYVAL GetWindowLong(BYVAL HWNDG,BYVAL %GWL_WNDPROC)) ' Store the previous procedure in the user data area
    SS2&=SetWindowLong (BYVAL HWNDG, BYVAL %GWL_WNDPROC, BYVAL CODEPTR(pIsep_GRAPHICAL_WINDOW_SUBCLASSPROC)) ' Change to the new procedure address

    GRAPHIC PAINT (50, 50),RGB(200, 200, 200)
    GRAPHIC COLOR -1, RGB(200, 200, 200)
    GRAPHIC LINE (50!, 40!) - (50!, CSNG(ART_Y_POS&-140)) ' pH
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), CSNG(ART_Y_POS&-140)) ' Column Volumes
    GRAPHIC LINE STEP - (CSNG(ART_X_POS&-50), 40!) '%ACIDIC BUFFER

    END IF

    END SELECT

    END IF
    END_DRAW&=1
    FUNCTION=1






    END FUNCTION





    FUNCTION PBMAIN () AS LONG
    #REGISTER NONE
    xyz%=0 'FORCE ACTUAL EXTENDED PRECISION CALCULATIONS
    ASM fstcw xyz%
    ASM OR xyz%, &B0000001100000000%
    ASM fldcw xyz%
    ID_ACTIVATE_GRAPHICS=122

    LOCAL Rresult AS LONG
    LOCAL hDlg2 AS LONG

    HWND=GetDesktopWindow ()
    WRECT_FIND&=GetWindowRect (BYVAL HWND, WINRECT)
    X&=ABS(WINRECT.nRight-WINRECT.nLeft)
    Y&=ABS(WINRECT.nBottom-WINRECT.nTop)
    FE&=FREEFILE 'STOP
    OPEN "MESSAGE ERROR CHECK PB 8.CSV" FOR OUTPUT AS FE&
    SS$="COUNT" & "," & "CBMSG" & "," & "CBCTLMSG"
    PRINT #FE&,SS$
    PRINT #FE&,



    STYLE&=%DS_CENTERMOUSE OR %WS_SYSMENU OR %WS_CAPTION OR %DS_SETFOREGROUND OR %WS_MAXIMIZEBOX OR %WS_MINIMIZEBOX OR %WS_MAXIMIZE OR %WS_THICKFRAME
    exstyle&=%WS_EX_CLIENTEDGE OR %WS_EX_STATICEDGE


    TITLE$="MESSAGE TEST PB 8"
    DIALOG NEW %HWND_DESKTOP, TITLE$, , , 100, 100 , STYLE&, TO hDlg&

    DIALOG GET SIZE hDlg& TO DIA_x&, DIA_y&

    DIALOG UNITS hDlg&, DIA_x&, DIA_y& TO PIXELS DIA_xx&, DIA_yy&



    CONTROL ADD BUTTON, hDlg&, %IDCANCEL, "EXIT PROGRAM", 4, 4, 60, 30, 0 CALL EXITButton

    STYLE&=%BS_MULTILINE OR %BS_NOTIFY
    CONTROL ADD BUTTON, hDlg&, ID_ACTIVATE_GRAPHICS, "PLOT LINEAR GRAPH", 65, 4, 50, 30, STYLE&, CALL ACTIVATE_PLOT_Button


    DIALOG SHOW MODAL hDlg& TO Rresult

    END FUNCTION




    As you can see I capture the message stream in the subclassed callback and store them in a global string that is printed to a file upon program exit. As in my large commercial program, the PB 8 program sees the %WM_MOUSEMOVE messages as you move the mouse over the graphic window, the PB 9 program does not. Any help is appreciated.

    Allen Hirsh

    Leave a comment:


  • Richard Angell
    replied
    Ms

    Show your 8.0x code then. You should have had to subclass the child Window of the GW for it to work (otherwise you would be subclassing the parent window not the child where the graphics really are). Like the simple example below which has only minor changes from v.8 and only subclasses the child window here.

    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "Win32API.inc"
    
    GLOBAL mx,my,mm,pOldGWProc,terminate AS LONG    ' Mouse x and y and flag
    
    FUNCTION GWSubProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS LONG, _
             BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
      SELECT CASE wMsg
        CASE %WM_MOUSEMOVE
          mm=1: mx=LO(WORD,lParam): my=HI(WORD,lParam)
          FUNCTION = 0 : EXIT FUNCTION
        CASE %WM_KEYDOWN
            terminate = -1
      END SELECT
      FUNCTION = CallWindowProc(pOldGWProc, hWnd, wMsg, wParam, lParam)
    END FUNCTION
    
    FUNCTION PBMAIN () AS LONG
        LOCAL hGW,hGWChild AS DWORD
        GRAPHIC WINDOW "",100,100,500,500 TO hGW
        GRAPHIC ATTACH hGW,0,REDRAW
        GRAPHIC FONT "Arial",14,1
        GRAPHIC COLOR %YELLOW,%BLUE
        GRAPHIC CLEAR
        GRAPHIC REDRAW
        hGWChild        = GetWindow (hGW, %GW_CHILD)
        pOldGWProc = SetWindowLong(hGWChild,%GWL_WNDPROC, CODEPTR(GWSubProc))
        WHILE hGW <> 0
            IF terminate = -1 THEN
                EXIT LOOP
            END IF
            IF mm = 1 THEN
                GRAPHIC SET POS (100,100) :  GRAPHIC PRINT SPACE$(40)
                GRAPHIC SET POS (100,100) :  GRAPHIC PRINT FORMAT$(mx)
                GRAPHIC SET POS (300,100) :  GRAPHIC PRINT SPACE$(40)
                GRAPHIC SET POS (300,100) :  GRAPHIC PRINT FORMAT$(my)
                mm = 0  'reset flag
            END IF
            GRAPHIC SET POS (50, 400)
            GRAPHIC PRINT  "Move or Press a key to quit"
            GRAPHIC REDRAW
        WEND
        SetWindowLong(hGWChild,%GWL_WNDPROC, pOldGWProc)
        GRAPHIC ATTACH hGW,0,REDRAW
        GRAPHIC WINDOW END
    END FUNCTION
    Last edited by Richard Angell; 13 Oct 2008, 11:23 AM. Reason: added additional text

    Leave a comment:


  • allen hirsh
    replied
    OK. My post is not my code, its just the sloppy one finger typing of an old guy who never learned typing in school, i.e %WM_MOUSEMOVE is correct in my code. Second, my numbers are in hex, so &h200 is 512. PB 8 certainly can recognize the equates if you have :

    $INCLUDE "C:\PBWin90\WinAPI\WIN32API.INC"

    at the top of your code as I do. Remember, the callback is seeing the 512 message coming in in PB 8, but is not seeing it in PB 9. The question remains why. If the mouse messages can be properly directed to the callback, I don't need to change any other code. While graphic window click detects clicks, only occasionally will advanced users click on the bitmap because that amounts to painting a nonlinear process. Mouse move detection is paramount. It is true, however, that mouse clicks are not coming through either, which only deepens my anxiety.

    Leave a comment:


  • Richard Angell
    replied
    Please note %WM_MOUSEMOVE is pre-defined by PBWin 9.00 as 512 and in your post %WM_ MOUSEMOVE has a space between _ and MOUSEMOVE... v.8 did not have these pre-defined equates.

    However, given that PBWin 9 introduces some mouse detection of it's own with GRAPHIC CLICK, it can make some sense to subclass not only the Graphic Window, but the child window it actually uses for graphic I/O as well. This has been well demonstrated in PBCC for some time.

    Leave a comment:


  • allen hirsh
    replied
    I suppose I am being dull, but the point I was trying to make is that the subclassed callback gets %WM_MOUSEMOVE (&H200) when compiled in PB 8.03, but not in PB 9. It looks like you are using another way of subclassing the graphic window, and, please no disrespect intended, I would rather not rewrite the entire subclass function if I can avoid it. The question remains, why is the callback receiving mousemove messages when compiled in PB 8, but not PB 9?

    Leave a comment:


  • Richard Angell
    replied
    One other example, without the hit test:

    GRAPHIC WINDOW CLICK does not return the button which was clicked, so a times you want to know which button was clicked. Possibly the example here could be expanded to detect combinations of mouse and keyboard keys, but that was no my intent. This uses some of the code Guy Dombrowski recently posted, which in turn probably draws on many of the other samples in the PBCC forum. Points to keep in mind: (1) undo the sub classing and (2) ensure termination of the message loop, which is needed if the system close ("X") buttton is used. Both these are needed to prevent memory leaks and proper termination:
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "Win32API.inc"
    GLOBAL mx,my AS LONG    ' Mouse x and y
    GLOBAL lb,rb AS LONG    ' Left and right mouse button
    GLOBAL mm,mk AS LONG    ' Detect mouse movements and key presses
    GLOBAL bg,fg AS LONG    ' Background and foreground colors
    GLOBAL wm,mb AS LONG    ' Wheel mouse and middle button
    GLOBAL mw    AS LONG    ' Wheel mouse detected
    GLOBAL hGW,hGWChild, pOldCBProc,pOldChildGWProc,hFnt AS DWORD
    
    FUNCTION ChildGWSubProc(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_MOUSEMOVE
          mm=1: mx=LO(WORD,lParam): my=HI(WORD,lParam)         ' Current Mouse X and Y Position in the graphic window
        CASE %WM_LBUTTONDOWN
          mk=1:lb=1: FUNCTION=0: EXIT FUNCTION                      ' Left button pressed
        CASE %WM_RBUTTONDOWN
          mk=1:rb=1: FUNCTION=0: EXIT FUNCTION                      ' Right button pressed
        CASE %WM_MBUTTONDOWN
          mk=1:mb=1: FUNCTION=0: EXIT FUNCTION                      ' Middle button pressed
    '    CASE %WM_MBUTTONUP
    '      mk=1:mb=0: FUNCTION=0: EXIT FUNCTION                      ' Middle button pressed
        CASE %WM_MOUSEWHEEL
          mw=1:wm=HI(WORD,wParam): IF wm>32768 THEN wm=-1 ELSE wm=1 ' Wheel turned (+)=up (-)=down
          FUNCTION=0: EXIT FUNCTION
      END SELECT
     FUNCTION = CallWindowProc(pOldChildGWProc, hWnd, wMsg, wParam, lParam)
    
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION MainGWSubProc (BYVAL hWnd AS DWORD, BYVAL Msg AS LONG, _
                            BYVAL wParam AS LONG, BYVAL lPARAM AS LONG) AS LONG
        SELECT CASE AS LONG Msg    'Select Case with AS LONG clause works faster
    
            CASE %WM_DESTROY
               IF hGW <> 0 THEN              'going to shut it all down
                    IF hGWChild <> 0 THEN       'is the child still subclassed
                        SetWindowLong hGWChild, %GWL_WNDPROC, pOldChildGWProc   'un-sub it
                        hGWChild = 0    'no longer need to track the handle separatedly
                    END IF
                    SetWindowLong hWnd, %GWL_WNDPROC, pOldCBProc  'un-sub the main GW
                    FONT END hFnt
                    GRAPHIC ATTACH hGW,0
                    GRAPHIC WINDOW END
                    hGW = 0     'signal window is closed to exit program loop, if running
                END IF
         END SELECT
         'pass all other messages back to the original processor
         FUNCTION = CallWindowProc(pOldCBProc, hWnd, Msg, wParam, lParam)
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN () AS LONG
        LOCAL rslt AS LONG
        FONT NEW "Arial",14,1 TO hFnt
    
        GRAPHIC WINDOW "Mouse Demo", 0, 0, 640, 480 TO hGW
        GRAPHIC ATTACH hGW,0, REDRAW
        GRAPHIC COLOR %YELLOW,%BLUE
        GRAPHIC SET FONT hFnt
        GRAPHIC CLEAR
        GRAPHIC SET POS (100, 400)
        GRAPHIC PRINT  "Move and click mouse or Press a key to quit"
        GRAPHIC REDRAW
    
        'subclass GW window  to intercept close
        pOldCBProc      = SetWindowLong(hGW, %GWL_WNDPROC, CODEPTR(MainGWSubProc))
        'find the graphic control child window handle
        hGWChild        = GetWindow (hGW, %GW_CHILD)
        'subclass graphic control child window for process the mouse and keys
        pOldChildGWProc = SetWindowLong(hGWChild, %GWL_WNDPROC, CODEPTR(ChildGWSubProc))
    
        WHILE hGW <> 0
            GRAPHIC INSTAT TO rslt
            IF rslt THEN
                GRAPHIC INPUT FLUSH
                PostMessage hGW,%WM_CLOSE,0,0
                EXIT DO
            END IF
            IF mm = 1 THEN
                GRAPHIC SET POS (100,100) :  GRAPHIC PRINT SPACE$(40)
                GRAPHIC SET POS (100,100) :  GRAPHIC PRINT FORMAT$(mx)
                GRAPHIC SET POS (300,100) :  GRAPHIC PRINT SPACE$(40)
                GRAPHIC SET POS (300,100) :  GRAPHIC PRINT FORMAT$(my)
                mm = 0  'reset flag
            END IF
            IF mk = 1 THEN
                IF lb = 1 THEN
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT SPACE$(50)
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT "Left Button Clicked"
                    lb = 0
                ELSEIF mb = 1 THEN
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT SPACE$(50)
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT "Middle Button Clicked"
                    mb = 0
                ELSEIF rb = 1 THEN
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT SPACE$(50)
                    GRAPHIC SET POS (100,200) :  GRAPHIC PRINT "Right Button Clicked"
                    rb = 0
                END IF
                mk = 0
            END IF
    
            IF mw = 1 THEN
                ' Wheel turned (+)=up (-)=down
                IF wm = -1 THEN
                    GRAPHIC SET POS (100,300) :  GRAPHIC PRINT SPACE$(50)
                    GRAPHIC SET POS (100,300) :  GRAPHIC PRINT "Wheeled Down"
                ELSE
                    GRAPHIC SET POS (100,300) :  GRAPHIC PRINT SPACE$(50)
                    GRAPHIC SET POS (100,300) :  GRAPHIC PRINT "Wheeled Up"
                END IF
                wm = 0
                mw = 0
            END IF
    
            GRAPHIC SET POS (100, 400)
            GRAPHIC PRINT  "Move, click or wheel mouse ... or Press a key to quit"
            GRAPHIC REDRAW
        WEND
    
    END FUNCTION

    Leave a comment:


  • Richard Angell
    replied
    Ms

    Here is a slightly re-worked example developed from code started by Mark Hunter, et.al.. It's like many that I and others have posted in the PBCC forum some time past as well as recently. Converted to PBWin this AM. This should get you started ... maybe:
    Code:
    #COMPILER PBWIN
    #COMPILE EXE
    #DIM ALL
    #REGISTER NONE
    #INCLUDE "Win32API.inc"
    '
    GLOBAL hGW,hGWChild, pOldCBProc,pOldChildGWProc AS DWORD
    '
    FUNCTION ChildGWSubProc (BYVAL hWnd AS DWORD, BYVAL Msg AS LONG, _
                            BYVAL wParam AS LONG, BYVAL lPARAM AS LONG) AS LONG
        LOCAL lResult AS LONG
        'send messages on to original processor for %WM_NCHITTEST checking
        lResult = CallWindowProc(pOldChildGWProc, hWnd, Msg, wParam, lParam)
        SELECT CASE AS LONG Msg    'Select Case with AS LONG clause works faster
            CASE %WM_NCHITTEST
                IF lResult = %HTTRANSPARENT THEN lResult = %HTCLIENT
    
            CASE %WM_MOUSEMOVE
                'printing the data in the message
                GRAPHIC ATTACH hGW,0
                GRAPHIC SET POS (10,30)
                GRAPHIC PRINT SPACE$(60)
                GRAPHIC SET POS (10,30)
                GRAPHIC PRINT FORMAT$(LOWRD(lParam))
                GRAPHIC SET POS (150,30)
                GRAPHIC PRINT FORMAT$(HIWRD(lParam))
                IF wParam <> 0 THEN
                    GRAPHIC SET POS (10,50)
                    GRAPHIC PRINT SPACE$(100)
                    GRAPHIC SET POS (10,50)
                    SELECT CASE AS LONG wParam
                        CASE %MK_CONTROL  : GRAPHIC PRINT "Moving, Ctrl Down"
                        CASE %MK_LBUTTON  : GRAPHIC PRINT "Dragging, LBtn Down"
                        CASE %MK_MBUTTON  : GRAPHIC PRINT "Dragging, MBtn Down"
                        CASE %MK_RBUTTON  : GRAPHIC PRINT "Dragging, RBtn Down"
                        CASE %MK_SHIFT    : GRAPHIC PRINT "Moving, Shift Down"
                        CASE = %MK_SHIFT OR %MK_LBUTTON   : GRAPHIC PRINT "Dragging, Shift+LBtn Down"
                        CASE = %MK_SHIFT OR %MK_MBUTTON   : GRAPHIC PRINT "Dragging, Shift+MBtn Down"
                        CASE = %MK_SHIFT OR %MK_RBUTTON   : GRAPHIC PRINT "Dragging, Shift+RBtn Down"
                        CASE = %MK_CONTROL OR %MK_LBUTTON : GRAPHIC PRINT "Dragging, Ctrl+LBtn Down"
                        CASE = %MK_CONTROL OR %MK_MBUTTON : GRAPHIC PRINT "Dragging, Ctrl+MBtn Down"
                        CASE = %MK_CONTROL OR %MK_RBUTTON : GRAPHIC PRINT "Dragging, Ctrl+RBtn Down"
                        CASE = %MK_SHIFT OR %MK_CONTROL OR %MK_LBUTTON   : GRAPHIC PRINT "Dragging, Ctrl+Shift+LBtn Down"
                        CASE = %MK_SHIFT OR %MK_CONTROL OR %MK_MBUTTON   : GRAPHIC PRINT "Dragging, Ctrl+Shift+MBtn Down"
                        CASE = %MK_SHIFT OR %MK_CONTROL OR %MK_RBUTTON   : GRAPHIC PRINT "Dragging, Ctrl+Shift+RBtn Down"
                        CASE = %MK_LBUTTON OR %MK_MBUTTON  : GRAPHIC PRINT "Dragging, LBtn+MBtn Down"
                        CASE = %MK_LBUTTON OR %MK_RBUTTON  : GRAPHIC PRINT "Dragging, LBtn+RBtn Down"
                        CASE = %MK_MBUTTON OR %MK_RBUTTON  : GRAPHIC PRINT "Dragging, MBtn+RBtn Down"
                        CASE = %MK_LBUTTON OR %MK_MBUTTON OR %MK_RBUTTON  : GRAPHIC PRINT "Dragging, LBtn+MBtn+RBtn Down"
                        'other insane cases for mouse combos ... up to the Ctrl+Shift+LBtn+MBtn+RBtn Down ...
                    END SELECT
                ELSE
                    GRAPHIC SET POS (10,50)
                    GRAPHIC PRINT SPACE$(100)
                END IF
    
            CASE %WM_LBUTTONDOWN
                GOSUB MKeys
                GRAPHIC PRINT "Last Pressed  LEFT mouse button"
    
            CASE %WM_MBUTTONDOWN
                GOSUB MKeys
                GRAPHIC PRINT "Last Pressed  CNTR mouse button"
    
            CASE %WM_RBUTTONDOWN
                GOSUB MKeys
                GRAPHIC PRINT "Last Pressed  RIGHT mouse button"
    
            CASE %WM_KEYDOWN
                IF wParam = %VK_Q THEN
                    PostMessage hGW,%WM_CLOSE,0,0
                    EXIT FUNCTION
                END IF
    
    
        END SELECT
        'done so ready for next time a message comes this way, passback lResult to Windows
        FUNCTION = lResult
        EXIT FUNCTION
    
    MKeys:     'setup for pressed mouse key message
        GRAPHIC ATTACH hGW,0
        GRAPHIC SET POS (10,80)
        GRAPHIC PRINT SPACE$(100)
        GRAPHIC SET POS (10,80)
        'not processing other keys held down in the sample
    RETURN
    END FUNCTION
    '
    FUNCTION MainGWSubProc (BYVAL hWnd AS DWORD, BYVAL Msg AS LONG, _
                            BYVAL wParam AS LONG, BYVAL lPARAM AS LONG) AS LONG
        SELECT CASE AS LONG Msg    'Select Case with AS LONG clause works faster
    
            CASE %WM_DESTROY
                IF hWnd = hGW THEN              'going to shut it all down
                    IF hGWChild <> 0 THEN       'is the child still subclassed
                        SetWindowLong hGWChild, %GWL_WNDPROC, pOldChildGWProc   'un-sub it
                        hGWChild = 0    'no longer need to track the handle separatedly
                    END IF
                    SetWindowLong hWnd, %GWL_WNDPROC, pOldCBProc  'un-sub the main GW
                    hGW = 0
                END IF
         END SELECT
         'pass all other messages back to the original processor
         FUNCTION = CallWindowProc(pOldCBProc, hWnd, Msg, wParam, lParam)
    END FUNCTION
    
    FUNCTION PBMAIN () AS LONG    'no need for SDK type WINMAIN here
        LOCAL ncWidth&, ncHeight&
        DESKTOP GET CLIENT TO ncWidth&, ncHeight&   'going to make a big GW
        GRAPHIC WINDOW "Example GW Subclassed",0,0,ncWidth&, ncHeight& TO hGW    'big GW
        'attach the MAIN GW and set font, and ...
        GRAPHIC ATTACH hGW,0
        GRAPHIC FONT "Arial", 14,1
        GRAPHIC SET POS (10,10)
        'set some persistent text for this sample, to id other writes to show the
        'subclassing below is "alive"
        GRAPHIC PRINT "Mouse X"
        GRAPHIC SET POS (150,10)
        GRAPHIC PRINT "Mouse Y"
        GRAPHIC SET POS (10,350)
        GRAPHIC PRINT "Press Q to quit"
        'subclass GW window  to intercept close
        pOldCBProc      = SetWindowLong(hGW, %GWL_WNDPROC, CODEPTR(MainGWSubProc))
        'find the graphic control child window handle
        hGWChild        = GetWindow (hGW, %GW_CHILD)
        'subclass graphic control child window for process the mouse and keys
        pOldChildGWProc = SetWindowLong(hGWChild, %GWL_WNDPROC, CODEPTR(ChildGWSubProc))
        WHILE hGW <> 0 : WEND     'will run until the main GW is "extinctly" ended
    END FUNCTION
    Last edited by Richard Angell; 10 Oct 2008, 09:41 AM. Reason: added credit

    Leave a comment:


  • Bob Zale
    replied
    Hi Allen--

    Rick Angel gave you the correct answer when you posted the same question in another thread...


    See this thread
    http://www.powerbasic.com/support/pb...ad.php?t=38632

    Rick Angell

    Leave a comment:


  • allen hirsh
    started a topic Problems subclassing a graphics window

    Problems subclassing a graphics window

    I have a created software over the last two years for my company’s patented chromatographic methods (including the software). We sell several different versions of the software and it has proven itself as reliable and extremely effective. All versions compile and perform flawlessly under PB 8.03. For the user the heart of the program is a Powerbasic graphical window that displays plots of critical chemical information. The information at each point of the plot is accessed by placing the mouse cursor over a small plot ellipse. The relevant information is then displayed in a custom tool tip. To access the mouse cursor information in the graphic window I subclassed the window using getwindowlong and setwindowlong. Below is a sample of the captured messages in hex as they flow into the sublassed callback function as the mouse moves across the graphic window, first in PB 8 where everything works perfectly-and the message stream is consistent with this upon examination-then in pB 9, where only the first of the expected messages appears:


    In PB8
    %WM_ MOUSEMOVE=200
    COUNT CBMSG

    841 84
    842 20
    843 200
    844 84
    845 20
    846 200
    847 84
    848 20
    849 200
    850 84
    851 20
    852 200


    In PB9
    COUNT CB.MSG CB.CTLMSG

    819 20 27
    820 20 27
    821 20 27
    822 20 27
    823 20 27
    824 20 27
    825 20 27
    826 20 27
    827 20 27
    828 20 27
    829 20 27
    830 20 27
    831 20 27
    832 20 27

    I guess I am misusing the new message functions, but I cannot figure out how. Any suggestions?? It is really important to us that we can compile our commercial products usi
Working...
X