• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 310
  • Last Modified:

Tray application.

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
nigel5
Asked:
nigel5
1 Solution
 
alexoCommented:
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
 
nigel5Author Commented:
Adjusted points to 200
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now