コード例 #1
0
/*
 * set the topmost selectable unit in window as the selection
 *
 * if bExtend is TRUE, then extend the selection to include this, rather
 * than replacing the existing selection. Note that (startrow, startcell)
 * is always the anchor point - ie most recently selected end, and the
 * (nrows, ncells) can be + or - to extend the selection downwards or upwards.
 */
void
gtab_selhome(HWND hwnd, lpTable ptab, BOOL bExtend)
{
    long startrow, startcell, ncells;

    if (ptab->hdr.selectmode & TM_ROW) {
        ncells = ptab->hdr.ncols;
    } else {
        ncells = 1;
    }
    startcell = 0;


    if (ptab->hdr.fixedselectable) {
        startrow = gtab_linetorow(hwnd, ptab, 0);
    } else {
        startrow = gtab_linetorow(hwnd, ptab, ptab->hdr.fixedrows);
        if (!(ptab->hdr.selectmode & TM_ROW)) {
            startcell = ptab->hdr.fixedcols;
        }
    }

    if (bExtend) {
        gtab_extendsel(hwnd, ptab, startrow, startcell, TRUE);
    } else {
        gtab_select(hwnd, ptab, startrow, startcell, 1, ncells, TRUE);
    }
}
コード例 #2
0
/*
 * called on right-click events. Select the cell clicked on, and if
 * valid, send on to owner for any context-menu type operation
 */
