//+--------------------------------------------------------------------- // // File: border.cxx // // Contents: Border Object Class // // Classes: OLEBorder // //------------------------------------------------------------------------ #include "headers.hxx" #pragma hdrstop BOOL OLEBorder::fInit = FALSE; HCURSOR OLEBorder::ahc[5] = { NULL, NULL, NULL, NULL, NULL }; int OLEBorder::iPartMap[14] = { ICURS_STD, // 0 NOWHERE ICURS_STD, // 1 TOP ICURS_STD, // 2 RIGHT ICURS_STD, // 3 BOTTOM ICURS_STD, // 4 LEFT ICURS_NESW, // 5 TOPRIGHT ICURS_NWSE, // 6 BOTTOMRIGHT ICURS_NESW, // 7 BOTTOMLEFT ICURS_NWSE, // 8 TOPLEFT ICURS_NS, // 9 TOPHAND ICURS_WE, //10 RIGHTHAND ICURS_NS, //11 BOTTOMHAND ICURS_WE, //12 LEFTHAND ICURS_STD //13 INSIDE }; HCURSOR OLEBorder::MapPartToCursor(USHORT usPart) { if (usPart > MAX_OBPART) usPart = 0; return ahc[iPartMap[usPart]]; } //+--------------------------------------------------------------- // // Member: OLEBorder::InitClass // //--------------------------------------------------------------- void OLEBorder::InitClass( void ) { _fErased = TRUE; _state = 0; _sThickness = FBORDER_THICKNESS; _sMinHeight = FBORDER_MINHEIGHT; _sMinWidth = FBORDER_MINWIDTH; if(fInit) return; ahc[ICURS_NWSE] = LoadCursor( NULL, IDC_SIZENWSE ); ahc[ICURS_NESW] = LoadCursor( NULL, IDC_SIZENESW ); ahc[ICURS_NS] = LoadCursor( NULL, IDC_SIZENS ); ahc[ICURS_WE] = LoadCursor( NULL, IDC_SIZEWE ); ahc[ICURS_STD] = LoadCursor( NULL, IDC_SIZEALL ); fInit = TRUE; } //+--------------------------------------------------------------- // // Member: OLEBorder::OLEBorder // //--------------------------------------------------------------- OLEBorder::OLEBorder( void ) { rect.top = 0; rect.left = 0; rect.bottom = 0; rect.right = 0; InitClass(); } //+--------------------------------------------------------------- // // Member: OLEBorder::OLEBorder // //--------------------------------------------------------------- OLEBorder::OLEBorder( RECT& r ) { rect = r; InitClass(); } //+--------------------------------------------------------------- // // Member: OLEBorder::~OLEBorder // //--------------------------------------------------------------- OLEBorder::~OLEBorder( void ) { } //+--------------------------------------------------------------- // // Member: OLEBorder::SetState // //--------------------------------------------------------------- USHORT OLEBorder::SetState( HDC hdc, HWND hwnd, USHORT usBorderState ) { if (_state ^ usBorderState) { if (hdc != NULL) { _state |= OBSTYLE_RESERVED; Draw(hdc,hwnd); } } _state = usBorderState & (~OBSTYLE_RESERVED); if (hdc != NULL) Draw(hdc,hwnd); return _state; } //+--------------------------------------------------------------- // // Member: OLEBorder::Erase // //--------------------------------------------------------------- void OLEBorder::Erase(HWND hwnd) { RECT r; if (hwnd != NULL && !_fErased) { _fErased = TRUE; if(_state & OBSTYLE_DIAGONAL_FILL) { GetBorderRect(r,BP_INSIDE); InvalidateRect(hwnd,&r,TRUE); } else { for(int i = BP_TOP; i <= BP_LEFT; i++) { GetBorderRect(r,i); InvalidateRect(hwnd,&r,TRUE); } } } _state = _state & OBSTYLE_INSIDE; } void OLEBorder::GetInsideBorder( RECT& rDest, int iEdge ) { int sHalf = _sThickness >> 1; int sMid; switch(iEdge) { case BP_TOP: case BP_BOTTOM: rDest.left = rect.left; rDest.right = rect.right; if (iEdge == BP_TOP) { rDest.top = rect.top; rDest.bottom = rect.top + _sThickness; } else { rDest.top = rect.bottom - _sThickness; rDest.bottom = rect.bottom; } break; case BP_RIGHT: case BP_LEFT: rDest.top = rect.top; rDest.bottom = rect.bottom; if (iEdge == BP_RIGHT) { rDest.left = rect.right - _sThickness; rDest.right = rect.right; } else { rDest.left = rect.left; rDest.right = rect.left + _sThickness; } break; case BP_TOPRIGHT: case BP_BOTTOMRIGHT: rDest.left = rect.right - _sThickness; rDest.right = rect.right; if (iEdge == BP_TOPRIGHT) { rDest.top = rect.top; rDest.bottom = rect.top + _sThickness; } else { rDest.top = rect.bottom - _sThickness; rDest.bottom = rect.bottom; } break; case BP_BOTTOMLEFT: case BP_TOPLEFT: rDest.left = rect.left; rDest.right = rect.left + _sThickness; if (iEdge == BP_BOTTOMLEFT) { rDest.top = rect.bottom - _sThickness; rDest.bottom = rect.bottom; } else { rDest.top = rect.top; rDest.bottom = rect.top + _sThickness; } break; case BP_TOPHAND: case BP_BOTTOMHAND: sMid = rect.left + ((rect.right - rect.left) >> 1); rDest.left = sMid - sHalf; rDest.right = sMid + sHalf; if (iEdge == BP_TOPHAND) { rDest.top = rect.top; rDest.bottom = rect.top + _sThickness; } else { rDest.top = rect.bottom - _sThickness; rDest.bottom = rect.bottom; } break; case BP_RIGHTHAND: case BP_LEFTHAND: sMid = rect.top + ((rect.bottom - rect.top) >> 1); rDest.top = sMid - sHalf; rDest.bottom = sMid + sHalf; if (iEdge == BP_LEFTHAND) { rDest.left = rect.left; rDest.right = rect.left + _sThickness; } else { rDest.left = rect.right - _sThickness; rDest.right = rect.right; } break; case BP_INSIDE: default: rDest = rect; break; } } void OLEBorder::GetOutsideBorder( RECT& rDest, int iEdge ) { int sHalf = _sThickness >> 1; int sMid; switch(iEdge) { case BP_TOP: case BP_BOTTOM: rDest.left = rect.left - _sThickness; rDest.right = rect.right + _sThickness; if (iEdge == BP_TOP) { rDest.top = rect.top - _sThickness; rDest.bottom = rect.top + 1; } else { rDest.top = rect.bottom; rDest.bottom = rect.bottom + _sThickness; } break; case BP_RIGHT: case BP_LEFT: rDest.top = rect.top - _sThickness; rDest.bottom = rect.bottom + _sThickness; if (iEdge == BP_RIGHT) { rDest.left = rect.right; rDest.right = rect.right + _sThickness; } else { rDest.left = rect.left - _sThickness; rDest.right = rect.left + 1; } break; case BP_TOPRIGHT: case BP_BOTTOMRIGHT: rDest.left = rect.right; rDest.right = rect.right + _sThickness; if (iEdge == BP_TOPRIGHT) { rDest.top = rect.top - _sThickness; rDest.bottom = rect.top + 1; } else { rDest.top = rect.bottom; rDest.bottom = rect.bottom + _sThickness; } break; case BP_BOTTOMLEFT: case BP_TOPLEFT: rDest.left = rect.left - _sThickness; rDest.right = rect.left + 1; if (iEdge == BP_BOTTOMLEFT) { rDest.top = rect.bottom; rDest.bottom = rect.bottom + _sThickness; } else { rDest.top = rect.top - _sThickness; rDest.bottom = rect.top + 1; } break; case BP_TOPHAND: case BP_BOTTOMHAND: sMid = rect.left + ((rect.right - rect.left) >> 1); rDest.left = sMid - sHalf; rDest.right = sMid + sHalf; if (iEdge == BP_TOPHAND) { rDest.top = rect.top - _sThickness; rDest.bottom = rect.top + 1; } else { rDest.top = rect.bottom; rDest.bottom = rect.bottom + _sThickness; } break; case BP_RIGHTHAND: case BP_LEFTHAND: sMid = rect.top + ((rect.bottom - rect.top) >> 1); rDest.top = sMid - sHalf; rDest.bottom = sMid + sHalf; if (iEdge == BP_LEFTHAND) { rDest.left = rect.left - _sThickness; rDest.right = rect.left + 1; } else { rDest.left = rect.right; rDest.right = rect.right + _sThickness; } break; case BP_INSIDE: default: //inactive border rDest.left = rect.left - 1; rDest.right = rect.right + 1; rDest.top = rect.top - 1; rDest.bottom = rect.bottom + 1; break; } } //+--------------------------------------------------------------- // // Member: OLEBorder::GetBorderRect // //--------------------------------------------------------------- void OLEBorder::GetBorderRect( RECT& rDest, int iEdge ) { if(_state & OBSTYLE_INSIDE) GetInsideBorder(rDest,iEdge); else GetOutsideBorder(rDest,iEdge); } //+--------------------------------------------------------------- // // Member: OLEBorder::SwitchCoords // //--------------------------------------------------------------- void OLEBorder::SwitchCoords( HWND hwndFrom, HWND hwndTo ) { MapWindowPoints(hwndFrom, hwndTo, (LPPOINT)&rect, 2); MapWindowPoints(hwndFrom, hwndTo, &_pt, 1); } //+--------------------------------------------------------------- // // Member: OLEBorder::Draw // //--------------------------------------------------------------- void OLEBorder::Draw( HDC hdc, HWND hwnd ) { if(hdc == NULL || (_state & ~OBSTYLE_INSIDE) == 0) { return; //nothing to do! } RECT r; // // the following should be rewritten so any border style // can be drawn in XOR mode... // if (_state & OBSTYLE_XOR) { if (_state & OBSTYLE_THICK) { PatBlt(hdc, rect.left - 1, rect.top - 1, rect.right - rect.left + 2, 3, PATINVERT); PatBlt(hdc, rect.left - 1, rect.bottom - 2, rect.right - rect.left + 2, 3, PATINVERT); PatBlt(hdc, rect.left - 1, rect.top + 2, 3, rect.bottom - rect.top - 4, PATINVERT); PatBlt(hdc, rect.right - 2, rect.top + 2, 3, rect.bottom - rect.top - 4, PATINVERT); } else DrawFocusRect(hdc,&rect); return; } HBRUSH hbrBlack = (HBRUSH)GetStockObject(BLACK_BRUSH); HBRUSH hbr; COLORREF clrref; int i; if (_state & OBSTYLE_RESERVED) { Erase(hwnd); return; } if (_state & OBSTYLE_ACTIVE) { clrref = GetSysColor(COLOR_ACTIVECAPTION); } else { clrref = GetSysColor(COLOR_WINDOWFRAME); } if ((_state & OBSTYLE_TYPEMASK) == OBSTYLE_DIAGONAL_FILL) { hbr = CreateHatchBrush(HS_DIAGCROSS,clrref); GetBorderRect(r,BP_INSIDE); FillRect(hdc,&r,hbr); DeleteObject(hbr); } else if ((_state & OBSTYLE_TYPEMASK) == OBSTYLE_SOLID_PEN) { GetBorderRect(r,BP_INSIDE); FrameRect(hdc,&r,hbrBlack); } if (_state & OBSTYLE_THICK) { if (_state & OBSTYLE_INSIDE) InflateRect(&r,-1,-1); else InflateRect(&r,1,1); FrameRect(hdc,&rect,hbrBlack); } if (_state & OBSTYLE_HANDLED) { for (i = BP_TOPRIGHT; i <= BP_TOPLEFT; i++) { GetBorderRect(r,i); FillRect(hdc,&r,hbrBlack); } for (i = BP_TOPHAND; i <= BP_LEFTHAND; i++) { GetBorderRect(r,i); FillRect(hdc,&r,hbrBlack); } } _fErased = FALSE; } //+--------------------------------------------------------------- // // Member: OLEBorder::QueryHit // //--------------------------------------------------------------- USHORT OLEBorder::QueryHit( POINT point ) { RECT r = rect; USHORT usWhere = BP_NOWHERE; if ((_state & OBSTYLE_INSIDE) == 0) InflateRect(&r,_sThickness,_sThickness); if (PtInRect(&r,point)) { usWhere = BP_INSIDE; // //test against the real inside to optimize this case... // InflateRect(&r,-_sThickness,-_sThickness); // // PtInRect counts the top and left borders as being inside, so // we must account for this. // r.left++; r.top++; if (!PtInRect(&r,point)) { // //Search for the "handle" that was hit... // USHORT i; for (i = BP_LEFTHAND; i >= BP_TOP; i--) { GetBorderRect(r,i); if (PtInRect(&r,point)) { usWhere = i; break; } } } } return(usWhere); } //+--------------------------------------------------------------- // // Member: OLEBorder::QueryMoveCursor // //--------------------------------------------------------------- HCURSOR OLEBorder::QueryMoveCursor( POINT ptCurrent, BOOL fMustMove ) { // //Stash part-hit info so we can do the right thing durring //upcomming move/size operation // if (fMustMove) { _usPart = BP_INSIDE; } else { _usPart = QueryHit(ptCurrent); } return MapPartToCursor(_usPart); } //+--------------------------------------------------------------- // // Member: OLEBorder::BeginMove // //--------------------------------------------------------------- HCURSOR OLEBorder::BeginMove( HDC hdc, HWND hwnd, POINT ptStart, BOOL fMustMove ) { if(_state == 0 ) _state = OBSTYLE_SOLID_PEN; SetState( hdc, hwnd, _state | OBSTYLE_XOR | OBSTYLE_THICK); _pt = ptStart; return QueryMoveCursor(ptStart,fMustMove); } //+--------------------------------------------------------------- // // Member: OLEBorder::UpdateMove // //--------------------------------------------------------------- RECT& OLEBorder::UpdateMove( HDC hdc, HWND hwnd, POINT ptCurrent, BOOL fNewRegion ) { if ((ptCurrent.x == _pt.x) && (ptCurrent.y == _pt.y)) return rect; RECT rTemp = rect; Draw(hdc,hwnd); if (fNewRegion) { rTemp.left = min(_pt.x,ptCurrent.x); rTemp.top = min(_pt.y,ptCurrent.y); rTemp.right = max(_pt.x,ptCurrent.x); rTemp.bottom = max(_pt.y,ptCurrent.y); } else { int xDelta = ptCurrent.x - _pt.x; int yDelta = ptCurrent.y - _pt.y; switch (_usPart) { case BP_INSIDE: case BP_TOP: case BP_BOTTOM: case BP_RIGHT: case BP_LEFT: default: OffsetRect(&rTemp,xDelta,yDelta); break; case BP_TOPRIGHT: rTemp.right += xDelta; rTemp.top += yDelta; break; case BP_BOTTOMRIGHT: rTemp.right += xDelta; rTemp.bottom += yDelta; break; case BP_BOTTOMLEFT: rTemp.bottom += yDelta; rTemp.left += xDelta; break; case BP_TOPLEFT: rTemp.top += yDelta; rTemp.left += xDelta; break; case BP_TOPHAND: rTemp.top += yDelta; break; case BP_BOTTOMHAND: rTemp.bottom += yDelta; break; case BP_RIGHTHAND: rTemp.right += xDelta; break; case BP_LEFTHAND: rTemp.left += xDelta; break; } } // //clip resize to repect minimum height & width specification // if((rTemp.right - rTemp.left >= _sMinWidth) && (rTemp.bottom - rTemp.top >= _sMinHeight)) { rect = rTemp; if (!fNewRegion) { _pt = ptCurrent; } } Draw(hdc,hwnd); return rect; } //+--------------------------------------------------------------- // // Member: OLEBorder::EndMove // //--------------------------------------------------------------- RECT& OLEBorder::EndMove( HDC hdc, HWND hwnd, POINT ptCurrent, USHORT usBorderState ) { SetState( hdc, hwnd, usBorderState ); return rect; }