Changeset 81


Ignore:
Timestamp:
Jun 23, 2001, 11:12:49 AM (24 years ago)
Author:
umoeller
Message:

Tons of changes from the last weeks.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/comctl.h

    r68 r81  
    3636#ifndef COMCTL_HEADER_INCLUDED
    3737    #define COMCTL_HEADER_INCLUDED
     38
     39    /* ******************************************************************
     40     *
     41     *   "XButton" control
     42     *
     43     ********************************************************************/
     44
     45    /*
     46     *@@ XBUTTONDATA:
     47     *      paint data for ctlPaintXButton.
     48     *
     49     *@@added V0.9.13 (2001-06-21) [umoeller]
     50     */
     51
     52    typedef struct _XBUTTONDATA
     53    {
     54        RECTL       rcl;                // size of button (in presentation space
     55                                        // coordinates); exclusive!
     56
     57        ULONG       cxMiniIcon;         // system mini icon size
     58
     59        LONG        lcol3DDark,         // lo-3D color
     60                    lcol3DLight,        // hi-3D color
     61                    lMiddle;            // color for center (button background)
     62
     63        HPOINTER    hptr;               // icon to paint or NULLHANDLE
     64
     65    } XBUTTONDATA, *PXBUTTONDATA;
     66
     67    #define XBF_FLAT                0x0001
     68
     69    #define XBF_PRESSED             0x00010000
     70    #define XBF_BACKGROUND          0x00020000
     71    #define XBF_INUSE               0x00040000
     72
     73    VOID ctlPaintXButton(HPS hps,
     74                         ULONG fl,
     75                         PXBUTTONDATA pxbd);
    3876
    3977    /* ******************************************************************
     
    670708    /*
    671709     *@@ TOOLTIPTEXT:
    672      *      identifies a tool for which text is to be displayed and
    673      *      receives the text for the tool. The tool must fill all
    674      *      fields of this structure.
    675      *
    676      *      This structure is used with the TTN_NEEDTEXT notification.
     710     *      identifies a tool for which text is to
     711     *      be displayed and receives the text for
     712     *      the tool. The tool must fill all fields
     713     *      of this structure.
     714     *
     715     *      This structure is used with the TTN_NEEDTEXT
     716     *      notification.
    677717     *
    678718     *@@changed V0.9.7 (2001-01-03) [umoeller]: got rid of this win95 crap
     
    693733                    // out: with TTFMT_PSZ, pointer to a string that contains the
    694734                    // tool text. Note that this is not copied into the tooltip...
    695                     // so this must point to a static buffer.
     735                    // so this must point to a static buffer that is valid while
     736                    // the tooltip is showing.
    696737        HMODULE hmod;
    697738                    // out: with TTFMT_STRINGRES, the module handle of the resource.
     
    790831     *      -- mp1 USHORT usID;
    791832     *             USHORT usNotifyCode == TTN_NEEDTEXT
    792      *      -- ULONG mp2: identifier of the tool, as in TOOLINFO.uId.
     833     *      -- ULONG mp2: PTOOLINFO of the tool for which the
     834     *             tool is about to be displayed.
    793835     *
    794836     *      Return value: always 0.
     
    808850     *      -- mp1 USHORT usID;
    809851     *             USHORT usNotifyCode == TTN_NEEDTEXT
    810      *      -- ULONG mp2: identifier of the tool, as in TOOLINFO.uId.
     852     *      -- ULONG mp2: PTOOLINFO of the tool for which the
     853     *             tooltip was visible.
    811854     *
    812855     *      Return value: always 0.
  • trunk/include/helpers/dosh.h

    r76 r81  
    6666     ********************************************************************/
    6767
    68     VOID XWPENTRY doshEnumDrives(PSZ pszBuffer,
    69                                  const char *pcszFileSystem,
    70                                  BOOL fSkipRemoveables);
    71     typedef VOID XWPENTRY DOSHENUMDRIVES(PSZ pszBuffer,
    72                                          const char *pcszFileSystem,
    73                                          BOOL fSkipRemoveables);
    74     typedef DOSHENUMDRIVES *PDOSHENUMDRIVES;
    75 
    76     CHAR doshQueryBootDrive(VOID);
    77 
    78     APIRET doshAssertDrive(ULONG ulLogicalDrive);
    79 
    80     APIRET doshSetLogicalMap(ULONG ulLogicalDrive);
    81 
    82     APIRET XWPENTRY doshQueryDiskSize(ULONG ulLogicalDrive, double *pdSize);
    83     typedef APIRET XWPENTRY DOSHQUERYDISKSIZE(ULONG ulLogicalDrive, double *pdSize);
    84     typedef DOSHQUERYDISKSIZE *PDOSHQUERYDISKSIZE;
    85 
    86     APIRET XWPENTRY doshQueryDiskFree(ULONG ulLogicalDrive, double *pdFree);
    87     typedef APIRET XWPENTRY DOSHQUERYDISKFREE(ULONG ulLogicalDrive, double *pdFree);
    88     typedef DOSHQUERYDISKFREE *PDOSHQUERYDISKFREE;
    89 
    90     APIRET XWPENTRY doshQueryDiskFSType(ULONG ulLogicalDrive, PSZ pszBuf, ULONG cbBuf);
    91     typedef APIRET XWPENTRY DOSHQUERYDISKFSTYPE(ULONG ulLogicalDrive, PSZ pszBuf, ULONG cbBuf);
    92     typedef DOSHQUERYDISKFSTYPE *PDOSHQUERYDISKFSTYPE;
    93 
    9468    APIRET doshIsFixedDisk(ULONG  ulLogicalDrive,
    9569                           PBOOL  pfFixed);
     
    10276        #define DEVATTR_GREATER16MB 0x0004      // physical device driver supports physical addresses > 16 MB
    10377
    104         #pragma pack(1)
     78        // #pragma pack(1)
    10579
    10680        /*
    107          *@@ DRIVEPARAMS:
     81         * DRIVEPARAMS:
    10882         *      structure used for doshQueryDiskParams.
     83         * removed this, we can directly use BIOSPARAMETERBLOCK
     84         * V0.9.13 (2001-06-14) [umoeller]
    10985         */
    11086
    111         typedef struct _DRIVEPARAMS
     87        /* typedef struct _DRIVEPARAMS
    11288        {
    11389            BIOSPARAMETERBLOCK bpb;
     
    11692                        // in the OS2 headers as follows:
    11793
    118                         /*
    11994                        typedef struct _BIOSPARAMETERBLOCK {
    120                           USHORT     usBytesPerSector;
     95                    0     USHORT     usBytesPerSector;
    12196                                        //  Number of bytes per sector.
    122                           BYTE       bSectorsPerCluster;
     97                    2     BYTE       bSectorsPerCluster;
    12398                                        //  Number of sectors per cluster.
    124                           USHORT     usReservedSectors;
     99                    3     USHORT     usReservedSectors;
    125100                                        //  Number of reserved sectors.
    126                           BYTE       cFATs;
     101                    5     BYTE       cFATs;
    127102                                        //  Number of FATs.
    128                           USHORT     cRootEntries;
     103                    6     USHORT     cRootEntries;
    129104                                        //  Number of root directory entries.
    130                           USHORT     cSectors;
     105                    8     USHORT     cSectors;
    131106                                        //  Number of sectors.
    132                           BYTE       bMedia;
     107                    10    BYTE       bMedia;
    133108                                        //  Media descriptor.
    134                           USHORT     usSectorsPerFAT;
     109                    11    USHORT     usSectorsPerFAT;
    135110                                        //  Number of secctors per FAT.
    136                           USHORT     usSectorsPerTrack;
     111                    13    USHORT     usSectorsPerTrack;
    137112                                        //  Number of sectors per track.
    138                           USHORT     cHeads;
     113                    15    USHORT     cHeads;
    139114                                        //  Number of heads.
    140                           ULONG      cHiddenSectors;
     115                    17    ULONG      cHiddenSectors;
    141116                                        //  Number of hidden sectors.
    142                           ULONG      cLargeSectors;
     117                    21    ULONG      cLargeSectors;
    143118                                        //  Number of large sectors.
    144                           BYTE       abReserved[6];
     119                    25    BYTE       abReserved[6];
    145120                                        //  Reserved.
    146                           USHORT     cCylinders;
     121                    31    USHORT     cCylinders;
    147122                                        //  Number of cylinders defined for the physical
    148123                                        // device.
    149                           BYTE       bDeviceType;
     124                    33    BYTE       bDeviceType;
    150125                                        //  Physical layout of the specified device.
    151                           USHORT     fsDeviceAttr;
     126                    34    USHORT     fsDeviceAttr;
    152127                                        //  A bit field that returns flag information
    153128                                        //  about the specified drive.
    154                         } BIOSPARAMETERBLOCK; */
     129                        } BIOSPARAMETERBLOCK;
     130
     131            // removed the following fields... these are already
     132            // in the extended BPB structure, as defined in the
     133            // Toolkit's BIOSPARAMETERBLOCK struct. Checked this,
     134            // the definition is the same for the Toolkit 3 and 4.5.
    155135
    156136            USHORT  usCylinders;
     
    167147                        // --  5:  Fixed disk
    168148                        // --  6:  Tape drive
    169                         // --  7:  Other (includes 1.44MB 3.5-inch diskette drive)
     149                        // --  7:  Other (includes 1.44MB 3.5-inch diskette drive
     150                        //         and CD-ROMs)
    170151                        // --  8:  R/W optical disk
    171152                        // --  9:  3.5-inch 4.0MB diskette drive (2.88MB formatted)
     
    173154                        // DEVATTR_* flags
    174155        } DRIVEPARAMS, *PDRIVEPARAMS;
    175         #pragma pack()
     156        #pragma pack() */
    176157
    177158        APIRET doshQueryDiskParams(ULONG ulLogicalDrive,
    178                                    PDRIVEPARAMS pdp);
     159                                   PBIOSPARAMETERBLOCK pdp);
    179160    #endif
     161
     162    VOID XWPENTRY doshEnumDrives(PSZ pszBuffer,
     163                                 const char *pcszFileSystem,
     164                                 BOOL fSkipRemoveables);
     165    typedef VOID XWPENTRY DOSHENUMDRIVES(PSZ pszBuffer,
     166                                         const char *pcszFileSystem,
     167                                         BOOL fSkipRemoveables);
     168    typedef DOSHENUMDRIVES *PDOSHENUMDRIVES;
     169
     170    CHAR doshQueryBootDrive(VOID);
     171
     172    #define ERROR_AUDIO_CD_ROM      10000
     173
     174    #define ASSERTFL_MIXEDMODECD    0x0001
     175
     176    APIRET doshAssertDrive(ULONG ulLogicalDrive,
     177                           ULONG fl);
     178
     179    APIRET doshSetLogicalMap(ULONG ulLogicalDrive);
     180
     181    APIRET XWPENTRY doshQueryDiskSize(ULONG ulLogicalDrive, double *pdSize);
     182    typedef APIRET XWPENTRY DOSHQUERYDISKSIZE(ULONG ulLogicalDrive, double *pdSize);
     183    typedef DOSHQUERYDISKSIZE *PDOSHQUERYDISKSIZE;
     184
     185    APIRET XWPENTRY doshQueryDiskFree(ULONG ulLogicalDrive, double *pdFree);
     186    typedef APIRET XWPENTRY DOSHQUERYDISKFREE(ULONG ulLogicalDrive, double *pdFree);
     187    typedef DOSHQUERYDISKFREE *PDOSHQUERYDISKFREE;
     188
     189    APIRET XWPENTRY doshQueryDiskFSType(ULONG ulLogicalDrive, PSZ pszBuf, ULONG cbBuf);
     190    typedef APIRET XWPENTRY DOSHQUERYDISKFSTYPE(ULONG ulLogicalDrive, PSZ pszBuf, ULONG cbBuf);
     191    typedef DOSHQUERYDISKFSTYPE *PDOSHQUERYDISKFSTYPE;
    180192
    181193    APIRET doshQueryDiskLabel(ULONG ulLogicalDrive,
     
    303315    APIRET doshSetPathAttr(const char* pcszFile,
    304316                           ULONG ulAttr);
     317
     318    APIRET doshOpenExisting(const char *pcszFilename,
     319                            ULONG ulOpenFlags,
     320                            HFILE *phf);
     321
     322    APIRET doshWriteAt(HFILE hf,
     323                       LONG lOffset,
     324                       ULONG ulMethod,
     325                       ULONG cb,
     326                       PBYTE pbData);
     327
     328    APIRET doshReadAt(HFILE hf,
     329                      LONG lOffset,
     330                      ULONG ulMethod,
     331                      ULONG cb,
     332                      PBYTE pbData);
    305333
    306334    APIRET doshLoadTextFile(const char *pcszFile,
  • trunk/include/helpers/except.h

    r64 r81  
    140140    extern PFNEXCHOOKERROR G_pfnExcHookError;
    141141
     142    extern ULONG G_ulExplainExceptionRunning;
     143
    142144    /********************************************************************
    143145     *
  • trunk/include/helpers/stringh.h

    r56 r81  
    157157     ********************************************************************/
    158158
    159     VOID strhArrayAppend(PSZ *ppszRoot,
    160                          const char *pcszNew,
    161                          PULONG pcbRoot);
     159    VOID XWPENTRY strhArrayAppend(PSZ *ppszRoot,
     160                                  const char *pcszNew,
     161                                  ULONG cbNew,
     162                                  PULONG pcbRoot);
    162163
    163164    PSZ strhCreateDump(PBYTE pb,
  • trunk/include/helpers/winh.h

    r76 r81  
    8383    #ifdef WINH_STANDARDWRAPPERS
    8484
    85         MRESULT _Optlink winhSendMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
     85        MRESULT XWPENTRY winhSendMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
    8686        #define WinSendMsg(a,b,c,d) winhSendMsg((a),(b),(c),(d))
    8787
    88         BOOL _Optlink winhPostMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
     88        BOOL XWPENTRY winhPostMsg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
    8989        #define WinPostMsg(a,b,c,d) winhPostMsg((a),(b),(c),(d))
    9090
    91         HWND _Optlink winhWindowFromID(HWND hwnd, ULONG id);
     91        HWND XWPENTRY winhWindowFromID(HWND hwnd, ULONG id);
    9292        #define WinWindowFromID(a,b) winhWindowFromID((a),(b))
    9393
    94         HWND _Optlink winhQueryWindow(HWND hwnd, LONG lCode);
     94        HWND XWPENTRY winhQueryWindow(HWND hwnd, LONG lCode);
    9595        #define WinQueryWindow(a,b) winhQueryWindow((a),(b))
    9696
     97        PVOID XWPENTRY winhQueryWindowPtr(HWND hwnd, LONG index);
     98        #define WinQueryWindowPtr(a,b) winhQueryWindowPtr((a),(b))
     99
     100        BOOL XWPENTRY winhSetWindowText(HWND hwnd, const char *pcsz);
     101        #define WinSetWindowText(a,b) winhSetWindowText((a),(b))
     102
     103        BOOL XWPENTRY winhSetDlgItemText(HWND hwnd, ULONG id, const char *pcsz);
     104        #define WinSetDlgItemText(a,b,c) winhSetDlgItemText((a),(b),(c))
    97105    #endif
    98106
  • trunk/src/helpers/cctl_tooltip.c

    r68 r81  
    8989 *
    9090 ********************************************************************/
    91 
    92 // screen size
    93 LONG        G_cxScreen = 0,
    94             G_cyScreen = 0;
    9591
    9692// linked list of all tools which were subclassed for tooltip
     
    365361    ULONG       ulTooltipID;        // from WM_CREATE
    366362
     363    LONG        cxScreen,
     364                cyScreen;
     365
    367366    BOOL        fIsActive;          // TRUE per default; changed by TTM_ACTIVATE
    368367
     
    407406 */
    408407
    409 VOID UpdateTooltipPresColors(HWND hwndTooltip,      // in: tooltip control
    410                              PTOOLTIPDATA pttd)     // in/out: tooltip data struct (QWL_USER) with color fields
    411 {
     408VOID UpdateTooltipPresColors(HWND hwndTooltip)      // in: tooltip control
     409{
     410    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     411
    412412    // tooltip background color:
    413413    pttd->lBackColor = winhQueryPresColor(hwndTooltip,
     
    433433
    434434/*
    435  *@@ PaintTooltip:
    436  *      this gets called from ctl_fnwpTooltip upon WM_PAINT.
     435 *@@ TtmCreate:
     436 *      implementation for WM_CREATE in ctl_fnwpTooltip.
     437 *
     438 *@@added V0.9.13 (2001-06-21) [umoeller]
     439 */
     440
     441MRESULT TtmCreate(HWND hwndTooltip,
     442                  MPARAM mp2)
     443{
     444    PTOOLTIPDATA pttd;
     445    PCREATESTRUCT pcs = (PCREATESTRUCT)mp2;
     446
     447    // allocate and initialize tooltip data
     448    pttd = (PTOOLTIPDATA)malloc(sizeof(TOOLTIPDATA));
     449    if (pttd)
     450    {
     451        CHAR        szFont[256];
     452        memset(pttd, 0, sizeof(TOOLTIPDATA));
     453        WinSetWindowPtr(hwndTooltip, 1, pttd);
     454
     455        pttd->hwndOwner = pcs->hwndOwner;
     456        pttd->hab = WinQueryAnchorBlock(hwndTooltip);
     457        pttd->ulTooltipID = pcs->id;
     458
     459        pttd->cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
     460        pttd->cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
     461
     462        pttd->fIsActive = TRUE;
     463
     464        // default timeouts
     465        pttd->ulTimeoutInitial = 1000;
     466        pttd->ulTimeoutAutopop = 5000;
     467        pttd->ulTimeoutReshow = 500;
     468
     469        // get colors from presparams/syscolors
     470        UpdateTooltipPresColors(hwndTooltip);
     471
     472        // check if font presparam set
     473        if (WinQueryPresParam(hwndTooltip,
     474                              PP_FONTNAMESIZE, 0,
     475                              NULL,
     476                              sizeof(szFont),
     477                              szFont,
     478                              QPF_NOINHERIT)
     479                == 0)
     480        {
     481            // no: set default font presparam
     482            // (we never want the System Proportional font)
     483            winhSetWindowFont(hwndTooltip,
     484                              NULL);      // default (WarpSans or 8.Helv)
     485        }
     486
     487        pttd->pszPaintText = strdup("undefined");
     488
     489        lstInit(&pttd->llTools, TRUE);      // auto-free items
     490
     491        // override CREATESTRUCT
     492        WinSetWindowPos(hwndTooltip,
     493                        HWND_TOP,
     494                        50, 50,
     495                        100, 100,
     496                        SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_HIDE);
     497
     498        return (MPARAM)FALSE;
     499    }
     500    else
     501        // malloc failed:
     502        return (MPARAM)TRUE;
     503}
     504
     505/*
     506 *@@ TtmTimer:
     507 *      implementation for WM_TIMER in ctl_fnwpTooltip.
     508 *
     509 *@@added V0.9.13 (2001-06-21) [umoeller]
     510 */
     511
     512BOOL TtmTimer(HWND hwndTooltip, MPARAM mp1)
     513{
     514    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     515    USHORT  usTimer = SHORT1FROMMP(mp1);
     516
     517    switch (usTimer)
     518    {
     519        case TOOLTIP_ID_TIMER_INITIAL:
     520            // _Pmpf(("WM_TIMER: Stopping initial timer: %d", usTimer));
     521            // _Pmpf((__FUNCTION__ ": TOOLTIP_ID_TIMER_INITIAL"));
     522            WinStopTimer(pttd->hab,
     523                         hwndTooltip,
     524                         usTimer);
     525            pttd->idTimerInitial = 0;
     526
     527            if (pttd->fIsActive)
     528                // show tooltip
     529                WinPostMsg(hwndTooltip, TTM_SHOWTOOLTIPNOW, (MPARAM)TRUE, 0);
     530        break;
     531
     532        case TOOLTIP_ID_TIMER_AUTOPOP:
     533            // _Pmpf(("WM_TIMER: Stopping autopop timer: %d", usTimer));
     534            WinStopTimer(pttd->hab,
     535                         hwndTooltip,
     536                         usTimer);
     537            pttd->idTimerAutopop = 0;
     538            WinPostMsg(hwndTooltip, TTM_SHOWTOOLTIPNOW, (MPARAM)FALSE, 0);
     539        break;
     540
     541        default:
     542            return FALSE;
     543    } // end switch
     544
     545    return (TRUE);
     546}
     547
     548/*
     549 *@@ TtmPaint:
     550 *      implementation for WM_PAINT in ctl_fnwpTooltip.
    437551 *
    438552 *@@added V0.9.1 (99-11-30) [umoeller]
    439553 */
    440554
    441 VOID PaintTooltip(HWND hwndTooltip,
    442                   PTOOLTIPDATA pttd)
    443 {
     555VOID TtmPaint(HWND hwndTooltip)
     556{
     557    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
    444558    HPS         hps = WinBeginPaint(hwndTooltip, NULLHANDLE, NULL);
    445559    POINTL      ptl = {0, 0};
     
    525639
    526640/*
     641 *@@ TtmDestroy:
     642 *      implementation for WM_DESTROY in ctl_fnwpTooltip.
     643 *
     644 *@@added V0.9.13 (2001-06-21) [umoeller]
     645 */
     646
     647VOID TtmDestroy(HWND hwndTooltip)
     648{
     649    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     650    // stop timers
     651    if (pttd->idTimerInitial)
     652        WinStopTimer(pttd->hab,
     653                     hwndTooltip,
     654                     pttd->idTimerInitial);
     655    if (pttd->idTimerAutopop)
     656        WinStopTimer(pttd->hab,
     657                     hwndTooltip,
     658                     pttd->idTimerAutopop);
     659    if (pttd->pszPaintText)
     660        free(pttd->pszPaintText);
     661
     662    // un-subclass all tools that we subclassed
     663    // V0.9.12 (2001-04-28) [umoeller]
     664    if (LockSubclassedTools())
     665    {
     666        PLISTNODE pNode;
     667        PSUBCLASSEDTOOL pst;
     668        for (pNode = lstQueryFirstNode(&pttd->llTools);
     669             pNode;
     670             pNode = pNode->pNext)
     671        {
     672            PTOOLINFO pti = (PTOOLINFO)pNode->pItemData;
     673            if (pst = FindSubclassedTool(pti->hwndTool))
     674                UnSubclassTool(pti->hwndTool);
     675        }
     676
     677        UnlockSubclassedTools();
     678    }
     679    // end V0.9.12 (2001-04-28) [umoeller]
     680
     681    lstClear(&pttd->llTools);
     682
     683    free(pttd);
     684}
     685
     686/*
     687 *@@ TtmAddTool:
     688 *      implementation for TTM_ADDTOOL in ctl_fnwpTooltip.
     689 *
     690 *@@added V0.9.13 (2001-06-21) [umoeller]
     691 */
     692
     693MRESULT TtmAddTool(HWND hwndTooltip, MPARAM mp2)
     694{
     695    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     696    if (mp2)
     697    {
     698        PTOOLINFO ptiPassed = (PTOOLINFO)mp2,
     699                  ptiNew = (PTOOLINFO)malloc(sizeof(TOOLINFO));
     700        if (ptiNew)
     701        {
     702            memcpy(ptiNew, ptiPassed, sizeof(TOOLINFO));
     703            lstAppendItem(&pttd->llTools,
     704                          ptiNew);
     705
     706            if (    (ptiPassed->ulFlags & TTF_SUBCLASS)
     707                 && (LockSubclassedTools()) // V0.9.12 (2001-04-28) [umoeller]
     708               )
     709            {
     710                // caller wants this tool to be subclassed:
     711                // well, do it then
     712                SubclassTool(hwndTooltip,
     713                             ptiPassed->hwndTool);
     714
     715                UnlockSubclassedTools();
     716            }
     717
     718            return ((MPARAM)TRUE);
     719        }
     720    }
     721
     722    return (MPARAM)FALSE;
     723}
     724
     725/*
     726 *@@ TtmDelTool:
     727 *      implementation for TTM_DELTOOL in ctl_fnwpTooltip.
     728 *
     729 *@@added V0.9.13 (2001-06-21) [umoeller]
     730 *@@changed V0.9.13 (2001-06-21) [umoeller]: fixed missing unlock
     731 *@@changed V0.9.13 (2001-06-21) [umoeller]: fixed endless loop
     732 */
     733
     734VOID TtmDelTool(HWND hwndTooltip, MPARAM mp2)
     735{
     736    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     737    PTOOLINFO ptiSearch = (PTOOLINFO)mp2;
     738    if (ptiSearch)
     739    {
     740        PLISTNODE pToolNode = lstQueryFirstNode(&pttd->llTools);
     741        while (pToolNode)
     742        {
     743            PTOOLINFO ptiThis = (PTOOLINFO)pToolNode->pItemData;
     744            if (    (ptiThis->hwndToolOwner == ptiSearch->hwndToolOwner)
     745                 && (ptiThis->hwndTool == ptiSearch->hwndTool)
     746               )
     747            {
     748                // found:
     749
     750                // V0.9.12 (2001-04-28) [umoeller]
     751                // unsubclass if this was subclassed
     752                if (ptiThis->ulFlags & TTF_SUBCLASS)
     753                {
     754                    if (LockSubclassedTools())
     755                    {
     756                        UnSubclassTool(ptiSearch->hwndTool);
     757
     758                        UnlockSubclassedTools();
     759                                // was missing V0.9.13 (2001-06-21) [umoeller]
     760                    }
     761                }
     762
     763                // remove the tool from the list
     764                lstRemoveNode(&pttd->llTools, pToolNode);
     765
     766                break;
     767            }
     768
     769            pToolNode = pToolNode->pNext;
     770                    // fixed endless loop V0.9.13 (2001-06-21) [umoeller]
     771        }
     772    }
     773}
     774
     775/*
     776 *@@ TtmRelayEvent:
     777 *      implementation for TTM_RELAYEVENT in ctl_fnwpTooltip.
     778 *
     779 *@@added V0.9.13 (2001-06-21) [umoeller]
     780 */
     781
     782VOID TtmRelayEvent(HWND hwndTooltip, MPARAM mp2)
     783{
     784    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     785    PQMSG pqmsg = (PQMSG)mp2;
     786    if (pqmsg)
     787    {
     788        POINTL      ptlPointer;
     789        PLISTNODE   pToolNode;
     790
     791        if (pttd->idTimerInitial)
     792        {
     793            // _Pmpf(("TTM_RELAYEVENT: Stopping timer: %d", pttd->idTimerInitial));
     794            WinStopTimer(pttd->hab,
     795                         hwndTooltip,
     796                         TOOLTIP_ID_TIMER_INITIAL);
     797            pttd->idTimerInitial = 0;
     798        }
     799
     800        WinQueryPointerPos(HWND_DESKTOP, &ptlPointer);
     801
     802        // find TOOLINFO from mouse position
     803        pttd->ptiMouseOver = NULL;
     804        pToolNode = lstQueryFirstNode(&pttd->llTools);
     805        while (pToolNode)
     806        {
     807            PTOOLINFO pti = (PTOOLINFO)pToolNode->pItemData;
     808            if (pti->hwndTool == pqmsg->hwnd)
     809            {
     810                // _Pmpf((__FUNCTION__ ": found tool"));
     811                pttd->ptiMouseOver = pti;
     812                break;
     813            }
     814            pToolNode = pToolNode->pNext;
     815        }
     816
     817        if (    (ptlPointer.x != pttd->ptlPointerLast.x)
     818             || (ptlPointer.y != pttd->ptlPointerLast.y)
     819             || (pqmsg->msg == WM_BUTTON1DOWN)
     820             || (pqmsg->msg == WM_BUTTON2DOWN)
     821             || (pqmsg->msg == WM_BUTTON3DOWN)
     822           )
     823        {
     824            // mouse pos changed:
     825            // hide tooltip
     826            WinPostMsg(hwndTooltip,
     827                       TTM_SHOWTOOLTIPNOW,
     828                       (MPARAM)FALSE,
     829                       0);
     830            memcpy(&pttd->ptlPointerLast, &ptlPointer, sizeof(POINTL));
     831
     832            // _Pmpf((__FUNCTION__ ": pttd->ptiMouseOver: 0x%lX", pttd->ptiMouseOver));
     833            // _Pmpf((__FUNCTION__ ": pttd->fIsActive: 0x%lX", pttd->fIsActive));
     834            if (    (pttd->ptiMouseOver)
     835                 && (pttd->fIsActive)
     836               )
     837            {
     838                // tool found and tooltip is activated:
     839                pttd->idTimerInitial = WinStartTimer(pttd->hab,
     840                                                     hwndTooltip,
     841                                                     TOOLTIP_ID_TIMER_INITIAL,
     842                                                     pttd->ulTimeoutInitial);
     843                // _Pmpf(("TTM_RELAYEVENT: Started timer: %d", pttd->idTimerInitial));
     844            }
     845        }
     846    } // end if (pqmsg)
     847}
     848
     849/*
     850 *@@ TtmGetDelayTime:
     851 *      implementation for TTM_GETDELAYTIME in ctl_fnwpTooltip.
     852 *
     853 *@@added V0.9.13 (2001-06-21) [umoeller]
     854 */
     855
     856MRESULT TtmGetDelayTime(HWND hwndTooltip, MPARAM mp1)
     857{
     858    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     859    switch ((ULONG)mp1)
     860    {
     861        case TTDT_AUTOPOP:
     862            return (MRESULT)pttd->ulTimeoutAutopop;
     863
     864        case TTDT_INITIAL:
     865            return (MRESULT)pttd->ulTimeoutInitial;
     866
     867        case TTDT_RESHOW:
     868            return (MRESULT)pttd->ulTimeoutReshow;
     869    }
     870
     871    return (0);
     872}
     873
     874/*
     875 *@@ TtmSetDelayTime:
     876 *      implementation for TTM_SETDELAYTIME in ctl_fnwpTooltip.
     877 *
     878 *@@added V0.9.13 (2001-06-21) [umoeller]
     879 */
     880
     881VOID TtmSetDelayTime(HWND hwndTooltip, MPARAM mp1, MPARAM mp2)
     882{
     883    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     884    ULONG   iDelay = (ULONG)mp2;
     885    switch (SHORT1FROMMP(mp1))
     886    {
     887        case TTDT_AUTOMATIC:
     888            pttd->ulTimeoutInitial = iDelay;
     889            pttd->ulTimeoutAutopop = iDelay * 5;
     890            pttd->ulTimeoutReshow = iDelay / 2;
     891        break;
     892
     893        case TTDT_AUTOPOP:
     894            pttd->ulTimeoutAutopop = iDelay;
     895        break;
     896
     897        case TTDT_INITIAL:
     898            pttd->ulTimeoutInitial = iDelay;
     899        break;
     900
     901        case TTDT_RESHOW:
     902            pttd->ulTimeoutReshow = iDelay;
     903        break;
     904    }
     905}
     906
     907/*
     908 *@@ TtmGetText:
     909 *      implementation for TTM_GETTEXT in ctl_fnwpTooltip.
     910 *
     911 *@@added V0.9.13 (2001-06-21) [umoeller]
     912 */
     913
     914VOID TtmGetText(HWND hwndTooltip, MPARAM mp2)
     915{
     916    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     917    PTOOLINFO pti = (PTOOLINFO)mp2;
     918
     919    if (pti->pszText == PSZ_TEXTCALLBACK)
     920    {
     921        // TTN_NEEDTEXT notification desired:
     922        // compose values for that msg
     923        TOOLTIPTEXT ttt = {0};
     924        // _Pmpf(("TTM_GETTEXT: PSZ_TEXTCALLBACK... sending TTN_NEEDTEXT"));
     925        ttt.hwndTooltip = hwndTooltip;
     926        ttt.hwndTool = pti->hwndTool;
     927        WinSendMsg(pti->hwndToolOwner,
     928                   WM_CONTROL,
     929                   MPFROM2SHORT(pttd->ulTooltipID,  // tooltip control wnd ID
     930                                TTN_NEEDTEXT),
     931                   &ttt);
     932
     933        // in case of error: set lpszText to NULL; this
     934        // is not specified in the docs however.
     935        pti->pszText = NULL;
     936
     937        switch (ttt.ulFormat)
     938        {
     939            case TTFMT_PSZ:
     940                if (ttt.pszText)
     941                    pti->pszText = ttt.pszText;
     942            break;
     943
     944            case TTFMT_STRINGRES:
     945                    // @@todo
     946            break;
     947        }
     948    }
     949}
     950
     951/*
     952 *@@ TtmEnumTools:
     953 *      implementation for TTM_ENUMTOOLS in ctl_fnwpTooltip.
     954 *
     955 *@@added V0.9.13 (2001-06-21) [umoeller]
     956 */
     957
     958MRESULT TtmEnumTools(HWND hwndTooltip, MPARAM mp1, MPARAM mp2)
     959{
     960    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     961    PTOOLINFO ptiTarget = (PTOOLINFO)mp2;
     962    if (ptiTarget)
     963    {
     964        PTOOLINFO ptiFound = (PTOOLINFO)lstItemFromIndex(&pttd->llTools,
     965                                                         SHORT1FROMMP(mp1));
     966        if (ptiFound)
     967        {
     968            memcpy(ptiTarget, ptiFound, sizeof(TOOLINFO));
     969            return (MRESULT)TRUE;
     970        }
     971    }
     972
     973    return (MRESULT)FALSE;
     974}
     975
     976/*
     977 *@@ TtmGetCurrentTool:
     978 *      implementation for TTM_GETCURRENTTOOL in ctl_fnwpTooltip.
     979 *
     980 *@@added V0.9.13 (2001-06-21) [umoeller]
     981 */
     982
     983MRESULT TtmGetCurrentTool(HWND hwndTooltip, MPARAM mp2)
     984{
     985    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     986    PTOOLINFO ptiTarget = (PTOOLINFO)mp2;
     987    if (ptiTarget)
     988    {
     989        if (pttd->ptiMouseOver)
     990        {
     991            memcpy(ptiTarget, pttd->ptiMouseOver, sizeof(TOOLINFO));
     992            return (MPARAM)TRUE;
     993        }
     994    }
     995
     996    return ((MPARAM)FALSE);
     997}
     998
     999/*
     1000 *@@ TtmGetToolInfo:
     1001 *      implementation for TTM_GETTOOLINFO in ctl_fnwpTooltip.
     1002 *
     1003 *@@added V0.9.13 (2001-06-21) [umoeller]
     1004 */
     1005
     1006MRESULT TtmGetToolInfo(HWND hwndTooltip, MPARAM mp2)
     1007{
     1008    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     1009    PTOOLINFO ptiSearch = (PTOOLINFO)mp2;
     1010    if (ptiSearch)
     1011    {
     1012        PLISTNODE pToolNode = lstQueryFirstNode(&pttd->llTools);
     1013        while (pToolNode)
     1014        {
     1015            PTOOLINFO ptiThis = (PTOOLINFO)pToolNode->pItemData;
     1016            if (    (ptiThis->hwndToolOwner == ptiSearch->hwndToolOwner)
     1017                 && (ptiThis->hwndTool == ptiSearch->hwndTool)
     1018               )
     1019            {
     1020                // found:
     1021                memcpy(ptiSearch, ptiThis, sizeof(TOOLINFO));
     1022                return (MPARAM)TRUE;
     1023            }
     1024            pToolNode = pToolNode->pNext;
     1025        }
     1026    }
     1027
     1028    return ((MPARAM)FALSE);
     1029}
     1030
     1031/*
     1032 *@@ FormatTooltip:
     1033 *      formats the tooltip window according to
     1034 *      its text (which is assumed to be in
     1035 *      pttd->pszPaintText) and positions it
     1036 *      on the screen.
     1037 *
     1038 *      This does not change the visibility
     1039 *      of the tooltip; if it is not yet visible,
     1040 *      you must show it afterwards.
     1041 *
     1042 *@@added V0.9.13 (2001-06-21) [umoeller]
     1043 */
     1044
     1045VOID FormatTooltip(HWND hwndTooltip,
     1046                   PTOOLTIPDATA pttd,
     1047                   PPOINTL pptlPointer)      // in: current pointer pos or NULL
     1048{
     1049    // find out how much space we need
     1050    RECTL   rcl = { 0, 0, 300, 1000 };
     1051    POINTL  ptlTooltip;
     1052    LONG    cx, cy;
     1053    ULONG   ulStyle = WinQueryWindowULong(hwndTooltip, QWL_STYLE);
     1054
     1055    HPS hps = WinGetPS(hwndTooltip);
     1056
     1057    winhDrawFormattedText(hps,
     1058                          &rcl,
     1059                          pttd->pszPaintText,
     1060                          DT_LEFT | DT_TOP | DT_WORDBREAK | DT_QUERYEXTENT);
     1061    WinReleasePS(hps);
     1062
     1063    // calc width and height of tooltip
     1064    cx = rcl.xRight + 2*TOOLTIP_CX_BORDER;
     1065    cy = (rcl.yTop - rcl.yBottom) + 2*TOOLTIP_CY_BORDER;
     1066
     1067    // calc x and y pos of tooltip:
     1068
     1069    // per default, use pointer pos
     1070    ptlTooltip.x = pptlPointer->x - cx/2;
     1071    ptlTooltip.y = pptlPointer->y - cy;
     1072
     1073    // do we need the tool's position?
     1074    if (    pttd->ptiMouseOver->ulFlags
     1075                & (TTF_CENTER_X_ON_TOOL | TTF_POS_Y_ABOVE_TOOL | TTF_POS_Y_BELOW_TOOL)
     1076       )
     1077    {
     1078        // yes:
     1079        SWP     swpTool;
     1080        POINTL  ptlTool;
     1081        WinQueryWindowPos(pttd->ptiMouseOver->hwndTool, &swpTool);
     1082        ptlTool.x = swpTool.x;
     1083        ptlTool.y = swpTool.y;
     1084        // convert x, y to desktop points
     1085        WinMapWindowPoints(WinQueryWindow(pttd->ptiMouseOver->hwndTool,
     1086                                          QW_PARENT), // hwndFrom
     1087                           HWND_DESKTOP,            // hwndTo
     1088                           &ptlTool,
     1089                           1);
     1090
     1091        // X
     1092        if (pttd->ptiMouseOver->ulFlags & TTF_CENTER_X_ON_TOOL)
     1093            // center X on tool:
     1094            ptlTooltip.x = ptlTool.x + ((swpTool.cx - cx) / 2L);
     1095
     1096        // Y
     1097        if (pttd->ptiMouseOver->ulFlags & TTF_POS_Y_ABOVE_TOOL)
     1098            ptlTooltip.y = ptlTool.y + swpTool.cy;
     1099        else if (pttd->ptiMouseOver->ulFlags & TTF_POS_Y_BELOW_TOOL)
     1100            ptlTooltip.y = ptlTool.y - cy;
     1101    }
     1102
     1103    // if "shy mouse" is enabled, make
     1104    // sure the tool tip is not under the
     1105    // mouse pointer
     1106    if (ulStyle & TTF_SHYMOUSE)
     1107    {
     1108        // we need to subtract the current mouse
     1109        // pointer's hot spot from the current
     1110        // pointer position
     1111        HPOINTER    hptr = WinQueryPointer(HWND_DESKTOP);
     1112        POINTERINFO pi;
     1113        if (WinQueryPointerInfo(hptr, &pi))
     1114        {
     1115            // calc bottom edge of mouse pointer rect
     1116            ULONG yBottomPointer = (pptlPointer->y - pi.yHotspot);
     1117            // _Pmpf(("yHotspot: %d", pi.yHotspot));
     1118            if (   (ptlTooltip.y + cy) // top edge of tool tip
     1119                 > yBottomPointer
     1120               )
     1121            {
     1122                ptlTooltip.y = pptlPointer->y - cy - pi.yHotspot;
     1123            }
     1124        }
     1125    }
     1126
     1127    // constrain to screen
     1128    if (ptlTooltip.x < 0)
     1129        ptlTooltip.x = 0;
     1130    if (ptlTooltip.y < 0)
     1131        ptlTooltip.y = 0;
     1132    if (ptlTooltip.x + cx > pttd->cxScreen)
     1133        ptlTooltip.x = pttd->cxScreen-cx;
     1134    if (ptlTooltip.y + cy > pttd->cyScreen)
     1135        ptlTooltip.y = pttd->cyScreen-cy;
     1136
     1137    // if shadow is enabled,
     1138    // enlarge; the shadow might by
     1139    // off-screen now, but that's OK
     1140    if (ulStyle & TTS_SHADOW)
     1141    {
     1142        cx += TT_SHADOWOFS;
     1143        cy += TT_SHADOWOFS;
     1144        ptlTooltip.y -= TT_SHADOWOFS;
     1145    }
     1146
     1147    // set tooltip position at the pos we calculated
     1148    // and show tooltip
     1149    WinSetWindowPos(hwndTooltip,
     1150                    HWND_TOP,
     1151                    ptlTooltip.x,
     1152                    ptlTooltip.y,
     1153                    cx,
     1154                    cy,
     1155                    SWP_MOVE | SWP_SIZE | SWP_ZORDER);
     1156}
     1157
     1158/*
     1159 *@@ TtmUpdateTipText:
     1160 *      implementation for TTM_UPDATETIPTEXT in ctl_fnwpTooltip.
     1161 *
     1162 *@@added V0.9.13 (2001-06-21) [umoeller]
     1163 */
     1164
     1165VOID TtmUpdateTipText(HWND hwndTooltip,
     1166                      const char *pcszNewText)
     1167{
     1168    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     1169
     1170    // has text really changed?
     1171    if (    (    (pttd->pszPaintText)
     1172              && (pcszNewText)
     1173              && (strcmp(pttd->pszPaintText, pcszNewText))
     1174            )
     1175         || (pttd->pszPaintText && !pcszNewText)
     1176         || (!pttd->pszPaintText && pcszNewText)
     1177       )
     1178    {
     1179        // yes:
     1180        if (pttd->pszPaintText)
     1181        {
     1182            free(pttd->pszPaintText);
     1183            pttd->pszPaintText = NULL;
     1184        }
     1185
     1186        if (pcszNewText)
     1187            pttd->pszPaintText = strdup(pcszNewText);
     1188
     1189        if (pttd->fIsVisible)
     1190        {
     1191            // currently showing:
     1192            // reformat
     1193            POINTL ptlPointer;
     1194            WinQueryPointerPos(HWND_DESKTOP, &ptlPointer);
     1195            FormatTooltip(hwndTooltip,
     1196                          pttd,
     1197                          &ptlPointer);
     1198            WinInvalidateRect(hwndTooltip, NULL, FALSE);
     1199        }
     1200    }
     1201}
     1202
     1203/*
    5271204 *@@ TtmShowTooltip:
    5281205 *      implementation for TTM_SHOW_TOOLTIP.
     
    5371214
    5381215VOID TtmShowTooltip(HWND hwndTooltip,
    539                     PTOOLTIPDATA pttd,
    5401216                    BOOL fShow)  // if TRUE: show, else: HIDE
    5411217{
    542     // _Pmpf((__FUNCTION__ ": fShow %d", fShow));
     1218    PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
    5431219    if (fShow)
    5441220    {
     
    5661242            // mouse not moved since timer was started:
    5671243            // find the current TOOLINFO
    568             // _Pmpf((__FUNCTION__ ": mouse not moved... pttd->ptiMouseOver 0x%lX", pttd->ptiMouseOver));
    5691244            if (pttd->ptiMouseOver)
    5701245            {
     
    5821257            }
    5831258
    584             // _Pmpf((__FUNCTION__ ": pttd->pszPaintText %s",
    585                //      (pttd->pszPaintText) ? pttd->pszPaintText : "NULL"));
    586 
    5871259            if (pttd->pszPaintText)
    5881260            {
    589                 // find out how much space we need
    590                 RECTL   rcl = { 0, 0, 300, 1000 };
    591                 POINTL  ptlTooltip;
    592                 LONG    cx, cy;
    593                 ULONG   ulStyle = WinQueryWindowULong(hwndTooltip, QWL_STYLE);
    594 
    595                 G_cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN),
    596                 G_cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
    597 
    598                 hps = WinGetPS(hwndTooltip);
    599                 winhDrawFormattedText(hps,
    600                                       &rcl,
    601                                       pttd->pszPaintText,
    602                                       DT_LEFT | DT_TOP | DT_WORDBREAK | DT_QUERYEXTENT);
    603                 WinReleasePS(hps);
    604 
    605                 // calc width and height of tooltip
    606                 cx = rcl.xRight + 2*TOOLTIP_CX_BORDER;
    607                 cy = (rcl.yTop - rcl.yBottom) + 2*TOOLTIP_CY_BORDER;
    608 
    609                 // calc x and y pos of tooltip:
    610 
    611                 // per default, use pointer pos
    612                 ptlTooltip.x = ptlPointer.x - cx/2;
    613                 ptlTooltip.y = ptlPointer.y - cy;
    614 
    615                 // do we need the tool's position?
    616                 if (    pttd->ptiMouseOver->ulFlags
    617                      & (TTF_CENTER_X_ON_TOOL | TTF_POS_Y_ABOVE_TOOL | TTF_POS_Y_BELOW_TOOL)
    618                    )
    619                 {
    620                     // yes:
    621                     SWP     swpTool;
    622                     POINTL  ptlTool;
    623                     WinQueryWindowPos(pttd->ptiMouseOver->hwndTool, &swpTool);
    624                     ptlTool.x = swpTool.x;
    625                     ptlTool.y = swpTool.y;
    626                     // convert x, y to desktop points
    627                     WinMapWindowPoints(WinQueryWindow(pttd->ptiMouseOver->hwndTool,
    628                                                       QW_PARENT), // hwndFrom
    629                                        HWND_DESKTOP,            // hwndTo
    630                                        &ptlTool,
    631                                        1);
    632 
    633                     // X
    634                     if (pttd->ptiMouseOver->ulFlags & TTF_CENTER_X_ON_TOOL)
    635                         // center X on tool:
    636                         ptlTooltip.x = ptlTool.x + ((swpTool.cx - cx) / 2L);
    637 
    638                     // Y
    639                     if (pttd->ptiMouseOver->ulFlags & TTF_POS_Y_ABOVE_TOOL)
    640                         ptlTooltip.y = ptlTool.y + swpTool.cy;
    641                     else if (pttd->ptiMouseOver->ulFlags & TTF_POS_Y_BELOW_TOOL)
    642                         ptlTooltip.y = ptlTool.y - cy;
    643                 }
    644 
    645                 // if "shy mouse" is enabled, make
    646                 // sure the tool tip is not under the
    647                 // mouse pointer
    648                 if (ulStyle & TTF_SHYMOUSE)
    649                 {
    650                     // we need to subtract the current mouse
    651                     // pointer's hot spot from the current
    652                     // pointer position
    653                     HPOINTER    hptr = WinQueryPointer(HWND_DESKTOP);
    654                     POINTERINFO pi;
    655                     if (WinQueryPointerInfo(hptr, &pi))
    656                     {
    657                         /* ULONG cyPointer = WinQuerySysValue(HWND_DESKTOP,
    658                                                            SV_CYPOINTER); */
    659                         // calc bottom edge of mouse pointer rect
    660                         ULONG yBottomPointer = (ptlPointer.y - pi.yHotspot);
    661                         // _Pmpf(("yHotspot: %d", pi.yHotspot));
    662                         if (   (ptlTooltip.y + cy) // top edge of tool tip
    663                              > yBottomPointer
    664                            )
    665                         {
    666                             ptlTooltip.y = ptlPointer.y - cy - pi.yHotspot;
    667                         }
    668                     }
    669                 }
    670 
    671                 // constrain to screen
    672                 if (ptlTooltip.x < 0)
    673                     ptlTooltip.x = 0;
    674                 if (ptlTooltip.y < 0)
    675                     ptlTooltip.y = 0;
    676                 if (ptlTooltip.x + cx > G_cxScreen)
    677                     ptlTooltip.x = G_cxScreen-cx;
    678                 if (ptlTooltip.y + cy > G_cyScreen)
    679                     ptlTooltip.y = G_cyScreen-cy;
    680 
    681                 // if shadow is enabled,
    682                 // enlarge; the shadow might by
    683                 // off-screen now, but that's OK
    684                 if (ulStyle & TTS_SHADOW)
    685                 {
    686                     cx += TT_SHADOWOFS;
    687                     cy += TT_SHADOWOFS;
    688                     ptlTooltip.y -= TT_SHADOWOFS;
    689                 }
    690 
    691                 // notify owner
     1261                FormatTooltip(hwndTooltip,
     1262                              pttd,
     1263                              &ptlPointer);
     1264
     1265                // notify owner (TTN_SHOW)
    6921266                WinSendMsg(pttd->hwndOwner,
    6931267                           WM_CONTROL,
    6941268                           MPFROM2SHORT(pttd->ulTooltipID,  // tooltip control wnd ID
    6951269                                        TTN_SHOW),
    696                            0);
    697 
    698                 // set tooltip position at the pos we calculated
    699                 // and show tooltip
    700                 WinSetWindowPos(hwndTooltip,
    701                                 HWND_TOP,
    702                                 ptlTooltip.x,
    703                                 ptlTooltip.y,
    704                                 cx, cy,
    705                                 SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW);
     1270                           pttd->ptiMouseOver);
     1271
     1272                WinShowWindow(hwndTooltip, TRUE);
    7061273                pttd->fIsVisible = TRUE;
    7071274
     
    7231290        if (pttd->fIsVisible)
    7241291        {
     1292            // notify owner (TTN_POP)
    7251293            WinSendMsg(pttd->hwndOwner,
    7261294                       WM_CONTROL,
    7271295                       MPFROM2SHORT(pttd->ulTooltipID,  // tooltip control wnd ID
    7281296                                    TTN_POP),
    729                        0);
     1297                       pttd->ptiMouseOver);
    7301298            WinShowWindow(hwndTooltip, FALSE);
    7311299        }
     
    8401408    MRESULT mrc = 0;
    8411409
    842     PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
    843 
    8441410    TRY_LOUD(excpt1)
    8451411    {
     
    8571423
    8581424            case WM_CREATE:
    859             {
    860                 PCREATESTRUCT pcs = (PCREATESTRUCT)mp2;
    861 
    862                 // allocate and initialize tooltip data
    863                 pttd = (PTOOLTIPDATA)malloc(sizeof(TOOLTIPDATA));
    864                 if (pttd)
    865                 {
    866                     CHAR        szFont[256];
    867                     memset(pttd, 0, sizeof(TOOLTIPDATA));
    868                     WinSetWindowPtr(hwndTooltip, 1, pttd);
    869 
    870                     pttd->hwndOwner = pcs->hwndOwner;
    871                     pttd->hab = WinQueryAnchorBlock(hwndTooltip);
    872                     pttd->ulTooltipID = pcs->id;
    873 
    874                     pttd->fIsActive = TRUE;
    875 
    876                     // default timeouts
    877                     pttd->ulTimeoutInitial = 1000;
    878                     pttd->ulTimeoutAutopop = 5000;
    879                     pttd->ulTimeoutReshow = 500;
    880 
    881                     // get colors from presparams/syscolors
    882                     UpdateTooltipPresColors(hwndTooltip, pttd);
    883 
    884                     // check if font presparam set
    885                     if (WinQueryPresParam(hwndTooltip,
    886                                           PP_FONTNAMESIZE, 0,
    887                                           NULL,
    888                                           sizeof(szFont),
    889                                           szFont,
    890                                           QPF_NOINHERIT)
    891                             == 0)
    892                     {
    893                         // no: set default font presparam
    894                         // (we never want the System Proportional font)
    895                         winhSetWindowFont(hwndTooltip,
    896                                           NULL);      // default (WarpSans or 8.Helv)
    897                     }
    898 
    899                     pttd->pszPaintText = strdup("undefined");
    900 
    901                     lstInit(&pttd->llTools, TRUE);      // auto-free items
    902 
    903                     // override CREATESTRUCT
    904                     WinSetWindowPos(hwndTooltip,
    905                                     HWND_TOP,
    906                                     50, 50,
    907                                     100, 100,
    908                                     SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_HIDE);
    909 
    910                     mrc = (MPARAM)FALSE;
    911                 }
    912                 else
    913                     // malloc failed:
    914                     mrc = (MPARAM)TRUE;
    915             break; }
    916 
    917             /*
    918              * WM_DESTROY:
    919              *      clean up upon destruction.
    920              */
    921 
    922             case WM_DESTROY:
    923                 // stop timers
    924                 if (pttd->idTimerInitial)
    925                     WinStopTimer(pttd->hab,
    926                                  hwndTooltip,
    927                                  pttd->idTimerInitial);
    928                 if (pttd->idTimerAutopop)
    929                     WinStopTimer(pttd->hab,
    930                                  hwndTooltip,
    931                                  pttd->idTimerAutopop);
    932                 if (pttd->pszPaintText)
    933                     free(pttd->pszPaintText);
    934 
    935                 // un-subclass all tools that we subclassed
    936                 // V0.9.12 (2001-04-28) [umoeller]
    937                 if (LockSubclassedTools())
    938                 {
    939                     PLISTNODE pNode;
    940                     PSUBCLASSEDTOOL pst;
    941                     for (pNode = lstQueryFirstNode(&pttd->llTools);
    942                          pNode;
    943                          pNode = pNode->pNext)
    944                     {
    945                         PTOOLINFO pti = (PTOOLINFO)pNode->pItemData;
    946                         if (pst = FindSubclassedTool(pti->hwndTool))
    947                             UnSubclassTool(pti->hwndTool);
    948                     }
    949 
    950                     UnlockSubclassedTools();
    951                 }
    952                 // end V0.9.12 (2001-04-28) [umoeller]
    953 
    954                 lstClear(&pttd->llTools);
    955 
    956                 free(pttd);
    957 
    958                 mrc = (MPARAM)0;
     1425                mrc = TtmCreate(hwndTooltip, mp2);
    9591426            break;
    9601427
     
    9791446
    9801447            case WM_TIMER:      // done
    981             {
    982                 USHORT  usTimer = SHORT1FROMMP(mp1);
    983 
    984                 switch (usTimer)
    985                 {
    986                     case TOOLTIP_ID_TIMER_INITIAL:
    987                         // _Pmpf(("WM_TIMER: Stopping initial timer: %d", usTimer));
    988                         // _Pmpf((__FUNCTION__ ": TOOLTIP_ID_TIMER_INITIAL"));
    989                         WinStopTimer(pttd->hab,
    990                                      hwndTooltip,
    991                                      usTimer);
    992                         pttd->idTimerInitial = 0;
    993 
    994                         if (pttd->fIsActive)
    995                             // show tooltip
    996                             WinPostMsg(hwndTooltip, TTM_SHOWTOOLTIPNOW, (MPARAM)TRUE, 0);
    997                     break;
    998 
    999                     case TOOLTIP_ID_TIMER_AUTOPOP:
    1000                         // _Pmpf(("WM_TIMER: Stopping autopop timer: %d", usTimer));
    1001                         WinStopTimer(pttd->hab,
    1002                                      hwndTooltip,
    1003                                      usTimer);
    1004                         pttd->idTimerAutopop = 0;
    1005                         WinPostMsg(hwndTooltip, TTM_SHOWTOOLTIPNOW, (MPARAM)FALSE, 0);
    1006                     break;
    1007 
    1008                     default:
    1009                         mrc = WinDefWindowProc(hwndTooltip, msg, mp1, mp2);
    1010                 } // end switch
    1011 
    1012             break; }
     1448                if (!TtmTimer(hwndTooltip, mp1))
     1449                    mrc = WinDefWindowProc(hwndTooltip, msg, mp1, mp2);
     1450            break;
    10131451
    10141452            /*
     
    10181456
    10191457            case WM_PAINT:      // done
    1020                 PaintTooltip(hwndTooltip, pttd);
     1458                TtmPaint(hwndTooltip);
    10211459            break;
    10221460
     
    10371475                    case PP_MENUHILITEBGNDCOLOR:
    10381476                        // re-query our presparams
    1039                         UpdateTooltipPresColors(hwndTooltip, pttd);
     1477                        UpdateTooltipPresColors(hwndTooltip);
    10401478                }
    10411479            break; }
     
    10471485
    10481486            case WM_SYSCOLORCHANGE:
    1049                 UpdateTooltipPresColors(hwndTooltip, pttd);
     1487                UpdateTooltipPresColors(hwndTooltip);
     1488            break;
     1489
     1490            /*
     1491             * WM_DESTROY:
     1492             *      clean up upon destruction.
     1493             */
     1494
     1495            case WM_DESTROY:
     1496                TtmDestroy(hwndTooltip);
    10501497            break;
    10511498
     
    10621509
    10631510            case TTM_ACTIVATE:      // done
    1064                 pttd->fIsActive = (BOOL)mp1;
    1065                 if (!pttd->fIsActive)
     1511            {
     1512                PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
     1513                if (!(pttd->fIsActive = (BOOL)mp1))
    10661514                    // disable: hide tooltip
    10671515                    WinPostMsg(hwndTooltip, TTM_SHOWTOOLTIPNOW, (MPARAM)FALSE, 0);
     1516            }
    10681517            break;
    10691518
     
    11211570
    11221571            case TTM_ADDTOOL:       // done
    1123                 mrc = (MPARAM)FALSE;
    1124                 if (mp2)
    1125                 {
    1126                     PTOOLINFO ptiPassed = (PTOOLINFO)mp2,
    1127                               ptiNew = (PTOOLINFO)malloc(sizeof(TOOLINFO));
    1128                     if (ptiNew)
    1129                     {
    1130                         memcpy(ptiNew, ptiPassed, sizeof(TOOLINFO));
    1131                         lstAppendItem(&pttd->llTools,
    1132                                       ptiNew);
    1133 
    1134                         if (    (ptiPassed->ulFlags & TTF_SUBCLASS)
    1135                              && (LockSubclassedTools()) // V0.9.12 (2001-04-28) [umoeller]
    1136                            )
    1137                         {
    1138                             // caller wants this tool to be subclassed:
    1139                             // well, do it then
    1140                             SubclassTool(hwndTooltip,
    1141                                          ptiPassed->hwndTool);
    1142 
    1143                             UnlockSubclassedTools();
    1144                         }
    1145 
    1146                         mrc = (MPARAM)TRUE;
    1147                     }
    1148                 }
     1572                mrc = TtmAddTool(hwndTooltip, mp2);
    11491573            break;
    11501574
     
    11561580             *      --  mp1: always 0.
    11571581             *      --  PTOOLINFO mp2: information about the tool;
    1158              *              all fields except cbSize, hwnd, uID are
    1159              *              ignored.
     1582             *              all fields except cbSize, hwndToolOwner,
     1583             *              and hwndTool are ignored.
    11601584             *
    11611585             *      Return value: 0 always.
     
    11631587
    11641588            case TTM_DELTOOL:       // done
    1165             {
    1166                 PTOOLINFO ptiSearch = (PTOOLINFO)mp2;
    1167                 if (ptiSearch)
    1168                 {
    1169                     PLISTNODE pToolNode = lstQueryFirstNode(&pttd->llTools);
    1170                     while (pToolNode)
    1171                     {
    1172                         PTOOLINFO ptiThis = (PTOOLINFO)pToolNode->pItemData;
    1173                         if (    (ptiThis->hwndToolOwner == ptiSearch->hwndToolOwner)
    1174                              && (ptiThis->hwndTool == ptiSearch->hwndTool)
    1175                            )
    1176                         {
    1177                             // found:
    1178 
    1179                             // V0.9.12 (2001-04-28) [umoeller]
    1180                             // unsubclass if this was subclassed
    1181                             if (ptiThis->ulFlags & TTF_SUBCLASS)
    1182                             {
    1183                                 if (LockSubclassedTools())
    1184                                 {
    1185                                     UnSubclassTool(ptiSearch->hwndTool);
    1186                                 }
    1187                             }
    1188 
    1189                             // remove the tool from the list
    1190                             lstRemoveNode(&pttd->llTools, pToolNode);
    1191 
    1192                             break;
    1193                         }
    1194                     }
    1195                     pToolNode = pToolNode->pNext;
    1196                 }
    1197             break; }
     1589                TtmDelTool(hwndTooltip, mp2);
     1590            break;
    11981591
    11991592            /*
     
    12931686
    12941687            case TTM_RELAYEVENT:
    1295             {
    1296                 PQMSG pqmsg = (PQMSG)mp2;
    1297                 if (pqmsg)
    1298                 {
    1299                     POINTL      ptlPointer;
    1300                     PLISTNODE   pToolNode;
    1301 
    1302                     if (pttd->idTimerInitial)
    1303                     {
    1304                         // _Pmpf(("TTM_RELAYEVENT: Stopping timer: %d", pttd->idTimerInitial));
    1305                         WinStopTimer(pttd->hab,
    1306                                      hwndTooltip,
    1307                                      TOOLTIP_ID_TIMER_INITIAL);
    1308                         pttd->idTimerInitial = 0;
    1309                     }
    1310 
    1311                     WinQueryPointerPos(HWND_DESKTOP, &ptlPointer);
    1312 
    1313                     // find TOOLINFO from mouse position
    1314                     pttd->ptiMouseOver = NULL;
    1315                     pToolNode = lstQueryFirstNode(&pttd->llTools);
    1316                     while (pToolNode)
    1317                     {
    1318                         PTOOLINFO pti = (PTOOLINFO)pToolNode->pItemData;
    1319                         if (pti->hwndTool == pqmsg->hwnd)
    1320                         {
    1321                             // _Pmpf((__FUNCTION__ ": found tool"));
    1322                             pttd->ptiMouseOver = pti;
    1323                             break;
    1324                         }
    1325                         pToolNode = pToolNode->pNext;
    1326                     }
    1327 
    1328                     if (    (ptlPointer.x != pttd->ptlPointerLast.x)
    1329                          || (ptlPointer.y != pttd->ptlPointerLast.y)
    1330                          || (pqmsg->msg == WM_BUTTON1DOWN)
    1331                          || (pqmsg->msg == WM_BUTTON2DOWN)
    1332                          || (pqmsg->msg == WM_BUTTON3DOWN)
    1333                        )
    1334                     {
    1335                         // mouse pos changed:
    1336                         // hide tooltip
    1337                         WinPostMsg(hwndTooltip,
    1338                                    TTM_SHOWTOOLTIPNOW,
    1339                                    (MPARAM)FALSE,
    1340                                    0);
    1341                         memcpy(&pttd->ptlPointerLast, &ptlPointer, sizeof(POINTL));
    1342 
    1343                         // _Pmpf((__FUNCTION__ ": pttd->ptiMouseOver: 0x%lX", pttd->ptiMouseOver));
    1344                         // _Pmpf((__FUNCTION__ ": pttd->fIsActive: 0x%lX", pttd->fIsActive));
    1345                         if (    (pttd->ptiMouseOver)
    1346                              && (pttd->fIsActive)
    1347                            )
    1348                         {
    1349                             // tool found and tooltip is activated:
    1350                             pttd->idTimerInitial = WinStartTimer(pttd->hab,
    1351                                                                  hwndTooltip,
    1352                                                                  TOOLTIP_ID_TIMER_INITIAL,
    1353                                                                  pttd->ulTimeoutInitial);
    1354                             // _Pmpf(("TTM_RELAYEVENT: Started timer: %d", pttd->idTimerInitial));
    1355                         }
    1356                     }
    1357                 } // end if (pqmsg)
    1358             break; }
     1688                TtmRelayEvent(hwndTooltip, mp2);
     1689            break;
    13591690
    13601691            /*
     
    13761707
    13771708            case TTM_GETDELAYTIME:
    1378                 switch ((ULONG)mp1)
    1379                 {
    1380                     case TTDT_AUTOPOP:
    1381                         mrc = (MRESULT)pttd->ulTimeoutAutopop;
    1382                     break;
    1383 
    1384                     case TTDT_INITIAL:
    1385                         mrc = (MRESULT)pttd->ulTimeoutInitial;
    1386                     break;
    1387 
    1388                     case TTDT_RESHOW:
    1389                         mrc = (MRESULT)pttd->ulTimeoutReshow;
    1390                     break;
    1391                 }
     1709                mrc = TtmGetDelayTime(hwndTooltip, mp1);
    13921710            break;
    13931711
     
    14331751
    14341752            case TTM_SETDELAYTIME:  // done
    1435             {
    1436                 ULONG   iDelay = (ULONG)mp2;
    1437                 switch (SHORT1FROMMP(mp1))
    1438                 {
    1439                     case TTDT_AUTOMATIC:
    1440                         pttd->ulTimeoutInitial = iDelay;
    1441                         pttd->ulTimeoutAutopop = iDelay * 5;
    1442                         pttd->ulTimeoutReshow = iDelay / 2;
    1443                     break;
    1444 
    1445                     case TTDT_AUTOPOP:
    1446                         pttd->ulTimeoutAutopop = iDelay;
    1447                     break;
    1448 
    1449                     case TTDT_INITIAL:
    1450                         pttd->ulTimeoutInitial = iDelay;
    1451                     break;
    1452 
    1453                     case TTDT_RESHOW:
    1454                         pttd->ulTimeoutReshow = iDelay;
    1455                     break;
    1456                 }
    1457             break; }
     1753                TtmSetDelayTime(hwndTooltip, mp1, mp2);
     1754            break;
    14581755
    14591756            /*
     
    14641761             *      -- mp1: always 0
    14651762             *      -- PTOOLINFO mp2: pointer to a TOOLINFO structure.
    1466              *         When sending the message, the hwnd and uId members
    1467              *         identify a tool. If the tooltip control includes
    1468              *         the tool, the lpszText member receives the pointer
    1469              *         to the string.
     1763             *         hwndTool identifies a tool. If the tooltip control
     1764             *         includes the tool, the pszText member receives
     1765             *         the pointer to the string on output.
    14701766             *
    14711767             *      Return value: 0 always.
     
    14771773
    14781774            case TTM_GETTEXT:       // done, I think
    1479             {
    1480                 PTOOLINFO pti = (PTOOLINFO)mp2;
    1481 
    1482                 if (pti->pszText == PSZ_TEXTCALLBACK)
    1483                 {
    1484                     // TTN_NEEDTEXT notification desired:
    1485                     // compose values for that msg
    1486                     TOOLTIPTEXT ttt = {0};
    1487                     // _Pmpf(("TTM_GETTEXT: PSZ_TEXTCALLBACK... sending TTN_NEEDTEXT"));
    1488                     ttt.hwndTooltip = hwndTooltip;
    1489                     ttt.hwndTool = pti->hwndTool;
    1490                     WinSendMsg(pti->hwndToolOwner,
    1491                                WM_CONTROL,
    1492                                MPFROM2SHORT(pttd->ulTooltipID,  // tooltip control wnd ID
    1493                                             TTN_NEEDTEXT),
    1494                                &ttt);
    1495 
    1496                     // in case of error: set lpszText to NULL; this
    1497                     // is not specified in the docs however.
    1498                     pti->pszText = NULL;
    1499 
    1500                     switch (ttt.ulFormat)
    1501                     {
    1502                         case TTFMT_PSZ:
    1503                             if (ttt.pszText)
    1504                                 pti->pszText = ttt.pszText;
    1505                         break;
    1506 
    1507                         case TTFMT_STRINGRES:
    1508                                 // @@todo
    1509                         break;
    1510                     }
    1511                 }
    1512             break; }
     1775                TtmGetText(hwndTooltip, mp2);
     1776            break;
    15131777
    15141778            /*
    15151779             *@@ TTM_UPDATETIPTEXT:
    1516              *      sets the tooltip text for a tool.
     1780             *      sets the current tooltip text explicitly,
     1781             *      no matter for what tool the tooltip is
     1782             *      currently being displayed. This might be
     1783             *      useful if you want to dynamically update
     1784             *      the tooltip display.
     1785             *
     1786             *      If the tooltip is currently showing,
     1787             *      it is reformatted with the new text.
     1788             *
     1789             *      Note that the change is not permanent;
     1790             *      if the mouse moves over a different
     1791             *      tool next, the change will be lost.
    15171792             *
    15181793             *      Parameters:
    1519              *      -- mp1: always 0.
    1520              *      -- PTOOLINFO mp2: pointer to a TOOLINFO structure.
    1521              *         The "hinst" and "lpszText" members must specify
    1522              *         the instance handle and the pointer to the text.
    1523              *         The "hwnd" and "uId" members identify the tool
    1524              *         to update.
     1794             *      -- PSZ mp1: new text to display.
     1795             *
     1796             *@@added V0.9.13 (2001-06-21) [umoeller]
    15251797             */
    15261798
    15271799            case TTM_UPDATETIPTEXT:
     1800                TtmUpdateTipText(hwndTooltip, (PSZ)mp1);
    15281801            break;
    15291802
     
    15931866
    15941867            case TTM_ENUMTOOLS:         // done
    1595             {
    1596                 PTOOLINFO ptiTarget = (PTOOLINFO)mp2;
    1597                 mrc = (MPARAM)FALSE;
    1598                 if (ptiTarget)
    1599                 {
    1600                     PTOOLINFO ptiFound = (PTOOLINFO)lstItemFromIndex(&pttd->llTools,
    1601                                                                      SHORT1FROMMP(mp1));
    1602                     if (ptiFound)
    1603                     {
    1604                         memcpy(ptiTarget, ptiFound, sizeof(TOOLINFO));
    1605                         mrc = (MRESULT)TRUE;
    1606                     }
    1607                 }
    1608             break; }
     1868                mrc = TtmEnumTools(hwndTooltip, mp1, mp2);
     1869            break;
    16091870
    16101871            /*
    16111872             *@@ TTM_GETCURRENTTOOL:
    1612              *      this message retrieves the information that the tooltip control
    1613              *      maintains for the _current_ tool; that is, the one for which
    1614              *      the tooltip control is currently displaying text.
     1873             *      this message retrieves the information that the
     1874             *      tooltip control maintains for the _current_ tool;
     1875             *      that is, the one for which the tooltip control
     1876             *      is currently displaying text.
    16151877             *
    16161878             *      Parameters:
     
    16231885
    16241886            case TTM_GETCURRENTTOOL:        // done
    1625             {
    1626                 PTOOLINFO ptiTarget = (PTOOLINFO)mp2;
    1627                 mrc = (MPARAM)FALSE;
    1628                 if (ptiTarget)
    1629                 {
    1630                     if (pttd->ptiMouseOver)
    1631                     {
    1632                         memcpy(ptiTarget, pttd->ptiMouseOver, sizeof(TOOLINFO));
    1633                         mrc = (MPARAM)TRUE;
    1634                     }
    1635                 }
    1636             break; }
     1887                mrc = TtmGetCurrentTool(hwndTooltip, mp2);
     1888            break;
    16371889
    16381890            /*
     
    16441896
    16451897            case TTM_GETTOOLCOUNT:          // done
     1898            {
     1899                PTOOLTIPDATA pttd = (PTOOLTIPDATA)WinQueryWindowPtr(hwndTooltip, 1);
    16461900                mrc = (MPARAM)lstCountItems(&pttd->llTools);
    1647             break;
     1901            break; }
    16481902
    16491903            /*
     
    16651919
    16661920            case TTM_GETTOOLINFO:       // done
    1667             {
    1668                 PTOOLINFO ptiSearch = (PTOOLINFO)mp2;
    1669                 mrc = (MPARAM)FALSE;
    1670                 if (ptiSearch)
    1671                 {
    1672                     PLISTNODE pToolNode = lstQueryFirstNode(&pttd->llTools);
    1673                     while (pToolNode)
    1674                     {
    1675                         PTOOLINFO ptiThis = (PTOOLINFO)pToolNode->pItemData;
    1676                         if (    (ptiThis->hwndToolOwner == ptiSearch->hwndToolOwner)
    1677                              && (ptiThis->hwndTool == ptiSearch->hwndTool)
    1678                            )
    1679                         {
    1680                             // found:
    1681                             memcpy(ptiSearch, ptiThis, sizeof(TOOLINFO));
    1682                             mrc = (MPARAM)TRUE;
    1683                             break;
    1684                         }
    1685                         pToolNode = pToolNode->pNext;
    1686                     }
    1687                 }
    1688             break; }
     1921                mrc = TtmGetToolInfo(hwndTooltip, mp2);
     1922            break;
    16891923
    16901924            /*
     
    17121946             *
    17131947             *      This is not part of the Win95 message set but used
    1714              *      in the OS/2 implementation only. This calls TtmShowTooltip
    1715              *      in turn.
     1948             *      in the OS/2 implementation only. This calls
     1949             *      TtmShowTooltip in turn.
    17161950             */
    17171951
    17181952            case TTM_SHOWTOOLTIPNOW:
    1719                 // _Pmpf((__FUNCTION__ ": TTM_SHOWTOOLTIPNOW %d", mp1));
    1720                 TtmShowTooltip(hwndTooltip, pttd, (BOOL)mp1);
     1953                TtmShowTooltip(hwndTooltip, (BOOL)mp1);
    17211954            break;
    17221955
  • trunk/src/helpers/comctl.c

    r53 r81  
    118118/* ******************************************************************
    119119 *
    120  *   Global variables
     120 *   "XButton" control
    121121 *
    122122 ********************************************************************/
     123
     124/*
     125 *@@ ctlPaintXButton:
     126 *      paints an X-button control. Can be called externally
     127 *      for just painting a button even if this is not really
     128 *      a window.
     129 *
     130 *      WARNING: this is work in progress and will change into
     131 *      the future. Eventually this will turn into a full
     132 *      button control replacement.
     133 *
     134 *@@added V0.9.13 (2001-06-21) [umoeller]
     135 */
     136
     137VOID ctlPaintXButton(HPS hps,               // in: presentation space (RGB mode)
     138                     ULONG fl,              // in: XBF_* flags
     139                     PXBUTTONDATA pxbd)     // in: button data
     140{
     141    ULONG   ulBorder = 0,
     142            cx,
     143            cy,
     144            ulOfs = 0;
     145    LONG    lLeft,
     146            lRight;
     147    RECTL   rclWin;
     148    memcpy(&rclWin, &pxbd->rcl, sizeof(RECTL));
     149
     150    if (0 == (fl & XBF_FLAT))
     151        ulBorder = 2;
     152
     153    gpihSwitchToRGB(hps);
     154
     155    if (fl & XBF_PRESSED)
     156    {
     157        // paint button "down":
     158        lLeft = pxbd->lcol3DDark;
     159        lRight = pxbd->lcol3DLight;
     160        // add offset for icon painting at the bottom
     161        ulOfs += 1;
     162        if (ulBorder == 0)
     163            ulBorder = 1;
     164    }
     165    else
     166    {
     167        lLeft = pxbd->lcol3DLight;
     168        lRight = pxbd->lcol3DDark;
     169    }
     170
     171    if (ulBorder)
     172    {
     173        // button border:
     174
     175        // now paint button frame
     176        rclWin.xRight--;
     177        rclWin.yTop--;
     178        gpihDraw3DFrame(hps,
     179                        &rclWin,        // inclusive
     180                        ulBorder,
     181                        lLeft,
     182                        lRight);
     183
     184        // now paint button middle
     185        rclWin.xLeft += ulBorder;
     186        rclWin.yBottom += ulBorder;
     187        rclWin.xRight -= ulBorder - 1;  // make exclusive again
     188        rclWin.yTop -= ulBorder - 1;    // make exclusive again
     189    }
     190
     191    if (fl & XBF_BACKGROUND)
     192        WinFillRect(hps,
     193                    &rclWin,        // exclusive
     194                    pxbd->lMiddle);
     195
     196    // get icon
     197    if (pxbd->hptr)
     198    {
     199        // calculate x and y to be centered in rectangle
     200        POINTL  ptl;
     201
     202        cx = rclWin.xRight - rclWin.xLeft;
     203        cy = rclWin.yTop - rclWin.yBottom;
     204
     205        ptl.x = rclWin.xLeft + ((cx - pxbd->cxMiniIcon) / 2);
     206        ptl.y = rclWin.yBottom + ((cy - pxbd->cxMiniIcon) / 2);
     207
     208        if (fl & XBF_INUSE)
     209        {
     210            // caller wants in-use (hatched) emphasis:
     211            // draw a box then
     212            POINTL ptl2;
     213            ptl2.x = ptl.x - 2;
     214            ptl2.y = ptl.y - 2;
     215            GpiMove(hps,
     216                    &ptl);
     217            GpiSetPattern(hps, PATSYM_DIAG1);
     218            ptl2.x = ptl.x + pxbd->cxMiniIcon + 1; // inclusive!
     219            ptl2.y = ptl.y + pxbd->cxMiniIcon + 1; // inclusive!
     220            GpiBox(hps,
     221                   DRO_FILL,
     222                   &ptl2,
     223                   0,
     224                   0);
     225        }
     226
     227        // now paint icon
     228        GpiIntersectClipRectangle(hps, &rclWin);    // exclusive!
     229        WinDrawPointer(hps,
     230                       // center this in remaining rectl
     231                       ptl.x + ulOfs,
     232                       ptl.y - ulOfs,
     233                       pxbd->hptr,
     234                       DP_MINI);
     235    }
     236}
    123237
    124238/*
  • trunk/src/helpers/dialog.c

    r80 r81  
    11651165 +                                        "My Dlg Title",
    11661166 +                                        DlgTemplate,      // DLGHITEM array
    1167  +                                        ARRAYITEMSIZE(DlgTemplate),
     1167 +                                        ARRAYITEMCOUNT(DlgTemplate),
    11681168 +                                        NULL))
    11691169 +          {
  • trunk/src/helpers/dosh.c

    r73 r81  
    251251
    252252/*
     253 *@@ doshDevIOCtl:
     254 *
     255 *      Works with those IOCtls where the buffer
     256 *      size parameters are always the same anyway,
     257 *      which applies to all IOCtls I have seen
     258 *      so far.
     259 *
     260 *@@added V0.9.13 (2001-06-14) [umoeller]
     261 */
     262
     263APIRET doshDevIOCtl(HFILE hf,
     264                    ULONG ulCategory,
     265                    ULONG ulFunction,
     266                    PVOID pvParams,
     267                    ULONG cbParams,
     268                    PVOID pvData,
     269                    ULONG cbData)
     270{
     271    return (DosDevIOCtl(hf,
     272                        ulCategory,
     273                        ulFunction,
     274                        pvParams, cbParams, &cbParams,
     275                        pvData, cbData, &cbData));
     276}
     277
     278/*
    253279 *@@category: Helpers\Control program helpers\Shared memory management
    254280 *      helpers for allocating and requesting shared memory.
     
    285311{
    286312    PVOID   pvrc = NULL;
    287     APIRET  arc = DosAllocSharedMem((PVOID*)(&pvrc),
     313    APIRET  arc = DosAllocSharedMem((PVOID*)&pvrc,
    288314                                    (PSZ)pcszName,
    289315                                    ulSize,
     
    312338{
    313339    PVOID pvrc = NULL;
    314     APIRET arc = DosGetNamedSharedMem((PVOID*)(pvrc),
     340    APIRET arc = DosGetNamedSharedMem((PVOID*)pvrc,
    315341                                      (PSZ)pcszName,
    316342                                      PAG_READ | PAG_WRITE);
     
    332358 *
    333359 ********************************************************************/
     360
     361/*
     362 *@@ doshIsFixedDisk:
     363 *      checks whether a disk is fixed or removeable.
     364 *      ulLogicalDrive must be 1 for drive A:, 2 for B:, ...
     365 *      The result is stored in *pfFixed.
     366 *      Returns DOS error code.
     367 *
     368 *      From my testing, this function does _not_ provoke
     369 *      "drive not ready" popups, even if the disk is not
     370 *      ready.
     371 *
     372 *      Warning: This uses DosDevIOCtl, which has proved
     373 *      to cause problems with some device drivers for
     374 *      removeable disks.
     375 */
     376
     377APIRET doshIsFixedDisk(ULONG  ulLogicalDrive,   // in: 1 for A:, 2 for B:, 3 for C:, ...
     378                       PBOOL  pfFixed)          // out: TRUE for fixed disks
     379{
     380    APIRET arc = ERROR_INVALID_DRIVE;
     381
     382    if (ulLogicalDrive)
     383    {
     384        // parameter packet
     385        #pragma pack(1)
     386        struct {
     387            UCHAR   command,
     388                    drive;
     389        } parms;
     390        #pragma pack()
     391
     392        // data packet
     393        UCHAR ucNonRemoveable;
     394
     395        parms.drive = (UCHAR)(ulLogicalDrive-1);
     396        arc = doshDevIOCtl((HFILE)-1,
     397                           IOCTL_DISK,
     398                           DSK_BLOCKREMOVABLE,
     399                           &parms, sizeof(parms),
     400                           &ucNonRemoveable, sizeof(ucNonRemoveable));
     401
     402        if (arc == NO_ERROR)
     403            *pfFixed = (BOOL)ucNonRemoveable;
     404    }
     405
     406    return (arc);
     407}
     408
     409/*
     410 *@@ doshQueryDiskParams:
     411 *      this retrieves more information about a given drive,
     412 *      which is stored in the specified BIOSPARAMETERBLOCK
     413 *      structure.
     414 *
     415 *      BIOSPARAMETERBLOCK is defined in the Toolkit headers,
     416 *      and from my testing, it's the same with the Toolkits
     417 *      3 and 4.5.
     418 *
     419 *      If NO_ERROR is returned, the bDeviceType field can
     420 *      be one of the following (according to CPREF):
     421 *
     422 *      --  0:  48 TPI low-density diskette drive
     423 *      --  1:  96 TPI high-density diskette drive
     424 *      --  2:  3.5-inch 720KB diskette drive
     425 *      --  3:  8-Inch single-density diskette drive
     426 *      --  4:  8-Inch double-density diskette drive
     427 *      --  5:  Fixed disk
     428 *      --  6:  Tape drive
     429 *      --  7:  Other (includes 1.44MB 3.5-inch diskette drive)
     430 *      --  8:  R/W optical disk
     431 *      --  9:  3.5-inch 4.0MB diskette drive (2.88MB formatted)
     432 *
     433 *      From my testing, this function does _not_ provoke
     434 *      "drive not ready" popups, even if the disk is not
     435 *      ready.
     436 *
     437 *      Warning: This uses DosDevIOCtl, which has proved
     438 *      to cause problems with some device drivers for
     439 *      removeable disks.
     440 *
     441 *      This returns the DOS error code of DosDevIOCtl.
     442 *
     443 *@@added V0.9.0 [umoeller]
     444 *@@changed V0.9.13 (2001-06-14) [umoeller]: changed prototype to use BIOSPARAMETERBLOCK directly
     445 *@@changed V0.9.13 (2001-06-14) [umoeller]: now querying standard media, no redetermine
     446 */
     447
     448APIRET doshQueryDiskParams(ULONG ulLogicalDrive,        // in:  1 for A:, 2 for B:, 3 for C:, ...
     449                           PBIOSPARAMETERBLOCK pdp)     // out: drive parameters
     450{
     451    APIRET arc = ERROR_INVALID_DRIVE;
     452
     453    if (ulLogicalDrive)
     454    {
     455        #pragma pack(1)
     456        // parameter packet
     457        struct {
     458            UCHAR   ucCommand,
     459                    ucDrive;
     460        } parms;
     461        #pragma pack()
     462
     463        parms.ucCommand = 0;    // 0 = return standard media,
     464                                // 1 = read currently inserted media
     465                                // (1 doesn't work any more, returns arc 87
     466                                // V0.9.13 (2001-06-14) [umoeller])
     467        parms.ucDrive=(UCHAR)(ulLogicalDrive-1);
     468
     469        // zero the structure V0.9.13 (2001-06-14) [umoeller]
     470        memset(pdp, 0, sizeof(BIOSPARAMETERBLOCK));
     471
     472        arc = doshDevIOCtl((HFILE)-1,
     473                           IOCTL_DISK,
     474                           DSK_GETDEVICEPARAMS,
     475                           &parms, sizeof(parms),
     476                           pdp,   sizeof(BIOSPARAMETERBLOCK));
     477
     478        if (!arc)
     479        {
     480            _Pmpf(("      bDeviceType: %d", pdp->bDeviceType));
     481            _Pmpf(("      bytes per sector: %d", pdp->usBytesPerSector));
     482            _Pmpf(("      sectors per track: %d", pdp->usSectorsPerTrack));
     483        }
     484    }
     485
     486    return (arc);
     487}
     488
     489/*
     490 *@@ doshIsCDROM:
     491 *      tests the specified BIOSPARAMETERBLOCK
     492 *      for whether it represents a CD-ROM drive.
     493 *
     494 *      The BIOSPARAMETERBLOCK must be filled
     495 *      first using doshQueryDiskParams.
     496 *
     497 *@@added V0.9.13 (2001-06-14) [umoeller]
     498 */
     499
     500BOOL doshIsCDROM(PBIOSPARAMETERBLOCK pdp)
     501{
     502    return (    (pdp)
     503             && (pdp->bDeviceType == 7)     // "other"
     504             && (pdp->usBytesPerSector == 2048)
     505             && (pdp->usSectorsPerTrack == (USHORT)-1)
     506           );
     507}
    334508
    335509/*
     
    376550    while (ulLogicalDrive <= 26)
    377551    {
    378         UCHAR nonRemovable=0;
    379         ULONG parmSize=2;
    380         ULONG dataLen=1;
    381 
    382552        #pragma pack(1)
    383553        struct
     
    387557        #pragma pack()
    388558
     559        // data packet
     560        UCHAR nonRemovable=0;
     561
    389562        parms.drive=(UCHAR)(ulLogicalDrive-1);
    390         arc = DosDevIOCtl((HFILE)-1,
    391                           IOCTL_DISK,
    392                           DSK_BLOCKREMOVABLE,
    393                           &parms,
    394                           parmSize,
    395                           &parmSize,
    396                           &nonRemovable,
    397                           1,
    398                           &dataLen);
     563        arc = doshDevIOCtl((HFILE)-1,
     564                           IOCTL_DISK,
     565                           DSK_BLOCKREMOVABLE,
     566                           &parms, sizeof(parms),
     567                           &nonRemovable, sizeof(nonRemovable));
    399568
    400569        if (    // fixed disk and non-removeable
     
    468637 *      those ugly white "Drive not ready" popups.
    469638 *
     639 *      "fl" can specify additional flags for testing
     640 *      and can be any combination of:
     641 *
     642 *      --  ASSERTFL_MIXEDMODECD: whether to allow
     643 *          mixed-mode CD-ROMs. See error codes below.
     644 *
    470645 *      This returns (from my testing):
     646 *
    471647 *      -- NO_ERROR: drive is available.
     648 *
    472649 *      -- ERROR_INVALID_DRIVE (15): drive letter does not exist.
    473  *      -- ERROR_NOT_READY (21): drive exists, but is not ready
    474  *                  (e.g. CD-ROM drive without CD inserted).
    475  *      -- ERROR_NOT_SUPPORTED (50): this is returned by the RAMFS.IFS
    476  *                  file system; apparently, the IFS doesn't support
    477  *                  DASD opening.
     650 *
     651 *      -- ERROR_NOT_READY (21): drive exists, but is not ready.
     652 *                  This is produced by floppies and CD-ROM drives
     653 *                  which do not have valid media inserted.
     654 *
     655 *      -- ERROR_AUDIO_CD_ROM (10000): special error code returned
     656 *                  only by this function if a CD-ROM drive has audio
     657 *                  media inserted.
     658 *
     659 *                  If ASSERTFL_MIXEDMODECD was specified, ERROR_AUDIO_CD_ROM
     660 *                  is returned _only_ if _no_ data tracks are
     661 *                  present on a CD-ROM. Since OS/2 is not very
     662 *                  good at handling mixed-mode CDs, this might not
     663 *                  be desireable.
     664 *
     665 *                  If ASSERTFL_MIXEDMODECD was not set, ERROR_AUDIO_CD_ROM
     666 *                  will be returned already if _one_ audio track is present.
    478667 *
    479668 *@@changed V0.9.1 (99-12-13) [umoeller]: rewritten, prototype changed. Now using DosOpen on the drive instead of DosError.
     
    484673 *@@changed V0.9.9 (2001-03-19) [pr]: validate drive number
    485674 *@@changed V0.9.11 (2001-04-23) [umoeller]: added an extra check for floppies
    486  */
    487 
    488 APIRET doshAssertDrive(ULONG ulLogicalDrive) // in: 1 for A:, 2 for B:, 3 for C:, ...
    489 {
    490     CHAR    szDrive[3] = "C:";
     675 *@@changed V0.9.13 (2001-06-14) [umoeller]: added "fl" parameter and lots of CD-ROM checks
     676 */
     677
     678APIRET doshAssertDrive(ULONG ulLogicalDrive,    // in: 1 for A:, 2 for B:, 3 for C:, ...
     679                       ULONG fl)                // in: ASSERTFL_* flags
     680{
    491681    HFILE   hfDrive = 0;
    492682    ULONG   ulTemp = 0;
    493     APIRET  arc;
     683    APIRET  arc = NO_ERROR;
     684    BOOL    fFixed = FALSE,
     685            fCDROM = FALSE;
    494686
    495687    if ((ulLogicalDrive < 1) || (ulLogicalDrive > 26))
    496688        return(ERROR_PATH_NOT_FOUND);
    497689
    498     szDrive[0] = 'A' + ulLogicalDrive - 1;
    499 
    500     arc = DosOpen(szDrive,   // "C:", "D:", ...
    501                   &hfDrive,
    502                   &ulTemp,
    503                   0,
    504                   FILE_NORMAL,
    505                   OPEN_ACTION_FAIL_IF_NEW
    506                          | OPEN_ACTION_OPEN_IF_EXISTS,
    507                   OPEN_FLAGS_DASD
    508                          | OPEN_FLAGS_FAIL_ON_ERROR
    509                          | OPEN_FLAGS_NOINHERIT     // V0.9.6 (2000-11-25) [pr]
    510                          | OPEN_ACCESS_READONLY
    511                          | OPEN_SHARE_DENYNONE,
    512                   NULL);
    513 
    514     // _Pmpf((__FUNCTION__ ": DosOpen(OPEN_FLAGS_DASD) returned %d", arc));
     690    arc = doshIsFixedDisk(ulLogicalDrive,
     691                          &fFixed);    // V0.9.13 (2001-06-14) [umoeller]
     692
     693    _Pmpf((__FUNCTION__ ": doshIsFixedDisk returned %d for disk %d", arc, ulLogicalDrive));
     694    _Pmpf(("   fFixed is %d", fFixed));
     695
     696    if (!arc)
     697        if (!fFixed)
     698        {
     699            // removeable disk:
     700            // check if it's a CD-ROM
     701            BIOSPARAMETERBLOCK bpb;
     702            arc = doshQueryDiskParams(ulLogicalDrive,
     703                                      &bpb);
     704            _Pmpf(("   doshQueryDiskParams returned %d", arc));
     705
     706            if (    (!arc)
     707                 && (doshIsCDROM(&bpb))
     708               )
     709            {
     710                _Pmpf(("   --> is CD-ROM"));
     711                fCDROM = TRUE;
     712            }
     713        }
     714
     715    if (!arc)
     716    {
     717        CHAR    szDrive[3] = "C:";
     718        szDrive[0] = 'A' + ulLogicalDrive - 1;
     719        arc = DosOpen(szDrive,   // "C:", "D:", ...
     720                      &hfDrive,
     721                      &ulTemp,
     722                      0,
     723                      FILE_NORMAL,
     724                      OPEN_ACTION_FAIL_IF_NEW
     725                             | OPEN_ACTION_OPEN_IF_EXISTS,
     726                      OPEN_FLAGS_DASD
     727                             | OPEN_FLAGS_FAIL_ON_ERROR
     728                             | OPEN_FLAGS_NOINHERIT     // V0.9.6 (2000-11-25) [pr]
     729                  //            | OPEN_ACCESS_READONLY  // V0.9.13 (2001-06-14) [umoeller]
     730                             | OPEN_SHARE_DENYNONE,
     731                      NULL);
     732
     733        _Pmpf(("   DosOpen(OPEN_FLAGS_DASD) returned %d", arc));
     734
     735        // this still returns NO_ERROR for audio CDs in a
     736        // CD-ROM drive...
     737        // however, the WPS then attempts to read in the
     738        // root directory for audio CDs, which produces
     739        // a "sector not found" error box...
     740
     741        if (!arc && hfDrive && fCDROM)     // determined above
     742        {
     743            ULONG ulAudioTracks = 0,
     744                  ulDataTracks = 0;
     745
     746            CHAR cds1[4] = { 'C', 'D', '0', '1' };
     747            CHAR cds2[4];
     748            // check for proper driver signature
     749            if (!(arc = doshDevIOCtl(hfDrive,
     750                                     IOCTL_CDROMDISK,
     751                                     CDROMDISK_GETDRIVER,
     752                                     &cds1, sizeof(cds1),
     753                                     &cds2, sizeof(cds2))))
     754            {
     755                if (memcmp(&cds1, &cds2, 4))
     756                    // this is not a CD-ROM then:
     757                    arc = NO_ERROR;
     758                else
     759                {
     760                    struct {
     761                        UCHAR   ucFirstTrack,
     762                                ucLastTrack;
     763                        ULONG   ulLeadOut;
     764                    } cdat;
     765
     766                    // get track count
     767                    if (!(arc = doshDevIOCtl(hfDrive,
     768                                             IOCTL_CDROMAUDIO,
     769                                             CDROMAUDIO_GETAUDIODISK,
     770                                             &cds1, sizeof(cds1),
     771                                             &cdat, sizeof(cdat))))
     772                    {
     773                        // still no error: build the audio TOC
     774                        ULONG i;
     775                        for (i = cdat.ucFirstTrack;
     776                             i <= cdat.ucLastTrack;
     777                             i++)
     778                        {
     779                            BYTE cdtp[5] =
     780                              { 'C', 'D', '0', '1', (UCHAR)i };
     781
     782                            struct {
     783                                ULONG   ulTrackAddress;
     784                                BYTE    bFlags;
     785                            } trackdata;
     786
     787                            if (!(arc = doshDevIOCtl(hfDrive,
     788                                                     IOCTL_CDROMAUDIO,
     789                                                     CDROMAUDIO_GETAUDIOTRACK,
     790                                                     &cdtp, sizeof(cdtp),
     791                                                     &trackdata, sizeof(trackdata))))
     792                            {
     793                                if (trackdata.bFlags & 64)
     794                                    ulDataTracks++;
     795                                else
     796                                {
     797                                    ulAudioTracks++;
     798
     799                                    if (!(fl & ASSERTFL_MIXEDMODECD))
     800                                    {
     801                                        // caller doesn't want mixed mode:
     802                                        // stop here
     803                                        ulDataTracks = 0;
     804                                        break;
     805                                    }
     806                                }
     807                            }
     808                        }
     809
     810                        _Pmpf(("   got %d audio, %d data tracks",
     811                                    ulAudioTracks, ulDataTracks));
     812
     813                        if (!ulDataTracks)
     814                            arc = ERROR_AUDIO_CD_ROM;       // special private error code (10000)
     815                    }
     816                    else
     817                    {
     818                        // not audio disk:
     819                        // go on then
     820                        _Pmpf(("   CDROMAUDIO_GETAUDIODISK returned %d", arc));
     821                        arc = NO_ERROR;
     822                    }
     823                }
     824            }
     825            else
     826            {
     827                // not CD-ROM: go on then
     828                _Pmpf(("   CDROMDISK_GETDRIVER returned %d", arc));
     829                arc = NO_ERROR;
     830            }
     831        }
     832    }
    515833
    516834    switch (arc)
     
    544862                                     &fsa,
    545863                                     sizeof(fsa));
     864                _Pmpf(("   re-checked, DosQueryFSInfo returned %d", arc));
    546865            }
    547866        break;
    548 
    549         case NO_ERROR:
    550             DosClose(hfDrive);
    551         break;
    552     }
     867    }
     868
     869    if (hfDrive)
     870        DosClose(hfDrive);
    553871
    554872    return (arc);
     
    597915        paramsize = sizeof(param);
    598916        datasize = sizeof(data);
    599         rc = DosDevIOCtl(fd,
    600                          IOCTL_DISK, DSK_SETLOGICALMAP,
    601                          &param, paramsize, &paramsize,
    602                          &data, datasize, &datasize);
     917        rc = doshDevIOCtl(fd,
     918                          IOCTL_DISK, DSK_SETLOGICALMAP,
     919                          &param, sizeof(param),
     920                          &data, sizeof(data));
    603921        DosClose(fd);
    604922    }
     
    7001018                   (CHAR*)(&pfsqBuffer->szName) + pfsqBuffer->cbName + 1);
    7011019        }
    702     }
    703 
    704     return (arc);
    705 }
    706 
    707 /*
    708  *@@ doshIsFixedDisk:
    709  *      checks whether a disk is fixed or removeable.
    710  *      ulLogicalDrive must be 1 for drive A:, 2 for B:, ...
    711  *      The result is stored in *pfFixed.
    712  *      Returns DOS error code.
    713  *
    714  *      Warning: This uses DosDevIOCtl, which has proved
    715  *      to cause problems with some device drivers for
    716  *      removeable disks.
    717  */
    718 
    719 APIRET doshIsFixedDisk(ULONG  ulLogicalDrive,   // in: 1 for A:, 2 for B:, 3 for C:, ...
    720                        PBOOL  pfFixed)          // out: TRUE for fixed disks
    721 {
    722     APIRET arc = ERROR_INVALID_DRIVE;
    723 
    724     if (ulLogicalDrive)
    725     {
    726         // parameter packet
    727         #pragma pack(1)
    728         struct {
    729             UCHAR command, drive;
    730         } parms;
    731         #pragma pack()
    732 
    733         // data packet
    734         UCHAR ucNonRemoveable;
    735 
    736         ULONG ulParmSize = sizeof(parms);
    737         ULONG ulDataSize = sizeof(ucNonRemoveable);
    738 
    739         parms.drive = (UCHAR)(ulLogicalDrive-1);
    740         arc = DosDevIOCtl((HFILE)-1,
    741                           IOCTL_DISK,
    742                           DSK_BLOCKREMOVABLE,
    743                           &parms,
    744                           ulParmSize,
    745                           &ulParmSize,
    746                           &ucNonRemoveable,
    747                           ulDataSize,
    748                           &ulDataSize);
    749 
    750         if (arc == NO_ERROR)
    751             *pfFixed = (BOOL)ucNonRemoveable;
    752     }
    753 
    754     return (arc);
    755 }
    756 
    757 /*
    758  *@@ doshQueryDiskParams:
    759  *      this retrieves more information about a given drive,
    760  *      which is stored in the specified DRIVEPARAMS structure
    761  *      (dosh.h).
    762  *
    763  *      Warning: This uses DosDevIOCtl, which has proved
    764  *      to cause problems with some device drivers for
    765  *      removeable disks.
    766  *
    767  *      This returns the DOS error code of DosDevIOCtl.
    768  *
    769  *@@added V0.9.0 [umoeller]
    770  */
    771 
    772 APIRET doshQueryDiskParams(ULONG ulLogicalDrive,        // in:  1 for A:, 2 for B:, 3 for C:, ...
    773                            PDRIVEPARAMS pdp)            // out: drive parameters
    774 {
    775     APIRET arc = ERROR_INVALID_DRIVE;
    776 
    777     if (ulLogicalDrive)
    778     {
    779         #pragma pack(1)
    780         // parameter packet
    781         struct {
    782             UCHAR command, drive;
    783         } parms;
    784         #pragma pack()
    785 
    786         ULONG ulParmSize = sizeof(parms);
    787         ULONG ulDataSize = sizeof(DRIVEPARAMS);
    788 
    789         parms.command = 1; // read currently inserted media
    790         parms.drive=(UCHAR)(ulLogicalDrive-1);
    791 
    792         arc = DosDevIOCtl((HFILE)-1,
    793                           IOCTL_DISK,
    794                           DSK_GETDEVICEPARAMS,
    795                           // parameter packet:
    796                           &parms, ulParmSize, &ulParmSize,
    797                           // data packet: DRIVEPARAMS structure
    798                           pdp,    ulDataSize, &ulDataSize);
    7991020    }
    8001021
     
    11091330    }
    11101331    return (rc);
     1332}
     1333
     1334/*
     1335 *@@ doshOpenExisting:
     1336 *      opens an existing file for read-write access. Does
     1337 *      not create a new file if the file doesn't exist.
     1338 *
     1339 *      This is just a simple wrapper around DosOpen.
     1340 *
     1341 *      ulOpenFlags is passed to DosOpen. Should be one
     1342 *      of:
     1343 *
     1344 *      --  for read-only access:
     1345 *
     1346 +              OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY
     1347 *
     1348 *      --  for read-write access:
     1349 *
     1350 +              OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE
     1351 *
     1352 *      In addition, you can specify
     1353 *
     1354 +          OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM
     1355 +                          | OPEN_FLAGS_NOINHERIT
     1356 *
     1357 *@@added V0.9.13 (2001-06-14) [umoeller]
     1358 */
     1359
     1360APIRET doshOpenExisting(const char *pcszFilename,   // in: file name
     1361                        ULONG ulOpenFlags,          // in: open flags
     1362                        HFILE *phf)                 // out: OS/2 file handle
     1363{
     1364    ULONG ulAction;
     1365    return (DosOpen((PSZ)pcszFilename,
     1366                    phf,
     1367                    &ulAction,
     1368                    0,          // cbFile
     1369                    0,          // attributes
     1370                    OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
     1371                    ulOpenFlags,
     1372                    NULL));     // EAs
     1373}
     1374
     1375/*
     1376 *@@ doshWriteAt:
     1377 *      writes cb bytes (pointed to by pbData) to the
     1378 *      position specified by ulMethod and lOffset into
     1379 *      the file specified by hf.
     1380 *
     1381 *      If ulMethod is FILE_BEGIN, lOffset specifies the
     1382 *      offset from the beginning of the file. With
     1383 *      FILE_CURRENT, lOffset is considered from the
     1384 *      current file pointer, and with FILE_END, it is
     1385 *      considered from the end of the file.
     1386 *
     1387 *@@added V0.9.13 (2001-06-14) [umoeller]
     1388 */
     1389
     1390APIRET doshWriteAt(HFILE hf,        // in: OS/2 file handle
     1391                   LONG lOffset,    // in: offset to write at (depends on ulMethod)
     1392                   ULONG ulMethod,  // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END
     1393                   ULONG cb,        // in: bytes to write
     1394                   PBYTE pbData)    // in: ptr to bytes to write (must be cb bytes)
     1395{
     1396    APIRET arc;
     1397    ULONG ulDummy;
     1398    if (!(arc = DosSetFilePtr(hf,
     1399                              lOffset,
     1400                              ulMethod,
     1401                              &ulDummy)))
     1402        arc = DosWrite(hf,
     1403                       pbData,
     1404                       cb,
     1405                       &ulDummy);
     1406
     1407    return (arc);
     1408}
     1409
     1410/*
     1411 *@@ doshReadAt:
     1412 *      reads cb bytes from the position specified by
     1413 *      ulMethod and lOffset into the buffer pointed to
     1414 *      by pbData, which should be cb bytes in size.
     1415 *
     1416 *      Use lOffset and ulMethod as with doshWriteAt.
     1417 *
     1418 *@@added V0.9.13 (2001-06-14) [umoeller]
     1419 */
     1420
     1421APIRET doshReadAt(HFILE hf,        // in: OS/2 file handle
     1422                  LONG lOffset,    // in: offset to write at (depends on ulMethod)
     1423                  ULONG ulMethod,  // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END
     1424                  ULONG cb,        // in: bytes to write
     1425                  PBYTE pbData)    // out: read buffer (must be cb bytes)
     1426{
     1427    APIRET arc;
     1428    ULONG ulDummy;
     1429    if (!(arc = DosSetFilePtr(hf,
     1430                              lOffset,
     1431                              ulMethod,
     1432                              &ulDummy)))
     1433        arc = DosRead(hf,
     1434                      pbData,
     1435                      cb,
     1436                      &ulDummy);
     1437
     1438    return (arc);
    11111439}
    11121440
  • trunk/src/helpers/except.c

    r68 r81  
    260260BOOL            G_fBeepOnException = TRUE;
    261261
     262ULONG           G_ulExplainExceptionRunning = 0;
     263    // global flag which is != 0 if some exception handler
     264    // is inside excExplainException, so that XShutdown can
     265    // wait until the trap log is done;
     266    // this is exported thru except.h
     267    // V0.9.13 (2001-06-19) [umoeller]
     268
    262269/*
    263270 *@@category: Helpers\Control program helpers\Exceptions/debugging
     
    452459 *@@changed V0.9.3 (2000-05-03) [umoeller]: fixed crashes
    453460 *@@changed V0.9.6 (2000-11-06) [umoeller]: added more register dumps
     461 *@@changed V0.9.13 (2001-06-19) [umoeller]: added global flag for whether this is running
    454462 */
    455463
     
    472480
    473481    ULONG       ulOldPriority = 0x0100; // regular, delta 0
     482
     483    // raise global flag for whether this func is running
     484    // V0.9.13 (2001-06-19) [umoeller]
     485    G_ulExplainExceptionRunning++;
    474486
    475487    // raise this thread's priority, because this
     
    750762                   (UCHAR)ulOldPriority,
    751763                   0);     // current thread
     764
     765    // lower global flag again V0.9.13 (2001-06-19) [umoeller]
     766    G_ulExplainExceptionRunning--;
    752767}
    753768
  • trunk/src/helpers/gpih.c

    r79 r81  
    12071207    }
    12081208
    1209     _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn));
     1209    // _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn));
    12101210
    12111211    return (lLCIDReturn);
  • trunk/src/helpers/stringh.c

    r73 r81  
    16421642 *      Note: On the first call, *ppszRoot and *pcbRoot
    16431643 *      _must_ be both NULL, or this crashes.
     1644 *
     1645 *@@changed V0.9.13 (2001-06-21) [umoeller]: added cbNew
    16441646 */
    16451647
    16461648VOID strhArrayAppend(PSZ *ppszRoot,         // in: root of array
    16471649                     const char *pcszNew,   // in: string to append
     1650                     ULONG cbNew,           // in: size of that string or 0 to run strlen() here
    16481651                     PULONG pcbRoot)        // in/out: size of array
    16491652{
    1650     ULONG cbNew = strlen(pcszNew);
    1651     PSZ pszTemp = (PSZ)malloc(*pcbRoot
    1652                               + cbNew
    1653                               + 1);    // two null bytes
     1653    PSZ pszTemp;
     1654
     1655    if (!cbNew)     // V0.9.13 (2001-06-21) [umoeller]
     1656        cbNew = strlen(pcszNew);
     1657
     1658    pszTemp = (PSZ)malloc(*pcbRoot
     1659                          + cbNew
     1660                          + 1);    // two null bytes
    16541661    if (*ppszRoot)
    16551662    {
  • trunk/src/helpers/winh.c

    r76 r81  
    160160        // put the call in brackets so the macro won't apply here
    161161        return ((WinQueryWindow)(hwnd, lCode));
     162    }
     163
     164    /*
     165     *@@ winhQueryWindowPtr:
     166     *
     167     *@@added V0.9.13 (2001-06-21) [umoeller]
     168     */
     169
     170    PVOID winhQueryWindowPtr(HWND hwnd, LONG index)
     171    {
     172        // put the call in brackets so the macro won't apply here
     173        return ((WinQueryWindowPtr)(hwnd, index));
     174    }
     175
     176    /*
     177     *@@ winhSetWindowText:
     178     *
     179     *@@added V0.9.13 (2001-06-21) [umoeller]
     180     */
     181
     182    BOOL winhSetWindowText(HWND hwnd, const char *pcsz)
     183    {
     184        // put the call in brackets so the macro won't apply here
     185        return (WinSetWindowText)(hwnd, (PSZ)pcsz);
     186    }
     187
     188    /*
     189     *@@ winhSetDlgItemText:
     190     *
     191     *@@added V0.9.13 (2001-06-21) [umoeller]
     192     */
     193
     194    BOOL winhSetDlgItemText(HWND hwnd, ULONG id, const char *pcsz)
     195    {
     196        // put the call in brackets so the macro won't apply here
     197        return (WinSetDlgItemText)(hwnd, id, (PSZ)pcsz);
    162198    }
    163199
Note: See TracChangeset for help on using the changeset viewer.