void
gtab_rightclick(HWND hwnd, lpTable ptab, int x, int y)
{
    long cell, ncells;
    long row;
    HWND hOwner;

    /* find which col, row he selected */
    cell = gtab_xtocol(hwnd, ptab, x);
    if (cell == -1) {
        return;
    }
    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;
        }
    }

    // ignore if beyond data
    if ((row >= ptab->hdr.nrows) ||
            (cell >= ptab->hdr.ncols)) {
        return;
    }

    /* is this within the already-selected area? */
    if (!gtab_insideselection(ptab, row, cell)) {
        // no selection, or clicked outside the selection - make new selection
        // before sending the right-click

        // if shift is down, extend selection
        if (GetKeyState(VK_SHIFT) & 0x8000) {
            gtab_extendsel(hwnd, ptab, row, cell, TRUE);
        } else {
            /* record and paint new selection */

            if (ptab->hdr.selectmode & TM_ROW) {
                cell = 0;
                ncells = ptab->hdr.ncols;
            } else {
                ncells = 1;
            }
            gtab_select(hwnd, ptab, row, cell, 1, ncells, TRUE);
        }
    }

    // now we have sent the selection, pass the message onto him
    hOwner = (HWND) GetWindowLongPtr(hwnd, WW_OWNER);
    SendMessage(hOwner, WM_RBUTTONDOWN, 0, MAKELONG( (short)x, (short)y));
}
コード例 #3
0
ファイル: table.cpp プロジェクト: firewood/sdkdiff
LRESULT
gtab_wndproc(
            HWND hwnd,
            UINT msg,
            WPARAM wParam,
            LPARAM lParam
            )
{
    CREATESTRUCT FAR * csp;
    HWND hOwner;
    lpTable ptab;
    lpTableSelection pselect;
    long oldtop;
    long change;

    switch (msg) {

        case WM_CREATE:
            /* create window. set the wnd extra bytes to
             * contain the owner window 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) csp->lpCreateParams;
            }
            ptab = NULL;

            SetWindowLongPtr(hwnd, WL_TABLE, (LONG_PTR) ptab);
            SetWindowLongPtr(hwnd, WW_OWNER, (LONG_PTR) hOwner);

            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) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_sendtq(hwnd, TQ_CLOSE, ptab->hdr.id);
                gtab_deltable(hwnd, ptab);
                SetCursor((HCURSOR)hNormCurs);
                SetWindowLongPtr(hwnd, WL_TABLE, 0);
            }
            if ( (ptab = gtab_buildtable(hwnd, (DWORD_PTR)lParam)) != NULL) {
                SetWindowLongPtr(hwnd, WL_TABLE, (LONG_PTR) 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) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_deltable(hwnd, ptab);
                SetCursor((HCURSOR)hNormCurs);
                SetWindowLongPtr(hwnd, WL_TABLE, 0);
            }
            if ( (ptab = gtab_buildtable(hwnd, (DWORD_PTR)lParam)) != NULL) {
                SetWindowLongPtr(hwnd, WL_TABLE, (LONG_PTR) 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) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_newsize(hwnd, ptab);
                gtab_sendtq(hwnd, TQ_SHOWWHITESPACE, (LPARAM) &ptab->show_whitespace);
            }
            InvalidateRect(hwnd, NULL, TRUE);
            break;

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

                gtab_select(hwnd, ptab, pselect->startrow,
                            pselect->startcell,
                            pselect->nrows,
                            pselect->ncells,
                            TRUE);
                gtab_showsel_middle(hwnd, ptab, pselect->dyRowsFromTop);
            }
            break;

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

                *pselect = ptab->select;
            }
            break;

        case TM_PRINT:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                return gtab_print(hwnd, ptab, (lpPrintContext) lParam);
            }
            return FALSE;

        case TM_SETTABWIDTH:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (!ptab)
                return 0;
            ptab->tabchars = (int)lParam;
            InvalidateRect(hwnd, NULL, FALSE);
            break;

        case TM_TOPROW:

            /* return top row. if wParam is TRUE, set lParam
             * as the new toprow
             */
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab == NULL) {
                return(0);
            }
            oldtop = ptab->toprow;
            if ((wParam) && (lParam < ptab->hdr.nrows)) {
                change = (long)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) GetWindowLongPtr(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 not
             * been changed. Update without forcing redraw of
             * everything.
             * lParam contains the new total nr of rows
             */
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_append(hwnd, ptab, (int) wParam, (DWORD_PTR)lParam);
                return(TRUE);
            }
            break;

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

        case WM_ERASEBKGND:
            return TRUE;

        case WM_DESTROY:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_sendtq(hwnd, TQ_CLOSE, ptab->hdr.id);
                gtab_deltable(hwnd, ptab);
            }
            break;

        case WM_SYSCOLORCHANGE:
            InvalidateRect(hwnd, NULL, TRUE);
            break;

        case WM_PAINT:
            gtab_paint(hwnd);
            break;

        case WM_HSCROLL:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_msg_hscroll(hwnd, ptab,
                                 GET_SCROLL_OPCODE(wParam, lParam),
                                 GET_SCROLL_POS(wParam, lParam));
            }
            break;

        case WM_VSCROLL:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_msg_vscroll(hwnd, ptab,
                                 GET_SCROLL_OPCODE(wParam, lParam),
                                 GET_SCROLL_POS(wParam, lParam));
            }
            break;

        case WM_MOUSEMOVE:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_move(hwnd, ptab, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
            } else {
                SetCursor((HCURSOR)hNormCurs);
            }
            break;

        case WM_LBUTTONDOWN:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_press(hwnd, ptab, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
            }
            break;

        case WM_RBUTTONDOWN:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_rightclick(hwnd, ptab, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
            }
            break;

        case WM_LBUTTONUP:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_release(hwnd, ptab,
                             (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
            }
            break;

        case WM_LBUTTONDBLCLK:
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                gtab_dblclick(hwnd, ptab,
                              (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam));
            }
            break;

        case WM_KEYDOWN:
            /* handle key presses for cursor movement about
             * the table, and return/space for selection.
             * Any key we don't handle is passed to the owner window
             * for him to handle.
             * The table window should have the focus
             */
            ptab = (lpTable) GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                if (gtab_key(hwnd, ptab, (int)wParam) != 0) {
                    hOwner = (HWND) GetWindowLongPtr(hwnd, WW_OWNER);
                    return(SendMessage(hOwner, WM_KEYDOWN, wParam, lParam));
                } else {
                    return(0);
                }
            }
            break;

#ifdef WM_MOUSEWHEEL
        case WM_MOUSEWHEEL:
            ptab = (lpTable)GetWindowLongPtr(hwnd, WL_TABLE);
            if (ptab != NULL) {
                if (gtab_mousewheel(hwnd,ptab, LOWORD(wParam), (short)HIWORD(wParam))) {
                    hOwner = (HWND)GetWindowLongPtr(hwnd, WW_OWNER);
                    return SendMessage(hOwner, WM_MOUSEWHEEL, wParam, lParam);
                }
            }
            break;
