table.c

来自「<Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.」· C语言 代码 · 共 917 行 · 第 1/3 页

C
917
字号

/****************************** Module Header *******************************
* Module Name: TABLE.C
*
* Standard table class and main interface functions.
*
* Functions:
*
* gtab_init()
* gtab_deltools()
* gtab_sendtq()
* gtab_freelinedata()
* gtab_wndproc()
* gtab_createtools()
* gtab_deltable()
* gtab_buildtable()
* gtab_setsize()
* gtab_newsize()
* gtab_calcwidths()
* gtab_alloclinedata()
* gtab_invallines()
* gtab_append()
*
* Comments:
*
* The table class communicates with its 'owner' window to
* get the layout info and the data to display. The owner window handle
* can be sent as the lParam in CreateWindow - if not, the parent window will
* be used.
*
* After creating the window, send it a TM_NEWID message, with a 'data id'
* as the lParam. This is any non-zero 32-bit value. The table will then call
* back to its owner window to find out how many rows/columns, then to fetch
* the name/properties of each column, and finally to get the data to display.
*
* Send TM_NEWID of 0 to close (or destroy the window) - wait for TQ_CLOSE
* (in either case) before discarding data. Send
* TM_REFRESH if data or row-count changes; send TM_NEWLAYOUT if column
* properties or nr cols change etc - this is the same as sending TM_NEWID
* except that no TQ_CLOSE happens on TM_NEWLAYOUT.
*
* TQ_SELECT is sent whenever the current selection changes. TQ_ENTER is sent
* when enter or double-click occurs.
*
****************************************************************************/

#include <windows.h>
#include <commdlg.h>

#include "gutils.h"
#include "table.h"
#include "tpriv.h"

/* global tools etc */
extern HANDLE hLibInst;
HANDLE hVertCurs;
HANDLE hNormCurs;
HPEN hpenDotted;
UINT gtab_msgcode;

/* function prototypes */
long FAR PASCAL gtab_wndproc(HWND, UINT, UINT, long);
void gtab_createtools(void);
void gtab_deltable(HWND hwnd, lpTable ptab);
lpTable gtab_buildtable(HWND hwnd, DWORD id);
void gtab_setsize(HWND hwnd, lpTable ptab);
void gtab_newsize(HWND hwnd, lpTable ptab);
void gtab_calcwidths(HWND hwnd, lpTable ptab);
BOOL gtab_alloclinedata(HWND hwnd, HANDLE heap, lpTable ptab);
void gtab_invallines(HWND hwnd, lpTable ptab, int start, int count);
void gtab_append(HWND hwnd, lpTable ptab, int rows, DWORD id);

/***************************************************************************
 * Function: gtab_init
 *
 * Purpose:
 *
 * Initialise window class - called from DLL main init
 */
void
gtab_init(void)
{
        WNDCLASS wc;

        gtab_createtools();
        gtab_msgcode = RegisterWindowMessage(TableMessage);

        wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
        wc.lpfnWndProc = gtab_wndproc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = WLTOTAL;
        wc.hInstance = hLibInst;
        wc.hIcon = NULL;
        wc.hCursor = NULL;
        wc.hbrBackground = GetStockObject(WHITE_BRUSH);
        wc.lpszClassName = TableClassName;
        wc.lpszMenuName = NULL;

        RegisterClass(&wc);
}

/***************************************************************************
 * Function: gtab_createtools
 *
 * Purpose:
 *
 * Load cursors and pens.
 */
 void
gtab_createtools(void)
{
        hVertCurs = LoadCursor(hLibInst, "VertLine");
        hNormCurs = LoadCursor(NULL, IDC_ARROW);

        hpenDotted = CreatePen(PS_DOT, 1, RGB(0, 0, 0));
}

/***************************************************************************
 * Function: gtab_deltools
 *
 * Purpose:
 *
 * Delete pen
 */
 void
gtab_deltools(void)
{
        DeleteObject(hpenDotted);
}


/***************************************************************************
 * Function: gtab_wndproc
 *
 * Purpose:
 *
 * Window procedure for table
 */
 long FAR PASCAL
