tscroll.c
来自「<Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.」· C语言 代码 · 共 1,139 行 · 第 1/3 页
C
1,139 行
}
}
/* set select fields and send TQ_SELECT */
if (row < ptab->hdr.nrows) {
ptab->select.startrow = row;
ptab->select.startcell = col;
ptab->select.nrows = nrows;
ptab->select.ncells = ncells;
} else {
ptab->select.nrows = 0;
ptab->select.startrow = 0;
ptab->select.startcell = 0;
ptab->select.ncells = 0;
}
if (bNotify) {
gtab_sendtq(hwnd, TQ_SELECT, (long) (LPSTR) &ptab->select);
}
/* paint in selection */
if (nrows > 0) {
if (!ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
ptab->selvisible = TRUE;
}
} else {
if (ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
ptab->selvisible = FALSE;
}
ptab->selvisible = FALSE;
}
}
/***************************************************************************
* Function: gtab_ytoline
*
* Purpose:
*
* Convert window y co-ord to a line nr
*/
int
gtab_ytoline(HWND hwnd, lpTable ptab, int y)
{
return(y / ptab->rowheight);
}
/***************************************************************************
* Function: gtab_xtocol
*
* Purpose:
*
* Convert window x co-ord to a cell nr
*/
int
gtab_xtocol(HWND hwnd, lpTable ptab, int x)
{
int i;
lpCellPos ppos;
for (i = 0; i < ptab->hdr.ncols; i++) {
ppos = &ptab->pcellpos[i];
if (ppos->clipstart < ppos->clipend) {
if ( (x >= ppos->clipstart) && (x < ppos->clipend)) {
return(i);
}
}
}
return(-1);
}
/***************************************************************************
* Function: gtab_isborder
*
* Purpose:
*
* Check if x co-ord is 'near' (+- 2 pixels) the right border of given cell
*/
BOOL
gtab_isborder(HWND hwnd, lpTable ptab, int x, int col)
{
if (abs(ptab->pcellpos[col].clipend - x) < 2) {
return(TRUE);
} else {
return(FALSE);
}
}
/***************************************************************************
* Function: gtab_enter
*
* Purpose:
*
* Set selection and send 'TQ_ENTER' event to owner
*/
void
gtab_enter(HWND hwnd, lpTable ptab, long row, long col, long nrows,
long ncells)
{
int line;
/* clear existing sel if valid and visible */
if ((ptab->select.nrows > 0) && (ptab->selvisible == TRUE)) {
/* only clear sel if it is different from the new one */
if ((ptab->select.startrow != row) ||
(ptab->select.startcell != col) ||
(ptab->select.nrows != nrows) ||
(ptab->select.ncells != ncells)) {
line = gtab_rowtoline(hwnd, ptab,
ptab->select.startrow);
if (line >= 0) {
gtab_invertsel(hwnd, ptab, NULL);
}
ptab->selvisible = FALSE;
}
}
/* set select fields and send TQ_SELECT */
if (row < ptab->hdr.nrows) {
ptab->select.startrow = row;
ptab->select.startcell = col;
ptab->select.nrows = nrows;
ptab->select.ncells = ncells;
} else {
ptab->select.nrows = 0;
ptab->select.startrow = 0;
ptab->select.startcell = 0;
ptab->select.ncells = 0;
}
/* paint in selection */
if (nrows > 0) {
if (!ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
ptab->selvisible = TRUE;
}
/* do this at end because it could cause a layout-change */
gtab_sendtq(hwnd, TQ_ENTER, (long) (LPSTR) &ptab->select);
} else {
if (ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
}
ptab->selvisible = FALSE;
}
}
/***************************************************************************
* Function: gtab_trackcol
*
* Purpose:
*
* Start re-sizing a column
*/
void
gtab_trackcol(HWND hwnd, lpTable ptab, int col, int x)
{
/* ensure we see the mouse-up */
SetCapture(hwnd);
ptab->trackmode = TRACK_COLUMN;
ptab->tracknr = col;
ptab->trackline1 = x;
/* if line at other side of cell is visible, draw that too */
if (ptab->pcellpos[col].start >= ptab->pcellpos[col].clipstart) {
ptab->trackline2 = ptab->pcellpos[col].start;
} else {
ptab->trackline2 = -1;
}
gtab_drawvertline(hwnd, ptab);
}
/***************************************************************************
* Function: gtab_press
*
* Purpose:
*
* Called on mouse-down events. decide what to start tracking.
*/
void
gtab_press(HWND hwnd, lpTable ptab, int x, int y)
{
int cell;
long row;
if (ptab->trackmode != TRACK_NONE) {
return;
}
/* has he grabbed a cell-edge to resize ? */
cell = gtab_xtocol(hwnd, ptab, x);
if (cell == -1) {
return;
}
if (gtab_isborder(hwnd, ptab, x, cell)) {
gtab_trackcol(hwnd, ptab, cell, x);
return;
}
if ( (cell > 0) && gtab_isborder(hwnd, ptab, x, cell-1)) {
gtab_trackcol(hwnd, ptab, cell, x);
return;
}
/* find which line he selected */
row = gtab_linetorow(hwnd, ptab, gtab_ytoline(hwnd, ptab, y));
/* is he selecting a disabled fixed area ? */
if ( (row < ptab->hdr.fixedrows) || (cell < ptab->hdr.fixedcols)) {
if (ptab->hdr.fixedselectable == FALSE) {
return;
}
}
/* ok, start cell selection */
ptab->trackmode = TRACK_CELL;
SetCapture(hwnd);
/* record and paint new selection */
if (ptab->hdr.selectmode & TM_ROW) {
gtab_select(hwnd, ptab, row, 0, 1, ptab->hdr.ncols, FALSE);
} else {
gtab_select(hwnd, ptab, row, cell, 1, 1, FALSE);
}
return;
}
/***************************************************************************
* Function: gtab_release
*
* Purpose:
*
* Called on mouse-up. complete any tracking that was happening
*/
void
gtab_release(HWND hwnd, lpTable ptab, int x, int y)
{
lpCellPos ppos;
lpProps pprop;
long row;
int cx;
switch(ptab->trackmode) {
case TRACK_NONE:
return;
case TRACK_COLUMN:
/* erase marker lines */
gtab_drawvertline(hwnd, ptab);
ReleaseCapture();
ptab->trackmode = TRACK_NONE;
/* adjust cell width */
ppos = &ptab->pcellpos[ptab->tracknr];
cx = ptab->trackline1 - ppos->start;
pprop = &ptab->pcolhdr[ptab->tracknr].props;
pprop->valid |= P_WIDTH;
pprop->width = cx;
gtab_calcwidths(hwnd, ptab);
gtab_setsize(hwnd, ptab);
InvalidateRect(hwnd, NULL, TRUE);
return;
case TRACK_CELL:
row = gtab_linetorow(hwnd, ptab, gtab_ytoline(hwnd, ptab, y));
ReleaseCapture();
ptab->trackmode = TRACK_NONE;
/* keep the same selection. if the mouse is still
* in the box, select it, otherwise de-select it
*/
if ((row == ptab->select.startrow) &&
( (ptab->hdr.selectmode & TM_ROW) ||
(ptab->select.startcell == gtab_xtocol(hwnd, ptab, x))) ) {
gtab_select(hwnd, ptab, ptab->select.startrow,
ptab->select.startcell,
ptab->select.nrows, ptab->select.ncells, TRUE);
} else {
gtab_select(hwnd, ptab, 0, 0, 0, 0, TRUE);
}
return;
}
}
/***************************************************************************
* Function: gtab_move
*
* Purpose:
*
* Called on mouse-move. if tracking - adjust position, if not,
* set correct cursor
*/
void
gtab_move(HWND hwnd, lpTable ptab, int x, int y)
{
BOOL fOK;
long row;
int col;
lpCellPos ppos;
switch(ptab->trackmode) {
case TRACK_NONE:
col = gtab_xtocol(hwnd, ptab, x);
if (col == -1) {
SetCursor(hNormCurs);
return;
}
if (gtab_isborder(hwnd, ptab, x, col)) {
SetCursor(hVertCurs);
return;
}
if ( (col > 0) && gtab_isborder(hwnd, ptab, x, col-1)) {
SetCursor(hVertCurs);
return;
}
SetCursor(hNormCurs);
return;
case TRACK_CELL:
row = gtab_linetorow(hwnd, ptab, gtab_ytoline(hwnd, ptab, y));
/* keep the same selection. if the mouse is still
* in the box, select it, otherwise de-select it
*/
if ((row == ptab->select.startrow) &&
( (ptab->hdr.selectmode & TM_ROW) ||
(ptab->select.startcell == gtab_xtocol(hwnd, ptab, x))) ) {
if (!ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
ptab->selvisible = TRUE;
}
} else {
if (ptab->selvisible) {
gtab_invertsel(hwnd, ptab, NULL);
ptab->selvisible = FALSE;
}
}
return;
case TRACK_COLUMN:
/* check that new x is still visible/valid */
ppos = &ptab->pcellpos[ptab->tracknr];
fOK = FALSE;
if (ptab->tracknr < ptab->hdr.fixedcols) {
if ((x > ppos->start) && (x < ptab->winwidth)) {
fOK = TRUE;
}
} else {
if ((x > ppos->clipstart) && (x < ptab->winwidth)) {
fOK = TRUE;
}
}
if (fOK == TRUE) {
gtab_drawvertline(hwnd, ptab);
ptab->trackline1 = x;
gtab_drawvertline(hwnd, ptab);
}
return;
}
}
/***************************************************************************
* Function: gtab_dblclick
*
* Purpose:
*
* dbl-click - send an TQ_ENTER event to the owner (if valid)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?