Index: trunk/src/helpers/dialog.c
===================================================================
--- trunk/src/helpers/dialog.c	(revision 196)
+++ trunk/src/helpers/dialog.c	(revision 197)
@@ -237,7 +237,9 @@
     LINKLIST    llRows;             // contains ROWDEF structs, no auto-free
 
-    PCONTROLDEF pCtlDef;            // if != NULL, we create a PM control around the table
+    const CONTROLDEF *pCtlDef;      // if != NULL, we create a PM control around the table
 
     CONTROLPOS  cpTable;
+
+    ULONG       flTable;            // copied from DLGHITEM
 
 } TABLEDEF;
@@ -274,5 +276,5 @@
  */
 
-static VOID SetDlgFont(PCONTROLDEF pControlDef,
+static VOID SetDlgFont(const CONTROLDEF *pControlDef,
                        PDLGPRIVATE pDlgData)
 {
@@ -340,5 +342,5 @@
  */
 
-static APIRET CalcAutoSizeText(PCONTROLDEF pControlDef,
+static APIRET CalcAutoSizeText(const CONTROLDEF *pControlDef,
                                BOOL fMultiLine,          // in: if TRUE, multiple lines
                                ULONG ulWidth,            // in: proposed width of control
@@ -407,5 +409,5 @@
  */
 
-static APIRET CalcAutoSize(PCONTROLDEF pControlDef,
+static APIRET CalcAutoSize(const CONTROLDEF *pControlDef,
                            ULONG ulWidth,            // in: proposed width of control
                            PSIZEL pszlAuto,          // out: computed size
@@ -519,5 +521,5 @@
 {
     APIRET      arc = NO_ERROR;
-    PCONTROLDEF pControlDef = NULL;
+    const CONTROLDEF *pControlDef = NULL;
     ULONG       xExtraColumn = 0,
                 yExtraColumn = 0;
@@ -574,5 +576,5 @@
         SIZEL       szlAuto;
 
-        pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition;
+        pControlDef = (const CONTROLDEF *)pColumnDef->pvDefinition;
 
         // do auto-size calculations only on the first loop
@@ -742,5 +744,5 @@
     {
         // no nested table, but control:
-        PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition;
+        const CONTROLDEF *pControlDef = (const CONTROLDEF *)pColumnDef->pvDefinition;
         xSpacingControl = pControlDef->duSpacing * FACTOR_X;
         ySpacingControl = pControlDef->duSpacing * FACTOR_Y;
@@ -788,5 +790,5 @@
     APIRET      arc = NO_ERROR;
 
-    PCONTROLDEF pControlDef = NULL;
+    const CONTROLDEF *pControlDef = NULL;
 
     PCSZ        pcszClass = NULL;
@@ -877,5 +879,5 @@
     {
         // no nested table, but control:
-        pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition;
+        pControlDef = (const CONTROLDEF *)pColumnDef->pvDefinition;
         // pcp = &pColumnDef->cpControl;
         pcszClass = pControlDef->pcszClass;
@@ -1113,4 +1115,5 @@
  *@@changed V0.9.12 (2001-05-31) [umoeller]: added control data
  *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed font problems
+ *@@changed V0.9.20 (2002-08-08) [umoeller]: added support for aligning columns horizontally
  */
 
@@ -1156,5 +1159,5 @@
             {
                 // no nested table, but control:
-                PCONTROLDEF pControlDef = (PCONTROLDEF)pColumnDef->pvDefinition;
+                const CONTROLDEF *pControlDef = (const CONTROLDEF *)pColumnDef->pvDefinition;
 
                 if (    (pControlDef->szlDlgUnits.cx < -1)
@@ -1225,4 +1228,6 @@
 
         case PROCESS_3_CALC_FINAL_TABLE_SIZES:
+        {
+            PTABLEDEF pOwningTable;
             // re-run calc sizes since we now know all
             // the auto-size items
@@ -1230,4 +1235,37 @@
                                   ProcessMode,
                                   pDlgData);
+
+
+            // now check if the table has TABLE_ALIGN_COLUMNS enabled
+            // (START_TABLE_ALIGN or START_GROUP_TABLE_ALIGN macros)
+            // and, if so, align the colums horizontally by making all
+            // columns as wide as the widest column in the table
+            // V0.9.20 (2002-08-08) [umoeller]
+            if (    (pOwningRow)
+                 && (pOwningTable = pOwningRow->pOwningTable)
+                 && (pOwningTable->flTable & TABLE_ALIGN_COLUMNS)
+               )
+            {
+                // determine the index of this column in the current row
+                ULONG ulMyIndex = lstIndexFromItem(&pOwningRow->llColumns,
+                                                   pColumnDef);
+                if (ulMyIndex == -1)
+                    arc = DLGERR_INTEGRITY_BAD_COLUMN_INDEX;
+                else
+                {
+                    // find the widest column with this index in the table
+                    PLISTNODE pRowNode;
+                    FOR_ALL_NODES(&pOwningTable->llRows, pRowNode)
+                    {
+                        PROWDEF     pRowThis = (PROWDEF)pRowNode->pItemData;
+                        PCOLUMNDEF  pCorrespondingColumn;
+                        if (    (pCorrespondingColumn = lstItemFromIndex(&pRowThis->llColumns, ulMyIndex))
+                             && (pCorrespondingColumn->cpColumn.cx > pColumnDef->cpColumn.cx)
+                           )
+                            pColumnDef->cpColumn.cx = pCorrespondingColumn->cpColumn.cx;
+                    }
+                }
+            }
+        }
         break;
 
@@ -1279,23 +1317,24 @@
     pRowDef->pOwningTable = pOwningTable;
 
-    if (    (ProcessMode == PROCESS_1_CALC_SIZES)
-         || (ProcessMode == PROCESS_3_CALC_FINAL_TABLE_SIZES)
-       )
-    {
-        pRowDef->cpRow.cx = 0;
-        pRowDef->cpRow.cy = 0;
-    }
-    else if (ProcessMode == PROCESS_4_CALC_POSITIONS)
-    {
-        // set up x and y so that the columns can
-        // base on that
-        pRowDef->cpRow.x = pOwningTable->cpTable.x;
-        // decrease y by row height
-        *plY -= pRowDef->cpRow.cy;
-        // and use that for our bottom position
-        pRowDef->cpRow.y = *plY;
-
-        // set lX to left of row; used by column calls below
-        lX = pRowDef->cpRow.x;
+    switch (ProcessMode)
+    {
+        case PROCESS_1_CALC_SIZES:
+        case PROCESS_3_CALC_FINAL_TABLE_SIZES:
+            pRowDef->cpRow.cx = 0;
+            pRowDef->cpRow.cy = 0;
+        break;
+
+        case PROCESS_4_CALC_POSITIONS:
+            // set up x and y so that the columns can
+            // base on that
+            pRowDef->cpRow.x = pOwningTable->cpTable.x;
+            // decrease y by row height
+            *plY -= pRowDef->cpRow.cy;
+            // and use that for our bottom position
+            pRowDef->cpRow.y = *plY;
+
+            // set lX to left of row; used by column calls below
+            lX = pRowDef->cpRow.x;
+        break;
     }
 
@@ -1356,4 +1395,8 @@
     {
         case PROCESS_1_CALC_SIZES:
+            pTableDef->cpTable.cx = 0;
+            pTableDef->cpTable.cy = 0;
+        break;
+
         case PROCESS_3_CALC_FINAL_TABLE_SIZES:
             pTableDef->cpTable.cx = 0;
@@ -1404,5 +1447,5 @@
  *
  *      The first trick to formatting is that ProcessAll will
- *      get three times, thus going down the entire tree three
+ *      get FIVE times, thus going down the entire tree FIVE
  *      times, with ProcessMode being set to one of the
  *      following for each call (in this order):
@@ -1510,6 +1553,6 @@
         {
             // create column and store ctl def
-            PCOLUMNDEF pColumnDef = NEW(COLUMNDEF);
-            if (!pColumnDef)
+            PCOLUMNDEF pColumnDef;
+            if (!(pColumnDef = NEW(COLUMNDEF)))
                 arc = ERROR_NOT_ENOUGH_MEMORY;
             else
@@ -1706,7 +1749,8 @@
                     lstInit(&pCurrentTable->llRows, FALSE);
 
-                    if (pItemThis->ulData)
-                        // control specified: store it (this will become a PM group)
-                        pCurrentTable->pCtlDef = (PCONTROLDEF)pItemThis->ulData;
+                    // if control specified: store it (this will become a PM group)
+                    pCurrentTable->pCtlDef = pItemThis->pCtlDef;        // can be NULL for plain table
+
+                    pCurrentTable->flTable = pItemThis->fl;         // V0.9.20 (2002-08-08) [umoeller]
 
                     if (fIsRoot)
@@ -1756,5 +1800,5 @@
                         lstInit(&pCurrentRow->llColumns, FALSE);
 
-                        pCurrentRow->flRowFormat = pItemThis->ulData;
+                        pCurrentRow->flRowFormat = pItemThis->fl;
 
                         lstAppendItem(&pCurrentTable->llRows, pCurrentRow);
@@ -1774,5 +1818,5 @@
                 if (!(arc = CreateColumn(pCurrentRow,
                                          FALSE,        // no nested table
-                                         (PVOID)pItemThis->ulData,
+                                         (PVOID)pItemThis->pCtlDef,
                                          &pColumnDef)))
                     lstAppendItem(&pCurrentRow->llColumns,
@@ -1961,6 +2005,6 @@
  *      automatically here. Even better, for many controls,
  *      auto-sizing is supported according to the control's
- *      text (e.g. for statics and checkboxes). In a way,
- *      this is a bit similar to HTML tables.
+ *      text (e.g. for statics and checkboxes). This is
+ *      quite similar to HTML tables.
  *
  *      A regular standard dialog would use something like
@@ -2005,4 +2049,9 @@
  *      --  START_TABLE starts a new table. The tables may nest,
  *          but must each be properly terminated with END_TABLE.
+ *
+ *          Note that as opposed to HTML tables, the columns
+ *          in the rows of the table are NOT aligned under each
+ *          other. If that is what you want, use START_TABLE_ALIGN
+ *          instead.
  *
  *      --  START_GROUP_TABLE(pDef) starts a group. This
@@ -2017,4 +2066,8 @@
  *          terminated with END_TABLE.
  *
+ *          As with START_TABLE, columns in the rows of the table
+ *          are NOT aligned under each other. If that is what you
+ *          want, use START_GROUP_TABLE_ALIGN instead.
+ *
  *      --  START_ROW(fl) starts a new row in a table (regular
  *          or group). This must also be the first item after
@@ -2044,4 +2097,8 @@
  *          control items will be considered to be in the same
  *          row (== positioned next to each other).
+ *
+ *          Columns will only be aligned horizontally if the
+ *          container table was specified with START_TABLE_ALIGN
+ *          or START_GROUP_TABLE_ALIGN.
  *
  *      There are a few rules, whose violation will produce
@@ -2163,9 +2220,10 @@
  *          specify a row first.
  *
- *      --  DLGERR_NULL_CTL_DEF: TYPE_END_TABLE was specified,
- *          but the CONTROLDEF ptr was NULL.
+ *      --  DLGERR_NULL_CTL_DEF: A required CONTROLDEF ptr
+ *          was NULL.
  *
  *      --  DLGERR_CANNOT_CREATE_FRAME: unable to create the
- *          WC_FRAME window. Maybe an invalid owner was specified.
+ *          WC_FRAME window. Typically an invalid owner was
+ *          specified.
  *
  *      --  DLGERR_INVALID_CODE: invalid "Type" field in
