Changeset 111 for trunk/src/helpers/dialog.c
- Timestamp:
- Oct 18, 2001, 11:06:02 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dialog.c
r108 r111 86 86 *@@ DLGPRIVATE: 87 87 * private data to the dlg manager, allocated 88 * by dlghCreateDlg. This is what is really 89 * used, even though the prototype only 90 * declares DIALOGDATA. 88 * by dlghCreateDlg. 91 89 * 92 90 * This only exists while the dialog is being … … 218 216 ********************************************************************/ 219 217 220 #define PM_GROUP_SPACING_X 1 0218 #define PM_GROUP_SPACING_X 16 221 219 #define PM_GROUP_SPACING_TOP 20 222 220 … … 294 292 *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed broken fonts 295 293 *@@changed V0.9.14 (2001-08-01) [umoeller]: now caching fonts, which is significantly faster 296 */ 297 298 VOID CalcAutoSizeText(PCONTROLDEF pControlDef, 299 BOOL fMultiLine, // in: if TRUE, multiple lines 300 PSIZEL pszlAuto, // out: computed size 301 PDLGPRIVATE pDlgData) 302 { 294 *@@changed V0.9.16 (2001-10-15) [umoeller]: added APIRET 295 */ 296 297 APIRET CalcAutoSizeText(PCONTROLDEF pControlDef, 298 BOOL fMultiLine, // in: if TRUE, multiple lines 299 PSIZEL pszlAuto, // out: computed size 300 PDLGPRIVATE pDlgData) 301 { 302 APIRET arc = NO_ERROR; 303 303 304 SetDlgFont(pControlDef, pDlgData); 304 305 … … 308 309 // ok, we FINALLY have a font now... 309 310 // get the control string and see how much space it needs 310 if (pControlDef->pcszText) 311 if ( (pControlDef->pcszText) 312 && (pControlDef->pcszText != (PCSZ)-1) 313 ) 311 314 { 312 315 // do we have multiple lines? … … 341 344 } 342 345 } 346 else 347 arc = DLGERR_INVALID_CONTROL_TITLE; 348 349 return (arc); 343 350 } 344 351 … … 347 354 * 348 355 *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed various things with statics 349 */ 350 351 VOID CalcAutoSize(PCONTROLDEF pControlDef, 352 PSIZEL pszlAuto, // out: computed size 353 PDLGPRIVATE pDlgData) 354 { 356 *@@changed V0.9.16 (2001-10-15) [umoeller]: added APIRET 357 */ 358 359 APIRET CalcAutoSize(PCONTROLDEF pControlDef, 360 PSIZEL pszlAuto, // out: computed size 361 PDLGPRIVATE pDlgData) 362 { 363 APIRET arc = NO_ERROR; 364 355 365 // dumb defaults 356 366 pszlAuto->cx = 100; … … 360 370 { 361 371 case 0xffff0003L: // WC_BUTTON: 362 CalcAutoSizeText(pControlDef, 363 FALSE, // no multiline 364 pszlAuto, 365 pDlgData); 366 if (pControlDef->flStyle & ( BS_AUTOCHECKBOX 367 | BS_AUTORADIOBUTTON 368 | BS_AUTO3STATE 369 | BS_3STATE 370 | BS_CHECKBOX 371 | BS_RADIOBUTTON)) 372 if (!(arc = CalcAutoSizeText(pControlDef, 373 FALSE, // no multiline 374 pszlAuto, 375 pDlgData))) 372 376 { 373 // give a little extra width for the box bitmap 374 pszlAuto->cx += 20; // @@todo 375 // and height 376 pszlAuto->cy += 2; 377 } 378 else if (pControlDef->flStyle & BS_BITMAP) 379 ; 380 else if (pControlDef->flStyle & (BS_ICON | BS_MINIICON)) 381 ; 382 // we can't test for BS_PUSHBUTTON because that's 0x0000 383 else if (!(pControlDef->flStyle & BS_USERBUTTON)) 384 { 385 pszlAuto->cx += (2 * WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER) + 15); 386 pszlAuto->cy += (2 * WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER) + 15); 377 if (pControlDef->flStyle & ( BS_AUTOCHECKBOX 378 | BS_AUTORADIOBUTTON 379 | BS_AUTO3STATE 380 | BS_3STATE 381 | BS_CHECKBOX 382 | BS_RADIOBUTTON)) 383 { 384 // give a little extra width for the box bitmap 385 pszlAuto->cx += 20; // @@todo 386 // and height 387 pszlAuto->cy += 2; 388 } 389 else if (pControlDef->flStyle & BS_BITMAP) 390 ; 391 else if (pControlDef->flStyle & (BS_ICON | BS_MINIICON)) 392 ; 393 // we can't test for BS_PUSHBUTTON because that's 0x0000 394 else if (!(pControlDef->flStyle & BS_USERBUTTON)) 395 { 396 pszlAuto->cx += (2 * WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER) + 15); 397 pszlAuto->cy += (2 * WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER) + 15); 398 } 387 399 } 388 400 break; … … 390 402 case 0xffff0005L: // WC_STATIC: 391 403 if ((pControlDef->flStyle & 0x0F) == SS_TEXT) 392 CalcAutoSizeText(pControlDef,393 ((pControlDef->flStyle & DT_WORDBREAK) != 0),394 pszlAuto,395 pDlgData);404 arc = CalcAutoSizeText(pControlDef, 405 ((pControlDef->flStyle & DT_WORDBREAK) != 0), 406 pszlAuto, 407 pDlgData); 396 408 else if ((pControlDef->flStyle & 0x0F) == SS_BITMAP) 397 409 { 398 HBITMAP hbm = (HBITMAP)pControlDef->pcszText;399 if (hbm )410 HBITMAP hbm; 411 if (hbm = (HBITMAP)pControlDef->pcszText) 400 412 { 401 413 BITMAPINFOHEADER2 bmih2; … … 408 420 pszlAuto->cy = bmih2.cy; 409 421 } 422 else 423 arc = DLGERR_INVALID_STATIC_BITMAP; 410 424 } 411 425 } … … 425 439 + 5; // some space 426 440 } 441 442 return (arc); 427 443 } 428 444 … … 433 449 * 434 450 *@@added V0.9.15 (2001-08-26) [umoeller] 435 */ 436 437 VOID ColumnCalcSizes(PCOLUMNDEF pColumnDef, 438 PDLGPRIVATE pDlgData) 439 { 451 *@@changed V0.9.16 (2001-10-15) [umoeller]: fixed ugly group table spacings 452 *@@changed V0.9.16 (2001-10-15) [umoeller]: added APIRET 453 */ 454 455 APIRET ColumnCalcSizes(PCOLUMNDEF pColumnDef, 456 PDLGPRIVATE pDlgData) 457 { 458 APIRET arc = NO_ERROR; 459 440 460 ULONG ulXSpacing = 0, 441 461 ulYSpacing = 0; … … 444 464 // nested table: recurse!! 445 465 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 446 ProcessTable(pTableDef, 447 NULL, 448 PROCESS_CALC_SIZES, 449 pDlgData); 450 451 // store the size of the sub-table 452 pColumnDef->cpControl.cx = pTableDef->cpTable.cx; 453 pColumnDef->cpControl.cy = pTableDef->cpTable.cy; 454 455 // should we create a PM control around the table? 456 if (pTableDef->pCtlDef) 457 { 458 // yes: make this wider 459 ulXSpacing = (2 * PM_GROUP_SPACING_X); 460 ulYSpacing = (PM_GROUP_SPACING_X + PM_GROUP_SPACING_TOP); 466 if (!(arc = ProcessTable(pTableDef, 467 NULL, 468 PROCESS_CALC_SIZES, 469 pDlgData))) 470 { 471 // store the size of the sub-table 472 pColumnDef->cpControl.cx = pTableDef->cpTable.cx; 473 pColumnDef->cpControl.cy = pTableDef->cpTable.cy; 474 475 // should we create a PM control around the table? 476 if (pTableDef->pCtlDef) 477 { 478 // yes: make this wider 479 ulXSpacing = 2 * PM_GROUP_SPACING_X; 480 ulYSpacing = // 3 * PM_GROUP_SPACING_X; 481 (PM_GROUP_SPACING_X + PM_GROUP_SPACING_TOP); 482 } 461 483 } 462 484 } … … 472 494 ) 473 495 { 474 CalcAutoSize(pControlDef, 475 &szlAuto, 476 pDlgData); 477 } 478 479 if (pszl->cx == -1) 480 pColumnDef->cpControl.cx = szlAuto.cx; 481 else 482 pColumnDef->cpControl.cx = pszl->cx; 483 484 if (pszl->cy == -1) 485 pColumnDef->cpControl.cy = szlAuto.cy; 486 else 487 pColumnDef->cpControl.cy = pszl->cy; 488 489 // @@todo hack sizes 490 491 ulXSpacing = ulYSpacing = (2 * pControlDef->ulSpacing); 496 arc = CalcAutoSize(pControlDef, 497 &szlAuto, 498 pDlgData); 499 } 500 501 if (!arc) 502 { 503 if (pszl->cx == -1) 504 pColumnDef->cpControl.cx = szlAuto.cx; 505 else 506 pColumnDef->cpControl.cx = pszl->cx; 507 508 if (pszl->cy == -1) 509 pColumnDef->cpControl.cy = szlAuto.cy; 510 else 511 pColumnDef->cpControl.cy = pszl->cy; 512 513 // @@todo hack sizes 514 515 ulXSpacing 516 = ulYSpacing 517 = (2 * pControlDef->ulSpacing); 518 } 492 519 } 493 520 … … 496 523 pColumnDef->cpColumn.cy = pColumnDef->cpControl.cy 497 524 + ulYSpacing; 525 526 return (arc); 498 527 } 499 528 … … 504 533 * 505 534 *@@added V0.9.15 (2001-08-26) [umoeller] 506 */ 507 508 VOID ColumnCalcPositions(PCOLUMNDEF pColumnDef, 509 PROWDEF pOwningRow, // in: current row from ProcessRow 510 PLONG plX, // in/out: PROCESS_CALC_POSITIONS only 511 PDLGPRIVATE pDlgData) 512 { 535 *@@changed V0.9.16 (2001-10-15) [umoeller]: added APIRET 536 */ 537 538 APIRET ColumnCalcPositions(PCOLUMNDEF pColumnDef, 539 PROWDEF pOwningRow, // in: current row from ProcessRow 540 PLONG plX, // in/out: PROCESS_CALC_POSITIONS only 541 PDLGPRIVATE pDlgData) 542 { 543 APIRET arc = NO_ERROR; 544 513 545 // calculate column position: this includes spacing 514 546 ULONG ulSpacing = 0; … … 544 576 if (pTableDef->pCtlDef) 545 577 // yes: 546 ulSpacing = PM_GROUP_SPACING_X ;578 ulSpacing = PM_GROUP_SPACING_X / 2; // V0.9.16 (2001-10-15) [umoeller] 547 579 } 548 580 else … … 568 600 569 601 // recurse!! to create windows for the sub-table 570 ProcessTable(pTableDef, 571 &pColumnDef->cpControl, // start pos for new table 572 PROCESS_CALC_POSITIONS, 573 pDlgData); 574 } 602 arc = ProcessTable(pTableDef, 603 &pColumnDef->cpControl, // start pos for new table 604 PROCESS_CALC_POSITIONS, 605 pDlgData); 606 } 607 608 return (arc); 575 609 } 576 610 … … 581 615 * 582 616 *@@added V0.9.15 (2001-08-26) [umoeller] 617 *@@changed V0.9.16 (2001-10-15) [umoeller]: fixed ugly group table spacings 583 618 */ 584 619 … … 595 630 ULONG flOld = 0; 596 631 597 LONG y, cy; // for combo box hacks632 LONG x, cx, y, cy; // for combo box hacks 598 633 599 634 if (pColumnDef->fIsNestedTable) … … 619 654 flStyle = pControlDef->flStyle; 620 655 656 x = pcp->x + pDlgData->ptlTotalOfs.x; 657 cx = pcp->cx - PM_GROUP_SPACING_X; 658 // note, just one spacing: for the _column_ size, 659 // we have specified 2 X spacings 621 660 y = pcp->y + pDlgData->ptlTotalOfs.y; 622 cy = pcp->cy; 661 // cy = pcp->cy - PM_GROUP_SPACING_X; 662 cy = pcp->cy - /* PM_GROUP_SPACING_X - */ PM_GROUP_SPACING_TOP / 2; 623 663 } 624 664 } … … 632 672 flStyle = pControlDef->flStyle; 633 673 674 x = pcp->x + pDlgData->ptlTotalOfs.x; 675 cx = pcp->cx; 634 676 y = pcp->y + pDlgData->ptlTotalOfs.y; 635 677 cy = pcp->cy; … … 685 727 : "", 686 728 flStyle, // hacked 687 pcp->x + pDlgData->ptlTotalOfs.x,729 x, 688 730 y, 689 pcp->cx,731 cx, 690 732 cy, 691 733 pDlgData->hwndDlg, // owner … … 806 848 807 849 case PROCESS_CALC_SIZES: 808 ColumnCalcSizes(pColumnDef,809 pDlgData);850 arc = ColumnCalcSizes(pColumnDef, 851 pDlgData); 810 852 break; 811 853 … … 816 858 817 859 case PROCESS_CALC_POSITIONS: 818 ColumnCalcPositions(pColumnDef,819 pOwningRow,820 plX,821 pDlgData);860 arc = ColumnCalcPositions(pColumnDef, 861 pOwningRow, 862 plX, 863 pDlgData); 822 864 break; 823 865 … … 1129 1171 /* ****************************************************************** 1130 1172 * 1131 * Public APIs1173 * Dialog formatter engine 1132 1174 * 1133 1175 ********************************************************************/ … … 1452 1494 } 1453 1495 } 1496 1497 /* ****************************************************************** 1498 * 1499 * Dialog formatter entry points 1500 * 1501 ********************************************************************/ 1454 1502 1455 1503 /* … … 1956 2004 return (arc); 1957 2005 } 2006 2007 /* ****************************************************************** 2008 * 2009 * Dialog arrays 2010 * 2011 ********************************************************************/ 2012 2013 /* 2014 *@@ dlghCreateArray: 2015 * creates a "dialog array" for dynamically 2016 * building a dialog template in memory. 2017 * 2018 * A dialog array is simply an array of 2019 * DLGHITEM structures, as you would normally 2020 * define them statically in the source. 2021 * However, there are situations where you 2022 * might want to leave out certain controls 2023 * depending on certain conditions, which 2024 * can be difficult with static arrays. 2025 * 2026 * As a result, these "array" functions have 2027 * been added to allow for adding static 2028 * DLGHITEM subarrays to a dynamic array in 2029 * memory, which can then be passed to the 2030 * formatter. 2031 * 2032 * Usage: 2033 * 2034 * 1) Call this function with the maximum 2035 * amount of DLGHITEM's that will need 2036 * to be allocated in cMaxItems. Set this 2037 * to the total sum of all DLGHITEM's 2038 * in all the subarrays. 2039 * 2040 * 2) For each of the subarrays, call 2041 * dlghAppendToArray to have the subarray 2042 * appended to the dialog array. 2043 * After each call, DLGARRAY.cDlgItemsNow 2044 * will contain the actual total count of 2045 * DLGHITEM's that were added. 2046 * 2047 * 3) Call dlghCreateDialog with the dialog 2048 * array. 2049 * 2050 * 4) Call dlghFreeArray. 2051 * 2052 * Sort of like this (error checking omitted): 2053 * 2054 + DLGHITEM dlgSampleFront = ... // always included 2055 + DLGHITEM dlgSampleSometimes = ... // not always included 2056 + DLGHITEM dlgSampleTail = ... // always included 2057 + 2058 + PDLGARRAY pArraySample = NULL; 2059 + dlghCreateArray( ARRAYITEMCOUNT(dlgSampleFront) 2060 + + ARRAYITEMCOUNT(dlgSampleSometimes) 2061 + + ARRAYITEMCOUNT(dlgSampleTail), 2062 + &pArraySample); 2063 + 2064 + // always include front 2065 + dlghAppendToArray(pArraySample, 2066 + dlgSampleFront, 2067 + ARRAYITEMCOUNT(dlgSampleFront)); 2068 + // include "sometimes" conditionally 2069 + if (...) 2070 + dlghAppendToArray(pArraySample, 2071 + dlgSampleSometimes, 2072 + ARRAYITEMCOUNT(dlgSampleSometimes)); 2073 + // include tail always 2074 + dlghAppendToArray(pArraySample, 2075 + dlgSampleTail, 2076 + ARRAYITEMCOUNT(dlgSampleTail)); 2077 + 2078 + // now create the dialog from the array 2079 + dlghCreateDialog(&hwndDlg, 2080 + hwndOwner, 2081 + FCF_ ... 2082 + fnwpMyDialogProc, 2083 + "Title", 2084 + pArray->paDialogItems, // dialog array! 2085 + pArray->cDlgItemsNow, // real count of items! 2086 + NULL, 2087 + NULL); 2088 + 2089 + dlghFreeArray(&pArraySample); 2090 * 2091 *@@added V0.9.16 (2001-10-15) [umoeller] 2092 */ 2093 2094 APIRET dlghCreateArray(ULONG cMaxItems, 2095 PDLGARRAY *ppArray) // out: DLGARRAY 2096 { 2097 APIRET arc = NO_ERROR; 2098 PDLGARRAY pArray; 2099 2100 if (pArray = NEW(DLGARRAY)) 2101 { 2102 ULONG cb; 2103 2104 ZERO(pArray); 2105 if ( (cb = cMaxItems * sizeof(DLGHITEM)) 2106 && (pArray->paDlgItems = (DLGHITEM*)malloc(cb)) 2107 ) 2108 { 2109 memset(pArray->paDlgItems, 0, cb); 2110 pArray->cDlgItemsMax = cMaxItems; 2111 *ppArray = pArray; 2112 } 2113 else 2114 arc = ERROR_NOT_ENOUGH_MEMORY; 2115 2116 if (arc) 2117 dlghFreeArray(&pArray); 2118 } 2119 else 2120 arc = ERROR_NOT_ENOUGH_MEMORY; 2121 2122 return arc; 2123 } 2124 2125 /* 2126 *@@ dlghFreeArray: 2127 * frees a dialog array created by dlghCreateArray. 2128 * 2129 *@@added V0.9.16 (2001-10-15) [umoeller] 2130 */ 2131 2132 APIRET dlghFreeArray(PDLGARRAY *ppArray) 2133 { 2134 PDLGARRAY pArray; 2135 if ( (ppArray) 2136 && (pArray = *ppArray) 2137 ) 2138 { 2139 if (pArray->paDlgItems) 2140 free(pArray->paDlgItems); 2141 free(pArray); 2142 } 2143 else 2144 return ERROR_INVALID_PARAMETER; 2145 2146 return NO_ERROR; 2147 } 2148 2149 /* 2150 *@@ dlghAppendToArray: 2151 * appends a subarray of DLGHITEM's to the 2152 * given DLGARRAY. See dlghCreateArray for 2153 * usage. 2154 * 2155 * Returns: 2156 * 2157 * -- NO_ERROR 2158 * 2159 * -- ERROR_INVALID_PARAMETER 2160 * 2161 * -- DLGERR_ARRAY_TOO_SMALL: pArray does not 2162 * have enough memory to hold the new items. 2163 * The cMaxItems parameter given to dlghCreateArray 2164 * wasn't large enough. 2165 * 2166 *@@added V0.9.16 (2001-10-15) [umoeller] 2167 */ 2168 2169 APIRET dlghAppendToArray(PDLGARRAY pArray, // in: dialog array created by dlghCreateArray 2170 DLGHITEM *paItems, // in: subarray to be appended 2171 ULONG cItems) // in: subarray item count (NOT array size) 2172 { 2173 APIRET arc = NO_ERROR; 2174 if (pArray) 2175 { 2176 if ( (pArray->cDlgItemsMax >= cItems) 2177 && (pArray->cDlgItemsMax - pArray->cDlgItemsNow >= cItems) 2178 ) 2179 { 2180 // enough space left in the array: 2181 memcpy(&pArray->paDlgItems[pArray->cDlgItemsNow], 2182 paItems, // source 2183 cItems * sizeof(DLGHITEM)); 2184 pArray->cDlgItemsNow += cItems; 2185 } 2186 else 2187 arc = DLGERR_ARRAY_TOO_SMALL; 2188 } 2189 else 2190 arc = ERROR_INVALID_PARAMETER; 2191 2192 return (arc); 2193 } 2194 2195 /* ****************************************************************** 2196 * 2197 * Standard dialogs 2198 * 2199 ********************************************************************/ 1958 2200 1959 2201 /* … … 2462 2704 } 2463 2705 2706 /* ****************************************************************** 2707 * 2708 * Dialog input handlers 2709 * 2710 ********************************************************************/ 2711 2464 2712 /* 2465 2713 *@@ dlghSetPrevFocus:
Note:
See TracChangeset
for help on using the changeset viewer.