Changeset 243 for trunk/src/helpers


Ignore:
Timestamp:
Jan 29, 2003, 7:41:39 PM (23 years ago)
Author:
umoeller
Message:

New build system, multimedia, other misc fixes.

Location:
trunk/src/helpers
Files:
1 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/_call_filedlg.c

    r242 r243  
    1515#define INCL_WINSTDCNR
    1616#define INCL_WINSTDFILE
     17#define INCL_WINTIMER
    1718
    1819#include <os2.h>
     
    2930#include "helpers\cnrh.h"
    3031#include "helpers\comctl.h"
     32#include "helpers\nls.h"
    3133#include "helpers\standards.h"
     34#include "helpers\stringh.h"
    3235#include "helpers\winh.h"
    3336#include "helpers\gpih.h"
     
    106109} GROUPRECORD, *PGROUPRECORD;
    107110
     111PFNWP G_pfnwpFrameOrig;
     112
     113#define RECORD_COUNT        20000
     114
     115PGROUPRECORD G_paRecs[RECORD_COUNT];
     116
     117CHAR    G_szText[] = "Longer test string with increasing length";
     118
     119/*
     120 *@@ fnwpSubclFrame:
     121 *
     122 */
     123
     124MRESULT EXPENTRY fnwpSubclFrame(HWND hwndFrame, ULONG msg, MPARAM mp1, MPARAM mp2)
     125{
     126    MRESULT mrc = 0;
     127
     128    switch (msg)
     129    {
     130        case WM_COMMAND:
     131            if (SHORT1FROMMP(mp1) == 1000)
     132                ShowFileDlg(hwndFrame);
     133        break;
     134
     135        case WM_CONTROL:
     136            if (SHORT1FROMMP(mp1) == FID_CLIENT)
     137            {
     138                switch (SHORT2FROMMP(mp1))
     139                {
     140                    case CN_VIEWPORTCHANGED:
     141                    {
     142                        PCNRVIEWPORT pcvp = (PCNRVIEWPORT)mp2;
     143
     144                        CHAR szTemp[100],
     145                             szNLS1[20],
     146                             szNLS2[20],
     147                             szNLS3[20],
     148                             szNLS4[20],
     149                             szNLS5[20],
     150                             szNLS6[20];
     151                        sprintf(szTemp,
     152                                "Win: (%s/%s), WArea: (%s/%s), scrl: (%s/%s)",
     153                                nlsThousandsULong(szNLS1,
     154                                                  pcvp->szlWin.cx,
     155                                                  '.'),
     156                                nlsThousandsULong(szNLS2,
     157                                                  pcvp->szlWin.cy,
     158                                                  '.'),
     159                                nlsThousandsULong(szNLS3,
     160                                                  pcvp->szlWorkarea.cx,
     161                                                  '.'),
     162                                nlsThousandsULong(szNLS4,
     163                                                  pcvp->szlWorkarea.cy,
     164                                                  '.'),
     165                                nlsThousandsULong(szNLS5,
     166                                                  pcvp->ptlScroll.x,
     167                                                  '.'),
     168                                nlsThousandsULong(szNLS6,
     169                                                  pcvp->ptlScroll.y,
     170                                                  '.'));
     171                        WinSetWindowText(WinWindowFromID(hwndFrame, FID_STATUSBAR),
     172                                         szTemp);
     173                    }
     174                    break;
     175
     176                    case CN_ENTER:
     177                    {
     178                        CHAR sz[100];
     179                        PCSZ pcsz;
     180                        PNOTIFYRECORDENTER pnre = (PNOTIFYRECORDENTER)mp2;
     181                        if (!pnre->pRecord)
     182                            pcsz = "Whitespace";
     183                        else
     184                        {
     185                            sprintf(sz, "group %d", ((PGROUPRECORD)pnre->pRecord)->gid);
     186                            pcsz = sz;
     187                        }
     188                        winhDebugBox(hwndFrame,
     189                                     "Enter pressed",
     190                                     pcsz);
     191                    }
     192                    break;
     193                }
     194            }
     195        break;
     196
     197        case WM_TIMER:
     198            if ((ULONG)mp1 == 1)
     199            {
     200                static ul = 0,
     201                       ul2 = 1;
     202
     203                HWND    hwndCnr = WinWindowFromID(hwndFrame, FID_CLIENT);
     204
     205                PGROUPRECORD precThis = G_paRecs[ul];
     206
     207                ULONG ulTimeNow;
     208                DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     209                                &ulTimeNow,
     210                                sizeof(ulTimeNow));
     211
     212                strhncpy0(precThis->szGroupName,
     213                          G_szText,
     214                          ul2++);
     215
     216                WinSendMsg(hwndCnr,
     217                           CM_INVALIDATERECORD,
     218                           (MPARAM)&precThis,
     219                           MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
     220
     221                if (++ul >= RECORD_COUNT)
     222                    ul = 0;
     223                if (ul2 > strlen(G_szText))
     224                    ul2 = 1;
     225            }
     226            else
     227                mrc = G_pfnwpFrameOrig(hwndFrame, msg, mp1, mp2);
     228        break;
     229
     230        default:
     231            mrc = G_pfnwpFrameOrig(hwndFrame, msg, mp1, mp2);
     232        break;
     233
     234    }
     235
     236    return mrc;
     237}
     238
    108239/*
    109240 *@@ main:
     
    203334                  | FCF_SHELLPOSITION
    204335                  | FCF_TASKLIST,
    205             0, // XFCF_TOOLBAR | XFCF_FORCETBOWNER | XFCF_STATUSBAR,
     336            XFCF_TOOLBAR | XFCF_FORCETBOWNER | XFCF_STATUSBAR,
    206337            WS_VISIBLE,                         // ulFrameStyle
    207338            "Test File Dialog",                 // pcszFrameTitle
    208339            0,                                  // ulResourcesID
    209 #if 1
     340#ifdef __USE_PM_CNR__
     341            WC_CONTAINER,
     342#else
    210343            WC_CCTL_CNR,
    211 #else
    212             WC_CONTAINER,
    213344#endif
    214             WS_VISIBLE,                         // flStyleClient
     345            WS_VISIBLE | CCS_EXTENDSEL,       // flStyleClient
    215346            0,                                  // ulID
    216347            NULL,
     
    262393    WinSendMsg(hwndFrame, WM_UPDATEFRAME, MPNULL, MPNULL);
    263394
     395    if (G_pfnwpFrameOrig = WinSubclassWindow(hwndFrame, fnwpSubclFrame))
    264396    {
    265397        XFIELDINFO  xfi[4];
     
    270402        // set up cnr details view
    271403        xfi[i].ulFieldOffset = FIELDOFFSET(GROUPRECORD, gid);
    272         xfi[i].pszColumnTitle = "Group ID";     // @@todo localize
     404        xfi[i].pszColumnTitle = "gid";
    273405        xfi[i].ulDataType = CFA_ULONG;
    274406        xfi[i++].ulOrientation = CFA_RIGHT;
     
    297429        } END_CNRINFO(hwndClient);
    298430
    299         #define RECORD_COUNT        200
    300 
    301431        if (preccFirst = (PGROUPRECORD)cnrhAllocRecords(hwndClient,
    302432                                                        sizeof(GROUPRECORD),
    303433                                                        RECORD_COUNT))
    304434        {
    305             PGROUPRECORD preccThis = preccFirst;
     435            PGROUPRECORD preccThis = preccFirst,
     436                         preccEmph;
    306437            ULONG   ul = 0;
    307438            while (preccThis)
    308439            {
     440                G_paRecs[ul] = preccThis;
     441
     442                if (ul & 1)
     443                    preccThis->recc.flRecordAttr |= CRA_FILTERED;
     444
     445                if (ul == 4)
     446                    preccEmph = preccThis;
     447
    309448                preccThis->gid = ul++;
    310449                sprintf(preccThis->szGroupName, "group %d", preccThis->gid);
     
    323462                              CRA_RECORDREADONLY,
    324463                              RECORD_COUNT);
     464
     465            WinSendMsg(hwndClient,
     466                       CM_SETRECORDEMPHASIS,
     467                       (MPARAM)preccEmph,
     468                       MPFROM2SHORT(TRUE, CRA_SELECTED));
    325469        }
    326470    }
    327471
     472    WinStartTimer(hab, hwndFrame, 1, 100);
     473
    328474    while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
    329     {
    330         BOOL fDispatch = TRUE;
    331 
    332         if (qmsg.hwnd == hwndFrame)
    333         {
    334             switch (qmsg.msg)
    335             {
    336                 case WM_COMMAND:
    337                     if (SHORT1FROMMP(qmsg.mp1) == 1000)
    338                     {
    339                         ShowFileDlg(hwndFrame);
    340                         fDispatch = FALSE;
    341                     }
    342                 break;
    343             }
    344         }
    345 
    346         if (fDispatch)
    347             WinDispatchMsg(hab, &qmsg);
    348     }
     475        WinDispatchMsg(hab, &qmsg);
    349476
    350477    WinDestroyMsgQueue(hmq);
  • trunk/src/helpers/cctl_checkcnr.c

    r238 r243  
    357357 *@@added V0.9.0 (99-11-29) [umoeller]
    358358 *@@changed V0.9.18 (2002-03-03) [umoeller]: fixed bad orig win msg, other optimizations
     359 *@@changed V1.0.1 (2003-01-22) [umoeller]: fixed wrong mouse pointers on WM_MOUSEMOVE
    359360 */
    360361
     
    457458                    }
    458459                }
     460
     461                // always call parent cos container changes mouse pointers
     462                // V1.0.1 (2003-01-22) [umoeller]
     463                mrc = pfnwpOrig(hwndCnr, msg, mp1, mp2);
    459464            break;
    460465
  • trunk/src/helpers/cctl_cnr.c

    r242 r243  
    2828#define INCL_WINWINDOWMGR
    2929#define INCL_WINFRAMEMGR
     30#define INCL_WININPUT
    3031#define INCL_WINSYS
    3132#define INCL_WINSCROLLBARS
     
    6263 ********************************************************************/
    6364
    64 extern const SYSCOLORSET G_scsCnr =
    65     {
    66         TRUE,       // inherit presparams
    67         SYSCLR_WINDOW,
    68         SYSCLR_WINDOWTEXT
     65extern const CCTLCOLOR G_scsCnr[] =
     66    {
     67            TRUE, PP_BACKGROUNDCOLOR, SYSCLR_WINDOW,
     68            TRUE, PP_FOREGROUNDCOLOR, SYSCLR_WINDOWTEXT,
     69            TRUE, PP_HILITEBACKGROUNDCOLOR, SYSCLR_HILITEBACKGROUND,
     70            TRUE, PP_HILITEFOREGROUNDCOLOR, SYSCLR_HILITEFOREGROUND,
     71            TRUE, PP_BORDERCOLOR, SYSCLR_WINDOWFRAME,
     72            TRUE, PP_PAGEBACKGROUNDCOLOR, RGBCOL_WHITE,
     73            TRUE, PP_PAGEFOREGROUNDCOLOR, RGBCOL_BLACK,
     74            TRUE, PP_FIELDBACKGROUNDCOLOR, SYSCLR_SCROLLBAR
    6975    };
    7076
     
    7581 ********************************************************************/
    7682
    77 VOID cnrDrawString(HPS hps,
     83/*
     84 *@@ ctnrInit:
     85 *
     86 */
     87
     88VOID ctnrInit(HWND hwnd,
     89              MPARAM mp2,
     90              ULONG flMainCnrStyle,     // in: window style bits of main cnr
     91              PDEFWINDATA pdwd)
     92{
     93    ctlInitDWD(hwnd,
     94               mp2,
     95               pdwd,
     96               WinDefWindowProc,
     97               (flMainCnrStyle & CCS_NOCONTROLPTR)
     98                    ? CCS_NOSENDCTLPTR
     99                    : 0,
     100               G_scsCnr,
     101               ARRAYITEMCOUNT(G_scsCnr));
     102}
     103
     104/*
     105 *@@ ctnrDrawString:
     106 *
     107 */
     108
     109VOID ctnrDrawString(HPS hps,
    78110                   PCSZ pcsz,              // in: string to test
    79111                   PRECTL prcl,            // in: clipping rectangle (inclusive!)
     
    115147
    116148/*
     149 *@@ ctnrGetRecordRect:
     150 *      returns the rectangle of the given record
     151 *      converted to window coordinates. Works for
     152 *      all views.
     153 */
     154
     155VOID ctnrGetRecordRect(PCNRDATA pData,
     156                       PRECTL prcl,
     157                       const RECORDLISTITEM *prli)
     158{
     159    LONG    deltaWorkspace =   (   pData->scrw.szlWorkarea.cy
     160                                 - pData->dwdContent.szlWin.cy)
     161                             - pData->scrw.ptlScrollOfs.y;
     162    prcl->xLeft = 0;
     163    prcl->xRight = pData->dwdContent.szlWin.cx;
     164    prcl->yBottom = prli->ptl.y - deltaWorkspace;
     165    prcl->yTop = prcl->yBottom + prli->szlBox.cy;
     166}
     167
     168/*
     169 *@@ ctnrRepaintRecord:
     170 *
     171 */
     172
     173BOOL ctnrRepaintRecord(PCNRDATA pData,
     174                         const RECORDLISTITEM *prli)
     175{
     176    RECTL   rcl;
     177    ctnrGetRecordRect(pData, &rcl, prli);
     178    ++rcl.xRight;       // for separators, if any
     179    return WinInvalidateRect(pData->dwdContent.hwnd, &rcl, FALSE);
     180}
     181
     182/*
     183 *@@ ctnrQuerySelMode:
     184 *      returns one of CCS_EXTENDSEL, CCS_MULTIPLESEL, or
     185 *      CCS_SINGLESEL, depending on the cnr's current view
     186 *      and window style bits.
     187 */
     188
     189ULONG ctnrQuerySelMode(PCNRDATA pData)
     190{
     191    // in tree view, there is always only single-sel mode
     192    if (!(pData->CnrInfo.flWindowAttr & CV_TREE))
     193    {
     194        // not tree view: then check window style bits
     195        ULONG   flStyle = winhQueryWindowStyle(pData->dwdMain.hwnd);
     196        if (flStyle & CCS_EXTENDSEL)
     197            return CCS_EXTENDSEL;
     198        else if (flStyle & CCS_MULTIPLESEL)
     199            return CCS_MULTIPLESEL;
     200
     201        // this appears to be what the pm cnr does...
     202        // the CCS_SINGLESEL is totally superfluous cos
     203        // if none of the "selection style" bits are
     204        // set, the cnr operates in "single sel" mode
     205    }
     206
     207    return CCS_SINGLESEL;
     208}
     209
     210/*
     211 *@@ ctnrChangeEmphasis:
     212 *
     213 */
     214
     215BOOL ctnrChangeEmphasis(PCNRDATA pData,
     216                        PRECORDLISTITEM prliSet,
     217                        BOOL fTurnOn,
     218                        ULONG fsEmphasis)
     219{
     220    PRECORDLISTITEM prliOld;
     221    ULONG   flRecordAttrOld = prliSet->flRecordAttr;
     222
     223/* #define CCS_EXTENDSEL             0x00000001L
     224#define CCS_MULTIPLESEL           0x00000002L
     225#define CCS_SINGLESEL             0x00000004L */
     226
     227    ULONG ulSel = ctnrQuerySelMode(pData);
     228
     229    if (fTurnOn)
     230    {
     231        ULONG   flMask;
     232        if (ulSel == CCS_SINGLESEL)
     233            flMask = CRA_CURSORED | CRA_SELECTED;
     234        else
     235            flMask = CRA_CURSORED;
     236
     237        if (fsEmphasis & flMask)
     238        {
     239            if (prliOld = pData->prliCursored)
     240            {
     241                prliOld->flRecordAttr &= ~flMask;
     242                ctnrRepaintRecord(pData, prliOld);
     243            }
     244
     245            pData->prliCursored = prliSet;
     246        }
     247
     248        prliSet->flRecordAttr |= fsEmphasis;
     249    }
     250    else
     251        prliSet->flRecordAttr &= ~fsEmphasis;
     252
     253    if (flRecordAttrOld != prliSet->flRecordAttr)
     254        ctnrRepaintRecord(pData, prliSet);
     255
     256    return TRUE;
     257}
     258
     259/*
     260 *@@ ctnrRecordEnter:
     261 *      helper function when a record gets double-clicked
     262 *      upon or when "Enter" key gets pressed.
     263 */
     264
     265VOID ctnrRecordEnter(PCNRDATA pData,
     266                     const RECORDLISTITEM *prli,
     267                     BOOL fKeyboard)
     268{
     269    NOTIFYRECORDENTER nre;
     270    nre.hwndCnr = pData->dwdMain.hwnd;
     271    nre.fKey = fKeyboard;
     272    nre.pRecord = (prli) ? (PRECORDCORE)prli->precc : NULL;
     273
     274    ctlSendWmControl(nre.hwndCnr,
     275                     CN_ENTER,
     276                     &nre);
     277}
     278
     279/*
    117280 *@@ CreateChild:
    118281 *      creates a container child window.
    119282 */
    120283
    121 HWND CreateChild(PCNRDATA pData,
    122                  PCSZ pcszClass,
    123                  ULONG id)
     284STATIC HWND CreateChild(PCNRDATA pData,
     285                        PCSZ pcszClass,
     286                        ULONG id)
    124287{
    125288    return WinCreateWindow(pData->dwdMain.hwnd,
     
    143306 */
    144307
    145 PDETAILCOLUMN FindColumnFromFI(PCNRDATA pData,
    146                                const FIELDINFO *pfi,
    147                                PLISTNODE *ppNode)       // out: listnode of column
     308STATIC PDETAILCOLUMN FindColumnFromFI(PCNRDATA pData,
     309                                      const FIELDINFO *pfi,
     310                                      PLISTNODE *ppNode)       // out: listnode of column
    148311{
    149312    PLISTNODE pNode;
    150313    FOR_ALL_NODES(&pData->llColumns, pNode)
    151314    {
    152         PDETAILCOLUMN pCol = pNode->pItemData;
     315        PDETAILCOLUMN pCol = (PDETAILCOLUMN)pNode->pItemData;
    153316        if (pCol->pfi == pfi)
    154317        {
     
    164327
    165328/*
    166  *@@ FindListNodeForRecc:
    167  *
    168  */
    169 
    170 PLISTNODE FindListNodeForRecc(PCNRDATA pData,
    171                               const RECORDCORE *precc)
     329 *@@ ctnrFindListNodeForRecc:
     330 *
     331 */
     332
     333PLISTNODE ctnrFindListNodeForRecc(PCNRDATA pData,
     334                                  const RECORDCORE *precc)
    172335{
    173336    RECORDTREEITEM  *pti;
     
    180343}
    181344
     345VOID SendViewportChanged(PCNRDATA pData)
     346{
     347    CNRVIEWPORT cvp;
     348    cvp.hwndCnr = pData->dwdMain.hwnd;
     349    cvp.szlWorkarea = pData->scrw.szlWorkarea;
     350    cvp.szlWin = pData->dwdContent.szlWin;
     351    cvp.ptlScroll = pData->scrw.ptlScrollOfs;
     352
     353    ctlSendWmControl(pData->dwdMain.hwnd,
     354                     CN_VIEWPORTCHANGED,
     355                     &cvp);
     356}
     357
     358/*
     359 *@@ ctnrUpdateScrollbars:
     360 *
     361 */
     362
     363VOID ctnrUpdateScrollbars(PCNRDATA pData,
     364                          LONG cx,
     365                          LONG cy)
     366{
     367    BOOL    fNotify = FALSE;
     368
     369    if (cx && pData->scrw.hwndHScroll)
     370    {
     371        winhUpdateScrollBar(pData->scrw.hwndHScroll,
     372                            cx,
     373                            pData->scrw.szlWorkarea.cx,
     374                            pData->scrw.ptlScrollOfs.x,
     375                            FALSE);
     376        fNotify = TRUE;
     377    }
     378
     379    if (cy && pData->scrw.hwndVScroll)
     380    {
     381        winhUpdateScrollBar(pData->scrw.hwndVScroll,
     382                            cy,
     383                            pData->scrw.szlWorkarea.cy,
     384                            pData->scrw.ptlScrollOfs.y,
     385                            FALSE);
     386        fNotify = TRUE;
     387    }
     388
     389    if (fNotify)
     390        SendViewportChanged(pData);
     391}
     392
    182393/* ******************************************************************
    183394 *
     
    191402 */
    192403
    193 MRESULT CnrCreate(HWND hwnd, MPARAM mp1, MPARAM mp2)
     404STATIC MRESULT CnrCreate(HWND hwnd,
     405                         MPARAM mp1,
     406                         MPARAM mp2)
    194407{
    195408    PCNRDATA    pData;
     
    202415
    203416    // initialize DEFWINDOWDATA
    204     ctlInitDWD(hwnd,
    205                mp2,
    206                &pData->dwdMain,
    207                WinDefWindowProc,
    208                &G_scsCnr);
    209 
    210     if (winhQueryWindowStyle(hwnd) & CCS_MINIRECORDCORE)
     417    ctnrInit(hwnd,
     418             mp2,
     419             ((PCREATESTRUCT)mp2)->flStyle,
     420             &pData->dwdMain);
     421
     422    if (((PCREATESTRUCT)mp2)->flStyle & CCS_MINIRECORDCORE)
    211423        pData->fMiniRecords = TRUE;
    212424
     
    229441    nlsQueryCountrySettings(&pData->cs);
    230442
    231     winhCreateScrollBars(hwnd,
    232                          &pData->hwndVScroll,
    233                          &pData->hwndHScroll);
    234 
    235     pData->cxScrollBar = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
    236     pData->cyScrollBar = WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
     443    winhCreateScroller(hwnd,
     444                       &pData->scrw,
     445                       CID_VSCROLL,
     446                       CID_HSCROLL);
    237447
    238448    return (MRESULT)FALSE;
     
    248458 */
    249459
    250 VOID CnrSem2(HWND hwnd, ULONG fl)
    251 {
    252     PCNRDATA    pData;
    253     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    254     {
    255         if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
    256         {
    257             if (fl & (DDFL_INVALIDATECOLUMNS | DDFL_INCALIDATERECORDS))
     460STATIC VOID CnrSem2(PCNRDATA pData,
     461                    ULONG fl)
     462{
     463    HWND    hwnd = pData->dwdMain.hwnd;
     464
     465    if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
     466    {
     467        if (fl & (DDFL_INVALIDATECOLUMNS | DDFL_INVALIDATERECORDS | DDFL_INVALIDATESOME))
     468        {
     469            HPS hps = WinGetPS(hwnd);
     470            cdtlRecalcDetails(pData, hps, &fl);
     471            WinReleasePS(hps);
     472        }
     473
     474        if (fl & (DDFL_WINDOWSIZECHANGED | DDFL_WORKAREACHANGED))
     475        {
     476            LONG    y = 0,
     477                    cx = pData->dwdMain.szlWin.cx,
     478                    cy = pData->dwdMain.szlWin.cy - pData->cyColTitlesBox;
     479
     480            if (pData->scrw.hwndVScroll)
     481                cx -= pData->scrw.cxScrollBar;
     482            if (pData->scrw.hwndHScroll)
    258483            {
    259                 HPS hps = WinGetPS(hwnd);
    260                 cdtlRecalcDetails(pData, hps, &fl);
    261                 WinReleasePS(hps);
    262 
    263                 if (fl & DDFL_WINDOWSIZECHANGED)
    264                     WinInvalidateRect(pData->dwdMain.hwnd, NULL, TRUE);
     484                y += pData->scrw.cyScrollBar;
     485                cy -= pData->scrw.cyScrollBar;
    265486            }
    266487
    267             if (fl & (DDFL_WINDOWSIZECHANGED | DDFL_WORKAREACHANGED))
     488            _PmpfF(("cyColTitlesBox %d, new cy: %d", pData->cyColTitlesBox, cy));
     489
     490            if (fl & DDFL_WINDOWSIZECHANGED)
     491                WinSetWindowPos(pData->dwdContent.hwnd,
     492                                HWND_TOP,
     493                                0,
     494                                y,
     495                                cx,
     496                                cy,
     497                                SWP_MOVE | SWP_SIZE);
     498                                        // SWP_MOVE is required or PM will move our
     499                                        // subwindow to some adjustment position
     500
     501            if (pData->scrw.hwndVScroll)
    268502            {
    269                 LONG    y = 0,
    270                         cx = pData->dwdMain.szlWin.cx,
    271                         cy = pData->dwdMain.szlWin.cy - pData->cyColTitlesBox;
    272 
    273                 if (pData->hwndVScroll)
    274                     cx -= pData->cxScrollBar;
    275                 if (pData->hwndHScroll)
    276                 {
    277                     y += pData->cyScrollBar;
    278                     cy -= pData->cyScrollBar;
    279                 }
    280 
    281                 _PmpfF(("cyColTitlesBox %d, new cy: %d", pData->cyColTitlesBox, cy));
    282 
    283                 if (fl & DDFL_WINDOWSIZECHANGED)
    284                     WinSetWindowPos(pData->hwndDetails,
    285                                     HWND_TOP,
    286                                     0,
    287                                     y,
    288                                     cx,
    289                                     cy,
    290                                     SWP_MOVE | SWP_SIZE);
    291                                             // SWP_MOVE is required or PM will move our
    292                                             // subwindow to some adjustment position
    293 
    294                 if (pData->hwndVScroll)
    295                 {
    296                     WinSetWindowPos(pData->hwndVScroll,
    297                                     HWND_TOP,
    298                                     cx,
    299                                     y,
    300                                     pData->cxScrollBar,
    301                                     cy,
    302                                     SWP_MOVE | SWP_SIZE);
    303 
    304                     _PmpfF(("updating VScroll, cy: %d, szlWorkarea.cy: %d",
    305                             cy,
    306                             pData->szlWorkarea.cy));
    307 
    308                     winhUpdateScrollBar(pData->hwndVScroll,
    309                                         cy,
    310                                         pData->szlWorkarea.cy,
    311                                         pData->ptlScrollOfs.y,
    312                                         FALSE);
    313                 }
    314 
    315                 if (pData->hwndHScroll)
    316                 {
    317                     WinSetWindowPos(pData->hwndHScroll,
    318                                     HWND_TOP,
    319                                     0,
    320                                     0,
    321                                     cx,
    322                                     pData->cyScrollBar,
    323                                     SWP_MOVE | SWP_SIZE);
    324 
    325                     _PmpfF(("updating HScroll, cx: %d, szlWorkarea.cx: %d",
    326                             cx,
    327                             pData->szlWorkarea.cx));
    328 
    329                     winhUpdateScrollBar(pData->hwndHScroll,
    330                                         cx,
    331                                         pData->szlWorkarea.cx,
    332                                         pData->ptlScrollOfs.x,
    333                                         FALSE);
    334                 }
     503                WinSetWindowPos(pData->scrw.hwndVScroll,
     504                                HWND_TOP,
     505                                cx,
     506                                y,
     507                                pData->scrw.cxScrollBar,
     508                                cy,
     509                                SWP_MOVE | SWP_SIZE);
     510
     511                _PmpfF(("updating VScroll, cy: %d, scrw.szlWorkarea.cy: %d",
     512                        cy,
     513                        pData->scrw.szlWorkarea.cy));
    335514            }
     515
     516            if (pData->scrw.hwndHScroll)
     517            {
     518                WinSetWindowPos(pData->scrw.hwndHScroll,
     519                                HWND_TOP,
     520                                0,
     521                                0,
     522                                cx,
     523                                pData->scrw.cyScrollBar,
     524                                SWP_MOVE | SWP_SIZE);
     525
     526                _PmpfF(("updating HScroll, cx: %d, scrw.szlWorkarea.cx: %d",
     527                        cx,
     528                        pData->scrw.szlWorkarea.cx));
     529            }
     530
     531            ctnrUpdateScrollbars(pData,
     532                                 cx,
     533                                 cy);
    336534        }
    337535    }
     
    341539 *@@ CnrPaint:
    342540 *      implementation for WM_PAINT in fnwpCnr.
    343  */
    344 
    345 VOID CnrPaint(HWND hwnd)
    346 {
    347     HPS         hps;
    348     PCNRDATA    pData;
    349     RECTL       rclPaint;
    350 
    351     if (    (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    352          && (hps = WinBeginPaint(hwnd, NULLHANDLE, &rclPaint))
     541 *
     542 *      This paints only the part of the container that belongs
     543 *      to the main container window, which is the title area
     544 *      and/or the details column headings.
     545 */
     546
     547STATIC VOID CnrPaint(PCNRDATA pData)
     548{
     549    HPS     hps;
     550    RECTL   rclPaint;
     551
     552    if (    (pData)
     553         && (hps = WinBeginPaint(pData->dwdMain.hwnd, NULLHANDLE, &rclPaint))
    353554       )
    354555    {
     
    376577                WinFillRect(hps,
    377578                            &rclPaint,
    378                             pData->dwdMain.lcolBackground);
     579                            ctlQueryColor(&pData->dwdMain, CTLCOL_BGND));
    379580
    380581                FOR_ALL_NODES(&pData->llColumns, pColNode)
     
    386587                    ULONG       cRow;
    387588
    388                     rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData->ptlScrollOfs.x;
    389                     rcl.xRight = rcl.xLeft + pCol->cxTotal;
     589                    rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData->scrw.ptlScrollOfs.x;
     590                    rcl.xRight = rcl.xLeft + pCol->cxContent;
    390591
    391592                    // we start out at the top and work our way down,
     
    402603                    else
    403604                    {
    404                         cnrDrawString(hps,
     605                        ctnrDrawString(hps,
    405606                                      (PCSZ)pfi->pTitleData,
    406607                                      &rcl,
     
    438639 */
    439640
    440 MRESULT CnrWindowPosChanged(HWND hwnd,
    441                             MPARAM mp1,
    442                             MPARAM mp2)
     641STATIC MRESULT CnrWindowPosChanged(PCNRDATA pData,
     642                                   MPARAM mp1,
     643                                   MPARAM mp2)
    443644{
    444645    MRESULT mrc = 0;
    445     PCNRDATA pData;
    446     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     646
     647    if (pData)
    447648    {
    448649        mrc = ctlDefWindowProc(&pData->dwdMain, WM_WINDOWPOSCHANGED, mp1, mp2);
     
    450651        if (((PSWP)mp1)->fl & SWP_SIZE)
    451652        {
    452             WinPostMsg(hwnd,
     653            WinPostMsg(pData->dwdMain.hwnd,
    453654                       WM_SEM2,
    454655                       (MPARAM)DDFL_WINDOWSIZECHANGED,
     
    461662
    462663/*
    463  *@@ cnrPresParamChanged:
     664 *@@ ctnrPresParamChanged:
    464665 *      implementation for WM_PRESPARAMCHANGED for both
    465666 *      fnwpCnr and fnwpCnrDetails.
    466667 */
    467668
    468 VOID cnrPresParamChanged(HWND hwnd,
     669VOID ctnrPresParamChanged(HWND hwnd,         // in: either main cnr or content subwindow
    469670                         ULONG ulpp)
    470671{
    471     PCNRDATA pData;
     672    PCNRDATA    pData;
    472673    if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    473674    {
    474         // note, we use the dwdMain buffer here cos
    475         // we share presparams with the cnr
     675        // note, no matter what hwnd is passed in,
     676        // we use the dwdMain buffer here cos we share presparams
     677        // between all cnr child windows
    476678        ctlRefreshColors(&pData->dwdMain);
    477679
     
    480682            case 0:     // layout palette thing dropped
    481683            case PP_FONTNAMESIZE:
    482                 if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
     684                if (!pData->fSettingPP)
    483685                {
    484                     // if we got this on the details window,
    485                     // set it on the main cnr as well, and
    486                     // vice versa
    487                     PSZ pszFont;
    488                     if (pszFont = winhQueryWindowFont(hwnd))
     686                    pData->fSettingPP = TRUE;
     687
     688                    if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
    489689                    {
    490                         HWND hwndOther;
    491                         DosBeep(1000, 10);
    492                         if (hwnd == pData->dwdMain.hwnd)
    493                             hwndOther = pData->dwdContent.hwnd;
    494                         else
    495                             hwndOther = pData->dwdMain.hwnd;
    496 
    497                         winhSetWindowFont(hwndOther, pszFont);
    498                         free(pszFont);
     690                        // if we got this on the contents window,
     691                        // set it on the main cnr as well, and
     692                        // vice versa
     693                        PSZ pszFont;
     694                        if (pszFont = winhQueryWindowFont(hwnd))
     695                        {
     696                            HWND hwndOther;
     697                            if (hwnd == pData->dwdMain.hwnd)
     698                                hwndOther = pData->dwdContent.hwnd;
     699                            else
     700                                hwndOther = pData->dwdMain.hwnd;
     701
     702                            winhSetWindowFont(hwndOther, pszFont);
     703                            free(pszFont);
     704                        }
     705
     706                        WinPostMsg(pData->dwdMain.hwnd,
     707                                   WM_SEM2,
     708                                   (MPARAM)(DDFL_INVALIDATECOLUMNS | DDFL_INVALIDATERECORDS),
     709                                   0);
    499710                    }
    500711
    501                     WinPostMsg(pData->dwdMain.hwnd,
    502                                WM_SEM2,
    503                                (MPARAM)(DDFL_INVALIDATECOLUMNS | DDFL_INCALIDATERECORDS),
    504                                0);
     712                    pData->fSettingPP = FALSE;
    505713                }
    506714            break;
     
    518726 */
    519727
    520 VOID CnrScroll(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
    521 {
    522     PCNRDATA pData;
    523     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    524     {
     728STATIC VOID CnrScroll(PCNRDATA pData,
     729                      ULONG msg,
     730                      MPARAM mp1,
     731                      MPARAM mp2)
     732{
     733    if (pData)
     734    {
     735        BOOL    fNotify = FALSE;
     736
    525737        if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
    526738        {
    527             POINTL  ptlScroll;
     739            POINTL          ptlScroll;
     740            NOTIFYSCROLL    ns;
     741            ns.hwndCnr = pData->dwdMain.hwnd;
     742
    528743            if (msg == WM_HSCROLL)
    529744            {
    530745                ptlScroll.y = 0;
    531                 if (ptlScroll.x = winhHandleScrollMsg2(pData->hwndHScroll,
    532                                                        &pData->ptlScrollOfs.x,
    533                                                        pData->dwdContent.szlWin.cx,
    534                                                        pData->szlWorkarea.cx,
    535                                                        5,
    536                                                        msg,
    537                                                        mp2))
     746                if (ptlScroll.x = winhHandleScrollMsg(pData->scrw.hwndHScroll,
     747                                                      &pData->scrw.ptlScrollOfs.x,
     748                                                      pData->dwdContent.szlWin.cx,
     749                                                      pData->scrw.szlWorkarea.cx,
     750                                                      5,
     751                                                      msg,
     752                                                      mp2))
    538753                {
     754                    winhScrollWindow(pData->dwdContent.hwnd,
     755                                     NULL,
     756                                     &ptlScroll);
     757
     758                    // scroll main cnr with detail titles too
    539759                    if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES)
    540760                    {
     
    544764                        rclClip.yBottom = pData->dwdMain.szlWin.cy - pData->cyColTitlesBox;
    545765                        rclClip.yTop = pData->dwdMain.szlWin.cy;
    546                         winhScrollWindow(hwnd,
     766                        winhScrollWindow(pData->dwdMain.hwnd,
    547767                                         &rclClip,
    548768                                         &ptlScroll);
    549769                    }
    550                     winhScrollWindow(pData->hwndDetails,
    551                                      NULL,
    552                                      &ptlScroll);
     770
     771                    ns.lScrollInc = ptlScroll.y;
     772                    ns.fScroll = CMA_HORIZONTAL;        // @@todo details flags
     773                    ctlSendWmControl(pData->dwdMain.hwnd,
     774                                     CN_SCROLL,
     775                                     &ns);
     776
     777                    fNotify = TRUE;
    553778                }
    554779            }
     
    556781            {
    557782                ptlScroll.x = 0;
    558                 if (ptlScroll.y = winhHandleScrollMsg2(pData->hwndVScroll,
    559                                                        &pData->ptlScrollOfs.y,
    560                                                        pData->dwdContent.szlWin.cy,
    561                                                        pData->szlWorkarea.cy,
    562                                                        5,
    563                                                        msg,
    564                                                        mp2))
    565                     winhScrollWindow(pData->hwndDetails,
     783                if (ptlScroll.y = winhHandleScrollMsg(pData->scrw.hwndVScroll,
     784                                                      &pData->scrw.ptlScrollOfs.y,
     785                                                      pData->dwdContent.szlWin.cy,
     786                                                      pData->scrw.szlWorkarea.cy,
     787                                                      5,
     788                                                      msg,
     789                                                      mp2))
     790                {
     791                    winhScrollWindow(pData->dwdContent.hwnd,
    566792                                     NULL,
    567793                                     &ptlScroll);
     794
     795                    ns.lScrollInc = ptlScroll.x;
     796                    ns.fScroll = CMA_VERTICAL;        // @@todo details flags
     797                    ctlSendWmControl(pData->dwdMain.hwnd,
     798                                     CN_SCROLL,
     799                                     &ns);
     800
     801                    fNotify = TRUE;
     802                }
    568803            }
    569804        }
     805
     806        if (fNotify)
     807            SendViewportChanged(pData);
    570808    }
    571809}
     
    576814 */
    577815
    578 VOID CnrDestroy(HWND hwnd)
    579 {
    580     PCNRDATA pData;
    581     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     816STATIC VOID CnrDestroy(PCNRDATA pData)
     817{
     818    if (pData)
    582819    {
    583820        // free all data that we ever allocated;
     
    605842 */
    606843
    607 USHORT CnrQueryCnrInfo(HWND hwnd,
    608                        PCNRINFO pci,        // in: mp1 of CM_QUERYCNRINFO
    609                        USHORT cb)           // in: mp2 of CM_QUERYCNRINFO
    610 {
    611     PCNRDATA pData;
    612     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     844STATIC USHORT CnrQueryCnrInfo(PCNRDATA pData,
     845                              PCNRINFO pci,        // out: target buffer (mp1 of CM_QUERYCNRINFO)
     846                              USHORT cb)           // in: mp2 of CM_QUERYCNRINFO
     847{
     848    if (pData)
    613849    {
    614850        USHORT cbCopied = max(cb, sizeof(CNRINFO));
     
    629865 */
    630866
    631 BOOL CnrSetCnrInfo(HWND hwnd,
    632                    PCNRINFO pci,        // in: mp1 of CM_SETCNRINFO
    633                    ULONG flCI)          // in: CMA_* flags in mp2 of CM_SETCNRINFO
    634 {
    635     PCNRDATA pData;
    636     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     867STATIC BOOL CnrSetCnrInfo(PCNRDATA pData,
     868                          PCNRINFO pci,        // in: mp1 of CM_SETCNRINFO
     869                          ULONG flCI)          // in: CMA_* flags in mp2 of CM_SETCNRINFO
     870{
     871    if (pData)
    637872    {
    638873        ULONG   flDirty = 0;
     
    680915                if (pData->CnrInfo.flWindowAttr & CV_DETAIL)
    681916                {
    682                     if (!pData->hwndDetails)
     917                    if (!pData->dwdContent.hwnd)
    683918                    {
    684                         if (pData->hwndDetails = CreateChild(pData,
    685                                                              WC_CCTL_CNR_DETAILS,
    686                                                              CID_LEFTDVWND))
     919                        if (pData->dwdContent.hwnd = CreateChild(pData,
     920                                                                 WC_CCTL_CNR_DETAILS,
     921                                                                 CID_LEFTDVWND))
    687922                        {
    688923                            flDirty = DDFL_ALL;
     
    692927                else
    693928                {
    694                     winhDestroyWindow(&pData->hwndDetails);
     929                    winhDestroyWindow(&pData->dwdContent.hwnd);
    695930                }
    696931            }
     
    7821017            // flWindowAttr field is not specified, these lines are not drawn.
    7831018            pData->CnrInfo.cxTreeLine = pci->cxTreeLine;
     1019
     1020            // @@todo recalc window components, repaint
    7841021        }
    7851022
     
    7901027            // value is negative one (-1).
    7911028            pData->CnrInfo.xVertSplitbar = pci->xVertSplitbar;
     1029
     1030            // @@todo recalc window components, repaint
    7921031        }
    7931032
    7941033        if (flDirty)
    7951034            // post semaphore to force resize of details wnd
    796             WinPostMsg(hwnd,
     1035            WinPostMsg(pData->dwdMain.hwnd,
    7971036                       WM_SEM2,
    7981037                       (MPARAM)flDirty,
     
    8051044}
    8061045
     1046/*
     1047 *@@ CnrQueryViewportRect:
     1048 *      implementation for CM_QUERYVIEWPORTRECT in fnwpCnr.
     1049 *
     1050 *      From my testing, this simply returns the extensions
     1051 *      of the container content window, which the cnr docs
     1052 *      dub the "viewport". This never returns the workarea
     1053 *      size, that is, the total size of the container's
     1054 *      viewable content.
     1055 */
     1056
     1057STATIC BOOL CnrQueryViewportRect(PCNRDATA pData,
     1058                                 PRECTL prcl,
     1059                                 USHORT usIndicator,
     1060                                 BOOL fRightSplitView)      // @@todo
     1061{
     1062    if (pData && prcl)
     1063    {
     1064        prcl->xLeft = 0;
     1065        prcl->yBottom = 0;
     1066        prcl->xRight = pData->dwdContent.szlWin.cx;
     1067        prcl->yTop = pData->dwdContent.szlWin.cy;
     1068
     1069        switch (usIndicator)
     1070        {
     1071            case CMA_WORKSPACE:
     1072                // for CMA_WORKSPACE, the PM cnr returns a 0 yBottom when
     1073                // the cnr is scrolled to the very top and negative y
     1074                // values when it has been scrolled down to some extent;
     1075                // wonder what the use for this would be
     1076                prcl->xLeft += pData->scrw.ptlScrollOfs.x;
     1077                prcl->xRight += pData->scrw.ptlScrollOfs.x;
     1078                prcl->yBottom -= pData->scrw.ptlScrollOfs.y;
     1079                prcl->yTop -= pData->scrw.ptlScrollOfs.y;
     1080            break;
     1081
     1082            case CMA_WINDOW:
     1083                // for CMA_WINDOW, the PM cnr returns a constant
     1084                // rectangle without scrolling taken into account
     1085                WinMapWindowPoints(pData->dwdContent.hwnd,
     1086                                   pData->dwdMain.hwnd,
     1087                                   (PPOINTL)prcl,
     1088                                   2);
     1089            break;
     1090        }
     1091
     1092        return TRUE;
     1093    }
     1094
     1095    return FALSE;
     1096}
     1097
    8071098/* ******************************************************************
    8081099 *
     
    8181109 */
    8191110
    820 PFIELDINFO CnrAllocDetailFieldInfo(HWND hwnd,
    821                                    USHORT cFieldInfos)      // in: no. of fieldinfos to allocate (> 0)
     1111STATIC PFIELDINFO CnrAllocDetailFieldInfo(PCNRDATA pData,
     1112                                          USHORT cFieldInfos)      // in: no. of fieldinfos to allocate (> 0)
    8221113{
    8231114    PFIELDINFO  pfiFirst = NULL,
    8241115                pfiPrev = NULL;
    8251116
    826     PCNRDATA    pData;
    827     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1117    if (pData)
    8281118    {
    8291119        ULONG       ul;
     
    8631153 */
    8641154
    865 USHORT CnrInsertDetailFieldInfo(HWND hwnd,
    866                                 PFIELDINFO pfiFirst,
    867                                 PFIELDINFOINSERT pfii)
     1155STATIC USHORT CnrInsertDetailFieldInfo(PCNRDATA pData,
     1156                                       PFIELDINFO pfiFirst,
     1157                                       PFIELDINFOINSERT pfii)
    8681158{
    8691159    USHORT      usrc = 0;
    870     PCNRDATA    pData;
    871     if (    (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1160
     1161    if (    (pData)
    8721162         && (pfiFirst)
    8731163         && (pfii)
     
    9331223        {
    9341224            // post semaphore to force resize of details wnd
    935             WinPostMsg(hwnd,
     1225            WinPostMsg(pData->dwdMain.hwnd,
    9361226                       WM_SEM2,
    9371227                       (MPARAM)DDFL_ALL,
     
    9481238 */
    9491239
    950 BOOL CnrInvalidateDetailFieldInfo(HWND hwnd)
    951 {
    952     PCNRDATA    pData;
    953     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    954     {
    955         WinPostMsg(hwnd,
    956                    WM_SEM2,
    957                    (MPARAM)DDFL_INVALIDATECOLUMNS,
    958                    0);
    959     }
     1240STATIC BOOL CnrInvalidateDetailFieldInfo(PCNRDATA pData)
     1241{
     1242    if (pData)
     1243        return WinPostMsg(pData->dwdMain.hwnd,
     1244                          WM_SEM2,
     1245                          (MPARAM)DDFL_INVALIDATECOLUMNS,
     1246                          0);
    9601247
    9611248    return FALSE;
     1249}
     1250
     1251/*
     1252 *@@ CnrQueryDetailFieldInfo:
     1253 *      implementation for CM_QUERYDETAILFIELDINFO in fnwpCnr.
     1254 */
     1255
     1256STATIC const FIELDINFO* CnrQueryDetailFieldInfo(PCNRDATA pData,
     1257                                                PFIELDINFO pfiIn,
     1258                                                USHORT cmd)        // in: mp2 (CMA_FIRST, CMA_LAST, CMA_NEXT, CMA_PREV)
     1259{
     1260    const FIELDINFO *pfiReturn = NULL;
     1261
     1262    if (pData)
     1263    {
     1264        PLISTNODE pNode;
     1265
     1266        switch (cmd)
     1267        {
     1268            case CMA_FIRST:
     1269                pNode = lstQueryFirstNode(&pData->llColumns);
     1270            break;
     1271
     1272            case CMA_LAST:
     1273                pNode = lstQueryLastNode(&pData->llColumns);
     1274            break;
     1275
     1276            case CMA_NEXT:
     1277            case CMA_PREV:
     1278                if (FindColumnFromFI(pData,
     1279                                     pfiIn,
     1280                                     &pNode))
     1281                    if (cmd == CMA_NEXT)
     1282                        pNode = pNode->pNext;
     1283                    else
     1284                        pNode = pNode->pPrevious;
     1285            break;
     1286        }
     1287
     1288        if (pNode)
     1289            pfiReturn = ((PDETAILCOLUMN)pNode->pItemData)->pfi;
     1290    }
     1291
     1292    return pfiReturn;
    9621293}
    9631294
     
    9671298 */
    9681299
    969 SHORT CnrRemoveDetailFieldInfo(HWND hwnd,
    970                                PFIELDINFO* ppafi,
    971                                USHORT cfi,
    972                                USHORT fl)
    973 {
    974     PCNRDATA    pData;
    975     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1300STATIC SHORT CnrRemoveDetailFieldInfo(PCNRDATA pData,
     1301                                      PFIELDINFO* ppafi,
     1302                                      USHORT cfi,
     1303                                      USHORT fl)
     1304{
     1305    if (pData)
    9761306    {
    9771307        SHORT   rc = lstCountItems(&pData->llColumns);
     
    10111341           )
    10121342        {
    1013             WinPostMsg(hwnd,
     1343            WinPostMsg(pData->dwdMain.hwnd,
    10141344                       WM_SEM2,
    10151345                       (MPARAM)DDFL_INVALIDATECOLUMNS,
     
    10281358 */
    10291359
    1030 BOOL CnrFreeDetailFieldInfo(HWND hwnd,
    1031                             PFIELDINFO *ppafi,      // in: mp1 of CM_FREEDETAILFIELDINFO
    1032                             USHORT cFieldInfos)     // in: no. of items in array
     1360STATIC BOOL CnrFreeDetailFieldInfo(PCNRDATA pData,
     1361                                   PFIELDINFO *ppafi,      // in: mp1 of CM_FREEDETAILFIELDINFO
     1362                                   USHORT cFieldInfos)     // in: no. of items in array
    10331363{
    10341364    BOOL        brc = FALSE;
    10351365
    1036     PCNRDATA    pData;
    1037     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1366    if (pData)
    10381367    {
    10391368        ULONG   ul;
     
    10701399 */
    10711400
    1072 PRECORDCORE CnrAllocRecord(HWND hwnd,
    1073                            ULONG cbExtra,
    1074                            USHORT cRecords)
     1401STATIC PRECORDCORE CnrAllocRecord(PCNRDATA pData,
     1402                                  ULONG cbExtra,
     1403                                  USHORT cRecords)
    10751404{
    10761405    PRECORDCORE preccFirst = NULL;
    1077     PCNRDATA    pData;
    1078     if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1406
     1407    if (pData)
    10791408    {
    10801409        ULONG   ul;
     
    11241453 */
    11251454
    1126 ULONG CnrInsertRecord(HWND hwnd,
    1127                       PRECORDCORE preccFirst,
    1128                       PRECORDINSERT pri)
     1455STATIC ULONG CnrInsertRecord(PCNRDATA pData,
     1456                             PRECORDCORE preccFirst,
     1457                             PRECORDINSERT pri)
    11291458{
    11301459    ULONG       cReturn = 0;
    1131     PCNRDATA    pData;
    1132     if (    (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1460
     1461    if (    (pData)
    11331462         && (preccFirst)
    11341463         && (pri)
     
    11631492
    11641493            default:
    1165                 pNodeInsertAfter = FindListNodeForRecc(pData,
    1166                                                        pri->pRecordOrder);
     1494                pNodeInsertAfter = ctnrFindListNodeForRecc(pData,
     1495                                                           pri->pRecordOrder);
    11671496        }
    11681497
     
    11711500             ++ul)
    11721501        {
    1173             PRECORDLISTITEM pListItem;
    1174 
    1175             if (pListItem = NEW(RECORDLISTITEM))
     1502            PRECORDLISTITEM prli;
     1503
     1504            if (prli = NEW(RECORDLISTITEM))
    11761505            {
    1177                 ZERO(pListItem);
    1178 
    1179                 pListItem->precc = preccThis;
    1180                 pListItem->preccParent = pri->pRecordParent;
     1506                ZERO(prli);
     1507
     1508                prli->precc = preccThis;
     1509                prli->preccParent = pri->pRecordParent;
     1510
     1511                // make private copy of record attributes
     1512                prli->flRecordAttr = preccThis->flRecordAttr;
     1513
     1514                // PM container gives the first record in the cnr
     1515                // "cursored" and "selected" emphasis, so that's
     1516                // what we'll do too
     1517                if (    (!cReturn)       // @@todo filtered records
     1518                     && (!(prli->flRecordAttr & CRA_FILTERED))
     1519                   )
     1520                {
     1521                    prli->flRecordAttr |= CRA_CURSORED | CRA_SELECTED;
     1522
     1523                    pData->prliCursored = prli;
     1524                }
    11811525
    11821526                if (pNodeInsertAfter = lstInsertItemAfterNode(pll,
    1183                                                               pListItem,
     1527                                                              prli,
    11841528                                                              pNodeInsertAfter))
    11851529                {
     
    12121556                }
    12131557
    1214                 free(pListItem);
     1558                free(prli);
    12151559            }
    12161560
    1217             free(pListItem);
     1561            free(prli);
    12181562
    12191563            cReturn = 0;
     
    12251569           )
    12261570        {
    1227             WinPostMsg(hwnd,
     1571            WinPostMsg(pData->dwdMain.hwnd,
    12281572                       WM_SEM2,
    1229                        (MPARAM)DDFL_INCALIDATERECORDS,
     1573                       (MPARAM)DDFL_INVALIDATERECORDS,
    12301574                       0);
    12311575        }
     
    12351579}
    12361580
     1581/*
     1582 *@@ CnrInsertRecordArray:
     1583 *      implementation for CM_INSERTRECORDARRAY in fnwpCnr.
     1584 */
     1585
     1586STATIC ULONG CnrInsertRecordArray(PCNRDATA pData,
     1587                                  PRECORDCORE *papRecords,
     1588                                  PRECORDINSERT pri)
     1589{
     1590    ULONG       cReturn = 0;
     1591
     1592    if (    (pData)
     1593         && (papRecords)
     1594         && (pri)
     1595         && (pri->cb = sizeof(RECORDINSERT))
     1596       )
     1597    {
     1598        // produce a linked list off the array and call
     1599        // the CM_INSERTRECORD implementation
     1600        ULONG   ul;
     1601        for (ul = 0;
     1602             ul < (pri->cRecordsInsert - 1);
     1603             ++ul)
     1604        {
     1605            papRecords[ul]->preccNextRecord = papRecords[ul + 1];
     1606        }
     1607
     1608        papRecords[pri->cRecordsInsert - 1]->preccNextRecord = (PRECORDCORE)NULL;
     1609
     1610        cReturn = CnrInsertRecord(pData,
     1611                                  papRecords[0],
     1612                                  pri);
     1613    }
     1614
     1615    return cReturn;
     1616}
     1617
     1618/*
     1619 *@@ CnrSetRecordEmphasis:
     1620 *      implementation for CM_SETRECORDEMPHASIS in fnwpCnr.
     1621 */
     1622
     1623STATIC BOOL CnrSetRecordEmphasis(PCNRDATA pData,
     1624                                 PRECORDCORE precc,
     1625                                 BOOL fTurnOn,
     1626                                 USHORT fsEmphasis)
     1627{
     1628    BOOL        brc = FALSE;
     1629
     1630    if (pData)
     1631    {
     1632        if (precc)
     1633        {
     1634            PLISTNODE   pNode;
     1635            if (pNode = ctnrFindListNodeForRecc(pData,
     1636                                                precc))
     1637            {
     1638                PRECORDLISTITEM prli = (PRECORDLISTITEM)pNode->pItemData;
     1639
     1640                ctnrChangeEmphasis(pData,
     1641                                   prli,
     1642                                   fTurnOn,
     1643                                   fsEmphasis);
     1644
     1645                // update caller's buffer too
     1646                precc->flRecordAttr = prli->flRecordAttr;
     1647
     1648                brc = TRUE;
     1649            }
     1650        } // if (precc)
     1651        // @@todo else set emphasis on entire cnr
     1652    }
     1653
     1654    return brc;
     1655}
     1656
     1657/*
     1658 *@@ CnrQueryRecordEmphasis:
     1659 *      implementation for CM_QUERYRECORDEMPHASIS in fnwpCnr.
     1660 *
     1661 *      Note, if several flags are set in fsEmphasis, all
     1662 *      of them must be set in the record to match.
     1663 */
     1664
     1665PRECORDCORE CnrQueryRecordEmphasis(PCNRDATA pData,
     1666                                   PRECORDCORE preccSearchAfter,
     1667                                   USHORT fsEmphasis)
     1668{
     1669    if (pData)
     1670    {
     1671        PLISTNODE pNode = NULL;
     1672        if (preccSearchAfter == (PRECORDCORE)CMA_FIRST)
     1673            pNode = lstQueryFirstNode(&pData->llRootRecords);
     1674        else
     1675            if (pNode = ctnrFindListNodeForRecc(pData, preccSearchAfter))
     1676                pNode = pNode->pNext;
     1677            else
     1678                return (PRECORDCORE)-1;
     1679        // @@todo how does this search tree subrecords?
     1680
     1681        while (pNode)
     1682        {
     1683            PRECORDLISTITEM prli = (PRECORDLISTITEM)pNode->pItemData;
     1684            if ((prli->flRecordAttr & fsEmphasis) == fsEmphasis)
     1685                return (PRECORDCORE)prli->precc;
     1686
     1687            pNode = pNode->pNext;
     1688        }
     1689    }
     1690
     1691    return NULL;
     1692}
     1693
     1694/*
     1695 *@@ CnrInvalidateRecord:
     1696 *      implementation for CM_INVALIDATERECORD in fnwpCnr.
     1697 *
     1698 */
     1699
     1700STATIC BOOL CnrInvalidateRecord(PCNRDATA pData,
     1701                                PRECORDCORE *papRecs,
     1702                                USHORT cRecs,
     1703                                USHORT fsInvalidate)
     1704{
     1705    BOOL    brc = TRUE;
     1706
     1707    if (pData)
     1708    {
     1709        if (    (!papRecs)
     1710             || (!cRecs)
     1711           )
     1712            // invalidate all:
     1713            CnrSem2(pData, DDFL_INVALIDATERECORDS);
     1714        else
     1715        {
     1716            ULONG   ul;
     1717            for (ul = 0;
     1718                 ul < cRecs;
     1719                 ++cRecs)
     1720            {
     1721                PRECORDCORE precc = papRecs[ul];
     1722                PLISTNODE pRecNode;
     1723                if (!(pRecNode = ctnrFindListNodeForRecc(pData,
     1724                                                         precc)))
     1725                {
     1726                    brc = FALSE;
     1727                    break;
     1728                }
     1729
     1730                // set special flag for recompute
     1731                ((PRECORDLISTITEM)pRecNode->pItemData)->flInvalidate = fsInvalidate;
     1732            }
     1733
     1734            if (brc)
     1735                CnrSem2(pData, DDFL_INVALIDATESOME);
     1736                // @@todo optimize: post sem only if a column size has
     1737                // actually changed
     1738        }
     1739    }
     1740
     1741    return brc;
     1742}
     1743
    12371744/* ******************************************************************
    12381745 *
     
    12491756{
    12501757    MRESULT     mrc = 0;
    1251     PCNRDATA    pData;
     1758
     1759    PCNRDATA    pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1);
    12521760
    12531761    switch (msg)
     
    12641772
    12651773        case WM_SEM2:
    1266             CnrSem2(hwnd, (ULONG)mp1);
     1774            CnrSem2(pData, (ULONG)mp1);
    12671775        break;
    12681776
    12691777        case WM_PAINT:
    1270             CnrPaint(hwnd);
     1778            CnrPaint(pData);
    12711779        break;
    12721780
    12731781        case WM_WINDOWPOSCHANGED:
    1274             mrc = CnrWindowPosChanged(hwnd, mp1, mp2);
     1782            mrc = CnrWindowPosChanged(pData, mp1, mp2);
     1783        break;
     1784
     1785        case WM_SYSCOLORCHANGE:
     1786            ctnrPresParamChanged(hwnd, 0);
     1787        break;
     1788
     1789        case WM_PRESPARAMCHANGED:
     1790            ctnrPresParamChanged(hwnd, (ULONG)mp1);
    12751791        break;
    12761792
    12771793        case WM_HSCROLL:
    12781794        case WM_VSCROLL:
    1279             CnrScroll(hwnd, msg, mp1, mp2);
     1795            CnrScroll(pData, msg, mp1, mp2);
    12801796        break;
    12811797
    12821798        case WM_DESTROY:
    1283             CnrDestroy(hwnd);
     1799            CnrDestroy(pData);
     1800        break;
     1801
     1802        /* ******************************************************************
     1803         *
     1804         *   Mouse and keyboard input
     1805         *
     1806         ********************************************************************/
     1807
     1808        /*
     1809         * WM_OPEN:
     1810         *      when the user double-clicks on the _main_ cnr
     1811         *      (i.e. details titles), we notify the owner
     1812         *      of a "whitespace" enter event.
     1813         */
     1814
     1815        case WM_OPEN:
     1816            ctnrRecordEnter(pData,
     1817                            NULL,
     1818                            FALSE);     // mouse, not keyboard
     1819            mrc = (MRESULT)TRUE;
    12841820        break;
    12851821
     
    13011837         */
    13021838
    1303         case CM_QUERYCNRINFO:
    1304             mrc = (MRESULT)CnrQueryCnrInfo(hwnd,
     1839        case CM_QUERYCNRINFO:       // done
     1840            mrc = (MRESULT)CnrQueryCnrInfo(pData,
    13051841                                           (PCNRINFO)mp1,
    1306                                            (USHORT)mp2);
     1842                                           SHORT1FROMMP(mp2));
    13071843        break;
    13081844
     
    13191855         */
    13201856
    1321         case CM_SETCNRINFO:
    1322             mrc = (MRESULT)CnrSetCnrInfo(hwnd,
     1857        case CM_SETCNRINFO:         // parlty done
     1858            mrc = (MRESULT)CnrSetCnrInfo(pData,
    13231859                                         (PCNRINFO)mp1,
    13241860                                         (ULONG)mp2);
    13251861        break;
    13261862
     1863        case CM_PAINTBACKGROUND:        // @@todo
     1864        break;
     1865
     1866        case CM_SCROLLWINDOW:           // @@todo
     1867        break;
     1868
     1869        /*
     1870         * CM_QUERYVIEWPORTRECT:
     1871         *
     1872         *      Parameters:
     1873         *
     1874         *      --  PRECTL mp1
     1875         *
     1876         *      --  SHORT1FROMMP(mp2): -- CMA_WINDOW: return window coordinates
     1877         *                             -- CMA_WORKSPACE: return workspace coordinates
     1878         *
     1879         *      --  BOOL SHORT2FROMMP(mp2): if TRUE, return right split details view
     1880         */
     1881
     1882        case CM_QUERYVIEWPORTRECT:          // done
     1883            mrc = (MRESULT)CnrQueryViewportRect(pData,
     1884                                                (PRECTL)mp1,
     1885                                                SHORT1FROMMP(mp2),
     1886                                                SHORT2FROMMP(mp2));
     1887        break;
     1888
     1889        case CM_SETTEXTVISIBILITY:      // @@todo
     1890        break;
     1891
    13271892        /* ******************************************************************
    13281893         *
    1329          *   FIELDINFO-related messages
     1894         *   Record allocation/insertion/removal
     1895         *
     1896         ********************************************************************/
     1897
     1898        /*
     1899         * CM_ALLOCRECORD:
     1900         *
     1901         *      Parameters:
     1902         *
     1903         *      --  ULONG mp1: record size in addition to (MINI)RECORDCORE size.
     1904         *
     1905         *      --  USHORT mp2: no. of records to allocate.
     1906         *
     1907         *      Returns linked list of RECORDCORE's or NULL on errors.
     1908         */
     1909
     1910        case CM_ALLOCRECORD:          // done
     1911            mrc = (MRESULT)CnrAllocRecord(pData,
     1912                                          (ULONG)mp1,
     1913                                          SHORT1FROMMP(mp2));
     1914        break;
     1915
     1916        /*
     1917         * CM_INSERTRECORD:
     1918         *      inserts one or more records. If there's more
     1919         *      than one record, we assume it's a linked list.
     1920         *
     1921         *      Parameters:
     1922         *
     1923         *      --  PRECORDCORE mp1: first record
     1924         *
     1925         *      --  PRECORDINSERT pri
     1926         *
     1927         *      Returns the no. of records in the container or 0 on errors.
     1928         */
     1929
     1930        case CM_INSERTRECORD:           // done
     1931            mrc = (MRESULT)CnrInsertRecord(pData,
     1932                                           (PRECORDCORE)mp1,
     1933                                           (PRECORDINSERT)mp2);
     1934        break;
     1935
     1936        /*
     1937         * CM_INSERTRECORDARRAY:
     1938         *      inserts one or more records. As opposed to with
     1939         *      CM_INSERTRECORD, mp1 points to an array of
     1940         *      record pointers instead of to a linked list
     1941         *      of records.
     1942         *
     1943         *      Parameters:
     1944         *
     1945         *      --  PRECORDCORE mp1: first record
     1946         *
     1947         *      --  PRECORDINSERT pri
     1948         *
     1949         *      Returns the no. of records in the container or 0 on errors.
     1950         */
     1951
     1952        case CM_INSERTRECORDARRAY:      // done
     1953            mrc = (MRESULT)CnrInsertRecordArray(pData,
     1954                                               (PRECORDCORE*)mp1,
     1955                                               (PRECORDINSERT)mp2);
     1956        break;
     1957
     1958        /*
     1959         * CM_QUERYRECORD:
     1960         *
     1961         *      Parameters:
     1962         *
     1963         *      --  PRECORDCORE mp1: preccSearch
     1964         *
     1965         *      --  SHORT1FROMMP(mp1): CMA_FIRST, CMA_LAST, CMA_NEXT, CMA_PREV
     1966         *
     1967         *          or for tree views: CMA_FIRSTCHILD, CMA_LASTCHILD, CMA_PARENT
     1968         *
     1969         *      --  SHORT2FROMMP(mp1): CMA_ITEMORDER or CMA_ZORDER
     1970         */
     1971
     1972        case CM_QUERYRECORD:            // @@todo
     1973        break;
     1974
     1975        /*
     1976         * CM_SETRECORDEMPHASIS:
     1977         *
     1978         *      Parameters:
     1979         *
     1980         *      --  PRECORDCORE mp1: record to change emphasis for.
     1981         *
     1982         *      --  SHORT1FROMMP(mp2): TRUE == turn flags on, FALSE == turn flags off.
     1983         *
     1984         *      --  SHORT2FROMMP(mp2): any combination of CRA_CURSORED, CRA_DISABLED,
     1985         *          CRA_INUSE, CRA_PICKED, CRA_SELECTED, CRA_SOURCE
     1986         *
     1987         *      Returns BOOL.
     1988         */
     1989
     1990        case CM_SETRECORDEMPHASIS:
     1991            mrc = (MRESULT)CnrSetRecordEmphasis(pData,
     1992                                                (PRECORDCORE)mp1,
     1993                                                SHORT1FROMMP(mp2),
     1994                                                SHORT2FROMMP(mp2));
     1995        break;
     1996
     1997        /*
     1998         * CM_QUERYRECORDEMPHASIS:
     1999         *
     2000         *      Parameters:
     2001         *
     2002         *      --  PRECORDCORE mp1: record after which to start search
     2003         *          or NULL to start search from beginning.
     2004         *
     2005         *      --  USHORT mp2: any combination of CRA_COLLAPSED, CRA_CURSORED,
     2006         *          CRA_DISABLED, CRA_DROPONABLE, CRA_EXPANDED, CRA_FILTERED,
     2007         *          CRA_INUSE, CRA_PICKED, CRA_SELECTED, CRA_SOURCE
     2008         */
     2009
     2010        case CM_QUERYRECORDEMPHASIS:    // done
     2011            mrc = (MRESULT)CnrQueryRecordEmphasis(pData,
     2012                                                  (PRECORDCORE)mp1,
     2013                                                  SHORT1FROMMP(mp2));
     2014        break;
     2015
     2016        case CM_QUERYRECORDFROMRECT:    // @@todo
     2017        break;
     2018
     2019        case CM_QUERYRECORDINFO:        // @@todo
     2020        break;
     2021
     2022        case CM_QUERYRECORDRECT:        // @@todo
     2023        break;
     2024
     2025        /*
     2026         * CM_INVALIDATERECORD:
     2027         *
     2028         *      Parameters:
     2029         *
     2030         *      --  PRECORDCORE* mp1: ptr to array of record pointers
     2031         *
     2032         *      --  SHORT1FROMMP(mp2): no. of records in array
     2033         *
     2034         *      --  SHORT2FROMMP(mp2): CMA_ERASE, CMA_REPOSITION,
     2035         *          CMA_NOREPOSITION, CMA_TEXTCHANGED
     2036         *
     2037         *      Returns BOOL.
     2038         */
     2039
     2040        case CM_INVALIDATERECORD:       // done
     2041            mrc = (MRESULT)CnrInvalidateRecord(pData,
     2042                                               (PRECORDCORE*)mp1,
     2043                                               SHORT1FROMMP(mp2),
     2044                                               SHORT2FROMMP(mp2));
     2045        break;
     2046
     2047        case CM_REMOVERECORD:   // @@todo
     2048        case CM_FREERECORD:     // @@todo
     2049        break;
     2050
     2051        case CM_ERASERECORD:    // @@todo
     2052        break;
     2053
     2054        case CM_ARRANGE:        // @@todo
     2055        break;
     2056
     2057        case CM_FILTER:         // @@todo
     2058        break;
     2059
     2060        case CM_QUERYDRAGIMAGE: // @@todo
     2061
     2062        case CM_SEARCHSTRING:
     2063
     2064        case CM_SORTRECORD:     // @@todo
     2065
     2066        /* ******************************************************************
     2067         *
     2068         *   Details view
    13302069         *
    13312070         ********************************************************************/
     
    13432082         */
    13442083
    1345         case CM_ALLOCDETAILFIELDINFO:
    1346             mrc = (MRESULT)CnrAllocDetailFieldInfo(hwnd,
    1347                                                    (USHORT)mp1);
     2084        case CM_ALLOCDETAILFIELDINFO: // done
     2085            mrc = (MRESULT)CnrAllocDetailFieldInfo(pData,
     2086                                                   SHORT1FROMMP(mp1));
    13482087        break;
    13492088
     
    13602099         */
    13612100
    1362         case CM_INSERTDETAILFIELDINFO:
    1363             mrc = (MRESULT)CnrInsertDetailFieldInfo(hwnd,
     2101        case CM_INSERTDETAILFIELDINFO:      // done
     2102            mrc = (MRESULT)CnrInsertDetailFieldInfo(pData,
    13642103                                                    (PFIELDINFO)mp1,
    13652104                                                    (PFIELDINFOINSERT)mp2);
     
    13732112         */
    13742113
    1375         case CM_INVALIDATEDETAILFIELDINFO:
    1376             mrc = (MRESULT)CnrInvalidateDetailFieldInfo(hwnd);
     2114        case CM_INVALIDATEDETAILFIELDINFO:  // done
     2115            mrc = (MRESULT)CnrInvalidateDetailFieldInfo(pData);
     2116        break;
     2117
     2118        /*
     2119         * CM_QUERYDETAILFIELDINFO:
     2120         *
     2121         *      Parameters:
     2122         *
     2123         *      --  PFIELDINFO mp1
     2124         *
     2125         *      --  USHORT mp2: CMA_FIRST, CMA_LAST, CMA_NEXT, CMA_PREV
     2126         */
     2127
     2128        case CM_QUERYDETAILFIELDINFO:       // done
     2129            mrc = (MRESULT)CnrQueryDetailFieldInfo(pData,
     2130                                                   (PFIELDINFO)mp1,
     2131                                                   SHORT1FROMMP(mp2));
    13772132        break;
    13782133
     
    13912146         */
    13922147
    1393         case CM_REMOVEDETAILFIELDINFO:
    1394             mrc = (MRESULT)CnrRemoveDetailFieldInfo(hwnd,
     2148        case CM_REMOVEDETAILFIELDINFO:      // done
     2149            mrc = (MRESULT)CnrRemoveDetailFieldInfo(pData,
    13952150                                                    (PFIELDINFO*)mp1,
    13962151                                                    SHORT1FROMMP(mp2),
     
    14092164         */
    14102165
    1411         case CM_FREEDETAILFIELDINFO:
    1412             mrc = (MRESULT)CnrFreeDetailFieldInfo(hwnd,
     2166        case CM_FREEDETAILFIELDINFO:        // done
     2167            mrc = (MRESULT)CnrFreeDetailFieldInfo(pData,
    14132168                                                  (PFIELDINFO*)mp1,
    1414                                                   (USHORT)mp2);
     2169                                                  SHORT1FROMMP(mp2));
     2170        break;
     2171
     2172        case CM_HORZSCROLLSPLITWINDOW:
    14152173        break;
    14162174
    14172175        /* ******************************************************************
    14182176         *
    1419          *   Record allocation/insertion/removal
     2177         *   Icon view
    14202178         *
    14212179         ********************************************************************/
    14222180
    1423         /*
    1424          * CM_ALLOCRECORD:
    1425          *
    1426          *      Parameters:
    1427          *
    1428          *      --  ULONG mp1: record size in addition to (MINI)RECORDCORE size.
    1429          *
    1430          *      --  USHORT mp2: no. of records to allocate.
    1431          *
    1432          *      Returns linked list of RECORDCORE's or NULL on errors.
    1433          */
    1434 
    1435         case CM_ALLOCRECORD:
    1436             mrc = (MRESULT)CnrAllocRecord(hwnd,
    1437                                           (ULONG)mp1,
    1438                                           (USHORT)mp2);
    1439         break;
    1440 
    1441         /*
    1442          * CM_INSERTRECORD:
    1443          *
    1444          *      Parameters:
    1445          *
    1446          *      --  PRECORDCORE mp1: first record
    1447          *
    1448          *      --  PRECORDINSERT pri
    1449          *
    1450          *      Returns the no. of records in the container or 0 on errors.
    1451          */
    1452 
    1453         case CM_INSERTRECORD:
    1454             mrc = (MRESULT)CnrInsertRecord(hwnd,
    1455                                            (PRECORDCORE)mp1,
    1456                                            (PRECORDINSERT)mp2);
    1457         break;
     2181        case CM_SETGRIDINFO:    // @@todo
     2182        case CM_QUERYGRIDINFO:  // @@todo
     2183        case CM_SNAPTOGRID:     // @@todo
     2184        break;
     2185
     2186        /* ******************************************************************
     2187         *
     2188         *   Tree management
     2189         *
     2190         ********************************************************************/
     2191
     2192        case CM_COLLAPSETREE:   // @@todo
     2193        case CM_EXPANDTREE:
     2194        case CM_MOVETREE:       // @@todo
     2195        break;
     2196
     2197        /* ******************************************************************
     2198         *
     2199         *   Direct editing
     2200         *
     2201         ********************************************************************/
     2202
     2203        case CM_OPENEDIT:       // @@todo
     2204
     2205        case CM_CLOSEEDIT:      // @@todo
     2206        break;
     2207
    14582208
    14592209        default:
    1460             if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     2210            if (pData)
    14612211                mrc = ctlDefWindowProc(&pData->dwdMain, msg, mp1, mp2);
    14622212        break;
  • trunk/src/helpers/cctl_cnr_dtls.c

    r242 r243  
    2626    // as unsigned char
    2727
     28#define INCL_DOSMISC
     29
    2830#define INCL_WINWINDOWMGR
    2931#define INCL_WINFRAMEMGR
    3032#define INCL_WINSYS
     33#define INCL_WININPUT
    3134#define INCL_WINSTDCNR
    3235#define INCL_GPIPRIMITIVES
     
    6164
    6265/*
     66 *@@ InvalidateColumn:
     67 *
     68 */
     69
     70VOID InvalidateColumn(PCNRDATA pData,
     71                      const DETAILCOLUMN *pColumn)
     72{
     73    RECTL   rcl;
     74    rcl.xLeft = pColumn->xLeft - pData->scrw.ptlScrollOfs.x;
     75    rcl.xRight = rcl.xLeft + pColumn->cxContent + 2 * COLUMN_PADDING_X + 1;
     76    rcl.yBottom = 0;
     77    rcl.yTop = pData->dwdContent.szlWin.cy;
     78
     79    WinInvalidateRect(pData->dwdContent.hwnd, &rcl, FALSE);
     80
     81    // and titles too
     82    rcl.yTop = pData->dwdMain.szlWin.cy;
     83    WinInvalidateRect(pData->dwdMain.hwnd, &rcl, FALSE);
     84}
     85
     86/*
    6387 *@@ cdtlRecalcDetails:
    6488 *      worker routine for refreshing all internal DETAILCOLUMN
     
    6892 *      in with sufficient update flags.
    6993 *
    70  *      Returns the following ORed flags:
     94 *      This sets the following flags in *pfl:
     95 *
     96 *      --  DDFL_INVALIDATECOLUMNS: columns have to be
     97 *          repositioned, so details window needs a full
     98 *          repaint.
    7199 *
    72100 *      --  DDFL_WINDOWSIZECHANGED: cnr titles area changed,
     
    79107VOID cdtlRecalcDetails(PCNRDATA pData,
    80108                       HPS hps,
    81                        PULONG pfl)
     109                       PULONG pfl)      // in/out: DDFL_* flags
    82110{
    83111    LONG        xCurrent = 0;
    84112    PLISTNODE   pColNode;
    85     ULONG       cRow = 0;
     113    ULONG       cColumn = 0;
    86114
    87115    // compute total padding for one row:
    88     LONG        cxPaddingRow = pData->CnrInfo.cFields * 2 * COLUMN_PADDING_X,
    89                 yOfsNow = 0;
    90 
     116    LONG        cxPaddingRow = pData->CnrInfo.cFields * 2 * COLUMN_PADDING_X;
    91117    LONG        cyColTitlesContent = 0,
    92118                cyColTitlesBox = 0;
    93119
     120    BOOL        fRefreshAll = (*pfl & (DDFL_INVALIDATECOLUMNS | DDFL_INVALIDATERECORDS));
     121
     122    LONG        yNow = 0;
     123
     124    // list of records to invalidate while we're running;
     125    // this only gets appended to if we're not invalidating
     126    // all records anyway
     127    LINKLIST    llInvalidateRecords;
     128    lstInit(&llInvalidateRecords, FALSE);       // receives RECORDLISTITEM's
     129
    94130    GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &pData->fm);
    95131
     
    97133    FOR_ALL_NODES(&pData->llColumns, pColNode)
    98134    {
    99         PDETAILCOLUMN pCol = (PDETAILCOLUMN)pColNode->pItemData;
    100         const FIELDINFO *pfi = pCol->pfi;
     135        PDETAILCOLUMN pColumn = (PDETAILCOLUMN)pColNode->pItemData;
     136        const FIELDINFO *pfi = pColumn->pfi;
    101137        PLISTNODE   pRecNode;
    102138
    103         pCol->xLeft = xCurrent;
    104 
    105         pCol->cxTotal
    106         = pCol->cxWidestRecord
    107         = 0;
    108 
    109         // inner loop: records (go DOWN)
    110         FOR_ALL_NODES(&pData->llRootRecords, pRecNode)
    111         {
    112             PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
    113             const   RECORDCORE *preccThis = prliThis->precc;
    114             PVOID   pColumnData = (PVOID)((PBYTE)preccThis + pfi->offStruct);
    115 
    116             SIZEL   szlThis = {10, 10};
    117             ULONG   cLines;
    118             PCSZ    pcsz = NULL;
    119             CHAR    szTemp[30];
    120 
    121             if (!cRow)
    122                 prliThis->szlContent.cy = 0;
    123 
    124             switch (pfi->flData & (   CFA_BITMAPORICON
    125                                     | CFA_DATE
    126                                     | CFA_STRING
    127                                     | CFA_TIME
    128                                     | CFA_ULONG))
     139        LONG        cxContent;
     140
     141        if (fRefreshAll)
     142            pColumn->cxWidestRecord = 0;
     143
     144        // skip invisible columns
     145        if (!(pfi->flData & CFA_INVISIBLE))
     146        {
     147            yNow = 0;
     148
     149            // inner loop: records (go UP)
     150            // (we start with the LAST record so we can calculate
     151            // the y coordinates correctly)
     152            pRecNode = lstQueryLastNode(&pData->llRootRecords);
     153            while (pRecNode)
    129154            {
    130                 case CFA_BITMAPORICON:
    131                     // @@todo
    132                 break;
    133 
    134                 case CFA_STRING:
    135                     pcsz = *(PSZ*)pColumnData;
    136                 break;
    137 
    138                 case CFA_DATE:
    139                     nlsDate(&pData->cs,
    140                             szTemp,
    141                             ((PCDATE)pColumnData)->year,
    142                             ((PCDATE)pColumnData)->month,
    143                             ((PCDATE)pColumnData)->day);
    144                     pcsz = szTemp;
    145                 break;
    146 
    147                 case CFA_TIME:
    148                     nlsTime(&pData->cs,
    149                             szTemp,
    150                             ((PCTIME)pColumnData)->hours,
    151                             ((PCTIME)pColumnData)->minutes,
    152                             ((PCTIME)pColumnData)->seconds);
    153                     pcsz = szTemp;
    154                 break;
    155 
    156                 case CFA_ULONG:
    157                     nlsThousandsULong(szTemp,
    158                                       *((PULONG)pColumnData),
    159                                       pData->cs.cs.cThousands);
    160                     pcsz = szTemp;
    161                 break;
    162             }
    163 
    164             if (pcsz)
     155                PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
     156                const   RECORDCORE *preccThis = prliThis->precc;
     157                PVOID   pColumnData = (PVOID)((PBYTE)preccThis + pfi->offStruct);
     158
     159                if (!(prliThis->flRecordAttr & CRA_FILTERED))
     160                {
     161                    // skip filtered records
     162                    if (    (*pfl & DDFL_INVALIDATERECORDS)
     163                         || (prliThis->flInvalidate)
     164                       )
     165                    {
     166                        ULONG   cLines;
     167                        SIZEL   szlThis = {10, 10};
     168                        PCSZ    pcsz = NULL;
     169                        CHAR    szTemp[30];
     170
     171                        if (!cColumn)
     172                        {
     173                            // we're in the leftmost column:
     174                            prliThis->szlContent.cx
     175                            = prliThis->szlContent.cy
     176                            = prliThis->szlBox.cx
     177                            = prliThis->szlBox.cy
     178                            = 0;
     179                        }
     180
     181                        switch (pfi->flData & (   CFA_BITMAPORICON
     182                                                | CFA_DATE
     183                                                | CFA_STRING
     184                                                | CFA_TIME
     185                                                | CFA_ULONG))
     186                        {
     187                            case CFA_BITMAPORICON:
     188                                // @@todo
     189                            break;
     190
     191                            case CFA_STRING:
     192                                pcsz = *(PSZ*)pColumnData;
     193                            break;
     194
     195                            case CFA_DATE:
     196                                nlsDate(&pData->cs,
     197                                        szTemp,
     198                                        ((PCDATE)pColumnData)->year,
     199                                        ((PCDATE)pColumnData)->month,
     200                                        ((PCDATE)pColumnData)->day);
     201                                pcsz = szTemp;
     202                            break;
     203
     204                            case CFA_TIME:
     205                                nlsTime(&pData->cs,
     206                                        szTemp,
     207                                        ((PCTIME)pColumnData)->hours,
     208                                        ((PCTIME)pColumnData)->minutes,
     209                                        ((PCTIME)pColumnData)->seconds);
     210                                pcsz = szTemp;
     211                            break;
     212
     213                            case CFA_ULONG:
     214                                nlsThousandsULong(szTemp,
     215                                                  *((PULONG)pColumnData),
     216                                                  pData->cs.cs.cThousands);
     217                                pcsz = szTemp;
     218                            break;
     219                        }
     220
     221                        if (pcsz)
     222                        {
     223                            gpihCalcTextExtent(hps,
     224                                               pcsz,
     225                                               &szlThis.cx,
     226                                               &cLines);
     227                            szlThis.cy = cLines * (pData->fm.lMaxBaselineExt + pData->fm.lExternalLeading);
     228                        }
     229
     230                        // increment record's total width
     231                        prliThis->szlContent.cx += szlThis.cx;
     232                        prliThis->szlBox.cx +=   szlThis.cx
     233                                               + cxPaddingRow;       // computed at top
     234
     235                        // record's content height = height of tallest column of that record
     236                        if (szlThis.cy > prliThis->szlContent.cy)
     237                            prliThis->szlContent.cy = szlThis.cy;
     238
     239                        // remember max width of this record's column
     240                        // for the entire column
     241                        if (szlThis.cx > pColumn->cxWidestRecord)
     242                            pColumn->cxWidestRecord = szlThis.cx;
     243
     244                        if (!pColNode->pNext)
     245                        {
     246                            // last column of outer loop:
     247
     248                            // clear refresh flags, if any
     249                            prliThis->flInvalidate = 0;
     250
     251                            // compute box cy from content
     252                            prliThis->szlBox.cy =   prliThis->szlContent.cy
     253                                                  + pData->CnrInfo.cyLineSpacing;
     254
     255                            // store record's position in workarea coords
     256                            prliThis->ptl.x = 0;        // we're in Details view
     257                            prliThis->ptl.y = yNow;
     258
     259                            if (!fRefreshAll)
     260                                // invalidate this record's rectangle
     261                                lstAppendItem(&llInvalidateRecords,
     262                                              prliThis);
     263                        }
     264                    }
     265
     266                    // go down for next record
     267                    yNow += prliThis->szlBox.cy;
     268
     269                } // if (!(prliThis->flRecordAttr & CRA_FILTERED))
     270
     271                pRecNode = pRecNode->pPrevious;
     272
     273            } // while (pRecNode)
     274
     275            if (!(cxContent = pfi->cxWidth))
    165276            {
    166                 gpihCalcTextExtent(hps,
    167                                    pcsz,
    168                                    &szlThis.cx,
    169                                    &cLines);
    170                 szlThis.cy = cLines * (pData->fm.lMaxBaselineExt + pData->fm.lExternalLeading);
    171             }
    172 
    173             // remember max width of this record's column
    174             // for the entire column
    175             if (szlThis.cx > pCol->cxWidestRecord)
    176                 pCol->cxWidestRecord = szlThis.cx;
    177 
    178             // record's content height = height of tallest column of that record
    179             if (szlThis.cy > prliThis->szlContent.cy)
    180                 prliThis->szlContent.cy = szlThis.cy;
    181 
    182             if (!pColNode->pNext)
    183             {
    184                 // last column: compute box from content
    185                 prliThis->szlBox.cx =   prliThis->szlContent.cx
    186                                       + cxPaddingRow;       // computed at top
    187                 prliThis->szlBox.cy =   prliThis->szlContent.cy
    188                                       + pData->CnrInfo.cyLineSpacing;
    189 
    190                 prliThis->yOfs = yOfsNow;
    191 
    192                 yOfsNow += prliThis->szlBox.cy;
    193             }
    194 
    195             ++cRow;
    196         }
    197 
    198         if (!(pCol->cxTotal = pfi->cxWidth))
    199         {
    200             // this is an auto-size column:
    201 
    202             if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES)
    203             {
    204                 // compute space needed for title
    205 
    206                 pCol->szlTitleData.cx
    207                 = pCol->szlTitleData.cy
    208                 = 0;
    209 
    210                 if (pfi->flTitle & CFA_BITMAPORICON)
    211                     // @@todo
    212                     ;
     277                // this is an auto-size column:
     278
     279                if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES)
     280                {
     281                    if (*pfl & DDFL_INVALIDATECOLUMNS)
     282                    {
     283                        // compute space needed for title
     284
     285                        pColumn->szlTitleData.cx
     286                        = pColumn->szlTitleData.cy
     287                        = 0;
     288
     289                        if (pfi->flTitle & CFA_BITMAPORICON)
     290                            // @@todo
     291                            ;
     292                        else
     293                        {
     294                            ULONG cLines;
     295                            gpihCalcTextExtent(hps,
     296                                               (PCSZ)pfi->pTitleData,
     297                                               &pColumn->szlTitleData.cx,
     298                                               &cLines);
     299                            pColumn->szlTitleData.cy = cLines * (pData->fm.lMaxBaselineExt + pData->fm.lExternalLeading);
     300                        }
     301                    }
     302
     303                    cxContent = max(pColumn->cxWidestRecord, pColumn->szlTitleData.cx);
     304
     305                    if (pColumn->szlTitleData.cy > cyColTitlesContent)
     306                        cyColTitlesContent = pColumn->szlTitleData.cy;
     307                }
    213308                else
    214309                {
    215                     ULONG cLines;
    216                     gpihCalcTextExtent(hps,
    217                                        (PCSZ)pfi->pTitleData,
    218                                        &pCol->szlTitleData.cx,
    219                                        &cLines);
    220                     pCol->szlTitleData.cy = cLines * (pData->fm.lMaxBaselineExt + pData->fm.lExternalLeading);
     310                    pColumn->szlTitleData.cx
     311                    = 0;
    221312                }
    222 
    223                 pCol->cxTotal =   max(pCol->cxWidestRecord, pCol->szlTitleData.cx);
    224 
    225                 if (pCol->szlTitleData.cy > cyColTitlesContent)
    226                     cyColTitlesContent = pCol->szlTitleData.cy;
    227313            }
    228             else
     314
     315            // check if column needs invalidating
     316            if (    (fRefreshAll)
     317                 || (pColumn->xLeft != xCurrent)
     318                 || (pColumn->cxContent != cxContent)
     319               )
    229320            {
    230                 pCol->szlTitleData.cx
    231                 = 0;
     321                pColumn->xLeft = xCurrent;
     322                pColumn->cxContent = cxContent;
     323
     324                if (!fRefreshAll)
     325                    InvalidateColumn(pData,
     326                                     pColumn);
    232327            }
    233         }
    234 
    235         // go one column to the right
    236         xCurrent += pCol->cxTotal + 2 * COLUMN_PADDING_X;
    237 
    238         if (    (pfi->flData & CFA_SEPARATOR)
    239              && (pColNode->pNext)
    240            )
    241             xCurrent += DEFAULT_BORDER_WIDTH;
    242     }
    243 
    244     if (    (pData->szlWorkarea.cx != xCurrent)
    245          || (pData->szlWorkarea.cy != yOfsNow)
     328
     329            // go one column to the right
     330            xCurrent += cxContent + 2 * COLUMN_PADDING_X;
     331
     332            if (    (pfi->flData & CFA_SEPARATOR)
     333                 && (pColNode->pNext)
     334               )
     335                xCurrent += DEFAULT_BORDER_WIDTH;
     336
     337            ++cColumn;
     338        }
     339    }
     340
     341    // has workarea changed?
     342    if (    (pData->scrw.szlWorkarea.cx != xCurrent)
     343         || (pData->scrw.szlWorkarea.cy != yNow)
    246344       )
    247345    {
    248         pData->szlWorkarea.cx = xCurrent;
    249         pData->szlWorkarea.cy = yOfsNow;
     346        pData->scrw.szlWorkarea.cx = xCurrent;
     347        pData->scrw.szlWorkarea.cy = yNow;
    250348        *pfl |= DDFL_WORKAREACHANGED;
    251349    }
    252350
     351    // has details title box changed?
    253352    if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES)
    254353        cyColTitlesBox =   cyColTitlesContent
     
    265364        *pfl |= DDFL_WINDOWSIZECHANGED | DDFL_WORKAREACHANGED;
    266365    }
     366
     367    // now invalidate records
     368    if (fRefreshAll)
     369        WinInvalidateRect(pData->dwdMain.hwnd, NULL, TRUE);
     370    else
     371    {
     372        PLISTNODE pNode = lstQueryFirstNode(&llInvalidateRecords);
     373        while (pNode)
     374        {
     375            ctnrRepaintRecord(pData, (PRECORDLISTITEM)pNode->pItemData);
     376            pNode = pNode->pNext;
     377        }
     378    }
     379
     380    lstClear(&llInvalidateRecords);
    267381}
    268382
     
    276390MRESULT DetailsCreate(HWND hwnd, MPARAM mp1, MPARAM mp2)
    277391{
    278     if (!mp1)
     392    HWND    hwndParent;
     393
     394    if (    (!mp1)
     395         || (!mp2)
     396         || (!(hwndParent = (((PCREATESTRUCT)mp2)->hwndParent)))
     397       )
    279398        return (MRESULT)TRUE;
    280399
     
    282401
    283402    // initialize DEFWINDOWDATA
    284     ctlInitDWD(hwnd,
    285                mp2,
    286                &((PCNRDATA)mp1)->dwdContent,
    287                WinDefWindowProc,
    288                &G_scsCnr);
     403    ctnrInit(hwnd,
     404             mp2,
     405             winhQueryWindowStyle(hwndParent),      // main container
     406             &((PCNRDATA)mp1)->dwdContent);
     407
     408    // the cnr appears to always grab the focus on creation
     409    WinSetFocus(HWND_DESKTOP, hwnd);    // @@todo how do we do this on creation only?
    289410
    290411    return (MRESULT)FALSE;
     
    297418 */
    298419
    299 VOID DetailsPaint(HWND hwnd)
     420VOID DetailsPaint(PCNRDATA pData)
    300421{
    301422    HPS         hps;
    302     PCNRDATA    pData;
    303     RECTL       rclPaint;
    304 
    305     if (    (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
    306          && (hps = WinBeginPaint(hwnd, NULLHANDLE, &rclPaint))
    307        )
    308     {
    309         PLISTNODE pColNode;
    310 
    311         POINTL  ptl;
    312         RECTL   rcl;
     423    RECTL       rclClip;
     424
     425    if (hps = WinBeginPaint(pData->dwdContent.hwnd, NULLHANDLE, &rclClip))
     426    {
     427        PLISTNODE pColNode,
     428                  pRecNodeFirst2Paint = NULL;        // first one to paint
     429
    313430        LONG    yPadding = pData->CnrInfo.cyLineSpacing / 2;
    314431        ULONG   cColumn = 0;
     432        BOOL    fFirstCol = TRUE;
     433
     434        BOOL    fHasFocus;
     435        HWND    hwndFocus;
     436
     437        if (    (hwndFocus = WinQueryFocus(HWND_DESKTOP))
     438             && (hwndFocus == pData->dwdContent.hwnd)
     439           )
     440            fHasFocus = TRUE;
     441        else
     442            fHasFocus = FALSE;
    315443
    316444        gpihSwitchToRGB(hps);
     445
     446#if 0
     447        {
     448            ULONG ulTimeNow;
     449            DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     450                            &ulTimeNow,
     451                            sizeof(ulTimeNow));
     452            WinFillRect(hps,
     453                        &rclClip,
     454                        ulTimeNow & 0xFFFFFF);
     455        }
     456#else
    317457        WinFillRect(hps,
    318                     &rclPaint,
    319                     pData->dwdMain.lcolBackground);
    320 
    321         FOR_ALL_NODES(&pData->llColumns, pColNode)
     458                    &rclClip,
     459                    ctlQueryColor(&pData->dwdMain, CTLCOL_BGND));
     460#endif
     461
     462        // skip columns that are not in paint rectangle
     463        pColNode = lstQueryFirstNode(&pData->llColumns);
     464        while (pColNode)
     465        {
     466            PDETAILCOLUMN pCol = (PDETAILCOLUMN)pColNode->pItemData;
     467            const FIELDINFO *pfi = pCol->pfi;
     468            if (    (!(pfi->flData & CFA_INVISIBLE))
     469                 && (pCol->xLeft + pCol->cxContent - pData->scrw.ptlScrollOfs.x >= rclClip.xLeft)
     470               )
     471                break;
     472
     473            pColNode = pColNode->pNext;
     474        }
     475
     476        // now loop for the remaining columns (go RIGHT)
     477        while (pColNode)
    322478        {
    323479            PDETAILCOLUMN pCol = (PDETAILCOLUMN)pColNode->pItemData;
    324480            const FIELDINFO *pfi = pCol->pfi;
    325481            PLISTNODE   pRecNode;
    326             ULONG       cRow;
    327 
    328             rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData->ptlScrollOfs.x;
    329             rcl.xRight = rcl.xLeft + pCol->cxTotal;
    330 
    331             // we start out at the top and work our way down,
    332             // decrementing rcl.yTop with every item we painted
    333             rcl.yTop = pData->dwdContent.szlWin.cy + pData->ptlScrollOfs.y;
    334 
    335             PMPF_RECT("rcl: ", &rcl);
    336 
    337             // now paint this column's data for all records!
    338             cRow = 0;
    339             FOR_ALL_NODES(&pData->llRootRecords, pRecNode)
     482
     483            if (!(pfi->flData & CFA_INVISIBLE))
    340484            {
    341                 PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
    342                 const   RECORDCORE *preccThis = prliThis->precc;
    343                 PVOID   pColumnData = (PVOID)((PBYTE)preccThis + pfi->offStruct);
    344                 CHAR    szTemp[30];
    345                 PCSZ    pcsz = NULL;
    346 
    347                 rcl.yTop -= yPadding;
    348                 rcl.yBottom =   rcl.yTop
    349                               - prliThis->szlContent.cy;
    350 
    351                 switch (pfi->flData & (   CFA_BITMAPORICON
    352                                         | CFA_DATE
    353                                         | CFA_STRING
    354                                         | CFA_TIME
    355                                         | CFA_ULONG))
     485                RECTL rclRecc,
     486                      rcl;
     487
     488                rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData->scrw.ptlScrollOfs.x;
     489                rcl.xRight = rcl.xLeft + pCol->cxContent;
     490
     491                if (fFirstCol)
    356492                {
    357                     case CFA_BITMAPORICON:
    358                         // @@todo
    359                     break;
    360 
    361                     case CFA_STRING:
    362                         pcsz = *(PSZ*)pColumnData;
    363                     break;
    364 
    365                     case CFA_DATE:
    366                         nlsDate(&pData->cs,
    367                                 szTemp,
    368                                 ((PCDATE)pColumnData)->year,
    369                                 ((PCDATE)pColumnData)->month,
    370                                 ((PCDATE)pColumnData)->day);
    371                         pcsz = szTemp;
    372                     break;
    373 
    374                     case CFA_TIME:
    375                         nlsTime(&pData->cs,
    376                                 szTemp,
    377                                 ((PCTIME)pColumnData)->hours,
    378                                 ((PCTIME)pColumnData)->minutes,
    379                                 ((PCTIME)pColumnData)->seconds);
    380                         pcsz = szTemp;
    381                     break;
    382 
    383                     case CFA_ULONG:
    384                         nlsThousandsULong(szTemp,
    385                                           *((PULONG)pColumnData),
    386                                           pData->cs.cs.cThousands);
    387                         pcsz = szTemp;
    388                     break;
     493                    // first time we get here: skip all records that
     494                    // are outside the paint rectangle
     495
     496                    pRecNode = lstQueryFirstNode(&pData->llRootRecords);
     497                    while (pRecNode)
     498                    {
     499                        PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
     500
     501                        if (!(prliThis->flRecordAttr & CRA_FILTERED))
     502                        {
     503                            ctnrGetRecordRect(pData, &rclRecc, prliThis);
     504                            if (rclRecc.yBottom <= rclClip.yTop)
     505                            {
     506                                pRecNodeFirst2Paint = pRecNode;
     507
     508                                break;
     509                            }
     510                        }
     511
     512                        pRecNode = pRecNode->pNext;
     513                    }
    389514                }
    390515
    391                 if (pcsz)
    392                     cnrDrawString(hps,
    393                                   pcsz,
    394                                   &rcl,
    395                                   pfi->flData,
    396                                   &pData->fm);
    397 
    398                 ++cRow;
    399 
    400                 rcl.yTop = rcl.yBottom - yPadding;
     516                // now inner loop for the remaining records (go DOWN)
     517                pRecNode = pRecNodeFirst2Paint;
     518                while (pRecNode)
     519                {
     520                    PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
     521
     522                    if (!(prliThis->flRecordAttr & CRA_FILTERED))
     523                    {
     524                        const   RECORDCORE *preccThis = prliThis->precc;
     525                        PVOID   pColumnData = (PVOID)((PBYTE)preccThis + pfi->offStruct);
     526                        CHAR    szTemp[100];
     527                        PCSZ    pcsz = NULL;
     528                        LONG    lcolBackground,
     529                                lcolForeground;
     530
     531                        ctnrGetRecordRect(pData, &rclRecc, prliThis);
     532
     533                        PMPF_RECT("rclRecc: ", &rclRecc);
     534
     535                        if (prliThis->flRecordAttr & CRA_SELECTED)
     536                        {
     537                            lcolBackground = ctlQueryColor(&pData->dwdMain, CNRCOL_HILITEBGND);
     538                            lcolForeground = ctlQueryColor(&pData->dwdMain, CNRCOL_HILITEFGND);
     539
     540                            if (fFirstCol)
     541                                WinFillRect(hps,
     542                                            &rclRecc,
     543                                            lcolBackground);
     544                        }
     545                        else
     546                        {
     547                            lcolBackground = ctlQueryColor(&pData->dwdMain, CTLCOL_BGND);
     548                            lcolForeground = ctlQueryColor(&pData->dwdMain, CTLCOL_FGND);
     549                        }
     550
     551                        GpiSetColor(hps, lcolForeground);
     552                        GpiSetBackColor(hps, lcolBackground);
     553
     554                        rcl.yTop = rclRecc.yTop - yPadding;
     555                        rcl.yBottom = rcl.yTop - prliThis->szlContent.cy;
     556
     557                        if (    (fFirstCol)
     558                             && (prliThis->flRecordAttr & CRA_CURSORED)
     559                           )
     560                        {
     561                            RECTL rcl2;
     562                            rcl2.xLeft = rclRecc.xLeft + 1;
     563                            rcl2.xRight = rclRecc.xRight - 2;
     564                            rcl2.yBottom = rclRecc.yBottom + 1;
     565                            rcl2.yTop = rclRecc.yTop - 2;
     566                            GpiSetLineType(hps, LINETYPE_ALTERNATE);
     567                            gpihBox(hps,
     568                                    DRO_OUTLINE,
     569                                    &rcl2);
     570                            GpiSetLineType(hps, LINETYPE_DEFAULT);
     571                        }
     572
     573                        switch (pfi->flData & (   CFA_BITMAPORICON
     574                                                | CFA_DATE
     575                                                | CFA_STRING
     576                                                | CFA_TIME
     577                                                | CFA_ULONG))
     578                        {
     579                            case CFA_BITMAPORICON:
     580                                // @@todo
     581                            break;
     582
     583                            case CFA_STRING:
     584                                pcsz = *(PSZ*)pColumnData;
     585                            break;
     586
     587                            case CFA_DATE:
     588                                nlsDate(&pData->cs,
     589                                        szTemp,
     590                                        ((PCDATE)pColumnData)->year,
     591                                        ((PCDATE)pColumnData)->month,
     592                                        ((PCDATE)pColumnData)->day);
     593                                pcsz = szTemp;
     594                            break;
     595
     596                            case CFA_TIME:
     597                                nlsTime(&pData->cs,
     598                                        szTemp,
     599                                        ((PCTIME)pColumnData)->hours,
     600                                        ((PCTIME)pColumnData)->minutes,
     601                                        ((PCTIME)pColumnData)->seconds);
     602                                pcsz = szTemp;
     603                            break;
     604
     605                            case CFA_ULONG:
     606                                nlsThousandsULong(szTemp,
     607                                                  *((PULONG)pColumnData),
     608                                                  pData->cs.cs.cThousands);
     609                                pcsz = szTemp;
     610                            break;
     611                        }
     612
     613                        if (pcsz)
     614                            ctnrDrawString(hps,
     615                                          pcsz,
     616                                          &rcl,
     617                                          pfi->flData,
     618                                          &pData->fm);
     619
     620                        // if we're outside the paint rect now,
     621                        // we can quit
     622                        // _Pmpf(("rcl.yBottom: %d, rclClip.yBottom: %d",
     623                        //         rcl.yBottom,
     624                        //         rclClip.yBottom));
     625                        if (rclRecc.yBottom <= rclClip.yBottom)
     626                            break;
     627
     628                    } // if (!(prliThis->flRecordAttr & CRA_FILTERED))
     629
     630                    pRecNode = pRecNode->pNext;
     631
     632                } // while (pRecNode)
     633
     634                // paint vertical separators after this column?
     635                if (pfi->flData & CFA_SEPARATOR)
     636                {
     637                    POINTL  ptl;
     638                    GpiSetColor(hps, ctlQueryColor(&pData->dwdMain, CNRCOL_BORDER));
     639                    ptl.x = rcl.xRight + COLUMN_PADDING_X;
     640                    ptl.y = pData->dwdContent.szlWin.cy;
     641                    GpiMove(hps,
     642                            &ptl);
     643                    ptl.y = 0;
     644                    GpiLine(hps,
     645                            &ptl);
     646                }
     647
     648                fFirstCol = FALSE;
     649
     650                ++cColumn;
     651
     652                // we're done if this column is outside the
     653                // paint rectangle
     654                if (    (!(pCol->pfi->flData & CFA_INVISIBLE))
     655                     && (pCol->xLeft + pCol->cxContent - pData->scrw.ptlScrollOfs.x >= rclClip.xRight)
     656                   )
     657                    break; // while (pColNode)
     658
     659            } // if (!(pfi->flData & CFA_INVISIBLE))
     660
     661            pColNode = pColNode->pNext;
     662
     663        } // while (pColNode)
     664
     665        WinEndPaint(hps);
     666    }
     667}
     668
     669/*
     670 *@@ FindRecordFromMouseY:
     671 *
     672 */
     673
     674PRECORDLISTITEM FindRecordFromMouseY(PCNRDATA pData,
     675                                     SHORT y)
     676{
     677    // convert y clickpos from window to workspace coordinates
     678    LONG    deltaWorkspace =   (   pData->scrw.szlWorkarea.cy
     679                                 - pData->dwdContent.szlWin.cy)
     680                             - pData->scrw.ptlScrollOfs.y;
     681    LONG    yWorkspace =  (LONG)y + deltaWorkspace;
     682
     683    PLISTNODE pRecNode = lstQueryFirstNode(&pData->llRootRecords);
     684    while (pRecNode)
     685    {
     686        PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
     687
     688        if (!(prliThis->flRecordAttr & CRA_FILTERED))
     689        {
     690            if (prliThis->ptl.y < yWorkspace)
     691                return prliThis;
     692        }
     693
     694        pRecNode = pRecNode->pNext;
     695    }
     696
     697    return NULL;
     698}
     699
     700/*
     701 *@@ DeselectExcept:
     702 *
     703 */
     704
     705VOID DeselectExcept(PCNRDATA pData,
     706                    PRECORDLISTITEM prliMouse)
     707{
     708    // deselect all selected
     709    PLISTNODE pRecNode;
     710    pRecNode = lstQueryFirstNode(&pData->llRootRecords);
     711    while (pRecNode)
     712    {
     713        PRECORDLISTITEM prliThis = (PRECORDLISTITEM)pRecNode->pItemData;
     714
     715        if (    (prliThis != prliMouse)
     716             && (prliThis->flRecordAttr & CRA_SELECTED)
     717           )
     718        {
     719            ctnrChangeEmphasis(pData,
     720                               prliThis,
     721                               FALSE,
     722                               CRA_SELECTED);
     723        }
     724
     725        pRecNode = pRecNode->pNext;
     726    }
     727}
     728
     729/*
     730 *@@ DetailsSingleSelect:
     731 *      implementation for WM_SINGLESELECT in fnwpCnrDetails.
     732 */
     733
     734MRESULT DetailsSingleSelect(PCNRDATA pData,
     735                            SHORT y)
     736{
     737    if (pData)
     738    {
     739        BOOL    fCtrl = WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000;
     740        ULONG   ulSel = ctnrQuerySelMode(pData);
     741
     742        // find record under mouse
     743        PRECORDLISTITEM prliMouse = FindRecordFromMouseY(pData, y);
     744
     745        if (    (ulSel == CCS_SINGLESEL)
     746             || (!fCtrl)
     747           )
     748        {
     749            DeselectExcept(pData, prliMouse);
     750        }
     751
     752        if (prliMouse)      // can be null with click on whitespace
     753        {
     754            // when ctrl is pressed, toggle the state of
     755            // the record under the mouse; otherwise select it
     756            ctnrChangeEmphasis(pData,
     757                               prliMouse,
     758                               (!fCtrl) || (!(prliMouse->flRecordAttr & CRA_SELECTED)),
     759                               CRA_SELECTED | CRA_CURSORED);
     760        }
     761
     762        return (MRESULT)TRUE;
     763    }
     764
     765    return (MRESULT)FALSE;
     766}
     767
     768/*
     769 *@@ DetailsBeginSelect:
     770 *      implementation for WM_BEGINSELECT in fnwpCnrDetails.
     771 *
     772 */
     773
     774MRESULT DetailsBeginSelect(PCNRDATA pData,
     775                           SHORT y)
     776{
     777    if (pData)
     778    {
     779        BOOL    fCtrl = WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000;
     780        ULONG   ulSel = ctnrQuerySelMode(pData);
     781        PRECORDLISTITEM prliMouse;
     782
     783        // find record under mouse
     784        prliMouse
     785        = pData->prliSwipingFirst
     786        = FindRecordFromMouseY(pData, y);
     787
     788        if (    (ulSel == CCS_SINGLESEL)
     789             || (!fCtrl)
     790           )
     791        {
     792            DeselectExcept(pData, prliMouse );
     793        }
     794
     795        if (prliMouse )
     796        {
     797            // when ctrl is pressed, toggle the state of
     798            // the record under the mouse; otherwise select it;
     799            // perform this operation on all the records that
     800            // user swipes over (seems to be how pm cnr does it)
     801            pData->fSwipeTurnOn = (!fCtrl) || (!(prliMouse->flRecordAttr & CRA_SELECTED));
     802
     803            ctnrChangeEmphasis(pData,
     804                               prliMouse ,
     805                               pData->fSwipeTurnOn,
     806                               CRA_SELECTED | CRA_CURSORED);
     807            WinSetCapture(HWND_DESKTOP, pData->dwdContent.hwnd);
     808        }
     809
     810        return (MRESULT)TRUE;
     811    }
     812
     813    return (MRESULT)FALSE;
     814}
     815
     816/*
     817 *@@ DetailsMouseMove:
     818 *      implementation for WM_MOUSEMOVE in fnwpCnrDetails.
     819 */
     820
     821MRESULT DetailsMouseMove(PCNRDATA pData,
     822                         MPARAM mp1,
     823                         MPARAM mp2)
     824{
     825    if (pData)
     826    {
     827        if (pData->prliSwipingFirst)
     828        {
     829            // we're swiping:
     830            PRECORDLISTITEM prliThis;
     831            if (prliThis = FindRecordFromMouseY(pData,
     832                                                SHORT2FROMMP(mp1)))
     833                ctnrChangeEmphasis(pData,
     834                                   prliThis,
     835                                   pData->fSwipeTurnOn,
     836                                   CRA_SELECTED | CRA_CURSORED);
     837        }
     838
     839        return ctlDefWindowProc(&pData->dwdContent, WM_MOUSEMOVE, mp1, mp2);
     840    }
     841
     842    return (MRESULT)FALSE;
     843}
     844
     845/*
     846 *@@ DetailsEndSelect:
     847 *      implementation for WM_ENDSELECT in fnwpCnrDetails.
     848 */
     849
     850MRESULT DetailsEndSelect(PCNRDATA pData)
     851{
     852    if (pData)
     853    {
     854        if (pData->prliSwipingFirst)
     855        {
     856            WinSetCapture(HWND_DESKTOP, NULLHANDLE);
     857            pData->prliSwipingFirst = NULL;
     858        }
     859
     860        return (MRESULT)TRUE;
     861    }
     862
     863    return (MRESULT)FALSE;
     864}
     865
     866/*
     867 *@@ DetailsOpen:
     868 *      implementation for WM_OPEN in fnwpCnrDetails.
     869 */
     870
     871MRESULT DetailsOpen(PCNRDATA pData)
     872{
     873    if (pData)
     874    {
     875        ctnrRecordEnter(pData,
     876                        pData->prliCursored,
     877                        FALSE);     // mouse, not keyboard
     878
     879        return (MRESULT)TRUE;
     880    }
     881
     882    return (MRESULT)FALSE;
     883}
     884
     885/*
     886 *@@ ScrollToRecord:
     887 *      scrolls the content area so that the given record becomes
     888 *      visible.
     889 *
     890 +      If fMakeTop == TRUE, we scroll so that the top of the
     891 *      record's box is scrolled to the top of the window.
     892 *      Otherwise we scroll so that the bottom of the record's
     893 *      box is at the bottom of the rectangle.
     894 */
     895
     896VOID ScrollToRecord(PCNRDATA pData,
     897                    PRECORDLISTITEM prliThis,
     898                    BOOL fMakeTop,
     899                    BOOL fForce)        // in: if TRUE, we scroll even if the record is already visible
     900{
     901    RECTL   rcl;
     902    LONG    lNewY = -100;
     903
     904    ctnrGetRecordRect(pData, &rcl, prliThis);
     905    if (fMakeTop)
     906    {
     907        if (    (rcl.yTop > pData->dwdContent.szlWin.cy)
     908             || (fForce)
     909           )
     910        {
     911/*
     912ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   Ä¿
     913³                             ³    ³ pData->scrw.ptlScrollOfs.y
     914+-----------------------------+   ÄÙ
     915+-----------------------------+
     916º                             º
     917º                             º
     918ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ
     919³                             ³
     920ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
     921*/
     922            lNewY =   pData->scrw.szlWorkarea.cy
     923                    - (prliThis->ptl.y + prliThis->szlBox.cy);
     924        }
     925    }
     926    else if (    (rcl.yBottom < 0)
     927              || (fForce)
     928            )
     929    {
     930/*
     931ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   Ä¿
     932³                             ³    ³ pData->scrw.ptlScrollOfs.y
     933ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»    ³
     934º                             º    ³
     935+-----------------------------+    ³
     936+-----------------------------+   ÄÙ
     937³                             ³
     938ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
     939*/
     940        lNewY =   pData->scrw.szlWorkarea.cy
     941                - pData->dwdContent.szlWin.cy
     942                - prliThis->ptl.y;
     943    }
     944
     945    if (lNewY != -100)
     946    {
     947        POINTL  ptlScroll;
     948
     949        if (lNewY < 0)
     950            lNewY = 0;
     951        else if (lNewY >= pData->scrw.szlWorkarea.cy)
     952            lNewY = pData->scrw.szlWorkarea.cy - 1;
     953
     954        ptlScroll.x = 0;
     955        ptlScroll.y = lNewY - pData->scrw.ptlScrollOfs.y;
     956
     957        winhScrollWindow(pData->dwdContent.hwnd,
     958                         NULL,
     959                         &ptlScroll);
     960
     961        pData->scrw.ptlScrollOfs.y = lNewY;
     962
     963        WinPostMsg(pData->dwdMain.hwnd,
     964                   WM_SEM2,
     965                   (MPARAM)DDFL_WORKAREACHANGED,
     966                   0);
     967    }
     968}
     969
     970/*
     971 *@@ DetailsChar:
     972 *      implementation for WM_CHAR in fnwpCnrDetails.
     973 */
     974
     975MRESULT DetailsChar(PCNRDATA pData,
     976                    MPARAM mp1,
     977                    MPARAM mp2)
     978{
     979    if (pData)
     980    {
     981        USHORT      usFlags = SHORT1FROMMP(mp1);
     982        USHORT      usch    = SHORT1FROMMP(mp2);
     983        USHORT      usvk    = SHORT2FROMMP(mp2);
     984
     985        PRECORDLISTITEM prliThis;
     986        PLISTNODE   pNode;
     987        PRECORDLISTITEM prliScrollTo = NULL;
     988        BOOL        fMakeTop = FALSE,
     989                    fForce = FALSE;
     990
     991        if (usFlags & KC_VIRTUALKEY)
     992        {
     993            switch (usvk)
     994            {
     995                case VK_ENTER:
     996                case VK_NEWLINE:
     997                    if (!(usFlags & KC_KEYUP))
     998                        if (pData->prliCursored)
     999                            ctnrRecordEnter(pData,
     1000                                            pData->prliCursored,
     1001                                            TRUE);      // keyboard
     1002
     1003                    return (MRESULT)TRUE;
     1004
     1005                case VK_SPACE:
     1006                    if (!(usFlags & KC_KEYUP))
     1007                    {
     1008                        if (    (CCS_SINGLESEL != ctnrQuerySelMode(pData))
     1009                             && (prliThis = pData->prliCursored)
     1010                           )
     1011                        {
     1012                            if (prliThis->flRecordAttr & CRA_SELECTED)
     1013                                DeselectExcept(pData, NULL);
     1014                            else
     1015                                ctnrChangeEmphasis(pData,
     1016                                                   prliThis,
     1017                                                   TRUE,
     1018                                                   CRA_SELECTED);
     1019                        }
     1020                    }
     1021
     1022                    return (MRESULT)TRUE;
     1023
     1024                case VK_DOWN:
     1025                case VK_UP:
     1026                    if (!(usFlags & KC_KEYUP))
     1027                    {
     1028                        if (    (prliThis = pData->prliCursored)
     1029                             && (pNode = ctnrFindListNodeForRecc(pData, prliThis->precc))
     1030                           )
     1031                        {
     1032                            while (TRUE)
     1033                            {
     1034                                if (usvk == VK_UP)
     1035                                {
     1036                                    if (!(pNode = pNode->pPrevious))
     1037                                        break;
     1038                                }
     1039                                else
     1040                                    if (!(pNode = pNode->pNext))
     1041                                        break;
     1042
     1043                                prliThis = (PRECORDLISTITEM)pNode->pItemData;
     1044                                if (!(prliThis->flRecordAttr & CRA_FILTERED))
     1045                                {
     1046                                    prliScrollTo = prliThis;
     1047                                    fMakeTop = (usvk == VK_UP);
     1048                                    break;
     1049                                }
     1050                            }
     1051                        }
     1052                    }
     1053                break;
     1054
     1055                case VK_HOME:
     1056                case VK_END:
     1057                    if (!(usFlags & KC_KEYUP))
     1058                    {
     1059                        if (usvk == VK_HOME)
     1060                            pNode = lstQueryFirstNode(&pData->llRootRecords);
     1061                        else
     1062                            pNode = lstQueryLastNode(&pData->llRootRecords);
     1063
     1064                        while (pNode)
     1065                        {
     1066                            prliThis = (PRECORDLISTITEM)pNode->pItemData;
     1067                            if (!(prliThis->flRecordAttr & CRA_FILTERED))
     1068                            {
     1069                                prliScrollTo = prliThis;
     1070                                if (usvk == VK_HOME)
     1071                                    fMakeTop = TRUE;
     1072                                fForce = TRUE;
     1073                                break;
     1074                            }
     1075
     1076                            if (usvk == VK_HOME)
     1077                                pNode = pNode->pNext;
     1078                            else
     1079                                pNode = pNode->pPrevious;
     1080                        }
     1081                    }
     1082                break;
     1083
     1084                case VK_PAGEDOWN:
     1085                    if (!(usFlags & KC_KEYUP))
     1086                    {
     1087                        // find the bottommost record currently visible in the
     1088                        // viewport and make that one the topmost
     1089                        prliScrollTo = FindRecordFromMouseY(pData,
     1090                                                            0);     // window y
     1091                        fMakeTop = TRUE;
     1092                        fForce = TRUE;
     1093                    }
     1094                break;
     1095
     1096                case VK_PAGEUP:
     1097                    if (!(usFlags & KC_KEYUP))
     1098                    {
     1099                        // find the topmost record currently visible in the
     1100                        // viewport
     1101                        prliScrollTo = FindRecordFromMouseY(pData,
     1102                                                            pData->dwdContent.szlWin.cy);     // window y
     1103                            // @@todo this is slightly different from the pm cnr behavior
     1104                        fForce = TRUE;
     1105                    }
     1106                break;
    4011107            }
    4021108
    403             // paint vertical separators after this column?
    404             if (pfi->flData & CFA_SEPARATOR)
     1109            if (prliScrollTo)
    4051110            {
    406                 ptl.x = rcl.xRight + COLUMN_PADDING_X;
    407                 ptl.y = pData->dwdContent.szlWin.cy;
    408                 GpiMove(hps,
    409                         &ptl);
    410                 ptl.y = 0;
    411                 GpiLine(hps,
    412                         &ptl);
     1111                DeselectExcept(pData, prliScrollTo);
     1112
     1113                ctnrChangeEmphasis(pData,
     1114                                   prliScrollTo,
     1115                                   TRUE,
     1116                                   CRA_SELECTED | CRA_CURSORED);
     1117
     1118                // now make sure the new record is visible
     1119                // in the viewport
     1120                ScrollToRecord(pData,
     1121                               prliScrollTo,
     1122                               fMakeTop,
     1123                               fForce);
     1124
     1125                return (MRESULT)TRUE;
    4131126            }
    414 
    415             ++cColumn;
    416 
    417         } // FOR_ALL_NODES(&pData->llColumns, pColNode)
    418 
    419         WinEndPaint(hps);
    420     }
     1127        }
     1128    }
     1129
     1130    return (MRESULT)FALSE;
    4211131}
    4221132
     
    4341144MRESULT EXPENTRY fnwpCnrDetails(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
    4351145{
    436     MRESULT mrc = 0;
    437     PCNRDATA    pData;
     1146    MRESULT     mrc = 0;
     1147    PCNRDATA    pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1);
    4381148
    4391149    switch (msg)
    4401150    {
     1151        /* ******************************************************************
     1152         *
     1153         *   Standard window messages
     1154         *
     1155         ********************************************************************/
     1156
    4411157        case WM_CREATE:
    4421158            mrc = DetailsCreate(hwnd, mp1, mp2);
     
    4441160
    4451161        case WM_PAINT:
    446             DetailsPaint(hwnd);
     1162            DetailsPaint(pData);
    4471163        break;
    4481164
     1165        case WM_SYSCOLORCHANGE:
     1166            ctnrPresParamChanged(hwnd, 0);
     1167        break;
     1168
    4491169        case WM_PRESPARAMCHANGED:
    450             cnrPresParamChanged(hwnd, (ULONG)mp1);
     1170            ctnrPresParamChanged(hwnd, (ULONG)mp1);
    4511171        break;
    4521172
     1173        /* ******************************************************************
     1174         *
     1175         *   Mouse and keyboard input
     1176         *
     1177         ********************************************************************/
     1178
     1179        case WM_MOUSEMOVE:
     1180            mrc = DetailsMouseMove(pData,
     1181                                   mp1,
     1182                                   mp2);
     1183        break;
     1184
     1185        case WM_BUTTON1DOWN:
     1186        case WM_BUTTON2DOWN:
     1187        case WM_BUTTON3DOWN:
     1188            WinSetFocus(HWND_DESKTOP, pData->dwdContent.hwnd);
     1189            mrc = (MPARAM)TRUE;
     1190        break;
     1191
     1192        case WM_SINGLESELECT:
     1193            mrc = DetailsSingleSelect(pData,
     1194                                      SHORT2FROMMP(mp1));       // we only need y in details view
     1195        break;
     1196
     1197        case WM_BEGINSELECT:
     1198            mrc = DetailsBeginSelect(pData,
     1199                                     SHORT2FROMMP(mp1));
     1200        break;
     1201
     1202        case WM_ENDSELECT:
     1203            mrc = DetailsEndSelect(pData);
     1204        break;
     1205
     1206        case WM_OPEN:
     1207            mrc = DetailsOpen(pData);
     1208        break;
     1209
     1210        case WM_CHAR:
     1211            mrc = DetailsChar(pData, mp1, mp2);
     1212        break;
     1213
     1214        /* ******************************************************************
     1215         *
     1216         *   Direct manipulation
     1217         *
     1218         ********************************************************************/
     1219
     1220        case DM_DRAGOVER:
     1221        case DM_DRAGLEAVE:
     1222        case DM_DROPNOTIFY:
     1223        case DM_DROP:
     1224        case DM_DROPHELP:
     1225
    4531226        default:
    454             if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))
     1227            if (pData)
    4551228                mrc = ctlDefWindowProc(&pData->dwdContent, msg, mp1, mp2);
    4561229        break;
    457 
    4581230    }
    4591231
  • trunk/src/helpers/cctl_toolbar.c

    r242 r243  
    186186    LONG    lLeft,
    187187            lRight,
    188             lColorMiddle = pbd->dwd.lcolBackground;
     188            lColorMiddle = ctlQueryColor(&pbd->dwd, CTLCOL_BGND); // pbd->dwd.lcolBackground;
    189189    RECTL   rclWin,
    190190            rclTemp;
     
    344344       )
    345345    {
    346         GpiSetColor(hps, pbd->dwd.lcolForeground);
     346        GpiSetColor(hps,
     347                    ctlQueryColor(&pbd->dwd, CTLCOL_FGND)); // pbd->dwd.lcolForeground);
    347348        rclTemp.yTop -= 2 * TBB_TEXTSPACING + lOfs;
    348349        rclTemp.xRight += 2 * lOfs;     // twice the offset because we center horizontally
     
    354355}
    355356
    356 static const SYSCOLORSET G_scsToolbarButton =
     357/* static const SYSCOLORSET G_scsToolbarButton =
    357358    {
    358359        TRUE,       // inherit presparams
     
    360361        SYSCLR_BUTTONMIDDLE,
    361362        SYSCLR_MENUTEXT
     363    };
     364*/
     365
     366static const CCTLCOLOR G_scsToolbarButton[] =
     367    {
     368        TRUE, PP_BACKGROUNDCOLOR, SYSCLR_BUTTONMIDDLE,
     369        TRUE, PP_FOREGROUNDCOLOR, SYSCLR_MENUTEXT,
    362370    };
    363371
     
    445453                   &pData->bd.dwd,
    446454                   WinDefWindowProc,
    447                    &G_scsToolbarButton);
     455                   0,
     456                   G_scsToolbarButton,
     457                   ARRAYITEMCOUNT(G_scsToolbarButton));
    448458
    449459        if (    (pcszText)
     
    851861 ********************************************************************/
    852862
    853 static const SYSCOLORSET G_scsToolbar =
    854     {
    855         TRUE,       // inherit presparams
    856         SYSCLR_MENU,
    857         SYSCLR_MENUTEXT
     863static const CCTLCOLOR G_scsToolbar[] =
     864    {
     865        TRUE, PP_BACKGROUNDCOLOR, SYSCLR_MENU,
     866        TRUE, PP_FOREGROUNDCOLOR, SYSCLR_MENUTEXT
    858867    };
    859868
     
    10171026                           (PVOID)pcszFont);
    10181027
    1019         lColor = winhQueryPresColor2(pData->dwd.hwnd,
    1020                                      PP_BACKGROUNDCOLOR,
    1021                                      PP_BACKGROUNDCOLORINDEX,
    1022                                      FALSE,
    1023                                      G_scsToolbar.lBackIndex);
     1028        lColor = ctlQueryColor(&pData->dwd, CTLCOL_BGND);
    10241029        winhStorePresParam(&ppp,
    10251030                           PP_BACKGROUNDCOLOR,
     
    10271032                           &lColor);
    10281033
    1029         lColor = winhQueryPresColor2(pData->dwd.hwnd,
    1030                                      PP_FOREGROUNDCOLOR,
    1031                                      PP_FOREGROUNDCOLORINDEX,
    1032                                      FALSE,
    1033                                      G_scsToolbar.lForeIndex);
     1034        lColor = ctlQueryColor(&pData->dwd, CTLCOL_FGND);
    10341035        winhStorePresParam(&ppp,
    10351036                           PP_FOREGROUNDCOLOR,
     
    11121113               &pData->dwd,
    11131114               WinDefWindowProc,
    1114                &G_scsToolbar);
     1115               0,
     1116               G_scsToolbar,
     1117               ARRAYITEMCOUNT(G_scsToolbar));
    11151118
    11161119    pData->hwndControlsOwner = ptbcd->hwndControlsOwner;
  • trunk/src/helpers/comctl.c

    r242 r243  
    178178 *      given window. This must be called in WM_CREATE
    179179 *      of a window proc if it intends to use
    180  *      ctlDefWindowProc as its default window procedure.
     180 *      ctlDefWindowProc as its default window procedure
     181 *      for generic message handling.
     182 *
     183 *      Parameter remarks:
     184 *
     185 *      --  For hwnd and mp2, pass in what you get in WM_CREATE.
     186 *
     187 *      --  pdwd must point to a static DEFWINDATA which will
     188 *          maintain instance data for this control. It is
     189 *          recommended to have a DEFWINDATA struct in your
     190 *          window's instance data, which you must allocate
     191 *          in WM_CREATE anyway. So just pass the address of
     192 *          that struct within your instance buffer.
     193 *
     194 *      --  pDefWindowProc is called by ctlDefWindowProc
     195 *          after its own message processing. In most cases,
     196 *          pass in WinDefWindowProc, unless you're superclassing
     197 *          a standard PM control.
     198 *
     199 *      --  flCtl fine-tunes the behavior of ctlDefWindowProc:
     200 *
     201 *          --  If CCS_NOSENDCTLPTR, we do not send WM_CONTROLPOINTER
     202 *              on every mouse move, but force the system "arrow"
     203 *              pointer over the control.
     204 *
     205 *      --  paCtlColors must point to a CCTLCOLOR array. This
     206 *          enables automatic presparams and syscolor caching
     207 *          within ctlDefWindowProc so your window gets invalidated
     208 *          automatically. If you always use ctlQueryColor() in your
     209 *          WM_PAINT handler to determine the colors to be used for
     210 *          painting, you have full presparams support.
    181211 *
    182212 *@@added V1.0.1 (2002-11-30) [umoeller]
     
    184214
    185215VOID ctlInitDWD(HWND hwnd,
    186                 MPARAM mp2,
     216                MPARAM mp2,                     // in: mp2 of WM_CREATE
    187217                PDEFWINDATA pdwd,
    188                 PFNWP pDefWindowProc,
    189                 const SYSCOLORSET *pSysColorSet)
     218                PFNWP pDefWindowProc,           // in: parent window proc
     219                ULONG flCtl,                    // in: CTL_* flags
     220                const CCTLCOLOR *paCtlColors,
     221                ULONG cCtlColors)
    190222{
    191223    pdwd->hwnd = hwnd;
     224    pdwd->hab = WinQueryAnchorBlock(hwnd);
     225    pdwd->pDefWindowProc = pDefWindowProc;
     226    pdwd->flCtl = flCtl;
    192227    pdwd->szlWin.cx = ((PCREATESTRUCT)mp2)->cx;
    193228    pdwd->szlWin.cy = ((PCREATESTRUCT)mp2)->cy;
    194     pdwd->hab = WinQueryAnchorBlock(hwnd);
    195     pdwd->pDefWindowProc = pDefWindowProc;
    196     pdwd->pSysColorSet = pSysColorSet;
     229    pdwd->paCtlColors = paCtlColors;
     230    pdwd->cCtlColors = cCtlColors;
     231
     232    pdwd->palColorValues = (PLONG)malloc(sizeof(LONG) * cCtlColors);
    197233
    198234    ctlRefreshColors(pdwd);
     
    207243VOID ctlRefreshColors(PDEFWINDATA pdwd)
    208244{
    209     pdwd->lcolBackground = winhQueryPresColor2(pdwd->hwnd,
    210                                                PP_BACKGROUNDCOLOR,
    211                                                PP_BACKGROUNDCOLORINDEX,
    212                                                pdwd->pSysColorSet->fInheritPP,
    213                                                pdwd->pSysColorSet->lBackIndex);
    214     pdwd->lcolForeground = winhQueryPresColor2(pdwd->hwnd,
    215                                                PP_FOREGROUNDCOLOR,
    216                                                PP_FOREGROUNDCOLORINDEX,
    217                                                pdwd->pSysColorSet->fInheritPP,
    218                                                pdwd->pSysColorSet->lForeIndex);
     245    ULONG   ul;
     246    for (ul = 0;
     247         ul < pdwd->cCtlColors;
     248         ++ul)
     249    {
     250        pdwd->palColorValues[ul] = winhQueryPresColor2(pdwd->hwnd,
     251                                                       pdwd->paCtlColors[ul].ulPP,
     252                                                       0,
     253                                                       pdwd->paCtlColors[ul].fInheritPP,
     254                                                       pdwd->paCtlColors[ul].ulSysColor);
     255    }
     256}
     257
     258/*
     259 *@@ ctlQueryColor:
     260 *      returns the color value corresponding to the given
     261 *      color index. The color index is interpreted according
     262 *      to the CCTLCOLOR array that was given to ctlInitDWD
     263 *      and must not be larger than the number of colors in
     264 *      that array minus 1.
     265 *
     266 *@@added V1.0.1 (2003-01-22) [umoeller]
     267 */
     268
     269LONG ctlQueryColor(PDEFWINDATA pdwd, ULONG ulIndex)
     270{
     271    if (ulIndex < pdwd->cCtlColors)
     272        return pdwd->palColorValues[ulIndex];
     273
     274    return 0;
    219275}
    220276
     
    238294{
    239295    MRESULT mrc = 0;
     296    BOOL    fCallDefault = TRUE;
     297    HWND    hwndOwner;
    240298
    241299    switch (msg)
    242300    {
     301        case WM_MOUSEMOVE:
     302            if (    (!(pdwd->flCtl & CCS_NOSENDCTLPTR))
     303                 && (hwndOwner = WinQueryWindow(pdwd->hwnd, QW_OWNER))
     304               )
     305            {
     306                HPOINTER hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
     307                WinSetPointer(HWND_DESKTOP,
     308                              (HPOINTER)WinSendMsg(hwndOwner,
     309                                                   WM_CONTROLPOINTER,
     310                                                   (MPARAM)WinQueryWindowUShort(pdwd->hwnd, QWS_ID),
     311                                                   (MPARAM)hptrArrow));
     312                fCallDefault = FALSE;
     313            }
     314        break;
     315
    243316        case WM_SYSCOLORCHANGE:
    244317        case WM_PRESPARAMCHANGED:
     
    258331        break;
    259332
    260         default:
    261             mrc = pdwd->pDefWindowProc(pdwd->hwnd, msg, mp1, mp2);
     333        case WM_DESTROY:
     334            FREE(pdwd->palColorValues);
     335        break;
    262336    }
     337
     338    if (fCallDefault)
     339        mrc = pdwd->pDefWindowProc(pdwd->hwnd, msg, mp1, mp2);
    263340
    264341    return mrc;
  • trunk/src/helpers/dosh.c

    r241 r243  
    32703270
    32713271/*
     3272 *@@ doshCreateLogFilename:
     3273 *      produces a log filename in pszBuf.
     3274 *      If $(LOGFILES) is set, that directory
     3275 *      is used; otherwise we use the root
     3276 *      directory of the boot drive.
     3277 *
     3278 *@@added V1.0.1 (2003-01-25) [umoeller]
     3279 */
     3280
     3281BOOL doshCreateLogFilename(PSZ pszBuf,             // out: fully qualified filename
     3282                           PCSZ pcszFilename,      // in: short log filename
     3283                           BOOL fAllowBootDrive)   // in: allow creating log files on boot drive?
     3284{
     3285    CHAR    szBoot[] = "?:";
     3286    PSZ     pszLogDir;
     3287    if (DosScanEnv("LOGFILES",      // new eCS 1.1 setting
     3288                   &pszLogDir))
     3289    {
     3290        // variable not set:
     3291        if (!fAllowBootDrive)
     3292            return FALSE;
     3293
     3294        szBoot[0] = doshQueryBootDrive();
     3295        pszLogDir = szBoot;
     3296    }
     3297
     3298    sprintf(pszBuf,
     3299            "%s\\%s",
     3300            pszLogDir,
     3301            pcszFilename);
     3302
     3303    return TRUE;
     3304}
     3305
     3306/*
    32723307 *@@ doshCreateBackupFileName:
    32733308 *      creates a valid backup filename of pszExisting
  • trunk/src/helpers/gpih.c

    r242 r243  
    737737    {
    738738        ULONG cLines = strhCount(pcsz, '\n') + 1;
    739         cyString = cLines * (pfm->lMaxBaselineExt + pfm->lExternalLeading);
     739        cyString = cLines * (pfm->lMaxBaselineExt + pfm->lMaxDescender + pfm->lExternalLeading);
    740740
    741741        if (fl & DT_VCENTER)
    742             ptlRun.y += (cyRect - cyString) / 2;
     742            ptlRun.y = (cyRect - cyString) / 2;
    743743        else
    744             ptlRun.y += cyRect - cyString;
     744            ptlRun.y = cyString;
    745745    }
    746746
     
    789789        ptlRun.y -= pfm->lExternalLeading;
    790790
     791        if (!*pNext)
     792            break;
     793
    791794        if (*pNext == '\r')
    792795            pNext++;
    793         pThis = pNext;
     796        pThis = ++pNext;
    794797    }
    795798}
     
    25532556LONG gpihStretchBitmap(HPS hpsTarget,       // in: memory PS to copy bitmap to
    25542557                       HBITMAP hbmSource,   // in: bitmap to be copied into hpsTarget (must be free)
    2555                        PRECTL prclSource,   // in: source rectangle -- if NULL, use size of bitmap
    2556                        PRECTL prclTarget,   // in: target rectangle (req.)
     2558                       PRECTL prclSource,   // in: source rectangle -- if NULL, use size of source bmp
     2559                       PRECTL prclTarget,   // in: target rectangle (required)
    25572560                       BOOL fProportional)  // in: preserve proportions when stretching?
    25582561{
  • trunk/src/helpers/helpers_post.in

    r196 r243  
    11#
    2 #   Post-Include file for the main helpers makefile.
    3 #   This contains inference rules for the files.
     2#   Post-include file for the main helpers makefile.
    43#
    5 
    6 # Now define inference rules for what to do with certain file
    7 # types, based on their file extension.
    8 # The syntax we need here is ".fromext.toext".
    9 # So whenever NMAKE encounters a .toext file, it
    10 # executes what we specify here.
    11 # The ugly {} brackets are some awkward syntax for specifying
    12 # files in other directories.
    13 
    14 # Special macros used here: $(@B) is the current target w/out ext.
    15 
    16 # -- compile C files to .OBJ files, using the CC_HELPPERS macro
    17 #    given to us.
    18 #    The output will be placed in the directory specified by
    19 #    the OUTPUTDIR variable (set above).
    20 
    21 .c.{$(OUTPUTDIR)}.obj:
    22     @echo $(MAKEDIR)\makefile: Compiling $(@B).c
    23 !ifdef EMX
    24     $(CC_HELPERS) -o $(OUTPUTDIR)\$(@B).obj $(@B).c
    25 !else
    26 !ifndef PRECH
    27     $(CC_HELPERS) /Fo$(OUTPUTDIR)\$(@B).obj $(@B).c
    28 !else
    29     $(CC_HELPERS) /fi"$(PRECH)\$(@B).pch" /si"$(PRECH)\$(@B).pch" /Fo$(OUTPUTDIR)\$(@B).obj $(@B).c
    30 !endif
    31 !endif
    32 
    33 $(OUTPUTDIR)\interlock.obj: $(@B).asm
    34     @echo $(MAKEDIR)\makefile: Assembling $(@B).asm
    35     alp -Sv:ALP -Fdo:$(OUTPUTDIR) $(@B).asm
     4#   This is shared between makefile and makefile_dll
     5#   and contains inference rules for the files.
     6#
    367
    378# The .OBJ-from-sources dependencies are now automatically
     
    4314!endif
    4415
     16$(OUTPUTDIR)\interlock.obj: $(@B).asm
    4517
    46 
  • trunk/src/helpers/helpers_pre.in

    r242 r243  
    11#
    22#   Pre-include file for the main helpers makefile.
    3 #   This contains shared definitions and all the objects
    4 #   that have to be built.
    53#
    6 
    7 !ifndef PROJECT_BASE_DIR
    8 !error in $(MAKEDIR)\makefile: PROJECT_BASE_DIR must be set before calling the HELPERS makefile. Terminating.
    9 !endif
    10 
    11 !if [@echo     $(MAKEDIR)\makefile: PROJECT_BASE_DIR is: $(PROJECT_BASE_DIR)]
    12 !endif
    13 
    14 # include setup (compiler options etc.)
    15 !include $(PROJECT_BASE_DIR)\config.in
    16 !include $(PROJECT_BASE_DIR)\make\setup.in
    17 
    18 !ifndef HELPERS_OUTPUT_DIR
    19 !error in $(MAKEDIR)\makefile: HELPERS_OUTPUT_DIR must be set before calling the HELPERS makefile. Terminating.
    20 !endif
    21 
    22 # Define the suffixes for files which NMAKE will work on.
    23 # .SUFFIXES is a reserved NMAKE keyword ("pseudotarget") for
    24 # defining file extensions that NMAKE will recognize in inference
    25 # rules.
    26 .SUFFIXES: .c .h .ih .obj .lib .dll
    27 
    28 # OUTPUTDIR specifies the directory where we will put the
    29 # files created by this makefile.
    30 OUTPUTDIR = $(HELPERS_OUTPUT_DIR)
    31 
    32 !if [@echo     $(MAKEDIR)\makefile: helpers OBJs will be written to $(OUTPUTDIR)]
    33 !endif
    34 
    35 !if [@md $(OUTPUTDIR) 2> NUL]
    36 !endif
     4#   This is shared between makefile and makefile_dll
     5#   and defines all the objects that have to be built.
     6#
    377
    388# The OBJS macro contains all the .OBJ files which need to be
     
    10171$(OUTPUTDIR)\memdebug.obj\
    10272$(OUTPUTDIR)\memdebug_win.obj\
     73$(OUTPUTDIR)\mmpmh.obj\
    10374$(OUTPUTDIR)\shapewin.obj\
    10475$(OUTPUTDIR)\threads.obj\
     
    10879$(OUTPUTDIR)\winh.obj
    10980
    110 # helpers include path
    111 INC = ..\..\include
    112 HLPINC = $(INC)\helpers
    113 
    114 PROJECTINC = $(PROJECT_BASE_DIR)\include
  • trunk/src/helpers/interlock.asm

    r196 r243  
    1919CODE32         SEGMENT DWORD PUBLIC USE32 'CODE'
    2020
    21 ;* LONG DosInterlockedIncrement(PLONG);
     21;* LONG lockIncrement(PLONG);
    2222;*
    2323;* InterlockedIncrement adds 1 to a long variable and returns
     
    2828;* The returned number need not be equal to the result!!!!
    2929
    30 public  DosInterlockedIncrement
    31 DosInterlockedIncrement proc near
     30public  lockIncrement
     31lockIncrement proc near
    3232        ;we are allowed to trash edx
    3333        mov     edx, dword ptr [esp+4] ; LPLONG lpAddend
     
    3636        inc     eax
    3737        ret     4
    38 DosInterlockedIncrement endp
     38lockIncrement endp
    3939
    40 ;* LONG DosInterlockedDecrement(PLONG);
     40;* LONG lockDecrement(PLONG);
    4141;*
    4242;* InterlockedIncrement adds 1 to a long variable and returns
     
    4747;* The returned number need not be equal to the result!!!!
    4848
    49 public  DosInterlockedDecrement
    50 DosInterlockedDecrement proc near
     49public  lockDecrement
     50lockDecrement proc near
    5151        ;we are allowed to trash edx
    5252        mov     edx, dword ptr [esp+4] ; LPLONG lpAddend
     
    5555        dec     eax
    5656        ret     4
    57 DosInterlockedDecrement endp
     57lockDecrement endp
    5858
    5959
    60 ; * LONG DosInterlockedExchange(PLONG, LONG);
     60; * LONG lockExchange(PLONG, LONG);
    6161; *
    6262; * Atomically exchanges a pair of values.
     
    6565; * Prior value of value pointed to by Target
    6666
    67 public  DosInterlockedExchange
    68 DosInterlockedExchange proc near
     67public  lockExchange
     68lockExchange proc near
    6969        push    edx
    7070        mov     eax, [esp+12]           ; LONG value
     
    7373        pop     edx
    7474        ret     8
    75 DosInterlockedExchange endp
     75lockExchange endp
    7676
    7777
    7878;/************************************************************************
    79 ; * LONG DosInterlockedCompareExchange(PLONG dest, LONG xchg, LONG compare)
     79; * LONG lockCompareExchange(PLONG dest, LONG xchg, LONG compare)
    8080; *
    8181; * Atomically compares Destination and Comperand, and if found equal exchanges
     
    8484; */
    8585
    86 public DosInterlockedCompareExchange
    87 DosInterlockedCompareExchange proc near
     86public lockCompareExchange
     87lockCompareExchange proc near
    8888        push    ebp
    8989        mov     ebp, esp
     
    100100        pop     ebp
    101101        ret     12
    102 DosInterlockedCompareExchange endp
     102lockCompareExchange endp
    103103
    104 ; * LONG DosInterlockedExchangeAdd(PLONG dest, LONG incr);
     104; * LONG lockExchangeAdd(PLONG dest, LONG incr);
    105105; *
    106106; * Atomically adds Increment to Addend and returns the previous value of
     
    111111; */
    112112
    113 public DosInterlockedExchangeAdd
    114 DosInterlockedExchangeAdd proc near
     113public lockExchangeAdd
     114lockExchangeAdd proc near
    115115        push    edx
    116116        mov     eax, dword ptr [esp+12] ;LONG Increment /* Value to add */
     
    119119        pop     edx
    120120        ret     8
    121 DosInterlockedExchangeAdd endp
     121lockExchangeAdd endp
    122122
    123123CODE32          ENDS
  • trunk/src/helpers/makefile

    r242 r243  
    1 # $Id$
    2 
    31#
    42# makefile:
     
    97#       This makefile is even more complicated than the other makefiles
    108#       because the helpers code has been designed to be independent
    11 #       of any single project. For example, the helpers code is used
    12 #       by XWorkplace also. As a result, I had to design a way so that
     9#       of any single project. Presently the helpers code is used in
     10#       XWorkplace and WarpIN. As a result, I had to design a way so that
    1311#       this makefile can produce output in a variable directory, with
    1412#       variable compiler flags, and so on. This is done via environment
    15 #       variables (see below).
     13#       variables passed in from the "parent" makefile of a specific
     14#       project.
    1615#
    1716#       Even worse, with V0.9.5, I chose to create a shared runtime DLL
     
    8584#
    8685
    87 # Say hello to yourself.
    88 !if [@echo +++++ Entering $(MAKEDIR)\makefile]
    89 !endif
    90 
    91 # helpers_pre.in: sets up more environment variables
    92 # and defines $(OBJ), which contains all object targets
     86# set up shared environment variables
     87!include ..\..\make\helpers.in
     88# define $(OBJ), which contains all object targets
    9389!include helpers_pre.in
    9490
     
    194190TESTCASE_DIR = testcase
    195191
    196 DEBUGDIALOG =
     192!undef DEBUGDIALOG
    197193!ifdef DBGDLG
    198194DEBUGDIALOG = /DDEBUG_DIALOG_WINDOWS=1
    199195!endif
    200196
    201 TESTCASE_CC = icc /c /ti+ /w2 /ss /se /D__DEBUG__=1 $(DEBUGDIALOG) /i$(HELPERS_BASE)\include /Fo$(TESTCASE_DIR)\$(@B).obj $(@B).c
     197TESTCASE_CC_BASE = icc /c /ti+ /w2 /ss /se /D__DEBUG__=1 $(DEBUGDIALOG) /i..\..\include
     198
     199TESTCASE_CC = $(TESTCASE_CC_BASE) /Fo$(TESTCASE_DIR)\$(@B).obj  $(@B).c
    202200
    203201.c.{$(TESTCASE_DIR)}.obj:
     
    212210    exeh.exe \
    213211    fdlg.exe \
     212    fdlg_pm.exe \
    214213    xmap.exe \
    215214    vcard.exe
     
    265264
    266265# fdlg.exe
    267 FDLG_TEST_OBJS = \
     266FDLG_TEST_OBJS_SHARED = \
    268267    $(TESTCASE_DIR)\comctl.obj \
    269268    $(TESTCASE_DIR)\cctl_cnr.obj \
     
    282281    $(TESTCASE_DIR)\tree.obj \
    283282    $(TESTCASE_DIR)\nls.obj \
    284     $(TESTCASE_DIR)\nlscache.obj \
     283    $(TESTCASE_DIR)\nlscache.obj
     284
     285FDLG_TEST_OBJS = \
     286    $(FDLG_TEST_OBJS_SHARED) \
    285287    $(TESTCASE_DIR)\_call_filedlg.obj
    286288
    287 fdlg.exe: $(FDLG_TEST_OBJS)
    288     ilink /debug /pmtype:pm $(FDLG_TEST_OBJS) pmprintf.lib /o:$@
     289$(TESTCASE_DIR)\_call_filedlg_pm.obj: _call_filedlg.c
     290    @echo $(MAKEDIR)\makefile: Compiling $(@B).c (PM version)
     291    @echo INCLUDE is $(INCLUDE)
     292    $(TESTCASE_CC_BASE) /D__USE_PM_CNR__=1 /Fo$(TESTCASE_DIR)\_call_filedlg_pm.obj _call_filedlg.c
     293
     294FDLG_TEST_OBJS_PM = \
     295    $(FDLG_TEST_OBJS_SHARED) \
     296    $(TESTCASE_DIR)\_call_filedlg_pm.obj
     297
     298fdlg.exe: $(FDLG_TEST_OBJS) makefile
     299    @echo $(MAKEDIR)\makefile: Linking $@
     300    ilink /nologo /debug /pmtype:pm $(FDLG_TEST_OBJS) pmprintf.lib /o:$@
     301
     302fdlg_pm.exe: $(FDLG_TEST_OBJS_PM) makefile
     303    @echo $(MAKEDIR)\makefile: Linking $@ (PM version)
     304    ilink /nologo /debug /pmtype:pm $(FDLG_TEST_OBJS_PM) pmprintf.lib /o:$@
    289305
    290306# xmap.exe
  • trunk/src/helpers/makefile_dll

    r9 r243  
    2121!endif
    2222
     23# set up shared environment variables
     24!include ..\..\make\helpers.in
     25# define $(OBJ), which contains all object targets
    2326!include helpers_pre.in
    2427
  • trunk/src/helpers/nls.c

    r242 r243  
    657657        break;
    658658
    659         case 2: // yyyy.mm.dd  (Japanese)
     659        case 2: // yyyy.mm.dd  (ISO and Japanese)
    660660            sprintf(pszDate, "%04d%c%02d%c%02d",
    661661                    year,
     
    849849
    850850    for (ul = 0;
    851          ul < sizeof(G_szUpperMap);
     851         ul < 256;
    852852         ++ul)
    853853    {
     
    901901{
    902902    ULONG   ul = 0;
     903    PSZ     p;
    903904
    904905    if (!G_fUpperMapInited)
    905906        InitUpperMap();
    906907
    907     if (psz)
    908     {
    909         PSZ     p = psz;
    910 
     908    if (p = psz)
     909    {
    911910        while (*p++ = G_szUpperMap[*p])
    912911            ++ul;
  • trunk/src/helpers/nlscache.c

    r236 r243  
    66 *
    77 *      Function prefixes (new with V0.81):
    8  *      --  stc*
     8 *      --  nls*
    99 *
    1010 *      This file is new with V0.9.19, but contains functions
  • trunk/src/helpers/sem.c

    r196 r243  
    22/*
    33 *@@sourcefile sem.c:
    4  *      implements fast mutex semaphores a la Win32
    5  *      critical sections.
    6  *
    7  *      This is an OS/2 implementation of what Win32 calls as
    8  *      "critical sections"
    9  *      It is an implementation that is highly optimized for
     4 *      implements fast mutex semaphores.
     5 *
     6 *      This is an OS/2 implementation of what Win32 calls
     7 *      "critical sections". This is highly optimized for
    108 *      the case where there is only one thread trying to
    119 *      access the critical section, i.e. it is available most
     
    194192    // do an atomic increase of the lockcounter and see if it is > 0
    195193    // (i.e. it is already posessed)
    196     if (DosInterlockedIncrement(&pmtx->LockCount))
     194    if (lockIncrement(&pmtx->LockCount))
    197195    {
    198196        // semaphore was already requested:
     
    206204        }
    207205
    208         // current owner is different thread thread:
     206        // current owner is different thread:
    209207
    210208        // do an atomic operation where we compare the owning thread id with 0
    211209        // and if this is true, exchange it with the id of the current thread
    212         if (DosInterlockedCompareExchange((PLONG)&pmtx->OwningThread, threadid, 0))
     210        if (lockCompareExchange((PLONG)&pmtx->OwningThread, threadid, 0))
    213211        {
    214212            // the compare did not return equal, i.e. the pmtx sect is in use
     
    257255BOOL semTry(PFASTMTX pmtx)
    258256{
    259     if (DosInterlockedIncrement(&pmtx->LockCount))
     257    if (lockIncrement(&pmtx->LockCount))
    260258    {
    261259        if (pmtx->OwningThread == GetTID())
     
    265263        }
    266264
    267         DosInterlockedDecrement(&pmtx->LockCount);
     265        lockDecrement(&pmtx->LockCount);
    268266
    269267        return FALSE;
     
    291289    if (--pmtx->RecursionCount)
    292290    {
    293         DosInterlockedDecrement(&pmtx->LockCount );
     291        lockDecrement(&pmtx->LockCount );
    294292        return NO_ERROR;
    295293    }
     
    297295    pmtx->OwningThread = 0;
    298296
    299     if (DosInterlockedDecrement(&pmtx->LockCount) >= 0)
     297    if (lockDecrement(&pmtx->LockCount) >= 0)
    300298        // someone is waiting
    301299        DosPostEventSem(pmtx->hmtxLock);
  • trunk/src/helpers/textview.c

    r242 r243  
    15221522                                       // can be NULL to paint all
    15231523                  LONG lViewXOfs,      // in: x offset to paint; 0 means rightmost
    1524                   PULONG pulViewYOfs,  // in: y offset to paint; 0 means _top_most;
     1524                  PLONG plViewYOfs,    // in: y offset to paint; 0 means _top_most;
    15251525                                       // out: y offset which should be passed to next call
    15261526                                       // (if TRUE is returned and fPaintHalfLines == FALSE)
     
    15341534            fAnyLinesPainted = FALSE;
    15351535    ULONG   ulCurrentLineIndex = *pulLineIndex;
    1536     // LONG    lViewYOfsSaved = *pulViewYOfs;
     1536    // LONG    lViewYOfsSaved = *plViewYOfs;
    15371537    PLISTNODE pRectNode = lstNodeFromIndex(&pxfd->llRectangles,
    15381538                                           ulCurrentLineIndex);
     
    15501550        rclLine.xLeft = pLineRcl->rcl.xLeft - lViewXOfs;
    15511551        rclLine.xRight = pLineRcl->rcl.xRight - lViewXOfs;
    1552         rclLine.yBottom = pLineRcl->rcl.yBottom + *pulViewYOfs;
    1553         rclLine.yTop = pLineRcl->rcl.yTop + *pulViewYOfs;
     1552        rclLine.yBottom = pLineRcl->rcl.yBottom + *plViewYOfs;
     1553        rclLine.yTop = pLineRcl->rcl.yTop + *plViewYOfs;
    15541554
    15551555        /* if (pmpf)
     
    17111711                    // return TRUE
    17121712                    brc = TRUE;
    1713                     // and set *pulViewYOfs to the top of
     1713                    // and set *plViewYOfs to the top of
    17141714                    // the next line, which wasn't visible
    17151715                    // on the page any more
    1716                     *pulViewYOfs = pLineRcl2->rcl.yTop + *pulViewYOfs;
     1716                    *plViewYOfs = pLineRcl2->rcl.yTop + *plViewYOfs;
    17171717                }
    17181718                break;
     
    18671867    XFORMATDATA xfd;
    18681868
    1869     HWND    hwndVScroll,        // vertical scroll bar
    1870             hwndHScroll;        // horizontal scroll bar
     1869    SCROLLABLEWINDOW scrw;      // V1.0.1 (2003-01-25) [umoeller]
     1870
     1871//     HWND    hwndVScroll,        // vertical scroll bar
     1872//             hwndHScroll;        // horizontal scroll bar
    18711873
    18721874    BOOL    fVScrollVisible,    // TRUE if vscroll is currently used
     
    18781880            rclViewText;        // same as rclViewPaint, but excluding cdata borders
    18791881
    1880     ULONG   ulViewXOfs,         // pixels that we have scrolled to the RIGHT; 0 means very left
    1881             ulViewYOfs;         // pixels that we have scrolled to the BOTTOM; 0 means very top
     1882//     LONG    lViewXOfs,          // pixels that we have scrolled to the RIGHT; 0 means very left
     1883//             lViewYOfs;          // pixels that we have scrolled to the BOTTOM; 0 means very top
    18821884
    18831885    BOOL    fAcceptsPresParamsNow; // TRUE after first WM_PAINT
     
    19931995        if (ptxvd->fHScrollVisible)
    19941996            ulOfs = ulScrollCX;
    1995         WinSetWindowPos(ptxvd->hwndVScroll,
     1997        WinSetWindowPos(ptxvd->scrw.hwndVScroll,
    19961998                        HWND_TOP,
    19971999                        ptxvd->rclViewReal.xRight - ulScrollCX,
     
    20072009        if (ptxvd->fVScrollVisible)
    20082010            ulOfs = ulScrollCX;
    2009         WinSetWindowPos(ptxvd->hwndHScroll,
     2011        WinSetWindowPos(ptxvd->scrw.hwndHScroll,
    20102012                        HWND_TOP,
    20112013                        0,
     
    20432045    ulWinCY = (ptxvd->rclViewText.yTop - ptxvd->rclViewText.yBottom);
    20442046
    2045     if (ptxvd->ulViewYOfs < 0)
    2046         ptxvd->ulViewYOfs = 0;
    2047     if (ptxvd->ulViewYOfs > ((LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY))
    2048         ptxvd->ulViewYOfs = (LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY;
     2047    if (ptxvd->scrw.ptlScrollOfs.y < 0)
     2048        ptxvd->scrw.ptlScrollOfs.y = 0;
     2049    if (ptxvd->scrw.ptlScrollOfs.y > ((LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY))
     2050        ptxvd->scrw.ptlScrollOfs.y = (LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY;
    20492051
    20502052    // vertical scroll bar enabled at all?
    20512053    if (ptxvd->flStyle & XS_VSCROLL)
    20522054    {
    2053         BOOL fEnabled = winhUpdateScrollBar(ptxvd->hwndVScroll,
     2055        BOOL fEnabled = winhUpdateScrollBar(ptxvd->scrw.hwndVScroll,
    20542056                                            ulWinCY,
    20552057                                            ptxvd->xfd.szlWorkspace.cy,
    2056                                             ptxvd->ulViewYOfs,
     2058                                            ptxvd->scrw.ptlScrollOfs.y,
    20572059                                            (ptxvd->flStyle & XS_AUTOVHIDE));
    20582060        // is auto-hide on?
     
    20822084    if (ptxvd->flStyle & XS_HSCROLL)
    20832085    {
    2084         BOOL fEnabled = winhUpdateScrollBar(ptxvd->hwndHScroll,
     2086        BOOL fEnabled = winhUpdateScrollBar(ptxvd->scrw.hwndHScroll,
    20852087                                            ulWinCX,
    20862088                                            ptxvd->xfd.szlWorkspace.cx,
    2087                                             ptxvd->ulViewXOfs,
     2089                                            ptxvd->scrw.ptlScrollOfs.x,
    20882090                                            (ptxvd->flStyle & XS_AUTOHHIDE));
    20892091        // is auto-hide on?
     
    21652167            xstrcatc(pstr, '\n');
    21662168
    2167         ptxvd->ulViewXOfs = 0;
    2168         ptxvd->ulViewYOfs = 0;
     2169        ptxvd->scrw.ptlScrollOfs.x = 0;
     2170        ptxvd->scrw.ptlScrollOfs.y = 0;
    21692171        AdjustViewRects(hwndTextView,
    21702172                        ptxvd);
     
    21872189{
    21882190    ULONG   ulLineIndex = 0;
    2189     ULONG   ulYOfs = ptxvd->ulViewYOfs;
     2191    LONG    lYOfs = ptxvd->scrw.ptlScrollOfs.y;
    21902192    txvPaintText(ptxvd->hab,
    21912193                 ptxvd->hps,        // paint PS: screen
    21922194                 &ptxvd->xfd,       // formatting data
    21932195                 prcl2Paint,        // update rectangle given to us
    2194                  ptxvd->ulViewXOfs,  // current X scrolling offset
    2195                  &ulYOfs,            // current Y scrolling offset
     2196                 ptxvd->scrw.ptlScrollOfs.x,  // current X scrolling offset
     2197                 &lYOfs,            // current Y scrolling offset
    21962198                 TRUE,              // draw even partly visible lines
    21972199                 &ulLineIndex);
     
    22432245
    22442246    RECTL           rclLine;
    2245     rclLine.xLeft = pLineRcl->rcl.xLeft - ptxvd->ulViewXOfs;
    2246     rclLine.xRight = pLineRcl->rcl.xRight - ptxvd->ulViewXOfs;
    2247     rclLine.yBottom = pLineRcl->rcl.yBottom + ptxvd->ulViewYOfs;
    2248     rclLine.yTop = pLineRcl->rcl.yTop + ptxvd->ulViewYOfs;
     2247    rclLine.xLeft = pLineRcl->rcl.xLeft - ptxvd->scrw.ptlScrollOfs.x;
     2248    rclLine.xRight = pLineRcl->rcl.xRight - ptxvd->scrw.ptlScrollOfs.x;
     2249    rclLine.yBottom = pLineRcl->rcl.yBottom + ptxvd->scrw.ptlScrollOfs.y;
     2250    rclLine.yTop = pLineRcl->rcl.yTop + ptxvd->scrw.ptlScrollOfs.y;
    22492251
    22502252    if (pWordThis->pcszLinkTarget)
     
    22522254
    22532255    // x start: this word's X coordinate
    2254     ptlStart.x = pWordThis->lX - ptxvd->ulViewXOfs;
     2256    ptlStart.x = pWordThis->lX - ptxvd->scrw.ptlScrollOfs.x;
    22552257    // y start: bottom line of rectangle plus highest
    22562258    // base line offset found in all words (format step 2)
     
    22802282                       &rclLine,
    22812283                       pWordThis,
    2282                        ptxvd->ulViewXOfs);
     2284                       ptxvd->scrw.ptlScrollOfs.x);
    22832285}
    22842286
     
    23792381        ptxvd->rclViewReal.yTop = pcs->cy;
    23802382
    2381         winhCreateScrollBars(hwndTextView,
    2382                              &ptxvd->hwndVScroll,
    2383                              &ptxvd->hwndHScroll);
     2383        winhCreateScroller(hwndTextView,
     2384                           &ptxvd->scrw,
     2385                           ID_VSCROLL,
     2386                           ID_HSCROLL);
    23842387
    23852388        fShow = ((ptxvd->flStyle & XS_VSCROLL) != 0);
    2386         WinShowWindow(ptxvd->hwndVScroll, fShow);
     2389        WinShowWindow(ptxvd->scrw.hwndVScroll, fShow);
    23872390        ptxvd->fVScrollVisible = fShow;
    23882391
    23892392        fShow = ((ptxvd->flStyle & XS_HSCROLL) != 0);
    2390         WinShowWindow(ptxvd->hwndHScroll, fShow);
     2393        WinShowWindow(ptxvd->scrw.hwndHScroll, fShow);
    23912394        ptxvd->fHScrollVisible = fShow;
    23922395
     
    25522555                              FALSE,
    25532556                              TRUE);    // full reformat
     2557    }
     2558}
     2559
     2560/*
     2561 *@@ ProcessScroll:
     2562 *
     2563 *@@added V1.0.1 (2003-01-25) [umoeller]
     2564 */
     2565
     2566STATIC VOID ProcessScroll(HWND hwndTextView,
     2567                          ULONG msg,
     2568                          MPARAM mp2)
     2569{
     2570    PTEXTVIEWWINDATA ptxvd;
     2571    if (ptxvd = (PTEXTVIEWWINDATA)WinQueryWindowPtr(hwndTextView, QWL_PRIVATE))
     2572    {
     2573        POINTL  ptlScroll = {0, 0};
     2574        if (    (msg == WM_VSCROLL)
     2575             && (ptxvd->fVScrollVisible)
     2576           )
     2577        {
     2578            LONG cy = ptxvd->rclViewText.yTop - ptxvd->rclViewText.yBottom;
     2579            ptlScroll.y = winhHandleScrollMsg(ptxvd->scrw.hwndVScroll,
     2580                                              &ptxvd->scrw.ptlScrollOfs.y,
     2581                                              cy,
     2582                                              ptxvd->xfd.szlWorkspace.cy,
     2583                                              ptxvd->cdata.ulVScrollLineUnit,
     2584                                              msg,
     2585                                              mp2);
     2586        }
     2587        else if (ptxvd->fHScrollVisible)
     2588        {
     2589            LONG cx = ptxvd->rclViewText.xRight - ptxvd->rclViewText.xLeft;
     2590            ptlScroll.x = winhHandleScrollMsg(ptxvd->scrw.hwndHScroll,
     2591                                              &ptxvd->scrw.ptlScrollOfs.x,
     2592                                              cx,
     2593                                              ptxvd->xfd.szlWorkspace.cx,
     2594                                              ptxvd->cdata.ulHScrollLineUnit,
     2595                                              msg,
     2596                                              mp2);
     2597        }
     2598
     2599        if (ptlScroll.x || ptlScroll.y)
     2600            winhScrollWindow(hwndTextView,
     2601                             &ptxvd->rclViewText,
     2602                             &ptlScroll);
    25542603    }
    25552604}
     
    26352684        PLISTNODE pWordNodeClicked;
    26362685
    2637         ptlPos.x = SHORT1FROMMP(mp1) + ptxvd->ulViewXOfs;
    2638         ptlPos.y = SHORT2FROMMP(mp1) - ptxvd->ulViewYOfs;
     2686        ptlPos.x = SHORT1FROMMP(mp1) + ptxvd->scrw.ptlScrollOfs.x;
     2687        ptlPos.y = SHORT2FROMMP(mp1) - ptxvd->scrw.ptlScrollOfs.y;
    26392688
    26402689        if (    (!(ptxvd->flStyle & XS_STATIC))
     
    27072756        HWND        hwndOwner = NULLHANDLE;
    27082757
    2709         ptlPos.x = SHORT1FROMMP(mp1) + ptxvd->ulViewXOfs;
    2710         ptlPos.y = SHORT2FROMMP(mp1) - ptxvd->ulViewYOfs;
     2758        ptlPos.x = SHORT1FROMMP(mp1) + ptxvd->scrw.ptlScrollOfs.x;
     2759        ptlPos.y = SHORT2FROMMP(mp1) - ptxvd->scrw.ptlScrollOfs.y;
    27112760        WinSetCapture(HWND_DESKTOP, NULLHANDLE);
    27122761
     
    28862935            // and then have lower y coordinates down to way in the negatives,
    28872936            // to get the y offset, we must...
    2888             ptxvd->ulViewYOfs = (-pRect->rcl.yTop) - ulWinCY;
    2889 
    2890             if (ptxvd->ulViewYOfs < 0)
    2891                 ptxvd->ulViewYOfs = 0;
    2892             if (ptxvd->ulViewYOfs > ((LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY))
    2893                 ptxvd->ulViewYOfs = (LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY;
     2937            ptxvd->scrw.ptlScrollOfs.y = (-pRect->rcl.yTop) - ulWinCY;
     2938
     2939            if (ptxvd->scrw.ptlScrollOfs.y < 0)
     2940                ptxvd->scrw.ptlScrollOfs.y = 0;
     2941            if (ptxvd->scrw.ptlScrollOfs.y > ((LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY))
     2942                ptxvd->scrw.ptlScrollOfs.y = (LONG)ptxvd->xfd.szlWorkspace.cy - ulWinCY;
    28942943
    28952944            // vertical scroll bar enabled at all?
    28962945            if (ptxvd->flStyle & XS_VSCROLL)
    28972946            {
    2898                 /* BOOL fEnabled = */ winhUpdateScrollBar(ptxvd->hwndVScroll,
     2947                /* BOOL fEnabled = */ winhUpdateScrollBar(ptxvd->scrw.hwndVScroll,
    28992948                                                    ulWinCY,
    29002949                                                    ptxvd->xfd.szlWorkspace.cy,
    2901                                                     ptxvd->ulViewYOfs,
     2950                                                    ptxvd->scrw.ptlScrollOfs.y,
    29022951                                                    (ptxvd->flStyle & XS_AUTOVHIDE));
    29032952                WinInvalidateRect(hwndTextView, NULL, FALSE);
     
    29903039 *@@changed V0.9.20 (2002-08-10) [umoeller]: added support for formatting HTML and plain text automatically
    29913040 *@@changed V1.0.0 (2002-08-12) [umoeller]: optimized locality by moving big chunks into subfuncs
     3041 *@@changed V1.0.1 (2003-01-25) [umoeller]: adjusted scroll msgs for new handler code
    29923042 */
    29933043
     
    30813131
    30823132        case WM_VSCROLL:
    3083             if (    (ptxvd = (PTEXTVIEWWINDATA)WinQueryWindowPtr(hwndTextView, QWL_PRIVATE))
    3084                  && (ptxvd->fVScrollVisible)
    3085                )
    3086             {
    3087                 winhHandleScrollMsg(hwndTextView,
    3088                                     ptxvd->hwndVScroll,
    3089                                     &ptxvd->ulViewYOfs,
    3090                                     &ptxvd->rclViewText,
    3091                                     ptxvd->xfd.szlWorkspace.cy,
    3092                                     ptxvd->cdata.ulVScrollLineUnit,
    3093                                     msg,
    3094                                     mp2);
    3095             }
    3096         break;
    3097 
    3098         /*
    3099          * WM_HSCROLL:
    3100          *
    3101          */
    3102 
    31033133        case WM_HSCROLL:
    3104             if (    (ptxvd = (PTEXTVIEWWINDATA)WinQueryWindowPtr(hwndTextView, QWL_PRIVATE))
    3105                  && (ptxvd->fHScrollVisible)
    3106                )
    3107             {
    3108                 winhHandleScrollMsg(hwndTextView,
    3109                                     ptxvd->hwndHScroll,
    3110                                     &ptxvd->ulViewXOfs,
    3111                                     &ptxvd->rclViewText,
    3112                                     ptxvd->xfd.szlWorkspace.cx,
    3113                                     ptxvd->cdata.ulHScrollLineUnit,
    3114                                     msg,
    3115                                     mp2);
    3116             }
     3134            ProcessScroll(hwndTextView, msg, mp2);
     3135                    // V1.0.1 (2003-01-22) [umoeller]
    31173136        break;
    31183137
     
    37773796    ULONG       ulCurrentLineIndex = 0,
    37783797                ulCurrentPage = 1;
    3779     ULONG       ulCurrentYOfs = 0;
     3798    LONG        lCurrentYOfs = 0;
    37803799
    37813800    /* MATRIXLF    matlf;
     
    38473866                                    &rclPageWorld,
    38483867                                    0,
    3849                                     &ulCurrentYOfs,
     3868                                    &lCurrentYOfs,
    38503869                                    FALSE,      // draw only fully visible lines
    38513870                                    &ulCurrentLineIndex); // in/out: line to start with
  • trunk/src/helpers/winh.c

    r242 r243  
    18961896
    18971897/*
    1898  *@@ winhCreateScrollBars:
    1899  *      creates two scroll bars with an arbitrary
    1900  *      position for later use with winhUpdateScrollBar.
    1901  *
    1902  *@@added V1.0.1 (2003-01-17) [umoeller]
    1903  */
    1904 
    1905 BOOL winhCreateScrollBars(HWND hwndParent,
    1906                           HWND *phwndV,     // out: vertical scroll bar
    1907                           HWND *phwndH)     // out: horizontal scroll bar
    1908 {
    1909     SBCDATA     sbcd;
    1910     sbcd.cb = sizeof(SBCDATA);
    1911     sbcd.sHilite = 0;
    1912     sbcd.posFirst = 0;
    1913     sbcd.posLast = 100;
    1914     sbcd.posThumb = 30;
    1915     sbcd.cVisible = 50;
    1916     sbcd.cTotal = 50;
    1917 
    1918     return (    (*phwndV = WinCreateWindow(hwndParent,
    1919                                            WC_SCROLLBAR,
    1920                                            "",
    1921                                            SBS_VERT | SBS_THUMBSIZE | WS_VISIBLE,
    1922                                            10, 10,
    1923                                            20, 100,
    1924                                            hwndParent,     // owner
    1925                                            HWND_TOP,
    1926                                            ID_VSCROLL,
    1927                                            &sbcd,
    1928                                            0))
    1929              && (*phwndH = WinCreateWindow(hwndParent,
    1930                                            WC_SCROLLBAR,
    1931                                            "",
    1932                                            SBS_THUMBSIZE | WS_VISIBLE,
    1933                                            10, 10,
    1934                                            20, 100,
    1935                                            hwndParent,     // owner
    1936                                            HWND_TOP,
    1937                                            ID_HSCROLL,
    1938                                            &sbcd,
    1939                                            0))
    1940            );
    1941 }
    1942 
    1943 /*
    19441898 *@@ winhUpdateScrollBar:
    19451899 *      updates the given scroll bar according to the given
     
    19581912 *      Terminology:
    19591913 *
    1960  *      -- "window": the actual window with scroll bars which displays
    1961  *         a subrectangle of the available data. With a typical PM
    1962  *         application, this will be your client window.
    1963  *
    1964  *         The width or height of this must be passed in ulWinPels.
    1965  *
    1966  *      -- "workarea": the entire data to be displayed, of which the
    1967  *         "window" can only display a subrectangle, if the workarea
    1968  *         is larger than the window.
    1969  *
    1970  *         The width or height of this must be passed in ulWorkareaPels.
    1971  *         This can be smaller than ulWinPels (if the window is larger
    1972  *         than the data) or the same or larger than ulWinPels
    1973  *         (if the window is too small to show all the data).
    1974  *
    1975  *      -- "window offset": the offset of the current window within
    1976  *         the workarea.
    1977  *
    1978  *         For horizontal scroll bars, this is the X coordinate,
    1979  *         counting from the left of the window (0 means leftmost).
    1980  *
    1981  *         For vertical scroll bars, this is counted from the _top_
    1982  *         of the workarea (0 means topmost, as opposed to OS/2
    1983  *         window coordinates!). This is because for vertical scroll
    1984  *         bars controls, higher values move the thumb _down_. Yes
    1985  *         indeed, this conflicts with PM's coordinate system.
    1986  *
    1987  *         The window offset is therefore always positive.
     1914 *      --  "window": the actual window with scroll bars which displays
     1915 *          a subrectangle of the available data. With a typical PM
     1916 *          application, this will be your client window.
     1917 *
     1918 *          The width or height of this must be passed in ulWinPels.
     1919 *
     1920 *      --  "workarea": the entire data to be displayed, of which the
     1921 *          "window" can only display a subrectangle, if the workarea
     1922 *          is larger than the window.
     1923 *
     1924 *          The width or height of this must be passed in ulWorkareaPels.
     1925 *          This can be smaller than ulWinPels (if the window is larger
     1926 *          than the data) or the same or larger than ulWinPels
     1927 *          (if the window is too small to show all the data).
     1928 *
     1929 *          This value is exclusive in the sense that the maximum
     1930 *          window offset (below) can be the workarea minus one.
     1931 *
     1932 *      --  "window offset": the zero-based offset of the current
     1933 *          window within the workarea, whose maximum value is
     1934 *          the workarea minus one.
     1935 *
     1936 *          For horizontal scroll bars, this is the X coordinate,
     1937 *          counting from the left of the window (0 means leftmost).
     1938 *
     1939 *          For vertical scroll bars, this is counted from the _top_
     1940 *          of the workarea (0 means topmost, as opposed to OS/2
     1941 *          window coordinates!). This is because for vertical scroll
     1942 *          bars controls, higher values move the thumb _down_. Yes
     1943 *          indeed, this conflicts with PM's coordinate system.
     1944 *
     1945 *          The window offset is therefore always positive.
    19881946 *
    19891947 *      The scroll bar gets disabled if the entire workarea is visible,
     
    20091967 *@@changed V0.9.3 (2000-04-30) [umoeller]: fixed pels/unit confusion
    20101968 *@@changed V0.9.3 (2000-05-08) [umoeller]: now handling scroll units automatically
     1969 *@@changed V1.0.1 (2003-01-25) [umoeller]: fixed max value which caused right/bottommost scroll button to never be disabled
     1970 *@@changed V1.0.1 (2003-01-25) [umoeller]: fixed bad thumb position for large offsets
    20111971 */
    20121972
     
    20261986    BOOL brc = FALSE;
    20271987
    2028     // _Pmpf(("Entering winhUpdateScrollBar"));
    2029 
    2030     // for large workareas, adjust scroll bar units
    2031     USHORT  usScrollUnitPels = 1;
    2032     if (ulWorkareaPels > 10000)
    2033         usScrollUnitPels = 100;
    2034 
    2035     if (ulWorkareaPels > ulWinPels)
    2036     {
     1988    if (ulWorkareaPels >= ulWinPels)
     1989    {
     1990        // for large workareas, adjust scroll bar units
     1991        USHORT  usDivisor = 1;
     1992        USHORT  lMaxAllowedUnitOfs;
     1993
     1994        if (ulWorkareaPels > 10000)
     1995            usDivisor = 100;
     1996
    20371997        // scrollbar needed:
    2038         USHORT  usThumbDivisorUnits = usScrollUnitPels;
    2039         USHORT  lMaxAllowedUnitOfs;
    2040         // _Pmpf(("winhUpdateScrollBar: ulWorkareaPels > ulWinPels, enabling scroller"));
    2041         // divisor for thumb size (below)
    2042         if (ulWorkareaPels > 10000)
    2043             // for very large workareas, we need to
    2044             // raise the divisor, because we only
    2045             // have a USHORT
    2046             usThumbDivisorUnits = usScrollUnitPels * 100;
    20471998
    20481999        // workarea is larger than window:
     
    20522003
    20532004        // calculate limit
    2054         lMaxAllowedUnitOfs = ((ulWorkareaPels - ulWinPels + usScrollUnitPels)
    2055                                // scroll unit is 10
    2056                                / usScrollUnitPels);
    2057 
    2058         // _Pmpf(("    usCurUnitOfs: %d", ulCurUnitOfs));
    2059         // _Pmpf(("    usMaxUnits: %d", lMaxAllowedUnitOfs));
     2005        lMaxAllowedUnitOfs =   (ulWorkareaPels - ulWinPels)
     2006                             / usDivisor;
    20602007
    20612008        // set thumb position and limit
    20622009        WinSendMsg(hwndScrollBar,
    20632010                   SBM_SETSCROLLBAR,
    2064                    (MPARAM)(ulCurPelsOfs), //  / usThumbDivisorUnits),   // position: 0 means top
     2011                   (MPARAM)(ulCurPelsOfs / usDivisor),   // position: 0 means top
    20652012                   MPFROM2SHORT(0,  // minimum
    20662013                                lMaxAllowedUnitOfs));    // maximum
     
    20702017        WinSendMsg(hwndScrollBar,
    20712018                   SBM_SETTHUMBSIZE,
    2072                    MPFROM2SHORT(    ulWinPels / usThumbDivisorUnits,       // visible
    2073                                     ulWorkareaPels / usThumbDivisorUnits), // total
     2019                   MPFROM2SHORT(    ulWinPels / usDivisor,       // visible
     2020                                    ulWorkareaPels / usDivisor), // total
    20742021                   0);
    20752022        brc = TRUE;
     
    20772024    else
    20782025    {
    2079         // _Pmpf(("winhUpdateScrollBar: ulWorkareaPels <= ulWinPels"));
    20802026        // entire workarea is visible:
    20812027        WinEnableWindow(hwndScrollBar, FALSE);
     
    20912037/*
    20922038 *@@ winhHandleScrollMsg:
    2093  *      this helper handles a WM_VSCROLL or WM_HSCROLL
    2094  *      message posted to a client window when the user
    2095  *      has worked on a client scroll bar. Calling this
    2096  *      function is ALL you need to do to handle those
    2097  *      two messages.
     2039 *      this helper handles a WM_VSCROLL or WM_HSCROLL message
     2040 *      posted to a client window when the user has worked on a
     2041 *      client scroll bar. Calling this function is all you need to
     2042 *      do to handle those two messages.
    20982043 *
    20992044 *      This is most useful in conjunction with winhUpdateScrollBar.
    21002045 *      See that function for the terminology also.
    21012046 *
    2102  *      This function calculates the new scrollbar position
    2103  *      (from the mp2 value, which can be line up/down,
    2104  *      page up/down, or slider track) and calls WinScrollWindow
    2105  *      accordingly. The window part which became invalid
    2106  *      because of the scrolling is automatically invalidated
    2107  *      (using WinInvalidateRect), so expect a WM_PAINT after
    2108  *      calling this function.
     2047 *      This function calculates the new scrollbar position (from
     2048 *      the mp2 value, which can be line up/down, page up/down, or
     2049 *      slider track) and calculates the scrolling offset
     2050 *      accordingly, which is returned as a LONG.
    21092051 *
    21102052 *      This function assumes that the scrollbar operates
    21112053 *      on values starting from zero. The maximum value
    2112  *      of the scroll bar is:
    2113  *
    2114  +          ulWorkareaPels - (prcl2Scroll->yTop - prcl2Scroll->yBottom)
    2115  *
    2116  *      This function also automatically changes the scroll bar
     2054 *      of the scroll bar is therefore
     2055 *
     2056 +          lWorkareaPels - (prcl2Scroll->yTop - prcl2Scroll->yBottom)
     2057 *
     2058 *      This function also automatically shrinks the scroll bar
    21172059 *      units, should you have a workarea size which doesn't fit
    21182060 *      into the SHORT's that the scroll bar uses internally. As
    21192061 *      a result, this function handles a the complete range of
    2120  *      a ULONG for the workarea.
     2062 *      a LONG for the workarea. (The PM scroll bar implementation
     2063 *      is really brain-dead in this respect... the workarea can
     2064 *      easily be larger than 32768 pixels. That's what scroll bars
     2065 *      are for in the first place, dammit.)
    21212066 *
    21222067 *      Replace "bottom" and "top" with "right" and "left" for
    21232068 *      horizontal scrollbars in the above formula.
     2069 *
     2070 *      Returns the amount of pixels to be passed to winhScrollWindow
     2071 *      afterwards.
    21242072 *
    21252073 *@@added V0.9.1 (2000-02-13) [umoeller]
     
    21272075 *@@changed V0.9.3 (2000-05-08) [umoeller]: now handling scroll units automatically
    21282076 *@@changed V0.9.7 (2001-01-17) [umoeller]: changed PLONG to PULONG
    2129  */
    2130 
    2131 BOOL winhHandleScrollMsg(HWND hwnd2Scroll,          // in: client window to scroll
    2132                          HWND hwndScrollBar,        // in: vertical or horizontal scroll bar window
    2133                          PULONG pulCurPelsOfs,      // in/out: current workarea offset;
    2134                                                     // this is updated with the proper scroll units
    2135                          PRECTL prcl2Scroll,        // in: hwnd2Scroll rectangle to scroll
    2136                                                     // (in window coordinates);
    2137                                                     // this is passed to WinScrollWindow,
    2138                                                     // which considers this inclusive!
    2139                          LONG ulWorkareaPels,       // in: total workarea dimension,
    2140                                                     // into which *pulCurPelsOfs is an offset
     2077 *@@changed V1.0.1 (2003-01-25) [umoeller]: changed prototype, no longer calling WinScrollWindow, fixed offset bugs
     2078 */
     2079
     2080LONG winhHandleScrollMsg(HWND hwndScrollBar,        // in: vertical or horizontal scroll bar window
     2081                         PLONG plCurPelsOfs,        // in/out: current workarea offset (in window coordinates)
     2082                         LONG lWindowPels,          // in: window cx or cy (in window coordinates)
     2083                         LONG lWorkareaPels,        // in: total workarea dimension,
     2084                                                    // into which *plCurPelsOfs is an offset
    21412085                         USHORT usLineStepPels,     // in: pixels to scroll line-wise
    21422086                                                    // (scroll bar buttons pressed)
     
    21462090                                                    // see PMREF for details
    21472091{
    2148     ULONG   ulOldPelsOfs = *pulCurPelsOfs;
     2092    LONG    lOldPelsOfs = *plCurPelsOfs;
    21492093    USHORT  usPosUnits = SHORT1FROMMP(mp2), // in scroll units
    21502094            usCmd = SHORT2FROMMP(mp2);
    2151     LONG    lMaxAllowedUnitOfs;
    2152     ULONG   ulWinPels;
     2095    LONG    lLimitPels;
    21532096
    21542097    // for large workareas, adjust scroll bar units
    2155     USHORT  usScrollUnitPels = 1;
    2156     if (ulWorkareaPels > 10000)
    2157         usScrollUnitPels = 100;
    2158 
    2159     // calculate window size (vertical or horizontal)
    2160     if (msg == WM_VSCROLL)
    2161         ulWinPels = (prcl2Scroll->yTop - prcl2Scroll->yBottom);
    2162     else
    2163         ulWinPels = (prcl2Scroll->xRight - prcl2Scroll->xLeft);
    2164 
    2165     lMaxAllowedUnitOfs = ((LONG)ulWorkareaPels - ulWinPels) / usScrollUnitPels;
    2166 
    2167     // _Pmpf(("Entering winhHandleScrollMsg"));
     2098    LONG    lScrollUnitPels = 1;
     2099    if (lWorkareaPels > 10000)
     2100        lScrollUnitPels = 100;
    21682101
    21692102    switch (usCmd)
    21702103    {
    21712104        case SB_LINEUP:
    2172             if (*pulCurPelsOfs > usLineStepPels)
    2173                 *pulCurPelsOfs -= usLineStepPels;  //  * usScrollUnitPels);
    2174             else
    2175                 *pulCurPelsOfs = 0;
     2105            *plCurPelsOfs -= usLineStepPels;
    21762106        break;
    21772107
    21782108        case SB_LINEDOWN:
    2179             *pulCurPelsOfs += usLineStepPels;  //  * usScrollUnitPels);
     2109            *plCurPelsOfs += usLineStepPels;
    21802110        break;
    21812111
    21822112        case SB_PAGEUP:
    2183             if (*pulCurPelsOfs > ulWinPels)
    2184                 *pulCurPelsOfs -= ulWinPels; // convert to units
    2185             else
    2186                 *pulCurPelsOfs = 0;
     2113            *plCurPelsOfs -= lWindowPels;
    21872114        break;
    21882115
    21892116        case SB_PAGEDOWN:
    2190             *pulCurPelsOfs += ulWinPels; // convert to units
     2117            *plCurPelsOfs += lWindowPels;
    21912118        break;
    21922119
    21932120        case SB_SLIDERTRACK:
    2194             *pulCurPelsOfs = (usPosUnits * usScrollUnitPels);
    2195             // _Pmpf(("    SB_SLIDERTRACK: usUnits = %d", usPosUnits));
     2121            *plCurPelsOfs = (LONG)usPosUnits * lScrollUnitPels;
    21962122        break;
    21972123
    21982124        case SB_SLIDERPOSITION:
    2199             *pulCurPelsOfs = (usPosUnits * usScrollUnitPels);
     2125            *plCurPelsOfs = (LONG)usPosUnits * lScrollUnitPels;
    22002126        break;
    22012127    }
    22022128
    2203     // are we close to the lower limit?
    2204     /* if (*plCurUnitOfs < usLineStepUnits) // usScrollUnit)
    2205         *plCurUnitOfs = 0;
    2206     // are we close to the upper limit?
    2207     else if (*plCurUnitOfs + usLineStepUnits > lMaxUnitOfs)
    2208     {
    2209         _Pmpf(("        !!! limiting: %d to %d", *plCurUnitOfs, lMaxUnitOfs));
    2210         *plCurUnitOfs = lMaxUnitOfs;
    2211     } */
    2212 
    2213     /* if (*plCurPelsOfs < 0)
    2214         *plCurPelsOfs = 0; */       // checked above
    2215     if (*pulCurPelsOfs > (lMaxAllowedUnitOfs * usScrollUnitPels))
    2216     {
    2217         *pulCurPelsOfs = (lMaxAllowedUnitOfs * usScrollUnitPels);
    2218     }
    2219     if (    (*pulCurPelsOfs != ulOldPelsOfs)
    2220          || (*pulCurPelsOfs == 0)
    2221          || (*pulCurPelsOfs == (lMaxAllowedUnitOfs * usScrollUnitPels))
     2129    // calc max scroll offset:
     2130    // if we have a viewport of 200 and the window size is 199,
     2131    // we can have scroll values of 0 or 1
     2132    lLimitPels = lWorkareaPels - lWindowPels;
     2133
     2134    // now delimit
     2135    if (*plCurPelsOfs < 0)
     2136        *plCurPelsOfs = 0;
     2137    else if (*plCurPelsOfs > lLimitPels)
     2138        *plCurPelsOfs = lLimitPels;
     2139
     2140    if (    (*plCurPelsOfs != lOldPelsOfs)
     2141         || (*plCurPelsOfs == 0)
     2142         || (*plCurPelsOfs == lLimitPels)
    22222143       )
    22232144    {
    2224         RECTL   rcl2Scroll,
    2225                 rcl2Update;
    2226 
    22272145        // changed:
    22282146        WinSendMsg(hwndScrollBar,
    22292147                   SBM_SETPOS,
    2230                    (MPARAM)(*pulCurPelsOfs / usScrollUnitPels), //  / usScrollUnit),
    2231                    0);
    2232         // scroll window rectangle:
    2233         rcl2Scroll.xLeft =  prcl2Scroll->xLeft;
    2234         rcl2Scroll.xRight =  prcl2Scroll->xRight;
    2235         rcl2Scroll.yBottom =  prcl2Scroll->yBottom;
    2236         rcl2Scroll.yTop =  prcl2Scroll->yTop;
    2237 
    2238         if (msg == WM_VSCROLL)
    2239             WinScrollWindow(hwnd2Scroll,
    2240                             0,
    2241                             (*pulCurPelsOfs - ulOldPelsOfs)  // scroll units changed
    2242                             ,    // * usScrollUnitPels,     // convert to pels
    2243                             &rcl2Scroll,  // rcl to scroll
    2244                             prcl2Scroll, // clipping rect
    2245                             NULLHANDLE, // no region
    2246                             &rcl2Update,
    2247                             0);
    2248         else
    2249             WinScrollWindow(hwnd2Scroll,
    2250                             -(LONG)(*pulCurPelsOfs - ulOldPelsOfs) // scroll units changed
    2251                             ,    // * usScrollUnitPels,
    2252                             0,
    2253                             &rcl2Scroll,  // rcl to scroll
    2254                             prcl2Scroll, // clipping rect
    2255                             NULLHANDLE, // no region
    2256                             &rcl2Update,
    2257                             0);
    2258 
    2259         // WinScrollWindow has stored the invalid window
    2260         // rectangle which needs to be repainted in rcl2Update:
    2261         WinInvalidateRect(hwnd2Scroll, &rcl2Update, FALSE);
    2262     }
    2263 
    2264     // _Pmpf(("End of winhHandleScrollMsg"));
    2265 
    2266     return TRUE;
    2267 }
    2268 
    2269 /*
    2270  *@@ winhHandleScrollMsg2:
    2271  *
    2272  *      Returns the amount of pixels to be passed to
    2273  *      WinScrollWindow.
    2274  *
    2275  *@@added V1.0.1 (2003-01-17) [umoeller]
    2276  */
    2277 
    2278 LONG winhHandleScrollMsg2(HWND hwndScrollBar,        // in: vertical or horizontal scroll bar window
    2279                           PLONG plCurPelsOfs,        // in/out: current workarea offset;
    2280                                                      // this is updated with the proper scroll units
    2281                           LONG lWindowPels,          // in: window cx or cy (in window coordinates);
    2282                           LONG lWorkareaPels,        // in: total workarea dimension,
    2283                                                      // into which *plCurPelsOfs is an offset
    2284                           USHORT usLineStepPels,     // in: pixels to scroll line-wise
    2285                                                      // (scroll bar buttons pressed)
    2286                           ULONG msg,                 // in: either WM_VSCROLL or WM_HSCROLL
    2287                           MPARAM mp2)                // in: complete mp2 of WM_VSCROLL/WM_HSCROLL;
    2288                                                      // this has two SHORT's (usPos and usCmd),
    2289                                                      // see PMREF for details
    2290 {
    2291     LONG    lOldPelsOfs = *plCurPelsOfs;
    2292     USHORT  usPosUnits = SHORT1FROMMP(mp2), // in scroll units
    2293             usCmd = SHORT2FROMMP(mp2);
    2294     LONG    lMaxAllowedUnitOfs;
    2295 
    2296     // for large workareas, adjust scroll bar units
    2297     USHORT  usScrollUnitPels = 1;
    2298     if (lWorkareaPels > 10000)
    2299         usScrollUnitPels = 100;
    2300 
    2301     lMaxAllowedUnitOfs = (lWorkareaPels - lWindowPels) / usScrollUnitPels;
    2302 
    2303     // _Pmpf(("Entering winhHandleScrollMsg"));
    2304 
    2305     switch (usCmd)
    2306     {
    2307         case SB_LINEUP:
    2308             if (*plCurPelsOfs > usLineStepPels)
    2309                 *plCurPelsOfs -= usLineStepPels;  //  * usScrollUnitPels);
    2310             else
    2311                 *plCurPelsOfs = 0;
    2312         break;
    2313 
    2314         case SB_LINEDOWN:
    2315             *plCurPelsOfs += usLineStepPels;  //  * usScrollUnitPels);
    2316         break;
    2317 
    2318         case SB_PAGEUP:
    2319             if (*plCurPelsOfs > lWindowPels)
    2320                 *plCurPelsOfs -= lWindowPels; // convert to units
    2321             else
    2322                 *plCurPelsOfs = 0;
    2323         break;
    2324 
    2325         case SB_PAGEDOWN:
    2326             *plCurPelsOfs += lWindowPels; // convert to units
    2327         break;
    2328 
    2329         case SB_SLIDERTRACK:
    2330             *plCurPelsOfs = (usPosUnits * usScrollUnitPels);
    2331             // _Pmpf(("    SB_SLIDERTRACK: usUnits = %d", usPosUnits));
    2332         break;
    2333 
    2334         case SB_SLIDERPOSITION:
    2335             *plCurPelsOfs = (usPosUnits * usScrollUnitPels);
    2336         break;
    2337     }
    2338 
    2339     if (*plCurPelsOfs > (lMaxAllowedUnitOfs * usScrollUnitPels))
    2340         *plCurPelsOfs = (lMaxAllowedUnitOfs * usScrollUnitPels);
    2341 
    2342     if (    (*plCurPelsOfs != lOldPelsOfs)
    2343          || (*plCurPelsOfs == 0)
    2344          || (*plCurPelsOfs == (lMaxAllowedUnitOfs * usScrollUnitPels))
    2345        )
    2346     {
    2347         // changed:
    2348         WinSendMsg(hwndScrollBar,
    2349                    SBM_SETPOS,
    2350                    (MPARAM)(*plCurPelsOfs / usScrollUnitPels), //  / usScrollUnit),
     2148                   (MPARAM)(*plCurPelsOfs / lScrollUnitPels),
    23512149                   0);
    23522150
     
    23812179
    23822180/*
    2383  *@@ winhProcessScrollChars:
     2181 *@@ winhProcessScrollChars2:
    23842182 *      helper for processing WM_CHAR messages for
    23852183 *      client windows with scroll bars.
     
    24002198 *      The following keystrokes are processed here:
    24012199 *
    2402  *      -- "cursor up, down, right, left": scroll one
    2403  *         line in the proper direction.
    2404  *      -- "page up, down": scroll one page up or down.
    2405  *      -- "Home": scroll leftmost.
    2406  *      -- "Ctrl+ Home": scroll topmost.
    2407  *      -- "End": scroll rightmost.
    2408  *      -- "Ctrl+ End": scroll bottommost.
    2409  *      -- "Ctrl + page up, down": scroll one screen left or right.
    2410  *
    2411  *      This is CUA behavior.
    2412  *
    2413  *      Returns TRUE if the message has been
    2414  *      processed.
     2200 *      --  "cursor up, down, right, left": scroll one
     2201 *          line in the proper direction.
     2202 *      --  "page up, down": scroll one page up or down.
     2203 *      --  "Home": scroll leftmost.
     2204 *      --  "Ctrl+ Home": scroll topmost.
     2205 *      --  "End": scroll rightmost.
     2206 *      --  "Ctrl+ End": scroll bottommost.
     2207 *      --  "Ctrl + page up, down": scroll one screen left or right.
     2208 *
     2209 *      This is CUA behavior, if anyone still cares about that.
     2210 *
     2211 *      Returns TRUE if the message has been processed.
    24152212 *
    24162213 *@@added V0.9.3 (2000-04-29) [umoeller]
     
    24182215 */
    24192216
    2420 BOOL winhProcessScrollChars(HWND hwndClient,    // in: client window
    2421                             HWND hwndVScroll,   // in: vertical scroll bar
    2422                             HWND hwndHScroll,   // in: horizontal scroll bar
    2423                             MPARAM mp1,         // in: WM_CHAR mp1
    2424                             MPARAM mp2,         // in: WM_CHAR mp2
    2425                             ULONG ulVertMax,    // in: maximum workarea cy
    2426                             ULONG ulHorzMax)    // in: maximum workarea cx
     2217BOOL winhProcessScrollChars2(HWND hwndClient,    // in: client window
     2218                             const SCROLLABLEWINDOW *pscrw,   // in: scroller data
     2219                             MPARAM mp1,         // in: WM_CHAR mp1
     2220                             MPARAM mp2)         // in: WM_CHAR mp2
    24272221{
    24282222    BOOL    fProcessed = FALSE;
    24292223    USHORT usFlags    = SHORT1FROMMP(mp1);
    2430     // USHORT usch       = SHORT1FROMMP(mp2);
    24312224    USHORT usvk       = SHORT2FROMMP(mp2);
    2432 
    2433     // _Pmpf(("Entering winhProcessScrollChars"));
    24342225
    24352226    if (usFlags & KC_VIRTUALKEY)
     
    24942285                    // vertical:
    24952286                    ulMsg = WM_VSCROLL;
    2496                     sPos = ulVertMax;
     2287                    sPos = pscrw->szlWorkarea.cy;
    24972288                }
    24982289                else
    24992290                {
    25002291                    ulMsg = WM_HSCROLL;
    2501                     sPos = ulHorzMax;
     2292                    sPos = pscrw->szlWorkarea.cx;
    25022293                }
    25032294
     
    25152306        {
    25162307            HWND   hwndScrollBar = ((ulMsg == WM_VSCROLL)
    2517                                         ? hwndVScroll
    2518                                         : hwndHScroll);
     2308                                        ? pscrw->hwndVScroll
     2309                                        : pscrw->hwndHScroll);
    25192310            if (WinIsWindowEnabled(hwndScrollBar))
    25202311            {
     
    25302321    }
    25312322
    2532     // _Pmpf(("End of  winhProcessScrollChars"));
    2533 
    25342323    return fProcessed;
     2324}
     2325
     2326/*
     2327 *@@ winhProcessScrollChars:
     2328 *      wrapper around winhProcessScrollChars2 for prototype
     2329 *      compatibility.
     2330 *
     2331 *@@added V1.0.1 (2003-01-25) [umoeller]
     2332 */
     2333
     2334BOOL winhProcessScrollChars(HWND hwndClient,    // in: client window
     2335                            HWND hwndVScroll,   // in: vertical scroll bar
     2336                            HWND hwndHScroll,   // in: horizontal scroll bar
     2337                            MPARAM mp1,         // in: WM_CHAR mp1
     2338                            MPARAM mp2,         // in: WM_CHAR mp2
     2339                            ULONG ulVertMax,    // in: maximum workarea cy
     2340                            ULONG ulHorzMax)    // in: maximum workarea cx
     2341{
     2342    SCROLLABLEWINDOW scrw;
     2343
     2344    scrw.hwndVScroll = hwndVScroll;
     2345    scrw.hwndHScroll = hwndHScroll;
     2346    scrw.szlWorkarea.cx = ulHorzMax;
     2347    scrw.szlWorkarea.cy = ulVertMax;
     2348
     2349    return winhProcessScrollChars2(hwndClient,
     2350                                   &scrw,
     2351                                   mp1,
     2352                                   mp2);
     2353}
     2354
     2355/*
     2356 *@@ winhCreateScrollBars:
     2357 *      creates two scroll bars with an arbitrary
     2358 *      position for later use with winhUpdateScrollBar.
     2359 *
     2360 *@@added V1.0.1 (2003-01-25) [umoeller]
     2361 */
     2362
     2363BOOL XWPENTRY winhCreateScroller(HWND hwndParent,           // in: parent and owner of scroll bars
     2364                                 PSCROLLABLEWINDOW pscrw,   // out: scroller data
     2365                                 ULONG idVScroll,           // in: window ID of vertical scroll bar
     2366                                 ULONG idHScroll)           // in: window ID of horizontal scroll bar
     2367{
     2368    SBCDATA     sbcd;
     2369    sbcd.cb = sizeof(SBCDATA);
     2370    sbcd.sHilite = 0;
     2371    sbcd.posFirst = 0;
     2372    sbcd.posLast = 100;
     2373    sbcd.posThumb = 30;
     2374    sbcd.cVisible = 50;
     2375    sbcd.cTotal = 50;
     2376
     2377    pscrw->cxScrollBar = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
     2378    pscrw->cyScrollBar = WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
     2379
     2380    pscrw->idVScroll = idVScroll;
     2381    pscrw->idHScroll = idHScroll;
     2382
     2383    pscrw->szlWorkarea.cx
     2384    = pscrw->szlWorkarea.cy
     2385    = pscrw->ptlScrollOfs.x
     2386    = pscrw->ptlScrollOfs.y
     2387    = 0;
     2388
     2389    return (    (pscrw->hwndVScroll = WinCreateWindow(hwndParent,
     2390                                                      WC_SCROLLBAR,
     2391                                                      "",
     2392                                                      SBS_VERT | SBS_THUMBSIZE | WS_VISIBLE,
     2393                                                      10, 10,
     2394                                                      20, 100,
     2395                                                      hwndParent,     // owner
     2396                                                      HWND_TOP,
     2397                                                      idVScroll,
     2398                                                      &sbcd,
     2399                                                      0))
     2400             && (pscrw->hwndHScroll = WinCreateWindow(hwndParent,
     2401                                                      WC_SCROLLBAR,
     2402                                                      "",
     2403                                                      SBS_THUMBSIZE | WS_VISIBLE,
     2404                                                      10, 10,
     2405                                                      20, 100,
     2406                                                      hwndParent,     // owner
     2407                                                      HWND_TOP,
     2408                                                      idHScroll,
     2409                                                      &sbcd,
     2410                                                      0))
     2411           );
     2412}
     2413
     2414/*
     2415 *@@ winhHandleScrollerMsgs:
     2416 *      unified function that you can simply call for all of
     2417 *      the WM_HSCROLL, WM_VSCROLL, and WM_CHAR messages to
     2418 *      get full automatic scrolling support for window
     2419 *      messages.
     2420 *
     2421 *      This calls winhHandleScrollMsg, winhScrollWindow,
     2422 *      and winhProcessScrollChars in turn as appropriate.
     2423 *
     2424 *      However, you still need to call winhUpdateScrollBar
     2425 *      for each scroll bar whenever either the workarea or
     2426 *      window size changes.
     2427 *
     2428 *      See winhUpdateScrollBar for the terminology.
     2429 *
     2430 *      The size of the workarea must be passed in with
     2431 *      pscrw, as well as the window and scrollbar handles.
     2432 *      By contrast, the current window size must be passed
     2433 *      in via the pszlWin parameter. This allows for cooperation
     2434 *      with the ctlDefWindowProc funcs, which have their own
     2435 *      fields for this in DEFWINDOWDATA so we won't duplicate.
     2436 *
     2437 *      Preconditions:
     2438 *
     2439 *      --  hwnd2Scroll (the "client") and the scroll bar windows
     2440 *          must be siblings presently. In other words, scrolling
     2441 *          won't work correctly if the scroll bars are children
     2442 *          of the client because we do not presently handle
     2443 *          passing a clipping rectangle to WinScrollWindow here.
     2444 *
     2445 *@@added V1.0.1 (2003-01-25) [umoeller]
     2446 */
     2447
     2448MRESULT winhHandleScrollerMsgs(HWND hwnd2Scroll,        // in: "client" window
     2449                               PSCROLLABLEWINDOW pscrw, // in: scroller data
     2450                               PSIZEL pszlWin,
     2451                               ULONG msg,
     2452                               MPARAM mp1,
     2453                               MPARAM mp2)
     2454{
     2455    MRESULT mrc = 0;
     2456    POINTL  ptlScroll = {0, 0};
     2457
     2458    switch (msg)
     2459    {
     2460        case WM_VSCROLL:
     2461            if (ptlScroll.y = winhHandleScrollMsg(pscrw->hwndVScroll,
     2462                                                  &pscrw->ptlScrollOfs.y,
     2463                                                  pszlWin->cy,
     2464                                                  pscrw->szlWorkarea.cy,
     2465                                                  10,
     2466                                                  msg,
     2467                                                  mp2))
     2468                winhScrollWindow(hwnd2Scroll,
     2469                                 NULL,
     2470                                 &ptlScroll);
     2471        break;
     2472
     2473        case WM_HSCROLL:
     2474            if (ptlScroll.x = winhHandleScrollMsg(pscrw->hwndHScroll,
     2475                                                  &pscrw->ptlScrollOfs.x,
     2476                                                  pszlWin->cx,
     2477                                                  pscrw->szlWorkarea.cx,
     2478                                                  10,
     2479                                                  msg,
     2480                                                  mp2))
     2481                winhScrollWindow(hwnd2Scroll,
     2482                                 NULL,
     2483                                 &ptlScroll);
     2484        break;
     2485
     2486        case WM_CHAR:
     2487            mrc = (MRESULT)winhProcessScrollChars(hwnd2Scroll,
     2488                                                  pscrw->hwndVScroll,
     2489                                                  pscrw->hwndHScroll,
     2490                                                  mp1,
     2491                                                  mp2,
     2492                                                  pscrw->szlWorkarea.cy,
     2493                                                  pscrw->szlWorkarea.cx);
     2494        break;
     2495    }
     2496
     2497    return mrc;
    25352498}
    25362499
     
    37633726
    37643727    return hswitch;
     3728}
     3729
     3730/*
     3731 *@@ winhUpdateTasklist:
     3732 *      refreshes the task list entry for the given
     3733 *      window with a new title text.
     3734 *
     3735 *@@added V1.0.1 (2003-01-25) [umoeller]
     3736 */
     3737
     3738BOOL winhUpdateTasklist(HWND hwnd,
     3739                        PCSZ pcszNewTitle)
     3740{
     3741    HSWITCH hsw;
     3742    if (hsw = WinQuerySwitchHandle(hwnd, 0))
     3743    {
     3744        SWCNTRL swc;
     3745        WinQuerySwitchEntry(hsw, &swc);
     3746        strhncpy0(swc.szSwtitle,
     3747                  pcszNewTitle,
     3748                  sizeof(swc.szSwtitle));
     3749        return !WinChangeSwitchEntry(hsw, &swc);
     3750    }
     3751
     3752    return FALSE;
    37653753}
    37663754
Note: See TracChangeset for help on using the changeset viewer.