Results 1 to 25 of 25

Thread: [RESOLVED] Can't get correct Left and Top of usercontrol

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Resolved [RESOLVED] Can't get correct Left and Top of usercontrol

    I use the following code to get the location of the user control

    Code:
    Private Sub GetLocationOfUserControl()
     Dim myRECT As RECT
     Dim ucLeft As Long
     Dim ucTop As Long
     Dim picLeft As long
     Dim picTop As Long
    
     ScreenToClient ucGrid.hWnd, myRECT
     ucLeft = Abs(myRECT.Left + FormLeftBorder + Me.Left / Screen.TwipsPerPixelX)
     ucTop = Abs(myRECT.Top + FormTopBorder + Me.Top / Screen.TwipsPerPixelY)
       
     ScreenToClient Picture1.hWnd, myRECT
     picLeft = Abs(myRECT.Left + FormLeftBorder + Me.Left / Screen.TwipsPerPixelX)
     picTop = Abs(myRECT.Top + FormTopBorder + Me.Top / Screen.TwipsPerPixelY)
    End Sub
    Now here's the problem

    The Left and Top values for Picture1 are correct. Picture1.Left = 813, Picture1.Top = 457 and that is exactly what I get using ScreenToClient

    The Left and Top values for ucGrid are incorrect. ucGrid.Left = 248, ucGrid.Top = 0 but when I use ScreenToClient I get ucLeft = 1207, ucTop = 542

    All ScaleModes are in Pixels

    I have no idea what is going on.
    Last edited by Code Dummy; Apr 23rd, 2019 at 05:23 PM.

  2. #2
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    706

    Re: Can't get correct Left and Top of usercontrol

    Please remove Abs(). Coordinates can be negative if you have multiple monitors. Also, use Debug.Print, or hover the mouse over a variable to see its value, or right-click on a variable, then select Add Watch to keep track of its value. That's how we debug our code.

    Also, the position you get is in the parent ScaleMode, so if the Form ScaleMode is vbPixel, then you shouldn't divide the controls within the form by TwipsPerPixel. Form position however is always in Twips. The proper way to convert is by using the ScaleX, ScaleY Methods:

    x = ucGrid.ScaleX(ControlInUCLeft, ucGrid.ScaleMode, Me.ScaleMode)
    y = ucGrid.ScaleY(ControlInUCTop, ucGrid.ScaleMode, Me.ScaleMode)

    See also this thread about DPI Awareness.
    Last edited by qvb6; Apr 24th, 2019 at 06:50 AM.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by qvb6 View Post
    Please remove Abs(). Coordinates can be negative if you have multiple monitors.
    They are negative whether you have one or multiple monitors. I don't see the point to this statement. Also, If I remove the Abs() then I get negative coordinates and that really screws thing up

    Quote Originally Posted by qvb6 View Post
    Also, use Debug.Print, or hover the mouse over a variable to see its value, or right-click on a variable, then select Add Watch to keep track of its value. That's how we debug our code.
    I stated in my post what the actual coordinates are and what I'm getting by using ScreenToClient. I know these because I hover the mouse over the variables. How did you think I got those values

    Quote Originally Posted by qvb6 View Post
    Also, the position you get is in the parent ScaleMode, so if the Form ScaleMode is vbPixel, then you shouldn't divide the controls within the form byTwips PerPixel. Form position however is always in Twips.
    Am I not just dividing the Form's Left and Top value by Screen.TwipsPerPixel. Why do you say I shouldn't divide the controls within the Form.... when I am not doing that. If I remove the Screen.TwipsPerPixel then I get a totally different incorrect coordinates for the user control and the picturebox. As it is I get correct coordinates for the picturebox but not for the user control which is the original problem for why I opened the thread.

    Quote Originally Posted by qvb6 View Post
    The proper way to convert is by using the ScaleX, ScaleY Methods:

    x = ucGrid.ScaleX(ControlInUCLeft, ucGrid.ScaleMode, Me.ScaleMode)
    y = ucGrid.ScaleY(ControlInUCTop, ucGrid.ScaleMode, Me.ScaleMode)
    What is ControlInUCLeft and ControlInUCTop. I don't understand the above as to what it is supposed to do and I don't see what it has to do with ScreenToClient.

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Can't get correct Left and Top of usercontrol

    The sited UserControl instance already has a Left and Top property. What are you trying to obtain that differs from those?

  5. #5
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,064

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by dilettante View Post
    The sited UserControl instance already has a Left and Top property. What are you trying to obtain that differs from those?
    Not only that.
    Does the code he posted make any sense to you?

    At the start:
    Code:
    ScreenToClient ucGrid.hWnd, myRECT
    How is it supposed to get the position with that?

    Also, ScreenToClient needs a POINT, not a RECT. That line could never run.

    Third issue: this person has a total lack of consideration to anyone willing to help, because he doesn't post any declaration nor working code.
    His posts are nonsense.

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    I'm moving the UserControl around using the following code...

    Code:
    Private Sub ucGrid_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
     If Button = 1 Then
       ReleaseCapture
       SendMessage ucGrid.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
     End If
    End Sub
    When using this code the Left and Top properties are not updated so I need to use ScreenToClient to
    get the current position of the control

    I'm using this approach to move the control because after trying many other approaches this is the only one that wont smear when the control is moved. The control contains 625 shape controls laid out in a 25 x 25 grid. Each shape represents a cell in a game program I am writing and they can be either black or green depending on how the user clicks on them. When the control is moved these "cells" smear if I use any other method other than the one I'm using.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    ---------------------------
    Last edited by Code Dummy; Apr 24th, 2019 at 10:02 PM.

  8. #8
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    706

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by Code Dummy View Post
    They are negative whether you have one or multiple monitors. I don't see the point to this statement. Also, If I remove the Abs() then I get negative coordinates and that really screws thing up
    Removing Abs might give you negative coordinates, but there is something else causing the negative numbers, which you shouldn't get from Windows, unless the form is off-screen, or you have multiple monitors. Having Abs maybe hiding some other issue in the code or coordinate type(Screen/Client). Client coordinates are relative to the container, which is not necessarily the form. You might want to check out GetWindowRect, as it gives screen coordinates always.

    Quote Originally Posted by Code Dummy View Post
    I stated in my post what the actual coordinates are and what I'm getting by using ScreenToClient. I know these because I hover the mouse over the variables. How did you think I got those values
    I wasn't sure if you have MSDN installed, so I mentioned these tips.

    Quote Originally Posted by Code Dummy View Post
    Am I not just dividing the Form's Left and Top value by Screen.TwipsPerPixel. Why do you say I shouldn't divide the controls within the Form.... when I am not doing that. If I remove the Screen.TwipsPerPixel then I get a totally different incorrect coordinates for the user control and the picturebox. As it is I get correct coordinates for the picturebox but not for the user control which is the original problem for why I opened the thread.
    I missed that, and I apologize for it.

    Quote Originally Posted by Code Dummy View Post
    What is ControlInUCLeft and ControlInUCTop. I don't understand the above as to what it is supposed to do and I don't see what it has to do with ScreenToClient.
    I meant Controls Inside UC, assuming that you have any. ScaleX/ScaleY convert coordinates from one scale mode to another.

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    Thanks, qvb6, for the response.

    It's been a very long time since I used ScreenToClient prior to this project. I can't remember if I got positive or negative results but I'm sure that when I did use this API it must have worked or I would have noticed the program not working correctly. It does appear to me that I should not get negative results since the two controls I used for testing are on a Form. The Form, the Picturebox, and the UserControl are in vbPixels. The UserControl does contain inner controls but they have no ScaleMode because they are shape controls so when you click on a shape control it is the same as clicking on the container which I am sure you already know. However, until I find out why I'm getting negative results I have to use the Abs() or my program will really fall to pieces. My Form is centered in the screen area and I am using only one monitor.

    My biggest issue is why with any MS control (pictureboxes, labels, buttons, etc) I get correct results as far as the X and Y goes but still they are negative but with a User Control (any User Control) I do not get correct results. I have tested with several pictureboxes and several user controls and I always get the same issue.

    Here's a weird thing. When I move a picturebox or a user control so that it's top border is above the top of the client area I always get a positive X and Y and this is when I would have expected negative results. I moved the picturebox to a .Top - 50 and the ScreenToClient returned a positive 50 as the results. And this is way above the Form top. When I say the API returned a positive result I mean the API itself and not the results in my variables.

    I also have tried using ScreenToClient with a PointAPI structure instead of a RECT and it's exactly the same results so that's not the problem. I have to say that there is nothing wrong with the way I use the ScreenToClient API.

  10. #10
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,064

    Re: Can't get correct Left and Top of usercontrol

    deleted

  11. #11
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    706

    Re: Can't get correct Left and Top of usercontrol

    Units matter, although when dealing with the API, you are using Pixels, but relative to what? Client is relative to the top left of the container. If the UserControl is on top of a PictureBox, then it would be relative to the PictureBox, not the form. To see if a control is a container for other controls(and not just visually on top of it), move the control in Design time, anything else that moves with that is contained controls, so they would be relative to the control that you just moved.

  12. #12
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,064

    Re: Can't get correct Left and Top of usercontrol

    Check attached.
    Attached Files Attached Files

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by qvb6 View Post
    Units matter, although when dealing with the API, you are using Pixels, but relative to what? Client is relative to the top left of the container. If the UserControl is on top of a PictureBox, then it would be relative to the PictureBox, not the form. To see if a control is a container for other controls(and not just visually on top of it), move the control in Design time, anything else that moves with that is contained controls, so they would be relative to the control that you just moved.
    The grid control is on top of a picturebox but it is not a child of the picturebox. User is able to move the user control anywhere on the Form. I even tried making the grid control a child of the picturebox but it didn't change anything.

    For example:

    1) the grid control is not a child of the picturebox and when I move it off the top of the Form I get a positive value where it should be negative so I have no idea that a user moved the grid above the Form top which would result in an error for the user.

    2) the grid control is a child of the picturebox and when I move it so that all or almost all of the grid control is moved above the top of the picturebox I still get a positive value.

    It turns out that no matter where I move the grid control I always get negative values as long as the grid is moved within the Form and always positive values when I move the grid above the Form top border. As I'm typing this it just occured to me that maybe I can use this to determine if the user did move the grid control above the Form top border. If ScreenToClient returns negative then I know it was moved within the Form and if it returns positive I know it was moved above the Form's top border. So, I can just reverse the returned results. I'll go do this now and see if this works.

  14. #14
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    706

    Re: Can't get correct Left and Top of usercontrol

    I meant drag the control at Design time, not when running, to see if it has child controls. Sometimes while dragging controls on the IDE, you might inadvertently make one control a child of another.

  15. #15

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    I understand that but then I would know that since I would not be able to drag the control beyond the Form boundaries at run time and I know for a fact that the control is not a child of another control; it is a child of the Form and like I said it doesn't matter I get same results. For example the results are the same values whether the control is a child of a picturebox or a child of the Form; nothing changes. I think this is typical and not just on my program.
    Last edited by Code Dummy; Apr 24th, 2019 at 10:04 PM.

  16. #16
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,156

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by qvb6 View Post
    Sometimes while dragging controls on the IDE, you might inadvertently make one control a child of another.
    How could that happen? This would be really handy if possible to re-parent controls w/o copy/paste all the time.

    cheers,
    </wqw>

  17. #17
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    706

    Re: Can't get correct Left and Top of usercontrol

    Quote Originally Posted by wqweto View Post
    How could that happen? This would be really handy if possible to re-parent controls w/o copy/paste all the time.
    I meant "while working on controls in the IDE".

  18. #18
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Can't get correct Left and Top of usercontrol

    I may have missed the problem to be solved here. I thought it had something to do with "smearing" when a UserControl is rapidly moved around at runtime.

    If your "grid of many colors" isn't much more than that and can be implemented as a fleet of rectangular Shape controls then there are fairly simple alternatives. 625 instances of any control carry significant overhead, and for a rectangular Shape you don't really get a lot for your money.

    What about just carrying a bitmap around, rendering it during the Paint event? That's almost as lightweight as it gets, eliminating the overhead of rendering 625 little rectangles each event.


    Since you want the UserControl to "ride over" other controls it can't be windowless which would lighten it up even more. But the repainting still seems quick enough to be usable, at least to me.

    In this quick and dirty demo the DragMe UserControl accepts left-click to toggle the cell moused over, right-drag to move. A menu item is there to test programmatic access to cell states.

    Name:  sshot.png
