using Easychart.Finance.DataProvider; using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Printing; using System.Globalization; using System.IO; using System.Text; using System.Windows.Forms; namespace Easychart.Finance.Win { public class ChartWinControl : UserControl, IObjectCanvas, IDisposable { #region Events of ChartWinControl (12) [Description("Occurs after apply skin"), Category("Stock Chart")] public event EventHandler AfterApplySkin; [Description("Occurs after data bind"), Category("Stock Chart")] public event Easychart.Finance.Win.AfterBindData AfterBindData; [Category("Stock Chart"), Description("Occurs after data cycle changed")] public event EventHandler AfterCycleChange; [Description("Occurs after mouse move"), Category("Stock Chart")] public event Easychart.Finance.Win.AfterMouseMove AfterMouseMove; [Description("Occurs before apply skin"), Category("Stock Chart")] public event ApplySkinHandler BeforeApplySkin; [Description("Occurs before data cycle changed"), Category("Stock Chart")] public event EventHandler BeforeCycleChange; [Description("Occurs when cursor pos changed"), Category("Stock Chart")] public event Easychart.Finance.Win.CursorPosChanged CursorPosChanged; [Category("Stock Chart"), Description("Occurs when stock data or data cycle changed")] public event EventHandler DataChanged; [Category("Stock Chart"), Description("Occurs when paint extra informations on the chart, it was used by Easy Stock Object")] public event NativePaintHandler ExtraPaint; [Category("Stock Chart"), Description("Occurs when paint the chart on native canvas")] public event NativePaintHandler NativePaint; [Description("Occurs when the value of ShowStatistic Changed"), Category("Stock Chart")] public event EventHandler ShowStatisticChanged; [Category("Stock Chart"), Description("Occurs when stock view changed")] public event ViewChangedHandler ViewChanged; #endregion Events of ChartWinControl (12) #region Members of ChartWinControl (114) private bool adjustData = true; private double afterBars = 0.1; private string areaPercent = "3;1;1;1;1"; private FormulaChart chart; private Easychart.Finance.ChartDragMode chartDragMode = Easychart.Finance.ChartDragMode.Axis; private ContextMenu cmMain; public ContextMenu cmRight; private double columnWidth = 4.0; private IContainer components; private Graphics ControlGraphics; private MouseAction crossCursorMouseMode = MouseAction.MouseMove; private Bitmap CrossMemBmp; private Graphics CrossMemBmpG; private DataCycle currentDataCycle = DataCycle.Day; private DataManagerBase CurrentDataManager; private Cursor defaultCursor = null; private const string defaultFavoriteCycles = "MINUTE1;MINUTE5;MINUTE15;MINUTE30;HOUR1;DAY1;WEEK1;MONTH1;YEAR1"; private string defaultFormulas; private static Color defaultZoomBackColor = Color.FromArgb(0x20, Color.Green); private bool designing; private ChartDragInfo DragInfo; private EventHandler ehFavoriteIndicator; private bool EnableResize; private bool EnableXScale; private bool EnableYScale; private DateTime endTime; private string favoriteCycles = "MINUTE1;MINUTE5;MINUTE15;MINUTE30;HOUR1;DAY1;WEEK1;MONTH1;YEAR1"; private ArrayList favoriteFormulas; private bool fixedTime; private Rectangle fixedZoomRect = Rectangle.Empty; private DataManagerBase historyDataManager; private DataManagerBase intraDataManager; private ExchangeIntraday intradayInfo = ExchangeIntraday.US; private int LastCursorPos; private FormulaHitInfo LastHitInfo; private IDataProvider LastProvider; private int LastX; private int LastY; private Easychart.Finance.LatestValueType latestValueType = Easychart.Finance.LatestValueType.All; private double maxColumnWidth = 500.0; private double maxPrice; private Bitmap MemBmp; private bool memoryCrossCursor; private MenuItem miAddFormula; private MenuItem miAdjust; private MenuItem miAxisType; private MenuItem miCalculator; private MenuItem miChart; private MenuItem miChartCopy; private MenuItem miChartEdit; private MenuItem miCloseFormula; private MenuItem miCopy; private MenuItem miCrossCursor; private MenuItem miCycle; private MenuItem miEdit; private MenuItem miFavorite; private MenuItem miFormulaManager; private MenuItem miIndicator; private MenuItem miLog; private double minColumnWidth = 0.01; private MenuItem miNormal; private double minPrice; private MenuItem miSkin; private MenuItem miSp1; private MenuItem miSp2; private MenuItem miSp4; private MenuItem miStatistic; private MenuItem miStatisticWindow; private MenuItem miView; private FormulaHitInfo MouseDownInfo; private Easychart.Finance.Win.MouseWheelMode mouseWheelMode = Easychart.Finance.Win.MouseWheelMode.Scroll; private Color mouseZoomBackColor = defaultZoomBackColor; private Bitmap MouseZoomBmp; private Graphics MouseZoomBmpG; private Easychart.Finance.Win.MouseZoomMode mouseZoomMode = Easychart.Finance.Win.MouseZoomMode.Rect; private RectangleF MouseZoomRect; private bool nativeContextMenu = true; private bool needAutoScaleY = true; private bool needDrawCursor; private bool needDrawLastBarOnly = false; private bool needRebind; private bool needRedraw; private bool needRefresh; private bool needResetCursorPos; private bool needSetDefaultFormulas; public static Easychart.Finance.Win.OnSelectFormula OnSelectFormula = new Easychart.Finance.Win.OnSelectFormula(ChartWinControl.DefaultSelectFormula); public static OnSelectString OnSelectMethod = new OnSelectString(ChartWinControl.DefaultSelectMethod); public static OnSelectString OnSelectSymbol = null; private int Page; private PrintPreviewDialog previewDialog; private PrintDialog printDialog; private PrintDocument printDocument; private bool resetYAfterXChanged = true; private Easychart.Finance.ScaleType scaleType = Easychart.Finance.ScaleType.Default; private MouseAction selectFormulaMouseMode = MouseAction.MouseDown; private PageSetupDialog setupDialog; private bool showCrossCursor = true; private bool showCursorLabel = true; private ShowLineMode showHorizontalGrid; private bool showIndicatorValues = true; private bool showOverlayValues = true; private bool showStatistic = true; private bool showTopLine = true; private ShowLineMode showVerticalGrid; private string skin = "RedWhite"; private DateTime startTime; public StatisticControl StatisticWindow = null; private Easychart.Finance.StickRenderType stickRenderType = Easychart.Finance.StickRenderType.Default; private int stockBars = 150; private Easychart.Finance.StockRenderType stockRenderType = Easychart.Finance.StockRenderType.Default; private string symbol = "MSFT"; public FormulaUserSkin UserSkin = new FormulaUserSkin(); private Easychart.Finance.ValueTextMode valueTextMode = Easychart.Finance.ValueTextMode.Default; private ZoomCenterPosition zoomPosition = ZoomCenterPosition.Center; public DateTime[] openCloseArray; //开收盘时间 public double LastClose; //昨收 public double Highest; //当天最高价 public double Lowsest; //当天最低价 private const string tickChartFormulas = "C#CAVG"; //分时图公式 private FormulaChart temKChartFormula; private FormulaChart tickChart; #endregion Members of ChartWinControl (114) #region Properties of ChartWinControl (55) [Category("Stock Chart"), DefaultValue(true), Description("Adjust the data automatically when there is price split")] public bool AdjustData { get { return this.adjustData; } set { this.adjustData = value; this.NeedRebind(); } } [DefaultValue((double)0.1), Category("Stock Chart Time"), Description("How many right space after the last bar of the chart. If the value between 0 and 1, it means the percentage of the bar.")] public double AfterBars { get { return this.afterBars; } set { this.afterBars = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] public int AreaCount { get { return this.chart.Areas.Count; } set { this.SetAreaCount(value); } } [Category("Stock Chart"), DefaultValue("3;1;1;1;1"), Description("Height percentage of each area,separated by semi colon.")] public string AreaPercent { get { return this.areaPercent; } set { this.areaPercent = value; } } [Browsable(false)] public string Caption { get { IDataProvider dataProvider = this.chart.DataProvider; string stringData = dataProvider.GetStringData("Code"); string str2 = dataProvider.GetStringData("Name"); if (str2 != null) { stringData = stringData + "(" + str2 + ")"; } string str3 = dataProvider.GetStringData("Exchange"); if (str3 != null) { stringData = stringData + "@" + str3; } return (stringData + " - " + this.CurrentDataCycle); } } [Browsable(false)] public FormulaChart Chart { get { return this.chart; } } [DefaultValue(1), Description("Behaver when drag the chart"), Category("Stock Chart")] public Easychart.Finance.ChartDragMode ChartDragMode { get { return this.chartDragMode; } set { this.chartDragMode = value; } } [Browsable(false), DefaultValue((double)4.0), Category("Stock Chart Time")] public double ColumnWidth { get { return this.columnWidth; } set { this.columnWidth = value; } } [DefaultValue(1), Category("Stock Chart"), Description("How to show the cross cursor according mouse action, mouse move or mouse down")] public MouseAction CrossCursorMouseMode { get { return this.crossCursorMouseMode; } set { this.crossCursorMouseMode = value; } } [Description("Data Cycle"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), DefaultValue(typeof(DataCycle), "DAY1"), Category("Stock Chart")] public DataCycle CurrentDataCycle { get { return this.currentDataCycle; } set { if (this.currentDataCycle != value) { if (this.BeforeCycleChange != null) { this.BeforeCycleChange(this, new EventArgs()); } if (DataCycle.TimeChart.Equals(currentDataCycle)&&!DataCycle.TimeChart.Equals(value)) { this.chart.NativePaint -= new NativePaintHandler(this.Chart_NativePaint); this.chart.ExtraPaint -= new NativePaintHandler(this.Chart_ExtraPaint); this.chart.ViewChanged -= new ViewChangedHandler(this.Chart_ViewChanged); this.chart = this.temKChartFormula; this.chart.NativePaint += new NativePaintHandler(this.Chart_NativePaint); this.chart.ExtraPaint += new NativePaintHandler(this.Chart_ExtraPaint); this.chart.ViewChanged += new ViewChangedHandler(this.Chart_ViewChanged); } if ((value.CycleBase >= DataCycleBase.DAY) && this.chart.FixedTime) { this.fixedTime = false; this.chart.FixedTime = false; } else if (DataCycle.TimeChart.Equals(value)) { this.temKChartFormula = this.chart; this.chart.NativePaint -= new NativePaintHandler(this.Chart_NativePaint); this.chart.ExtraPaint -= new NativePaintHandler(this.Chart_ExtraPaint); this.chart.ViewChanged -= new ViewChangedHandler(this.Chart_ViewChanged); tickChart.Rect = this.chart.Rect; this.chart = tickChart; tickChart.Areas.Clear(); tickChart.StringsToArea(tickChartFormulas.Split(new char[] { ';' })); this.chart.NativePaint += new NativePaintHandler(this.Chart_NativePaint); this.chart.ExtraPaint += new NativePaintHandler(this.Chart_ExtraPaint); this.chart.ViewChanged += new ViewChangedHandler(this.Chart_ViewChanged); tickChart.LastClose = this.LastClose; tickChart.Highest = this.Highest; tickChart.Lowsest = this.Lowsest; tickChart.openCloseArray = this.openCloseArray; this.chart.DataCycle = value; } this.NeedRebind(); this.currentDataCycle = value; if (this.AfterCycleChange != null) { this.AfterCycleChange(this, new EventArgs()); } } } } [Browsable(false)] public DataManagerBase DataManager { set { this.HistoryDataManager = value; this.IntraDataManager = value; } } [Description("Default cursor"), DefaultValue((string)null), Category("Stock Chart")] public Cursor DefaultCursor { get { return this.defaultCursor; } set { this.defaultCursor = value; } } [Category("Stock Chart"), DefaultValue("VOLMA;RSI(14)#RSI(28);MACD;SlowSTO")] public string DefaultFormulas { get { return this.defaultFormulas; } set { this.defaultFormulas = value; this.needSetDefaultFormulas = true; this.NeedRebind(); } } [Browsable(false)] public Control DesignerControl { get { return this; } } [Browsable(false)] public bool Designing { get { return this.designing; } set { this.designing = value; } } [Description("End time of the chart, if leave this field empty, will use StockBars instead"), DefaultValue(typeof(DateTime), "1-1-1"), Category("Stock Chart Time")] public DateTime EndTime { get { return this.endTime; } set { this.endTime = value; if (this.fixedTime || ((this.CurrentDataManager != null) && this.CurrentDataManager.VirtualFetch)) { this.NeedRebind(); } else { this.NeedRedraw(); } if (this.memoryCrossCursor) { this.needDrawCursor = true; } } } [Category("Stock Chart"), DefaultValue("MINUTE1;MINUTE5;MINUTE15;MINUTE30;HOUR1;DAY1;WEEK1;MONTH1;YEAR1")] public string FavoriteCycles { get { return this.favoriteCycles; } set { this.favoriteCycles = value; this.CreateCycleMenu(); } } [Category("Stock Chart")] public string FavoriteFormulas { get { return string.Join(";", (string[])this.favoriteFormulas.ToArray(typeof(string))); } set { if ((value != null) && (value != "")) { this.favoriteFormulas.Clear(); this.favoriteFormulas.AddRange(value.Split(new char[] { ';' })); this.BuildFavoriteMenu(); } } } [DefaultValue(false), Category("Stock Chart"), Description("Fixed time frame between StartTime and EndTime, used for intraday chart")] public bool FixedTime { get { return this.fixedTime; } set { this.fixedTime = value; this.NeedRebind(); } } [Category("Stock Chart Mouse Zoom"), Description("Rectangle for fixed zoom box. Empty box will draw the zoom box by hand. Center fixed zoom box (-150,-150,300,300), TopLeft fixed zoom box (0,0,300,300)"), DefaultValue(typeof(Rectangle), "0, 0, 0, 0")] public Rectangle FixedZoomRect { get { return this.fixedZoomRect; } set { this.fixedZoomRect = value; } } [DefaultValue((string)null), Browsable(false)] public DataManagerBase HistoryDataManager { get { return this.historyDataManager; } set { if (value != this.historyDataManager) { this.historyDataManager = value; this.NeedRebind(); } } } [Browsable(false), DefaultValue((string)null)] public DataManagerBase IntraDataManager { get { return this.intraDataManager; } set { if (value != this.intraDataManager) { this.intraDataManager = value; this.NeedRebind(); } } } [Description("Intraday exchange informations"), Browsable(false)] public ExchangeIntraday IntradayInfo { get { return this.intradayInfo; } set { this.intradayInfo = value; this.NeedRebind(); } } [Browsable(false)] public bool IsDragging { get { return (this.DragInfo != null); } } [Category("Stock Chart"), DefaultValue(2), Description("How to show the latest value in the axis-Y")] public Easychart.Finance.LatestValueType LatestValueType { get { return this.latestValueType; } set { this.latestValueType = value; this.NeedRedraw(); } } [DefaultValue((double)500.0), Category("Stock Chart")] public double MaxColumnWidth { get { return this.maxColumnWidth; } set { this.maxColumnWidth = value; } } [Browsable(false)] public double MaxPrice { get { return this.maxPrice; } set { this.maxPrice = value; } } [DefaultValue(false), Description("Draw cross cursor in memory , this will prevent flicker"), Category("Stock Chart")] public bool MemoryCrossCursor { get { return this.memoryCrossCursor; } set { this.memoryCrossCursor = value; } } [Category("Stock Chart"), DefaultValue((double)0.01)] public double MinColumnWidth { get { return this.minColumnWidth; } set { this.minColumnWidth = value; } } [Browsable(false)] public double MinPrice { get { return this.minPrice; } set { this.minPrice = value; } } [Description("Use mouse wheel to scroll or zoom the chart"), DefaultValue(1), Category("Stock Chart")] public Easychart.Finance.Win.MouseWheelMode MouseWheelMode { get { return this.mouseWheelMode; } set { this.mouseWheelMode = value; } } [DefaultValue(typeof(Color), "32, 0, 128, 0"), Description("The background color of the mouse zoom"), Category("Stock Chart Mouse Zoom")] public Color MouseZoomBackColor { get { return this.mouseZoomBackColor; } set { this.mouseZoomBackColor = value; } } [Description("Use mouse to zoom the chart"), DefaultValue(1), Category("Stock Chart Mouse Zoom")] public Easychart.Finance.Win.MouseZoomMode MouseZoomMode { get { return this.mouseZoomMode; } set { this.mouseZoomMode = value; } } [Description("Use native context menu"), Category("Stock Chart"), DefaultValue(true)] public bool NativeContextMenu { get { return this.nativeContextMenu; } set { this.nativeContextMenu = value; } } [Description("If you specify this, will add these text in the price area,Sample format:Prev Close:{LC}O:{OPEN}H:{HIGH}L:{LOW}C:{CLOSE}V:{VOLUME}Chg:{Change} {D:yyyy-MM-dd}"), Category("Stock Chart")] public string PriceLabelFormat { get { return this.chart.PriceLabelFormat; } set { this.chart.PriceLabelFormat = value; } } [Category("Stock Chart"), DefaultValue(true), Description("Reset Y-axis to auto scale when X-axis changed.")] public bool ResetYAfterXChanged { get { return this.resetYAfterXChanged; } set { this.resetYAfterXChanged = value; } } [DefaultValue(3), Category("Stock Chart"), Description("Get or set the scale type of main stock area")] public Easychart.Finance.ScaleType ScaleType { get { return this.scaleType; } set { this.scaleType = value; this.NeedRedraw(); } } [DefaultValue(2), Description("How to select a formula through mouse"), Category("Stock Chart")] public MouseAction SelectFormulaMouseMode { get { return this.selectFormulaMouseMode; } set { this.selectFormulaMouseMode = value; } } [DefaultValue(true), Description("Show cross cursor on the chart"), Category("Stock Chart")] public bool ShowCrossCursor { get { return this.showCrossCursor; } set { this.showCrossCursor = value; this.miCrossCursor.Checked = value; this.chart.ShowHLine = value; this.chart.ShowVLine = value; if (!value) { base.Invalidate(); } } } [DefaultValue(true), Category("Stock Chart")] public bool ShowCursorLabel { get { return this.showCursorLabel; } set { this.showCursorLabel = value; this.NeedRebind(); } } [Category("Stock Chart"), Description("How to show the horizontal grid line"), DefaultValue(0)] public ShowLineMode ShowHorizontalGrid { get { return this.showHorizontalGrid; } set { this.showHorizontalGrid = value; this.NeedRedraw(); } } [DefaultValue(true), Category("Stock Chart"), Description("Show indicator values in the statistic window")] public bool ShowIndicatorValues { get { return this.showIndicatorValues; } set { this.showIndicatorValues = value; } } [DefaultValue(true), Description("Show overlay values in the statistic window"), Category("Stock Chart")] public bool ShowOverlayValues { get { return this.showOverlayValues; } set { this.showOverlayValues = value; } } [Category("Stock Chart"), DefaultValue(true), Description("Show statistic windows on the chart")] public bool ShowStatistic { get { return this.showStatistic; } set { bool flag = (this.showStatistic != value) && (this.ShowStatisticChanged != null); this.showStatistic = value; if (flag) { this.ShowStatisticChanged(this, new EventArgs()); } } } [Description("Draw a line on top of the chart control"), Category("Stock Chart"), DefaultValue(true)] public bool ShowTopLine { get { return this.showTopLine; } set { this.showTopLine = value; } } [Description("How to show the vertical grid line"), DefaultValue(0), Category("Stock Chart")] public ShowLineMode ShowVerticalGrid { get { return this.showVerticalGrid; } set { this.showVerticalGrid = value; this.NeedRedraw(); } } [TypeConverter(typeof(SkinConverter)), Category("Stock Chart"), DefaultValue("RedWhite")] public string Skin { get { return this.skin; } set { this.skin = value; this.NeedRebind(); } } [Browsable(false), DefaultValue(0), Category("Stock Chart Time")] public int StartBar { get { return this.chart.Start; } set { if (value < 0) { value = 0; } this.chart.Start = value; if (!this.chart.FixedTime) { this.chart.StartTime = DateTime.MinValue; this.chart.EndTime = DateTime.MaxValue; } this.NeedRedraw(); } } [Category("Stock Chart Time"), Description("Start time of the chart"), DefaultValue(typeof(DateTime), "1-1-1")] public DateTime StartTime { get { return this.startTime; } set { this.startTime = value; if (this.fixedTime || ((this.CurrentDataManager != null) && this.CurrentDataManager.VirtualFetch)) { this.NeedRebind(); } else { this.NeedRedraw(); } if (this.memoryCrossCursor) { this.needDrawCursor = true; } } } [DefaultValue(4), Description("Stick render type is used for Volumn Stick,Color Stick and Stick Line"), Category("Stock Chart")] public Easychart.Finance.StickRenderType StickRenderType { get { return this.stickRenderType; } set { this.stickRenderType = value; this.NeedRebind(); } } [Category("Stock Chart Time"), Description("This will take effect when EndTime is empty."), DefaultValue(150)] public int StockBars { get { return this.stockBars; } set { if (value < 1) { value = 1; } this.stockBars = value; this.NeedRedraw(); this.EndTime = DateTime.MinValue; } } [Description("Stock chart render type"), Category("Stock Chart"), DefaultValue(4)] public Easychart.Finance.StockRenderType StockRenderType { get { return this.stockRenderType; } set { this.stockRenderType = value; this.NeedRebind(); } } [DefaultValue("MSFT"), Description("Stock Symbol"), Category("Stock Chart")] public string Symbol { get { return this.symbol; } set { if (value != this.symbol) { this.symbol = value; this.NeedRebind(); } } } [Description("How to draw the value text"), DefaultValue(4), Category("Stock Chart")] public Easychart.Finance.ValueTextMode ValueTextMode { get { return this.valueTextMode; } set { this.valueTextMode = value; this.NeedRebind(); } } [Category("Stock Chart Mouse Zoom"), DefaultValue(0), Description("Position of the zoom center")] public ZoomCenterPosition ZoomPosition { get { return this.zoomPosition; } set { this.zoomPosition = value; } } #endregion Properties of ChartWinControl (55) #region Constructors of ChartWinControl (1) public ChartWinControl() { this.InitializeComponent(); this.Page = 10; this.LastCursorPos = -1; this.favoriteFormulas = new ArrayList(); this.EnableYScale = true; this.EnableXScale = true; this.EnableResize = true; this.chart = new FormulaChart { BitmapCache = true, LatestValueType = this.LatestValueType }; tickChart = new FormulaChart { BitmapCache = true, LatestValueType = this.LatestValueType }; tickChart.Areas.Clear(); tickChart.StringsToArea(tickChartFormulas.Split(new char[] { ';' })); this.showHorizontalGrid = ShowLineMode.HideAll; base.MouseWheel += new MouseEventHandler(this.ChartWinControl_MouseWheel); this.AfterApplySkin = (EventHandler)Delegate.Combine(this.AfterApplySkin, new EventHandler(this.ChartWinControl_AfterApplySkin)); this.chart.NativePaint += new NativePaintHandler(this.Chart_NativePaint); this.chart.ExtraPaint += new NativePaintHandler(this.Chart_ExtraPaint); this.chart.ViewChanged += new ViewChangedHandler(this.Chart_ViewChanged); this.chart.AddArea("MAIN", 3.0); this.FavoriteFormulas = "VOLMA;RSI;CCI;OBV;ATR;FastSTO;SlowSTO;ROC;TRIX;WR;AD;CMF;PPO;StochRSI;ULT;BBWidth;PVO"; this.CursorPosChanged = (Easychart.Finance.Win.CursorPosChanged)Delegate.Combine(this.CursorPosChanged, new Easychart.Finance.Win.CursorPosChanged(this.ShowStatisticWindow)); this.ehFavoriteIndicator = new EventHandler(this.mmFavorite_SelectedIndexChanged); this.CreateCycleMenu(); this.StatisticWindow.OnHide += new EventHandler(this.StatisticWindow_OnHide); } public ChartWinControl(DateTime[] openCloses,double lastClose) : this() { openCloseArray = openCloses; LastClose = lastClose; } #endregion Constructors of ChartWinControl (1) #region Methods of ChartWinControl (126) /// /// 销毁对象 /// public new void Dispose() { this.MouseWheel -= this.ChartWinControl_MouseWheel; this.StatisticWindow.OnHide -= this.StatisticWindow_OnHide; this.StatisticWindow.Dispose(); if (this.cmMain != null) this.cmMain.Dispose(); this.cmMain = null; if (this.cmRight != null) this.cmRight.Dispose(); this.cmRight = null; if (this.chart == null) return; this.chart.NativePaint -= this.Chart_NativePaint; this.chart.ExtraPaint -= this.Chart_ExtraPaint; this.chart.ViewChanged -= this.Chart_ViewChanged; this.chart.Dispose(); this.chart = null; if (ControlGraphics != null) ControlGraphics.Dispose(); ControlGraphics = null; if (components != null) components.Dispose(); components = null; if (CrossMemBmp != null) CrossMemBmp.Dispose(); CrossMemBmp = null; if (currentDataCycle != null) currentDataCycle.Dispose(); currentDataCycle = null; if (CurrentDataManager != null) CurrentDataManager.Dispose(); CurrentDataManager = null; if (defaultCursor != null) defaultCursor.Dispose(); defaultCursor = null; defaultFormulas = null; if (DragInfo != null) DragInfo.Dispose(); DragInfo = null; if (favoriteFormulas != null) favoriteFormulas.Clear(); favoriteFormulas = null; if (historyDataManager != null) historyDataManager.Dispose(); historyDataManager = null; if (intraDataManager != null) intraDataManager.Dispose(); intraDataManager = null; if (intradayInfo != null) intradayInfo.Dispose(); intradayInfo = null; LastProvider = null; if (MemBmp != null) MemBmp.Dispose(); MemBmp = null; if (miAddFormula != null) miAddFormula.Dispose(); miAddFormula = null; if (miAdjust != null) miAdjust.Dispose(); miAdjust = null; if (miAxisType != null) miAxisType.Dispose(); miAxisType = null; if (miCalculator != null) miCalculator.Dispose(); miCalculator = null; if (miChart != null) miChart.Dispose(); miChart = null; if (miChartCopy != null) miChartCopy.Dispose(); miChartCopy = null; if (miChartEdit != null) miChartEdit.Dispose(); miChartEdit = null; if (miCloseFormula != null) miCloseFormula.Dispose(); miCloseFormula = null; if (miCopy != null) miCopy.Dispose(); miCopy = null; if (miCrossCursor != null) miCrossCursor.Dispose(); miCrossCursor = null; if (miCycle != null) miCycle.Dispose(); miCycle = null; if (miEdit != null) miEdit.Dispose(); miEdit = null; if (miFavorite != null) miFavorite.Dispose(); miFavorite = null; if (miFormulaManager != null) miFormulaManager.Dispose(); miFormulaManager = null; if (miIndicator != null) miIndicator.Dispose(); miIndicator = null; if (miLog != null) miLog.Dispose(); miLog = null; if (miNormal != null) miNormal.Dispose(); miNormal = null; if (miSkin != null) miSkin.Dispose(); miSkin = null; if (miSp1 != null) miSp1.Dispose(); miSp1 = null; if (miSp2 != null) miSp2.Dispose(); miSp2 = null; if (miSp4 != null) miSp4.Dispose(); miSp4 = null; if (miStatistic != null) miStatistic.Dispose(); miStatistic = null; if (miStatisticWindow != null) miStatisticWindow.Dispose(); miStatisticWindow = null; if (miView != null) miView.Dispose(); miView = null; if (MouseZoomBmp != null) MouseZoomBmp.Dispose(); MouseZoomBmp = null; if (MouseZoomBmpG != null) MouseZoomBmpG.Dispose(); MouseZoomBmpG = null; if (previewDialog != null) previewDialog.Dispose(); previewDialog = null; if (printDialog != null) printDialog.Dispose(); printDialog = null; if (printDocument != null) printDocument.Dispose(); printDocument = null; if (setupDialog != null) setupDialog.Dispose(); setupDialog = null; if (UserSkin != null) UserSkin.Dispose(); UserSkin = null; base.Dispose(); } private void ApplySkin() { FormulaSkin skinByName = FormulaSkin.GetSkinByName(this.skin); this.ApplySkin(skinByName); } public void ApplySkin(FormulaSkin fs) { if (fs != null) { if (this.BeforeApplySkin != null) { this.BeforeApplySkin(this, fs); } this.chart.SetSkin(fs); this.chart[0].Back.TopPen.Width = this.ShowTopLine ? 1 : 0; this.chart[0].AxisY.Back.TopPen.Width = this.ShowTopLine ? 1 : 0; if (this.AfterApplySkin != null) { this.AfterApplySkin(this, new EventArgs()); } foreach (FormulaArea area in this.chart.Areas) { area.RemoveAutoMultiplyForStockYAxis(); } } } private void AreasToDefaultFormulas() { this.defaultFormulas = string.Join(";", this.chart.AreaToStrings()); } public void AutoAdjustYAxis() { foreach (FormulaArea area in this.chart.Areas) { foreach (FormulaAxisY sy in area.AxisYs) { this.AutoAdjustYAxis(sy); } } } public void AutoAdjustYAxis(FormulaAxisY fay) { this.MinPrice = 0.0; fay.AutoScale = true; this.NeedRedraw(); } public void AutoScaleAxisY() { foreach (FormulaArea area in this.chart.Areas) { foreach (FormulaAxisY sy in area.AxisYs) { sy.AutoScale = true; } } this.NeedRebind(); } public bool BindData() { bool flag = true; if ((this.HistoryDataManager != null) && (this.IntraDataManager != null)) { CommonDataProvider cdp = null; if (this.currentDataCycle.CycleBase >= DataCycleBase.DAY) { this.CurrentDataManager = this.HistoryDataManager; } else { this.CurrentDataManager = this.IntraDataManager; this.CurrentDataManager.IsFix = this.fixedTime; this.chart.FixedTime = this.fixedTime; } if (this.CurrentDataManager.VirtualFetch) { this.CurrentDataManager.StartTime = this.startTime; this.CurrentDataManager.EndTime = this.endTime; } flag = false; try { cdp = (CommonDataProvider)this.CurrentDataManager[this.symbol]; if (this.AfterBindData != null) { this.AfterBindData(this, new BindDataEventArgs(cdp, this.CurrentDataManager)); } flag = cdp != null; } catch { } if (cdp != null) { this.chart.SetDataProviderNoBind(cdp); } else { this.endTime = DateTime.MinValue; } if (this.fixedTime && (cdp != null)) { cdp.IntradayInfo = this.IntradayInfo; } if ((this.chart.DataProvider != null) && (this.chart.DataProvider is CommonDataProvider)) { if (this.HasData()) { if (this.chart.DataProvider.DataCycle.ToString() != this.currentDataCycle.ToString()) { this.ColumnWidth = 5.0; this.StartBar = 0; this.chart.DataProvider.DataCycle = this.currentDataCycle; } if (this.DataChanged != null) { this.DataChanged(this, new EventArgs()); } } (this.chart.DataProvider as CommonDataProvider).Adjusted = this.adjustData; } this.chart.SetAreaPercent(this.areaPercent); this.chart.Bind(); this.ApplySkin(); } return flag; } private void BuildFavoriteMenu() { this.cmRight.MenuItems.Remove(this.miFavorite); this.miFavorite = new MenuItem("&Favorite Indicators"); this.cmRight.MenuItems.Add(0, this.miFavorite); foreach (string str in this.favoriteFormulas) { this.miFavorite.MenuItems.Add(str, this.ehFavoriteIndicator); } } private void CancelMouseZoom() { if (this.MouseZoomBmp != null) { this.DragInfo = null; this.MouseZoomBmp = null; this.MouseZoomRect = Rectangle.Empty; } } private void ChangeCursorPos() { if (((this.chart != null) && (this.chart.DataProvider != null)) && ((this.LastCursorPos != this.chart.CursorPos) || (this.LastProvider != this.chart.DataProvider))) { IDataProvider dataProvider = this.chart.DataProvider; if ((this.chart.CursorPos >= 0) && (this.chart.CursorPos < dataProvider.Count)) { this.LastProvider = this.chart.DataProvider; this.LastCursorPos = this.chart.CursorPos; if (this.CursorPosChanged != null) { this.CursorPosChanged(this, this.chart, this.LastCursorPos, dataProvider); } } } } private void Chart_ExtraPaint(object sender, NativePaintArgs e) { if (this.ExtraPaint != null) { this.ExtraPaint(this, e); } } private void Chart_NativePaint(object sender, NativePaintArgs e) { if (this.NativePaint != null) { this.NativePaint(this, e); } } private void Chart_ViewChanged(object sender, ViewChangedArgs e) { if (this.ViewChanged != null) { this.ViewChanged(this, e); } } private void ChartWinControl_AfterApplySkin(object sender, EventArgs e) { this.chart.ExtendYAxis(TwoYAxisType.AreaSame); } private void ChartWinControl_DoubleClick(object sender, EventArgs e) { if (this.MouseDownInfo.HitType == FormulaHitType.htAxisY) { this.AutoAdjustYAxis(this.MouseDownInfo.AxisY); } } private void ChartWinControl_Enter(object sender, EventArgs e) { base.Invalidate(); } private void ChartWinControl_KeyDown(object sender, KeyEventArgs e) { int start; int cursorPos; if (this.chart != null) { start = this.chart.Start; cursorPos = this.chart.CursorPos; int num3 = e.Control ? this.Page : 1; switch (e.KeyCode) { case Keys.End: this.chart.AdjustCursorByPos(this.ControlGraphics, 0x7fffffff, this.chart.Start); e.Handled = true; goto Label_0221; case Keys.Home: this.chart.AdjustCursorByPos(this.ControlGraphics, 0, this.chart.Start); e.Handled = true; goto Label_0221; case Keys.Left: this.chart.AdjustCursorByPos(this.ControlGraphics, this.chart.CursorPos - num3, this.chart.Start + (e.Shift ? num3 : 0)); e.Handled = true; goto Label_0221; case Keys.Up: case Keys.Add: if (e.Control) { this.NextArea(-1); e.Handled = true; } else { this.ScaleChart(0.05); } goto Label_0221; case Keys.Right: this.chart.AdjustCursorByPos(this.ControlGraphics, this.chart.CursorPos + num3, this.chart.Start - (e.Shift ? num3 : 0)); e.Handled = true; goto Label_0221; case Keys.Down: case Keys.Subtract: if (e.Control) { this.NextArea(1); e.Handled = true; } else { this.ScaleChart(-0.05); } goto Label_0221; case Keys.Escape: this.CancelMouseZoom(); base.Invalidate(); break; case Keys.Multiply: this.NextFormula(1); e.Handled = true; goto Label_0221; case Keys.Divide: this.NextFormula(-1); e.Handled = true; goto Label_0221; case Keys.F7: case Keys.F8: this.NextCycle(1 - ((e.KeyCode == Keys.F8) ? 0 : 2)); e.Handled = true; goto Label_0221; } } return; Label_0221: if (e.Handled) { this.ChangeCursorPos(); } if ((cursorPos != this.chart.CursorPos) && (start != this.chart.Start)) { this.NeedRedraw(); } if (this.needRedraw) { if (start != this.chart.Start) { this.MoveChartXBars(3, 1, start - this.chart.Start); } e.Handled = true; this.needDrawCursor = true; } else { this.DrawCursorByPos(this.ControlGraphics); } } private void ChartWinControl_MouseDown(object sender, MouseEventArgs e) { this.MouseDownInfo = this.chart.GetHitInfo((float)e.X, (float)e.Y); if (this.MouseDownInfo.Area != null) { this.chart.SelectedArea = this.MouseDownInfo.Area; if ((this.selectFormulaMouseMode == MouseAction.MouseDown) && !this.Designing) { this.chart.SetSelectedData(this.MouseDownInfo); } if (((e.Button != MouseButtons.Right) && (this.CrossCursorMouseMode == MouseAction.MouseDown)) && !this.Designing) { this.MouseCrossCursor(this.ControlGraphics, this.MouseDownInfo); } this.NeedRedraw(); } if ((e.Button == MouseButtons.Right) && !this.Designing) { if (this.MouseZoomBmp != null) { this.CancelMouseZoom(); } else if (base.Visible) { ContextMenu cmRight = this.cmRight; if (!this.nativeContextMenu) { cmRight = this.ContextMenu; } if (cmRight != null) { cmRight.Show(this, new Point(e.X, e.Y)); } } } else if (!this.Designing) { this.DragInfo = new ChartDragInfo(this.chart, this.MouseDownInfo); if (((this.MouseDownInfo.HitType == FormulaHitType.htArea) && (this.mouseZoomMode != Easychart.Finance.Win.MouseZoomMode.None)) && !this.FixedTime) { this.LastX = e.X; this.LastY = e.Y; this.MemBmp = this.GetBitmap(false, true); this.MouseZoomBmp = new Bitmap(this.MemBmp.Width, this.MemBmp.Height, PixelFormat.Format32bppPArgb); this.MouseZoomBmpG = Graphics.FromImage(this.MouseZoomBmp); this.HideCursor(); } } } private void ChartWinControl_MouseLeave(object sender, EventArgs e) { if ((this.chart != null) && (this.CrossCursorMouseMode == MouseAction.MouseMove)) { this.HideCursor(); } } private void ChartWinControl_MouseMove(object sender, MouseEventArgs e) { try { if (this.Designing) { return; } int totalPart = 3 - ((this.ChartDragMode == Easychart.Finance.ChartDragMode.Chart) ? 1 : 0); if ((this.LastX == e.X) && (this.LastY == e.Y)) { return; } FormulaHitInfo hitInfo = this.chart.GetHitInfo((float)e.X, (float)e.Y); if (this.DragInfo != null) { float deltaY = this.DragInfo.HitInfo.Y - hitInfo.Y; float deltaX = this.DragInfo.HitInfo.X - hitInfo.X; FormulaArea fa = this.DragInfo.HitInfo.Area; if (this.MouseZoomBmp != null) { RectangleF fixedZoomRect; RectangleF ef2; if (this.FixedZoomRect != Rectangle.Empty) { fixedZoomRect = this.FixedZoomRect; fixedZoomRect.Offset((float)e.X, (float)e.Y); ef2 = this.FixedZoomRect; ef2.Offset((float)this.LastX, (float)this.LastY); } else { fixedZoomRect = this.GetRect(this.DragInfo.HitInfo.X, this.DragInfo.HitInfo.Y, (float)e.X, (float)e.Y); ef2 = this.GetRect(this.DragInfo.HitInfo.X, this.DragInfo.HitInfo.Y, (float)this.LastX, (float)this.LastY); } this.MouseZoomRect = RectangleF.Union(fixedZoomRect, ef2); this.MouseZoomBmpG.DrawImage(this.MemBmp, this.MouseZoomRect, this.MouseZoomRect, GraphicsUnit.Pixel); Rectangle rect = Rectangle.Truncate(fixedZoomRect); rect.Width--; rect.Height--; this.MouseZoomBmpG.DrawRectangle(Pens.Black, rect); if (this.mouseZoomBackColor.A != 0) { this.MouseZoomBmpG.FillRectangle(new SolidBrush(this.mouseZoomBackColor), rect); } this.ControlGraphics.DrawImage(this.MouseZoomBmp, this.MouseZoomRect, this.MouseZoomRect, GraphicsUnit.Pixel); } else if (this.EnableResize && (this.DragInfo.HitInfo.HitType == FormulaHitType.htSize)) { for (int i = 0; i < this.chart.Areas.Count; i++) { this.chart.Areas[i].HeightPercent = this.DragInfo.AreaHeight[i]; } int index = this.chart.Areas.IndexOf(fa); if (index < (this.chart.Areas.Count - 1)) { FormulaArea area2 = this.chart.Areas[index + 1]; double num6 = this.DragInfo.AreaHeight[index] - deltaY; double num7 = this.DragInfo.AreaHeight[index + 1] + deltaY; if (num6 < 40.0) { num7 -= 40.0 - num6; num6 = 40.0; } if (num7 < 40.0) { num6 -= 40.0 - num7; num7 = 40.0; } fa.HeightPercent = num6; area2.HeightPercent = num7; this.NeedRedraw(fa); this.NeedRedraw(area2); } this.areaPercent = this.chart.GetAreaPercent(); } else if (this.ChartDragMode != Easychart.Finance.ChartDragMode.None) { if ((this.EnableXScale && !this.chart.FixedTime) && (this.DragInfo.HitInfo.HitType == FormulaHitType.htAxisX)) { this.MoveChartX(fa, totalPart, this.DragInfo.HitInfo.XPart(totalPart), deltaX); } else if (this.EnableYScale && (this.DragInfo.HitInfo.HitType == FormulaHitType.htAxisY)) { this.MoveChartY(fa, totalPart, this.DragInfo.HitInfo.YPart(totalPart), deltaY); } else if ((this.ChartDragMode == Easychart.Finance.ChartDragMode.Chart) && (this.DragInfo.HitInfo.HitType == FormulaHitType.htArea)) { if (!this.chart.FixedTime) { this.MoveChartX(fa, 3, 1, deltaX); } this.MoveChartY(fa, 3, 1, deltaY); } } } else { if (this.CrossCursorMouseMode == MouseAction.MouseMove) { this.MouseCrossCursor(this.ControlGraphics, hitInfo); } if ((this.selectFormulaMouseMode == MouseAction.MouseMove) && !object.Equals(this.chart.GetSelectedData(), hitInfo.Data)) { this.chart.SetSelectedData(hitInfo); this.NeedRedraw(); } if (hitInfo.Area != null) { switch (hitInfo.HitType) { case FormulaHitType.htSize: if (this.EnableResize) { this.Cursor = Cursors.HSplit; } goto Label_05D3; case FormulaHitType.htAxisX: { if ((!this.EnableXScale || this.chart.FixedTime) || (this.ChartDragMode == Easychart.Finance.ChartDragMode.None)) { goto Label_0518; } int num8 = hitInfo.XPart(totalPart); if ((num8 != 0) && (num8 != (totalPart - 1))) { break; } this.Cursor = Cursors.SizeWE; goto Label_05D3; } case FormulaHitType.htAxisY: { if (!this.EnableYScale || (this.ChartDragMode == Easychart.Finance.ChartDragMode.None)) { goto Label_0568; } int num9 = hitInfo.YPart(totalPart); if ((num9 != 0) && (num9 != (totalPart - 1))) { goto Label_055B; } this.Cursor = Cursors.SizeNS; goto Label_05D3; } case FormulaHitType.htArea: if (this.selectFormulaMouseMode == MouseAction.None) { goto Label_05B7; } if (hitInfo.Formula == null) { goto Label_05A9; } this.Cursor = Cursors.Hand; goto Label_05D3; default: this.Cursor = this.DefaultCursor; goto Label_05D3; } this.Cursor = Cursors.Hand; } } goto Label_05D3; Label_0518: this.Cursor = this.DefaultCursor; goto Label_05D3; Label_055B: this.Cursor = Cursors.Hand; goto Label_05D3; Label_0568: this.Cursor = this.DefaultCursor; goto Label_05D3; Label_05A9: this.Cursor = this.DefaultCursor; goto Label_05D3; Label_05B7: this.Cursor = this.DefaultCursor; Label_05D3: this.LastX = e.X; this.LastY = e.Y; if (this.AfterMouseMove != null) { this.AfterMouseMove(this, e, hitInfo); } } catch { } } private void ChartWinControl_MouseUp(object sender, MouseEventArgs e) { if (this.DragInfo != null) { this.DragInfo = null; base.Invalidate(); } if (this.MouseZoomBmp != null) { if (((e.Button == MouseButtons.Left) && !this.MouseZoomRect.IsEmpty) && (this.MouseZoomRect.Width > 100f)) { FormulaHitInfo hitInfo = this.chart.GetHitInfo(this.MouseZoomRect.X, this.MouseZoomRect.Y); FormulaHitInfo info2 = this.chart.GetHitInfo(this.MouseZoomRect.Right, this.MouseZoomRect.Bottom); int cursorPos = hitInfo.CursorPos; int num2 = info2.CursorPos; if (this.chart.DataProvider != null) { double[] numArray = this.chart.DataProvider["DATE"]; if (cursorPos < numArray.Length) { this.StartTime = this.chart.IndexToDate(hitInfo.CursorPos); this.EndTime = this.chart.IndexToDate(info2.CursorPos); } } } this.MouseZoomBmp = null; this.MouseZoomRect = Rectangle.Empty; } } private void ChartWinControl_MouseWheel(object sender, MouseEventArgs e) { if (((this.mouseWheelMode != Easychart.Finance.Win.MouseWheelMode.None) && (this.chart != null)) && !this.FixedTime) { int moveBars = Math.Sign(e.Delta) * (((Control.ModifierKeys & Keys.Alt) != Keys.None) ? 1 : 12); if (this.mouseWheelMode == Easychart.Finance.Win.MouseWheelMode.Scroll) { this.MoveChartXBars(3, 1, moveBars); } //删除滑动放大 //else //{ // this.ScaleChart(((double)moveBars) / 100.0); //} this.needResetCursorPos = true; this.needDrawCursor = false; this.LastHitInfo = this.chart.GetHitInfo((float)e.X, (float)e.Y); } } private void ChartWinControl_Paint(object sender, PaintEventArgs e) { if (this.chart != null) { this.StatisticWindow.Visible = this.showStatistic && this.StatisticWindow.HasData(); if (this.needSetDefaultFormulas) { this.DefaultFormulasToAreas(); this.needSetDefaultFormulas = false; } if (this.needRefresh) { this.RecreateFormula(); } bool flag = true; if (this.needRebind) { flag = this.BindData(); } if (this.needRedraw && flag) { if (this.chart.FixedTime && (this.CurrentDataManager != null)) { this.chart.StartTime = this.startTime; this.chart.EndTime = this.endTime; } else if (this.chart.DataProvider != null) { double[] numArray = this.chart.DataProvider["DATE"]; if (this.endTime == DateTime.MinValue) { if (numArray.Length > 0) { this.chart.EndTime = DateTime.FromOADate(numArray[numArray.Length - 1]); this.chart.StartTime = DateTime.FromOADate(numArray[Math.Max(0, numArray.Length - this.stockBars)]); this.EndTime = this.chart.EndTime; this.StartTime = this.chart.StartTime; } } else { int num2; int num = this.chart.DateToIndex(this.endTime); if (this.afterBars < 1.0) { num2 = (int)((numArray.Length - 1) * (1.0 + this.afterBars)); } else { num2 = (numArray.Length - 1) + ((int)this.afterBars); } if (num > num2) { this.endTime = this.chart.IndexToDate(num2); } this.chart.StartTime = this.startTime; this.chart.EndTime = this.endTime; } } FormulaArea mainArea = this.chart.MainArea; if (mainArea != null) { if (this.minPrice > 0.0) { mainArea.AxisY.MinY = this.minPrice; mainArea.AxisY.MaxY = this.maxPrice; mainArea.AxisY.AutoScale = false; } if (this.stockRenderType != Easychart.Finance.StockRenderType.Default) { mainArea.StockRenderType = this.stockRenderType; } if (this.HasData() && (this.scaleType != Easychart.Finance.ScaleType.Default)) { mainArea.AxisY.Scale = this.scaleType; } } this.chart.ValueTextMode = this.valueTextMode; if (this.stickRenderType != Easychart.Finance.StickRenderType.Default) { this.chart.StickRenderType = this.stickRenderType; } this.chart.LatestValueType = this.latestValueType; this.chart.ShowCursorLabel = this.showCursorLabel; if (this.showVerticalGrid != ShowLineMode.Default) { if (this.showVerticalGrid == ShowLineMode.HidePrice) { mainArea.AxisY.MajorTick.ShowLine = false; } else { foreach (FormulaArea area2 in this.chart.Areas) { area2.AxisY.MajorTick.ShowLine = this.showVerticalGrid == ShowLineMode.Show; } } } if (this.showHorizontalGrid != ShowLineMode.Default) { if (this.showHorizontalGrid == ShowLineMode.HidePrice) { mainArea.AxisX.MajorTick.ShowLine = false; } else { foreach (FormulaArea area3 in this.chart.Areas) { area3.AxisX.MajorTick.ShowLine = this.showHorizontalGrid == ShowLineMode.Show; } } } this.chart.NeedRedraw = true; this.chart.ExtraNeedRedraw = true; } if (this.needResetCursorPos) { this.SetCursorPos(); this.ChangeCursorPos(); this.needResetCursorPos = false; } this.RenderChart(e.Graphics); this.needRedraw = false; this.needRebind = false; this.needRefresh = false; e.Graphics.Dispose(); } } private void ChartWinControl_SizeChanged(object sender, EventArgs e) { this.ControlGraphics = base.CreateGraphics(); if (this.chart != null) { Rectangle clientRectangle = base.ClientRectangle; this.chart.Rect = clientRectangle; } else { this.ControlGraphics.Clear(this.BackColor); } this.NeedRedraw(); } public void CloseArea(FormulaArea fa) { int index = this.chart.Areas.IndexOf(fa); if ((index >= 0) && (this.chart.Areas.Count > 1)) { this.chart.Areas.RemoveAt(index); this.areaPercent = this.chart.GetAreaPercent(); this.SaveChartProperties(); this.NeedRebind(); } } private void cmRight_Popup(object sender, EventArgs e) { this.miStatisticWindow.Checked = this.ShowStatistic; this.miAdjust.Checked = this.AdjustData; FormulaArea selectedArea = this.chart.SelectedArea; if (selectedArea != null) { this.miFavorite.Enabled = !selectedArea.IsMain(); if (selectedArea.Formulas.Count > 0) { foreach (MenuItem item in this.miFavorite.MenuItems) { item.Checked = string.Compare(item.Text, selectedArea.Formulas[0].Name, true) == 0; } } } } public void CopyAreaToClipboard(string Separatar) { Clipboard.SetDataObject(this.chart.GetAreaTextData(Separatar, true)); } public void CopyToClipboard(string Separatar) { Clipboard.SetDataObject(this.chart.GetChartTextData(Separatar, true)); } private void CreateCycleMenu() { if (this.favoriteCycles != null) { this.miCycle.MenuItems.Clear(); foreach (string str in this.favoriteCycles.Split(new char[] { ';' })) { this.miCycle.MenuItems.Add(str, new EventHandler(this.miCycle_SelectedIndexChanged)); } } } private void DefaultFormulasToAreas() { if (this.defaultFormulas != null) { this.chart.Areas.Clear(); this.chart.StringsToArea(this.defaultFormulas.Split(new char[] { ';' })); } } private static string DefaultSelectFormula(string Default, string[] FilterPrefixes, bool SelectLine) { return new SelectFormula().Select(Default, FilterPrefixes, SelectLine); } private static string DefaultSelectMethod(string Default) { return new SelectMethod().Select(Default); } protected override void Dispose(bool disposing) { if (disposing && (this.components != null)) { this.components.Dispose(); } base.Dispose(disposing); } public static string DoSelectFormula(string Default, string[] FilterPrefixes, bool SelectLine) { if (OnSelectFormula != null) { return OnSelectFormula(Default, FilterPrefixes, SelectLine); } return Default; } public static string DoSelectSymbol(string Default) { if (OnSelectSymbol != null) { return OnSelectSymbol(Default); } return Default; } private void DrawCursor(Graphics g) { this.chart.DrawCursor(g, this.LastHitInfo.X, this.LastHitInfo.Y, false); } private void DrawCursorByPos(Graphics g) { this.DrawCursorByPos(g, float.NaN); } private void DrawCursorByPos(Graphics g, float DefaultY) { float num; float num2; this.chart.GetXYFromPos(out num, out num2); this.LastHitInfo = this.chart.GetHitInfo(num, num2); if (!float.IsNaN(DefaultY)) { this.LastHitInfo.Y = DefaultY; } if ((this.LastHitInfo.HitType == FormulaHitType.htArea) && (g != null)) { this.DrawCursor(g); } else { this.LastHitInfo.X = -1f; } } public void DrawCursorByTime(DateTime t) { int num = this.chart.DateToIndex(t.ToOADate()); if (num != this.chart.CursorPos) { this.chart.CursorPos = num; this.DrawCursorByPos(this.ControlGraphics, -1f); this.ChangeCursorPos(); } } public void EditFormula() { FormulaArea selectedArea = this.chart.SelectedArea; if ((selectedArea != null) && (selectedArea.Formulas.Count > 0)) { FormulaBase fb = null; if (selectedArea.SelectedFormula != null) { fb = selectedArea.SelectedFormula; } else { fb = selectedArea.Formulas[0]; } if (EditFormula(fb)) { return; } } MessageBox.Show("Can't edit the source code of this formula"); } public void EditFormula(FormulaArea fa) { if (fa != null) { FormulaManager manager = new FormulaManager(); if (manager.ShowForm(fa, fa.SelectedFormula) == DialogResult.OK) { this.SetAreaByName(fa, manager.CurrentFormulas); } } else { this.EditOverlay(); } } public static bool EditFormula(FormulaBase fb) { string formulaFile = PluginManager.GetFormulaFile(fb); if (formulaFile != null) { string directoryName = Path.GetDirectoryName(formulaFile); formulaFile = Path.GetFileNameWithoutExtension(formulaFile).Replace('_', '.'); formulaFile = directoryName + @"\" + formulaFile; if (File.Exists(formulaFile)) { OpenFormulaSourceEditor(formulaFile, fb.GetType().ToString()); return true; } } return false; } public void EditOverlay() { } private void ExpandDefaultFormulas(int Count) { double percent = this.chart.Areas[0].HeightPercent / 3.0; if (percent < 1.0) { percent = 1.0; } while (Count > this.chart.Areas.Count) { this.chart.AddArea("VOLMA", percent); } } public MenuItem GetAreaMenu(int Count) { this.miIndicator.MenuItems.Clear(); for (int i = 0; i < Count; i++) { this.miIndicator.MenuItems.Add(new MenuItem(string.Concat(new object[] { "&", i + 1, " area", (i > 0) ? "s" : "" }), new EventHandler(this.miIndicator_SelectedIndexChanged), (Shortcut)(0x40031 + i))); } return this.miIndicator; } public MenuItem GetAxisMenu() { return this.miAxisType; } public Bitmap GetBitmap(bool ShowStatistic, bool ShowExtra) { this.chart.ExtraNeedRedraw = ShowExtra; Bitmap memBitmap = this.chart.GetMemBitmap(); Bitmap image = new Bitmap(memBitmap); Graphics g = Graphics.FromImage(image); g.DrawImage(memBitmap, 0, 0); g.DrawLine(Pens.Black, 0, 0, image.Width, 0); if (ShowStatistic) { this.StatisticWindow.PaintTo(g); } return image; } public MenuItem GetChartMenu() { return this.GetChartMenu(true, true, true, true); } public MenuItem GetChartMenu(bool Skin, bool Cycle, bool Area, bool Axis) { this.miChart.MenuItems.Clear(); if (Skin) { this.miChart.MenuItems.Add(this.GetSkinMenu()); } if (Cycle) { this.miChart.MenuItems.Add(this.miCycle); } if (Area) { this.miChart.MenuItems.Add(this.GetAreaMenu(9)); } if (Axis) { this.miChart.MenuItems.Add(this.GetAxisMenu()); } return this.miChart; } public DateTime GetCurrentTime() { return this.chart.IndexToDate(); } public MenuItem GetEditMenu() { return this.miChartEdit; } private RectangleF GetRect(float x1, float y1, float x2, float y2) { return new RectangleF(Math.Min(x1, x2), Math.Min(y1, y2), Math.Abs((float)(x2 - x1)), Math.Abs((float)(y2 - y1))); } public MenuItem GetSkinMenu() { string[] buildInSkins = FormulaSkin.GetBuildInSkins(); this.miSkin.MenuItems.Clear(); foreach (string str in buildInSkins) { this.miSkin.MenuItems.Add(str, new EventHandler(this.mmSkin_SelectedIndexChanged)); } return this.miSkin; } public MenuItem GetViewMenu() { return this.miView; } public void HandleKeyEvent(object sender, KeyEventArgs e) { if (base.ContainsFocus) { this.OnKeyDown(e); } } private bool HasData() { return ((this.chart != null) && (this.chart.DataProvider != null)); } private void HideCursor() { this.chart.HideCursor(this.ControlGraphics); } private void InitializeComponent() { this.cmRight = new System.Windows.Forms.ContextMenu(); this.miAddFormula = new System.Windows.Forms.MenuItem(); this.miCloseFormula = new System.Windows.Forms.MenuItem(); this.miFormulaManager = new System.Windows.Forms.MenuItem(); this.miEdit = new System.Windows.Forms.MenuItem(); this.miFavorite = new System.Windows.Forms.MenuItem(); this.miSp4 = new System.Windows.Forms.MenuItem(); this.miStatisticWindow = new System.Windows.Forms.MenuItem(); this.miAdjust = new System.Windows.Forms.MenuItem(); this.miSp2 = new System.Windows.Forms.MenuItem(); this.miCopy = new System.Windows.Forms.MenuItem(); this.cmMain = new System.Windows.Forms.ContextMenu(); this.miChart = new System.Windows.Forms.MenuItem(); this.miSkin = new System.Windows.Forms.MenuItem(); this.miCycle = new System.Windows.Forms.MenuItem(); this.miIndicator = new System.Windows.Forms.MenuItem(); this.miAxisType = new System.Windows.Forms.MenuItem(); this.miNormal = new System.Windows.Forms.MenuItem(); this.miLog = new System.Windows.Forms.MenuItem(); this.miView = new System.Windows.Forms.MenuItem(); this.miCrossCursor = new System.Windows.Forms.MenuItem(); this.miStatistic = new System.Windows.Forms.MenuItem(); this.miSp1 = new System.Windows.Forms.MenuItem(); this.miCalculator = new System.Windows.Forms.MenuItem(); this.miChartEdit = new System.Windows.Forms.MenuItem(); this.miChartCopy = new System.Windows.Forms.MenuItem(); this.StatisticWindow = new Easychart.Finance.Win.StatisticControl(); this.SuspendLayout(); // // cmRight // this.cmRight.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miAddFormula, this.miCloseFormula, this.miFormulaManager, this.miEdit, this.miFavorite, this.miSp4, this.miStatisticWindow, this.miAdjust, this.miSp2, this.miCopy}); this.cmRight.Popup += new System.EventHandler(this.cmRight_Popup); // // miAddFormula // this.miAddFormula.Index = 0; this.miAddFormula.Text = "&Add New Formula Area"; this.miAddFormula.Click += new System.EventHandler(this.miAddFormula_Click); // // miCloseFormula // this.miCloseFormula.Index = 1; this.miCloseFormula.MergeOrder = 10; this.miCloseFormula.Text = "Close Selected Formula"; this.miCloseFormula.Click += new System.EventHandler(this.miCloseFormula_Click); // // miFormulaManager // this.miFormulaManager.Index = 2; this.miFormulaManager.MergeOrder = 20; this.miFormulaManager.Text = "E&dit Formula"; this.miFormulaManager.Click += new System.EventHandler(this.miFormulaEditor_Click); // // miEdit // this.miEdit.Index = 3; this.miEdit.MergeOrder = 30; this.miEdit.Shortcut = System.Windows.Forms.Shortcut.CtrlE; this.miEdit.Text = "&Edit Formula Source Code"; this.miEdit.Click += new System.EventHandler(this.miEdit_Click); // // miFavorite // this.miFavorite.Index = 4; this.miFavorite.MergeOrder = 40; this.miFavorite.Text = "&Favorite Indicators"; // // miSp4 // this.miSp4.Index = 5; this.miSp4.MergeOrder = 50; this.miSp4.Text = "-"; // // miStatisticWindow // this.miStatisticWindow.Index = 6; this.miStatisticWindow.MergeOrder = 80; this.miStatisticWindow.Text = "Show &statistic window"; this.miStatisticWindow.Click += new System.EventHandler(this.miStatisticWindow_Click); // // miAdjust // this.miAdjust.Index = 7; this.miAdjust.MergeOrder = 90; this.miAdjust.Text = "&Adjust Data"; this.miAdjust.Click += new System.EventHandler(this.miAdjust_Click); // // miSp2 // this.miSp2.Index = 8; this.miSp2.MergeOrder = 100; this.miSp2.Text = "-"; // // miCopy // this.miCopy.Index = 9; this.miCopy.MergeOrder = 110; this.miCopy.Shortcut = System.Windows.Forms.Shortcut.CtrlC; this.miCopy.Text = "&Copy"; this.miCopy.Click += new System.EventHandler(this.miCopy_Click); // // cmMain // this.cmMain.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miChart, this.miView, this.miChartEdit}); // // miChart // this.miChart.Index = 0; this.miChart.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miSkin, this.miCycle, this.miIndicator, this.miAxisType}); this.miChart.Text = "&Chart"; // // miSkin // this.miSkin.Index = 0; this.miSkin.Text = "&Skin"; // // miCycle // this.miCycle.Index = 1; this.miCycle.Text = "&Cycle"; this.miCycle.Click += new System.EventHandler(this.miCycle_Popup); // // miIndicator // this.miIndicator.Index = 2; this.miIndicator.Text = "&Indicator Areas"; // // miAxisType // this.miAxisType.Index = 3; this.miAxisType.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miNormal, this.miLog}); this.miAxisType.Text = "&Axis Type"; // // miNormal // this.miNormal.Index = 0; this.miNormal.RadioCheck = true; this.miNormal.Shortcut = System.Windows.Forms.Shortcut.CtrlN; this.miNormal.Text = "Normal"; this.miNormal.Click += new System.EventHandler(this.miNormalAxis_Click); // // miLog // this.miLog.Index = 1; this.miLog.MergeOrder = 1; this.miLog.RadioCheck = true; this.miLog.Shortcut = System.Windows.Forms.Shortcut.CtrlL; this.miLog.Text = "Logarithm"; this.miLog.Click += new System.EventHandler(this.miNormalAxis_Click); // // miView // this.miView.Index = 1; this.miView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miCrossCursor, this.miStatistic, this.miSp1, this.miCalculator}); this.miView.Text = "&View"; this.miView.Popup += new System.EventHandler(this.miView_Popup); // // miCrossCursor // this.miCrossCursor.Checked = true; this.miCrossCursor.Index = 0; this.miCrossCursor.Text = "Cross Cursor"; this.miCrossCursor.Click += new System.EventHandler(this.miCrossCursor_Click); // // miStatistic // this.miStatistic.Index = 1; this.miStatistic.Text = "Statistic Window"; this.miStatistic.Click += new System.EventHandler(this.miStatistic_Click); // // miSp1 // this.miSp1.Index = 2; this.miSp1.Text = "-"; // // miCalculator // this.miCalculator.Index = 3; this.miCalculator.Shortcut = System.Windows.Forms.Shortcut.CtrlJ; this.miCalculator.Text = "&Calculator"; this.miCalculator.Click += new System.EventHandler(this.miCalculator_Click); // // miChartEdit // this.miChartEdit.Index = 2; this.miChartEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miChartCopy}); this.miChartEdit.Text = "&Edit"; // // miChartCopy // this.miChartCopy.Index = 0; this.miChartCopy.Text = "&Copy"; this.miChartCopy.Click += new System.EventHandler(this.miChartCopy_Click); // // StatisticWindow // this.StatisticWindow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.StatisticWindow.BackColor = System.Drawing.SystemColors.Info; this.StatisticWindow.Cursor = System.Windows.Forms.Cursors.Arrow; this.StatisticWindow.ForeColor = System.Drawing.Color.Black; this.StatisticWindow.Location = new System.Drawing.Point(-1000, 35); this.StatisticWindow.Name = "StatisticWindow"; this.StatisticWindow.Size = new System.Drawing.Size(192, 296); this.StatisticWindow.TabIndex = 0; this.StatisticWindow.Visible = false; // // ChartWinControl // this.CausesValidation = false; this.Controls.Add(this.StatisticWindow); this.Name = "ChartWinControl"; this.Size = new System.Drawing.Size(584, 427); this.SizeChanged += new System.EventHandler(this.ChartWinControl_SizeChanged); this.Paint += new System.Windows.Forms.PaintEventHandler(this.ChartWinControl_Paint); this.DoubleClick += new System.EventHandler(this.ChartWinControl_DoubleClick); this.Enter += new System.EventHandler(this.ChartWinControl_Enter); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ChartWinControl_KeyDown); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ChartWinControl_MouseDown); this.MouseLeave += new System.EventHandler(this.ChartWinControl_MouseLeave); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ChartWinControl_MouseMove); this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ChartWinControl_MouseUp); this.ResumeLayout(false); } public void InsertNewFormula() { this.InsertNewFormula(""); } public void InsertNewFormula(string Default) { FormulaArea fa = new FormulaArea(this.chart); FormulaManager manager = new FormulaManager(); manager.CurrentFormulas = Default; if (manager.ShowForm() == DialogResult.OK) { fa.HeightPercent = this.chart[0].HeightPercent / 3.0; this.chart.Areas.Add(fa); this.SetAreaByName(fa, manager.CurrentFormulas); this.NeedRebind(); } } private void InvalidateHitInfo(FormulaHitInfo fhi) { Region region = new Region(new RectangleF(fhi.X - 1f, 0f, 2f, (float)this.chart.Rect.Height)); region.Union(new RectangleF(0f, fhi.Y - 1f, (float)this.chart.Rect.Width, 2f)); foreach (FormulaArea area in this.chart.Areas) { RectangleF lastCursorRect = area.AxisX.LastCursorRect; region.Union(new RectangleF(fhi.X - lastCursorRect.Width, lastCursorRect.Y, lastCursorRect.Width * 2f, lastCursorRect.Height)); region.Union(new RectangleF((float)area.Rect.X, (float)area.Rect.Y, (float)area.Rect.Width, 20f)); foreach (FormulaAxisY sy in area.AxisYs) { lastCursorRect = sy.LastCursorRect; if (!lastCursorRect.IsEmpty) { region.Union(new RectangleF(lastCursorRect.X, fhi.Y, lastCursorRect.Width, lastCursorRect.Height)); } } } base.Invalidate(region); } public void MergeRightMenu(ContextMenu cm) { this.cmRight.MergeMenu(cm); } /// /// hulu /// /// /// public void mi_Checked(MenuItem mi) { foreach (MenuItem item in this.miSkin.MenuItems) { item.Checked = false; } //MenuItem item2 = mi; mi.Checked = true; string text = mi.Text; this.Skin = text; } private void miAddFormula_Click(object sender, EventArgs e) { this.InsertNewFormula(); } private void miAdjust_Click(object sender, EventArgs e) { this.AdjustData = !this.AdjustData; } private void miCalculator_Click(object sender, EventArgs e) { Process.Start("Calc.exe"); } private void miChartCopy_Click(object sender, EventArgs e) { this.CopyToClipboard(","); } private void miCloseFormula_Click(object sender, EventArgs e) { this.CloseArea(this.chart.SelectedArea); } private void miCopy_Click(object sender, EventArgs e) { this.CopyAreaToClipboard(","); } private void miCrossCursor_Click(object sender, EventArgs e) { this.ShowCrossCursor = !this.ShowCrossCursor; } private void miCycle_Popup(object sender, EventArgs e) { foreach (MenuItem item in this.miCycle.MenuItems) { item.Checked = item.Text == this.currentDataCycle.ToString(); } } private void miCycle_SelectedIndexChanged(object sender, EventArgs e) { this.EndTime = DateTime.MinValue; this.CurrentDataCycle = DataCycle.Parse((sender as MenuItem).Text); } private void miEdit_Click(object sender, EventArgs e) { this.EditFormula(); } private void miFormulaEditor_Click(object sender, EventArgs e) { this.EditFormula(this.chart.SelectedArea); } private void miIndicator_SelectedIndexChanged(object sender, EventArgs e) { this.AreaCount = (sender as MenuItem).Index + 1; } private void miNormalAxis_Click(object sender, EventArgs e) { foreach (MenuItem item in this.miAxisType.MenuItems) { item.Checked = false; } MenuItem item2 = sender as MenuItem; item2.Checked = true; this.ScaleType = (Easychart.Finance.ScaleType)item2.MergeOrder; } private void miOverlay_Click(object sender, EventArgs e) { this.EditOverlay(); } private void miStatistic_Click(object sender, EventArgs e) { this.ShowStatistic = !this.ShowStatistic; } private void miStatisticWindow_Click(object sender, EventArgs e) { this.ShowStatistic = !this.ShowStatistic; } private void miView_Popup(object sender, EventArgs e) { this.miStatistic.Checked = this.ShowStatistic; } private void mmFavorite_SelectedIndexChanged(object sender, EventArgs e) { FormulaArea selectedArea = this.chart.SelectedArea; if ((selectedArea != null) && !selectedArea.IsMain()) { this.SetAreaByName(selectedArea, (sender as MenuItem).Text); } } private void mmSkin_SelectedIndexChanged(object sender, EventArgs e) { foreach (MenuItem item in this.miSkin.MenuItems) { item.Checked = false; } MenuItem item2 = (MenuItem)sender; item2.Checked = true; string text = item2.Text; this.Skin = text; } private void MouseCrossCursor(Graphics g, FormulaHitInfo HitInfo) { if (!this.Designing) { if (HitInfo.HitType == FormulaHitType.htArea) { this.chart.CursorPos = HitInfo.CursorPos; if (this.memoryCrossCursor) { this.InvalidateHitInfo(this.LastHitInfo); this.InvalidateHitInfo(HitInfo); } else { this.chart.DrawCursor(g, HitInfo.X, HitInfo.Y, false); } this.ChangeCursorPos(); this.LastHitInfo = HitInfo; } else { this.HideCursor(); this.LastHitInfo.X = 0f; } } } public void MoveArea(FormulaArea fa, int NewIndex) { int index = this.chart.Areas.IndexOf(fa); if (index >= 0) { if (NewIndex > index) { NewIndex--; } if (NewIndex >= 0) { this.chart.Areas.RemoveAt(index); if (NewIndex > this.chart.Areas.Count) { NewIndex = this.chart.Areas.Count; } this.chart.Areas.Insert(NewIndex, fa); this.areaPercent = this.chart.GetAreaPercent(); this.SaveChartProperties(); this.NeedRebind(); } } } public void MoveAreaDown(FormulaArea fa) { int index = this.chart.Areas.IndexOf(fa); this.MoveArea(fa, index + 2); } public void MoveAreaUp(FormulaArea fa) { int index = this.chart.Areas.IndexOf(fa); this.MoveArea(fa, index - 1); } private void MoveChartX(FormulaArea fa, int TotalPart, int CurrentPart, float DeltaX) { if (DeltaX != 0f) { if (this.EndTime == DateTime.MinValue) { this.EndTime = this.chart.EndTime; this.StartTime = this.chart.StartTime; } int num = this.chart.DateToIndex(this.chart.EndTime, -1); int num2 = this.chart.DateToIndex(this.chart.StartTime); double num3 = (num - num2) + 1; int moveBars = (int)((num3 * DeltaX) / ((double)fa.Rect.Width)); this.MoveChartXBars(TotalPart, CurrentPart, this.DragInfo.StartTime, this.DragInfo.EndTime, moveBars); } } public void MoveChartXBars(int MoveBars) { this.MoveChartXBars(3, 1, MoveBars); } private void MoveChartXBars(int TotalPart, int CurrentPart, int MoveBars) { this.MoveChartXBars(TotalPart, CurrentPart, this.chart.StartTime, this.chart.EndTime, MoveBars); } private void MoveChartXBars(int TotalPart, int CurrentPart, DateTime StartTime, DateTime EndTime, int MoveBars) { if ((this.chart != null) && (this.chart.DataProvider != null)) { double[] numArray = this.chart.DataProvider["DATE"]; DateTime startTime = this.StartTime; DateTime endTime = this.EndTime; bool flag = false; if (CurrentPart > 0) { int i = this.chart.DateToIndex(EndTime, -1) + MoveBars; if (i < 0) { i = 0; flag = true; } if (this.chart.CursorPos > i) { this.chart.CursorPos = i; this.ChangeCursorPos(); } this.EndTime = this.chart.IndexToDate(i); } if (CurrentPart < (TotalPart - 1)) { int num2 = this.chart.DateToIndex(StartTime) + MoveBars; if (num2 >= (numArray.Length - 1)) { num2 = numArray.Length - 2; flag = true; } if (num2 < 0) { num2 = 0; } if (this.chart.CursorPos < num2) { this.chart.CursorPos = num2; this.ChangeCursorPos(); } this.StartTime = this.chart.IndexToDate(num2); } if (flag && (CurrentPart == 1)) { this.StartTime = startTime; this.EndTime = endTime; } if (this.resetYAfterXChanged) { FormulaArea mainArea = this.chart.MainArea; if (mainArea != null) { this.minPrice = 0.0; mainArea.AxisY.AutoScale = true; } } if ((this.CurrentDataManager != null) && this.CurrentDataManager.VirtualFetch) { this.NeedRebind(); } } } private void MoveChartY(FormulaArea fa, int Part, int CurrentPart, float DeltaY) { if (DeltaY != 0f) { FormulaAxisY axisY = this.DragInfo.HitInfo.AxisY; if (axisY == null) { axisY = fa.AxisY; } axisY.AutoScale = false; double num = ((this.DragInfo.AreaMaxY - this.DragInfo.AreaMinY) / ((double)fa.Rect.Height)) * DeltaY; if (CurrentPart > 0) { axisY.MinY = this.DragInfo.AreaMinY - num; } if (CurrentPart < (Part - 1)) { axisY.MaxY = this.DragInfo.AreaMaxY - num; } this.minPrice = 0.0; this.maxPrice = 0.0; this.NeedRedraw(fa); } } public void NeedRebind() { this.NeedRebind(true); } public void NeedRebind(bool AutoScaleY) { this.NeedRebind(AutoScaleY, false); } private void NeedRebind(bool AutoScaleY, bool DrawLastBarOnly) { this.needAutoScaleY = AutoScaleY; this.needDrawLastBarOnly = DrawLastBarOnly; this.needRedraw = true; this.needRebind = true; base.Invalidate(); } public void NeedRedraw() { this.NeedRedraw(null); } public void NeedRedraw(FormulaArea fa) { this.needRedraw = true; if (fa != null) { Rectangle rect = fa.Rect; rect.Inflate(1, 1); base.Invalidate(rect); } else { base.Invalidate(); } } public void NeedRefresh() { this.needRedraw = true; this.needRebind = true; this.needRefresh = true; base.Invalidate(); } private void NextArea(int Delta) { int num = ((this.chart.Areas.IndexOf(this.chart.SelectedArea) + Delta) + this.chart.Areas.Count) % this.chart.Areas.Count; if (num < this.chart.Areas.Count) { this.chart.SelectedArea = this.chart[num]; } this.NeedRedraw(); } private void NextCycle(int Delta) { if ((this.favoriteCycles != null) && (this.favoriteCycles != "")) { ArrayList list = new ArrayList(); list.AddRange(this.favoriteCycles.Split(new char[] { ';' })); int index = list.IndexOf(this.CurrentDataCycle.ToString()); if (index < 0) { index = 0; } index = ((index + Delta) + list.Count) % list.Count; if (!this.fixedTime) { this.EndTime = DateTime.MinValue; } this.CurrentDataCycle = DataCycle.Parse(list[index].ToString()); } } private void NextFormula(int Delta) { int index = this.chart.Areas.IndexOf(this.chart.SelectedArea); if (index < 0) { index = this.chart.Areas.Count - 1; } if (index >= 0) { FormulaArea area = this.chart[index]; if (!area.IsMain()) { string str = area.FormulaToString('#'); int length = str.IndexOf('('); if (length >= 0) { str = str.Substring(0, length); } int num3 = -1; for (int i = 0; i < this.favoriteFormulas.Count; i++) { if (string.Compare(str, (string)this.favoriteFormulas[i], true) == 0) { num3 = i; } } if (num3 < 0) { num3 = 0; } num3 = ((num3 + Delta) + this.favoriteFormulas.Count) % this.favoriteFormulas.Count; this.SetAreaByName(index, (string)this.favoriteFormulas[num3]); this.NeedRebind(); } } } protected override void OnPaintBackground(PaintEventArgs pevent) { if ((this.chart == null) || (this.chart.DataProvider == null)) { base.OnPaintBackground(pevent); } } public static void OpenFormulaSourceEditor() { OpenFormulaSourceEditor("", ""); } public static void OpenFormulaSourceEditor(string Filename, string Formula) { FormulaSourceEditor.Open(Filename, Formula); } public void Print() { this.SetupPrinting(); if (this.printDialog.ShowDialog() == DialogResult.OK) { this.printDocument.Print(); } } private void printDocument_PrintPage(object sender, PrintPageEventArgs e) { Bitmap image = this.GetBitmap(true, true); e.Graphics.DrawImage(image, e.MarginBounds, new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel); } public void PrintPreview() { this.SetupPrinting(); this.previewDialog.ShowDialog(); } public void PrintSetup() { this.SetupPrinting(); this.setupDialog.ShowDialog(); } private void RebindLastBar() { this.needDrawLastBarOnly = true; this.BindData(); this.RenderChart(this.ControlGraphics); } private void RecreateFormula() { if (this.chart != null) { foreach (FormulaArea area in this.chart.Areas) { this.RecreateFormula(area); } } this.SaveChartProperties(); } private void RecreateFormula(FormulaArea fa) { string[] ss = fa.FormulaToStrings(); fa.Formulas.Clear(); fa.StringsToFormula(ss); } public void RenderChart(Graphics g) { Graphics graphics = g; if (this.memoryCrossCursor) { Rectangle rect = this.chart.Rect; if (((this.CrossMemBmp == null) || (this.CrossMemBmp.Width != rect.Width)) || (this.CrossMemBmp.Height != rect.Height)) { this.CrossMemBmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppPArgb); this.CrossMemBmpG = Graphics.FromImage(this.CrossMemBmp); } Region r = null; if (this.needDrawLastBarOnly && this.needRebind) { r = new Region(); r.MakeEmpty(); } g = this.CrossMemBmpG; g.SetClip(graphics); this.chart.Render(g, r); graphics.SetClip(g); if (this.LastHitInfo.X != 0f) { if (this.needRebind) { this.SetCursorPos(); } if (this.needDrawCursor) { this.DrawCursorByPos(g); this.needDrawCursor = false; } else { this.DrawCursor(g); } } } else { this.chart.Render(g); if (this.needDrawCursor) { this.chart.DrawCursor(g); this.needDrawCursor = false; } else if ((this.crossCursorMouseMode == MouseAction.MouseDown) && (this.LastHitInfo.X != 0f)) { this.LastHitInfo = this.chart.GetHitInfo(this.LastHitInfo.X, this.LastHitInfo.Y); this.MouseCrossCursor(this.ControlGraphics, this.LastHitInfo); } } if (this.MouseZoomBmp != null) { g.DrawImage(this.MouseZoomBmp, this.MouseZoomRect, this.MouseZoomRect, GraphicsUnit.Pixel); } if (this.memoryCrossCursor) { graphics.DrawImage(this.CrossMemBmp, 0, 0); } } public void Reset(int columnWidth) { this.EndTime = DateTime.MinValue; this.StockBars = base.Width / columnWidth; this.AutoScaleAxisY(); } public void SaveChartProperties() { this.AreasToDefaultFormulas(); this.areaPercent = this.chart.GetAreaPercent(); } public void ScaleChart(double ScaleFactor) { if ((this.chart != null) && !this.chart.FixedTime) { int moveBars = (int)((this.chart.GetTotalBars() * ScaleFactor) + 0.5); if (moveBars == 0) { if (ScaleFactor > 0.0) { moveBars = 1; } else { moveBars = -1; } } int num3 = -moveBars; if (this.zoomPosition == ZoomCenterPosition.Left) { moveBars = 0; } if (this.zoomPosition == ZoomCenterPosition.Right) { num3 = 0; } this.MoveChartXBars(3, 0, moveBars); this.MoveChartXBars(3, 2, num3); } } public void SetAreaByName(string FormulaName) { FormulaArea selectedArea = this.chart.SelectedArea; if (selectedArea == null) { selectedArea = this.chart.Areas[this.chart.Areas.Count - 1]; } this.SetAreaByName(selectedArea, FormulaName); } public void SetAreaByName(FormulaArea fa, string FormulaName) { if (fa != null) { int index = this.chart.Areas.IndexOf(fa); if (index >= 0) { string s = fa.FormulaToString('#'); try { this.SetDefaultFormulas(index, FormulaName); } catch { this.SetDefaultFormulas(index, s); throw; } this.SaveChartProperties(); this.NeedRebind(); //todo:重新赋值行情格式化字符串-Daniel //this.chart.MainArea.AxisY.Format = "f" + _quoteDigits; //this.NeedRedraw(this.chart.MainArea); } } } public void SetAreaByName(int AreaIndex, string FormulaName) { if ((AreaIndex >= 0) && (AreaIndex < this.chart.Areas.Count)) { this.SetAreaByName(this.chart.Areas[AreaIndex], FormulaName); } } private void SetAreaCount(int Count) { if (this.chart.Areas.Count != Count) { while (this.chart.Areas.Count > Count) { this.chart.Areas.RemoveAt(Count); } int num = this.chart.Areas.Count; this.ExpandDefaultFormulas(Count); double num2 = 1.0; if (this.chart.Areas.Count > 0) { num2 = this.chart[0].HeightPercent / 3.0; } for (int i = num; i < this.chart.Areas.Count; i++) { this.chart[i].HeightPercent = num2; } this.areaPercent = this.chart.GetAreaPercent(); this.NeedRebind(); } this.UseDefaultFormulas(false); } private void SetCursorPos() { this.chart.CursorPos = this.LastHitInfo.CursorPos; } private void SetDefaultFormulas(int Index, string s) { this.ExpandDefaultFormulas(Index); this.chart[Index].Formulas.Clear(); this.chart[Index].StringToFormula(s, '#'); } private void SetupPrinting() { if (this.printDialog == null) { this.printDialog = new PrintDialog(); this.printDocument = new PrintDocument(); this.previewDialog = new PrintPreviewDialog(); this.setupDialog = new PageSetupDialog(); this.printDocument.DefaultPageSettings.Landscape = true; this.printDocument.DefaultPageSettings.Margins = new Margins(30, 30, 30, 30); this.printDialog.Document = this.printDocument; this.printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage); this.previewDialog.Document = this.printDocument; this.setupDialog.Document = this.printDocument; } } public void ShowAllBars() { if ((this.chart != null) && (this.chart.DataProvider != null)) { double[] numArray = this.chart.DataProvider["DATE"]; if (numArray.Length > 0) { this.StartTime = DateTime.FromOADate(numArray[0]); this.EndTime = DateTime.FromOADate(numArray[numArray.Length - 1]); } } } private void ShowStatisticWindow(object Sender, FormulaChart Chart, int Pos, IDataProvider idp) { if (this.ShowStatistic) { if (this.StatisticWindow.Left < 0) { this.StatisticWindow.Left = 10; } //使用给定的行情小数位数 string format = "f" + _quoteDigits; //string format = "f2"; //if ((Chart.MainArea != null) && Chart.MainArea.IsMain()) //{ // format = Chart.MainArea.AxisY.Format; //} double d = idp["DATE"][Chart.CursorPos]; double num2 = idp["OPEN"][Chart.CursorPos]; double num3 = idp["HIGH"][Chart.CursorPos]; double num4 = idp["LOW"][Chart.CursorPos]; double num5 = idp["CLOSE"][Chart.CursorPos]; double num6 = idp["VOLUME"][Chart.CursorPos]; string str2 = ""; string str3 = ""; string str4 = ""; if (Chart.CursorPos > 0) { double num7 = idp["CLOSE"][Chart.CursorPos - 1]; if (num7 != double.NaN) { str2 = FormulaHelper.FormatDouble(num7, format); str3 = FormulaHelper.FormatDouble(num5 - num7, format); //(num5 - num7).ToString("f2"); str4 = ((num5 - num7) / num7).ToString("p2"); } } var builder = new StringBuilder(); //todo:以后可做成多语言资源-Daniel builder.Append("商品代码=" + idp.GetStringData("Code") + ";"); builder.Append("日 期=" + DateTime.FromOADate(d).ToString(Chart.XCursorFormat, DateTimeFormatInfo.CurrentInfo) + ";"); builder.Append("开盘价=" + FormulaHelper.FormatDouble(num2, format) + ";"); builder.Append("最高价=" + FormulaHelper.FormatDouble(num3, format) + ";"); builder.Append("最低价=" + FormulaHelper.FormatDouble(num4, format) + ";"); builder.Append("收盘价=" + FormulaHelper.FormatDouble(num5, format) + ";"); builder.Append("涨 幅=" + str3 + ";"); builder.Append("涨 跌=" + str4 + ";"); builder.Append("成交量=" + num6.ToString() + ";"); //builder.Append("Symbol=" + idp.GetStringData("Code") + ";"); //builder.Append("Date=" + DateTime.FromOADate(d).ToString(Chart.XCursorFormat, DateTimeFormatInfo.InvariantInfo) + ";"); //builder.Append("Current=" + FormulaHelper.FormatDouble(num5, format) + ";"); //builder.Append("Last=" + str2 + ";"); //builder.Append("Open=" + FormulaHelper.FormatDouble(num2, format) + ";"); //builder.Append("High=" + FormulaHelper.FormatDouble(num3, format) + ";"); //builder.Append("Low=" + FormulaHelper.FormatDouble(num4, format) + ";"); //builder.Append("Close=" + FormulaHelper.FormatDouble(num5, format) + ";"); //builder.Append("Volume=" + num6.ToString() + ";"); //builder.Append("Change=" + str3 + ";"); //builder.Append("Percent=" + str4 + ";"); if (this.ShowIndicatorValues) { try { for (int i = this.showOverlayValues ? 0 : 1; i < Chart.Areas.Count; i++) { int num9 = 0; int num10 = 0; foreach (FormulaData data in Chart[i].FormulaDataArray) { string displayName; if (num10 == 0) { displayName = Chart[i].Formulas[num9].DisplayName; } else { displayName = string.Empty; } if (data.ValueTextMode != Easychart.Finance.ValueTextMode.None) { string str6 = (displayName + data.Name).Trim(); if (str6 != "") { builder.Append(str6 + "=" + FormulaHelper.FormatDouble(data[Chart.CursorPos], Chart[i].AxisYs[data.AxisYIndex].Format) + ";"); } } num10++; if (num10 == Chart[i].Packages[num9].Count) { num9++; num10 = 0; } } } } catch { } } this.StatisticWindow.RefreshData(builder.ToString()); this.LastProvider = Chart.DataProvider; this.LastCursorPos = Chart.CursorPos; //固定统计窗口位置-Daniel this.StatisticWindow.Top = 20; this.StatisticWindow.Left = 60; } } private string[] Split(string s, char separator) { ArrayList list = new ArrayList(); int num = 0; int startIndex = 0; for (int i = 0; i < s.Length; i++) { if (s[i] == '(') { num++; } else if (s[i] == ')') { num--; } if ((num == 0) && (s[i] == separator)) { list.Add(s.Substring(startIndex, i - startIndex)); startIndex = i + 1; } } return (string[])list.ToArray(typeof(string)); } private void StatisticWindow_OnHide(object sender, EventArgs e) { this.ShowStatistic = this.StatisticWindow.Visible; } public void UseDefaultFormulas(bool b) { this.needSetDefaultFormulas = b; } #endregion Methods of ChartWinControl (126) #region Public Methods /// /// 插入默认指标 /// /// The name. /// The precent. public void InsertDefaultFormula(string name, double precent = 1.0) { this.chart.AddArea(name, precent); ApplySkin(); this.NeedRefresh(); } /// /// 添加指标到主图 /// /// public void InsertFormulaToMain(string newFormula) { InsertFormulaToArea(this.chart.MainArea, newFormula); } /// /// 添加指标到图表区 /// /// 指定区域 /// 新添加的指标全名(带参数) public void InsertFormulaToArea(FormulaArea area, string newFormula) { if (area == null || string.IsNullOrEmpty(newFormula)) { return; } var formulaStrings = string.Empty; if (area.Formulas == null || area.Formulas.Count == 0) { formulaStrings = newFormula; } else { foreach (var formula in area.Formulas) { var formulaBase = formula as FormulaBase; if (formulaBase == null || string.IsNullOrEmpty(formulaBase.FormulaName) || formulaBase.FormulaName.ToLower() == newFormula.ToLower()) { return; } formulaStrings += formulaBase.FormulaName + "#"; } formulaStrings += newFormula; } this.SetAreaByName(area, formulaStrings); } /// /// 删除图表菜单 /// public void DeleteChartMenu() { this.cmRight = null; ShowStatistic = false; } #endregion #region Extended Methods /// /// 行情小数位数 /// protected int _quoteDigits; /// /// 设置行情小数位数用来格式化价格 /// 在控件完成加载后调用,否则取的MainArea不一样 /// /// The quote digits. public void SetQuoteDigits(int quoteDigits) { //在控件完成加载后调用,否则取的MainArea不一样-Daniel try { _quoteDigits = quoteDigits; this.chart.MainArea.AxisY.Format = "f" + _quoteDigits; this.NeedRedraw(this.chart.MainArea); } catch (Exception e) { } } #endregion } }