00001 /**************************** Module Header ********************************\ 00002 * Module Name: lboxmult.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Multi column list box routines 00007 * 00008 * History: 00009 * ??-???-???? ianja Ported from Win 3.0 sources 00010 * 14-Feb-1991 mikeke Added Revalidation code 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * LBCalcItemRowsAndColumns 00018 * 00019 * Calculates the number of columns (including partially visible) 00020 * in the listbox and calculates the number of items per column 00021 * 00022 * History: 00023 \***************************************************************************/ 00024 00025 void LBCalcItemRowsAndColumns( 00026 PLBIV plb) 00027 { 00028 RECT rc; 00029 00030 _GetClientRect(plb->spwnd, &rc); 00031 00032 // 00033 // B#4155 00034 // We need to check if plb->cyChar has been initialized. This is because 00035 // we remove WS_BORDER from old listboxes and add on WS_EX_CLIENTEDGE. 00036 // Since listboxes are always inflated by CXBORDER and CYBORDER, a 00037 // listbox that was created empty always ends up 2 x 2. Since this isn't 00038 // big enough to fit the entire client border, we don't mark it as 00039 // present. Thus the client isn't empty in VER40, although it was in 00040 // VER31 and before. It is possible to get to this spot without 00041 // plb->cyChar having been initialized yet if the listbox is 00042 // multicolumn && ownerdraw variable. 00043 // 00044 00045 if (rc.bottom && rc.right && plb->cyChar) { 00046 00047 /* 00048 * Only make these calculations if the width & height are positive 00049 */ 00050 plb->itemsPerColumn = (INT)max(rc.bottom / plb->cyChar, 1); 00051 plb->numberOfColumns = (INT)max(rc.right / plb->cxColumn, 1); 00052 00053 plb->cItemFullMax = plb->itemsPerColumn * plb->numberOfColumns; 00054 00055 /* 00056 * Adjust iTop so it's at the top of a column 00057 */ 00058 xxxNewITop(plb, plb->iTop); 00059 } 00060 } 00061 00062 00063 /***************************************************************************\ 00064 * xxxLBoxCtlHScrollMultiColumn 00065 * 00066 * Supports horizontal scrolling of multicolumn listboxes 00067 * 00068 * History: 00069 \***************************************************************************/ 00070 00071 void xxxLBoxCtlHScrollMultiColumn( 00072 PLBIV plb, 00073 INT cmd, 00074 INT xAmt) 00075 { 00076 INT iTop = plb->iTop; 00077 00078 CheckLock(plb->spwnd); 00079 00080 if (!plb->cMac) return; 00081 00082 switch (cmd) { 00083 case SB_LINEUP: 00084 if (plb->fRightAlign) 00085 goto ReallyLineDown; 00086 ReallyLineUp: 00087 iTop -= plb->itemsPerColumn; 00088 break; 00089 case SB_LINEDOWN: 00090 if (plb->fRightAlign) 00091 goto ReallyLineUp; 00092 ReallyLineDown: 00093 iTop += plb->itemsPerColumn; 00094 break; 00095 case SB_PAGEUP: 00096 if (plb->fRightAlign) 00097 goto ReallyPageDown; 00098 ReallyPageUp: 00099 iTop -= plb->itemsPerColumn * plb->numberOfColumns; 00100 break; 00101 case SB_PAGEDOWN: 00102 if (plb->fRightAlign) 00103 goto ReallyPageUp; 00104 ReallyPageDown: 00105 iTop += plb->itemsPerColumn * plb->numberOfColumns; 00106 break; 00107 case SB_THUMBTRACK: 00108 case SB_THUMBPOSITION: 00109 if (plb->fRightAlign) { 00110 int iCols = plb->cMac ? ((plb->cMac-1) / plb->itemsPerColumn) + 1 : 0; 00111 00112 xAmt = iCols - (xAmt + plb->numberOfColumns); 00113 if (xAmt<0) 00114 xAmt=0; 00115 } 00116 iTop = xAmt * plb->itemsPerColumn; 00117 break; 00118 case SB_TOP: 00119 if (plb->fRightAlign) 00120 goto ReallyBottom; 00121 ReallyTop: 00122 iTop = 0; 00123 break; 00124 case SB_BOTTOM: 00125 if (plb->fRightAlign) 00126 goto ReallyTop; 00127 ReallyBottom: 00128 iTop = plb->cMac - 1 - ((plb->cMac - 1) % plb->itemsPerColumn); 00129 break; 00130 case SB_ENDSCROLL: 00131 plb->fSmoothScroll = TRUE; 00132 xxxLBShowHideScrollBars(plb); 00133 break; 00134 } 00135 00136 xxxNewITop(plb, iTop); 00137 }