Changeset 103 for trunk/src/helpers/dialog.c
- Timestamp:
- Aug 29, 2001, 8:52:22 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dialog.c
r101 r103 398 398 399 399 /* 400 *@@ ColumnCalcSizes: 401 * implementation for PROCESS_CALC_SIZES in 402 * ProcessColumn. 403 * 404 *@@added V0.9.15 (2001-08-26) [umoeller] 405 */ 406 407 VOID ColumnCalcSizes(PCOLUMNDEF pColumnDef, 408 PDLGPRIVATE pDlgData) 409 { 410 ULONG ulXSpacing = 0, 411 ulYSpacing = 0; 412 if (pColumnDef->fIsNestedTable) 413 { 414 // nested table: recurse!! 415 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 416 ProcessTable(pTableDef, 417 NULL, 418 PROCESS_CALC_SIZES, 419 pDlgData); 420 421 // store the size of the sub-table 422 pColumnDef->cpControl.cx = pTableDef->cpTable.cx; 423 pColumnDef->cpControl.cy = pTableDef->cpTable.cy; 424 425 // should we create a PM control around the table? 426 if (pTableDef->pCtlDef) 427 { 428 // yes: make this wider 429 ulXSpacing = (2 * PM_GROUP_SPACING_X); 430 ulYSpacing = (PM_GROUP_SPACING_X + PM_GROUP_SPACING_TOP); 431 } 432 } 433 else 434 { 435 // no nested table, but control: 436 PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 437 PSIZEL pszl = &pControlDef->szlControlProposed; 438 SIZEL szlAuto; 439 440 if ( (pszl->cx == -1) 441 || (pszl->cy == -1) 442 ) 443 { 444 CalcAutoSize(pControlDef, 445 &szlAuto, 446 pDlgData); 447 } 448 449 if (pszl->cx == -1) 450 pColumnDef->cpControl.cx = szlAuto.cx; 451 else 452 pColumnDef->cpControl.cx = pszl->cx; 453 454 if (pszl->cy == -1) 455 pColumnDef->cpControl.cy = szlAuto.cy; 456 else 457 pColumnDef->cpControl.cy = pszl->cy; 458 459 // @@todo hack sizes 460 461 ulXSpacing = ulYSpacing = (2 * pControlDef->ulSpacing); 462 } 463 464 pColumnDef->cpColumn.cx = pColumnDef->cpControl.cx 465 + ulXSpacing; 466 pColumnDef->cpColumn.cy = pColumnDef->cpControl.cy 467 + ulYSpacing; 468 } 469 470 /* 471 *@@ ColumnCalcPositions: 472 * implementation for PROCESS_CALC_POSITIONS in 473 * ProcessColumn. 474 * 475 *@@added V0.9.15 (2001-08-26) [umoeller] 476 */ 477 478 VOID ColumnCalcPositions(PCOLUMNDEF pColumnDef, 479 PROWDEF pOwningRow, // in: current row from ProcessRow 480 PLONG plX, // in/out: PROCESS_CALC_POSITIONS only 481 PDLGPRIVATE pDlgData) 482 { 483 // calculate column position: this includes spacing 484 ULONG ulSpacing = 0; 485 486 // column position = *plX on ProcessRow stack 487 pColumnDef->cpColumn.x = *plX; 488 pColumnDef->cpColumn.y = pOwningRow->cpRow.y; 489 490 // check vertical alignment of row; 491 // we might need to increase column y 492 switch (pOwningRow->flRowFormat & ROW_VALIGN_MASK) 493 { 494 // case ROW_VALIGN_BOTTOM: // do nothing 495 496 case ROW_VALIGN_CENTER: 497 if (pColumnDef->cpColumn.cy < pOwningRow->cpRow.cy) 498 pColumnDef->cpColumn.y 499 += ( (pOwningRow->cpRow.cy - pColumnDef->cpColumn.cy) 500 / 2); 501 break; 502 503 case ROW_VALIGN_TOP: 504 if (pColumnDef->cpColumn.cy < pOwningRow->cpRow.cy) 505 pColumnDef->cpColumn.y 506 += (pOwningRow->cpRow.cy - pColumnDef->cpColumn.cy); 507 break; 508 } 509 510 if (pColumnDef->fIsNestedTable) 511 { 512 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 513 // should we create a PM control around the table? 514 if (pTableDef->pCtlDef) 515 // yes: 516 ulSpacing = PM_GROUP_SPACING_X; 517 } 518 else 519 { 520 // no nested table, but control: 521 PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 522 ulSpacing = pControlDef->ulSpacing; 523 } 524 525 // increase plX by column width 526 *plX += pColumnDef->cpColumn.cx; 527 528 // calculate CONTROL pos from COLUMN pos by applying spacing 529 pColumnDef->cpControl.x = pColumnDef->cpColumn.x 530 + ulSpacing; 531 pColumnDef->cpControl.y = pColumnDef->cpColumn.y 532 + ulSpacing; 533 534 if (pColumnDef->fIsNestedTable) 535 { 536 // nested table: 537 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 538 539 // recurse!! to create windows for the sub-table 540 ProcessTable(pTableDef, 541 &pColumnDef->cpControl, // start pos for new table 542 PROCESS_CALC_POSITIONS, 543 pDlgData); 544 } 545 } 546 547 /* 548 *@@ ColumnCreateControls: 549 * implementation for PROCESS_CREATE_CONTROLS in 550 * ProcessColumn. 551 * 552 *@@added V0.9.15 (2001-08-26) [umoeller] 553 */ 554 555 APIRET ColumnCreateControls(PCOLUMNDEF pColumnDef, 556 PDLGPRIVATE pDlgData) 557 { 558 APIRET arc = NO_ERROR; 559 560 PCONTROLPOS pcp = NULL; 561 PCONTROLDEF pControlDef = NULL; 562 const char *pcszTitle = NULL; 563 ULONG flStyle = 0; 564 LHANDLE lHandleSet = NULLHANDLE; 565 ULONG flOld = 0; 566 567 if (pColumnDef->fIsNestedTable) 568 { 569 // nested table: 570 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 571 572 // recurse!! 573 if (!(arc = ProcessTable(pTableDef, 574 NULL, 575 PROCESS_CREATE_CONTROLS, 576 pDlgData))) 577 { 578 // should we create a PM control around the table? 579 // (do this AFTER the other controls from recursing, 580 // otherwise the stupid container doesn't show up) 581 if (pTableDef->pCtlDef) 582 { 583 // yes: 584 pcp = &pColumnDef->cpColumn; // !! not control 585 pControlDef = pTableDef->pCtlDef; 586 pcszTitle = pControlDef->pcszText; 587 flStyle = pControlDef->flStyle; 588 } 589 } 590 } 591 else 592 { 593 // no nested table, but control: 594 pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 595 pcp = &pColumnDef->cpControl; 596 pcszTitle = pControlDef->pcszText; 597 flStyle = pControlDef->flStyle; 598 599 // change the title if this is a static with SS_BITMAP; 600 // we have used a HBITMAP in there! 601 if ( ((ULONG)pControlDef->pcszClass == 0xffff0005L) // WC_STATIC: 602 && ( ((flStyle & 0x0F) == SS_BITMAP) 603 || ((flStyle & 0x0F) == SS_ICON) 604 ) 605 ) 606 { 607 // change style flag to not use SS_BITMAP nor SS_ICON; 608 // control creation fails otherwise (stupid, stupid PM) 609 flOld = flStyle; 610 flStyle = ((flStyle & ~0x0F) | SS_FGNDFRAME); 611 pcszTitle = ""; 612 lHandleSet = (LHANDLE)pControlDef->pcszText; 613 } 614 } 615 616 if (pcp && pControlDef) 617 { 618 // create something: 619 // PPRESPARAMS ppp = NULL; 620 621 const char *pcszFont = pControlDef->pcszFont; 622 // can be NULL, or CTL_COMMON_FONT 623 if (pcszFont == CTL_COMMON_FONT) 624 pcszFont = pDlgData->pcszControlsFont; 625 626 /* if (pcszFont) 627 winhStorePresParam(&ppp, 628 PP_FONTNAMESIZE, 629 strlen(pcszFont), 630 (PVOID)pcszFont); */ 631 632 if (pColumnDef->hwndControl 633 = WinCreateWindow(pDlgData->hwndDlg, // parent 634 (PSZ)pControlDef->pcszClass, 635 (pcszTitle) // hacked 636 ? (PSZ)pcszTitle 637 : "", 638 flStyle, // hacked 639 pcp->x + pDlgData->ptlTotalOfs.x, 640 pcp->y + pDlgData->ptlTotalOfs.y, 641 pcp->cx, 642 pcp->cy, 643 pDlgData->hwndDlg, // owner 644 HWND_BOTTOM, 645 pControlDef->usID, 646 pControlDef->pvCtlData, 647 NULL)) 648 { 649 if (lHandleSet) 650 { 651 // subclass the damn static 652 if ((flOld & 0x0F) == SS_ICON) 653 // this was a static: 654 ctlPrepareStaticIcon(pColumnDef->hwndControl, 655 1); 656 else 657 // this was a bitmap: 658 ctlPrepareStretchedBitmap(pColumnDef->hwndControl, 659 TRUE); 660 661 WinSendMsg(pColumnDef->hwndControl, 662 SM_SETHANDLE, 663 (MPARAM)lHandleSet, 664 0); 665 } 666 else 667 if (pcszFont) 668 // we must set the font explicitly here... 669 // doesn't always work with WinCreateWindow 670 // presparams parameter, for some reason 671 // V0.9.12 (2001-05-31) [umoeller] 672 winhSetWindowFont(pColumnDef->hwndControl, 673 pcszFont); 674 675 lstAppendItem(&pDlgData->llControls, 676 pColumnDef); 677 678 // if this is the first control with WS_TABSTOP, 679 // we give it the focus later 680 if ( (flStyle & WS_TABSTOP) 681 && (!pDlgData->hwndFirstFocus) 682 ) 683 pDlgData->hwndFirstFocus = pColumnDef->hwndControl; 684 685 // if this is the first default push button, 686 // go store it too 687 // V0.9.14 (2001-08-21) [umoeller] 688 if ( (!pDlgData->hwndDefPushbutton) 689 && ((ULONG)pControlDef->pcszClass == 0xffff0003L) 690 && (pControlDef->flStyle & BS_DEFAULT) 691 ) 692 pDlgData->hwndDefPushbutton = pColumnDef->hwndControl; 693 } 694 else 695 // V0.9.14 (2001-08-03) [umoeller] 696 arc = DLGERR_CANNOT_CREATE_CONTROL; 697 } 698 699 return (arc); 700 } 701 702 /* 400 703 *@@ ProcessColumn: 401 704 * processes a column, which per definition is either … … 455 758 456 759 case PROCESS_CALC_SIZES: 457 { 458 ULONG ulXSpacing = 0, 459 ulYSpacing = 0; 460 if (pColumnDef->fIsNestedTable) 461 { 462 // nested table: recurse!! 463 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 464 ProcessTable(pTableDef, 465 NULL, 466 ProcessMode, 467 pDlgData); 468 469 // store the size of the sub-table 470 pColumnDef->cpControl.cx = pTableDef->cpTable.cx; 471 pColumnDef->cpControl.cy = pTableDef->cpTable.cy; 472 473 // should we create a PM control around the table? 474 if (pTableDef->pCtlDef) 475 { 476 // yes: make this wider 477 ulXSpacing = (2 * PM_GROUP_SPACING_X); 478 ulYSpacing = (PM_GROUP_SPACING_X + PM_GROUP_SPACING_TOP); 479 } 480 } 481 else 482 { 483 // no nested table, but control: 484 PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 485 PSIZEL pszl = &pControlDef->szlControlProposed; 486 SIZEL szlAuto; 487 488 if ( (pszl->cx == -1) 489 || (pszl->cy == -1) 490 ) 491 { 492 CalcAutoSize(pControlDef, 493 &szlAuto, 494 pDlgData); 495 } 496 497 if (pszl->cx == -1) 498 pColumnDef->cpControl.cx = szlAuto.cx; 499 else 500 pColumnDef->cpControl.cx = pszl->cx; 501 502 if (pszl->cy == -1) 503 pColumnDef->cpControl.cy = szlAuto.cy; 504 else 505 pColumnDef->cpControl.cy = pszl->cy; 506 507 // @@todo hack sizes 508 509 ulXSpacing = ulYSpacing = (2 * pControlDef->ulSpacing); 510 } 511 512 pColumnDef->cpColumn.cx = pColumnDef->cpControl.cx 513 + ulXSpacing; 514 pColumnDef->cpColumn.cy = pColumnDef->cpControl.cy 515 + ulYSpacing; 516 break; } 760 ColumnCalcSizes(pColumnDef, 761 pDlgData); 762 break; 517 763 518 764 /* … … 522 768 523 769 case PROCESS_CALC_POSITIONS: 524 { 525 // calculate column position: this includes spacing 526 ULONG ulSpacing = 0; 527 528 // column position = *plX on ProcessRow stack 529 pColumnDef->cpColumn.x = *plX; 530 pColumnDef->cpColumn.y = pOwningRow->cpRow.y; 531 532 // check vertical alignment of row; 533 // we might need to increase column y 534 switch (pOwningRow->flRowFormat & ROW_VALIGN_MASK) 535 { 536 // case ROW_VALIGN_BOTTOM: // do nothing 537 538 case ROW_VALIGN_CENTER: 539 if (pColumnDef->cpColumn.cy < pOwningRow->cpRow.cy) 540 pColumnDef->cpColumn.y 541 += ( (pOwningRow->cpRow.cy - pColumnDef->cpColumn.cy) 542 / 2); 543 break; 544 545 case ROW_VALIGN_TOP: 546 if (pColumnDef->cpColumn.cy < pOwningRow->cpRow.cy) 547 pColumnDef->cpColumn.y 548 += (pOwningRow->cpRow.cy - pColumnDef->cpColumn.cy); 549 break; 550 } 551 552 if (pColumnDef->fIsNestedTable) 553 { 554 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 555 // should we create a PM control around the table? 556 if (pTableDef->pCtlDef) 557 // yes: 558 ulSpacing = PM_GROUP_SPACING_X; 559 } 560 else 561 { 562 // no nested table, but control: 563 PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 564 ulSpacing = pControlDef->ulSpacing; 565 } 566 567 // increase plX by column width 568 *plX += pColumnDef->cpColumn.cx; 569 570 // calculate CONTROL pos from COLUMN pos by applying spacing 571 pColumnDef->cpControl.x = pColumnDef->cpColumn.x 572 + ulSpacing; 573 pColumnDef->cpControl.y = pColumnDef->cpColumn.y 574 + ulSpacing; 575 576 if (pColumnDef->fIsNestedTable) 577 { 578 // nested table: 579 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 580 581 // recurse!! to create windows for the sub-table 582 ProcessTable(pTableDef, 583 &pColumnDef->cpControl, // start pos for new table 584 ProcessMode, 585 pDlgData); 586 } 587 break; } 770 ColumnCalcPositions(pColumnDef, 771 pOwningRow, 772 plX, 773 pDlgData); 774 break; 588 775 589 776 /* … … 593 780 594 781 case PROCESS_CREATE_CONTROLS: 595 { 596 PCONTROLPOS pcp = NULL; 597 PCONTROLDEF pControlDef = NULL; 598 const char *pcszTitle = NULL; 599 ULONG flStyle = 0; 600 LHANDLE lHandleSet = NULLHANDLE; 601 ULONG flOld = 0; 602 603 if (pColumnDef->fIsNestedTable) 604 { 605 // nested table: 606 PTABLEDEF pTableDef = (PTABLEDEF)pColumnDef->pvDefinition; 607 608 // recurse!! 609 if (!(arc = ProcessTable(pTableDef, 610 NULL, 611 ProcessMode, 612 pDlgData))) 613 { 614 // should we create a PM control around the table? 615 // (do this AFTER the other controls from recursing, 616 // otherwise the stupid container doesn't show up) 617 if (pTableDef->pCtlDef) 618 { 619 // yes: 620 pcp = &pColumnDef->cpColumn; // !! not control 621 pControlDef = pTableDef->pCtlDef; 622 pcszTitle = pControlDef->pcszText; 623 flStyle = pControlDef->flStyle; 624 } 625 } 626 else 627 break; 628 } 629 else 630 { 631 // no nested table, but control: 632 pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition; 633 pcp = &pColumnDef->cpControl; 634 pcszTitle = pControlDef->pcszText; 635 flStyle = pControlDef->flStyle; 636 637 // change the title if this is a static with SS_BITMAP; 638 // we have used a HBITMAP in there! 639 if ( ((ULONG)pControlDef->pcszClass == 0xffff0005L) // WC_STATIC: 640 && ( ((flStyle & 0x0F) == SS_BITMAP) 641 || ((flStyle & 0x0F) == SS_ICON) 642 ) 643 ) 644 { 645 // change style flag to not use SS_BITMAP nor SS_ICON; 646 // control creation fails otherwise (stupid, stupid PM) 647 flOld = flStyle; 648 flStyle = ((flStyle & ~0x0F) | SS_FGNDFRAME); 649 pcszTitle = ""; 650 lHandleSet = (LHANDLE)pControlDef->pcszText; 651 } 652 } 653 654 if (pcp && pControlDef) 655 { 656 // create something: 657 // PPRESPARAMS ppp = NULL; 658 659 const char *pcszFont = pControlDef->pcszFont; 660 // can be NULL, or CTL_COMMON_FONT 661 if (pcszFont == CTL_COMMON_FONT) 662 pcszFont = pDlgData->pcszControlsFont; 663 664 /* if (pcszFont) 665 winhStorePresParam(&ppp, 666 PP_FONTNAMESIZE, 667 strlen(pcszFont), 668 (PVOID)pcszFont); */ 669 670 if (pColumnDef->hwndControl 671 = WinCreateWindow(pDlgData->hwndDlg, // parent 672 (PSZ)pControlDef->pcszClass, 673 (pcszTitle) // hacked 674 ? (PSZ)pcszTitle 675 : "", 676 flStyle, // hacked 677 pcp->x + pDlgData->ptlTotalOfs.x, 678 pcp->y + pDlgData->ptlTotalOfs.y, 679 pcp->cx, 680 pcp->cy, 681 pDlgData->hwndDlg, // owner 682 HWND_BOTTOM, 683 pControlDef->usID, 684 pControlDef->pvCtlData, 685 NULL)) 686 { 687 if (lHandleSet) 688 { 689 // subclass the damn static 690 if ((flOld & 0x0F) == SS_ICON) 691 // this was a static: 692 ctlPrepareStaticIcon(pColumnDef->hwndControl, 693 1); 694 else 695 // this was a bitmap: 696 ctlPrepareStretchedBitmap(pColumnDef->hwndControl, 697 TRUE); 698 699 WinSendMsg(pColumnDef->hwndControl, 700 SM_SETHANDLE, 701 (MPARAM)lHandleSet, 702 0); 703 } 704 else 705 if (pcszFont) 706 // we must set the font explicitly here... 707 // doesn't always work with WinCreateWindow 708 // presparams parameter, for some reason 709 // V0.9.12 (2001-05-31) [umoeller] 710 winhSetWindowFont(pColumnDef->hwndControl, 711 pcszFont); 712 713 lstAppendItem(&pDlgData->llControls, 714 pColumnDef); 715 716 // if this is the first control with WS_TABSTOP, 717 // we give it the focus later 718 if ( (flStyle & WS_TABSTOP) 719 && (!pDlgData->hwndFirstFocus) 720 ) 721 pDlgData->hwndFirstFocus = pColumnDef->hwndControl; 722 723 // if this is the first default push button, 724 // go store it too 725 // V0.9.14 (2001-08-21) [umoeller] 726 if ( (!pDlgData->hwndDefPushbutton) 727 && ((ULONG)pControlDef->pcszClass == 0xffff0003L) 728 && (pControlDef->flStyle & BS_DEFAULT) 729 ) 730 pDlgData->hwndDefPushbutton = pColumnDef->hwndControl; 731 } 732 else 733 // V0.9.14 (2001-08-03) [umoeller] 734 arc = DLGERR_CANNOT_CREATE_CONTROL; 735 } 736 break; } 782 arc = ColumnCreateControls(pColumnDef, 783 pDlgData); 784 break; 737 785 } 738 786 … … 885 933 * 886 934 * After this first call, we know all the sizes 887 * only and then then calculate the positions.935 * only and can then calculate the positions. 888 936 * 889 937 * -- PROCESS_CALC_POSITIONS: calculates the positions … … 894 942 * 895 943 * The second trick is the precondition that tables may 896 * nest by allowing a table definition instead of a 897 * control definition in a column. This way we can 898 * recurse from columns back into tables and thus 899 * know the size and position of a nested table column 900 * just as if it were a regular control. 944 * nest by allowing another table definition in a column. 945 * This way we can recurse from ProcessColumn back into 946 * ProcessTable and thus know the size and position of a 947 * nested table column just as if it were a regular control. 901 948 */ 902 949 … … 1049 1096 1050 1097 } STACKITEM, *PSTACKITEM; 1098 1099 #define SPACING 10 1100 1101 /* 1102 *@@ Dlg0_Init: 1103 * 1104 *@@added V0.9.15 (2001-08-26) [umoeller] 1105 */ 1106 1107 APIRET Dlg0_Init(PDLGPRIVATE *ppDlgData, 1108 PCSZ pcszControlsFont) 1109 { 1110 PDLGPRIVATE pDlgData; 1111 if (!(pDlgData = NEW(DLGPRIVATE))) 1112 return (ERROR_NOT_ENOUGH_MEMORY); 1113 ZERO(pDlgData); 1114 lstInit(&pDlgData->llTables, FALSE); 1115 lstInit(&pDlgData->llControls, FALSE); 1116 1117 pDlgData->pcszControlsFont = pcszControlsFont; 1118 1119 *ppDlgData = pDlgData; 1120 1121 return NO_ERROR; 1122 } 1123 1124 /* 1125 *@@ Dlg1_ParseTables: 1126 * 1127 *@@added V0.9.15 (2001-08-26) [umoeller] 1128 */ 1129 1130 APIRET Dlg1_ParseTables(PDLGPRIVATE pDlgData, 1131 PDLGHITEM paDlgItems, // in: definition array 1132 ULONG cDlgItems) // in: array item count (NOT array size) 1133 { 1134 APIRET arc = NO_ERROR; 1135 1136 LINKLIST llStack; 1137 ULONG ul; 1138 PTABLEDEF pCurrentTable = NULL; 1139 PROWDEF pCurrentRow = NULL; 1140 1141 lstInit(&llStack, TRUE); // this is our stack for nested table definitions 1142 1143 for (ul = 0; 1144 ul < cDlgItems; 1145 ul++) 1146 { 1147 PDLGHITEM pItemThis = &paDlgItems[ul]; 1148 1149 switch (pItemThis->Type) 1150 { 1151 /* 1152 * TYPE_START_NEW_TABLE: 1153 * 1154 */ 1155 1156 case TYPE_START_NEW_TABLE: 1157 { 1158 // root table or nested? 1159 BOOL fIsRoot = (pCurrentTable == NULL); 1160 1161 // push the current table on the stack 1162 PSTACKITEM pStackItem; 1163 if (!(pStackItem = NEW(STACKITEM))) 1164 { 1165 arc = ERROR_NOT_ENOUGH_MEMORY; 1166 break; 1167 } 1168 else 1169 { 1170 pStackItem->pLastTable = pCurrentTable; 1171 pStackItem->pLastRow = pCurrentRow; 1172 lstPush(&llStack, pStackItem); 1173 } 1174 1175 // create new table 1176 if (!(pCurrentTable = NEW(TABLEDEF))) 1177 arc = ERROR_NOT_ENOUGH_MEMORY; 1178 else 1179 { 1180 ZERO(pCurrentTable); 1181 1182 lstInit(&pCurrentTable->llRows, FALSE); 1183 1184 if (pItemThis->ulData) 1185 // control specified: store it (this will become a PM group) 1186 pCurrentTable->pCtlDef = (PCONTROLDEF)pItemThis->ulData; 1187 1188 if (fIsRoot) 1189 // root table: 1190 // append to dialog data list 1191 lstAppendItem(&pDlgData->llTables, pCurrentTable); 1192 else 1193 { 1194 // nested table: 1195 // create "table" column for this 1196 PCOLUMNDEF pColumnDef; 1197 if (!(arc = CreateColumn(pCurrentRow, 1198 TRUE, // nested table 1199 pCurrentTable, 1200 &pColumnDef))) 1201 lstAppendItem(&pCurrentRow->llColumns, 1202 pColumnDef); 1203 } 1204 } 1205 1206 pCurrentRow = NULL; 1207 break; } 1208 1209 /* 1210 * TYPE_START_NEW_ROW: 1211 * 1212 */ 1213 1214 case TYPE_START_NEW_ROW: 1215 { 1216 if (!pCurrentTable) 1217 arc = DLGERR_ROW_BEFORE_TABLE; 1218 else 1219 { 1220 // create new row 1221 if (!(pCurrentRow = NEW(ROWDEF))) 1222 arc = ERROR_NOT_ENOUGH_MEMORY; 1223 else 1224 { 1225 ZERO(pCurrentRow); 1226 1227 pCurrentRow->pOwningTable = pCurrentTable; 1228 lstInit(&pCurrentRow->llColumns, FALSE); 1229 1230 pCurrentRow->flRowFormat = pItemThis->ulData; 1231 1232 lstAppendItem(&pCurrentTable->llRows, pCurrentRow); 1233 } 1234 } 1235 break; } 1236 1237 /* 1238 * TYPE_CONTROL_DEF: 1239 * 1240 */ 1241 1242 case TYPE_CONTROL_DEF: 1243 { 1244 PCOLUMNDEF pColumnDef; 1245 if (!(arc = CreateColumn(pCurrentRow, 1246 FALSE, // no nested table 1247 (PVOID)pItemThis->ulData, 1248 &pColumnDef))) 1249 lstAppendItem(&pCurrentRow->llColumns, 1250 pColumnDef); 1251 break; } 1252 1253 /* 1254 * TYPE_END_TABLE: 1255 * 1256 */ 1257 1258 case TYPE_END_TABLE: 1259 { 1260 PLISTNODE pNode = lstPop(&llStack); 1261 if (!pNode) 1262 // nothing on the stack: 1263 arc = DLGERR_TOO_MANY_TABLES_CLOSED; 1264 else 1265 { 1266 PSTACKITEM pStackItem = (PSTACKITEM)pNode->pItemData; 1267 pCurrentTable = pStackItem->pLastTable; 1268 pCurrentRow = pStackItem->pLastRow; 1269 1270 lstRemoveNode(&llStack, pNode); 1271 } 1272 break; } 1273 1274 default: 1275 arc = DLGERR_INVALID_CODE; 1276 } 1277 1278 if (arc) 1279 break; 1280 } 1281 1282 if ((!arc) && (lstCountItems(&llStack))) 1283 arc = DLGERR_TABLE_NOT_CLOSED; 1284 1285 lstClear(&llStack); 1286 1287 return (arc); 1288 } 1289 1290 /* 1291 *@@ Dlg2_CalcSizes: 1292 * 1293 *@@added V0.9.15 (2001-08-26) [umoeller] 1294 */ 1295 1296 APIRET Dlg2_CalcSizes(PDLGPRIVATE pDlgData, 1297 PSIZEL pszlClient) // out: dialog's client size 1298 { 1299 APIRET arc = ProcessAll(pDlgData, 1300 pszlClient, 1301 PROCESS_CALC_SIZES); 1302 // this goes into major recursions... 1303 1304 // free the cached font resources that 1305 // might have been created here 1306 if (pDlgData->hps) 1307 { 1308 if (pDlgData->lcidLast) 1309 { 1310 GpiSetCharSet(pDlgData->hps, LCID_DEFAULT); 1311 GpiDeleteSetId(pDlgData->hps, pDlgData->lcidLast); 1312 } 1313 WinReleasePS(pDlgData->hps); 1314 } 1315 1316 return (arc); 1317 } 1318 1319 /* 1320 *@@ Dlg3_PositionAndCreate: 1321 * 1322 *@@added V0.9.15 (2001-08-26) [umoeller] 1323 *@@changed V0.9.15 (2001-08-26) [umoeller]: BS_DEFAULT for other than first button was ignored, fixed 1324 */ 1325 1326 APIRET Dlg3_PositionAndCreate(PDLGPRIVATE pDlgData, 1327 PSIZEL pszlClient, // in: dialog's client size 1328 HWND *phwndFocusItem) // out: item to give focus to 1329 { 1330 APIRET arc = NO_ERROR; 1331 1332 /* 1333 * 5) compute _positions_ of all controls 1334 * 1335 */ 1336 1337 ProcessAll(pDlgData, 1338 pszlClient, 1339 PROCESS_CALC_POSITIONS); 1340 1341 /* 1342 * 6) create control windows, finally 1343 * 1344 */ 1345 1346 pDlgData->ptlTotalOfs.x 1347 = pDlgData->ptlTotalOfs.y 1348 = SPACING; 1349 1350 ProcessAll(pDlgData, 1351 pszlClient, 1352 PROCESS_CREATE_CONTROLS); 1353 1354 if (pDlgData->hwndDefPushbutton) 1355 { 1356 // we had a default pushbutton: 1357 // go set it V0.9.14 (2001-08-21) [umoeller] 1358 WinSetWindowULong(pDlgData->hwndDlg, 1359 QWL_DEFBUTTON, 1360 pDlgData->hwndDefPushbutton); 1361 *phwndFocusItem = pDlgData->hwndDefPushbutton; 1362 // V0.9.15 (2001-08-26) [umoeller] 1363 } 1364 else 1365 *phwndFocusItem = (pDlgData->hwndFirstFocus) 1366 ? pDlgData->hwndFirstFocus 1367 : pDlgData->hwndDlg; 1368 1369 return (arc); 1370 } 1371 1372 /* 1373 *@@ Dlg9_Cleanup: 1374 * 1375 *@@added V0.9.15 (2001-08-26) [umoeller] 1376 */ 1377 1378 VOID Dlg9_Cleanup(PDLGPRIVATE *ppDlgData) 1379 { 1380 PDLGPRIVATE pDlgData; 1381 if ( (ppDlgData) 1382 && (pDlgData = *ppDlgData) 1383 ) 1384 { 1385 PLISTNODE pTableNode; 1386 1387 // in any case, clean up our mess: 1388 1389 // clean up the tables 1390 FOR_ALL_NODES(&pDlgData->llTables, pTableNode) 1391 { 1392 PTABLEDEF pTable = (PTABLEDEF)pTableNode->pItemData; 1393 1394 FreeTable(pTable); 1395 // this may recurse for nested tables 1396 } 1397 1398 lstClear(&pDlgData->llTables); 1399 lstClear(&pDlgData->llControls); 1400 1401 free(pDlgData); 1402 1403 *ppDlgData = NULL; 1404 } 1405 } 1051 1406 1052 1407 /* … … 1291 1646 APIRET arc = NO_ERROR; 1292 1647 1293 #define SPACING 101294 1295 PTABLEDEF pCurrentTable = NULL;1296 PROWDEF pCurrentRow = NULL;1297 1648 ULONG ul; 1298 LINKLIST llStack; 1299 1300 PDLGPRIVATE pDlgData = NEW(DLGPRIVATE); 1301 1302 if (!pDlgData) 1303 return (ERROR_NOT_ENOUGH_MEMORY); 1304 1305 ZERO(pDlgData); 1306 lstInit(&pDlgData->llTables, FALSE); 1307 lstInit(&pDlgData->llControls, FALSE); 1308 1309 pDlgData->pcszControlsFont = pcszControlsFont; 1649 1650 PDLGPRIVATE pDlgData = NULL; 1310 1651 1311 1652 /* … … 1314 1655 */ 1315 1656 1316 lstInit(&llStack, TRUE); // this is our stack for nested table definitions 1317 1318 for (ul = 0; 1319 ul < cDlgItems; 1320 ul++) 1321 { 1322 PDLGHITEM pItemThis = &paDlgItems[ul]; 1323 1324 switch (pItemThis->Type) 1657 if (!(arc = Dlg0_Init(&pDlgData, 1658 pcszControlsFont))) 1659 { 1660 if (!(arc = Dlg1_ParseTables(pDlgData, 1661 paDlgItems, 1662 cDlgItems))) 1325 1663 { 1326 1664 /* 1327 * TYPE_START_NEW_TABLE:1665 * 2) create empty dialog frame 1328 1666 * 1329 1667 */ 1330 1668 1331 case TYPE_START_NEW_TABLE: 1669 FRAMECDATA fcData = {0}; 1670 ULONG flStyle = 0; 1671 1672 fcData.cb = sizeof(FRAMECDATA); 1673 fcData.flCreateFlags = flCreateFlags | 0x40000000L; 1674 1675 if (flCreateFlags & FCF_SIZEBORDER) 1676 // dialog has size border: 1677 // add "clip siblings" style 1678 flStyle |= WS_CLIPSIBLINGS; 1679 1680 if (hwndOwner == HWND_DESKTOP) 1681 // there's some dumb XWorkplace code left 1682 // which uses this, and this disables the 1683 // mouse for some reason 1684 // V0.9.14 (2001-07-07) [umoeller] 1685 hwndOwner = NULLHANDLE; 1686 1687 if (!(pDlgData->hwndDlg = WinCreateWindow(HWND_DESKTOP, 1688 WC_FRAME, 1689 (PSZ)pcszDlgTitle, 1690 flStyle, // style; invisible for now 1691 0, 0, 0, 0, 1692 hwndOwner, 1693 HWND_TOP, 1694 0, // ID 1695 &fcData, 1696 NULL))) // presparams 1697 arc = DLGERR_CANNOT_CREATE_FRAME; 1698 else 1332 1699 { 1333 // root table or nested? 1334 BOOL fIsRoot = (pCurrentTable == NULL); 1335 1336 // push the current table on the stack 1337 PSTACKITEM pStackItem; 1338 if (!(pStackItem = NEW(STACKITEM))) 1700 HWND hwndDlg = pDlgData->hwndDlg; 1701 HWND hwndFocusItem = NULLHANDLE; 1702 SIZEL szlClient = {0}; 1703 RECTL rclClient; 1704 1705 /* 1706 * 3) compute size of all controls 1707 * 1708 */ 1709 1710 Dlg2_CalcSizes(pDlgData, 1711 &szlClient); 1712 1713 WinSubclassWindow(hwndDlg, pfnwpDialogProc); 1714 1715 /* 1716 * 4) compute size of dialog client from total 1717 * size of all controls 1718 */ 1719 1720 // calculate the frame size from the client size 1721 rclClient.xLeft = 10; 1722 rclClient.yBottom = 10; 1723 rclClient.xRight = szlClient.cx + 2 * SPACING; 1724 rclClient.yTop = szlClient.cy + 2 * SPACING; 1725 WinCalcFrameRect(hwndDlg, 1726 &rclClient, 1727 FALSE); // frame from client 1728 1729 WinSetWindowPos(hwndDlg, 1730 0, 1731 10, 1732 10, 1733 rclClient.xRight, 1734 rclClient.yTop, 1735 SWP_MOVE | SWP_SIZE | SWP_NOADJUST); 1736 1737 arc = Dlg3_PositionAndCreate(pDlgData, 1738 &szlClient, 1739 &hwndFocusItem); 1740 1741 /* 1742 * 7) WM_INITDLG, set focus 1743 * 1744 */ 1745 1746 if (!WinSendMsg(pDlgData->hwndDlg, 1747 WM_INITDLG, 1748 (MPARAM)hwndFocusItem, 1749 (MPARAM)pCreateParams)) 1339 1750 { 1340 arc = ERROR_NOT_ENOUGH_MEMORY; 1341 break; 1751 // if WM_INITDLG returns FALSE, this means 1752 // the dlg proc has not changed the focus; 1753 // we must then set the focus here 1754 WinSetFocus(HWND_DESKTOP, hwndFocusItem); 1342 1755 } 1343 else1344 {1345 pStackItem->pLastTable = pCurrentTable;1346 pStackItem->pLastRow = pCurrentRow;1347 lstPush(&llStack, pStackItem);1348 }1349 1350 // create new table1351 if (!(pCurrentTable = NEW(TABLEDEF)))1352 arc = ERROR_NOT_ENOUGH_MEMORY;1353 else1354 {1355 ZERO(pCurrentTable);1356 1357 lstInit(&pCurrentTable->llRows, FALSE);1358 1359 if (pItemThis->ulData)1360 // control specified: store it (this will become a PM group)1361 pCurrentTable->pCtlDef = (PCONTROLDEF)pItemThis->ulData;1362 1363 if (fIsRoot)1364 // root table:1365 // append to dialog data list1366 lstAppendItem(&pDlgData->llTables, pCurrentTable);1367 else1368 {1369 // nested table:1370 // create "table" column for this1371 PCOLUMNDEF pColumnDef;1372 if (!(arc = CreateColumn(pCurrentRow,1373 TRUE, // nested table1374 pCurrentTable,1375 &pColumnDef)))1376 lstAppendItem(&pCurrentRow->llColumns,1377 pColumnDef);1378 }1379 }1380 1381 pCurrentRow = NULL;1382 break; }1383 1384 /*1385 * TYPE_START_NEW_ROW:1386 *1387 */1388 1389 case TYPE_START_NEW_ROW:1390 {1391 if (!pCurrentTable)1392 arc = DLGERR_ROW_BEFORE_TABLE;1393 else1394 {1395 // create new row1396 if (!(pCurrentRow = NEW(ROWDEF)))1397 arc = ERROR_NOT_ENOUGH_MEMORY;1398 else1399 {1400 ZERO(pCurrentRow);1401 1402 pCurrentRow->pOwningTable = pCurrentTable;1403 lstInit(&pCurrentRow->llColumns, FALSE);1404 1405 pCurrentRow->flRowFormat = pItemThis->ulData;1406 1407 lstAppendItem(&pCurrentTable->llRows, pCurrentRow);1408 }1409 }1410 break; }1411 1412 /*1413 * TYPE_CONTROL_DEF:1414 *1415 */1416 1417 case TYPE_CONTROL_DEF:1418 {1419 PCOLUMNDEF pColumnDef;1420 if (!(arc = CreateColumn(pCurrentRow,1421 FALSE, // no nested table1422 (PVOID)pItemThis->ulData,1423 &pColumnDef)))1424 lstAppendItem(&pCurrentRow->llColumns,1425 pColumnDef);1426 break; }1427 1428 /*1429 * TYPE_END_TABLE:1430 *1431 */1432 1433 case TYPE_END_TABLE:1434 {1435 PLISTNODE pNode = lstPop(&llStack);1436 if (!pNode)1437 // nothing on the stack:1438 arc = DLGERR_TOO_MANY_TABLES_CLOSED;1439 else1440 {1441 PSTACKITEM pStackItem = (PSTACKITEM)pNode->pItemData;1442 pCurrentTable = pStackItem->pLastTable;1443 pCurrentRow = pStackItem->pLastRow;1444 1445 lstRemoveNode(&llStack, pNode);1446 }1447 break; }1448 1449 default:1450 arc = DLGERR_INVALID_CODE;1451 }1452 1453 if (arc)1454 break;1455 }1456 1457 if (arc == NO_ERROR)1458 if (lstCountItems(&llStack))1459 arc = DLGERR_TABLE_NOT_CLOSED;1460 1461 lstClear(&llStack);1462 1463 if (arc == NO_ERROR)1464 {1465 /*1466 * 2) create empty dialog frame1467 *1468 */1469 1470 FRAMECDATA fcData = {0};1471 ULONG flStyle = 0;1472 1473 fcData.cb = sizeof(FRAMECDATA);1474 fcData.flCreateFlags = flCreateFlags | 0x40000000L;1475 1476 if (flCreateFlags & FCF_SIZEBORDER)1477 // dialog has size border:1478 // add "clip siblings" style1479 flStyle |= WS_CLIPSIBLINGS;1480 1481 if (hwndOwner == HWND_DESKTOP)1482 // there's some dumb XWorkplace code left1483 // which uses this, and this disables the1484 // mouse for some reason1485 // V0.9.14 (2001-07-07) [umoeller]1486 hwndOwner = NULLHANDLE;1487 1488 if (!(pDlgData->hwndDlg = WinCreateWindow(HWND_DESKTOP,1489 WC_FRAME,1490 (PSZ)pcszDlgTitle,1491 flStyle, // style; invisible for now1492 0, 0, 0, 0,1493 hwndOwner,1494 HWND_TOP,1495 0, // ID1496 &fcData,1497 NULL))) // presparams1498 arc = DLGERR_CANNOT_CREATE_FRAME;1499 else1500 {1501 HWND hwndDlg = pDlgData->hwndDlg;1502 SIZEL szlClient = {0};1503 RECTL rclClient;1504 HWND hwndFocusItem = NULLHANDLE;1505 1506 /*1507 * 3) compute size of all controls1508 *1509 */1510 1511 ProcessAll(pDlgData,1512 &szlClient,1513 PROCESS_CALC_SIZES);1514 // this goes into major recursions...1515 1516 // free the cached font resources that1517 // might have been created here1518 if (pDlgData->lcidLast)1519 {1520 GpiSetCharSet(pDlgData->hps, LCID_DEFAULT);1521 GpiDeleteSetId(pDlgData->hps, pDlgData->lcidLast);1522 1756 } 1523 if (pDlgData->hps) 1524 WinReleasePS(pDlgData->hps); 1525 1526 WinSubclassWindow(hwndDlg, pfnwpDialogProc); 1527 1528 /* 1529 * 4) compute size of dialog client from total 1530 * size of all controls 1531 */ 1532 1533 // calculate the frame size from the client size 1534 rclClient.xLeft = 10; 1535 rclClient.yBottom = 10; 1536 rclClient.xRight = szlClient.cx + 2 * SPACING; 1537 rclClient.yTop = szlClient.cy + 2 * SPACING; 1538 WinCalcFrameRect(hwndDlg, 1539 &rclClient, 1540 FALSE); // frame from client 1541 1542 WinSetWindowPos(hwndDlg, 1543 0, 1544 10, 1545 10, 1546 rclClient.xRight, 1547 rclClient.yTop, 1548 SWP_MOVE | SWP_SIZE | SWP_NOADJUST); 1549 1550 /* 1551 * 5) compute _positions_ of all controls 1552 * 1553 */ 1554 1555 ProcessAll(pDlgData, 1556 &szlClient, 1557 PROCESS_CALC_POSITIONS); 1558 1559 /* 1560 * 6) create control windows, finally 1561 * 1562 */ 1563 1564 pDlgData->ptlTotalOfs.x = SPACING; 1565 pDlgData->ptlTotalOfs.y = SPACING; 1566 1567 ProcessAll(pDlgData, 1568 &szlClient, 1569 PROCESS_CREATE_CONTROLS); 1570 1571 if (pDlgData->hwndDefPushbutton) 1572 // we had a default pushbutton: 1573 // go set it V0.9.14 (2001-08-21) [umoeller] 1574 WinSetWindowULong(pDlgData->hwndDlg, 1575 QWL_DEFBUTTON, 1576 pDlgData->hwndDefPushbutton); 1577 1578 /* 1579 * 7) WM_INITDLG, set focus 1580 * 1581 */ 1582 1583 hwndFocusItem = (pDlgData->hwndFirstFocus) 1584 ? pDlgData->hwndFirstFocus 1585 : hwndDlg; 1586 if (!WinSendMsg(hwndDlg, 1587 WM_INITDLG, 1588 (MPARAM)hwndFocusItem, 1589 (MPARAM)pCreateParams)) 1590 { 1591 // if WM_INITDLG returns FALSE, this means 1592 // the dlg proc has not changed the focus; 1593 // we must then set the focus here 1594 WinSetFocus(HWND_DESKTOP, hwndFocusItem); 1595 } 1596 } 1597 } 1598 1599 if (pDlgData) 1600 { 1601 PLISTNODE pTableNode; 1757 } 1602 1758 1603 1759 if (arc) … … 1605 1761 // error: clean up 1606 1762 if (pDlgData->hwndDlg) 1763 { 1607 1764 WinDestroyWindow(pDlgData->hwndDlg); 1765 pDlgData->hwndDlg = NULLHANDLE; 1766 } 1608 1767 } 1609 1768 else … … 1611 1770 *phwndDlg = pDlgData->hwndDlg; 1612 1771 1613 // in any case, clean up our mess: 1614 1615 // clean up the tables 1616 FOR_ALL_NODES(&pDlgData->llTables, pTableNode) 1617 { 1618 PTABLEDEF pTable = (PTABLEDEF)pTableNode->pItemData; 1619 1620 FreeTable(pTable); 1621 // this may recurse for nested tables 1622 } 1623 1624 lstClear(&pDlgData->llTables); 1625 lstClear(&pDlgData->llControls); 1626 1627 free(pDlgData); 1772 Dlg9_Cleanup(&pDlgData); 1628 1773 } 1629 1774
Note:
See TracChangeset
for help on using the changeset viewer.