#endif

        default:
            return(DefWindowProc(hwnd, msg, wParam, lParam));
    }
    return(TRUE);
}
コード例 #4
0
ファイル: table.cpp プロジェクト: firewood/sdkdiff
/*
 * build up a Table struct (excluding data allocation and
 * anything to do with font or window size).
 * return ptr to this or NULL if error
 */
lpTable
gtab_buildtable(
               HWND hwnd,
               DWORD_PTR id
               )
{
    lpTable ptab;
    int ncols, i;
    ColPropsList cplist;

    ptab = (lpTable) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Table));
    if (ptab == NULL) {
        return(NULL);
    }

    // get the tab width. most clients will not support this
    if (gtab_sendtq(hwnd, TQ_TABS, (LPARAM) &ptab->tabchars) == FALSE) {
        ptab->tabchars = TABWIDTH_DEFAULT;
    }

    // get the show whitespace value
    if (gtab_sendtq(hwnd, TQ_SHOWWHITESPACE, (LPARAM) &ptab->show_whitespace) == FALSE) {
        ptab->show_whitespace = FALSE;
    }

    /* get the row/column count from owner window */
    ptab->hdr.id = id;
    ptab->hdr.props.valid = 0;
    ptab->hdr.sendscroll = FALSE;
    if (gtab_sendtq(hwnd, TQ_GETSIZE, (LPARAM) &ptab->hdr) == FALSE) {
        return(NULL);
    }

    ncols = ptab->hdr.ncols;
    ptab->pcolhdr = (lpColProps) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ColProps) * ncols);
    if (ptab->pcolhdr == NULL) {
        /* should prob send TQ_CLOSE at this point */
        return(NULL);
    }

    /* init col properties to default */
    for (i=0; i < ncols; i++) {
        ptab->pcolhdr[i].props.valid = 0;
        ptab->pcolhdr[i].nchars = 0;
    }
    /* get the column props from owner */
    cplist.plist = ptab->pcolhdr;
    cplist.id = id;
    cplist.startcol = 0;
    cplist.ncols = ncols;
    gtab_sendtq(hwnd, TQ_GETCOLPROPS, (LPARAM) &cplist);

    /* init remaining fields */
    ptab->pcellpos = (lpCellPos) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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);
}
コード例 #5
0
/*
 * extend the selection to set the new anchor point as startrow, startcell.
 *
 * nrows and ncells will then be set to include the end row of the previous
 * selection. nrows, ncells < 0 indicate left and up. -1 and +1 both indicate
 * just one cell or row selected.
 */
