Changeset 21592 for trunk/src


Ignore:
Timestamp:
Mar 18, 2011, 11:37:52 PM (14 years ago)
Author:
dmik
Message:

shell32: Implemented xsystray support (#16).

Location:
trunk/src/shell32
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/systray.c

    r21591 r21592  
    88 *  X11DRV_WND_DockWindow.
    99 *
    10  *  Modified by ErOs2 for usage with systray_os2.c
     10 *  Modified by ErOs2 and Dmitriy Kuminov for usage with systray_os2.c
    1111 *
    1212 */
     
    3434
    3535struct _SystrayItem {
    36   HWND                  hWnd;
    37   HWND                  hWndToolTip;
    38   NOTIFYICONDATAA       notifyIcon;
    39   struct _SystrayItem   *nextTrayItem;
     36    HWND                  hWnd;
     37    HWND                  hWndToolTip;
     38    NOTIFYICONDATAA       notifyIcon;
     39    UINT                  uIdx;
     40    struct _SystrayItem   *nextTrayItem;
    4041};
    4142
    42 static SystrayItem *systray=NULL;
     43static SystrayItem *systray = NULL;
    4344
    4445BOOL (*SYSTRAY_ItemInit)(SystrayItem *ptrayItem) = 0;
    4546void (*SYSTRAY_ItemTerm)(SystrayItem *ptrayItem) = 0;
    46 void (*SYSTRAY_ItemSetMessage)(SystrayItem *ptrayItem, ULONG uCallbackMessage) = 0;
    47 void (*SYSTRAY_ItemSetIcon)(SystrayItem *ptrayItem, HICON hIcon) = 0;
    48 void (*SYSTRAY_ItemSetTip)(SystrayItem *ptrayItem, CHAR* szTip, int modify) = 0;
    49 
     47void (*SYSTRAY_ItemUpdate)(SystrayItem *ptrayItem, ULONG uFlags) = 0;
    5048
    5149static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
    5250{
    53   if (pnid1->hWnd != pnid2->hWnd) return FALSE;
    54   if (pnid1->uID  != pnid2->uID)  return FALSE;
    55   return TRUE;
    56 }
    57 
     51    if (pnid1->hWnd != pnid2->hWnd) return FALSE;
     52    if (pnid1->uID  != pnid2->uID)  return FALSE;
     53    return TRUE;
     54}
    5855
    5956static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
    6057{
    61   SystrayItem **ptrayItem = &systray;
    62 
    63   /* Find last element. */
    64   while( *ptrayItem ) {
    65     if ( SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon) )
    66       return FALSE;
    67     ptrayItem = &((*ptrayItem)->nextTrayItem);
    68   }
    69   /* Allocate SystrayItem for element and add to end of list. */
    70   (*ptrayItem) = ( SystrayItem *)malloc( sizeof(SystrayItem) );
    71 
    72   /* Initialize and set data for the tray element. */
    73   SYSTRAY_ItemInit( (*ptrayItem) );
    74   (*ptrayItem)->notifyIcon.uID = pnid->uID; /* only needed for callback message */
    75   (*ptrayItem)->notifyIcon.hWnd = pnid->hWnd; /* only needed for callback message */
    76   SYSTRAY_ItemSetIcon   (*ptrayItem, (pnid->uFlags&NIF_ICON)   ?GetOS2Icon(pnid->hIcon)  :0);
    77   SYSTRAY_ItemSetMessage(*ptrayItem, (pnid->uFlags&NIF_MESSAGE)?pnid->uCallbackMessage:0);
    78   SYSTRAY_ItemSetTip    (*ptrayItem, (pnid->uFlags&NIF_TIP)    ?pnid->szTip           :"", FALSE);
    79 
    80   TRACE("SYSTRAY_Add %p: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",  (*ptrayItem),
    81         (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.hIcon,
    82         pnid->uCallbackMessage, (*ptrayItem)->notifyIcon.uCallbackMessage,
    83         pnid->szTip );
    84   return TRUE;
    85 }
    86 
     58    SystrayItem *pItem = systray, *pPrevItem = NULL, *ptrayItem;
     59    ULONG uIdx = 0;
     60
     61    /* Search for the first free index and also check if already in list */
     62    while (pItem)
     63    {
     64        if (SYSTRAY_ItemIsEqual(pnid, &pItem->notifyIcon))
     65          return FALSE;
     66
     67        uIdx = pPrevItem->uIdx + 1;
     68
     69        if (pPrevItem && pItem->uIdx - pPrevItem->uIdx > 1)
     70        {
     71            /* found a hole in the index row, will insert here */
     72            break;
     73        }
     74
     75        pPrevItem = pItem;
     76        pItem = pItem->nextTrayItem;
     77    }
     78
     79    /* check the rest (if any) for duplicates */
     80    ptrayItem = pItem;
     81    while (ptrayItem)
     82    {
     83        if (SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon))
     84            return FALSE;
     85        ptrayItem = ptrayItem->nextTrayItem;
     86    }
     87
     88    /* Allocate SystrayItem for the new element and insert it */
     89    ptrayItem = ( SystrayItem *)malloc(sizeof(SystrayItem));
     90    memset(ptrayItem, 0, sizeof(SystrayItem));
     91    ptrayItem->nextTrayItem = pItem;
     92
     93    if (pPrevItem)
     94    {
     95        pPrevItem->nextTrayItem = ptrayItem;
     96        ptrayItem->uIdx = pPrevItem->uIdx + 1;
     97    }
     98    else
     99    {
     100        systray = ptrayItem;
     101        ptrayItem->uIdx = 0;
     102    }
     103
     104    /* Initialize and set data for the tray element. */
     105    ptrayItem->uIdx = uIdx;
     106
     107    ptrayItem->notifyIcon.uID = pnid->uID;
     108    ptrayItem->notifyIcon.hWnd = pnid->hWnd;
     109
     110    ptrayItem->notifyIcon.hIcon =
     111        (pnid->uFlags & NIF_ICON) ? GetOS2Icon(pnid->hIcon) : 0;
     112    ptrayItem->notifyIcon.uCallbackMessage =
     113        (pnid->uFlags & NIF_MESSAGE) ? pnid->uCallbackMessage : 0;
     114
     115    if (pnid->uFlags & NIF_TIP)
     116        CharToOemA(pnid->szTip, ptrayItem->notifyIcon.szTip);
     117    else
     118        ptrayItem->notifyIcon.szTip[0] = '\0';
     119
     120    /* Implementation specific initialization */
     121    if (!SYSTRAY_ItemInit(ptrayItem))
     122    {
     123        free(ptrayItem);
     124        if (pPrevItem)
     125            pPrevItem->nextTrayItem = pItem;
     126        else
     127            systray = NULL;
     128        return FALSE;
     129    }
     130
     131    /* Trigger the data update (flags = 0 means it's the first time) */
     132    SYSTRAY_ItemUpdate(ptrayItem, 0);
     133
     134    TRACE("SYSTRAY_Add %p: uIdx %u, hWnd 0x%08x, uID %d, hIcon 0x%08x, "
     135          "uCallbackMessage 0x%08x, szTip [%s]\n",
     136          ptrayItem, ptrayItem->uIdx, ptrayItem->hWnd, ptrayItem->notifyIcon.uID,
     137          ptrayItem->notifyIcon.hIcon,ptrayItem->notifyIcon.uCallbackMessage,
     138          ptrayItem->notifyIcon.szTip);
     139
     140    return TRUE;
     141}
    87142
    88143static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
    89144{
    90   SystrayItem *ptrayItem = systray;
    91 
    92   while ( ptrayItem ) {
    93     if ( SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon) ) {
    94       if (pnid->uFlags & NIF_ICON)
    95         SYSTRAY_ItemSetIcon(ptrayItem, GetOS2Icon(pnid->hIcon) );
    96       if (pnid->uFlags & NIF_MESSAGE)
    97         SYSTRAY_ItemSetMessage(ptrayItem, pnid->uCallbackMessage);
    98       if (pnid->uFlags & NIF_TIP)
    99         SYSTRAY_ItemSetTip(ptrayItem, pnid->szTip, TRUE);
    100 
    101       TRACE("SYSTRAY_Modify %p: 0x%08x %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, pnid->szTip);
    102       return TRUE;
    103     }
    104     ptrayItem = ptrayItem->nextTrayItem;
    105   }
    106   return FALSE; /* not found */
    107 }
    108 
     145    SystrayItem *ptrayItem = systray;
     146
     147    while (ptrayItem)
     148    {
     149        if (SYSTRAY_ItemIsEqual(pnid, &ptrayItem->notifyIcon))
     150        {
     151            if (pnid->uFlags & NIF_ICON)
     152                ptrayItem->notifyIcon.hIcon = GetOS2Icon(pnid->hIcon);
     153            if (pnid->uFlags & NIF_MESSAGE)
     154                ptrayItem->notifyIcon.uCallbackMessage = pnid->uCallbackMessage;
     155            if (pnid->uFlags & NIF_TIP)
     156                CharToOemA(pnid->szTip, ptrayItem->notifyIcon.szTip);
     157
     158            SYSTRAY_ItemUpdate(ptrayItem, pnid->uFlags);
     159
     160            TRACE("SYSTRAY_Modify %p: uIdx %u, hWnd 0x%08x, uID %d, hIcon 0x%08x, "
     161                  "uCallbackMessage 0x%08x, szTip [%s]\n",
     162                  ptrayItem, ptrayItem->uIdx, ptrayItem->hWnd, ptrayItem->notifyIcon.uID,
     163                  ptrayItem->notifyIcon.hIcon,ptrayItem->notifyIcon.uCallbackMessage,
     164                  ptrayItem->notifyIcon.szTip);
     165
     166            return TRUE;
     167        }
     168        ptrayItem = ptrayItem->nextTrayItem;
     169    }
     170
     171    return FALSE; /* not found */
     172}
    109173
    110174static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid)
    111175{
    112   SystrayItem **ptrayItem = &systray;
    113 
    114   while (*ptrayItem) {
    115     if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
    116       SystrayItem *next = (*ptrayItem)->nextTrayItem;
    117       TRACE("%p: 0x%08x %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.szTip);
    118       SYSTRAY_ItemTerm(*ptrayItem);
    119 
    120       free(*ptrayItem);
    121       *ptrayItem = next;
    122 
    123       return TRUE;
    124     }
    125     ptrayItem = &((*ptrayItem)->nextTrayItem);
    126   }
    127 
    128   return FALSE; /* not found */
     176    SystrayItem **ptrayItem = &systray;
     177
     178    while (*ptrayItem)
     179    {
     180        if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon))
     181        {
     182            SystrayItem *next = (*ptrayItem)->nextTrayItem;
     183
     184            TRACE("SYSTRAY_Delete %p: uIdx %u, hWnd 0x%08x, uID %d\n",
     185                  *ptrayItem, (*ptrayItem)->uIdx, (*ptrayItem)->notifyIcon.hWnd,
     186                  (*ptrayItem)->notifyIcon.uID);
     187
     188            SYSTRAY_ItemTerm(*ptrayItem);
     189
     190            free(*ptrayItem);
     191            *ptrayItem = next;
     192
     193            return TRUE;
     194        }
     195        ptrayItem = &((*ptrayItem)->nextTrayItem);
     196    }
     197
     198    return FALSE; /* not found */
    129199}
    130200
     
    135205BOOL SYSTRAY_Init(void)
    136206{
    137   return TRUE;
     207    return TRUE;
    138208}
    139209#endif
    140210
    141211/*************************************************************************
     212 *
     213 */
     214SystrayItem *SYSTRAY_FindItem(ULONG uIdx)
     215{
     216    SystrayItem *ptrayItem = systray;
     217
     218    while (ptrayItem)
     219    {
     220        if (ptrayItem->uIdx == uIdx)
     221            return ptrayItem;
     222
     223        ptrayItem = ptrayItem->nextTrayItem;
     224    }
     225
     226    return NULL; /* not found */
     227}
     228
     229/*************************************************************************
    142230 * Shell_NotifyIconA            [SHELL32.297][SHELL32.296]
    143231 */
    144232BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
    145233{
    146   BOOL flag=FALSE;
    147   TRACE("enter %d %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
    148   switch(dwMessage) {
    149   case NIM_ADD:
    150     flag = SYSTRAY_Add(pnid);
    151     break;
    152   case NIM_MODIFY:
    153     flag = SYSTRAY_Modify(pnid);
    154     break;
    155   case NIM_DELETE:
    156     flag = SYSTRAY_Delete(pnid);
    157     break;
    158   }
    159   TRACE("leave %d %d %ld=%d\n", pnid->hWnd, pnid->uID, dwMessage, flag);
    160   return flag;
     234    BOOL flag = FALSE;
     235    switch(dwMessage)
     236    {
     237        case NIM_ADD:
     238            flag = SYSTRAY_Add(pnid);
     239            break;
     240        case NIM_MODIFY:
     241            flag = SYSTRAY_Modify(pnid);
     242            break;
     243        case NIM_DELETE:
     244            flag = SYSTRAY_Delete(pnid);
     245            break;
     246    }
     247    return flag;
    161248}
    162249
     
    192279}
    193280
    194 BOOL DoWin32CharToOem(const char *s, char *t)
    195 {
    196         return CharToOemA( s , t );
    197 }
    198 
    199281#endif
  • trunk/src/shell32/systray.h

    r21591 r21592  
    1414BOOL (*SYSTRAY_ItemInit)(SystrayItem *ptrayItem);
    1515void (*SYSTRAY_ItemTerm)(SystrayItem *ptrayItem);
    16 void (*SYSTRAY_ItemSetMessage)(SystrayItem *ptrayItem, ULONG uCallbackMessage);
    17 void (*SYSTRAY_ItemSetIcon)(SystrayItem *ptrayItem, HICON hIcon);
    18 void (*SYSTRAY_ItemSetTip)(SystrayItem *ptrayItem, CHAR* szTip, int modify);
     16void (*SYSTRAY_ItemUpdate)(SystrayItem *ptrayItem, ULONG uFlags);
     17
     18SystrayItem *SYSTRAY_FindItem(ULONG uIdx);
    1919
    2020#endif // __WINE_SYSTRAY_H
  • trunk/src/shell32/systray_os2.c

    r21591 r21592  
    9797    ULONG fcf = FCF_TITLEBAR;
    9898
    99     if ( !SYSTRAY_Old_RegisterClass() )
     99    if (!SYSTRAY_Old_RegisterClass())
    100100    {
    101101        return FALSE;
    102102    }
    103103
    104 
    105     memset( ptrayItem, 0, sizeof(SystrayItem) );
    106     ptrayItem->hWndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &fcf, NULL,
    107                                                "", 0, NULLHANDLE, 0, NULL );
    108     if ( !ptrayItem->hWndFrame ) {
     104    ptrayItem->hWndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &fcf, NULL,
     105                                              "", 0, NULLHANDLE, 0, NULL);
     106    if (!ptrayItem->hWndFrame)
     107    {
    109108        return FALSE;
    110109    }
    111110    ptrayItem->hWndClient = WinCreateWindow(ptrayItem->hWndFrame, systraysupclass, "",
    112111                                            0, 0, 0, 0, 0, ptrayItem->hWndFrame,
    113                                             HWND_TOP, FID_CLIENT, ptrayItem, NULL );
    114     if ( !ptrayItem->hWndClient ) {
     112                                            HWND_TOP, FID_CLIENT, ptrayItem, NULL);
     113    if (!ptrayItem->hWndClient)
     114    {
    115115        return FALSE;
    116116    }
    117117
    118     WinDdeInitiate(ptrayItem->hWndClient,SZAPP,SZTOPIC,NULL);
     118    WinDdeInitiate(ptrayItem->hWndClient, SZAPP, SZTOPIC, NULL);
    119119    if (hwndTrayServer)
    120         WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
     120        WinPostMsg(hwndTrayServer, WM_TRAYICON,
     121                   (MPARAM)ptrayItem->hWndClient, (MPARAM)NULL);
    121122
    122     return (hwndTrayServer!=NULLHANDLE);
     123    return (hwndTrayServer != NULLHANDLE);
    123124}
    124125
     
    132133}
    133134
     135static void SYSTRAY_Old_ItemUpdate(SystrayItem *ptrayItem, ULONG uFlags)
     136{
     137    // uFlags = 0 means it's the first time, add everything
    134138
    135 static void SYSTRAY_Old_ItemSetMessage(SystrayItem *ptrayItem, ULONG uCallbackMessage)
    136 {
    137   ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage;
     139    if (uFlags == 0 || (uFlags & NIF_ICON))
     140    {
     141        // Windows seems to make a copy of icons displayed in the tray area. At
     142        // least, calling DestroyIcon() after passing the icon handle to
     143        // Shell_NotifyIcon() doesn't harm the icon displayed in the tray.
     144        // Behave similarly on OS/2 (some applications do call DestroyIcon()).
     145        // The copy is deleted in SYSTRAY_Old_ItemTerm().
     146
     147        POINTERINFO Info;
     148        HPOINTER hIcon = NULLHANDLE;
     149        BOOL brc;
     150        brc = WinQueryPointerInfo(ptrayItem->notifyIcon.hIcon, &Info);
     151        if (brc)
     152        {
     153            hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &Info);
     154            if (hIcon != NULLHANDLE)
     155            {
     156                WinSendMsg(ptrayItem->hWndFrame, WM_SETICON,
     157                           MPFROMLONG(hIcon), MPVOID);
     158                if (hwndTrayServer)
     159                    WinPostMsg(hwndTrayServer, WM_TRAYICON,
     160                               (MPARAM)ptrayItem->hWndClient, (MPARAM)NULL);
     161            }
     162        }
     163    }
     164    if (uFlags == 0 || (uFlags & NIF_TIP))
     165    {
     166        WinSetWindowText(ptrayItem->hWndFrame, ptrayItem->notifyIcon.szTip);
     167        if (hwndTrayServer)
     168            WinPostMsg(hwndTrayServer, WM_TRAYICON,
     169                       (MPARAM)ptrayItem->hWndClient, (MPARAM)NULL);
     170    }
    138171}
    139 
    140 
    141 static void SYSTRAY_Old_ItemSetIcon(SystrayItem *ptrayItem, HPOINTER hIcon)
    142 {
    143     // Windows seems to make a copy of icons displayed in the tray area. At
    144     // least, calling DestroyIcon() after passing the icon handle to
    145     // Shell_NotifyIcon() doesn't harm the icon displayed in the tray. Behave
    146     // similarly on OS/2 (some applications do call DestroyIcon()). The copy is
    147     // deleted in SYSTRAY_Old_ItemTerm().
    148 
    149     POINTERINFO Info;
    150     HPOINTER hIcon2 = NULLHANDLE;
    151     APIRET arc;
    152     arc = WinQueryPointerInfo(hIcon, &Info);
    153     if (!arc)
    154         return;
    155     hIcon2 = WinCreatePointerIndirect(HWND_DESKTOP, &Info);
    156     if (hIcon2 == NULLHANDLE)
    157         return;
    158     hIcon = hIcon2;
    159 
    160     WinSendMsg( ptrayItem->hWndFrame, WM_SETICON, MPFROMLONG( hIcon ), MPVOID );
    161     if (hwndTrayServer)
    162         WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
    163 }
    164 
    165 
    166 static void SYSTRAY_Old_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
    167 {
    168         char tmp[ 64 ];
    169     strncpy(ptrayItem->notifyIcon.szTip, szTip, 64 );
    170     ptrayItem->notifyIcon.szTip[ 63 ] = 0;
    171     DoWin32CharToOem( ptrayItem->notifyIcon.szTip, tmp );
    172     WinSetWindowText( ptrayItem->hWndFrame, tmp );
    173     if (hwndTrayServer)
    174         WinPostMsg(hwndTrayServer,WM_TRAYICON,(MPARAM)ptrayItem->hWndClient,(MPARAM)NULL);
    175 }
    176 
    177172
    178173BOOL SYSTRAY_Init(void)
     
    185180    SYSTRAY_ItemInit = SYSTRAY_Old_ItemInit;
    186181    SYSTRAY_ItemTerm = SYSTRAY_Old_ItemTerm;
    187     SYSTRAY_ItemSetMessage = SYSTRAY_Old_ItemSetMessage;
    188     SYSTRAY_ItemSetIcon = SYSTRAY_Old_ItemSetIcon;
    189     SYSTRAY_ItemSetTip = SYSTRAY_Old_ItemSetTip;
     182    SYSTRAY_ItemUpdate = SYSTRAY_Old_ItemUpdate;
    190183
    191184    return TRUE;
  • trunk/src/shell32/systray_os2.h

    r21591 r21592  
    1818// to avoid Win32 header inclusion and conflicts
    1919
     20#define NIF_MESSAGE             0x00000001
     21#define NIF_ICON                0x00000002
     22#define NIF_TIP                 0x00000004
     23
    2024typedef struct _NOTIFYICONDATAA
    2125{   ULONG    cbSize;
     
    2832} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
    2933
     34// Note: This must match _SystrayItem from systray.c
    3035struct _SystrayItem {
    3136  HWND                  hWndFrame;
    3237  HWND                  hWndClient;
    3338  NOTIFYICONDATAA       notifyIcon;
     39  ULONG                 uIdx;
    3440  struct _SystrayItem   *nextTrayItem;
    3541};
    3642
    3743BOOL DoWin32PostMessage(HWND, ULONG, MPARAM, MPARAM);
    38 BOOL DoWin32CharToOem(const char *s, char *t);
    3944
    4045BOOL SYSTRAY_Ex_Init(void);
  • trunk/src/shell32/systray_os2ex.c

    r21591 r21592  
    77
    88#define  INCL_WIN
     9#define  INCL_DOS
     10#define  INCL_DOSERRORS
    911#include <os2wrap.h>
    1012
     
    1416#include <winconst.h>
    1517
    16 //@todo later
    17 //#include <xsystray_api.h>
     18// declare function pointers for dynamic linking to xsystray DLL
     19#define XSTAPI_FPTRS_STATIC
     20#include <xsystray.h>
    1821
    1922#include "systray_os2.h"
    2023
     24#define WM_XST_MYNOTIFY (WM_USER + 1000)
     25
     26static HWND hwndProxy = NULLHANDLE;
     27static ULONG hwndProxyRefs = 0;
     28
     29static PFNWP OldProxyWndProc = NULL;
     30
     31static MRESULT EXPENTRY ProxyWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     32{
     33    switch (msg)
     34    {
     35    case WM_XST_MYNOTIFY:
     36    {
     37        USHORT usIconID = SHORT1FROMMP(mp1);
     38        USHORT usNotifyCode = SHORT2FROMMP(mp1);
     39
     40        SystrayItem *ptrayItem = SYSTRAY_FindItem(usIconID);
     41        if (!ptrayItem)
     42            return (MRESULT)FALSE;
     43
     44        switch (usNotifyCode)
     45        {
     46        case XST_IN_MOUSE:
     47        {
     48            PXSTMOUSEMSG pmmsg = (PXSTMOUSEMSG)mp2;
     49            ULONG winMsg = 0;
     50
     51            switch (pmmsg->ulMouseMsg)
     52            {
     53            case WM_BUTTON1DBLCLK: winMsg = WM_LBUTTONDBLCLK_W; break;
     54            case WM_BUTTON2DBLCLK: winMsg = WM_RBUTTONDBLCLK_W; break;
     55            case WM_BUTTON3DBLCLK: winMsg = WM_MBUTTONDBLCLK_W; break;
     56            case WM_BUTTON1UP: winMsg = WM_LBUTTONUP_W; break;
     57            case WM_BUTTON2UP: winMsg = WM_RBUTTONUP_W; break;
     58            case WM_BUTTON3UP: winMsg = WM_MBUTTONUP_W; break;
     59            case WM_BUTTON1DOWN: winMsg = WM_LBUTTONDOWN_W; break;
     60            case WM_BUTTON2DOWN: winMsg = WM_RBUTTONDOWN_W; break;
     61            case WM_BUTTON3DOWN: winMsg = WM_MBUTTONDOWN_W; break;
     62            default: break;
     63            }
     64
     65            if (winMsg)
     66            {
     67                DoWin32PostMessage(ptrayItem->notifyIcon.hWnd,
     68                                   ptrayItem->notifyIcon.uCallbackMessage,
     69                                   (MPARAM)ptrayItem->notifyIcon.uID,
     70                                   (MPARAM)winMsg);
     71            }
     72
     73            return (MRESULT)FALSE;
     74        }
     75        default:
     76            break;
     77        }
     78    }
     79
     80    default:
     81        break;
     82    }
     83
     84    return OldProxyWndProc(hWnd, msg, mp1, mp2);
     85}
     86
    2187static BOOL SYSTRAY_Ex_ItemInit(SystrayItem *ptrayItem)
    2288{
    23     //@todo later
     89    if (hwndProxyRefs == 0)
     90    {
     91        ULONG fcf = 0;
     92        hwndProxy = WinCreateStdWindow(HWND_DESKTOP, 0, &fcf, NULL,
     93                                       NULL, 0, NULLHANDLE, 0, NULL);
     94        if (hwndProxy == NULLHANDLE)
     95            return FALSE;
     96
     97        OldProxyWndProc = WinSubclassWindow(hwndProxy, ProxyWndProc);
     98    }
     99    ++ hwndProxyRefs;
     100
    24101    return TRUE;
    25102}
     
    27104static void SYSTRAY_Ex_ItemTerm(SystrayItem *ptrayItem)
    28105{
    29     //@todo later
     106    xstRemoveSysTrayIcon(hwndProxy, ptrayItem->uIdx);
    30107
     108    if (-- hwndProxyRefs == 0)
     109    {
     110        WinDestroyWindow(hwndProxy);
     111        hwndProxy = NULLHANDLE;
     112    }
    31113}
    32114
    33 static void SYSTRAY_Ex_ItemSetMessage(SystrayItem *ptrayItem, ULONG uCallbackMessage)
     115static void SYSTRAY_Ex_ItemUpdate(SystrayItem *ptrayItem, ULONG uFlags)
    34116{
    35     //@todo later
     117    if (uFlags == 0 || (uFlags & (NIF_ICON | NIF_TIP) == NIF_ICON | NIF_TIP))
     118    {
     119        // uFlags = 0 means it's the first time so add the icon. The other case
     120        // is true when a bunch of the parameters is changed at once so use
     121        // xstAdd... too to save a few IPC calls.
     122        xstAddSysTrayIcon(hwndProxy, ptrayItem->uIdx,
     123                          ptrayItem->notifyIcon.hIcon,
     124                          ptrayItem->notifyIcon.szTip,
     125                          WM_XST_MYNOTIFY,
     126                          XST_IN_MOUSE | XST_IN_CONTEXT);
     127        return;
     128    }
    36129
    37 }
    38 
    39 static void SYSTRAY_Ex_ItemSetIcon(SystrayItem *ptrayItem, HPOINTER hIcon)
    40 {
    41     //@todo later
    42 
    43 }
    44 
    45 static void SYSTRAY_Ex_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
    46 {
    47     //@todo later
     130    if (uFlags & NIF_ICON)
     131    {
     132        xstReplaceSysTrayIcon(hwndProxy, ptrayItem->uIdx,
     133                              ptrayItem->notifyIcon.hIcon);
     134    }
     135    if (uFlags & NIF_TIP)
     136    {
     137        xstSetSysTrayIconToolTip(hwndProxy, ptrayItem->uIdx,
     138                                 ptrayItem->notifyIcon.szTip);
     139    }
    48140}
    49141
    50142BOOL SYSTRAY_Ex_Init(void)
    51143{
     144    static BOOL tried = FALSE;
     145    if (!tried) {
     146        char err[CCHMAXPATH];
     147        HMODULE hmod;
     148
     149        tried = TRUE;
     150
     151        // link to the xsystray DLL at runtime
     152        if (DosLoadModule(err, sizeof(err), "XSYSTRAY", &hmod) != NO_ERROR)
     153            return FALSE;
     154
     155        #define R(f) if (DosQueryProcAddr(hmod, 0, #f, (PFN*)&f) != NO_ERROR) return FALSE
     156
     157        R(xstQuerySysTrayVersion);
     158        R(xstAddSysTrayIcon);
     159        R(xstReplaceSysTrayIcon);
     160        R(xstRemoveSysTrayIcon);
     161        R(xstSetSysTrayIconToolTip);
     162        R(xstQuerySysTrayIconRect);
     163        R(xstGetSysTrayCreatedMsgId);
     164        R(xstGetSysTrayMaxTextLen);
     165
     166        #undef R
     167    }
     168
     169    // check if xsystray is there
     170    if (!xstQuerySysTrayVersion(NULL, NULL, NULL))
     171        return FALSE;
     172
    52173    SYSTRAY_ItemInit = SYSTRAY_Ex_ItemInit;
    53174    SYSTRAY_ItemTerm = SYSTRAY_Ex_ItemTerm;
    54     SYSTRAY_ItemSetMessage = SYSTRAY_Ex_ItemSetMessage;
    55     SYSTRAY_ItemSetIcon = SYSTRAY_Ex_ItemSetIcon;
    56     SYSTRAY_ItemSetTip = SYSTRAY_Ex_ItemSetTip;
     175    SYSTRAY_ItemUpdate = SYSTRAY_Ex_ItemUpdate;
    57176
    58177    return TRUE;
Note: See TracChangeset for help on using the changeset viewer.