不使用Shell_NotifyIcon,如何添加托盘图标?
或者Shell_NotifyIcon向系统发送的哪个消息呢?

解决方案 »

  1.   

    有点难度.这个是一个API应该是不发消息的
      

  2.   

    不用Shell_NotifyIcon是加不上去的,因为你的程序跟任务栏所在的shell属于不同的进程
      

  3.   

    Shell_NotifyIcon函数的功能说明: Sends a message to the taskbar's status area。
      

  4.   

    我想我大概知道了,不过需要试一下,应该是可以的,网上search的时候看到有不使用Shell_NotifyIcon这个API的,不过没有找到源代码
      

  5.   

    TB_INSERTBUTTON、TB_SETBUTTONINFO等TB_开头的消息。
      

  6.   

    这里的消息指的是NIM_ADD、NIM_DELETE等,就是Shell_NotifyIcon的第1个参数。
      

  7.   

    用Spy++等捕获一下 Shell_NotifyIcon 看它发送了什么消息..
      

  8.   


    Shell_NotifyIcon的功能描述:This function sends a message to the system to add, modify, or delete an icon from the taskbar status area. 看上去应该是可以的,网上也有说有不使用Shell_NotifyIcon的实现~只是没具体
      

  9.   

    MSDN上说是Shell_NotifyIcon这个函数就是给系统发添加、修改或者删除托盘图标的。
    系统托盘实际上就是一个ToolBar,所以是可以用消息来控制的,就是TB_开头的消息,不过这样添加的图标不会给你的程序发消息。
      

  10.   

    除了shell notifyicon,我不知道其他的办法。呵呵,有办法了就告诉我一下。
      

  11.   


    TCHAR const c_szTrayClass[] = TEXT(WNDCLASS_TRAYNOTIFY);
    BOOL AllowSetForegroundWindow(DWORD dwProcessId);STDAPI_(BOOL) Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA lpData)
    {
        HWND hwndTray;    SetLastError(0);        // Clean any previous last error (code to help catch another bug)    hwndTray = FindWindow(c_szTrayClass, NULL);
        if (hwndTray)
        {
            COPYDATASTRUCT cds;
            TRAYNOTIFYDATA tnd = {0};
            DWORD_PTR dwRes = FALSE;
            DWORD dwValidFlags;        int cbSize = lpData->cbSize;        if (cbSize == SIZEOF(NOTIFYICONDATA))
            {
                dwValidFlags = NIF_VALID;
            }
            else
            {
                // This will RIP if the app was stupid and passed stack
                // garbage as cbSize.  Apps got away with this on Win95
                // and NT4 because those versions didn't validate cbSize.
                // So if we see a strange cbSize, assume it's the V1 size.
                RIP(cbSize == NOTIFYICONDATA_V1_SIZE);
                cbSize = NOTIFYICONDATA_V1_SIZE;            dwValidFlags = NIF_VALID_V1;
            }#ifdef  _WIN64
            // Thunking NOTIFYICONDATA to NOTIFYICONDATA32 is annoying
            // on Win64 due to variations in the size of HWND and HICON
            // We have to copy each field individually.
            tnd.nid.dwWnd            = PtrToUlong(lpData->hWnd);
            tnd.nid.uID              = lpData->uID;
            tnd.nid.uFlags           = lpData->uFlags;
            tnd.nid.uCallbackMessage = lpData->uCallbackMessage;
            tnd.nid.dwIcon           = PtrToUlong(lpData->hIcon);        // The rest of the fields don't change size between Win32 and
            // Win64, so just block copy them over        // Toss in an assertion to make sure
            COMPILETIME_ASSERT(
                sizeof(NOTIFYICONDATA  ) - FIELD_OFFSET(NOTIFYICONDATA  , szTip) ==
                sizeof(NOTIFYICONDATA32) - FIELD_OFFSET(NOTIFYICONDATA32, szTip));        memcpy(&tnd.nid.szTip, &lpData->szTip, cbSize - FIELD_OFFSET(NOTIFYICONDATA, szTip));#else
            // On Win32, the two structures are the same
            COMPILETIME_ASSERT(sizeof(NOTIFYICONDATA) == sizeof(NOTIFYICONDATA32));
            memcpy(&tnd.nid, lpData, cbSize);
    #endif        tnd.nid.cbSize = sizeof(NOTIFYICONDATA32);        // This will RIP if the app was really stupid and passed stack
            // garbage as uFlags.
            RIP(!(lpData->uFlags & ~dwValidFlags));
            tnd.nid.uFlags &= dwValidFlags;        if (dwMessage == NIM_SETFOCUS)
            {
                DWORD dwProcId;
                GetWindowThreadProcessId(hwndTray, &dwProcId);
                AllowSetForegroundWindow(dwProcId);
            }
            
            tnd.dwSignature = NI_SIGNATURE;
            tnd.dwMessage = dwMessage;        cds.dwData = TCDM_NOTIFY;
            cds.cbData = SIZEOF(tnd);
            cds.lpData = &tnd;        if (SendMessageTimeout(hwndTray, WM_COPYDATA, (WPARAM)lpData->hWnd, (LPARAM)&cds,
                SMTO_ABORTIFHUNG | SMTO_BLOCK, 4000, &dwRes))
            {
                return (BOOL) dwRes;
            }
        }    return FALSE;
    }以上代码来自private\shell\shell32\shlnot.c,有这些文件的可以自己去看,都在shell32目录里面。
      

  12.   

    ringphone  非常感谢。你的方法说出了关键点,我也是这么做的,要用 WM_COPYDATA这个消息
      

  13.   

    ringphone  非常感谢。你的方法说出了关键点,我也是这么做的,要用 WM_COPYDATA这个消息
      

  14.   

    case WM_COPYDATA: // This is only used for NOTIFYICONDATA and SHNOTIFICATIONDATA
            {
                PCOPYDATASTRUCT pCDS = (PCOPYDATASTRUCT) lParam;
                PNOTIFYICONDATA pNID = NULL;
                NOTIFYCOPYSTRUCT *pNCS = NULL;
                BOOL bRecalc = TRUE;            ASSERT(pCDS);
                ASSERT((sizeof(NOTIFYICONDATA) == pCDS->cbData) || (sizeof(NOTIFYCOPYSTRUCT) == pCDS->cbData));
                ASSERT(pCDS->lpData);            if ((pCDS->dwData >= NIM_ADD) && (pCDS->dwData <= NIM_DELETE))
                {
                     pNID = (PNOTIFYICONDATA) pCDS->lpData;
                }
                else if ((pCDS->dwData >= NIM_BUBBLE_ADD) && (pCDS->dwData <= NIM_BUBBLE_DELETE))
                {
                    pNCS = (NOTIFYCOPYSTRUCT *) pCDS->lpData;
                }
                else
                {
                    return FALSE;
                }            switch (pCDS->dwData)
                {
                    case NIM_ADD:
                    {
                        if ((UINT) -1 != FindNotify(m_hwndTaskBar, pNID))
                        {
                            return FALSE;
                        }                    if (!InsertNotify(m_hwndTaskBar, pNID))
                        {
                            return FALSE;
                        }
                        bRecalc = FALSE;    // insert calls recalc directly                    break;
                    }                case NIM_MODIFY:
                    {
                        int nIcon = FindNotify(m_hwndTaskBar, pNID);
                        if (nIcon < 0)
                        {
                            return FALSE;
                        }                    if (!ModifyNotify(m_hwndTaskBar, pNID, nIcon))
                        {
                            return FALSE;
                        }
                        bRecalc = FALSE;
                        break;
                    }                case NIM_DELETE:
                    {
                        int nIcon = FindNotify(m_hwndTaskBar, pNID);
                        if (nIcon < 0)
                        {
                            return FALSE;
                        }
                        DeleteItem(m_hwndTaskBar, nIcon);
                        bRecalc = FALSE;                    // delete calls recalc directly                    break;
                    }                case NIM_BUBBLE_MODIFY:
                        bRecalc = FALSE;
                    case NIM_BUBBLE_ADD:
                    case NIM_BUBBLE_DELETE:
                        if (!HandleNimBubbleMessage(pNCS, pCDS->dwData))
                        {
                            return FALSE;
                        }
                        break;                default:
                        return FALSE;
                }上面的代码也是MS实现的,我是从这里知道怎么做的