Announcement

Collapse
No announcement yet.

Dialog units before a "Dialog New" statement

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

  • Guest's Avatar
    Guest replied
    Lance,

    Found this code in one of my "C" ref files. Haven't tried
    the translated version.

    Cecil

    FUNCTION dlgBaseUnits2Pels(hDlg AS LONG) AS DWORD

    LOCAL rc AS RECT

    SetRect rc, 0, 0, 4, 8
    MapDialogRect hDlg, rc

    FUNCTION = MAKDWD(rc.nRight, rc.nBottom)

    END FUNCTION


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

    Leave a comment:


  • Lance Edmonds
    replied
    Anand, the problem is that GetDialogBaseUnits() is not guaranteed to return correct values in all circumstances, hence the reason for this thread.

    There is another way to do it using MapDialogRect(), but I don't have the code handy for this (I came across it in a WIN32.ANN annotation file).


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

    Leave a comment:


  • Anand Kumar
    replied
    You can also the following API call

    GetDialogBaseunits

    to get the dialog base units and then convert it to the pixel format.



    ------------------
    Anand Kumar

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric et al,

    I implemented Eric's idea of "Dialog New" and "Dialog
    End" in LibMain. I tested the speed with my first
    functions and compared the speed with them modified to
    work with Eric's idea. The speed improvement is
    significant.

    Creating the dialog in LibMain when attached, getting my
    conversions while it is created, and then ending the
    dialog when detached (as Eric suggested) was nine (9)
    times faster
    than the original functions.

    That kind of speed increase is worthwhile. Thanks Eric
    for the help. That Pixel to/from dlgUnits issue was the
    last real hurdle for my DLL. I am tweaking now and will
    have a first final, 1.0, in the near future.

    Thanks again.


    ------------------
    Terry

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric,

    Of course! Its obvious when you show to me. Now why didn't I
    think of that. Seriously, thanks for the help. This solves the
    final problem.

    I have not programmed in Basic for at least 15 years. I keep getting sidetracked as see things and begin thinking in Basic. PB seems like a great product for what it claims to be. I especially like the fast execution and small executables, perfect for DLLs.

    When I get back into a Basic frame of mind, the development time,
    for the programs, usually DLLs, that I will be writing beats
    anything else I have worked with.

    But one terrific feature of PB is its forums. Your input, and
    others, has been wonderful. I am days ahead of where I would be
    if I were researching and testing all of this stuff alone. Plus,
    I have much more confidence in the code because of our dialogues.

    Thanks again, and thanks to the others who have responded. All
    of you and your ideas have truly assisted me. And, while I am
    thanking people, thanks to PB for providing such a good forum.

    Sheesh! Before I start thanking my next door neighbors and their
    dogs, I guess I will stop.


    ------------------
    Terry

    Leave a comment:


  • Eric Pearson
    replied
    Terry --

    > Do you see any pitfalls to leaving the function open so that it will be faster?

    Do it this way and you should be fine...

    Code:
    FUNCTION LibMain(BYVAL hInstance AS LONG, _
                     BYVAL Reason    AS LONG, _
                     BYVAL Reserved  AS LONG) EXPORT AS LONG
     
            IF Reason = %DLL_PROCESS_ATTACH THEN
     
                    'Use DIALOG NEW to create the dummy dialog here.
                     
            ELSEIF Reason = %DLL_PROCESS_DETACH THEN
     
                    'Destroy the dummy dialog here.
     
            END IF
     
    END FUNCTION
    The %DLL_PROCESS_ equates are defined in the WIN32API.INC file.

    Each time a new application starts using your DLL they will get their own "copy" of the dummy dialog. And each time an app exits, that dialog will be destroyed.

    -- Eric


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



    [This message has been edited by Eric Pearson (edited February 18, 2000).]

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Terry,

    One more consideration from the speed aspect would be to
    combine those 4 functions into 2, pass the long as usual,
    parse the long into HI and LO word, calculate both the xx
    and yy, combine into 32bit for returning, then parse the
    return value into HI or LO order word. If you are looking for only one say x, then HI word y in long would be zero (0). Vice versa for y on LO end. Just something to consider.

    Cecil

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

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric,

    One consideration that I am not sure about. These functions are
    being used in a DLL that is being used by another language for
    applications. Do you see any pitfalls to leaving the function
    open so that it will be faster? I think it will work okay, but I
    feel a bit uneasy since multiple applications, from different
    languages could be calling these functions in this DLL.

    Back to the issue of speed. In some applications with which I
    will use the DLL, speed is very important. With others,
    functionality is the key. These are compromises I will have to
    deal with. I just don't want to fall into an obvious pit that I
    should have avoided.



    ------------------
    Terry

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric,

    Good idea. I am going to do some simple benchmarking (simple
    loops), using both techniques. I will let you know what
    difference in time there is.


    ------------------
    Terry

    Leave a comment:


  • Eric Pearson
    replied
    Terry --

    If speed is a major concern, you might consider creating the dummy dialog once at the beginning of your program, and leave it "open" so its handle could be used by your conversion functions. That way you would not be creating and destroying dialogs so often, and it would be a lot faster.

    And a tip...

    If you put the following "tags" around your source code, but with [square] brackets instead of {curly} ones, the BBS will preserve your indenting...

    {CODE}
    Code:
    FOR X = 1 TO 2
        PRINT X
    NEXT
    {/code}

    -- Eric

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

    Leave a comment:


  • Lance Edmonds
    replied
    Excellent routines Terry... very creative. Fancy placing them in the Source Code forum? Thanks!


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

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric and Jim,

    Here are four simple functions that seem to be working for my purposes. They use the "dummy 'Dialog New'" approach that we discussed. I thought you might like to see the approach. Notice the "Export", since these are used in a DLL. I know this, using these functions beats anything I tried based on the Win32Api funtion, GetDialogBaseUnits() and the formulas in its discussion.

    Function DlgXtoPixX (ByVal x As Long) Export As Long
    Local xx As Long
    Local yy As Long
    Local hDlg As Long

    Dialog New 0, "", 0, 0, 0, 0, 0, 0 To hDlg
    Dialog Units hDlg, x, 0 To Pixels xx, yy
    Dialog End hDlg
    Function = xx
    End Function 'DlgXtoPixX

    Function DlgYtoPixY (ByVal y As Long) Export As Long
    Local xx As Long
    Local yy As Long
    Local hDlg As Long

    Dialog New 0, "", 0, 0, 0, 0, 0, 0 To hDlg
    Dialog Units hDlg, 0, y To Pixels xx, yy
    Dialog End hDlg
    Function = yy
    End Function 'DlgYtoPixY

    Function PixXtoDlgX (ByVal x As Long) Export As Long
    Local xx As Long
    Local yy As Long
    Local hDlg As Long

    Dialog New 0, "", 0, 0, 0, 0, 0, 0 To hDlg
    Dialog Pixels hDlg, x, 0 To Units xx, yy
    Dialog End hDlg
    Function = xx
    End Function 'PixXtoDlgX

    Function PixYtoDlgY (ByVal y As Long) Export As Long
    Local xx As Long
    Local yy As Long
    Local hDlg As Long

    Dialog New 0, "", 0, 0, 0, 0, 0, 0 To hDlg
    Dialog Pixels hDlg, 0, y To Units xx, yy
    Dialog End hDlg
    Function = yy
    End Function 'PixYtoDlgY


    ------------------
    Terry

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Eric,

    Thanks for the ideas. I am going to research some of the things that you mention. I will let you know if I find anything worthwhile.

    As to the controls with wrappers and dynamic calculations, those are good ideas. However, I am not having trouble with controls. Dialog units have always worked as expected with controls inside of dialogs. I needed to precisely determine where the dialog itself would be positioned and, if at all possible, to determine the position in advance of "Dialog New", really makes things easier in this other language I am working in.

    The dummy "Dialog New" idea that we discussed is working, like I want, in the first routines that I have completed. If they stand up to testing after I polish them, then I think my problem is handled. Thanks for the input on that idea.


    BTW I am still open to any suggestions from anyone else.



    ------------------
    Terry

    Leave a comment:


  • Eric Pearson
    replied
    I guess you need to find out exactly what makes the ratios change. I know that changing from Small Fonts to Large Fonts does it on my NT4 system, but you have to restart Windows in order for the change to take effect so it could never affect a running app. It is possible to change the screen resolution "on the fly" while an app is running, but I don't think that that changes the ratios. Does anybody know exactly what causes the ratios to change?

    If you find out that it is impossible for the ratios to change while an app is running, then you can use the "check ratios at app startup" method with complete safety and confidence. I'm betting that only a change in the system font will change the ratios, and that you can't change the system font without restarting. So you'd be home free.

    Or how about this...

    Write a "wrapper" function for each of the CONTROL ADD functions. Then you could use pixel measurments for everything in your program, and the wrapper functions would do the DIALOG PIXELS calculations for you. The converted numbers would never leave the wrapper functions. In pseudo-code...

    Code:
    FUNCTION AddButton(MyStruct AS WHAT_EVER) AS LONG
     
       DIM LocalStruct AS LOCAL WHAT_EVER
        
       LocalStruct = MyStruct
     
       DIALOG PIXELS LocalStruct.hParent, LocalStruct.Width, LocalStruct.Height, _
            TO UNITS LocalStruct.Width, LocalStruct.Height
     
       CONTROL ADD BUTTON LocalStruct.hParent... (etc.)
    
    END FUNCTION
    If you're worried about a speed penalty caused by doing the calculations on the fly, you'll probably be very surprised how fast DIALOG PIXELS is.

    -- Eric

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

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Jim,

    You said 'you sort of have a "cart before the horse" situation.'

    That is what I am afraid of, but I was hoping.


    Eric,

    Without going into details, I keep dialog and control properties in an object (or structure if you prefer). I do a lot of calculations about positioning and sizing and so forth and keep these settings. Then I create a dialog and its controls all at one time. I was hoping to have everything correct before creating any dialog stuff.

    I have done something like you mentioned with a dummy "Dialog New" to get the conversions. But it seems a bit too imprecise or chancy. I was hoping to find a more stable or accepted method of accomplishing my goals. I guess, unless someone else chimes in with a better idea, I will continue with this line of programming. It gives me some hope that you and I both thought of this same alternative/option. Maybe it will be doable. So, I am off to flesh out and perfect (at least I hope to perfect) this approach.

    Thanks to both of you, Jim and Eric, for quick responses. At least now, I feel more confident that I had not missed something obvious that would make my task easier and better.

    Thanks again


    ------------------
    Terry

    Leave a comment:


  • Jim Huguley
    replied
    Terry...

    That is beyond my expertise. Since the conversion requires that the font of the Dialog is used in the calculation you sort of
    have a "cart before the horse" situation.


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

    Leave a comment:


  • Eric Pearson
    replied
    Terry --

    > It would solve mulitple problems for me if I
    > can determine correct dialog units before
    > creating a dialog, displaying it, and then
    > setting its position.

    That's what Jim is suggesting. Try it in this order...

    Code:
    DIALOG CREATE           (with arbitrary size)
    DIALOG PIXELS TO UNITS  (using handle from CREATE)
    DIALOG SIZE             (with calculated size)
    DIALOG MOVE             (with calculated location)
    DIALOG SHOW             (dialog actually becomes visible here)
    Unfortunately, the dialog-units-to-pixels ratio is dynamic. It is certainly unlikely, but it would be possible for a user to change the Large/Small Fonts setting (in the Control Panel's "Display" applet's "Settings" tab) and thereby change the ratio while your app is running. So if you want to be 100% certain that you are doing the math correctly, you have to create a window, check the ratio, and then size the window.

    If you want to take the (admittedly minor) risk, you could use DIALOG NEW create a "dummy" dialog when your app first starts up (or in your DLL's LibMain %PROCESS_ATTACH case), check the horizontal and vertical ratios, save them in GLOBAL variables, and then never show that particular window. As long as the user doesn't change the Large/Small Fonts setting while your app is running, you would be able to safely use those ratios to do all of your calculations for "real" dialogs that you do intend to show.

    (Hmmm... off the top of my head, I'm not certain that the ratios don't change when the screen resolution is changed. But even if they do, that's a pretty rare thing too, and the same warning would apply.)

    -- Eric


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



    [This message has been edited by Eric Pearson (edited February 17, 2000).]

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Jim,

    Thanks for your response.

    I understand about when dialogs are created and so forth. My problem is that I am writing a DLL to be used with an application. It would solve mulitple problems for me if I can determine correct dialog units before creating a dialog, displaying it, and then setting its position.

    It would not be productive for me to go into all the specifics. But it would be MUCH better for me and the application I am writing, in another programming language, if I could determine the correct coordinates in the appropriate dialogs units before I create the dialog, that is, to use with "Dialog New".

    Again, thanks for your response, but I am hoping there is a way to accomplish what I want to do.


    ------------------
    Terry

    Leave a comment:


  • Jim Huguley
    replied
    Terry..

    The Dialog is not displayed when you create it with Dialog New.
    Create it, do your calculations for new position and then use

    DIALOG SET LOC hDlg&, x&, y&

    to move it where you want it.



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

    Leave a comment:


  • Guest's Avatar
    Guest started a topic Dialog units before a "Dialog New" statement

    Dialog units before a "Dialog New" statement

    I have researched the forum on dialog units. I have found
    much info. But I cannot determine how to do one simple
    (at least in concept) thing. Determine the precise
    location of a dialog on the screen when I create it.

    I am using a 1280x1024 pixels resolution, so I will base
    my question these dimensions.

    Suppose that I want to create a dialog with its left top
    corner in the middle of the screen, that is at 640x512
    pixels. The "Dialog New" statement requires that these
    coordinates be specified in dialog units. However, the
    "Dialog Pixels hDlg,... To Units ..." statement and the
    "Dialog Units hDlg,... To Pixels ..." require that the
    dialog handle, that is the dialog, exists before I can
    convert pixels to dialog units. I want the correct dialog
    units before the dialog exists so that I can precisely
    position it when I create it.

    I have worked with GetDialogBaseUnits() without success,
    and Lance points out that the function does not
    necessarily return the info needed to make the
    conversions.

    I have researched and tried many approaches and none
    work.

    How can I get the pixels in dialog units or the
    dimensions of my desktop screen in dialog units, before I
    create a dialog so that I can use the units with "Dialog
    New". I need to be able to do this to be able to
    precisely set the coordinates, in units, for a "Dialog
    New" statement.

    What have I missed? Or can someone tell me what I need to
    do?

    Thanks,

    Terry



    -------------
    Terry
Working...
X