VOID
gtab_extendsel(
    HWND hwnd,
    lpTable ptab,
    long startrow,
    long startcell,
    BOOL bNotify
)
{
    long endrow, endcell, nrows, ncells;

    /*
     * if no current selection, then just select the new anchor point
     */
    if (ptab->select.nrows == 0) {
        gtab_select(hwnd, ptab, startrow, startcell, 1,
            (ptab->hdr.selectmode & TM_ROW) ? ptab->hdr.ncols:1,
            bNotify);
        return;
    }

    if (startrow >= ptab->hdr.nrows) {
        startrow = ptab->hdr.nrows -1;
    } else if (startrow < 0) {
        startrow = 0;
    }
    if (startcell >= ptab->hdr.ncols) {
        startcell = ptab->hdr.ncols-1;
    } else if (startcell < 0) {
        startcell = 0;
    }



    /* calculate the row just beyond the selection
     * this is one above for upwards sels, and one below for
     * downard-extending sels. Then adjust down or up one
     * to be the actual (inclusive) last row.
     */
    endrow = ptab->select.startrow + ptab->select.nrows;
    if (ptab->select.nrows < 0) {
        endrow++;
    } else {
        endrow--;
    }

    if (endrow >= ptab->hdr.nrows) {
        endrow = ptab->hdr.nrows-1;
    }
    nrows = endrow - startrow;

    if (nrows >= 0) {
        // convert from exclusive to inclusive
        nrows++;
    } else {
        // convert from exclusive to inclusive
        nrows--;
    }

    /* same calculation for cells */
    endcell = ptab->select.startcell + ptab->select.ncells;
    if (ptab->select.ncells < 0) {
        endcell++;
    } else {
        endcell--;
    }
    ncells = endcell - startcell;
    if (ncells >= 0) {
        ncells++;
    } else {
        ncells--;
    }
    gtab_select(hwnd, ptab, startrow, startcell, nrows, ncells, bNotify);
}
コード例 #6
0
/*
 * 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, cell;
    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, FALSE);
        return;

    case TRACK_CELL:
        row = gtab_linetorow(hwnd, ptab, gtab_ytoline(hwnd, ptab, y));
        cell = gtab_xtocol(hwnd, ptab, x);

        ReleaseCapture();
        ptab->trackmode = TRACK_NONE;

        // ignore if before or beyond data
        if ( (row < ptab->hdr.fixedrows) ||
             (cell < ptab->hdr.fixedcols)) {
            if (ptab->hdr.fixedselectable == FALSE) {
                gtab_select(
                    hwnd,
                    ptab,
                    ptab->select.startrow,
                    ptab->select.startcell,
                    ptab->select.nrows,
                    ptab->select.ncells,
                    TRUE);

                return;
            }
        }

        if ((row >= ptab->hdr.nrows) ||
                (cell >= ptab->hdr.ncols)) {
            gtab_select(
                    hwnd,
                    ptab,
                    ptab->select.startrow,
                    ptab->select.startcell,
                    ptab->select.nrows,
                    ptab->select.ncells,
                    TRUE);
            return;
        }

        /*
         * Extend to this new selection end point
         * we used to only do this if shift key pressed, but that
         * is not a good UI.
         */
        gtab_extendsel(hwnd, ptab, row, cell, TRUE);
        return;
    }
}
コード例 #7
0
/*
 * called on mouse-down events. decide what to start tracking.
 */
