Ignore:
Timestamp:
Nov 3, 2009, 2:39:49 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

3rdparty: os2/xsystray: Added new xstReplaceSysTrayIcon() API call, implemented xstSetSysTrayIconToolTip() API call.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/3rdparty/os2/xsystray/xsystray.c

    r281 r282  
    7575#pragma hdrstop                     // VAC++ keeps crashing otherwise
    7676
     77// copy paste from helpers\comctl.h
     78// @todo not necessary when we become part of XWorkplace
     79
     80#define TTN_NEEDTEXT        1000
     81#define TTN_SHOW            1001
     82#define TTN_POP             1002
     83
     84#define TTFMT_PSZ           0x01
     85#define TTFMT_STRINGRES     0x02
     86
     87typedef struct _TOOLTIPTEXT
     88{
     89    HWND    hwndTooltip;
     90    HWND    hwndTool;
     91    ULONG   ulFormat;
     92    PSZ     pszText;
     93    HMODULE hmod;
     94    ULONG   idResource;
     95} TOOLTIPTEXT, *PTOOLTIPTEXT;
     96
     97#define TTM_FIRST                   (WM_USER + 1000)
     98#define TTM_UPDATETIPTEXT           (TTM_FIRST + 9)
     99#define TTM_SHOWTOOLTIPNOW          (TTM_FIRST + 17)
     100
    77101// primitive debug logging to a file
    78102#if 0
     
    123147    PSZ         pszToolTip;
    124148                // icon tooltip (NULL if none)
     149    BOOL        bIsToolTipShowing;
     150                // whether the tooltip is currently shown
    125151    BOOL        bMemoryPoolGiven;
    126152                // TRUE if SYSTRAYDATA::pvMemoryPool is already given to
     
    150176    size_t      cIconsMax;
    151177                // maximum number of icons pIcons can fit
     178    CHAR        szToolTip[sizeof(((PSYSTRAYCTLDATA)0)->u.icon.szToolTip)];
     179                // "static" buffer for the tooltip (XCenter requirement)
    152180    PVOID       pvMemoryPool;
    153181                // memory pool for NOTIFYDATA structures
     
    207235        INTCLASS_WIDGET_XSYSTRAY,   // internal widget class name
    208236        HUMANSTR_WIDGET_XSYSTRAY,   // widget class name displayed to user
    209         WGTF_UNIQUEGLOBAL,          // widget class flags
     237        WGTF_UNIQUEGLOBAL |         // widget class flags
     238        WGTF_TOOLTIP,
    210239        NULL                        // no settings dialog
    211240    }
     
    360389        *pIdx = i;
    361390    return NULL;
     391}
     392
     393/*
     394 *@@ FindIconDataAtPt:
     395 *      Searches for the icon under the given point.
     396 *      Returns NULL if no icon found (e.g. the pad space).
     397 *
     398 *      Refer to WgtPaint() for system tray geometry description.
     399 */
     400
     401static
     402PICONDATA FindIconDataAtPt(PXCENTERWIDGET pWidget,
     403                           PPOINTL pptl,    // point coordinates (relative to systray)
     404                           size_t *pIdx)    // out: index of the icon in the icon array
     405                                            // (optional, may be NULL)
     406{
     407    PSYSTRAYDATA pSysTrayData = (PSYSTRAYDATA)pWidget->pUser;
     408
     409    SWP     swp;
     410    RECTL   rcl;
     411    BOOL    bLeftToRight;
     412    LONG    y, lIconStep;
     413    size_t  i;
     414
     415    // start with invalid index index
     416    if (pIdx)
     417        *pIdx = pSysTrayData->cIcons;
     418
     419    WinQueryWindowPos(pWidget->hwndWidget, &swp);
     420    WinQueryWindowRect(pWidget->pGlobals->hwndClient, &rcl);
     421
     422    y = (swp.cy - pSysTrayData->lIconHeight) / 2;
     423    if (pptl->y < y || pptl->y >= y + pSysTrayData->lIconHeight)
     424        return NULL; // hit pad space
     425
     426    // detect the direction
     427    bLeftToRight = swp.x + swp.cx / 2 < (rcl.xRight / 2);
     428
     429    lIconStep = pSysTrayData->lIconWidth + pSysTrayData->lIconPad;
     430
     431    // which icon is that?
     432    if (bLeftToRight)
     433    {
     434        i = pptl->x / lIconStep;
     435        if (pptl->x % lIconStep < pSysTrayData->lIconPad)
     436            return NULL; // hit pad space
     437    }
     438    else
     439    {
     440        i = (swp.cx - pptl->x - 1) / lIconStep;
     441        if ((swp.cx - pptl->x - 1) % lIconStep < pSysTrayData->lIconPad)
     442            return NULL; // hit pad space
     443    }
     444    if (i >= pSysTrayData->cIcons)
     445        return NULL; // hit pad space
     446
     447    if (pIdx)
     448        *pIdx = i;
     449    return &pSysTrayData->pIcons[i];
     450}
     451
     452static
     453VOID FreeSysTrayData(PSYSTRAYDATA pSysTrayData)
     454{
     455    // destroy the server
     456    if (pSysTrayData->hwndServer != NULLHANDLE)
     457    {
     458        WinDestroyWindow(pSysTrayData->hwndServer);
     459        pSysTrayData->hwndServer = NULLHANDLE;
     460    }
     461
     462    // free all system tray data
     463    if (pSysTrayData->pvMemoryPool)
     464    {
     465        DosFreeMem(pSysTrayData->pvMemoryPool);
     466    }
     467    if (pSysTrayData->pIcons)
     468    {
     469        size_t i;
     470        for (i = 0; i < pSysTrayData->cIcons; ++i)
     471            FreeIconData(&pSysTrayData->pIcons[i]);
     472        pSysTrayData->cIcons = 0;
     473        free(pSysTrayData->pIcons);
     474        pSysTrayData->pIcons = NULL;
     475    }
     476
     477    free(pSysTrayData);
    362478}
    363479
     
    558674            break;
    559675
    560         } // end switch (usNotifyCode)
    561     } // end if (usID == ID_XCENTER_CLIENT)
     676        }
     677    }
     678    else if (usID == ID_XCENTER_TOOLTIP)
     679    {
     680        PICONDATA pIconData;
     681        POINTL ptl;
     682
     683        WinQueryMsgPos(pWidget->habWidget, &ptl);
     684        // make the coordinates systray-relative
     685        WinMapWindowPoints(HWND_DESKTOP, pWidget->hwndWidget, &ptl, 1);
     686
     687        pIconData = FindIconDataAtPt(pWidget, &ptl, NULL);
     688
     689        switch (usNotifyCode)
     690        {
     691            case TTN_NEEDTEXT:
     692            {
     693                LOGF(("TTN_NEEDTEXT\n"));
     694
     695                PTOOLTIPTEXT pttt = (PTOOLTIPTEXT)mp2;
     696                pttt->ulFormat = TTFMT_PSZ;
     697
     698                if (!pIconData || !pIconData->pszToolTip)
     699                    pttt->pszText = NULL;
     700                else
     701                {
     702                    strncpy(pSysTrayData->szToolTip, pIconData->pszToolTip,
     703                            sizeof(pSysTrayData->szToolTip) - 1);
     704                    // be on the safe side
     705                    pSysTrayData->szToolTip[sizeof(pSysTrayData->szToolTip) - 1] = '\0';
     706
     707                    pttt->pszText = pSysTrayData->szToolTip;
     708                }
     709
     710                LOGF((" pszText '%s'\n", pttt->pszText));
     711            }
     712            break;
     713
     714            case TTN_SHOW:
     715                if (pIconData)
     716                    pIconData->bIsToolTipShowing = TRUE;
     717            break;
     718
     719            case TTN_POP:
     720                if (pIconData)
     721                    pIconData->bIsToolTipShowing = FALSE;
     722            break;
     723        }
     724    }
    562725
    563726    return brc;
     
    571734 *      the XCenter's center, icons go left to right. Otherwise, they go right
    572735 *      to left.
     736 *
     737 *      NOTE: This function must be keept in sync with FindIconDataAtPt() in
     738 *      terms of system tray geometry.
    573739 */
    574740/*
     
    695861
    696862    POINTL  ptl;
    697     SWP     swp;
    698     RECTL   rcl;
    699     BOOL    bLeftToRight;
    700     LONG    y, lIconStep;
    701     size_t  i;
    702863
    703864    PICONDATA   pIconData;
     
    709870    LOGF(("msg %x ptl %ld,%ld\n", msg, ptl.x, ptl.y));
    710871
    711     WinQueryWindowPos(hwnd, &swp);
    712     WinQueryWindowRect(pWidget->pGlobals->hwndClient, &rcl);
    713 
    714     y = (swp.cy - pSysTrayData->lIconHeight) / 2;
    715     if (ptl.y < y || ptl.y >= y + pSysTrayData->lIconHeight)
     872    pIconData = FindIconDataAtPt(pWidget, &ptl, NULL);
     873    if (!pIconData)
    716874        return FALSE; // hit pad space
    717 
    718     // detect the direction
    719     bLeftToRight = swp.x + swp.cx / 2 < (rcl.xRight / 2);
    720 
    721     lIconStep = pSysTrayData->lIconWidth + pSysTrayData->lIconPad;
    722 
    723     // which icon is that?
    724     if (bLeftToRight)
    725     {
    726         i = ptl.x / lIconStep;
    727         if (ptl.x % lIconStep < pSysTrayData->lIconPad)
    728             return FALSE; // hit pad space
    729     }
    730     else
    731     {
    732         i = (swp.cx - ptl.x - 1) / lIconStep;
    733         if ((swp.cx - ptl.x - 1) % lIconStep < pSysTrayData->lIconPad)
    734             return FALSE; // hit pad space
    735     }
    736     if (i >= pSysTrayData->cIcons)
    737         return FALSE; // hit pad space
    738 
    739     pIconData = &pSysTrayData->pIcons[i];
    740875
    741876    LOGF(("hwnd  %x\n", pIconData->hwnd));
     
    785920
    786921    return TRUE;
    787 }
    788 
    789 static
    790 VOID FreeSysTrayData(PSYSTRAYDATA pSysTrayData)
    791 {
    792     // destroy the server
    793     if (pSysTrayData->hwndServer != NULLHANDLE)
    794     {
    795         WinDestroyWindow(pSysTrayData->hwndServer);
    796         pSysTrayData->hwndServer = NULLHANDLE;
    797     }
    798 
    799     // free all system tray data
    800     if (pSysTrayData->pvMemoryPool)
    801     {
    802         DosFreeMem(pSysTrayData->pvMemoryPool);
    803     }
    804     if (pSysTrayData->pIcons)
    805     {
    806         size_t i;
    807         for (i = 0; i < pSysTrayData->cIcons; ++i)
    808             FreeIconData(&pSysTrayData->pIcons[i]);
    809         pSysTrayData->cIcons = 0;
    810         free(pSysTrayData->pIcons);
    811         pSysTrayData->pIcons = NULL;
    812     }
    813 
    814     free(pSysTrayData);
    815922}
    816923
     
    11011208
    11021209            LOGF(("SYSTRAYCMD_ADDICON\n"));
    1103             LOGF((" hwnd  %x\n", pCtlData->hwndSender));
    1104             LOGF((" usId  %d\n", pCtlData->u.icon.usId));
    1105             LOGF((" hIcon %x\n", pCtlData->u.icon.hIcon));
     1210            LOGF((" hwnd       %x\n", pCtlData->hwndSender));
     1211            LOGF((" usId       %d\n", pCtlData->u.icon.usId));
     1212            LOGF((" hIcon      %x\n", pCtlData->u.icon.hIcon));
     1213            LOGF((" szToolTip  '%s'\n", pCtlData->u.icon.szToolTip));
    11061214
    11071215            pCtlData->bAcknowledged = TRUE;
     
    11201228            if (pData)
    11211229            {
    1122                 LOGF((" Updating hIcon %x\n", hIcon));
    1123 
     1230                LOGF((" Replacing with hIcon %x\n", hIcon));
     1231
     1232                // try update the tooltip first
     1233                free(pData->pszToolTip);
     1234                pData->pszToolTip = NULL;
     1235                if (pCtlData->u.icon.szToolTip[0] != '\0')
     1236                {
     1237                    pData->pszToolTip = strdup(pCtlData->u.icon.szToolTip);
     1238                    if (!pData->pszToolTip)
     1239                    {
     1240                        WinDestroyPointer(hIcon);
     1241                        break;
     1242                    }
     1243                }
     1244
     1245                if (pData->bIsToolTipShowing)
     1246                {
     1247                    if (pData->pszToolTip)
     1248                        // update the tooltip on screen
     1249                        WinSendMsg(pWidget->pGlobals->hwndTooltip,
     1250                                   TTM_UPDATETIPTEXT,
     1251                                   (MPARAM)pData->pszToolTip, 0);
     1252                    else
     1253                        // hide the tooltip
     1254                        WinSendMsg(pWidget->pGlobals->hwndTooltip,
     1255                                   TTM_SHOWTOOLTIPNOW,
     1256                                   (MPARAM)FALSE, 0);
     1257                }
     1258
     1259                // now update the icon
    11241260                WinDestroyPointer(pData->hIcon);
    11251261                pData->hIcon = hIcon;
     
    11561292
    11571293                i = pSysTrayData->cIcons;
    1158                 ++pSysTrayData->cIcons;
    11591294
    11601295                pData = &pSysTrayData->pIcons[i];
     
    11661301                pData->ulMsgId = pCtlData->u.icon.ulMsgId;
    11671302
     1303                if (pCtlData->u.icon.szToolTip[0] != '\0')
     1304                {
     1305                    pData->pszToolTip = strdup(pCtlData->u.icon.szToolTip);
     1306                    if (!pData->pszToolTip)
     1307                    {
     1308                        WinDestroyPointer(hIcon);
     1309                        break;
     1310                    }
     1311                }
     1312
    11681313                WgtXSysTrayUpdateAfterIconAddRemove(pWidget);
     1314
     1315                ++pSysTrayData->cIcons;
    11691316
    11701317                xrc = XST_OK;
    11711318            }
     1319        }
     1320        break;
     1321
     1322        case SYSTRAYCMD_REPLACEICON:
     1323        {
     1324            POINTERINFO Info;
     1325            HPOINTER hIcon = NULLHANDLE;
     1326            size_t i;
     1327            PICONDATA pData;
     1328
     1329            LOGF(("SYSTRAYCMD_REPLACEICON\n"));
     1330            LOGF((" hwnd  %x\n", pCtlData->hwndSender));
     1331            LOGF((" usId  %d\n", pCtlData->u.icon.usId));
     1332
     1333            pCtlData->bAcknowledged = TRUE;
     1334
     1335            // make a private copy of the provided icon (it will get lost after
     1336            // we return from this message)
     1337            brc = WinQueryPointerInfo(pCtlData->u.icon.hIcon, &Info);
     1338            if (!brc)
     1339                break;
     1340            hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &Info);
     1341            if (hIcon == NULLHANDLE)
     1342                break;
     1343
     1344            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
     1345                                 pCtlData->u.icon.usId, &i);
     1346            if (pData)
     1347            {
     1348                LOGF((" Replacing with hIcon %x\n", hIcon));
     1349
     1350                WinDestroyPointer(pData->hIcon);
     1351                pData->hIcon = hIcon;
     1352                pData->ulMsgId = pCtlData->u.icon.ulMsgId;
     1353
     1354                // we didn't change the number of icons so simply invalidate
     1355                WinInvalidateRect(pWidget->hwndWidget, NULL, FALSE);
     1356
     1357                xrc = XST_OK;
     1358            }
     1359            else
     1360                LOGF((" Icon not found!\n"));
    11721361        }
    11731362        break;
     
    12011390
    12021391                WgtXSysTrayUpdateAfterIconAddRemove(pWidget);
     1392
     1393                xrc = XST_OK;
     1394            }
     1395            else
     1396                LOGF((" Icon not found!\n"));
     1397        }
     1398        break;
     1399
     1400        case SYSTRAYCMD_SETTOOLTIP:
     1401        {
     1402            size_t i;
     1403            PICONDATA pData;
     1404
     1405            LOGF(("SYSTRAYCMD_SETTOOLTIP\n"));
     1406            LOGF((" hwnd  %x\n", pCtlData->hwndSender));
     1407            LOGF((" usId  %d\n", pCtlData->u.icon.usId));
     1408
     1409            pCtlData->bAcknowledged = TRUE;
     1410
     1411            pData = FindIconData(pSysTrayData, pCtlData->hwndSender,
     1412                                 pCtlData->u.icon.usId, &i);
     1413            if (pData)
     1414            {
     1415                LOGF((" Replacing with szToolTip '%s'\n",
     1416                      pCtlData->u.icon.szToolTip));
     1417
     1418                free(pData->pszToolTip);
     1419                pData->pszToolTip = NULL;
     1420                if (pCtlData->u.icon.szToolTip[0] != '\0')
     1421                {
     1422                    pData->pszToolTip = strdup(pCtlData->u.icon.szToolTip);
     1423                    if (!pData->pszToolTip)
     1424                        break;
     1425                }
     1426
     1427                if (pData->bIsToolTipShowing)
     1428                {
     1429                    if (pData->pszToolTip)
     1430                        // update the tooltip on screen
     1431                        WinSendMsg(pWidget->pGlobals->hwndTooltip,
     1432                                   TTM_UPDATETIPTEXT,
     1433                                   (MPARAM)pData->pszToolTip, 0);
     1434                    else
     1435                        // hide the tooltip
     1436                        WinSendMsg(pWidget->pGlobals->hwndTooltip,
     1437                                   TTM_SHOWTOOLTIPNOW,
     1438                                   (MPARAM)FALSE, 0);
     1439                }
    12031440
    12041441                xrc = XST_OK;
Note: See TracChangeset for help on using the changeset viewer.