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
------------------
Announcement
Collapse
No announcement yet.
DDT Pixels to Unit confusion
Collapse
X
-
Guest replied
-
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
------------------
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).]
Leave a comment:
-
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]
Leave a comment:
-
Guest repliedNo, 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
------------------
Leave a comment:
-
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]
Leave a comment:
-
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 =============================================================
Tags: None
Leave a comment: