Announcement

Collapse
No announcement yet.

DDT - Dialog Send

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

  • DDT - Dialog Send

    I want to send a modal dialog one or two messages just before showing. The idea is to send two longs, one a number representing what I am doing with the dialog, and the other a pointer to a string that I want to use to hold the return. All this is to avoid two more global variables.

    I have tried dialog send with a wm_user + 1 but the dialog callback does not seem to receive the message, or I am not reading it correctly.

    Lance etal. While you are considering the setting of the default dialog font, how about letting us send a parameter too?

    [email protected]

  • #2
    Dennis --
    Callback receives messages, but you can process it after all initial messages (INITDIALOG, PAINT and so on).
    But there is very simple solution.

    Code:
       #Compile Exe
       #Register None
       #Dim All
       #Include "win32api.inc"
       CallBack Function hDlg_CB()
          Static Active As Long
          Select Case CbMsg
             Case %WM_INITDIALOG: ShowWindow CbHndl, 0
             Case %WM_USER + 1: Dialog Set Size CbHndl, CbWparam, CbLparam
                                Control Add TextBox, CbHndl, 101, "", _
                                    0.1 * CbWparam, 0.1 * CbLparam, 0.8 * CbWparam, 0.7 * CbLparam
             Case %WM_USER + 2: Dialog Set Loc CbHndl, CbWparam, CbLparam
                                ShowWindow CbHndl, 1
          End Select
       End Function
    
       Function PbMain
         Dim hDlg As Long
         Dialog New 0, "Select Test", 0, 0, 0, 0, %WS_SYSMENU To hDlg
         PostMessage hDlg, %WM_USER + 1, 300, 200
         PostMessage hDlg, %WM_USER + 2, 150, 100
         Dialog Show Modal hDlg, Call hDlg_CB
       End Function
    ------------------

    Comment


    • #3
      Thank you Semen - the PostMessage did the trick. There is some info in the win help about not sending pointers with PostMessage so passing a string pointer may not work, but at least I can pass the "type" of function I am using.

      Now I am curious, why do SendMessage and Dialog Send (some relationship I assume) not work?

      The dialog is serving as a password input. It handles the setting/changing of the password and entering the password. There are 6 functions: 1. Enter the password (first try) 2. Enter the password (second try) 3. Enter the password (third try) 4. Too many tries warning 5. Change/sed password 6. Confirm new password.

      I want to send the "action" to the dlgproc and, if possible a string pointer for the new password so I do not have to use a global.

      [email protected]

      ------------------

      Comment


      • #4
        Originally posted by Dennis Pearson:
        TThere is some info in the win help about not sending pointers with PostMessage so passing a string pointer may not work, but at least I can pass the "type" of function I am using.
        Why ?
        Code:
           #Compile Exe
           #Register None
           #Dim All
           #Include "win32api.inc"
           CallBack Function hDlg_CB()
              Static Psw As Asciiz Ptr
              Static Active As Long
              Select Case CbMsg
                 Case %WM_INITDIALOG: ShowWindow CbHndl, 0
                 Case %WM_USER + 1: Psw = CbWparam
                 Case %WM_USER + 2: Dialog Set Size CbHndl, CbWparam, CbLparam
                                    Control Add TextBox, CbHndl, 101, "", _
                                        0.1 * CbWparam, 0.1 * CbLparam, 0.8 * CbWparam, 0.7 * CbLparam
                                    Control Set Text CbHndl, 101, @Psw
                 Case %WM_USER + 3: Dialog Set Loc CbHndl, CbWparam, CbLparam
                                    ShowWindow CbHndl, 1
              End Select
           End Function
        
           Function PbMain
             Dim hDlg As Long, Password As Asciiz * 10
             Dialog New 0, "Select Test", 0, 0, 0, 0, %WS_SYSMENU To hDlg
             Password = "Semen"
             PostMessage hDlg, %WM_USER + 1, VarPtr(Password), 0
             PostMessage hDlg, %WM_USER + 2, 300, 200
             PostMessage hDlg, %WM_USER + 3, 150, 100
             Dialog Show Modal hDlg, Call hDlg_CB
           End Function


        ------------------

        Comment


        • #5
          Maybe this is what you are looking for. GetWindowLong and SetWindowLong can be very usefull.

          Regards
          Peter
          Code:
          #COMPILE EXE
          #INCLUDE "win32api.inc"
           
          TYPE MYTYPE
              WhatIAmDoing AS LONG
              ReturnString AS ASCIIZ*128
          END TYPE
           
          DECLARE CALLBACK FUNCTION DlgProc
           
          FUNCTION PBMAIN
           
              LOCAL hDlg AS LONG
              LOCAL mt AS MYTYPE
           
              mt.WhatIAmDoing = 1
           
              DIALOG NEW 0, "",,,400, 300, %WS_SYSMENU OR %WS_MINIMIZEBOX OR %DS_CENTER TO hDlg
              SetWindowLong hDlg, %GWL_USERDATA, VARPTR(mt)
              DIALOG SHOW MODAL hDlg CALL DlgProc
           
              MSGBOX mt.ReturnString
           
          END FUNCTION
           
          CALLBACK FUNCTION DlgProc
           
              STATIC pmt AS MYTYPE PTR
           
              SELECT CASE CBMSG
              CASE %WM_INITDIALOG
                  pmt = GetWindowLong(CBHNDL, %GWL_USERDATA)
                  SELECT CASE @pmt.WhatIAmDoing
                  CASE 1
                      ' ...
                  CASE 2
                      ' ...
                  CASE 3
                      ' ...
                  END SELECT
           
              CASE %WM_SYSCOMMAND
                  IF CBWPARAM = %SC_CLOSE THEN
                      @pmt.ReturnString = "This is the end"
                      DIALOG END CBHNDL
                  END IF
           
              END SELECT
           
          END FUNCTION
          ------------------

          Comment


          • #6
            Thank you for the ideas.

            ------------------
            [email protected]

            Comment


            • #7
              Peter,
              It is my understanding that DDT uses %GWL_USERDATA for it's own purposes so
              it is unavailable for user data.

              James


              ------------------

              Comment


              • #8


                according to dave, it is the dwl_user that is used for ddt.

                ------------------
                [email protected]

                Comment


                • #9
                  I am inclined to think PB uses the GWL_UserData also. If I add a msgbox "1" to Peter's example, I get an error. Setting the userdata on close does not seem to be a problem.

                  SELECT CASE @pmt.WhatIAmDoing
                  CASE 1
                  msgbox "1"

                  ------------------
                  [email protected]

                  Comment


                  • #10
                    Peter's suggestion looks enough interesting.
                    I modified it - address through caption.
                    Code:
                       #Compile Exe
                       #Register None
                       #Dim All
                       #Include "win32api.inc"
                    
                       Type MYTYPE
                          WhatIAmDoing As Long
                          ReturnString As Asciiz * 128
                       End Type
                    
                       CallBack Function DlgProc
                          Static pmt As MYTYPE Ptr
                          Local Capt As Asciiz * 12
                          Select Case CbMsg
                             Case %WM_INITDIALOG
                                GetWindowText CbHndl, Capt, 11: pmt = Val(Capt)
                                SetWindowText CbHndl, Str$(@pmt.WhatIAmDoing) + @pmt.ReturnString
                             Case %WM_DESTROY: @pmt.ReturnString = "This is the end"
                          End Select
                       End Function
                    
                       Function PbMain
                          Local hDlg As Long, mt As MYTYPE
                          mt.WhatIAmDoing = 1: mt.ReturnString = "  Set PassWord  "
                          Dialog New 0, Str$(VarPtr(mt)),,,400, 300, %WS_SYSMENU To hDlg
                          Dialog Show Modal hDlg Call DlgProc
                          MsgBox mt.ReturnString
                       End Function
                    ------------------

                    Comment


                    • #11
                      Great minds...

                      That is very similar to my solution. Since my dialog has a simple caption I want the user to see ("Password") I can use the caption to pass the ptr to the wm_initdialog, get the pointer, then show the "real" caption.

                      Such fun and I get paid too

                      ------------------
                      [email protected]

                      Comment


                      • #12
                        I replaced %GWL_USERDATA with %DWL_MSGRESULT.
                        I'm not quite sure what %DWL_MSGRESULT is - but it seems to work

                        Regards
                        Peter

                        ------------------


                        [This message has been edited by Peter Stephensen (edited March 31, 2000).]

                        Comment


                        • #13
                          Thank you Semen - the PostMessage did the trick. There is some info in the win help about not sending pointers with PostMessage so passing a string pointer may not work, but at least I can pass the "type" of function I am using.
                          You heard correctly, PostMessage sends the message and does not wait for the window to process the message before returning. However, it is ok to do it in the PB/WinMain function because all of the variables defined there never get removed from memory till the application ends. Use this anywhere else & you must point at a variable on the heap. (global)
                          Code:
                          PostMessage hDlg, %WM_USER + 1, VarPtr(Password), 0 ' sends pointer
                          PostMessage hDlg, %WM_USER + 2, 300, 200 
                          PostMessage hDlg, %WM_USER + 3, 150, 100
                          Dialog Show Modal hDlg, Call hDlg_CB ' the function will not exit and Password will not be removed from the stack.

                          ------------------

                          Comment


                          • #14
                            Inspired by Semens method I made the functions SetDDTUserData and GetDDTUserData. The trick is to make a secret button.

                            Regards
                            Peter
                            Code:
                            #COMPILE EXE
                            #INCLUDE "win32api.inc"
                             
                            '------------ DDT UserData - functions ------------------------------------------
                             
                            FUNCTION SetDDTUserData(BYVAL hDlg AS LONG, BYVAL UserDataID AS LONG, BYVAL UserData AS LONG) AS LONG
                                CONTROL ADD BUTTON, hDlg, UserDataID, FORMAT$(UserData),0,0,0,0
                            END FUNCTION
                             
                            FUNCTION GetDDTUserData(BYVAL hDlg AS LONG, BYVAL UserDataID AS LONG) AS LONG
                             
                                LOCAL s AS STRING
                             
                                CONTROL GET TEXT hDlg, UserDataID TO s
                                FUNCTION = VAL(s)
                             
                            END FUNCTION
                             
                            '----------------------------------------------------------------------------------
                            ' Main program:
                            '----------------------------------------------------------------------------------
                            DECLARE CALLBACK FUNCTION DlgProc
                             
                            TYPE DLGHDR
                                cDlgType AS LONG
                                zReturnString AS ASCIIZ*128
                            END TYPE
                             
                            %ID_USERDATA = 100
                             
                            FUNCTION PBMAIN
                             
                                LOCAL hDlg AS LONG
                                LOCAL dh AS DLGHDR
                             
                                DIALOG NEW 0, "",,,400, 300, %WS_SYSMENU OR %WS_MINIMIZEBOX OR %DS_CENTER TO hDlg
                                dh.cDlgType = 2
                                SetDDTUserData hDlg, %ID_USERDATA, VARPTR(dh)
                                DIALOG SHOW MODAL hDlg CALL DlgProc
                             
                                MSGBOX dh.zReturnString
                             
                            END FUNCTION
                             
                            CALLBACK FUNCTION DlgProc
                             
                                STATIC pdh AS DLGHDR PTR
                             
                                SELECT CASE CBMSG
                                CASE %WM_INITDIALOG
                                    pdh = GetDDTUserData(CBHNDL, %ID_USERDATA)
                                    SELECT CASE @pdh.cDlgType
                                    CASE 1
                                        MSGBOX "Type 1"
                                    CASE 2
                                        MSGBOX "Type 2"
                                    CASE 3
                                        MSGBOX "Type 3"
                                    CASE ELSE
                                        MSGBOX "Some other type"
                                    END SELECT
                             
                                CASE %WM_DESTROY
                                    @pdh.zReturnString = "The end"
                                END SELECT
                             
                            END FUNCTION
                            ------------------

                            Comment


                            • #15
                              Kind of complicated, but useful if you want to store loads of data. However, if you only want to store one of more 32-bit values (which could include pointers to strings, etc), then Windows provides a much easier way to do this... "Window Properties". Take a look at:

                              SetProp()
                              GetProp()
                              RemoveProp()
                              EnumProps()
                              EnumPropsEx()
                              PropEnumProp()
                              PropEnumPropEx()


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

                              Comment


                              • #16
                                Lance,

                                All I want is to be able to store a 32-bit value. Your aproach is better.

                                Regards
                                Peter


                                ------------------


                                [This message has been edited by Peter Stephensen (edited April 02, 2000).]

                                Comment


                                • #17
                                  Using Get/SetProp:
                                  Code:
                                  #COMPILE EXE
                                  #INCLUDE "win32api.inc"
                                   
                                  DECLARE CALLBACK FUNCTION  DlgProc
                                   
                                  TYPE DLGHDR
                                      cDlgType AS LONG
                                      zReturnString AS ASCIIZ*128
                                  END TYPE
                                   
                                  %ID_USERDATA = 100
                                   
                                  FUNCTION PBMAIN
                                   
                                      LOCAL hDlg AS LONG
                                      LOCAL dh AS DLGHDR
                                   
                                      DIALOG NEW 0, "",,,400, 300, %WS_SYSMENU OR %WS_MINIMIZEBOX OR %DS_CENTER TO hDlg
                                      dh.cDlgType = 2
                                      SetProp hDlg, BYVAL %ID_USERDATA, VARPTR(dh)
                                      DIALOG SHOW MODAL hDlg CALL DlgProc
                                   
                                      MSGBOX dh.zReturnString
                                   
                                  END FUNCTION
                                   
                                  CALLBACK FUNCTION DlgProc
                                   
                                      STATIC pdh AS DLGHDR PTR
                                   
                                      SELECT CASE CBMSG
                                      CASE %WM_INITDIALOG
                                          pdh = GetProp(CBHNDL, BYVAL %ID_USERDATA)
                                          SELECT CASE @pdh.cDlgType
                                          CASE 1
                                              MSGBOX "Type 1"
                                          CASE 2
                                              MSGBOX "Type 2"
                                          CASE 3
                                              MSGBOX "Type 3"
                                          CASE ELSE
                                              MSGBOX "Some other type"
                                          END SELECT
                                   
                                      CASE %WM_DESTROY
                                          @pdh.zReturnString = "The end"
                                      END SELECT
                                   
                                  END FUNCTION
                                  ------------------

                                  Comment


                                  • #18
                                    Peter --
                                    Now it's really nice.
                                    + thanks to Lance (GetProp/SetProp could be useful in other cases)

                                    ------------------

                                    Comment


                                    • #19
                                      I'm a bit confused on why/if Peter's code is working? The second parameter to
                                      SetProp should be an asczii string or an Atom.

                                      From The Win32 help:

                                      Points to a null-terminated string or contains an atom that identifies a string.
                                      If this parameter is an atom, it must be a global atom created by a previous call
                                      to the GlobalAddAtom function. The atom, a 16-bit value, must be placed in the
                                      low-order word of lpsz; the high-order word must be zero.


                                      Also most books state you should use RemoveProp before destroying the Window??

                                      James


                                      ------------------


                                      [This message has been edited by jcfuller (edited April 02, 2000).]

                                      Comment


                                      • #20
                                        This is better:
                                        Code:
                                            CASE %WM_DESTROY
                                                @pdh.zReturnString = "The end"
                                                RemoveProp CBHNDL, BYVAL %ID_USERDATA
                                        BYVAL %ID_USERDATA is a well-known method from e.g. the DialogBox-function.

                                        Regards
                                        Peter



                                        ------------------

                                        Comment

                                        Working...
                                        X