Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Enumerate Favorites Folder and Create a Menu structure 2

Status
Not open for further replies.

Kazim

Programmer
Jul 23, 2001
26
GB
Hi.

I am creating a browser program that I wish to use myself. There are a number of custom features that I particularly need when I am researching something.

I would very much like to include a menu of the same type as the Favorites menu in IE, which would be generated at run time.

I have found several snippets of code that allow me to add my favorites to a treeview, which I have done, however, adding them to a menu seems impossible since I am unable to create the submenus at runtime.

I have a great many categorized items in my favorites folder, sometimes several folders deep.

Is there a way to enumerate these and add them to a menu?
If not is there some kind of workaround or control that can be used to do this?
Is there a way to bolt the IE favorites menu into my app?

Any help would be greatly received.

Thanks

Kazim
 
This should work. It searches the favorites folder for all files and (sub)folders and generates a menu. In order to actually use the menu, you will have to subclass the window and catch the messages in the window procedure (that last bit is not included).

Good luck..
Remedy

Code:
Private Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32.dll" (ByVal hFindFile As Long) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
Private Declare Function SHGetSpecialFolderLocation Lib "shell32" (ByVal hwndOwner As Long, ByVal nFolder As Long, ByRef pIdl As Long) As Long
Private Declare Function SHGetPathFromIDListA Lib "shell32" (ByVal pIdl As Long, ByVal pszPath As String) As Long

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * 260
    cAlternate As String * 14
End Type

Private Const INVALID_HANDLE_VALUE = -1
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FOLDER_FAVORITES = &H6
Private Const MAX_PATH = 255

Private Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SetMenu Lib "user32" (ByVal hWnd As Long, ByVal hMenu As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function CreatePopupMenu Lib "user32" () As Long
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function ModifyMenu Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpString As Any) As Long

Private Const MF_STRING = &H0&
Private Const MF_POPUP = &H10&
Private Const MF_BYPOSITION = &H400&

Private Type MENU_SUBITEM
    MenuID As Long
    MenuHandle As Long
    Path As String
End Type

Public Sub CreateFavoritesMenu(ByVal hWnd As Long)

    Dim MSI() As MENU_SUBITEM
    Dim lsPath As String
    Dim pIDList As Long
    Dim liCount As Long
    Dim liMenuID As Long
    Dim i As Long
    
    Dim hMenu As Long
    Dim hMenuPopup As Long
    
    If SHGetSpecialFolderLocation(0, FOLDER_FAVORITES, pIDList) = 0 Then
        
        'get path to favorites
        lsPath = Space$(MAX_PATH)
        SHGetPathFromIDListA pIDList, lsPath
        lsPath = Left$(lsPath, InStr(lsPath, vbNullChar) - 1)
        
        'create menu
        hMenu = GetMenu(hWnd)
        liMenuID = 1000
        
        ReDim MSI(0)
        MSI(0).MenuHandle = CreatePopupMenu
        MSI(0).Path = lsPath
        
        AppendMenu hMenu, MF_POPUP, MSI(0).MenuHandle, "&Favorites"
        
        SearchFiles MSI, lsPath, liCount, liMenuID, MSI(0).MenuHandle
        While i < liCount
            SearchFiles MSI, MSI(i).Path, liCount, liMenuID, MSI(i).MenuHandle
            i = i + 1
        Wend
        
        DrawMenuBar hWnd
    End If
End Sub

Public Sub SearchFiles(ByRef MenuItem() As MENU_SUBITEM, ByVal Path As String, ByRef Count As Long, ByRef MenuID As Long, ByVal hMenuPopup As Long)

    Dim hFile As Long
    Dim WFD As WIN32_FIND_DATA
    Dim lsFileName As String
    
    If Right$(Path, 1) <> &quot;\&quot; Then Path = Path & &quot;\&quot;
    hFile = FindFirstFile(Path & &quot;*.*&quot;, WFD)
    If hFile <> 0 Then
        Do
            lsFileName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
            If (WFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) Then
                'folder
                If (lsFileName <> &quot;.&quot;) And (lsFileName <> &quot;..&quot;) Then
                    ReDim Preserve MenuItem(Count)
                    MenuItem(Count).MenuHandle = CreatePopupMenu()
                    AppendMenu hMenuPopup, MF_POPUP, MenuItem(Count).MenuHandle, lsFileName
                    
                    MenuID = MenuID + 1
                    MenuItem(Count).Path = Path & lsFileName
                    MenuItem(Count).MenuID = MenuID
                    Count = Count + 1
                End If
            Else
                'file
                If Right$(lsFileName, 4) = &quot;.url&quot; Then
                    AppendMenu hMenuPopup, MF_STRING, MenuID, Left$(lsFileName, Len(lsFileName) - 4)
                    MenuID = MenuID + 1
                End If
            End If
        Loop Until FindNextFile(hFile, WFD) = 0
    End If
