Announcement

Collapse
No announcement yet.

Dialog units before a "Dialog New" statement

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

  • 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

  • #2
    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]
    Jim..

    Comment


    • #3
      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

      Comment


      • #4
        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).]
        "Not my circus, not my monkeys."

        Comment


        • #5
          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]
          Jim..

          Comment


          • #6
            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

            Comment


            • #7
              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].com</A>

              "Not my circus, not my monkeys."

              Comment


              • #8
                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

                Comment


                • #9
                  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

                  Comment


                  • #10
                    Excellent routines Terry... very creative. Fancy placing them in the Source Code forum? Thanks!


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

                    Comment


                    • #11
                      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>

                      "Not my circus, not my monkeys."

                      Comment


                      • #12
                        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

                        Comment


                        • #13
                          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

                          Comment


                          • #14
                            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

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

                            Comment


                            • #15
                              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).]
                              "Not my circus, not my monkeys."

                              Comment


                              • #16
                                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

                                Comment


                                • #17
                                  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

                                  Comment


                                  • #18
                                    You can also the following API call

                                    GetDialogBaseunits

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



                                    ------------------
                                    Anand Kumar
                                    An&

                                    Comment


                                    • #19
                                      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>
                                      Lance
                                      mailto:[email protected]

                                      Comment


                                      • #20
                                        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


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

                                        Comment

                                        Working...
                                        X