Solved

Clicking on the desktop won't minimise popup menu

Posted on 2004-08-27
10
209 Views
Last Modified: 2010-05-02
I've created a small app which runs in the system tray. The popup works fine except if I decide not to use any of the options and just click on the desktop to minimise the menu again (standard behaviour, basically) the menu just stays there until I select something. Can anyone tell me what I need to add to enable the menu to close? Here is the code:

' Type passed to Shell_NotifyIcon
Private Type NotifyIconData
  Size As Long
  Handle As Long
  ID As Long
  Flags As Long
  CallBackMessage As Long
  Icon As Long
  Tip As String * 64
End Type

' Constants for managing System Tray tasks, foudn in shellapi.h
Private Const AddIcon = &H0
Private Const ModifyIcon = &H1
Private Const DeleteIcon = &H2

Private Const WM_MOUSEMOVE = &H200
Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202

Private Const WM_RBUTTONDBLCLK = &H206
Private Const WM_RBUTTONDOWN = &H204
Private Const WM_RBUTTONUP = &H205

Private Const MessageFlag = &H1
Private Const IconFlag = &H2
Private Const TipFlag = &H4
     
Private Declare Function Shell_NotifyIcon _
  Lib "shell32" Alias "Shell_NotifyIconA" ( _
  ByVal Message As Long, Data As NotifyIconData) As Boolean

Private Data As NotifyIconData

Private Sub Form_Terminate()
  DeleteIconFromTray
End Sub

Private Sub AddIconToTray()

  Data.Size = Len(Data)
  Data.Handle = hWnd
  Data.ID = vbNull
  Data.Flags = IconFlag Or TipFlag Or MessageFlag
  Data.CallBackMessage = WM_MOUSEMOVE
  Data.Icon = Icon
  Data.Tip = Status1$ & vbNullChar
  Call Shell_NotifyIcon(AddIcon, Data)

End Sub

Private Sub DeleteIconFromTray()
  Call Shell_NotifyIcon(DeleteIcon, Data)
End Sub

Private Sub Form_MouseMove(Button As Integer, _
  Shift As Integer, X As Single, Y As Single)
 
  Dim Message As Long
  Message = X / Screen.TwipsPerPixelX
 
  Select Case Message
    Case WM_LBUTTONDBLCLK
      Visible = Not Visible
      WindowState = Abs(Not Visible)
     
     Case WM_RBUTTONDOWN
     Call Me.PopupMenu(rmenu, MenuVisible)
0
Comment
Question by:The__Saint
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 7

Expert Comment

by:Burbble
Comment Utility
Need the rest of your code :-)

Here's how I always do it:

modSysTray
-----
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long

Public Type NOTIFYICONDATA
    cbSize As Long
    hWnd As Long
    uID As Long
    uFlags As Long
    uCallbackMessage As Long
    hIcon As Long
    sTip As String * 64
End Type

Public SysTrayIcon As NOTIFYICONDATA

Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4
Public Const SW_RESTORE = 9
Public Const SW_MINIMIZE = 6
Public Const WM_MOUSEMOVE = &H200
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Public Const WM_LBUTTONDBLCLK = &H203
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_RBUTTONUP = &H205
Public Const WM_RBUTTONDBLCLK = &H206

Public Function SetIcon(IconPath As String)
    frmIcon.Icon = LoadPicture(IconPath)
    SysTrayIcon.hIcon = frmIcon.Icon
    Shell_NotifyIcon NIM_MODIFY, SysTrayIcon
End Function

Public Function SetIconToolTip(Text As String)
    SysTrayIcon.sTip = Text & vbNullChar
    Shell_NotifyIcon NIM_MODIFY, SysTrayIcon
End Function
-----

frmIcon
-----
Private Sub Form_Load()
    SysTrayIcon.cbSize = Len(SysTrayIcon)
    SysTrayIcon.hWnd = frmIcon.hWnd
    SysTrayIcon.uID = vbNull
    SysTrayIcon.uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP
    SysTrayIcon.uCallbackMessage = WM_MOUSEMOVE
    SysTrayIcon.hIcon = frmIcon.Icon
    SysTrayIcon.sTip = "InfiniTalk - Offline" & vbNullChar
    Shell_NotifyIcon NIM_ADD, SysTrayIcon
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim IconEvent As Long

    IconEvent = X / Screen.TwipsPerPixelX

    Select Case IconEvent
        Case WM_RBUTTONUP
            PopupMenu frmIcon.mnuMain
        Case WM_LBUTTONUP
            If frmMain.Visible = False Or (frmMain.WindowState = vbMinimized And frmMain.Visible = True) Then
                frmMain.WindowState = vbNormal
                frmMain.Visible = True
            ElseIf frmMain.Visible = True Then
                frmMain.Visible = False
            End If
    End Select
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Shell_NotifyIcon NIM_DELETE, SysTrayIcon
    Unload frmMain
    Set frmMain = Nothing
    Unload frmIcon
    Set frmIcon = Nothing
    End
End Sub
-----

You can modify it to your liking...

-Burbble
0
 

Author Comment

