Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

lboxvar.c

Go to the documentation of this file.
00001 /**************************** Module Header ********************************\ 00002 * Module Name: lboxvar.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * List Box variable height owner draw routines 00007 * 00008 * History: 00009 * ??-???-???? ianja Ported from Win 3.0 sources 00010 * 14-Feb-1991 mikeke Added Revalidation code (None) 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * LBGetVariableHeightItemHeight 00018 * 00019 * Returns the height of the given item number. Assumes variable 00020 * height owner draw. 00021 * 00022 * History: 00023 \***************************************************************************/ 00024 00025 INT LBGetVariableHeightItemHeight( 00026 PLBIV plb, 00027 INT itemNumber) 00028 { 00029 BYTE itemHeight; 00030 int offsetHeight; 00031 00032 if (plb->cMac) { 00033 if (plb->fHasStrings) 00034 offsetHeight = plb->cMac * sizeof(LBItem); 00035 else 00036 offsetHeight = plb->cMac * sizeof(LBODItem); 00037 00038 if (plb->wMultiple) 00039 offsetHeight += plb->cMac; 00040 00041 offsetHeight += itemNumber; 00042 00043 itemHeight = *(plb->rgpch+(UINT)offsetHeight); 00044 00045 return (INT)itemHeight; 00046 00047 } 00048 00049 /* 00050 *Default, we return the height of the system font. This is so we can draw 00051 * the focus rect even though there are no items in the listbox. 00052 */ 00053 return gpsi->cySysFontChar; 00054 } 00055 00056 00057 /***************************************************************************\ 00058 * LBSetVariableHeightItemHeight 00059 * 00060 * Sets the height of the given item number. Assumes variable height 00061 * owner draw, a valid item number and valid height. 00062 * 00063 * 00064 * History: 00065 \***************************************************************************/ 00066 00067 void LBSetVariableHeightItemHeight( 00068 PLBIV plb, 00069 INT itemNumber, 00070 INT itemHeight) 00071 { 00072 int offsetHeight; 00073 00074 if (plb->fHasStrings) 00075 offsetHeight = plb->cMac * sizeof(LBItem); 00076 else 00077 offsetHeight = plb->cMac * sizeof(LBODItem); 00078 00079 if (plb->wMultiple) 00080 offsetHeight += plb->cMac; 00081 00082 offsetHeight += itemNumber; 00083 00084 *(plb->rgpch + (UINT)offsetHeight) = (BYTE)itemHeight; 00085 00086 } 00087 00088 00089 /***************************************************************************\ 00090 * CItemInWindowVarOwnerDraw 00091 * 00092 * Returns the number of items which can fit in a variable height OWNERDRAW 00093 * list box. If fDirection, then we return the number of items which 00094 * fit starting at sTop and going forward (for page down), otherwise, we are 00095 * going backwards (for page up). (Assumes var height ownerdraw) If fPartial, 00096 * then include the partially visible item at the bottom of the listbox. 00097 * 00098 * History: 00099 \***************************************************************************/ 00100 00101 INT CItemInWindowVarOwnerDraw( 00102 PLBIV plb, 00103 BOOL fPartial) 00104 { 00105 RECT rect; 00106 INT sItem; 00107 INT clientbottom; 00108 00109 _GetClientRect(plb->spwnd, (LPRECT)&rect); 00110 clientbottom = rect.bottom; 00111 00112 /* 00113 * Find the number of var height ownerdraw items which are visible starting 00114 * from plb->iTop. 00115 */ 00116 for (sItem = plb->iTop; sItem < plb->cMac; sItem++) { 00117 00118 /* 00119 * Find out if the item is visible or not 00120 */ 00121 if (!LBGetItemRect(plb, sItem, (LPRECT)&rect)) { 00122 00123 /* 00124 * This is the first item which is completely invisible, so return 00125 * how many items are visible. 00126 */ 00127 return (sItem - plb->iTop); 00128 } 00129 00130 if (!fPartial && rect.bottom > clientbottom) { 00131 00132 /* 00133 * If we only want fully visible items, then if this item is 00134 * visible, we check if the bottom of the item is below the client 00135 * rect, so we return how many are fully visible. 00136 */ 00137 return (sItem - plb->iTop - 1); 00138 } 00139 } 00140 00141 /* 00142 * All the items are visible 00143 */ 00144 return (plb->cMac - plb->iTop); 00145 } 00146 00147 00148 /***************************************************************************\ 00149 * LBPage 00150 * 00151 * For variable height ownerdraw listboxes, calaculates the new iTop we must 00152 * move to when paging (page up/down) through variable height listboxes. 00153 * 00154 * History: 00155 \***************************************************************************/ 00156 00157 INT LBPage( 00158 PLBIV plb, 00159 INT startItem, 00160 BOOL fPageForwardDirection) 00161 { 00162 INT i; 00163 INT height; 00164 RECT rc; 00165 00166 if (plb->cMac == 1) 00167 return(0); 00168 00169 _GetClientRect(plb->spwnd, &rc); 00170 height = rc.bottom; 00171 i = startItem; 00172 00173 if (fPageForwardDirection) { 00174 while ((height >= 0) && (i < plb->cMac)) 00175 height -= LBGetVariableHeightItemHeight(plb, i++); 00176 00177 return((height >= 0) ? plb->cMac - 1 : max(i - 2, startItem + 1)); 00178 } else { 00179 while ((height >= 0) && (i >= 0)) 00180 height -= LBGetVariableHeightItemHeight(plb, i--); 00181 00182 return((height >= 0) ? 0 : min(i + 2, startItem - 1)); 00183 } 00184 00185 } 00186 00187 00188 /***************************************************************************\ 00189 * LBCalcVarITopScrollAmt 00190 * 00191 * Changing the top most item in the listbox from iTopOld to iTopNew we 00192 * want to calculate the number of pixels to scroll so that we minimize the 00193 * number of items we will redraw. 00194 * 00195 * History: 00196 \***************************************************************************/ 00197 00198 INT LBCalcVarITopScrollAmt( 00199 PLBIV plb, 00200 INT iTopOld, 00201 INT iTopNew) 00202 { 00203 RECT rc; 00204 RECT rcClient; 00205 00206 _GetClientRect(plb->spwnd, (LPRECT)&rcClient); 00207 00208 /* 00209 * Just optimize redrawing when move +/- 1 item. We will redraw all items 00210 * if moving more than 1 item ahead or back. This is good enough for now. 00211 */ 00212 if (iTopOld + 1 == iTopNew) { 00213 00214 /* 00215 * We are scrolling the current iTop up off the top off the listbox so 00216 * return a negative number. 00217 */ 00218 LBGetItemRect(plb, iTopOld, (LPRECT)&rc); 00219 return (rcClient.top - rc.bottom); 00220 } 00221 00222 if (iTopOld - 1 == iTopNew) { 00223 00224 /* 00225 * We are scrolling the current iTop down and the previous item is 00226 * becoming the new iTop so return a positive number. 00227 */ 00228 LBGetItemRect(plb, iTopNew, (LPRECT)&rc); 00229 return -rc.top; 00230 } 00231 00232 return rcClient.bottom - rcClient.top; 00233 }

Generated on Sat May 15 19:40:37 2004 for test by doxygen 1.3.7