Solved

Clicking on the desktop won't minimise popup menu

Posted on 2004-08-27
10
211 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
ID: 11918123
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
ID: 11945847
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
ID: 11948335
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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:The__Saint
ID: 11950093
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
ID: 11953558
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
 
LVL 17

Accepted Solution

by:
zzzzzooc earned 150 total points
ID: 11955295
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
ID: 11955624
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
ID: 11955653
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
ID: 11967729
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
ID: 11967787
Interesting... Glad you got it working :-)

-Burbble
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

837 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