Views: 669
Size:  2.4 KB

    Maximize the Form to test fast-dragging, so you can whip it around to see whether the motion blur issues are acceptable.

    This demo uses a Drawing canvas class I had on hand. It could be pared way down, eliminating stuff not used here. You could replace that a different one, or use something like an invisible PictureBox instead.

    There are few API calls outside the Drawing class.
    Attached Files Attached Files

  19. #19
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Can't get correct Left and Top of usercontrol

    That's not meant as a solution, more of an illustration of a suggestion.

  20. #20

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    @dilettante

    Thank you for your post and your very clever user control.

    There was a problem with smearing until I changed the drag method as I pointed out in post #6 but for this thread the problem is knowing the user control's location after it has been moved using that method.

    Dragging your user control around rapidly on the Form does tend to smear and from much testing on my part using various ways of dragging the control I found that the method I am currently using appears to either not smear or the smear is so minute that it doesn't present a problem. Of course, it leaves the problem of not having the control's Left and Top properties updated, thus the reason for this thread.

    It occurred to me when I first started this project to draw the cells like you do in your posted example to avoid using 625 of any control but at that time it presented other problems that I didn't want to (or didn't know how to handle) get into so I decided to use shape controls because I figured they were the lightest of anything other than drawing the cells.

    One problem with drawing the cells was that I was faced with how to show only the green cells and not the black cells. I didn't know how to accomplish this but with shapes I had control over each cell and I can turn on or off each cell by it's index. This seemed a lot easier that computing the "drawn" cell's index (maybe now I might be able to do that but I am too far into this project that it's not worth the time and effort to change it now).

    In my project at any given time in the game a cell is either on(green) or off(black) but I don't show the black cells; only the green cells are visible. I accomplish this by using a transparent user control and if a cell is off I simply make it's shape control invisible. I suppose if I drew the cells I could do the same by making the off cell white so that it becomes transparent the same as the user control. Like I said, however, I'm just too far along to change it now. Maybe I'll play around with this idea using your posted project unless of course you already have such code.
    Last edited by Code Dummy; Apr 25th, 2019 at 12:34 PM.

  21. #21

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    Well, I guess my idea isn't going to work. I played around alittle with your control and it appears that a colored area will not show up on a transparent user control. I colored the area for cell 1,1 green before I started the project. When it came up the control was transparent but the colored area was also transparent. That kind of caught me off guard, I didn't expect that. So, that puts me back to using shape controls unless you have an idea.
    Last edited by Code Dummy; Apr 25th, 2019 at 02:55 PM.

  22. #22
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Can't get correct Left and Top of usercontrol

    Wow, the goalposts move quickly here!

    Have you tried working with MaskColor and MaskPicture? The odds seem slim that this is what you want either, but here is an illustration:

    Name:  sshot1.png
