Solved

Tray application.

Posted on 1998-11-29
2
305 Views
Last Modified: 2010-04-01
I am trying to write a tray based application, and need to know how to do it. I want a menu when you click on the icon in the tray, that pops up different dialogs for different purposes. I did use the traynot example once, but that did not provide a menu. For the points offered, could someone tell me where I can download the source. (I don't have my MSVC++CD to hand - bummer), and the msdn keeps producing a 404 - file not found error.

For 200 points though, could someone produce a skeleton app. with dialog/menu and string table resources

Thanks,
Nigel.
0
Comment
Question by:nigel5
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 11

Accepted Solution

by:
alexo earned 200 total points
ID: 1178797
Nigel, there is no such thing as a "tray based application".  Any application can create one or several tray icons using the Shell_NotifyIcon() API.

Here's a sample source:

////////////////////////////////////////////////////////////////////////////////

// Disable some warnings on Windows include files
#pragma warning(disable: 4514)      // Unreferenced inline function
#pragma warning(disable: 4201 4214) // Non-standard extensions

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>

#pragma warning(default: 4201 4214)

#include "resource.h"

////////////////////////////////////////////////////////////////////////////////

#define APP_NAME            "My App"        // Application name
#define MYWM_NOTIFYICON     (WM_USER + 1)   // Tray notification message

////////////////////////////////////////////////////////////////////////////////

// Local functions

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

////////////////////////////////////////////////////////////////////////////////

// Main routine

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    OSVERSIONINFO   version = { sizeof(OSVERSIONINFO) };
    NOTIFYICONDATA  nid     = { sizeof(NOTIFYICONDATA) };
    WNDCLASS        wc      = { 0 };

    HWND            hwnd;
    MSG             msg;

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    // Check windows version
    GetVersionEx(&version);
    if (version.dwMajorVersion < 4)
        return 0;

    // Register the window class for the application main window
    wc.style         = CS_HREDRAW | CS_VREDRAW;     // Class style(s)
    wc.lpfnWndProc   = (WNDPROC) WindowProc;        // Window Procedure
    wc.hInstance     = hInstance;                   // Owner of this class
    wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU);   // Menu
    wc.lpszClassName = APP_NAME;                    // Name to register as

    if (!RegisterClass(&wc))
        return 0;

    // Create a main window for this application instance.
    hwnd = CreateWindow(APP_NAME, APP_NAME,     // Class and title
                        WS_OVERLAPPEDWINDOW,    // Window style
                        CW_USEDEFAULT, 0,       // Use default positioning
                        CW_USEDEFAULT, 0,       // Use default size
                        NULL, NULL,             // No parent, no menu
                        hInstance,              // This instance owns this window
                        NULL);                  // Don't need data in WM_CREATE
    if (!hwnd)
        return 0;

    // Link with tray icon
    nid.hWnd = hwnd;
    nid.uID = IDI_TRAYICON;
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    nid.uCallbackMessage = MYWM_NOTIFYICON;
    nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRAYICON));
    lstrcpy(nid.szTip, APP_NAME);

    if (!Shell_NotifyIcon(NIM_ADD, &nid))
        return 0;

    // Acquire and dispatch messages until a WM_QUIT message is received.
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);  // Translates virtual key codes
        DispatchMessage(&msg);   // Dispatches message to window
    }

    // Delete tray icon
    Shell_NotifyIcon(NIM_DELETE, &nid);

    // Adios!
    return 1;
}

////////////////////////////////////////////////////////////////////////////////

// Main window message processing procedure

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        // Tray icon notification message
        case MYWM_NOTIFYICON:
            // Button event is single click?
            if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN)
            {
                POINT   pos;

                // Show and process menu
                // SetForegroundWindow() and PostMessage() used to circumvent a Win95 bug
                GetCursorPos(&pos);
                SetForegroundWindow(hwnd);
                TrackPopupMenuEx(GetSubMenu(GetMenu(hwnd), 0), TPM_HORIZONTAL, pos.x, pos.y, hwnd, NULL);
                PostMessage(hwnd, WM_NULL, 0, 0);
            }

            break;

        // Menu commands
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                // Check menu commands here...
            }

            break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    } // switch (msg)

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

Of course, you also have to have a menu resource and an icon resource.

The Relevant portion of the .RC file will look like this:

IDR_MENU MENU DISCARDABLE
BEGIN
    POPUP "Menu"
    BEGIN
        MENUITEM "About",                       IDM_ABOUT
        MENUITEM SEPARATOR
        MENUITEM "Exit",                        IDM_EXIT
    END
END

IDI_TRAYICON            ICON    DISCARDABLE     "MyApp.ico"


And the usual "resource.h" that defines the resource constants...

0
 

Author Comment

by:nigel5
ID: 1178798
Adjusted points to 200
0

Featured Post

Enroll in June's Course of the Month

June's Course of the Month is now available! Every 10 seconds, a consumer gets hit with ransomware. Refresh your knowledge of ransomware best practices by enrolling in this month's complimentary course for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

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

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

729 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