/* * 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); }
/* * 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; } }