by:The__Saint
Comment Utility
Looking through this I couldn't see anything which stood out as to be the cause of my issue. I was hoping there maybe just a minor change I need to make to mine so I appreciate perhaps I didn't include everything I should have! Here is the lot (apologies for not cutting this slightly but I figure it's easier to look at in full):


' Type passed to Shell_NotifyIcon
Private Type NotifyIconData
  Size As Long
  Handle As Long
  ID As Long
  Flags As Long
  CallBackMessage As Long
  Icon As Long
  Tip As String * 64
End Type

' Constants for managing System Tray tasks, foudn in shellapi.h
Private Const AddIcon = &H0
Private Const ModifyIcon = &H1
Private Const DeleteIcon = &H2

Private Const WM_MOUSEMOVE = &H200
Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202

Private Const WM_RBUTTONDBLCLK = &H206
Private Const WM_RBUTTONDOWN = &H204
Private Const WM_RBUTTONUP = &H205

Private Const MessageFlag = &H1
Private Const IconFlag = &H2
Private Const TipFlag = &H4
     
Private Declare Function Shell_NotifyIcon _
  Lib "shell32" Alias "Shell_NotifyIconA" ( _
  ByVal Message As Long, Data As NotifyIconData) As Boolean

Private Data As NotifyIconData



Private Sub Form_Terminate()
  DeleteIconFromTray
End Sub

Private Sub AddIconToTray()

  Data.Size = Len(Data)
  Data.Handle = hWnd
  Data.ID = vbNull
  Data.Flags = IconFlag Or TipFlag Or MessageFlag
  Data.CallBackMessage = WM_MOUSEMOVE
  Data.Icon = Icon
  Data.Tip = Status1$ & vbNullChar
  Call Shell_NotifyIcon(AddIcon, Data)

End Sub

Private Sub DeleteIconFromTray()
  Call Shell_NotifyIcon(DeleteIcon, Data)
End Sub

Private Sub Form_MouseMove(Button As Integer, _
  Shift As Integer, X As Single, Y As Single)
 
  Dim Message As Long
  Message = X / Screen.TwipsPerPixelX
 
  Select Case Message
    Case WM_LBUTTONDBLCLK
      Visible = Not Visible
      WindowState = Abs(Not Visible)
     
     Case WM_RBUTTONDOWN
     Call Me.PopupMenu(rmenu, MenuVisible)

  End Select
End Sub


Private Sub MExit_Click()
Unload Form1
End Sub

Private Sub minbutton_Click()
AddIconToTray
Visible = False
End Sub
Private Sub MNIProxy_Click(Index As Integer)
Call NIPROXY_Click
End Sub

Private Sub MNoProxy_Click(Index As Integer)
Call NOPROXY_Click
End Sub

Private Sub MProxyDev_Click(Index As Integer)
Call PROXYDEV_Click
End Sub

Private Sub MStreaming_Click(Index As Integer)
Call stream_Click
End Sub

Private Sub NIPROXY_Click()

<code for subroutine>

End Sub

Private Sub Form_Load()

<Stuff>

Private Sub PROXYDEV_Click()
<code for subroutine>

Private Sub NOPROXY_Click()
<code for subroutine>

Private Sub stream_Click()
<code for subroutine>

Private Sub ToggleState()
   Visible = Not Visible
   WindowState = GetWindowState(Not Visible)
 End Sub

 Private Sub MenuVisible_Click()
   ToggleState
 End Sub
Private Function GetWindowState(ByVal Value As Boolean) As Integer

    GetWindowState = Abs(Value)
End Function

----------------------------------------------------------------------------------
Hope this make things clearer.

Cheers
0
 
LVL 7

Expert Comment

by:Burbble
Comment Utility
Hmm, I don't know what to say... The only real difference is this line:

    Call Me.PopupMenu(rmenu, MenuVisible)

compared to this:

    PopupMenu rmenu

Try changing it and see if that makes a difference... Otherwise, I am stumped.

-Burbble
0
 

Author Comment

by:The__Saint
Comment Utility
Thanks for your help Burbble, have tried changing it and it's exactly the same. I assumed it was standard behaviour of a popup menu to close when the desktop was clicked but obviously not!
I would think that I might need to add some code to the MenuVisible_Click procedure but I'm not sure how to detect for a right-click on the desktop. Of course, I may be barking up the wrong tree.
I'm going to up the points a bit as it doesn't appear to be quite a straightforward as I first thought it might be.
0
 
LVL 7

Expert Comment

by:Burbble
Comment Utility
I don't know. I posted a pointer question to hopefully draw other Experts to this question.

Sorry I can't help, hopefulyl someone else can :/

-Burbble
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 17

Accepted Solution

by:
zzzzzooc earned 150 total points
Comment Utility
The window from which the PopupMenu originates needs to have focus if I recall correctly.

Try using Call SetForegroundWindow(FormThatHasMenu.hWnd) before showing the PopupMenu.

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long


0
 
LVL 3

Expert Comment

by:nichia
Comment Utility
Taking the example from MS the call to SetForegroundWindow should do the trick, as zzzzzzzzzzzzzoooc has already mentioned.

Their example code:

Case WM_RBUTTONUP        '517 display popup menu
Result = SetForegroundWindow(Me.hwnd)
         Me.PopupMenu Me.mPopupSys
       End Select
0
 
LVL 3

Expert Comment

by:nichia
Comment Utility
Note also they use the button UP message.

The MS example is here:

http://support.microsoft.com/support/kb/articles/Q176/0/85.asp

Hope it helps!
0
 

Author Comment

by:The__Saint
Comment Utility
Yes this is what I needed. Problem solved. Thanks to everyone for taking time out, cheers Burble for bringing this to people attention and nichia for the link which helped finish it off. Much appreciated!
0
 
LVL 7

Expert Comment

by:Burbble
Comment Utility
Interesting... Glad you got it working :-)

-Burbble
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now