Today, the OwnerDrawn menu class has been updated (the article was published on UT Magazine October 2005 edition). A few bug has been fixed. And few features has been added based on e-mail I received lately.
I hope you enjoy the new class,
happy coding!
Download OwnerDrawn Menus class & sample
10 comments:
Thanks Hermam, I will look at it.
Hello Hermman.
Happy New Year!
Your OwnerDrawn menu class is excellent!
I only see one drawback: You have to write too much code to define your menu.
I tried to make the life of developers easier by giving your class the ability to read and execute a standard VFP Menu (MPX) but I couldn’t because I don’t understand your code, I’m not that good ;).
I only could find some code to extract the contents of a MNX table into a treeview. Maybe with this you would be able to do it.
The code is attached; please give this request a try, in the MNX you could find the Prompt name, the accelerator key, the picture and the code to execute when the menu bar is pressed.
Thanks in advance.
Best regards:
Victor Chigne
(Code below)
menu2tree.prg
lparameters tcMenuAlias, toTreeControl
if pcount() < 1
messagebox("No Menu Table or no tree view object reference has been passed")
tcMenuAlias = GETFILE("mnx","Open a menu..")
IF EMPTY(tcMenuAlias)
return .f.
ENDIF
ENDIF
lOnluMenu=.F.
IF PCOUNT()=1
* only convert menu
lOnlyMenu = .T.
ENDIF
LOCAL lcMenuBarName, ;
lcWorkingKey, ;
lcKey, ;
lnPads
lcMenuBarName = SPACE(0)
lcWorkingKey = SPACE(0)
lcKey = SPACE(0)
DIMENSION laNode[1,2]
if used('mainmenu')
use in mainmenu
endif
use (tcMenuAlias) in 0 alias mainmenu again shared noupdate
SELECT mainmenu
LOCATE
* No need to work with the default header record of the menu.
SKIP 1
WITH toTreeControl
* Clear previous menu if one existed.
.Nodes.Clear()
lcMenuBarName = mainmenu.LevelName
lnPads = mainmenu.NumItems
laNode[1,1] = lcMenuBarName
laNode[1,2] = .NULL.
SELECT *, RECNO() as nRecno ;
FROM mainmenu ;
WHERE LevelName = lcMenuBarName ;
INTO CURSOR curTreeRootNodes
* Build root
SCAN
IF VAL(curTreeRootNodes.ItemNum) # 0
lcKey = "M" + PADL(TRANSFORM(curTreeRootNodes.nRecNo), 6, "0")
.Nodes.Add(, 1, lcKey, iif(curTreeRootNodes.Prompt='\-','------',strtran(curTreeRootNodes.Prompt,'\<','')))
ENDIF
ENDSCAN
SELECT curTreeRootNodes
PopulateTreeChildNodes("curTreeRootNodes")
ENDWITH
USE IN (SELECT("curTreeRootNodes"))
SELECT MainMenu
LOCATE
return
********************************************************
function PopulateTreeChildNodes
LPARAMETERS tcCursor
SELECT (tcCursor)
SCAN
lcItemNum = &tcCursor..ItemNum
IF VAL(lcItemNum) = 0
LOOP
ENDIF
lnRecordNo = &tcCursor..nRecno
GO lnRecordNo IN MainMenu
SKIP 1 IN MainMenu
lcLevelName = MainMenu.LevelName
lcLevelCursor = "curNodes" + ALLTRIM(lcLevelName)
SELECT *, RECNO() as nRecno ;
FROM mainmenu ;
WHERE LevelName == lcLevelName ;
INTO CURSOR (lcLevelCursor) NOFILTER
SELECT (lcLevelCursor)
SCAN
IF VAL(ItemNum) # 0
lcParentNodeKey = "M" + PADL(TRANSFORM(&tcCursor..nRecno), 6, "0")
lcKey = "M" + PADL(TRANSFORM(&lcLevelCursor..nRecno), 6, "0")
.Nodes.Add(lcParentNodeKey, 4, lcKey, iif(&lcLevelCursor..Prompt='\-','------',strtran(&lcLevelCursor..Prompt,'\<','')))
ENDIF
ENDSCAN
* Select all options at current level that are submenus
lcLevelCursorSub = lcLevelCursor + "subonly"
SELECT * ;
FROM (lcLevelCursor) ;
WHERE ObjCode = 77 ;
INTO CURSOR (lcLevelCursorSub) NOFILTER
IF _tally > 0
PopulateTreeChildNodes(lcLevelCursorSub)
ENDIF
USE IN (SELECT(lcLevelCursorSub))
ENDSCAN
*USE IN (SELECT(lcLevelCursor))
return
Hi Herman,
You might have a look at this sample, created by Rafael Lippert. Basically, he tried to d the same as you do, starting from the MNX file to create his menu. This way, people could continue using their own original menus, with no code changes.
Since he saw your ownerdrawn menus, he stopped developing it. Maybe you can get some ideas from there !
Please download directly from:
http://www.lipsil.com.br/arquivos/menu_26_10_2006.zip
At this link you can see some screenshots:
http://www.lipsil.com.br/menu.htm
Regards
Cesar Chalom
Hi Cesar,
I've been asked to do the same thing by others too. You can see the comment from Victor's :)
Now that's what I want to do. I'm sorry I had to postponed that for some time. I think it's time for me to finish this.
Thanks for the link to Rafael's page. Look's good, I'll try it soon.
Thank you for comments & feedback. Appreciate it!
Regards
Herman Tan
Hi Herman,
Your OwnerDrawn menu is exellent work. Thank you for sharing it with VFP community.
A question:
I was trying frm_popupmenu.scx sample, and ACTIVATEPOPUP method. It seems will always activate "main" popup. How can I activate a subpopup along with "main" popup ?
Something like native ACTIVATE POPUP xxx BAR yyy, which also shows whole structure above bar specified.
Best regards,
Kruno Malovic
Croatia, Europe
Hi Kruno,
Thanks for your feedback!
Yes it always activate the first (main) popup. Sorry, at this moment the class does not support the activation on specific popup or on specific bar. However, I'll put this on my todo list.
Best regards,
Herman Tan
Perhaps you could clarify for me how to use the class with the VFP special menu items like Edit,Cut, Paste, etc. I am using the class fine with other things. What I do not get is how to make them enable/disable automaticakky like they normally would.
Thanks
If you talking about Shortcut popup, then you have to disable the item manually. For instance, put this code in an EditBox.RightClick() event:
Declare Long IsClipboardFormatAvailable in User32 Long nFormat
With oPopup
.CreatePopupItem( 3 )
.aPopupItem[1] = 'Cu&t'
.aPopupItem[2] = '&Copy'
.aPopupItem[3] = '&Paste'
hPopup = .CreatePopup( 1 )
.nFirstId = 1
** Disable Cut & Copy Item
If (This.SelLength == 0)
.DisablePopupItem( 1, 1 )
.DisablePopupItem( 1, 2 )
endif
** Disable Paste Item
If (IsClipboardFormatAvailable(1) == 0)
.DisablePopupItem( 1, 3 )
endif
nResult = .ActivatePopup()
** Do the rest
endif
EndWith
HTH
Herman
pak Herman
kl untuk nampilin di menu gambar dari pictres bukan bmp gmana?..
Halo vcwalet,
PictRes memang tidak di support oleh class ini. Hal ini juga sudah disebutkan pada Form OD Menu Generator (OD_GenMenu). Silahkan di baca pada EditBox nya tentang batasan-batasan yg mungkin belum/perlu anda ketahui.
Post a Comment