- Timestamp:
- Jan 29, 2003, 7:41:39 PM (23 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/comctl.h
r242 r243 52 52 53 53 /* 54 *@@ SYSCOLORSET:54 *@@ CCTLCOLOR: 55 55 * 56 56 *@@added V1.0.1 (2002-11-30) [umoeller] 57 57 */ 58 58 59 typedef struct _ SYSCOLORSET59 typedef struct _CCTLCOLOR 60 60 { 61 61 BOOL fInheritPP; 62 63 LONG lBackIndex, 64 lForeIndex; 65 } SYSCOLORSET, *PSYSCOLORSET; 62 ULONG ulPP, 63 ulSysColor; 64 } CCTLCOLOR, *PCCTLCOLOR; 65 66 #define CTLCOL_BGND 0 67 #define CTLCOL_FGND 1 68 69 #define CCS_NOSENDCTLPTR 0x0001 66 70 67 71 /* … … 77 81 78 82 PFNWP pDefWindowProc; 79 const SYSCOLORSET *pSysColorSet; 80 81 LONG lcolBackground, 82 lcolForeground; 83 84 ULONG flCtl; // CTL_* flags 83 85 84 86 SIZEL szlWin; // current window dimensions 85 87 86 88 PSZ pszText; // window text or NULL 89 90 const CCTLCOLOR *paCtlColors; 91 ULONG cCtlColors; 92 93 PLONG palColorValues; 87 94 88 95 } DEFWINDATA, *PDEFWINDATA; … … 92 99 PDEFWINDATA pdwd, 93 100 PFNWP pDefWindowProc, 94 const SYSCOLORSET *pSysColorSet); 101 ULONG flCtl, 102 const CCTLCOLOR *paCtlColors, 103 ULONG cCtlColors); 95 104 96 105 VOID ctlRefreshColors(PDEFWINDATA pdwd); 106 107 LONG ctlQueryColor(PDEFWINDATA pdwd, ULONG ulIndex); 97 108 98 109 MRESULT ctlDefWindowProc(PDEFWINDATA pdwd, ULONG msg, MPARAM mp1, MPARAM mp2); … … 1005 1016 HPOINTER hptr; // icon to paint or NULLHANDLE 1006 1017 1007 // BOOL fPaintButtonSunk;1008 1009 1018 } XBUTTONDATA, *PXBUTTONDATA; 1010 1019 … … 1410 1419 #define WC_CCTL_CNR "ComctlCnr" 1411 1420 1421 typedef struct _CNRVIEWPORT 1422 { 1423 HWND hwndCnr; 1424 SIZEL szlWorkarea, 1425 szlWin; 1426 POINTL ptlScroll; 1427 } CNRVIEWPORT, *PCNRVIEWPORT; 1428 1429 #define CN_VIEWPORTCHANGED 159 1430 1412 1431 MRESULT EXPENTRY fnwpCnr(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2); 1413 1432 -
trunk/include/helpers/dosh.h
r234 r243 621 621 622 622 #define XOPEN_BINARY 0x10000000 623 #define XOPEN_WRITETHRU 0x20000000 623 624 624 625 APIRET doshOpen(PCSZ pcszFilename, … … 658 659 PSZ* ppszContent, 659 660 PULONG pcbRead); 661 662 BOOL doshCreateLogFilename(PSZ pszBuf, 663 PCSZ pcszFilename, 664 BOOL fAllowBootDrive); 660 665 661 666 PSZ doshCreateBackupFileName(const char* pszExisting); -
trunk/include/helpers/sem.h
r196 r243 63 63 APIRET semRelease(PFASTMTX pmtx); 64 64 65 LONG APIENTRY DosInterlockedCompareExchange(PLONG dest, LONG xchg, LONG compare);66 LONG APIENTRY DosInterlockedDecrement(PLONG);67 LONG APIENTRY DosInterlockedExchange(PLONG, LONG);68 LONG APIENTRY DosInterlockedExchangeAdd(PLONG dest, LONG incr);69 LONG APIENTRY DosInterlockedIncrement(PLONG);65 LONG APIENTRY lockCompareExchange(PLONG dest, LONG xchg, LONG compare); 66 LONG APIENTRY lockDecrement(PLONG); 67 LONG APIENTRY lockExchange(PLONG, LONG); 68 LONG APIENTRY lockExchangeAdd(PLONG dest, LONG incr); 69 LONG APIENTRY lockIncrement(PLONG); 70 70 71 71 #endif -
trunk/include/helpers/winh.h
r242 r243 673 673 ********************************************************************/ 674 674 675 #define ID_VSCROLL 100676 #define ID_HSCROLL 101677 678 BOOL XWPENTRY winhCreateScrollBars(HWND hwndParent,679 HWND *phwndV,680 HWND *phwndH);681 682 675 BOOL XWPENTRY winhUpdateScrollBar(HWND hwndScrollBar, 683 676 ULONG ulWinPels, … … 686 679 BOOL fAutoHide); 687 680 688 BOOL XWPENTRY winhHandleScrollMsg(HWND hwnd2Scroll, 689 HWND hwndScrollBar, 690 PULONG pulCurPelsOfs, 691 PRECTL prcl2Scroll, 692 LONG ulViewportPels, 693 USHORT usLineStepUnits, 681 LONG XWPENTRY winhHandleScrollMsg(HWND hwndScrollBar, 682 PLONG plCurPelsOfs, 683 LONG lWindowPels, 684 LONG lWorkareaPels, 685 USHORT usLineStepPels, 694 686 ULONG msg, 695 687 MPARAM mp2); 696 688 697 LONG XWPENTRY winhHandleScrollMsg2(HWND hwndScrollBar,698 PLONG plCurPelsOfs,699 LONG lWindowPels,700 LONG lWorkareaPels,701 USHORT usLineStepPels,702 ULONG msg,703 MPARAM mp2);704 689 BOOL XWPENTRY winhScrollWindow(HWND hwnd2Scroll, 705 690 PRECTL prclClip, … … 714 699 ULONG ulHorzMax); 715 700 701 /* 702 *@@ SCROLLABLEWINDOW: 703 * scroll data struct for use with winhHandleScrollerMsgs. 704 * 705 *@@added V1.0.1 (2003-01-25) [umoeller] 706 */ 707 708 typedef struct _SCROLLABLEWINDOW 709 { 710 LONG cxScrollBar, 711 cyScrollBar; 712 HWND hwndVScroll, // vertical scroll bar 713 hwndHScroll; // horizontal scroll bar 714 ULONG idVScroll, 715 idHScroll; 716 SIZEL szlWorkarea; // workarea dimensions (over which window scrolls) 717 POINTL ptlScrollOfs; // current scroll offset; positive x means right, 718 // positive y means down 719 } SCROLLABLEWINDOW, *PSCROLLABLEWINDOW; 720 721 #define ID_VSCROLL 100 722 #define ID_HSCROLL 101 723 724 BOOL XWPENTRY winhCreateScroller(HWND hwndParent, 725 PSCROLLABLEWINDOW pscrw, 726 ULONG idVScroll, 727 ULONG idHScroll); 728 729 MRESULT XWPENTRY winhHandleScrollerMsgs(HWND hwnd2Scroll, 730 PSCROLLABLEWINDOW pscrw, 731 PSIZEL pszlWin, 732 ULONG msg, 733 MPARAM mp1, 734 MPARAM mp2); 735 716 736 /* ****************************************************************** 717 737 * … … 841 861 842 862 HSWITCH XWPENTRY winhAddToTasklist(HWND hwnd, HPOINTER hIcon); 863 864 BOOL XWPENTRY winhUpdateTasklist(HWND hwnd, PCSZ pcszNewTitle); 843 865 844 866 /* ****************************************************************** -
trunk/include/private/cnr.h
r242 r243 35 35 #define WC_CCTL_CNR_DETAILS "ComctlCnrDtls" 36 36 37 extern const SYSCOLORSET G_scsCnr; 37 extern const CCTLCOLOR G_scsCnr[]; 38 39 #define CNRCOL_HILITEBGND 2 40 #define CNRCOL_HILITEFGND 3 41 #define CNRCOL_BORDER 4 42 #define CNRCOL_EDITBGND 5 43 #define CNRCOL_EDITFGND 6 44 #define CNRCOL_SIZINGBOX 7 38 45 39 46 #define COLUMN_PADDING_X 7 … … 53 60 const FIELDINFO *pfi; // ptr to fieldinfo for this column 54 61 55 LONG cx Total;// current width of the column (excluding padding);62 LONG cxContent; // current width of the column (excluding padding); 56 63 // -- if pfi->cxWidth == 0, this is the computed auto-size; 57 64 // -- otherwise this is a copy of the pfi->cxWidth value … … 61 68 SIZEL szlTitleData; // dimensions of title data (excluding padding) 62 69 63 LONG xLeft; // position of column in cnr workspace coordinates 70 LONG xLeft; // left border of column in cnr workspace coordinates; 71 // this includes spacing, i.e. is 0 for the leftmost column 64 72 65 73 } DETAILCOLUMN, *PDETAILCOLUMN; … … 79 87 *precc, // ptr to app's RECORDCORE buffer 80 88 *preccParent; // parent of record or NULL if root 89 90 ULONG flRecordAttr; // private copy of record's attributes 91 92 ULONG flInvalidate; // CMA_TEXTCHANGED et al flags from 93 // CM_INVALIDATERECORD or 0 if record is fresh 94 95 POINTL ptl; // position of record as calculated by us (in 96 // workspace coordinates) 81 97 82 98 SIZEL szlContent; // space that records needs in current cnr view … … 84 100 SIZEL szlBox; // space that records needs in current cnr view 85 101 // (including padding) 86 LONG yOfs; // y offset of the top of this record's rectangle102 // LONG yOfs; // y offset of the top of this record's rectangle 87 103 // from the top of the cnr workspace. Positive 88 104 // values mean the record is further down. … … 109 125 /* 110 126 *@@ CNRDATA: 111 * 127 * private container data, allocated on WM_CREATE and 128 * stored at QWL_USER + 1 in the container main and 129 * subwindows. 112 130 */ 113 131 … … 117 135 dwdContent; 118 136 119 BOOL fMiniRecords; 120 121 CNRINFO CnrInfo; 137 BOOL fMiniRecords; // set to TRUE on WM_CREATE if we have the 138 // CCS_MINIRECORDCORE style bit set 139 140 CNRINFO CnrInfo; // private container info struct 122 141 123 142 LINKLIST llAllocatedFIs; // contains PFIELDINFO's that were allocated, auto-free … … 133 152 134 153 // paint data 135 FONTMETRICS fm; 136 COUNTRYSETTINGS2 cs; 137 138 HWND hwndDetails; // child of main cnr window 139 140 HWND hwndVScroll, // child of hwndDetails 141 hwndHScroll; 142 143 LONG cxScrollBar, 144 cyScrollBar; 154 155 COUNTRYSETTINGS2 cs; // current NLS settings for painting CMA_DATE etc. 156 157 FONTMETRICS fm; // font metrics of current font 145 158 146 159 LONG cyColTitlesContent, // if CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES, height of … … 148 161 cyColTitlesBox; // ... and including those 149 162 150 SIZEL szlWorkarea; // dimensions of cnr workarea (area that window scrolls over) 151 152 POINTL ptlScrollOfs; // scroll ofs: x = 0 means topmost, y = 0 means leftmost 163 BOOL fSettingPP; // anti-recursion flag 164 165 // scrolling data 166 167 SCROLLABLEWINDOW scrw; 168 169 // selection data 170 171 PRECORDLISTITEM 172 prliCursored; // currently cursored record (there can only be one ever) 173 174 PRECORDLISTITEM 175 prliSwipingFirst; // set to record on which swipe select started; NULL if 176 // we're not currently swipe-selecting 177 BOOL fSwipeTurnOn; // if TRUE, we select records while swiping; if FALSE, 178 // we deselect 153 179 154 180 } CNRDATA, *PCNRDATA; 155 181 156 182 // bits for WM_SEM2 157 #define DDFL_INVALIDATECOLUMNS 0x0001 158 // no. of columns changed 159 160 #define DDFL_INCALIDATERECORDS 0x0002 161 162 #define DDFL_WINDOWSIZECHANGED 0x0004 163 164 #define DDFL_WORKAREACHANGED 0x0008 183 #define DDFL_INVALIDATECOLUMNS 0x0001 184 // no. of columns changed, recompute column data 185 186 #define DDFL_INVALIDATERECORDS 0x0002 187 // record data changed, recompute all records and adjust columns 188 189 #define DDFL_INVALIDATESOME 0x0004 190 // some records changed, recompute only those that have szlContent.x == -1 191 192 #define DDFL_WINDOWSIZECHANGED 0x0008 193 // subwindows need repositioning 194 195 #define DDFL_WORKAREACHANGED 0x0010 196 // cnr workarea changed, adjust scrollbars 165 197 166 198 #define DDFL_ALL 0xFFFF … … 172 204 ********************************************************************/ 173 205 174 VOID cnrDrawString(HPS hps, 206 VOID ctnrInit(HWND hwnd, 207 MPARAM mp2, 208 ULONG flMainCnrStyle, 209 PDEFWINDATA pdwd); 210 211 VOID ctnrDrawString(HPS hps, 175 212 PCSZ pcsz, 176 213 PRECTL prcl, … … 178 215 PFONTMETRICS pfm); 179 216 180 VOID cnrPresParamChanged(HWND hwnd, 217 VOID ctnrGetRecordRect(PCNRDATA pData, 218 PRECTL prcl, 219 const RECORDLISTITEM *prli); 220 221 BOOL ctnrRepaintRecord(PCNRDATA pData, 222 const RECORDLISTITEM *prli); 223 224 ULONG ctnrQuerySelMode(PCNRDATA pData); 225 226 BOOL ctnrChangeEmphasis(PCNRDATA pData, 227 PRECORDLISTITEM prliSet, 228 BOOL fTurnOn, 229 ULONG fsEmphasis); 230 231 VOID ctnrPresParamChanged(HWND hwnd, 181 232 ULONG ulpp); 233 234 BOOL ctnrSetRecordEmphasis(PCNRDATA pData, 235 PRECORDCORE precc, 236 BOOL fTurnOn, 237 USHORT fsEmphasis, 238 BOOL fMouse); 239 240 VOID ctnrRecordEnter(PCNRDATA pData, 241 const RECORDLISTITEM *prli, 242 BOOL fKeyboard); 243 244 PLISTNODE ctnrFindListNodeForRecc(PCNRDATA pData, 245 const RECORDCORE *precc); 182 246 183 247 VOID cdtlRecalcDetails(PCNRDATA pData, -
trunk/src/helpers/_call_filedlg.c
r242 r243 15 15 #define INCL_WINSTDCNR 16 16 #define INCL_WINSTDFILE 17 #define INCL_WINTIMER 17 18 18 19 #include <os2.h> … … 29 30 #include "helpers\cnrh.h" 30 31 #include "helpers\comctl.h" 32 #include "helpers\nls.h" 31 33 #include "helpers\standards.h" 34 #include "helpers\stringh.h" 32 35 #include "helpers\winh.h" 33 36 #include "helpers\gpih.h" … … 106 109 } GROUPRECORD, *PGROUPRECORD; 107 110 111 PFNWP G_pfnwpFrameOrig; 112 113 #define RECORD_COUNT 20000 114 115 PGROUPRECORD G_paRecs[RECORD_COUNT]; 116 117 CHAR G_szText[] = "Longer test string with increasing length"; 118 119 /* 120 *@@ fnwpSubclFrame: 121 * 122 */ 123 124 MRESULT 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 108 239 /* 109 240 *@@ main: … … 203 334 | FCF_SHELLPOSITION 204 335 | FCF_TASKLIST, 205 0, //XFCF_TOOLBAR | XFCF_FORCETBOWNER | XFCF_STATUSBAR,336 XFCF_TOOLBAR | XFCF_FORCETBOWNER | XFCF_STATUSBAR, 206 337 WS_VISIBLE, // ulFrameStyle 207 338 "Test File Dialog", // pcszFrameTitle 208 339 0, // ulResourcesID 209 #if 1 340 #ifdef __USE_PM_CNR__ 341 WC_CONTAINER, 342 #else 210 343 WC_CCTL_CNR, 211 #else212 WC_CONTAINER,213 344 #endif 214 WS_VISIBLE ,// flStyleClient345 WS_VISIBLE | CCS_EXTENDSEL, // flStyleClient 215 346 0, // ulID 216 347 NULL, … … 262 393 WinSendMsg(hwndFrame, WM_UPDATEFRAME, MPNULL, MPNULL); 263 394 395 if (G_pfnwpFrameOrig = WinSubclassWindow(hwndFrame, fnwpSubclFrame)) 264 396 { 265 397 XFIELDINFO xfi[4]; … … 270 402 // set up cnr details view 271 403 xfi[i].ulFieldOffset = FIELDOFFSET(GROUPRECORD, gid); 272 xfi[i].pszColumnTitle = " Group ID"; // @@todo localize404 xfi[i].pszColumnTitle = "gid"; 273 405 xfi[i].ulDataType = CFA_ULONG; 274 406 xfi[i++].ulOrientation = CFA_RIGHT; … … 297 429 } END_CNRINFO(hwndClient); 298 430 299 #define RECORD_COUNT 200300 301 431 if (preccFirst = (PGROUPRECORD)cnrhAllocRecords(hwndClient, 302 432 sizeof(GROUPRECORD), 303 433 RECORD_COUNT)) 304 434 { 305 PGROUPRECORD preccThis = preccFirst; 435 PGROUPRECORD preccThis = preccFirst, 436 preccEmph; 306 437 ULONG ul = 0; 307 438 while (preccThis) 308 439 { 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 309 448 preccThis->gid = ul++; 310 449 sprintf(preccThis->szGroupName, "group %d", preccThis->gid); … … 323 462 CRA_RECORDREADONLY, 324 463 RECORD_COUNT); 464 465 WinSendMsg(hwndClient, 466 CM_SETRECORDEMPHASIS, 467 (MPARAM)preccEmph, 468 MPFROM2SHORT(TRUE, CRA_SELECTED)); 325 469 } 326 470 } 327 471 472 WinStartTimer(hab, hwndFrame, 1, 100); 473 328 474 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); 349 476 350 477 WinDestroyMsgQueue(hmq); -
trunk/src/helpers/cctl_checkcnr.c
r238 r243 357 357 *@@added V0.9.0 (99-11-29) [umoeller] 358 358 *@@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 359 360 */ 360 361 … … 457 458 } 458 459 } 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); 459 464 break; 460 465 -
trunk/src/helpers/cctl_cnr.c
r242 r243 28 28 #define INCL_WINWINDOWMGR 29 29 #define INCL_WINFRAMEMGR 30 #define INCL_WININPUT 30 31 #define INCL_WINSYS 31 32 #define INCL_WINSCROLLBARS … … 62 63 ********************************************************************/ 63 64 64 extern const SYSCOLORSET G_scsCnr = 65 { 66 TRUE, // inherit presparams 67 SYSCLR_WINDOW, 68 SYSCLR_WINDOWTEXT 65 extern 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 69 75 }; 70 76 … … 75 81 ********************************************************************/ 76 82 77 VOID cnrDrawString(HPS hps, 83 /* 84 *@@ ctnrInit: 85 * 86 */ 87 88 VOID 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 109 VOID ctnrDrawString(HPS hps, 78 110 PCSZ pcsz, // in: string to test 79 111 PRECTL prcl, // in: clipping rectangle (inclusive!) … … 115 147 116 148 /* 149 *@@ ctnrGetRecordRect: 150 * returns the rectangle of the given record 151 * converted to window coordinates. Works for 152 * all views. 153 */ 154 155 VOID 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 173 BOOL 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 189 ULONG 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 215 BOOL 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 265 VOID 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 /* 117 280 *@@ CreateChild: 118 281 * creates a container child window. 119 282 */ 120 283 121 HWND CreateChild(PCNRDATA pData,122 PCSZ pcszClass,123 ULONG id)284 STATIC HWND CreateChild(PCNRDATA pData, 285 PCSZ pcszClass, 286 ULONG id) 124 287 { 125 288 return WinCreateWindow(pData->dwdMain.hwnd, … … 143 306 */ 144 307 145 PDETAILCOLUMN FindColumnFromFI(PCNRDATA pData,146 const FIELDINFO *pfi,147 PLISTNODE *ppNode) // out: listnode of column308 STATIC PDETAILCOLUMN FindColumnFromFI(PCNRDATA pData, 309 const FIELDINFO *pfi, 310 PLISTNODE *ppNode) // out: listnode of column 148 311 { 149 312 PLISTNODE pNode; 150 313 FOR_ALL_NODES(&pData->llColumns, pNode) 151 314 { 152 PDETAILCOLUMN pCol = pNode->pItemData;315 PDETAILCOLUMN pCol = (PDETAILCOLUMN)pNode->pItemData; 153 316 if (pCol->pfi == pfi) 154 317 { … … 164 327 165 328 /* 166 *@@ FindListNodeForRecc:167 * 168 */ 169 170 PLISTNODE FindListNodeForRecc(PCNRDATA pData,171 const RECORDCORE *precc)329 *@@ ctnrFindListNodeForRecc: 330 * 331 */ 332 333 PLISTNODE ctnrFindListNodeForRecc(PCNRDATA pData, 334 const RECORDCORE *precc) 172 335 { 173 336 RECORDTREEITEM *pti; … … 180 343 } 181 344 345 VOID 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 363 VOID 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 182 393 /* ****************************************************************** 183 394 * … … 191 402 */ 192 403 193 MRESULT CnrCreate(HWND hwnd, MPARAM mp1, MPARAM mp2) 404 STATIC MRESULT CnrCreate(HWND hwnd, 405 MPARAM mp1, 406 MPARAM mp2) 194 407 { 195 408 PCNRDATA pData; … … 202 415 203 416 // 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) 211 423 pData->fMiniRecords = TRUE; 212 424 … … 229 441 nlsQueryCountrySettings(&pData->cs); 230 442 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); 237 447 238 448 return (MRESULT)FALSE; … … 248 458 */ 249 459 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)) 460 STATIC 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) 258 483 { 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; 265 486 } 266 487 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) 268 502 { 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)); 335 514 } 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); 336 534 } 337 535 } … … 341 539 *@@ CnrPaint: 342 540 * 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 547 STATIC VOID CnrPaint(PCNRDATA pData) 548 { 549 HPS hps; 550 RECTL rclPaint; 551 552 if ( (pData) 553 && (hps = WinBeginPaint(pData->dwdMain.hwnd, NULLHANDLE, &rclPaint)) 353 554 ) 354 555 { … … 376 577 WinFillRect(hps, 377 578 &rclPaint, 378 pData->dwdMain.lcolBackground);579 ctlQueryColor(&pData->dwdMain, CTLCOL_BGND)); 379 580 380 581 FOR_ALL_NODES(&pData->llColumns, pColNode) … … 386 587 ULONG cRow; 387 588 388 rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData-> ptlScrollOfs.x;389 rcl.xRight = rcl.xLeft + pCol->cx Total;589 rcl.xLeft = pCol->xLeft + COLUMN_PADDING_X - pData->scrw.ptlScrollOfs.x; 590 rcl.xRight = rcl.xLeft + pCol->cxContent; 390 591 391 592 // we start out at the top and work our way down, … … 402 603 else 403 604 { 404 c nrDrawString(hps,605 ctnrDrawString(hps, 405 606 (PCSZ)pfi->pTitleData, 406 607 &rcl, … … 438 639 */ 439 640 440 MRESULT CnrWindowPosChanged(HWND hwnd,441 MPARAM mp1,442 MPARAM mp2)641 STATIC MRESULT CnrWindowPosChanged(PCNRDATA pData, 642 MPARAM mp1, 643 MPARAM mp2) 443 644 { 444 645 MRESULT mrc = 0; 445 PCNRDATA pData; 446 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))646 647 if (pData) 447 648 { 448 649 mrc = ctlDefWindowProc(&pData->dwdMain, WM_WINDOWPOSCHANGED, mp1, mp2); … … 450 651 if (((PSWP)mp1)->fl & SWP_SIZE) 451 652 { 452 WinPostMsg( hwnd,653 WinPostMsg(pData->dwdMain.hwnd, 453 654 WM_SEM2, 454 655 (MPARAM)DDFL_WINDOWSIZECHANGED, … … 461 662 462 663 /* 463 *@@ c nrPresParamChanged:664 *@@ ctnrPresParamChanged: 464 665 * implementation for WM_PRESPARAMCHANGED for both 465 666 * fnwpCnr and fnwpCnrDetails. 466 667 */ 467 668 468 VOID c nrPresParamChanged(HWND hwnd,669 VOID ctnrPresParamChanged(HWND hwnd, // in: either main cnr or content subwindow 469 670 ULONG ulpp) 470 671 { 471 PCNRDATA pData;672 PCNRDATA pData; 472 673 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1)) 473 674 { 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 476 678 ctlRefreshColors(&pData->dwdMain); 477 679 … … 480 682 case 0: // layout palette thing dropped 481 683 case PP_FONTNAMESIZE: 482 if ( pData->CnrInfo.flWindowAttr & CV_DETAIL)684 if (!pData->fSettingPP) 483 685 { 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) 489 689 { 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); 499 710 } 500 711 501 WinPostMsg(pData->dwdMain.hwnd, 502 WM_SEM2, 503 (MPARAM)(DDFL_INVALIDATECOLUMNS | DDFL_INCALIDATERECORDS), 504 0); 712 pData->fSettingPP = FALSE; 505 713 } 506 714 break; … … 518 726 */ 519 727 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 { 728 STATIC VOID CnrScroll(PCNRDATA pData, 729 ULONG msg, 730 MPARAM mp1, 731 MPARAM mp2) 732 { 733 if (pData) 734 { 735 BOOL fNotify = FALSE; 736 525 737 if (pData->CnrInfo.flWindowAttr & CV_DETAIL) 526 738 { 527 POINTL ptlScroll; 739 POINTL ptlScroll; 740 NOTIFYSCROLL ns; 741 ns.hwndCnr = pData->dwdMain.hwnd; 742 528 743 if (msg == WM_HSCROLL) 529 744 { 530 745 ptlScroll.y = 0; 531 if (ptlScroll.x = winhHandleScrollMsg 2(pData->hwndHScroll,532 &pData->ptlScrollOfs.x,533 534 pData->szlWorkarea.cx,535 536 537 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)) 538 753 { 754 winhScrollWindow(pData->dwdContent.hwnd, 755 NULL, 756 &ptlScroll); 757 758 // scroll main cnr with detail titles too 539 759 if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES) 540 760 { … … 544 764 rclClip.yBottom = pData->dwdMain.szlWin.cy - pData->cyColTitlesBox; 545 765 rclClip.yTop = pData->dwdMain.szlWin.cy; 546 winhScrollWindow( hwnd,766 winhScrollWindow(pData->dwdMain.hwnd, 547 767 &rclClip, 548 768 &ptlScroll); 549 769 } 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; 553 778 } 554 779 } … … 556 781 { 557 782 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, 566 792 NULL, 567 793 &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 } 568 803 } 569 804 } 805 806 if (fNotify) 807 SendViewportChanged(pData); 570 808 } 571 809 } … … 576 814 */ 577 815 578 VOID CnrDestroy(HWND hwnd) 579 { 580 PCNRDATA pData; 581 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1)) 816 STATIC VOID CnrDestroy(PCNRDATA pData) 817 { 818 if (pData) 582 819 { 583 820 // free all data that we ever allocated; … … 605 842 */ 606 843 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)) 844 STATIC 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) 613 849 { 614 850 USHORT cbCopied = max(cb, sizeof(CNRINFO)); … … 629 865 */ 630 866 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)) 867 STATIC 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) 637 872 { 638 873 ULONG flDirty = 0; … … 680 915 if (pData->CnrInfo.flWindowAttr & CV_DETAIL) 681 916 { 682 if (!pData-> hwndDetails)917 if (!pData->dwdContent.hwnd) 683 918 { 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)) 687 922 { 688 923 flDirty = DDFL_ALL; … … 692 927 else 693 928 { 694 winhDestroyWindow(&pData-> hwndDetails);929 winhDestroyWindow(&pData->dwdContent.hwnd); 695 930 } 696 931 } … … 782 1017 // flWindowAttr field is not specified, these lines are not drawn. 783 1018 pData->CnrInfo.cxTreeLine = pci->cxTreeLine; 1019 1020 // @@todo recalc window components, repaint 784 1021 } 785 1022 … … 790 1027 // value is negative one (-1). 791 1028 pData->CnrInfo.xVertSplitbar = pci->xVertSplitbar; 1029 1030 // @@todo recalc window components, repaint 792 1031 } 793 1032 794 1033 if (flDirty) 795 1034 // post semaphore to force resize of details wnd 796 WinPostMsg( hwnd,1035 WinPostMsg(pData->dwdMain.hwnd, 797 1036 WM_SEM2, 798 1037 (MPARAM)flDirty, … … 805 1044 } 806 1045 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 1057 STATIC 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 807 1098 /* ****************************************************************** 808 1099 * … … 818 1109 */ 819 1110 820 PFIELDINFO CnrAllocDetailFieldInfo(HWND hwnd,821 USHORT cFieldInfos) // in: no. of fieldinfos to allocate (> 0)1111 STATIC PFIELDINFO CnrAllocDetailFieldInfo(PCNRDATA pData, 1112 USHORT cFieldInfos) // in: no. of fieldinfos to allocate (> 0) 822 1113 { 823 1114 PFIELDINFO pfiFirst = NULL, 824 1115 pfiPrev = NULL; 825 1116 826 PCNRDATA pData; 827 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1)) 1117 if (pData) 828 1118 { 829 1119 ULONG ul; … … 863 1153 */ 864 1154 865 USHORT CnrInsertDetailFieldInfo(HWND hwnd,866 PFIELDINFO pfiFirst,867 PFIELDINFOINSERT pfii)1155 STATIC USHORT CnrInsertDetailFieldInfo(PCNRDATA pData, 1156 PFIELDINFO pfiFirst, 1157 PFIELDINFOINSERT pfii) 868 1158 { 869 1159 USHORT usrc = 0; 870 PCNRDATA pData; 871 if ( (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))1160 1161 if ( (pData) 872 1162 && (pfiFirst) 873 1163 && (pfii) … … 933 1223 { 934 1224 // post semaphore to force resize of details wnd 935 WinPostMsg( hwnd,1225 WinPostMsg(pData->dwdMain.hwnd, 936 1226 WM_SEM2, 937 1227 (MPARAM)DDFL_ALL, … … 948 1238 */ 949 1239 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 } 1240 STATIC BOOL CnrInvalidateDetailFieldInfo(PCNRDATA pData) 1241 { 1242 if (pData) 1243 return WinPostMsg(pData->dwdMain.hwnd, 1244 WM_SEM2, 1245 (MPARAM)DDFL_INVALIDATECOLUMNS, 1246 0); 960 1247 961 1248 return FALSE; 1249 } 1250 1251 /* 1252 *@@ CnrQueryDetailFieldInfo: 1253 * implementation for CM_QUERYDETAILFIELDINFO in fnwpCnr. 1254 */ 1255 1256 STATIC 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; 962 1293 } 963 1294 … … 967 1298 */ 968 1299 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)) 1300 STATIC SHORT CnrRemoveDetailFieldInfo(PCNRDATA pData, 1301 PFIELDINFO* ppafi, 1302 USHORT cfi, 1303 USHORT fl) 1304 { 1305 if (pData) 976 1306 { 977 1307 SHORT rc = lstCountItems(&pData->llColumns); … … 1011 1341 ) 1012 1342 { 1013 WinPostMsg( hwnd,1343 WinPostMsg(pData->dwdMain.hwnd, 1014 1344 WM_SEM2, 1015 1345 (MPARAM)DDFL_INVALIDATECOLUMNS, … … 1028 1358 */ 1029 1359 1030 BOOL CnrFreeDetailFieldInfo(HWND hwnd,1031 PFIELDINFO *ppafi, // in: mp1 of CM_FREEDETAILFIELDINFO1032 USHORT cFieldInfos) // in: no. of items in array1360 STATIC BOOL CnrFreeDetailFieldInfo(PCNRDATA pData, 1361 PFIELDINFO *ppafi, // in: mp1 of CM_FREEDETAILFIELDINFO 1362 USHORT cFieldInfos) // in: no. of items in array 1033 1363 { 1034 1364 BOOL brc = FALSE; 1035 1365 1036 PCNRDATA pData; 1037 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1)) 1366 if (pData) 1038 1367 { 1039 1368 ULONG ul; … … 1070 1399 */ 1071 1400 1072 PRECORDCORE CnrAllocRecord(HWND hwnd,1073 ULONG cbExtra,1074 USHORT cRecords)1401 STATIC PRECORDCORE CnrAllocRecord(PCNRDATA pData, 1402 ULONG cbExtra, 1403 USHORT cRecords) 1075 1404 { 1076 1405 PRECORDCORE preccFirst = NULL; 1077 PCNRDATA pData; 1078 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))1406 1407 if (pData) 1079 1408 { 1080 1409 ULONG ul; … … 1124 1453 */ 1125 1454 1126 ULONG CnrInsertRecord(HWND hwnd,1127 PRECORDCORE preccFirst,1128 PRECORDINSERT pri)1455 STATIC ULONG CnrInsertRecord(PCNRDATA pData, 1456 PRECORDCORE preccFirst, 1457 PRECORDINSERT pri) 1129 1458 { 1130 1459 ULONG cReturn = 0; 1131 PCNRDATA pData; 1132 if ( (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))1460 1461 if ( (pData) 1133 1462 && (preccFirst) 1134 1463 && (pri) … … 1163 1492 1164 1493 default: 1165 pNodeInsertAfter = FindListNodeForRecc(pData,1166 pri->pRecordOrder);1494 pNodeInsertAfter = ctnrFindListNodeForRecc(pData, 1495 pri->pRecordOrder); 1167 1496 } 1168 1497 … … 1171 1500 ++ul) 1172 1501 { 1173 PRECORDLISTITEM p ListItem;1174 1175 if (p ListItem= NEW(RECORDLISTITEM))1502 PRECORDLISTITEM prli; 1503 1504 if (prli = NEW(RECORDLISTITEM)) 1176 1505 { 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 } 1181 1525 1182 1526 if (pNodeInsertAfter = lstInsertItemAfterNode(pll, 1183 p ListItem,1527 prli, 1184 1528 pNodeInsertAfter)) 1185 1529 { … … 1212 1556 } 1213 1557 1214 free(p ListItem);1558 free(prli); 1215 1559 } 1216 1560 1217 free(p ListItem);1561 free(prli); 1218 1562 1219 1563 cReturn = 0; … … 1225 1569 ) 1226 1570 { 1227 WinPostMsg( hwnd,1571 WinPostMsg(pData->dwdMain.hwnd, 1228 1572 WM_SEM2, 1229 (MPARAM)DDFL_IN CALIDATERECORDS,1573 (MPARAM)DDFL_INVALIDATERECORDS, 1230 1574 0); 1231 1575 } … … 1235 1579 } 1236 1580 1581 /* 1582 *@@ CnrInsertRecordArray: 1583 * implementation for CM_INSERTRECORDARRAY in fnwpCnr. 1584 */ 1585 1586 STATIC 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 1623 STATIC 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 1665 PRECORDCORE 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 1700 STATIC 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 1237 1744 /* ****************************************************************** 1238 1745 * … … 1249 1756 { 1250 1757 MRESULT mrc = 0; 1251 PCNRDATA pData; 1758 1759 PCNRDATA pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1); 1252 1760 1253 1761 switch (msg) … … 1264 1772 1265 1773 case WM_SEM2: 1266 CnrSem2( hwnd, (ULONG)mp1);1774 CnrSem2(pData, (ULONG)mp1); 1267 1775 break; 1268 1776 1269 1777 case WM_PAINT: 1270 CnrPaint( hwnd);1778 CnrPaint(pData); 1271 1779 break; 1272 1780 1273 1781 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); 1275 1791 break; 1276 1792 1277 1793 case WM_HSCROLL: 1278 1794 case WM_VSCROLL: 1279 CnrScroll( hwnd, msg, mp1, mp2);1795 CnrScroll(pData, msg, mp1, mp2); 1280 1796 break; 1281 1797 1282 1798 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; 1284 1820 break; 1285 1821 … … 1301 1837 */ 1302 1838 1303 case CM_QUERYCNRINFO: 1304 mrc = (MRESULT)CnrQueryCnrInfo( hwnd,1839 case CM_QUERYCNRINFO: // done 1840 mrc = (MRESULT)CnrQueryCnrInfo(pData, 1305 1841 (PCNRINFO)mp1, 1306 (USHORT)mp2);1842 SHORT1FROMMP(mp2)); 1307 1843 break; 1308 1844 … … 1319 1855 */ 1320 1856 1321 case CM_SETCNRINFO: 1322 mrc = (MRESULT)CnrSetCnrInfo( hwnd,1857 case CM_SETCNRINFO: // parlty done 1858 mrc = (MRESULT)CnrSetCnrInfo(pData, 1323 1859 (PCNRINFO)mp1, 1324 1860 (ULONG)mp2); 1325 1861 break; 1326 1862 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 1327 1892 /* ****************************************************************** 1328 1893 * 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 1330 2069 * 1331 2070 ********************************************************************/ … … 1343 2082 */ 1344 2083 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)); 1348 2087 break; 1349 2088 … … 1360 2099 */ 1361 2100 1362 case CM_INSERTDETAILFIELDINFO: 1363 mrc = (MRESULT)CnrInsertDetailFieldInfo( hwnd,2101 case CM_INSERTDETAILFIELDINFO: // done 2102 mrc = (MRESULT)CnrInsertDetailFieldInfo(pData, 1364 2103 (PFIELDINFO)mp1, 1365 2104 (PFIELDINFOINSERT)mp2); … … 1373 2112 */ 1374 2113 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)); 1377 2132 break; 1378 2133 … … 1391 2146 */ 1392 2147 1393 case CM_REMOVEDETAILFIELDINFO: 1394 mrc = (MRESULT)CnrRemoveDetailFieldInfo( hwnd,2148 case CM_REMOVEDETAILFIELDINFO: // done 2149 mrc = (MRESULT)CnrRemoveDetailFieldInfo(pData, 1395 2150 (PFIELDINFO*)mp1, 1396 2151 SHORT1FROMMP(mp2), … … 1409 2164 */ 1410 2165 1411 case CM_FREEDETAILFIELDINFO: 1412 mrc = (MRESULT)CnrFreeDetailFieldInfo( hwnd,2166 case CM_FREEDETAILFIELDINFO: // done 2167 mrc = (MRESULT)CnrFreeDetailFieldInfo(pData, 1413 2168 (PFIELDINFO*)mp1, 1414 (USHORT)mp2); 2169 SHORT1FROMMP(mp2)); 2170 break; 2171 2172 case CM_HORZSCROLLSPLITWINDOW: 1415 2173 break; 1416 2174 1417 2175 /* ****************************************************************** 1418 2176 * 1419 * Record allocation/insertion/removal2177 * Icon view 1420 2178 * 1421 2179 ********************************************************************/ 1422 2180 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 1458 2208 1459 2209 default: 1460 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))2210 if (pData) 1461 2211 mrc = ctlDefWindowProc(&pData->dwdMain, msg, mp1, mp2); 1462 2212 break; -
trunk/src/helpers/cctl_cnr_dtls.c
r242 r243 26 26 // as unsigned char 27 27 28 #define INCL_DOSMISC 29 28 30 #define INCL_WINWINDOWMGR 29 31 #define INCL_WINFRAMEMGR 30 32 #define INCL_WINSYS 33 #define INCL_WININPUT 31 34 #define INCL_WINSTDCNR 32 35 #define INCL_GPIPRIMITIVES … … 61 64 62 65 /* 66 *@@ InvalidateColumn: 67 * 68 */ 69 70 VOID 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 /* 63 87 *@@ cdtlRecalcDetails: 64 88 * worker routine for refreshing all internal DETAILCOLUMN … … 68 92 * in with sufficient update flags. 69 93 * 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. 71 99 * 72 100 * -- DDFL_WINDOWSIZECHANGED: cnr titles area changed, … … 79 107 VOID cdtlRecalcDetails(PCNRDATA pData, 80 108 HPS hps, 81 PULONG pfl) 109 PULONG pfl) // in/out: DDFL_* flags 82 110 { 83 111 LONG xCurrent = 0; 84 112 PLISTNODE pColNode; 85 ULONG c Row= 0;113 ULONG cColumn = 0; 86 114 87 115 // 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; 91 117 LONG cyColTitlesContent = 0, 92 118 cyColTitlesBox = 0; 93 119 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 94 130 GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &pData->fm); 95 131 … … 97 133 FOR_ALL_NODES(&pData->llColumns, pColNode) 98 134 { 99 PDETAILCOLUMN pCol = (PDETAILCOLUMN)pColNode->pItemData;100 const FIELDINFO *pfi = pCol ->pfi;135 PDETAILCOLUMN pColumn = (PDETAILCOLUMN)pColNode->pItemData; 136 const FIELDINFO *pfi = pColumn->pfi; 101 137 PLISTNODE pRecNode; 102 138 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) 129 154 { 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)) 165 276 { 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 } 213 308 else 214 309 { 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; 221 312 } 222 223 pCol->cxTotal = max(pCol->cxWidestRecord, pCol->szlTitleData.cx);224 225 if (pCol->szlTitleData.cy > cyColTitlesContent)226 cyColTitlesContent = pCol->szlTitleData.cy;227 313 } 228 else 314 315 // check if column needs invalidating 316 if ( (fRefreshAll) 317 || (pColumn->xLeft != xCurrent) 318 || (pColumn->cxContent != cxContent) 319 ) 229 320 { 230 pCol->szlTitleData.cx 231 = 0; 321 pColumn->xLeft = xCurrent; 322 pColumn->cxContent = cxContent; 323 324 if (!fRefreshAll) 325 InvalidateColumn(pData, 326 pColumn); 232 327 } 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) 246 344 ) 247 345 { 248 pData->s zlWorkarea.cx = xCurrent;249 pData->s zlWorkarea.cy = yOfsNow;346 pData->scrw.szlWorkarea.cx = xCurrent; 347 pData->scrw.szlWorkarea.cy = yNow; 250 348 *pfl |= DDFL_WORKAREACHANGED; 251 349 } 252 350 351 // has details title box changed? 253 352 if (pData->CnrInfo.flWindowAttr & CA_DETAILSVIEWTITLES) 254 353 cyColTitlesBox = cyColTitlesContent … … 265 364 *pfl |= DDFL_WINDOWSIZECHANGED | DDFL_WORKAREACHANGED; 266 365 } 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); 267 381 } 268 382 … … 276 390 MRESULT DetailsCreate(HWND hwnd, MPARAM mp1, MPARAM mp2) 277 391 { 278 if (!mp1) 392 HWND hwndParent; 393 394 if ( (!mp1) 395 || (!mp2) 396 || (!(hwndParent = (((PCREATESTRUCT)mp2)->hwndParent))) 397 ) 279 398 return (MRESULT)TRUE; 280 399 … … 282 401 283 402 // 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? 289 410 290 411 return (MRESULT)FALSE; … … 297 418 */ 298 419 299 VOID DetailsPaint( HWND hwnd)420 VOID DetailsPaint(PCNRDATA pData) 300 421 { 301 422 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 313 430 LONG yPadding = pData->CnrInfo.cyLineSpacing / 2; 314 431 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; 315 443 316 444 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 317 457 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) 322 478 { 323 479 PDETAILCOLUMN pCol = (PDETAILCOLUMN)pColNode->pItemData; 324 480 const FIELDINFO *pfi = pCol->pfi; 325 481 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)) 340 484 { 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) 356 492 { 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 } 389 514 } 390 515 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 674 PRECORDLISTITEM 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 705 VOID 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 734 MRESULT 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 774 MRESULT 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 821 MRESULT 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 850 MRESULT 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 871 MRESULT 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 896 VOID 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 975 MRESULT 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; 401 1107 } 402 1108 403 // paint vertical separators after this column? 404 if (pfi->flData & CFA_SEPARATOR) 1109 if (prliScrollTo) 405 1110 { 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; 413 1126 } 414 415 ++cColumn; 416 417 } // FOR_ALL_NODES(&pData->llColumns, pColNode) 418 419 WinEndPaint(hps); 420 } 1127 } 1128 } 1129 1130 return (MRESULT)FALSE; 421 1131 } 422 1132 … … 434 1144 MRESULT EXPENTRY fnwpCnrDetails(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 435 1145 { 436 MRESULT mrc = 0;437 PCNRDATA pData ;1146 MRESULT mrc = 0; 1147 PCNRDATA pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1); 438 1148 439 1149 switch (msg) 440 1150 { 1151 /* ****************************************************************** 1152 * 1153 * Standard window messages 1154 * 1155 ********************************************************************/ 1156 441 1157 case WM_CREATE: 442 1158 mrc = DetailsCreate(hwnd, mp1, mp2); … … 444 1160 445 1161 case WM_PAINT: 446 DetailsPaint( hwnd);1162 DetailsPaint(pData); 447 1163 break; 448 1164 1165 case WM_SYSCOLORCHANGE: 1166 ctnrPresParamChanged(hwnd, 0); 1167 break; 1168 449 1169 case WM_PRESPARAMCHANGED: 450 c nrPresParamChanged(hwnd, (ULONG)mp1);1170 ctnrPresParamChanged(hwnd, (ULONG)mp1); 451 1171 break; 452 1172 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 453 1226 default: 454 if (pData = (PCNRDATA)WinQueryWindowPtr(hwnd, QWL_USER + 1))1227 if (pData) 455 1228 mrc = ctlDefWindowProc(&pData->dwdContent, msg, mp1, mp2); 456 1229 break; 457 458 1230 } 459 1231 -
trunk/src/helpers/cctl_toolbar.c
r242 r243 186 186 LONG lLeft, 187 187 lRight, 188 lColorMiddle = pbd->dwd.lcolBackground;188 lColorMiddle = ctlQueryColor(&pbd->dwd, CTLCOL_BGND); // pbd->dwd.lcolBackground; 189 189 RECTL rclWin, 190 190 rclTemp; … … 344 344 ) 345 345 { 346 GpiSetColor(hps, pbd->dwd.lcolForeground); 346 GpiSetColor(hps, 347 ctlQueryColor(&pbd->dwd, CTLCOL_FGND)); // pbd->dwd.lcolForeground); 347 348 rclTemp.yTop -= 2 * TBB_TEXTSPACING + lOfs; 348 349 rclTemp.xRight += 2 * lOfs; // twice the offset because we center horizontally … … 354 355 } 355 356 356 static const SYSCOLORSET G_scsToolbarButton =357 /* static const SYSCOLORSET G_scsToolbarButton = 357 358 { 358 359 TRUE, // inherit presparams … … 360 361 SYSCLR_BUTTONMIDDLE, 361 362 SYSCLR_MENUTEXT 363 }; 364 */ 365 366 static const CCTLCOLOR G_scsToolbarButton[] = 367 { 368 TRUE, PP_BACKGROUNDCOLOR, SYSCLR_BUTTONMIDDLE, 369 TRUE, PP_FOREGROUNDCOLOR, SYSCLR_MENUTEXT, 362 370 }; 363 371 … … 445 453 &pData->bd.dwd, 446 454 WinDefWindowProc, 447 &G_scsToolbarButton); 455 0, 456 G_scsToolbarButton, 457 ARRAYITEMCOUNT(G_scsToolbarButton)); 448 458 449 459 if ( (pcszText) … … 851 861 ********************************************************************/ 852 862 853 static const SYSCOLORSET G_scsToolbar = 854 { 855 TRUE, // inherit presparams 856 SYSCLR_MENU, 857 SYSCLR_MENUTEXT 863 static const CCTLCOLOR G_scsToolbar[] = 864 { 865 TRUE, PP_BACKGROUNDCOLOR, SYSCLR_MENU, 866 TRUE, PP_FOREGROUNDCOLOR, SYSCLR_MENUTEXT 858 867 }; 859 868 … … 1017 1026 (PVOID)pcszFont); 1018 1027 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); 1024 1029 winhStorePresParam(&ppp, 1025 1030 PP_BACKGROUNDCOLOR, … … 1027 1032 &lColor); 1028 1033 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); 1034 1035 winhStorePresParam(&ppp, 1035 1036 PP_FOREGROUNDCOLOR, … … 1112 1113 &pData->dwd, 1113 1114 WinDefWindowProc, 1114 &G_scsToolbar); 1115 0, 1116 G_scsToolbar, 1117 ARRAYITEMCOUNT(G_scsToolbar)); 1115 1118 1116 1119 pData->hwndControlsOwner = ptbcd->hwndControlsOwner; -
trunk/src/helpers/comctl.c
r242 r243 178 178 * given window. This must be called in WM_CREATE 179 179 * 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. 181 211 * 182 212 *@@added V1.0.1 (2002-11-30) [umoeller] … … 184 214 185 215 VOID ctlInitDWD(HWND hwnd, 186 MPARAM mp2, 216 MPARAM mp2, // in: mp2 of WM_CREATE 187 217 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) 190 222 { 191 223 pdwd->hwnd = hwnd; 224 pdwd->hab = WinQueryAnchorBlock(hwnd); 225 pdwd->pDefWindowProc = pDefWindowProc; 226 pdwd->flCtl = flCtl; 192 227 pdwd->szlWin.cx = ((PCREATESTRUCT)mp2)->cx; 193 228 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); 197 233 198 234 ctlRefreshColors(pdwd); … … 207 243 VOID ctlRefreshColors(PDEFWINDATA pdwd) 208 244 { 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 269 LONG ctlQueryColor(PDEFWINDATA pdwd, ULONG ulIndex) 270 { 271 if (ulIndex < pdwd->cCtlColors) 272 return pdwd->palColorValues[ulIndex]; 273 274 return 0; 219 275 } 220 276 … … 238 294 { 239 295 MRESULT mrc = 0; 296 BOOL fCallDefault = TRUE; 297 HWND hwndOwner; 240 298 241 299 switch (msg) 242 300 { 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 243 316 case WM_SYSCOLORCHANGE: 244 317 case WM_PRESPARAMCHANGED: … … 258 331 break; 259 332 260 default: 261 mrc = pdwd->pDefWindowProc(pdwd->hwnd, msg, mp1, mp2); 333 case WM_DESTROY: 334 FREE(pdwd->palColorValues); 335 break; 262 336 } 337 338 if (fCallDefault) 339 mrc = pdwd->pDefWindowProc(pdwd->hwnd, msg, mp1, mp2); 263 340 264 341 return mrc; -
trunk/src/helpers/dosh.c
r241 r243 3270 3270 3271 3271 /* 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 3281 BOOL 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 /* 3272 3307 *@@ doshCreateBackupFileName: 3273 3308 * creates a valid backup filename of pszExisting -
trunk/src/helpers/gpih.c
r242 r243 737 737 { 738 738 ULONG cLines = strhCount(pcsz, '\n') + 1; 739 cyString = cLines * (pfm->lMaxBaselineExt + pfm->l ExternalLeading);739 cyString = cLines * (pfm->lMaxBaselineExt + pfm->lMaxDescender + pfm->lExternalLeading); 740 740 741 741 if (fl & DT_VCENTER) 742 ptlRun.y += (cyRect - cyString) / 2;742 ptlRun.y = (cyRect - cyString) / 2; 743 743 else 744 ptlRun.y += cyRect -cyString;744 ptlRun.y = cyString; 745 745 } 746 746 … … 789 789 ptlRun.y -= pfm->lExternalLeading; 790 790 791 if (!*pNext) 792 break; 793 791 794 if (*pNext == '\r') 792 795 pNext++; 793 pThis = pNext;796 pThis = ++pNext; 794 797 } 795 798 } … … 2553 2556 LONG gpihStretchBitmap(HPS hpsTarget, // in: memory PS to copy bitmap to 2554 2557 HBITMAP hbmSource, // in: bitmap to be copied into hpsTarget (must be free) 2555 PRECTL prclSource, // in: source rectangle -- if NULL, use size of bitmap2556 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) 2557 2560 BOOL fProportional) // in: preserve proportions when stretching? 2558 2561 { -
trunk/src/helpers/helpers_post.in
r196 r243 1 1 # 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. 4 3 # 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 # 36 7 37 8 # The .OBJ-from-sources dependencies are now automatically … … 43 14 !endif 44 15 16 $(OUTPUTDIR)\interlock.obj: $(@B).asm 45 17 46 -
trunk/src/helpers/helpers_pre.in
r242 r243 1 1 # 2 2 # Pre-include file for the main helpers makefile. 3 # This contains shared definitions and all the objects4 # that have to be built.5 3 # 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 # 37 7 38 8 # The OBJS macro contains all the .OBJ files which need to be … … 101 71 $(OUTPUTDIR)\memdebug.obj\ 102 72 $(OUTPUTDIR)\memdebug_win.obj\ 73 $(OUTPUTDIR)\mmpmh.obj\ 103 74 $(OUTPUTDIR)\shapewin.obj\ 104 75 $(OUTPUTDIR)\threads.obj\ … … 108 79 $(OUTPUTDIR)\winh.obj 109 80 110 # helpers include path111 INC = ..\..\include112 HLPINC = $(INC)\helpers113 114 PROJECTINC = $(PROJECT_BASE_DIR)\include -
trunk/src/helpers/interlock.asm
r196 r243 19 19 CODE32 SEGMENT DWORD PUBLIC USE32 'CODE' 20 20 21 ;* LONG DosInterlockedIncrement(PLONG);21 ;* LONG lockIncrement(PLONG); 22 22 ;* 23 23 ;* InterlockedIncrement adds 1 to a long variable and returns … … 28 28 ;* The returned number need not be equal to the result!!!! 29 29 30 public DosInterlockedIncrement31 DosInterlockedIncrement proc near30 public lockIncrement 31 lockIncrement proc near 32 32 ;we are allowed to trash edx 33 33 mov edx, dword ptr [esp+4] ; LPLONG lpAddend … … 36 36 inc eax 37 37 ret 4 38 DosInterlockedIncrement endp38 lockIncrement endp 39 39 40 ;* LONG DosInterlockedDecrement(PLONG);40 ;* LONG lockDecrement(PLONG); 41 41 ;* 42 42 ;* InterlockedIncrement adds 1 to a long variable and returns … … 47 47 ;* The returned number need not be equal to the result!!!! 48 48 49 public DosInterlockedDecrement50 DosInterlockedDecrement proc near49 public lockDecrement 50 lockDecrement proc near 51 51 ;we are allowed to trash edx 52 52 mov edx, dword ptr [esp+4] ; LPLONG lpAddend … … 55 55 dec eax 56 56 ret 4 57 DosInterlockedDecrement endp57 lockDecrement endp 58 58 59 59 60 ; * LONG DosInterlockedExchange(PLONG, LONG);60 ; * LONG lockExchange(PLONG, LONG); 61 61 ; * 62 62 ; * Atomically exchanges a pair of values. … … 65 65 ; * Prior value of value pointed to by Target 66 66 67 public DosInterlockedExchange68 DosInterlockedExchange proc near67 public lockExchange 68 lockExchange proc near 69 69 push edx 70 70 mov eax, [esp+12] ; LONG value … … 73 73 pop edx 74 74 ret 8 75 DosInterlockedExchange endp75 lockExchange endp 76 76 77 77 78 78 ;/************************************************************************ 79 ; * LONG DosInterlockedCompareExchange(PLONG dest, LONG xchg, LONG compare)79 ; * LONG lockCompareExchange(PLONG dest, LONG xchg, LONG compare) 80 80 ; * 81 81 ; * Atomically compares Destination and Comperand, and if found equal exchanges … … 84 84 ; */ 85 85 86 public DosInterlockedCompareExchange87 DosInterlockedCompareExchange proc near86 public lockCompareExchange 87 lockCompareExchange proc near 88 88 push ebp 89 89 mov ebp, esp … … 100 100 pop ebp 101 101 ret 12 102 DosInterlockedCompareExchange endp102 lockCompareExchange endp 103 103 104 ; * LONG DosInterlockedExchangeAdd(PLONG dest, LONG incr);104 ; * LONG lockExchangeAdd(PLONG dest, LONG incr); 105 105 ; * 106 106 ; * Atomically adds Increment to Addend and returns the previous value of … … 111 111 ; */ 112 112 113 public DosInterlockedExchangeAdd114 DosInterlockedExchangeAdd proc near113 public lockExchangeAdd 114 lockExchangeAdd proc near 115 115 push edx 116 116 mov eax, dword ptr [esp+12] ;LONG Increment /* Value to add */ … … 119 119 pop edx 120 120 ret 8 121 DosInterlockedExchangeAdd endp121 lockExchangeAdd endp 122 122 123 123 CODE32 ENDS -
trunk/src/helpers/makefile
r242 r243 1 # $Id$2 3 1 # 4 2 # makefile: … … 9 7 # This makefile is even more complicated than the other makefiles 10 8 # because the helpers code has been designed to be independent 11 # of any single project. For example, the helpers code is used12 # by XWorkplace also. As a result, I had to design a way so that9 # 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 13 11 # this makefile can produce output in a variable directory, with 14 12 # 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. 16 15 # 17 16 # Even worse, with V0.9.5, I chose to create a shared runtime DLL … … 85 84 # 86 85 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 93 89 !include helpers_pre.in 94 90 … … 194 190 TESTCASE_DIR = testcase 195 191 196 DEBUGDIALOG = 192 !undef DEBUGDIALOG 197 193 !ifdef DBGDLG 198 194 DEBUGDIALOG = /DDEBUG_DIALOG_WINDOWS=1 199 195 !endif 200 196 201 TESTCASE_CC = icc /c /ti+ /w2 /ss /se /D__DEBUG__=1 $(DEBUGDIALOG) /i$(HELPERS_BASE)\include /Fo$(TESTCASE_DIR)\$(@B).obj $(@B).c 197 TESTCASE_CC_BASE = icc /c /ti+ /w2 /ss /se /D__DEBUG__=1 $(DEBUGDIALOG) /i..\..\include 198 199 TESTCASE_CC = $(TESTCASE_CC_BASE) /Fo$(TESTCASE_DIR)\$(@B).obj $(@B).c 202 200 203 201 .c.{$(TESTCASE_DIR)}.obj: … … 212 210 exeh.exe \ 213 211 fdlg.exe \ 212 fdlg_pm.exe \ 214 213 xmap.exe \ 215 214 vcard.exe … … 265 264 266 265 # fdlg.exe 267 FDLG_TEST_OBJS = \266 FDLG_TEST_OBJS_SHARED = \ 268 267 $(TESTCASE_DIR)\comctl.obj \ 269 268 $(TESTCASE_DIR)\cctl_cnr.obj \ … … 282 281 $(TESTCASE_DIR)\tree.obj \ 283 282 $(TESTCASE_DIR)\nls.obj \ 284 $(TESTCASE_DIR)\nlscache.obj \ 283 $(TESTCASE_DIR)\nlscache.obj 284 285 FDLG_TEST_OBJS = \ 286 $(FDLG_TEST_OBJS_SHARED) \ 285 287 $(TESTCASE_DIR)\_call_filedlg.obj 286 288 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 294 FDLG_TEST_OBJS_PM = \ 295 $(FDLG_TEST_OBJS_SHARED) \ 296 $(TESTCASE_DIR)\_call_filedlg_pm.obj 297 298 fdlg.exe: $(FDLG_TEST_OBJS) makefile 299 @echo $(MAKEDIR)\makefile: Linking $@ 300 ilink /nologo /debug /pmtype:pm $(FDLG_TEST_OBJS) pmprintf.lib /o:$@ 301 302 fdlg_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:$@ 289 305 290 306 # xmap.exe -
trunk/src/helpers/makefile_dll
r9 r243 21 21 !endif 22 22 23 # set up shared environment variables 24 !include ..\..\make\helpers.in 25 # define $(OBJ), which contains all object targets 23 26 !include helpers_pre.in 24 27 -
trunk/src/helpers/nls.c
r242 r243 657 657 break; 658 658 659 case 2: // yyyy.mm.dd ( Japanese)659 case 2: // yyyy.mm.dd (ISO and Japanese) 660 660 sprintf(pszDate, "%04d%c%02d%c%02d", 661 661 year, … … 849 849 850 850 for (ul = 0; 851 ul < sizeof(G_szUpperMap);851 ul < 256; 852 852 ++ul) 853 853 { … … 901 901 { 902 902 ULONG ul = 0; 903 PSZ p; 903 904 904 905 if (!G_fUpperMapInited) 905 906 InitUpperMap(); 906 907 907 if (psz) 908 { 909 PSZ p = psz; 910 908 if (p = psz) 909 { 911 910 while (*p++ = G_szUpperMap[*p]) 912 911 ++ul; -
trunk/src/helpers/nlscache.c
r236 r243 6 6 * 7 7 * Function prefixes (new with V0.81): 8 * -- stc*8 * -- nls* 9 9 * 10 10 * This file is new with V0.9.19, but contains functions -
trunk/src/helpers/sem.c
r196 r243 2 2 /* 3 3 *@@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 10 8 * the case where there is only one thread trying to 11 9 * access the critical section, i.e. it is available most … … 194 192 // do an atomic increase of the lockcounter and see if it is > 0 195 193 // (i.e. it is already posessed) 196 if ( DosInterlockedIncrement(&pmtx->LockCount))194 if (lockIncrement(&pmtx->LockCount)) 197 195 { 198 196 // semaphore was already requested: … … 206 204 } 207 205 208 // current owner is different thread thread:206 // current owner is different thread: 209 207 210 208 // do an atomic operation where we compare the owning thread id with 0 211 209 // 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)) 213 211 { 214 212 // the compare did not return equal, i.e. the pmtx sect is in use … … 257 255 BOOL semTry(PFASTMTX pmtx) 258 256 { 259 if ( DosInterlockedIncrement(&pmtx->LockCount))257 if (lockIncrement(&pmtx->LockCount)) 260 258 { 261 259 if (pmtx->OwningThread == GetTID()) … … 265 263 } 266 264 267 DosInterlockedDecrement(&pmtx->LockCount);265 lockDecrement(&pmtx->LockCount); 268 266 269 267 return FALSE; … … 291 289 if (--pmtx->RecursionCount) 292 290 { 293 DosInterlockedDecrement(&pmtx->LockCount );291 lockDecrement(&pmtx->LockCount ); 294 292 return NO_ERROR; 295 293 } … … 297 295 pmtx->OwningThread = 0; 298 296 299 if ( DosInterlockedDecrement(&pmtx->LockCount) >= 0)297 if (lockDecrement(&pmtx->LockCount) >= 0) 300 298 // someone is waiting 301 299 DosPostEventSem(pmtx->hmtxLock); -
trunk/src/helpers/textview.c
r242 r243 1522 1522 // can be NULL to paint all 1523 1523 LONG lViewXOfs, // in: x offset to paint; 0 means rightmost 1524 P ULONG pulViewYOfs,// in: y offset to paint; 0 means _top_most;1524 PLONG plViewYOfs, // in: y offset to paint; 0 means _top_most; 1525 1525 // out: y offset which should be passed to next call 1526 1526 // (if TRUE is returned and fPaintHalfLines == FALSE) … … 1534 1534 fAnyLinesPainted = FALSE; 1535 1535 ULONG ulCurrentLineIndex = *pulLineIndex; 1536 // LONG lViewYOfsSaved = *p ulViewYOfs;1536 // LONG lViewYOfsSaved = *plViewYOfs; 1537 1537 PLISTNODE pRectNode = lstNodeFromIndex(&pxfd->llRectangles, 1538 1538 ulCurrentLineIndex); … … 1550 1550 rclLine.xLeft = pLineRcl->rcl.xLeft - lViewXOfs; 1551 1551 rclLine.xRight = pLineRcl->rcl.xRight - lViewXOfs; 1552 rclLine.yBottom = pLineRcl->rcl.yBottom + *p ulViewYOfs;1553 rclLine.yTop = pLineRcl->rcl.yTop + *p ulViewYOfs;1552 rclLine.yBottom = pLineRcl->rcl.yBottom + *plViewYOfs; 1553 rclLine.yTop = pLineRcl->rcl.yTop + *plViewYOfs; 1554 1554 1555 1555 /* if (pmpf) … … 1711 1711 // return TRUE 1712 1712 brc = TRUE; 1713 // and set *p ulViewYOfs to the top of1713 // and set *plViewYOfs to the top of 1714 1714 // the next line, which wasn't visible 1715 1715 // on the page any more 1716 *p ulViewYOfs = pLineRcl2->rcl.yTop + *pulViewYOfs;1716 *plViewYOfs = pLineRcl2->rcl.yTop + *plViewYOfs; 1717 1717 } 1718 1718 break; … … 1867 1867 XFORMATDATA xfd; 1868 1868 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 1871 1873 1872 1874 BOOL fVScrollVisible, // TRUE if vscroll is currently used … … 1878 1880 rclViewText; // same as rclViewPaint, but excluding cdata borders 1879 1881 1880 ULONG ulViewXOfs,// pixels that we have scrolled to the RIGHT; 0 means very left1881 ulViewYOfs;// pixels that we have scrolled to the BOTTOM; 0 means very top1882 // 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 1882 1884 1883 1885 BOOL fAcceptsPresParamsNow; // TRUE after first WM_PAINT … … 1993 1995 if (ptxvd->fHScrollVisible) 1994 1996 ulOfs = ulScrollCX; 1995 WinSetWindowPos(ptxvd-> hwndVScroll,1997 WinSetWindowPos(ptxvd->scrw.hwndVScroll, 1996 1998 HWND_TOP, 1997 1999 ptxvd->rclViewReal.xRight - ulScrollCX, … … 2007 2009 if (ptxvd->fVScrollVisible) 2008 2010 ulOfs = ulScrollCX; 2009 WinSetWindowPos(ptxvd-> hwndHScroll,2011 WinSetWindowPos(ptxvd->scrw.hwndHScroll, 2010 2012 HWND_TOP, 2011 2013 0, … … 2043 2045 ulWinCY = (ptxvd->rclViewText.yTop - ptxvd->rclViewText.yBottom); 2044 2046 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; 2049 2051 2050 2052 // vertical scroll bar enabled at all? 2051 2053 if (ptxvd->flStyle & XS_VSCROLL) 2052 2054 { 2053 BOOL fEnabled = winhUpdateScrollBar(ptxvd-> hwndVScroll,2055 BOOL fEnabled = winhUpdateScrollBar(ptxvd->scrw.hwndVScroll, 2054 2056 ulWinCY, 2055 2057 ptxvd->xfd.szlWorkspace.cy, 2056 ptxvd-> ulViewYOfs,2058 ptxvd->scrw.ptlScrollOfs.y, 2057 2059 (ptxvd->flStyle & XS_AUTOVHIDE)); 2058 2060 // is auto-hide on? … … 2082 2084 if (ptxvd->flStyle & XS_HSCROLL) 2083 2085 { 2084 BOOL fEnabled = winhUpdateScrollBar(ptxvd-> hwndHScroll,2086 BOOL fEnabled = winhUpdateScrollBar(ptxvd->scrw.hwndHScroll, 2085 2087 ulWinCX, 2086 2088 ptxvd->xfd.szlWorkspace.cx, 2087 ptxvd-> ulViewXOfs,2089 ptxvd->scrw.ptlScrollOfs.x, 2088 2090 (ptxvd->flStyle & XS_AUTOHHIDE)); 2089 2091 // is auto-hide on? … … 2165 2167 xstrcatc(pstr, '\n'); 2166 2168 2167 ptxvd-> ulViewXOfs= 0;2168 ptxvd-> ulViewYOfs= 0;2169 ptxvd->scrw.ptlScrollOfs.x = 0; 2170 ptxvd->scrw.ptlScrollOfs.y = 0; 2169 2171 AdjustViewRects(hwndTextView, 2170 2172 ptxvd); … … 2187 2189 { 2188 2190 ULONG ulLineIndex = 0; 2189 ULONG ulYOfs = ptxvd->ulViewYOfs;2191 LONG lYOfs = ptxvd->scrw.ptlScrollOfs.y; 2190 2192 txvPaintText(ptxvd->hab, 2191 2193 ptxvd->hps, // paint PS: screen 2192 2194 &ptxvd->xfd, // formatting data 2193 2195 prcl2Paint, // update rectangle given to us 2194 ptxvd-> ulViewXOfs, // current X scrolling offset2195 & ulYOfs, // current Y scrolling offset2196 ptxvd->scrw.ptlScrollOfs.x, // current X scrolling offset 2197 &lYOfs, // current Y scrolling offset 2196 2198 TRUE, // draw even partly visible lines 2197 2199 &ulLineIndex); … … 2243 2245 2244 2246 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; 2249 2251 2250 2252 if (pWordThis->pcszLinkTarget) … … 2252 2254 2253 2255 // x start: this word's X coordinate 2254 ptlStart.x = pWordThis->lX - ptxvd-> ulViewXOfs;2256 ptlStart.x = pWordThis->lX - ptxvd->scrw.ptlScrollOfs.x; 2255 2257 // y start: bottom line of rectangle plus highest 2256 2258 // base line offset found in all words (format step 2) … … 2280 2282 &rclLine, 2281 2283 pWordThis, 2282 ptxvd-> ulViewXOfs);2284 ptxvd->scrw.ptlScrollOfs.x); 2283 2285 } 2284 2286 … … 2379 2381 ptxvd->rclViewReal.yTop = pcs->cy; 2380 2382 2381 winhCreateScrollBars(hwndTextView, 2382 &ptxvd->hwndVScroll, 2383 &ptxvd->hwndHScroll); 2383 winhCreateScroller(hwndTextView, 2384 &ptxvd->scrw, 2385 ID_VSCROLL, 2386 ID_HSCROLL); 2384 2387 2385 2388 fShow = ((ptxvd->flStyle & XS_VSCROLL) != 0); 2386 WinShowWindow(ptxvd-> hwndVScroll, fShow);2389 WinShowWindow(ptxvd->scrw.hwndVScroll, fShow); 2387 2390 ptxvd->fVScrollVisible = fShow; 2388 2391 2389 2392 fShow = ((ptxvd->flStyle & XS_HSCROLL) != 0); 2390 WinShowWindow(ptxvd-> hwndHScroll, fShow);2393 WinShowWindow(ptxvd->scrw.hwndHScroll, fShow); 2391 2394 ptxvd->fHScrollVisible = fShow; 2392 2395 … … 2552 2555 FALSE, 2553 2556 TRUE); // full reformat 2557 } 2558 } 2559 2560 /* 2561 *@@ ProcessScroll: 2562 * 2563 *@@added V1.0.1 (2003-01-25) [umoeller] 2564 */ 2565 2566 STATIC 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); 2554 2603 } 2555 2604 } … … 2635 2684 PLISTNODE pWordNodeClicked; 2636 2685 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; 2639 2688 2640 2689 if ( (!(ptxvd->flStyle & XS_STATIC)) … … 2707 2756 HWND hwndOwner = NULLHANDLE; 2708 2757 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; 2711 2760 WinSetCapture(HWND_DESKTOP, NULLHANDLE); 2712 2761 … … 2886 2935 // and then have lower y coordinates down to way in the negatives, 2887 2936 // 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; 2894 2943 2895 2944 // vertical scroll bar enabled at all? 2896 2945 if (ptxvd->flStyle & XS_VSCROLL) 2897 2946 { 2898 /* BOOL fEnabled = */ winhUpdateScrollBar(ptxvd-> hwndVScroll,2947 /* BOOL fEnabled = */ winhUpdateScrollBar(ptxvd->scrw.hwndVScroll, 2899 2948 ulWinCY, 2900 2949 ptxvd->xfd.szlWorkspace.cy, 2901 ptxvd-> ulViewYOfs,2950 ptxvd->scrw.ptlScrollOfs.y, 2902 2951 (ptxvd->flStyle & XS_AUTOVHIDE)); 2903 2952 WinInvalidateRect(hwndTextView, NULL, FALSE); … … 2990 3039 *@@changed V0.9.20 (2002-08-10) [umoeller]: added support for formatting HTML and plain text automatically 2991 3040 *@@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 2992 3042 */ 2993 3043 … … 3081 3131 3082 3132 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 3103 3133 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] 3117 3136 break; 3118 3137 … … 3777 3796 ULONG ulCurrentLineIndex = 0, 3778 3797 ulCurrentPage = 1; 3779 ULONG ulCurrentYOfs = 0;3798 LONG lCurrentYOfs = 0; 3780 3799 3781 3800 /* MATRIXLF matlf; … … 3847 3866 &rclPageWorld, 3848 3867 0, 3849 & ulCurrentYOfs,3868 &lCurrentYOfs, 3850 3869 FALSE, // draw only fully visible lines 3851 3870 &ulCurrentLineIndex); // in/out: line to start with -
trunk/src/helpers/winh.c
r242 r243 1896 1896 1897 1897 /* 1898 *@@ winhCreateScrollBars:1899 * creates two scroll bars with an arbitrary1900 * 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 bar1907 HWND *phwndH) // out: horizontal scroll bar1908 {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, // owner1925 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, // owner1936 HWND_TOP,1937 ID_HSCROLL,1938 &sbcd,1939 0))1940 );1941 }1942 1943 /*1944 1898 *@@ winhUpdateScrollBar: 1945 1899 * updates the given scroll bar according to the given … … 1958 1912 * Terminology: 1959 1913 * 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. 1988 1946 * 1989 1947 * The scroll bar gets disabled if the entire workarea is visible, … … 2009 1967 *@@changed V0.9.3 (2000-04-30) [umoeller]: fixed pels/unit confusion 2010 1968 *@@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 2011 1971 */ 2012 1972 … … 2026 1986 BOOL brc = FALSE; 2027 1987 2028 // _Pmpf(("Entering winhUpdateScrollBar"));2029 2030 // for large workareas, adjust scroll bar units2031 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 2037 1997 // 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 to2044 // raise the divisor, because we only2045 // have a USHORT2046 usThumbDivisorUnits = usScrollUnitPels * 100;2047 1998 2048 1999 // workarea is larger than window: … … 2052 2003 2053 2004 // 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; 2060 2007 2061 2008 // set thumb position and limit 2062 2009 WinSendMsg(hwndScrollBar, 2063 2010 SBM_SETSCROLLBAR, 2064 (MPARAM)(ulCurPelsOfs ), // / usThumbDivisorUnits), // position: 0 means top2011 (MPARAM)(ulCurPelsOfs / usDivisor), // position: 0 means top 2065 2012 MPFROM2SHORT(0, // minimum 2066 2013 lMaxAllowedUnitOfs)); // maximum … … 2070 2017 WinSendMsg(hwndScrollBar, 2071 2018 SBM_SETTHUMBSIZE, 2072 MPFROM2SHORT( ulWinPels / us ThumbDivisorUnits, // visible2073 ulWorkareaPels / us ThumbDivisorUnits), // total2019 MPFROM2SHORT( ulWinPels / usDivisor, // visible 2020 ulWorkareaPels / usDivisor), // total 2074 2021 0); 2075 2022 brc = TRUE; … … 2077 2024 else 2078 2025 { 2079 // _Pmpf(("winhUpdateScrollBar: ulWorkareaPels <= ulWinPels"));2080 2026 // entire workarea is visible: 2081 2027 WinEnableWindow(hwndScrollBar, FALSE); … … 2091 2037 /* 2092 2038 *@@ 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. 2098 2043 * 2099 2044 * This is most useful in conjunction with winhUpdateScrollBar. 2100 2045 * See that function for the terminology also. 2101 2046 * 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. 2109 2051 * 2110 2052 * This function assumes that the scrollbar operates 2111 2053 * 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 bar2054 * of the scroll bar is therefore 2055 * 2056 + lWorkareaPels - (prcl2Scroll->yTop - prcl2Scroll->yBottom) 2057 * 2058 * This function also automatically shrinks the scroll bar 2117 2059 * units, should you have a workarea size which doesn't fit 2118 2060 * into the SHORT's that the scroll bar uses internally. As 2119 2061 * 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.) 2121 2066 * 2122 2067 * Replace "bottom" and "top" with "right" and "left" for 2123 2068 * horizontal scrollbars in the above formula. 2069 * 2070 * Returns the amount of pixels to be passed to winhScrollWindow 2071 * afterwards. 2124 2072 * 2125 2073 *@@added V0.9.1 (2000-02-13) [umoeller] … … 2127 2075 *@@changed V0.9.3 (2000-05-08) [umoeller]: now handling scroll units automatically 2128 2076 *@@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 2080 LONG 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 2141 2085 USHORT usLineStepPels, // in: pixels to scroll line-wise 2142 2086 // (scroll bar buttons pressed) … … 2146 2090 // see PMREF for details 2147 2091 { 2148 ULONG ulOldPelsOfs = *pulCurPelsOfs;2092 LONG lOldPelsOfs = *plCurPelsOfs; 2149 2093 USHORT usPosUnits = SHORT1FROMMP(mp2), // in scroll units 2150 2094 usCmd = SHORT2FROMMP(mp2); 2151 LONG lMaxAllowedUnitOfs; 2152 ULONG ulWinPels; 2095 LONG lLimitPels; 2153 2096 2154 2097 // 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; 2168 2101 2169 2102 switch (usCmd) 2170 2103 { 2171 2104 case SB_LINEUP: 2172 if (*pulCurPelsOfs > usLineStepPels) 2173 *pulCurPelsOfs -= usLineStepPels; // * usScrollUnitPels); 2174 else 2175 *pulCurPelsOfs = 0; 2105 *plCurPelsOfs -= usLineStepPels; 2176 2106 break; 2177 2107 2178 2108 case SB_LINEDOWN: 2179 *p ulCurPelsOfs += usLineStepPels; // * usScrollUnitPels);2109 *plCurPelsOfs += usLineStepPels; 2180 2110 break; 2181 2111 2182 2112 case SB_PAGEUP: 2183 if (*pulCurPelsOfs > ulWinPels) 2184 *pulCurPelsOfs -= ulWinPels; // convert to units 2185 else 2186 *pulCurPelsOfs = 0; 2113 *plCurPelsOfs -= lWindowPels; 2187 2114 break; 2188 2115 2189 2116 case SB_PAGEDOWN: 2190 *p ulCurPelsOfs += ulWinPels; // convert to units2117 *plCurPelsOfs += lWindowPels; 2191 2118 break; 2192 2119 2193 2120 case SB_SLIDERTRACK: 2194 *pulCurPelsOfs = (usPosUnits * usScrollUnitPels); 2195 // _Pmpf((" SB_SLIDERTRACK: usUnits = %d", usPosUnits)); 2121 *plCurPelsOfs = (LONG)usPosUnits * lScrollUnitPels; 2196 2122 break; 2197 2123 2198 2124 case SB_SLIDERPOSITION: 2199 *p ulCurPelsOfs = (usPosUnits * usScrollUnitPels);2125 *plCurPelsOfs = (LONG)usPosUnits * lScrollUnitPels; 2200 2126 break; 2201 2127 } 2202 2128 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) 2222 2143 ) 2223 2144 { 2224 RECTL rcl2Scroll,2225 rcl2Update;2226 2227 2145 // changed: 2228 2146 WinSendMsg(hwndScrollBar, 2229 2147 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), 2351 2149 0); 2352 2150 … … 2381 2179 2382 2180 /* 2383 *@@ winhProcessScrollChars :2181 *@@ winhProcessScrollChars2: 2384 2182 * helper for processing WM_CHAR messages for 2385 2183 * client windows with scroll bars. … … 2400 2198 * The following keystrokes are processed here: 2401 2199 * 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. 2415 2212 * 2416 2213 *@@added V0.9.3 (2000-04-29) [umoeller] … … 2418 2215 */ 2419 2216 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 2217 BOOL 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 2427 2221 { 2428 2222 BOOL fProcessed = FALSE; 2429 2223 USHORT usFlags = SHORT1FROMMP(mp1); 2430 // USHORT usch = SHORT1FROMMP(mp2);2431 2224 USHORT usvk = SHORT2FROMMP(mp2); 2432 2433 // _Pmpf(("Entering winhProcessScrollChars"));2434 2225 2435 2226 if (usFlags & KC_VIRTUALKEY) … … 2494 2285 // vertical: 2495 2286 ulMsg = WM_VSCROLL; 2496 sPos = ulVertMax;2287 sPos = pscrw->szlWorkarea.cy; 2497 2288 } 2498 2289 else 2499 2290 { 2500 2291 ulMsg = WM_HSCROLL; 2501 sPos = ulHorzMax;2292 sPos = pscrw->szlWorkarea.cx; 2502 2293 } 2503 2294 … … 2515 2306 { 2516 2307 HWND hwndScrollBar = ((ulMsg == WM_VSCROLL) 2517 ? hwndVScroll2518 : hwndHScroll);2308 ? pscrw->hwndVScroll 2309 : pscrw->hwndHScroll); 2519 2310 if (WinIsWindowEnabled(hwndScrollBar)) 2520 2311 { … … 2530 2321 } 2531 2322 2532 // _Pmpf(("End of winhProcessScrollChars"));2533 2534 2323 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 2334 BOOL 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 2363 BOOL 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 2448 MRESULT 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; 2535 2498 } 2536 2499 … … 3763 3726 3764 3727 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 3738 BOOL 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; 3765 3753 } 3766 3754
Note:
See TracChangeset
for help on using the changeset viewer.