Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

233 lines
6.3 KiB

/**************************** Module Header ********************************\
* Module Name: lboxvar.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* List Box variable height owner draw routines
*
* History:
* ??-???-???? ianja Ported from Win 3.0 sources
* 14-Feb-1991 mikeke Added Revalidation code (None)
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* LBGetVariableHeightItemHeight
*
* Returns the height of the given item number. Assumes variable
* height owner draw.
*
* History:
\***************************************************************************/
INT LBGetVariableHeightItemHeight(
PLBIV plb,
INT itemNumber)
{
BYTE itemHeight;
int offsetHeight;
if (plb->cMac) {
if (plb->fHasStrings)
offsetHeight = plb->cMac * sizeof(LBItem);
else
offsetHeight = plb->cMac * sizeof(LBODItem);
if (plb->wMultiple)
offsetHeight += plb->cMac;
offsetHeight += itemNumber;
itemHeight = *(plb->rgpch+(UINT)offsetHeight);
return (INT)itemHeight;
}
/*
*Default, we return the height of the system font. This is so we can draw
* the focus rect even though there are no items in the listbox.
*/
return gpsi->cySysFontChar;
}
/***************************************************************************\
* LBSetVariableHeightItemHeight
*
* Sets the height of the given item number. Assumes variable height
* owner draw, a valid item number and valid height.
*
*
* History:
\***************************************************************************/
void LBSetVariableHeightItemHeight(
PLBIV plb,
INT itemNumber,
INT itemHeight)
{
int offsetHeight;
if (plb->fHasStrings)
offsetHeight = plb->cMac * sizeof(LBItem);
else
offsetHeight = plb->cMac * sizeof(LBODItem);
if (plb->wMultiple)
offsetHeight += plb->cMac;
offsetHeight += itemNumber;
*(plb->rgpch + (UINT)offsetHeight) = (BYTE)itemHeight;
}
/***************************************************************************\
* CItemInWindowVarOwnerDraw
*
* Returns the number of items which can fit in a variable height OWNERDRAW
* list box. If fDirection, then we return the number of items which
* fit starting at sTop and going forward (for page down), otherwise, we are
* going backwards (for page up). (Assumes var height ownerdraw) If fPartial,
* then include the partially visible item at the bottom of the listbox.
*
* History:
\***************************************************************************/
INT CItemInWindowVarOwnerDraw(
PLBIV plb,
BOOL fPartial)
{
RECT rect;
INT sItem;
INT clientbottom;
_GetClientRect(plb->spwnd, (LPRECT)&rect);
clientbottom = rect.bottom;
/*
* Find the number of var height ownerdraw items which are visible starting
* from plb->iTop.
*/
for (sItem = plb->iTop; sItem < plb->cMac; sItem++) {
/*
* Find out if the item is visible or not
*/
if (!LBGetItemRect(plb, sItem, (LPRECT)&rect)) {
/*
* This is the first item which is completely invisible, so return
* how many items are visible.
*/
return (sItem - plb->iTop);
}
if (!fPartial && rect.bottom > clientbottom) {
/*
* If we only want fully visible items, then if this item is
* visible, we check if the bottom of the item is below the client
* rect, so we return how many are fully visible.
*/
return (sItem - plb->iTop - 1);
}
}
/*
* All the items are visible
*/
return (plb->cMac - plb->iTop);
}
/***************************************************************************\
* LBPage
*
* For variable height ownerdraw listboxes, calaculates the new iTop we must
* move to when paging (page up/down) through variable height listboxes.
*
* History:
\***************************************************************************/
INT LBPage(
PLBIV plb,
INT startItem,
BOOL fPageForwardDirection)
{
INT i;
INT height;
RECT rc;
if (plb->cMac == 1)
return(0);
_GetClientRect(plb->spwnd, &rc);
height = rc.bottom;
i = startItem;
if (fPageForwardDirection) {
while ((height >= 0) && (i < plb->cMac))
height -= LBGetVariableHeightItemHeight(plb, i++);
return((height >= 0) ? plb->cMac - 1 : max(i - 2, startItem + 1));
} else {
while ((height >= 0) && (i >= 0))
height -= LBGetVariableHeightItemHeight(plb, i--);
return((height >= 0) ? 0 : min(i + 2, startItem - 1));
}
}
/***************************************************************************\
* LBCalcVarITopScrollAmt
*
* Changing the top most item in the listbox from iTopOld to iTopNew we
* want to calculate the number of pixels to scroll so that we minimize the
* number of items we will redraw.
*
* History:
\***************************************************************************/
INT LBCalcVarITopScrollAmt(
PLBIV plb,
INT iTopOld,
INT iTopNew)
{
RECT rc;
RECT rcClient;
_GetClientRect(plb->spwnd, (LPRECT)&rcClient);
/*
* Just optimize redrawing when move +/- 1 item. We will redraw all items
* if moving more than 1 item ahead or back. This is good enough for now.
*/
if (iTopOld + 1 == iTopNew) {
/*
* We are scrolling the current iTop up off the top off the listbox so
* return a negative number.
*/
LBGetItemRect(plb, iTopOld, (LPRECT)&rc);
return (rcClient.top - rc.bottom);
}
if (iTopOld - 1 == iTopNew) {
/*
* We are scrolling the current iTop down and the previous item is
* becoming the new iTop so return a positive number.
*/
LBGetItemRect(plb, iTopNew, (LPRECT)&rc);
return -rc.top;
}
return rcClient.bottom - rcClient.top;
}