End Sub

Use it like this: CreateFavoritesMenu Me.hWnd

Oh, I forgot: you must already have a menubar (so at least one menu) on your form.
 
Many thanks - Ill look at this right now but... one thing:

SubClass the Window?

Forgive me but I have no idea what you mean by that! Do you mean that although the code will create the menu it cant pick up the clicks on the menu items?

Anyway, thanks again - Ill look at the code now and see if I can fathom out what its doing!

Kazim
 
You've got it right.
I realize the code isn't too clear, but maybe with a little experimenting you can figure out how it works.
I don't have the time now to show you how to actually use the menu (and that might be useful ;-)) , but I will as soon I can. Or maybe somebody else will show you..

Remedy
 
Whoa! That code is excellent! Really fast too - I have an awful lot of items in my Favorites folder (Upwards of about 2000) Very impressive.

I look forward to some information on how to SubClass the window, meanwhile I will endevour to pick through this code and see if I can work it out myself.

Very many thanks - Excellent work so far.

Kazim
 
Okay - I have been totally unsuccessful in my attempts to Subclass the window, although I have managed to perform some spectacular system crashes!

I even went so far as to download a DLL which claimed to do the same as the code you posted, but this caused the program to crash as well, although it did create the menus.

The problem seems to be when I maximize a child window of my main form. There are no menus on any of the child windows, however, as soon as I try to minimize or restore a child window the program (And VB) crash, with no error message at all!

I know this is probably caused by the fact that the MDI form that has the menus also handles the menus of child forms when they maximize, however they don’t have any menus so I’m not sure how to handle this now.

Will ANY code that gets the favorites list crash like this when a child form is manipulated?

The child forms are all dynamically created when needed (There is only one of them) and there can be quite a few of them. I thought of putting this code onto the child forms themselves, but this seems pointless since the code would run every time a child form was created, and I’m not sure what would happen when a child form is destroyed.

Any further help on this would be greatly received - I’m completely at a loss now. I have the code but no way of accessing the events it can generate, and, more to the point it will crash the program under circumstances that are likely to be replicated a great deal in normal use!

Any ideas anyone?

K
 
