#include #include #include #include char GridMesh::szClassName[]="MESH93B"; char GridMesh::szMenuName[]={'\0'}; GridMesh::GridMesh(HWND hParent,int width,int height,GridShow visibility) : mhParent(hParent), mStatus(InActive), mGridLines(GridLines), mStandardColor(RGB(0,0,0)), mIsSuspended(FALSE), mhInstance(Main::processInstance()) { mVersionInfo=szClassName; mhDrawingPen=::CreatePen(PS_SOLID,1,mStandardColor); registerClass(); ::CreateWindowEx(WS_EX_TRANSPARENT,(LPSTR)szClassName,0, WS_CHILD|WS_CLIPSIBLINGS, CW_USEDEFAULT,CW_USEDEFAULT, width,height, mhParent,0x00,mhInstance,(LPSTR)(Window*)this); if(GridMesh::Show==visibility) { Window::Show(SW_SHOW); Update(); ::InvalidateRect(GetHandle(),0,TRUE); } } GridMesh::~GridMesh() { ::DeleteObject(mhDrawingPen); if(::IsWindow(GetHandle()))::DestroyWindow(GetHandle()); } void GridMesh::registerClass(void) { WNDCLASS wndClass; if(::GetClassInfo(mhInstance,szClassName,(WNDCLASS FAR *)&wndClass))return; wndClass.style =CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; wndClass.lpfnWndProc =(WNDPROC)::WndProc; wndClass.cbClsExtra =0; wndClass.cbWndExtra =sizeof(GridMesh*); wndClass.hInstance =mhInstance; wndClass.hIcon =0; wndClass.hCursor =::LoadCursor(NULL,IDC_ARROW); wndClass.hbrBackground =(HBRUSH)::GetStockObject(NULL_BRUSH);; wndClass.lpszMenuName =szMenuName; wndClass.lpszClassName =szClassName; ::RegisterClass(&wndClass); } long GridMesh::WndProc(UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_CREATE : ::SendMessage(GetHandle(),WM_NCACTIVATE,TRUE,0L); newMesh(); return FALSE; case WM_PAINT : paint(); return FALSE; case WM_LBUTTONUP : mouseUp(LOWORD(lParam),HIWORD(lParam)); return FALSE; case WM_LBUTTONDOWN : mouseDown(LOWORD(lParam),HIWORD(lParam)); return FALSE; case WM_MOUSEMOVE : mouseMove(LOWORD(lParam),HIWORD(lParam)); return FALSE; case WM_DESTROY : return FALSE; } return ::DefWindowProc(GetHandle(),message,wParam,lParam); } void GridMesh::showWindow(int visible) { Window::Show(visible?SW_SHOW:SW_HIDE); ::InvalidateRect(GetHandle(),0,TRUE); } void GridMesh::newMesh(WORD gridLines) { createMesh(gridLines,(Vector&)*this); ::InvalidateRect(mhParent,0,TRUE); ::InvalidateRect(GetHandle(),0,TRUE); } void GridMesh::createMesh(WORD gridLines,Vector &someSegmentVector) { RECT clientRect; WORD xLength; WORD yLength; Point tempFirstPoint; Point tempSecondPoint; WORD vectorSize(0); Index vectorIndex(0); if(gridLines>MaxGridLines)mGridLines=GridLines; else mGridLines=gridLines; ::GetClientRect(GetHandle(),(RECT FAR *)&clientRect); xLength=clientRect.right/(mGridLines+1); yLength=clientRect.bottom/(mGridLines+1); for(int x=0,xCount=0;xCount<=mGridLines;x+=xLength,xCount++) for(int y=0,yCount=0;yCount<=mGridLines;y+=yLength,yCount++)vectorSize+=2; someSegmentVector.size(vectorSize); for(x=0,xCount=0;xCount<=mGridLines;x+=xLength,xCount++) { for(int y=0,yCount=0;yCount<=mGridLines;y+=yLength,yCount++) { tempFirstPoint.setPoint(x+xLength,y+yLength); tempSecondPoint.setPoint(x+xLength,y); someSegmentVector[vectorIndex]=Segment(tempFirstPoint,tempSecondPoint,(WORD)vectorIndex); vectorIndex++; tempSecondPoint.setPoint(x,y+yLength); someSegmentVector[vectorIndex]=Segment(tempFirstPoint,tempSecondPoint,(WORD)vectorIndex); vectorIndex++; } } } void GridMesh::paint(void)const { PAINTSTRUCT ps; HDC hDC; size_t size((int)Vector::size()); hDC=::BeginPaint(GetHandle(),(PAINTSTRUCT FAR*)&ps); for(int i=0;i::operator[](i)).drawSegment(hDC,mhDrawingPen); ::EndPaint(GetHandle(),(PAINTSTRUCT FAR *)&ps); } void GridMesh::mouseDown(int x,int y) { HDC hDC; Point mousePoint; size_t size; if(mIsSuspended)return; mCurrentIntersection.remove(); mousePoint.setPoint(x,y); if(!closestIntersection(mCurrentIntersection,mousePoint)) { mStatus=InActive; ::MessageBeep(-1); return; } mStatus=Active; hDC=::GetDC(GetHandle()); size=(int)mCurrentIntersection.size(); for(int i=0;i::operator[](mCurrentIntersection[index].vectorIndex())=mCurrentIntersection[index]; size=(int)Vector::size(); for(int i=0;i::operator[](i)).drawSegment(hDC,mhDrawingPen); ::ReleaseDC(GetHandle(),hDC); ::InvalidateRect(GetHandle(),0,TRUE); ::UpdateWindow(GetHandle()); } WORD GridMesh::closestIntersection(Block &filterBlock,Point &mousePoint) { DWORD tempDistance; DWORD leastDistance; Segment tempSegment; Segment minSegment; size_t size((int)Vector::size()); if(!size)return FALSE; filterBlock.remove(); while(IntersectionSegments!=filterBlock.size()) { for(int index=0;index::operator[](index); while(isInBlock(filterBlock,tempSegment)) tempSegment=Vector::operator[](++index); leastDistance=minDistance(tempSegment,mousePoint); } else { tempDistance=minDistance(Vector::operator[](index),mousePoint); if(tempDistance::operator[](index); if(!isInBlock(filterBlock,minSegment)) { tempSegment=minSegment; leastDistance=tempDistance; } } } } filterBlock.insert(&tempSegment); } return orderIntersection(filterBlock); } WORD GridMesh::orderIntersection(Block &intersection) { Point tempPoint; Point swapPoint; size_t size((int)intersection.size()); int firstSection(0); int secondSection(0); int index; if(IntersectionSegments!=size)return FALSE; tempPoint=intersection[0].firstPoint(); firstSection=(tempPoint==intersection[1].firstPoint()); if(!firstSection)firstSection=(tempPoint==intersection[1].secondPoint()); if(!firstSection) { tempPoint=intersection[0].secondPoint(); secondSection=tempPoint==intersection[1].firstPoint(); if(!secondSection)secondSection=tempPoint==intersection[1].secondPoint(); } if(!firstSection && !secondSection)return FALSE; for(index=1;index &source,Segment &someSegment) { size_t size((int)source.size()); for(int i=0;i::size()); if(!size)return FALSE; if(0==(fp=::fopen((LPSTR)pathFileName,"wb")))return FALSE; ::fwrite((void*)(LPSTR)mVersionInfo,::strlen(mVersionInfo),1,fp); ::fwrite((void*)&size,sizeof(size),1,fp); ::fwrite((void*)&mGridLines,sizeof(mGridLines),1,fp); for(int i=0;i::operator[](i).firstPoint(); ::fwrite((void *)&tempPoint,sizeof(Point),1,fp); tempPoint=Vector::operator[](i).secondPoint(); ::fwrite((void*)&tempPoint,sizeof(Point),1,fp); } ::fclose(fp); return TRUE; } WORD GridMesh::loadMesh(String &pathFileName) { FILE *fp; Point firstPoint; Point secondPoint; String versionString; int vectorIndex(0); size_t size; if(0==(fp=::fopen((LPSTR)pathFileName,"rb")))return upgradeStatus(FALSE); versionString.reserve(String::MaxString); ::fread((void*)(LPSTR)versionString,::strlen(mVersionInfo),1,fp); if(versionString!=mVersionInfo) { ::fclose(fp); return upgradeStatus(FALSE); } ::fread((void*)&size,sizeof(size),1,fp); ::fread((void*)&mGridLines,sizeof(mGridLines),1,fp); Vector::size(size); for(int i=0;i::operator[](vectorIndex)=Segment(firstPoint,secondPoint,vectorIndex); vectorIndex++; } ::fclose(fp); return upgradeStatus(TRUE); } WORD GridMesh::upgradeStatus(WORD retCode)const { if(!::IsWindowVisible(GetHandle()))Window::Show(SW_SHOW); ::InvalidateRect(mhParent,0,TRUE); ::InvalidateRect(GetHandle(),0,TRUE); return retCode; } WORD GridMesh::retrieveMesh(Vector &sourcePoints,Vector &destPoints) { Vector sourceSegments; createMesh(mGridLines,sourceSegments); retrieveMesh(sourcePoints,sourceSegments); retrieveMesh(destPoints,(Vector&)*this); if(sourcePoints.size()!=destPoints.size())return FALSE; return (WORD)sourcePoints.size(); } WORD GridMesh::retrieveMesh(Vector &meshPoints,Vector &someSegmentVector)const { Segment tempSegment; int vectorIndex; int pointIndex(0); size_t vectorSize((int)someSegmentVector.size()); int haveFirstColumn(FALSE); Vector dummyPoint; meshPoints.size(0); meshPoints.size((mGridLines+2)*(mGridLines+2)); for(vectorIndex=0;vectorIndex