void
gtab_press(HWND hwnd, lpTable ptab, int x, int y)
{
    long cell, ncells;
    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;
        }
    }

    // ignore if beyond data
    if ((row >= ptab->hdr.nrows) ||
            (cell >= ptab->hdr.ncols)) {
        return;
    }


    /* ok, start cell selection */
    ptab->trackmode = TRACK_CELL;
    SetCapture(hwnd);

    /* record and paint new selection */

    if (ptab->hdr.selectmode & TM_ROW) {
        cell = 0;
        ncells = ptab->hdr.ncols;
    } else {
        ncells = 1;
    }

    /*
     * if the shift key is down, then extend the selection to this
     * new anchor point, rather than create a new selection
     */
    if (GetKeyState(VK_SHIFT) & 0x8000) {
        gtab_extendsel(hwnd, ptab, row, cell, FALSE);
    } else {
        gtab_select(hwnd, ptab, row, cell, 1, ncells, FALSE);
    }
    return;
}
コード例 #8
0
/* handle key-down events - scroll windows and/or move selection */
int
gtab_key(HWND hwnd, lpTable ptab, int vkey)
{
    long startrow, ncells, startcell;
    BOOL bControl = FALSE;
    BOOL bShift = FALSE;

    if (GetKeyState(VK_CONTROL) & 0x8000) {
        bControl = TRUE;
    }
    if (GetKeyState(VK_SHIFT) & 0x8000) {
        /* ignore shift key here if TM_MANY -multiple selection flag- is
         * not selected
         */
        if (ptab->hdr.selectmode & TM_MANY) {
            bShift = TRUE;
        }
    }

    switch(vkey) {

    case VK_UP:
        if (bControl) {
            /* control-uparrow scrolls window without selection.
             * the selection is de-selected (to avoid surprises
             * moving back to it).
             */
            gtab_select(hwnd, ptab, 0, 0, 0, 0, TRUE);
            gtab_dovscroll(hwnd, ptab, -1);
        } else {
            /* uparrow moves selection up one line */
            gtab_changesel(hwnd, ptab, -1, 0, FALSE, bShift);
        }
        return(0);

    case VK_DOWN:
        if (bControl) {
            /* control downarrow scrolls window without
             * a selection.
             */
            gtab_select(hwnd, ptab, 0, 0, 0, 0, TRUE);
            gtab_dovscroll(hwnd, ptab, 1);
        } else {
            /* the normal gtab_changesel behaviour is
             * that if the selected line is not visible now,
             * we scroll it to the top of the window. This is fine
             * in most cases but causes unacceptable jumps when
             * repeatedly scrolling down with the down key.
             *
             * Thus we now have an argument to changesel to say
             * that in this case, if you need to move the line onto
             * the window, move it to the bottom and not the top
             */
            gtab_changesel(hwnd, ptab, 1, 0, TRUE, bShift);
        }
        return(0);

    case VK_LEFT:
        /* if cell-selection mode, move left one cell.
         * otherwise the whole row is selected - scroll
         * the line left a little
         */

        if (ptab->hdr.selectmode & TM_ROW) {
            if (bControl) {
                /* ctrl-left moves to start of line */
                gtab_dohscroll(hwnd, ptab, -(ptab->scroll_dx));
            } else {
                gtab_dohscroll(hwnd, ptab, -(ptab->avewidth));
            }
        } else {
            gtab_changesel(hwnd, ptab, 0, -1, FALSE, bShift);
        }
        return(0);

    case VK_RIGHT:
        /* if cell-selection mode, move right one cell.
         * otherwise the whole row is selected - scroll
         * the line right a little
         */
        if (ptab->hdr.selectmode & TM_ROW) {
            if (bControl) {
                /* control-right moves to right end of line */
                gtab_dohscroll(hwnd, ptab, ptab->rowwidth -
                                ptab->winwidth);
            } else {
                gtab_dohscroll(hwnd, ptab, ptab->avewidth);
            }
        } else {
            gtab_changesel(hwnd, ptab, 0, 1, TRUE, bShift);
        }
        return(0);

    case VK_HOME:
        if (bControl) {
            /* control-home == top of file */
            gtab_dovscroll(hwnd, ptab, -(ptab->toprow));
        }
        /* top of window */
        gtab_selhome(hwnd, ptab, bShift);
        gtab_showsel(hwnd, ptab, FALSE);

        return(0);

    case VK_END:
        if (bControl) {
            /* control-end -> end of file */
            startrow = ptab->hdr.nrows-1;
        } else {
            startrow = gtab_linetorow(hwnd, ptab, ptab->nlines - 1);
            if (startrow >= ptab->hdr.nrows) {
                startrow = ptab->hdr.nrows-1;
            }
        }

        startcell = 0;
        ncells = ptab->hdr.ncols;
        if (!(ptab->hdr.selectmode & TM_ROW)) {
            startcell = ptab->hdr.ncols-1;
            ncells = 1;
        }

        if (bShift) {
            gtab_extendsel(hwnd, ptab, startrow, startcell, TRUE);
        } else {
            gtab_select(hwnd, ptab, startrow, startcell, 1, ncells, TRUE);
        }

        /* we have selected the bottom line. We don't want to
         * move it up into the window, since the intended
         * effect is to select the lowest line. This doesn't
         * apply to the ctrl-end behaviour (move to bottom of
         * buffer.
         */
        if (bControl) {
            /* move the selection to make it visible - but move it
             * to the bottom and not to the top of the window
             */
            gtab_showsel(hwnd, ptab, TRUE);
        }
        return(0);

    case VK_RETURN:
        if (ptab->select.nrows != 0) {
            gtab_showsel(hwnd, ptab, FALSE);
            gtab_enter(hwnd, ptab, ptab->select.startrow,
                    ptab->select.startcell,
                    ptab->select.nrows, ptab->select.ncells);
        }
        return(0);

    case VK_SPACE:
        /* toggle the selection */
        if (ptab->select.nrows == 0) {
                /* no selection - make one */
                gtab_changesel(hwnd, ptab, 0, 0, TRUE, FALSE);
        } else {
                /* there is a selection - deselect it */
                gtab_select(hwnd, ptab, 0, 0, 0, 0, TRUE);
        }
        return(0);

    case VK_PRIOR:          /* page up */

        if (ptab->nlines > 3) {
            gtab_dovscroll(hwnd, ptab, -(ptab->nlines - 3));
        }
        gtab_selhome(hwnd, ptab, bShift);
        return(0);

    case VK_NEXT:           /* page down */

        /* scroll down one page */
        if (ptab->nlines > 3) {
            gtab_dovscroll(hwnd, ptab, (ptab->nlines - 3));
        }

        /* select new bottom line */
        startrow = gtab_linetorow(hwnd, ptab, ptab->nlines - 1);
        if (startrow >= ptab->hdr.nrows) {
            startrow = ptab->hdr.nrows-1;
        }
        startcell = 0;
        ncells = ptab->hdr.ncols;
        if (!(ptab->hdr.selectmode & TM_ROW)) {
            startcell = ptab->hdr.ncols-1;
            ncells = 1;
        }

        /* select bottom line, but don't call showsel
         * since we don't want to adjust it's position - we
         * want it to remain at the bottom of the window
         */
        if (bShift) {
            gtab_extendsel(hwnd, ptab, startrow, startcell, TRUE);
        } else {
            gtab_select(hwnd, ptab, startrow, startcell, 1, ncells, TRUE);
        }
        return(0);

    default:
        return(1);
    }
}
コード例 #9
0
/* move the selection a specified nr of rows or cells
 * if no selection, select first visible unit
 *
 * if bExtend is true and there is a current selection, then extend it rather than
 * replace it. Note that (startrow, startcell) will always be set to the newly
 * selected position - this is the anchor point. nrows or ncells may be negative
 * if the selection extends upwards above the anchor. nrows == -1 is the same
 * as nrows == 1, meaning only the current row is visible. Similarly
 * (in TM_CELL mode), ncells may be negative.
 *
 * Move the selection (ie anchor point) to make it visible. bToBottom
 * indicates whether it should be moved to the bottom or the top
 * of the window.
 */
