-
May 21st, 2014, 09:09 PM
#1
VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
As the title says, just an example for dynamic Menu and ToolBar-handling,
based on the Graphics-Classes (the Widget- and Form-Engine) of vbRichClient5.dll:
http://vbrichclient.com/#/en/Downloads.htm
The contained Modules of the Demo:
modMenuResources.bas
Code:
Option Explicit
'this function returns a dynamically created Menu as a JSON-String (which could be stored in a DB, or elsewhere)
Public Function ExampleMenuAsJSONString() As String
Dim Root As cMenuItem
Set Root = Cairo.CreateMenuItemRoot("MenuBar", "MenuBar")
AddFileMenuEntriesTo Root.AddSubItem("File", "&File")
AddEditMenuEntriesTo Root.AddSubItem("Edit", "&Edit")
AddEditMenuEntriesTo Root.AddSubItem("Disabled", "&Disabled", , False) 'just to demonstrate a disabled entry
AddExtrMenuEntriesTo Root.AddSubItem("Extras", "E&xtras")
AddHelpMenuEntriesTo Root.AddSubItem("Help", "&Help")
ExampleMenuAsJSONString = Root.ToJSONString
End Function
Public Sub AddFileMenuEntriesTo(MI As cMenuItem)
MI.AddSubItem "New", "&New", "Document-New"
MI.AddSubItem "Sep", "-"
MI.AddSubItem "Open", "&Open...", "Document-Open"
MI.AddSubItem "Save", "&Save", "Document-Save"
MI.AddSubItem "SaveAs", "&Save as...", "Document-Save-As"
MI.AddSubItem "Sep2", "-"
MI.AddSubItem "ExitApp", "E&xit Application", "Application-Exit"
End Sub
Public Sub AddEditMenuEntriesTo(MI As cMenuItem)
MI.AddSubItem "Cut", "C&ut", "Edit-Cut"
MI.AddSubItem "Copy", "&Copy", "Edit-Copy"
MI.AddSubItem "Paste", "&Paste", "Edit-Paste", CBool(Len(New_c.Clipboard.GetText))
MI.AddSubItem "Delete", "&Delete", "Edit-Delete"
MI.AddSubItem "Sep", "-" '<- a Menu-Separatorline-Definiton
MI.AddSubItem "Select all", "&Select all", "Edit-Select-All"
End Sub
Public Sub AddExtrMenuEntriesTo(MI As cMenuItem)
Dim SubMenuPar As cMenuItem, SubSubMenuPar As cMenuItem
MI.AddSubItem "Item1", "Menu-Item&1", "MenuIconKey1"
MI.AddSubItem "Item2", "Menu-Item&2", "MenuIconKey3", False
MI.AddSubItem "Item3", "-" '<- a Menu-Separatorline-Definiton
MI.AddSubItem "Item4", "&Menu-Item2 disabled", "MenuIconKey1", , True
Set SubMenuPar = MI.AddSubItem("Item5", "This pops up a &SubMenu", "MenuIconKey2")
'two entries into the SubMenu (as children of 'Item5' of the above Code-Block)
SubMenuPar.AddSubItem "SubItem1", "Caption SubItem1", "MenuIconKey1"
Set SubSubMenuPar = SubMenuPar.AddSubItem("SubItem2", "Caption SubItem2", "MenuIconKey2")
'and just 1 entry into the SubSubMenu (children of 'SubItem2' of the above Code-Block)
SubSubMenuPar.AddSubItem "SubSubItem1", "Caption SubSubItem1", "MenuIconKey1"
End Sub
Public Sub AddHelpMenuEntriesTo(MI As cMenuItem)
MI.AddSubItem "About", "&About", "About-Hint"
MI.AddSubItem "Sep", "-"
MI.AddSubItem "Index", "&Index...", "Help-Contents"
MI.AddSubItem "Find", "&Find...", "Edit-Find"
End Sub
and modToolBarResources.bas
Code:
Option Explicit
Public Sub CreateToolBarEntriesOn(ToolBar As cwToolBar)
ToolBar.AddItem "Home", "go-home", , , "normal Icon with 'IsCheckable = True'", , True
ToolBar.AddItem "Undo", "go-previous", , , "normal Icon"
ToolBar.AddItem "Redo", "go-next", , , "disabled Icon", False
ToolBar.AddItem "Search", "page-zoom", , ddDropDown, "Icon with DropDownArrow"
ToolBar.AddItem "Sep", , "-", , "Separator-Line"
ToolBar.AddItem "TxtItem1", , "TxtItem1", , "plain Text-Item"
ToolBar.AddItem "TxtItem2", "Document-Save-As", "TxtItem2", , "Text-Item with Icon"
ToolBar.AddItem "Sep2", , "-", , "Separator-Line"
ToolBar.AddItem "TxtItem3", , "TxtItem3", ddDropDown, "Text-Item with DropDown"
ToolBar.AddItem "TxtItem4", "Edit-Find", "TxtItem4", ddDropDown, "Text-Item with Icon and DropDown"
ToolBar.AddItem "Sep3", , "-", , "Separator-Line"
ToolBar.AddItem "TxtItem5", "Document-Open", "TxtItem5", ddCrumbBar, "Text-Item with Icon and CrumbBar-Style-DropDown"
ToolBar.AddItem "TxtItem6", , "TxtItem6", ddCrumbBar, "Text-Item with CrumbBar-Style-DropDown"
ToolBar.AddItem "TxtItem7", , "TxtItem7", , "plain Text-Item"
End Sub
... contain the lines of code which are needed, to construct and achieve the following output:
MenuBar-DropDown:
ToolBar-DropDown as the result of a DropArrow-Click (showing a dynamic PopUp-Menu):
The constructed Menus use String-Keys to refer to previously loaded Icon and Image-Resources -
and they can be serialized to JSON-Strings (storable in a DB for example).
Any imaginable modern Alpha-Image-Resource can be used, as e.g. *.png, *.ico - but also
(as shown in the Demo) *.svg and *.svgz Vector-Images.
The example is completely ownerdrawn and truly independent from any MS-Menu-APIs, so one
can adapt *anything* as needed (e.g. the shape of the dropdown-form, colors, fonts, etc.) -
though the Demo as it is tries for a moderate style, mimicking a Win7-look roughly (with some
slight differences I personally like, but the whole thing is adaptable as said).
The code which implements this Menu-System is contained in one 'cf'-prefixed cWidgetForm-class
(cfPopUp for the hWnd-based Popups) - accompanied by 6 additional 'cw'-prefixed cWidgetBase-derived Classes:
cwMenuBar + cwMenuBarItem for the Menu-Strip
cwMenu + cwMenuItem for the DropDown-menus
cwToolBar + cwToolBarItem for the simple ToolBar-Implementation
I post this example more with regards to those, who want to learn how to program Widgets using
the vbRichClient-lib...
The above mentioned cwSomething Classes are programmable very similar to a VB-UserControl
(internally the same Event-Set is provided with KeyDown, MouseMove, MouseWheel, MouseEnter/MouseLeave etc.)
E.g. the cwToolBar-WidgetClass has only 100 lines of code - and the cwToolBarItem only 130 -
that's quite lean for what it does and offer, when you compare that with the efforts needed,
when "fighting" with SubClassing and SendMessage Calls against e.g. the MS-CommonControls.
There's not a single Win-API-call throughout the implementation - but that's normal
for any framework, since they usually try to abstract from the underlying system.
The Menu- and ToolBar-Textrendering is Unicode-capable.
Have fun with it - here's the Zip-Download-Link: http://vbRichClient.com/Downloads/Me...oolbarDemo.zip
Olaf
Last edited by Schmidt; May 22nd, 2014 at 09:53 AM.
-
May 22nd, 2014, 06:55 AM
#2
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Nice, Olaf. Quick 'behavioural' report; when one presses ALT the first menu item is activated (as it should be) but the arrow-left/right keys do not do anything (like they should).
However, if one presses ALT, followed by 'ESC', the arrow-key behaviour functions correctly. Haven't had time to trouble-shoot the code for this as yet so thought I'd post in case you were aware of a quick fix, being the author....
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 09:36 AM
#3
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Nice, Olaf. Quick 'behavioural' report; when one presses ALT the first menu item is activated (as it should be) but the arrow-left/right keys do not do anything (like they should).
However, if one presses ALT, followed by 'ESC', the arrow-key behaviour functions correctly. Haven't had time to trouble-shoot the code for this as yet so thought I'd post in case you were aware of a quick fix, being the author....
Ok, thanks for the report... "quick-fix-applied now"... (just re-download).
The behaviour is only seen, because I wrote this Demo using cWidgetForm-Panels, and then
placed them on a normal VB-TopLevel-Form as the Host.
In case a cWidgetForm is used as the TopLevel-HostForm, then the mis-behaviour you've encountered is not happening.
Olaf
-
May 22nd, 2014, 03:38 PM
#4
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Working as expected, though I have observed some other quirks which I can report if you're interested?
For example, press ALT, and then press ALT-X. Notice that you now appear to have two 'active' menus (though, of course, only one actually is) i.e. two top-level menus now have the 'active' outline effect.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 04:36 PM
#5
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Working as expected, though I have observed some other quirks which I can report if you're interested?
For example, press ALT, and then press ALT-X. Notice that you now appear to have two 'active' menus (though, of course, only one actually is) i.e. two top-level menus now have the 'active' outline effect.
Ah thanks - fixed now as well - also encountered that whilst a Bar-Menu is already in dropped-down-state
(e.g. when the File-Menu is dropped down), that you couldn't activate another Top-Menu per accelerator-keys
(e.g.per <Alt>+<x>, to switch over from the dropped-down-FileMenu to the Extras-Menu).
Download with these newest fixes again from the same link...
Olaf
-
May 22nd, 2014, 05:04 PM
#6
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
I'll check it out...
I also noticed that when a sub-menu pops-up, the first item has the mouse-over effect even though the mouse isn't yet (and may never be) over that item. Looking at the code, I can see why this is; the line (from memory) about W.Focused or W.MouseOver is true because the first sub-menu item is focused as soon as the sub-menu's window is created, correct? Anyhow, perhaps the sub-menu window should remain un-activated until a mouse-over or key-press activates it? Just a thought.
More of a quirk in behaviour than something that creates a real problem although it could be argued that it is unclear to the user what will happen when they press the enter key since the mouse is over one menu item but the focus is on another. Hope that makes sense.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 05:13 PM
#7
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
I'll check it out...
I also noticed that when a sub-menu pops-up, the first item has the mouse-over effect even though the mouse isn't yet (and may never be) over that item. Looking at the code, I can see why this is; the line (from memory) about W.Focused or W.MouseOver is true because the first sub-menu item is focused as soon as the sub-menu's window is created, correct? Anyhow, perhaps the sub-menu window should remain un-activated until a mouse-over or key-press activates it? Just a thought.
More of a quirk in behaviour than something that creates a real problem although it could be argued that it is unclear to the user what will happen when they press the enter key since the mouse is over one menu item but the focus is on another. Hope that makes sense.
Makes sense perfectly - though not really a problem (IMO) - since when using the Mouse,
the Enter-Key will (with high probability) not be used - whilst when using the Keyboard for
Menu-Interaction, the behaviour could almost be considered "a feature" <g>.
Olaf
-
May 22nd, 2014, 05:35 PM
#8
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Indeed. When using the keyboard, the current behaviour is as expected since the pop-up doesn't appear until the user presses the right arrow key and, in that case, it is natural for the first sub-menu item to become 'active' since it's parent window is also active. Just thought I'd mention it anyway even though I know that you do not necessarily subscribe to the idea that Windows UI behaviour should be meticulously mimicked.
btw, not to side-track the thread but any news on that DirectDraw issue?
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 05:45 PM
#9
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Gah! Just noticed that latest version crashes when using the keyboard;
'path key has to start with the key of this item, which is; Menubar'
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 06:10 PM
#10
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Gah! Just noticed that latest version crashes when using the keyboard;
'path key has to start with the key of this item, which is; Menubar'
Oops, sorry - this is due to an enhancement on the cMenuItem.SubItemByPathKey method,
which now understands also PathKeys, which do not include the Key of the cMenuItem itself
(e.g. the Key of the RootObject doesn't have to be given anmyore in the newest, not yet
uploaded Version of the RichClient, which now supports both, the old mode and this new,
shorter notation)... the problem was, that I didn't switch back the Demo-Sources to the
older (longer) path-Keys after my tests.
I've re-uploaded the Demo with the older Path-Key-Notations, which the older RC5-version supports.
Olaf
-
May 22nd, 2014, 06:19 PM
#11
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Cool. Loving it that you can describe a hard crash as the result of an enhancement, btw; ever considered a career in politics
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 22nd, 2014, 07:17 PM
#12
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Cool. Loving it that you can describe a hard crash as the result of an enhancement, btw; ever considered a career in politics
Nah, an active SubClassing (as in cwMenu) can cause IDE-Crashes when unhandled COM-Errors are involved -
if you'd use the cf and cw-Classes from a Dll-Binary (I've copied the Classes as Private ones into this Demo,
to avoid vbWidgets.dll) - then you would have got a clean (debuggable) Error for the non-resolvable
(too short) Key, your current RC5 doesn't support yet.
Olaf
-
May 22nd, 2014, 08:47 PM
#13
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Actually, it was trying its best to allow me to debug the error (the IDE debug dialog did appear) but it crashed hard if I tried to take up its offer!
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 23rd, 2014, 05:29 AM
#14
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Actually, it was trying its best to allow me to debug the error (the IDE debug dialog did appear) but it crashed hard if I tried to take up its offer!
Just an attempt to explain the "why"...
... I get the same "hard freeze" here, when I cause an unhandled error in a routine
which in IDE-mode would jump to the line in question - but that attempt of the IDE will then
interact with the SubClassing in a way which is not healthy...
The SubClasser within RC5 (cSubClass) is already hardened for userplaced IDE-Breakpoints,
which it allows and survives - and it also has code in it, which survives IDE-StopButton presses -
where it doesn't offer a safety-nets yet, is direct jumping of the IDE to the place where an
unhandled Error "just happened" (in a context which involved an Event on a hWnd which was
subclassed).
And this latter problem becomes only apparent in (IDE-reachable) classes which use cSubClass -
and are not (yet) contained and used from a Dll. In our case this class is cwMenu, which is using
cSubClass to detect Non-Client-Area Mouseclicks (namely the Hosting-Forms Caption),
to be able to immediately hide the Popup-Window in this case...
Ok, but since cwMenu is the only WidgetClass in the whole vbWidgets-Project which uses internal
SubClassing - and since what it subclasses is not "mission-critical" - I've now built-in a switch which
simply disables the SubClassing when cwMenu is "exposed" as sourcecode in the IDE.
Uploaded a new version.
Olaf
-
May 23rd, 2014, 07:37 AM
#15
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Thanks for taking the time to explain.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 25th, 2014, 06:01 PM
#16
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Just took another look at this as I (and it's a personal thing) found that mouse-over behaviour on the sub-menus a little annoying. Anyway, I made these code changes to get the effect I prefer.
cwMenu
Code:
Private Sub ShowSubMenu(ByVal MenuItem As cwMenuItem, ByVal WithFocus As Boolean)
.
.
.
End If
Set mSubMenu = New cwMenu
mSubMenu.Widget.FontSize = MenuItem.Widget.FontSize
mSubMenu.InitAndShow MenuItem.Widget, WithFocus, MenuItem.SubMenuDS
End Sub
Public Sub InitAndShow(InitiatorWidget As cWidgetBase, WithFocus As Boolean, Optional DataSource As cMenuItem, Optional ByVal DirectionBehaviour As enmMenuPopUpPosition)
Dim MenuItem As cwMenuItem, PopupPosX As Single, PopupPosY As Single, MousePosX As Long, MousePosY As Long
.
.
.
If Not TypeOf mInitiatorWidget.object Is cwMenu Then
mInitiatorWidget.Root.BlockKeyEvents True, PopUp.Form
Set SC = New_c.SubClass
If App.LogMode Then SC.Hook mInitiatorWidget.Root.DialogFormHwnd
Else 'a SubMenu
If WithFocus And Widgets.Count Then Widgets(1).Widget.SetFocus
End If
End Sub
Private Sub W_BubblingEvent(Sender As Object, EventName As String, P1 As Variant, P2 As Variant, P3 As Variant, P4 As Variant, P5 As Variant, P6 As Variant, P7 As Variant)
Dim SW As cWidgetBase
.
.
.
Case "ShowSubMenu"
Set mActiveMenuItem = Sender
ShowSubMenu P1, False
End Select
' Debug.Print "W_BubblingEvent", MenuItemKeyPath
End Sub
Public Sub KeyDown(KeyCode As Integer, Shift As Integer)
.
.
.
Case vbKeyRight
If Not MItem Is Nothing Then
If MItem.Widget.Enabled And Not MItem.SubMenuDS Is Nothing Then
ShowSubMenu MItem, True
Exit Sub
End If
End If
.
.
.
cwMenuBarItem
Code:
Public Sub ShowPopUp()
.
.
.
MenuBar.CurPopUp.Widget.FontSize = W.FontSize
MenuBar.CurPopUp.InitAndShow W, True, mDataSource, PopupBehaviourDropDownLeftAligned
End Sub
fTest
Code:
Private Sub ToolBar_ArrowClick(Sender As cwToolBarItem)
Dim PopupRoot As cMenuItem
Set PopupRoot = Cairo.CreateMenuItemRoot("PopUp", "PopUp")
AddEditMenuEntriesTo PopupRoot
Set PopUp = New cwMenu
PopUp.InitAndShow Sender.Widget, True, PopupRoot, PopupBehaviourDropDownRightAligned
End Sub
I think that's all the changes - if I missed one here and there I'm pretty sure that it's obvious what I've done. And maybe you won't even like it anyway!
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
May 26th, 2014, 08:55 AM
#17
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Thanks Colin,
the behaviour makes more sense this way, so I've updated the Demo-project in this thread appropriately
(just re-download again).
Though I've changed the position of the 'WithFocus' Param to the end of the Public Methods (as an optional
Param), to not break applications which might already use the Menu-Classes from vbWidgets.dll.
(I keep the cwMenu-stuff from this Demo here in sync with vbWidgets.dll).
Olaf
-
May 26th, 2014, 09:08 AM
#18
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by Schmidt
Though I've changed the position of the 'WithFocus' Param to the end of the Public Methods (as an optional
Param), to not break applications which might already use the Menu-Classes from vbWidgets.dll.
Oops, yes, should've thought of that...
btw, just noticed that it is still a little imperfect; when moving the mouse off of a sub-menu and returning it to it's parent menu, the mouse effect remains on the sub-menu (which it shouldn't). Easily fixed if it's possible to make the 'just-departed' cwMenuItem lose its 'focused' state?
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 10:36 AM
#19
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Been playing around a bit more with this to get more 'compliance' with conventional menus mouse behaviour; just a few small changes and I think it's there:
cwMenuItem:
Code:
'New module-level declaration
Private mDeactivatedViaMouseLeave As Boolean
'New Property
Public Property Get IsActive() As Boolean
IsActive = W.MouseOver Or (W.Focused And Not mSubMenuDS Is Nothing) Or (W.Focused And Not mDeactivatedViaMouseLeave)
End Property
'New event handler
Private Sub W_GotFocus()
mDeactivatedViaMouseLeave = False
End Sub
'modified event handler
Private Sub W_MouseLeave(ByVal MouseEnterWidget As cWidgetBase)
Set tmrSubMenuHover = Nothing
mDeactivatedViaMouseLeave = True
W.Refresh
End Sub
'change to Draw sub
Private Sub Draw(CC As cCairoContext)
.
.
.
If mCaption = "-" Then
CC.DrawLine IcoOffsX, 4, dx - 2, 4, True, 1, &HD0D0D0, Alpha
CC.DrawLine IcoOffsX, 5, dx - 2, 5, True, 1, vbWhite, Alpha
Else
If IsActive Then
W.Alpha = 0.6
CC.SetLineWidth 1, True
Cairo.Theme.DrawTo CC, W, thmTypeListSelection, 0, 2, 0, dx - 4, dy, 3
End If
.
.
.
End Sub
cwMenu
Code:
'change to event handler
Public Property Get MenuItemKeyPath() As String
If Not mActiveMenuItem Is Nothing And Not mActiveMenuItem.IsActive Then Exit Property
If mDataSource Is Nothing Then Exit Property
MenuItemKeyPath = MenuKeyPath
If Not mActiveMenuItem Is Nothing Then MenuItemKeyPath = MenuItemKeyPath & ">" & mActiveMenuItem.Widget.Key
End Property
Now, when the mouse leaves the menu form, nothing is highlighted and an enter key press will not do anything (standard behaviour)
Last edited by ColinE66; Jun 7th, 2014 at 10:39 AM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 10:47 AM
#20
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Actually, IsActive can be reduced to
Code:
Public Property Get IsActive() As Boolean
IsActive = W.Focused And (Not mSubMenuDS Is Nothing Or Not mDeactivatedViaMouseLeave)
End Property
Since MouseEnter always sets focus to the widget
Also, need another line in here to handle cases where a widget already has focus
cwMenuItem
Code:
Private Sub W_MouseEnter(ByVal MouseLeaveWidget As cWidgetBase)
If Not mSubMenuDS Is Nothing Then
Set tmrSubMenuHover = New_c.Timer(350, True)
Debug.Print mSubMenuDS.Caption, W.Parent.Active
End If
mDeactivatedViaMouseLeave = False
W.SetFocus
W.Refresh
End Sub
Hopefully, that's it!
Last edited by ColinE66; Jun 7th, 2014 at 10:53 AM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 02:53 PM
#21
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Throwing another one in - discard if you don't like! This one makes the up/down keys loop through the menu items so that, when the last item is bypassed the first is selected (or vice verse). If these are becoming unwelcome for any reason just say the word!
cwMenu
Code:
Public Sub KeyDown(KeyCode As Integer, Shift As Integer)
If Not mSubMenu Is Nothing Then mSubMenu.KeyDown KeyCode, Shift: Exit Sub
Dim i As Long, j As Long, MItem As cwMenuItem, MItemIdx As Long, RM As cwMenu
.
.
.
Case vbKeyUp
For i = 1 To Widgets.Count
j = MItemIdx - i
If j < 1 Then j = Widgets.Count
If Widgets(j).Widget.Enabled Then Widgets(j).Widget.SetFocus: Exit For
Next i
Case vbKeyDown
For i = 1 To Widgets.Count
j = MItemIdx + i
If j > Widgets.Count Then j = 1
If Widgets(j).Widget.Enabled Then Widgets(j).Widget.SetFocus: Exit For
Next i
.
.
.
End Sub
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 03:04 PM
#22
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Thanks Colin,
re-uploaded the example in post #1 with your changes (also updated vbWidgets.dll).
Edit: now also with your new Menu-cycling from your post above
Any further differences always preferrably from that Zip, to not get "out of sync" in
our efforts - thanks again.
Olaf
Last edited by Schmidt; Jun 7th, 2014 at 03:11 PM.
-
Jun 7th, 2014, 03:10 PM
#23
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Thanks. Just the change in #21 if you want that behaviour (I changed the code form the previous zip but no impact either way)
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 03:14 PM
#24
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Yep, #21 is now also in the Zip.
Olaf
-
Jun 7th, 2014, 04:22 PM
#25
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Last few for now - sorry to bombard you. This time, just refining the pWithFocus param I introduced in the first of my changes back in #16:
cwMenuBar [ensure first menu item is active as it was triggered via keyboard]
Code:
Private Sub W_KeyDown(KeyCode As Integer, Shift As Integer)
.
.
.
Case vbKeyDown:
If Not MenuBarItem Is Nothing Then
MenuBarItem.Widget.MouseLeave Nothing
MenuBarItem.ShowPopUp True
MenuBarItem.Widget.Refresh
End If
.
.
.
End Sub
Private Sub CurPopUp_MenuBarEntryShift(ByVal ShiftLeft As Boolean)
.
.
.
mBlockDestroy = True
MenuBarItem.ShowPopUp True
MenuBarItem.Widget.Refresh
W.Refresh
mBlockDestroy = False
.
.
.
End Sub
cwMenuBarItem [ensure first menu item is active as it was triggered via keyboard]
Code:
Private Sub W_AccessKeyPress(KeyAscii As Integer)
If W.Root.IsHidden Then Exit Sub
If InStr(1, W.AccessKeys, Chr$(KeyAscii), vbTextCompare) Then
W.Parent.object.CleanupActiveState W
W.SetFocus
ShowPopUp True
W.Refresh
W.Parent.Refresh
End If
End Sub
Public Sub ShowPopUp(Optional pWithFocus As Boolean)
Dim MenuBar As cwMenuBar
If Not W.Enabled Then Exit Sub
Set MenuBar = W.Parent.object
If Not MenuBar.CurPopUp Is Nothing Then
If Not MenuBar.CurPopUp.DataSource Is mDataSource Then MenuBar.CurPopUp.DestroyPopup
End If
Set MenuBar.CurPopUp = New cwMenu
MenuBar.CurPopUp.Widget.FontSize = W.FontSize
MenuBar.CurPopUp.InitAndShow W, mDataSource, PopupBehaviourDropDownLeftAligned, pWithFocus
End Sub
cwMenu
Code:
Public Sub InitAndShow(InitiatorWidget As cWidgetBase, Optional DataSource As cMenuItem, Optional ByVal DirectionBehaviour As enmMenuPopUpPosition, Optional ByVal WithFocus As Boolean)
.
.
.
If Not TypeOf mInitiatorWidget.object Is cwMenu Then
mInitiatorWidget.Root.BlockKeyEvents True, PopUp.Form
Set SC = New_c.SubClass
If App.LogMode Then SC.Hook mInitiatorWidget.Root.DialogFormHwnd
' Else 'a SubMenu 'Remove this line
' If WithFocus And Widgets.Count > 0 Then Widgets(1).Widget.SetFocus 'Remove this line
End If
If WithFocus And Widgets.Count > 0 Then Widgets(1).Widget.SetFocus
End Sub
If I got that right, the only time the first menu item is ever activated is when the menu was triggered to appear via the keyboard; no mouse-triggered menu appearance should have any menu item active.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 7th, 2014, 04:36 PM
#26
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Ok, updated and re-uploaded with the changes in #25 now...
Olaf
-
Jun 8th, 2014, 03:26 PM
#27
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
HI again. I've successfully added keyboard shortcuts to menu items (Ctrl+V) for paste, etc. Currently, I am adding a suffix to a menu's caption to implement this
e.g. MI.AddSubItem "Save", "&Save|Ctrl+Shift+V", "Document-Save"
and then, when setting the DataSource for a cwMenuBar, I recursively walk down the menu, populating a cCollection with the MenuItem path. Each member of this collection has a key representing the required Ctrl-Shift Modifier + Keycode)
i.e. 3+86 = Ctrl(1) + Shift(2) + Keycode for letter V (86) contains Edit>Copy
Whilst doing this, I build up a string for the KeyWatcher containing all the KeyCodes to be monitored and have modified the KeyWatcher's KeyDown event so that it calls a new sub
Code:
Private Sub CheckForKeyBoardShortcut(vKey As Integer)
Dim pMenuItemPath As String
If mKeyboardShortcuts.Exists(mCtrlDown + mShiftDown & "+" & vKey) Then
pMenuItemPath = mKeyboardShortcuts(mCtrlDown + mShiftDown & "+" & vKey)
If mDataSource.SubItemByPathKey(mDataSource.Key & ">" & pMenuItemPath).Enabled Then
CurPopUp_Click pMenuItemPath
End If
End If
End Sub
I can continue with this if you like but will need some support from you, I suspect. For instance, re-setting the KeyWatcher with a new comma-separated list appears to stop it from functioning if it has already been started, regardless of what I try. Help!
Also, I will need to re-measure all the MenuItems in order to right-align the short-cut text tidily.
Also, also, not sure that implementing via the caption text is a good idea; opinion, please. Maybe it belongs in the underlying cMenuItems class. I just did it this way as proof-of-concept.
Ask, if something didn't make sense or you want to see more code...
Last edited by ColinE66; Jun 8th, 2014 at 03:30 PM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 8th, 2014, 07:35 PM
#28
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
I've successfully added keyboard shortcuts to menu items (Ctrl+V) for paste, etc. Currently, I am adding a suffix to a menu's caption to implement this
e.g. MI.AddSubItem "Save", "&Save|Ctrl+Shift+V", "Document-Save"
...
Also, I will need to re-measure all the MenuItems in order to right-align the short-cut text tidily.
That alone would be a nice addition to have (detecting the Pipe in a Caption-Description,
recalcalculating the resulting lenght of the Menu-Text - and then rendering that Info-Text
right-aligned in the cwMenuItem.
But I would stop there for the moment (the Menu-Item only showing the Info-Text) -
not really sure what would be the best way to proceed from there (where the Events
should be handled or raised from).
Originally Posted by ColinE66
I can continue with this if you like but will need some support from you, I suspect. For instance, re-setting the KeyWatcher with a new comma-separated list appears to stop it from functioning if it has already been started, regardless of what I try. Help!
Normally it should work, when you overwrite an existing (WithEvents declared)
cKeyWatcher-Instance with a new one...
Private WithEvents MyKeyWatcher As cKeyWatcher
Set MyKeyWatcher = New_c.KeyWatcher(NewVKeyList)
Hmm, not yet sure if I'd rather like to handle this <Ctrl>+Key stuff over Form KeyPreview -
and Keydown/Up-Events, implementing the <Ctrl>+Something Handling there (fullfilling
the Promise of the Menu's "Info-only Captions" not in the Menu-System itself).
If you find a way to solve it over the Key-Watcher directly, resulting in a Menu-Event,
then Ok - but some Control-widgets as e.g. the cwTextBox already come with their
own KeyDown-Event Handling for <Ctrl>+C and <Ctrl>+V etc. - though that could
be solved with an Extra-Property on the Textbox perhaps - or by checking in the central
<Ctrl>+C Handler, if the currently focused Widget if of Type cwTextBox ...
If TypeOf cWidgetForm.Root.ActiveWidget Is cwTextBox...
Originally Posted by ColinE66
... also, not sure that implementing via the caption text is a good idea; opinion, please. Maybe it belongs in the underlying cMenuItems class. I just did it this way as proof-of-concept.
I see nothing wrong with the Pipe-Char delimiter in the Caption-String - since the Caption-Strings
are potential candidates to have defined in a language-resource - and what's written in english as:
"&Save|Ctrl+Shift+V"
would in a german language-table-column written as:
"&Speichern|Strg+Umsch+V"
So, it's indeed a good idea to have it in the Caption itself, to already cover proper translation in one place.
Olaf
-
Jun 9th, 2014, 02:28 AM
#29
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Just a quick note as I'm off to work; it is not implemented in a form keypreview - it's in the cwMenuBar class. I think this is a good place for it as only menu items on a menu bar should have shortcuts. Here's a few code snips to give you a better idea (not tidied up as I'm still playing).
cwMenuBar
Code:
Public Property Set DataSource(NewValue As cMenuItem)
.
.
.
Set KWatch = Nothing
Set mKeyboardShortcuts = New cCollection
mKeyWatcherCodes = "9,16,17,18"
.
.
.
For i = 0 To mDataSource.SubItemCount - 1
TxtWidth = CC.GetTextExtents(mDataSource.SubItemByIndex(i).Caption, FontHeight)
.
.
.
RegisterKeyboardShortcuts mDataSource.SubItemByIndex(i), mDataSource.SubItemByIndex(i).Key
Next i
Set KWatch = New_c.KeyWatcher(mKeyWatcherCodes)
W.Refresh
End Property
Private Sub RegisterKeyboardShortcuts(pItem As cMenuItem, pPath As String)
Dim i As Long, s() As String, ModifierValue As Long, KeyCode As Long
Debug.Print pItem.Caption, pItem.Key, pPath
If InStr(pItem.Caption, "|") Then
s = Split(pItem.Caption, "|")
ModifierValue = IIf(InStr(s(1), "Ctrl+"), 1, 0) + IIf(InStr(s(1), "Shift+"), 2, 0)
s = Split(s(1), "+")
KeyCode = Asc(s(1))
If Not mKeyboardShortcuts.Exists(ModifierValue & "+" & KeyCode) Then
mKeyboardShortcuts.Add pPath, ModifierValue & "+" & KeyCode
mKeyWatcherCodes = mKeyWatcherCodes & "," & KeyCode
End If
End If
For i = 0 To pItem.SubItemCount - 1
RegisterKeyboardShortcuts pItem.SubItemByIndex(i), pPath & ">" & pItem.SubItemByIndex(i).Key
Next i
End Sub
Code:
Private Sub KWatch_VKeyDown(ByVal vKey As Integer, ByVal MapIdx As Long)
If vKey = 9 Or vKey = 16 Or vKey = 17 Then TabOrShiftOrCtrlKeyDown = True
If vKey = 17 Then mCtrlDown = 1
If vKey = 16 Then mShiftDown = 2
CheckForKeyBoardShortcut vKey
If vKey = 18 And Not TabOrShiftOrCtrlKeyDown Then
AltDown = CurPopUp Is Nothing
If Not Screen.ActiveForm Is Nothing Then 'we send an Esc-KeyUp-Event in case of a VB-Form as TopLevel-Host
Dim Evt(0 To 27) As Byte: Evt(0) = 1: Evt(4) = vbKeyEscape: Evt(8) = 2 '<- flagged as KeyUp
SendInput 1, Evt(0), UBound(Evt) + 1
End If
If Not CurPopUp Is Nothing Then
CurPopUp.DestroyPopup
Set CurPopUp = Nothing
End If
End If
End Sub
Code:
Private Sub CheckForKeyBoardShortcut(vKey As Integer)
Dim pMenuItemPath As String
If Not CurPopUp Is Nothing Then Exit Sub
Debug.Print mCtrlDown + mShiftDown, vKey
If mKeyboardShortcuts.Exists(mCtrlDown + mShiftDown & "+" & vKey) Then
pMenuItemPath = mKeyboardShortcuts(mCtrlDown + mShiftDown & "+" & vKey)
If mDataSource.SubItemByPathKey(mDataSource.Key & ">" & pMenuItemPath).Enabled Then
CurPopUp_Click pMenuItemPath
End If
End If
End Sub
That's not everything but it should help to clarify my approach...
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 9th, 2014, 09:32 AM
#30
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by Schmidt
I see nothing wrong with the Pipe-Char delimiter in the Caption-String - since the Caption-Strings
are potential candidates to have defined in a language-resource - and what's written in english as:
"&Save|Ctrl+Shift+V"
would in a german language-table-column written as:
"&Speichern|Strg+Umsch+V"
Just a thought - but in some cases we might want to offer dynamic user-defined captions, and a user might want to use the pipe character (however unlikely). This would need some extra escaping code, so perhaps it would be better to use vbTab for the separator? I guess a knock against it is that it would involve a bit of extra typing though... "&Save" & vbTab & "Ctrl+Shift+V"
A more complete approach (though perhaps too much effort?) would be to have a Shortcut property and corresponding class that offered properties such as Enabled (Boolean), Ctrl (Boolean), Alt (Boolean), Shift (Boolean), KeyCode (Integer) and then the menu drawing class itself could handle displaying the shortcut in the appropriate language (although this would also required a mechanism to provide translations, but this could become a community effort).
-
Jun 9th, 2014, 10:47 AM
#31
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by jpbro
Just a thought - but in some cases we might want to offer dynamic user-defined captions, and a user might want to use the pipe character (however unlikely). This would need some extra escaping code, so perhaps it would be better to use vbTab for the separator? I guess a knock against it is that it would involve a bit of extra typing though... "&Save" & vbTab & "Ctrl+Shift+V"
I'd like a "typeable char", which is easy to enter into a DataGrid-Cell or a TextBox
(without causing Focus-Switching or something like that - always having the
"language-translator-guy" in mind, who's wading through the text-columns).
The Pipe-Char is (IMO) already unlikely enough - and we could handle it in the same way
as the &-Char currently is handled (a user who wants it in a normal Caption would have
to "escape" it by typing it twice).
Originally Posted by jpbro
A more complete approach (though perhaps too much effort?) would be to have a Shortcut property and corresponding class that offered properties such as Enabled (Boolean), Ctrl (Boolean), Alt (Boolean), Shift (Boolean), KeyCode (Integer) and then the menu drawing class itself could handle displaying the shortcut in the appropriate language (although this would also required a mechanism to provide translations, but this could become a community effort).
The Enabled-State, as well as the Alt-Key Handling (per &) is already covered in the current approach.
There's only the <Ctrl>+Something and the <Shift>+Something which needs to be added...
And there is already an Event which can be used for dynamic Menu-Text-Translations
(named 'ReplaceCaption' and raised by the cwMenu-Class shortly before "showing")
The following Zip contains a ProjectGroup (_TestGroup.vbg),
which joins the two Projects: PopUpDemo.vbp and vbWidgets.vbp
and shows the usage of this Event in cfMain.cls of the PopupDemo-Project.
http://vbRichClient.com/Downloads/PopUpMenus.zip
(showing the interaction of a Cut/Copy/Paste/SelectAll popup with the cwTextBox-Widget,
including dynamic lang-switching)
Olaf
-
Jun 9th, 2014, 01:17 PM
#32
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Right guys, I suspect there's more mileage left in the language discussion but I'm posting my code as of now just so y'all can see it in action and think a little more about the best way to implement this. As it stands, if the words 'Ctrl' and 'Shift' are not universal then this approach is a complete non-starter!
I have made no attempt to version control my changes in the attachment, I'm afraid, as I'm still playing around but the changes are not significant; Olaf will spot them immediately given that he is the original author, of course.
It's just presented here for information and to provoke thought about implementation details...
MenuAndToolbarDemoMOD.zip
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 9th, 2014, 07:49 PM
#33
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Right guys, I suspect there's more mileage left in the language discussion but I'm posting my code as of now just so y'all can see it in action and think a little more about the best way to implement this. As it stands, if the words 'Ctrl' and 'Shift' are not universal then this approach is a complete non-starter!
I've introduced two Public String-Properties (LocalizedCtrlMarker and LocalizedShiftMarker) into cwMenuBar to handle that
(those are per default at the english localized Strings "Ctrl" and "Shift")
Originally Posted by ColinE66
I have made no attempt to version control my changes in the attachment, I'm afraid, as I'm still playing around but the changes are not significant; Olaf will spot them immediately given that he is the original author, of course.
Thanks for the Code - so far everything is looking nice - so I took over your changes (only slight adaptions in cwMenuBar) -
and recommend a new download of the original Demo in Post #1, to work further from there, for the next potential "Diff"
(Ping-Pong-principle so to say, when you post a Zip with changes, wait for the update of the "Post #1 download-sources"
before adding new stuff).
But if possible in small(er) increments, since these are easier to follow... (sometimes that's difficult, I know)
Olaf
-
Jun 10th, 2014, 11:31 AM
#34
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Downloaded new zip from #1...
fyi, it wasn't my intention that you'd need to pick through the stuff in #32 to find the differences; I'd have done that for you had you been happy with the approach I took and the way it functioned. Anyway, hope it wasn't too onerous for you...
btw, how much more robust do you want me to make the modifier/keycode parsing? You will have seen that it was pretty much thrown-together up til now. Obviously, this aspect could grow by quite a few lines of code, if you'd like? However, it isn't really that difficult for the developer to conform to a (e.g.) '|Ctrl+Shift+V' style of notation. Your call....?
EDIT:
I meant to point out that the current design has implications on what will be returned by the Caption property of a cwMenuItem and also the fact that the property Let for the Caption property will not, of course, re-trigger the re-population of the shortcut handling collection in the parent cwMenuBar. Just food for thought...
Last edited by ColinE66; Jun 10th, 2014 at 11:40 AM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 10th, 2014, 06:27 PM
#35
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Originally Posted by ColinE66
Downloaded new zip from #1...
fyi, it wasn't my intention that you'd need to pick through the stuff in #32 to find the differences; I'd have done that for you had you been happy with the approach I took and the way it functioned. Anyway, hope it wasn't too onerous for you...
No - the larger change took (in Sum) perhaps the same time, as 3 smaller ones -
it's just that those 3 smaller ones could be handled "somewhere in-between" more
easily - larger changes require a larger "contiguos timespan", which is not available everyday -
but Monday was a Holiday in germany - so I had this larger timeframe to react immediately -
no problem.
Originally Posted by ColinE66
btw, how much more robust do you want me to make the modifier/keycode parsing? You will have seen that it was pretty much thrown-together up til now. Obviously, this aspect could grow by quite a few lines of code, if you'd like? However, it isn't really that difficult for the developer to conform to a (e.g.) '|Ctrl+Shift+V' style of notation. Your call....?
I would leave it as it is for the time being - we already tried to think ahead with the two new Public Props on
the interface, which allow to specify the "Ctrl" and "Shift" parsing-strings for other locales.
The Public interface is what makes the most worries later on, when it's lacking some things - internal stuff
can be fixed and hardened over time...
I plan to include at least the intrinsic-Widgets (CommandButton, Label, Frame, TextBox, Image -
as well as the MenuSystem we have isolated here) directly into vbRichClient6 at the end of the year -
for that the Public Interfaces need to be stable - the internal stuff is easier to understand, fix and enhance,
when it's still kept as simple as possible in each Widget - so let's keep up with KISS for a while longer
Originally Posted by ColinE66
I meant to point out that the current design has implications on what will be returned by the Caption property of a cwMenuItem and also the fact that the property Let for the Caption property will not, of course, re-trigger the re-population of the shortcut handling collection in the parent cwMenuBar. Just food for thought...
Yes - I'm aware of that - but thought that your current parsing-routine (the one which currently
takes the MenuItem as its first Parameter) could be made Friend - and then just called from the
"deeper-layers" of the Menu-Hierarchy, since it is quite easy to reach the Parent-Widget (in this case
cwMenuBar) from any Child-Widget deeper down (then in turn calling the Friend-tagged Parsing-Function).
I perhaps forgot two or three stumbling-points, but still think that it's solvable internally
(without introducing new things on the Public Widget-Interfaces...).
Thanks again for your work on this.
Olaf
Last edited by Schmidt; Jun 11th, 2014 at 04:46 AM.
-
Jun 11th, 2014, 01:42 PM
#36
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
OK - I'll leave the parsing as-is, then...
One last change. Remember how, occasionally, a menubaritem can appear to be 'active? You can replicate this by pressing alt and clicking on another app's window and back again; notice how the menu still appears to be active (outline effect)?
Well, anyway, it occurred to me that this could be eliminated by reacting to when the app loses focus. Now, I know that your WidgetForms support such an event so there may be a better way of solving this 'issue' but, in terms of your vb-Form-hosted demo, I got around the problem as follows:
fTest
Code:
Private WithEvents SC As cSubClass
Private Sub SC_WindowProc(Result As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long)
Select Case Msg
Case &H1C 'app activate/deactivate
MenuBar.CleanupActiveState , True
End Select
Result = SC.CallWindowProc(Msg, wParam, lParam)
End Sub
and
cwMenuBar
Code:
Public Sub CleanupActiveState(Optional ExcludeW As cWidgetBase, Optional AppFocusedStateChanged As Boolean)
Dim MenuBarItem As cwMenuBarItem
mKeyWatcherCodesChanged = AppFocusedStateChanged
For Each MenuBarItem In Widgets
If Not ExcludeW Is MenuBarItem.Widget Then MenuBarItem.Widget.MouseLeave W
MenuBarItem.Widget.Refresh
Next
End Sub
It basically codes around your IsTopWindowActive test in Sub ShortcutActivation and has the side-effect of turning the KeyWatcher on and off. As said, that is just a side-effect but, because the impact of that is so minimal, it seems like a good one-line-of-code-fix to a problem, even if that solution is not necessarily elegant or intuitive with regard to future code maintenance.
EDIT:
Actually, I should explain a little more: Without resetting the mKeyWatcherCodesChanged flag, it will have required many more lines of code to achieve a fix because of the behaviour of the widget's refresh mechanism i.e. always calling the ShortcutActivation sub and therefore failing the IsTopWindowActive test when the app loses focus. I'm sure you know that anyway but it only took a few seconds more to read this!
Last edited by ColinE66; Jun 11th, 2014 at 01:50 PM.
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 11th, 2014, 07:51 PM
#37
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
I've now built-in a solution for the HoveredMenu-Deactivation-Routine (without SubClassing, using a Timer) -
and also cleaned up a bit around the mKeyWatcherCodesChanged-stuff (which is gone
and not needed anymore).
Please check-out the new version from #1...
Olaf
-
Jun 12th, 2014, 07:05 AM
#38
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
All good, Olaf. I now declare your menus to be officially awesome
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
-
Jun 12th, 2014, 08:38 AM
#39
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
I've discovered a couple of issues with the current/latest menu implementation. I'm trying to familiarize myself with the code to see if I can fix the issues myself, but I figured I would report them here in case Olaf or Colin can see a quick and easy fix (being more familiar with the code).
1) If you move focus to another program, then return focus to the demo app, then press Alt+F (to try to activate the file menu), then only the parent menu bar gets focus (the menu doesn't appear). A subsequent Alt+F will flash the menu, but it will disappear. A third Alt+F will show the menu as expected.
2) In native Windows menus, pressing Alt (and releasing) and then pressing F will show the File menu. This doesn't happen with the vbWidgets menus.
-
Jun 12th, 2014, 02:08 PM
#40
Re: VB6 Dynamic Menu-, Popup- and Toolbar-Demo (vbRichClient-based)
Good catch.
With regard to (2), this will fix it if Olaf is happy with it:
cwMenubar
Code:
Private Sub W_KeyDown(KeyCode As Integer, Shift As Integer)
If Not CurPopUp Is Nothing Then Exit Sub
Dim MenuBarItem As cwMenuBarItem
For Each MenuBarItem In Widgets
If MenuBarItem.Widget.MouseOver And KeyCode = vbKeyDown Then
Exit For
ElseIf InStr(1, MenuBarItem.Widget.AccessKeys, Chr$(KeyCode), vbTextCompare) Then
CleanupActiveState
KeyCode = vbKeyDown 'pretend the down arrow was pressed
Exit For
End If
Next
Select Case KeyCode
Case vbKeyEscape
If Not MenuBarItem Is Nothing Then MenuBarItem.Widget.MouseLeave Nothing
W.Root.Widget.MouseUp 0, 0, -1, -1
W.Root.Refresh
Case vbKeyDown:
If Not MenuBarItem Is Nothing Then
MenuBarItem.Widget.MouseLeave Nothing
MenuBarItem.ShowPopUp True
MenuBarItem.Widget.Refresh
End If
Case vbKeyLeft: CurPopUp_MenuBarEntryShift True
Case vbKeyRight: CurPopUp_MenuBarEntryShift False
End Select
End Sub
If you don't know where you're going, any road will take you there...
My VB6 love-children: Vee-Hive and Vee-Launcher
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|