Announcement

Collapse
No announcement yet.

Problems subclassing a graphics window

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

  • 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

  • #2
    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

    Comment


    • #3
      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
      Rick Angell

      Comment


      • #4
        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
        Rick Angell

        Comment


        • #5
          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?

          Comment


          • #6
            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.
            Rick Angell

            Comment


            • #7
              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.

              Comment


              • #8
                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
                Rick Angell

                Comment


                • #9
                  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

                  Comment


                  • #10
                    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
                    So here we are, this is the end.
                    But all that dies, is born again.
                    - From The Ashes (In This Moment)

                    Comment


                    • #11
                      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

                      Comment


                      • #12
                        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.
                        Rick Angell

                        Comment

                        Working...
                        X