/// <summary> /// On Paint /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); // Caption Data.GradientPaint(g, rectCaption, colorCaptionBack, LayoutColors.DepthCaption); if (showCaption) { g.DrawString(captionText, fontCaption, brushCaption, rectCaption, stringFormatCaption); } g.DrawLine(penBorder, 1, CaptionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, CaptionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); // Paint the panel background var rectClient = new RectangleF(Border, CaptionHeight, width, height); Data.GradientPaint(g, rectClient, LayoutColors.ColorControlBack, LayoutColors.DepthControl); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// On Paint /// </summary> protected override void OnPaint(PaintEventArgs e) { var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); for (int row = 0; row *rowHeight < pnlHeight; row++) { float vertPos = row * rowHeight; // Row background var rectRow = new RectangleF(0, vertPos, pnlWidth + 2 * Space, rowHeight); g.FillRectangle( Math.Abs(row % 2f) > 0.001 ? new SolidBrush(colorBackroundEvenRows) : new SolidBrush(colorBackroundOddRows), rectRow); if (row + vScrollBar.Value >= rows) { continue; } var pointMessage = new PointF(IconWidth + 2 * Space, vertPos); int index = rows - row - vScrollBar.Value - 1; g.DrawImage(GetImage(messages[index].Icon), Space, vertPos, IconWidth, IconHeight); string text = messages[index].Time.ToString(Data.Df + " HH:mm:ss") + " " + messages[index].Message; g.DrawString(text, fontMessage, brushParams, pointMessage); } DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Convert a DIB section to a BitmapSource. /// </summary> /// <param name="dibSection">The dib section.</param> /// <returns>The BitmapSource.</returns> public static BitmapSource DIBSectionToBitmapSource(DIBSection dibSection) { BitmapSource bitSrc = null; try { bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(dibSection.Bits, dibSection.Width, dibSection.Height, PixelFormats.Bgra32, dibSection.Width * 4, 0); } catch (Win32Exception) { bitSrc = null; } return bitSrc; }
/// <summary> /// Paints the journal /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); // Caption background var rectCaption = new RectangleF(0, 0, ClientSize.Width, 2 * rowHeight); Data.GradientPaint(g, rectCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); int hScroll = -HScrollBar.Value; //var size = new Size(ContextButtonLocation.X, rowHeight); var size = new Size(ClientSize.Width, rowHeight); var sf = new StringFormat { Alignment = StringAlignment.Center }; // Print the journal caption string stringCaptionText = Language.T("Orders During the Bar") + (Configs.AccountInMoney ? " [" + Configs.AccountCurrency + "]" : " [" + Language.T("points") + "]"); g.DrawString(stringCaptionText, font, brushCaptionText, new RectangleF(Point.Empty, size), sf); g.SetClip(new RectangleF(Border, rowHeight, ClientSize.Width - 2 * Border, rowHeight)); if (Configs.AccountInMoney) { for (int i = 0; i < columns; i++) { g.DrawString(titlesMoney[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } else { for (int i = 0; i < columns; i++) { g.DrawString(titlesPoints[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } g.ResetClip(); // Paints the journal's data field var rectField = new RectangleF(Border, 2 * rowHeight, ClientSize.Width - 2 * Border, ClientSize.Height - 2 * rowHeight - Border); g.FillRectangle(new SolidBrush(colorBack), rectField); size = new Size(ClientSize.Width - VScrollBar.Width - 2 * Border, rowHeight); // Prints the journal data for (int ord = firstOrd; ord < firstOrd + shownOrd; ord++) { int row = ord - firstOrd; if (journalData == null || journalData[row, 0] == null) { Console.WriteLine("Break"); break; } int y = (row + 2) * rowHeight; var point = new Point(Border, y); // Even row if (Math.Abs(row % 2f - 0) > 0.0001) { g.FillRectangle(brushEvenRowBack, new Rectangle(point, size)); } // Draw the position icon int iImgY = y + (int)Math.Floor((rowHeight - 16) / 2.0); g.DrawImage(orderIcons[row], hScroll + 2, iImgY, 16, 16); // Prints the data g.DrawString(journalData[row, 0], font, brushRowText, hScroll + (16 + xScaled[1]) / 2, (row + 2) * rowHeight, sf); for (int i = 1; i < columns; i++) { if (i == columns - 1) { g.DrawString(journalData[row, i], font, brushRowText, hScroll + xScaled[i], (row + 2) * rowHeight); } else { g.DrawString(journalData[row, i], font, brushRowText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, (row + 2) * rowHeight, sf); } } } for (int i = 1; i < columns; i++) { g.DrawLine(penLines, xScaled[i] + hScroll, 2 * rowHeight, xScaled[i] + hScroll, ClientSize.Height); } // Border g.DrawLine(penBorder, 1, 2 * rowHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * rowHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Sets the chart params /// </summary> protected override void OnPaint(PaintEventArgs e) { var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); try { g.Clear(LayoutColors.ColorChartBack); } catch (Exception exception) { Console.WriteLine(exception.Message); } Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); g.DrawString(caption, fontCaption, brushCaption, rectfCaption, stringFormatCaption); g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); if (tickData == null || tickData.Length < 2) { string text = Language.T("Waiting for ticks..."); g.DrawString(text, fontCaption, penChart.Brush, chartArea); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); return; } int ticks = tickData.Length; double maximum = double.MinValue; double minimum = double.MaxValue; foreach (double tick in tickData) { if (maximum < tick) { maximum = tick; } if (minimum > tick) { minimum = tick; } } maximum += point; minimum -= point; const int space = Border + 2; const int xLeft = space; int xRight = ClientSize.Width - space; double scaleX = (xRight - xLeft) / ((double)ticks - 1); int yTop = (int)captionHeight + space; int yBottom = ClientSize.Height - space; double scaleY = (yBottom - yTop) / (maximum - minimum); int index = 0; var apntTick = new PointF[ticks]; foreach (double tick in tickData) { apntTick[index].X = (float)(xLeft + index * scaleX); apntTick[index].Y = (float)(yBottom - (tick - minimum) * scaleY); index++; } g.DrawLines(penChart, apntTick); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// On Paint /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); // Caption Data.GradientPaint(g, rectCaption, colorCaptionBack, LayoutColors.DepthCaption); g.DrawString(captionText, fontCaption, brushCaption, rectCaption, stringFormatCaption); for (int i = 0; i *rowHeight + captionHeight < height; i++) { float fVerticalPosition = i * rowHeight + captionHeight; var pointFParam = new PointF(paramTab + 2, fVerticalPosition); var pointFValue = new PointF(valueTab + 2, fVerticalPosition); var rectRow = new RectangleF(Border, fVerticalPosition, width, rowHeight); // Row background if (i + vScrollBar.Value < rows && flagsList[i + vScrollBar.Value]) { g.FillRectangle(new SolidBrush(colorBackroundWarningRow), rectRow); } else if (Math.Abs(i % 2f - 0) > 0.001) { g.FillRectangle(new SolidBrush(colorBackroundEvenRows), rectRow); } else { g.FillRectangle(new SolidBrush(colorBackroundOddRows), rectRow); } if (i + vScrollBar.Value >= rows) { continue; } if (i + vScrollBar.Value < rows && flagsList[i + vScrollBar.Value]) { Brush brush = new SolidBrush(colorTextWarningRow); g.DrawString(paramsList[i + vScrollBar.Value], fontData, brush, pointFParam, stringFormatData); g.DrawString(valuesList[i + vScrollBar.Value], fontData, brush, pointFValue, stringFormatData); } else { g.DrawString(paramsList[i + vScrollBar.Value], fontData, brushParams, pointFParam, stringFormatData); g.DrawString(valuesList[i + vScrollBar.Value], fontData, brushData, pointFValue, stringFormatData); } } // Border g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Paints the chart /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); var chartArea = new Rectangle(Border, (int)captionHeight, ClientSize.Width - 2 * Border, ClientSize.Height - (int)captionHeight - Border); Data.GradientPaint(g, chartArea, LayoutColors.ColorChartBack, LayoutColors.DepthControl); // Panel caption Data.GradientPaint(g, captionRectangle, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); g.DrawString(captionText, captionFont, captionBrush, captionRectangle, captionStringFormat); // Border g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); if (!Data.IsData || !Data.IsResult || Data.Bars <= StatsBuffer.FirstBar) { return; } // Limits the drawing into the chart area only g.SetClip(new Rectangle(xLeft, yTop, xRight - xLeft, yPriceBottom - yTop)); // Draws Volume, Lots and Price int index = 0; for (int bar = chartFirstBar; bar <= chartLastBar; bar++) { // Draw the volume if (yVolume[index] != yPriceBottom) { g.DrawLine(penVolume, axisX[index], yVolume[index], axisX[index], yPriceBottom - 1); } // Draw position lots if (rectPosition[index] != Rectangle.Empty) { g.FillRectangle(brushPosition[index], rectPosition[index]); } // Draw the bar var penBar = new Pen(LayoutColors.ColorBarBorder); g.DrawLine(penBar, axisX[index], yLow[index], axisX[index], yHigh[index]); g.DrawLine(penBar, axisX[index], yClose[index], axisX[index] + 1, yClose[index]); index++; } // Drawing the indicators in the chart int slots = StatsBuffer.Strategy.Slots; for (int slot = 0; slot < slots; slot++) { if (isSeparatedChart[slot]) { continue; } for (int comp = 0; comp < componentLength[slot]; comp++) { switch (chartType[slot][comp]) { case IndChartType.Line: g.DrawLines(new Pen(chartBrush[slot][comp]), chartLine[slot][comp]); break; case IndChartType.Dot: for (int bar = chartFirstBar; bar <= chartLastBar; bar++) { g.FillRectangle(chartBrush[slot][comp], chartDot[slot][comp][bar - chartFirstBar]); } break; case IndChartType.Level: for (int bar = chartFirstBar; bar <= chartLastBar; bar++) { g.FillRectangle(chartBrush[slot][comp], chartLevel[slot][comp][bar - chartFirstBar]); } break; case IndChartType.CloudUp: g.DrawLines(new Pen(chartBrush[slot][comp]) { DashStyle = DashStyle.Dash }, chartLine[slot][comp]); break; case IndChartType.CloudDown: g.DrawLines(new Pen(chartBrush[slot][comp]) { DashStyle = DashStyle.Dash }, chartLine[slot][comp]); break; } } } g.ResetClip(); // Separate indicators for (int ind = 0; ind < separateIndicatorsCount; ind++) { int slot = indicatorSlots[ind]; for (int comp = 0; comp < componentLength[slot]; comp++) { switch (chartType[slot][comp]) { case IndChartType.Line: g.DrawLines(new Pen(chartBrush[slot][comp]), chartLine[slot][comp]); break; case IndChartType.Histogram: double zero = 0; if (zero < minValues[ind]) { zero = minValues[ind]; } if (zero > maxValues[ind]) { zero = maxValues[ind]; } var y0 = (int)(yIndBottom[ind] - (zero - minValues[ind]) * scales[ind]); g.DrawLine(penDarkGray, xLeft, y0, xRight, y0); for (int bar = chartFirstBar; bar <= chartLastBar; bar++) { double val = chartValue[slot][comp][bar - chartFirstBar]; int x = (bar - chartFirstBar) * chartBarWidth + xLeft; var y = (int)(yIndBottom[ind] - (val - minValues[ind]) * scales[ind]); g.DrawLine(chartPen[slot][comp][bar - chartFirstBar], x, y0, x, y); } break; } } } // Lines for (int ind = 0; ind < separateIndicatorsCount; ind++) { int y = yBottom - (ind + 1) * separateIndicatorsChartHeight; g.DrawLine(penFore, xLeft, y, xRight, y); } g.DrawLine(penFore, xLeft, yBottom, xRight, yBottom); g.DrawLine(penFore, xLeft, yTop, xLeft, yBottom); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Paints the chart /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); // Caption bar Data.GradientPaint(g, rectCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); g.DrawString(strChartTitle, Font, new SolidBrush(LayoutColors.ColorCaptionText), rectCaption, sfCaption); // Border g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); // Paints the background by gradient var rectField = new RectangleF(Border, captionHeight, ClientSize.Width - 2 * Border, ClientSize.Height - captionHeight - Border); Data.GradientPaint(g, rectField, LayoutColors.ColorChartBack, LayoutColors.DepthControl); if (isNotPaint) { return; } string unit = " [" + (Configs.AccountInMoney ? Configs.AccountCurrency : Language.T("points")) + "]"; string subHeader = isCounts ? Language.T("Count of Trades") : Language.T("Accumulated Amount") + unit; g.DrawString(subHeader, Font, new SolidBrush(LayoutColors.ColorChartFore), rectSubHeader, sfCaption); var formatCenter = new StringFormat { Alignment = StringAlignment.Center }; // Grid and Price labels for (int label = xAxisMin10; label <= xAxisMax; label += stepX) { float xPoint = xLeft + ((xAxisMin10 - xAxisMin) + (label - xAxisMin10)) * xScale; float yPoint = yBottom - Font.Height; if (xPoint <= xRight - labelWidthX / 2) { g.DrawString(label.ToString(CultureInfo.InvariantCulture), Font, brushFore, xPoint, yPoint, formatCenter); } } for (int label = yAxisMin; label <= yAxisMax; label += stepY) { var labelY = (int)(xAxisY - (label - yAxisMin) * yScale); if (label > -1) { g.DrawString(label.ToString(CultureInfo.InvariantCulture), Font, brushFore, xRight, labelY - Font.Height / 2 - 1); } g.DrawLine(penGrid, xLeft, labelY, xRight, labelY); } foreach (var data in chartData) { double val = isCounts ? data.Value.TradesCount : Math.Abs(data.Value.TotalResult); float xPt = xLeft + (data.Key - minIndex + 1) * xScale; float yPtBottom = xAxisY; var yPtTop = (float)(xAxisY - (val - yAxisMin) * yScale); Color color = isCounts ? Color.Blue : data.Value.TotalResult < 0 ? Color.Red : Color.Green; g.DrawLine(new Pen(color), xPt, yPtBottom, xPt, yPtTop); } // Coordinate axes g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yTop - Space, xLeft - 1, xAxisY); g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, xAxisY, xRight, xAxisY); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Paints the chart /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); // Caption bar Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); g.DrawString(chartTitle, Font, new SolidBrush(LayoutColors.ColorCaptionText), rectfCaption, stringFormatCaption); // Border g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); // Paints the background by gradient var rectChartField = new RectangleF(Border, captionHeight, ClientSize.Width - 2 * Border, ClientSize.Height - captionHeight - Border); Data.GradientPaint(g, rectChartField, LayoutColors.ColorChartBack, LayoutColors.DepthControl); if (isNotPaint) { return; } // Grid and Price labels for (int labelPrice = data.Minimum; labelPrice <= data.Minimum + countLabels * labelStep; labelPrice += labelStep) { var labelY = (int)(yBottom - (labelPrice - data.Minimum) * yScale); g.DrawString(labelPrice.ToString(CultureInfo.InvariantCulture), Font, brushFore, xRight, labelY - Font.Height / 2 - 1); g.DrawLine(penGrid, xLeft, labelY, xRight, labelY); } // Price close if (showPriceLine) { g.DrawLines(new Pen(LayoutColors.ColorChartGrid), closePricePoints); } // Equity line g.DrawLines(new Pen(LayoutColors.ColorChartEquityLine), equityPoints); // Draw Long and Short balance if (Configs.AdditionalStatistics) { g.DrawLines(new Pen(Color.Red), shortBalancePoints); g.DrawLines(new Pen(Color.Green), longBalancePoints); } // Out of Sample if (IsOOS && OOSBar > 0) { g.DrawLine(new Pen(LayoutColors.ColorChartFore), xOOSBar, yTop, xOOSBar, yBottom); Brush brushOOS = new Pen(LayoutColors.ColorChartFore).Brush; g.DrawString("OOS", Font, brushOOS, xOOSBar, yBottom - Font.Height); float widthOOSBarDate = g.MeasureString(data.DataTimeBarOOS.ToShortDateString(), Font).Width; g.DrawString(data.DataTimeBarOOS.ToShortDateString(), Font, brushOOS, xOOSBar - widthOOSBarDate, yBottom - Font.Height); } // Draw Balance Line if (data.MarginCallBar > 0) // In case of Margin Call { // Draw balance line up to Margin Call var balPoints = new PointF[data.MarginCallBar - data.FirstBar]; for (int i = 0; i < balPoints.Length; i++) { balPoints[i] = balancePoints[i]; } if (balPoints.Length > 1) { g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), balPoints); } // Draw balance line after Margin Call var redBalancePoints = new PointF[data.Bars - data.MarginCallBar]; for (int i = 0; i < redBalancePoints.Length; i++) { redBalancePoints[i] = balancePoints[i + data.MarginCallBar - data.FirstBar]; } g.DrawLines(new Pen(LayoutColors.ColorSignalRed), redBalancePoints); // Margin Call line g.DrawLine(new Pen(LayoutColors.ColorChartCross), xMarginCallBar, yTop, xMarginCallBar, yBottom); // Margin Call label float widthMarginCallLabel = g.MeasureString(Language.T("Margin Call"), Font).Width; if (xMarginCallBar < xRight - widthMarginCallLabel) { g.DrawString(Language.T("Margin Call"), Font, brushFore, xMarginCallBar, yTop); } else if (xMarginCallBar > Space + widthMarginCallLabel) { g.DrawString(Language.T("Margin Call"), Font, brushFore, xMarginCallBar - widthMarginCallLabel, yTop); } else { g.DrawString("MC", Font, brushFore, xMarginCallBar, yTop); } } else { // Draw the balance line g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), balancePoints); } // Scanning note var fontNote = new Font(Font.FontFamily, Font.Size - 1); if (Data.Period != DataPeriod.M1 && Configs.Autoscan && !Data.IsIntrabarData) { g.DrawString(Language.T("Load intrabar data"), fontNote, Brushes.Red, xLeft, captionHeight - 2); } else if (Data.Period != DataPeriod.M1 && isScanPerformed) { g.DrawString(Language.T("Scanned") + data.ModellingQuolity, fontNote, Brushes.LimeGreen, xLeft, captionHeight - 2); } // Scanned bars if (isScanPerformed && !isHideScanningLine && (Data.IntraBars != null && Data.IsIntrabarData || Data.Period == DataPeriod.M1 && Data.IsTickData && Configs.UseTickData)) { DataPeriod dataPeriod = Data.Period; Color color = Data.PeriodColor[Data.Period]; int fromBar = data.FirstBar; for (int bar = data.FirstBar; bar < data.Bars; bar++) { if (Data.IntraBarsPeriods[bar] == dataPeriod && bar != data.Bars - 1) { continue; } int xStart = (int)((fromBar - data.FirstBar) * xScale) + xLeft; int xEnd = (int)((bar - data.FirstBar) * xScale) + xLeft; fromBar = bar; dataPeriod = Data.IntraBarsPeriods[bar]; Data.GradientPaint(g, new RectangleF(xStart, yBottom + 4, xEnd - xStart + 2, 5), color, 60); color = Data.PeriodColor[Data.IntraBarsPeriods[bar]]; } // Tick Data if (Data.IsTickData && Configs.UseTickData) { int firstBarWithTicks = -1; int lastBarWithTicks = -1; for (int b = 0; b < data.Bars; b++) { if (firstBarWithTicks == -1 && Data.TickData[b] != null) { firstBarWithTicks = b; } if (Data.TickData[b] != null) { lastBarWithTicks = b; } } int xStart = (int)(firstBarWithTicks * xScale) + xLeft; int xEnd = (int)((lastBarWithTicks - data.FirstBar) * xScale) + xLeft; if (xStart < xLeft) { xStart = xLeft; } if (xEnd < xStart) { xEnd = xStart; } Data.DrawCheckerBoard(g, Color.ForestGreen, new Rectangle(xStart, yBottom + 5, xEnd - xStart + 2, 3)); } // Vertical coordinate axes g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yBottom, xLeft - 1, yBottom + 9); } // Coordinate axes g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yTop - Space, xLeft - 1, yBottom + 1); g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yBottom + 1, xRight, yBottom + 1); // Balance level g.DrawLine(new Pen(LayoutColors.ColorChartCross), xLeft, yBalance, xRight - Space + 1, yBalance); // Balance label var labelSize = new Size(labelWidth + Space, Font.Height + 2); var labelPoint = new Point(xRight - Space + 2, (int)(yBalance - Font.Height / 2.0 - 1)); var labelRect = new Rectangle(labelPoint, labelSize); g.FillRectangle(new SolidBrush(LayoutColors.ColorLabelBack), labelRect); g.DrawRectangle(new Pen(LayoutColors.ColorChartCross), labelRect); g.DrawString((Math.Round(data.NetBalance)).ToString(CultureInfo.InvariantCulture), Font, new SolidBrush(LayoutColors.ColorLabelText), labelRect, stringFormatCaption); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
public HelloTriangle(Form form, IntPtr handle) { _form = form; _requestedOpenGLVersion = OpenGLVersion.OpenGL4_4; _delegateCache = new DelegateCache(); _windowBuilder = new GLWindowBuilder("OpenGLSurface"); _dibSection = new DIBSection(); var _hostGraphics = Graphics.FromHwnd(handle); _hostDc = _hostGraphics.GetHdc(); _windowHandle = _windowBuilder.BuildNativeWindow(_roundedWidth, _roundedHeight); _deviceContextHandle = Native.GetDC(_windowHandle); var pfd = new Pixelformatdescriptor(); pfd.Init(); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = _bitDepth; pfd.cDepthBits = 16; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; Int32 iPixelformat; if ((iPixelformat = Native.ChoosePixelFormat(_deviceContextHandle, pfd)) == 0) { throw new InvalidOperationException(); } if (Native.SetPixelFormat(_deviceContextHandle, iPixelformat, pfd) == 0) { throw new InvalidOperationException(); } _renderContextHandle = GLWindows.wglCreateContext(_deviceContextHandle); GLWindows.wglMakeCurrent(_deviceContextHandle, _renderContextHandle); UpdateContextVersion(); CreateDBOs(); OnSizeChanged(); const String vertexShaderSource = "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" + "}\0"; const String fragmentShaderSource = "#version 330 core\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" + "}\n\0"; var vertexShader = GL.CreateVertexShader(); GL.ShaderSource(vertexShader, vertexShaderSource); GL.CompileShader(vertexShader); var rdrr = GL.GetCompileStatus(vertexShader); if (!rdrr) { throw new InvalidProgramException("Unable to compile vertex shader"); } var fragmentShader = GL.CreateShader(GL.GL_FRAGMENT_SHADER); GL.ShaderSource(fragmentShader, fragmentShaderSource); GL.CompileShader(fragmentShader); rdrr = GL.GetCompileStatus(fragmentShader); if (!rdrr) { throw new InvalidProgramException("Unable to compile fragment shader"); } _shaderProgram = GL.CreateProgram(); GL.AttachShader(_shaderProgram, vertexShader); GL.AttachShader(_shaderProgram, fragmentShader); GL.LinkProgram(_shaderProgram); // check for linking errors var parameters = new[] { 0 }; GL.GetProgram(_shaderProgram, GL.GL_LINK_STATUS, parameters); var ok = parameters[0] == GL.GL_TRUE; if (!ok) { throw new InvalidProgramException("Unable to link shader"); } GL.DeleteShader(vertexShader); GL.DeleteShader(fragmentShader); var vertices = new[] { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; UInt16[] indices = { // note that we start from 0! 0, 1, 3, // first Triangle 1, 2, 3 // second Triangle }; var buff = new UInt32[1]; GL.GenVertexArrays(1, buff); VAO = buff[0]; GL.GenBuffers(1, buff); VBO = buff[0]; GL.GenBuffers(1, buff); EBO = buff[0]; //// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). GL.BindVertexArray(VAO); GL.BindBuffer(GL.GL_ARRAY_BUFFER, VBO); GL.BufferData(GL.GL_ARRAY_BUFFER, vertices, GL.GL_STATIC_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, EBO); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW); GL.VertexAttribPointer(0, 3, GL.GL_FLOAT, false, 3 * sizeof(Single), IntPtr.Zero); GL.EnableVertexAttribArray(0); //// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind GL.BindBuffer(GL.GL_ARRAY_BUFFER, 0); // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. GL.BindVertexArray(0); }
/// <summary> /// Paints the journal /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); int hScroll = -HScrollBar.Value; var sf = new StringFormat { Alignment = StringAlignment.Center }; // Caption background var rectCaption = new RectangleF(0, 0, ClientSize.Width, 2 * rowHeight); Data.GradientPaint(g, rectCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); var font = new Font(Font.FontFamily, 9); Color colorBack = LayoutColors.ColorControlBack; var brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText); var brushEvenRowBack = new SolidBrush(LayoutColors.ColorEvenRowBack); var brushSelectedRowBack = new SolidBrush(LayoutColors.ColorSelectedRowBack); var brushSelectedRowText = new SolidBrush(LayoutColors.ColorSelectedRowText); var brushRowText = new SolidBrush(LayoutColors.ColorControlText); var brushWarningBack = new SolidBrush(LayoutColors.ColorWarningRowBack); var brushWarningText = new SolidBrush(LayoutColors.ColorWarningRowText); var penLines = new Pen(LayoutColors.ColorJournalLines); var penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border); // Print the journal caption string unit = Configs.AccountInMoney ? " [" + Configs.AccountCurrency + "]" : " [" + Language.T("points") + "]"; string accUnit = " [" + Configs.AccountCurrency + "]"; g.SetClip(new RectangleF(Border, 0, ClientSize.Width - 2 * Border, 2 * rowHeight)); g.DrawString(Language.T("Market Data"), font, brushCaptionText, hScroll + (xScaled[8] + xScaled[0]) / 2, 0, sf); g.DrawString(Language.T("Summary") + unit, font, brushCaptionText, hScroll + (xScaled[14] + xScaled[8]) / 2, 0, sf); g.DrawString(Language.T("Account") + unit, font, brushCaptionText, hScroll + (xScaled[16] + xScaled[14]) / 2, 0, sf); g.DrawString(Language.T("Margin") + accUnit, font, brushCaptionText, hScroll + (xScaled[18] + xScaled[16]) / 2, 0, sf); g.DrawString(Language.T("Backtest"), font, brushCaptionText, hScroll + (xScaled[19] + xScaled[18]) / 2, 0, sf); if (Configs.AccountInMoney) { for (int i = 0; i < columns; i++) { g.DrawString(titlesInMoney[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } else { for (int i = 0; i < columns; i++) { g.DrawString(titlesInPoints[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } g.ResetClip(); var rectField = new RectangleF(Border, 2 * rowHeight, ClientSize.Width - 2 * Border, ClientSize.Height - 2 * rowHeight - Border); g.FillRectangle(new SolidBrush(colorBack), rectField); var size = new Size(ClientSize.Width - VScrollBar.Width - 2 * Border, rowHeight); // Prints the journal data for (int bar = firstBar; bar < firstBar + shownBars; bar++) { int y = (bar - firstBar + 2) * rowHeight; var point = new Point(Border, y); // Even row if (Math.Abs((bar - firstBar) % 2f - 0) > 0.0001) { g.FillRectangle(brushEvenRowBack, new Rectangle(point, size)); } // Warning row bool isWarningRow = false; if (journalData[bar - firstBar, columns - 1] == Language.T("Ambiguous")) { g.FillRectangle(brushWarningBack, new Rectangle(point, size)); isWarningRow = true; } // Selected row Brush brush; if (bar - firstBar == selectedRow) { g.FillRectangle(brushSelectedRowBack, new Rectangle(point, size)); brush = brushSelectedRowText; } else { brush = isWarningRow ? brushWarningText : brushRowText; } int index = bar - firstBar; // Draw the position icon int imgY = y + (int)Math.Floor((rowHeight - 16) / 2.0); g.DrawImage(positionIcons[index], hScroll + 2, imgY, 16, 16); // Prints the data g.DrawString(journalData[index, 0], font, brush, hScroll + (16 + xScaled[1]) / 2, (index + 2) * rowHeight, sf); for (int i = 1; i < columns; i++) { g.DrawString(journalData[index, i], font, brush, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, (index + 2) * rowHeight, sf); } } // Vertical grid lines for (int i = 1; i < columns; i++) { if (i == 8 || i == 14 || i == 16 || i == 18) { var rectSeparator = new RectangleF(xScaled[i] + hScroll, (float)(rowHeight / 2.0), 1, (float)(3 * rowHeight / 2.0)); Data.GradientPaint(g, rectSeparator, LayoutColors.ColorCaptionBack, -2 * LayoutColors.DepthCaption); } g.DrawLine(penLines, xScaled[i] + hScroll, 2 * rowHeight, xScaled[i] + hScroll, ClientSize.Height); } // Borders g.DrawLine(penBorder, 1, 2 * rowHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * rowHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); OnSelectedBarChange(new EventArgs()); }
/// <summary> /// Paints the chart /// </summary> protected override void OnPaint(PaintEventArgs e) { var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); try { g.Clear(LayoutColors.ColorChartBack); } catch (Exception exception) { Console.WriteLine(exception.Message); } // Caption bar Data.GradientPaint(g, rectfCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); g.DrawString(chartTitle, Font, new SolidBrush(LayoutColors.ColorCaptionText), rectfCaption, stringFormatCaption); // Border g.DrawLine(penBorder, 1, captionHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, captionHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); if (balanceData == null || balanceData.Length < 1 || equityData == null || equityData.Length < 1) { DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); return; } // Grid and Price labels for (int iLabel = minValue; iLabel <= maxValue; iLabel += stepLabels) { var iLabelY = (int)(yBottom - (iLabel - minValue) * scaleY); g.DrawString(iLabel.ToString(".00"), Font, brushFore, xRight, iLabelY - Font.Height / 2 - 1); g.DrawLine(penGrid, xLeft, iLabelY, xRight, iLabelY); } // Equity and Balance lines g.DrawLines(new Pen(LayoutColors.ColorChartEquityLine), apntEquity); g.DrawLines(new Pen(LayoutColors.ColorChartBalanceLine), apntBalance); // Coordinate axes g.DrawLine(new Pen(LayoutColors.ColorChartFore), xLeft - 1, yTop - Space, xLeft - 1, yBottom + 1 + Font.Height); // Equity price label. var pntEquity = new Point(xRight - Space + 2, (int)(equityY - font.Height / 2.0 - 1)); var sizeEquity = new Size(labelWidth + Space, font.Height + 2); string equity = (netEquity.ToString("F2")); var halfEquity = (int)(sizeEquity.Height / 2.0); var apEquity = new[] { new PointF(xRight - Space - 8, equityY), new PointF(xRight - Space, equityY - halfEquity), new PointF(xRight - Space + sizeEquity.Width + 5, equityY - halfEquity), new PointF(xRight - Space + sizeEquity.Width + 5, equityY + halfEquity), new PointF(xRight - Space, equityY + halfEquity) }; g.FillPolygon(new SolidBrush(LayoutColors.ColorChartEquityLine), apEquity); g.DrawString(equity, font, new SolidBrush(LayoutColors.ColorChartBack), pntEquity); // Balance price label. var pntBalance = new Point(xRight - Space + 2, (int)(balanceY - font.Height / 2.0 - 1)); var sizeBalance = new Size(labelWidth + Space, font.Height + 2); var halfBalance = (int)(sizeBalance.Height / 2.0); string balance = (netBalance.ToString("F2")); var apBalance = new[] { new PointF(xRight - Space - 8, balanceY), new PointF(xRight - Space, balanceY - halfBalance), new PointF(xRight - Space + sizeBalance.Width + 5, balanceY - halfBalance), new PointF(xRight - Space + sizeBalance.Width + 5, balanceY + halfBalance), new PointF(xRight - Space, balanceY + halfBalance) }; g.FillPolygon(new SolidBrush(LayoutColors.ColorChartBalanceLine), apBalance); g.DrawString(balance, font, new SolidBrush(LayoutColors.ColorChartBack), pntBalance); // Chart Text string chartText = startTime.ToString(CultureInfo.InvariantCulture); g.DrawString(chartText, font, new SolidBrush(LayoutColors.ColorChartFore), xLeft, yBottom); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Paints the journal /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); int hScroll = -hScrollBar.Value; var size = new Size(visibleWidth, rowHeight); var sf = new StringFormat { Alignment = StringAlignment.Center }; // Caption background var rectCaption = new RectangleF(0, 0, ClientSize.Width, 2 * rowHeight); Data.GradientPaint(g, rectCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); Color colorBack = LayoutColors.ColorControlBack; var brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText); var brushEvenRowBack = new SolidBrush(LayoutColors.ColorEvenRowBack); var brushRowText = new SolidBrush(LayoutColors.ColorControlText); var penLines = new Pen(LayoutColors.ColorJournalLines); var penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), Border); var font = new Font(Font.FontFamily, 9); // Print the journal caption string caption = Language.T("Positions During the Bar") + (Configs.AccountInMoney ? " [" + Configs.AccountCurrency + "]" : " [" + Language.T("points") + "]"); g.DrawString(caption, font, brushCaptionText, new RectangleF(Point.Empty, size), sf); g.SetClip(new RectangleF(Border, rowHeight, ClientSize.Width - 2 * Border, rowHeight)); if (Configs.AccountInMoney) { for (int i = 0; i < columns; i++) { g.DrawString(titlesMoney[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } else { for (int i = 0; i < columns; i++) { g.DrawString(titlesPoints[i], font, brushCaptionText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, rowHeight, sf); } } g.ResetClip(); // Paints the journal's data field var rectField = new RectangleF(Border, 2 * rowHeight, ClientSize.Width - 2 * Border, ClientSize.Height - 2 * rowHeight - Border); g.FillRectangle(new SolidBrush(colorBack), rectField); size = new Size(ClientSize.Width - vScrollBar.Width - 2 * Border, rowHeight); // Prints the journal data for (int pos = firstPos; pos < firstPos + shownPos; pos++) { int row = pos - firstPos; int y = (row + 2) * rowHeight; var point = new Point(Border, y); // Even row if (Math.Abs(row % 2f - 0) > 0.0001) { g.FillRectangle(brushEvenRowBack, new Rectangle(point, size)); } // Draw the position icon int iImgY = y + (int)Math.Floor((rowHeight - 16) / 2.0); g.DrawImage(positionIcons[pos - firstPos], hScroll + 2, iImgY, 16, 16); // Prints the data g.DrawString(journalData[row, 0], font, brushRowText, hScroll + (16 + xScaled[1]) / 2, (row + 2) * rowHeight, sf); for (int i = 1; i < columns; i++) { g.DrawString(journalData[row, i], font, brushRowText, hScroll + (xScaled[i] + xScaled[i + 1]) / 2, (row + 2) * rowHeight, sf); } } for (int i = 1; i < columns; i++) { g.DrawLine(penLines, xScaled[i] + hScroll, 2 * rowHeight, xScaled[i] + hScroll, ClientSize.Height); } // Border g.DrawLine(penBorder, 1, 2 * rowHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * rowHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); }
/// <summary> /// Paints the journal /// </summary> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (ClientSize.Width == 0 || ClientSize.Height == 0) { return; } var bitmap = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bitmap); int scroll = -hScrollBar.Value; var size = new Size(ClientSize.Width, rowHeight); var stringFormat = new StringFormat { Alignment = StringAlignment.Center }; // Caption background var rectCaption = new RectangleF(0, 0, ClientSize.Width, 2 * rowHeight); Data.GradientPaint(g, rectCaption, LayoutColors.ColorCaptionBack, LayoutColors.DepthCaption); // Print the journal caption string stringCaptionText = Language.T("Journal by Positions") + (ShowTransfers ? "" : " " + Language.T("without Transfers")) + (Configs.AccountInMoney ? " [" + Configs.AccountCurrency + "]" : " [" + Language.T("points") + "]"); g.DrawString(stringCaptionText, font, brushCaptionText, new RectangleF(Point.Empty, size), stringFormat); g.SetClip(new RectangleF(Border, rowHeight, ClientSize.Width - 2 * Border, rowHeight)); if (Configs.AccountInMoney) { g.DrawString(titlesInMoney[0], font, brushCaptionText, scroll + (scaledX[0] + scaledX[1]) / 2, rowHeight, stringFormat); for (int i = 1; i < columns; i++) { g.DrawString(titlesInMoney[i], font, brushCaptionText, scroll + (scaledX[i] + scaledX[i + 1]) / 2, rowHeight, stringFormat); } } else { g.DrawString(titlesInPoints[0], font, brushCaptionText, scroll + (scaledX[0] + scaledX[1]) / 2, rowHeight, stringFormat); for (int i = 1; i < columns; i++) { g.DrawString(titlesInPoints[i], font, brushCaptionText, scroll + (scaledX[i] + scaledX[i + 1]) / 2, rowHeight, stringFormat); } } g.ResetClip(); // Paints the journal's data field var rectField = new RectangleF(Border, 2 * rowHeight, ClientSize.Width - 2 * Border, ClientSize.Height - 2 * rowHeight - Border); g.FillRectangle(new SolidBrush(colorBack), rectField); size = new Size(ClientSize.Width - vScrollBar.Width - 2 * Border, rowHeight); // Prints the journal data for (int pos = firstPos; pos < firstPos + shownPos; pos++) { int y = (pos - firstPos + 2) * rowHeight; var point = new Point(Border, y); // Even row if (Math.Abs((pos - firstPos) % 2f - 0) > 0.0001) { g.FillRectangle(brushEvenRowBack, new Rectangle(point, size)); } // Warning row bool isWarning = false; if (journalData[pos - firstPos, columns - 1] == Language.T("Ambiguous")) { g.FillRectangle(brushWarningBack, new Rectangle(point, size)); isWarning = true; } // Selected row Brush brush; if (pos - firstPos == selectedRow) { g.FillRectangle(brushSelectedRowBack, new Rectangle(point, size)); brush = brushSelectedRowText; } else { brush = isWarning ? brushWarningText : brushRowText; } // Draw the position icon int iImgY = y + (int)Math.Floor((rowHeight - 16) / 2.0); g.DrawImage(posIcons[pos - firstPos], scroll + 2, iImgY, 16, 16); // Prints the data g.DrawString(journalData[pos - firstPos, 0], font, brush, scroll + (16 + scaledX[1]) / 2, (pos - firstPos + 2) * rowHeight, stringFormat); for (int i = 1; i < columns; i++) { g.DrawString(journalData[pos - firstPos, i], font, brush, scroll + (scaledX[i] + scaledX[i + 1]) / 2, (pos - firstPos + 2) * rowHeight, stringFormat); } } //g.DrawLine(penLines, 0, iRowHeight, ClientSize.Width, iRowHeight); for (int i = 1; i < columns; i++) { g.DrawLine(penLines, scaledX[i] + scroll, 2 * rowHeight, scaledX[i] + scroll, ClientSize.Height); } // Border g.DrawLine(penBorder, 1, 2 * rowHeight, 1, ClientSize.Height); g.DrawLine(penBorder, ClientSize.Width - Border + 1, 2 * rowHeight, ClientSize.Width - Border + 1, ClientSize.Height); g.DrawLine(penBorder, 0, ClientSize.Height - Border + 1, ClientSize.Width, ClientSize.Height - Border + 1); DIBSection.DrawOnPaint(e.Graphics, bitmap, Width, Height); OnSelectedBarChange(new EventArgs()); }