Well, the lower the level, the better the crashes (now there's a fine signature ;-) ).
The following code should work, although I haven't tested it with child windows. It places a hook on the window, and prints the text of the selected menu item, when receiving a WM_MENUSELECT message.

Code:
Public Declare Function SetWindowLong Lib &quot;user32.dll&quot; Alias &quot;SetWindowLongA&quot; (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib &quot;user32.dll&quot; Alias &quot;CallWindowProcA&quot; (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public Declare Sub CopyMemory Lib &quot;kernel32&quot; Alias &quot;RtlMoveMemory&quot; (Destination As Integer, ByVal Source As Long, ByVal Length As Long)
Public Declare Function GetMenuString Lib &quot;user32&quot; Alias &quot;GetMenuStringA&quot; (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_MENUSELECT = &H11F

Public pOldProc As Long    'pointer to old window procedure

This is the actual window procedure:
Code:
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
   
    Dim lsItem As String
    Dim liLength As Long
    
    Select Case uMsg
            
        Case WM_MENUSELECT
        
            lsItem = Space$(255)
            liLength = GetMenuString(lParam, LOWORD(wParam), lsItem, Len(lsItem), 0)
            If liLength > 0 Then
                lsItem = Left$(lsItem, liLength)
                Debug.Print &quot;ITEM = &quot; & lsItem
                Debug.Print &quot;ITEM ID = &quot; & LOWORD(wParam)
            End If
            WindowProc = 1
            
        Case Else               'use default message handler
            
            WindowProc = CallWindowProc(pOldProc, hwnd, uMsg, wParam, lParam)
            
    End Select
End Function

This is macro to extract the lower half of a dword value:
Code:
Public Function LOWORD(dw As Long) As Integer
    CopyMemory LOWORD, VarPtr(dw), 2
End Function

And, since it's almost x-mas, I'll throw in this extra, free function to get the other half (although not used in this code sample):
Code:
Public Function HIWORD(dw As Long) As Integer
    CopyMemory HIWORD, VarPtr(dw) + 2, 2
End Function

This is the call to start subclassing (put in in Form_Load or something..):
Code:
pOldProc = SetWindowLong(frmMain.hwnd, GWL_WNDPROC, AddressOf WindowProc)

And the call to end it (put in Form_Unload or something..),
don't forget this one, or a crash is almost garanteed:
Code:
SetWindowLong frmMain.hwnd, GWL_WNDPROC, pOldProc

Good luck again!
Remedy
 
Um....

The line &quot;pOldProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WindowProc)&quot;

Gives the error &quot;Invalid Use of AddressOf Operator&quot;

I would try to work out what that means but I have not the slightest idea how to follow this code!

This is being tested in just a single normal form, not an MDI one. There is nothing added to the form except a single menu item which needs to be there or the menus dont show up at all.

Any ideas?
 
One idea: the WindowProc function must be placed in a module (not in a form).

Remedy
 
Excellent! But now this line:

&quot;Public Sub SearchFiles(ByRef MenuItem() As MENU_SUBITEM, ByVal Path As String, ByRef Count As Long, ByRef MenuID As Long, ByVal hMenuPopup As Long)&quot;

give me this error:

&quot;Only Public User Defined Types defined in Public Object Modules can be used as Parameters or Return Types for Public Procedures of Class Modules or as fields of Public user Defined Types&quot;

To say that is confusing would be an understatement!! I would like to get this all working, not least so that my project will work now, but also so that I can work through it and try to understand what you have done with the code!

Unfortunately this is holding me up, but I have to be honest and say that this error didnt occur when I first tried the code!

I have tried this code on a normal form and on an MDI form and both give the same error and I just dont know where to look or what to look for!

Sorry to be a pain!

K
 
I've created a better, faster version of the code. Hope it doesn't confuse you even more ;-). Since it doesn't need the MENU_SUBITEM structure anymore, that error should be eliminated.

This is the code for a bas-module:
Code:
'// FILES - READ INTERNET SHORTCUT (INI)
Private Declare Function GetPrivateProfileString Lib &quot;kernel32&quot; Alias &quot;GetPrivateProfileStringA&quot; (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

'// FILES - GET FAVORITES PATH
Private Declare Function SHGetSpecialFolderLocation Lib &quot;shell32&quot; (ByVal hwndOwner As Long, ByVal nFolder As Long, ByRef pIdl As Long) As Long
Private Declare Function SHGetPathFromIDListA Lib &quot;shell32&quot; (ByVal pIdl As Long, ByVal pszPath As String) As Long

Private Const CSIDL_FAVORITES = &H6     'path id of favorites folder
Private Const MAX_PATH = 255            'max length path name

'// FILES - SEARCH FILES
Private Declare Function FindFirstFile Lib &quot;kernel32.dll&quot; Alias &quot;FindFirstFileA&quot; (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib &quot;kernel32.dll&quot; Alias &quot;FindNextFileA&quot; (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib &quot;kernel32.dll&quot; (ByVal hFindFile As Long) As Long

Private Const FILE_ATTRIBUTE_HIDDEN = &H2           'file is hidden
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10       'file is directory
Private Const FILE_ATTRIBUTE_READONLY = &H1

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * 260
    cAlternate As String * 14
End Type

'// MENU
Private Declare Function DrawMenuBar Lib &quot;user32&quot; (ByVal hWnd As Long) As Long
Private Declare Function SetMenu Lib &quot;user32&quot; (ByVal hWnd As Long, ByVal hMenu As Long) As Long
Private Declare Function GetMenu Lib &quot;user32&quot; (ByVal hWnd As Long) As Long
Private Declare Function CreateMenu Lib &quot;user32&quot; () As Long
Private Declare Function CreatePopupMenu Lib &quot;user32&quot; () As Long
Private Declare Function InsertMenu Lib &quot;user32&quot; Alias &quot;InsertMenuA&quot; (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function DestroyMenu Lib &quot;user32&quot; (ByVal hMenu As Long) As Long

Private Declare Function AppendMenu Lib &quot;user32&quot; Alias &quot;AppendMenuA&quot; (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function GetMenuString Lib &quot;user32&quot; Alias &quot;GetMenuStringA&quot; (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long

Private Const MF_STRING = &H0
Private Const MF_POPUP = &H10
Private Const MF_BYPOSITION = &H400

'// WINDOW HOOK
Private Declare Function CallWindowProc Lib &quot;user32.dll&quot; Alias &quot;CallWindowProcA&quot; (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowLong Lib &quot;user32&quot; Alias &quot;GetWindowLongA&quot; (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib &quot;user32.dll&quot; Alias &quot;SetWindowLongA&quot; (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Const GWL_WNDPROC = (-4)
Private Const WM_COMMAND = &H111
Private Const WM_MENUSELECT = &H11F

'// GLOBAL VARIABLES
Public pWndProc As Long
Public ShortCutPath() As String

Public Sub Hook(ByVal hWnd As Long, ByVal SetHook As Boolean)
    
    If SetHook Then
        pWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
    Else
        SetWindowLong hWnd, GWL_WNDPROC, pWndProc
    End If
End Sub

Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
     
    Dim liMenuID As Long
    
    Select Case uMsg
            
        Case WM_COMMAND     'use WM_MENUSELECT to capture MouseOver event
            
            liMenuID = LOWORD(wParam) - 1000
            If liMenuID >= 0 And liMenuID < UBound(ShortCutPath) Then
                Debug.Print ShortCutPath(liMenuID)
            End If
            WindowProc = 1
            
        Case Else
            WindowProc = CallWindowProc(pWndProc, hWnd, uMsg, wParam, lParam)
    End Select
End Function

Public Function LOWORD(ByVal dwValue As Long) As Long
    Dim hexstr As String
    hexstr = Right(&quot;00000000&quot; & Hex(dwValue), 8)
    LOWORD = CLng(&quot;&H&quot; & Right(hexstr, 4))
End Function

Public Function HIWORD(ByVal dwValue As Long) As Long
    Dim hexstr As String
    hexstr = Right(&quot;00000000&quot; & Hex(dwValue), 8)
    HIWORD = CLng(&quot;&H&quot; & Left(hexstr, 4))
End Function

Public Sub CreateFavoritesMenu(ByVal hWnd As Long)

    Dim hMenu As Long       'handle to menu(bar)
    Dim hSubMenu As Long    'handle to submenu
    Dim lsPath As String
    Dim pIDList As Long
    
    'get path to favorites
    If SHGetSpecialFolderLocation(0, CSIDL_FAVORITES, pIDList) <> 0 Then Exit Sub
    
    lsPath = Space$(MAX_PATH)
    SHGetPathFromIDListA pIDList, lsPath
    lsPath = Left$(lsPath, InStr(lsPath, vbNullChar) - 1)
    
    'get the window's main menu (if there's no menu, create one)
    hMenu = GetMenu(hWnd)
    If hMenu Then DestroyMenu hMenu
    hMenu = CreateMenu()

    'create a submenu (&quot;favorites&quot;)
    hSubMenu = CreatePopupMenu()
    If Right$(lsPath, 1) = &quot;\&quot; Then lsPath = Left$(lsPath, Len(lsPath) - 1)
    InsertMenu hMenu, 1, MF_BYPOSITION Or MF_POPUP, hSubMenu, Mid$(lsPath, InStrRev(lsPath, &quot;\&quot;) + 1)
        
    'search for files
    EnumFiles lsPath, hSubMenu
        
    'append menu to window and draw menu
    SetMenu hWnd, hMenu
    DrawMenuBar hWnd
    
    'start hook (not before menu is generated)
    Hook frmMain.hWnd, True
End Sub

Public Sub EnumFiles(ByVal Path As String, ByVal hSubMenu As Long)
   
    Static liMenuID As Long
    
    Dim hFile As Long
    Dim WFD As WIN32_FIND_DATA
    Dim lsFileName As String
    Dim hSubMenuNew As Long
    
    If Right$(Path, 1) <> &quot;\&quot; Then Path = Path & &quot;\&quot;
    
    hFile = FindFirstFile(Path & &quot;*&quot;, WFD)
    
    If hFile <> -1 Then
    
        Do
            DoEvents
            lsFileName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
            If ((WFD.dwFileAttributes Or FILE_ATTRIBUTE_DIRECTORY) = WFD.dwFileAttributes) Then
                'is directory
                If (lsFileName <> &quot;.&quot;) And (lsFileName <> &quot;..&quot;) Then
                    'create a new sub menu
                    hSubMenuNew = CreatePopupMenu()
                    'insert it
                    InsertMenu hSubMenu, 0, MF_BYPOSITION Or MF_POPUP, hSubMenuNew, lsFileName
                    'and keep on searching..
                    EnumFiles Path & lsFileName, hSubMenuNew
                End If
            Else
                'is file
                If ((WFD.dwFileAttributes Or FILE_ATTRIBUTE_HIDDEN) <> WFD.dwFileAttributes) Then
                    'scale array of url's and add destination of current file
                    ReDim Preserve ShortCutPath(liMenuID)
                    ShortCutPath(liMenuID) = GetShortCutPath(Path & lsFileName)
                    'remove file extension
                    If Mid$(lsFileName, Len(lsFileName) - 3, 1) = &quot;.&quot; Then
                        lsFileName = Left$(lsFileName, Len(lsFileName) - 4)
                    End If
                    'create a new menu item
                    AppendMenu hSubMenu, MF_STRING, liMenuID + 1000, lsFileName
                    liMenuID = liMenuID + 1
                End If
            End If
        Loop Until FindNextFile(hFile, WFD) = 0
    End If
End Sub

Public Function GetShortCutPath(ByVal FileName As String) As String

    Dim lsPath As String
    Dim liLength As Long
    
    lsPath = Space$(MAX_PATH)
    liLength = GetPrivateProfileString(&quot;InternetShortcut&quot;, &quot;URL&quot;, &quot;&quot;, lsPath, Len(lsPath), FileName)
    GetShortCutPath = Left$(lsPath, liLength)
End Function

And this you could put in a form:

Code:
Private Sub cmdCreate_Click()
    CreateFavoritesMenu Me.hWnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Hook Me.hWnd, False
End Sub

I've commented a little better than the previous version, and it now prints the url of the favorites-shortcut when you click the menu item, so you can actually use it.

Hope it doesn't only work on my computer..;-)

Remedy
 
Ah now! That’s excellent! It works fine on my computer, and works just fine in an MDI form too.

It doesn’t work when its added to a child form, but that’s okay, and for some odd reason it prevents the child form from maximizing properly, but again, that’s something I can work around.

I only have one problem with this now.....

It seems that the only menu that I can have on the form is the favorites menu! Is there a way to add other menus to the form as well as use this code?

Aside from this you have produced some exceptional work there and I am very grateful for it.
 
Glad I could help you out..

About the &quot;one problem&quot;:
Do you mean: how can I create a menu for a directory other than the favorites folder?
Or: how can I create any menu (using winapi)?

Remedy
 
No, what I mean is that when I use this code, any other menus that happen to be set up already (Via the VB GUI interface itself) are removed, leaving the favorites the only menu available.

It is not actually a problem right now; most of the stuff that would have been on menus can be added to a toolbar, but it would be good to be able to keep menus that already exist.

As to making a menu using winapi - I don’t think I would be able to get to grips with that yet - I did look at several bits of code that were meant to do what you have done here, and they used winapi and just seemed an incredible mess! (Not many actually worked either!)

Anyway, thanks again - Great work.
 
Ah, in that case, remove this bit of code:
Code:
If hMenu Then DestroyMenu hMenu
hMenu = CreateMenu()
I used this to make sure that the favorites menu isn't created twice (by destroying every menu on the window and create a new one). That's not the best to do it, to say the least. Just being lazy.

This line:
Code:
hMenu = GetMenu(hWnd)
is used to get a handle to the menu(bar) of the window. So if there are already menus present on the form, we can use this handle to add the favorites menu. If it would be the first menu to be placed on the form, you's have to create a new menu.

By the way, in this line:
Code:
InsertMenu hMenu, 1, MF_BYPOSITION Or MF_POPUP, hSubMenu...
you can specify the position where to place the new menu (because the MF_BYPOSITION flag is used). In this example it's 1, which means that it will be the second menu from the left (unless the are no other menu's).

Remedy
 
Excellent job! Ill be looking at this as soon as I get home tonight!

Thanks very much!
 
Hi Remedy, I just want to say this is an EXCELLENT tutorial. I'm having a problem exiting my app in WinXP. I can exit by clicking on X, but when I try to exit from a command button, the click event doesn't even fire. Any idea how to fix this?
 
ponerse

Since your problem isn't even slightly connected to the rest of this thread you should start a new thread.

Have a look at faq222-2244 as well. It may help you ask a clearer question.

BTW if the command button click event doesn't fire:
1. Is enable set to True
2. Is there code in the Mousedown event
3. Is the form Mousedown catching the event
4. Does it work with the keyboard or mouse or neither
________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'People who live in windowed environments shouldn't cast pointers.'
 
John, I'm sorry, I didn't really explain it that well. I used remedy's module for adding the favorites into a menu, and it loads the favorites in just fine. The problem is, when I click on any sort of command button, the click event doesn't even fire. The only way to exit is to click the X. I think it may be do to hooking but I'm not really strong on hooking. This is happening on win98 and winXP. Hope this explains it a little bit better :)
 
Just want to say thanks for the compliment. If you'll post your question regarding the mysterious x-button as a new thread, I (or others) might be able to help you. Hooking window procedures can easily lead to strange side-effects, so that could be the problem. And provide sample code, that always makes things clearer.

Remedy
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top