diff options
| -rw-r--r-- | wintable/accessibility.h | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/wintable/accessibility.h b/wintable/accessibility.h index 0e989c6..9d94f78 100644 --- a/wintable/accessibility.h +++ b/wintable/accessibility.h @@ -1,5 +1,10 @@ // 24 december 2014 +// notes: +// - TODO figure out what to do about header +// - a row extends as far right as the right edge of the last cell in the row; anything to the right of that is treated as table space (just like with mouse selection) +// - this has the added effect that hit-testing can only ever return either the table or a cell, never a row + // TODOs: // - make sure E_POINTER and RPC_E_DISCONNECTED are correct returns for IAccessible @@ -353,14 +358,16 @@ static HRESULT STDMETHODCALLTYPE tableAccaccLocation(IAccessible *this, long *px case ROLE_SYSTEM_TABLE: return IAccessible_accLocation(TA->std, pxLeft, pyTop, pcxWidth, pcyHeight, varChild); case ROLE_SYSTEM_ROW: - // TODO see below about width of a row + // TODO actually write this return E_FAIL; case ROLE_SYSTEM_CELL: rc.row = what.row; rc.column = what.column; if (!rowColumnToClientRect(TA->t, rc, &r)) { // TODO what do we do here? + // TODO we have to return something indicating that the object is off-screen } + // TODO intersect with client rect? break; } pt.x = r.left; @@ -400,39 +407,54 @@ static HRESULT STDMETHODCALLTYPE tableAccaccHitTest(IAccessible *this, long xLef if (ScreenToClient(TA->t->hwnd, &pt) == 0) return HRESULT_FROM_WIN32(GetLastError()); + // first see if the point is even IN the table + if (GetClientRect(TA->t->hwnd, &r) == 0) + return HRESULT_FROM_WIN32(GetLastError()); + r.top += TA->t->headerHeight; + if (PtInRect(&r, pt) == 0) + goto outside; + + // now see if we're in a cell or in the table + // TODO also handle GetLastError() here + rc = clientCoordToRowColumn(TA->t, pt); switch (TA->what.role) { case ROLE_SYSTEM_TABLE: - if (GetClientRect(TA->t->hwnd, &r) == 0) - return HRESULT_FROM_WIN32(GetLastError()); - r.top += TA->t->headerHeight; - break; + // either the table or the cell + if (rc.row == -1 || rc.column == -1) + goto self; + goto specificCell; case ROLE_SYSTEM_ROW: - // TODO do we extend the row to the last cell or to the edge of the client rect? - return E_FAIL; + // a specific cell, but only if in the same row + // TODO actually do we really need these spurious rc.column ==/!= -1 checks? + if (rc.row == TA->what.row) { + if (rc.column == -1) + // TODO de-GetLastError() this + panic("impossible situation TODO write this"); + goto specificCell; + } + goto outside; case ROLE_SYSTEM_CELL: - // TODO could probably be its own code path -pvarChild->vt = VT_I4; -pvarChild->lVal = CHILDID_SELF; -return S_OK; - return E_FAIL; - } - if (PtInRect(&r, pt) == 0) { - pvarChild->vt = VT_EMPTY; - return S_FALSE; + if (rc.row == TA->what.row && rc.column == TA->what.column) + goto self; + goto outside; } + // TODO actually do this right + // TODO un-GetLastError() this + panic("impossible blah blah blah TODO write this"); + return E_FAIL; - // TODO adjust the rest of this function to account for rows and cells +outside: + pvarChild->vt = VT_EMPTY; + return S_FALSE; - // TODO also handle GetLastError() here - rc = clientCoordToRowColumn(TA->t, pt); - // in the table itself? - if (rc.row == -1 || rc.column == -1) { - pvarChild->vt = VT_I4; - pvarChild->lVal = CHILDID_SELF; - return S_OK; - } - // nope, on a cell +self: + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + return S_OK; + +specificCell: pvarChild->vt = VT_DISPATCH; + // TODO GetLastError() here too pvarChild->pdispVal = (IDispatch *) newTableAcc(TA->t, ROLE_SYSTEM_CELL, rc.row, rc.column); return S_OK; } |
