openframeworks / openframeworks/openFrameworks

Feature Request: Add windows TrayMode

Open
#2,167 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

core feature
Dominant language
C++
Stars
10.4k
Forks
2.6k
Avg merge
1d 21h
Merged PRs (30d)
9

Description

ofAppGlutWindow.cpp

#ifdef TRAYMODE
#include "shellapi.h"
#include "WinDef.h"
#define WM_NOTIFY_ICON WM_USER+100//custom ico
#define IDC_BUTTON_EXIT WM_USER+101//custom exit message
#define IDC_BUTTON_SHOW WM_USER+102//custom show message
#define IDI_ICON1 100
#endif

#ifdef TRAYMODE
void ShowTask(WPARAM wParam,LPARAM lParam)
{
    if(wParam==IDI_ICON1){
        switch(lParam)
        {
        case WM_RBUTTONUP:
            {
                tagPOINT point;
                GetCursorPos(&point);
                HMENU hMenu;
                hMenu=CreatePopupMenu();

                AppendMenu(hMenu,MF_STRING,IDC_BUTTON_SHOW,L"show");
                AppendMenu(hMenu,MF_SEPARATOR,0,NULL);
                AppendMenu(hMenu,MF_STRING,IDC_BUTTON_EXIT,L"exit");

                TrackPopupMenu(hMenu,TPM_LEFTALIGN,point.x,point.y,NULL,handle,NULL);
            }
            break;
        case WM_LBUTTONDOWN:
            {
                ShowWindow(handle,SW_SHOW);  
                ShowWindow(handle,SW_SHOWNORMAL); 
            }
            break;
    }
}
#endif

static LRESULT CALLBACK winProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam){

   //we catch close and destroy messages
   //and send them to OF

   switch(Msg){

      case WM_CLOSE:
#ifdef TRAYMODE
          ShowWindow(handle,SW_HIDE);
#else
           OF_EXIT_APP(0);
#endif
      break;
      case WM_DESTROY:
         OF_EXIT_APP(0);
         break;
      case WM_DROPFILES:
            // Call our function we created to display all the files.
            // We pass the wParam because it's the HDROP handle.
            HandleFiles(wParam);
            break;

#ifdef TRAYMODE

      case WM_NOTIFY_ICON:
          ShowTask(wParam,lParam);
          //cout<<"WM_MYMESSAGE"<<endl;
          break;
      case WM_COMMAND:
          switch(wParam)
          {
          case IDC_BUTTON_SHOW:
              ShowWindow(handle,SW_SHOW);
              break;
          case IDC_BUTTON_EXIT:
              NOTIFYICONDATA nid;
              nid.hWnd = handle;
              nid.uID = IDI_ICON1;
              nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
              nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
              nid.uFlags = NIF_MESSAGE|NIF_ICON;
              nid.uCallbackMessage = WM_NOTIFY_ICON;
              Shell_NotifyIcon(NIM_DELETE,&nid);  
              EndDialog(handle,0);
              DestroyWindow(handle);
              break;
          }
          break;
#endif
      default:
         return CallWindowProc(currentWndProc, handle, Msg, wParam, lParam);
      break;
    }

    return 0;
}
#ifdef TRAYMODE
void toTray(HWND handle)
{
    NOTIFYICONDATA nid;
    nid.cbSize = sizeof(NOTIFYICONDATA);
    nid.hWnd = handle; //the hWnd and uID members allow the OS to uniquely identify your icon. One window (the hWnd) can have more than one icon, as long as they have unique uIDs.
    nid.uID = IDI_ICON1;
    nid.uCallbackMessage = WM_NOTIFY_ICON;
    nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    //nid.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON2);
    nid.uFlags = //some flags that determine the tray's behavior:
        NIF_ICON //we're adding an icon
        | NIF_MESSAGE //we want the tray to send a message to the window identified by hWnd when something happens to our icon (see uCallbackMesage member below).
        | NIF_TIP; //our icon has a tooltip.
    lstrcpy(nid.szTip, L"my exe");
    //strcpy(nid.szTip, "My very own system tray icon!"); //this string cannot be longer than 64 characters including the NULL terminator (which is added by default to string literals).
    //There are some more members of the NOTIFYICONDATA struct that are for advanced features we aren't using. See sources below for MSDN docs if you want to use balloon tips (only Win2000/XP).
    Shell_NotifyIcon(NIM_ADD, &nid); //add ico
}
#endif

//--------------------------------------
static void fixCloseWindowOnWin32(){

    //get the HWND
    handle = WindowFromDC(wglGetCurrentDC());

    // enable drag and drop of files.
    DragAcceptFiles (handle, TRUE);
#ifdef TRAYMODE
    toTray(handle);
#endif
    //store the current message event handler for the window
    currentWndProc = (WNDPROC)GetWindowLongPtr(handle, GWL_WNDPROC);

    //tell the window to now use our event handler!
    SetWindowLongPtr(handle, GWL_WNDPROC, (long)winProc);

}

#endif

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ofAppGlutWindow.cpp and inspect the existing TRAYMODE sections, including fixCloseWindowOnWin32, winProc, ShowTask, and toTray. Verify how the Win32 window messages and tray icon lifecycle fit the current implementation. Done means a Windows application can hide to the tray, show again, and exit while removing its tray icon.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, operating-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.