⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listview.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 4 页
字号:
/*** $Id: listview.c,v 1.76.8.1 2004/04/30 01:21:48 snig Exp $**** listview.c: the ListView control**** Copyright (C) 2003 Feynman Software.** ** 2003/05/17: Rewritten by Zhong Shuyi.**** Create date: 2001/12/03**** Original authors: Shu Ming, Amokaqi, chenjm, kevin.*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//*** Modify records:****  Who             When        Where       For What                Status**-----------------------------------------------------------------------------**  amokaqi  2002/9/26        add CURSORBLOCKDOWN and UP            finish**  amokaqi  2002/10/8        add KILLFOCUS and SETFOCUS            finish**  amokaqi  2002/10/8        add GETDLGCODE for dialog             finish**  chenjm   2002/10/24       add LVM_SELECTITEM and LVM_SHOWITEM   finish**  kevin    2003/01/03       modify KILLFOCUS and SETFOCUS         finish**  snig     2003/05/06       add SB_PAGELEFT, SB_PAGERIGHT         finish**                                SB_PAGEUP and SB_PAGEDOWN;**  snig     2003/05/13       code cleanup, rewrite ...             finish****  snig     2003/05/15       entirely new listview interfaces      done**-----------------------------------------------------------------------------**** TODO:*/#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef __MINIGUI_LIB__#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "control.h"#else#include <minigui/common.h>#include <minigui/minigui.h>#include <minigui/gdi.h>#include <minigui/window.h>#include <minigui/control.h>#endif#ifdef _EXT_CTRL_LISTVIEW#include "mgext.h"#include "listview.h"/********************** internals functions declaration **********************/static int itemDelete (PITEMDATA pHead);#define sGetItemFromList(nSeq, plvdata)  lvGetItemByRow(plvdata, nSeq)inline static int sGetFrontSubItemsWidth (int end, PLVDATA plvdata);static int sGetSubItemWidth (int nCols, PLVDATA plvdata);static int sAddOffsetToTailSubItem (int nCols, int offset,                                    PLVDATA plvdata);static int sGetItemWidth (PLVDATA plvdata);static PITEMDATA lvGetItemByRow (PLVDATA plvdata, int nRows);static int lstSetVScrollInfo (PLVDATA plvdata);static int lstSetHScrollInfo (PLVDATA plvdata);static PSUBITEMDATA lvGetSubItemByCol (PITEMDATA pItem, int nCols);static PLSTHDR lvGetHdrByCol (PLVDATA plvdata, int nCols);/* =========================================================================  * size and position operation section of the listview control.   ========================================================================= */#define LV_HDR_HEIGHT        (plvdata->nHeadHeight)#define LV_ITEM_Y(nRows)     ((nRows-1) * plvdata->nItemHeight)#define LV_ITEM_YY(nRows)    ( LV_ITEM_Y(nRows) - plvdata->nOriginalY )#define LV_ITEM_YYH(nRows)    ( LV_ITEM_YY(nRows) + plvdata->nHeadHeight)#define sGetSubItemX(nCols)   ((lvGetHdrByCol(plvdata, nCols))->x)/* Gets the rect of an item */#define LV_GET_ITEM_RECT(nRow, rect)        \	    GetClientRect(plvdata->hWnd, &rect);     \            rect.top = LV_ITEM_YYH(nRow);    \            rect.bottom = rect.top + plvdata->nItemHeight;/* Gets the rect of a subitem */#define LV_GET_SUBITEM_RECT(nRows, nCols, rect)  \		LV_GET_ITEM_RECT(nRows, rect);                   \		rect.left = sGetSubItemX(nCols) - plvdata->nOriginalX;  \	        rect.right = rect.left + sGetSubItemWidth(nCols, plvdata); /* Gets the text rect of a subitem */#define LV_GET_SUBITEM_TEXTRECT(rect, textrect)  \                  textrect.left = rect.left + 2;     \		  textrect.top = rect.top + 2;       \		  textrect.right = rect.right - 2;   \		  textrect.bottom = rect.bottom - 2;#define LV_GET_HDR_RECT(p1, rect)      \                  rect.left = p1->x - plvdata->nOriginalX + 1;   \		  rect.right = p1->x + p1->width - plvdata->nOriginalX - 1;  \		  rect.top = LV_HDR_TOP;     \		  rect.bottom = plvdata->nHeadHeight;#if 0#define LV_GET_BD_RECT(p1, rect)      \                  rect.left = p1->x + p1->width - plvdata->nOriginalX - 1;   \		  rect.right = p1->x + p1->width - plvdata->nOriginalX + 1;  \		  rect.top = 0;     \		  rect.bottom = plvdata->nHeadHeight;/* Gets the rect of a column */#define LV_GET_COL_RECT(nCols, rect)  \	    GetClientRect(plvdata->hWnd, &rect);  \	    rect.left = sGetSubItemX (nCols) - plvdata->nOriginalX;    \	    rect.right = rect.left + sGetSubItemWidth (nCols, plvdata);#endif#define LV_BE_VALID_COL(nPosition)    (nPosition <= plvdata->nCols && nPosition >= 1)#define LV_BE_VALID_ROW(nPosition)    (nPosition <= plvdata->nRows && nPosition >= 1)#define LV_H_OUTWND(plvdata, rcClient)    \               ( sGetItemWidth (plvdata) - 2 > rcClient.right - rcClient.left)inline static BOOL lvBeInHeadBorder (int mouseX, int mouseY, PLSTHDR p1, PLVDATA plvdata){	/*	RECT rect;	LV_GET_BD_RECT(p1, rect);	if (PtInRect (&rect, mouseX, mouseY))	*/        if ( (mouseX >= (p1->x + p1->width - plvdata->nOriginalX - 1))             && (mouseX <= (p1->x + p1->width - plvdata->nOriginalX))             && (mouseY >= 0) && (mouseY <= plvdata->nHeadHeight) )	    return TRUE;	return FALSE;}static int lvInWhichHeadBorder (int mouseX, int mouseY, PLSTHDR * pRet, PLVDATA plvdata){    int nPosition = 0;    PLSTHDR p1 = plvdata->pLstHead;    while (p1 != NULL)    {        nPosition++;	if (lvBeInHeadBorder(mouseX, mouseY, p1, plvdata))            break;            p1 = p1->pNext;    }        if (!p1) {        if (pRet)            *pRet = NULL;        return -1;    }    if (pRet)        *pRet = p1;            return nPosition;}static int isInListViewHead (int mouseX, int mouseY, PLSTHDR * pRet, PLVDATA plvdata){    int nPosition = 0;    PLSTHDR p1 = plvdata->pLstHead;    RECT rect;    while (p1)    {        nPosition++;	LV_GET_HDR_RECT(p1, rect);	if (PtInRect (&rect, mouseX, mouseY))            break;                p1 = p1->pNext;    }    //not in head    if (!p1 || (nPosition > plvdata->nCols) || (nPosition == 0)) {        if (pRet)	    *pRet = NULL;        return -1;    }    //in head    if (pRet)        *pRet = p1;    return nPosition;}static int isInLVItem (int mouseX, int mouseY, PITEMDATA * pRet, PLVDATA plvdata){    int ret, j;    PITEMDATA p1;    if ((mouseY < plvdata->nHeadHeight))        return -1;    ret = (mouseY + plvdata->nOriginalY - plvdata->nHeadHeight) / plvdata->nItemHeight;    ret++;    *pRet = NULL;    p1 = plvdata->pItemHead;    j = 0;    while ((p1 != NULL) && (j < ret))    {        *pRet = p1;        p1 = p1->pNext;        j++;    }        if (ret > j)        return -1;        return ret;}/* =========================================================================  * Drawing section of the listview control.   ========================================================================= */static void sDrawText (HDC hdc, int x, int y, int width, int height, 		const char *pszText, UINT format){    RECT rect;    //SIZE size;    if (pszText != NULL)    {	SetRect (&rect, x+2, y+2, x+width, y+height);        DrawText (hdc, pszText, -1, &rect, format);    }}static void lvDrawSubItem (HDC hdc, int nRows, int nCols, PLVDATA plvdata){    RECT rect, rect_text;    PITEMDATA pItem;    PSUBITEMDATA psub;    PLSTHDR ph;    UINT text_format;    if ( !(pItem = lvGetItemByRow(plvdata, nRows)) )	return;    if ( !(psub = lvGetSubItemByCol(pItem, nCols)) )	return;    ph = lvGetHdrByCol (plvdata, nCols);    LV_GET_SUBITEM_RECT(nRows, nCols, rect);    if (!pItem->bSelected) {	SetBrushColor (hdc, GetWindowBkColor(plvdata->hWnd));	SetBkColor (hdc, GetWindowBkColor(plvdata->hWnd));        SetTextColor (hdc, psub->nTextColor);    }    else {        SetBkColor (hdc, plvdata->bkc_selected);        SetBrushColor (hdc, plvdata->bkc_selected);        SetTextColor (hdc, PIXEL_lightwhite);    }    FillBox (hdc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);    LV_GET_SUBITEM_TEXTRECT(rect, rect_text);    if (psub->Image) {       int width, height;       if (psub->dwFlags & LVIF_BITMAP) {	   PBITMAP bmp = (PBITMAP)psub->Image;	   height = (bmp->bmHeight < plvdata->nItemHeight)? bmp->bmHeight : plvdata->nItemHeight;	   rect.top += (plvdata->nItemHeight - height) / 2;	   rect.left += 2;	   FillBoxWithBitmap (hdc, rect.left, rect.top, 0, height, bmp);           rect_text.left = rect.left + bmp->bmWidth + 2;       }       else if (psub->dwFlags & LVIF_ICON) {	   GetIconSize ((HICON)psub->Image, &width, &height);	   height = (height < plvdata->nItemHeight) ? height : plvdata->nItemHeight;	   rect.top += (plvdata->nItemHeight - height) / 2;	   rect.left += 2;	   DrawIcon (hdc, rect.left, rect.top, 0, height,			   (HICON)psub->Image);           rect_text.left = rect.left + width + 2;       }    }    if (!psub->pszInfo)	return;    if (ph->flags & LVCF_RIGHTALIGN)	text_format = DT_SINGLELINE | DT_RIGHT | DT_VCENTER;    else if (ph->flags & LVCF_CENTERALIGN)	text_format = DT_SINGLELINE | DT_CENTER | DT_VCENTER;    else	text_format = DT_SINGLELINE | DT_LEFT | DT_VCENTER;    DrawText (hdc, psub->pszInfo, -1, &rect_text, text_format);}//Draws listview headerstatic void lvDrawHeader (HWND hwnd, HDC hdc){    PLSTHDR p1 = NULL;    PLVDATA plvdata;    RECT rcClient;    BOOL up = TRUE;    UINT format;    GetClientRect (hwnd, &rcClient);    plvdata = (PLVDATA) GetWindowAdditionalData2 (hwnd);    p1 = plvdata->pLstHead;    if (LVSTATUS(hwnd) & LVST_HEADCLICK && LVSTATUS(hwnd) & LVST_INHEAD)	up = FALSE;    SetBkColor (hdc, PIXEL_lightgray);    SetBrushColor (hdc, PIXEL_lightgray);    FillBox (hdc, rcClient.left, rcClient.top, rcClient.right - rcClient.left,             plvdata->nHeadHeight);    SetTextColor (hdc, PIXEL_black);    while (p1)    {#ifdef _FLAT_WINDOW_STYLE        DrawFlatControlFrameEx (hdc, p1->x - plvdata->nOriginalX-1,                          LV_HDR_TOP - plvdata->nOriginalY-1,                          p1->x - plvdata->nOriginalX + p1->width,                          LV_HDR_TOP + LV_HDR_HEIGHT, PIXEL_lightgray, 0, up);#else        Draw3DControlFrame (hdc, p1->x - plvdata->nOriginalX + 1,		          LV_HDR_TOP,                          p1->x - plvdata->nOriginalX + p1->width - 1,                          LV_HDR_TOP + LV_HDR_HEIGHT, PIXEL_lightgray, up);#endif	if (p1->flags & LVHF_CENTERALIGN)	    format = DT_SINGLELINE | DT_CENTER | DT_VCENTER;	else if (p1->flags & LVHF_RIGHTALIGN)	    format = DT_SINGLELINE | DT_RIGHT | DT_VCENTER;	else	    format = DT_SINGLELINE | DT_LEFT | DT_VCENTER;        sDrawText (hdc, p1->x - plvdata->nOriginalX + 2, LV_HDR_TOP,                 p1->width - 4, LV_HDR_HEIGHT, p1->pTitle, format);        p1 = p1->pNext;    }    //draws the right most unused header    if ( !LV_H_OUTWND(plvdata, rcClient) ) {#ifdef _FLAT_WINDOW_STYLE      DrawFlatControlFrameEx (hdc, sGetItemWidth (plvdata)-2,		          LV_HDR_TOP-1,                          rcClient.right+2,                          LV_HDR_TOP + LV_HDR_HEIGHT, PIXEL_lightgray, 0, up);#else      Draw3DControlFrame (hdc, sGetItemWidth (plvdata),		          LV_HDR_TOP,                          rcClient.right+2,                          LV_HDR_TOP + LV_HDR_HEIGHT, PIXEL_lightgray, up);#endif    }}static void lvDrawItem (HWND hwnd, HDC hdc, int nRows){    int i;    RECT rcClient;    PLVDATA plvdata;    PITEMDATA p3 = NULL;    plvdata = (PLVDATA) GetWindowAdditionalData2 (hwnd);    p3 = lvGetItemByRow(plvdata, nRows);    GetClientRect (hwnd, &rcClient);    /*    if (p3->bSelected) {        SetBrushColor (hdc,plvdata->bkc_selected);    }    else        SetBrushColor (hdc, PIXEL_lightwhite);    FillBox (hdc, rcClient.left,             (nRows - 1) * plvdata->nItemHeight +             plvdata->nHeadHeight,             sGetItemWidth(plvdata)-1,             plvdata->nItemHeight);    */    for (i = 1; i <= plvdata->nCols; i++)    {        lvDrawSubItem (hdc, nRows, i, plvdata);    }}static void lvOnDraw (HWND hwnd, HDC hdc){    int j;    RECT rcClient;    PLVDATA plvdata;    plvdata = (PLVDATA) GetWindowAdditionalData2 (hwnd);    GetClientRect (hwnd, &rcClient);    SetBkColor (hdc, PIXEL_lightwhite);    SetBrushColor (hdc, PIXEL_lightwhite);    FillBox (hdc, rcClient.left, rcClient.top, rcClient.right - rcClient.left,             rcClient.bottom - rcClient.top);    //draws item area    for (j = 1; j <= plvdata->nRows; j++)    {	lvDrawItem (hwnd, hdc, j);    }    lvDrawHeader (hwnd, hdc);}/*************************************  Listview Move/Scroll Action ***********************//* Makes an item to be visible */static voidlvMakeItemVisible (HWND hwnd, PLVDATA plvdata, int nRows){    int scrollHeight = 0;    RECT rect;    int area_height;    if (!LV_BE_VALID_ROW(nRows))	nRows = plvdata->nItemSelected;    if (!LV_BE_VALID_ROW(nRows))	return;    GetClientRect (hwnd, &rect);    area_height = rect.bottom - rect.top - plvdata->nHeadHeight;    if ( LV_ITEM_Y(nRows) < plvdata->nOriginalY) {        scrollHeight = plvdata->nOriginalY - LV_ITEM_Y(nRows);    }    else if ( LV_ITEM_Y(nRows+1) - plvdata->nOriginalY > area_height ) {        scrollHeight = plvdata->nOriginalY + area_height - LV_ITEM_Y(nRows+1);    }    if (scrollHeight != 0) {        plvdata->nOriginalY -= scrollHeight;        lstSetVScrollInfo (plvdata);	InvalidateRect(hwnd, NULL, FALSE);    }}static void lvVScroll (HWND hwnd, WPARAM wParam, LPARAM lParam){    int scrollHeight = 0;    RECT rect;    int scrollBoundMax;    int scrollBoundMin;    int vscroll = 0;    PLVDATA plvdata;    plvdata = (PLVDATA) GetWindowAdditionalData2 (hwnd);    GetClientRect (hwnd, &rect);    scrollBoundMax = plvdata->nRows * plvdata->nItemHeight -		     (rect.bottom - rect.top - plvdata->nHeadHeight);    scrollBoundMin = 0;        //decides the desired value to scroll    if (wParam == SB_LINEUP || wParam == SB_LINEDOWN)	vscroll = VSCROLL;    else if (wParam == SB_PAGEUP || wParam == SB_PAGEDOWN)	vscroll = rect.bottom - rect.top - plvdata->nHeadHeight -		  plvdata->nItemHeight;    //scroll down    if ( (wParam == SB_LINEDOWN || wParam == SB_PAGEDOWN) &&                    plvdata->nOriginalY < scrollBoundMax )    {	if ((plvdata->nOriginalY + vscroll) > scrollBoundMax)	{	    scrollHeight = plvdata->nOriginalY - scrollBoundMax;	    plvdata->nOriginalY = scrollBoundMax;	}	else	{	    plvdata->nOriginalY += vscroll;	    scrollHeight = -vscroll;	}    }    //scroll up    else if ( (wParam == SB_LINEUP || wParam == SB_PAGEUP) &&	            plvdata->nOriginalY > scrollBoundMin )    {	if ((plvdata->nOriginalY - vscroll) > scrollBoundMin)	{	    plvdata->nOriginalY -= vscroll;	    scrollHeight = vscroll;	}	else	{	    scrollHeight = plvdata->nOriginalY - scrollBoundMin;	    plvdata->nOriginalY = scrollBoundMin;	}    }    //dragging    else if ( wParam == SB_THUMBTRACK )    {	    int scrollNewPos = (int) lParam;	    if (((scrollNewPos - plvdata->nOriginalY) < 5) &&		  ((scrollNewPos - plvdata->nOriginalY) > -5) &&		  (scrollNewPos > 5) && ((scrollBoundMax - scrollNewPos) > 5))		return;	    if ((scrollNewPos < plvdata->nOriginalY) && (scrollNewPos <= VSCROLL))	    {		scrollHeight = plvdata->nOriginalY - 0;		plvdata->nOriginalY = 0;	    }	    else	    {		if ((scrollNewPos > plvdata->nOriginalY) && ((scrollBoundMax - scrollNewPos) < VSCROLL))		{		    scrollHeight = plvdata->nOriginalY - scrollBoundMax;		    plvdata->nOriginalY = scrollBoundMax;		}		else		{		    scrollHeight = plvdata->nOriginalY - scrollNewPos;		    plvdata->nOriginalY = scrollNewPos;		}	    }    }    if (scrollHeight != 0) {	InvalidateRect (hwnd, NULL, FALSE);        lstSetVScrollInfo (plvdata);    }}static void lvHScroll (HWND hwnd, WPARAM wParam, LPARAM lParam){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -