Complete guide to System Tray programming (2)

Source: Internet
Author: User
Tags implement resource

In the first part of this article, we discussed and demonstrated how to apply the system tray icon in your own program. By using a reusable C + + class--ctrayicon that you have created, we can easily implement the pallet program. I used this class to write a program not long ago, it's normal to start running, but there's a reason why Windows Explorer is dead, which means it's not shutting down properly, and when you restart Explorer, you find that the tray program is still running, but the tray icon doesn't show up, and the tray icon is not visible in the taskbar. Only reboot the machine to display the tray icon, people feel very uncomfortable, there is no way at this time without restarting the machine and let Windows automatically retrieve the tray icon and add it to the taskbar? , that is, let it automatically restore the tray icon Program user interface, after a study, finally some harvest.

In fact, if you're using Windows 98 or you've installed the IE4.0 desktop. So whenever IE4.0 starts the taskbar, it broadcasts a registration message to all top-level parent windows: taskbarcreated. With this clue, you can recreate the icon. If you are programming with MFC, simply define a whole variable to save the registration message and implement the On_registered_message message processing routines:

const UINT WM_TASKBARCREATED =
  ::RegisterWindowMessage(_T("TaskbarCreated"));
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  ON_REGISTERED_MESSAGE(WM_TASKBARCREATED,
             OnTaskBarCreated)
END_MESSAGE_MAP(CMainFrame, CFrameWnd)
   The handler itself should reinstall whatever icons you need.
LRESULT CMainFrame::OnTaskBarCreated(WPARAM wp, LPARAM lp)
{
  VERIFY(InstallIcons());
  return 0;
}
BOOL CMainFrame::InstallIcons()
{
  NOTIFYICONDATA nid;
  //
  // 准备 nid 参数
  //
  return Shell_NotifyIcon(NIM_ADD, &nid);   

Is it that easy? Of course not, you have to implement the Installicons function individually, instead of calling Shell_NotifyIcon directly from ontaskbarcreated, because generally you will call it when the application is started.

When I figured out the secret of taskbarcreated, I went back to the Ctrayicon class that I created in the first part of this article, modified it and perfected it, and it didn't change very much. This class manages a single tray icon (if you have multiple, create a separate instance for each icon). When using Ctrayicon, you simply create an instance in CMainFrame M_trayicon and install it as follows:

// 在CMainFrame::OnCreate中
m_trayIcon.SetNotificationWnd(this,
  WM_MY_TRAY_NOTIFICATION);
m_trayIcon.SetIcon(IDI_MYICON);   

Wm_my_tray_notification is its own private message, and only when an event occurs does the tray icon send this message, such as when the user clicks the icon. For a tray icon, you don't have to do anything with it, and Ctrayicon is solely responsible. Just when you're constructing a Ctrayicon object, you can give it a resource ID. Ctrayicon uses this ID to find the context menu, and if found, it automatically handles the right click Tray icon event, which pops up the context menu. If the user double-clicks the icon, Ctrayicon executes the first menu item command. So all you have to do is create a menu resource, pass the ID to the constructor, and then drive the Ctrayicon. If you want some non-standard routines, just deal with Wm_my_tray_notification. Please refer to the source code for details.

To realize the feature of automatic icon reconstruction, I used a class CSubclassWnd used in many previous articles, and this class was almost ubiquitous in my programming career. Without it, I could hardly do anything; it is one of the most useful classes in all my programming know-how. You can use this class to intercept Windows messages and send it to another window message processing routine to process, rather than send to Windows ' own default message handler function. Ctrayicon uses it to intercept taskbarcreated messages, so you don't have to write a message handler for that--this is a cool way to do it. CSubclassWnd the message by installing its own window procedure, which is preceded by an MFC step.

When CMainFrame calls Ctrayicon::setnotificationwnd, Ctrayicon calls Gettoplevelparent to get the top-level parent window and then installs the CSubclassWnd window procedure, which is equivalent to a hook , the CSubclassWnd window process is processed before the message reaches any top-level window. It must be understood here that Windows sends only taskbarcreated messages to the top-level parent window. It's a bit like Wm_querynewpalette, wm_syscolorchange messages, and other top-level window messages. Now when Windows sends taskbarcreated, control is first passed to Ctrayicon::ctrayhook::windowproc.

Ctrayicon::ontaskbarcreate is a new virtual function in the Ctrayicon class, whose default implementation is to reinstall the icon in the system tray. If you want to do something else, you can derive a new class and override this default behavior. The actual WindowProc code is slightly more complicated than what I described in this article, because it also handles pallet notifications to drive the default menu-processing routines, which previously, when wm_my_tray_notification messages were obtained, You must call Ontraynotification yourself. For a new Ctrayicon implementation please refer to the source code in this article.

By the way, do you want to know how I tested the feature of automatic reconstruction of icons? (If it were you, what would you do?) ), very easily. In Windows 98, press Ctrl+alt+del to eject the Task Manager's task list. Select Resource Manager (Explorer), and then select End Task. The Shutdown/Restart dialog box appears, and the Cancel button is pressed (do not press the shutdown button). Then, wait a few seconds, and you get the message that "this task is not responding," and then you need to reply with "end of task." The next Windows Resource Manager will not terminate properly! It then automatically gets up again and broadcasts taskbarcreated messages to all top-level parent windows. If your operating system is Windows NT/2000/XP and installs the IE4.0, do the same. When the taskbar dies, tap the Explorer initiator Source Manager from the Run dialog box on the Start menu. Regardless of the operating system, before killing the taskbar, if the Traytest program is running, the tray icon for the Traytest program is automatically innovated when the resource manager recovers its status. If you don't believe it, you can try it with the example program in the first part of this article and the sample program provided in this article. You will find that the example program in this article will handle taskbarcreated messages, while the other will not. adjourned

This article supporting source code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.