Views: 613
Size:  3.6 KB

    Name:  sshot2.png
Views: 601
Size:  4.1 KB

    Bigger attachment due to inclusion of a backdrop EMF image.
    Attached Files Attached Files

  23. #23
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,064

    Re: Can't get correct Left and Top of usercontrol

    sorry, posted in the wrong thread

  24. #24

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    554

    Re: Can't get correct Left and Top of usercontrol

    @dilettante

    Thank you very much for posting that example in #22

    After making a few modifications to suit my needs it works quit nice. Every once in awhile I notice that it flickers just a tiny bit when I mouse down to turn on a cell but not enough to discourage using it. The smear is gone and that's a major improvement.

    The transparency using mask color is very nice. I have heard of mask color but didn't know about using it.

    It appears that there is a lot of code needed to just turn cells on and off and drag the grid around. I removed every sub and function that is not used from both the control and the Drawing.cls and still a lot of code was left over. However, I wonder if the amount of visible code in your example is more or less than the "under the hood" plus my own code in my project to accomplish the same effect.

  25. #25
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [RESOLVED] Can't get correct Left and Top of usercontrol

    Here is a version of the same thing that strips out every API call and only uses VB6 statements, employing the UserControl itself as the canvas. I stripped out the Form's backdrop image as well to save on attachment size.

    The result is essentially the same, but uses high-level VB operations. These have significant amounts of fixed code behind them so you lose a lot of flexibility. But if you can accomplish what you want to within the limitations it imposes then great. Just don't ask for alpha blending or anything too sophisticated.
    Attached Files Attached Files
    Last edited by dilettante; Apr 30th, 2019 at 02:05 AM. Reason: trimmed out a few more lines

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width