table.c
来自「<Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.」· C语言 代码 · 共 917 行 · 第 1/3 页
C
917 行
ptab->pcellpos = (lpCellPos) gmem_get(hHeap, sizeof(CellPos) * ncols);
if (ptab->pcellpos == NULL) {
return(NULL);
}
ptab->scrollscale = 1;
ptab->scroll_dx = 0;
ptab->toprow = 0;
ptab->pdata = NULL;
ptab->nlines = 0;
ptab->trackmode = TRACK_NONE;
/* we have to notify owner of the current selection
* whenever it is changed
*/
ptab->select.id = id;
gtab_select(hwnd, ptab, 0, 0, 0, 0, TRUE);
/* calc ave height/width, cell widths and min height.
* these change only when cell properties / col count changes -
* ie only on rebuild-header events
*/
gtab_calcwidths(hwnd, ptab);
return(ptab);
}
/***************************************************************************
* Function: gtab_setsize
*
* Purpose:
*
* Set sizes that are based on window size and scroll pos
* set:
* winwidth
* nlines
* cellpos start, clip start/end
* Alloc linedata and init
*/
void
gtab_setsize(HWND hwnd, lpTable ptab)
{
RECT rc;
int nlines;
HANDLE heap;
long range, change;
GetClientRect(hwnd, &rc);
ptab->winwidth = rc.right - rc.left;
nlines = (rc.bottom - rc.top) / ptab->rowheight;
/* nlines is the number of whole lines - add one extra
* for the partial line at the bottom
*/
nlines += 1;
/* alloc space for nlines of data - if nlines has changed */
if (nlines != ptab->nlines) {
heap = (HANDLE) GetWindowLong(hwnd, WW_HEAP);
gtab_freelinedata(heap, ptab);
ptab->nlines = nlines;
if (!gtab_alloclinedata(hwnd, heap, ptab)) {
ptab->nlines = 0;
return;
}
}
/* set scroll vertical range */
range = ptab->hdr.nrows - (ptab->nlines - 1);
if (range < 0) {
range = 0;
change = -(ptab->toprow);
} else if (ptab->toprow > range) {
change = range - ptab->toprow;
} else {
change = 0;
}
/* the scroll range must be 16-bits for Win3
* scale until this is true
*/
ptab->scrollscale = 1;
while (range > 32766) {
ptab->scrollscale *= 16;
range /= 16;
}
SetScrollRange(hwnd, SB_VERT, 0, (int) range, TRUE);
gtab_dovscroll(hwnd, ptab, change);
/* set horz scroll range */
range = ptab->rowwidth - ptab->winwidth;
if (range < 0) {
range = 0;
change = -(ptab->scroll_dx);
} else if (ptab->scroll_dx > range) {
change = range - ptab->scroll_dx;
} else {
change = 0;
}
/* horz scroll range will always be < 16 bits */
SetScrollRange(hwnd, SB_HORZ, 0, (int) range, TRUE);
gtab_dohscroll(hwnd, ptab, change);
}
/***************************************************************************
* Function: gtab_calcwidths
*
* Purpose:
*
* Set column widths/height and totals (based on column props)
* - no assumption of window size (see gtab_setsize)
* sets avewidth,rowheight,cellpos.size,rowwidth (total of cellpos.size)
*/
void
gtab_calcwidths(HWND hwnd, lpTable ptab)
{
int i, cxtotal, cx, ave;
TEXTMETRIC tm, tmcol;
HDC hdc;
lpProps hdrprops, cellprops;
HFONT hfont;
hdrprops = &ptab->hdr.props;
hdc = GetDC(hwnd);
if (hdrprops->valid & P_FONT) {
hfont = SelectObject(hdc, hdrprops->hFont);
}
GetTextMetrics(hdc, &tm);
if (hdrprops->valid & P_FONT) {
SelectObject(hdc, hfont);
}
ReleaseDC(hwnd, hdc);
/* get width and height of average character */
ptab->avewidth = tm.tmAveCharWidth;
ptab->rowheight = tm.tmHeight + tm.tmExternalLeading;
if (hdrprops->valid & P_HEIGHT) {
ptab->rowheight = hdrprops->height;
}
/* set pixel width of each cell (and add up for row total)
* based on ave width * nr chars, unless P_WIDTH set
*/
cxtotal = 0;
for (i = 0; i < ptab->hdr.ncols; i++) {
cellprops = &ptab->pcolhdr[i].props;
if (cellprops->valid & P_WIDTH) {
cx = cellprops->width;
} else if (hdrprops->valid & P_WIDTH) {
cx = hdrprops->width;
} else {
if (cellprops->valid & P_FONT) {
hdc = GetDC(hwnd);
hfont = SelectObject(hdc, cellprops->hFont);
GetTextMetrics(hdc, &tmcol);
SelectObject(hdc, hfont);
ReleaseDC(hwnd, hdc);
ave = tmcol.tmAveCharWidth;
} else {
ave = ptab->avewidth;
}
/* ave width * nchars */
cx = ptab->pcolhdr[i].nchars + 1;
cx *= ave;
}
/* add 2 pixels for box lines */
cx += 2;
ptab->pcellpos[i].size = cx;
cxtotal += cx;
}
ptab->rowwidth = cxtotal;
}
/***************************************************************************
* Function: gtab_newsize
*
* Purpose:
*
* Called when row data + possible nrows changes.
* other changes are ignored
*/
void
gtab_newsize(HWND hwnd, lpTable ptab)
{
TableHdr hdr;
/* get new row count */
hdr = ptab->hdr;
gtab_sendtq(hwnd, TQ_GETSIZE, (long) (LPSTR) &hdr);
if (hdr.nrows != ptab->hdr.nrows) {
ptab->hdr.nrows = hdr.nrows;
gtab_setsize(hwnd, ptab);
}
gtab_invallines(hwnd, ptab, 0, ptab->nlines);
InvalidateRect(hwnd, NULL, TRUE);
}
void
gtab_invallines(HWND hwnd, lpTable ptab, int start, int count)
{
int i, j;
for (i = start; i < start + count; i++) {
for (j = 0; j < ptab->hdr.ncols; j++) {
ptab->pdata[i].pdata[j].flags = 0;
}
}
}
/***************************************************************************
* Function: gtab_append
*
* Purpose:
*
* New rows have been added to the table. Adjust the scroll range and
* position, and redraw the rows if the end of the table is currently
* visible.
* rows = the new total row count.
*/
void
gtab_append(HWND hwnd, lpTable ptab, int rows, DWORD id)
{
long range;
long oldrows;
int line, nupdates;
RECT rc;
/* change to the new id */
ptab->hdr.id = id;
ptab->select.id = id;
/* update the header, but remember the old nr of rows
* so we know where to start updating
*/
oldrows = ptab->hdr.nrows;
/* check that the new nr of rows is not smaller. this is
* illegal at this point and should be ignored
*/
if (oldrows >= rows) {
return;
}
ptab->hdr.nrows = rows;
/* set the vertical scroll range */
range = rows - (ptab->nlines - 1);
if (range < 0) {
range = 0;
}
/* force the scroll range into 16-bits for win 3.1 */
ptab->scrollscale = 1;
while (range > 32766) {
ptab->scrollscale *= 16;
range /= 16;
}
/* now set the scroll bar range and position */
SetScrollRange(hwnd, SB_VERT, 0, (int) range, TRUE);
if (range > 0) {
SetScrollPos(hwnd, SB_VERT,
(int) (ptab->toprow / ptab->scrollscale), TRUE);
}
/* calculate which screen lines need to be updated - find what
* screen line the start of the new section is at
*/
line = gtab_rowtoline(hwnd, ptab, oldrows);
if (line == -1) {
/* not visible -> no more to do */
return;
}
/* how many lines to update - rest of screen or nr of
* new lines if less than rest of screen
*/
nupdates = min((ptab->nlines - line), (int)(rows - oldrows));
/* invalidate the screen line buffers to indicate data
* needs to be refetch from parent window
*/
gtab_invallines(hwnd, ptab, line, nupdates);
/* calculate the region of the screen to be repainted -
* left and right are same as window. top and bottom
* need to be calculated from screen line height
*/
GetClientRect(hwnd, &rc);
rc.top += line * ptab->rowheight;
rc.bottom = rc.top + (nupdates * ptab->rowheight);
/* force a repaint of the updated region */
InvalidateRect(hwnd, &rc, TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?