gtab_wndproc(HWND hwnd, UINT msg, UINT wParam, long lParam)
{
        CREATESTRUCT FAR * csp;
        HWND hOwner;
        lpTable ptab;
        HANDLE hHeap;
        PAINTSTRUCT ps;
        int y, y2, i;
        HDC hDC;
        lpTableSelection pselect;
        long oldtop;
        long change;

        switch(msg) {

        case WM_CREATE:
                /* create window. set the wnd extra bytes to
                 * contain the owner window, a heap and a null table.
                 * Owner window is either in lParam or the parent.
                 * Then wait for TM_NEWID.
                 */
                csp = (CREATESTRUCT FAR *) lParam;
                if (csp->lpCreateParams == NULL) {
                        hOwner = GetParent(hwnd);
                } else {
                        hOwner = (HWND) (long) csp->lpCreateParams;
                }
                ptab = NULL;
                hHeap = gmem_init();
                SetWindowLong(hwnd, WL_TABLE, (LONG) ptab);
                SetWindowLong(hwnd, WW_OWNER, (LONG) hOwner);
                SetWindowLong(hwnd, WW_HEAP, (LONG) hHeap);

                SetScrollRange(hwnd, SB_VERT, 0, 0, TRUE);
                SetScrollRange(hwnd, SB_HORZ, 0, 0, TRUE);
                break;

        case TM_NEWID:
                /* complete change of table.
                 * close old table, discard memory and
                 * build new table
                 */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        gtab_sendtq(hwnd, TQ_CLOSE, ptab->hdr.id);
                        gtab_deltable(hwnd, ptab);
                        SetCursor(hNormCurs);
                        SetWindowLong(hwnd, WL_TABLE, 0);
                }
                if ( (ptab = gtab_buildtable(hwnd, lParam)) != NULL) {
                        SetWindowLong(hwnd, WL_TABLE, (long) (LPSTR) ptab);
                        gtab_setsize(hwnd, ptab);
                } else {
                        SetScrollRange(hwnd, SB_VERT, 0, 0, TRUE);
                        SetScrollRange(hwnd, SB_HORZ, 0, 0, TRUE);
                }
                InvalidateRect(hwnd, NULL, TRUE);
                break;

        case TM_NEWLAYOUT:
                /* change of layout but for same id. no TQ_CLOSE,
                 * but otherwise same as TM_NEWID
                 */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        gtab_deltable(hwnd, ptab);
                        SetCursor(hNormCurs);
                        SetWindowLong(hwnd, WL_TABLE, 0);
                }
                if ( (ptab = gtab_buildtable(hwnd, lParam)) != NULL) {
                        SetWindowLong(hwnd, WL_TABLE, (long) (LPSTR) ptab);
                        gtab_setsize(hwnd, ptab);
                } else {
                        SetScrollRange(hwnd, SB_VERT, 0, 0, TRUE);
                        SetScrollRange(hwnd, SB_HORZ, 0, 0, TRUE);
                }
                InvalidateRect(hwnd, NULL, TRUE);
                break;

        case TM_REFRESH:
                /* data in table has changed. nrows may have
                 * changed. ncols and col types have not changed
                 */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        gtab_newsize(hwnd, ptab);
                }
                InvalidateRect(hwnd, NULL, TRUE);
                break;

        case TM_SELECT:
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        pselect = (lpTableSelection) lParam;

                        /*
                         * we only support TM_SINGLE - so force the
                         * selection to a single row or cell.
                         */
                        gtab_select(hwnd, ptab, pselect->startrow,
                                pselect->startcell,
                                1,
                                (ptab->hdr.selectmode & TM_ROW) ?
                                        ptab->hdr.ncols : 1,
                                TRUE);
                        gtab_showsel_middle(hwnd, ptab);
                }
                break;

        case TM_PRINT:
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                hHeap = (HANDLE) GetWindowLong(hwnd, WW_HEAP);
                if (ptab != NULL) {
                        gtab_print(hwnd, ptab, hHeap, (lpPrintContext) lParam);
                        return(TRUE);
                }

        case TM_TOPROW:

                /* return top row. if wParam is TRUE, set lParam
                 * as the new toprow
                 */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab == NULL) {
                        return(0);
                }
                oldtop = ptab->toprow;
                if ((wParam) && (lParam < ptab->hdr.nrows)) {
                        change = lParam - ptab->toprow;
                        change -= ptab->hdr.fixedrows;
                        gtab_dovscroll(hwnd, ptab, change);
                }
                return(oldtop);

        case TM_ENDROW:
                /* return the last visible row in the window */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab == NULL) {
                        return(0);
                }
                return(ptab->nlines + ptab->toprow - 1);


        case TM_APPEND:
                /* new rows have been added to the end of the
                 * table, but the rest of the table has no
                 * been change. Update without forcing redraw of
                 * everything.
                 * lParam contains the new total nr of rows
                 */
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        gtab_append(hwnd, ptab, wParam, lParam);
                        return(TRUE);
                }
                break;

        case WM_SIZE:
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {
                        gtab_setsize(hwnd, ptab);
                }
                break;

        case WM_DESTROY:
                ptab = (lpTable) GetWindowLong(hwnd, WL_TABLE);
                if (ptab != NULL) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?