bjay55 Posted May 3, 2005 Posted May 3, 2005 How would I restore a program that is in the system tray to normal from another program. Could I do this by using the handle of this program and if so how would I get the handle. Any help greatly appreciated. Thankyou Quote
mark007 Posted May 4, 2005 Posted May 4, 2005 It depends on how you can retsore it manually from the system tray. If you have to go via a right-click menu for exmaple then maybe not but if it is a double click or single click then you could send a Tray events message using the Sendmessage API. To get the handle of the other app you need to use the FindWindow API. Not sure off the top of my head whather the window still exists when the item is in the systray - may well be application specific. I suggest using something like Spy++ or Winspector Spy to check for it when it is minimised to the taskbar. Check out: http://www.mentalis.org/index2.shtml for more info on the API's involved. Hope that helps. :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
mark007 Posted May 4, 2005 Posted May 4, 2005 In fact thinking about it more if you gave the hanlde and the window does still exists but it's hiden you could use SetWindowLong to display it again. Would probably be safer to send a tray message though as then any intialistaion type stuff that might be doen when it is reshown from the tray would be done. :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 4, 2005 Author Posted May 4, 2005 What I have so far Thank you for your reply and help. Here is what I have come up with so far. Dim appProcesses As Process() = _ Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName) If appProcesses.Length > 1 Then Dim time As Date = appProcesses(0).StartTime Dim time2 As Date = appProcesses(1).StartTime If time < time2 Then handle = appProcesses(0).MainWindowHandle.ToInt32 Else handle = appProcesses(1).MainWindowHandle.ToInt32 End If result = OpenIcon(handle) result = SetForegroundWindow(handle) End End If This code checks for a previous instance of the program and if there is one ends the current and brings the previous instance to front of all other windows. This works except when the program is minimized to the system tray. The value of handle when the program is minimized to the system tray is 0. Quote
mark007 Posted May 5, 2005 Posted May 5, 2005 For example just now I used Winspector Spy to find the class name of AVG antivirus which is in my systray. I then watched the messages for the message sent on Double-Click which was WM_USER+23. I then knocked up a windows app with a button on the form called Show AVG. The code behind the form is then: Public Class Form1 Inherits System.Windows.Forms.Form Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Int32) As Int32 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32 'Windows Form Designer Generated Code Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'find avg handle Dim hWnd As Int32 Const WM_USER As Int32 = &H400 Const msg As Int32 = WM_USER + 23 hwnd = FindWindow("AVG70ControlCenter", 0&) 'show it SendMessage(hWnd, msg, 0&, 0&) End Sub End Class Hope that helps. :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 5, 2005 Author Posted May 5, 2005 Finally got it, thank you I really appreciate your help, Thankyou very much. I got what I neede to work, thankyou. I have just started programming not to long ago and am just starting to learn how to use the api. This is really cool, you can do just about anything with the api it seems. I am working on another problem which is : when you change the background color of the desktop in the desktop settings window, I am trying to figure out how windows does it. After change the registry value "Control Panel\Colors-Background, they are able to update or refresh the windows background according to the new color value in the registry. I watched the messages as I changed the background color but one of them is 0x0000031a and I don't know what that is. Once agian, thank you for your help. greatly appreciated. Quote
mark007 Posted May 5, 2005 Posted May 5, 2005 You could try the following: private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Int32, ByVal uParam As Int32, ByVal lpvParam As Int32, ByVal fuWinIni As Int32) As Int32 Private Const SPI_SETDESKPATTERN as Int32 = 21 Private Const SPIF_UPDATEINIFILE as Int32 = &H1 SystemParametersInfo SPI_SETDESKPATTERN, 0&, 0&, SPIF_UPDATEINIFILE :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 5, 2005 Author Posted May 5, 2005 Good Idea But Did Not Work I tried what you said with the spi_setdeskpattern but it did not work. I also tried spi_setdeskwallpaper and it did not work either. I am trying to follow the messages from the desktop while I change the background color with the display properties window to figure out which messages I could send to the desktop to get it to change the background color according to the regestry value. Do you think this could eventually lead to a solution? Quote
mark007 Posted May 5, 2005 Posted May 5, 2005 Hmm, ok try this one: Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Int32, ByVal msg As Int32, ByVal wParam As Int32, ByVal lParam As String, ByVal fuFlags As Int32, ByVal uTimeout As Int32, lpdwResult As Int32) As Int32 Private Const HWND_BROADCAST As Long = &HFFFF& Private Const WM_SETTINGCHANGE = &H1A& Private Const SMTO_ABORTIFHUNG = &H2& Dim Result as Int32 SendMessageTimeout HWND_BROADCAST, WM_SETTINGCHANGE, _ SPI_SETNONCLIENTMETRICS, 0&, SMTO_ABORTIFHUNG, _ 10000&, Result :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 5, 2005 Author Posted May 5, 2005 Still does not work The desktop still does not change color. You can see that the desktop icons are being refreshed because they flicker but the background color does not change. Quote
mark007 Posted May 6, 2005 Posted May 6, 2005 Could try with: SPI_SETDESKPATTERN instead of: SPI_SETNONCLIENTMETRICS Though I suspect this may ahve the same effect as post #7 above. Will keep looking.. :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
mark007 Posted May 6, 2005 Posted May 6, 2005 OK, the following might do it. I think this will give a temporary instant fix which you can combine with the long term registry fix: Private Declare Function SetSysColors Lib "user32" Alias "SetSysColors" (ByVal nChanges As int32, lpSysColor As Int32, lpColorValues As Int32) As Int32 Private Const COLOR_BACKGROUND as Int32 = 1 'Colour of the background with no wallpaper 'not sure of .Net equivalent of RGB function so that will need changing SetSysColors(1, COLOR_BACKGROUND, RGB(255, 0, 0)) :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 6, 2005 Author Posted May 6, 2005 The setsyscolors does get the job done, but it refreshes all the windows open at the time. If internet explorer is open it causes a pretty ugly flash, so it will work temporarily but I think I will keep trying to find a permanent fix. Hey, thanks alot for your help. See ya later. Quote
mark007 Posted May 7, 2005 Posted May 7, 2005 I don't think any solution would avoid the flash as that would happen on any update. What I meant by temporary was that I'm not sure this sets the registry setting for you so you might have to do that in addition for a permanent colour change i.e. on reboot. In any case glad I finally found the API that did it! :) Quote Please check the Knowledge Base before you post. "Computers are useless. They can only give you answers." - Pablo Picasso The Code Net
bjay55 Posted May 7, 2005 Author Posted May 7, 2005 Thanks Hey, Thanks for your help, I really appreciate it. I actually don't need the color change to be permanent so I'm alright. Thanks Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.