📄 list.c
字号:
// 必须大于固定的项目数
if( newLimit < ITEMEXT )
newLimit = ITEMEXT;
if( newLimit != lpListData->limit )
{ //重新分配
lpItem = (_LPLISTITEM)realloc( lpListData->lpItems, newLimit*sizeof( _LISTITEM ) );
if( lpItem )
{ //分配成功,设置新的列表框数据
lpListData->lpItems = lpItem;
lpListData->limit = newLimit;
}
else
return FALSE;
}
return TRUE;
}
// **************************************************
// 声明:static int SetItemTypeData( _LPLISTDATA lpListData, int index, WORD dwTypeData )
// 参数:
// IN/OUT lpListData - 列表框对象指针
// IN index - 列表项目索引号
// IN dwTypeData - 需要设置的类型数据
// 返回值:
// 假如成功,返回0; 否则,返回LB_ERR
// 功能描述:
// 设置项目类型数据
// 引用:
//
// ************************************************
static int SetItemTypeData( _LPLISTDATA lpListData, int index, WORD dwTypeData )
{
_ASSERT( index >=0 && index < lpListData->count );
(lpListData->lpItems+index)->typeData = dwTypeData;
return 0;
}
// **************************************************
// 声明:static int SetItemState( _LPLISTDATA lpListData, int index, WORD state, BOOL bEnable )
// 参数:
// IN/OUT lpListData - 列表框对象指针
// IN index - 列表项目索引号
// IN state - 列表项目状态
// IN bEnable - 表示设置或是清除项目状态
// 返回值:
// 假如成功,返回0; 否则,返回LB_ERR
// 功能描述:
// 设置或清除项目状态
// 引用:
//
// ************************************************
static int SetItemState( _LPLISTDATA lpListData, int index, WORD state, BOOL bEnable )
{
_ASSERT( index >=0 && index < lpListData->count );
if( bEnable )
{ //设置
(lpListData->lpItems+index)->state |= state;
}
else //清除
(lpListData->lpItems+index)->state &= ~state;
return 0;
}
// **************************************************
// 声明:static BOOL FreeItem( LPSTR lpstr )
// 参数:
// IN lpstr - 字符串指针
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 释放项目内容
// 引用:
//
// ************************************************
static BOOL FreeItem( LPSTR lpstr )
{
free( lpstr );
return TRUE;
}
// **************************************************
// 声明:static _LPLISTITEM At( _LPLISTDATA lpListData, int index )
// 参数:
// IN lpListData - 列表框对象指针
// IN index - 列表项目索引号
// 返回值:
// 假如成功,返回列表项目指针; 否则,返回NULL
// 功能描述:
// 得到列表项目索引号对应的列表项目指针对象
// 引用:
//
// ************************************************
static _LPLISTITEM At( _LPLISTDATA lpListData, int index )
{
_ASSERT( index >= 0 && index < lpListData->count );
return lpListData->lpItems + index;
}
// **************************************************
// 声明:static int Count( _LPLISTDATA lpListData )
// 参数:
// IN lpListData - 列表框对象指针
// 返回值:
// 返回列表框的实际项目数
// 功能描述:
// 统计列表框的实际项目数
// 引用:
//
// ************************************************
static int Count( _LPLISTDATA lpListData )
{
return lpListData->count;
}
// **************************************************
// 声明:static BOOL Pack( _LPLISTDATA lpListData )
// 参数:
// IN lpListData - 列表框对象指针
// 返回值:
// 假如成功,返回; 否则,返回0
// 功能描述:
//
// 引用:
//
// ************************************************
//static BOOL Pack( _LPLISTDATA lpListData )
//{
// return TRUE;
//}
// **************************************************
// 声明:static LRESULT DoADDFILE( HWND hWnd, LPCSTR lpName )
// 参数:
// IN hWnd - 窗口句柄
// IN lpName - 文件名
// 返回值:
// 假如成功,返回增加的项目索引号; 否则,返回LB_ERR
// 功能描述:
// 中间文件名到列表框
// 暂不支持
// 引用:
//
// ************************************************
static LRESULT DoADDFILE( HWND hWnd, LPCSTR lpName )
{
return LB_ERR;
}
// **************************************************
// 声明:static LRESULT DoADDSTRING( HWND hWnd, LPCSTR lpcstr )
// 参数:
// IN hWnd - 窗口句柄
// IN lpcstr - 字符串项目
// 返回值:
// 假如成功,返回新增项目索引号; 否则,假如没有内存, 返回 LB_ERRSPACE, 其它错误返回LB_ERR
// 功能描述:
// 增加一个字符串项目到末尾
// 处理 LB_ADDSTRING 消息
// 引用:
//
// ************************************************
static LRESULT DoADDSTRING( HWND hWnd, LPCSTR lpcstr )
{
return DoINSERTSTRING( hWnd, -1, lpcstr );
}
// **************************************************
// 声明:static void FillSolidRect( HDC hdc, const RECT * lprc, COLORREF clr )
// 参数:
// IN hdc - 绘图DC
// IN lprc - 需要填充的矩形
// IN clr - 颜色
// 返回值:
// 无
// 功能描述:
// 填充矩形框
// 引用:
//
// ************************************************
static void FillSolidRect( HDC hdc, const RECT * lprc, COLORREF clr )
{
SetBkColor( hdc, clr );
ExtTextOut( hdc, 0, 0, ETO_OPAQUE, lprc, NULL, 0, NULL );
}
// **************************************************
// 声明:static void ReflashScrollBar( HWND hWnd, DWORD dwStyle, _LPLISTDATA lpListData )
// 参数:
// IN hWnd - 列表框窗口句柄
// IN dwStyle - 窗口风格
// IN lpListData - 列表框对象指针
// 返回值:
// 假如成功,返回; 否则,返回0
// 功能描述:
// 刷新滚动棒数据和显示
// 引用:
//
// ************************************************
static void ReflashScrollBar( HWND hWnd, DWORD dwStyle, _LPLISTDATA lpListData )
{
SetScrollBar( hWnd, lpListData->topIndex, 0 );
}
// **************************************************
// 声明:static LRESULT DoINSERTSTRING( HWND hWnd, int index, LPCSTR lpcstr )
// 参数:
// IN hWnd - 窗口句柄
// IN index - 需要插入的位置
// IN lpcstr - 需要插入的字符串
// 返回值:
// 假如成功,返回插入的索引号; 否则,假如没有内存, 返回LB_ERRSPACE, 其它错误, 返回LB_ERR
// 功能描述:
// 插入一个字符串项目到指定的位置
// 处理 LB_INSERTSTRING
// 引用:
//
// ************************************************
static LRESULT DoINSERTSTRING( HWND hWnd, int index, LPCSTR lpcstr )
{
_LPLISTDATA lpListData;
_LPLISTITEM lpItem;
DWORD dwStyle;
WORD len;
LPSTR lp = NULL;
int cur;
lpListData = (_LPLISTDATA)GetWindowLong( hWnd, 0 );//得到列表框私有数据指针
// 得到窗口风格
dwStyle = GetWindowLong( hWnd, GWL_STYLE );
if( index > lpListData->limit )
{ // 错误位置
return LB_ERR;
}
if( dwStyle & LBS_HASSTRINGS )
{ // 列表框项目为字符串, 分配新的字符串内存
len = (WORD)strlen( lpcstr );
lp = malloc( len + 1 );
if( lp == NULL )
return LBN_ERRSPACE;
}
// 假如可能,隐含当前选择项
cur = lpListData->curSel;
DoSETCURSEL( hWnd, -1, FALSE ); // hide cur-sel
// 插入
lpItem = InsertItem( lpListData, &index );
if( lpItem )
{ //插入成功
if( dwStyle & LBS_HASSTRINGS )
{ // 如果是字符串类型, 拷贝内容
lpItem->state = 0;
lpItem->typeData = len;
lpItem->lpszItem = lp;
strcpy( lpItem->lpszItem, lpcstr );
}
else
{ // 用户自定义数据类型 LBS_OWNERDRAWVARIABLE ..
lpItem->lpszItem = NULL;
lpItem->state = 0;
lpItem->typeData = 0;
lpItem->dwItemData = (DWORD)lpcstr;
}
if( dwStyle & LBS_OWNERDRAWVARIABLE )
{ // 如果是自定义数据类型, 发送消息到父窗口去得到项目高度
MEASUREITEMSTRUCT mis;
mis.CtlID = GetWindowLong( hWnd, GWL_ID );
mis.CtlType = ODT_LISTBOX;
mis.itemData = (DWORD)lpcstr;
mis.itemHeight = 0;
mis.itemID = index;
mis.itemWidth = 0;
if( SendMessage( GetParent( hWnd ), WM_MEASUREITEM, mis.CtlID, (LPARAM)&mis ) )
{
lpItem->typeData = (short)mis.itemHeight;
}
else
lpItem->typeData = 1; // safe value
}
// 修正当前选择项的索引号
if( index <= cur && !(dwStyle & LBS_MULTIPLESEL) )
cur++;
if( !(dwStyle & LBS_NOREDRAW) )
{ // 需要重绘
HDC hdc;
// 得到绘图DC
hdc = GetListDC( hWnd, NULL, lpListData );//GetDC( hWnd );
// 绘图项目
RedrawItem( lpListData, hWnd, dwStyle, hdc, index, lpListData->count, FALSE );
// 释放DC
ReleaseListDC( hWnd, hdc, NULL );//ReleaseDC( hWnd, hdc );
// 刷新滚动棒
ReflashScrollBar( hWnd, dwStyle, lpListData );
}
// 显示选择项
DoSETCURSEL( hWnd, cur, FALSE ); // show cur-sel
return index;
}
else
{ //插入不成功, 释放之前的数据
if( lp )
free( lp );
}
// 重新显示之前隐藏的项目
DoSETCURSEL( hWnd, cur, FALSE ); // show cur-sel
// 向父窗口发送通知消息
SendNotify( hWnd, LBN_ERRSPACE );
return LBN_ERRSPACE;
}
// **************************************************
// 声明:LRESULT DoDELETESTRING( HWND hWnd, int index )
// 参数:
// IN hWnd - 窗口句柄
// IN index - 项目索引号
// 返回值:
// 假如成功,返回当前列表框项目数; 否则,返回LB_ERR
// 功能描述:
// 删除索引号对应的项目
// 处理 LB_DELETESTRING
// 引用:
//
// ************************************************
LRESULT DoDELETESTRING( HWND hWnd, int index )
{
_LPLISTDATA lpListData = (_LPLISTDATA)GetWindowLong( hWnd, 0 ); //得到列表框窗口的列表框数据对象指针
short retv = LB_ERR, cur;
DWORD dwStyle;
RECT rect;
_ASSERT( lpListData );
//if( index < lpListData->count && index >= 0 )
if( (DWORD)index < lpListData->count )
{ //合法的索引号值
cur = lpListData->curSel;
//假如有选择项或标注项,先隐含它们
if( cur != -1 )
DoSETCURSEL( hWnd, -1, FALSE ); // hide cur-sel
if( lpListData->caret != -1 ) // hide cur-caret
DoSETCARETINDEX( hWnd, -1, FALSE );
//得到窗口风格
dwStyle = GetWindowLong( hWnd, GWL_STYLE );
//删除项目
retv = DeleteItem( hWnd, dwStyle, lpListData, index );
//得到窗口客户区矩形坐标
GetClientRect( hWnd, &rect );
// reset the topIndex
// 重新设置当前窗口的第一个项目
if( (dwStyle & LBS_OWNERDRAWVARIABLE) == 0 )
{ // 得到窗口矩形能够显示的最大行数
int rows = GetRows( lpListData, dwStyle, &rect );
int t = rows;
int iTopIndex;
if( dwStyle & LBS_MULTICOLUMN )
{ // 多列显示风格, 得到列数
int cols = GetCols( lpListData, &rect );
t = t * cols; // 当前窗口所能显示的最大项目数
}
if( cur < lpListData->topIndex )
{ //选择项目索引号比窗口的最顶项目号小
iTopIndex = cur - 1 < 0 ? 0 : cur;
}
else if( cur >= lpListData->topIndex + t )
{ //选择项目索引号比窗口的最底项目号大
iTopIndex = cur - t;
}
else //
iTopIndex = lpListData->topIndex;
//确定最后一页的最顶项目索引号
t -= (lpListData->count - iTopIndex );
if( t > 0 )
{ //当前的最顶项目索引号(iTopIndex)之下 没有足够的项目显示最后一页
t = iTopIndex - t;
if( t < 0 )
t = 0; //最顶项目索引号应该为0
}
else
t = iTopIndex; //足够
DoSETTOPINDEX( hWnd, t );
}
if( !(dwStyle & LBS_NOREDRAW) )
{ // 需要重绘风格
HDC hdc;
hdc = GetListDC( hWnd, NULL, lpListData );//GetDC( hWnd );
if( index == lpListData->count )// the bottom item
{
RedrawItem( lpListData, hWnd, dwStyle, hdc, index-1, lpListData->count, TRUE );
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -