自己写的GRID控件源码(源文件)

本文档提供了一个自定义GRID控件的源码,包含消息定义、结构体和内部函数实现,用于理解控件的工作原理和进行二次开发。源码中详细定义了各种常量、结构体成员以及数据处理函数,例如列宽调整、颜色设置、数据获取与设置等。
摘要由CSDN通过智能技术生成

#include "stdafx.h"
#include "common.h"
#include "RRGrid.h"

 

 

//内部消息定义
#define GM_LOAD_GRID      WM_GRID_USER_INNER + 1
#define GM_SAVE_GRID     WM_GRID_USER_INNER+2
#define GM_SET_EDIT_TEXT    WM_GRID_USER_INNER+3
#define GM_GET_EDIT_TEXT    WM_GRID_USER_INNER+4
#define GM_GET_TITLE_TEXT    WM_GRID_USER_INNER+5

#define ROWS_MAX 32000//不包括第0行
#define COLS_MAX 256 //不包括第0列

#define CELL_TEXT_MAX    512
#define DATA_SYMBOL_LEN   12

#define LINE_BORDER_SIZE 6

#define CURSOR_ARROW  1
#define CURSOR_DRAG  2//改变列宽时光标状态
#define CURSOR_EDITING  3

//RR_GridCtrl_GetLogicColOnScreen 参数/返回值描述
#define RR_PARAM_MASk       0x0F
#define RR_PARAM_START_COLNO       0x00
#define RR_PARAM_END_COLNO     0x01
#define RR_RESULT_MASK       0xF0
#define RR_RESULT_HALF       0x00
#define RR_RESULT_INTACT      0x10

#define RR_GRID_FILE_HEAD      "RRGrid"
#define RR_STRUCT_SIZE_MAX      1300

 

typedef struct _tagGrid
{
 HWND hWnd;
 HWND hChildEdit;
 
 StringLink_T  *ptTextLink;

 UINT nGridId;
 
 HFONT hbodyfont;//第0列和数据单元采用一样的字体
 HFONT hheadfont;//标题字体
 HFONT htitlefont;//第0行字体

 HBRUSH hEditBackBrush;

 //栅格线颜色
 COLORREF crGridLine;
 
 //标题/第0行/0列文本颜色
 COLORREF crTextTitle;

 //画刷颜色(未选择高亮时,选择行画刷颜色跟其他行一样)
 COLORREF crBrushReadOnly;//只读时的颜色
 COLORREF crBrushCommon;//一般状态颜色
 //高亮:Grid有焦点时选择行画刷颜色
 COLORREF crBrushLight;
 //高亮: Grid无焦点时选择行画刷颜色
 COLORREF crBrushGray;

 //每个画刷颜色有一个文本颜色与之相配
 COLORREF crTextReadOnly;
 COLORREF crTextCommon;
 COLORREF crTextLight;
 COLORREF crTextGray;
 
 char *pszTitle;

 int titleheight;//标题高度
 int headerrowheight;//第0行高度(没有第0行,该值为0)
 int rowheight; //行高等高
 int columnwidths[COLS_MAX+1];//列宽不等宽
 int gridHeight;//客户区域高
 int gridWidth;//客户区域宽

 GridCell_T tEditCell;//当前正在编辑的逻辑单元
 int rows;//行数(包括第0行)
 int cols;//列数(包括第0列)
 int homerow;
 int homecol;//逻辑列号,指示横向滚动条当前位置所对应的左边第一列(不包括第0列,最小值为1)
 int leftvisiblecol; //逻辑列号,指示当前显示的左边第一列(为0(最小值)时表示当前没有显示的数据单元)
 int rightvisiblecol;
 int topvisiblerow;//逻辑行号
 int bottomvisiblerow;
 int sel_row;

 DWORD dwStyle;

 BOOL bCellModified;//单元内容被修改标志
 BOOL bRowModified;//行内容被修改标志
 BOOL bGridTextModified;//Grid内容被修改标志
 BOOL bGridFrameModified;
 
 //内部使用的一些状态变量
 int adjust_height;//bShowIntegralRow为TRUE时累计调整的高度
 BOOL bColumnSizing;//列宽正在改变中
 int resizeColumn;//改变列宽时使用
 int columnInitSize;//改变列宽时使用
 int columnInitx;//改变列宽时使用
 int cursortype;
 BOOL bGridHasFocus;//当前Grid获得焦点
 BOOL bSizing; //正在响应WM_SIZE
 BOOL bShowHScroll;//是否显示横向滚动条
 BOOL bShowVScroll; //是否显示纵向滚动条
 BOOL bEditing;//正在编辑中


 //默认值
 int init_rows;//行数(包括第0行)
 int init_cols;//列数(包括第0列)
 DWORD dwInitStyle;
} Grid_T;

typedef struct _tagGridSaveStruct
{
 COLORREF crGridLine;
 COLORREF crTextTitle;//Roger: 暂未提供接口修改
 COLORREF crBrushReadOnly;//只读时的颜色
 COLORREF crBrushCommon;//一般状态颜色
 COLORREF crBrushLight;
 COLORREF crBrushGray;
 COLORREF crTextReadOnly;
 COLORREF crTextCommon;
 COLORREF crTextLight;
 COLORREF crTextGray;
 int titleheight;//标题高度//Roger: 标题高度由标题文本确定
 int headerrowheight;//第0行高度(没有第0行,该值为0)
 int rowheight; //行高等高
 int columnwidths[COLS_MAX+1];//列宽不等宽
 int rows;//行数(包括第0行)
 int cols;//列数(包括第0列)
 int homerow; //单单homerow/homecol改变,不置Grid修改标志
 int homecol;//逻辑列号,指示横向滚动条当前位置所对应的左边第一列(不包括第0列,最小值为1)
 int sel_row;

 DWORD dwStyle;

}GridSaveStruct_T;

static BOOL RR_GridCtrl_Exit_Edit(HWND hWnd);
static BOOL RR_GridCtrl_Enter_Edit(HWND hWnd,GridCell_T*ptCell,int iSetSel);
static int RR_GridCtrl_GetNextNthColWithWidth(Grid_T * pGridData, int startcol, int direction);
static LRESULT RR_GridCtrlOnVScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static int RR_GridCtrl_ChgSelRow(HWND hWnd,int new_row);
static void RR_GridCtrl_CalcVisibleCellBoundaries(Grid_T * pGridData);
static BOOL RR_GridCtrl_Discard_Edit(HWND hWnd);
static BOOL RR_GridCtrl_Force_Exit_Edit(HWND hWnd);


typedef   long  (__stdcall   *CELLEDIT_PROC_T)(HWND,UINT,WPARAM,LPARAM);  
static CELLEDIT_PROC_T OriginalEditProc;

 





//
static BOOL RR_GridCtrl_CopyStruct(GridSaveStruct_T *pSaveStruct,Grid_T* pGridData,BOOL bFirstIsDest)
{
 
 if(pGridData==NULL || pSaveStruct == NULL )
 {
  return FALSE;
 }

 if(bFirstIsDest)
 {
  memcpy(pSaveStruct->columnwidths,pGridData->columnwidths,sizeof(pGridData->columnwidths));

  pSaveStruct->crGridLine = pGridData->crGridLine;
  pSaveStruct->crTextTitle = pGridData->crTextTitle;
  pSaveStruct->crBrushReadOnly = pGridData->crBrushReadOnly;
  pSaveStruct->crBrushCommon = pGridData->crBrushCommon;
  pSaveStruct->crBrushLight = pGridData->crBrushLight;
  pSaveStruct->crBrushGray = pGridData->crBrushGray;
  pSaveStruct->crTextReadOnly = pGridData->crTextReadOnly;
  pSaveStruct->crTextCommon = pGridData->crTextCommon;
  pSaveStruct->crTextLight = pGridData->crTextLight;
  pSaveStruct->crTextGray = pGridData->crTextGray;

  pSaveStruct->titleheight =  pGridData->titleheight;
  pSaveStruct->headerrowheight= pGridData->headerrowheight;
  pSaveStruct->rowheight = pGridData->rowheight;
  pSaveStruct->rows = pGridData->rows;
  pSaveStruct->cols = pGridData->cols;
  pSaveStruct->homerow=pGridData->homerow;
  pSaveStruct->homecol = pGridData->homecol;
  pSaveStruct->sel_row = pGridData->sel_row;

  pSaveStruct->dwStyle = pGridData->dwStyle;

 }
 else
 {
  memcpy(pGridData->columnwidths,pSaveStruct->columnwidths,sizeof(pSaveStruct->columnwidths));

  pGridData->crGridLine = pSaveStruct->crGridLine;
  pGridData->crTextTitle = pSaveStruct->crTextTitle;
  pGridData->crBrushReadOnly = pSaveStruct->crBrushReadOnly;
  pGridData->crBrushCommon = pSaveStruct->crBrushCommon;
  pGridData->crBrushLight = pSaveStruct->crBrushLight;
  pGridData->crBrushGray = pSaveStruct->crBrushGray;
  pGridData->crTextReadOnly = pSaveStruct->crTextReadOnly;
  pGridData->crTextCommon = pSaveStruct->crTextCommon;
  pGridData->crTextLight = pSaveStruct->crTextLight;
  pGridData->crTextGray = pSaveStruct->crTextGray;
  pGridData->titleheight =  pSaveStruct->titleheight;
  pGridData->headerrowheight= pSaveStruct->headerrowheight;
  pGridData->rowheight = pSaveStruct->rowheight;
  pGridData->rows = pSaveStruct->rows;
  pGridData->cols = pSaveStruct->cols;
  pGridData->homerow=pSaveStruct->homerow;
  pGridData->homecol = pSaveStruct->homecol;
  pGridData->sel_row = pSaveStruct->sel_row;

  pGridData->dwStyle = pSaveStruct->dwStyle;
 }

 return TRUE;
}

