-
May 18th, 2012, 02:09 AM
#1
How to remove the systray icon of another application
To restore an application from "minimize to system tray" mode to "Normal" mode (visible) from another application, I am using "Showwindow" method of "user32.dll". The API is working as expected i.e. displaying the application on Normal mode.
Moreover, I want to remove that application's System tray icon as soon as its mode changes from "minimize to system tray" to "Normal".
I had tried using "Shell_NotifyIcon" method of "shell32.dll" by passing "NIM_DELETE" & reference of "NOTIFYICONDATA" but no luck.
The API method declaration is as follows:
Shared Function Shell_NotifyIcon(ByVal dwMessage As UInteger, ByRef pnid As NOTIFYICONDATA) As Boolean
Can anyone suggest me a solution for solving this issue.
-
May 22nd, 2012, 06:27 AM
#2
Re: How to remove the systray icon of another application
may be that you are using the wrong application pointer in your Shell_NotifyIcon API. May also be that your datat types are mixed up. We need more code, especially the code where you obtain the Window's handle
-
May 22nd, 2012, 07:21 AM
#3
Re: How to remove the systray icon of another application
Thanks HanneSThEGreaT!
May be you are right, because I am not very well aware of how to use 'NOTIFYICONDATA' Structure.
Here is my code, correct me where I am going wrong.
Code:
Private Const NIM_DELETE As Integer = &H2
Dim nid As NOTIFYICONDATA
Dim HWnd As Integer
HWnd = FindWindow(Nothing, "My Systray Minimized Application Title")
ShowWindow(HWnd, SW_RESTORE)
With nid
.cbSize = Len(nid)
.hWnd = HWnd
.uID = MinAppProcessID
End With
Shell_NotifyIcon(NIM_DELETE, nid)
-
May 22nd, 2012, 07:46 AM
#4
Re: How to remove the systray icon of another application
Hmm, OK. At a quick glance it looks as if your code is correct.
I have come accross this issue once. I had to use the SendMessage API to send a WM_PAINT message to the system tray - where all notifyicons reside.
Try this code :
Code:
Public Class Form1
Dim WM_PAINT As Integer = 15
Private Declare Function SendMessage Lib "USER32.DLL" (ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal character As Integer, ByVal lpsText As IntPtr) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Send WM_PAINT Message to paint System Tray which will refresh it.
SendMessage(traynotifywnd, WM_PAINT, 0, IntPtr.Zero)
End Sub
End Class
After the call to delete the Sehll_Notify Icon, so your code should look more or less like :
Code:
Private Const NIM_DELETE As Integer = &H2
Dim WM_PAINT As Integer = 15
Private Declare Function SendMessage Lib "USER32.DLL" (ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal character As Integer, ByVal lpsText As IntPtr) As Integer
Dim nid As NOTIFYICONDATA
Dim HWnd As Integer
HWnd = FindWindow(Nothing, "My Systray Minimized Application Title")
ShowWindow(HWnd, SW_RESTORE)
With nid
.cbSize = Len(nid)
.hWnd = HWnd
.uID = MinAppProcessID
End With
Shell_NotifyIcon(NIM_DELETE, nid)
'Send WM_PAINT Message to paint System Tray which will refresh it.
SendMessage(traynotifywnd, WM_PAINT, 0, IntPtr.Zero)
I hope it helps!
-
May 22nd, 2012, 08:14 AM
#5
Re: How to remove the systray icon of another application
Thanks HanneS!
I had tried your code but its not working for me.
I had passed my window's handle i-e; Hwnd to SendMessage.
Code:
SendMessage(HWnd , WM_PAINT, 0, IntPtr.Zero)
Is it right? or I had to get 'traynotifywnd' by someother way.
-
May 22nd, 2012, 08:46 AM
#6
Re: How to remove the systray icon of another application
OK, I had a decent look again at your first code... May be we are in fact not getting the proper handle of the window. So, the problem must be with your FindWindow statement.
Have a look here :
http://www.pinvoke.net/default.aspx/user32.findwindow
Last resort, if the above doesn't help. attach your project here in Zip format, then we can have a proper look
-
May 23rd, 2012, 01:56 AM
#7
Re: How to remove the systray icon of another application
I have checked the link.
I had passed the same handle to showwindow & it is displaying the desired window so there should not be any issue with findwindow statement.
I had also tried sendmessage other overloads but no luck.
Let me debug my code to find out the exact scenario.
-
May 23rd, 2012, 03:46 AM
#8
Re: How to remove the systray icon of another application
Hmm, OK, I am running out of ideas. It's getting difficult to establish where things go wrong without seeing your project. I am also starting to think that this external program was programmed to have the icon remain in the System tray.
Perhaps we could send a double click message to the icon :
Code:
SendMessage(HWnd, WM_USER, 0, WM_LBUTTONDBLCLK)
If that doesn't work, I am stumped.
-
May 23rd, 2012, 06:02 AM
#9
Re: How to remove the systray icon of another application
Thanks Hannes!
I had tried using "PostMessage" API method by passing 'WM_CLOSE' to it, it closes the said application.
Code:
PostMessage(HWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)
Do you know what parameter should be passed instead of WM_CLOSE for removing only the Icon of that application from tray.
-
May 23rd, 2012, 08:48 AM
#10
Re: How to remove the systray icon of another application
Thanks for what? Truthfully, I wasn't much help hahaha
Anyways, you'd have to send a WM_MOUSEMOVE event or something similar to that window, here is an off-the-cuff example :
Code:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByClass( _
ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByCaption( _
ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _
ByVal childAfter As IntPtr, _
ByVal lclassName As String, _
ByVal windowTitle As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Const WM_MOUSEMOVE = &H200
Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim tmpWnd&
Dim res As IntPtr
tmpWnd = FindWindow("Shell_TrayWnd", vbNullString) 'Task bar
tmpWnd = FindWindowEx(tmpWnd, 0&, "TrayNotifyWnd", vbNullString) 'System tray
res = SendMessage(tmpWnd, WM_MOUSEMOVE, New IntPtr(1), MakeLParam(80, 160))
End Sub
Shared Function MakeLParam(ByVal LoWord As Integer, ByVal HiWord As Integer) As IntPtr
Return New IntPtr((HiWord << 16) Or (LoWord And &HFFFF))
End Function
End Class
Or even broadcast a system setting change...
Code:
Declare Auto Function SendMessageTimeout Lib "User32" ( _
ByVal hWnd As Integer, _
ByVal Msg As UInt32, _
ByVal wParam As Integer, _
ByVal lParam As Integer, _
ByVal fuFlags As UInt32, _
ByVal uTimeout As UInt32, _
ByRef lpdwResult As IntPtr _
) As Long
Private Const HWND_BROADCAST = &HFFFF&
Private Const WM_SETTINGCHANGE = &H1A
Private Const SMTO_ABORTIFHUNG = &H2
Public Sub EnvRefresh ( )
Dim dwResult As IntPtr '
SendMessageTimeout(HWND_BROADCAST, _
Convert.ToUInt32(WM_SETTINGCHANGE), _
0, 0, _
Convert.ToUInt32(SMTO_ABORTIFHUNG), _
Convert.ToUInt32(5000), _
dwResult)
MsgBox(dwResult)
That is as far as my abilities goes
-
May 23rd, 2012, 12:17 PM
#11
Re: How to remove the systray icon of another application
Thanks for sparing your time & giving me different ideas for solving my issue.
Really, it's because of your help I am able to look & try different techniques for this issue.
I had already tried the similar code for 'sending a WM_MOUSEMOVE event' before, but didn't used 'MakeLParam'. Let me try it.
I'll let you know after trying both of your suggestions.
-
May 23rd, 2012, 02:47 PM
#12
Re: How to remove the systray icon of another application
Please let me know how it goes. I'm hoping for the best. Good luck!
-
May 24th, 2012, 02:14 AM
#13
Re: How to remove the systray icon of another application
Hi Hannes!
It looks I am having a bad luck, tried both of your suggestions, but none of it did the trick for me.
Now, looking for someother possible way of solving this issue.
Thanks for your help!
-
May 24th, 2012, 02:56 AM
#14
Re: How to remove the systray icon of another application
That is indeed bad news
Attach your project here, then we could have a look and see how we can solve this.
Tags for this Thread
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
|