Results 1 to 7 of 7

Thread: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Hello, I want to solve the following, I have a usercontrol Windowless = true, and I want to be able to receive the arrow keys and not lose focus, the arrow keys act as the tabular key with this type of control, I think the way to do this It's through IOleInPlaceActiveObject, but I didn't know how to apply it, maybe someone can give me a hand or know of some other method.

    Example.zip
    leandroascierto.com Visual Basic 6 projects

  2. #2

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Hello, I think it's already solved, I'll leave it here in case someone wants to review it and leave their opinion, my knowledge are not very advanced with IPAO, but I tried to adjust it to my needs, at least it doesn't seem to crash.

    too bad it depends on ole.tlb

    Example2.zip
    leandroascierto.com Visual Basic 6 projects

  3. #3
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Quote Originally Posted by LeandroA View Post
    ...too bad it depends on ole.tlb
    You can solve this easy enough in a Windowless-Control via:
    - internal, WithEvents-based Self-SubClassing
    - on the UCs own Extender-Object
    - to receive the Validate-Event (which offers a Cancel-Param to prevent Focus-changes)

    The only thing with this simple approach that is not "straight forward" is:
    - that holding an internal ObjRef to the UCs own Extender
    - will definitely produce a cyclic reference
    - and thus the UC "wouldn't die" when it gets unloaded

    Therefore we have to remove the Reference to the internal "Withevents Ext-Variable",
    when the Control gets "un-sited" from its container (e.g. via Controls.Remove ...)

    Sadly the VB6-UC-implementation does not signal this directly -
    but an already established workaround for UC-devs is, to use UserControl_Hide as an alternative -
    (because this is called at "remove-time" as well).

    Here is complete code for your own experiments with a little ucWindowLess:
    Code:
    Option Explicit 'Demo which prevents ArrowKey-based Focus-changes in windowless Controls (O.Schmidt 2010)
    
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
    
    Private m_Focused As Boolean, WithEvents Ext As VBControlExtender
    
    'the following 3 EventHandlers take care of "Extender-WithEvents-Subclassing without cycle-refs"
    Private Sub UserControl_Show() 'as soon as the Ctl becomes visible (again)...
      Set Ext = UserControl.Extender '<- we use its own Extender-Object for "Withevents-Subclassing"
    End Sub
    Private Sub UserControl_Hide() 'this is called when the Ctl unloads (gets "un-sited")
      Set Ext = Nothing 'so let's make sure, to set the internal Ref to Nothing, to avoid a cycle-ref
    End Sub
    Private Sub Ext_Validate(Cancel As Boolean) 'simply set Cancel=True, to prevent Focus-loss in case of ArrowKeys
      Dim Shift As Integer
      If GetAsyncKeyState(vbKeyShift) And &H8000 Then Shift = Shift Or vbShiftMask
      If GetAsyncKeyState(vbKeyControl) And &H8000 Then Shift = Shift Or vbCtrlMask
      If GetAsyncKeyState(vbKeyMenu) And &H8000 Then Shift = Shift Or vbAltMask
    
      If GetAsyncKeyState(vbKeyLeft) And &H8000 Then Cancel = True: UserControl_KeyDown vbKeyLeft, Shift
      If GetAsyncKeyState(vbKeyRight) And &H8000 Then Cancel = True: UserControl_KeyDown vbKeyRight, Shift
      If GetAsyncKeyState(vbKeyUp) And &H8000 Then Cancel = True: UserControl_KeyDown vbKeyUp, Shift
      If GetAsyncKeyState(vbKeyDown) And &H8000 Then Cancel = True: UserControl_KeyDown vbKeyDown, Shift
    End Sub
    
    'the following 3 EventHandlers take care of "Focus-Rect-Drawing"
    Private Sub UserControl_GotFocus()
      m_Focused = True:  UserControl.Refresh
    End Sub
    Private Sub UserControl_LostFocus()
      m_Focused = False: UserControl.Refresh
    End Sub
    Private Sub UserControl_Paint() 'visualize focus
      ScaleMode = vbPixels: Line (0, 0)-(ScaleWidth - 1, ScaleHeight - 1), IIf(m_Focused, vbGreen, vbBlue), B
    End Sub
     
    'and the internal UserControl-Keydown (which is now able to receive ArrowKeys again - via Delegation from Ext_Validate)
    Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
      Debug.Print KeyCode, Shift
    End Sub
    HTH

    Olaf
    Last edited by Schmidt; Jan 30th, 2022 at 03:25 PM. Reason: Added UserControl_KeyDown support for ArrowKeys

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Excellent Olaf, very good trick, with this I save myself from using an extra module and a tlb, thank you very much

    I have not tested but I think another option is within GotFocus Set Ext = UserControl.Extender and in LostFocus release it.
    leandroascierto.com Visual Basic 6 projects

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    hello, I found a small problem, when there is only one control, the validate event is not produced since it does not leave the focus, the thing is that it does not receive a keydown event, really that there is only one control is something very rare, in specific cases you have to keep it in mind.
    leandroascierto.com Visual Basic 6 projects

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    441

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Well, I had also asked in foren.activevb.de to be able to release the TLB and master Frank Schüler took the trouble to write it, this module now helped me in my GridPlus control where for the OCX version I use UniTextBox.ctl, and at Being a single control on the grid, Olaf's solution was not valid for me, but it will work for the other controls, so I share Frank's modifications in case someone else needs it.

    VBC_IOleInPlaceActiveObject3.zip

    Thanks
    leandroascierto.com Visual Basic 6 projects

  7. #7
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    Re: Usercontrol Windowless + arrow keys (IOleInPlaceActiveObject?)

    Krool's VBCCR project implements IPAO for the numerous controls in the pack and the implementation is battle tested with a lot of edge cases coming up through the years.

    I would certainly take a peek at his implementation because vbAccelerator's IPAO is bug ridden -- at least current SetIPAO function certainly looks fishy.

    cheers,
    </wqw>

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