static BOOL RR_GetReadOnlyStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 if(pGridData->dwStyle & GS_READONLY)
 {
  return TRUE;
 }
 else
 {
  return FALSE;
 }
}

static void RR_SetReadOnlyStyle(HWND hWnd ,BOOL bReadOnly)
{
 Grid_T * pGridData;
 DWORD dwSysStyle ;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 dwSysStyle = GetWindowLong(hWnd,GWL_STYLE);

 if (bReadOnly)
 {
  //只读时不接受焦点
  if(dwSysStyle & WS_TABSTOP)
  {
   dwSysStyle= dwSysStyle & (~WS_TABSTOP);
   SetWindowLong(hWnd,GWL_STYLE ,dwSysStyle);
  }
  pGridData->dwStyle = pGridData->dwStyle | GS_READONLY;
 }
 else
 {
  if(!(dwSysStyle & WS_TABSTOP))
  {
   dwSysStyle= dwSysStyle | WS_TABSTOP;
   SetWindowLong(hWnd,GWL_STYLE ,dwSysStyle);
  }
  pGridData->dwStyle = pGridData->dwStyle & ~GS_READONLY;
 }
}
 

static BOOL RR_GetExtendLastColumnStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_LASTCOL_NOEXTEND)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}


static BOOL RR_GetColumnAllowResizeStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_COLUMN_NORESIZE)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}

static void RR_SetColumnAllowResizeStyle(HWND hWnd ,BOOL bAllow)
{

 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 if (bAllow)
 {
  pGridData->dwStyle = pGridData->dwStyle & ~GS_COLUMN_NORESIZE;
 }
 else
 {
  pGridData->dwStyle = pGridData->dwStyle | GS_COLUMN_NORESIZE;
 }
}

static BOOL RR_GetColHeadIsNumberStyle(HWND hWnd)
{
 //第0行是否设成ABCDE之类的字母
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_COLHEAD_CUSTOM)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}

 

static BOOL RR_GetRowHeadIsNumberStyle(HWND hWnd)
{
 //第0列是否设成12345之类的数字
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_ROWHEAD_CUSTOM)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}


static BOOL RR_GetShowIntegralRowStyle(HWND hWnd)
{
 //是否调整Grid高度,以显示完整的行高
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_GRIDHIGH_NOADJUST)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}


static BOOL RR_GetHighLightStyle(HWND hWnd)
{
 //选择行是否高亮显示
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_SELROW_INVISIBLE)
 {
  return FALSE;
 }
 else
 {
  return TRUE;
 }
}

static void RR_SetHighLightStyle(HWND hWnd ,BOOL bHighLight)
{
 //选择行是否高亮显示

 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 if (bHighLight)
 {
  pGridData->dwStyle = pGridData->dwStyle & ~GS_SELROW_INVISIBLE;
 }
 else
 {
  pGridData->dwStyle = pGridData->dwStyle | GS_SELROW_INVISIBLE;
 }
}

static BOOL RR_GetInsertKeyStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_CANCEL_INSKEY)
 {
  return FALSE;//不响应Insert键进行插入
 }
 else
 {
  return TRUE;
 }
}

static BOOL RR_GetDeleteKeyStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_CANCEL_DELKEY)
 {
  return FALSE;//不响应Delete键进行行删除
 }
 else
 {
  return TRUE;
 }
}

static BOOL RR_GetEnterKeyStyle(HWND hWnd)
{
 Grid_T * pGridData;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 
 if(pGridData->dwStyle & GS_CANCEL_ENTER_INSERT)
 {
  return FALSE;//回车键在最后行没有添加行功能
 }
 else
 {
  return TRUE;
 }
}

 
 
 

//返回值:TRUE ,不再交给默认过程处理
static LRESULT RR_CellEditOnKeyDown(HWND  hCellEdit, UINT message, WPARAM wParam, LPARAM lParam)
{
 LRESULT lRet = 0;
 HWND hGrid=GetParent(hCellEdit);
 Grid_T * pGridData = NULL;
 GridCell_T  tMoveToCell;

 pGridData = (Grid_T *)GetWindowLong(hGrid,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 if(!pGridData->bEditing)
 {
  return lRet;
 }

 switch(wParam)
 {
  case VK_ESCAPE:
   RR_GridCtrl_Discard_Edit(hGrid);
    lRet = TRUE;
   break;
  case VK_RETURN:
   if(pGridData->tEditCell.row == pGridData->rows-1 &&
    pGridData->tEditCell.col ==pGridData->cols-1 &&
    RR_GetEnterKeyStyle(hGrid))
   {
    //插入新行,进入新行编辑
    int row = pGridData->rows;
    
    if(SendMessage(hGrid,GM_GRID_INSERT_ROW,row,0)==0)
    {
     tMoveToCell.row = row ;
     tMoveToCell.col = pGridData->leftvisiblecol;
     RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,0);
    }
    lRet = TRUE;
    break;
   }
   
   
   if(pGridData->tEditCell.col<pGridData->rightvisiblecol)
   {
    tMoveToCell.row = pGridData->tEditCell.row ;
    tMoveToCell.col = RR_GridCtrl_GetNextNthColWithWidth(pGridData,pGridData->tEditCell.col,1);
   }
   else if(pGridData->tEditCell.row < pGridData->bottomvisiblerow)
   {
    tMoveToCell.row = pGridData->tEditCell.row +1;
    tMoveToCell.col = pGridData->leftvisiblecol;
   }
   else
   {
    tMoveToCell.row = pGridData->topvisiblerow;
    tMoveToCell.col = pGridData->leftvisiblecol;
   }
   RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,0);
   lRet = TRUE;
   break;
  case VK_TAB:
   if(GetKeyState(VK_SHIFT) < 0)
   {
    //支持shift+TAB反方向移动
     if(pGridData->tEditCell.col>pGridData->leftvisiblecol)
    {
     tMoveToCell.row = pGridData->tEditCell.row ;
     tMoveToCell.col = RR_GridCtrl_GetNextNthColWithWidth(pGridData,pGridData->tEditCell.col,-1);
    }
    else if(pGridData->tEditCell.row > pGridData->topvisiblerow)
    {
     tMoveToCell.row = pGridData->tEditCell.row -1;
     tMoveToCell.col = pGridData->rightvisiblecol;
    }
    else
    {
     tMoveToCell.row = pGridData->bottomvisiblerow;
     tMoveToCell.col = pGridData->rightvisiblecol;
    }
    
   }
   else
   {
    if(pGridData->tEditCell.col<pGridData->rightvisiblecol)
    {
     tMoveToCell.row = pGridData->tEditCell.row ;
     tMoveToCell.col = RR_GridCtrl_GetNextNthColWithWidth(pGridData,pGridData->tEditCell.col,1);
    }
    else if(pGridData->tEditCell.row < pGridData->bottomvisiblerow)
    {
     tMoveToCell.row = pGridData->tEditCell.row +1;
     tMoveToCell.col = pGridData->leftvisiblecol;
    }
    else
    {
     tMoveToCell.row = pGridData->topvisiblerow;
     tMoveToCell.col = pGridData->leftvisiblecol;
    }
   }
   
   RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,0);
   lRet = TRUE;
   break;
  case VK_LEFT:
  {
   int start=0;
   int end=0;

   SendMessage(hCellEdit,EM_GETSEL,(WPARAM)&start,(LPARAM)&end);
   if(GetKeyState(VK_CONTROL) < 0 && (start >0 || end >0))
   {
     //VK_CONTROL键被按下(组合键)
     SendMessage(hCellEdit,EM_SETSEL,0,0);
    lRet = TRUE;
    break;
   }
   
   if(start==0 && end ==0)//左移一单元编辑
   {
    tMoveToCell.col = RR_GridCtrl_GetNextNthColWithWidth(pGridData,pGridData->tEditCell.col,-1);
    tMoveToCell.row = pGridData->tEditCell.row;    
    RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,1);
    lRet = TRUE;
   }
   
  }
   break;
  case VK_RIGHT:
  {
   int start=0;
   int end=0;
   int len=0;

   len = SendMessage(hCellEdit,EM_LINELENGTH,0,0);
   SendMessage(hCellEdit,EM_GETSEL,(WPARAM)&start,(LPARAM)&end);
   if(GetKeyState(VK_CONTROL) < 0 && (end<len ||start<len))
   {
     //VK_CONTROL键被按下(组合键)
     SendMessage(hCellEdit,EM_SETSEL,len+1,len+1);
    lRet = TRUE;
    break;
   }
   
   if(start == len && end == len)
   {
    tMoveToCell.col = RR_GridCtrl_GetNextNthColWithWidth(pGridData,pGridData->tEditCell.col,1);
    tMoveToCell.row = pGridData->tEditCell.row;    
    RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,1);
    lRet = TRUE;
   }
   
  }
   break;
  case VK_UP:
   tMoveToCell.col = pGridData->tEditCell.col;
   tMoveToCell.row = pGridData->tEditCell.row-1;    
   RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,1);
   lRet = TRUE;
   break;   
  case VK_DOWN:
   tMoveToCell.col = pGridData->tEditCell.col;
   tMoveToCell.row = pGridData->tEditCell.row+1;    
   RR_GridCtrl_Enter_Edit(hGrid,&tMoveToCell,1);
   lRet = TRUE; 
   break;
  default:
   break;
 }

 return lRet;
}

static LRESULT   ModifierCellEditProc(HWND   hCellEdit,UINT   message,WPARAM   wParam,LPARAM   lParam)
{
 LRESULT lRet;
 
  switch (message)
  {
   case WM_GETDLGCODE:
  {
   lRet = CallWindowProc(OriginalEditProc,hCellEdit,message,wParam,lParam);  
   // If lParam points to an MSG structure
         if (lParam)
         {
          LPMSG lpmsg = (LPMSG)lParam;
          if (lpmsg->message == WM_KEYDOWN)
          {
           switch(lpmsg->wParam)
           {
            case VK_ESCAPE:
      case VK_RETURN:
      case VK_TAB:
      case VK_LEFT:
      case VK_RIGHT:
      case VK_UP:
      case VK_DOWN:
             lRet |= DLGC_WANTMESSAGE;
       break;
      default:
       break;
           }
          }
        }

   }   
   return lRet;
  case WM_KEYDOWN:
   lRet = RR_CellEditOnKeyDown(hCellEdit,message,wParam,lParam);
   if(lRet)
   {
    return 0;//lRet 返回TRUE ,不再交给默认过程处理
   }
   
   break;
   case WM_KILLFOCUS: 
  {
   HWND hParent = GetParent(hCellEdit);
   
   RR_GridCtrl_Force_Exit_Edit(hParent);
   SendMessage(hParent,message,wParam,lParam);
   }
   break;
  case WM_SETCURSOR:
   SetCursor(LoadCursor(NULL,IDC_IBEAM));
   return 0;
  case WM_ERASEBKGND:
   return 0;//直接return 编辑框将不会画鼠标指针
  default:
   break;
  }
 
 return   CallWindowProc(OriginalEditProc,hCellEdit,message,wParam,lParam);  
 }

static int  RR_GridCtrl_Notify(HWND hWnd,UINT code,LPARAM lParam)
{
 Grid_T * pGridData = NULL;
 GridNotify_T tNotify;
 WPARAM wParam;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);

 //memset(tNotify,0,sizeof(GridNotify_T));
 tNotify.hwndFrom = hWnd;
 tNotify.idFrom = pGridData->nGridId;
 tNotify.code = code;
 tNotify.param = lParam;
 tNotify.retVal =0;

 wParam=MAKEWPARAM(tNotify.idFrom,tNotify.code);

 SendMessage(GetParent(hWnd),GM_GRID_NOTIFY,wParam,(LPARAM)&tNotify);
 //SendMessage(GetParent(hWnd),WM_COMMAND,wParam,lParam);

 return tNotify.retVal;

}
 

BOOL RR_GridCtrl_OutOfRange(GridCell_T *cell)
{
 if(cell->row > ROWS_MAX || cell->row <0 ||
  cell->col > COLS_MAX || cell->col<0)
 {
  return TRUE;
 }
 else
 {
  return FALSE;
 }
}

 

//返回与szSymbol匹配项的索引
static ListNode * RR_GridCtrl_SearchData(StringLink_T  *ptStrLink,char  szSymbol[])
{
 StringLinkNode_T* pStrNode;
 ListNode *p = NULL;
 int len =0;

 if(ptStrLink == NULL || szSymbol == NULL)
 {
  return NULL;
 }

 len = strlen(szSymbol);
 
 List_ForEach(p,&(ptStrLink->head))
 {
  pStrNode = List_Entry(p,StringLinkNode_T,node);
  if(strncmp(pStrNode->szString,szSymbol,len) ==0)
  {
   return p;
  }
 }

 return NULL;
}

//bInsert :TRUE -- 插入行,排在row/col后面的单元行号加1
//FALSE -- 删除行,排在row/col后面的单元行号减1

static BOOL RR_GridCtrl_UpdateData(StringLink_T  *ptStrLink,int row ,BOOL bInsert)
{
 char szSymbol[DATA_SYMBOL_LEN+1];
 char szRow[DATA_SYMBOL_LEN+1];
 ListNode *p,*q;
 StringLinkNode_T *pStrNode = NULL;
 int len =0;
 int line=0;


 if(ptStrLink == NULL || row <1)
 {
  return FALSE;
 }

 sprintf(szSymbol,"%05d-%03d",row,0); //9
 len = strlen(szSymbol);

 List_ForEachSafe(p,q,&(ptStrLink->head))
  {
   pStrNode = List_Entry(p,StringLinkNode_T,node);
  if(strncmp(pStrNode->szString,szSymbol,len) >=0)
  {
   line = atoi(pStrNode->szString);
   RR_ASSERT(line>=row);

   if(bInsert)
   {
    line++;
    sprintf(szRow,"%05d",line);
    strncpy(pStrNode->szString,szRow,5);
   }
   else
   {
    if(line == row)
    {
     //删除该行的数据单元
     List_Del(&pStrNode->node);
     ptStrLink->node_cnt --;
     RR_Safe_Free(pStrNode->szString);
     RR_Safe_Free(pStrNode);
    }
    else
    {
     line--;
     sprintf(szRow,"%05d",line);
     strncpy(pStrNode->szString,szRow,5);
    }
   }
  }
  }

 return TRUE;
 
}

static int RR_GridCtrl_ChgSelRow(HWND hWnd,int new_row)
{
 Grid_T * pGridData = NULL;
 int old_row;
 int ret;

 pGridData = (Grid_T *)GetWindowLong(hWnd,GWL_USERDATA);
 RR_ASSERT(pGridData!=NULL);
 RR_ASSERT(new_row>0 && new_row <pGridData->rows);

 old_row = pGridData->sel_row;
 if(new_row == old_row)
 {
  return 0;
 }

 ret = RR_GridCtrl_Notify(hWnd,GN_ROW_CHANGED,MAKELPARAM(new_row,old_row));
 if(ret== 0)
 {
  //选择行被改变
  pGridData->sel_row = new_row;
  pGridData->bRowModified = FALSE;
 }

 return ret; 
}

static int RR_GridCtrl_GetLogicColOnScreen(Grid_T* pGridData,int reference_col,unsigned char description)
{
 int gridWidth;
 int i=0;
 int col;

 RR_ASSERT(pGridData!=NULL);

 if(reference_col<0 || reference_col>=pGridData->cols)
 {
  RR_ASSERT(0);
  return -1;
 }


 gridWidth =  pGridData->gridWidth;
 col = reference_col;
  
 if((description&RR_PARAM_MASk) == RR_PARAM_START_COLNO)
 {
  //reference_col是开始列号
  if(reference_col>0)
  {
   gridWidth-=pGridData->columnwidths[0];
  }

  for(i = reference_col;i<pGridData->cols;i++)
  {
   if(pGridData->columnwidths[i]>0)
   {
    if(gridWidth <= pGridData->columnwidths[i])
    {
     if((description & RR_RESULT_MASK) == RR_RESULT_HALF)
     {
      //可以部分显示
      col = i;
     }
     else if(gridWidth == pGridData->columnwidths[i])
     {
      //完整显示单元
      col =i;
     }
     
     break;
    }
    
    gridWidth-=pGridData->columnwidths[i];
    col = i;

   }
  }

 }
 else
 {
  //reference_col是结束列号
  //返回的一定是Grid能完全装下的列号
  if(reference_col ==0 )
  {
   return 0;
  }
  
  gridWidth -= pGridData->columnwidths[0];

  //返回值>0
  for(i =reference_col;i>=1;i--)
  {
   if(pGridData->columnwidths[i]>0)
   {
    if(gridWidth < pGridData->columnwidths[i])
    {
     break;
    }
    else if (gridWidth ==pGridData->columnwidths[i])
    {
     col = i;
     break;
    }
     
    gridWidth-=pGridData->columnwidths[i];
    col = i;
   }
  }

 }

 return col;
}

//统计从startcol开始(含该列)到endcol(含)之间有宽度的列数
//pTotalWidth返回startcol 到endcol之间有宽度列宽度之和
//返回值:
static int RR_GridCtrl_GetColumnsWithWidth(Grid_T * pGridData, int startcol,int endcol,int* pTotalWidth)
{
 int totalpixels=0;
 int j;
 int colswithwidth=0;
 
 RR_ASSERT(pGridData!=NULL);

 if(startcol<0 || startcol>=pGridData->cols ||
  endcol<0 || endcol>=pGridData->cols||
  startcol>endcol)
 {
  if(pTotalWidth!=NULL)
  {
   *pTotalWidth =0;
  }
  return 0;
 }

 
 //列宽不等宽
 for(j=startcol;j<=endcol;j++)
 {
  if(pGridData->columnwidths[j]>0)
  {
   totalpixels += pGridData->columnwidths[j];
   colswithwidth++;
  }
 }

 if(pTotalWidth!=NULL)
 {
  *pTotalWidth = totalpixels;
 }

 return colswithwidth;
}

//得到下|direction|个有宽度的列的列号
//direction>0 往右数,direction <0往左数
//返回值<0表示往左(右)没有第|direction|个有宽度的列
//该函数可以返回第0列(调用时注意)
static int RR_GridCtrl_GetNextNthColWithWidth(Grid_T * pGridData, int startcol, int direction)
{
 int n=0;
 int col=startcol;
 int abs_val=abs(direction);

 RR_ASSERT(pGridData!=NULL);

 if(startcol<0 || startcol>=pGridData->cols)
 {
  //输入参数不合法
  return -1;
 }

 if(direction==0)
 {
  //RR_ASSERT(0);
  return startcol;
 }
 else if(direction>0)
 {
  col++;
 }
 else
 {
  col--;
 }

 while(col>=0 && col<pGridData->cols)
 {
  if(pGridData->columnwidths[col]!= 0)
  {
   n++;
   if(n==abs_val)
   {
    break;
   }
  }
  
  if(direction>0)
  {
   col++;
  }
  else
  {
   col--;
  }
 }

 if(n==abs_val)
 {
  RR_ASSERT(col>=0 && col<pGridData->cols);
  return col;
 }
 else
 {
  return -2;
 }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值