using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; namespace NewsCrawler { public partial class NewsForm : Form { class PRICE_CHECK_DATA { public int m_iID; public CodeList.CODE_VALUE m_Code; public int m_iPriceStart = 0; public int m_iPriceLow = 0; public int m_iPriceHigh = 0; public DateTime m_StartTime; } CybosHelper m_CybosHelper = null; CodeList m_CodeList = null; TextCondition m_Condition = null; ConfigForm m_ConfigForm = null; System.Timers.Timer m_CrawlTimer = new System.Timers.Timer(); int m_iCrawlInterval = 500; bool m_bBrowserReload = false; bool m_bBuy = false; ConcurrentQueue m_PriceCheckList = new ConcurrentQueue(); System.Timers.Timer m_PriceCheckTimer = new System.Timers.Timer(); public NewsForm() { InitializeComponent(); Config.Init(); Util.SetLogView(tbLog); m_CodeList = new CodeList(); m_Condition = new TextCondition(); m_CybosHelper = new CybosHelper(this); MessageBox.Show("Keywords : \n\n" + m_Condition.GetKeywordsCnt()); wbView.ScriptErrorsSuppressed = false; ReadKIND(true); ReadDart(true); ReadEtoday(true); ReadEToday2(true); ReadAsiaE(true); ReadEdaily(true); ReadMoneyToday(true); ReadFinacialNews(true); lvList.ListViewItemSorter = new ListViewItemComparer(chId.Index, SortOrder.Ascending); lvList.Sorting = SortOrder.Ascending; lvList.Sort(); if(lvList.Items.Count > 0) { lvList.Items[lvList.Items.Count - 1].Selected = true; lvList.Select(); if(lvList.SelectedItems.Count > 0) lvList.SelectedItems[0].EnsureVisible(); } lvList.Columns[chTime.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chResponseT.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chResT.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chId.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chPriceS.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chPriceLow.Index].TextAlign = HorizontalAlignment.Right; lvList.Columns[chPriceHigh.Index].TextAlign = HorizontalAlignment.Right; m_CrawlTimer.Elapsed+=CrawlTimer_Tick; m_CrawlTimer.Interval=m_iCrawlInterval; m_CrawlTimer.Start(); m_PriceCheckTimer.Interval = 5000; m_PriceCheckTimer.Elapsed += PriceCheckTimer_Elapsed; m_PriceCheckTimer.Start(); Test(); } void Test() { if(Util.IsDebugging() == false) return; InsertItem("[test] 덕산하이메탈, 덕산네오룩스 66만여주 취득14:38", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914371817318", "asiae", 0, false); InsertItem("[test] 자연과환경, 12월15일~22일 주주명부폐쇄14:19", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914193170301", "asiae", 0, false); InsertItem("[test] 이엠코리아, 한국항공우주산업과 3억원 규모 공급계약14:06", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "asiae", 0, false); InsertItem("[test] [특징주] 진원생명과학, 국외 AI 인체감염증...", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.etoday.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "이투데이", 0, false); } private void BuyItem(CodeList.CODE_VALUE Code) { if(m_bBuy == false) return; if((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL) { Util.Log(Util.LOG_TYPE.DENIAL, string.Format("거부종목 ({0})", Code)); return; } if((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED) { Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("중복종목 ({0})", Code)); return; } m_CybosHelper.Buy(Code, Config.GetBuyPrice()); m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); } public void OnManualItemBuy(CodeList.CODE_VALUE Code) { BuyItem(Code); } void CheckPrice(int iID, CodeList.CODE_VALUE Code) { PRICE_CHECK_DATA CheckData = new PRICE_CHECK_DATA(); CheckData.m_iID = iID; CheckData.m_Code = Code; CheckData.m_StartTime = DateTime.Now; m_PriceCheckList.Enqueue(CheckData); } void ProcessSearchAndBuy(string strTitle, string strName, string strCode, string strRef, int iID) { CodeList.CODE_VALUE Code; if(strCode == "") Code = m_CodeList.SearchCode(strTitle); else Code = m_CodeList.GetCode(strCode); if(Code != null) { TextCondition.RESULT MatchResult = m_Condition.Match(strTitle); switch(MatchResult.m_enType) { case TextCondition.TYPE.NEGATIVE: Util.Log(Util.LOG_TYPE.NEGATIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); break; case TextCondition.TYPE.POSITIVE: if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL) Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); else if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DUPLICATED) Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); else if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.MANUAL) Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); else { Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); BuyItem(Code); } m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); break; case TextCondition.TYPE.MANUAL: Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); if(m_bBuy == true) { ModelessPopup ManualPopup = new ModelessPopup(this); ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?", DateTime.Now.ToString("[hh:mm:ss]"), strRef, strTitle, MatchResult.m_strKeyword, Code), Code); ManualPopup.TopMost = true; ManualPopup.Show(); } m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); break; case TextCondition.TYPE.NOT_MATCHED: Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", strRef, strTitle, Code.ToString())); break; } if(cbPriceCheck.Checked == true) CheckPrice(iID, Code); } } delegate void InsertListView(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial); public void InsertItem(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial) { try { if(this.InvokeRequired) { this.Invoke(new InsertListView(InsertItem), strTitle, strName, strCode, time, ResTime, strURL, strRef, responseT, bInitial); } else { if(strURL != "" && lvList.Items.Cast().Any(s => s.SubItems[chLink.Index].Text == strURL)) return; int iID = lvList.Items.Count+1; lvList.Items.Add(new ListViewItem(new string[] { iID.ToString(), time.ToString("HH:mm:ss"), ResTime.ToString("HH:mm:ss:fff"), strRef, strTitle, string.Format("{0:0.0000} ms", responseT), "", "", "", strURL })); if(bInitial == false && chAutoSelect.Checked == true) { m_bBrowserReload = true; } if(bInitial == false) { foreach(ColumnHeader col in lvList.Columns) { if(!(col == chPriceS || col == chPriceLow || col == chPriceHigh)) col.Width = -2; } } if(bInitial == false) { lvList.Sort(); ProcessSearchAndBuy(strTitle, strName, strCode, strRef, iID); } } } catch(Exception ex) { Util.Log(Util.LOG_TYPE.ERROR, ex.Message); } } bool ReadAsiaE(bool bInitial = false) { bool bHasNew = false; try { string strServerURL = "http://www.asiae.co.kr"; WebRequest request = WebRequest.Create("http://www.asiae.co.kr/news/sokbo/sokbo_left.htm"); request.Credentials=CredentialCache.DefaultCredentials; request.Timeout=2000; System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { timer.Stop(); using(Stream dataStream = response.GetResponseStream()) { using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR"))) { string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); responseFromServer = responseFromServer.Replace("\"\"", "\""); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(responseFromServer); string strXPath = "//div[contains(@class, 'txtform')]/ul/li"; var lists = doc.DocumentNode.SelectNodes(strXPath); foreach(var item in lists) { string strTitle1 = item.SelectSingleNode(".//a").GetAttributeValue("title", ""); string strTitle2 = item.SelectSingleNode(".//a").FirstChild.InnerText; string strTitle = (strTitle1.Length > strTitle2.Length ? strTitle1 : strTitle2); string strTime = item.SelectSingleNode(".//span").InnerText; string strURL = strServerURL+item.SelectSingleNode(".//a").GetAttributeValue("href", ""); if(Regex.IsMatch(strTime, @"\d+/\d+")==true) { //Console.WriteLine("어제 기사 : " + item.InnerHtml); continue; } InsertItem(strTitle, "", "", DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), DateTime.Now, strURL, "아시아경제", timer.Elapsed.TotalMilliseconds, bInitial); } } } } } catch(Exception e) { Console.WriteLine(e.ToString()); } return bHasNew; } bool ReadEtoday(bool bInitial = false) { bool bHasNew = false; try { //string strServerURL = "http://www.etoday.co.kr"; WebRequest request = WebRequest.Create("http://www.etoday.co.kr/news/flash/flash_list.php?tab=1"); request.Credentials=CredentialCache.DefaultCredentials; request.Timeout=2000; System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { timer.Stop(); using(Stream dataStream = response.GetResponseStream()) { using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8"))) { string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(responseFromServer); string strXPath = "//div[contains(@class, 'flash_tab_lst')]/ul/li"; var lists = doc.DocumentNode.SelectNodes(strXPath); foreach(var item in lists) { string strTitle = item.SelectSingleNode(".//a").InnerText; string strTime = item.SelectSingleNode(".//span[contains(@class, 'flash_press')]").InnerText; string strURL = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); strURL="http://www.etoday.co.kr/news/section/newsview.php?idxno="+Regex.Replace(strURL, @"\D", ""); if(Regex.IsMatch(strTime, @"\d+/\d+")==true) { //Console.WriteLine("어제 기사 : " + item.InnerHtml); continue; } InsertItem(strTitle, "", "", DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), DateTime.Now, strURL, "이투데이", timer.Elapsed.TotalMilliseconds, bInitial); } } } } } catch(Exception e) { Console.WriteLine(e.ToString()); } return bHasNew; } bool ReadEToday2(bool bInitial = false) { bool bHasNew = false; try { WebRequest request = WebRequest.Create("http://rss.etoday.co.kr/etoday/etoday_news_all.xml"); request.Credentials=CredentialCache.DefaultCredentials; request.Timeout=2000; int iCDATALen = " PrevTime) break; PrevTime = Time; InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "이데일리", timer.Elapsed.TotalMilliseconds, bInitial); } } } } } catch(Exception e) { Console.WriteLine(e.ToString()); } return bHasNew; } bool ReadMoneyToday(bool bInitial = false) { bool bHasNew = false; try { string strServerURL = "http://news.mt.co.kr/mtview.php?no="; WebRequest request = WebRequest.Create("http://news.mt.co.kr/newsflash/newsflash.html"); request.Credentials=CredentialCache.DefaultCredentials; request.Timeout=2000; DateTime PrevTime = DateTime.Now; System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { timer.Stop(); using(Stream dataStream = response.GetResponseStream()) { using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR"))) { string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(responseFromServer); string strXPath = "//div[@id='articleList']//li[@class='bundle']"; var lists = doc.DocumentNode.SelectNodes(strXPath); foreach(var item in lists) { string strTitle = item.SelectSingleNode(".//a").InnerText; string strTime = item.SelectSingleNode(".//span").InnerText; string strID = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); int iStart = strID.IndexOf('\'', 0); iStart = strID.IndexOf('\'', iStart+1); iStart = strID.IndexOf('\'', iStart+1); int iEnd = strID.IndexOf('\'', iStart+1); strID = strID.Substring(iStart+1, iEnd-iStart+1); string strURL = strServerURL+strID; DateTime Time; DateTime.TryParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); if(Time > PrevTime) break; PrevTime = Time; InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "머니투데이", timer.Elapsed.TotalMilliseconds, bInitial); } } } } } catch(Exception e) { Console.WriteLine(e.ToString()); } return bHasNew; } bool ReadFinacialNews(bool bInitial = false) { bool bHasNew = false; try { string strServerURL = "http://www.fnnews.com/news/"; WebRequest request = WebRequest.Create("http://www.fnnews.com/newsflash/today/data?type=json"); request.Credentials=CredentialCache.DefaultCredentials; request.Timeout=2000; DateTime Today = DateTime.Now; System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); timer.Start(); using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { timer.Stop(); using(Stream dataStream = response.GetResponseStream()) { using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8"))) { string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer); foreach(var data in jObj) { string strTitle = data["title"]; string strTime = data["date"]; DateTime Time; DateTime.TryParseExact(strTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); string strCode = data["code"]; string strURL = strServerURL+strCode; if(Time.DayOfYear == Today.DayOfYear) InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", timer.Elapsed.TotalMilliseconds, bInitial); } } } } } catch(Exception e) { Console.WriteLine(e.ToString()); } return bHasNew; } private void UpdateBrowser() { if(lvList.InvokeRequired == true) { lvList.Invoke(new Action(UpdateBrowser)); } else { if(chAutoSelect.Checked == true && m_bBrowserReload == true) { if(lvList.SelectedItems.Count == 0 || lvList.SelectedItems[0].Index != lvList.Items.Count-1) { lvList.Items[lvList.Items.Count - 1].Selected = true; lvList.Select(); if(lvList.SelectedItems.Count > 0) lvList.SelectedItems[0].EnsureVisible(); } m_bBrowserReload = false; } } } private void CrawlTimer_Tick(object sender, EventArgs e) { m_CrawlTimer.Enabled = false; //Console.WriteLine(string.Format("timer thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId.ToString())); if(chAutoReload.Checked == true) { ReadKIND(); ReadDart(); ReadAsiaE(); ReadEtoday(); ReadEToday2(); ReadEdaily(); ReadMoneyToday(); ReadFinacialNews(); } UpdateBrowser(); m_CrawlTimer.Interval = m_iCrawlInterval; m_CrawlTimer.Enabled = true; } private void UpdateStartPrice(int iID, int iPrice) { if(lvList.InvokeRequired) { lvList.BeginInvoke((MethodInvoker)delegate () { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); item.SubItems[chPriceS.Index].Text = iPrice.ToString("n0"); }); } else { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); item.SubItems[chPriceS.Index].Text = iPrice.ToString("n0"); } } private void UpdateLowHighPrice(int iID, int iPriceStart, int iPriceLow, int iPriceHigh) { if(lvList.InvokeRequired) { lvList.BeginInvoke((MethodInvoker)delegate () { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}({1:n}%)", iPriceLow, iPriceLow/(float)iPriceStart); item.SubItems[chPriceHigh.Index].Text = string.Format("{0:0}({1:n}%)", iPriceHigh, iPriceHigh/(float)iPriceStart); }); } else { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}({1:n}%)", iPriceLow, iPriceLow/(float)iPriceStart); item.SubItems[chPriceHigh.Index].Text = string.Format("{0:0}({1:n}%)", iPriceHigh, iPriceHigh/(float)iPriceStart); } } private void PriceCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { m_PriceCheckTimer.Enabled = false; DateTime CurTime = DateTime.Now; foreach(PRICE_CHECK_DATA data in m_PriceCheckList) { if(data.m_iPriceStart == 0) { data.m_iPriceStart = m_CybosHelper.GetCurPrice(data.m_Code); UpdateStartPrice(data.m_iID, data.m_iPriceStart); } else if(data.m_iPriceHigh == 0 && (CurTime - data.m_StartTime).Minutes >= 1) { m_CybosHelper.GetLowHighPrice(data.m_Code, data.m_StartTime, 5, out data.m_iPriceLow, out data.m_iPriceHigh); if(data.m_iPriceHigh > 0) UpdateLowHighPrice(data.m_iID, data.m_iPriceStart, data.m_iPriceLow, data.m_iPriceHigh); } } while(m_PriceCheckList.Count > 0) { PRICE_CHECK_DATA data; if(m_PriceCheckList.TryPeek(out data) == false) break; if(data.m_iPriceHigh == 0) break; m_PriceCheckList.TryDequeue(out data); } m_PriceCheckTimer.Enabled = true; } private void lvList_SelectedIndexChanged(object sender, EventArgs e) { if(lvList.SelectedItems.Count <= 0) return; string strURL = lvList.SelectedItems[0].SubItems[chLink.Index].Text; wbView.ScriptErrorsSuppressed = true; //wbView.Navigate(strURL); } private void tbInterval_KeyPress(object sender, KeyPressEventArgs e) { if(e.KeyChar == Convert.ToChar(Keys.Enter)) { m_iCrawlInterval = (int)(float.Parse(Regex.Replace(tbInterval.Text, @"\D\.", "")) * 1000); if(m_iCrawlInterval < 1) m_iCrawlInterval = 500; tbInterval.Text = (m_iCrawlInterval / (float)1000).ToString("##0.0") + "초"; } } private void lvList_ColumnClick(object sender, ColumnClickEventArgs e) { SortOrder Order = (lvList.Sorting == SortOrder.Descending || lvList.Sorting == SortOrder.None) ? SortOrder.Ascending : SortOrder.Descending; lvList.ListViewItemSorter = new ListViewItemComparer(e.Column, Order); lvList.Sorting = Order; lvList.Sort(); } private void btnConfig_Click(object sender, EventArgs e) { if(m_ConfigForm == null) m_ConfigForm = new ConfigForm(this); FormCollection OpenForms = Application.OpenForms; bool bOpen = false; foreach(Form form in OpenForms) { if(form == m_ConfigForm) { bOpen = true; break; } } if(bOpen == false) { m_ConfigForm.Show(); } else { m_ConfigForm.BringToFront(); } } public void OnConfigFormClosing() { m_ConfigForm = null; } public void OnManualCodeClick(int iPrice) { m_CodeList.MakeManualList(iPrice); } public void ApplyDenialCode() { m_CodeList.LoadDenialList(); } public void ApplyDuplicatedCode() { m_CodeList.LoadDuplicatedList(); } public void ApplyPositive() { m_Condition.LoadPositive(); } public void ApplyManual() { m_Condition.LoadManual(); } public void ApplyNegative() { m_Condition.LoadNegative(); } public void ApplySynonym() { m_CodeList.LoadSynonym(); } private void NewsForm_FormClosing(object sender, FormClosingEventArgs e) { Util.Clear(); } private void chBuy_CheckedChanged(object sender, EventArgs e) { m_bBuy = chBuy.Checked; if(m_bBuy == true && Config.GetAccount() == "") { chBuy.Checked = false; MessageBox.Show("계좌를 선택해주시기 바랍니다"); return; } if(m_bBuy == true) Util.Log(Util.LOG_TYPE.VERVOSE, "매수 시작"); else Util.Log(Util.LOG_TYPE.VERVOSE, "매수 취소"); } public string[] GetAccounts() { return m_CybosHelper.GetAccounts(); } public void ApplyAccount(string strAccount, string strAccountSub) { Config.SetAccount(strAccount, strAccountSub); } } class ListViewItemComparer : IComparer { int m_iColumn = 0; SortOrder m_Order = SortOrder.Ascending; public ListViewItemComparer(int column, SortOrder Order) { m_iColumn = column; m_Order = Order; } public int Compare(object x, object y) { ListViewItem item1 = (ListViewItem)x; ListViewItem item2 = (ListViewItem)y; double num1; double num2; if(double.TryParse(item1.SubItems[m_iColumn].Text, out num1) && double.TryParse(item2.SubItems[m_iColumn].Text, out num2)) { return (num1>num2)?1:-1; } else { if(m_Order == SortOrder.Ascending) return string.Compare(item1.SubItems[m_iColumn].Text, item2.SubItems[m_iColumn].Text); else return string.Compare(item2.SubItems[m_iColumn].Text, item1.SubItems[m_iColumn].Text); } } } }