tscroll.c
来自「<Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.」· C语言 代码 · 共 1,139 行 · 第 1/3 页
C
1,139 行
/****************************** Module Header *******************************
* Module Name: TSCROLL.C
*
* Scrolling and selection routines.
*
* Functions:
*
* gtab_msg_vscroll()
* gtab_msg_hscroll()
* gtab_dovscroll()
* gtab_dohscroll()
* gtab_linetorow()
* gtab_rowtoline()
* gtab_select()
* gtab_ytoline()
* gtab_xtocol()
* gtab_isborder()
* gtab_enter()
* gtab_trackcol()
* gtab_press()
* gtab_release()
* gtab_move()
* gtab_dblclick()
* gtab_showsel()
* gtab_showsel_middle()
* gtab_changesel()
* gtab_selhome()
* gtab_key()
*
* Comments:
*
* This implementation currently only supports TM_SINGLE, not TM_MANY
* modes of selection.
*
****************************************************************************/
#include <windows.h>
#include <commdlg.h>
#include "gutils.h"
#include "table.h"
#include "tpriv.h"
/***************************************************************************
* Function: gtab_msg_vscroll
*
* Purpose:
*
* Handle a vscroll message
*/
void
gtab_msg_vscroll(HWND hwnd, lpTable ptab, int opcode, int pos)
{
long change;
switch(opcode) {
case SB_THUMBPOSITION:
change = (pos * ptab->scrollscale) - ptab->toprow;
break;
case SB_LINEUP:
change = -1;
break;
case SB_LINEDOWN:
change = 1;
break;
case SB_PAGEUP:
change = - (ptab->nlines - 3);
break;
case SB_PAGEDOWN:
change = (ptab->nlines - 3);
break;
default:
return;
}
gtab_dovscroll(hwnd, ptab, change);
}
/***************************************************************************
* Function: gtab_msg_hscroll
*
* Purpose:
*
* Handle a hscroll message
*/
void
gtab_msg_hscroll(HWND hwnd, lpTable ptab, int opcode, int pos)
{
int change;
switch(opcode) {
case SB_THUMBPOSITION:
change = pos - ptab->scroll_dx;
break;
case SB_LINEUP:
change = -(ptab->avewidth);
break;
case SB_LINEDOWN:
change = ptab->avewidth;
break;
case SB_PAGEUP:
change = - (ptab->winwidth * 2 / 3);
break;
case SB_PAGEDOWN:
change = (ptab->winwidth * 2 / 3);
break;
default:
return;
}
gtab_dohscroll(hwnd, ptab, change);
}
/***************************************************************************
* Function: gtab_dovscroll
*
* Purpose:
*
* Set new vertical scroll pos,
* adjust linedata array
* set line win-relative start posns & clip top/bottom posns
* revise display.
*/
void
gtab_dovscroll(HWND hwnd, lpTable ptab, long change)
{
int cury, i;
long ncopy;
lpCellPos cp;
LineData ldtemp;
RECT rc, rcpaint;
long range;
long newtop;
int newpos;
range = ptab->hdr.nrows - (ptab->nlines - 1);
newtop = ptab->toprow + change;
if (range < 0) {
range = 0;
}
if (newtop > range) {
change = range - ptab->toprow;
} else if (newtop < 0) {
change = -(ptab->toprow);
}
ptab->toprow += change;
newpos = (int) (newtop / ptab->scrollscale);
SetScrollPos(hwnd, SB_VERT, newpos, TRUE);
if (ptab->hdr.sendscroll) {
gtab_sendtq(hwnd, TQ_SCROLL, ptab->toprow);
}
/* adjust data ptrs rather than invalidate, to retain the
* data we know is still valid
*/
if (abs(change) >= ptab->nlines) {
gtab_invallines(hwnd, ptab, ptab->hdr.fixedrows,
ptab->nlines - ptab->hdr.fixedrows);
InvalidateRect(hwnd, NULL, TRUE);
change = 0;
} else if (change < 0) {
/* copy data down */
ncopy = (ptab->nlines - ptab->hdr.fixedrows) - abs(change);
for (i = ptab->nlines - 1;
i >= (ptab->hdr.fixedrows + abs(change)); i--) {
ldtemp = ptab->pdata[i - abs(change)];
ptab->pdata[i - abs(change)] = ptab->pdata[i];
ptab->pdata[i] = ldtemp;
}
gtab_invallines(hwnd, ptab,
ptab->hdr.fixedrows, (int) abs(change));
} else if (change > 0) {
ncopy = (ptab->nlines - ptab->hdr.fixedrows) - change;
for (i = ptab->hdr.fixedrows;
i < (ncopy + ptab->hdr.fixedrows); i++) {
ldtemp = ptab->pdata[i + change];
ptab->pdata[i + change] = ptab->pdata[i];
ptab->pdata[i] = ldtemp;
}
gtab_invallines(hwnd, ptab,
(int) ncopy + ptab->hdr.fixedrows, (int) change);
}
/* scroll window */
GetClientRect(hwnd, &rc);
rcpaint = rc;
if (change > 0) {
rc.top += (int) (change + ptab->hdr.fixedrows) * ptab->rowheight;
rcpaint.top = (ptab->hdr.fixedrows * ptab->rowheight);
rcpaint.top += rc.bottom - rc.top;
} else if (change < 0) {
rc.top += (ptab->hdr.fixedrows * ptab->rowheight);
rc.bottom -= (int) (change * ptab->rowheight);
rcpaint.bottom -= rc.bottom - rc.top;
}
/* loop through each line setting relative posn and clipping */
/* set up all rows - the fixed/moveable difference for
* rows is made at fetch-time during painting, when we remember
* which absolute row nr to ask for, for a given screen line
*/
cury = 0;
for (i = 0; i < ptab->nlines; i++) {
cp = &ptab->pdata[i].linepos;
cp->start = cury;
cp->clipstart = cury;
cp->clipend = cury + cp->size;
cury += cp->size;
}
/* now move and repaint the window */
if (change != 0) {
if (rc.top < rc.bottom) {
ScrollWindow(hwnd, 0, (int) -(change * ptab->rowheight),
&rc, NULL);
}
/* force repaint now, not just post message for later,
* since we want to repaint that line before the next
* scroll down occurs
*/
RedrawWindow(hwnd, &rcpaint, NULL,
RDW_ERASE | RDW_INVALIDATE|RDW_UPDATENOW);
}
}
/***************************************************************************
* Function: gtab_dohscroll
*
* Purpose:
*
* Set new horizontal scroll pos,
* set col win-relative start posns & clip left/right posns
* revise display.
*/
void
gtab_dohscroll(HWND hwnd, lpTable ptab, long change)
{
int curx, i;
int moveable;
lpCellPos cp;
int newdx, range;
/* check that the new scroll pos is still within the valid range */
range = ptab->rowwidth - ptab->winwidth;
newdx = ptab->scroll_dx + (int) change;
if (range < 0) {
range = 0;
}
if (newdx > range) {
change = range - ptab->scroll_dx;
} else if (newdx < 0) {
change = -(ptab->scroll_dx);
}
ptab->scroll_dx += (int) change;
SetScrollPos(hwnd, SB_HORZ, ptab->scroll_dx, TRUE);
InvalidateRect(hwnd, NULL, TRUE);
/* loop through each col setting relative posn and clipping */
/* clip off 1 pixel left and right (we added 2 on to size for this) */
/* first set up fixed columns */
curx = 0;
for (i = 0; i < ptab->hdr.fixedcols; i++) {
cp = &ptab->pcellpos[i];
cp->start = curx + 1;
cp->clipstart = cp->start;
cp->clipend = cp->start + cp->size - 2;
curx += cp->size;
}
/* now moveable columns. remember start of moveable cols */
moveable = curx;
curx = - ptab->scroll_dx; /* rel. pos of col */
for (i = ptab->hdr.fixedcols; i < ptab->hdr.ncols; i++) {
cp = &ptab->pcellpos[i];
cp->start = curx + moveable + 1;
cp->clipstart = max(moveable+1, cp->start);
cp->clipend = cp->start + cp->size - 2;
curx += cp->size;
}
}
/***************************************************************************
* Function: gtab_linetorow
*
* Purpose:
*
* Convert screen line nr to table row nr
*/
long
gtab_linetorow(HWND hwnd, lpTable ptab, int line)
{
if (line < ptab->hdr.fixedrows) {
return(line);
}
return (line + ptab->toprow);
}
/***************************************************************************
* Function: gtab_rowtoline
*
* Purpose:
*
* Convert table row nr to screen line nr or -1 if not on screen
*/
int
gtab_rowtoline(HWND hwnd, lpTable ptab, long row)
{
if (row < ptab->hdr.fixedrows) {
return( (int) row);
}
row -= ptab->toprow;
if ((row >= ptab->hdr.fixedrows) && (row < ptab->nlines)) {
return ( (int) row);
}
return(-1);
}
/***************************************************************************
* Function: gtab_select
*
* Purpose:
*
* Replace old selection with new. Notify owner if bNotify. Change
* display to reflect new display.
*/
void
gtab_select(
HWND hwnd,
lpTable ptab,
long row,
long col,
long nrows,
long ncells,
BOOL bNotify)
{
int line;
/* if in ROW mode, force col and ncells to reflect the entire row. */
if (ptab->hdr.selectmode & TM_ROW) {
col = 0;
ncells = ptab->hdr.ncols;
}
/* 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?