Changeset 243 for trunk/src/helpers
- Timestamp:
- Jan 29, 2003, 7:41:39 PM (23 years ago)
- Location:
- trunk/src/helpers
- Files:
-
- 1 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
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.