namespace FileStreamRead { class Program { static void Main(string[] args) { FileStream fs; //得到文件所在路徑 string filePath = "C:\\file1.txt"; //打開文件 try { fs = new FileStream(filePath, FileMode.Open); } catch(Exception) { throw; } //還沒有讀取的文件內容長度 long left = fs.Length; //存儲讀取結果 byte[] bytes = new byte[100]; //每次讀取長度 int maxLength = bytes.Length; //讀取位置 int start = 0; //實際返回結果長度 int num = 0; //當文件未讀取長度大於0時,不斷進行讀取 while (left > 0) { fs.Position = start; num = 0; if (left < maxLength) num = fs.Read(bytes, 0, Convert.ToInt32(left)); else num = fs.Read(bytes, 0, maxLength); if (num == 0) break; start += num; left -= num; Console.WriteLine(Encoding.UTF8.GetString(bytes)); } Console.WriteLine("end of file"); Console.ReadLine(); fs.Close(); } } }
C#文件列表操做四大重點javascript
C#文件列表要點1:上傳文件 HTML部分: 1. 〈 formid=\"form1\"runat=\" 2. server\"method=\"post\"enctype=\ 3. "multipart/form-data\"〉 4. 〈 inputid=\"FileUpLoad\"type=\" 5. file\"runat=\"server\"/〉〈 br/〉 6. 後臺CS部分按鈕事件 7. //stringstrFileFullName= 8. System.IO.Path.GetFileName(this. 9. FileUpLoad.PostedFile.FileName); 10. //this.FileUpLoad.PostedFile.SaveAs(Server.MapPath( 11. \"./Xmlzip/\")+strFileFullName); C#文件列表要點2.文件下載 1. ListBox的SelectedIndexChanged事件設 2. 定相關下載鏈接 3. protectedvoidlst_DownLoadFileList 4. _SelectedIndexChanged(objectsender,EventArgse) 5. { 6. try 7. { 8. stringstrJS=\"window.open(\'Xmlzip/\"; 9. strJS+=this.lst_DownLoadFileList. 10. SelectedItem.Text.Trim(); 11. strJS+=\"\');returnfalse;\"; 12. this.imgbtn_DownLoadFile.Attributes. 13. Add(\"onclick\",strJS); 14. } 15. catch(Exceptionex) 16. { 17. ex.ToString(); 18. } 19. } 20. 或者也能夠經過改變Label的Text值來實現點擊 21. 後實現文件下載的超級鏈接 22. this.Label1.Text=\"〈 ahref= 23. \\\"Xmlzip/a.rar\\\"〉a.rar〈 /a〉\" C#文件列表要點3.文件刪除 1. stringstrFilePath=Server.MapPath( 2. \"../CountryFlowMgr/Xmlzip/\"+this.lst_ 3. DownLoadFileList.SelectedItem.Text.Trim()); 4. if(File.Exists(strFilePath)) 5. { 6. File.Delete(strFilePath); 7. if(File.Exists(strFilePath)) 8. { 9. Response.Write(\"ok\"); 10. } 11. else 12. { 13. Response.Write(\"ok\"); 14. } 15. } C#文件列表要點4.獲得文件夾下的文件列表 1. #region獲得當前可用的文件列表 2. ///〈 summary〉 3. ///獲得當前可用的文件列表 4. ///〈 /summary〉 5. ///〈 paramname=\"IsAlert\"〉 6. 是否須要彈出提示信息〈 /param〉 7. privatevoidfn_getCurrFileList(boolIsAlert) 8. { 9. try 10. { 11. //查找Xmlzip文件夾下屬於其本 12. 身UnitCoding的相關zip文件 13. stringstrXmlZipDirectory= 14. Server.MapPath(\"../Xmlzip/\"); 15. if(Directory.Exists(strXmlZipDirectory)) 16. { 17. //DirectoryInfodi=newDirectoryInfo( 18. Environment.CurrentDirectory); 19. DirectoryInfodi=newDirectoryInfo( 20. strXmlZipDirectory); 21. 22. FileInfo[]FI=di.GetFiles(\"*.zip\" 23. );//只查.zip文件 24. if(FI.Length〉0) 25. { 26. lst_DownLoadFileList.Items.Clear(); 27. foreach(FileInfotmpFIinFI) 28. { 29. ListItemtmpItem=newListItem(); 30. tmpItem.Text=tmpFI.Name; 31. lst_DownLoadFileList.Items.Add(tmpItem); 32. } 33. lst_DownLoadFileList.SelectedIndex=0; 34. } 35. else 36. { 37. if(IsAlert) 38. { 39. Response.write(\"查無能夠下載的文件!\"); 40. } 41. } 42. } 43. } 44. catch(Exceptionex) 45. { 46. ex.ToString(); 47. } 48. } 49. #endregion
Color TabControl(C#)html
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Drawing.Imaging; namespace wgscd { public partial class myTabControl : TabControl { public myTabControl() { InitializeComponent(); this.DrawMode = TabDrawMode.OwnerDrawFixed;//必須 SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);//避免閃爍 UpdateStyles(); } protected Color HeaderBackColor1 = Color.DarkGreen; protected Color HeaderBackColor2 = Color.DarkKhaki; protected float headerbackangle = 45; protected Color titlebackcolor1 = Color.Bisque; protected Color titlebackcolor2 = Color.Blue; protected float titlebackangle = 45; protected Font headerfont = new Font("Arial", 12, FontStyle.Bold); protected StringAlignment titlealignment = StringAlignment.Center; protected Color headerfontcolor = Color.Plum; protected Font focusedheaderfont = new Font("Arial", 11, FontStyle.Regular); protected Color focusedheaderfontcolor = Color.PowderBlue; Rectangle r = new Rectangle(1, 1, 200, 200); protected override void OnPaint(PaintEventArgs e)//繪製整個TabControl控件背景不起做用。。。。。。。。。。。。 { r = new Rectangle(0, 0, this.Width, this.Height); Brush b = new SolidBrush(Color.Azure); Graphics g = e.Graphics; g.FillRectangle(b, r); // base.OnPaint(e); } protected override void OnDrawItem(DrawItemEventArgs e) { Graphics g = e.Graphics; Rectangle endPageRect = GetTabRect(TabPages.Count - 1); //最後一個標題欄的範圍 Rectangle TitleRect = GetTabRect(e.Index); //當前標題欄的範圍 Rectangle HeaderBackRect = Rectangle.Empty; //背景區域 switch (Alignment) { case TabAlignment.Top: HeaderBackRect = new Rectangle(new Point(endPageRect.X + endPageRect.Width, endPageRect.Y), new Size(Width - endPageRect.X - endPageRect.Width, endPageRect.Height)); break; case TabAlignment.Bottom: HeaderBackRect = new Rectangle(new Point(endPageRect.X + endPageRect.Width, endPageRect.Y), new Size(Width - endPageRect.X - endPageRect.Width, endPageRect.Height)); break; case TabAlignment.Left: HeaderBackRect = new Rectangle(new Point(endPageRect.X, endPageRect.Y + endPageRect.Height), new Size(endPageRect.Width, Height - endPageRect.Y - endPageRect.Height)); break; case TabAlignment.Right: HeaderBackRect = new Rectangle(new Point(endPageRect.X, endPageRect.Y + endPageRect.Height), new Size(endPageRect.Width, Height - endPageRect.Y - endPageRect.Height)); break; } Brush TitleBackBrush = new LinearGradientBrush(TitleRect, titlebackcolor1, titlebackcolor2, titlebackangle); //漸變角度 Font font = headerfont; StringFormat sf = new StringFormat(); sf.Alignment = titlealignment; sf.LineAlignment = StringAlignment.Center; Color fontcolor = headerfontcolor; if (SelectedIndex == e.Index) //若是繪製的標題就是選中的標題,則使用選中標題的字體,同時更新font和fontcolor { g.DrawRectangle(new Pen(TabPages[e.Index].BackColor), TitleRect); //消除選中標題的矩形方框 font = focusedheaderfont; fontcolor = focusedheaderfontcolor; } Brush fontbrush = new SolidBrush(fontcolor); //繪製標題文本 g.DrawString(TabPages[e.Index].Text, font, fontbrush, TitleRect, sf); //繪製背景 if (HeaderBackRect != Rectangle.Empty) { Brush HeaderBackBrush = new LinearGradientBrush(HeaderBackRect, HeaderBackColor1, HeaderBackColor2, headerbackangle); g.FillRectangle(HeaderBackBrush, HeaderBackRect); } // base.OnDrawItem(e); } } }
C#詞法分析程序java
namespace 詞法分析 { /// <summary> /// Form1 的摘要說明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button3; private System.Windows.Forms.RichTextBox richTextBox1; private System.Windows.Forms.RichTextBox richTextBox2; private System.Windows.Forms.OpenFileDialog openFileDialog1; private System.Windows.Forms.SaveFileDialog saveFileDialog1; /// <summary> /// 必需的設計器變量。 /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Windows 窗體設計器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 調用後添加任何構造函數代碼 // } /// <summary> /// 清理全部正在使用的資源。 /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows 窗體設計器生成的代碼 /// <summary> /// 設計器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內容。 /// </summary> private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.button1 = new System.Windows.Forms.Button(); this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.button2 = new System.Windows.Forms.Button(); this.richTextBox2 = new System.Windows.Forms.RichTextBox(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); this.button3 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // label1 // this.label1.Location = new System.Drawing.Point(8, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(72, 24); this.label1.TabIndex = 0; this.label1.Text = "詞法分析"; // // button1 // this.button1.Location = new System.Drawing.Point(240, 8); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 23); this.button1.TabIndex = 1; this.button1.Text = "分析"; this.button1.Click += new System.EventHandler(this.button1_Click); // // richTextBox1 // this.richTextBox1.Location = new System.Drawing.Point(24, 48); this.richTextBox1.Name = "richTextBox1"; this.richTextBox1.Size = new System.Drawing.Size(240, 352); this.richTextBox1.TabIndex = 2; this.richTextBox1.Text = ""; // this.richTextBox1.TextChanged += new System.EventHandler(this.richTextBox1_TextChanged); // // button2 // this.button2.Location = new System.Drawing.Point(96, 8); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(64, 23); this.button2.TabIndex = 3; this.button2.Text = "讀入"; this.button2.Click += new System.EventHandler(this.button2_Click); // // richTextBox2 // this.richTextBox2.Location = new System.Drawing.Point(280, 48); this.richTextBox2.Name = "richTextBox2"; this.richTextBox2.Size = new System.Drawing.Size(280, 352); this.richTextBox2.TabIndex = 4; this.richTextBox2.Text = ""; // // button3 // this.button3.Location = new System.Drawing.Point(384, 8); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(56, 23); this.button3.TabIndex = 5; this.button3.Text = "保存"; this.button3.Click += new System.EventHandler(this.button3_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(584, 430); this.Controls.Add(this.button3); this.Controls.Add(this.richTextBox2); this.Controls.Add(this.button2); this.Controls.Add(this.richTextBox1); this.Controls.Add(this.button1); this.Controls.Add(this.label1); this.MaximizeBox = false; this.Name = "Form1"; this.Text = "Form1"; // this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); } #endregion /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } /// <summary> /// 詞法分析函數 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, System.EventArgs e) { //獲得想要的字符數組。 char[] getch = textToCharArray(); //將字符數組,轉換爲詞法分析後的 單詞數組。 string[] stringArray = charArrayToStringArray(getch); //將單詞數組分類,用數字標出各個單詞所在的類別。 string[,] twoStringArray = stringArrayToTwoStringArray(stringArray); //用於輸出二維數組。 printString(twoStringArray); } /// <summary> /// 輸出結果 即用於輸出二維數組。 /// </summary> /// <param name="twoStringArray"></param> private void printString(string[,] twoStringArray) { //提示說明 this.richTextBox2.Text = "1 -> 保留字" + "\r\n" + "2 -> 運算符" + "\r\n" + "3 -> 分隔符" + "\r\n" + "4 -> 數字 " + "\r\n" + "5 -> 其它" + "\r\n"; //輸出二維數組中的數據 for (int x = 0; x < twoStringArray.Length / 2; x++) { for (int y = 0; y < 2; y++) { this.richTextBox2.Text = this.richTextBox2.Text + twoStringArray[y, x] + " "; if (y == 1) { this.richTextBox2.Text = this.richTextBox2.Text + "\r\n"; } } } } /// <summary> /// 打開方件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, System.EventArgs e)// 文件打開的方法。 { openFileDialog1.Filter = "文本文件(*.txt)|*.txt"; openFileDialog1.Title = "打開要分析的源文件。"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { System.IO.StreamReader sr = new System.IO.StreamReader(openFileDialog1.FileName); this.richTextBox1.Text = sr.ReadToEnd(); sr.Close(); } } /// <summary> /// 保存文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, System.EventArgs e) { saveFileDialog1.Filter = "文本文件(*.txt)|*.txt"; saveFileDialog1.Title = "保存分析結果."; if(saveFileDialog1.ShowDialog() == DialogResult.OK) { System.IO.StreamWriter wr = new System.IO.StreamWriter(saveFileDialog1.FileName); wr.Write(this.richTextBox2.Text); wr.Close(); } } /// <summary> /// 引用二維數組和單詞的標誌j /// </summary> /// <param name="twoArray"></param> /// <param name="j"></param> private void oneArrayToTwo(ref string[,] twoArray, ref int j) { string[,] tempArray = twoArray; twoArray = new string[2, j + 2]; for (int x = 0; x < 2; x++) { for (int y = 0; y < j + 1; y++) { twoArray[x, y] = tempArray[x, y]; } } j = j + 1; } /// <summary> /// 引用單詞數組,和要加入單詞數組的單詞 /// </summary> /// <param name="stringArrange"></param> /// <param name="st"></param> private void stringToArrayString(ref string[] stringArrange, string st) { if (stringArrange[0] == "") { stringArrange[0] = st; } else { string[] oldA = stringArrange;//剛獲得的字符串 int i = oldA.Length + 1; stringArrange = new string[i];//申請一個長一個的字符數組。 oldA.CopyTo(stringArrange, 0);//將先前的字符數組考到如今這個數組中。 stringArrange[stringArrange.Length - 1] = st; } } /// <summary> /// 將Text中的字符串,存入一個字符數組中。 /// </summary> /// <returns></returns> private char[] textToCharArray() { string stringTemp; stringTemp = this.richTextBox1.Text; char[] getch = stringTemp.ToCharArray();//要處理的字符都在getch這個數組中。 return getch; } /// <summary> /// 字符數組 到 單詞數組 /// </summary> /// <param name="getch"></param> /// <returns></returns> private string[] charArrayToStringArray(char[] getch)//將字符數組轉換爲字符串數組。即詞法分析後的單詞數組。 { string[] stringArrange ={ "" };//用這個字符串數組存放詞法分析後獲得的單詞。 char charTemp; string stringSave = "";// 存放一個分析獲得的單詞 //一次循環因獲得一個單詞。 for (int i = 0; i < getch.Length; i++) { charTemp = getch[i]; //由字母開頭 數字和字母組成的單詞。 if (charTemp >= 'a' && charTemp <= 'z' || charTemp >= 'A' && charTemp <= 'Z') { stringSave = charTemp.ToString(); i = i + 1; int test = 0;//判斷循環是否結束,1 爲結束。 while (test == 0) { charTemp = getch[i]; if (charTemp >= 'a' && charTemp <= 'z' || charTemp >= 'A' && charTemp <= 'Z' || charTemp >= '0' && charTemp <= '9') { stringSave = stringSave + charTemp.ToString(); i = i + 1; } else test = 1; } stringToArrayString(ref stringArrange, stringSave); } stringSave = ""; //由數字組成的單詞。 if (charTemp >= '0' && charTemp <= '9') { stringSave = stringSave + charTemp.ToString(); i = i + 1; int test1 = 0; while (test1 == 0) { charTemp = getch[i]; if (charTemp >= '0' && charTemp <= '9') { stringSave = stringSave + charTemp.ToString(); i = i + 1; } else test1 = 1; } stringToArrayString(ref stringArrange, stringSave); } stringSave = ""; //由運算符組成的單詞。 if (charTemp == '+' || charTemp == '-' || charTemp == '*' || charTemp == '/' || charTemp == '=' || charTemp == '<' || charTemp == '>' || charTemp == '!') { stringSave = stringSave + charTemp.ToString(); i = i + 1; int test2 = 0; while (test2 == 0) { charTemp = getch[i]; if (charTemp == '+' || charTemp == '-' || charTemp == '*' || charTemp == '/' || charTemp == '=' || charTemp == '<' || charTemp == '>' || charTemp == '!') { stringSave = stringSave + charTemp.ToString(); i = i + 1; } else test2 = 1; } stringToArrayString(ref stringArrange, stringSave); } stringSave = ""; //由介符組成的單詞。 if (charTemp == '(' || charTemp == ')' || charTemp == '{' || charTemp == '}' || charTemp == '[' || charTemp == ']' || charTemp == ',' || charTemp == ':' || charTemp == ';' || charTemp == '"' || charTemp == '\'' || charTemp == '\\') { stringSave = stringSave + charTemp.ToString(); stringToArrayString(ref stringArrange, stringSave); } } return stringArrange; } /// <summary> /// 單詞數組 到 二維單詞數組。 /// </summary> /// <param name="stringArray"></param> /// <returns></returns> private string[,] stringArrayToTwoStringArray(string[] stringArray) { //存放單詞標識後的結果。 string[,] twoArray = new string[2, 1]; //單詞的標誌 int j = 0; //每循環一次,把一個單詞歸於一類,即前面加上一個數字。 for (int i = 0; i < stringArray.Length; i++) { //保留字 1 if (stringArray[i] == "main" || stringArray[i] == "int" || stringArray[i] == "float" || stringArray[i] == "printf" || stringArray[i] == "if" || stringArray[i] == "for" || stringArray[i] == "while" || stringArray[i] == "do" || stringArray[i] == "return" || stringArray[i] == "break" || stringArray[i] == "continue") { twoArray[0, j] = "1"; twoArray[1, j] = stringArray[i]; this.oneArrayToTwo(ref twoArray, ref j); } //運算符 2 else if (stringArray[i] == "+" || stringArray[i] == "-" || stringArray[i] == "*" || stringArray[i] == "/" || stringArray[i] == ">" || stringArray[i] == "<" || stringArray[i] == ">=" || stringArray[i] == "<=" || stringArray[i] == "!=" || stringArray[i] == "==" || stringArray[i] == "++" || stringArray[i] == "--" || stringArray[i] == "=") { twoArray[0, j] = "2"; twoArray[1, j] = stringArray[i]; this.oneArrayToTwo(ref twoArray, ref j); } //分隔符 3 else if (stringArray[i] == "(" || stringArray[i] == ")" || stringArray[i] == "{" || stringArray[i] == "}" || stringArray[i] == "[" || stringArray[i] == "]" || stringArray[i] == "," || stringArray[i] == ";" || stringArray[i] == ":" || stringArray[i] == "\"" || stringArray[i] == "/*" || stringArray[i] == "*/") { twoArray[0, j] = "3"; twoArray[1, j] = stringArray[i]; this.oneArrayToTwo(ref twoArray, ref j); } //數字 4 else if (stringArray[i].ToCharArray()[0] >= '0' && stringArray[i].ToCharArray()[0] <= '9') { twoArray[0, j] = "4";//數字 twoArray[1, j] = stringArray[i]; this.oneArrayToTwo(ref twoArray, ref j); } //其它 5(變量等) else { twoArray[0, j] = "5"; twoArray[1, j] = stringArray[i]; this.oneArrayToTwo(ref twoArray, ref j); } } return twoArray; } } }
IMAP文件夾名稱編碼和解碼方法web
// 編碼 private string IMAPEncode(string folder) { string rtn = "", base64; int index = 0; Regex regAsis = new Regex(@"\G(?:[\x20-\x25\x27-\x7e])+"); Regex reg26 = new Regex(@"\G&"); Regex regEncode = new Regex(@"\G(?:[^\x20-\x7e])+"); Regex regEq = new Regex(@"=+$"); Regex regSlash = new Regex(@"\/"); while (index < folder.Length) { Match m; m = regAsis.Match(folder, index); if(m.Success) { index = index + m.Length; rtn = rtn + m.Value; continue; } m = reg26.Match(folder, index); if(m.Success) { index = index + m.Length; rtn = rtn + "&-"; continue; } m = regEncode.Match(folder, index); if(m.Success) { index = index + m.Length; base64 = Convert.ToBase64String(Encoding.GetEncoding("UTF-16BE").GetBytes(m.Value)); base64 = regEq.Replace(base64, ""); base64 = regSlash.Replace(base64, ","); rtn = rtn + "&" + base64 + "-"; continue; } } return rtn; } // 解碼 private string IMAPDeconde(string folder) { string rtn = "", base64; int index = 0; Regex regAsis = new Regex(@"\G([^&]+)"); Regex reg26 = new Regex(@"\G\&-"); Regex regDecode = new Regex(@"\G\&([A-Za-z0-9+,]+)-?"); Regex regComma = new Regex(@","); while (index < folder.Length) { Match m; m = regAsis.Match(folder, index); if(m.Success) { index = index + m.Length; rtn = rtn + m.Value; continue; } m = reg26.Match(folder, index); if(m.Success) { index = index + m.Length; rtn = rtn + "&"; continue; } m = regDecode.Match(folder, index); if(m.Success) { index = index + m.Length; base64 = m.Value.Substring(1, m.Value.Length - 2); base64 = regComma.Replace(base64, "/"); int mod = base64.Length % 4; if(mod > 0 ) base64 = base64.PadRight(base64.Length + (4 - mod), '='); base64 = Encoding.GetEncoding("UTF-16BE").GetString(Convert.FromBase64String(base64)); rtn = rtn + base64; continue; } } return rtn; }
MFC選項卡的實現數據庫
方案一 在對話框上放置一個Tab Control的控件,再在對話框上放置所需的控件(本例放置了2個按鈕,試圖在每一個標籤中顯示一個)。而後利用Class Wizard來爲Tab Control控件建立一個控件變量,該變量是CTabCtrl類的,再爲其餘控件也建立相應的控件類。 在主對話框的初始函數中CProperty1Dlg::OnInitDialog()加入以下代碼: //本例插入兩個標籤,實際運用中可經過循環插入所需個數的標籤,運行後默認第一個標籤被選中 m_tab.InsertItem( 0, _T("Tab1") ); m_tab.InsertItem( 1, _T("Tab2") ); //將不是第一個標籤的控件隱藏掉,只留下你要的控件 m_button2.ShowWindow( SW_HIDE ); 再利用ClassWizard處理Tab Control的 TCN_SELCHANGE 的消息。在消息處理函數中,利用CWnd::ShowWindow來使相應的控件顯示和隱藏。 void CProperty1Dlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) { //GetCurSel返回當前被選中的標籤的索引號(以0爲基礎算起) int sel = m_tab.GetCurSel(); switch(sel) { case 0: m_button1.ShowWindow( SW_SHOW ); m_button2.ShowWindow( SW_HIDE ); break; case 1: m_button2.ShowWindow( SW_SHOW ); m_button1.ShowWindow( SW_HIDE ); break; } *pResult = 0; } 方案二 本這個方案中,我將使用MFC中現成的CPropertySheet和CPropertyPage類來完成將控件分散到各個對話框類中。 首先加入兩個(或數個)對話框資源。修改各對話框資源的屬性,將對話框的Caption屬性改成你要在標籤上所顯示的文字。將對話框的Style屬性改成:Child, Border屬性改成:Thin, 只選中Title Bar複選框,去掉其餘複選框。而後你能夠在這些對話框中加入要分開顯示的各個控件。 爲上述對話框資源分別製做一個對話框類,該對話框類是從CPropertyPage繼承。這樣一來各子對話框類就行了,主對話框類能夠直接使用CPropertySheet類。使用以下代碼便可: CPropertySheet sheet("屬性頁對話框"); CPage1 page1; CPage2 page2; //加入子對話框做爲一個屬性頁 sheet.AddPage(&page1); sheet.AddPage(&page2); //產生一個模態對話框,也可使用Create方法來產生一個非模態對話框(具體參見MSDN) sheet.DoModal(); 如何在主對話框中放置其餘控件呢?若是直接使用CPropertySheet的話,是不能夠的,可是別忘了咱們能夠從CPropertySheet類繼承本身的類啊! 方案三 首先仍是要建立那些要在屬性頁中的顯示的子對話框類,建立步驟和方案二同樣,都是從CPropertyPage繼承。 此次咱們將從CPropertySheet類繼承本身的類(假設類名爲CMySheet)。咱們要在這裏放上一個button控件。那麼如今先在CMySheet中加入一個CButton類的成員變量m_button。 在CMySheet類中的OnInitDialog()函數裏,這樣寫: BOOL bResult = CPropertySheet::OnInitDialog(); //取得屬性頁的大小 CRect rectWnd; GetWindowRect(rectWnd); //調整對話框的寬度 SetWindowPos(NULL, 0, 0,rectWnd.Width() + 100,rectWnd.Height(),SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); CRect rectButton(rectWnd.Width() + 25, 25,rectWnd.Width()+75, 75); //用程序建立一個按鈕 m_button.Create("Button", BS_PUSHBUTTON, CRect(rectWnd.Width(), 25,rectWnd.Width()+75, 50) , this, 1); //顯示這個按鈕 m_button.ShowWindow( SW_SHOW ); CenterWindow(); return bResult; 使用方案三雖然能在主對話框中加入控件,可是也比較麻煩,首先所加的控件只能在屬性頁的右邊或下邊。而且用程序來產生控件比較煩瑣,位置與大小不易控制。那麼還有其餘方法,既能在對話框中加入屬性頁,又能在主對話框隨意添加控件? 方案四 不從CPropertySheet繼承本身的類,仍是直接使用它。各屬性頁的子對話框類仍是須要的,建立方法和上述兩個方案相同。 首先咱們新建一個基於對話框的工程。在編輯已有的一個主對話框中能夠自由加一些所需的控件,可是得留出必定的空間用於放置屬性頁。 在主對話框類里加入一個CPropertySheet類的一個成員變量(m_sheet)表明整個屬性頁。再加入一些各子對話框類的實例做爲成員變量(m_page一、m_page2……)。 在主對話框類的OnInitDialog()函數中加入: //加入標籤,標籤名由各個子對話框的標題欄決定 m_sheet.AddPage(&m_page1); m_sheet.AddPage(&m_page2); //用Create來建立一個屬性頁 m_sheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT); RECT rect; m_sheet.GetWindowRect(&rect); int width = rect.right - rect.left; int height = rect.bottom - rect.top; //調整屬性頁的大小和位置 m_sheet.SetWindowPos(NULL, 20, 50, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); 這個方案能夠自由在主對話框中加一些必要的控件,並且屬性頁中的控件也都分散在了各個子對話框類中,使用很是方便。 方案五 使用Tab Control,而且從CTabCtrl控件類繼承本身的類(CTabSheet)來處理。 首先我先介紹一下如何使用CTabSheet。 先要製做子對話框類,此次的子對話框類不要從CPropertyPage繼承,而是直接從CDialog繼承。而且各個子對話框資源的屬性應設置爲:Style爲Child, Border爲None。 在主對話框資源中,加入一個Tab Control,而且適當調整位置和大小。利用ClassWizard來爲這個Tab Control建立一個CTabSheet的控件變量。 在主對話框的OnInitDialog()加入: m_sheet.AddPage("tab1", &m_page1, IDD_DIALOG1); m_sheet.AddPage("tab2", &m_page2, IDD_DIALOG2); m_sheet.Show(); 就這樣就能夠在對話框上製做出一個完美的屬性頁了。效果和上圖徹底同樣。 下面我就來說講CTabSheet類的細節內容。 CTabSheet是從CTabCtrl繼承來的,用於Tab Control的控件類。在類中有一個成員變量用來記錄各子對話框的指針CDialog* m_pPages[MAXPAGE]; MAXPAGE是該類所能加載的標籤的最大值。 類中有一個AddPage方法,用於記錄子對話框的指針和所使用對話框資源的ID號。 BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID) { if( MAXPAGE == m_nNumOfPages ) return FALSE; //保存目前總的子對話框數 m_nNumOfPages++; //記錄子對話框的指針、資源ID、要在標籤上顯示的文字 m_pPages[m_nNumOfPages-1] = pDialog; m_IDD[m_nNumOfPages-1] = ID; m_Title[m_nNumOfPages-1] = title; return TRUE; } 在使用AddPage加入了若干子對話框後,必須調用CTabSheet的Show方法來真正生成標籤和子對話框。 void CTabSheet::Show() { //利用CDialog::Create來建立子對話框,而且使用CTabCtrl::InsertItem來加上相應的標籤 for( int i=0; i < m_nNumOfPages; i++ ) { m_pPages[i]->Create( m_IDD[i], this ); InsertItem( i, m_Title[i] ); } //因爲對話框顯示時默認的是第一個標籤被選中,因此應該讓第一個子對話框顯示,其餘子對話框隱藏 m_pPages[0]->ShowWindow(SW_SHOW); for( i=1; i < m_nNumOfPages; i++) m_pPages[i]->ShowWindow(SW_HIDE); SetRect(); } 生成好標籤和子對話框後,調用CTabSheet::SetRect來計算並調整屬性頁的大小。 void CTabSheet::SetRect() { CRect tabRect, itemRect; int nX, nY, nXc, nYc; //獲得Tab Control的大小 GetClientRect(&tabRect); GetItemRect(0, &itemRect); //計算出各子對話框的相對於Tab Control的位置和大小 nX=itemRect.left; nY=itemRect.bottom+1; nXc=tabRect.right-itemRect.left-2; nYc=tabRect.bottom-nY-2; //利用計算出的數據對各子對話框進行調整 m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW); for( int nCount=1; nCount < m_nNumOfPages; nCount++ ) m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW); } 在單擊標籤欄後,應該是相應的子對話框顯示,正在顯示的子對話框應該隱藏。所以利用ClassWizard來處理WM_LBUTTONDOWN消息。 void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) { CTabCtrl::OnLButtonDown(nFlags, point); //判斷是否單擊了其餘標籤 if(m_nCurrentPage != GetCurFocus()) { //將原先的子對話框隱藏 m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE); m_nCurrentPage=GetCurFocus(); //顯示當前標籤所對應的子對話框 m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW); } } 這樣利用CTabSheet這個類就能夠輕鬆地在對話框上放置本身的屬性頁了,而且控件都分散在各子對話框類中,符合對象封裝的思想。並且用這個方法來製做屬性頁就能夠利用ClassWizard來輕鬆地生成消息映射處理Tab Control的消息了。例如:能夠處理TCN_SELCHANGE消息來對切換了標籤時進行一些動做。 方案五另外一寫法 思路:當咱們調用InsertItem()這個函數的時候,選項卡控件將會添加一個標籤頁,這個時候,咱們將本身的對話框的窗體的指針與此標籤頁關聯起來,當用戶進行標籤頁的切換的時候,咱們根據當前是哪一個標籤頁,顯示哪一個對話框,不是與當前標籤頁關聯的對話框,咱們將其隱藏便可.這樣咱們即可以實現選項卡控件. 第一步:新建一個本身的類CTabSheet繼承CTabCtrl. 第二步:定義有用的成員變量 CDialog* m_dlgWnd[MAXTABPAGE]; //這個是存放對話框指針的指針數組 int m_curTabNumber; //記錄當前用戶添加了幾個標籤頁 int m_selTabID; //當前用戶點擊的標籤頁的ID 第三步:添加成員函數 //經過這個函數,能夠將一個對話框指針與添加的標籤頁關聯起來,insWnd是建立的非模式對話框的指針,wndID是對話框的ID,pageText是標籤頁的標題 void CreateTabPage(CWnd *insWnd, int wndID,CString pageText) //添加控件的點擊事件的處理,當點擊後獲得當前點擊的標籤頁的ID,而後將與此標籤頁相關的對話框顯示,其它的隱藏便可 void OnLButtonDown(UINT nFlags, CPoint point) 經過添加以上的成員變量及成員函數便可實現一個簡單的選項卡控件的用法 下面我將這兩個成員函數的代碼貼出來,並詳細講解 //建立而且增長一個標籤頁 //建立而且增長一個標籤頁 void CTabSheet::CreateTabPage(CWnd *insWnd, int wndID,CString pageText) { if (m_curTabNumber >= MAXTABPAGE) { MessageBox("標籤頁己經達到最大!","建立出錯!",MB_OK); return; } //首先new一個對話框的指針,可是不要調用create函數,再將些指針當成參數傳進來便可,建立己由此函數作完 if (NULL == insWnd) { MessageBox("標籤頁爲空","建立出錯",MB_OK); return; } //建立對話框,而且增長標籤頁 CDialog* curDlg = (CDialog*)insWnd; curDlg->Create(wndID,this); int suc = InsertItem(m_curTabNumber,pageText); if (-1 == suc) { MessageBox("插入標籤頁失敗","失敗",MB_OK); return; } curDlg->ShowWindow(SW_SHOW); //將這個對應的窗體指針存放起來 m_dlgWnd[m_curTabNumber] = curDlg; //此時選擇當前頁面 SetCurSel(m_curTabNumber); m_selTabID = m_curTabNumber; m_curTabNumber ++; } //點擊左鍵事件,處理 void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CTabCtrl::OnLButtonDown(nFlags, point); //獲得當前用戶點擊的標籤頁的ID int curSelect = GetCurSel(); //獲得當前標籤頁的位置以便設置對話框顯示的位置 CRect curRect; GetClientRect(curRect); if (-1 == curSelect) { return; } //查找標籤頁,將與當前用戶點擊的標籤頁相關的對話框顯示出來,其它的對話框隱藏 for (int i = 0; i < m_curTabNumber; i ++) { if (i == curSelect) { m_dlgWnd[i]->SetWindowPos(NULL,0,20,curRect.Width(),curRect.bottom,SWP_SHOWWINDOW); } else { m_dlgWnd[i]->SetWindowPos(NULL,0,20,curRect.Width(),curRect.bottom,SWP_HIDEWINDOW); } } m_selTabID = curSelect; Invalidate(); //CTabCtrl::OnLButtonDown(nFlags, point); } 以上爲關鍵的兩個函數,下面介紹調用的方法 建立非模式的對話框 CTabSheet m_tabSheet; CMyDlg* m_dlg = new CMyDlg; m_tabSheet.CreateTabPage(m_dlg ,IDD_DLG_ID,"第一個標籤頁"); 這樣就能夠產生一個標籤頁了,固然還能夠繼續調用此函數添加標籤頁 本文根據網上的資料整理,如下是用方案五寫的一個實例程序。 來自:http://c.chinaitlab.com/vc/838702.html
Net下幾種日誌管理方法express
日誌是應用程序中不可缺乏的一部份,不只能夠記錄應用程序的運行狀態,還能夠記錄一些BUG,便於應用程序的更新與修改。 在.Net有好幾種方法能夠對日誌進行管理。 1、數據庫日誌。 2、文本日誌。 3、系統事件日誌。 首先,對於數據庫日誌而言,它的使用簡單並且方便。這裏就不作太多的討論,相信寫過與數據相關的項目的人都會用數據來記錄一些日誌。然而它惟一很差的就是:必須先保證你的數據庫連接是正確無誤的。 然而這一保證不是必然的,因此這裏我再討論一下其它的兩種狀況,文本日誌及系統事件日誌。 文本日誌: 它使用簡單,並且查看也方便。很差的就是不便於作大量的日誌,並且日誌內容的查看與分析都不方便。然而它仍是可在在一些不適合數據庫日誌的地方使用。例如一些測試消息的輸出,一些獨立組件的少許日誌等。 通常狀況下,爲了方便管理,以天爲單位對日誌文件進行分類。這樣一來也能夠簡單的對文件進行管理。例如:你的文件名能夠知道這個日誌是何時的,而後能夠簡單的作一個相似數據庫同樣的查詢,管理也還方便。畢竟文本對系統來講是如此的簡單。 .Net有一個診斷類,能夠把文本以監聽的方式添加到Trace以及Debug上,這樣一來,你的全部指向Trace和Degug的輸出都會記錄到文件裏去。這是一個很不錯的方法。 using System.Diagnostics; Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(DateTime.Now.ToString("yyyyMMdd")+"..log")); Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out)); 或者: Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(DateTime.Now.ToString("yyyyMMdd")+"..log")); Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out)); 這裏的區別是:Trace在Release下可使用,而Debug只在Debug下使用。 我以爲全部的文本日誌中,上面的方法是最好用的。你只需要再作一個日誌管理的類就好了。 固然,還要注意,就是監聽在24小時後要更新一次,應該把當前的監聽清理掉,而後從新添加一個。這也簡單。 另外一個方法就是本身寫文本進行管理。這樣的方法要略麻煩一點點,道也不難。 然而文本日誌除了不便於作大量日誌的工做以還,還有一個致命的問題:進程衝突! 由於文本日誌要鎖定正在寫的文本文件,因此其它要寫該文件的程序會出現錯誤。通常狀況下,若是應該程序只有一個副本在運行,並且把日誌作爲一個全局的靜態對象來處理,也不會有什麼太大的問題。但程序的第二個副本會由於文件不能打開而啓動失敗。 這並非一個沒法解決的問題,只用保證程序有一個副本就好了。若是不保證的話,那麼小有一點複雜,這裏就再也不討論了,下次有機會再討論這個問題。 對於上面的問題,我想暫時放棄文本日誌,用系統的事件日誌來處理。 系統事件日誌: .net下有一個EventLog類,它直接與系統的事件日誌關聯。 簡單的一個: EventLog.WriteEntry("LogSource","This is a test log."); 就能夠往系統裏寫一個事件了。 然而把它用好也還有點點麻煩。首先是上面的方法會在系統的Application下寫一個事件日誌,並且爲默認爲Information類型。這樣很不利於管理,你們能夠在管理工具裏看一下日誌,就會發現大量的日誌,本身寫的一個小日誌簡直沒法找到。 然而.Net爲咱們提供了幾個方法來更好的管理日誌。 1、添加一個新的LogSource。 什麼是LogSource?其實簡單的說,它就是日誌的一個分類標記,例如你能夠用程序一次取出因此LogSource爲指定內容的日誌。這樣一來,只要你記得這個Source名,你就能夠讀取和分類管理日誌了。 默認狀況下,你在直接用EventLog的靜態函數寫日誌的時候,要指定一個LogSource,若是LogSource不存在,那麼它就自動在Application下創建一個,所以,建立LogSource就這麼簡單了。 2、添加一個新的Log. 什麼是Log.這裏的Log是指系統事件日誌裏的大日誌分類,通常狀況下,系統有Application,System和Sercuity三個日誌,每一個下面有不一樣的Soucce,這樣就構成了日誌系統。 你不能獨立的建立一個Log,由於.NET裏沒有提供任何方法來建立一個Log,只能經過函數:CreateEventSource(string,string) 來建立一個Sourcce,此時若是你這樣作:CreateEventSource("MySource","MyLog"); 你就會在日誌管理器裏看到多了一個MyLog類,然而再這樣寫日誌: EventLog.WriteEntry("MySource","This is a test log."); 就能夠寫一條記錄到MyLog分類下,這樣就能夠很好的管理本身的日誌了。 須要說明的是: 若是Source已經存在,那麼建立會失敗。注意:無論Source的哪一個Log下,只要Source的名字已經存在,那麼你的建立都會失敗。例如:若是有一個"Source1"的日誌在Application裏,那麼你就不能再到其它Log裏再建立一個名爲"Source1"的日誌了。另外:你用程序建立的日誌不能在日誌管理器裏刪除它(Messages能夠刪除,但日誌分類不能刪除)。方法是你仍是用程序能夠來刪除,或者在註冊表裏來刪除它。它的位置:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\] 看一下注冊表,或許你會明白一些。 最後就是用日誌實例對象來寫日誌。你能夠指定一個Log名和一個Source名來寫日誌,但要注意,必須是Log與Source匹配,不然也會出現錯誤。這比直接用靜態方法來寫日誌要複雜一點點,但你有更多的自由空間。 系統事件日誌很差的地方就是日誌只保存三個月,並且很差管理。若是你能夠直接管理服務器,或者就在本機上運行應該會好一些,不然你就不得不本身寫些代碼來管理日誌了。固然,若是一些重要的日誌,能夠導出到其它文件中。 它的好處是不少的: 1、沒必要與數據庫連接,效率會高一些,也不會有數據庫訪問失敗的問題。 2、不會有進程衝突問題,它是系統的日誌,無論是什麼應用程序均可以寫日誌。 3、全局可用,無論在哪裏均可以直接寫日誌,並且可讀。所以能夠把它當成一個消息通訊平臺。(固然,可能只有那些大腦有點問題的人會這樣作。)然而我只是想說明:A進程寫的日誌,B進程能夠直接讀取。 好了,關於日誌此次就總結這些。
VC 給Tab控件的標籤貼圖canvas
設置TAB標題前的小圖標: HIMAGELIST hImageList = ImageList_Create(24,24,ILC_COLOR32,0,2); HICON himodify = (HICON)LoadImage(NULL,TEXT("res\\Pictures.ico"),IMAGE_ICON,24,24,LR_LOADFROMFILE); ImageList_AddIcon(hImageList , himodify); TabCtrl_SetImageList(hTabCtrl ,hImageList); TCITEM tabitem; tabitem.mask = TCIF_TEXT | TCIF_IMAGE ; tabitem.pszText = TEXT("1"); tabitem.iImage = 0; TabCtrl_InsertItem(hTabCtrl,0,&tabitem); 或者採用: void CFormTabView::OnInitialUpdate() { m_imagelist.Create(16,16,ILC_MASK,4,4);//建立圖標 HICON hIcon; //hIcon = ::LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_ICON1)); hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LEDON);// icon 0 m_imagelist.Add(hIcon); hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LEDOFF);//icon 1 m_imagelist.Add(hIcon); CRect rect; GetClientRect(rect); rect.top += 0; m_ctTab.MoveWindow(rect); m_ctTab.SetImageList(&m_TabImageList); m_ctTab.InsertItem(TCIF_TEXT | TCIF_IMAGE,0,"page0",0,0);//選擇的是icon 0,倒數第二個參數 m_ctTab.InsertItem(TCIF_TEXT | TCIF_IMAGE,1,"page1",1,0);//選擇的是icon 1 m_ctTab.InsertItem(TCIF_TEXT | TCIF_IMAGE,2,"page2",1,0);//選擇的是icon 1 m_ctTab.InsertItem(TCIF_TEXT | TCIF_IMAGE,3,"page3",1,0);//選擇的是icon 1 // m_ctTab.HighlightItem(0); // m_ctTab.SetPadding(CSize(3,3)); int x; x = (rect.Width()-10)/m_ctTab.GetItemCount(); m_ctTab.SetItemSize(CSize(x,20)); ....... } m_imagelist 是 view/dialog成員變量CImageList m_ctTab 是 tabctrl控件映射的變量 用image 的話是同樣的,也用cimagelist 參考:http://topic.csdn.net/t/20050415/16/3939802.html
WinForms C#:html編輯器工程源碼,含直接寫WebBrowser的文件流、IPersistStreamInit接口的聲明和一些相關的小方法c#
首先多謝朋友們的捧場; 今天給你們帶來一個操做WebBrowser的一些高級方法,我專門寫了一個html編輯器的實現代碼,有須要的朋友能夠本身擴充; 功能實現是直接寫流到WebBrowser內不經過臨時文件,而且支持對WebBrowser的一些高級控制(其實script能夠達到的都可達到,想知道怎麼搞的能夠閱讀代碼)。 其中關於IPersistStreamInit接口的聲明費了翻工夫,由於之前在 delphi 中沒這麼麻煩,呵呵。在網絡上找了大半天沒找到,最後仍是祭出Reflector,反編譯Windows.Forms,須要的朋友能夠不用辛苦的本身搞了! 我在這個演示裏,製做的html編輯環境是比簡單的,您能夠看看,比較比較 CodeProject 上的代碼;我採用的是ie自身提供的編輯方法,只是這樣的方式都被運用於web方式的編輯器內,就比如這個freeTextBox 如下是主要的代碼: 1 /******************************** 2 * 初始化瀏覽器狀態 3 * 指向about:blank 4 * *****************************/ 5 private void Form1_Load(object sender, System.EventArgs e) { 6 object obj = null; 7 this.Show(); 8 this.axWb.Navigate("about:blank",ref obj,ref obj,ref obj,ref obj); 9 //等待完成動做 10 while(axWb.ReadyState < SHDocVw.tagREADYSTATE.READYSTATE_INTERACTIVE) 11 Application.DoEvents(); 12 13 //初始化html編輯器 14 InitHtmlEditor(); 15 } 16 17 /******************************* 18 * 這裏是核心方法 19 * 徹底調用IE自身的html編輯功能 20 * 能夠看到,我採用了一種兼容的 21 * 方式,用Frame(框架),這樣 22 * 的話,默認安裝的Windows 98都 23 * 支持html編輯功能; 24 * 關鍵代碼以下: 25 * frame.document.designMode = "on"; 26 * 表示開啓設計模式 27 ******************************/ 28 private void InitHtmlEditor(){ 29 string sw = ""; 30 sw += "<html>\r\n"; 31 sw += "<script language=javascript>\r\n"; 32 sw += " function loadSet(){\r\n"; 33 sw += " var frame=document.getElementById(\"i-frame\").contentWindow;\r\n"; 34 sw += " frame.document.designMode = \"on\";\r\n"; 35 sw += " frame.document.open();\r\n"; 36 sw += " frame.document.write(\"<html><font color=red>hello 你們好啊!<br>我是S.F. <br>"; 37 sw += " <a href=\\\"http://www.cnblogs.com/chinasf\\\">歡迎訪問個人weblog</a></font></html>\");\r\n"; 38 sw += " frame.document.close();\r\n"; 39 sw += " }\r\n"; 40 sw += " function setBlod(obj){\r\n"; 41 sw += " document.getElementById(\"i-frame\").contentWindow.document.execCommand(\"bold\");\r\n"; 42 sw += " }\r\n"; 43 sw += "</script>\r\n"; 44 //這裏加入了一個html的button,也就是說,你能夠把web模式的html編輯器的代碼徹底copy進來 45 sw += "<body onload=\"loadSet()\" scroll=\"yes\"><button onclick=\"setBlod(this);\">Blod</button>\r\n"; 46 sw += "<iframe id=\"i-frame\" frameBorder=\"1\" width=\"640\" height=\"480\"></iframe>\r\n"; 47 sw += "</body></html>\r\n"; 48 49 //寫入瀏覽器 50 WriteHtml(sw); 51 } 52 53 private void WriteHtml(string s){ 54 //內存流,用於轉換string 55 MemoryStream ms = new MemoryStream(); 56 try{ 57 byte[] htmlcode = System.Text.Encoding.Default.GetBytes(s); 58 ms.Write(htmlcode,0,htmlcode.Length); 59 Stream dataStream = ms; 60 //恢復指針位置 61 dataStream.Seek(0,0); 62 63 if(axWb.Document!=null){ 64 //轉換接口,並轉換爲IStream 65 (axWb.Document as UnsafeNativeMethods.IPersistStreamInit).Load(new UnsafeNativeMethods.ComStreamFromDataStream(dataStream)); 66 } 67 }finally{ 68 ms.Close(); 69 } 70 } 71 72 private void button1_Click(object sender, System.EventArgs e) { 73 //獲取document,在IHTMLDocument2中取得楨 74 mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document; 75 mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame"); 76 object obj=null; 77 fb.contentWindow.document.execCommand("bold",true,obj); 78 } 79 80 private void button3_Click(object sender, System.EventArgs e) { 81 //獲取document,在IHTMLDocument2中才有body.style 82 mshtml.IHTMLDocument2 idoc = (mshtml.IHTMLDocument2)axWb.Document; 83 //指定爲IHTMLStyle3,才能夠定製滾動條顏色 84 mshtml.IHTMLStyle3 istyle = (mshtml.IHTMLStyle3)idoc.body.style; 85 istyle.scrollbarArrowColor = "#0099FF"; 86 istyle.scrollbar3dLightColor = "#FFFFFF"; 87 istyle.scrollbarDarkShadowColor = "#0099FF"; 88 istyle.scrollbarFaceColor = "#99CCFF"; 89 istyle.scrollbarHighlightColor = "#0099FF"; 90 istyle.scrollbarShadowColor = "#0099FF"; 91 istyle.scrollbarTrackColor = "#FFFFFF"; 92 93 } 94 95 private void button2_Click(object sender, System.EventArgs e) { 96 //查看源碼,文本方式 97 mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document; 98 mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame"); 99 MessageBox.Show(fb.contentWindow.document.body.innerText); 100 } 101 102 private void button4_Click(object sender, System.EventArgs e) { 103 //查看源碼,HTML方式 104 mshtml.IHTMLDocument3 idoc = (mshtml.IHTMLDocument3)axWb.Document; 105 mshtml.IHTMLFrameBase2 fb= (mshtml.IHTMLFrameBase2)idoc.getElementById("i-frame"); 106 MessageBox.Show(fb.contentWindow.document.body.innerHTML); }
UDP打洞原理及代碼設計模式
UDP"打洞"原理 1. NAT分類 根據Stun協議(RFC3489),NAT大體分爲下面四類 1) Full Cone 這種NAT內部的機器A鏈接過外網機器C後,NAT會打開一個端口.而後外網的任何發到這個打開的端口的UDP數據報均可以到達A.無論是否是C發過來的. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) 任何發送到 NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000) 2) Restricted Cone 這種NAT內部的機器A鏈接過外網的機器C後,NAT打開一個端口.而後C能夠用任何端口和A通訊.其餘的外網機器不行. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) 任何從C發送到 NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000) 3) Port Restricted Cone 這種NAT內部的機器A鏈接過外網的機器C後,NAT打開一個端口.而後C能夠用原來的端口和A通訊.其餘的外網機器不行. 例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88 A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000) C(202.88.88.88:2000)發送到 NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000) 以上三種NAT通稱Cone NAT.咱們只能用這種NAT進行UDP打洞. 4) Symmetic 對於這種NAT.鏈接不一樣的外部目標.原來NAT打開的端口會變化.而Cone NAT不會.雖然能夠用端口猜想.可是成功的機率很小.所以放棄這種NAT的UDP打洞. 2. UDP hole punching 對於Cone NAT.要採用UDP打洞.須要一個公網機器C來充當」介紹人」.內網的A,B先分別和C通訊.打開各自的NAT端口.C這個時候知道A,B的公網IP: Port. 如今A和B想直接鏈接.好比A給B發.除非B是Full Cone.不然不能通訊.反之亦然.可是咱們能夠這樣. A要鏈接B.A給B發一個UDP包.同時.A讓那個介紹人給B發一個命令,讓B同時給A發一個UDP包.這樣雙方的NAT都會記錄對方的IP,而後就會容許互相通訊. 3. 同一個NAT後面的狀況 若是A,B在同一個NAT後面.若是用上面的技術來進行互連.那麼若是NAT支持loopback(就是本地到本地的轉換),A,B能夠鏈接,可是比較浪費帶寬和NAT.有一種辦法是,A,B和介紹人通訊的時候,同時把本身的local IP也告訴服務器.A,B通訊的時候,同時發local ip和公網IP.誰先到就用哪一個IP.可是local ip就有可能不知道發到什麼地方去了.好比A,B在不一樣的NAT後面可是他們各自的local ip段同樣.A給B的local IP發的UDP就可能發給本身內部網裏面的某某某了. 還有一個辦法是服務器來判斷A,B是否在一個NAT後面.(網絡拓樸不一樣會不會有問題?) WellKnown.cs //WellKnown公用庫 using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Net; using System.Net.Sockets; using System.Collections; namespace P2PWellKnown { /// <summary> /// UDP用戶登陸事件委託 /// </summary> /// <param name="sender">事件源對象</param> /// <param name="e">事件實體</param> public delegate void UdpUserLogInDelegate(object sender, UDPSockEventArgs e); /// <summary> /// 通常UDP消息事件委託 /// </summary> /// <param name="sender">事件源對象</param> /// <param name="e">事件實體</param> public delegate void UdpMessageDelegate(object sender, UDPSockEventArgs e); /// <summary> /// 初始化一個新鏈接的事件委託 /// </summary> /// <param name="sender">事件源對象</param> /// <param name="e">事件實體</param> public delegate void UdpNewConnectDelegate(object sender, UDPSockEventArgs e); /// <summary> /// P2P共享數據類 /// </summary> public class P2PConsts { /// <summary> /// UDP服務器監聽端口 /// </summary> public const int UDP_SRV_PORT = 2280; /// <summary> ///TCP服務器監聽端口 /// </summary> public const int TCP_SRV_PORT = 2000; } /// <summary> /// FormatterHelper 序列化,反序列化消息的幫助類 /// </summary> public class FormatterHelper { public static byte[] Serialize(object obj) { BinaryFormatter binaryF = new BinaryFormatter(); MemoryStream ms = new MemoryStream(1024 * 10); binaryF.Serialize(ms, obj); ms.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[(int)ms.Length]; ms.Read(buffer, 0, buffer.Length); ms.Close(); return buffer; } public static object Deserialize(byte[] buffer) { BinaryFormatter binaryF = new BinaryFormatter(); MemoryStream ms = new MemoryStream(buffer, 0, buffer.Length, false); object obj = binaryF.Deserialize(ms); ms.Close(); return obj; } } /// <summary> /// 用於承載UDPSock信息的事件類 /// </summary> public class UDPSockEventArgs : EventArgs { /// <summary> /// 要承載的消息 /// </summary> private string m_strMsg; /// <summary> /// 用戶信息 /// </summary> private string m_strUserName; /// <summary> /// 觸發該事件的公共終端 /// </summary> private IPEndPoint m_EndPoint; /// <summary> /// 初始化UDPSock事件 /// </summary> /// <param name="sMsg">用戶發送的信息</param> public UDPSockEventArgs(string sMsg) : base() { this.m_strMsg = sMsg; } /// <summary> /// 遠端用戶名 /// </summary> public string RemoteUserName { get { return m_strUserName; } set { m_strUserName = value; } } /// <summary> /// 通常套接字消息 /// </summary> public string SockMessage { get { return m_strMsg; } set { m_strMsg = value; } } /// <summary> /// 公共遠端節點 /// </summary> public IPEndPoint RemoteEndPoint { get { return m_EndPoint; } set { m_EndPoint = value; } } } } UDPP2PSock.cs //UDPP2PSock.cs using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using P2PWellKnown; namespace UDPP { /// <summary> /// UDPP2P套接字管理類 /// </summary> public class UDPP2PSock { /// <summary> /// 用戶登陸事件 /// </summary> public event UdpUserLogInDelegate OnUserLogInU; /// <summary> /// 通常UDP消息事件 /// </summary> public event UdpMessageDelegate OnSockMessageU; /// <summary> /// 初始化一個新鏈接事件 /// </summary> public event UdpNewConnectDelegate OnNewConnectU; /// <summary> /// UDP服務器 /// </summary> private UdpClient m_udpServer; /// <summary> /// UDP客戶端 /// </summary> private UdpClient m_udpClient; /// <summary> /// 服務器實際上在本地機器上監聽的 /// 端口,用於當一臺計算機上同時啓 /// 動兩個可兩以上服務器進程時,標 /// 識不一樣的服務器進程 /// </summary> private int m_iMyServerPort; /// <summary> /// 客戶端在本地機器上實際使用的端口, /// 用於當一臺計算機上同時有兩個或兩 /// 個以上客戶端進程在運行時,標識不 /// 同的客戶端進程 /// </summary> private int m_iMyClientPort; /// <summary> /// 標識是否已成功創服務器 /// </summary> private bool m_bServerCreated; /// <summary> /// 標識是否已成功建立客戶端 /// </summary> private bool m_bClientCreated; /// <summary> /// 服務器使用的線程 /// </summary> private Thread m_serverThread; /// <summary> /// 客戶端使用的線程 /// </summary> private Thread m_clientThread; /// <summary> /// 打洞線程 /// </summary> //private Thread m_burrowThread; /// <summary> /// 遠端節點 /// </summary> private IPEndPoint m_remotePoint; /// <summary> /// 當前進程做爲客戶端的公共終端 /// </summary> private string m_strMyPublicEndPoint; /// <summary> /// 當前進程做爲客戶端的私有終端 /// </summary> private string m_strMyPrivateEndPoint; /// <summary> /// 用於接受信息的 StringBuilder實例 /// </summary> private StringBuilder m_sbResponse = new StringBuilder(); /// <summary> /// P2P打洞時標識是否收到迴應消息 /// </summary> private bool m_bRecvAck = false; /// <summary> /// 請求向其方向打洞的私有終端 /// </summary> private IPEndPoint m_requestPrivateEndPoint; /// <summary> /// 請求向其方向打洞的公共終端 /// </summary> private IPEndPoint m_requestPublicEndPoint; /// <summary> /// 打洞消息要發向的節點 /// </summary> private ToEndPoint m_toEndPoint; /// <summary> /// 用於標識是否已經和請求客戶端創建點對鏈接 /// </summary> //private bool m_bHasConnected=false ; /// <summary> /// 建立服務器或客戶端的最大嘗試 /// 次數,爲(65536-60000),防止 /// 因不能建立而限入死循環或使用 /// 無效端口 /// </summary> private const int MAX_CREATE_TRY = 5536; /// <summary> /// 打洞時嘗試鏈接的最大嘗試次數 /// </summary> private const int MAX_CONNECT_TRY = 10; /// <summary> /// 構造函數,初始化UDPP2P實例 /// </summary> public UDPP2PSock() { m_iMyServerPort = P2PConsts.UDP_SRV_PORT; m_iMyClientPort = 60000; m_bClientCreated = false; m_bServerCreated = false; m_toEndPoint = new ToEndPoint(); m_serverThread = new Thread(new ThreadStart(RunUDPServer)); m_clientThread = new Thread(new ThreadStart(RunUDPClient)); //m_burrowThread = new Thread(new ThreadStart(BurrowProc)); } /// <summary> /// 建立UDP 服務器 /// </summary> public void CreateUDPSever() { int iTryNum = 0; //開始嘗試建立服務器 while (!m_bServerCreated && iTryNum < MAX_CREATE_TRY) { try { m_udpServer = new UdpClient(m_iMyServerPort); m_bServerCreated = true; } catch { m_iMyServerPort++; iTryNum++; } } //建立失敗,拋出異常 if (!m_bServerCreated && iTryNum == MAX_CREATE_TRY) { throw new Exception("建立服務器嘗試失敗!"); } m_serverThread.Start(); } /// <summary> /// 建立UDP客戶端 /// </summary> /// <param name="strServerIP"& gt;服務器IP</param> /// <param name="iServerPort"& gt;服務器端口</param> public void CreateUDPClient(string strServerIP, int iServerPort) { int iTryNum = 0; //開始嘗試建立服務器 while (!m_bClientCreated && iTryNum < MAX_CREATE_TRY) { try { m_udpClient = new UdpClient(m_iMyClientPort); m_bClientCreated = true; string strIPAddress = (System.Net.Dns.GetHostAddresses("localhost")[0]).ToString(); m_strMyPrivateEndPoint = strIPAddress + ":" + m_iMyClientPort.ToString(); } catch { m_iMyClientPort++; iTryNum++; } } //建立失敗,拋出異常 if (!m_bClientCreated && iTryNum == MAX_CREATE_TRY) { throw new Exception("建立客戶端嘗試失敗!"); } IPEndPoint hostPoint = new IPEndPoint(IPAddress.Parse(strServerIP), iServerPort); string strLocalIP = (System.Net.Dns.GetHostAddresses("localhost"))[0].ToString(); SendLocalPoint(strLocalIP, m_iMyClientPort, hostPoint); m_clientThread.Start(); } /// <summary> /// 運行UDP 服務器 /// </summary> private void RunUDPServer() { while (true) { byte[] msgBuffer = m_udpServer.Receive(ref m_remotePoint); m_sbResponse.Append(System.Text.Encoding.Default.GetString(msgBuffer)); CheckCommand(); Thread.Sleep(10); } } /// <summary> /// 運行UDP客戶端 /// </summary> private void RunUDPClient() { while (true) { byte[] msgBuffer = m_udpClient.Receive(ref m_remotePoint); m_sbResponse.Append(System.Text.Encoding.Default.GetString(msgBuffer)); CheckCommand(); Thread.Sleep(10); } } /// <summary> /// 銷燬UDP 服務器 /// </summary> public void DisposeUDPServer() { m_serverThread.Abort(); m_udpServer.Close(); } /// <summary> /// 銷燬UDP客房端 /// </summary> public void DisposeUDPClient() { m_clientThread.Abort(); m_udpClient.Close(); } /// <summary> /// 發送消息 /// </summary> /// <param name="strMsg"& gt;消息內容</param> /// <param name="REP"& gt;接收節點</param> public void SendData(string strMsg, IPEndPoint REP) { byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray()); m_udpClient.Send(byMsg, byMsg.Length, REP); } /// <summary> /// 發送消息,服務器專用 /// </summary> /// <param name="strMsg"& gt;消息內容</param> /// <param name="REP"& gt;接收節點</param> private void ServerSendData(string strMsg, IPEndPoint REP) { byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray()); m_udpServer.Send(byMsg, byMsg.Length, REP); } /// <summary> /// 發送本地節點信息 /// </summary> /// <param name="strLocalIP"& gt;本地IP</param> /// <param name="iLocalPort"& gt;本地端口</param> public void SendLocalPoint(string strLocalIP, int iLocalPort, IPEndPoint REP) { string strLocalPoint = "\x01\x02" + strLocalIP + ":" + iLocalPort.ToString() + "\x02\x01"; SendData(strLocalPoint, REP); } /// <summary> /// 同時向指定的終端(包括公共終端和私有終端)打洞 /// </summary> /// <param name="pubEndPoint"& gt;公共終端</param> /// <param name="prEndPoint"& gt;私有終端</param> /// <returns>打洞成功返回true,不然返回false</returns> public void StartBurrowTo(IPEndPoint pubEndPoint, IPEndPoint prEndPoint) { Thread burrowThread = new Thread(new ThreadStart(BurrowProc)); m_toEndPoint.m_privateEndPoint = prEndPoint; m_toEndPoint.m_publicEndPoint = pubEndPoint; burrowThread.Start(); } /// <summary> /// 打洞線程 /// </summary> private void BurrowProc() { IPEndPoint prEndPoint = m_toEndPoint.m_privateEndPoint; IPEndPoint pubEndPoint = m_toEndPoint.m_publicEndPoint; int j = 0; for (int i = 0; i < MAX_CONNECT_TRY; i++) { SendData("\x01\x07\x07\x01", prEndPoint); SendData("\x01\x07\x07\x01", pubEndPoint); // 等待接收線程標記修改 for (j = 0; j < MAX_CONNECT_TRY; j++) { if (m_bRecvAck) { m_bRecvAck = false; SendData("\x01\x07\x07\x01", prEndPoint); Thread.Sleep(50); SendData("\x01\x07\x07\x01", pubEndPoint); UDPSockEventArgs args = new UDPSockEventArgs(""); args.RemoteEndPoint = pubEndPoint; if (OnNewConnectU != null) { OnNewConnectU(this, args); } //Thread .Sleep (System .Threading.Timeout .Infinite ); return; } else { Thread.Sleep(100); } } //若是沒有收到目標主機的迴應,代表本次打 // 洞嘗試失敗,等待100毫秒後嘗試下一次打洞 Thread.Sleep(100); } //MAX_CONNECT_TRY 嘗試都失敗,代表打洞失敗,拋出異常 //throw new Exception(" 打洞失敗!"); System.Windows.Forms.MessageBox.Show("打洞失敗!");//////////// } /// <summary> /// 轉發打洞請求消息,在服務器端使用 /// </summary> /// <param name="strSrcPrEndpoint"& gt;請求轉發的源私有終端</param> /// <param name="strSrcPubEndPoint"& gt;請求轉發的源公共終端</param> /// <param name="REP"& gt;轉發消息到達的目的終端</param> public void SendBurrowRequest(string strSrcPrEndpoint, string strSrcPubEndPoint, IPEndPoint REP) { string strBurrowMsg = "\x04\x07" + strSrcPrEndpoint + " " + strSrcPubEndPoint + "\x07\x04"; ServerSendData(strBurrowMsg, REP); } /// <summary> /// 檢查字符串中的命令 /// </summary> private void CheckCommand() { int nPos; string strCmd = m_sbResponse.ToString(); //若是接收遠端用戶名 if ((nPos = strCmd.IndexOf("\x01\x02")) > -1) { ReceiveName(strCmd, nPos); // 反饋公共終給端遠端主機 string strPubEPMsg = "\x03\x07" + m_remotePoint.ToString() + "\x07\x03"; SendData(strPubEPMsg, m_remotePoint); return; } //若是接收個人公共終端 if ((nPos = strCmd.IndexOf("\x03\x07")) > -1) { ReceiveMyPublicEndPoint(strCmd, nPos); return; } //若是是打洞請求消息 if ((nPos = strCmd.IndexOf("\x04\x07")) > -1) { ReceiveAndSendAck(strCmd, nPos); return; } //若是是打洞迴應消息 if ((nPos = strCmd.IndexOf("\x01\x07")) > -1) { m_bRecvAck = true; int nPos2 = strCmd.IndexOf("\x07\x01"); if (nPos2 > -1) { m_sbResponse.Remove(nPos, nPos2 - nPos + 2); } return; } //通常聊天消息 m_sbResponse.Remove(0, strCmd.Length); RaiseMessageEvent(strCmd); } /// <summary> /// 接收遠端用戶名 /// </summary> /// <param name="strCmd"& gt;包含用戶名的控制信息</param> /// <param name="nPos"></param> private void ReceiveName(string strCmd, int nPos) { int nPos2 = strCmd.IndexOf("\x02\x01"); if (nPos2 == -1) { return; } m_sbResponse.Remove(nPos, nPos2 - nPos + 2); string strUserName = strCmd.Substring(nPos + 2, nPos2 - nPos - 2); UDPSockEventArgs e = new UDPSockEventArgs(""); e.RemoteUserName = strUserName; e.RemoteEndPoint = m_remotePoint; //觸發用戶登陸事件 if (OnUserLogInU != null) { OnUserLogInU(this, e); } } /// <summary> /// 接收打洞請求的消息併發送回應 /// </summary> /// <param name="strCmd"></param> /// <param name="nPos"></param> private void ReceiveAndSendAck(string strCmd, int nPos) { int nPos2 = strCmd.IndexOf("\x07\x04"); if (nPos2 == -1) { return; } m_sbResponse.Remove(nPos, nPos2 - nPos + 2); string strBurrowMsg = strCmd.Substring(nPos + 2, nPos2 - nPos - 2); string[] strSrcPoint = strBurrowMsg.Split(' '); //分析控制字符串包含的節點信息 string[] strPrEndPoint = strSrcPoint[0].Split(':'); string[] strPubEndPoint = strSrcPoint[1].Split(':'); m_requestPrivateEndPoint = new IPEndPoint(IPAddress.Parse(strPrEndPoint[0]), int.Parse(strPrEndPoint[1])); m_requestPublicEndPoint = new IPEndPoint(IPAddress.Parse(strPubEndPoint[0]), int.Parse(strPubEndPoint[1])); //向請求打洞終端的方向打洞 StartBurrowTo(m_requestPublicEndPoint, m_requestPrivateEndPoint); } /// <summary> /// 接收個人公共終端 /// </summary> /// <param name="strCmd"& gt;包含公共終端的控制信息</param> /// <param name="nPos"& gt;控制字符串的起始位置</param> private void ReceiveMyPublicEndPoint(string strCmd, int nPos) { int nPos2 = strCmd.IndexOf("\x07\x03"); if (nPos2 == -1) { return; } m_sbResponse.Remove(nPos, nPos2 - nPos + 2); m_strMyPublicEndPoint = strCmd.Substring(nPos + 2, nPos2 - nPos - 2); } /// <summary> /// 觸發通常UDP消息事件 /// </summary> /// <param name="strMsg"& gt;消息內容</param> private void RaiseMessageEvent(string strMsg) { UDPSockEventArgs args = new UDPSockEventArgs(""); args.SockMessage = strMsg; args.RemoteEndPoint = m_remotePoint; if (OnSockMessageU != null) { OnSockMessageU(this, args); } } /// <summary> /// 獲取當前進程做爲客戶端的公共終端 /// </summary> public string MyPublicEndPoint { get { return m_strMyPublicEndPoint; } } /// <summary> /// 獲取當前進程做爲客戶端的私有終端 /// </summary> public string MyPrivateEndPoint { get { return m_strMyPrivateEndPoint; } } } /// <summary> /// 保存打洞消息要發向的節點信息 /// </summary> class ToEndPoint { /// <summary> /// 私有節點 /// </summary> public IPEndPoint m_privateEndPoint; /// <summary> /// 公共節點 /// </summary> public IPEndPoint m_publicEndPoint; } } 關於如何使用上述程序包的一些說明: 主要程序的初始化,參考代碼以下: using UDPP; using P2PWellKnown; //建立UDP服務器和客戶端 try { string strServerIP = "127.0.0.1"; UDPP2PSock udpSock = new UDPP2PSock(); udpSock.OnUserLogInU += new UdpUserLogInDelegate(OnUserLogInU); udpSock.OnNewConnectU += new UdpNewConnectDelegate(OnNewConnectU); udpSock.CreateUDPSever(); udpSock.CreateUDPClient(strServerIP, P2PConsts.UDP_SRV_PORT); } catch (Exception ex) { } 經上面的初始化後,就可使用類UDPP2PSock中的方法了。 注: udpSock.OnUserLogInU += new UdpUserLogInDelegate(OnUserLogInU); udpSock.OnNewConnectU += new UdpNewConnectDelegate(OnNewConnectU); 中的OnUserLogInU和OnNewConnectU是事件名稱 如 private void test(object sender, UDPSockEventArgs e) { MessageBox.Show("ok"); } 個性簽名:作要作好,作到不倫不類不如不作。
c# 中如何結束進程explorer.exe數組
foreach (System.Diagnostics.Process thisproc in System.Diagnostics.Process.GetProcesses()) { if(thisproc.ProcessName.Equals("explorer")) { thisproc.Kill(); } }
c#換ip代理源碼
不少朋友都想如何提升本身的網站流量,但是都沒有什麼好的辦法 通過很長時間的研究,在C#中實現了,固然了,這部分代碼其中一部分是網上的,不是原創。 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; using System.Text; using System.Net; namespace WebSock { /// <summary> /// Form1 的摘要說明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.GroupBox groupBox1; private AxSHDocVw.AxWebBrowser axWebBrowser1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.OpenFileDialog openFileDialog1; private System.Windows.Forms.Timer timer1; private System.ComponentModel.IContainer components; private System.Windows.Forms.StatusBar statusBar1; private System.Windows.Forms.StatusBarPanel statusBarPanel1; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.GroupBox groupBox4; private System.Windows.Forms.Button button3; ArrayList arrText = new ArrayList(); int Total = 0; int i,k=0; private System.Windows.Forms.GroupBox groupBox5; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox txtWebUrl; private const string TitleInfo = "程序製做紅色銀狐"; private System.Windows.Forms.ListBox listBox1; private string strUrl = ""; public Form1() { // // Windows 窗體設計器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 調用後添加任何構造函數代碼 // } /// <summary> /// 清理全部正在使用的資源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows 窗體設計器生成的代碼 /// <summary> /// 設計器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內容。 /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.axWebBrowser1 = new AxSHDocVw.AxWebBrowser(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.listBox1 = new System.Windows.Forms.ListBox(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); this.timer1 = new System.Windows.Forms.Timer(this.components); this.statusBar1 = new System.Windows.Forms.StatusBar(); this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.button3 = new System.Windows.Forms.Button(); this.groupBox5 = new System.Windows.Forms.GroupBox(); this.label1 = new System.Windows.Forms.Label(); this.txtWebUrl = new System.Windows.Forms.TextBox(); this.groupBox1.SuspendLayout(); this.groupBox3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).BeginInit(); this.groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit(); this.groupBox4.SuspendLayout(); this.groupBox5.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Controls.Add(this.groupBox3); this.groupBox1.Controls.Add(this.groupBox2); this.groupBox1.Location = new System.Drawing.Point(0, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(810, 440); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; // // groupBox3 // this.groupBox3.Controls.Add(this.axWebBrowser1); this.groupBox3.Location = new System.Drawing.Point(312, 8); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(490, 424); this.groupBox3.TabIndex = 2; this.groupBox3.TabStop = false; this.groupBox3.Text = "瀏覽器"; // // axWebBrowser1 // this.axWebBrowser1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.axWebBrowser1.ContainingControl = this; this.axWebBrowser1.Enabled = true; this.axWebBrowser1.Location = new System.Drawing.Point(8, 16); this.axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser1.OcxState"))); this.axWebBrowser1.Size = new System.Drawing.Size(474, 400); this.axWebBrowser1.TabIndex = 0; // // groupBox2 // this.groupBox2.Controls.Add(this.listBox1); this.groupBox2.Location = new System.Drawing.Point(8, 8); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(296, 424); this.groupBox2.TabIndex = 1; this.groupBox2.TabStop = false; this.groupBox2.Text = "代理IP地址"; // // listBox1 // this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.listBox1.ItemHeight = 12; this.listBox1.Location = new System.Drawing.Point(8, 16); this.listBox1.Name = "listBox1"; this.listBox1.Size = new System.Drawing.Size(280, 398); this.listBox1.TabIndex = 2; // // button1 // this.button1.Location = new System.Drawing.Point(310, 16); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(176, 32); this.button1.TabIndex = 1; this.button1.Text = "載入代理IP"; this.button1.Click += new System.EventHandler(this.button1_Click_1); // // button2 // this.button2.Location = new System.Drawing.Point(486, 16); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(176, 32); this.button2.TabIndex = 2; this.button2.Text = "開始刷流量"; this.button2.Click += new System.EventHandler(this.button2_Click); // // timer1 // this.timer1.Interval = 10000; this.timer1.Tick += new System.EventHandler(this.timer1_Tick); // // statusBar1 // this.statusBar1.Dock = System.Windows.Forms.DockStyle.None; this.statusBar1.Location = new System.Drawing.Point(0, 552); this.statusBar1.Name = "statusBar1"; this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] { this.statusBarPanel1}); this.statusBar1.ShowPanels = true; this.statusBar1.Size = new System.Drawing.Size(810, 24); this.statusBar1.TabIndex = 3; // // statusBarPanel1 // this.statusBarPanel1.Width = 820; // // groupBox4 // this.groupBox4.Controls.Add(this.button3); this.groupBox4.Controls.Add(this.button2); this.groupBox4.Controls.Add(this.button1); this.groupBox4.Location = new System.Drawing.Point(0, 496); this.groupBox4.Name = "groupBox4"; this.groupBox4.Size = new System.Drawing.Size(810, 56); this.groupBox4.TabIndex = 4; this.groupBox4.TabStop = false; this.groupBox4.Text = "操做區"; // // button3 // this.button3.Location = new System.Drawing.Point(134, 16); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(176, 32); this.button3.TabIndex = 3; this.button3.Text = "從網絡獲取代理IP"; this.button3.Click += new System.EventHandler(this.button3_Click); // // groupBox5 // this.groupBox5.Controls.Add(this.label1); this.groupBox5.Controls.Add(this.txtWebUrl); this.groupBox5.Location = new System.Drawing.Point(0, 444); this.groupBox5.Name = "groupBox5"; this.groupBox5.Size = new System.Drawing.Size(810, 48); this.groupBox5.TabIndex = 5; this.groupBox5.TabStop = false; this.groupBox5.Text = "要刷網站地址"; // // label1 // this.label1.Location = new System.Drawing.Point(16, 21); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(56, 16); this.label1.TabIndex = 1; this.label1.Text = "網站地址"; // // txtWebUrl // this.txtWebUrl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.txtWebUrl.Location = new System.Drawing.Point(80, 16); this.txtWebUrl.Name = "txtWebUrl"; this.txtWebUrl.Size = new System.Drawing.Size(720, 21); this.txtWebUrl.TabIndex = 0; this.txtWebUrl.Text = "http://www.51solve.com/"; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(810, 575); this.Controls.Add(this.groupBox5); this.Controls.Add(this.groupBox4); this.Controls.Add(this.statusBar1); this.Controls.Add(this.groupBox1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.Name = "Form1"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "網站流量訪問程序製做:紅色銀狐"; this.groupBox1.ResumeLayout(false); this.groupBox3.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).EndInit(); this.groupBox2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit(); this.groupBox4.ResumeLayout(false); this.groupBox5.ResumeLayout(false); this.ResumeLayout(false); } #endregion /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } //定義結構體代理信息 public struct Struct_INTERNET_PROXY_INFO { public int dwAccessType; public IntPtr proxy; public IntPtr proxyBypass; }; [DllImport("wininet.dll", SetLastError = true)] private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength); private void RefreshIESettings(string strProxy) { const int INTERNET_OPTION_PROXY = 38; const int INTERNET_OPEN_TYPE_PROXY = 3; Struct_INTERNET_PROXY_INFO struct_IPI; // Filling in structure struct_IPI.dwAccessType = INTERNET_OPEN_TYPE_PROXY; struct_IPI.proxy = Marshal.StringToHGlobalAnsi(strProxy); struct_IPI.proxyBypass = Marshal.StringToHGlobalAnsi("local"); // Allocating memory IntPtr intptrStruct = Marshal.AllocCoTaskMem(Marshal.SizeOf(struct_IPI)); // Converting structure to IntPtr Marshal.StructureToPtr(struct_IPI, intptrStruct, true); bool iReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, intptrStruct, Marshal.SizeOf(struct_IPI)); } private void StartShua() { statusBar1.Panels[0].Text = "正在使用" + arrText[k].ToString() + "代理IP訪問網站"; this.listBox1.SetSelected(k,true); RefreshIESettings(arrText[k].ToString()); System.Object nullObject = 0; string strTemp = String.Empty; System.Object nullObjStr = strTemp; axWebBrowser1.Navigate(strUrl, ref nullObject, ref nullObjStr, ref nullObjStr, ref nullObjStr); k+=1; if(k>=i)k=0; } private void button1_Click_1(object sender, System.EventArgs e) { arrText.Clear(); i = 0; if(openFileDialog1.ShowDialog() ==DialogResult.OK) { string strPath,strLine = ""; strPath = openFileDialog1.FileName.ToString(); StreamReader sr = new StreamReader(strPath); while(strLine != null) { strLine = sr.ReadLine(); if(strLine != null) { i+=1; arrText.Add(strLine); listBox1.Items.Add(strLine); } } sr.Close(); } } private void timer1_Tick(object sender, System.EventArgs e) { StartShua(); } private void button2_Click(object sender, System.EventArgs e) { Total = listBox1.Items.Count; strUrl = txtWebUrl.Text; if(button2.Text == "開始刷流量") { if(i == 0 && Total == 0)return; if(strUrl.Length == 0)return; StartShua(); button2.Text = "中止刷流量"; timer1.Enabled = true; timer1.Start(); button1.Enabled = false; button3.Enabled = false; } else { timer1.Stop(); timer1.Enabled = false; button2.Text = "開始刷流量"; button1.Enabled = true; button3.Enabled = true; arrText.Clear(); } } private void button3_Click(object sender, System.EventArgs e) { arrText.Clear(); i = 0; listBox1.Items.Clear(); string strHtml = ""; string strPort = ""; string strResultIP = ""; long PosB = 0; long PosA = 0; long PosC = 0; string Url = "http://www.pass-e.com/proxy/"; try { strHtml = GetHtml(Url); strHtml = checkStr(strHtml); strHtml = strHtml.ToLower(); PosA = strHtml.IndexOf("list",0); //MessageBox.Show(GetHtml(Url)); while(PosA>0) { i+=1; PosB = strHtml.IndexOf(",",(int)PosA); strResultIP = strHtml.Substring((int)PosA,(int)PosB-(int)PosA); strResultIP = strResultIP.Replace("list",""); PosC = strHtml.IndexOf(",",(int)PosB+1); strPort = strHtml.Substring((int)PosB,(int)PosC-(int)PosB); strPort = strPort.Replace(",",""); listBox1.Items.Add(strResultIP+":"+strPort); PosA = strHtml.IndexOf("list",(int)PosC); arrText.Add(strResultIP+":"+strPort); } } catch(Exception ex) { MessageBox.Show(ex.Message,TitleInfo,MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } public string checkStr(string html) { string str = Convert.ToString((char)34); Regex regex1 = new Regex(@"<mce:script[/s/S]+</script *><!-- ", RegexOptions.IgnoreCase); Regex regex2 = new Regex(@" href *= *[/s/S]*script *:", RegexOptions.IgnoreCase); Regex regex3 = new Regex(@" no[/s/S]*=", RegexOptions.IgnoreCase); Regex regex4 = new Regex(@"<iframe[/s/S]+</iframe *>", RegexOptions.IgnoreCase); Regex regex5 = new Regex(@"<frameset[/s/S]+</frameset *>", RegexOptions.IgnoreCase); Regex regex6 = new Regex(@"/<img[^/>]+/>", RegexOptions.IgnoreCase); Regex regex7 = new Regex(@"</p>", RegexOptions.IgnoreCase); Regex regex8 = new Regex(@"<p>", RegexOptions.IgnoreCase); Regex regex9 = new Regex(@"<[^>]*>", RegexOptions.IgnoreCase); html = html.Replace("/r/n",""); //html = regex1.Replace(html, ""); //過濾<script> // --></mce:script>標記 html = regex2.Replace(html, ""); //過濾href=javascript: (<A>) 屬性 html = regex3.Replace(html, " _disibledevent="); //過濾其它控件的on...事件 html = regex4.Replace(html, ""); //過濾iframe html = regex5.Replace(html, ""); //過濾frameset html = regex6.Replace(html, ""); //過濾frameset html = regex7.Replace(html, ""); //過濾frameset html = regex8.Replace(html, ""); //過濾frameset html = regex9.Replace(html, ""); html = html.Replace(" ", ""); html = html.Replace("</strong>", ""); html = html.Replace("<strong>", ""); html = html.Replace("/n",""); html = html.Replace(str ,""); html = html.Replace("}" ,""); html = html.Replace("(" ,""); html = html.Replace(")" ,""); //html = html.Replace(";" ,""); html = html.Replace("'" ,""); html = html.Replace(" " ,""); html = html.Replace(" ",""); return html; } public string GetHtml(string myUrl) { HttpWebRequest myHttpWebRequest; HttpWebResponse myHttpWebResponse; //string Html; try { string URL = myUrl; Uri myUri = new Uri(myUrl); WebRequest myWebRequest = WebRequest.Create(URL); //使用Creat方法建立WebRequest實例 myHttpWebRequest = (HttpWebRequest)myWebRequest; //實現WebRequest類型和HttpWebRequest類型的轉換 WebResponse myWebResponse = myHttpWebRequest.GetResponse(); //得到響應信息 myHttpWebResponse = (HttpWebResponse)myWebResponse; Stream myStream = myHttpWebResponse.GetResponseStream(); //得到從當前Internet資源返回的響應流數據 StreamReader srReader = new StreamReader(myStream, Encoding.Default); //利用得到的響應流和系統缺省編碼來初始化StreamReader實例。 string sTemp = srReader.ReadToEnd(); //從響應流從讀取數據 srReader.Close(); return sTemp; } //顯示讀取的數據 ( ) catch (WebException WebExcp) { return WebExcp.Message.ToString(); } } } } 經過它的實現,只要你有足夠的代理IP那麼你的網站流量變飛速的提高。
c#中WinForm的TextBox循環自動滾動示例
這個問題來自論壇提問,演示代碼以下 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsApplication27 { /// <summary> /// 演示如何在TextBox中讓文字循環滾動: /// 做者jinjazz /// 做者blog:http://blog.csdn.net/jinjazz /// </summary> public partial class Form1 : Form { public Form1() { InitializeComponent(); this.textBox1.Clear(); for (int i = 0; i <= 20;i++ ) { this.textBox1.Text += string.Format("{0}:jinjazz__{1} ", i,i); } this.timer1.Interval = 200; this.timer1.Start(); } //發送消息 [DllImport("user32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam); //獲取滾動條位置 [DllImport("user32")] public static extern int GetScrollPos(IntPtr hwnd, int nBar); //設置滾動條位置 [DllImport("user32.dll")] static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); public const int EM_LINESCROLL = 0xb6; private void timer1_Tick(object sender, EventArgs e) { int i= GetScrollPos(this.textBox1.Handle,1); //向下滾動一行 SendMessage(this.textBox1.Handle, EM_LINESCROLL, 0, 1);//0,1表明垂直滾動條向下滾動 //判斷是否有位置變化,若是沒有則說明到了底部,返回開始處 if (i == GetScrollPos(this.textBox1.Handle, 1)) { //回到頂部,這裏用SetScrollPos彷佛有問題,滾動條和文字不是同步更新 this.textBox1.SelectionStart = 0; this.textBox1.SelectionLength = 1; this.textBox1.ScrollToCaret(); this.textBox1.SelectionLength = 0; } Console.WriteLine(i); } private void textBox1_MouseEnter(object sender, EventArgs e) { this.timer1.Stop(); } private void textBox1_MouseLeave(object sender, EventArgs e) { this.timer1.Start(); } } }
wpf翻頁效果
教你打造Silverlight超酷翻頁實例 做者:洗碗心得 | 出處:博客園 | 2011/10/18 19:47:52 | 閱讀22次 常常閱讀電子雜誌的朋友對其流暢天然的翻頁過渡效果應當留下了十分深入的印象。這些雜誌都是使用Flash技術製做而成的。總想着能用Silverlight實現這樣的效果,去網上查查資料,找到了一個微軟官方提供的翻頁效果例子(教程說明點這裏,在線實例演示及源代碼下載點這裏)。這裏再推薦一個外國網站的Silverlight翻頁在線實例。 效果是十分的贊,只惋惜控制的邏輯是用JavaScript代碼實現的,這就不利於程序邏輯的總體控制。筆者最近在CodePlex上,找到了一個開源的翻頁控件WPF and Silverlight BookControls(點這裏進入),用它進行Silverlight翻頁效果的開發就顯得十分駕輕就熟了。下面就向你們一步一步地介紹Silverlight翻頁效果的實現過程。 導航: ①創建翻頁項目解決方案 ②添加必要文件 ③構建應用程序界面 ④設置應用程序控制邏輯 ⑤最終效果圖 1、創建翻頁項目解決方案 點擊File->Projects...菜單選項,新建一個ASP.NET Web Application。 將新建工程名稱命名爲FlipPage。 在解決方案下繼續添加一個Silverlight應用程序項目,將該工程命名爲SilverlightClient。 在彈出的對話框中,直接點OK按鈕。 點擊一下「所有保存」按鈕,完成項目工程的建立。 2、添加必要文件 在SilverlightClient項目文件夾下,新建一個名爲Dll的文件夾,在裏面放入WPF and Silverlight BookControls的動態連接庫文件SLMitsuControls.dll(以下圖)。在FlipPage項目文件夾下,新建一個名爲mediaPictures的子文件夾,在裏面放入將在書中顯示的圖片,以下圖所示命名。一樣的,在SilverlightClient項目文件夾下,新建一個名爲PageType的文件夾,而後再新建兩個類分別命名爲LeftPage.cs和RightPage.cs(以下圖),它們分別表明了書的偶數和奇數頁面,具體代碼以下所示(詳細的說明請見代碼註釋)。 LeftPage.cs文件代碼: Code System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace SilverlightClient.TypePage { public class LeftPage : Canvas { //定義將在頁面上顯示的元素 private Image imgPhoto; private Button btnPrevious; private Rectangle RecBorder; private TextBlock PageNum; //構造函數 public LeftPage() { //頁面的設置 this.Width = 452; this.Height = 630; this.Background = new SolidColorBrush(Colors.White); Canvas.SetLeft(this, 0); Canvas.SetTop(this, 0); //頁面邊框的設置 RecBorder = new Rectangle(); RecBorder.Width = 452; RecBorder.Height = 630; Canvas.SetLeft(RecBorder, 0);//設置頁面邊框在Canvas中的位置,下同。 Canvas.SetTop(RecBorder, 0); RecBorder.Stroke = new SolidColorBrush(Colors.Black); RecBorder.StrokeThickness = 0; this.Children.Add(RecBorder); //照片的設置 imgPhoto = new Image(); imgPhoto.Width = 450; imgPhoto.Height = 600; Canvas.SetLeft(imgPhoto, 1); Canvas.SetTop(imgPhoto, 1); this.Children.Add(imgPhoto); //「前一頁」按鈕的設置 btnPrevious = new Button(); btnPrevious.Width = 150; btnPrevious.Height = 20; btnPrevious.Content = "<< 前一頁"; btnPrevious.HorizontalContentAlignment = HorizontalAlignment.Center; btnPrevious.VerticalContentAlignment = VerticalAlignment.Center; btnPrevious.Cursor = Cursors.Hand; Canvas.SetLeft(btnPrevious, 151); Canvas.SetTop(btnPrevious, 605); this.Children.Add(btnPrevious); //頁碼文本的設置 PageNum = new TextBlock(); PageNum.Width = 100; PageNum.Height = 20; PageNum.Text = "00 / 00"; PageNum.TextAlignment = TextAlignment.Left; PageNum.VerticalAlignment = VerticalAlignment.Center; PageNum.FontFamily = new FontFamily("Comic sans MS"); Canvas.SetLeft(PageNum, 10); Canvas.SetTop(PageNum, 607); this.Children.Add(PageNum); } //設置圖片路徑 public void setterimgPhoto(string path) { BitmapImage btm = new BitmapImage(); btm.UriSource = new Uri(path, UriKind.Relative); imgPhoto.Source = btm; } //設置按鈕是否可見 public void setterDisplayBtnPrevious(bool YesNo) { if (YesNo) { btnPrevious.Visibility = Visibility.Visible; } else { btnPrevious.Visibility = Visibility.Collapsed; } } //設置頁碼 public void setterPageNumber(string currentPageNum, string TotalPageNum) { PageNum.Text = currentPageNum + " / " + TotalPageNum; } //返回按鈕單擊事件關聯 public Button getbtnPrevious() { return btnPrevious; } } } RightPage.cs文件代碼: Code System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace SilverlightClient.TypePage { public class RightPage : Canvas { //定義將在頁面上顯示的元素 private Image imgPhoto; private Button btnNext; private Rectangle RecBorder; private TextBlock PageNum; //構造函數 public RightPage() { //頁面的設置 this.Width = 452; this.Height = 630; this.Background = new SolidColorBrush(Colors.White); Canvas.SetLeft(this, 0);//設置頁面邊框在Canvas中的位置,下同。 Canvas.SetTop(this, 0); //頁面邊框的設置 RecBorder = new Rectangle(); RecBorder.Width = 452; RecBorder.Height = 630; Canvas.SetLeft(RecBorder, 0); Canvas.SetTop(RecBorder, 0); RecBorder.Stroke = new SolidColorBrush(Colors.Black); RecBorder.StrokeThickness = 0; this.Children.Add(RecBorder); //照片的設置 imgPhoto = new Image(); imgPhoto.Width = 450; imgPhoto.Height = 600; Canvas.SetLeft(imgPhoto, 1); Canvas.SetTop(imgPhoto, 1); this.Children.Add(imgPhoto); //「後一頁」按鈕的設置 btnNext = new Button(); btnNext.Width = 150; btnNext.Height = 20; btnNext.Content = "後一頁 >>"; btnNext.HorizontalContentAlignment = HorizontalAlignment.Center; btnNext.VerticalContentAlignment = VerticalAlignment.Center; btnNext.Cursor = Cursors.Hand; Canvas.SetLeft(btnNext, 151); Canvas.SetTop(btnNext, 605); this.Children.Add(btnNext); //頁碼文本的設置 PageNum = new TextBlock(); PageNum.Width = 100; PageNum.Height = 20; PageNum.Text = "00 / 00"; PageNum.TextAlignment = TextAlignment.Right; PageNum.VerticalAlignment = VerticalAlignment.Center; PageNum.FontFamily = new FontFamily("Comic sans MS"); Canvas.SetLeft(PageNum, 340); Canvas.SetTop(PageNum, 607); this.Children.Add(PageNum); } //設置圖片路徑 public void setterimgPhoto(string path) { BitmapImage btm = new BitmapImage(); btm.UriSource = new Uri(path, UriKind.Relative); imgPhoto.Source = btm; } //設置按鈕是否可見 public void setterDisplayBtnNext(bool YesNo) { if (YesNo) { btnNext.Visibility = Visibility.Visible; } else { btnNext.Visibility = Visibility.Collapsed; } } //設置頁碼 public void setterPageNumber(string currentPageNum, string TotalPageNum) { PageNum.Text = currentPageNum + " / " + TotalPageNum; } //返回按鈕單擊事件關聯 public Button getbtnNext() { return btnNext; } } } 3、構建應用程序界面 詳細的說明請見代碼註釋。 MainPage.xaml文件代碼: CodeUserControl x:Class="SilverlightClient.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls" mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" Loaded="UserControl_Loaded"> <Grid x:Name="LayoutRoot"> <Canvas x:Name="layout" Background="White" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0"> <!--顯示層--> <Canvas x:Name="canvasBook" Background="White" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0" Visibility="Collapsed"> <local:UCBook x:Name="book" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0" /><!--BookControl--> </Canvas> <!--加載層--> <Canvas x:Name="canvChanging" Width="500" Height="75" Canvas.Left="200" Canvas.Top="250" Visibility="Collapsed" Background="Transparent"> <TextBlock x:Name="changingText" Text="頁面加載中 " Width="200" Height="30" Canvas.Left="0" Canvas.Top="0" FontFamily="comic sans ms" FontSize="14"></TextBlock> <ProgressBar x:Name="changingProgressBar" Width="500" Height="30" Canvas.Left="0" Canvas.Top="30"></ProgressBar> </Canvas> </Canvas> </Grid> </UserControl> 4、設置應用程序控制邏輯 詳細的說明請見代碼註釋。 1)MainPage.xaml.cs文件代碼: Code System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Threading; using SLMitsuControls; namespace SilverlightClient { public partial class MainPage : UserControl, IDataProvider { //定義全局變量 private List<object> PageObjectList;//頁面對象列表 public enum PageType { right, left };//頁面類型 public string fileMedia = "";//文件媒體 public string headerPage = "";//首頁 public int maxiPageNum = 0;//最大頁數 public enum Location { local, web };//枚舉應用程序所在 public Location modeLocation; private int pageDownload = 0;//下載的頁面數 private string uriResources = "";//Uri地址 //構造函數 public MainPage() { InitializeComponent(); PageObjectList = new List<object>(); } //UserControl事件觸發處理 private void UserControl_Loaded(object sender, RoutedEventArgs e) { if (modeLocation == Location.local) { this.canvChanging.Visibility = Visibility.Collapsed; this.canvasBook.Visibility = Visibility.Visible; //填充頁面列表 FillPagesList(); } if (modeLocation == Location.web) { this.canvChanging.Visibility = Visibility.Visible; this.canvasBook.Visibility = Visibility.Collapsed; //開始下載頁面 DownloadPages(); } } //開始將頁面填充至List中 private void FillPagesList() { //用頁面填充列表 for (int xx = 1; xx <= maxiPageNum; xx++) { if (xx % 2 != 0) { //前一頁即奇數頁 AddPageToList(PageType.right, fileMedia + "/" + headerPage + xx.ToString("00") + ".jpg", xx.ToString(), maxiPageNum.ToString(), true); } else { //後一頁即偶數頁 AddPageToList(PageType.left, fileMedia + "/" + headerPage + xx.ToString("00") + ".jpg", xx.ToString(), maxiPageNum.ToString(), true); } } //移除最後一頁的按鈕 TypePage.RightPage page = PageObjectList[maxiPageNum - 1] as TypePage.RightPage; page.setterDisplayBtnNext(false); //爲翻頁按鈕指派事件觸發處理 for (int xx = 1; xx < maxiPageNum; xx++) { if (xx % 2 != 0) { //前一頁即奇數頁 TypePage.RightPage pp = PageObjectList[xx - 1] as TypePage.RightPage; Button btnNext = pp.getbtnNext(); btnNext.Click += new RoutedEventHandler(btnNext_Click); } else { //後一頁即偶數頁 TypePage.LeftPage pp = PageObjectList[xx - 1] as TypePage.LeftPage; Button btnPrevious = pp.getbtnPrevious(); btnPrevious.Click += new RoutedEventHandler(btnPrevious_Click); } } //爲Book設置數據內容 book.SetData(this); } //向頁面列表中添加具體頁面 private void AddPageToList(PageType pageType, string pathImage, string numPage, string numMaxiPage, bool showBtnYesNo) { switch (pageType) { case PageType.right: TypePage.RightPage pcd = new SilverlightClient.TypePage.RightPage(); pcd.setterimgPhoto(pathImage); pcd.setterPageNumber(numPage, numMaxiPage); pcd.setterDisplayBtnNext(showBtnYesNo); PageObjectList.Add(pcd); break; case PageType.left: TypePage.LeftPage pcg = new SilverlightClient.TypePage.LeftPage(); pcg.setterimgPhoto(pathImage); pcg.setterPageNumber(numPage, numMaxiPage); pcg.setterDisplayBtnPrevious(showBtnYesNo); PageObjectList.Add(pcg); break; } } //「下一頁」按鈕事件觸發處理 private void btnNext_Click(object sender, RoutedEventArgs e) { book.AnimateToNextPage(500); } //「上一頁」按鈕事件觸發處理 private void btnPrevious_Click(object sender, RoutedEventArgs e) { book.AnimateToPreviousPage(500); } //從網絡上下載頁面 private void DownloadPages() { this.canvChanging.Visibility = Visibility.Visible; this.uriResources = Application.Current.Host.Source.AbsoluteUri; int index = uriResources.IndexOf("SilverlightClient.xap"); uriResources = uriResources.Substring(0, index); this.changingProgressBar.Minimum = 0; this.changingProgressBar.Maximum = maxiPageNum - 1; string theResources = uriResources + fileMedia + "/" + headerPage + (pageDownload + 1).ToString("00") + ".jpg"; string theResourcesNum = headerPage + (pageDownload + 1).ToString("00") + ".jpg"; AsynchronouslyDownloadPage(theResources, theResourcesNum); } //異步下載頁面 private void AsynchronouslyDownloadPage(string path, string num) { WebClient unWeb = new WebClient(); unWeb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(unWeb_DownloadStringCompleted); unWeb.DownloadStringAsync(new Uri(path)); this.changingText.Text = "正在下載 : " + num; this.changingProgressBar.Value = this.pageDownload; } //異步下載頁面完成事件觸發處理 private void unWeb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { this.pageDownload++; if (this.pageDownload < this.maxiPageNum)//持續不斷下載頁面直到全部頁面都下完 { string theResources = uriResources + fileMedia + "/" + headerPage + (pageDownload + 1).ToString("00") + ".jpg"; string theResourcesNum = headerPage + (pageDownload + 1).ToString("00") + ".jpg"; AsynchronouslyDownloadPage(theResources, theResourcesNum); } else { FillPagesList(); this.canvChanging.Visibility = Visibility.Collapsed; this.canvasBook.Visibility = Visibility.Visible; } } //強制聲明接口 #region IDataProvider Members public object GetItem(int index) { return PageObjectList[index]; } public int GetCount() { return PageObjectList.Count; } #endregion } } 2)App.xaml.cs文件代碼: Code System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SilverlightClient { public partial class App : Application { public string gFileMedia = ""; public string gHeaderPage = ""; public int gPageNumber = 0; public string gModeLocation = ""; public App() { this.Startup += this.Application_Startup; this.Exit += this.Application_Exit; this.UnhandledException += this.Application_UnhandledException; InitializeComponent(); } private void Application_Startup(object sender, StartupEventArgs e) { int paramOk = 0; //從HTML中取出初始化數據 if (e.InitParams.ContainsKey("gFile")) { gFileMedia = e.InitParams["gFile"]; paramOk++; } if (e.InitParams.ContainsKey("gHeaderPage")) { gHeaderPage = e.InitParams["gHeaderPage"]; paramOk++; } if (e.InitParams.ContainsKey("gNum")) { string recup = e.InitParams["gNum"]; gPageNumber = int.Parse(recup); paramOk++; } if (e.InitParams.ContainsKey("gLocation")) { gModeLocation = e.InitParams["gLocation"]; paramOk++; } if (paramOk == 4) { //初始化MainPage MainPage maPage = new MainPage(); maPage.fileMedia = gFileMedia; maPage.headerPage = gHeaderPage; maPage.maxiPageNum = gPageNumber; if (gModeLocation.CompareTo("local") == 0) { maPage.modeLocation = MainPage.Location.local; } if (gModeLocation.CompareTo("web") == 0) { maPage.modeLocation = MainPage.Location.web; } this.RootVisual = maPage; } } private void Application_Exit(object sender, EventArgs e) { } private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) { if (!System.Diagnostics.Debugger.IsAttached) { e.Handled = true; Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); } } private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) { try { string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n"); System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); } catch (Exception) { } } } } 3)在SilverlightClientTestPage.aspx文件(位於工程FlipPage文件夾下)中,添加用綠色粗體標明的代碼: <body> <form id="form1" runat="server" style="height:100%"> <div id="silverlightControlHost"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/SilverlightClient.xap"/> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="3.0.40624.0" /> <param name="autoUpgrade" value="true" /> <!--設置Book初始化參數--> <param name="initParams" value="gFile=mediaPictures, gHeaderPage=albumPictures, gNum=9, gLocation=web" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/> </a> </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div> </form> </body> 5、最終效果圖 [項目源文件下載]
代理IP的高匿名,匿名和透明的區別
若是從隱藏使用代理用戶的級別上劃分,代理能夠分爲三種,即高度匿名代理、普通匿名代理和透明代理。
(1)高度匿名代理不改變客戶機的請求,這樣在服務器看來就像有個真正的客戶瀏覽器在訪問它,這時客戶的真實IP是隱藏的,服務器端不會認爲咱們使用了代理。
(2)普通匿名代理能隱藏客戶機的真實IP,但會改變咱們的請求信息,服務器端有可能會認爲咱們使用了代理。不過使用此種代理時,雖然被訪問的網站不能知道你的ip地址,但仍然能夠知道你在使用代理,固然某些可以偵測ip的網頁仍然能夠查到你的ip。
(3)透明代理,它不但改變了咱們的請求信息,還會傳送真實的IP地址。
三者隱藏使用代理者身份的級別依次爲高度匿名代理最隱蔽,其次是普通匿名代理,最差的是透明代理。
對winform中tabContorl隱藏tabPage的補充
前幾天說到winfom中tabContorl隱藏tabPage的問題,總的來講達到了目的,但效果通常。 今天在看msdn時候發現了一個tabPage的屬性其實也能夠實現這個效果。 微軟對tabContorl中的tabPage隱藏的實現方法也是在集合中刪除,彷佛只有這一個方法,因此個人方法也跟這個差很少。 就是設置tabPage的parent屬性爲null 原理很簡單,若是tabPage的parent控件不存在,則tabPage也不存在。 若是想讓它顯示就設置tabPage的parent爲tabContorl控件就能夠了。 下面是主要代碼 /// <summary> /// 隱藏tabPage1 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { this.tabPage1.Parent = null; } /// <summary> /// 顯示tabPage1 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { this.tabPage1.Parent = this.tabControl1; } 很簡單吧? 恩,不過問題跟上一次同樣,順序又不對了。 但這個問題只存在於隱藏了前一個tabPage的狀況。
分解Gif圖像
對於一個Gif進行拆分,其實Image對象自己就支持,例如對於一個Gif文件拆分紅Jpeg文件方式,能夠按照以下的方式進行處理。 using System.Drawing.Drawing2D; using System.Drawing.Imaging; Image imgGif = Image.FromFile(@"d:\test.gif"); //Create a new FrameDimension object from this image FrameDimension ImgFrmDim = new FrameDimension( imgGif.FrameDimensionsList[0] ); //Determine the number of frames in the image //Note that all images contain at least 1 frame, //but an animated GIF will contain more than 1 frame. int nFrameCount = imgGif.GetFrameCount( ImgFrmDim ); // Save every frame into jpeg format for( int i = 0; i < nFrameCount; i++ ) { imgGif.SelectActiveFrame( ImgFrmDim, i ); imgGif.Save( string.Format( @"d:\Frame{0}.jpg", i ), ImageFormat.Jpeg ); }