VOID
gtab_changesel(
    HWND hwnd,
    lpTable ptab,
    long rowincr,
    int cellincr,
    BOOL bToBottom,
    BOOL bExtend
)
{
    long row, col, ncols;

    /* is there a selection ? */
    if (ptab->select.nrows == 0) {

        /* no selection - force a selection
         * at the first visible unit
         */
        if (ptab->hdr.fixedselectable) {
            row = 0;
            col = 0;
        } else {
            row = gtab_linetorow(hwnd, ptab, ptab->hdr.fixedrows);
            /* should really check for first visible cell */
            col = ptab->hdr.fixedcols;
        }
        ncols = 1;
        if (ptab->hdr.selectmode & TM_ROW) {
            col = 0;
            ncols = ptab->hdr.ncols;
        }
        gtab_select(hwnd, ptab, row, col, 1, ncols, TRUE);

    } else {
        /* move the anchor point by rowincr, cellincr */
        row = ptab->select.startrow + rowincr;
        col = ptab->select.startcell + cellincr;


        /*
         * ensure that new anchor point is in a valid position
         */

        while (col >= ptab->hdr.ncols) {
            col -= ptab->hdr.ncols;
            row++;
        }
        while (col < 0) {
            col += ptab->hdr.ncols;
            row--;
        }
        if (row < 0) {
            row = 0;
        }
        if (row >= ptab->hdr.nrows) {
            row = ptab->hdr.nrows-1;
        }
        /* check we haven't moved into non-selectable region */
        if ((row < ptab->hdr.fixedrows) &&
            (!ptab->hdr.fixedselectable)) {
                    row = ptab->hdr.fixedrows;
        }

        if (bExtend) {
            gtab_extendsel(hwnd, ptab, row, col, TRUE);
        } else {
            gtab_select(
                hwnd,
                ptab,
                row,
                col,
                1,
                (ptab->hdr.selectmode & TM_ROW) ? ptab->hdr.ncols : 1,
                TRUE);
        }
    }

    /* ensure selection visible */
    gtab_showsel(hwnd, ptab, bToBottom);
}