Announcement

Collapse
No announcement yet.

DDT Pixels to Unit confusion

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

  • DDT Pixels to Unit confusion

    I have tried to write an initialization subroutine for my ddt dialogs
    but I do not seem to be using the Pixel/Unit conversion functions
    correctly. What I would like to have happen is for the user to place the
    dialog where he wants and then when he restarts the app the program remembers
    where it was and the dialog appears where he left it.

    This is more of a concern with Win98 and now Win2000 multiple monitor
    PC's

    I want to store the user selected location with these statements:

    Dialog Get Client hDlg To rcDlgIni.nWidth, rcDlgIni.nHeight
    Dialog Get Loc hDlg To nPixLeft, nPixTop
    Dialog Pixels hDlg, nPixLeft, nPixTop To Units rcDlgIni.nLeft, rcDlgIni.nTop

    and store those values in an INI file

    and then use to re-create the Dialog

    Dialog New hParent, sAppTitle, _
    rcDlgIni.nLeft, rcDlgIni.nTop, rcDlgIni.nWidth, rcDlgIni.nHeight _ etc

    But each time the program is stopped and then restarted the Dialog creeps toward
    the Top Left corner. I have found through trial and error that the following
    statement mostly stop the dialog movement.

    rcDlgIni.nTop = (rcDlgIni.nTop * 8&) \ 5&
    rcDlgIni.nLeft = (rcDlgIni.nLeft * 3&) \ 2&

    An example source code is shown below
    Does anyone know what I am doing wrong -or- have a better way of
    saving the Dialog Position from the previous run.

    Code:
    =============================================================
    Main Program
    =============================================================
    #COMPILE EXE "c:\murphy\status\xstatus.exe"
    #DIM ALL
    #REGISTER NONE
    #INCLUDE "c:\pbdll60\winapi\win32api.inc"
    
    #INCLUDE "c:\murphy\status\appinfo.inc"
    #INCLUDE "c:\murphy\status\dlgini.bas"
    #INCLUDE "c:\murphy\status\globequ.bas"
    #INCLUDE "c:\murphy\status\status.ddt"
    
    Function PbMain () As Long
        Dim hParent As Long
        Dim nRetC As Long
        Call GetAppInfo ("Trade Completion Status Program")
        hParent = 0
        nRetC = Create_StatusDialog(hParent)
    End Function
    =============================================================
        Included Sources Code:
        GLOBEQU.BAS
    =============================================================
    Global hStatusDialog As Long
    %DLG_1_Timer = 101
    %DLG_1_Pause = 102
    %DLG_1_Continue = 103
    %DLG_1_Exit = 104
    %DLG_1_LastUser = 105
    %DLG_1_Status = 106
    %DLG_1_Number = 107
    =============================================================
        APPINFO.INC
    =============================================================
    Type tyApp
        Path as String * 128
        EXEName as String * 8
        Title as String * 128
    End Type
    Global App0 as tyApp
    
    Sub GetAppInfo (Byval sBuffer As String)
        Local nLen As Long
        Local nRet As Long
        Local sTxt As String
        Local nDot As Long
        Local nSlash As Long
    
        App0.Title = Trim$(sBuffer)
        App0.Path = "Not Available"
        App0.EXEName = "NONE"
    
        nLen = 127
        sTxt = Space$(nLen)
        nRet = GetModuleFileName (0, BYVAL STRPTR(sTxt), nLen)
        sBuffer = Trim$(sTxt)
        App0.Path = sBuffer
        ' Remember that pesky Hex(00) at the end of the String
        sTxt = Left$(UCase$(Right$(sBuffer, 5)), 4)
        If sTxt < > ".EXE" Then Exit Sub
        nDot = Len(sBuffer) - 4
        nSlash = nDot - 1
        Do While nSlash > 0
            If Mid$(sBuffer, nSlash, 1) = "\" Then Exit Do
            If Mid$(sBuffer, nSlash, 1) = ":" Then Exit Do
            nSlash = nSlash - 1
        Loop
        If (nDot - nSlash) < 2 Then Exit Sub
        If nSlash > 1 Then
            App0.Path = LEFT$(sBuffer, nSlash)
            nSlash = nSlash + 1
            nDot = nDot - nSlash
            App0.EXEName = Mid$(sBuffer, nSlash, nDot)
        End If
    End Sub
    =============================================================
        DLGINI.BAS
    =============================================================
    Declare Function MakeSureDir Lib "Imagehlp" Alias _
            "MakeSureDirectoryPathExists" (lpPath As Asciiz) As Long
    '   Example of MakeSureDir Win32API function call
    '   Dim RetC As Long
    '   RetC = MakeSureDir("s:\archive\trading\ccyymmdd\")
    
    Type tyDlgIni
        nTop As Long
        nLeft As Long
        nHeight As Long
        nWidth As Long
    End Type
    Global rcDlgIni As tyDlgIni
    Global FileIni As String
    
    Sub ReadDlgIni()
        Dim xSection As Asciiz * 128
        Dim xKey As Asciiz * 128
        Dim xVar As Asciiz * 128
        Dim xDefault As Asciiz * 128
        Dim xFileName As Asciiz * 128
        Dim xLen As Long
        Dim xRet As Long
    
        xFileName = FileIni
        xSection = "Setup"
    
        xKey = "Top"
        xDefault = "5"
        xLen = 128
        xVar = Space$(127)
        xRet = GetPrivateProfileString(xSection, xKey, xDefault, xVar, xLen, xFileName)
        rcDlgIni.nTop = Val(Trim$(Left$(xVar, xRet)))
    
        xKey = "Left"
        xDefault = "5"
        xLen = 128
        xVar = Space$(127)
        xRet = GetPrivateProfileString(xSection, xKey, xDefault, xVar, xLen, xFileName)
        rcDlgIni.nLeft = Val(Trim$(Left$(xVar, xRet)))
    
        xKey = "Height"
        xDefault = "280"
        xLen = 128
        xVar = Space$(127)
        xRet = GetPrivateProfileString(xSection, xKey, xDefault, xVar, xLen, xFileName)
        rcDlgIni.nHeight = Val(Trim$(Left$(xVar, xRet)))
    
        xKey = "Width"
        xDefault = "420"
        xLen = 128
        xVar = Space$(127)
        xRet = GetPrivateProfileString(xSection, xKey, xDefault, xVar, xLen, xFileName)
        rcDlgIni.nWidth = Val(Trim$(Left$(xVar, xRet)))
    
    End Sub
    
    Sub WriteDlgIni(hDlg As Long)
        Dim xSection As Asciiz * 128
        Dim xKey As Asciiz * 128
        Dim xVar As Asciiz * 128
        Dim xFileName As Asciiz * 128
        Dim xRet As Long
        Dim nPixTop As Long
        Dim nPixLeft As Long
        
        Dialog Get Client hDlg To rcDlgIni.nWidth, rcDlgIni.nHeight
        Dialog Get Loc hDlg To nPixLeft, nPixTop
        Dialog Pixels hDlg, nPixLeft, nPixTop To Units rcDlgIni.nLeft, rcDlgIni.nTop
    '    rcDlgIni.nTop = (rcDlgIni.nTop * 8&) \ 5&
    '    rcDlgIni.nLeft = (rcDlgIni.nLeft * 3&) \ 2&
        xFileName = FileIni
        xSection = "Setup"
    
        xKey = "Top"
        xVar = Str$(rcDlgIni.nTop)
        xRet = WritePrivateProfileString(xSection, xKey, xVar, xFileName)
    
        xKey = "Left"
        xVar = Str$(rcDlgIni.nLeft)
        xRet = WritePrivateProfileString(xSection, xKey, xVar, xFileName)
    
        xKey = "Height"
        xVar = Str$(rcDlgIni.nHeight)
        xRet = WritePrivateProfileString(xSection, xKey, xVar, xFileName)
    
        xKey = "Width"
        xVar = Str$(rcDlgIni.nWidth)
        xRet = WritePrivateProfileString(xSection, xKey, xVar, xFileName)
    
    End Sub
    =============================================================
        STATUS.DDT
    =============================================================
    CallBack Function StatusDialog_CB As Long
    
        Dim hJunk As Long
        Dim hMenu As Long
        Dim szText As Asciiz * 100
        Dim sTxtStart As String
    
        Select Case CbMsg
          Case %WM_INITDIALOG
            Control Disable hStatusDialog, %DLG_1_Continue
            sTxtStart = "Request #0"
            Control Set Text hStatusDialog, %DLG_1_Number , sTxtStart
            hMenu = 500 ' 0.5 Seconds
            hJunk = SetTimer (hStatusDialog, %DLG_1_Timer , hMenu , %NULL)
          Case %WM_TIMER
            ' Call the timer subroutine
            UpdateWindow hStatusDialog
            Dialog DoEvents
          Case %WM_COMMAND
            If CbCtlMsg = %BN_CLICKED Then
                Select Case CbCtl
                  Case %DLG_1_Pause
                    ' MAKDWD(%DLG_1_Pause, %BN_CLICKED)
                    Control Enable hStatusDialog, %DLG_1_Continue
                    Control Disable hStatusDialog, %DLG_1_Pause
                    Control Set Text hStatusDialog, %DLG_1_Status , "Press Continue to restart"
                  Case %DLG_1_Continue
                    ' MAKDWD(%DLG_1_Continue, %BN_CLICKED)
                    Control Disable hStatusDialog, %DLG_1_Continue
                    Control Enable hStatusDialog, %DLG_1_Pause
                    Control Set Text hStatusDialog, %DLG_1_Status , "Continuing ..."
                  Case %DLG_1_Exit
                    ' MAKDWD(%DLG_1_Exit, %BN_CLICKED)
                    hJunk = KillTimer (hStatusDialog, %DLG_1_Timer)
                    UpdateWindow hStatusDialog
                    Dialog DoEvents
                    Call WriteDlgIni(hStatusDialog)
                    Dialog End CbHndl, - 1
                End Select
            End If
        End Select
    End Function
    '===========================================================================
    Function Create_StatusDialog (ByVal hParent As Long ) As Long
        Dim lRetVal As Long
        Dim sAppTitle As String
        FileIni = "c:\windows\xstatus.ini"
        Call ReadDlgIni
        ' Dialog will not be resizable, only moveable so I will force my width and height
        rcDlgIni.nWidth = 220
        rcDlgIni.nHeight = 65
        sAppTitle = Trim$(App0.Title)
        Dialog New hParent, sAppTitle, _
                rcDlgIni.nLeft, rcDlgIni.nTop, rcDlgIni.nWidth, rcDlgIni.nHeight _
                , %WS_POPUP Or %WS_CAPTION Or %WS_SYSMENU Or %DS_MODALFRAME Or %WS_MINIMIZEBOX _
                To hStatusDialog
    
        Control Add Button, hStatusDialog, %DLG_1_Pause , "&Pause" , 5, 5, 50, 14
        Control Add Button, hStatusDialog, %DLG_1_Continue, "&Continue", 5, 25, 50, 14
        Control Add Button, hStatusDialog, %DLG_1_Exit , "E&xit" , 5, 45, 50, 14
    
        Control Add Label, hStatusDialog, %DLG_1_LastUser, "Last User Serviced", _
                           60, 5, 155, 25, %SS_LEFT Or %SS_SUNKEN
        Control Add Label, hStatusDialog, %DLG_1_Status , "Program Status" , _
                           60, 35, 155, 11, %SS_LEFT Or %SS_SUNKEN
        Control Add Label, hStatusDialog, %DLG_1_Number , "Number of Requests", _
                           60, 48, 155, 11, %SS_LEFT Or %SS_SUNKEN
    
        Dialog Show Modal hStatusDialog, Call StatusDialog_CB To lRetVal
    End Function
    =============================================================
    End of Listing
    =============================================================
    Thanks Joe Murphy

  • #2
    Hi Joe..

    Without trying, my observation is that you want to use

    Dialog Get Size hDlg To rcDlgIni.nWidth, rcDlgIni.nHeight
    Not
    Dialog Get Client hDlg To rcDlgIni.nWidth, rcDlgIni.nHeight

    in Sub WriteDlgIni()..



    ------------------
    Jim..
    [email protected]
    Jim..

    Comment


    • #3
      No, Dialog Get Client is the correct function to get height and width. The units are in Dialog Units.
      The problem is definitely with Dialog Get Loc, because it returns Pixels.

      Joe

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

      Comment


      • #4
        Joe..

        You are correct that the help file requires the Client area in
        the xx&, yy& positions, my mistake. Below is a small program that
        you might find helpful. It seems that the DIALOG NEW and the
        DIALOG SET/GET LOC statements want PIXELS not Dialog Units. If
        you will run the below program. Drag the Dialog to a new location
        and then click the Reset Button. You will see that on occassion
        the Dialog will move slightly. If you Unrem the line that I have
        commented in the code you will see that the Dialog will move
        to the up and left when the pixels are converted to dialog units.
        Also dragging the dialog to a new location and clicking the reset
        button will cause the dialog to move to the left and up.


        Code:
        '==============================================================================
        '
        '
        '
        '
        '==============================================================================
        
        #COMPILE EXE
        #DIM ALL
        #INCLUDE "WIN32API.INC"
        
        %IDOK      = 1
        %IDRESET   = 2
        
        %BS_DEFAULT = 1
        
        $AppTitle = "Template..."
        
        '------------------------------------------------------------------------------
        CALLBACK FUNCTION OkButton()
        
          DIALOG END CBHNDL
        
        END FUNCTION
        
        '------------------------------------------------------------------------------
        CALLBACK FUNCTION ResetButton()
        
            LOCAL lLeft AS LONG
            LOCAL lTop  AS LONG
            
            DIALOG GET LOC CBHNDL TO lLeft, lTop
        '    DIALOG PIXELS CBHNDL, lLeft, lTop TO UNITS lLeft, lTop
        '   UnRem the above line
        '   Run Program
        '   Click Reset button several times
        '   Dialog will move to the left and up
        '   With smaller and smaller increments
        
        '   With above line rem'ed the Dialog will
        '   sometimes move slightly if ResetButton is
        '   clicked AFTER dragging the Dialog to a new
        '   position
            
            DIALOG SET LOC CBHNDL, lLeft, lTop
        
        END FUNCTION
        '------------------------------------------------------------------------------
        CALLBACK FUNCTION MainDlg_CallBack()
        
            SELECT CASE CBMSG
            END SELECT
            
        END FUNCTION
        '------------------------------------------------------------------------------
        
        FUNCTION PBMAIN () AS LONG
        
            #REGISTER NONE
        
            LOCAL hDlg   AS LONG
            LOCAL result AS LONG
        
            ' ** Create a new dialog template
            DIALOG NEW 0, $AppTitle,,, 150, 100, _
                          %WS_POPUP OR %WS_CAPTION OR _
                          %WS_SYSMENU OR %DS_MODALFRAME OR %WS_MINIMIZEBOX, _
                          0 TO hDlg
            ' ** Add controls to it
            CONTROL ADD BUTTON, hDlg, %IDOK,    "Quit", 20, 30, 40, 14, %BS_DEFAULT CALL OkButton
            CONTROL ADD BUTTON, hDlg, %IDRESET, "Reset", 80, 30, 40, 14, 0 CALL ResetButton
        
            ' ** Display the dialog
            DIALOG SHOW MODAL hDlg, CALL MainDlg_CallBack TO result
        
        END FUNCTION
        '------------------------------------------------------------------------------

        ------------------
        Jim..
        [email protected]
        Jim..

        Comment


        • #5
          Joe --

          [Jim apparently posted his answer while I was composing mine. At first I thought that we were saying the same thing, but we came to different conclusions...]

          > The problem is definitely with Dialog Get Loc,
          > because it returns Pixels.

          The following test code seems to show that the PB/DLL Help File contains an error. DIALOG GET LOC apparently returns Dialog Units, not Pixels.

          The SetCursorPos API function (which definitely requires parameters in Pixels) is used below to programmatically move the mouse cursor to the calculated location, and you'll see that if you remove the DIALOG UNITS TO PIXELS line, the program does not move the cursor to the top-left corner of the dialog.

          100% of the other DIALOG functions use Dialog Units instead of Pixels, so it is pretty clearly a simple documentation error. I would assume that in future versions of PB/DLL, PowerBASIC will change the docs, not the way function works, so it is probably safe to write code that assumes Dialog Units.

          Knowing that, it should be easy to work around. All you have to do is remove your DIALOG PIXELS TO UNITS line, because DIALOG SET LOC requires Dialog Units, not Pixels. (In other words, DIALOG GET LOC and DIALOG SET LOC use the same system of measurement, which is pretty logical.)

          Code:
          $COMPILE EXE
          $DIM ALL
          $REGISTER NONE
          #INCLUDE "WIN32API.INC"
           
          FUNCTION PBMain AS LONG
                            
                  DIM hWnd AS LOCAL LONG
                  DIM lXPos AS LOCAL LONG
                  DIM lYPos AS LOCAL LONG
                  DIM lResult AS LOCAL LONG
           
                  DIALOG NEW 0, "Test",,, 70, 35, %WS_SYSMENU TO hWnd
                  DIALOG SHOW MODELESS hWnd
                  DIALOG GET LOC hWnd TO lXPos, lYPos
                  DIALOG UNITS hWnd, lXPos, lYPos TO PIXELS lXPos, lYPos
                  SetCursorPos lXPos, lYPos
                   
                  DO
                          DIALOG DOEVENTS TO lResult      
                          IF lResult = 0 THEN EXIT LOOP
                  LOOP
             
          END FUNCTION
          -- Eric


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



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

          Comment


          • #6
            Thanks Eric and Jim.
            Eric's Solution worked perfectly. I do not know why I did not try it.

            I forgot to write earlier that I put in a little known API call:

            Declare Function MakeSureDir Lib "Imagehlp" Alias _
            "MakeSureDirectoryPathExists" (lpPath As Asciiz) As Long
            ' Example of MakeSureDir Win32API function call
            ' the trailing slash is necessary -- or use full file name
            ' Dim RetC As Long
            ' RetC = MakeSureDir("s:\archive\trading\ccyymmdd\")

            This API call will create the directory structure if it does not exist.
            I find it very useful.

            I hope to post the DLGINI code with explanation to the source code forum.

            Joe Murphy

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

            Comment

            Working...
            X