Results 1 to 36 of 36

Thread: UserControl ScaleMode issue

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    UserControl ScaleMode issue

    I like to reopen the previous thread:
    http://www.vbforums.com/showpost.php...8&postcount=16:

    "Hello LaVolpe, I have got a similar problem, but I couldn't solve it with your code advices. Please see the attached archive: its a subclassing control for lazy noobs . Open the test form of the test project and change the FitSizeTo property to see the whole magic . - It works perfectly if the parent form is in vbTwips mode, but not if it is switched to vbPixels.

    Do you have an idea to overcome the problem without adding a ParentScaleMode property?"
    Last edited by NeedHelp!; Feb 25th, 2010 at 07:20 AM.

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    All windowed controls' dimensions and position can be retrieved if you know their hWnd. APIs for resizing use Pixel sizes, APIs that get the dimensions/position return those in pixels. Look at these following APIs
    GetWindowRect, GetClientRect, ScreenToClient, MoveWindow/SetWindowPosition
    Samples can be found on AllAPI.net
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    All windowed controls' dimensions and position can be retrieved if you know their hWnd. APIs for resizing use Pixel sizes, APIs that get the dimensions/position return those in pixels. Look at these following APIs
    GetWindowRect, GetClientRect, ScreenToClient, MoveWindow/SetWindowPosition
    Samples can be found on AllAPI.net
    Ok, actually I wanted to avoid APIs. I did write extra code for the line control, because it has X1, Y1, X2 and Y2 instead of Left, Top, Width and Height.

    This control has no hWnd, so how can I handle this with the API solution?

    Btw: just for basic understanding - what is the advantage of MoveWindow compared to SetWindowPos?

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    VB line controls, image controls, shape controls and labels do not have hWnds. And line control's don't have a width/height property either. So, you may have to handle specific types of controls vs some generic routine.

    I do not know what your intentions are, but if it is some sort of resizing/positioning program, take a look at the CodeBank and search for: AutoSizer. It should give you some ideas how to handle the various types of controls.

    MoveWindow: Just positions a window & optionally repaints it.
    SetWindowPos: Much more flexibility: moves, sizes, changes zOrder, shows/hides & more.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    So, you may have to handle specific types of controls vs some generic routine.
    What do you mean with that?

    I do not know what your intentions are, but if it is some sort of resizing/positioning program, take a look at the CodeBank and search for: AutoSizer.
    I want to write a subclassing control. It is a container. It will subclass all contained controls. The control should be able to automatically take the client size of the parent form or be as little as possible - so that all outer containted controls touch the containers border.
    Please see my project, as I descripted above - it will give a good impression and takes just a few seconds.
    I will have a look at AutoSizer. - Can I find it here in the forum?
    Because I did only find this thread: http://www.vbforums.com/showthread.p...ight=autosizer

    MoveWindow: Just positions a window & optionally repaints it.
    SetWindowPos: Much more flexibility: moves, sizes, changes zOrder, shows/hides & more.
    Thank you for explanation. But I have problems with these API calls: they do paint the control resized, but the controls resizer marks keep staying at the old position. - If I click the control afterwards, it will show the old size again.
    Last edited by NeedHelp!; Feb 24th, 2010 at 07:20 PM.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Maybe Resizer, Autosizer might be better search terms.

    Well, you cannot subclass a windowless control. It is impossible because in order to subclass, you need a window handle. Windowless controls don't have those.

    I took a look at your project and suggest two things.
    1. Move it to this thread so people don't have to jump to another thread to look at it.
    2. I don't see any code in there where you are using MoveWindow or SetWindowPos APIs. You may not be using them correctly; but we don't know.

    A slightly different approach to your project is not to use a containerized usercontrol. Maybe just use one usercontrol where the coder adds control hWnds to it via a method like: Public Function AttachHwnd(theHwnd As Long); the actual control isn't placed inside the uc, only its hWnd is used for subclassing purposes. This would allow the user to place just one control on their form and subclass any hWnd they send to your usercontrol. Just an idea.

    Oh, and what happens if someone drops multiple controls in your uc? How are you going to resize it to the group of controls? Image this can get really nasty. Example: if there were 5 controls like the 5 dots on a dice. If user adds the 4 corner dots to your uc, then tries to add the middle dot to another uc, one uc will overlap the other.

    And one last thing. I doubt anyone is going to want to see your uc's text and borders in runtime. If you continue with using a containerized uc, you may want to test for runtime/designtime and do not draw text/borders at runtime. This of course means that you'll have two resize scenarios because the uc won't be the same size during runtime/designtime if you go that route.
    Last edited by LaVolpe; Feb 25th, 2010 at 12:40 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Maybe Resizer, Autosizer might be better search terms.
    Yes, I could find that Resizer control, its a cool pice of code. - But nothing useful for this project I guess.
    http://www.vbforums.com/showthread.p...hlight=Resizer

    Well, you cannot subclass a windowless control.
    I know, but the user might want to subclass several controls with my UserControl and wants to add some non-hWnd controls also.
    e.g. two textboxes and an arrow made out of lines:
    _____________________________________
    | ____________ Subclasser _____________ |
    || Textbox1 .....| <------> | Textbox2 .....||
    ||____________| ............ |____________||
    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    - These line controls don't have to be subclassed, but should be respositioned like the textboxes as well.


    1. Move it to this thread so people don't have to jump to another thread to look at it.
    Sorry, I thought it would be the best to write in this other thread, since it fits to the topic, because I got now answers there I opend a new one and posted a link to my original post.

    I did upload my newes version to this post.
    In this version I did solve the problem, by setting the container ScaleMode to vbTwips for the time of repositioning. - It's so simple!

    2. I don't see any code in there where you are using MoveWindow or SetWindowPos APIs. You may not be using them correctly; but we don't know.
    Yes, the project you looked at was my first attempt, before you did suggest me to use these APIs - my API version is also attached to this post.
    I could solve the problem, but I am still interested to know, why the API version is not working.

    A slightly different approach to your project is not to use a containerized usercontrol. Maybe just use one usercontrol where the coder adds control hWnds to it via a method like: Public Function AttachHwnd(theHwnd As Long). This would allow the user to place just one control on their form and subclass any hWnd they send to your usercontrol. Just an idea.
    Yes, this is also a possibility. But there are so much Subclassing examples out there (mostly classes, without the need to add a control at all) - this would be just another taste of it...

    my solution has following advantages:
    - no single line of code needed
    - it is possible to see, which controls are subclassed, just by looking at the visual editor => this is a very visual proceeding, and fits perfectly to VISUAL Basic

    Maybe I'll add this Attach_hWnd() method as additional feature, but I will keep the container functionality, since this was the initial idea to start this project.

    I am also thinking about a PropertyPage, where the user can select the controls, which shall be subclassed, via checkboxes. But than I have to distribute the UserControl as OCX instead of a source file

    Oh, and what happens if someone drops multiple controls in your uc? How are you going to resize it to the group of controls? Image this can get really nasty. Example: if there were 5 controls like the 5 dots on a dice. If user adds the 4 corner dots to your uc, then tries to add the middle dot to another uc, one uc will overlap the other.
    Sorry, I can't see a problem here... What do you mean exactly?

    And one last thing. I doubt anyone is going to want to see your uc's text and borders in runtime.
    Hmm, actually the Title "control name (class name)" and the borders are only for easier handling at design time. There is no need to show them at runtime - except for a demo project which likes to show, which controls are subclassed.

    If you continue with using a containerized uc, you may want to test for runtime/designtime and do not draw text/borders at runtime. This of course means that you'll have two resize scenarios because the uc won't be the same size during runtime/designtime if you go that route.
    You mean that 1 pixel border? - Well, I thought this shouldn't matter.

    I've got another question:
    Why is the Ambient.DisplayName and Extender.Name? What is the difference?


    - outdated attachments deleted -
    Last edited by NeedHelp!; Mar 8th, 2010 at 08:11 AM.

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    I haven't tried your latest version yet. Just have enough time to respond to some of your questions so you have the opportunity to rethink if needed.
    Quote Originally Posted by NeedHelp! View Post
    Yes, I could find that Resizer control, its a cool pice of code. - But nothing useful for this project I guess.
    http://www.vbforums.com/showthread.p...hlight=Resizer

    I know, but the user might want to subclass several controls with my UserControl and wants to add some non-hWnd controls also.
    e.g. two textboxes and an arrow made out of lines:
    _____________________________________
    | ____________ Subclasser _____________ |
    || Textbox1 .....| <------> | Textbox2 .....||
    ||____________| ............ |____________||
    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    - These line controls don't have to be subclassed, but should be respositioned like the textboxes as well.
    The resizer you found at least would give you some insight on which types of controls you cannot subclass. If some is going to place a line control in your uc, why would you need to change its size? Maybe looking at your latest project might answer that question.

    Quote Originally Posted by NeedHelp! View Post
    In this version I did solve the problem, by setting the container ScaleMode to vbTwips for the time of repositioning. - It's so simple!
    Yes & no. Not all containers have scalemodes. Frames for example do not as well as possbily other custom ucs. If this control is only designed to be used with VB and no other types of IDEs, then this may not be a big deal.

    Quote Originally Posted by NeedHelp! View Post
    Yes, the project you looked at was my first attempt, before you did suggest me to use these APIs - my API version is also attached to this post.
    I could solve the problem, but I am still interested to know, why the API version is not working.
    Hopefully you have that code in there so we can look at what you attempted with those APIs.

    Quote Originally Posted by NeedHelp! View Post
    (Regarding not having a container-type control). Yes, this is also a possibility. But there are so much Subclassing examples out there (mostly classes, without the need to add a control at all) - this would be just another taste of it...
    I wasn't going to go there, but honestly, I'd never use a control that hindered my form design. Your control is not "see-through", so what happens if I have images on my form that would normally show between the buttons? But the buttons are now in your control and I can't see the images because your uc is ontop of my image/picturebox? Your first gut response may be to put the image/picturebox in the uc, but that may not be possible for so many reasons.

    Quote Originally Posted by NeedHelp! View Post
    my solution has following advantages:
    - no single line of code needed
    - it is possible to see, which controls are subclassed, just by looking at the visual editor => this is a very visual proceeding, and fits perfectly to VISUAL Basic
    I do agree it is a nice touch in theory, but in practice I doubt it will be usable to anyone unless they have a solid backcolor form. Otherwise, it would be far more effort to try to get your uc to look transparent. Try it. Change your form's backcolor to yellow and don't mess with your uc. Granted you can give your uc a backcolor property, but that won't help if it spans over/ontop of image controls or custom painted forms (i.e., gradients).

    Quote Originally Posted by NeedHelp! View Post
    I am also thinking about a PropertyPage, where the user can select the controls, which shall be subclassed, via checkboxes. But than I have to distribute the UserControl as OCX instead of a source file
    Why? I've distributed many ucs, in recent past, with & without property pages.

    Quote Originally Posted by NeedHelp! View Post
    Hmm, actually the Title "control name (class name)" and the borders are only for easier handling at design time. There is no need to show them at runtime - except for a demo project which likes to show, which controls are subclassed.
    You may have addressed this in your recent project, but I found it difficult to resize your uc because it tried to fit the contained controls to closely.

    Quote Originally Posted by NeedHelp! View Post
    You mean that 1 pixel border? - Well, I thought this shouldn't matter.
    Of course it does (in runtime). Trust me, no one is going to want to see boxes around their controls at runtime.

    Quote Originally Posted by NeedHelp! View Post
    Why is the Ambient.DisplayName
    The name the coder gave your uc.

    Quote Originally Posted by NeedHelp! View Post
    .. and Extender.Name? What's the difference?
    Make one of your controls Indexed and you'll see the difference.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    The resizer you found at least would give you some insight on which types of controls you cannot subclass.
    It is indeed a nice control. I truly think, I can use it in future.

    If some is going to place a line control in your uc, why would you need to change its size?
    The contained controls will not be resized - just the uc (to fit to the container or to take as less space as possible)

    Yes & no. Not all containers have scalemodes.
    Therefore I did implement a GetScaleModeContainer() function: it checks recursively, if a container has a ScaleMode property - if not, it checks for the containers container until it finds one, which has this property.

    If this control is only designed to be used with VB and no other types of IDEs, then this may not be a big deal.
    Yes, this was actually my plan.
    So ScaleMode would be compatibility breaker to other IDEs?

    Hopefully you have that code in there so we can look at what you attempted with those APIs.
    Yes, its in the second file.

    I wasn't going to go there, but honestly, I'd never use a control that hindered my form design. Your control is not "see-through", so what happens if I have images on my form that would normally show between the buttons? But the buttons are now in your control and I can't see the images because your uc is ontop of my image/picturebox? Your first gut response may be to put the image/picturebox in the uc, but that may not be possible for so many reasons.
    Therefore I like to give the addional feature to subclass by attaching the hWnds.

    I do agree it is a nice touch in theory, but in practice I doubt it will be usable to anyone unless they have a solid backcolor form. Otherwise, it would be far more effort to try to get your uc to look transparent.
    Well, it should be possible to set the BackStyle to transparent and use shapes to make the contained controls visible again. A problem would be the line control in this case. But that shouldn't be a big deal - especially with hWnd attache feature.

    Why? I've distributed many ucs, in recent past, with & without property pages.
    I prefer to add UCs instead of OCXs, so that the final compiled executable is independent from external libraries. But all the libraries I add to a project should consist out of only one single file, to keep project chaos out.
    So after my rule I have to distribute the OCX - which is also, what I don't like.

    You may have addressed this in your recent project, but I found it difficult to resize your uc because it tried to fit the contained controls to closely.
    Yes, this is planed. The control can be resized and selected via the property list.
    I did even take the title away lately, so moving and selecting is even harder.
    I guess I will add a property to let the user decide, if the title should be shown or not.

    Of course it does (in runtime). Trust me, no one is going to want to see boxes around their controls at runtime.
    Yes, the border is visible just in design mode. And for the case there is a picture on the form, I like to add transparency.

    Make one of your controls Indexed and you'll see the difference.
    Ok, I will check this tomorrow.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Hello LaVolpe!

    Did you find the time to look at the APIs?

    Please see my latest version attached to this post. - It supports title hide and show and transparency (at runtime only).

    Maybe I'll at scaling, so that the contained controls will scale with the container size, like the resizer is doing it. Let's see.

    Btw:
    Quote Originally Posted by LaVolpe
    Quote Originally Posted by NeedHelp!
    Why is the Ambient.DisplayName
    The name the coder gave your uc.
    Many thanks for that hint to check an indexed control!

    But its the opposite: Extender.Name gives the name, which the coder gave the UC. - Ambient.DisplayName give the name + the index in brackets:
    UserControl.Extender.Name = "TestUC"
    UserControl.Ambient.DisplayName = "TestUC(0)"



    - outdated attachment deleted -
    Last edited by NeedHelp!; Mar 8th, 2010 at 08:13 AM.

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    PS: I want to make my uc index safe now, but this is a pain in the ass...
    I like to get my uc as control to have access to the Left and Top property for intance. This is possible via Ambient.DisplayName, by retrieving both: the name and the index also.
    I was wondering, if there is a easier way to do this?

    Best

  12. #12
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    No I haven't had time to look at it (real world programming taking alot of my time). Maybe tomorrow.

    Regarding getting the index? That's simple. Test the Ambient.DisplayName to see if it ends in a right parenthesis. If so, it's indexed. VB won't allow parentheses in control names. Simple parsing will get you both or one or the other.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    (real world programming taking alot of my time). Maybe tomorrow.
    Oh, ok. This means, you are seeing this forum as your second life...
    Please take your time. It's not a hurry.

    Regarding getting the index? That's simple. Test the Ambient.DisplayName to see if it ends in a right parenthesis. If so, it's indexed. VB won't allow parentheses in control names. Simple parsing will get you both or one or the other.
    Yes, this is how I did solve that issue:
    Code:
    'retruns this UserControl as Control (now index safe)
    Private Function This() As Control
        Dim arrTmp() As String
        Dim strCtrlName As String
        Dim intCtrlIndex As Integer
        Dim bHasIndex As Boolean
    
        Dim Ctrl As Control
    
    
        arrTmp = Split(UserControl.Ambient.DisplayName, "(")
        
        If UBound(arrTmp) = 1 Then
            bHasIndex = True
            intCtrlIndex = Val(arrTmp(1))
        End If
        
        strCtrlName = arrTmp(0)
        
        'On Error Resume Next
        For Each Ctrl In UserControl.Parent.Controls
            If Ctrl.Name = strCtrlName Then
                If bHasIndex Then
                    If Ctrl.Index = intCtrlIndex Then
                        Set This = Ctrl
                        Exit Function
                    End If
                Else
                    Set This = Ctrl
                    Exit Function
                End If
            End If
        Next Ctrl
        
        'Info - if the coder gave the UserControl the name "TestUC" and the index zero:
        'UserControl.Extender.Name = "TestUC"
        'UserControl.Ambient.DisplayName = "TestUC(0)"
    End Function
    But I thought my code is a little long and there might be a better solution/trick.

    The same with comparing controls: since they not always have a hWnd or a unique name (if they are indexed), I am using following code to find out, if controls are equal:

    Code:
    Private Function ControlsAreEqual(Ctrl_1 As Object, Ctrl_2 As Object) As Boolean
        If Ctrl_1.Name = Ctrl_2.Name Then
            'error occurs, if object is no array -> Resume Next will result in returning True in this case
            On Error Resume Next                                                        
            If Ctrl_1.Index = Ctrl_2.Index Then ControlsAreEqual = True
        End If
    End Function
    It's working, but I don't like, that I have to use the On Error Resume Next. - But maybe this is the way you have to write code...
    Last edited by NeedHelp!; Feb 27th, 2010 at 05:23 AM.

  14. #14
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Hmmm, how'd you like to replace 99&#37; of that code with just one line?

    Code:
    If Ctrl2 Is Me Then ' Ctrl2 and ThisControl are the same
    ' or another way to skin that cat: If ObjPtr(Me) = ObjPtr(Ctrl2) Then ' the same
    Try it.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  15. #15
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Read post #14 too.
    Here is a simple, compact, and efficient routine that uses APIs to calculate the autofit size for contained controls. It does include calculations for line controls too.

    Note, in this case, we don't need APIs to get control sizes/positions because they are contained in the uc and the contained control's width/height position are always in twips. This won't necessarily be true for non-contained controls (i.e., your shape control).

    Play with it. I commented it so you can follow my logic.
    Here are the APIs
    Code:
    Private Declare Function MoveWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
    Private Declare Function UnionRect Lib "user32.dll" (ByRef lpDestRect As RECT, ByRef lpSrc1Rect As RECT, ByRef lpSrc2Rect As RECT) As Long
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Private Declare Function SetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare Function ClientToScreen Lib "user32.dll" (ByVal hwnd As Long, ByRef lpPoint As POINTAPI) As Long
    Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hwnd As Long, ByRef lpPoint As POINTAPI) As Long
    Private Type POINTAPI
        X As Long
        Y As Long
    End Type
    Here is the routine. Needs slight tweaking for other non-standard controls.
    Code:
    Private Sub calculateAutoFit()
        Dim v As Variant
        Dim totalRect As RECT, ctrlRect As RECT, tPt As POINTAPI
        
        ' create rectangle that contains all controls
        On Error Resume Next
        For Each v In UserControl.ContainedControls
            If TypeOf v Is VB.Line Then ' handle other controls that don't have .width/.height properites as you find them
                If v.X2 < v.X1 Then ctrlRect.Left = v.X2 Else ctrlRect.Left = v.X1
                If v.Y2 < v.Y1 Then ctrlRect.Top = v.Y2 Else ctrlRect.Top = v.Y1
                ctrlRect.Right = ctrlRect.Left + Abs(v.X1 - v.X2) + 1
                ctrlRect.Bottom = ctrlRect.Top + Abs(v.Y1 - v.Y2) + 1
            Else ' when control has height/width property:
                SetRect ctrlRect, v.Left, v.Top, v.Width + v.Left, v.Height + v.Top
            End If
            If Err Then ' maybe a menu or some other control you will have handle separately. 
                 ' Though menu is an example; you can't have contained controls of type menus
                 Err.Clear
            Else
                 UnionRect totalRect, totalRect, ctrlRect
            End If
        Next
        ' offset/move each control in relation to the combined rectangle
        ' On Error Resume Next is still active
        For Each v In UserControl.ContainedControls
            If TypeOf v Is VB.Line Then
                v.X1 = v.X1 - totalRect.Left: v.X2 = v.X2 - totalRect.Left
                v.Y1 = v.Y1 - totalRect.Top: v.Y2 = v.Y2 - totalRect.Top
            Else
                v.Move v.Left - totalRect.Left, v.Top - totalRect.Top
            End If
        Next
        ' rectangle is in twips, but APIs need pixels, so convert it
        SetRect ctrlRect, ScaleX(totalRect.Left, vbTwips, vbPixels), ScaleY(totalRect.Top, vbTwips, vbPixels), _
            ScaleX(totalRect.Right, vbTwips, vbPixels), ScaleY(totalRect.Bottom, vbTwips, vbPixels)
        ' transfer left/top to POINT structure
        tPt.X = ctrlRect.Left: tPt.Y = ctrlRect.Top
        ' get rectangle's coordinates relative to the desktop
        ClientToScreen UserControl.hwnd, tPt
        ' convert those coordinates relative to the uc's container
        ScreenToClient UserControl.ContainerHwnd, tPt
        ' now resize the uc leaving a 1 pixel edge around the contained controls
        MoveWindow UserControl.hwnd, tPt.X - 1, tPt.Y - 1, ctrlRect.Right - ctrlRect.Left + 2, ctrlRect.Bottom - ctrlRect.Top + 2, True
        
    End Sub
    Edited: That 2nd For Loop is needed unfortunately. What I didn't appreciate in your control is that if you resized the uc using the left sizing handle, the controls moved with it. In my opinion that is incorrect, your control should not be moving the contained controls in relation to the uc when the uc is being resized, the contained controls should stay fixed relative to their original container. Now it's a different story if you are moving the uc, then obviously the contained controls move with it.

    Edited yet again. That resizing issue, I described in last para, isn't your code, rather it is VB. This is something you can handle if you wish too. You will have to respond to the Resize event of the uc and determine whether you are resizing it via code or not. If not, the VB/user is resizing it and attempt to keep the contained control positions fixed to original coordinates relative to original container. People spend a lot of time positiong their controls exactly where they want them and if your uc moves them, that will be a frustration factor that many may not be willing to live with.

    Other potential issues/problems with containerizing their controls.
    1. User can no longer align the containerized controls with non-containerized controls
    2. Does it interfere with their tab stops and tab order? I'll leave that for you to test
    3. If user is dynamically creating conrols at runtime, where does the new control go if the base control was containerized?
    4. Not saying they will do this, but what happens if they move a control into/out of your uc during runtime.
    Like I said in an earlier posting, the idea is a nice touch but I fear it won't be really user-friendly except for the most basic GUIs.
    Last edited by LaVolpe; Feb 27th, 2010 at 01:12 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  16. #16

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Hallo LaVolpe, thank you for all your work!

    Code:
    If Ctrl2 Is Me Then ' Ctrl2 and ThisControl are the same
    ' or another way to skin that cat: If ObjPtr(Me) = ObjPtr(Ctrl2) Then ' the same
    This was a good call.

    If Ctrl_1 Is Ctrl_2 Then ...
    Works great, so I wont need the function ControlsAreEqual(Ctrl_1 As Object, Ctrl_2 As Object) anymore.

    But following code did not work:
    Code:
    Private Function This() As Control
        Dim Ctrl As Control
    
        For Each Ctrl In UserControl.Parent.Controls
            If ObjPtr(Ctrl) = ObjPtr(Me) Then      'the same with "If Ctrl Is Me Then"
                Debug.Print "Found Me!"
                Set This = Ctrl
                Exit Function
            End If
        Next Ctrl
    End Function
    -> the debug output "Found Me!" did never show up.

    Quote Originally Posted by LaVolpe View Post
    Here is a simple, compact, and efficient routine that uses APIs to calculate the autofit size for contained controls. It does include calculations for line controls too.
    Thank you. It is really short and doing exactly the same like my non-API code.
    But as I mentioned before - I am having trouble with that API calls.
    I did attach some screen shots to show you what happens (at least on my system):
    1.) initial condition: uc with 4 buttons in the center
    2.) AutoSize performed: uc fits the contained controls and buttons stay fix, where the were before. But the visual editor resize markers keep staying at the original position. Also: the uc border is not updated, this happens, because the UserControl_Resize event is not fired, when APIs are used (this might also be the reason, why the VB6 IDE does not detect the new uc position)
    3.) Resizing the uc by using the resize markers, which kept staying at the old postion
    4.) After releasing the mouse button: uc takes back the old size again - but at the new position. Still the resize markers are at the original position.
    5.) Now moving the uc
    6.) After releasing the mouse button, the uc's visual surface and its resize markers fall together again. But the uc's suface is taking the position and size of the resize markers. The only thing, which changed is the position of the contained controls...


    Quote Originally Posted by LaVolpe
    Note, in this case, we don't need APIs to get control sizes/positions because they are contained in the uc and the contained control's width/height position are always in twips. This won't necessarily be true for non-contained controls (i.e., your shape control).
    I see.


    Quote Originally Posted by LaVolpe
    What I didn't appreciate in your control is that if you resized the uc using the left sizing handle, the controls moved with it. In my opinion that is incorrect [...] Now it's a different story if you are moving the uc, then obviously the contained controls move with it.
    You are right, according the my AutoResize feature the uc should behave like you said.
    I did not pay attention to that, because the idea was this:
    - giving the uc the size of its container, to have enought space to move controls aside and place them where they should be
    - after that, it is possible to make the uc fitting to its controls again for least waste of space
    -> acutally uc resizing by its resize handle/marker should not be necessary.

    Quote Originally Posted by LaVolpe
    That resizing issue, I described in last para, isn't your code, rather it is VB. This is something you can handle if you wish too. You will have to respond to the Resize event of the uc and determine whether you are resizing it via code or not.
    I guess, it is not so easy. Let's say, I have determined, that the coder did resize the uc via the visual editor. - How do I get the original position?
    I could introduce a static variable, where I can save the current uc position for the next resize event. But what, if the coder moves the uc fist and does resize it afterwards? - If a control is moved in the visual editor, no event will be fired, right? The only way I can go would be, to use a timer I guess - but this would be a very bad solution for my understanding. Do you have another idea?

    Quote Originally Posted by LaVolpe
    If not, the VB/user is resizing it and attempt to keep the contained control positions fixed to original coordinates relative to original container. People spend a lot of time positiong their controls exactly where they want them and if your uc moves them, that will be a frustration factor that many may not be willing to live with.
    Thats right, but in fact, its the standard behavior for container controls (even it does not fit to my uc)...

    Quote Originally Posted by LaVolpe
    Other potential issues/problems with containerizing their controls.
    1. User can no longer align the containerized controls with non-containerized controls
    That is right. They have to put all controls inside the container (which will cause some additional subclassings, which are not needed) or use the Attach_hWnd feature which I like to add, as you recommended.

    Quote Originally Posted by LaVolpe
    2. Does it interfere with their tab stops and tab order? I'll leave that for you to test
    Well, the uc itself does catch the Focus, which is not preferable.
    Therefore I did add already the command This.TabStop = False in the UserControl_Show section.

    Quote Originally Posted by LaVolpe
    3. If user is dynamically creating conrols at runtime, where does the new control go if the base control was containerized?
    It will go to the same container. But it will not be subclassed.
    -> I really have to implement that Attach_hWnd method...

    Quote Originally Posted by LaVolpe
    4. Not saying they will do this, but what happens if they move a control into/out of your uc during runtime.
    I guess this is only possible with API. Somebody who uses API that way should know what he is doing.
    But it should not effect the subclassing. The subclassing is performed for all controls which are already in the uc at design time. It's a design mode control.

    Quote Originally Posted by LaVolpe
    Like I said in an earlier posting, the idea is a nice touch but I fear it won't be really user-friendly except for the most basic GUIs.
    Like I said in an earlier posting, it is a lazy noob subclasser!
    I like the fact, that I can easily add a uc for each control I like to subclass, without wasting a lot of space in the visual editor and with the visual feedback, which control is subclassed. Therefore I can give that subclasser almost the same name like the control, which I like to subclass - so that the code can be better read. And it is not needed to write any line of code for this.
    It is designed for basic GUIs only - with the option to attach further hWnds it will also get some more flexibility. But for advanced subclassing, my controls is the wrong way - there are other better solution available out there.
    Attached Images Attached Images      

  17. #17

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    this is the last attachment (because there are only 5 allowed):
    Attached Images Attached Images  

  18. #18
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    But following code did not work...
    Oops, my bad. It will work for forms, classes but for usercontrols, it is actually ObjPtr(UserControl.Extender) if I recall correctly. By using the IS operator is easier anyway.

    Quote Originally Posted by NeedHelp! View Post
    ... I guess, it is not so easy. Let's say, I have determined, that the coder did resize the uc via the visual editor. - How do I get the original position? I could introduce a static variable, where I can save the current uc position for the next resize event. But what, if the coder moves the uc fist and does resize it afterwards? - If a control is moved in the visual editor, no event will be fired, right? The only way I can go would be, to use a timer I guess - but this would be a very bad solution for my understanding. Do you have another idea?
    Moving the uc is out of your control and not really a player here. The offset you can cache is the X,Y distance of the top/left-most control inside your uc to the 0,0 position of the uc's container hwnd. So if the control is resized using left-side grab handles, your uc will get a resize event. At that point, you can test the top/left most control to see where its relation is to the uc's container's 0,0 position. If it is different, offset all of your controls the difference between the top/left most control's current position and its last position. Where this logic fails is if a user moves a control within your uc during design time; do you get any event to let you know it was moved, so you can re-cache the offset?

    Quote Originally Posted by NeedHelp! View Post
    ...I guess this is only possible with API. Somebody who uses API that way should know what he is doing.
    Not really. Set myControl.Container = Picture1. No APIs.

    I'll take a look at why MoveWindow api is not refreshing the uc. Maybe a simple UserControl.Refresh would do the trick? Maybe SetWindowPos vs MoveWindow?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  19. #19
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Moving the uc is out of your control and not really a player here. The offset you can cache is the X,Y distance of the top/left-most control inside your uc to the 0,0 position of the uc's container hwnd. So if the control is resized using left-side grab handles, your uc will get a resize event. At that point, you can test the top/left most control to see where its relation is to the uc's container's 0,0 position. If it is different, offset all of your controls the difference between the top/left most control's current position and its last position. Where this logic fails is if a user moves a control within your uc during design time; do you get any event to let you know it was moved, so you can re-cache the offset?
    Actually this is more painful than it sounds. To keep track of the offset so that original control positions can be maintained, you'd also have to know if the uc is moved within its container because the offset will now be different. And if the top left contained control is moved or a new control is added to the uc, the offset may need to be recalculated. Hmmmm.

    If the uc does not have AutoRedraw set to true, you should get a paint event when contained controls are moved within the control? You might also get a paint event if the uc is moved vs. resized? Worth testing.
    Last edited by LaVolpe; Mar 2nd, 2010 at 03:08 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  20. #20

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Oops, my bad. It will work for forms, classes but for usercontrols, it is actually ObjPtr(UserControl.Extender) if I recall correctly. By using the IS operator is easier anyway.
    As it turns out, my 24 line This() function can be replaced with just one command: UserControl.Extender - I was not aware of this.
    To make it a little shorter I will keep my This() function, but now that short:
    Code:
    Private Function This() As Control
        Set This = UserControl.Extender
    End Function
    Thank you LaVolpe, to point me in that direction.

    Quote Originally Posted by LaVolpe View Post
    Moving the uc is out of your control and not really a player here.
    Sorry, I don't get it...
    The resize event is fired after the resize operation was already done by the coder. At this time, the contained controls are also already moved with the uc.
    Now I can retrieve the X,Y coordinates of the top left control in relation to the uc's container - and save them for the next resize event.
    But if the uc is moved (and all contained controls with it), my saved coordinates still point to the old position.
    Since there is no move event available, I don't see any way to make this working.

    Quote Originally Posted by LaVolpe View Post
    Where this logic fails is if a user moves a control within your uc during design time; do you get any event to let you know it was moved, so you can re-cache the offset?
    You are right - this is another situation, on which I did not think of...
    It is the problem: there is no move event.

    VB6 is not able to detect any move event - even not for forms.
    This is also one reason, why I do write this subclasser.

    Quote Originally Posted by LaVolpe View Post
    Not really. Set myControl.Container = Picture1. No APIs.
    Cool, I did not think, that this is possible. - I thought this is a read only property.


    Quote Originally Posted by LaVolpe View Post
    Maybe a simple UserControl.Refresh would do the trick?
    Unfortunatelly not.

    Quote Originally Posted by LaVolpe View Post
    Maybe SetWindowPos vs MoveWindow?
    I think I did try both - and both did not work.
    I guess this is, because there is no resize event fired at design time, when APIs are used. VB cannot detect, that on window was moved...


    I have another question:
    I did write a function, which removes all non-hWnd controls from a List of controls:
    Code:
    'Removes non-hWnd controls from a "collection" of controls
    Private Function With_hWnd(oControls As ContainedControls) As Collection
        Dim colReturn As New Collection
        Dim ctrl As Control
        
        For Each ctrl In oControls
            If Has_hWnd(ctrl) Then Call colReturn.Add(ctrl)
        Next ctrl
        
        Set With_hWnd = colReturn
    End Function
    So I can use it like that:
    Code:
    For each Ctrl In With_hWnd(UserControl.ContainedControls)
    Now I like to use this function for another function. This other function (SiblingControls) returns a collection of controls, which are in the same container like the UserControl (this is not needed for this subclasser, but interesting for an OptionButton for example).
    The problem is, that the types ContainedControls and Collection are not compatible. It is not possible to use a Variant instead. Overloading is also not possible. Is there a way to have just one function, which can handle both: ContainedControls and Collections?

  21. #21

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Actually this is more painful than it sounds. To keep track of the offset so that original control positions can be maintained, you'd also have to know if the uc is moved within its container because the offset will now be different. And if the top left contained control is moved or a new control is added to the uc, the offset may need to be recalculated. Hmmmm.
    Ok, you were faster than me...
    Yes, this is the problem.

    Quote Originally Posted by LaVolpe View Post
    If the uc does not have AutoRedraw set to true, you should get a paint event when contained controls are moved within the control? You might also get a paint event if the uc is moved vs. resized? Worth testing.
    Your are right, there is a paint event for moving contained controls and resizing the uc, but not for moving the uc.

    But if AutoRedraw is false, it is not possible to draw the title to the uc. I could use a label for this, but this would make only sense, if I can also detect the uc movment.

    I would say, that the current behavior of my control (since it is a little different to other containers) is not perfect, but it is also not too bad - so I think I will leave it as it is, since it would be a pain in the ass to get what you suggested (and -no doubt- what really would be nice)

  22. #22
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    ...I would say, that the current behavior of my control (since it is a little different to other containers) is not perfect, but it is also not too bad - so I think I will leave it as it is, since it would be a pain in the ass to get what you suggested (and -no doubt- what really would be nice)
    You can actually detect both sizing and moving if you really wanted to: Subclass your uc. Paul Caton's subclassing routine allows that, but you have to ensure you set the IDE protection variable to false to allow subclassing during uc design. Caution though because doing so introduces easy subclass crashing again. If you want to go that route, suggest doing so for testing purposes and then turn it off. When compiled to an ocx, if I remember that version of Caton's self-subclasser, the IDE protection setting should not interfere. Now, this does mean that while not self-subclassing the uc, you lose ability to easily detect uc moves.

    Edited: You might event get WM_Paint events even if VB doesn't send you one.

    Regarding movewindow & setwindow apis not redawing the uc & grab handles... I think I know the answer. UpdateWindow API, passing the uc's ContainerhWnd as the API's hWnd parameter. I haven't tested this new theory.
    Last edited by LaVolpe; Mar 2nd, 2010 at 04:16 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  23. #23

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    You can actually detect both sizing and moving if you really wanted to: Subclass your uc. Paul Caton's subclassing routine allows that, but you have to ensure you set the IDE protection variable to false to allow subclassing during uc design.
    Interesting. - I did try to subclass during design mode before, but it did not work... As it turns out, this IDE protection was the reason.

    Quote Originally Posted by LaVolpe View Post
    Caution though because doing so introduces easy subclass crashing again. If you want to go that route, suggest doing so for testing purposes and then turn it off. When compiled to an ocx, if I remember that version of Caton's self-subclasser, the IDE protection setting should not interfere. Now, this does mean that while not self-subclassing the uc, you lose ability to easily detect uc moves.
    Hmmm, since I prefer including an ctl file instead of integrating an ocx, I think it will be better not to bring that feature. It would be to insecure and I guess not worth the effort. Let's see. I am doing this also to get some experience, maybe I'll try it some day...

    Quote Originally Posted by LaVolpe View Post
    Edited: You might event get WM_Paint events even if VB doesn't send you one.
    Do you mean the self-subclassing with that?

    Quote Originally Posted by LaVolpe View Post
    Regarding movewindow & setwindow apis not redawing the uc & grab handles... I think I know the answer. UpdateWindow API, passing the uc's ContainerhWnd as the API's hWnd parameter. I haven't tested this new theory.
    No, it did not work.
    This is also not that bad, because my non-API code is also working (at least for the VB6 IDE).


    Do you have an idea regarding the ContainedControls/Collections problem?

  24. #24
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Ok, I kind of give up regarding using apis to resize the uc. It does not seem to work in design view while the uc is uncompiled. What is interesting is that once you run the code and verify the uc width (i.e., debug.print usercontrol.width\screen.twipsperpixelx), the width is exactly what was set with MoveWindow. But in design view, and you click on the uc, VB says its width is the original non-autofit size. So I ran the project and printed out the uc's width... VB thinks it is larger than it really is. Would this problem go away if the uc was compiled into an ocx? Maybe/probably.

    Regarding your collections problem. Variant is the key. Here is a tweaked version of your routine, along with a sample call in the uc's Show event.
    Code:
    Private Function With_hWndEx(oControls As Variant) As Collection
        
        Dim colReturn As New Collection
        Dim Ctrl As Control
        
        For Each Ctrl In oControls
            Call colReturn.Add(Ctrl)
        Next Ctrl
        
        Set With_hWndEx = colReturn
    End Function
    
    Private Sub UserControl_Show()
        
        Dim Ctrl As Control
        Dim tCol As Collection
        
        ' setup a test collection & some controls in it
        Set tCol = New Collection
        For Each Ctrl In UserControl.ContainedControls
            Call tCol.Add(Ctrl)
        Next Ctrl
        
        ' call this, passing contained controls
        For Each Ctrl In With_hWndEx(UserControl.ContainedControls)
            Debug.Print Ctrl.Name
        Next
        ' call this, passing a collection
        For Each Ctrl In With_hWndEx(tCol)
            Debug.Print Ctrl.Name
        Next
    End Sub
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  25. #25

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Ok, I kind of give up regarding using apis to resize the uc. It does not seem to work in design view while the uc is uncompiled. What is interesting is that once you run the code and verify the uc width (i.e., debug.print usercontrol.width\screen.twipsperpixelx), the width is exactly what was set with MoveWindow. But in design view, and you click on the uc, VB says its width is the original non-autofit size. So I ran the project and printed out the uc's width... VB thinks it is larger than it really is.
    Cool, it seems we drove VB6 to its limits!

    Quote Originally Posted by LaVolpe View Post
    Would this problem go away if the uc was compiled into an ocx? Maybe/probably.
    I did try it: compiled uc shows the same problem, even if UpdateWindow() is called...

    Quote Originally Posted by LaVolpe View Post
    Regarding your collections problem. Variant is the key. Here is a tweaked version of your routine, along with a sample call in the uc's Show event.
    Yes, it works now! - I did try it with Variant before, but it gave me an error...

    This is strange, sometimes I am also getting an error, if a command requires a constant, but I am passing an enum value. Than I have to close and restart the IDE again. - Maybe this was also the problem with the Variant.

    Do you know why this is? Is there a trick to avoid to restart the IDE?

    EDIT: For what stants the "Ex", which you added to With_hWndEx?


    And I have another question:
    As I did compile my uc with your API code, I got the library "prjSubclasser" in the components list, which is the project name of my uc. But I like to give another name, one with whitespaces - other libraries in the component list have such names. How can I also apply such a name?
    Last edited by NeedHelp!; Mar 3rd, 2010 at 08:30 AM.

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Here is a great reference for active-x controls. Part 3, Chapter 16 starts the uc section. Part 2, Chapter 8 should answer your last question.

    As for your error regarding constants? I don't follow, but consider it a snafu if it doesn't happen again.

    The Ex in the function name? Just wanted to name it something different in case you simply copied and pasted the sample code into your project. That way it wouldn't conflict with your existing routine. In Windows APIs, Ex at the end of a function stands for Extended, i.e., extended version that allows more flexibility/functionality over a previous version.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Thank you for the link LaVolpe.

    And I have another question again...

    The Resizer you did recommend me, shows only a few properties in the property table. - How can I achieve this too?
    I did already figure out, how to hide my own properties. But how can I hide standard properties?

  28. #28
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Standard properties, as in the ones vb provides like tooltip, width, height, etc? You can't, it is not in your control. Those are the properties that the ocx extender expose and different language IDE's (i.e., MS Access, Excel, Word, etc) can provide different properties.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  29. #29

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Standard properties, as in the ones vb provides like tooltip, width, height, etc? You can't, it is not in your control. Those are the properties that the ocx extender expose and different language IDE's (i.e., MS Access, Excel, Word, etc) can provide different properties.
    Ok, if I set the Resizers property InvisibleAtRuntime to False, all these other standard properties appear again - and I need visibility at runtime.

  30. #30
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    Ok, if I set the Resizers property InvisibleAtRuntime to False, all these other standard properties appear again - and I need visibility at runtime.
    Maybe you should specifically address which properties you are talking about so that there is no confusion.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  31. #31

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    Maybe you should specifically address which properties you are talking about so that there is no confusion.
    Ok, with CanGetFocus it is possible to remove a lot of these not needed properties. There are a few left, which I don't need, since my container is not really visible for the user at runtime, so following properties are kind of obsolete:
    • DragIcon
    • DragMode
    • ToolTipText
    • WhatsThisHelpID


    These 4 properties are not such a big deal anymore. But if there is a way to get rid of them, please let me know.

    The rest of the properties is ok:
    • Height
    • Index
    • Left
    • Tag
    • Top
    • Visible
    • Width

  32. #32
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    Ok, with CanGetFocus it is possible to remove a lot of these not needed properties. There are a few left, which I don't need, since my container is not really visible for the user at runtime, so following properties are kind of obsolete:
    • DragIcon
    • DragMode
    • ToolTipText
    • WhatsThisHelpID


    These 4 properties are not such a big deal anymore. But if there is a way to get rid of them, please let me know.

    The rest of the properties is ok:
    • Height
    • Index
    • Left
    • Tag
    • Top
    • Visible
    • Width
    As I mentioned earlier, they are out of your control, you have no way of adding/removing design/runtime properties exposed by the extender object.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  33. #33

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Hello LaVolpe, thank you for all your help.
    I think my subclasser is almost done now. Please feel free to check the latest version, which I attached to this post.

    Just a few more questions:

    * What means "Copyright free, use and abuse as you see fit." in detail? - I don't understand "as you see fit".

    * I did implement the properties "ContainedControls" (as ContainedControls) and "SubclassedObjects" (as Collection) as properties, like UserControl.ContainedControls is doing it. - But I am not sure, if I should use a Method instead. What would you say?
    Is UserControl.ContainedControls a read only property?

    * Is there a way to iterate over all forms in a project?
    Attached Files Attached Files
    Last edited by NeedHelp!; Mar 8th, 2010 at 08:19 AM.

  34. #34
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    * What means "Copyright free, use and abuse as you see fit." in detail? - I don't understand "as you see fit".
    I use this term occassionally too. It simply means modify it as desired.
    Quote Originally Posted by NeedHelp! View Post
    * I did implement the properties "ContainedControls" (as ContainedControls) and "SubclassedObjects" (as Collection) as properties, like UserControl.ContainedControls is doing it. - But I am not sure, if I should use a Method instead. What would you say?
    Use whichever fits your logic best. Personal preferences really. I tend to never expose a collection to the user for fear that user will accidentally clear it or modify it in ways I did not intend. In those cases, I will add properties/methods to allow the user to get/set a collection item, but not the entire collection. If this method/property is only exposed to your control and never to the user, use whichever is easiest for you.
    Quote Originally Posted by NeedHelp! View Post
    Is UserControl.ContainedControls a read only property?
    Yes.
    Quote Originally Posted by NeedHelp! View Post
    * Is there a way to iterate over all forms in a project?
    If the control is never developed/compiled as a separate ocx, you should be able to use VB's Forms collection, i.e., "For Each Frm In Forms" and then use the .Controls collection within each form. However, if it is compiled to an ocx, the form's collection will be relative to the ocx, not the project the ocx is hosted in.

    Also, this could be problematic too. How are you going to know if a new form is loaded or not? It is possible with message hooks (SetWindowsHookEx) and/or timers to test for new window creation, then check to see if the window's class is a VB form object or not.
    Last edited by LaVolpe; Mar 8th, 2010 at 08:12 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  35. #35

    Thread Starter
    Lively Member
    Join Date
    Sep 2009
    Posts
    95

    Re: UserControl ScaleMode issue

    Quote Originally Posted by LaVolpe View Post
    I use this term occassionally too. It simply means modify it as desired.
    Good. Just because I am interested: is this proper English or more slang style?

    Use whichever fits your logic best. Personal preferences really.
    I think a Method would be better, since it is read only.
    But I will stay with the property, since UserControl.ContainedControls is also one.

    I tend to never expose a collection to the user for fear that user will accidentally clear it or modify it in ways I did not intend.
    Well, I did use following code, so the changes made by the coder will not effect the stability of my control:

    Code:
    Public Property Get SubclassedObjects() As Collection
        Dim colReturn As New Collection
        Dim oObj As Object
        
        For Each oObj In m_SubclassedObjects
            Call colReturn.Add(oObj)
        Next oObj
        
        Set SubclassedObjects = colReturn
    End Property
    Ok, maybe the coder thinks, that he can change subclassing by just adding/deleting items to/from the collection (which will have no effect).

    In those cases, I will add properties/methods to allow the user to get/set a collection item, but not the entire collection.
    That is also a good way, but I like to have a similar behaviour like UserControl.ContainedControls or Form1.Controls.
    Is there a way to turn a collection into a ContainedControls type an return this?

    If the control is never developed/compiled as a separate ocx, you should be able to use VB's Forms collection, i.e., "For Each Frm In Forms" and then use the .Controls collection within each form. However, if it is compiled to an ocx, the form's collection will be relative to the ocx, not the project the ocx is hosted in.
    Ok, this was a general question, which had nothing to do with my control.
    But I have to load all forms before I can loop through them with Forms, right?
    Is there another way, without loading them first? (I guess not...)

    Also, this could be problematic too. How are you going to know if a new form is loaded or not? It is possible with message hooks (SetWindowsHookEx) and/or timers to test for new window creation, then check to see if the window's class is a VB form object or not.
    Ok, since this was not my intension, I won't have to do that. But wouldn't I get also Windows from other VB projects, if I would do it in this way?

  36. #36
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: UserControl ScaleMode issue

    Quote Originally Posted by NeedHelp! View Post
    ...
    Ok, this was a general question, which had nothing to do with my control.
    But I have to load all forms before I can loop through them with Forms, right?
    Is there another way, without loading them first? (I guess not...)
    You answered your own question

    Quote Originally Posted by NeedHelp! View Post
    ...Ok, since this was not my intension, I won't have to do that. But wouldn't I get also Windows from other VB projects, if I would do it in this way?
    You answered your own question again. Depending on what you use, a hook for example can be process/thread specific, so you wouldn't get other VB project's windows, but a timer would. Again, depending on the method you use, you could get other window creations too, like message boxes, inputboxes, all controls on a newly loaded form and more. You would have to test the window class against known VB Form classes (normal form & mdi form). And VB form classes are different, named different, when forms are compiled and uncompiled. If using a timer, you'd also have to check that the new hWnd you discovered is, in fact, associated with the same process/thread that your ocx's container is attached too.
    Last edited by LaVolpe; Mar 12th, 2010 at 12:38 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

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