// // lpRect This is the owner window client area // xShift shift on X axis from the client area rectangle // yShift shift on Y axis from the client area rectangle // // // Call by OnPaint as DrawChart(hMemDC, &rcClient, dx, dy); // void GDisplay::DrawChart( HDC hDC, LPRECT lpRect, INT xShift, INT yShift) { // At this point lpRect is owner window client rectangle MyFillRect(hDC, lpRect, m_clrBackDark); InflateRect(lpRect, -xShift, -yShift); // Uncomment the next line to see proper chart rectangle //BorderRect(hDC, lpRect, RGB(255,255,255)); DrawGrid(hDC, lpRect); // Form rectangle for painting SetRect(&m_rcChart, xShift + m_dxText, lpRect->top, m_nMarginRight, // These margings came from DrawGrid() m_nMarginBottom); // where they are calculated // How many items the current screen can show ? // Note: m_xMinStep forced to be set to DEFAULT_XSTEP ('4' pixels) m_nScreenBufferSize = (m_rcChart.right - m_rcChart.left)/m_xMinStep; if (m_nScreenBufferSize < MIN_SCREEN_BUFFER_SIZE) m_nScreenBufferSize = MIN_SCREEN_BUFFER_SIZE; if (m_nScreenBufferSize > MAX_SCREEN_BUFFER_SIZE) m_nScreenBufferSize = MAX_SCREEN_BUFFER_SIZE; POINT ptOld[MAX_CHART_COUNT]; // Start point POINT ptNew[MAX_CHART_COUNT]; // End point double new_value[MAX_CHART_COUNT]; double old_value[MAX_CHART_COUNT]; for (int i = 0; i < m_nScreenBufferSize; i++) { for (int k = 0; k < m_nChartCount; k++) { new_value[k] = m_dScreenBuffer[k][i+1]; old_value[k] = m_dScreenBuffer[k][i]; ptOld[k].x = m_xMinStep*i + m_rcChart.left; ptNew[k].x = m_xMinStep*(i+1)+ m_rcChart.left; // Convert actual value to screen units if (!dtoi(m_rcChart.bottom, m_rcChart.top, m_dblMin[k], m_dblMax[k], old_value[k], &(ptOld[k].y))) { ptOld[k].y = m_rcChart.bottom; } if (!dtoi(m_rcChart.bottom, m_rcChart.top, m_dblMin[k], m_dblMax[k], new_value[k], &(ptNew[k].y))) { ptNew[k].y = m_rcChart.bottom; } if (ptOld[k].y <= m_rcChart.top) ptOld[k].y = m_rcChart.top; if (ptOld[k].y >= m_rcChart.bottom) ptOld[k].y = m_rcChart.bottom; if (ptNew[k].y <= m_rcChart.top) ptNew[k].y = m_rcChart.top; if (ptNew[k].y >= m_rcChart.bottom) ptNew[k].y = m_rcChart.bottom; // we out of the right border if (ptNew[k].x >= m_rcChart.right) { ResetBuffer(INIT_BUFFER_VALUE); } DrawMarker(hDC, &ptOld[k], &ptNew[k], m_rcChart.right, m_clrMarker[k]); DrawUpdateLine(hDC, m_xUpdatePosition, &m_rcChart); DrawDescription(hDC, &m_rcChart); } // for (k < m_nChartCount) } // for (i < m_nScreenBufferSize) }
void CEditView::DrawBackImage(HDC hdc, RECT& rcPaint, HDC hdcBgImg) { #if 0 // テスト背景パターン static int testColorIndex = 0; testColorIndex = testColorIndex % 7; COLORREF cols[7] = {RGB(255,255,255), RGB(200,255,255),RGB(255,200,255),RGB(255,255,200), RGB(200,200,255),RGB(255,200,200),RGB(200,255,200), }; COLORREF colorOld = ::SetBkColor(hdc, cols[testColorIndex]); MyFillRect(hdc, rcPaint); ::SetBkColor(hdc, colorOld); testColorIndex++; #else CTypeSupport cTextType(this,COLORIDX_TEXT); COLORREF colorOld = ::SetBkColor(hdc, cTextType.GetBackColor()); const CTextArea& area = GetTextArea(); const CEditDoc& doc = *m_pcEditDoc; const STypeConfig& typeConfig = doc.m_cDocType.GetDocumentAttribute(); CMyRect rcImagePos; switch( typeConfig.m_backImgPos ){ case BGIMAGE_TOP_LEFT: case BGIMAGE_BOTTOM_LEFT: case BGIMAGE_CENTER_LEFT: rcImagePos.left = area.GetAreaLeft(); break; case BGIMAGE_TOP_RIGHT: case BGIMAGE_BOTTOM_RIGHT: case BGIMAGE_CENTER_RIGHT: rcImagePos.left = area.GetAreaRight() - doc.m_nBackImgWidth; break; case BGIMAGE_TOP_CENTER: case BGIMAGE_BOTTOM_CENTER: case BGIMAGE_CENTER: rcImagePos.left = area.GetAreaLeft() + area.GetAreaWidth()/2 - doc.m_nBackImgWidth/2; break; default: assert_warning(0 != typeConfig.m_backImgPos); break; } switch( typeConfig.m_backImgPos ){ case BGIMAGE_TOP_LEFT: case BGIMAGE_TOP_RIGHT: case BGIMAGE_TOP_CENTER: rcImagePos.top = area.GetAreaTop(); break; case BGIMAGE_BOTTOM_LEFT: case BGIMAGE_BOTTOM_RIGHT: case BGIMAGE_BOTTOM_CENTER: rcImagePos.top = area.GetAreaBottom() - doc.m_nBackImgHeight; break; case BGIMAGE_CENTER_LEFT: case BGIMAGE_CENTER_RIGHT: case BGIMAGE_CENTER: rcImagePos.top = area.GetAreaTop() + area.GetAreaHeight()/2 - doc.m_nBackImgHeight/2; break; default: assert_warning(0 != typeConfig.m_backImgPos); break; } rcImagePos.left += typeConfig.m_backImgPosOffset.x; rcImagePos.top += typeConfig.m_backImgPosOffset.y; // スクロール時の画面の端を作画するときの位置あたりへ移動 if( typeConfig.m_backImgScrollX ){ int tile = typeConfig.m_backImgRepeatX ? doc.m_nBackImgWidth : INT_MAX; Int posX = (area.GetViewLeftCol() % tile) * GetTextMetrics().GetCharPxWidth(); rcImagePos.left -= posX % tile; } if( typeConfig.m_backImgScrollY ){ int tile = typeConfig.m_backImgRepeatY ? doc.m_nBackImgHeight : INT_MAX; Int posY = (area.GetViewTopLine() % tile) * GetTextMetrics().GetHankakuDy(); rcImagePos.top -= posY % tile; } if( typeConfig.m_backImgRepeatX ){ if( 0 < rcImagePos.left ){ // rcImagePos.left = rcImagePos.left - (rcImagePos.left / doc.m_nBackImgWidth + 1) * doc.m_nBackImgWidth; rcImagePos.left = rcImagePos.left % doc.m_nBackImgWidth - doc.m_nBackImgWidth; } } if( typeConfig.m_backImgRepeatY ){ if( 0 < rcImagePos.top ){ // rcImagePos.top = rcImagePos.top - (rcImagePos.top / doc.m_nBackImgHeight + 1) * doc.m_nBackImgHeight; rcImagePos.top = rcImagePos.top % doc.m_nBackImgHeight - doc.m_nBackImgHeight; } } rcImagePos.SetSize(doc.m_nBackImgWidth, doc.m_nBackImgHeight); RECT rc = rcPaint; // rc.left = t_max((int)rc.left, area.GetAreaLeft()); rc.top = t_max((int)rc.top, area.GetRulerHeight()); // ルーラーを除外 const int nXEnd = area.GetAreaRight(); const int nYEnd = area.GetAreaBottom(); CMyRect rcBltAll; rcBltAll.SetLTRB(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX); CMyRect rcImagePosOrg = rcImagePos; for(; rcImagePos.top <= nYEnd; ){ for(; rcImagePos.left <= nXEnd; ){ CMyRect rcBlt; if( ::IntersectRect(&rcBlt, &rc, &rcImagePos) ){ ::BitBlt( hdc, rcBlt.left, rcBlt.top, rcBlt.right - rcBlt.left, rcBlt.bottom - rcBlt.top, hdcBgImg, rcBlt.left - rcImagePos.left, rcBlt.top - rcImagePos.top, SRCCOPY ); rcBltAll.left = t_min(rcBltAll.left, rcBlt.left); rcBltAll.top = t_min(rcBltAll.top, rcBlt.top); rcBltAll.right = t_max(rcBltAll.right, rcBlt.right); rcBltAll.bottom = t_max(rcBltAll.bottom, rcBlt.bottom); } rcImagePos.left += doc.m_nBackImgWidth; rcImagePos.right += doc.m_nBackImgWidth; if( !typeConfig.m_backImgRepeatX ){ break; } } rcImagePos.left = rcImagePosOrg.left; rcImagePos.right = rcImagePosOrg.right; rcImagePos.top += doc.m_nBackImgHeight; rcImagePos.bottom += doc.m_nBackImgHeight; if( !typeConfig.m_backImgRepeatY ){ break; } } if( rcBltAll.left != INT_MAX ){ // 上下左右ななめの隙間を埋める CMyRect rcFill; LONG& x1 = rc.left; LONG& x2 = rcBltAll.left; LONG& x3 = rcBltAll.right; LONG& x4 = rc.right; LONG& y1 = rc.top; LONG& y2 = rcBltAll.top; LONG& y3 = rcBltAll.bottom; LONG& y4 = rc.bottom; if( y1 < y2 ){ rcFill.SetLTRB(x1,y1, x4,y2); MyFillRect(hdc, rcFill); } if( x1 < x2 ){ rcFill.SetLTRB(x1,y2, x2,y3); MyFillRect(hdc, rcFill); } if( x3 < x4 ){ rcFill.SetLTRB(x3,y2, x4,y3); MyFillRect(hdc, rcFill); } if( y3 < y4 ){ rcFill.SetLTRB(x1,y3, x4,y4); MyFillRect(hdc, rcFill); } }else{ MyFillRect(hdc, rc); } ::SetBkColor(hdc, colorOld); #endif }
// HERE: lpRect is available rect for painting void GDisplay::DrawGrid(HDC hDC, LPRECT lpRect) { // They cannot be zero ASSERT(m_xCount); ASSERT(m_yCount); // Calculate dynamic step on X and Y axis div_t dx = div((int)(lpRect->right - lpRect->left), (int)m_xCount); div_t dy = div((int)(lpRect->bottom - lpRect->top), (int)m_yCount); int xStep = dx.quot; int yStep = dy.quot; // Calculate margins of drawing m_nMarginTop = lpRect->top; m_nMarginRight = lpRect->left + m_dxText + xStep*(m_xCount-2); m_nMarginBottom = lpRect->top + yStep*(m_yCount-1); // Set appropriate rectangle RECT m_rcWork; ::SetRect(&m_rcWork, lpRect->left+m_dxText, lpRect->top, m_nMarginRight, m_nMarginBottom); // Fill old values area by dark color RECT rcUpdate; SetRect(&rcUpdate, m_rcWork.left, m_rcWork.top, m_rcWork.left+m_xUpdatePosition, m_rcWork.bottom); MyFillRect(hDC, &rcUpdate, m_clrBackDark); // Fill new values area by light color SetRect(&rcUpdate, m_rcWork.left+m_xUpdatePosition, m_rcWork.top, m_rcWork.right, m_rcWork.bottom); MyFillRect(hDC, &rcUpdate, m_clrBackLight); // // Draw proper grid // HPEN hPen = CreatePen(PS_SOLID, 1, m_clrGrid); HPEN hOldPen = (HPEN)SelectObject(hDC, hPen); // draw lines along X axis (prefix 'y') for (int a = 0; a < m_yCount; a++) { MoveToEx(hDC, m_rcWork.left, m_rcWork.top + yStep*a, NULL); LineTo(hDC, m_rcWork.right, m_rcWork.top + yStep*a); } // draw lines along Y axis (prefix 'x') for (int a = 0; a < m_xCount-1; a++) { MoveToEx(hDC, m_rcWork.left + xStep*a, m_rcWork.top, NULL); LineTo(hDC, m_rcWork.left + xStep*a, m_rcWork.bottom); } SelectObject(hDC, hOldPen); DeleteObject((HGDIOBJ)hPen); if (m_nChartType == CHART_TYPE_SIMPLE) { long y; dtoi(m_rcWork.bottom, m_rcWork.top, 0.75, 2.00, 1.0, &y); hPen = CreatePen(PS_SOLID, 1, RGB(43,123,89)); hOldPen = (HPEN)SelectObject(hDC, hPen); MoveToEx(hDC, m_rcWork.left, y, NULL); LineTo(hDC, m_rcWork.right, y); SelectObject(hDC, hOldPen); DeleteObject((HGDIOBJ)hPen); } // // Output text labels // HFONT hOldFont = (HFONT)SelectObject(hDC, m_hFont); SetBkColor(hDC, m_clrBackDark); // ------------ first ---------------------- SetTextColor(hDC, m_clrMarker[0]); for (int a = 0; a < m_yCount; a++) { size_t nSize; if (SUCCEEDED(StringCbLength(m_szLabel1[a], MAX_LABEL_LENGTH, &nSize))) { TextOut(hDC, m_rcWork.left - m_dxText, m_rcWork.top + yStep*a - m_dyText, m_szLabel1[a], (int)nSize / sizeof(TCHAR)); } } if (m_nChartType != CHART_TYPE_SIMPLE) { // ------------ second ---------------------- SetTextColor(hDC, m_clrMarker[1]); for (int a = 0; a < m_yCount; a++) { size_t nSize; if (SUCCEEDED(StringCbLength(m_szLabel2[a], MAX_LABEL_LENGTH, &nSize))) { TextOut(hDC, m_rcWork.left + 6, m_rcWork.top + yStep*a + 2/* + m_dyText*/, m_szLabel2[a], (int)nSize / sizeof(TCHAR)); } } // -------------- third ------------------------ SetTextColor(hDC, m_clrMarker[2]); for (int a = 0; a < m_yCount; a++) { size_t nSize; if (SUCCEEDED(StringCbLength(m_szLabel3[a], MAX_LABEL_LENGTH, &nSize))) { TextOut(hDC, m_rcWork.right + 6, m_rcWork.top + yStep*a - m_dyText, m_szLabel3[a], (int)nSize / sizeof(TCHAR)); } } } // ------------------------------------------------- SelectObject(hDC, hOldFont); // // Draw light border // hPen = CreatePen(PS_SOLID, 1, m_clrBorder); hOldPen = (HPEN)SelectObject(hDC, hPen); // top border MoveToEx(hDC, m_rcWork.left, m_rcWork.top, NULL); LineTo(hDC, m_nMarginRight, m_rcWork.top); // right border LineTo(hDC, m_nMarginRight, m_nMarginBottom); // bottom border LineTo(hDC, m_rcWork.left, m_nMarginBottom); // left border LineTo(hDC, m_rcWork.left, m_rcWork.top); SelectObject(hDC, hOldPen); DeleteObject((HGDIOBJ)hPen); }