Announcement

Collapse
No announcement yet.

CALLBACK

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

  • CALLBACK

    Is there a hierarchy to callback functions?

    For example:

    DIALOG NEW blah, blah, blah

    CONTROL ADD BUTTON blah blah blah CALL ButCallBack
    CONTROL ADD TEXTBOX blah, blah, blah Call TxtCallBack

    SHOW MODAL blah CALL DiaCallBack

    Does the SHOW MODAL callback take precedence over the button and textbox callbacks?
    Walt Decker

  • #2
    Walt --

    No, just the opposite. If you don't specify the optional CALLBACK function for a control, its messages will be sent to the dialog's CALLBACK function. If you do specify a CALLBACK function for a control, it will get the control's messages instead of the dialog's CALLBACK function. Messages that don't have anyplace else to go are sent to the dialog's CALLBACK function.

    -- Eric

    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>



    [This message has been edited by Eric Pearson (edited June 04, 2000).]
    "Not my circus, not my monkeys."

    Comment


    • #3
      Adding to my previous response... If a control's callback function does not set FUNCTION = 1 to tell Windows that it handled a message, the message will be "passed on" to the dialog's CALLBACK function.

      Compile and run this program...

      Code:
      #COMPILE EXE 
      #REGISTER NONE
      #DEBUG ERROR ON
      #DIM ALL
        
      #INCLUDE "WIN32API.INC"
       
      CALLBACK FUNCTION DlgCallback
      	IF CBMSG = %WM_COMMAND AND CBCTLMSG = %BN_CLICKED  THEN
      		MSGBOX "Dialog Callback"
      	END IF
      END FUNCTION
       
      CALLBACK FUNCTION Button1Callback
      	IF CBMSG = %WM_COMMAND AND CBCTLMSG = %BN_CLICKED THEN
      		MSGBOX "Button Callback"
      	END IF
      	FUNCTION = 1
      END FUNCTION
       
      FUNCTION PBMain AS LONG
      	DIM hDlg AS LOCAL LONG
      	DIALOG NEW 0, "Callback Demo (Alt+F4=Exit)",,, 120,32 TO hDlg
      	CONTROL ADD BUTTON, hDlg, 100, "Click Me", 10, 10, 50, 14 CALL Button1Callback
      	CONTROL ADD BUTTON, hDlg, 101, "Or Me", 60, 10, 50, 14
      	DIALOG SHOW MODAL hDlg, CALL DlgCallback
      	FUNCTION = 1
      END FUNCTION
      ...and you'll see that the buttons do different things. Remove the FUNCTION=1 line from the buttons's callback function and you'll see two message boxes when you click that button.

      -- Eric

      ------------------
      Perfect Sync: Perfect Sync Development Tools
      Email: mailto:[email protected][email protected]</A>

      "Not my circus, not my monkeys."

      Comment


      • #4
        Eric, do you live here?

        The reason I asked about callback precedence is that the following code is supposed to begin counting when the OK button is pressed and continue counting until the cancel button is pressed. However, it starts counting before the window is actually visible, stops until the OK button is pressed, then only counts while the mouse cursor is moved in the window. In addition, it doesn't recognize when the cancel or the system button is pressed.

        In DOS programming I can easily control what happens but this windows stuff is a different ball of string.

        #COMPILE EXE

        $INCLUDE "ddt.inc"

        DECLARE CALLBACK FUNCTION ModalCall
        DECLARE CALLBACK FUNCTION Cncl
        DECLARE CALLBACK FUNCTION Ok
        DECLARE SUB AddOne(Q AS LONG)

        FUNCTION PBMAIN

        #REGISTER NONE

        DIM LnDiaHand AS GLOBAL LONG
        DIM LnIds(1 TO 3) AS GLOBAL LONG
        DIM StTxt AS GLOBAL STRING
        DIM LnMask AS GLOBAL LONG
        DIM Result AS LONG
        LnIds(1) = 1
        LnIds(2) = 2
        LnIds(3) = 3

        StTxt = "This is a test"
        LnMask = %DS_SETFOREGROUND OR %WS_CAPTION OR %WS_MAXIMIZEBOX OR %WS_MINIMIZEBOX
        LnMask = LnMask OR %WS_SYSMENU OR %WS_THICKFRAME

        DIALOG NEW LnDiaHand,StTxt,,,100,100,LnMask, TO LnDiaHand

        CONTROL ADD LABEL,LnDiaHand,LnIds(1),"",10,10,50,10,%SS_SUNKEN
        CONTROL ADD BUTTON,LnDiaHand,LnIds(2),"OK",10,30,20,20,%BS_FLAT
        CONTROL ADD BUTTON,LnDiaHand,LnIds(3),"Cancel",10,60,30,20,%BS_NOTIFY OR %WS_TABSTOP, CALL Cncl

        DIALOG SHOW MODAL LnDiaHand, CALL ModalCall TO Result

        IF Result THEN MSGBOX "good by"

        END FUNCTION

        CALLBACK FUNCTION ModalCall

        DIM LnMess AS LONG, I AS STATIC LONG

        SELECT CASE CBMSG

        CASE %WM_COMMAND
        IF CBCTLMSG=%BN_CLICKED THEN
        LnMess = CBCTL
        IF LnMess = LnIds(2) THEN
        CONTROL DISABLE LnDiaHand, LnIds(2)
        CONTROL ENABLE LnDiaHand, LnIds(3)
        CALL AddOne(I)
        IF BIT(I,0) THEN
        CONTROL SET TEXT LnDiaHand, LnIds(1),STR$(I)
        END IF
        END IF
        IF LnMess = LnIds(3) THEN
        DIALOG END LnDiaHand, 1
        END IF
        END IF
        CASE ELSE
        CALL AddOne(I)
        IF BIT(I,0) THEN
        CONTROL SET TEXT LnDiaHand, LnIds(1), STR$(I)
        END IF
        END SELECT

        END FUNCTION

        SUB AddOne(LnI AS LONG)

        LnI = LnI + 1

        END SUB

        CALLBACK FUNCTION Cncl
        BEEP
        DIALOG END LnDiaHand,1
        END FUNCTION


        ------------------
        Walt Decker

        Comment


        • #5
          > do you live here?

          Yes.

          At least it seems that way sometimes. I learn a lot by reading this BBS, and researching the answers. But there are days and weeks when I'm too pre-occupied to even read messages, much less respond to them.

          I haven't run you program (too busy this morning ) but my guess is that you're not filtering your messages properly. Notice in my sample program I used this:

          Code:
          IF CBMSG = %WM_COMMAND AND CBCTLMSG = %BN_CLICKED  THEN
          You see, an equate like %BN_CLICKED is really just a mnemonic for a number (in this case zero) and many different Window messages may use that same number. You have to do a double (or sometimes triple) test to make sure you know what you're seeing.

          If that's not it, maybe somebody else will jump in...

          -- Eric


          ------------------
          Perfect Sync: Perfect Sync Development Tools
          Email: mailto:[email protected][email protected]</A>



          [This message has been edited by Eric Pearson (edited June 05, 2000).]
          "Not my circus, not my monkeys."

          Comment


          • #6
            That's OK, Eric. I found out what the problem is. It seems that when one specifies a dialog callback in the dialog show statement, that callback is the main driver even though various buttons have their own callback. What I had to do was set a global flag in the button callback and check that flag in the dialog callback (nowhere in the docs or help does it mention that the dialog callback acts as the main loop). Anyway, it now works. However, it seems that certain other processes that I've been trying to implement don't. For example, I've tried to create some different controls in either the dialog callback or a button callback. But it doesn't seem to work. I guess controls can only be created in either WINMAIN or PBMAIN, but they can be altered or destroyed almost anywhere.

            Thanks for your time, Eric. I appreciate it.

            Walt Decker

            ------------------
            Walt Decker

            Comment


            • #7
              Walt --

              > It seems that when one specifies a dialog callback in
              > the dialog show statement, that callback is the main
              > driver even though various buttons have their
              > own callback. What I had to do was set a global flag...

              It really sound to me like you're not setting FUNCTION = 1 in your button's callback function, so messages are being automatically forwarded to the dialog's callback function. That is the Windows default behavior and it is actually pretty useful, because it allows you to have two different callback functions process any given message if that is what you want to do.

              Think of it this way... it is very unlikely that your button's callback function handles 100% of the messages that Windows generates for your button. (Ever put a BEEP in a callback function? It will drive you crazy! ) When your callback funtion handles a specific message you're supposed to set FUNCTION = 1 to tell Windows "stop processing this message". The remaining hundreds of unhandled messages have to go somewhere, so they are forwarded to your dialog's callback function. If that function doesn't handle them (and set FUNCTION = 1 to indicate that it has done so) then they are forwarded to the internal "default window proc" which handles everything that your callback functions don't, which is 99% of the total number of messages.

              > I guess controls can only be created in either
              > WINMAIN or PBMAIN, but they can be altered or
              > destroyed almost anywhere.

              Not true! You can create controls anywhere, with one exception. Windows requires that you confine GUI-related operations to a single thread. For example, you can't create a window in one thread and run its message loop in another thread. But as long as you do that, there are no restrictions like the one you're describing. At least not that I'm aware of!

              -- Eric

              ------------------
              Perfect Sync: Perfect Sync Development Tools
              Email: mailto:[email protected][email protected]</A>



              [This message has been edited by Eric Pearson (edited June 06, 2000).]
              "Not my circus, not my monkeys."

              Comment


              • #8
                Following up... I just wrote a quick test program that adds a new button when certain a button is clicked, and it works fine. The control is created in the callback function with no problems.

                -- Eric

                ------------------
                Perfect Sync: Perfect Sync Development Tools
                Email: mailto:[email protected][email protected]</A>



                [This message has been edited by Eric Pearson (edited June 06, 2000).]
                "Not my circus, not my monkeys."

                Comment


                • #9
                  Hmm. I did go back and set FUNCTION = 1 in the dialog call back, but perhaps I set it in the wrong place. Also, I used CONTROL GET LOC and CONTROL GET SIZE to find the location of a textbox in a button callback then erased the textbox and tried to create a label control in the same place. It could be that I actually drew the label outside of the dialog window. I'll try it again.

                  You are a big help, Eric. Thanks.

                  ------------------
                  Walt Decker

                  Comment


                  • #10
                    One small note to add: you should avoid trying to kill/destroy a control during processing of a message that it generated itself. IOW, any form of notification message from a control should not be used to kill that same control.

                    It is akin to suicide, and the Windows Dialog engine does not appreciate it! (g)

                    ------------------
                    Lance
                    PowerBASIC Support
                    mailto:[email protected][email protected]</A>
                    Lance
                    mailto:[email protected]

                    Comment

                    Working...
                    X