/* 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, (LPARAM) &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, FALSE); }
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); }
/* * 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; } }