LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int idx; hdc=BeginPaint(hWnd, &ps); for (idx=0;idx<arNum;idx++) { switch (arObj[idx]->Type) { case DT_LINE: if ((arObj[idx]->Flag & 0x3) == DS_LT || (arObj[idx]->Flag & 0x3) == DS_RB) { MoveToEx(hdc,arObj[idx]->rt.left,arObj[idx]->rt.top,NULL); LineTo(hdc,arObj[idx]->rt.right,arObj[idx]->rt.bottom); } else { MoveToEx(hdc,arObj[idx]->rt.left,arObj[idx]->rt.bottom,NULL); LineTo(hdc,arObj[idx]->rt.right,arObj[idx]->rt.top); } break; case DT_ELLIPSE: Ellipse(hdc,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; case DT_RECTANGLE: Rectangle(hdc,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; } } if (NowSel != -1) { DrawTracker(hdc,NowSel); } EndPaint(hWnd, &ps); return 0; }
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int idx; HPEN hPen,hOldPen; HBRUSH hBrush,hOldBrush; RECT crt; HDC hMemDC; HBITMAP hOldBitmap; int x,y; BITMAPFILEHEADER *fh; BITMAPINFOHEADER *ih; int bx,by; BYTE *pRaster; HFONT hFont,hOldFont; int FontHeight; int FontIdx; LOGFONT tFont; hdc=BeginPaint(hWnd, &ps); hMemDC=CreateCompatibleDC(hdc); GetClientRect(hWnd,&crt); if (hBackBit == NULL) { hBackBit=CreateCompatibleBitmap(hdc,crt.right,crt.bottom); } hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBackBit); FillRect(hMemDC,&crt,GetSysColorBrush(COLOR_WINDOW)); if (bGridLine) { hPen=CreatePen(PS_SOLID,1,RGB(192,192,192)); hOldPen=(HPEN)SelectObject(hMemDC,hPen); for (y=0; y<crt.bottom; y=y+GridLineY*GridY) { MoveToEx(hMemDC,0,y,NULL); LineTo(hMemDC,crt.right,y); } for (x=0; x<crt.right; x=x+GridLineX*GridX) { MoveToEx(hMemDC,x,0,NULL); LineTo(hMemDC,x,crt.bottom); } DeleteObject(SelectObject(hMemDC,hOldPen)); } SetStretchBltMode(hMemDC,StretchMode); SetBkMode(hMemDC,TRANSPARENT); for (idx=0; idx<arNum; idx++) { if (arObj[idx]->LineColor == (COLORREF)-1) { hPen=(HPEN)GetStockObject(NULL_PEN); } else { hPen=CreatePen(PS_INSIDEFRAME,arObj[idx]->LineWidth,arObj[idx]->LineColor); } hOldPen=(HPEN)SelectObject(hMemDC,hPen); if (arObj[idx]->PlaneColor == (COLORREF)-1) { hBrush=(HBRUSH)GetStockObject(NULL_BRUSH); } else { hBrush=CreateSolidBrush(arObj[idx]->PlaneColor); } hOldBrush=(HBRUSH)SelectObject(hMemDC,hBrush); switch (arObj[idx]->Type) { case DT_LINE: if ((arObj[idx]->Flag & 0x3) == DS_LT || (arObj[idx]->Flag & 0x3) == DS_RB) { MoveToEx(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top,NULL); LineTo(hMemDC,arObj[idx]->rt.right,arObj[idx]->rt.bottom); } else { MoveToEx(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.bottom,NULL); LineTo(hMemDC,arObj[idx]->rt.right,arObj[idx]->rt.top); } break; case DT_ELLIPSE: Ellipse(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; case DT_RECTANGLE: Rectangle(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; case DT_BITMAP: fh=(BITMAPFILEHEADER *)arObj[idx]->Bitmap; pRaster=(PBYTE)fh+fh->bfOffBits; ih=(BITMAPINFOHEADER *)((PBYTE)fh+sizeof(BITMAPFILEHEADER)); bx=ih->biWidth; by=ih->biHeight; StretchDIBits(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right-arObj[idx]->rt.left, arObj[idx]->rt.bottom-arObj[idx]->rt.top,0,0,bx,by, pRaster,(BITMAPINFO *)ih,DIB_RGB_COLORS,SRCCOPY); break; case DT_META: PlayPlaceableMeta(hMemDC,arObj[idx]->Meta,arObj[idx]->Len,&arObj[idx]->rt); break; case DT_TEXT: FillRect(hMemDC,&arObj[idx]->rt,hBrush); FontHeight=arObj[idx]->FontSize*GetDeviceCaps(hMemDC,LOGPIXELSY)/72; FontIdx=FindFontFromFace(arObj[idx]->FontFace); if (FontIdx!=-1) { tFont=logfont[FontIdx]; tFont.lfHeight=FontHeight; tFont.lfWidth=0; hFont=CreateFontIndirect(&tFont); hOldFont=(HFONT)SelectObject(hMemDC,hFont); } if (arObj[idx]->FontColor != (COLORREF)-1) { SetTextColor(hMemDC,arObj[idx]->FontColor); DrawText(hMemDC,arObj[idx]->Text,-1,&arObj[idx]->rt,DT_WORDBREAK); } if (FontIdx!=-1) { DeleteObject(SelectObject(hMemDC,hOldFont)); } break; } SelectObject(hMemDC,hOldPen); SelectObject(hMemDC,hOldBrush); if (arObj[idx]->LineColor != (COLORREF)-1) { DeleteObject(hPen); } if (arObj[idx]->PlaneColor != (COLORREF)-1) { DeleteObject(hBrush); } } if (NowSel != -1) { DrawTracker(hMemDC,NowSel); } BitBlt(hdc,0,0,crt.right,crt.bottom,hMemDC,0,0,SRCCOPY); SelectObject(hMemDC,hOldBitmap); DeleteDC(hMemDC); EndPaint(hWnd, &ps); return 0; }
BOOL CPolylineCreatorTracker::CreatePolyline(CWnd* pWnd, CDPoint point, CSnapper* pSnapper) { // don't handle if capture already set if (::GetCapture() != NULL) return FALSE; AfxLockTempMaps(); // protect maps while looping m_bErase = FALSE; m_bFinalErase = FALSE; // set capture to the window which received this message pWnd->SetCapture(); ASSERT(pWnd == CWnd::GetCapture()); pWnd->UpdateWindow(); m_Points.AddTail(new CDPOINT(point)); CPoint LastPoint(point); // get DC for drawing CDC* pDrawDC; // otherwise, just use normal DC pDrawDC = pWnd->GetDC(); ASSERT_VALID(pDrawDC); BOOL bMoved = FALSE; // get messages until capture lost or cancelled/accepted for (;;) { MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if (CWnd::GetCapture() != pWnd) break; if(msg.message == WM_MOUSEMOVE) DispatchMessage(&msg); switch (msg.message) { // handle movement/accept messages case WM_MOUSEMOVE: { // handle resize cases (and part of move) CPoint point; ::GetCursorPos(&point); pWnd->ScreenToClient(&point); if((::GetKeyState(VK_SHIFT) & 0x8000)!=0) { CDPoint *pLastPoint = (CDPoint*)m_Points.GetTail(); if(pLastPoint!=NULL) { CDPOINT ppp = CDPoint(point)-(*pLastPoint); if(ABS(ppp.x)>ABS(ppp.y)) ppp.y=0; else ppp.x=0; point = *pLastPoint+ppp; } } if(pSnapper!=NULL) pSnapper->FixSnapTo(&point); if (LastPoint != point) { m_bErase = FALSE; DrawTracker(point, pDrawDC, pWnd); bMoved = TRUE; } LastPoint = point; } break; case WM_LBUTTONDOWN: { // handle resize cases (and part of move) CPoint point; ::GetCursorPos(&point); pWnd->ScreenToClient(&point); CDPoint dpoint(point); if((::GetKeyState(VK_SHIFT) & 0x8000)!=0) { CDPoint *pLastPoint = (CDPoint*)m_Points.GetTail(); if(pLastPoint!=NULL) { CDPOINT ppp = dpoint-(*pLastPoint); if(ABS(ppp.x)>ABS(ppp.y)) ppp.y=0; else ppp.x=0; dpoint = *pLastPoint+ppp; } } if(pSnapper!=NULL) pSnapper->FixSnapTo(&dpoint); point = dpoint; if (LastPoint != dpoint) { m_bErase = FALSE; DrawTracker(point, pDrawDC, pWnd); } m_Points.AddTail(new CDPoint(dpoint)); //the tracker will not erease the last line if(m_PointsLast!=NULL) delete []m_PointsLast; bMoved = FALSE; m_PointsLast = NULL; LastPoint = point; } break; // handle cancel messages case WM_KEYDOWN: if (msg.wParam != VK_ESCAPE) break; case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: { if (bMoved) { m_bErase = m_bFinalErase = TRUE; DrawTracker(point, pDrawDC, pWnd); } UINT uiCount = GetPointsCount(); if(uiCount>1)//erace all the line { LPPOINT lpPoints = new POINT[uiCount]; LPCDPOINT lpDPoints = new CDPOINT[uiCount]; GetPoints(lpDPoints); for(UINT ui=0; ui<uiCount; ui++) lpPoints[ui] = lpDPoints[ui]; CLineTracker::DrawDragPolyLine(pDrawDC, lpPoints, 1, NULL, 1, uiCount); delete []lpPoints; delete []lpDPoints; } } goto ExitLoop; // just dispatch rest of the messages default: DispatchMessage(&msg); break; } } ExitLoop: pWnd->ReleaseDC(pDrawDC); ReleaseCapture(); AfxUnlockTempMaps(FALSE); // restore rect in case bMoved is still FALSE m_bFinalErase = FALSE; m_bErase = FALSE; // return TRUE only if rect has changed return GetPointsCount()>1; }
BOOL CPicTracker::Track(CWnd* pWnd, CPoint point, BOOL bRotate, CSnapper* pSnapper, CWnd* pWndClipTo) { BOOL bResizeOrMove = HitTest(point)==hitOnPoint ? TRUE : FALSE; // don't handle if capture already set if (::GetCapture() != NULL) return FALSE; m_rectOrigianl = m_rect; AfxLockTempMaps(); // protect maps while looping ASSERT(!m_bFinalErase); // set capture to the window which received this message pWnd->SetCapture(); ASSERT(pWnd == CWnd::GetCapture()); pWnd->UpdateWindow(); if (pWndClipTo != NULL) pWndClipTo->UpdateWindow(); CPoint LastPoint(point); // get DC for drawing CDC* pDrawDC; if (pWndClipTo != NULL) { // clip to arbitrary window by using adjusted Window DC pDrawDC = pWndClipTo->GetDCEx(NULL, DCX_CACHE); } else { // otherwise, just use normal DC pDrawDC = pWnd->GetDC(); } ASSERT_VALID(pDrawDC); CDRectangle rectOld; BOOL bMoved = FALSE; // get messages until capture lost or cancelled/accepted for (;;) { MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if (CWnd::GetCapture() != pWnd) break; if(msg.message == WM_MOUSEMOVE) DispatchMessage(&msg); switch (msg.message) { // handle movement/accept messages case WM_LBUTTONUP: case WM_MOUSEMOVE: OnCheange: { rectOld = m_rect; m_rect = m_rectOrigianl; // handle resize cases (and part of move) CPoint p; ::GetCursorPos(&p); pWnd->ScreenToClient(&p); p -= LastPoint; //LastPoint = point; // handle move case if(bRotate) { LPDPOINT lpPoints = m_rect.GetPoints(); CPoint pp = p+LastPoint; double dAngle = GetPointAng(&pp, &LastPoint); double dist = sqrt((double)(p.x*p.x + p.y*p.y)); if(dist<30) { dAngle /= 30; dAngle *= dist; } if(::GetKeyState(VK_SHIFT) & 0x8000) //if the shift is pressed then snap to the close 45 degrees { dAngle = ((int)((dAngle/(RAD90D/2))+0.499))*(RAD90D/2); } RotatePoints((LPCDPOINT)lpPoints, m_rect.GetNumOfPoints(), dAngle, NULL); } else if (!bResizeOrMove) { if((::GetKeyState(VK_SHIFT) & 0x8000)!=0) { if(ABS(p.x)>ABS(p.y)) p.y=0; else p.x=0; } LPDPOINT lpPoints = m_rect.GetPoints(); for(int i=0; i<m_rect.GetNumOfPoints();i++) { lpPoints[i].x += p.x; lpPoints[i].y += p.y; } if(pSnapper!=NULL) pSnapper->FixSnapTo((LPCDPOINT)lpPoints,m_rect.GetNumOfPoints()); } else { double dAngle1 = m_rect.GetAngle1(); double dAngle2 = m_rect.GetAngle2()-RAD90D; CDPoint center(0,0); CDPoint dp(p); RotatePoints(&dp, 1, -dAngle1, ¢er); if(CheckRetainProportions() && (m_dWidthDivHeight!=0)) //if the shift is pressed then remain proporions { dp.y=dp.x/m_dWidthDivHeight; } LPDPOINT lpPoints = m_rect.GetPoints(); center = GetPointsCenter((LPCDPOINT)lpPoints, m_rect.GetNumOfPoints()); RotatePoints((LPCDPOINT)lpPoints, m_rect.GetNumOfPoints(), -dAngle1, ¢er); int i; for(i=0; i<m_rect.GetNumOfPoints(); i++) { CDPoint ppp = lpPoints[i]; ppp-=center; if(ppp.x>0) ppp.x += dp.x; else ppp.x -= dp.x; ppp+=center; lpPoints[i] = ppp; } RotatePoints((LPCDPOINT)lpPoints, m_rect.GetNumOfPoints(), dAngle1-dAngle2, ¢er); for(i=0; i<m_rect.GetNumOfPoints(); i++) { CDPoint ppp = lpPoints[i]; ppp-=center; if(ppp.y>0) ppp.y += dp.y; else ppp.y -= dp.y; ppp+=center; lpPoints[i] = ppp; } RotatePoints((LPCDPOINT)lpPoints, m_rect.GetNumOfPoints(), dAngle2, ¢er); if(pSnapper!=NULL) pSnapper->FixSnapTo((LPCDPOINT)lpPoints,m_rect.GetNumOfPoints()); } // only redraw and callback if the rect actually changed! m_bFinalErase = (msg.message == WM_LBUTTONUP); if (!rectOld.IsEqual(m_rect) || m_bFinalErase) { if (bMoved) { m_bErase = TRUE; DrawTracker(&rectOld, pWndClipTo, pDrawDC, pWnd); } if (msg.message != WM_LBUTTONUP) bMoved = TRUE; } if (m_bFinalErase) goto ExitLoop; if (!rectOld.IsEqual(m_rect)) { m_bErase = FALSE; DrawTracker(&m_rect, pWndClipTo, pDrawDC, pWnd); } } break; case WM_KEYUP: if (msg.wParam == VK_SHIFT) goto OnCheange; break; // handle cancel messages case WM_KEYDOWN: if (msg.wParam == VK_SHIFT) goto OnCheange; if (msg.wParam != VK_ESCAPE) break; case WM_RBUTTONDOWN: if (bMoved) { m_bErase = m_bFinalErase = TRUE; DrawTracker(&m_rect, pWndClipTo, pDrawDC, pWnd); } m_rect = m_rectOrigianl; goto ExitLoop; // just dispatch rest of the messages default: DispatchMessage(&msg); break; } } ExitLoop: if (pWndClipTo != NULL) pWndClipTo->ReleaseDC(pDrawDC); else pWnd->ReleaseDC(pDrawDC); ReleaseCapture(); AfxUnlockTempMaps(FALSE); // restore rect in case bMoved is still FALSE if (!bMoved) m_rect = m_rectOrigianl; m_bFinalErase = FALSE; m_bErase = FALSE; // return TRUE only if rect has changed return !m_rectOrigianl.IsEqual(m_rect); }
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int idx; HPEN hPen,hOldPen; HBRUSH hBrush,hOldBrush; RECT crt; HDC hMemDC; HBITMAP hOldBitmap; int x,y; hdc=BeginPaint(hWnd, &ps); hMemDC=CreateCompatibleDC(hdc); GetClientRect(hWnd,&crt); if (hBackBit == NULL) { hBackBit=CreateCompatibleBitmap(hdc,crt.right,crt.bottom); } hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBackBit); FillRect(hMemDC,&crt,GetSysColorBrush(COLOR_WINDOW)); if (bGridLine) { hPen=CreatePen(PS_SOLID,1,RGB(192,192,192)); hOldPen=(HPEN)SelectObject(hMemDC,hPen); for (y=0;y<crt.bottom;y=y+GridLineY*GridY) { MoveToEx(hMemDC,0,y,NULL); LineTo(hMemDC,crt.right,y); } for (x=0;x<crt.right;x=x+GridLineX*GridX) { MoveToEx(hMemDC,x,0,NULL); LineTo(hMemDC,x,crt.bottom); } DeleteObject(SelectObject(hMemDC,hOldPen)); } for (idx=0;idx<arNum;idx++) { if (arObj[idx]->LineColor == (COLORREF)-1) { hPen=(HPEN)GetStockObject(NULL_PEN); } else { hPen=CreatePen(PS_INSIDEFRAME,arObj[idx]->LineWidth,arObj[idx]->LineColor); } hOldPen=(HPEN)SelectObject(hMemDC,hPen); if (arObj[idx]->PlaneColor == (COLORREF)-1) { hBrush=(HBRUSH)GetStockObject(NULL_BRUSH); } else { hBrush=CreateSolidBrush(arObj[idx]->PlaneColor); } hOldBrush=(HBRUSH)SelectObject(hMemDC,hBrush); switch (arObj[idx]->Type) { case DT_LINE: if ((arObj[idx]->Flag & 0x3) == DS_LT || (arObj[idx]->Flag & 0x3) == DS_RB) { MoveToEx(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top,NULL); LineTo(hMemDC,arObj[idx]->rt.right,arObj[idx]->rt.bottom); } else { MoveToEx(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.bottom,NULL); LineTo(hMemDC,arObj[idx]->rt.right,arObj[idx]->rt.top); } break; case DT_ELLIPSE: Ellipse(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; case DT_RECTANGLE: Rectangle(hMemDC,arObj[idx]->rt.left,arObj[idx]->rt.top, arObj[idx]->rt.right,arObj[idx]->rt.bottom); break; } SelectObject(hMemDC,hOldPen); SelectObject(hMemDC,hOldBrush); if (arObj[idx]->LineColor != (COLORREF)-1) { DeleteObject(hPen); } if (arObj[idx]->PlaneColor != (COLORREF)-1) { DeleteObject(hBrush); } } if (NowSel != -1) { DrawTracker(hMemDC,NowSel); } BitBlt(hdc,0,0,crt.right,crt.bottom,hMemDC,0,0,SRCCOPY); SelectObject(hMemDC,hOldBitmap); DeleteDC(hMemDC); EndPaint(hWnd, &ps); return 0; }