Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 10-11-2006, 16:44
MarkusO
 
Posts: n/a
"minimize to tray" function - clean programming

I'm currently trying to add a "minimize to tray" function to one of my programs. But I'm usure how the code should work correctly, since currently I'm using a some invalid code (but for some reason it works).

The program uses a DialogBox as main window and works like the pseudo code below (number of function parameters here is NOT correct - it's just pseudo code):
Code:
if (cmd = WM_SYSCOMMAND)
{
  if (wParam = SC_MINIMIZE)
  {
// Variant 1
    ShowWindow(SW_HIDE)
    return FALSE

// Variant 2
    ShowWindow(SW_HIDE)
    return TRUE

// Variant 3
    SendMessage(SC_MINIMIZE)
    ShowWindow(SW_HIDE)
    return FALSE

// Variant 4
    DefWindowProc()
    ShowWindow(SW_HIDE)
    return FALSE
  }
}
Variant 1:
The DialogBox vanishes without the default minimizing animation and will not disappear from the taskbar.

Variant 2:
The DialogBox vanishes and is removed from the taskbar, but the minimizing animation is not shown. When restoring the DialogBox from the tray icon by calling ShowWindow(SW_SHOW) and SendMessage(SC_RESTORE), it is visible at once and not restored with the default restore animation. It's no "minimize to tray", but just a "hide to tray" function.

Variant 3:
As you might have guessed, it's an infinite loop.

Variant 4:
The DialogBox is minimized to the taskbar and will be hidden after that. It's exactly what I want. Unhiding and restoring works also like I want it.

The problem is that I'm using "DefWindowProc". It is only a valid call in window procedures, not in dialog box procedures. "DefDlgProc" is also invalid, since it will produce an infinite loop.

How do I code the "minimize to tray" function correctly, so that I'm using "clean" code and not some hack which works for some reason?

One other thing I would like to know it the following:

When disassembling some programs which have the "minimize to tray" function, I saw that many of then compare not "wParam", but "wParam & 0x0000FFF0" to SC_MINIMIZE. According to MSDN, wParam can be only one of the SC_* parameters and not some bitmask. Why would somebody use this code if it's not neccessary?

p.s. 1: I know why Variant 1-3 fails the way I coded it above, so please don't explain me that. But in my oppinion Variant 4 should fail too.

p.s. 2: The programs I disassembled for "minimize to tray" all use Variant 2 ("hide to tray"). For some reason I wasn't able to find the "minimize to tray" code in the programs which really minimize before hiding.

Last edited by MarkusO; 10-11-2006 at 16:48.
Reply With Quote
  #2  
Old 10-11-2006, 20:49
Av0id Av0id is offline
VIP
 
Join Date: Jan 2006
Posts: 399
Rept. Given: 112
Rept. Rcvd 111 Times in 69 Posts
Thanks Given: 0
Thanks Rcvd at 15 Times in 15 Posts
Av0id Reputation: 100-199 Av0id Reputation: 100-199
here you can found short description (c++, but it isn't hard to porting it to any language):
http://www.codeguru.com/Cpp/controls/statusbar/systemtray/article.php/c5933
Reply With Quote
  #3  
Old 10-11-2006, 20:55
condzero
 
Posts: n/a
This is an article from the Code Project that may suit your needs:

System Tray Icons - Minimize Your Application to the SysTray
By Daniel Zilcsak.

This article illustrates the use of Shell_NotifyIcon to create and manage System Tray icons. The article explains the basics of this operation and assists you in creating your own 'Minimize To Tray' applications. The source code provided with this article is designed to work with dialog-based applications, but it can easily be modified to work with a CFrameWnd or CWnd based application.

Code:
link: http://72.14.209.104/search?q=cache:m6gkjJygLB4J:https://secure.codeproject.com/shell/trayicons.asp+windows+code+minimize+to+tray+function&hl=en&gl=us&ct=clnk&cd=17&lr=lang_en
Demo project attached.

cheers
Attached Files
File Type: zip TrayIcons_demo.zip (17.7 KB, 5 views)
Reply With Quote
  #4  
Old 10-11-2006, 23:22
MarkusO
 
Posts: n/a
I think you didn't understand what I was asking for. I don't need to know how to use "tray icons". I know that myself, it's no problem and I didn't include it in my pseudo code above.

I want to know how to "hide" and "unhide" a window while still showing the animations for minimizing/restoring windows.

If you haven't disabled this visual feature in Windows, you will see a short (about 0.2 seconds) animation when minimizing/maximizing/restoring/resizing a window. This animation is missing when using "Variant 2" from above. If I use "Variant 4" I see the animation, but it is invalid code. Microsoft clearly says that you must not call "DefWindowProc" from DialogBox procudures or you will end up in an recursive infinite loop. "DefWindowProc" is only to be called from window procudures.

For some reason the code I posted works, but it is invalid code. I want to know how the correct code looks like.

The examples you posted only show how to create tray icons, not how to keep the animation.
Reply With Quote
  #5  
Old 10-12-2006, 16:55
_Ramirez_
 
Posts: n/a
You should get two rects. First one is for your app and the second one is for the tray. The second one is a bit tricky since taskbar can be positioned on all 4 sides of the screen. I'll try to find a code that does this...

Then:

1. Hide your main window
2. call BOOL WINAPI DrawAnimatedRects(HWND hwnd, int idAni, CONST RECT *lprcFrom, CONST RECT *lprcTo);
Reply With Quote
  #6  
Old 10-13-2006, 20:38
MarkusO
 
Posts: n/a
Yes, that is the kind of API I was looking for. The problem now is that the animation is displayed always, even if the user has disabled this option for all windows.

The taskbar dimensions can be found quite simple with "FindWindowEx" and "GetWindowRect".
Reply With Quote
  #7  
Old 10-14-2006, 19:54
_Ramirez_
 
Posts: n/a
I think this is what you're looking for. First part is about finding the tray rect and the second one is about checking if animation is disabled.

Text taken from "Minimizing windows to the System Tray" by Matthew Ellis.
http://www.codeproject.com/shell/minimizetotray.asp

Determining the Animation Parameters

It’s not enough to know how to display the animation; we also need to know the start and end position. When minimizing, the “from�value is simple, you can use the RECT of the window. This gives us the correct width of the window, but the height is going to be larger than the caption bar. This is not a problem, however. We have told Windows that we are animating the caption, so Windows only uses the caption’s height.

The “to�value is slightly trickier. We need to get the RECT of the system tray. Unfortunately, there is no documented way to do this, and each method we can use has its downside.

The most accurate way of getting the system tray dimensions is to actually get the system tray’s window. Through judicious use of the very handy Spy++ utility, we can see that the system tray is a window of class “TrayNotifyWnd� which is a child of the top-level window of class “Shell_TrayWnd� We can easily get these windows using FindWindow, and then simply call GetWindowRect to get the dimensions of the system tray. As this gives the best results, this is the preferable method, but it must be remembered that this is undocumented and utilises window class names and hierarchies that might not exist in future versions of the shell, so mustn’t be relied upon. If this method fails, we drop through to the next method.

The nearest thing we can get to a documented method is to use the SHAppBarMessage function with the ABM_GETTASKBARPOS message. This will return us the bounding rectangle and edge position of the task bar. From this we can tell where the system tray is. If the edge position is the left or the right of the screen, the tray is at the bottom of the task bar. If the edge position is the top or the bottom of the screen, the tray is to the right of the screen. The only problem with this method is that it doesn’t give us the actual coordinates of the system tray, just the rough position - we have to give a default size for the system tray.

There is still the possibility that this will fail. This is really only likely if explorer has been replaced by a third party shell. Many of these shells now support a system tray (Shell_NotifyIcon sends a WM_COPYDATA message to a top level window of class “Shell_TrayWnd� which is the task bar) If we find this window, we can get some dimensions for the system tray.

If all else fails, we just use a default value in the bottom right of the screen.

Obviously enough, when maximizing, the “to�and “from�values are the opposite to when minimizing.


One Last Nicety

Windows allows the animation to be disabled (using a registry setting, or a tool such as the infamous TweakUI), so we must check for that before calling DrawAnimatedRects. This is a simple call to SystemParametersInfo, with the SPI_GETANIMATION value. If the animation has been disabled, the window is simply hidden; otherwise, we call DrawAnimatedRects.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Wlscgen: Are "Vendor Id" and "Developer Id" different ? Numega Softice General Discussion 6 02-12-2007 18:12
how to enable the function of "alt+f4" deadfish General Discussion 0 11-10-2003 21:19


All times are GMT +8. The time now is 17:51.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )