📄 grid.c
字号:
#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_GRID#include "mgext.h"#include "grid.h"#define IDC_EDIT 101/********************** interface functions declaration **********************///add and remove headerstatic PGRIDDATA NewGrid(HWND hwnd, int nRows, int nCols);static int DeleteGrid(PGRIDDATA pGridData);static int DeleteCol(int nCols, PGRIDDATA pGridData);static int DeleteRow(int nRows, PGRIDDATA pGridData);static int AddCol(HWND hwnd, PGRIDCOLHEADER pHeader, PGRIDDATA pGridData);static int AddRow(HWND hwnd, PGRIDROWHEADER pHeader, PGRIDDATA pGridData);/*//width and heightstatic int SetWidth(PGRIDCOLHDR pGridColHdr, PGRIDDATA pGridData);static int GetWidth(PGRIDCOLHDR pGridColHdr, PGRIDDATA pGridData);static int SetHeight(PGRIDROWHDR pGridRowHdr, PGRIDDATA pGridData);static int GetHeight(PGRIDROWHDR pGridRowHdr, PGRIDDATA pGridData);*///draw functionstatic void GridDrawCells(HWND hwnd, HDC hdc);static void GridDrawHeader(HWND hwnd, HDC hdc);///************************ internal functions declaration *******************/static void freecell(PCELLDATA pCell);static void freerow(PGRIDROWHDR pRow);static void freecol(PGRIDCOLHDR pCol);static PCELLDATA newcell(PGRIDCELL pCell);static PGRIDCOLHDR newcolhdr(PGRIDCOLHEADER pHeader);static PGRIDROWHDR newrowhdr(PGRIDROWHEADER pHeader);static void showGrid(PGRIDDATA pGridData);/**************************************************************************/static WNDPROC old_edit_proc;static int EnterEditBox(HWND hwnd, int message, WPARAM wParam, LPARAM lParam){ HWND parent; if(message == MSG_KEYDOWN) { if(wParam == SCANCODE_ENTER) { parent = ((PGRIDDATA)GetWindowAdditionalData(hwnd))->hWnd; PostMessage(parent, GRID_EDITENTER, 0, 0); } } return (*old_edit_proc)(hwnd, message, wParam, lParam);}/**********************def ***********************************************/#define GRID_H_OUTWND(pGridData, rcClient) \ ( GetGridWidth (pGridData) - 2 > rcClient.right - rcClient.left)#define GRID_V_OUTWND(pGridData, rcClient) \ (GetGridHeight(pGridData) -2 > rcClient.bottom - rcClient.top)static PCELLDATA GetCellByNum(int nCols, int nRows, PGRIDDATA pgriddata){ PCELLDATA pCell; PGRIDCOLHDR pColHdr = pgriddata->pGridColHdr; PGRIDROWHDR pRowHdr = pgriddata->pGridRowHdr; while(pColHdr && (pColHdr->nCols != nCols)) pColHdr = pColHdr->pNext; if(pColHdr) { pCell = pColHdr->pHeadCell; while(pRowHdr && (pRowHdr->nRows != nRows)) { pRowHdr = pRowHdr->pNext; pCell = pCell->pRight; } if(pRowHdr) return pCell; } return NULL;}static PGRIDCOLHDR GetColHdrByNum(int nCols, PGRIDDATA pgriddata){ PGRIDCOLHDR p1 = pgriddata->pGridColHdr; if(nCols <= pgriddata->nCols) { while(p1) { if(p1->nCols == nCols) { return p1; break; } p1 = p1->pNext; } } return NULL;}static PGRIDROWHDR GetRowHdrByNum(int nRows, PGRIDDATA pgriddata){ PGRIDROWHDR p1 = pgriddata->pGridRowHdr; if(nRows <= pgriddata->nRows) { while(p1) { if(p1->nRows == nRows) { return p1; break; } p1 = p1->pNext; } } return NULL;}static int IsInGridCell(int mouseX, int mouseY, PCELLDATA *pRet, PGRIDDATA pgriddata){ int ret = -1; PGRIDCOLHDR pColHdr = pgriddata->pGridColHdr; PGRIDROWHDR pRowHdr = pgriddata->pGridRowHdr; PCELLDATA pCell = NULL; //mouseX -= GRID_TOP; if((mouseX < pgriddata->nHeadWidth) || (mouseY < pgriddata->nHeadHeight)) return ret; while(pColHdr) { if(mouseX > pColHdr->x - pgriddata->nOriginalX + 1 && mouseX > pgriddata->nHeadWidth && mouseX < pColHdr->x - pgriddata->nOriginalX + pColHdr->nWidth -1) break; else pColHdr = pColHdr->pNext; } if(pColHdr) { pCell = pColHdr->pHeadCell; while(pRowHdr) { if(mouseY > pRowHdr->y - pgriddata->nOriginalY + 1 && mouseY > pgriddata->nHeadHeight && mouseY < pRowHdr->y - pgriddata->nOriginalY + pRowHdr->nHeight -1) { ret = 1; if(pRet) *pRet = pCell; break; } else { pRowHdr = pRowHdr->pNext; pCell = pCell->pNext; } } } return ret;}static int IsInGridColHdr(int mouseX, int mouseY, PGRIDCOLHDR *pRet, PGRIDDATA pgriddata){ int nPosition = 0; PGRIDCOLHDR p1 = pgriddata->pGridColHdr; RECT rect; while (p1){ rect.left = p1->x - pgriddata->nOriginalX + 1; rect.top = GRID_HDR_TOP; rect.right = p1->x + p1->nWidth -pgriddata->nOriginalX - 1; rect.bottom = pgriddata->nHeadHeight; if (PtInRect (&rect, mouseX, mouseY)) break; p1 = p1->pNext; nPosition++; } //not in head if (!p1 || (nPosition > pgriddata->nCols) || (nPosition < 0)) { if (pRet) *pRet = NULL; return -1; } //in head if (pRet) *pRet = p1; return nPosition;}static int IsInGridRowHdr(int mouseX, int mouseY, PGRIDROWHDR *pRet, PGRIDDATA pgriddata){ int nPosition = -1; PGRIDROWHDR p1 = pgriddata->pGridRowHdr; RECT rect; while (p1){ nPosition++; rect.left = GRID_HDR_LEFT; rect.top = p1->y - pgriddata->nOriginalY - 1; rect.right = GRID_HDR_LEFT + pgriddata->nHeadWidth; rect.bottom = p1->y + p1->nHeight - pgriddata->nOriginalY - 1; if (PtInRect (&rect, mouseX, mouseY)) break; p1 = p1->pNext; } //not in head if (!p1 || (nPosition > pgriddata->nRows) || (nPosition < 0)) { if (pRet) *pRet = NULL; return -1; } //in head if (pRet) *pRet = p1; return nPosition;}static int GridInWhichColHdrBorder(int mouseX, int mouseY, PGRIDCOLHDR *pRet, PGRIDDATA pgriddata){ int nPosition = -1; PGRIDCOLHDR p1 = pgriddata->pGridColHdr; while (p1){ nPosition++; if((mouseX >= (p1->x + p1->nWidth - pgriddata->nOriginalX - 2)) && (mouseX <= (p1->x + p1->nWidth - pgriddata->nOriginalX)) && (mouseY >= 0) && (mouseY <= pgriddata->nHeadHeight) ) break; p1 = p1->pNext; } if (!p1) { if (pRet) *pRet = NULL; return -1; } if (pRet) *pRet = p1; return nPosition;}static int GridInWhichRowHdrBorder(int mouseX, int mouseY, PGRIDROWHDR *pRet, PGRIDDATA pgriddata){ int nPosition = 0; PGRIDROWHDR p1 = pgriddata->pGridRowHdr; while (p1 != NULL){ if((mouseY >= (p1->y + p1->nHeight - pgriddata->nOriginalY - 2)) && (mouseY <= (p1->y + p1->nHeight - pgriddata->nOriginalY)) && (mouseX >= 0) && (mouseX <= pgriddata->nHeadWidth) ) break; p1 = p1->pNext; nPosition++; } if (!p1) { if (pRet) *pRet = NULL; return -1; } if (pRet) *pRet = p1; return nPosition;}static int GridSetColWidth (PGRIDCOLHDR pColHdr, int width, PGRIDDATA pgriddata){ PGRIDCOLHDR p1 = pgriddata->pGridColHdr; if(!pColHdr) return -1; while(p1 && p1 != pColHdr) p1 = p1->pNext; if(!p1) return -1; if(width < COLWIDTHMIN) width = COLWIDTHMIN; p1->nWidth = width; while(p1->pNext) { p1->pNext->x = p1->x + p1->nWidth; p1 = p1->pNext; } return 1;}static int GridSetRowHeight (PGRIDROWHDR pRowHdr, int height, PGRIDDATA pgriddata){ PGRIDROWHDR p1 = pgriddata->pGridRowHdr; if(!pRowHdr) return -1; while(p1 && p1 != pRowHdr) p1 = p1->pNext; if(!p1) return -1; if(height < ROWHEIGHTMIN) height = ROWHEIGHTMIN; p1->nHeight = height; while(p1->pNext) { p1->pNext->y = p1->y + p1->nHeight; p1 = p1->pNext; } return 1;}static void GridColBorderDrag (HWND hwnd, int x, int y){ int mouseX = x, mouseY = y; PGRIDDATA pgriddata; RECT rcClient; int offset; PGRIDCOLHDR pDrag; pgriddata = (PGRIDDATA)GetWindowAdditionalData2(hwnd); pDrag = pgriddata->pColDraged; GetClientRect(hwnd, &rcClient); ScreenToClient(hwnd, &mouseX, &mouseY); if((pDrag->x - pgriddata->nOriginalX + COLWIDTHMIN) > mouseX - 1) return; offset = mouseX - (pDrag->x + pDrag->nWidth-pgriddata->nOriginalX); GridSetColWidth(pgriddata->pColDraged, pDrag->nWidth+offset, pgriddata); /*rect.left = rcClient.left; rect.right = rcClient.right; rect.top = rcClient.top; rect.bottom = rect.top + pgriddata->nHeadHeight+1;*/ InvalidateRect(hwnd, NULL, FALSE); /*if (offset < 0) { pgriddata->nOriginalX += offset; if(pgriddata->nOriginalX < 0) pgriddata->nOriginalX = 0; }*/ return;}static void GridRowBorderDrag (HWND hwnd, int x, int y){ int mouseX = x, mouseY = y; PGRIDDATA pgriddata; RECT rcClient; int offset; PGRIDROWHDR pDrag; pgriddata = (PGRIDDATA)GetWindowAdditionalData2(hwnd); pDrag = pgriddata->pRowDraged; GetClientRect(hwnd, &rcClient); ScreenToClient(hwnd, &mouseX, &mouseY); if((pDrag->y - pgriddata->nOriginalY + ROWHEIGHTMIN) > mouseY - 1) return; offset = mouseY - (pDrag->y + pDrag->nHeight-pgriddata->nOriginalY); GridSetRowHeight(pgriddata->pRowDraged, pDrag->nHeight+offset, pgriddata); /*rect.left = rcClient.left; rect.right = rcClient.right; rect.top = rcClient.top; rect.bottom = rect.top + pgriddata->nHeadHeight+1;*/ InvalidateRect(hwnd, NULL, FALSE); /*if (offset < 0) { pgriddata->nOriginalY += offset; if(pgriddata->nOriginalY < 0) pgriddata->nOriginalY = 0; }*/ return;}/*********************** inline functions for convinient ******************/static inline int AddRowTail(HWND hwnd, PGRIDDATA pGridData){ GRIDROWHEADER row; memset(&row, 0, sizeof(row)); row.nRows = pGridData->nRows; return AddRow(hwnd, &row, pGridData);}static inline int AddColTail(HWND hwnd, PGRIDDATA pGridData){ GRIDCOLHEADER col; memset(&col, 0, sizeof(col)); col.nCols = pGridData->nCols; return AddCol(hwnd, &col, pGridData);} static inline int DeleteRowTail(PGRIDDATA pGridData){ return DeleteRow(pGridData->nRows - 1, pGridData);}static inline int DeleteColTail(PGRIDDATA pGridData){ return DeleteCol(pGridData->nCols - 1, pGridData);}/***************************************************************************//* Grid control constuctor. * @nRows: number of rows; * @nCols: number of columns * return pointer of Grid control if success, or return NULL */static PGRIDDATA NewGrid(HWND hwnd, int nRows, int nCols){ int i; PGRIDDATA pGridData = calloc(1, sizeof(GRIDDATA)); if(!pGridData) return NULL; pGridData->nHeadHeight = GRID_HDRH_DEF(hwnd); pGridData->nHeadWidth = GRID_HDRW_DEF(hwnd); for(i=0; i<nRows; i++) { if(!AddRowTail(hwnd, pGridData)) return NULL; } for(i=0; i<nCols; i++) { if(!AddColTail(hwnd, pGridData)) return NULL; } pGridData->bkc_selected = LIGHTBLUE; pGridData->hWnd = hwnd; pGridData->hwnd_edit = 0; pGridData->pCellEdit = NULL; pGridData->pCellFocus = pGridData->pGridColHdr->pHeadCell; return pGridData;}/* Grid control deconstructor * @pGridData: pointer of control to delete * return 1 if success, 0 for failure */static int DeleteGrid(PGRIDDATA pGridData){ while(pGridData->nCols) if(DeleteCol(0, pGridData) == 0) return 0; while(pGridData->nRows) if(DeleteRow(0, pGridData) == 0) return 0; free(pGridData); return 1;}/* Delete a column indexed by nCols * @nCols: index. * @pGridData: Grid control instance. * return 1 if success */static int DeleteCol(int nCols, PGRIDDATA pGridData){ PGRIDCOLHDR pCol1, pCol2; PGRIDROWHDR pRowHdr; PCELLDATA pCell1, pCell2, pCell3; if(nCols > pGridData->nCols-1) return 0; pCol1 = pCol2 = pGridData->pGridColHdr; if(nCols == 0) {//the first column pGridData->pGridColHdr = pCol2->pNext; if(pCol1->pNext) pCell1 = pCol1->pNext->pHeadCell; else pCell1 = NULL; pCell3 = pCell2 = pCol1->pHeadCell; //adjust pointers of row pRowHdr = pGridData->pGridRowHdr; while(pRowHdr) { pCell3 = pCell2->pNext; freecell(pCell2); pCell2 = pCell3; pRowHdr->pHeadCell = pCell1; pRowHdr = pRowHdr->pNext; if(pCell1) pCell1 = pCell1->pNext; } freecol(pCol2); } else {//!first column while(pCol2->nCols != nCols ) { pCol1 = pCol2; pCol2 = pCol2->pNext; } pCol1->pNext = pCol2->pNext;//adjust column header pointer pRowHdr = pGridData->pGridRowHdr;//adjust pointers of previous column pCell3 = pCol2->pHeadCell; while(pRowHdr) { pCell1 = pCell2 = pRowHdr->pHeadCell; while(pCell2 != pCell3) { pCell1 = pCell2; pCell2 = pCell2->pRight; } pCell1->pRight = pCell2->pRight; pRowHdr = pRowHdr->pNext; pCell3 = pCell3->pNext; freecell(pCell2); } freecol(pCol2); } //dec column header nCols field pCol2 = pCol1->pNext; while(pCol2) { pCol2->x = pCol1->x +pCol1->nWidth; pCol2->nCols--; pCol1 = pCol2; pCol2 = pCol2->pNext; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -