dcsimg
Page 61 of 61 FirstFirst ... 115158596061
Results 2,401 to 2,425 of 2425

Thread: CommonControls (Replacement of the MS common controls)

  1. #2401

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by Karl77 View Post
    That's now logical to me, because the list gets populated before the UC can read the property.
    And after I set the ExcludeList property there is not function to recreate the list.
    So no need to check on this.


    That seems to be the only correct way to me, and not a workaround.
    Because the EnumFontFunction runs twice as you explained, it makes no sense to do the exclusion in that place.

    Could you make a very short example on how to CB_DELETESTRING from the Combobox?
    I fear to destroy the order when certain items get deleted.

    Thank you for that.
    I can't code right now. It's just illustration and not tested. But it should give you the idea.

    Code:
    With FontCombo1
    Do
      bDelete = False
      For i = 0 To .ListCount - 1
        If .List(i) = strExcludeList Then
          SendMessage .hWnd, CB_DELETESTRING, i, ByVal 0&
          bDelete = True
          Exit For
        End If
      Next i
    Loop Until bDelete = False
    End With

  2. #2402
    Hyperactive Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    293

    Re: Run-time-error ī429ī ActiveX component canīt create object

    Quote Originally Posted by AAraya View Post
    Did you ever discover the cause of this? I'm having what I believe is a similar issue. Upon launching my application, two users both report a msgbox window with title "VBCCR16" and a message of "Run-time error 0". When they click OK they get a Run-time-error 429. And my app never appears. This is my first app I've deployed with VBCCR16 so any support tips for dealing with these issues would be appreciated!
    As an update for any others who may encounter this problem. I replace hundreds of 32-bit icons with 24-bit icons in my app but it did not resolve the problem.

    Three of my users were having this issue. One had Vista and two had Win 7 which had not had all updates installed. When the Windows 7 computer was updated, the VBCCR16 "run-time error 0" issue no longer happens.

    Hope this saves someone a bunch of time chasing down other possibilities.

  3. #2403
    Junior Member
    Join Date
    Nov 2015
    Posts
    29

    Re: Run-time-error ī429ī ActiveX component canīt create object

    Quote Originally Posted by AAraya View Post
    When the Windows 7 computer was updated, the VBCCR16 "run-time error 0" issue no longer happens.

    What specifically was updated? What changed? Thanks

  4. #2404
    Hyperactive Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    293

    Re: Run-time-error ī429ī ActiveX component canīt create object

    Quote Originally Posted by DaveInCaz View Post
    What specifically was updated? What changed? Thanks
    The Windows 7 OS was updated. No idea exactly which patch(es) resolved this issue. These are end-users, not computer engineers. They didn't go one-by-one, install update, test, install update, test. They just let Windows install all needed OS updates that hadn't been applied yet.
    Last edited by AAraya; Oct 1st, 2019 at 08:18 AM.

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

    Re: CommonControls (Replacement of the MS common controls)

    This is for Krool. Others may want to experiment.

    Background: When a DPI-aware project is loaded into non-integral DPI (my own term), 175%, 200%, etc, where VB's twipsPerPixel (TPP) is not the same as the system's (1440 / realDPI) <> VB's TPP, then OCXs have problems. An ocx for simplicity: any control that is not a VB intrinsic control.

    Problem: The ocx does not draw into the full width/height of the ocx, it draws smaller than expected. This is directly related to the TPP discrepancy.

    Fix when resizing ocxs in this scenario: while sizing, also move the control +1 units Left & Top, then re-move the control -1 units left and top. Though this does address the problem, it still fails when an OCX has an Align property that is set to other than vbAlignNone (zero). You can try with common controls progressbar and set its Align property to non-zero. Again project must be DPI-aware and loaded into 175% DPI or similar non-integral DPI

    Ultimate fix is to send the control the dimensions of itself as pixels via an Interface method. That addresses the problem whether the ocx is aligned or not. This requires a bit of low-level API calls, if no TLB for that interface. We would call that interface method each time the form is resized because resizing the form changes the ocx dimensions when Align is non-zero.

    Here is some sample code that can be used from the parent/form of an ocx. It should be called from within the Form_Resize event for ocxs that have an Align property set to non-zero.
    Code:
    Private Declare Function DispCallFunc Lib "oleaut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As Long, ByVal paValues As Long, ByRef retVAR As Variant) As Long
    Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, ByVal lpiid As Long) As Long
    
    Public Sub SyncOcxClientToParent(theControl As Control)
    
        ' This can be called in any DPI, but for for non-intrinsic controls, should always
        ' be called in non-integral DPI. In that case, external OCXs (not VB
        ' intrinsic controls) may not render to the full bounds of the control. This method
        ' attempts to fix that. It should only be called for non-intrinsic controls and
        ' after the control is sized. 
    
        Dim oIUnk As IUnknown, oObj As Object, frm As Form
        Dim vParamPtr(0 To 1) As Long, vParamType(0 To 1) As Integer
        Dim vRtn As Variant, vParams(0 To 1) As Variant
        Dim aData(0 To 3) As Long
        Dim hWnd As Long, sm As ScaleModeConstants
        Const IID_IOleInPlaceObject = "{00000113-0000-0000-c000-000000000046}"
        Const IOIP_SetRects As Long = 28&
    
        On Error Resume Next
        Set oObj = theControl.object
        If Err Then
            Err.Clear
        Else
            Set frm = theControl.Parent
            If Err Then                     ' applies to forms only
                Err.Clear: Set oObj = Nothing
            Else
                sm = theControl.Container.ScaleMode
                If Err Then
                    Err.Clear: sm = vbTwips
                End If
            End If
        End If
        On Error GoTo 0
        
        If oObj Is Nothing Then Exit Sub
        
        IIDFromString StrPtr(IID_IOleInPlaceObject), VarPtr(aData(0))
        ' set up call to DispCallFunc for querying for IID_IOleInPlaceObject
        vParams(0) = VarPtr(aData(0)): vParams(1) = VarPtr(oIUnk)
        vParamType(0) = vbLong: vParamType(1) = vbLong
        vParamPtr(0) = VarPtr(vParams(0)): vParamPtr(1) = VarPtr(vParams(1))
        ' does object implement IID_IOleInPlaceObject?
        DispCallFunc ObjPtr(oObj), 0&, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
        If oIUnk Is Nothing Then
            With theControl
                .Move .Left + frm.ScaleX(1, vbPixels, sm), .Top + frm.ScaleX(1, vbPixels, sm)
                .Move .Left - frm.ScaleX(1, vbPixels, sm), .Top - frm.ScaleX(1, vbPixels, sm)
            End With
        Else
            aData(0) = frm.ScaleX(theControl.Left, sm, vbPixels)
            aData(1) = frm.ScaleX(theControl.Top, sm, vbPixels)
            aData(2) = aData(0) + frm.ScaleX(theControl.Width, sm, vbPixels)
            aData(3) = aData(1) + frm.ScaleX(theControl.Height, sm, vbPixels)
            vParams(1) = VarPtr(aData(0))
            DispCallFunc ObjPtr(oIUnk), IOIP_SetRects, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
        End If
        Set oObj = Nothing: Set oIUnk = Nothing: Set frm = Nothing
    
    End Sub
    Now, the above should work in most cases, but can still fail when multiple aligned controls are stacked on each other. Multiple sizing events may occur that undoes the call to SyncOcxClientToParent. In that case, you need a delay. For example, use a disabled timer with a short interval and when Form_Resize kicks off, enable the timer. When the timer kicks off, disable it, and call SyncOcxClientToParent for the affected controls.

    For Krool: The above code is for an external call. I'd imagine you can fix your own CCR controls using the same logic. However, here's some things to consider:

    1. That sample code needs the UC's position/dimensions from the container's point of view and translated to pixels relative to the form's client area. Consider using the UC's Extender. You can't use GetWindowRect on the UC.hWnd because it will return the wrong dimensions. Actually, you could but would need to scale it by the difference in VB TPP vs real TPP. But not all UCs have hWnds (windowless).

    2. The interface method expects two rectangles. Both are identical, so use the same pointer: VarPtr(udtRect)

    3. If you are using TLBs, may want to include IOleInPlaceObject. Doing so should negate the DispCallFunc, IIDFromString calls along with the variables used for those calls.

    4. From trial and error. Calling the interface method should be done whenever the control resizes, after it resizes, i.e., trap WM_SIZE if possible. If no subclassing is in play, see if Usercontrol_Resize will be good enough & if not, maybe a timer delay method like described earlier.

    Questions? PM me.
    Last edited by LaVolpe; Oct 1st, 2019 at 06:16 PM. Reason: typos
    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}

  6. #2406
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    446

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by Krool View Post
    I can't code right now. It's just illustration and not tested. But it should give you the idea.

    Code:
    With FontCombo1
    Do
      bDelete = False
      For i = 0 To .ListCount - 1
        If .List(i) = strExcludeList Then
          SendMessage .hWnd, CB_DELETESTRING, i, ByVal 0&
          bDelete = True
          Exit For
        End If
      Next i
    Loop Until bDelete = False
    End With
    Perfect, thank you.
    I implemented it in the UC directly.

  7. #2407

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Response to LaVolpe's post:

    As preparation I included now IOleInPlaceObject in the OLEGuids.tlb.
    In a second update then all the UC's will be updated. It needs time and to test everything out.

    ---

    PS: The ComCtlsDemo in the thread's first post is now only as .zip and not anymore with .docx extension. This was now possible as the VBForums file size limit has been increas for ZIP to 1,024,000.

  8. #2408

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Criticial bug for the OLEGuids.tlb.
    The recent modification - few hours ago - included interface IOleInPlaceObject.
    However, it was defined as:
    Code:
    interface IOleInPlaceObject : IUnknown
    But should have been
    Code:
    interface IOleInPlaceObject : IOleWindow
    This is now fixed. If anyone replaced OLEGuids.tlb just recently please do again.
    If not replaced again now it's not an issue "right now" but may become in future an issue.

    Sorry for the inconvinience caused.

  9. #2409

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by LaVolpe View Post
    This is for Krool. Others may want to experiment.

    Background: When a DPI-aware project is loaded into non-integral DPI (my own term), 175%, 200%, etc, where VB's twipsPerPixel (TPP) is not the same as the system's (1440 / realDPI) <> VB's TPP, then OCXs have problems. An ocx for simplicity: any control that is not a VB intrinsic control.

    Problem: The ocx does not draw into the full width/height of the ocx, it draws smaller than expected. This is directly related to the TPP discrepancy.

    Fix when resizing ocxs in this scenario: while sizing, also move the control +1 units Left & Top, then re-move the control -1 units left and top. Though this does address the problem, it still fails when an OCX has an Align property that is set to other than vbAlignNone (zero). You can try with common controls progressbar and set its Align property to non-zero. Again project must be DPI-aware and loaded into 175% DPI or similar non-integral DPI

    Ultimate fix is to send the control the dimensions of itself as pixels via an Interface method. That addresses the problem whether the ocx is aligned or not. This requires a bit of low-level API calls, if no TLB for that interface. We would call that interface method each time the form is resized because resizing the form changes the ocx dimensions when Align is non-zero.

    Here is some sample code that can be used from the parent/form of an ocx. It should be called from within the Form_Resize event for ocxs that have an Align property set to non-zero.
    Code:
    Private Declare Function DispCallFunc Lib "oleaut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As Long, ByVal paValues As Long, ByRef retVAR As Variant) As Long
    Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As Long, ByVal lpiid As Long) As Long
    
    Public Sub SyncOcxClientToParent(theControl As Control)
    
        ' This can be called in any DPI, but for for non-intrinsic controls, should always
        ' be called in non-integral DPI. In that case, external OCXs (not VB
        ' intrinsic controls) may not render to the full bounds of the control. This method
        ' attempts to fix that. It should only be called for non-intrinsic controls and
        ' after the control is sized. 
    
        Dim oIUnk As IUnknown, oObj As Object, frm As Form
        Dim vParamPtr(0 To 1) As Long, vParamType(0 To 1) As Integer
        Dim vRtn As Variant, vParams(0 To 1) As Variant
        Dim aData(0 To 3) As Long
        Dim hWnd As Long, sm As ScaleModeConstants
        Const IID_IOleInPlaceObject = "{00000113-0000-0000-c000-000000000046}"
        Const IOIP_SetRects As Long = 28&
    
        On Error Resume Next
        Set oObj = theControl.object
        If Err Then
            Err.Clear
        Else
            Set frm = theControl.Parent
            If Err Then                     ' applies to forms only
                Err.Clear: Set oObj = Nothing
            Else
                sm = theControl.Container.ScaleMode
                If Err Then
                    Err.Clear: sm = vbTwips
                End If
            End If
        End If
        On Error GoTo 0
        
        If oObj Is Nothing Then Exit Sub
        
        IIDFromString StrPtr(IID_IOleInPlaceObject), VarPtr(aData(0))
        ' set up call to DispCallFunc for querying for IID_IOleInPlaceObject
        vParams(0) = VarPtr(aData(0)): vParams(1) = VarPtr(oIUnk)
        vParamType(0) = vbLong: vParamType(1) = vbLong
        vParamPtr(0) = VarPtr(vParams(0)): vParamPtr(1) = VarPtr(vParams(1))
        ' does object implement IID_IOleInPlaceObject?
        DispCallFunc ObjPtr(oObj), 0&, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
        If oIUnk Is Nothing Then
            With theControl
                .Move .Left + frm.ScaleX(1, vbPixels, sm), .Top + frm.ScaleX(1, vbPixels, sm)
                .Move .Left - frm.ScaleX(1, vbPixels, sm), .Top - frm.ScaleX(1, vbPixels, sm)
            End With
        Else
            aData(0) = frm.ScaleX(theControl.Left, sm, vbPixels)
            aData(1) = frm.ScaleX(theControl.Top, sm, vbPixels)
            aData(2) = aData(0) + frm.ScaleX(theControl.Width, sm, vbPixels)
            aData(3) = aData(1) + frm.ScaleX(theControl.Height, sm, vbPixels)
            vParams(1) = VarPtr(aData(0))
            DispCallFunc ObjPtr(oIUnk), IOIP_SetRects, 4&, vbLong, 2, VarPtr(vParamType(0)), VarPtr(vParamPtr(0)), vRtn
        End If
        Set oObj = Nothing: Set oIUnk = Nothing: Set frm = Nothing
    
    End Sub
    Now, the above should work in most cases, but can still fail when multiple aligned controls are stacked on each other. Multiple sizing events may occur that undoes the call to SyncOcxClientToParent. In that case, you need a delay. For example, use a disabled timer with a short interval and when Form_Resize kicks off, enable the timer. When the timer kicks off, disable it, and call SyncOcxClientToParent for the affected controls.

    For Krool: The above code is for an external call. I'd imagine you can fix your own CCR controls using the same logic. However, here's some things to consider:

    1. That sample code needs the UC's position/dimensions from the container's point of view and translated to pixels relative to the form's client area. Consider using the UC's Extender. You can't use GetWindowRect on the UC.hWnd because it will return the wrong dimensions. Actually, you could but would need to scale it by the difference in VB TPP vs real TPP. But not all UCs have hWnds (windowless).

    2. The interface method expects two rectangles. Both are identical, so use the same pointer: VarPtr(udtRect)

    3. If you are using TLBs, may want to include IOleInPlaceObject. Doing so should negate the DispCallFunc, IIDFromString calls along with the variables used for those calls.

    4. From trial and error. Calling the interface method should be done whenever the control resizes, after it resizes, i.e., trap WM_SIZE if possible. If no subclassing is in play, see if Usercontrol_Resize will be good enough & if not, maybe a timer delay method like described earlier.
    This seems not to be an issue because when the control moves +1 units Left & Top, then re-move -1 units left and top adresses the issue properly when done within UserControl_Resize.
    However, I will consider using IOleInPlaceObject::SetObjectRects as this will move the control once instead of twice. (Small benefit)
    Also it looks better, rather a direct fix instead a strange looking workaround.
    LaVolpe confirmed it.

  10. #2410

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by LaVolpe View Post
    1. That sample code needs the UC's position/dimensions from the container's point of view and translated to pixels relative to the form's client area. Consider using the UC's Extender. You can't use GetWindowRect on the UC.hWnd because it will return the wrong dimensions. Actually, you could but would need to scale it by the difference in VB TPP vs real TPP. But not all UCs have hWnds (windowless).
    To assume VB.Form as control's container is not secure. It could be nested within another UserControl.
    I liked the idea to use GetWindowRect and correct accordingly VB TPP vs real TPP. However, as you mention, it's not possible for windowless controls. (e.g. LabelW)

    So, I come up with this function below. It seems to work. Can you review/comment and/or confirm?
    removed

    In this context I noticed that in the DPICorrectionFactor common function was a flaw. It should be:
    Code:
    Public Function DPICorrectionFactor() As Single
    Static Done As Boolean, Value As Single
    If Done = False Then
        Value = ((96 / DPI_X()) * 15) / Screen.TwipsPerPixelX
        Done = True
    End If
    ' Returns exactly 1 when no corrections are required.
    DPICorrectionFactor = Value
    End Function
    instead of
    Code:
    Public Function DPICorrectionFactor() As Single
    Static Done As Boolean, Value As Single
    If Done = False Then
        Value = Screen.TwipsPerPixelX / ((96 / DPI_X()) * 15)
        Done = True
    End If
    ' Returns exactly 1 when no corrections are required.
    DPICorrectionFactor = Value
    End Function
    So currently the Factor must be divided. Which is odd, because a Factor means by definition always multiplication from a result.

    I wait a little bit before doing something ..
    Last edited by Krool; Oct 8th, 2019 at 02:47 PM.

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

    Re: CommonControls (Replacement of the MS common controls)

    @Krool, we we're talking about the Align property. A control cannot have it set to other than vbAlignNone if the form is not its container. That is correct, isn't it?

    In that code, the form was located to use ScaleX,ScaleY. The scalemode of the control's parent was retrieved from theControl.Container.

    And non-integral TPP/DPI only needs to compare the system DPI to the form's TPP, if project is system aware or better. VB can only be loaded into system DPI or virtual 100% DPI.
    Last edited by LaVolpe; Oct 7th, 2019 at 06:22 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}

  12. #2412

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by LaVolpe View Post
    @Krool, we we're talking about the Align property. A control cannot have it set to other than vbAlignNone if the form is not its container. That is correct, isn't it?

    In that code, the form was located to use ScaleX,ScaleY. The scalemode of the control's parent was retrieved from theControl.Container.

    And non-integral TPP/DPI only needs to compare the system DPI to the form's TPP, if project is system aware or better. VB can only be loaded into system DPI or virtual 100% DPI.
    The fix to sync the object rect is always necessary regardless of Align property. Right?
    If the new fix should only be used for <> vbAlignNone than I can keep the current implementation and change nothing? Sounds easier for me..
    My attempt was now to get rid of the double resizing and only fix resize once for all cases.

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

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by Krool View Post
    The fix to sync the object rect is always necessary regardless of Align property. Right?
    Yes, if (1440 / Screen.TwipsPerPixelX) <> (1440 \ Screen.TwipsPerPixelX)

    However, and this may not apply to you, but maybe it does. With Win10, one could load forms into different DPI awareness contexts. This means on one form with your controls can be running in per-monitor awareness, while in another form they run in system awareness and in yet in another they run as unaware. In all three cases VB's TwipsPerPixel values do not change. Those values are set when VB initially loads and do not change for the life of the project. When forms are run in a different awareness than what the project loaded into, it has an affect on UCs/OCXs similar to running @ 175% DPI in some cases. I've just discovered that yesterday and am still trying to understand when/why it happens so it can be addressed. I'll follow up once I know more details.
    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}

  14. #2414

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by LaVolpe View Post
    Yes, if (1440 / Screen.TwipsPerPixelX) <> (1440 \ Screen.TwipsPerPixelX)

    However, and this may not apply to you, but maybe it does. With Win10, one could load forms into different DPI awareness contexts. This means on one form with your controls can be running in per-monitor awareness, while in another form they run in system awareness and in yet in another they run as unaware. In all three cases VB's TwipsPerPixel values do not change. Those values are set when VB initially loads and do not change for the life of the project. When forms are run in a different awareness than what the project loaded into, it has an affect on UCs/OCXs similar to running @ 175% DPI in some cases. I've just discovered that yesterday and am still trying to understand when/why it happens so it can be addressed. I'll follow up once I know more details.
    I understand.
    In logic I first need to fix the object rect to an system DPI aware state and the VB TPP vs real TPP bug within UserControl_Resize.
    I would skip per monitor awareness in that case.

    Then later in another step there could be a DPIMonitorVsSystemScaleFactor(...) which when <> 1 on WM_DPICHANGE_BEFOREPARENT then scale another time object rect accordingly with the current diff factor to system aware state.

    Agree?

    EDIT: maybe this was too easy thought. What happens when the control resizes again due to .Align? I don't know how the behavior is exactly. Maybe such a DPIMonitorVsSystemScaleFactor needs to be done already also within UserControl_Resize...

    It's a messy topic. Something in me tells just stick to system dpi awareness and just don't do a per monitor manifest.
    Even MS states in their memo about it that it still is in early stages where sometimes mixed-mode dpi awareness is necessary.
    So best IMO is to get system dpi aware done properly and don't loose the nerves for per monitor awareness.
    I don't find it bad when the OS bitmap stretches system dpi vs monitor dpi the applications. This at least ensures ecerything is in correct physical sizes.
    Last edited by Krool; Oct 8th, 2019 at 12:54 PM.

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

    Re: CommonControls (Replacement of the MS common controls)

    You can always ensure the user has access to graphical items so that they can change the scale if they want to, i.e., ensure fonts and images (that don't change automatically by the API window) are available to the user either via SendMessage and/or public UC properties. That might be a good workaround and allows users to make your control fully DPI aware.

    The biggest issue I have right now with per-monitor awareness is that not all API windows may support it. And when they do, is there any guarantee that what isn't scaled now won't be scaled in future versions (backward compatibility). It would also have been nice if Microsoft required WM_DPICHANGED_BEFOREPARENT to return non-zero if it DPI changes are going to be handled by the window.
    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. #2416

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    So I think I got my SyncObjectRectsToContainer now pretty straight forward without any cumbersum calculations.

    It now receives the border rect of the parent window where the object's window should be located. IOleInPlaceSite::GetWindowContext
    Together with IOleInPlaceObject::SetObjectRects it functions now as a perfect straight forward fix for the VB TPP vs real TPP bug.
    Or in other words: Apply the dimensions what the host reports to the client.

    Doesn't it look clean the new function? Works for all scenarios.
    Code:
    Public Sub SyncObjectRectsToContainer(ByVal This As Object)
    On Error GoTo CATCH_EXCEPTION
    Dim PropOleObject As OLEGuids.IOleObject
    Dim PropOleInPlaceObject As OLEGuids.IOleInPlaceObject
    Dim PropOleInPlaceSite As OLEGuids.IOleInPlaceSite
    Dim PosRect As OLEGuids.OLERECT
    Dim ClipRect As OLEGuids.OLERECT
    Dim FrameInfo As OLEGuids.OLEINPLACEFRAMEINFO
    Set PropOleObject = This
    Set PropOleInPlaceObject = This
    Set PropOleInPlaceSite = PropOleObject.GetClientSite
    PropOleInPlaceSite.GetWindowContext Nothing, Nothing, VarPtr(PosRect), VarPtr(ClipRect), VarPtr(FrameInfo)
    PropOleInPlaceObject.SetObjectRects VarPtr(PosRect), VarPtr(ClipRect)
    CATCH_EXCEPTION:
    End Sub
    LaVolpe: I wait your feedback until I release an update.
    The question remains. Should this new function be always called to ensrue integrity between host and client dimensions? Or only when DPICorrectionFactor() is <> 1 ? (DPICorrectionFactor is only system DPI; not per monitor)
    Last edited by Krool; Oct 9th, 2019 at 02:02 PM.

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

    Re: CommonControls (Replacement of the MS common controls)

    Don't wait too long for feedback. You are using some interfaces and methods I have never played with. I'm interested in it as it does look like it should be a better option than using ScaleX,ScaleY and trying to get container scalemode, etc, that I was initially using.

    BTW, I did figure out in what scenarios mixing DPI awareness within a project would cause the OCX to not size correctly. It isn't just DPIs like 175%. The logic looks like this: If 1440 / GetDpiForSystem <> Screen.TwipsPerPixel. At 175%, 200% DPI, that calculation returns not equal. And when mixed awareness is in play, the calculation appears to work perfectly. When that calculation returns not equal, then sync is needed else is not. This is just FYI for you. I don't know if you plan on calling your new SyncObjectRectsToContainer during every resize or not. Prior to Win8.1, the old calculation will work just fine.

    Tip: GetDpiForSystem is for Win10,v1607 or better. Need to use GetProcessAwareness for Win8.1 to Win10 before v1607.

    Just saw your edited question. That's kinda tough. Right now, I know of two specific/different scenarios that cause DPICorrectionFactor<>1. Will there be more in future Win10 updates. If your new function does not trigger extra resize events, maybe always call it, else only call it when DPICorrectionFactor<>1.
    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}

  18. #2418

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by LaVolpe View Post
    I don't know if you plan on calling your new SyncObjectRectsToContainer during every resize or not.
    That's the questions.. Should I just call SyncObjectRectsToContainer on every UserControl_Resize. My feeling says just call it when it's necessary.
    But what should be the condition when to call it? So that system DPI user or per Monitor DPI user will be happy and face no issues with the VBCCR.

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

    Re: CommonControls (Replacement of the MS common controls)

    Krool, I tried your new routine and converted it to TLB-less calls and tested that too. All looks good.

    In my tests, I chose only to sync when DPICorrectionFactor<>1 and it worked well.

    FYI: I re-ran your CCR project in that other DPI awareness scenario discussed earlier: Started VB in per-monitor & then loaded your test form as DPI unaware. The current method of moving the control twice worked there too. So I think that answers your question -- maybe just sync when DPICorrectionFactor<>1
    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. #2420

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Update released.

    New function SyncObjectRectsToContainer now in place for all controls to support non-integral DPI.
    For the end-user is no visible impact. Before it "works" and now it works. However, the number of resizes is reduced a lot for non-integral DPI.

  21. #2421

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Update released.

    Affected are all controls which has a Transparent property and set to True and also the app runs on non-integral DPI. (dpi-aware)
    The background most likely is black. A .Refresh fixes this issue but it's unfair when on integral DPI it's not necessary. So the developer is most likely not aware to call .Refresh after load.
    Thus now whenever UserControl_Resize is called the transparent background will be updated.

  22. #2422
    Addicted Member
    Join Date
    Aug 2016
    Posts
    174

    Re: CommonControls (Replacement of the MS common controls)

    EN_SETEVENTMASK value (although CCR's RichTextBox doesn't use it) is 1073 (&H431) or 1093 (&H445)? I am confused.

    Edited: EN_SETEVENTMASK should be 1093. I am confused on some pages by google search.

    internal const int EM_SCROLLCARET = (NativeMethods.WM_USER + 49);
    internal const int EM_SETEVENTMASK = (NativeMethods.WM_USER + 69);
    Last edited by DaveDavis; Oct 14th, 2019 at 10:33 PM.

  23. #2423

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,303

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by DaveDavis View Post
    EN_SETEVENTMASK value (although CCR's RichTextBox doesn't use it) is 1073 (&H431) or 1093 (&H445)? I am confused.

    Edited: EN_SETEVENTMASK should be 1093. I am confused on some pages by google search.

    internal const int EM_SCROLLCARET = (NativeMethods.WM_USER + 49);
    internal const int EM_SETEVENTMASK = (NativeMethods.WM_USER + 69);
    ?
    EM_SETEVENTMASK is used already.

  24. #2424
    Addicted Member
    Join Date
    Aug 2016
    Posts
    174

    Re: CommonControls (Replacement of the MS common controls)

    Quote Originally Posted by Krool View Post
    ?
    EM_SETEVENTMASK is used already.
    Sorry, I missed. CCR used during creation.

    I taught EM_SETEVENTMASK can do fast updating. But I have no evidence.

    Code:
    private int updating = 0;
    private int oldEventMask = 0;
    public void BeginUpdate() //Faster Updating
            {
                ++updating;
                if (updating <= 1)
                {                
                    const int EM_SETEVENTMASK = 0x445;
                    const int WM_SETREDRAW = 0xB;    
                    //Prevent the control from raising any events. This message returns the previous event mask.                         
                    oldEventMask = SendMessage(new HandleRef(this, base.Handle), EM_SETEVENTMASK, 0, 0); 
                    // Prevent the control from redrawing itself.
                    SendMessage(new HandleRef(this, base.Handle), WM_SETREDRAW, 0, 0); 
                }
            }
    
            public void EndUpdate() 
            {
    
                --updating;
                if (updating <= 0)
                {                
                    const int EM_SETEVENTMASK = 0x445; 
                    const int WM_SETREDRAW = 0xB;                
                    // Allow the control to redraw itself.
                    SendMessage(new HandleRef(this, base.Handle), WM_SETREDRAW, 1, 0); 
                    // Allow the control to raise event messages.
                    SendMessage(new HandleRef(this, base.Handle), EM_SETEVENTMASK, 0, oldEventMask); 
                }
            }
    Last edited by DaveDavis; Oct 15th, 2019 at 01:38 AM.

  25. #2425
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    2,327

    Re: CommonControls (Replacement of the MS common controls)

    So the TabStrip randomly stopped working today. Didn't make any changes to any control-related files. The tabs stopped displaying, and when I try to open the (Custom) property page, I get run-time error 0x80010108 'The object invoked has disconnected from its clients.' at which point VB freezes and has to be killed from a process manager. No idea where this could be coming from.
    I'm using it as a UserControl; added all needed files. It's been stable for years. A frame control also stopped drawing but deleting it and creating a new one fixed that issue; deleting and creating a new TabStrip however did not.

Page 61 of 61 FirstFirst ... 115158596061

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width