<?xml version="1.0" encoding="GBK" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
  	  <title><![CDATA[流光]]></title>
	  <link>http://blog.163.com/liuguangqian_866</link>
	  <description><![CDATA[ ]]></description>
	  <language>zh-CN</language>
	  <pubDate>Fri, 8 May 2009 10:23:23 +0800</pubDate>
	  <lastBuildDate>Fri, 8 May 2009 10:23:23 +0800</lastBuildDate>
	  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
	  <generator><![CDATA[NetEase Space]]></generator>
	  <managingEditor><![CDATA[liuguangqian_866]]></managingEditor>
	  <webMaster><![CDATA[流光]]></webMaster>
		  <ttl>120</ttl>
	  <image>
	  	<title><![CDATA[流光]]></title>
	  	<url>http://ava.bimg.126.net/photo/RPSqxFm_icN_vVjcdaiQOw==/226587356252124089.jpg</url>
	  	<link>http://blog.163.com/liuguangqian_866</link>
	  </image>
  <item>
  	<title><![CDATA[ CListCtrl使用技巧]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008422105648412</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">以下未经说明，listctrl默认view 风格为report</P>
<P style="TEXT-INDENT: 2em">1. CListCtrl 风格</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVS_ICON: 为每个item显示大图标</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVS_SMALLICON: 为每个item显示小图标</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVS_LIST: 显示一列带有小图标的item</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVS_REPORT: 显示item详细资料</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 直观的理解：windows资源管理器，“查看”标签下的“大图标，小图标，列表，详细资料”</P>
<P style="TEXT-INDENT: 2em">2. 设置listctrl 风格及扩展风格</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LONG lStyle;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lStyle &amp;= ~LVS_TYPEMASK; //清除显示方式位</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lStyle |= LVS_REPORT; //设置style</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwStyle = m_list.GetExtendedStyle();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮（只适用与report风格的listctrl）</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwStyle |= LVS_EX_GRIDLINES;//网格线（只适用与report风格的listctrl）</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetExtendedStyle(dwStyle); //设置扩展风格</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注：listview的style请查阅msdn</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrflistviewstyles.asp</A></P>
<P style="TEXT-INDENT: 2em">3. 插入数据</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.InsertColumn( 0, "ID", LVCFMT_LEFT, 40 );//插入列</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.InsertColumn( 1, "NAME", LVCFMT_LEFT, 50 );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nRow = m_list.InsertItem(0, “11”);//插入行</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetItemText(nRow, 1, “jacky”);//设置数据</P>
<P style="TEXT-INDENT: 2em">4. 一直选中item</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 选中style中的Show selection always，或者在上面第2点中设置LVS_SHOWSELALWAYS</P>
<P style="TEXT-INDENT: 2em">5. 选中和取消选中一行</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int nIndex = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; //选中</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; //取消选中</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);</P>
<P style="TEXT-INDENT: 2em">6. 得到listctrl中所有行的checkbox的状态</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString str;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.Format(_T("第%d行的checkbox为选中状态"), i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(str);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">7. 得到listctrl中所有选中行的序号</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 方法一：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString str;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED )</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.Format(_T("选中了第%d行"), i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(str);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法二：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POSITION pos = m_list.GetFirstSelectedItemPosition();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pos == NULL)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE0("No items were selected!\n");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (pos)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nItem = m_list.GetNextSelectedItem(pos);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE1("Item %d was selected!\n", nItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // you could do your own processing on nItem here</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">8. 得到item的信息</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCHAR szBuf[1024];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVITEM lvi;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvi.iItem = nItemIndex;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvi.iSubItem = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvi.mask = LVIF_TEXT;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvi.pszText = szBuf;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvi.cchTextMax = 1024;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.GetItem(&amp;lvi);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于得到设置item的状态，还可以参考msdn文章</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Q173242: Use Masks to Set/Get Item States in CListCtrl</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://support.microsoft.com/kb/173242/en-us">http://support.microsoft.com/kb/173242/en-us</A></P>
<P style="TEXT-INDENT: 2em">9. 得到listctrl的所有列的header字符串内容</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVCOLUMN lvcol;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp; str[256];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; nColNum;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString&nbsp; strColumnName[4];//假如有4列</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nColNum = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvcol.mask = LVCF_TEXT;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvcol.pszText = str;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvcol.cchTextMax = 256;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(m_list.GetColumn(nColNum, &amp;lvcol))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strColumnName[nColNum] = lvcol.pszText;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nColNum++;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">10. 使listctrl中一项可见，即滚动滚动条</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; m_list.EnsureVisible(i, FALSE);</P>
<P style="TEXT-INDENT: 2em">11. 得到listctrl列数</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int nHeadNum = m_list.GetHeaderCtrl()-&gt;GetItemCount();</P>
<P style="TEXT-INDENT: 2em">12. 删除所有列</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp; 方法一：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ( m_list.DeleteColumn (0))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 因为你删除了第一列后，后面的列会依次向上移动。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp; 方法二：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nColumns = 4;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=nColumns-1; i&gt;=0; i--)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_list.DeleteColumn (i);</P>
<P style="TEXT-INDENT: 2em">13. 得到单击的listctrl的行列号</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 添加listctrl控件的NM_CLICK消息相应函数</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 方法一：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwPos = GetMessagePos();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CPoint point( LOWORD(dwPos), HIWORD(dwPos) );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.ScreenToClient(&amp;point);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVHITTESTINFO lvinfo;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvinfo.pt = point;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvinfo.flags = LVHT_ABOVE;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nItem = m_list.SubItemHitTest(&amp;lvinfo);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(nItem != -1)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString strtemp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(strtemp);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 方法二:</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(pNMListView-&gt;iItem != -1)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString strtemp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strtemp.Format("单击的是第%d行第%d列",</P>
<P style="TEXT-INDENT: 2em">&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;&nbsp; pNMListView-&gt;iItem, pNMListView-&gt;iSubItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(strtemp);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pResult = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">14. 判断是否点击在listctrl的checkbox上</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 添加listctrl控件的NM_CLICK消息相应函数</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwPos = GetMessagePos();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CPoint point( LOWORD(dwPos), HIWORD(dwPos) );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.ScreenToClient(&amp;point);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVHITTESTINFO lvinfo;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvinfo.pt = point;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvinfo.flags = LVHT_ABOVE;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT nFlag;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nItem = m_list.HitTest(point, &amp;nFlag);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //判断是否点在checkbox上</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(nFlag == LVHT_ONITEMSTATEICON)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("点在listctrl的checkbox上");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pResult = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">15. 右键点击listctrl的item弹出菜单</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 添加listctrl控件的NM_RCLICK消息相应函数</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(pNMListView-&gt;iItem != -1)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwPos = GetMessagePos();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CPoint point( LOWORD(dwPos), HIWORD(dwPos) );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMenu menu;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VERIFY( menu.LoadMenu( IDR_MENU1 ) );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMenu* popup = menu.GetSubMenu(0);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ASSERT( popup != NULL );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; popup-&gt;TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pResult = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">16. item切换焦点时(包括用键盘和鼠标切换item时)，状态的一些变化顺序</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 添加listctrl控件的LVN_ITEMCHANGED消息相应函数</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CTest6Dlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString sTemp;</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((pNMListView-&gt;uOldState &amp; LVIS_FOCUSED) == LVIS_FOCUSED &amp;&amp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (pNMListView-&gt;uNewState &amp; LVIS_FOCUSED) == 0)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sTemp.Format("%d losted focus",pNMListView-&gt;iItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if((pNMListView-&gt;uOldState &amp; LVIS_FOCUSED) == 0 &amp;&amp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (pNMListView-&gt;uNewState &amp; LVIS_FOCUSED) == LVIS_FOCUSED)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sTemp.Format("%d got focus",pNMListView-&gt;iItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((pNMListView-&gt;uOldState &amp; LVIS_SELECTED) == LVIS_SELECTED &amp;&amp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (pNMListView-&gt;uNewState &amp; LVIS_SELECTED) == 0)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sTemp.Format("%d losted selected",pNMListView-&gt;iItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if((pNMListView-&gt;uOldState &amp; LVIS_SELECTED) == 0 &amp;&amp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (pNMListView-&gt;uNewState &amp; LVIS_SELECTED) == LVIS_SELECTED)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sTemp.Format("%d got selected",pNMListView-&gt;iItem);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *pResult = 0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">17. 得到另一个进程里的listctrl控件的item内容</P>
<P style="TEXT-INDENT: 2em">&nbsp;<A href="http://www.codeproject.com/threads/int64_memsteal.asp">http://www.codeproject.com/threads/int64_memsteal.asp</A></P>
<P style="TEXT-INDENT: 2em">18. 选中listview中的item </P>
<P style="TEXT-INDENT: 2em">Q131284: How To Select a Listview Item Programmatically</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/131284/en-us">http://support.microsoft.com/kb/131284/en-us</A></P>
<P style="TEXT-INDENT: 2em"></P>
<P style="TEXT-INDENT: 2em">19. 如何在CListView中使用CListCtrl的派生类</P>
<P style="TEXT-INDENT: 2em"><A href="http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/">http://www.codeguru.com/cpp/controls/listview/introduction/article.php/c919/</A></P>
<P style="TEXT-INDENT: 2em"></P>
<P style="TEXT-INDENT: 2em">&nbsp;20. listctrl的subitem添加图标</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetExtendedStyle(LVS_EX_SUBITEMIMAGES);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetItem(..); //具体参数请参考msdn</P>
<P style="TEXT-INDENT: 2em">&nbsp;21. 在CListCtrl显示文件，并根据文件类型来显示图标</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 网上找到的代码，share</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL CTest6Dlg::OnInitDialog()</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CDialog::OnInitDialog();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HIMAGELIST himlSmall;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HIMAGELIST himlLarge;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHFILEINFO sfi;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp; cSysDir[MAX_PATH];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString&nbsp; strBuf;</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(cSysDir, 0, MAX_PATH);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetWindowsDirectory(cSysDir, MAX_PATH);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strBuf = cSysDir;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(cSysDir, "%s", strBuf.Left(strBuf.Find("<A href="file:///">\\")+1</A>));</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; himlSmall = (HIMAGELIST)SHGetFileInfo ((LPCSTR)cSysDir,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sfi, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(SHFILEINFO),&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_SYSICONINDEX | SHGFI_SMALLICON );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; himlLarge = (HIMAGELIST)SHGetFileInfo((LPCSTR)cSysDir,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sfi,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(SHFILEINFO),&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_SYSICONINDEX | SHGFI_LARGEICON);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (himlSmall &amp;&amp; himlLarge)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,</P>
<P style="TEXT-INDENT: 2em">&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; (WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ::SendMessage(m_list.m_hWnd, LVM_SETIMAGELIST,</P>
<P style="TEXT-INDENT: 2em">&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; (WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;&nbsp; // return TRUE&nbsp; unless you set the focus to a control</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void CTest6Dlg::AddFiles(LPCTSTR lpszFileName, BOOL bAddToDocument)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nIcon = GetIconIndex(lpszFileName, FALSE, FALSE);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString strSize;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CFileFind filefind;</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; get file size</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (filefind.FindFile(lpszFileName))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filefind.FindNextFile();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSize.Format("%d", filefind.GetLength());</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSize = "0";</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // split path and filename</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString strFileName = lpszFileName;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString strPath;</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nPos = strFileName.ReverseFind('\\');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nPos != -1)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strPath = strFileName.Left(nPos);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName = strFileName.Mid(nPos + 1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // insert to list</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nItem = m_list.GetItemCount();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.InsertItem(nItem, strFileName, nIcon);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetItemText(nItem, 1, strSize);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetItemText(nItem, 2, strFileName.Right(3));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetItemText(nItem, 3, strPath);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int CTest6Dlg::GetIconIndex(LPCTSTR lpszPath, BOOL bIsDir, BOOL bSelected)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHFILEINFO sfi;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;sfi, 0, sizeof(sfi));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (bIsDir)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGetFileInfo(lpszPath,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE_ATTRIBUTE_DIRECTORY,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sfi,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(sfi),&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_SMALLICON | SHGFI_SYSICONINDEX |</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_USEFILEATTRIBUTES |(bSelected ? SHGFI_OPENICON : 0));&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; sfi.iIcon;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGetFileInfo (lpszPath,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE_ATTRIBUTE_NORMAL,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sfi,&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(sfi),&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_SMALLICON | SHGFI_SYSICONINDEX |&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHGFI_USEFILEATTRIBUTES | (bSelected ? SHGFI_OPENICON : 0));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp; sfi.iIcon;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; -1;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">22. listctrl内容进行大数据量更新时，避免闪烁</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetRedraw(FALSE);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //更新内容</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.SetRedraw(TRUE);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.Invalidate();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.UpdateWindow();</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">或者参考 </P>
<P style="TEXT-INDENT: 2em"><A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwnd.3a3a.setredraw.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwnd.3a3a.setredraw.asp</A></P>
<P style="TEXT-INDENT: 2em">23. listctrl排序 </P>
<P style="TEXT-INDENT: 2em">Q250614：How To Sort Items in a CListCtrl in Report View</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/250614/en-us">http://support.microsoft.com/kb/250614/en-us</A></P>
<P style="TEXT-INDENT: 2em">24. 在listctrl中选中某个item时动态改变其icon或bitmap</P>
<P style="TEXT-INDENT: 2em">Q141834: How to change the icon or the bitmap of a CListCtrl item in Visual C++</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/141834/en-us">http://support.microsoft.com/kb/141834/en-us</A></P>
<P style="TEXT-INDENT: 2em">25. 在添加item后，再InsertColumn()后导致整列数据移动的问题</P>
<P style="TEXT-INDENT: 2em">Q151897: CListCtrl::InsertColumn() Causes Column Data to Shift </P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/151897/en-us">http://support.microsoft.com/kb/151897/en-us</A></P>
<P style="TEXT-INDENT: 2em">26. 关于listctrl第一列始终居左的问题</P>
<P style="TEXT-INDENT: 2em">解决办法：把第一列当一个虚列，从第二列开始插入列及数据，最后删除第一列。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">具体解释参阅&nbsp;&nbsp; <A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvcolumn.asp</A></P>
<P style="TEXT-INDENT: 2em">27. 锁定column header的拖动</P>
<P style="TEXT-INDENT: 2em"><A href="http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/">http://msdn.microsoft.com/msdnmag/issues/03/06/CQA/</A></P>
<P style="TEXT-INDENT: 2em">28. 如何隐藏clistctrl的列</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 把需隐藏的列的宽度设为0,然后检测当该列为隐藏列时，用上面第27点的锁定column 的拖动来实现</P>
<P style="TEXT-INDENT: 2em">29. listctrl进行大数据量操作时，使用virtual list&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em"><A href="http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/">http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/</A></P>
<P style="TEXT-INDENT: 2em"><A href="http://www.codeproject.com/listctrl/virtuallist.asp">http://www.codeproject.com/listctrl/virtuallist.asp</A></P>
<P style="TEXT-INDENT: 2em">30. 关于item只能显示259个字符的问题</P>
<P style="TEXT-INDENT: 2em">解决办法：需要在item上放一个edit。</P>
<P style="TEXT-INDENT: 2em">31. 响应在listctrl的column header上的鼠标右键单击</P>
<P style="TEXT-INDENT: 2em">Q125694: How To Find Out Which Listview Column Was Right-Clicked</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/125694/en-us">http://support.microsoft.com/kb/125694/en-us</A></P>
<P style="TEXT-INDENT: 2em">32. 类似于windows资源管理器的listview</P>
<P style="TEXT-INDENT: 2em">Q234310: How to imple**** ListView control that is similar to Windows Explorer by using DirLV.exe</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/234310/en-us">http://support.microsoft.com/kb/234310/en-us</A></P>
<P style="TEXT-INDENT: 2em">33. 在ListCtrl中OnTimer只响应两次的问题</P>
<P style="TEXT-INDENT: 2em">Q200054：</P>
<P style="TEXT-INDENT: 2em">PRB: OnTimer() Is Not Called Repeatedly for a List Control</P>
<P style="TEXT-INDENT: 2em"><A href="http://support.microsoft.com/kb/200054/en-us">http://support.microsoft.com/kb/200054/en-us</A></P>
<P style="TEXT-INDENT: 2em">34. 以下为一些为实现各种自定义功能的listctrl派生类</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)&nbsp;&nbsp;&nbsp; 拖放&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/dragtest.asp">http://www.codeproject.com/listctrl/dragtest.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在CListCtrl和CTreeCtrl间拖放</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://support.microsoft.com/kb/148738/en-us">http://support.microsoft.com/kb/148738/en-us</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)&nbsp;&nbsp;&nbsp; 多功能listctrl</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持subitem可编辑，图标，radiobutton，checkbox，字符串改变颜色的类</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/quicklist.asp">http://www.codeproject.com/listctrl/quicklist.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持排序，subitem可编辑，subitem图标，subitem改变颜色的类</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/ReportControl.asp">http://www.codeproject.com/listctrl/ReportControl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)&nbsp;&nbsp;&nbsp; subitem中显示超链接</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/CListCtrlLink.asp">http://www.codeproject.com/listctrl/CListCtrlLink.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)&nbsp;&nbsp;&nbsp; subitem的tooltip提示</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/ctooltiplistctrl.asp">http://www.codeproject.com/listctrl/ctooltiplistctrl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)&nbsp;&nbsp;&nbsp; subitem中显示进度条&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/ProgressListControl.asp">http://www.codeproject.com/listctrl/ProgressListControl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/napster.asp">http://www.codeproject.com/listctrl/napster.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/">http://www.codeguru.com/Cpp/controls/listview/article.php/c4187/</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6)&nbsp;&nbsp;&nbsp; 动态改变subitem的颜色和背景色</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/highlightlistctrl.asp">http://www.codeproject.com/listctrl/highlightlistctrl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/">http://www.codeguru.com/Cpp/controls/listbox/colorlistboxes/article.php/c4757/</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7)&nbsp;&nbsp;&nbsp; 类vb属性对话框</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/propertylistctrl.asp">http://www.codeproject.com/listctrl/propertylistctrl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/">http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c995/</A> </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/">http://www.codeguru.com/Cpp/controls/listview/propertylists/article.php/c1041/</A> </P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8)&nbsp;&nbsp;&nbsp; 选中subitem(只高亮选中的item)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/SubItemSel.asp">http://www.codeproject.com/listctrl/SubItemSel.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/ListSubItSel.asp">http://www.codeproject.com/listctrl/ListSubItSel.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9)&nbsp;&nbsp;&nbsp; 改变行高</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/changerowheight.asp">http://www.codeproject.com/listctrl/changerowheight.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (10)&nbsp;&nbsp; 改变行颜色</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/coloredlistctrl.asp">http://www.codeproject.com/listctrl/coloredlistctrl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (11)&nbsp;&nbsp; 可编辑subitem的listctrl</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/nirs2000.asp">http://www.codeproject.com/listctrl/nirs2000.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp">http://www.codeproject.com/listctrl/editing_subitems_in_listcontrol.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (12)&nbsp;&nbsp; subitem可编辑，插入combobox，改变行颜色，subitem的tooltip提示</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/reusablelistcontrol.asp">http://www.codeproject.com/listctrl/reusablelistcontrol.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (13)&nbsp;&nbsp; header 中允许多行字符串</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/headerctrlex.asp">http://www.codeproject.com/listctrl/headerctrlex.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (14)&nbsp;&nbsp; 插入combobox</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/">http://www.codeguru.com/Cpp/controls/listview/editingitemsandsubitem/article.php/c979/</A></P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (15)&nbsp;&nbsp; 添加背景图片</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/">http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c4173/</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/">http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.vchelp.net/vchelp/archive.asp?type_id=9&amp;class_id=1&amp;cata_id=1&amp;article_id=1088&amp;search_term">http://www.vchelp.net/vchelp/archive.asp?type_id=9&amp;class_id=1&amp;cata_id=1&amp;article_id=1088&amp;search_term</A>=</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (16)&nbsp; 自适应宽度的listctrl</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/useritems/AutosizeListCtrl.asp">http://www.codeproject.com/useritems/AutosizeListCtrl.asp</A></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; (17)&nbsp; 改变ListCtrl高亮时的颜色(默认为蓝色)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; 处理</P>
<P style="TEXT-INDENT: 2em">NM_CUSTOMDRAW </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.codeproject.com/listctrl/lvcustomdraw.asp">http://www.codeproject.com/listctrl/lvcustomdraw.asp</A></P>
<P style="TEXT-INDENT: 2em">CListCtrl使用详解 </P>
<P style="TEXT-INDENT: 2em">1。先来介绍REPORT类型的CListCtrl：</P>
<P style="TEXT-INDENT: 2em">首先使用下面的语句设置CListCtrl的style：</P>
<P style="TEXT-INDENT: 2em">&nbsp;DWORD SetExtendedStyle( DWORD dwNewStyle );</P>
<P style="TEXT-INDENT: 2em">其中</P>
<P style="TEXT-INDENT: 2em">&nbsp;LVS_EX_CHECKBOXES&nbsp;表示添加CheckBox</P>
<P style="TEXT-INDENT: 2em">&nbsp;LVS_EX_FULLROWSELECT&nbsp;表示选择整行</P>
<P style="TEXT-INDENT: 2em">&nbsp;LVS_EX_GRIDLINES&nbsp;表示添加表格线</P>
<P style="TEXT-INDENT: 2em">如果设置了LVS_EX_CHECKBOXES属性，则可以用</P>
<P style="TEXT-INDENT: 2em">&nbsp;BOOL GetCheck( int nItem ) const;</P>
<P style="TEXT-INDENT: 2em">来得到某一行是否Checked。</P>
<P style="TEXT-INDENT: 2em">可以先用下面的语句来删除以前的东西：</P>
<P style="TEXT-INDENT: 2em">&nbsp;for(int k=2;k&gt;=0;k--)&nbsp;//注意要从后往前删，否则出错</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.DeleteColumn(k);</P>
<P style="TEXT-INDENT: 2em">&nbsp;m_ListCtrl.DeleteAllItems();</P>
<P style="TEXT-INDENT: 2em">用下面的语句新建列：</P>
<P style="TEXT-INDENT: 2em">&nbsp;m_ListCtrl.InsertColumn(0,_T("文件名"),LVCFMT_IMAGE|LVCFMT_LEFT);</P>
<P style="TEXT-INDENT: 2em">&nbsp;m_ListCtrl.InsertColumn(1,_T("仪器类别"));</P>
<P style="TEXT-INDENT: 2em">&nbsp;m_ListCtrl.InsertColumn(2,_T("项目类别"));</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">其中LVCFMT_IMAGE表示可以在第一列加入图标。如果不要图标可以删去。</P>
<P style="TEXT-INDENT: 2em">然后设置列宽：</P>
<P style="TEXT-INDENT: 2em">&nbsp;for(j=0;j&lt;3;j++)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.SetColumnWidth(j ,100);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">以下为列表加入图标，如果不需要图标，可以跳过这一步。注意只在第一次加入，如果多次加入会出错！</P>
<P style="TEXT-INDENT: 2em">先在头文件中加入声明：</P>
<P style="TEXT-INDENT: 2em">&nbsp;CImageList m_ImageList;</P>
<P style="TEXT-INDENT: 2em">这是必要的，如果在cpp的某个函数中加入由于生命期结束，CImageList自动释放，则效果是列表中看不到图标，只看到一个白方块。</P>
<P style="TEXT-INDENT: 2em">下面生成CImageList，并将其绑定到CListCtrl中，这是CImageList中还没有图标，只是一个容器：</P>
<P style="TEXT-INDENT: 2em">&nbsp;static int flag=2;</P>
<P style="TEXT-INDENT: 2em">&nbsp;if(flag==2){//只调用一次SetImageList，否则出错</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ImageList.Create(128, 128, ILC_COLORDDB|ILC_MASK, 20, 1);&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.SetImageList(&amp;m_ImageList,LVSIL_SMALL);</P>
<P style="TEXT-INDENT: 2em">&nbsp;}</P>
<P style="TEXT-INDENT: 2em">&nbsp;flag=(flag+1)%2;</P>
<P style="TEXT-INDENT: 2em">如果CListCtrl已经用过，曾经加过图标进去，这时就要删除上次放进m_ImageList中的Image</P>
<P style="TEXT-INDENT: 2em">&nbsp;for(int kk=0;kk&lt;m_ImageList.GetImageCount();kk++)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ImageList.Remove(k);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">下面介绍如何向CListCtrl里面加入行，并同时为每一行动态加入图标：</P>
<P style="TEXT-INDENT: 2em">假设m_listRowCount为要加入的行数。</P>
<P style="TEXT-INDENT: 2em">&nbsp;CBitmap* bitmap;</P>
<P style="TEXT-INDENT: 2em">&nbsp;bitmap=new CBitmap[m_list1rowCount];</P>
<P style="TEXT-INDENT: 2em">&nbsp;HBITMAP hbitmap;&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;for(int i = 0; i &lt; m_listRowCount; i++)</P>
<P style="TEXT-INDENT: 2em">&nbsp;{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;//为每一行插入相应的缩略图</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;CFile f;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;CFileException e;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;if( !f.Open(m_FileName, CFile::modeRead, &amp;e )){&nbsp;//m_FileName为bmp文件名，由你来定</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;hbitmap = (HBITMAP)LoadImage(NULL,path+"blank.bmp",IMAGE_BITMAP,0,0,</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;}else{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;f.Close();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;hbitmap = (HBITMAP)LoadImage(NULL,bmpFile,IMAGE_BITMAP,0,0,</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;bitmap[i].Attach(hbitmap);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ImageList.Add(&amp;bitmap[i], RGB(0, 128, 128));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;//插入行</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.InsertItem(i,m_FileName,i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.SetItemText(i,1,type);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;m_ListCtrl.SetItemText(i,2,m_Path);</P>
<P style="TEXT-INDENT: 2em">&nbsp;}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;//记得删除已经没用的临时文件</P>
<P style="TEXT-INDENT: 2em">&nbsp;if(m_list1rowCount!=0)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;delete[] bitmap;</P>
<P style="TEXT-INDENT: 2em">2。如果是ICON类型的CListCtrl，则要做一点点改动：</P>
<P style="TEXT-INDENT: 2em">把绑定图标集的代码由</P>
<P style="TEXT-INDENT: 2em">&nbsp;SetImageList(&amp;m_ImageList,LVSIL_SMALL);</P>
<P style="TEXT-INDENT: 2em">改为</P>
<P style="TEXT-INDENT: 2em">&nbsp;SetImageList(&amp;m_ImageList,LVSIL_NORMAL);</P>
<P style="TEXT-INDENT: 2em">插入行时只用</P>
<P style="TEXT-INDENT: 2em">&nbsp;InsertItem(i,mainSet.m_FileName,i);</P>
<P style="TEXT-INDENT: 2em">不用</P>
<P style="TEXT-INDENT: 2em">&nbsp;SetItemText(i,1,type);</P>
<P style="TEXT-INDENT: 2em">之类的代码。</P>
<P style="TEXT-INDENT: 2em"></P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008422105648412</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008422105648412</guid>
    <pubDate>Thu, 22 May 2008 10:56:48 +0800</pubDate>
    <dcterms:modified>2008-05-22T17:16:51+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[VC++通用控件编程]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008422105434966</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">滑动条控制（Slider Control）也叫轨道条控制，其主要是用一个带有轨道和滑标的小窗口以及窗口上的刻度，来让用户选择一个离散数据或一个连续的数值区间。通过鼠标或键盘来进行数据的选择操作，这在WIN98/95中的很多应用程序中都可以看到，如控制面板中的鼠标等，滑动条既可以是水平方式的也可以是垂直方式的。滑动条控制的风格如下：</P>
<P style="TEXT-INDENT: 2em">TBS_HORZ 滑动条是水平方向的&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBS_VERT 滑动条是垂直方向的</P>
<P style="TEXT-INDENT: 2em">TBS_LEFT 滑动条位于窗口左侧&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBS_RIGHT 滑动条位于窗口右侧</P>
<P style="TEXT-INDENT: 2em">TBS_TOP 滑动条位于窗口顶部&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBS_BOTTOM 滑动条位于窗口底部</P>
<P style="TEXT-INDENT: 2em">TBS_BOTH 滑动条位于窗口两侧&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TBS_AUTOTICKS滑动条具有刻度，默认</P>
<P style="TEXT-INDENT: 2em">TBS_NOTICKS 滑动条不具有刻度</P>
<P style="TEXT-INDENT: 2em">　　滑动条的刻度条在每一个数值位置显示一个刻度标记，如果在滑动条上显示某一数值选择区间，则应使用风格TBS_ENABLESELRANGE，此时选择区间两个不再是刻度标记，而是一个小的三角形符号。另外，使用风格TBS_NOTHUMB会使滑标消隐起来。</P>
<P style="TEXT-INDENT: 2em">　　滑动条控制在MFC类库中被封装为CSliderCtrl控制，其主要操作是设置刻度范围、绘制刻度标记、设置选择范围和当前滑标位置等。当用户进行交互操作时，滑动条控制将向其父窗口发送消息WM_HSCROLL，所以在应用程序中应重载父窗口的OnHScroll()成员函数，以便对消息进行正确处理系统发送的通知代码、滑标位置和指向CSliderCtrl对象的指针等。由于考虑到和水平卷动杆公用同一个成员函数，OnHScroll()函数参数表中的指针变量被定义为CScrollBar*类型，由于实际上消息是由滑动条产生的，所以在程序中必须把这个指针变量强制转换为CSliderCtrl*类型。滑动条和卷动杆的消息代码和含义都非常类似如TB_BOTTOM等，所以这种处理方法比较合理。SetRange()函数用来设置范围，SetPos()函数用来设置当前位置。</P>
<P style="TEXT-INDENT: 2em">（二）滑动条控制的对象结构</P>
<P style="TEXT-INDENT: 2em">　　滑动条控制的建立方法</P>
<P style="TEXT-INDENT: 2em">　　　CsliderCtrl &amp;SliderCtrl 建立滑动条控制对象结构；Create 建立滑动条控制对象并绑定对象</P>
<P style="TEXT-INDENT: 2em">　　　滑动条控制类CSliderCtrl::Create的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">　　BOOL Create( DWORD dwStyle, const RECT&amp; rect, CWnd* pParentWnd, UINT nID );</P>
<P style="TEXT-INDENT: 2em">　　其中参数dwStyle用来确定滑动条控制风格；参数rect用来确定滑动条控制的大小和位置；参数pParentWnd用来确定滑动条控制的父窗口指针；参数nID用来确定滑动条控制的控制符ID值。</P>
<P style="TEXT-INDENT: 2em">　　2、滑动条控制的类属性</P>
<P style="TEXT-INDENT: 2em">　　滑动条控制对象的类属性包括取得滑动条大小GetLineSize、设置滑动条大小SetLineSize、取得滑动条页大小GetPageSize、设置滑动条页大小SetPageSize、取得滑动条最大位置GetRangeMax、取得滑动条最小位置GetRangeMin、取得滑动条范围GetRange、设置滑块最小位置SetRangeMin、设置滑块最大位置SetRangeMax、设置滑动条范围SetRange、取得滑块当前位置GetSelection、设置滑块当前位置SetSelection、取得滑动条当前位置GetPos和设置滑动条当前位置SetPos等。</P>
<P style="TEXT-INDENT: 2em">　　3、滑动条控制的操作方法</P>
<P style="TEXT-INDENT: 2em">　　滑动条控制的操作方法包括清除滑动条当前选择ClearSel、验证滑动条当前位置是否在最大最小位置之间VerifyPos和清除当前刻度标志ClearTics。</P>
<P style="TEXT-INDENT: 2em">　　滑动条控制的应用技巧示例</P>
<P style="TEXT-INDENT: 2em">　　1、利用应用程序向导AppWizard生成基于对象框的应用程序CSlidDlg；</P>
<P style="TEXT-INDENT: 2em">　　2、在对话框中设置滑动条控制，其ID为IDC_SLIDER；</P>
<P style="TEXT-INDENT: 2em">　　3、在对话框初始代码中增加控制的范围和位置：</P>
<P style="TEXT-INDENT: 2em">　　（1）在SlidDlg.h中设置数据成员，用来表示滑动条的当前值：</P>
<P style="TEXT-INDENT: 2em">//SlidDlg.h</P>
<P style="TEXT-INDENT: 2em">class CSlidDlg:public Cdialog</P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;&nbsp;．．．．．．//其它代码</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; public:</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_nCur;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; ．．．．．．//其它代码</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">（2）在SlidDlg.cpp中设置初始状态</P>
<P style="TEXT-INDENT: 2em">BOOL CSlidDlg::OnInitDialog()</P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;&nbsp;Cdialog::OnInitDialog();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; ．．．．．．//其它代码</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; //TODO:Add extra initialization here</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLLIDER);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; pSlidCtrl-&gt;SetRange(1,5,TRUE);//设置滑动条范围</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; pSlidCtrl-&gt;SetPos(2);//设置滑动条位置</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; ．．．．．．//其它代码</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">（3）完善滑动条的消息处理，利用类向导ClassWizard增加对话框窗口的WM_HSCROLL消息处理函数，并取得滑标所指位置值：</P>
<P style="TEXT-INDENT: 2em">void CSlidDlg::OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)</P>
<P style="TEXT-INDENT: 2em">{ //TODO:Add your message handler?</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; Cdialog::OnHScroll(nSBCode,nPos,pScrollBar);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLLIDER);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; m_nCur=pSlidCtrl-&gt;GetPos();//取得当前位置值</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">VC通用控件编程之CStatusBar控件</P>
<P style="TEXT-INDENT: 2em">（一）状态条控制的主要功能 </P>
<P style="TEXT-INDENT: 2em">状态条控制(Status Bar <A href="http://www.yesky.com/key/478/125478.html">Control</A>)比较容易理解，使用起来也比较简单。状态条是位于父窗口底部的一个水平子窗口，它可以被分成多个显示信息的小区域。其MFC中封装的CstatusBarCtrl控制类提供了应用的基本方法。</P>
<P style="TEXT-INDENT: 2em">（二）状态条控制的对象结构</P>
<P style="TEXT-INDENT: 2em">1、状态条控制的建立方法</P>
<P style="TEXT-INDENT: 2em">CStatusBarCtrl &amp;StatusBarCtrl 建立状态条控制对象结构；Create 建立状态条控制对象并绑定状态条控制类CstatusBarCtrl::Create的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">BOOL Create( DWORD dwStyle,const RECT&amp; rect,CWnd* pParentWnd,UINT nID);</P>
<P style="TEXT-INDENT: 2em">其中参数dwStyle用来确定状态条的控制风格；参数rect用来确定状态条窗口的大小和位置；参数pParentWnd用来确定状态条父窗口的指针；nID用来确定状态条控制的标识符。</P>
<P style="TEXT-INDENT: 2em">状态条控制风格可以是下列值的组合：CCS_BOTTOM、CCS_NODIVIDER、CCS_NOHILITE、CCS_NOMOVEY、CCS_NOPARENTALIGN、CCS_NORESIZE和CCS_TOP等，具体内容和含义请见工具条控制中的有关部分。</P>
<P style="TEXT-INDENT: 2em">2、状态条控制的类属性</P>
<P style="TEXT-INDENT: 2em">状态条控制类属性包括设置给定部分显示文本SetText、取得给定部分的文本GetText、设置状态条区域划分数及其每部分的右边坐标SetParts、取得状态条区域划分数量GetParts、取得状态条的水平和垂直宽度GetBorders和取得状态条矩形区域GetRect。</P>
<P style="TEXT-INDENT: 2em">（三）状态条控制的应用技巧</P>
<P style="TEXT-INDENT: 2em">状态条控制除可以显示一定的帮助和提示信息外，还可以实现响应鼠标输入等功能。这里以在状态条上显示鼠标移动坐标为例，具体说明其应用技巧。</P>
<P style="TEXT-INDENT: 2em">利用应用程序向导生成的程序代码中，状态条作为主窗口的子窗口，其具有一个AFX_IDW_STATUS _BAR标识符，通过它调用函数GetDescendantWindow()和AfxGetMainWnd()，就可以取得状态条窗口的指针。由于基于文档的应用程序在建立时就具有状态条区域，所以只要利用类向导简单地加入鼠标移动消息处理功能函数和下述函数代码，就可以实现这一功能：</P>
<P style="TEXT-INDENT: 2em">Void CTestView::OnMouseMove(UINT nFlags,Cpoint point)</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">CclientDC dc(this);//建立设备文本</P>
<P style="TEXT-INDENT: 2em">OnPrepareDC(&amp;dc,NULL);//设备映射处理</P>
<P style="TEXT-INDENT: 2em">dc.DPtoLP(&amp;point);//鼠标指针转换</P>
<P style="TEXT-INDENT: 2em">char text[128];</P>
<P style="TEXT-INDENT: 2em">CstatusBar *pStatus=(CstatusBar *)AfxGetApp()-&gt;m_pMainWnd-&gt;</P>
<P style="TEXT-INDENT: 2em">GetDescendanWindow(AFX_IDW_STATUS_BAR);//取得窗口指针</P>
<P style="TEXT-INDENT: 2em">If(pStatus){//如果存在显示鼠标坐标</P>
<P style="TEXT-INDENT: 2em">Sprintf(text,”X坐标=%4d,Y坐标=%4d”,point.x,point.y);</P>
<P style="TEXT-INDENT: 2em">pStatus-&gt;SetPaneText(0,text);}</P>
<P style="TEXT-INDENT: 2em">CscrollView::OnMouseMove(nFlags,point); </P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">VC通用控件编程之CProgress控件</P>
<P style="TEXT-INDENT: 2em">（一）进度条的主要功能 </P>
<P style="TEXT-INDENT: 2em">　　进度条控制（Progress Control）主要用来进行数据读写、文件拷贝和磁盘格式等操作时的工作进度提示情况，如安装程序等，伴随工作进度的进展，进度条的矩形区域从左到右利用当前活动窗口标题条的颜色来不断填充。</P>
<P style="TEXT-INDENT: 2em">进度条控制在MFC类库中的封装类为CProgressCtrl，通常仅作为输出类控制，所以其操作主要是设置进度条的范围和当前位置，并不断地更新当前位置。进度条的范围用来表示整个操作过程的时间长度，当前位置表示完成情况的当前时刻。SetRange()函数用来设置范围，初始范围为0-100，SetPos()函数用来设置当前位置，初始值为0，SetStep()函数用来设置步长，初始步长为10，StepIt()函数用来按照当前步长更新位置，OffsetPos()函数用来直接将当前位置移动一段距离。如果范围或位置发生变化，那么进度条将自动重绘进度区域来及时反映当前工作的进展情况。</P>
<P style="TEXT-INDENT: 2em">进度条的对象结构</P>
<P style="TEXT-INDENT: 2em">　　进度条控制的建立方法</P>
<P style="TEXT-INDENT: 2em">　　CProgressCtrl &amp;ProgressCtrl 建立进度条控制对象结构</P>
<P style="TEXT-INDENT: 2em">　　Create 建立进度条控制对象并绑定对象</P>
<P style="TEXT-INDENT: 2em">　　进度条控制类CprogressCtrl::Create的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">　　BOOL Create( DWORD dwStyle, const RECT&amp; rect, CWnd* pParentWnd, UINT nID );</P>
<P style="TEXT-INDENT: 2em">　　其中参数dwStyle用来确定进度条控制的控制风格；参数rect用来确定进度条控制的大小和位置；参数pParentWnd用来确定进度条父窗口指针；参数nID用来确定进度条控制的控制符ID值。</P>
<P style="TEXT-INDENT: 2em">　　2、进度条控制的类属性</P>
<P style="TEXT-INDENT: 2em">　　进度条控制的类属性包括设置进度条最大最小控制范围SetRange、设置进度条当前位置 SetPos、设置进度条当前位置偏移值OffsetPos和设置进度条控制增量值SetStep。</P>
<P style="TEXT-INDENT: 2em">　3、进度条控制的操作方法</P>
<P style="TEXT-INDENT: 2em">　　进度条控制的操作方法主要是使进度条控制并重绘进度条的StepIt函数。</P>
<P style="TEXT-INDENT: 2em">　　进度条控制的应用技巧示例</P>
<P style="TEXT-INDENT: 2em">　　1、利用应用程序向导AppWizard生成基于对象框的应用程序CProgDlg；</P>
<P style="TEXT-INDENT: 2em">　　2、在对话框中设置进度条和静态文本控制，其ID分别为IDC_PROG和IDCPERCENT；</P>
<P style="TEXT-INDENT: 2em">在对话框初始代码中增加控制的范围和位置：</P>
<P style="TEXT-INDENT: 2em">　　在ProgDlg.h中设置两个数据成员，用来表示进度条的最大值和步长：</P>
<P style="TEXT-INDENT: 2em">//ProgDlg.h</P>
<P style="TEXT-INDENT: 2em">class CProgDlg:public Cdialog</P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;．．．．．．//其它代码</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; public:</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_nMax,m_nStep;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; ．．．．．．　//其它代码</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">(2)在ProgDlg.cpp中设置初始状态</P>
<P style="TEXT-INDENT: 2em">BOOL CProgDlg::OnInitDialog()</P>
<P style="TEXT-INDENT: 2em">(3)完善WM_TIMER消息处理，使进度条按照当前步长进行更新，同时完成进度条的百分比显示：</P>
<P style="TEXT-INDENT: 2em">void CProgDlg::OnTimer(UINT nIDEvent)</P>
<P style="TEXT-INDENT: 2em">{&nbsp;&nbsp;&nbsp; &nbsp;//TODO:Add your message handler?</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; CProgressCtrl *pProgCtrl=(CProgressCtrl*)GetDlgItem(IDC_PROG);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; int nPrePos=pProgCtrl-&gt;StepIt();//取得更新前位置</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; char test[10];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; int nPercent=(int)(((nPrePos+m_nStep)/m_nMax*100+0.5);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; wsprintf(test,?%d%%?,nPercent);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; GetDlgItem(IDC_PERCENT)-&gt;SetWindowText(text);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; Cdialog::OnTimer(nIDEvent);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">VC通用控件编程之CList控件</P>
<P style="TEXT-INDENT: 2em">（一）列表控制的主要功能 </P>
<P style="TEXT-INDENT: 2em">&nbsp; 列表控制和视（List Control&amp;View)主要用来以各种方式显示一组数据记录供用户进行各种操作，Windows98/95中资源管理器中的“查看”标签下的“大图标｜小图标｜列表｜详细资源”就是一个非常好的典型应用。列表中的记录可以包括多个数据项，也可以包括表示数据内容的大小图标，用来表示数据记录的　列表控制提供了对Windows列表功能操作的基本方法，而使用列表视的视函数可以对列表视进行各种操作，通过调用视成员GetListCtrl获取嵌在列表视内列表控制的引用（GetListCtrl&amp; ctrlList = GetListCtrl()），就可以和列表控制一样进行各种操作。操作一个列表控制和视的基本方法为：创建列表控制；创建列表控制所需要的图像列表；向列表控制添加表列和表项；对列表进行各种控制，主要包括查找、排序、删除、显示方式、排列方式以及各种消息处理功能等；最后撤消列表控制。</P>
<P style="TEXT-INDENT: 2em">对于一个列表控制，其最典型最常用的显示控制方式为：大图标方式（LVS_ICON）、小图标方式（LVS_SMALLICON）、列表显示方式（LVS_LIST）和详细资料（即报告LVS_REPORT）显示方式。这可以通过设置其显示方式属性来实现。要控制列表所在窗口的风格，可通过功能函数GetWindowLong和SetWindowLong来实现，要控制列表图标的对齐方式，可通过设置列表窗口的风格LVS_ALIGNTOP或LVS_ALIGNLEFT来实现，</P>
<P style="TEXT-INDENT: 2em">（二）列表控制的对象结构</P>
<P style="TEXT-INDENT: 2em">1、列表控制的建立方法</P>
<P style="TEXT-INDENT: 2em">CListCtrl＆listCtrl 定义列表对象的结构</P>
<P style="TEXT-INDENT: 2em">Create 建立列表控制并绑定对象</P>
<P style="TEXT-INDENT: 2em">列表控制CListCtrl::Create的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">BOOL Create( DWORD dwStyle, const RECT&amp; rect, CWnd* pParentWnd, UINT nID );</P>
<P style="TEXT-INDENT: 2em">其中参数dwStyle用来确定列表控制的风格；rect用来确定列表控制的大小和位置；pParentWnd用来确定列表控制的父窗口，通常是一个对话框；nID用来确定列表控制的标识。其中列表控制的风格可以是下列值的组合：</P>
<P style="TEXT-INDENT: 2em">LVS_ALIGNLEFT 用来确定表项的大小图标以左对齐方式显示；</P>
<P style="TEXT-INDENT: 2em">LVS_ALIGNTOP 用来确定表项的大小图标以顶对齐方式显示；</P>
<P style="TEXT-INDENT: 2em">LVS_AUTOARRANGE 用来确定表项的大小图标以自动排列方式显示；</P>
<P style="TEXT-INDENT: 2em">LVS_EDITLABELS 设置表项文本可以编辑，父窗口必须设有LVN_ENDLABELEDIT风格；</P>
<P style="TEXT-INDENT: 2em">LVS_ICON 用来确定大图标的显示方式；</P>
<P style="TEXT-INDENT: 2em">LVS_LIST 用来确定列表方式显示；</P>
<P style="TEXT-INDENT: 2em">LVS_NOCOLUMNHEADER 用来确定在详细资料方式时不显示列表头；</P>
<P style="TEXT-INDENT: 2em">LVS_NOLABELWRAP 用来确定以单行方式显示图标的文本项；</P>
<P style="TEXT-INDENT: 2em">LVS_NOSCROLL 用来屏蔽滚动条；</P>
<P style="TEXT-INDENT: 2em">LVS_NOSORTHEADER 用来确定列表头不能用作按钮功能；</P>
<P style="TEXT-INDENT: 2em">LVS_OWNERDRAWFIXED 在详细列表方式时允许自绘窗口；</P>
<P style="TEXT-INDENT: 2em">LVS_REPORT 用来确定以详细资料即报告方式显示；</P>
<P style="TEXT-INDENT: 2em">LVS_SHAREIMAGELISTS用来确定共享图像列表方式；</P>
<P style="TEXT-INDENT: 2em">LVS_SHOWSELALWAYS 用来确定一直显示被选中表项方式；</P>
<P style="TEXT-INDENT: 2em">LVS_SINGLESEL 用来确定在某一时刻只能有一项被选中；</P>
<P style="TEXT-INDENT: 2em">LVS_SMALLICON 用来确定小图标显示方式；</P>
<P style="TEXT-INDENT: 2em">LVS_SORTASCENDING 用来确定表项排序时是基于表项文本的升序方式；</P>
<P style="TEXT-INDENT: 2em">LVS_SORTDESCENDING 用来确定表项排序时是基于表项文本的降序方式；</P>
<P style="TEXT-INDENT: 2em">2、列表控制的属性类</P>
<P style="TEXT-INDENT: 2em">列表控制的属性类包括取得列表控制的背景色GetBkColor、设置列表控制的背景色SetBkColor、取得列表控制的图像列表GetImageList、设置列表控制的图像列表SetImageList、取得列表项数目GetItemCount、取得列表控制的属性GetItem、取得与表项相关的数据GetItemData、设置表项的属性SetItem、设置与表项相关的数值SetItemData、取得相关联的下一个表项GetNextItem、设置列表控制的文本颜色SetTextColor、取得列表控制的文本背景颜色GetTextBkColor、设置表项的最大数目SetItemCount和取得被选中表项的数目GetSelectedCount等。</P>
<P style="TEXT-INDENT: 2em">3、列表控制的操作方法</P>
<P style="TEXT-INDENT: 2em">列表控制的操作方法包括插入一个新的表项InsertItem、删除一个表项DeleteItem、排序表项SortItems、测试列表的位置HitTest、重绘表项RedrawItems、插入一个表列InsertColumn、删除一个表列DeleteColumn、编辑一个表项文本EditLabel和重绘一个表项DrawItem等。</P>
<P style="TEXT-INDENT: 2em">（三）列表控制的数据结构 </P>
<P style="TEXT-INDENT: 2em">列表控制中包含两个非常重要的数据结构LV_ITEM和LV_COLUMN。LV_ITEM用于定义列表控制的一个表项，LV_COLUMN用于定义列表控制的一个表列，其定义格式分别为：</P>
<P style="TEXT-INDENT: 2em">typedef struct _LV_ITEM { </P>
<P style="TEXT-INDENT: 2em">UINT mask; //结构成员屏蔽位</P>
<P style="TEXT-INDENT: 2em">int iItem; //表项索引号</P>
<P style="TEXT-INDENT: 2em">int iSubItem; //子表项索引号</P>
<P style="TEXT-INDENT: 2em">UINT state; //表项状态</P>
<P style="TEXT-INDENT: 2em">UINT stateMask; //状态有效性屏蔽位 </P>
<P style="TEXT-INDENT: 2em">LPTSTR pszText; //表项名文本</P>
<P style="TEXT-INDENT: 2em">int cchTextMax; //表项名最大长度</P>
<P style="TEXT-INDENT: 2em">int iImage; // 表项图标的索引号</P>
<P style="TEXT-INDENT: 2em">LPARAM lParam; // 与表项相关的32位数</P>
<P style="TEXT-INDENT: 2em">} LV_ITEM; </P>
<P style="TEXT-INDENT: 2em">typedef struct _LV_COLUMN { </P>
<P style="TEXT-INDENT: 2em">UINT mask; //结构成员有效性屏蔽位</P>
<P style="TEXT-INDENT: 2em">int fmt; //表列对齐方式</P>
<P style="TEXT-INDENT: 2em">int cx; //表列的象素宽度</P>
<P style="TEXT-INDENT: 2em">LPTSTR pszText; //表列的表头名</P>
<P style="TEXT-INDENT: 2em">int cchTextMax; //表列名的文本长度</P>
<P style="TEXT-INDENT: 2em">int iSubItem; //与表列关联的子表项索引号</P>
<P style="TEXT-INDENT: 2em">} LV_COLUMN;</P>
<P style="TEXT-INDENT: 2em">　　其中fmt可以取如下值：</P>
<P style="TEXT-INDENT: 2em">LVCFMT_CENTER 表列居中对齐 </P>
<P style="TEXT-INDENT: 2em">LVCFMT_LEFT 表列左对齐</P>
<P style="TEXT-INDENT: 2em">（四）列表控制的应用技巧示例 </P>
<P style="TEXT-INDENT: 2em">本文给出具体实例演示列表控制及前面的表头控制和图像列表的应用技巧。步骤如下：</P>
<P style="TEXT-INDENT: 2em">1、&nbsp;&nbsp; 通过“FILE-&gt;NEW-&gt;PROJECTS-&gt;MFC AppWizard(EXE)”建立名为VCLIST的工程，在建立过程中选择基于对话框（Dialog based）的应用；将对话框中的默认控件删除，并将所有对话框属性中的Language域设置为Chinese(P.R.C.),以使应用程序支持中文；</P>
<P style="TEXT-INDENT: 2em">2、&nbsp;&nbsp; 建立两个图标IDI_GJ和IDI_XS，用来表示图标的选中和非选中状态，对于每个图标都应建立32X32和16X16两种大小，以保证程序的需要； </P>
<P style="TEXT-INDENT: 2em">3、&nbsp;&nbsp; 在对话框窗口中设计组合框（Group Box）,组合框中设置四个无线按钮（Radio）“大图标｜小图标｜列表｜资料”，同时设置排序、删除和关闭三个控制按钮(Button），并在对话框中设置大小合适的列表控制（List Ctrl），其对应标识分别如下：</P>
<P style="TEXT-INDENT: 2em">--------------------------------------------------------------------------------</P>
<P style="TEXT-INDENT: 2em">控制名称 标题名称标识符号</P>
<P style="TEXT-INDENT: 2em">--------------------------------------------------------------------------------</P>
<P style="TEXT-INDENT: 2em">列表控制 IDC_LISTCTRL</P>
<P style="TEXT-INDENT: 2em">组合框 方式 IDC_STATIC</P>
<P style="TEXT-INDENT: 2em">无线按钮 大图标 IDC_STDICON</P>
<P style="TEXT-INDENT: 2em">小图标 IDC_SMLICON</P>
<P style="TEXT-INDENT: 2em">列 表 IDC_LIST</P>
<P style="TEXT-INDENT: 2em">资 料 IDC_REPORT</P>
<P style="TEXT-INDENT: 2em">按钮 排 序 IDC_SORT</P>
<P style="TEXT-INDENT: 2em">删 除 IDC_DEL</P>
<P style="TEXT-INDENT: 2em">关 闭 IDOK</P>
<P style="TEXT-INDENT: 2em">--------------------------------------------------------------------------------</P>
<P style="TEXT-INDENT: 2em">4、在设置无线按钮时，需要注意的是只有大图标的Group属性为选中状态，而其它无线按钮的状态均为默认值。</P>
<P style="TEXT-INDENT: 2em">5、选中列表控制控件，选择“VIEW-&gt;ClassWizard-&gt;Memory Variables”，并利用IDC_ LISTCTRL引入成员变量，其变量类型为：</P>
<P style="TEXT-INDENT: 2em">变量名 种类 变量类型</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl Control ClistCtrl</P>
<P style="TEXT-INDENT: 2em">同时利用“MESSAGES MAP”为各无线按钮和命令按钮增加控制功能</P>
<P style="TEXT-INDENT: 2em">6、然后在包含文件和代码文件中分别加入如下代码：</P>
<P style="TEXT-INDENT: 2em">（1）在VCLISTDlg.h中增加数据结构和定义</P>
<P style="TEXT-INDENT: 2em">typedef struct tagSPS { //定义结构</P>
<P style="TEXT-INDENT: 2em">char szPm[10]; //品名</P>
<P style="TEXT-INDENT: 2em">int Lx; //0-GJ 1-XS</P>
<P style="TEXT-INDENT: 2em">char szSl[10]; //数量</P>
<P style="TEXT-INDENT: 2em">char szDj[10]; //单价</P>
<P style="TEXT-INDENT: 2em">char szJe[10]; //金额</P>
<P style="TEXT-INDENT: 2em">} SPS;</P>
<P style="TEXT-INDENT: 2em">int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);</P>
<P style="TEXT-INDENT: 2em">（2）在VCLISTDlg.CPP中的起始处增加初始化数据和程序定义</P>
<P style="TEXT-INDENT: 2em">//在文件开始处增加数据结构初始化</P>
<P style="TEXT-INDENT: 2em">SPS Sps[]={//信息</P>
<P style="TEXT-INDENT: 2em">{"红梅",0,"1000","30","30000"},</P>
<P style="TEXT-INDENT: 2em">{"黄梅",0,"1000","29","29000"},</P>
<P style="TEXT-INDENT: 2em">{"绿梅",0,"1000","28","28000"},</P>
<P style="TEXT-INDENT: 2em">{"青梅",0,"1000","27","27000"},</P>
<P style="TEXT-INDENT: 2em">{"白梅",0,"1000","31","31000"},</P>
<P style="TEXT-INDENT: 2em">{"红梅",1,"1000","30","30000"},</P>
<P style="TEXT-INDENT: 2em">{"黄梅",1,"1000","29","29000"},</P>
<P style="TEXT-INDENT: 2em">{"绿梅",1,"1000","28","28000"},</P>
<P style="TEXT-INDENT: 2em">{"青梅",1,"1000","27","27000"},</P>
<P style="TEXT-INDENT: 2em">{"白梅",1,"1000","31","31000"}};</P>
<P style="TEXT-INDENT: 2em">CImageList Cil1,Cil2;//大小图像列表</P>
<P style="TEXT-INDENT: 2em">（3）在程序初始化处增加表头、图像和列表控制建立代码</P>
<P style="TEXT-INDENT: 2em">BOOL CVCLISTDlg::OnInitDialog()</P>
<P style="TEXT-INDENT: 2em">{&nbsp;&nbsp; CDialog::OnInitDialog();</P>
<P style="TEXT-INDENT: 2em">//......//其它代码</P>
<P style="TEXT-INDENT: 2em">// TODO: Add extra initialization here此处增加代码</P>
<P style="TEXT-INDENT: 2em">LV_ITEM lvitem;</P>
<P style="TEXT-INDENT: 2em">LV_COLUMN lvcol;</P>
<P style="TEXT-INDENT: 2em">int i,iPos,iItemNum;</P>
<P style="TEXT-INDENT: 2em">CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//创建图象列表</P>
<P style="TEXT-INDENT: 2em">Cil1.Create(32,32,TRUE,2,2);</P>
<P style="TEXT-INDENT: 2em">Cil1.Add(pApp-&gt;LoadIcon(IDI_GJ));</P>
<P style="TEXT-INDENT: 2em">Cil1.Add(pApp-&gt;LoadIcon(IDI_XS));</P>
<P style="TEXT-INDENT: 2em">Cil2.Create(16,16,TRUE,2,2);</P>
<P style="TEXT-INDENT: 2em">Cil2.Add(pApp-&gt;LoadIcon(IDI_GJ));</P>
<P style="TEXT-INDENT: 2em">Cil2.Add(pApp-&gt;LoadIcon(IDI_XS));//设置图象列表</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SetImageList(&amp;Cil1,LVSIL_NORMAL);</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SetImageList(&amp;Cil2,LVSIL_SMALL);//向列表控制中添加表列</P>
<P style="TEXT-INDENT: 2em">lvcol.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;</P>
<P style="TEXT-INDENT: 2em">lvcol.fmt=LVCFMT_CENTER;//居中</P>
<P style="TEXT-INDENT: 2em">i=0;</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="品 名";</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i;</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="数 量";</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i;</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="单 价";</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i;</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="金 额";</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i;</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);</P>
<P style="TEXT-INDENT: 2em">//向列表控制中添加表项</P>
<P style="TEXT-INDENT: 2em">iItemNum=sizeof(Sps)/sizeof(SPS);</P>
<P style="TEXT-INDENT: 2em">for(i=0;i&lt;iItemNum;i++){</P>
<P style="TEXT-INDENT: 2em">lvitem.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;</P>
<P style="TEXT-INDENT: 2em">lvitem.iItem=i;</P>
<P style="TEXT-INDENT: 2em">lvitem.iSubItem=0;</P>
<P style="TEXT-INDENT: 2em">lvitem.pszText=Sps[i].szPm;</P>
<P style="TEXT-INDENT: 2em">lvitem.iImage=Sps[i].Lx;</P>
<P style="TEXT-INDENT: 2em">lvitem.lParam=i;</P>
<P style="TEXT-INDENT: 2em">iPos=m_ListCtrl.InsertItem(&amp;lvitem);//返回表项插入后的索引号</P>
<P style="TEXT-INDENT: 2em">lvitem.mask=LVIF_TEXT;</P>
<P style="TEXT-INDENT: 2em">lvitem.iItem=iPos;</P>
<P style="TEXT-INDENT: 2em">lvitem.iSubItem=1;</P>
<P style="TEXT-INDENT: 2em">lvitem.pszText=Sps[i].szSl;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SetItem(&amp;lvitem);</P>
<P style="TEXT-INDENT: 2em">lvitem.iSubItem=2;</P>
<P style="TEXT-INDENT: 2em">lvitem.pszText=Sps[i].szDj;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SetItem(&amp;lvitem);</P>
<P style="TEXT-INDENT: 2em">lvitem.iSubItem=3;</P>
<P style="TEXT-INDENT: 2em">lvitem.pszText=Sps[i].szJe;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SetItem(&amp;lvitem);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">CheckRadioButton(IDC_STDICON,IDC_REPORT,IDC_STDICON);</P>
<P style="TEXT-INDENT: 2em">return TRUE; // return TRUE unless you set the focus to a control</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">（4）完善列表显示方式代码</P>
<P style="TEXT-INDENT: 2em">在利用Classwizard类向导创建各功能按钮显示功能函数之后，必须依次完善这些功能函数的代码，这些功能函数如下：</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnStdicon()//设置大图标显示方式</P>
<P style="TEXT-INDENT: 2em">{ // TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">LONG lStyle;</P>
<P style="TEXT-INDENT: 2em">lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型</P>
<P style="TEXT-INDENT: 2em">lStyle&amp;=~LVS_TYPEMASK; //清除显示方式位</P>
<P style="TEXT-INDENT: 2em">lStyle|=LVS_ICON; //设置显示方式</P>
<P style="TEXT-INDENT: 2em">SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnSmlicon() //设置小图标显示方式</P>
<P style="TEXT-INDENT: 2em">{ // TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">LONG lStyle;</P>
<P style="TEXT-INDENT: 2em">lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型</P>
<P style="TEXT-INDENT: 2em">lStyle&amp;=~LVS_TYPEMASK; //清除显示方式位</P>
<P style="TEXT-INDENT: 2em">lStyle|=LVS_SMALLICON; //设置显示方式</P>
<P style="TEXT-INDENT: 2em">SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnList() //设置列表显示方式</P>
<P style="TEXT-INDENT: 2em">{ // TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">LONG lStyle;</P>
<P style="TEXT-INDENT: 2em">lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型</P>
<P style="TEXT-INDENT: 2em">lStyle&amp;=~LVS_TYPEMASK; //清除显示方式位</P>
<P style="TEXT-INDENT: 2em">lStyle|=LVS_LIST; //设置显示方式</P>
<P style="TEXT-INDENT: 2em">SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnReport() //详细资料显示方式</P>
<P style="TEXT-INDENT: 2em">{ // TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">LONG lStyle;</P>
<P style="TEXT-INDENT: 2em">lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型</P>
<P style="TEXT-INDENT: 2em">lStyle&amp;=~LVS_TYPEMASK; //清除显示方式位</P>
<P style="TEXT-INDENT: 2em">lStyle|=LVS_REPORT; //设置显示方式</P>
<P style="TEXT-INDENT: 2em">SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">（5）删除功能的实现</P>
<P style="TEXT-INDENT: 2em">要实现删除功能，必须取得选中表项的数和表项总数，并且需要从后向前进行依次删除，其原因是每个表项被删除后，其后各表项的索引号均会发生递减变化，如果采取从前向后删除的方法，就会造成无法正常删除选中的表项，其功能代码如下：</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnDel() //删除按钮功能</P>
<P style="TEXT-INDENT: 2em">{&nbsp; &nbsp;// TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">int i,iState;</P>
<P style="TEXT-INDENT: 2em">int nItemSelected=m_ListCtrl.GetSelectedCount();//所选表项数</P>
<P style="TEXT-INDENT: 2em">int nItemCount=m_ListCtrl.GetItemCount();//表项总数</P>
<P style="TEXT-INDENT: 2em">if(nItemSelected&lt;1) return;</P>
<P style="TEXT-INDENT: 2em">for(i=nItemCount-1;i&gt;=0;i--){</P>
<P style="TEXT-INDENT: 2em">iState=m_ListCtrl.GetItemState(i,LVIS_SELECTED);</P>
<P style="TEXT-INDENT: 2em">if(iState!=0) m_ListCtrl.DeleteItem(i);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">（6）排序功能的实现</P>
<P style="TEXT-INDENT: 2em">列表控制有一个特殊的功能，当以详细资料方式显示时，列表顶部的表头可以当作按钮来使用，这可以通过列表控制创建时的风格来控制。当鼠标点击列表头名称时，列表控制就会向其父窗口发送一个LNV_COLUMNCLICK消息，利用类导向中列表控制IDC_LISTCTRL对应的LNV_COLUMNCLICK消息加入相应处理函数，就可将表列按照特定顺序进行排列。其函数使用方法见程序，其中iSort为排序的表列索引号，(PFNLVCOMPARE)CompareFunc为进行具体排序的回调函数，也就是说，通过鼠标点击表头实现的排序过程是由第三方开发的专用排序函数来实现的，排序函数只是实现表项的具体比较操作，而整个排序过程是由SortItemS属性通过不断调用这个函数来实现的。正常的排序过程是升序方式，通过调换排序函数中的参数值，就可实现降序排列，即将PARAM1与PARAM2调换位置。这个回调函数的前两个参数为表列中表项的索引号，第三个参数为排序的表列索引号。</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnColumnclickListctrl(NMHDR* pNMHDR, LRESULT* pResult) </P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//鼠标左键单击表头处理函数</P>
<P style="TEXT-INDENT: 2em">NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;</P>
<P style="TEXT-INDENT: 2em">// TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">static int iSorted=-1;//排列序号</P>
<P style="TEXT-INDENT: 2em">if (pNMListView-&gt;iSubItem==iSorted) return;</P>
<P style="TEXT-INDENT: 2em">iSorted=pNMListView-&gt;iSubItem;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,iSorted);</P>
<P style="TEXT-INDENT: 2em">*pResult = 0;</P>
<P style="TEXT-INDENT: 2em">} //排序时比较表项的回调函数</P>
<P style="TEXT-INDENT: 2em">int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)</P>
<P style="TEXT-INDENT: 2em">{&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;char *text1,*text2;</P>
<P style="TEXT-INDENT: 2em">switch (lParamSort){</P>
<P style="TEXT-INDENT: 2em">case 0L:text1=Sps[lParam1].szPm;</P>
<P style="TEXT-INDENT: 2em">text2=Sps[lParam2].szPm;break;</P>
<P style="TEXT-INDENT: 2em">case 1L:text1=Sps[lParam1].szSl;</P>
<P style="TEXT-INDENT: 2em">text2=Sps[lParam2].szSl;break;</P>
<P style="TEXT-INDENT: 2em">case 2L:text1=Sps[lParam1].szDj;</P>
<P style="TEXT-INDENT: 2em">text2=Sps[lParam2].szDj;break;</P>
<P style="TEXT-INDENT: 2em">case 3L:text1=Sps[lParam1].szJe;</P>
<P style="TEXT-INDENT: 2em">text2=Sps[lParam2].szJe;break;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">return (strcmp(text1,text2));//结果为&gt;0 =0 &lt;0</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">同样，也可以通过专用按钮来实现排序功能，如本文的排序按钮对应的功能代码如下：</P>
<P style="TEXT-INDENT: 2em">void CVCLISTDlg::OnSort() </P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;&nbsp;// TODO: Add your control notification handler code here</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,0);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">7、列表视的演练技巧</P>
<P style="TEXT-INDENT: 2em">在使用列表视时，其方法与列表控制基本相同，只不过列表视是在窗口中来实现的而列表控制是在对话框中实现，列表视的各种功能是通过菜单来实现的而列表控制是通过按钮等方式来实现的，列表控制需要在对话框中创建列表控制控件而列表视直接占据整个窗口，在设计过程中只要将按钮和列表控制设计过程变为菜单设计，并注意在功能增加是在类向导中是通过菜单命令来操作，同时在每个功能函数前面增加取得列表视引用的命令（ CListCtrl&amp; ListCtrl = GetListCtrl()），而其余数据结构和代码均不需要修改，实现起来比较容易。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">VC通用控件编程之CImageList控件</P>
<P style="TEXT-INDENT: 2em">图像列表控制（CImageList）是相同大小图像的一个集合，每个集合中均以0为图像的索引序号基数，图像列表通常由大图标或位图构成，其中包含透明位图模式。可以利用WINDOWS32位应用程序接口函数API来绘制、建立和删除图像，并能实现增加、删除、替换和拖动图像等操作。图像列表控制提供了控制图像列表的基本方法，这些方法在WINDOWS95及以后版本才能实现。</P>
<P style="TEXT-INDENT: 2em">（一）图像控制的对象结构</P>
<P style="TEXT-INDENT: 2em">1、图像控制的数据成员</P>
<P style="TEXT-INDENT: 2em">m_hImageList 连接图像对象的控制句柄</P>
<P style="TEXT-INDENT: 2em">2、图像控制的建立方法</P>
<P style="TEXT-INDENT: 2em">CimageList＆imageList建立图像控制对象结构</P>
<P style="TEXT-INDENT: 2em">Create 初始化图像列表并绑定对象</P>
<P style="TEXT-INDENT: 2em">图像控制的建立方法如下：</P>
<P style="TEXT-INDENT: 2em">BOOL Create( int cx, int cy, UINT nFlags, int nInitial, int nGrow );</P>
<P style="TEXT-INDENT: 2em">BOOL Create( UINT nBitmapID, int cx, int nGrow, COLORREF crMask );</P>
<P style="TEXT-INDENT: 2em">BOOL Create( LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask );</P>
<P style="TEXT-INDENT: 2em">BOOL Create( CImageList&amp; imagelist1, int nImage1, CImageList&amp; imagelist2</P>
<P style="TEXT-INDENT: 2em">,int nImage2,int dx, int dy );</P>
<P style="TEXT-INDENT: 2em">其中各项参数的含义为：cx定义图像的宽度，单位为象素；cy定义图象的高度，单位为象素；nFlags确定建立图像列表的类型，可以是以下值的组合：ILC_COLOR、ILC_COLOR4、ILC_COLOR8、ILC_COLOR16、ILC_COLOR24、ILC_COLOR32、ILC_COLORDDB和ILC_<A href="http://www.yesky.com/key/33/20033.html">MASK</A>；nInitial用来确定图像列表包含的图像数量；nGrow用来确定图像列表可控制的图像数量。NbitmapID 用来确定图像列表联系的位图标志值；crMask表示颜色屏蔽位；LpszBitmapID 用来确定包含位图资源的标识串；</P>
<P style="TEXT-INDENT: 2em">imagelist1 指向图像列表控制对象的一个指针；nImage1图像列表1中包含的图像数 量；imagelist2指向图像列表控制对象的一个指针；nImage2图像列表2中包含的图像数量；dx表示以象素为单位的图像宽度；dy表示以象素为单位的图像高度。</P>
<P style="TEXT-INDENT: 2em">同样，图像控制的建立也包括两个步骤，首先建立图像列表结构，然后建立图像列表控制。</P>
<P style="TEXT-INDENT: 2em">3、图像控制的属性类</P>
<P style="TEXT-INDENT: 2em">图像控制的属性类包括返回m_hImageList.控制句柄GetSafeHandle、取得图像列表中的图像数量GetImageCount、设置图像列表的背景颜色SetBkColor、取得图像列表的背景颜色SetBkColor和取得图像的有关信息SetBkColor。</P>
<P style="TEXT-INDENT: 2em">4、图像控制的操作方法</P>
<P style="TEXT-INDENT: 2em">图像控制的操作方法包括将一个图像列表绑定到一个对象上Attach、将对象上的图像列表解除绑定并返回句柄Detach、删除一个图像列表DeleteImageList、将一个图像增加到图像列表中Add和将一个图像从图像列表中删除Remove等。</P>
<P style="TEXT-INDENT: 2em">（二）图像控制的应用技巧</P>
<P style="TEXT-INDENT: 2em">对于图像控制，同样不能单独使用，必须与列表控制、树控制和标签控制相互结合应用，下面分别介绍其具体应用技巧。</P>
<P style="TEXT-INDENT: 2em">1、图像控制在列表控制中的应用技巧</P>
<P style="TEXT-INDENT: 2em">①设置图像控制CListCtrl::SetImageList的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">CImageList* SetImageList( CImageList* pImageList, int nImageList );</P>
<P style="TEXT-INDENT: 2em">其返回值是指向前一个图像列表控制的一个指针，如果不存在前一个图像列表则为NULL；其中参数pImageList是指向图像列表的标识，nImageList是图像列表的类型，可以是如下值：</P>
<P style="TEXT-INDENT: 2em">LVSIL_NORMAL 用大图标方式进行图像列表；</P>
<P style="TEXT-INDENT: 2em">LVSIL_SMALL 用小图标方式进行图像列表；</P>
<P style="TEXT-INDENT: 2em">LVSIL_STATE 以图像状态进行图像列表；</P>
<P style="TEXT-INDENT: 2em">②取得图像控制CListCtrl::GetImageList的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">CImageList* GetImageList( int nImageList ) const;</P>
<P style="TEXT-INDENT: 2em">其返回值为指向图像列表控制的指针，其中nImageList用来确定取得返回值的图像列表的 值，其取值与设置图像列表函数相同。</P>
<P style="TEXT-INDENT: 2em">③图像控制在列表控制中的应用示例</P>
<P style="TEXT-INDENT: 2em">CImageList Cil1,Cil2; //定义大小图标像列表</P>
<P style="TEXT-INDENT: 2em">　　CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//取得列表控制程序</P>
<P style="TEXT-INDENT: 2em">　　Cil1.Create(32,32,TRUE,2,2); //建立32位图像控制</P>
<P style="TEXT-INDENT: 2em">　　Cil1.Add(pApp-&gt;LoadIcon(IDI_GJ));//增加选中状态图像</P>
<P style="TEXT-INDENT: 2em">　　Cil1.Add(pApp-&gt;LoadIcon(IDI_XS));//增加非选中状态图像</P>
<P style="TEXT-INDENT: 2em">　　Cil2.Create(16,16,TRUE,2,2); //建立16位图像控制</P>
<P style="TEXT-INDENT: 2em">　　Cil2.Add(pApp-&gt;LoadIcon(IDI_GJ));//增加选中状态图像</P>
<P style="TEXT-INDENT: 2em">　　Cil2.Add(pApp-&gt;LoadIcon(IDI_XS));//增加非选中状态图像</P>
<P style="TEXT-INDENT: 2em">　　m_ListCtrl.SetImageList(&amp;Cil1,LVSIL_NORMAL);//设置大图标控制</P>
<P style="TEXT-INDENT: 2em">　　m_ListCtrl.SetImageList(&amp;Cil2,LVSIL_SMALL);//设置小图标控制</P>
<P style="TEXT-INDENT: 2em">2、图像控制在树控制中的应用技巧</P>
<P style="TEXT-INDENT: 2em">①设置图像控制CTreeCtrl::SetImageList的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">CImageList* SetImageList( CImageList * pImageList, int nImageListType );</P>
<P style="TEXT-INDENT: 2em">其返回值为指向前前一个图像列表的指针，否则为NULL；参数pImageList为指向图像列表的标识，如果pImageList为NULL则所有的图像都将从树控制中被清除；nImageListType为图像列表设置的类型，可以是如下值之一：</P>
<P style="TEXT-INDENT: 2em">TVSIL_NORMAL 设置正常图像列表，其中包括选中和非选中两种图标； </P>
<P style="TEXT-INDENT: 2em">TVSIL_STATE 设置图像列表状态，指用户自定义状态；</P>
<P style="TEXT-INDENT: 2em">②取得图像控制CTreeCtrl::GetImageList的调用格式如下：</P>
<P style="TEXT-INDENT: 2em">CImageList* GetImageList( UINT nImage );</P>
<P style="TEXT-INDENT: 2em">如果调用成功则返回图像列表控制指针，否则为NULL；nImage为取得返回值的图像列表类型，其取值和取得图像列表控制完全相同。</P>
<P style="TEXT-INDENT: 2em">③图像控制在树控制中的应用示例</P>
<P style="TEXT-INDENT: 2em">CImageList Cil1,Cil2;//定义大小图标像列表</P>
<P style="TEXT-INDENT: 2em">CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//获取应用程序指针</P>
<P style="TEXT-INDENT: 2em">Cil1.Create(16,16,ILC_COLOR,2,2);//建立图像控制</P>
<P style="TEXT-INDENT: 2em">Cil1.Add(pApp-&gt;LoadIcon(IDI_PM));//增加选中状态图像</P>
<P style="TEXT-INDENT: 2em">Cil1.Add(pApp-&gt;LoadIcon(IDI_CJ));//增加非选中状态图像</P>
<P style="TEXT-INDENT: 2em">m_TreeCtrl.SetImageList(&amp;Cil1,TVSIL_NORMAL);//设置图像控制列表</P>
<P style="TEXT-INDENT: 2em">然后在树控制的结构定义中进行如下设置：</P>
<P style="TEXT-INDENT: 2em">TCItem.item.iImage=0; //设置未选中图像索引号</P>
<P style="TEXT-INDENT: 2em">TCItem.item.iSelectedImage=1;//设置选中时图像引号</P>
<P style="TEXT-INDENT: 2em">3、图像控制在标签控制中的应用技巧</P>
<P style="TEXT-INDENT: 2em">①设置图像控制CTabCtrl::SetImageList的调用格式</P>
<P style="TEXT-INDENT: 2em">CImageList * SetImageList( CImageList * pImageList );</P>
<P style="TEXT-INDENT: 2em">其返回值为指向前一个图像列表的指针，如果不存在前一个图像列表则为NULL；pImageList为标识TAB控制的图像列表指针。</P>
<P style="TEXT-INDENT: 2em">②取得图像控制CTabCtrl::GetImageList的调用格式</P>
<P style="TEXT-INDENT: 2em">HIMAGELIST GetImageList() const;</P>
<P style="TEXT-INDENT: 2em">　其返回值为指向TAB控制的图像列表指针，如果调用不成功则为NULL。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">VC通用控件编程之CHeadCtrl控件</P>
<P style="TEXT-INDENT: 2em">表头控制（CHeaderCtrl）通常应用在窗口中的文本或数据的列表之上。一般为数据列的标题，可以包括多个部分，用户可以拖动每个部分并可以控制每列的宽度。表头控制类提供了普通表头控制的基本方法，只有在WINDOWS95以后版本系统中才提供，其方法包含在afxcmn.h文件中，一般与标签控制（CTabCtrl)和列表控制(CListCtrl)组合使用。</P>
<P style="TEXT-INDENT: 2em">（一）表头控制的对象结构</P>
<P style="TEXT-INDENT: 2em">1、表头控制对象的建立方法</P>
<P style="TEXT-INDENT: 2em">CHeaderCtrl &amp;cheaderCtrl 建立表头控制对象</P>
<P style="TEXT-INDENT: 2em">Create 建立表头并绑定对象</P>
<P style="TEXT-INDENT: 2em">CHeaderCtrl::Create的格式如下：</P>
<P style="TEXT-INDENT: 2em">BOOL Create( DWORD dwStyle, const RECT&amp;rect, CWnd* pParentWnd, UINT nID );其返回值非零时初始化成功，否则失败。</P>
<P style="TEXT-INDENT: 2em">参数dwStyle用来确定表头控制类型；rect用来确定表头控制的大小和位置；ParentWnd用来确定表头控制的父窗口；nID用来表示表头控制的标志。</P>
<P style="TEXT-INDENT: 2em">表头控制风格包括：</P>
<P style="TEXT-INDENT: 2em">HDS_BUTTONS 表示表头控制外观类似按钮；</P>
<P style="TEXT-INDENT: 2em">HDS_HORZ 表示表头控制为水平排列；</P>
<P style="TEXT-INDENT: 2em">HDS_VERT 表示表头控制为垂直排列；</P>
<P style="TEXT-INDENT: 2em">HDS_HIDDEN 表示表头控制为隐藏模式。</P>
<P style="TEXT-INDENT: 2em">它也可以使用普通类控制风格，包括：</P>
<P style="TEXT-INDENT: 2em">CCS_BOTTOM 设置控制位置在父窗口的底部并与父窗口同样宽度；</P>
<P style="TEXT-INDENT: 2em">CCS_NODIVIDER 在控制顶部形成两个像素的高亮区；</P>
<P style="TEXT-INDENT: 2em">CCS_NOHILITE 在控制顶部形成一个像素的高亮区；</P>
<P style="TEXT-INDENT: 2em">CCS_NOMOVEY 在响应WM_SIZE消息时重置大小并水平排列；</P>
<P style="TEXT-INDENT: 2em">CCS_NOPARENTALIGN 使控制自动靠近父窗口的顶部或底部；</P>
<P style="TEXT-INDENT: 2em">CCS_NORESIZE 设置初始大小或新值时使控制使用默认宽度和高度；</P>
<P style="TEXT-INDENT: 2em">CCS_TOP 设置在父窗口客户区域的顶部并与父窗口同样宽度；</P>
<P style="TEXT-INDENT: 2em">同样表头控制也可以使用窗口控制风格，包括：</P>
<P style="TEXT-INDENT: 2em">WS_CHILD 建立一个子窗口，不能用于WS_POPUP窗口类型；</P>
<P style="TEXT-INDENT: 2em">WS_VISIBLE 建立一个初始时不可见的窗口；</P>
<P style="TEXT-INDENT: 2em">WS_DISABLED 建立一个初始时无效的窗口；</P>
<P style="TEXT-INDENT: 2em">WS_GROUP 确定可用光标移动的控制群组；</P>
<P style="TEXT-INDENT: 2em">WS_TABSTOP 确定可用TAB控制移动站点；</P>
<P style="TEXT-INDENT: 2em">表头控制一般分为两个步骤，首先确定表头控制的数据结构，然后建立表头控制并绑定对象。</P>
<P style="TEXT-INDENT: 2em">2、表头控制的属性</P>
<P style="TEXT-INDENT: 2em">表头控制的属性包括取得表头控制中项目的数量GetItemCount、取得表头控制中某一项目的内容GetItem和设置表头控制中某一项目的内容SetItem。</P>
<P style="TEXT-INDENT: 2em">3、表头控制的操作方法</P>
<P style="TEXT-INDENT: 2em">表头控制的操作方法包括向表头控制中插入一个新项目InsertItem、从表头控制中删除一个项目DeleteItem和绘制表头中给定的项目DrawItem等。</P>
<P style="TEXT-INDENT: 2em">（二）表头控制的数据结构</P>
<P style="TEXT-INDENT: 2em">在使用表头控制时，首先必须建立一个数据结构HD_ITEM,其结构定义如下：</P>
<P style="TEXT-INDENT: 2em">typedef struct _HD_ITEM </P>
<P style="TEXT-INDENT: 2em">{ &nbsp;&nbsp;&nbsp;UINT mask; //结构成员有效控制位</P>
<P style="TEXT-INDENT: 2em">int cxy; //表头项目的宽度</P>
<P style="TEXT-INDENT: 2em">LPSTR pszText; //表头项目内容</P>
<P style="TEXT-INDENT: 2em">HBITMAP hbm; //表头项目的位置句柄</P>
<P style="TEXT-INDENT: 2em">int cchTextMax; //表头内容字符串长度</P>
<P style="TEXT-INDENT: 2em">int fmt; //表头项目的格式</P>
<P style="TEXT-INDENT: 2em">LPARAM lParam; //应用程序定义的32位数据</P>
<P style="TEXT-INDENT: 2em">} HD_ITEM;</P>
<P style="TEXT-INDENT: 2em">屏蔽控制位说明了数据结构成员中包含的有效数据，可以是下面标志的组合：</P>
<P style="TEXT-INDENT: 2em">HDI_BITMAP hbm成员有效</P>
<P style="TEXT-INDENT: 2em">HDI_FORMAT fmt 成员有效</P>
<P style="TEXT-INDENT: 2em">HDI_LPARAM lParam成员有效</P>
<P style="TEXT-INDENT: 2em">HDI_TEXT pszText 和cchTextMax 成员有效</P>
<P style="TEXT-INDENT: 2em">HDI_WIDTH cxy 成员有效并确定项目宽度值</P>
<P style="TEXT-INDENT: 2em">格式标志位fmt可以是以下标志的组合：</P>
<P style="TEXT-INDENT: 2em">HDF_CENTER 表头项目居中</P>
<P style="TEXT-INDENT: 2em">HDF_LEFT 表头项目左对齐</P>
<P style="TEXT-INDENT: 2em">HDF_RIGHT 表头项目右对齐</P>
<P style="TEXT-INDENT: 2em">HDF_BITMAP 表头显示一个位图</P>
<P style="TEXT-INDENT: 2em">HDF_OWNERDRAW 由主窗口自绘表头项目</P>
<P style="TEXT-INDENT: 2em">HDF_STRING 表头项目为一个字符串</P>
<P style="TEXT-INDENT: 2em">（三）表头控制的应用技巧</P>
<P style="TEXT-INDENT: 2em">由于表头控制无法单独使用，其主要是配合列表控制和标签控制，并多以文字表头应用多见，InsertItem、SetItem和GetItem是常用的方法，如在列表控制时利用InsertColumn属性就可以增加一个表列的文本标题，具体用法和技巧见列表控制和标签控制。下面以在列表控制中的增加表列的方法来具体说明：</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="品 名";//设置第一列表头名</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i; //表列序号</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70; //表列宽度</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);//插入一个表列</P>
<P style="TEXT-INDENT: 2em">lvcol.pszText="数 量";//设置第二列表头名</P>
<P style="TEXT-INDENT: 2em">lvcol.iSubItem=i;</P>
<P style="TEXT-INDENT: 2em">lvcol.cx=70;</P>
<P style="TEXT-INDENT: 2em">m_ListCtrl.InsertColumn(i++,&amp;lvcol);//插入一个表列</P>
<P style="TEXT-INDENT: 2em">......//其它代码</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008422105434966</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008422105434966</guid>
    <pubDate>Thu, 22 May 2008 10:54:34 +0800</pubDate>
    <dcterms:modified>2008-05-22T10:54:34+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[尾递归 ]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200842085430532</link>
    <description><![CDATA[<div>尾递归 - Tail Recursion<BR><BR>一种算法, 用于计算机编程技术.<BR><BR>尾递归是针对传统的递归算法而言的, 传统的递归算法在很多时候被视为洪水猛兽. 它的名声狼籍, 好像永远和低效联系在一起.<BR><BR>尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去.<BR><BR>以下是具体实例:<BR><BR>线性递归:<BR>long Rescuvie(long n) {&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp;&nbsp;return(n == 1) ? 1 : n * Rescuvie(n - 1);&nbsp; &nbsp;&nbsp; &nbsp;<BR>}&nbsp; &nbsp;&nbsp; &nbsp;<BR><BR>尾递归:<BR>long TailRescuvie(long n, long a) {&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp;&nbsp;return(n == 1) ? a : TailRescuvie(n - 1, a * n);&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>}&nbsp; &nbsp;&nbsp; &nbsp;<BR><BR>long TailRescuvie(long n) {//封装用的&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp;&nbsp;return(n == 0) ? 1 : TailRescuvie(n, 1);&nbsp; &nbsp; <BR>}&nbsp; &nbsp;&nbsp; &nbsp;<BR><BR>当n = 5时<BR>对于线性递归, 他的递归过程如下:<BR>Rescuvie(5)&nbsp;&nbsp;<BR>{5 * Rescuvie(4)}<BR>{5 * {4 * Rescuvie(3)}}<BR>{5 * {4 * {3 * Rescuvie(2)}}}<BR>{5 * {4 * {3 * {2 * Rescuvie(1)}}}}<BR>{5 * {4 * {3 * {2 * 1}}}}<BR>{5 * {4 * {3 * 2}}}<BR>{5 * {4 * 6}}<BR>{5 * 24}<BR>120<BR><BR>对于尾递归, 他的递归过程如下:<BR>TailRescuvie(5)<BR>TailRescuvie(5, 1)<BR>TailRescuvie(4, 5)<BR>TailRescuvie(3, 20)<BR>TailRescuvie(2, 60)<BR>TailRescuvie(1, 120)<BR>120<BR><BR>很容易看出, 普通的线性递归比尾递归更加消耗资源, 在实现上说, 每次重复的过程<BR>调用都使得调用链条不断加长. 系统不得不使用栈进行数据保存和恢复.而尾递归就<BR>不存在这样的问题, 因为他的状态完全由n和a保存.<BR></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200842085430532</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200842085430532</guid>
    <pubDate>Tue, 20 May 2008 08:54:30 +0800</pubDate>
    <dcterms:modified>2008-05-20T08:54:30+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[VC 中的定时]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/4303660120084904944429</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">VC中提供了很多关于时间操作的函数，编写程序时我们可以跟据定时的不同精度要求选择不同的时间函数来完成定时和计时操作。 </P>
<P style="TEXT-INDENT: 2em">　　 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;方式一：VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔，如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer()，并在该函数中添加响应的处理语句，用来完成到达定时时间的操作。这种定时方法非常简单，可以实现一定的定时功能，但其定时功能如同Sleep()函数的延时功能一样，精度非常低，最小计时精度仅为18ms。CPU占用低，且定时器消息在多任务操作系统中的优先级很低，不能得到及时响 应，往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。 </P>
<P style="TEXT-INDENT: 2em">　　方式二：VC中使用sleep()函数实现延时，它的单位是ms，如延时2秒，用sleep(2000)。精度非常 低，最小计时精度仅为30ms，用sleep函数的不利处在于延时期间不能处理其他的消息，如果时间太 长，就好象死机一样，CPU占用率非常高，只能用于要求不高的延时程序中。 </P>
<P style="TEXT-INDENT: 2em">　　方式三：利用COleDateTime类和COleDateTimeSpan类结合WINDOWS的消息处理过程来实现秒级延时。以下是实现2秒的延时代码： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COleDateTime &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_time = COleDateTime::GetCurrentTime(); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COleDateTimeSpan &nbsp;end_time= COleDateTime::GetCurrentTime()-start_time; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(end_time.GetTotalSeconds()&lt; 2) //实现延时2秒 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSG &nbsp;&nbsp;msg; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMessage(&amp;msg,NULL,0,0); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage(&amp;msg); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage(&amp;msg); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//以上四行是实现在延时或定时期间能处理其他的消息， </P>
<P style="TEXT-INDENT: 2em">　　　　 //虽然这样可以降低CPU的占有率， </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//但降低了延时或定时精度，实际应用中可以去掉。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end_time = COleDateTime::GetCurrentTime()-start_time; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//这样在延时的时候我们也能够处理其他的消息。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　方式四：在精度要求较高的情况下，VC中可以利用GetTickCount()函数，该函数的返回值是 &nbsp;DWORD型，表示以ms为单位的计算机启动后经历的时间间隔。精度比WM_TIMER消息映射高，在较短的定时中其计时误差为15ms，在较长的定时中其计时误差较低，如果定时时间太长，就好象死机一样，CPU占用率非常高，只能用于要求不高的延时程序中。下列代码可以实现50ms的精确定时： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwStart = GetTickCount(); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwEnd &nbsp;&nbsp;= dwStart; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwEnd = GetTickCount() - dwStart; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(dwEnd &lt;50); </P>
<P style="TEXT-INDENT: 2em">为使GetTickCount()函数在延时或定时期间能处理其他的消息，可以把代码改为： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwStart = GetTickCount(); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwEnd &nbsp;&nbsp;= dwStart; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSG &nbsp;&nbsp;msg; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMessage(&amp;msg,NULL,0,0); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage(&amp;msg); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage(&amp;msg); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwEnd = GetTickCount()-dwStart; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(dwEnd &lt;50); </P>
<P style="TEXT-INDENT: 2em">虽然这样可以降低CPU的占有率，并在延时或定时期间也能处理其他的消息，但降低了延时或定时精度。 </P>
<P style="TEXT-INDENT: 2em">　　方式五：与GetTickCount()函数类似的多媒体定时器函数DWORD timeGetTime(void)，该函数定时精 度为ms级，返回从Windows启动开始经过的毫秒数。微软公司在其多媒体Windows中提供了精确定时器的底 层API持，利用多媒体定时器可以很精确地读出系统的当前时间，并且能在非常精确的时间间隔内完成一 个事件、函数或过程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须将 Winmm.lib &nbsp;和 Mmsystem.h 添加到工程中，否则在编译时提示DWORD timeGetTime(void)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的，所以，应该建立定时循环来进行定时事件的控制。 </P>
<P style="TEXT-INDENT: 2em">　　方式六：使用多媒体定时器timeSetEvent()函数，该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。函数的原型如下： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MMRESULT timeSetEvent（ UINT uDelay, </P>
<P style="TEXT-INDENT: 2em">&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;UINT uResolution, </P>
<P style="TEXT-INDENT: 2em">&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;LPTIMECALLBACK lpTimeProc, </P>
<P style="TEXT-INDENT: 2em">&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;WORD dwUser, </P>
<P style="TEXT-INDENT: 2em">&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;UINT fuEvent ） </P>
<P style="TEXT-INDENT: 2em">　　该函数设置一个定时回调事件，此事件可以是一个一次性事件或周期性事件。事件一旦被激活，便调用指定的回调函数， 成功后返回事件的标识符代码，否则返回NULL。函数的参数说明如下： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uDelay：以毫秒指定事件的周期。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uresolution：以毫秒指定延时的精度，数值越小定时器事件分辨率越高。缺省值为1ms。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LpTimeProc：指向一个回调函数。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DwUser：存放用户提供的回调数据。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FuEvent：指定定时器事件类型： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_ONESHOT：uDelay毫秒后只产生一次事件 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_PERIODIC ：每隔uDelay毫秒周期性地产生事件。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　具体应用时，可以通过调用timeSetEvent()函数，将需要周期性执行的任务定义在LpTimeProc回调函数 中(如：定时采样、控制等)，从而完成所需处理的事件。需要注意的是，任务处理的时间不能大于周期间隔时间。另外，在定时器使用完毕后， 应及时调用timeKillEvent()将之释放。 </P>
<P style="TEXT-INDENT: 2em">　　方式七：对于精确度要求更高的定时操作，则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数，并要求计算机从硬件上支持精确定时器。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOL &nbsp;QueryPerformanceFrequency(LARGE_INTEGER ＊lpFrequency); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOL &nbsp;QueryPerformanceCounter(LARGE_INTEGER ＊lpCount); </P>
<P style="TEXT-INDENT: 2em">　　数据类型ARGE_INTEGER既可以是一个8字节长的整型数，也可以是两个4字节长的整型数的联合结构， 其具体用法根据编译器是否支持64位而定。该类型的定义如下： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef union _LARGE_INTEGER </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD LowPart ;// 4字节整型数 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LONG &nbsp;HighPart;// 4字节整型数 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LONGLONG QuadPart ;// 8字节整型数 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}LARGE_INTEGER ; </P>
<P style="TEXT-INDENT: 2em">　　 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在进行定时之前，先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率， 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数，利用两次获得的计数之差及时钟频率，计算出事件经 历的精确时间。下列代码实现1ms的精确定时： </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LARGE_INTEGER litmp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LONGLONG QPart1,QPart2; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double dfMinus, dfFreq, dfTim; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueryPerformanceFrequency(&amp;litmp); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueryPerformanceCounter(&amp;litmp); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QPart1 = litmp.QuadPart;// 获得初始值 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueryPerformanceCounter(&amp;litmp); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QPart2 = litmp.QuadPart;//获得中止值 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfMinus = (double)(QPart2-QPart1); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfTim = dfMinus / dfFreq;// 获得对应的时间值，单位为秒 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}while(dfTim&lt;0.001); </P>
<P style="TEXT-INDENT: 2em">　　 </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;另外值得一提的是，由于机器自身的差别和机器运行负荷的不同，要实现非常精确定时实际上是很难做到的，以上定时精度都是理论上能够达到的，实际运行中要降低很多。第七种方式中我做实验时精度基本能准确</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/4303660120084904944429</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/4303660120084904944429</guid>
    <pubDate>Fri, 9 May 2008 12:49:44 +0800</pubDate>
    <dcterms:modified>2008-05-09T12:49:44+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 删除文件，目录，文件夹]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008490401094</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://lingchuangsong.blog.163.com/" target=_blank>Austin</A> 的 <A href="http://lingchuangsong.blog.163.com/blog/static/1269323220082268102962" target=_blank>删除文件，目录，文件夹</A><BR>
<P>项目中突然要使用删除文件的功能，于是看看书，网上找找资料，总结了一些方法，其实都很简单的。希望对大家有帮助：</P>
<P>第一种方法：&nbsp;&nbsp;&nbsp;定义一个文件类对象来操作<BR>CFile &nbsp; TempFile; &nbsp; <BR>&nbsp; TempFile.Remove(指定文件名); </P>
<P>第二种方法：&nbsp; 使用系统函数 DeleteFile( LPCSTR filename )删除文件&nbsp;&nbsp;&nbsp; _rmdir(),删除目录 DeleteDirectory(sTempDir);&nbsp; 删除目录 RemoveDirectory(sTempDir);删除目录<BR>eg:&nbsp; DeleteFile( &nbsp; char &nbsp; *tempFileName);&nbsp;&nbsp; </P>
<P>上面提到的删除目录的方法只能删除空目录（即文件夹），如果目录下有文件或者子目录，就不能删除了，VC里好像没有直接的函数，只能手动写个函数来删除了： </P>
<P>&nbsp;</P>
<P style="TEXT-INDENT: 2em">【问题】怎样删除一个非空目录，及其目录里面所有内容：</P>
<P style="TEXT-INDENT: 2em">【解答1】如果不进行递归删除。你可以使用API函数SHFileOperation，它可以一次删除目录及其下面的子目录和文件。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 示例代码：&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">BOOL DelTree(LPCTSTR lpszPath)</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; SHFILEOPSTRUCT FileOp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.fFlags = FOF_NOCONFIRMATION;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.hNameMappings = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.hwnd = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.lpszProgressTitle = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.pFrom = lpszPath;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.pTo = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; FileOp.wFunc = FO_DELETE;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return SHFileOperation(&amp;FileOp) == 0;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">【解答2】使用递归调用，逐个删除：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 示例代码：</P>
<P style="TEXT-INDENT: 2em">BOOL DeleteDirectory(char *DirName)//如删除 DeleteDirectory("c:\\aaa") </P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CFileFind tempFind;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char tempFileFind[MAX_PATH];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(tempFileFind,"%s\\*.*",DirName);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(IsFinded)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IsFinded=(BOOL)tempFind.FindNextFile();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!tempFind.IsDots())</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char foundFileName[MAX_PATH];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(foundFileName,tempFind.GetFileName().GetBuffer(MAX_PATH));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(tempFind.IsDirectory())</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char tempDir[MAX_PATH];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(tempDir,"%s\\%s",DirName,foundFileName);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteDirectory(tempDir);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char tempFileName[MAX_PATH];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(tempFileName,"%s\\%s",DirName,foundFileName);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteFile(tempFileName);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempFind.Close();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!RemoveDirectory(DirName))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(0,"删除目录失败！","警告信息",MB_OK);//比如没有找到文件夹,删除失败，可把此句删除</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return FALSE;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">//删除文件夹目录(非空)<IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0>bool DeleteDirectory(char* sDirName) </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615543.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/0615544.gif" border=0>...{&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; CFileFind tempFind; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;char sTempFileFind[200] ;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; sprintf(sTempFileFind,"%s\*.*",sDirName); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; BOOL IsFinded = tempFind.FindFile(sTempFileFind);&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;while (IsFinded) </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155411.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/06155412.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;...{&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IsFinded = tempFind.FindNextFile(); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!tempFind.IsDots()) </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155411.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/06155412.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...{&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char sFoundFileName[200]; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(sFoundFileName,tempFind.GetFileName().GetBuffer(200)); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (tempFind.IsDirectory())&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155411.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/06155412.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...{&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char sTempDir[200]; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(sTempDir,"%s\%s",sDirName,sFoundFileName); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteDirectory(sTempDir);&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155427.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155411.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/06155412.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...{&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char sTempFileName[200]; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(sTempFileName,"%s\%s",sDirName,sFoundFileName); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteFile(sTempFileName);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155427.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155427.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155427.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; tempFind.Close(); </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;if(!RemoveDirectory(sDirName))&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155411.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/06155412.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;...{&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155427.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;return TRUE; </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155444.gif" border=0>} </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615543.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/0615544.gif" border=0>/**////////////////////////////////////////// </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0>//下面是应用，CString m_strDir 是一个文件夹路径，如：d:downloadpic</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615540.gif" border=0>BOOL DelAll()</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615543.gif" border=0><IMG src="http://www.87717.com/upimg/allimg/071001/0615544.gif" border=0>...{ </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;if(PathFileExists(m_strDir))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteDirectory((LPSTR)(LPCTSTR)m_strDir);</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/0615545.gif" border=0>&nbsp;&nbsp;&nbsp;&nbsp;return 1;</P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.87717.com/upimg/allimg/071001/06155444.gif" border=0>} </P>
<P style="TEXT-INDENT: 2em"></P></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008490401094</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008490401094</guid>
    <pubDate>Fri, 9 May 2008 12:40:10 +0800</pubDate>
    <dcterms:modified>2008-05-09T12:40:10+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 VC键盘消息大全]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/4303660120084903915939</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://lingchuangsong.blog.163.com/" target=_blank>Austin</A> 的 <A href="http://lingchuangsong.blog.163.com/blog/static/1269323220084751957159" target=_blank>VC键盘消息大全</A><BR>符号常量 十六进制值 指定的鼠标或键盘按键<BR>　　VK_LBUTTON 01 鼠标左键<BR>　　VK_RBUTTON 02 鼠标右键<BR>　　VK_CANCEL 03 Control-break 过程<BR>　　VK_MBUTTON 04 鼠标中键<BR>　　VK_BACK 08 BACKSPACE 键<BR>　　VK_TAB 09 TAB 键<BR>　　VK_CLEAR 0C CLEAR 键<BR>　　VK_RETURN 0D ENTER 键<BR>　　VK_SHIFT 10 SHIFT 键<BR>　　VK_CONTROL 11 CTRL 键<BR>　　VK_MENU 12 ALT 键<BR>　　VK_PAUSE 13 PAUSE 键<BR>　　VK_CAPITAL 14 CAPS LOCK 键<BR>　　VK_ESCAPE 1B ESC 键<BR>　　VK_SPACE 20 SPACEBAR<BR>　　VK_PRIOR 21 PAGE UP 键<BR>　　VK_NEXT 22 PAGE DOWN 键<BR>　　VK_END 23 END 键<BR>　　VK_HOME 24 HOME 键<BR>　　VK_LEFT 25 LEFT ARROW 键<BR>　　VK_UP 26 UP ARROW 键<BR>　　VK_RIGHT 27 RIGHT ARROW 键<BR>　　VK_DOWN 28 DOWN ARROW 键<BR>　　VK_SELECT 29 SELECT 键<BR>　　VK_EXECUTE 2B EXECUTE 键<BR>　　VK_SNAPSHOT 2C PRINT SCREEN键（用于Windows 3.0及以后版本）<BR>　　VK_INSERT 2D INS 键<BR>　　VK_DELETE 2E DEL 键<BR>　　VK_HELP 2F HELP 键<BR>　　///////////////////////////////////////////////////<BR>　　对于字母键和非小键盘上的数字键,直接在单引号中加入该键就行.<BR>　　比如:a键:'A'<BR>　　 1键:'1'<BR>　　//////////////////////////////////////////////<BR><BR>　　VK_LWIN 5B Left Windows 键 (Microsoft自然键盘)<BR>　　VK_RWIN 5C Right Windows 键 (Microsoft自然键盘)<BR>　　VK_APPS 5D Applications 键 (Microsoft自然键盘)<BR>　　VK_NUMPAD0 60 数字小键盘上的 0 键<BR>　　VK_NUMPAD1 61 数字小键盘上的 1 键<BR>　　VK_NUMPAD2 62 数字小键盘上的 2 键<BR>　　VK_NUMPAD3 63 数字小键盘上的 3 键<BR>　　VK_NUMPAD4 64 数字小键盘上的 4 键<BR>VK_NUMPAD5 65 数字小键盘上的 5 键<BR>　　VK_NUMPAD6 66 数字小键盘上的 6 键<BR>　　VK_NUMPAD7 67 数字小键盘上的 7 键<BR>　　VK_NUMPAD8 68 数字小键盘上的 8 键<BR>　　VK_NUMPAD9 69 数字小键盘上的 9 键<BR>　　VK_MULTIPLY 6A Multiply 键<BR>　　VK_ADD 6B Add 键<BR>　　VK_SEPARATOR 6C Separator 键<BR>　　VK_SUBTRACT 6D Subtract 键<BR>　　VK_DECIMAL 6E Decimal 键<BR>　　VK_DIVIDE 6F Divide 键<BR>　　VK_F1 70 F1 键<BR>　　VK_F2 71 F2 键<BR>　　VK_F3 72 F3 键<BR>　　VK_F4 73 F4 键<BR>　　VK_F5 74 F5 键<BR>　　VK_F6 75 F6 键<BR>　　VK_F7 76 F7 键<BR>　　VK_F8 77 F8 键<BR>　　VK_F9 78 F9 键<BR>　　VK_F10 79 F10 键<BR>　　VK_F11 7A F11 键<BR>　　VK_F12 7B F12 键<BR>　　VK_F13 7C F13 键<BR>　　VK_F14 7D F14 键<BR>　　VK_F15 7E F15 键<BR>　　VK_F16 7F F16 键<BR>　　VK_F17 80H F17 键<BR>　　VK_F18 81H F18 键<BR>　　VK_F19 82H F19 键<BR>　　VK_F20 83H F20 键<BR>　　VK_F21 84H F21 键<BR>　　VK_F22 85H F22 键<BR>　　VK_F23 86H F23 键<BR>　　VK_F24 87H F24 键<BR>　　VK_NUMLOCK 90 NUM LOCK 键<BR>　　VK_SCROLL 91 SCROLL LOCK 键<BR>　　VK_ATTN F6 Attn 键<BR>　　VK_CRSEL F7 CrSel 键<BR>　　VK_EXSEL F8 ExSel 键<BR>　　VK_EREOF F9 Erase EOF 键<BR>VK_PLAY FA Play 键<BR>　　VK_ZOOM FB Zoom 键<BR>　　VK_OEM_CLEAR FE Clear 键</BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/4303660120084903915939</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/4303660120084903915939</guid>
    <pubDate>Fri, 9 May 2008 12:39:15 +0800</pubDate>
    <dcterms:modified>2008-05-09T12:39:15+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[VC++结束进程]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008480476714</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">1.使用ExitProcess()结束进程</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; 进程只是提供了一段地址空间和内核对象，其运行时通过在其地址空间内的主线程来体现的。当主线程的进入点函数返回时，进程也就随之结束。这种进程的终止方式是进程的正常退出，进程中的所有线程资源都能够得到正确的清除。除了这种进程的正常退出方式外，有时还需要在<A href="http://www.programbbs.com/doc/">程序</A>中通过代码来强制结束本进程或其他进程的运行。ExitProcess()函数的原型为：</P>
<P style="TEXT-INDENT: 2em">&nbsp;void ExitProcess(UINT uExitCode);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; 其参数uExitCode为进程设置了退出代码。该函数具有强制性，在执行完毕后进程即被结束，因此位于其后的任何代码将不能被执行。虽然ExitProcess()函数可以在结束进程的同时通知与其关联的动态链接库，但是由于它的这种执行的强制性，使得ExitProcess()函数在使用上将存在有安全隐患。例如，如果在<A href="http://www.programbbs.com/doc/">程序</A>调用ExitProcess()函数之前曾用new操作符申请过一段空间，那么将会由于ExitProcess()函数的强制性而无法通过delete操作符将其释放，从而造成内存泄露。有鉴于ExitProcess()函数的强制性和不安全性，在使用时一定要引起注意。</P>
<P style="TEXT-INDENT: 2em">2.使用TerminateProcess()结束进程</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; ExitProcess()只能强制执行本进程的退出，如果要在一个进程中强制结束其他进程就要用TerminateProcess()来实现。与ExitProcess()不同，TerminateProcess()函数执行后，被终止的进程是不会的到任何关于<A href="http://www.programbbs.com/doc/">程序</A>退出的通知的。也就是说，被终止的进程是无法在结束运行前进行退出前的收尾工作的。所以，通常只有在其他任何方法都无法迫使进程退出时才会考虑使用TerminateProcess()去强制结束进程。下面给出TerminateProcess()的函数原型：</P>
<P style="TEXT-INDENT: 2em">&nbsp;BOOL TerminateProcess(HANDLE hProcess,UINT uExitCode);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; 参数hProcess和uExitCode分别为进程句柄和退出代码。如果被结束的是本进程，可以通过GetCurrentProcess()获取到句柄。TerminateProcess()是异步执行的，在调用返回后并不能确定被终止进程是否已经真的退出，如果调用TerminateProcess()的进程对此细节关心，可以通过WaitForSingleObject()来等待进程的真正结束。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; 在VC<A href="http://www.programbbs.com/doc/">程序</A>中如何结束系统正在运行的其他进程（该进程必须有窗口界面），其实很简单，按如下步骤进行即可：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 1.取得进程的句柄（利用FindWindow函数得到）;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 2.获取进程ID号（用GetWindowThreadProcessId函数获取）;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 3.打开进程，OpenProcess函数中的第一个参数设为PROCESS_TERMINATE，就可以获取处理该进程的句柄;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 4.利用TerminateProcess函数结束进程，将该函数的第二个参数设为4。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 代码如下： </P>
<P style="TEXT-INDENT: 2em">//结束进程</P>
<P style="TEXT-INDENT: 2em">int CStaticFunc::KillProcess(LPCSTR pszClassName, LPCSTR </P>
<P style="TEXT-INDENT: 2em">pszWindowTitle)</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; HANDLE hProcessHandle;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; ULONG nProcessID;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; HWND TheWindow;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; TheWindow = ::FindWindow( NULL, pszWindowTitle );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; ::GetWindowThreadProcessId( TheWindow, &amp;nProcessID );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; hProcessHandle = ::OpenProcess( PROCESS_TERMINATE, FALSE, </P>
<P style="TEXT-INDENT: 2em">nProcessID );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return ::TerminateProcess( hProcessHandle, 4 );</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 而启动进程则只需要CreateProcess函数就可完成，需要注意的是这个函数的几个输入参数，第一个参数是</P>
<P style="TEXT-INDENT: 2em">//启动新进程</P>
<P style="TEXT-INDENT: 2em">int CStaticFunc::CreateNewProcess(LPCSTR pszExeName)</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; PROCESS_INFORMATION piProcInfoGPS;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; STARTUPINFO siStartupInfo;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; SECURITY_ATTRIBUTES saProcess, saThread;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; ZeroMemory( &amp;siStartupInfo, sizeof(siStartupInfo) );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; siStartupInfo.cb = sizeof(siStartupInfo);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saProcess.nLength = sizeof(saProcess);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saProcess.lpSecurityDescriptor = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saProcess.bInheritHandle = true;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saThread.nLength = sizeof(saThread);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saThread.lpSecurityDescriptor = NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; saThread.bInheritHandle = true;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return ::CreateProcess( NULL, (LPTSTR)pszExeName, &amp;saProcess, </P>
<P style="TEXT-INDENT: 2em">&amp;saThread, false,</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CREATE_DEFAULT_ERROR_MODE, NULL, NULL, </P>
<P style="TEXT-INDENT: 2em">&amp;siStartupInfo,&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; &amp;piProcInfoGPS );</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em"></P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008480476714</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008480476714</guid>
    <pubDate>Thu, 8 May 2008 12:47:06 +0800</pubDate>
    <dcterms:modified>2008-05-08T12:47:06+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[二插链表存储结构源程序清单]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008480333479</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">#include&lt;stdio.h&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">typedef struct Tnode{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; data;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*输入的数据*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; struct&nbsp; Tnode&nbsp;&nbsp;&nbsp; *lchild,*rchild;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; /*结点的左右指针，分别指向结点的左右孩子*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }*node,BSTnode;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">searchBST(node t,int key,node f,node *p) /*查找函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(!t)&nbsp; {*p=f;return (0);}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*查找不成功*/</P>
<P style="TEXT-INDENT: 2em">else&nbsp;&nbsp;&nbsp; if(key==t-&gt;data)&nbsp;&nbsp;&nbsp; {*p=t;return (1);}&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*查找成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(key&lt;t-&gt;data)&nbsp;&nbsp; searchBST(t-&gt;lchild,key,t,p);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;/*在左子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">else&nbsp;&nbsp;&nbsp; searchBST(t-&gt;rchild,key,t,p);&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*在右子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">insertBST(node *t,int key)&nbsp; /*插入函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; node p=NULL,s=NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(!searchBST(*t,key,NULL,&amp;p))&nbsp;&nbsp; /*查找不成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;s=(node)malloc(sizeof(BSTnode));</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s-&gt;data=key;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s-&gt;lchild=s-&gt;rchild=NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!p)&nbsp; *t=s;&nbsp;&nbsp;&nbsp;&nbsp; /*被插结点*s为新的根结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(key&lt;p-&gt;data)&nbsp;&nbsp; p-&gt;lchild=s; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*被插结点*s为左孩子*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; p-&gt;rchild=s;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*被插结点*s为右孩子*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;return (1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">else&nbsp; return (0); </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*树中已有关键字相同的结点，不再插入*/</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">inorderTraverse(node *t)&nbsp; /*中序遍历函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(*t){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(inorderTraverse(&amp;(*t)-&gt;lchild)) &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;/*中序遍历根的左子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d&nbsp; ",(*t)-&gt;data);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*输出根结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(inorderTraverse(&amp;(*t)-&gt;rchild));&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*中序遍历根的右子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; return(1);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">calculateASL(node *t,int *s,int *j,int i)&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*计算平均查找长度*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(*t){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;&nbsp;&nbsp; /*i记录当前结点的在当前树中的深度*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;*s=*s+i;&nbsp;&nbsp; /*s记录已遍历过的点的深度之和*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(calculateASL(&amp;(*t)-&gt;lchild,s,j,i))&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*计算左子树的ASL*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*j)++;&nbsp;&nbsp; /*j记录树中结点的数目*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(calculateASL(&amp;(*t)-&gt;rchild,s,j,i)) /*计算右子树的ASL*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {i--; return(1);}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; return(1);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">node Delete(node t,int&nbsp; key)&nbsp;&nbsp; /*删除函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; node&nbsp;&nbsp;&nbsp; p=t,q=NULL,s,f;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; while(p!=NULL)&nbsp;&nbsp; /*查找要删除的点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p-&gt;data==key)&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q=p;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p-&gt;data&gt;key)&nbsp;&nbsp; p=p-&gt;lchild;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else &nbsp;&nbsp;&nbsp;p=p-&gt;rchild;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(p==NULL)&nbsp;&nbsp; return&nbsp; t;&nbsp;&nbsp;&nbsp; /*查找失败*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(p-&gt;lchild==NULL)&nbsp;&nbsp;&nbsp;&nbsp; /*p指向当前要删除的结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(q==NULL)&nbsp;&nbsp; t=p-&gt;rchild;&nbsp; /*q指向要删结点的父母*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(q-&gt;lchild==p)&nbsp;&nbsp;&nbsp; q-&gt;lchild=p-&gt;rchild;&nbsp; /*p为q的左孩子*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp; &nbsp;&nbsp;q-&gt;rchild=p-&gt;rchild;</P>
<P style="TEXT-INDENT: 2em">&nbsp;/*p为q的右孩子*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(p);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*p的左孩子不为空*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f=p;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=p-&gt;lchild;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(s-&gt;rchild)&nbsp;&nbsp; /*左拐后向右走到底*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f=s;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s=s-&gt;rchild;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(f==p)&nbsp;&nbsp;&nbsp; f-&gt;lchild=s-&gt;lchild;&nbsp; /*重接f的左子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; f-&gt;rchild=s-&gt;lchild;&nbsp;&nbsp; /*重接f的右子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;data=s-&gt;data;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free (s);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return&nbsp; t;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">int balanceBST(node t,int *i)&nbsp; /*判断是否为平衡二叉树的函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; dep1,dep2;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(!t)&nbsp; return(0);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dep1=balanceBST(t-&gt;lchild,i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dep2=balanceBST(t-&gt;rchild,i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">if((dep1-dep2)&gt;1||(dep1-dep2)&lt;-1) *i=dep1-dep2; </P>
<P style="TEXT-INDENT: 2em">/*用i值记录是否存在不平衡现象*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(dep1&gt;dep2) return(dep1+1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; return(dep2+1);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">void main()</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; node&nbsp; T=NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; num;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; s=0,j=0,i=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; ch=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; node&nbsp; p=NULL;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("please input a list of numbers end with zero:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; do{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!num) printf("you have finished your input!\n");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; insertBST(&amp;T,num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }while(num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n\n---the menu of the opperation---\n");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*主程序菜单*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 0:&nbsp; exit" );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 1:&nbsp; inorder travel the tree");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 2:&nbsp; the average search length for the tree");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 3:&nbsp; delete");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 4:&nbsp; judge the balance");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; while(ch==ch)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n&nbsp;&nbsp; choose the opperation to continue:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;ch);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(ch){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:&nbsp;&nbsp; exit(0);&nbsp;&nbsp;&nbsp; /*0－－退出*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:&nbsp;&nbsp; printf("&nbsp;&nbsp; The result of the inorder traverse is:\n&nbsp;&nbsp; ");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inorderTraverse(&amp;T);&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*1－－中序遍历*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 2:&nbsp;&nbsp; s=0;j=0;i=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calculateASL(&amp;T,&amp;s,&amp;j,i);&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*2－－计算平均查找长度*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("&nbsp;&nbsp; ASL=%d/%d",s,j);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 3:&nbsp;&nbsp; printf("&nbsp;&nbsp; Please input the number you want to delete:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;num);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*3－－删除某个结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(searchBST(T,num,NULL,&amp;p))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T=Delete(T,num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; You have delete the number successfully!\n&nbsp;&nbsp; ");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inorderTraverse(&amp;T);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp; printf("&nbsp;&nbsp; No node %d you want to delete!",num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 4:&nbsp;&nbsp; i=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; balanceBST(T,&amp;i);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*判断是否为平衡二插树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i==0)&nbsp;&nbsp; printf("&nbsp;&nbsp; OK!The tree is a balanced tree!");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; NO!");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:&nbsp; printf("Your input is wrong!please input again!\n");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; /*输入无效字符*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; (2) 一维数组顺序表存储结构源程序清单：</P>
<P style="TEXT-INDENT: 2em">#include&lt;stdio.h&gt;</P>
<P style="TEXT-INDENT: 2em">#define&nbsp;&nbsp; N&nbsp;&nbsp; 100&nbsp;&nbsp;&nbsp; /*可建树结点的最大数目*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">typedef&nbsp;&nbsp; struct {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; *data;&nbsp;&nbsp;&nbsp; /*数组首址指针*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; lenth;&nbsp;&nbsp;&nbsp; /*数组长度*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }BST;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">insert(BST T,int i,int key)&nbsp;&nbsp; /*插入函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(i&lt;1||i&gt;N)&nbsp;&nbsp; printf("overflow!"); /*查找不成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(T.data[i]==0)&nbsp;&nbsp; T.data[i]=key;&nbsp;&nbsp; /*查找成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp; &nbsp;&nbsp;else&nbsp;&nbsp;&nbsp; if(key&lt;T.data[i])&nbsp;&nbsp; insert(T,2*i,key);&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&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;/*在左子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(key&gt;T.data[i])&nbsp;&nbsp; insert(T,2*i+1,key);</P>
<P style="TEXT-INDENT: 2em">&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;/*在右子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">BST create(int *crew,int num)&nbsp; &nbsp;/*创建二插排序树的函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; BST&nbsp;&nbsp; T;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; i,j;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; T.data=(int *)malloc(N*sizeof(int)); /*数组初始化*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for(j=0;j&lt;N;j++)&nbsp;&nbsp;&nbsp; T.data[j]=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; T.lenth=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for(i=0;i&lt;num;i++)&nbsp;&nbsp; /*边查找边插入建立二插排序树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert(T,1,crew[i]);&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++T.lenth;&nbsp;&nbsp;&nbsp; /*记录树中结点的个数*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return (T);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">inordertraverse(BST T,int i)&nbsp; /*中序遍历*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(T.data[i])</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inordertraverse(T,2*i); /*中序遍历根的左子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d&nbsp; ",T.data[i]);/*输出根结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inordertraverse(T,2*i+1);/*中序遍历根的右子树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">computeASL(BST T,int i,int *s,int j)/*计算平均查找长度*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(T.data[i]){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j++;&nbsp; /*j记录当前结点的在当前树中的深度*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *s=*s+j;&nbsp; /*s记录已遍历过的点的深度之和*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(computeASL(T,2*i,s,j))</P>
<P style="TEXT-INDENT: 2em">/*计算左子树的ASL*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(computeASL(T,2*i+1,s,j))</P>
<P style="TEXT-INDENT: 2em">/*计算右子树的ASL*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {j--; return(1);}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; return(1);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">int search(BST T,int key,int i)/*查找函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(!T.data[i])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0); /*查找不成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(key==T.data[i])&nbsp;&nbsp; return(i);/*查找成功*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; if(key&lt;T.data[i])&nbsp;&nbsp; search(T,key,2*i);</P>
<P style="TEXT-INDENT: 2em">&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;/*在左子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; search(T,key,2*i+1); /*在右子树中继续查找*/</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">BST delete(BST T,int key)&nbsp; /*删除函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; BST&nbsp;&nbsp; Q;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; i;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; Q.data=(int *)malloc(N*sizeof(int)); /*重新初始化一个数组Q*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for(i=0;i&lt;N;i++)&nbsp;&nbsp;&nbsp; Q.data[i]=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; Q.lenth=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for(i=1;i&lt;N&amp;&amp;T.lenth&gt;0;i++)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*T中不为要删结点的元素全部复制到Q*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(T.data[i]==0||T.data[i]==key) continue;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert(Q,1,T.data[i]);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --T.lenth;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++Q.lenth;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return(Q);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">int balance(BST T,int i,int *j)</P>
<P style="TEXT-INDENT: 2em">/*判断是否为平衡二叉树的函数*/</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; dep1,dep2;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(!T.data[i])&nbsp; return(0);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dep1= balance(T,2*i,j);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dep2= balance(T,2*i+1,j);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if((dep1-dep2)&gt;1||(dep1-dep2)&lt;-1) *j=dep1-dep2;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*用j值记录是否存在不平衡现象*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(dep1&gt;dep2) return(dep1+1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; return(dep2+1);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">main()</P>
<P style="TEXT-INDENT: 2em">{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; BST&nbsp;&nbsp; T;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; crew[N];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; i=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; num,ch=0,j;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("please input a list of numbers end with zero:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; do{</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;num);</P>
<P style="TEXT-INDENT: 2em">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!num)&nbsp;&nbsp;&nbsp; printf("you have finished your input!\n");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; { crew[i]=num;&nbsp; i++;}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }while(num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; T=create(crew,i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n\n---the menu of the opperation---\n");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*主程序菜单*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 0:&nbsp; exit" );</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n &nbsp;1:&nbsp; inorder travel the tree");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 2:&nbsp; the average search length for the tree");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 3:&nbsp; delete");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; printf("\n&nbsp; 4:&nbsp; judge the balance");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; while(ch==ch)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n&nbsp;&nbsp; choose the opperation to continue:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;ch);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(ch){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:&nbsp;&nbsp; exit(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*0－－退出*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:&nbsp;&nbsp; printf("&nbsp;&nbsp; The result of the inorder traverse is:\n&nbsp;&nbsp; ");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inordertraverse(T,1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;/*1－－中序遍历*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 2:&nbsp;&nbsp; j=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; computeASL(T,1,&amp;j,0);&nbsp; </P>
<P style="TEXT-INDENT: 2em">/*2－－计算平均查找长度*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; ASL=%d/%d",j,i);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 3:&nbsp;&nbsp; printf("&nbsp;&nbsp; please input the number you want to delete:");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d",&amp;num);&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;/*3－－删除某个结点*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j=search(T,num,1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(j)</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T=delete(T,num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; You have delete the number successfully!\n&nbsp;&nbsp; ");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inordertraverse(T,1);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i--;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp; printf("&nbsp;&nbsp; no node %d you want to delete!",num);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 4:&nbsp;&nbsp; num=0;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; balance(T,1,&amp;num); </P>
<P style="TEXT-INDENT: 2em">/*判断是否为平衡二插树*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(num==0)&nbsp;&nbsp; printf("&nbsp;&nbsp; OK!The tree is a balance tree!");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp; printf("&nbsp;&nbsp; NO!The tree isn't a balance tree!");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:&nbsp; printf("Your input is wrong!please input again!\n");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; /*输入无效字符*/</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">}</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008480333479</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008480333479</guid>
    <pubDate>Thu, 8 May 2008 12:33:34 +0800</pubDate>
    <dcterms:modified>2008-05-08T12:33:34+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Kriging 算法实现 2维和3维地图等高线]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008480261769</link>
    <description><![CDATA[<div>A year and a half year ago, I published this article to the Codeguru site and got a number of requests about the Kriging algorithm contour map. Unfortunately, my project was changed shortly after that article and later I quit the company so I couldn‘t find time to finish this Contour business. A week ago, I happened to need a contour map again so I decided to solve the Kriging algorithm. I searched the Internet for a commercial library but they all look ugly and hard to use. So, I made up my mind to make my own algorithm. The Kriging algorithm is easy to find, but this algorithm needs a Matrix and solver (LU-Decomposition). Again, I couldn‘t find suitable code for this. I tried to use GSL first but this made my code too big and was slower. Finally, I went back to &amp;quot;Numerical Recipe in C&amp;quot;—yes, that horrible-looking C code—and changed the code there to my taste.<BR><BR>If you read this article before, the rendering part hasn‘t been changed much. I added the Kriging algorithm and revised the codes a little bit. Following is the Kriging Algorithm:<BR><BR>template&amp;lt;class ForwardIterator&amp;gt;<BR>double GetDistance(const ForwardIterator start, int i, int j)<BR>{<BR>&nbsp;&nbsp;return ::sqrt(::pow(((*(start+i)).x - (*(start+j)).x), 2) +<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ::pow(((*(start+i)).y - (*(start+j)).y), 2));<BR>}<BR><BR>template&amp;lt;class ForwardIterator&amp;gt;<BR>double GetDistance(double xpos, double ypos,<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; const ForwardIterator start, int i)<BR>{<BR>&nbsp;&nbsp;return ::sqrt(::pow(((*(start+i)).x - xpos), 2) +<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ::pow(((*(start+i)).y - ypos), 2));<BR>}<BR><BR>template&amp;lt;class T, class ForwardIterator&amp;gt;<BR>class TKriging : public TInterpolater&amp;lt;ForwardIterator&amp;gt;<BR>{<BR>public:<BR>&nbsp;&nbsp;TKriging(const ForwardIterator first, const ForwardIterator last,<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;double dSemivariance) : m_dSemivariance(dSemivariance)<BR>&nbsp;&nbsp;{<BR>&nbsp; &nbsp; m_nSize = 0;<BR>&nbsp; &nbsp; ForwardIterator start = first;<BR>&nbsp; &nbsp; while(start != last) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;++m_nSize;<BR>&nbsp; &nbsp;&nbsp; &nbsp;++start;<BR>&nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; m_matA.SetDimension(m_nSize, m_nSize);<BR><BR>&nbsp; &nbsp; for(int j=0; j&amp;lt;m_nSize; j++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int i=0; i&amp;lt;m_nSize; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if(i == m_nSize-1 || j == m_nSize-1) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; m_matA(i, j) = 1;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if(i == m_nSize-1 &amp;amp;&amp;amp; j == m_nSize-1)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;m_matA(i, j) = 0;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; continue;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;m_matA(i, j) = ::GetDistance(first, i, j) * dSemivariance;<BR>&nbsp; &nbsp;&nbsp; &nbsp;}<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; int nD;<BR>&nbsp; &nbsp; LUDecompose(m_matA, m_Permutation, nD);<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;double GetInterpolatedZ(double xpos, double ypos,<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ForwardIterator first,<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ForwardIterator last)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;throw(InterpolaterException)<BR>&nbsp;&nbsp;{<BR>&nbsp; &nbsp; std::vector&amp;lt;T&amp;gt; vecB(m_nSize);<BR>&nbsp; &nbsp; for(int i=0; i&amp;lt;m_nSize; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;double dist = ::GetDistance(xpos, ypos, first, i);<BR>&nbsp; &nbsp;&nbsp; &nbsp;vecB[i] = dist * m_dSemivariance;<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; vecB[m_nSize-1] = 1;<BR><BR>&nbsp; &nbsp; LUBackSub(m_matA, m_Permutation, vecB);<BR><BR>&nbsp; &nbsp; double z = 0;<BR>&nbsp; &nbsp; for(i=0; i&amp;lt;m_nSize-1; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;double inputz = (*(first+i)).z;<BR>&nbsp; &nbsp;&nbsp; &nbsp;z += vecB[i] * inputz;<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; if(z &amp;lt; 0)<BR>&nbsp; &nbsp;&nbsp; &nbsp;z = 0;<BR>&nbsp; &nbsp; return z;<BR>&nbsp;&nbsp;}<BR>private:<BR>&nbsp;&nbsp;TMatrix&amp;lt;T&amp;gt; m_matA;<BR>&nbsp;&nbsp;vector&amp;lt;int&amp;gt; m_Permutation;<BR>&nbsp;&nbsp;int m_nSize;<BR>&nbsp;&nbsp;double m_dSemivariance;<BR>};<BR><BR>typedef TKriging&amp;lt;double, Point3D*&amp;gt; Kriging;<BR><BR>Because of the template, this doesn‘t look that clean but you can get the idea if you look at it carefully. The matrix solver is as follows:<BR><BR>template&amp;lt;class T&amp;gt;<BR>void LUDecompose(TMatrix&amp;lt;T&amp;gt;&amp;amp; A, std::vector&amp;lt;int&amp;gt;&amp;amp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Permutation, int&amp;amp; d) throw(NumericException)<BR>{<BR>&nbsp;&nbsp;int n = A.GetHeight();<BR>&nbsp;&nbsp;vector&amp;lt;T&amp;gt; vv(n);<BR>&nbsp;&nbsp;Permutation.resize(n);<BR><BR>&nbsp;&nbsp;d=1;<BR><BR>&nbsp;&nbsp;T amax;<BR>&nbsp;&nbsp;for(int i=0; i&amp;lt;n; i++) {<BR>&nbsp; &nbsp; amax = 0.0;<BR>&nbsp; &nbsp; for(int j=0; j&amp;lt;n; j++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;if(fabs(A(i, j)) &amp;gt; amax)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;amax = fabs(A(i, j));<BR><BR>&nbsp; &nbsp; if(amax &amp;lt; TINY_VALUE)<BR>&nbsp; &nbsp;&nbsp; &nbsp;throw NumericException();<BR><BR>&nbsp; &nbsp; vv[i] = 1.0 / amax;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;T sum, dum;<BR>&nbsp;&nbsp;int imax;<BR>&nbsp;&nbsp;for(int j=0; j&amp;lt;n; j++) {<BR>&nbsp; &nbsp; for (i=0; i&amp;lt;j; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;sum = A(i, j);<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int k=0; k&amp;lt;i; k++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;sum -= A(i, k) * A(k, j);<BR>&nbsp; &nbsp;&nbsp; &nbsp;A(i, j) = sum;<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; amax = 0.0;<BR><BR>&nbsp; &nbsp; for(i=j; i&amp;lt;n; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;sum = A(i, j);<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int k=0; k&amp;lt;j; k++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;sum -= A(i, k) * A(k, j);<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;A(i, j) = sum;<BR>&nbsp; &nbsp;&nbsp; &nbsp;dum = vv[i] * fabs(sum);<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;if(dum &amp;gt;= amax) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;imax = i;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;amax = dum;<BR>&nbsp; &nbsp;&nbsp; &nbsp;}<BR>&nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; if(j != imax) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int k=0; k&amp;lt;n; k++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;dum = A(imax, k);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;A(imax, k) = A(j, k);<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;A(j, k) = dum;<BR>&nbsp; &nbsp;&nbsp; &nbsp;}<BR>&nbsp; &nbsp;&nbsp; &nbsp;d = -d;<BR>&nbsp; &nbsp;&nbsp; &nbsp;vv[imax] = vv[j];<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; Permutation[j] = imax;<BR><BR>&nbsp; &nbsp; if(fabs(A(j, j)) &amp;lt; TINY_VALUE)<BR>&nbsp; &nbsp;&nbsp; &nbsp;A(j, j) = TINY_VALUE;<BR><BR>&nbsp; &nbsp; if(j != n) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;dum = 1.0 / A(j, j);<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(i=j+1; i&amp;lt;n; i++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;A(i, j) *= dum;<BR>&nbsp; &nbsp; }<BR>&nbsp;&nbsp;}<BR>}<BR><BR>template&amp;lt;class T&amp;gt;<BR>void LUBackSub(TMatrix&amp;lt;T&amp;gt;&amp;amp; A, std::vector&amp;lt;int&amp;gt;&amp;amp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;Permutation, std::vector&amp;lt;T&amp;gt;&amp;amp; B)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;throw(NumericException)<BR>{<BR>&nbsp;&nbsp;int n = A.GetHeight();<BR>&nbsp;&nbsp;T sum;<BR>&nbsp;&nbsp;int ii = 0;<BR>&nbsp;&nbsp;int ll;<BR>&nbsp;&nbsp;for(int i=0; i&amp;lt;n; i++) {<BR>&nbsp; &nbsp; ll = Permutation[i];<BR>&nbsp; &nbsp; sum = B[ll];<BR>&nbsp; &nbsp; B[ll] = B[i];<BR>&nbsp; &nbsp; if(ii != 0)<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int j=ii; j&amp;lt;i; j++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;sum -= A(i, j) * B[j];<BR>&nbsp; &nbsp; else if(sum != 0.0)<BR>&nbsp; &nbsp;&nbsp; &nbsp;ii = i;<BR>&nbsp; &nbsp; B[i] = sum;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;for(i=n-1; i&amp;gt;=0; i--) {<BR>&nbsp; &nbsp; sum = B[i];<BR>&nbsp; &nbsp; if(i&amp;lt; n) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;for(int j=i+1; j&amp;lt;n; j++)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;sum -= A(i, j) * B[j];<BR>&nbsp; &nbsp; }<BR>&nbsp; &nbsp; B[i] = sum / A(i, i);<BR>&nbsp;&nbsp;}<BR>}<BR><BR>By using this algorithm, making a 3D grid is easy. Let‘s assume we‘re making a 200x200 grid and we have some scattered data. Then, what we need to do is this:<BR><BR>&nbsp;&nbsp;vector&amp;lt;Point3D&amp;gt; input&nbsp; &nbsp; // assume this vector has KNOWN 3D points<BR><BR>&nbsp;&nbsp;Interpolater* pInterpolater = new Kriging(input.begin(),<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;input.end(), 4);<BR><BR>&nbsp;&nbsp;vector&amp;lt;double&amp;gt; vecZs;<BR><BR>&nbsp;&nbsp;for(int j=0; j&amp;lt;200; j++) {<BR>&nbsp; &nbsp; for(int i=0; i&amp;lt;200; i++) {<BR>&nbsp; &nbsp;&nbsp; &nbsp;vecZs.push_back(pInterpolater-&amp;gt;GetInterpolatedZ(i, j,<BR>&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;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;input.begin(),<BR>&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;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;input.end()));<BR>&nbsp; &nbsp; }<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;// Now, vecZs has 40000 z values<BR><BR>&nbsp;&nbsp;delete pInterpolater;<BR><BR>If you have all the grid points with 3D data, you can make a bitmap file with it, or make a triangle strip to render with OpenGL. If you remember that the old contour map was produced from an InverseDistanced algorithm (you can switch to Inverse Distance in the Option menu), you‘ll find a vast improvement over it. I compared the Kriging generated contour map with some commercial programs, and they were almost identical. I hope this helps programmers who want to make a contour map.</div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008480261769</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008480261769</guid>
    <pubDate>Thu, 8 May 2008 12:26:01 +0800</pubDate>
    <dcterms:modified>2008-05-08T12:26:01+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[使用OpenGL实现三维坐标的鼠标拣选]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008457757990</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本文提出并实现一种用于三维坐标拣选的RIP（Ray-Intersection-Penetration）方法。介绍了如何在已经渲染至窗口的三维场景中，使用鼠标或者相关设备拣选特定三维对象的方法。此方法对于正交投影或透视投影均有效，相对于OpenGL自带的选择与反馈机制，本方法无论是拣选精度还是算法实现效率均高出许多，是一种比较通用的解决方案。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">关键词（Keywords）</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正交投影（Ortho-Projection）、透视投影（Perspective-Projection）</P>
<P style="TEXT-INDENT: 2em">世界坐标系、屏幕坐标系、三维拣选、OpenGL </P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">一、简介（Introduction）</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenGL是一种比较“纯粹”的3D图形API，一般仅用于三维图形的渲染，对于特定领域的开发者（如游戏开发者）而言，如果选择使用 OpenGL进行开发，类似碰撞检测的机制就都需要自行编写了。但是由于鼠标在图形程序中的应用非常非常之广泛（例如现在已经很少有PC游戏能完全地脱离鼠标），OpenGL在图形库的基础上添加了选择与反馈机制（Select &amp; Feedback）来满足用户使用鼠标实时操作三维图形的需要。但由于种种原因，我们需要更为特殊的选择机制以满足特定需求，在这里我们提出了一种简单迅速的RIP（Ray-Intersection-Penetration）方法，可以满足绝大多数典型应用的需要。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">二、相关研究（Related Work）</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用过OpenGL选择与反馈机制的开发者，或多或少可能都会觉得它难以令人满意。大致表现在下面几个方面：</P>
<P style="TEXT-INDENT: 2em">一、编写程序比较繁琐。</P>
<P style="TEXT-INDENT: 2em">想要使用选择反馈机制就需要切换渲染模式，操作命名堆栈，计算拣选矩阵，检查选中记录，这些繁琐的步骤很容易出错，而且非常不便于调试，只会降低工作效率和热情。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">二、只能做基于图元的选定。</P>
<P style="TEXT-INDENT: 2em">如下图（1 - a），使用GL_TRIANGLES绘制了一个三角形，三个顶点分别为 P1、P2和P3。若使用该机制，你将只能判断是否在三维场景中选中了这个三角形（用户点击处是否在P1、P2和P3的范围内），而无法判断用户是点击了这个三角形哪一部分（是左边的m区域内还是右边的n区域内），因为所绘制的P1、P2和P3本身构成的三角形就是一个基本图元，对于拣选机制而言是不可分的。当然，把这个三角形拆成两个三角形再分别进行测试也是一个可行的方案，可是看看图（1 - b），这可怎么拆呢？还有图（1 – c）呢？另外，如果n和m两个平面不共面呢？对于使用者而言，OpenGL提供的拣选机制功能的确有限。</P>
<P style="TEXT-INDENT: 2em">&nbsp;
</P><P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
</P><P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 三、降低了渲染效率。</P>
<P style="TEXT-INDENT: 2em">OpenGL中的选择和反馈是与普通渲染方式不同的一种特殊的渲染方式。我们使用时一般是先在帧缓存中渲染普通场景，然后进入选择模式重绘场景，此时帧缓存的内容并无变化。也就是说，为了选择某些物体，我们需要在一帧中使用不同的渲染方式将其渲染两遍。我们知道对对象进行渲染是比较耗时的操作，当场景中需要选择的对象多而杂的时候，采用这个机制是非常影响速度的。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外在OpenGL红宝书中介绍了一种简便易行的办法：在后缓冲中使用不同的颜色重绘所有对象，每个对象用一个单色来标示其颜色，这样画好之后我们读取鼠标所在点的颜色，就能够确定我们拣选了哪个物体。这种方法有一个缺陷，当场景中需要选择的对象的数目超出一定限度时，可能会出现标识数的溢出。对于这个问题，红宝书给出的解决办法就是多次扫描。实践证明这种方法的确简便易行，但仍有不少局限性，而且做起来并不比第一种机制方便多少。限于篇幅，不再赘述。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">三、具体描述（Related Work）</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看过了上面两种方法，我们会发现这两种方法都不是十分的方便，而且使用者不能对其进行完全的控制，不能精确地判定鼠标定位与实际的世界空间中三维坐标的关系。那么有什么更好的办法能够更简单更精确地对其加以控制呢？</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际上此处给出的解决方案十分简单，就是一个很普通也很有用的 GLU 函数 gluUnProject()。</P>
<P style="TEXT-INDENT: 2em">此函数的具体用途是将一个OpenGL视区内的二维点转换为与其对应的场景中的三维坐标。</P>
<P style="TEXT-INDENT: 2em">转换过程如下图所示（由点P在窗口中的XY坐标得到其在三维空间中的世界坐标）：</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个函数在glu.h中的原型定义如下：</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">int APIENTRY gluUnProject (</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; winx, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; winy, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; winz, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; const GLdouble modelMatrix[16], </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; const GLdouble projMatrix[16], </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; const GLint&nbsp;&nbsp;&nbsp; viewport[4], </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *objx, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *objy, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *objz);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">其中前三个值表示窗口坐标，中间三个分别为模型视图矩阵（Model/View Matrix），投影矩阵（Projection Matrix）和视区（ViewPort），最后三个为输出的世界坐标值。</P>
<P style="TEXT-INDENT: 2em">可能你会问：窗口坐标不是只有X轴和Y轴两个值么，怎么这里还有Z值？这就要从二维空间与三维空间的关系说起了。</P>
<P style="TEXT-INDENT: 2em">众所周知，我们通过一个放置在三维世界中的摄像机，来观察当前场景中的对象。通过使用诸如gluPerspective() 这样的OpenGL函数，我们可以设置这个摄像机所能看到的视野的大小范围。这个视野的边界所围成的几何体是一个标准的平截头体（Frustum），可以看做是金字塔状的几何体削去金字塔的上半部分后形成的一个台状物，如果还原成金字塔状，就得到了通常我们所说的视锥（View Frustum）这个视锥的锥顶就是视点（View Point）也就是摄像机所在的位置。平截头体，视锥以及视点之间的关系，如下图所示：</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">在上面的图中，远裁剪面ABCD和近裁剪面A’B’C’D’构成了平截头体，加上虚线部分就是视锥，顶点O就是摄像机所在的视点。我们在窗口中所能看到的东东，全部都在此平截头体内。这跟前面的窗口坐标Z值有什么关系呢？看下图：</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">如此图所示，点P和点P’分别在远裁剪面ABCD和近裁剪面A’B’C’D’上。我们点击屏幕上的点P，反映到视锥中，就是选中了所有的从点P到点P’的点。举个形象的例子，这就像是我们挽弓放箭，如果射出去的箭近乎笔直地飞出（假设力量非常之大近乎无穷），从挽弓的地点直至击中目标，在这条直线的轨迹上任何物体都将被一穿而过。对应这里的情况，用户单击鼠标获得屏幕上的某一点，即是指定了从视点指向屏幕深处的某一方向，也就确定了屏幕上某条从O点出发的射线（在图中即为OP）。在这里，我们称呼其为拣选射线。</P>
<P style="TEXT-INDENT: 2em">因此，从窗口的XY坐标，我们仅仅只能获得一条出发自O点的拣选射线，并不能得到用户想要的点在这条射线上的确切位置。</P>
<P style="TEXT-INDENT: 2em">这时候窗口坐标的Z值就能派上用场了。我们通过Z值，来指定我们想要的点在射线上的位置。假如用户点击了屏幕上的点（100,100）得到了这条射线OP，那么我们传入值1.0f就表示近裁剪面上的P点，而值0.0f则对应远裁剪面上的P’点。</P>
<P style="TEXT-INDENT: 2em">这样，我们通过引入一个窗口坐标的Z值，就能指定视锥内任意点的三维坐标。与此同时，我们还解决了前面红宝书给出的方法中存在的缺陷——同一位置上重叠物体的选择问题。解决办法是：从屏幕坐标得到射线之后，分别让重叠的物体与该射线求交，得到的交点，然后根据这些与视点的远近确定选择的对象。如此我们就不必受“仅仅只能选取屏幕中离观察者最近的物体”的限制了。这样一来，如果需要的话，我们甚至可以用代码来作一定的限定，通过判断交点与视点的距离，使得与该拣选射线相交的物体中，离视点远的对象才能被选取，这样就能够对那些暂时被其他对象遮住的物体进行选取。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 至于如何求拣选射线与对象的交点，在各种图形学的书中的数学部分均有讲述，在此不再赘述。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">四、例程（Sample Code Fragment）</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 前面讲述了RIP方法，现在我们来看如何编写代码以实现之，以及一些需要注意的问题。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于拣选射线以线段形式存储更加便于后面的计算，况且我们可以直接得到纵跨整个平截头体的线段（即前面图中的线段PP’），故我们直接计算出这条连接远近裁剪面的线段。我们将拣选射线的线段形式称之为拣选线段。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在下面的代码前方声明有两个类Point3f和LineSegment这分别表示由三个浮点数构成的三维空间中的点，以及由两个点构成的空间中的一条线段。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应注意代码中用到了类Point3f的一个需要三个浮点参数的构造函数，以及类LineSegment的一个需要两个点参数的构造函数。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 获取拣选射线的例程如下所示（使用C++语言编写）：<S></S></P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">class Point3f;</P>
<P style="TEXT-INDENT: 2em">class LineSegment;</P>
<P style="TEXT-INDENT: 2em">LineSegment GetSelectionRay(int mouse_x, int mouse_y) {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; // 获取 Model-View、Projection 矩阵 &amp; 获取Viewport视区</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp; modelview[16];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble&nbsp;&nbsp;&nbsp; projection[16];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewport[4];</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; glGetDoublev (GL_MODELVIEW_MATRIX, modelview);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; glGetDoublev (GL_PROJECTION_MATRIX, projection);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; glGetIntegerv (GL_VIEWPORT, viewport);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; GLdouble world_x, world_y, world_z;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; // 获取近裁剪面上的交点</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y, 0.0, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;modelview, projection, viewport, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;world_x, &amp;world_y, &amp;world_z); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; Point3f near_point(world_x, world_y, world_z);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; // 获取远裁剪面上的交点</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y, 1.0, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; modelview, projection, viewport, </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;world_x, &amp;world_y, &amp;world_z); </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; Point3f far_point(world_x, world_y, world_z);</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; return LineSegment(near_point, far_point);</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你是使用Win32平台进行开发，那么应当注意传入正确的参数。因为无论是使用Win32 API 还是DirectInput 来获取鼠标坐标，得到的Y值都应取反后再传入。因为OpenGL默认的原点在视区的左下角，Y轴从左下角指向左上角，而Windows默认的原点在窗口的左上角，而Y轴方向与OpenGL相反，从左上角指向左下角。如下图所示：</P>
<P style="TEXT-INDENT: 2em">
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">0</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">X</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">Win32 默认窗口坐标样式</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">OpenGL 默认窗口坐标样式</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">0</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">X</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">Y</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">Y</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">我们可以看到代码被注释分为了三个部分：获取当前矩阵及视区，获取近裁剪面的交点，获取远裁剪面的交点。</P>
<P style="TEXT-INDENT: 2em">我们通过OpenGL提供的查询函数轻松得到当前的ModelView和Projection矩阵，以及当前的Viewport（视区，也就是窗口的客户端区域，如果整个窗口区域用于OpenGL渲染的话）。</P>
<P style="TEXT-INDENT: 2em">获得两个裁剪面上的交点的代码基本上是一样的，唯一的不同点是我们前面曾经详细地讨论过的窗口的Z坐标。不错，这个坐标表示的就是“深浅”的概念。它的值从点P’到点P的变化是从0.0f逐渐增至1.0f。此处类似于OpenGL的深度测试机制。</P>
<P style="TEXT-INDENT: 2em">在得到两个交点之后，我们使用它们通过返回语句直接构建一条线段。在这里仅仅作为实例代码，故简捷清晰地直接返回线段对象，而没有通过引用参数来提高效率。</P>
<P style="TEXT-INDENT: 2em">此时用户可以使用这个函数来判断所选择的对象了。只需在需要的地方判断对象是否与此线段相交即可判断对象是否被选中，还可以通过进一步计算其交点位置来得到详细的交点信息。这些计算均是常见的计算机图形学与三维数学计算，比如线段与三角形求交，线段与面求交，线段与球体求交，线段与柱体或锥体求交，等等。请参考所列出的计算机图形学书籍。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">五、结论（Conclusion）</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在本文中，我们介绍了一种行之有效的三维坐标拾取方法，主要使用GLU库中的实用工具实现。这种方法速度快，效率高，能在不必重新绘制对象的前提下完成拣选工作。对比OpenGL自带的拣选机制来看，RIP的确在各种方面均有一定的优势。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">六、参考文献（Reference）</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 【1】《OpenGL Programming Guide》</P>
<P style="TEXT-INDENT: 2em"><I>OpenGL ARB&nbsp; Mason Woo, Jackie Heider, Tom Davis, Dave Shreiner</I></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 【2】《OpenGL Reference Manual》</P>
<P style="TEXT-INDENT: 2em"><I>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenGL ARB</I></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 【3】《Computer Graphics》</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <I>Donald Heam, M. Pauline Baker</I></P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 【4】《Computer Graphics using OpenGL 2nd Edition》</P>
<P style="TEXT-INDENT: 2em"><I>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F.S. Hill, JR.</I></P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008457757990</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008457757990</guid>
    <pubDate>Mon, 5 May 2008 19:07:57 +0800</pubDate>
    <dcterms:modified>2008-05-05T19:09:29+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[基于VC++的OpenGL编程讲座之坐标变换]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/430366012008456551961</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em"></P>
<P style="TEXT-INDENT: 2em"><A href="http://www.yesky.com/key/4543/134543.html">OpenGL</A>通过相机模拟、可以实现计算机图形学中最基本的三维变换，即几何变换、投影变换、裁剪变换、视口变换等，同时，OpenGL还实现了矩阵堆栈等。理解掌握了有关坐标变换的内容，就算真正走进了精彩地三维世界。</P>
<P style="TEXT-INDENT: 2em">　　一、OpenGL中的三维物体的显示</P>
<P style="TEXT-INDENT: 2em">　　（一）坐标系统</P>
<P style="TEXT-INDENT: 2em">　　在现实世界中，所有的物体都具有三维特征，但计算机本身只能处理数字，显示二维的图形，将三维物体及二维数据联系在一起的唯一纽带就是坐标。</P>
<P style="TEXT-INDENT: 2em">　　为了使被显示的三维物体数字化，要在被显示的物体所在的空间中定义一个坐标系。这个坐标系的长度单位和坐标轴的方向要适合对被显示物体的描述，这个坐标系称为世界坐标系。世界坐标系是始终固定不变的。</P>
<P style="TEXT-INDENT: 2em">　　OpenGL还定义了局部坐标系的概念，所谓局部坐标系，也就是坐标系以物体的中心为坐标原点，物体的旋转或平移等操作都是围绕局部坐标系进行的，这时，当物体模型进行旋转或平移等操作时，局部坐标系也执行相应的旋转或平移操作。需要注意的是，如果对物体模型进行缩放操作，则局部坐标系也要进行相应的缩放，如果缩放比例在案各坐标轴上不同，那么再经过旋转操作后，局部坐标轴之间可能不再相互垂直。无论是在世界坐标系中进行转换还是在局部坐标系中进行转换，程序代码是相同的，只是不同的坐标系考虑的转换方式不同罢了。</P>
<P style="TEXT-INDENT: 2em">　　计算机对数字化的显示物体作了加工处理后，要在图形显示器上显示，这就要在图形显示器屏幕上定义一个二维直角坐标系，这个坐标系称为屏幕坐标系。这个坐标系坐标轴的方向通常取成平行于屏幕的边缘，坐标原点取在左下角，长度单位常取成一个象素。</P>
<P style="TEXT-INDENT: 2em">　　（二）三维物体的相机模拟</P>
<P style="TEXT-INDENT: 2em">　　为了说明在三维物体到二维图象之间，需要经过什么样的变换，我们引入了相机（<A href="http://www.yesky.com/key/1478/126478.html">Camera</A>）模拟的方式，假定用相机来拍摄这个世界，那么在相机的取景器中，就存在人眼和现实世界之间的一个变换过程。</P>
<P style="TEXT-INDENT: 2em">　　 </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/w60a0088i390.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">　　图一、相机模拟OpenGL中的各种坐标变换</P>
<P style="TEXT-INDENT: 2em">　　从三维物体到二维图象，就如同用相机拍照一样，通常都要经历以下几个步骤：</P>
<P style="TEXT-INDENT: 2em">　　1、将相机置于三<A href="http://www.yesky.com/key/3035/78035.html">角架</A>上，让它对准三维景物，它相当于OpenGL中调整视点的位置，即视点变换（Viewing Transformation）。</P>
<P style="TEXT-INDENT: 2em">　　2、将三维物体放在场景中的适当位置，它相当于OpenGL中的模型变换（Modeling Transformation），即对模型进行旋转、平移和缩放。</P>
<P style="TEXT-INDENT: 2em">　　3、选择相机镜头并调焦，使三维物体投影在二维胶片上，它相当于OpenGL中把三维模型投影到二维屏幕上的过程，即OpenGL的投影变换（Projection Transformation），OpenGL中投影的方法有两种，即正射投影和透视投影。为了使显示的物体能以合适的位置、大小和方向显示出来，必须要通过投影。有时为了突出图形的一部分，只把图形的某一部分显示出来，这时可以定义一个三维视景体（Viewing <A href="http://www.yesky.com/key/3724/98724.html">Volume</A>）。正射投影时一般是一个长方体的视景体，透视投影时一般是一个棱台似的视景体。只有视景体内的物体能被投影在显示平面上，其他部分则不能。</P>
<P style="TEXT-INDENT: 2em">　　4、冲洗<A href="http://www.yesky.com/key/2990/87990.html">底片</A>，决定二维相片的大小，它相当与OpenGL中的视口变换（Viewport Transformation）（在屏幕窗口内可以定义一个矩形，称为视口（Viewport），视景体投影后的图形就在视口内显示）规定屏幕上显示场景的范围和尺寸。</P>
<P style="TEXT-INDENT: 2em">　　通过上面的几个步骤，一个三维空间里的物体就可以用相应的二维平面物体表示了，也就能在二维的电脑屏幕上正确显示了。总的来说，三维物体的显示过程如下：</P>
<P style="TEXT-INDENT: 2em">　　 </P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/i35e8vt13ih1.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">　　图二、三维物体的显示过程</P>
<P style="TEXT-INDENT: 2em">二、OpenGL中的几种变换</P>
<P style="TEXT-INDENT: 2em">　　OpenGL中的各种转换是通过矩阵运算实现的，具体的说，就是当发出一个转换命令时，该命令会生成一个4X4阶的转换矩阵（OpenGL中的物体坐标一律采用齐次坐标，即(x, y, z, w)，故所有变换矩阵都采用4X4矩阵），当前矩阵与这个转换矩阵相乘，从而生成新的当前矩阵。例如，对于顶点坐标v ，转换命令通常在顶点坐标命令之前发出，若当前矩阵为C，转换命令构成的矩阵为M，则发出转换命令后，生成的新的当前矩阵为CM，这个矩阵再乘以顶点坐标v，从而构成新的顶点坐标CMv。上述过程说明，程序中绘制顶点前的最后一个变换命令最先作用于顶点之上。这同时也说明，OpenGL编程中，实际的变换顺序与指定的顺序是相反的。</P>
<P style="TEXT-INDENT: 2em">　　（一）视点变换</P>
<P style="TEXT-INDENT: 2em">　　视点变换确定了场景中物体的视点位置和方向，就向上边提到的，它象是在场景中放置了一架照相机，让相机对准要拍摄的物体。确省时，相机（即视点）定位在坐标系的原点（相机初始方向都指向Z负轴），它同物体模型的缺省位置是一致的，显然，如果不进行视点变换，相机和物体是重叠在一起的。</P>
<P style="TEXT-INDENT: 2em">　　执行视点变换的命令和执行模型转换的命令是相同的，想一想，在用相机拍摄物体时，我们可以保持物体的位置不动，而将相机移离物体，这就相当于视点变换；另外，我们也可以保持相机的固定位置，将物体移离相机，这就相当于模型转换。这样，在OpenGL中，以逆时针旋转物体就相当于以顺时针旋转相机。因此，我们必须把视点转换和模型转换结合在一起考虑，而对这两种转换单独进行考虑是毫无意义的。</P>
<P style="TEXT-INDENT: 2em">除了用模型转换命令执行视点转换之外，OpenGL实用库还提供了gluLookAt()函数，该函数有三个变量，分别定义了视点的位置、相机瞄准方向的参考点以及相机的向上方向。该函数的原型为：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble upx,GLdouble upy,GLdouble upz);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　该函数定义了视点矩阵，并用该矩阵乘以当前矩阵。eyex,eyey,eyez定义了视点的位置；centerx、centery和centerz变量指定了参考点的位置，该点通常为相机所瞄准的场景中心轴线上的点；upx、upy、upz变量指定了向上向量的方向。</P>
<P style="TEXT-INDENT: 2em">　　通常，视点转换操作在模型转换操作之前发出，以便模型转换先对物体发生作用。场景中物体的顶点经过模型转换之后移动到所希望的位置，然后再对场景进行视点定位等操作。模型转换和视点转换共同构成模型视景矩阵。</P>
<P style="TEXT-INDENT: 2em">　　（二）模型变换</P>
<P style="TEXT-INDENT: 2em">　　模型变换是在世界坐标系中进行的。缺省时，物体模型的中心定位在坐标系的中心处。OpenGL在这个坐标系中，有三个命令，可以模型变换。</P>
<P style="TEXT-INDENT: 2em">　　1、模型平移</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>glTranslate{fd}(TYPE x,TYPE y,TYPE z);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　该函数用指定的x,y,z值沿着x轴、y轴、z轴平移物体（或按照相同的量值移动局部坐标系）。</P>
<P style="TEXT-INDENT: 2em">　　2、模型旋转 </P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>glRotate{fd}(TYPE angle,TYPE x,TYPE,y,TYPE z);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　该函数中第一个变量angle制定模型旋转的角度，单位为度，后三个变量表示以原点（0,0,0）到点(x,y,z)的连线为轴线逆时针旋转物体。例如，glRotatef(45.0,0.0,0.0,1.0)的结果是绕z轴旋转45度。</P>
<P style="TEXT-INDENT: 2em">　　3、模型缩放</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>glScale{fd}(TYPE x,TYPE y,TYPE z);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　该函数可以对物体沿着x,y,z轴分别进行放大缩小。函数中的三个参数分别是x、y、z轴方向的比例变换因子。缺省时都为1.0，即物体没变化。程序中物体Y轴比例为2.0，其余都为1.0，就是说将立方体变成长方体。</P>
<P style="TEXT-INDENT: 2em">　　（三）投影变换</P>
<P style="TEXT-INDENT: 2em">　　经过模型视景的转换后，场景中的物体放在了所希望的位置上，但由于显示器只能用二维图象显示三维物体，因此就要靠投影来降低维数（投影变换类似于选择相机的镜头）。</P>
<P style="TEXT-INDENT: 2em">　　事实上，投影变换的目的就是定义一个视景体，使得视景体外多余的部分裁剪掉，最终进入图像的只是视景体内的有关部分。投影包括透视投影（Perspective Projection）和正视投影（Orthographic Projection）两种。</P>
<P style="TEXT-INDENT: 2em">　　透视投影，符合人们心理习惯，即离视点近的物体大，离视点远的物体小，远到极点即为消失，成为灭点。它的视景体类似于一个顶部和底部都被进行切割过的棱椎，也就是棱台。这个投影通常用于动画、视觉仿真以及其它许多具有真实性反映的方面。</P>
<P style="TEXT-INDENT: 2em">　　OpenGL透视投影函数有两个，其中函数glFrustum()的原型为：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　它创建一个透视视景体。其操作是创建一个透视投影矩阵，并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标，即（left，bottom，-near）和（right，top，-near）；最后一个参数far是远裁剪平面的Z负值，其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近，它们总为正值。该函数形成的视景体如图三所示。</P>
<P style="TEXT-INDENT: 2em">
<TABLE width="90%" align=center>
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/67lb0ywdfrr7.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">图三、透视投影视景体</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　另一个透视函数是：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　它也创建一个对称透视视景体，但它的参数定义于前面的不同，参数fovy定义视野在X-Z平面的角度，范围是[0.0, 180.0]；参数aspect是投影平面宽度与高度的比率；参数zNear和Far分别是远近裁剪面沿Z负轴到视点的距离，它们总为正值。</P>
<P style="TEXT-INDENT: 2em">
<TABLE width="90%" align=center>
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/75wv4bzp3p07.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">图四、透视投影视景体</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　以上两个函数缺省时，视点都在原点，视线沿Z轴指向负方向。</P>
<P style="TEXT-INDENT: 2em">　　正射投影，又叫平行投影。这种投影的视景体是一个矩形的平行管道，也就是一个长方体，如图五所示。正射投影的最大一个特点是无论物体距离相机多远，投影后的物体大小尺寸不变。这种投影通常用在建筑蓝图绘制和计算机辅助设计等方面，这些行业要求投影后的物体尺寸及相互间的角度不变，以便施工或制造时物体比例大小正确。</P>
<P style="TEXT-INDENT: 2em">
<TABLE width="90%" align=center>
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/66pk3t00292w.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">图五、正射投影视景体</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　OpenGL正射投影函数也有两个，一个函数是：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far)</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　它创建一个平行视景体。实际上这个函数的操作是创建一个正射投影矩阵，并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形，矩形左下角点三维空间坐标是（left，bottom，-near），右上角点是（right，top，-near）；远裁剪平面也是一个矩形，左下角点空间坐标是（left，bottom，-far），右上角点是（right，top，-far）。所有的near和far值同时为正或同时为负。如果没有其他变换，正射投影的方向平行于Z轴，且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值，物体在视点后面时far和near都为正值。</P>
<P style="TEXT-INDENT: 2em">　　另一个函数是：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　它是一个特殊的正射投影函数，主要用于二维图像到二维屏幕上的投影。它的near和far缺省值分别为-1.0和1.0，所有二维物体的Z坐标都为0.0。因此它的裁剪面是一个左下角点为（left，bottom）、右上角点为（right，top）的矩形。
</P><P style="TEXT-INDENT: 2em">（四）视口变换。</P>
<P style="TEXT-INDENT: 2em">　　视口变换就是将视景体内投影的物体显示在二维的视口平面上。运用相机模拟方式，我们很容易理解视口变换就是类似于照片的放大与缩小。在计算机图形学中，它的定义是将经过几何变换、投影变换和裁剪变换后的物体显示于屏幕窗口内指定的区域内，这个区域通常为矩形，称为视口。OpenGL中相关函数是：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>glViewport(GLint x,GLint y,GLsizei width, GLsizei height);</TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　这个函数定义一个视口。函数参数(x, y)是视口在屏幕窗口坐标系中的左下角点坐标，参数width和height分别是视口的宽度和高度。缺省时，参数值即(0, 0, winWidth, winHeight) 指的是屏幕窗口的实际尺寸大小。所有这些值都是以象素为单位，全为整型数。</P>
<P style="TEXT-INDENT: 2em">　　（5）裁剪变换</P>
<P style="TEXT-INDENT: 2em">　　在OpenGL中，除了视景体定义的六个裁剪平面（上、下、左、右、前、后）外，用户还可自己再定义一个或多个附加裁剪平面，以去掉场景中无关的目标，如图六所示。</P>
<P style="TEXT-INDENT: 2em">
<TABLE width="90%" align=center>
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://dev.yesky.com/imagelist/05/09/b790797hb2cq.jpg" border=0></P>
<P style="TEXT-INDENT: 2em">图六、附加裁剪平面</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">　　附加平面裁剪函数为：</P>
<P style="TEXT-INDENT: 2em">　　1、void glClipPlane(GLenum plane,Const GLdouble *equation);</P>
<P style="TEXT-INDENT: 2em">　　函数参数equation指向一个拥有四个系数值的数组，这四个系数分别是裁剪平面Ax+By+Cz+D=0的A、B、C、D值。因此，由这四个系数就能确定一个裁剪平面。参数plane是GL_CLIP_PLANEi(i=0,1,...)，指定裁剪面号。</P>
<P style="TEXT-INDENT: 2em">　　在调用附加裁剪函数之前，必须先启动glEnable(GL_CLIP_PLANEi)，使得当前所定义的裁剪平面有效；当不再调用某个附加裁剪平面时，可用glDisable(GL_CLIP_PLANEi)关闭相应的附加裁剪功能。</P>
<P style="TEXT-INDENT: 2em">　　下面这个例子不仅说明了附加裁剪函数的用法，而且调用了gluPerspective()透视投影函数，读者可以细细体会其中的用法。例程如下：</P>
<P style="TEXT-INDENT: 2em">
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#edeceb border=1>
<TBODY>
<TR>
<TD>　　#include "glos.h"
<P></P>
<P style="TEXT-INDENT: 2em">　　#include &lt;GL/gl.h&gt;</P>
<P style="TEXT-INDENT: 2em">　　#include &lt;GL/glu.h&gt;</P>
<P style="TEXT-INDENT: 2em">　　#include &lt;GL/glaux.h&gt;</P>
<P style="TEXT-INDENT: 2em">　　void myinit(void);</P>
<P style="TEXT-INDENT: 2em">　　void CALLBACK myReshape(GLsizei w, GLsizei h);</P>
<P style="TEXT-INDENT: 2em">　　void CALLBACK display(void);</P>
<P style="TEXT-INDENT: 2em">　　void CALLBACK display(void)</P>
<P style="TEXT-INDENT: 2em">　　{</P>
<P style="TEXT-INDENT: 2em">　　　　GLdouble eqn[4] = {1.0, 0.0, 0.0, 0.0};</P>
<P style="TEXT-INDENT: 2em">　　　　glClear(GL_COLOR_BUFFER_BIT);</P>
<P style="TEXT-INDENT: 2em">　　　　glColor3f (1.0, 0.0, 1.0);</P>
<P style="TEXT-INDENT: 2em">　　　　glPushMatrix();</P>
<P style="TEXT-INDENT: 2em">　　　　glTranslatef (0.0, 0.0, -5.0);</P>
<P style="TEXT-INDENT: 2em">　　　　/* clip the left part of wire_sphere : x&lt;0 */</P>
<P style="TEXT-INDENT: 2em">　　　　glClipPlane (GL_CLIP_PLANE0, eqn);</P>
<P style="TEXT-INDENT: 2em">　　　　glEnable (GL_CLIP_PLANE0);</P>
<P style="TEXT-INDENT: 2em">　　　　glRotatef (-90.0, 1.0, 0.0, 0.0);</P>
<P style="TEXT-INDENT: 2em">　　　　auxWireSphere(1.0);</P>
<P style="TEXT-INDENT: 2em">　　　　glPopMatrix();</P>
<P style="TEXT-INDENT: 2em">　　　　glFlush();</P>
<P style="TEXT-INDENT: 2em">　　}</P>
<P style="TEXT-INDENT: 2em">　　void myinit (void)</P>
<P style="TEXT-INDENT: 2em">　　{</P>
<P style="TEXT-INDENT: 2em">　　　　glShadeModel (GL_FLAT);</P>
<P style="TEXT-INDENT: 2em">　　}</P>
<P style="TEXT-INDENT: 2em">　　void CALLBACK myReshape(GLsizei w, GLsizei h)</P>
<P style="TEXT-INDENT: 2em">　　{</P>
<P style="TEXT-INDENT: 2em">　　　　glViewport(0, 0, w, h);</P>
<P style="TEXT-INDENT: 2em">　　　　glMatrixMode(GL_PROJECTION);</P>
<P style="TEXT-INDENT: 2em">　　　　glLoadIdentity();</P>
<P style="TEXT-INDENT: 2em">　　　&nbsp;&nbsp; gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);</P>
<P style="TEXT-INDENT: 2em">　　　　glMatrixMode(GL_MODELVIEW);</P>
<P style="TEXT-INDENT: 2em">　　} </P>
<P style="TEXT-INDENT: 2em">　　void main(void)</P>
<P style="TEXT-INDENT: 2em">　　{</P>
<P style="TEXT-INDENT: 2em">　　　　auxInitDisplayMode (AUX_SINGLE | AUX_RGB);</P>
<P style="TEXT-INDENT: 2em">　　　　auxInitPosition (0, 0, 500, 500);</P>
<P style="TEXT-INDENT: 2em">　　　　auxInitWindow ("Arbitrary Clipping Planes");</P>
<P style="TEXT-INDENT: 2em">　　　　myinit ();</P>
<P style="TEXT-INDENT: 2em">　　　　auxReshapeFunc (myReshape);</P>
<P style="TEXT-INDENT: 2em">　　　　auxMainLoop(display);</P>
<P style="TEXT-INDENT: 2em">　　}</P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em">（六）矩阵栈的操作</P>
<P style="TEXT-INDENT: 2em">　　在讲述矩阵栈之前，首先介绍两个基本OpenGL矩阵操作函数：</P>
<P style="TEXT-INDENT: 2em">　　1、void glLoadMatrix{fd}(const TYPE *m)</P>
<P style="TEXT-INDENT: 2em">　　设置当前矩阵中的元素值。函数参数*m是一个指向16个元素(m0, m1, ..., m15)的指针，这16个元素就是当前矩阵M中的元素，其排列方式如下：</P>
<P style="TEXT-INDENT: 2em">M = | m0 m4 m8　m12 |</P>
<P style="TEXT-INDENT: 2em">　　| m1 m5 m9　m13 |</P>
<P style="TEXT-INDENT: 2em">　　| m2 m6 m10 m14 |</P>
<P style="TEXT-INDENT: 2em">　　| m3 m7 m11 M15 |</P>
<P style="TEXT-INDENT: 2em">　　2、void glMultMatrix{fd}(const TYPE *m)</P>
<P style="TEXT-INDENT: 2em">　　用当前矩阵去乘*m所指定的矩阵，并将结果存放于*m中。当前矩阵可以是用glLoadMatrix() 指定的矩阵，也可以是其它矩阵变换函数的综合结果。</P>
<P style="TEXT-INDENT: 2em">　　OpenGL的矩阵堆栈指的就是<A href="http://product.yesky.com/catalog/219/">内存</A>中专门用来存放矩阵数据的某块特殊区域。一般说来，矩阵堆栈常用于构造具有继承性的模型，即由一些简单目标构成的复杂模型。矩阵堆栈对复杂模型运动过程中的多个变换操作之间的联系与独立十分有利。因为所有矩阵操作函数如glLoadMatrix()、glMultMatrix()、glLoadIdentity()等只处理当前矩阵或堆栈顶部矩阵，这样堆栈中下面的其它矩阵就不受影响。堆栈操作函数有以下两个：</P>
<P style="TEXT-INDENT: 2em">　　·void glPushMatrix(void);</P>
<P style="TEXT-INDENT: 2em">　　该函数表示将所有矩阵依次压入堆栈中，顶部矩阵是第二个矩阵的备份；压入的矩阵数不能太多，否则出错。</P>
<P style="TEXT-INDENT: 2em">　　·void glPopMatrix(void);</P>
<P style="TEXT-INDENT: 2em">　　该函数表示弹出堆栈顶部的矩阵，令原第二个矩阵成为顶部矩阵，接受当前操作，故原顶部矩阵被破坏；当堆栈中仅存一个矩阵时，不能进行弹出操作，否则出错。</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/430366012008456551961</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/430366012008456551961</guid>
    <pubDate>Mon, 5 May 2008 18:55:01 +0800</pubDate>
    <dcterms:modified>2008-05-05T18:55:01+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 国家法定节假日新规定]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200833081656814</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://lscdyx321.blog.163.com/" target=_blank>lscdyx321</A> 的 <A href="http://lscdyx321.blog.163.com/blog/static/4525621820083275369930" target=_blank>国家法定节假日新规定</A><BR>
<P c07? g_c_pdin g_t_24 g_t_bold g_t_center g_t_wrap>国家法定节假日新规定 </P>
<DIV>
<DIV style="WIDTH: 760px" g_c_pdin content? c07 g_p_center>
<P>&nbsp;&nbsp;&nbsp;&nbsp; 前面我转发了报刊上一篇关于节假日的调整意见的探讨，没想到这么快中央政府就出台了规定。其实早在前几年这个问题就在政协等会上提出过，今天终于成为了现实，很高兴！终于可以过一些自己的传统节日了，这是中华民族传统的继承和发扬，同时也是一种文化的回归！就像成立孔子学院一样，我们的老祖宗还是不能忘的啊！不要让我们再为不知所云的外来节日浪费精力和金钱了！今天把调整后的节日新规定与朋友们分享一下：</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一、调整后的规定<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、国家法定节假日总天数增加1天，即由目前的10天增加到11天。 <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、对国家法定节假日时间安排进行调整：元旦放假1天不变；春节放假3天不变，但放假起始时间由农历年正月初一调整为除夕；“五一”国际劳动节由3天调整为1天，减少2天；“十一”国庆节放假3天不变；清明、端午、中秋增设为国家法定节假日，各放假1天(农历节日如遇闰月，以第一个月为休假日)。 <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、允许周末上移下错，与法定节假日形成连休。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 二、&nbsp;改革原则<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此次国家法定节假日制度调整方案的拟订体现了以下原则：一是法定休假日天数要与经济社会发展阶段相适应；二是法定节假日安排要有利于弘扬和传承民族传统文化；三是节假日制度安排要尽量减少对经济社会运行影响和冲击；四是休假制度安排要体现社会公平，让全体公民共享经济社会发展的成果；五是法定节假日调整和带薪休假制度安排要充分考虑到国民旅游需求。</P>
<P>&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;三、 改革特点<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此次国家法定节假日制度调整方案具有以下几个特点，一是国家法定节假日总天数增加1天，由原来的10天增加到11天，使广大居民得到更多的休息时间。二是增加清明、端午、中秋三个传统节日，增强了国家法定节假日的传统文化影响力，同时将春节放假的起始时间调整为除夕，更加符合广大群众的文化和生活需要。三是允许周末上移下错，与国家法定节假日形成两个七天的“黄金周”(春节和国庆节)和五个三天的“小长假”(元旦、清明、国际劳动节、端午、中秋)，增加了假日的次数，节假日的分布更加合理。四是通过法定节假日的调整和职工带薪休假规定的同步出台，既可满足广大人民群众的旅游要求，又可有效避免因出行过于集中对社会和经济造成的冲击，降低交通、安全、市场、环境、企业经营的压力，有利于广大群众开展假日期间的各种活动。五是国家将同步出台《职工带薪休假规定》，为全面落实职工休假权利提供法律保障，使广大职工可以更加人性化地安排家庭及个人生活。<BR><BR><B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 四、解读黄金周改革方案：五一黄金周出除，10.1黄金周不变</B><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;1、 5.1黄金周改革方案已定，具体方案为：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 五一黄金周将调整为一天，清明、端午、中秋成为新的法定假日，各放假一天。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、10.1黄金周不变，<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 春节长假前挪一天将除夕包含在内。<BR>黄金周改革后将会比原来多一天的法定假日，调整后法定假日为：元旦1天+清明1天+劳动节1天+端午节1天+中秋节1天+国庆节3天+春节3=11天<BR>比原来的法定假日：元旦1天+劳动节3天+国庆节3天+春节3=10天多了1天。<BR>因其他原因不能享受法定假日的，用工单位必须支付不少于3倍的工资。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#000000>&nbsp; 五、新增享受假期的节日解读</FONT></P>
<P style="TEXT-INDENT: 2em">&nbsp; &nbsp;除夕：除夕是指每年农历腊月的最后一天的晚上，它与春节(正月初一)首尾相连。除夕的主要活动有三项：吃团圆饭，祭祀，守岁。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;清明：清明节古时也叫三月节，已有２５００多年历史。公历四月五日前后为清明节，是二十四节气之一。在二十四个节气中，既是节气又是节日的只有清明。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 端午：农历五月初五是端午节。两千多年来，端午节一直是一个多民族的全民健身、防疫祛病、避瘟驱毒、祈求健康的民俗佳节。</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;中秋：每年农历八月十五日，是我国传统的中秋佳节。这时是一年秋季的中期，所以被称为中秋。这也是我国仅次于春节的第二大传统节日。 </P>
<P style="TEXT-INDENT: 2em"><BR></P></DIV></DIV></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200833081656814</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200833081656814</guid>
    <pubDate>Wed, 30 Apr 2008 08:16:56 +0800</pubDate>
    <dcterms:modified>2008-04-30T08:16:56+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 对话框中OpenGL的设置]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200832031446360</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://huhuiowen.blog.163.com/" target=_blank>擎天柱</A> 的 <A href="http://huhuiowen.blog.163.com/blog/static/130103920083193167420" target=_blank>对话框中OpenGL的设置</A><BR>基于对话框的OpenGL图形程序的基本框架<BR> 1、 理论基础<BR> a、在对话框中建立需要OpenGL绘图的窗口，并按OpenGL得要求设置窗口的属性和风格；<BR> b、在该窗口的创建过程中，设置好显示的像素格式，并创建OpenGL绘制描述表RC；<BR> c、在窗口的绘制过程中，首先获得Windows设备描述表DC,然后将其与事先设置好的OpenGL绘制表述表RC联系起来；<BR> d、调用OpenGL命令进行图形绘制；<BR> e、退出OpenGL图形窗口时，释放OpenGL绘制描述表RC和Windows设备描述表DC。<BR> <BR> 2、变成步骤<BR> a、设置好OpenGL得编程环境<BR> b、启动vc6.0，选择NEW菜单，在NEW对话框中选择Project标签，选择"MFC AppWizard(exe)",新建一个基于对话框的工程。名称为MyDlgOpenGL。<BR> c、删除对话框的静态文本控件。<BR> d、选择insert-&gt;new class菜单，在工程中插入一个新类COpenGL,基类选择generic CWnd。<BR> e、利用MFC ClassWizard为COpenGL类添加消息WM_CREATE、WM_PAINT得响应函数，WM_CREATE为了设置绘图像素格式，创建渲染描述表。WM_PAINT进行OpenGL渲染。<BR> f、在OpenGL.h中加入源代码<BR> public:<BR> virtual ~COpenGL();<BR> <BR> ///////////////////////////////////////////////////////////<BR> //添加的成员函数与成员变量<BR> int MySetPixelFormat(HDC hdc);<BR> void DrawColorBox(void);<BR> HDC hdc;<BR> HGLRC hglrc;<BR> GLfloat step,s;<BR> ////////////////////////////////////////////////////////////<BR> <BR> g、在文件OpenGL.cpp中加入如下代码<BR> <BR> COpenGL::COpenGL()<BR> {<BR> //给成员变量赋初值<BR> step = 0.0;<BR> s = 0.1;<BR> }<BR><BR> COpenGL::~COpenGL()<BR> {<BR> wglMakeCurrent(NULL,NULL);<BR> wglDeleteContext(hglrc);//删除渲染描述表<BR> ::ReleaseDC(m_hWnd,hdc);//释放设备描述表<BR> }<BR> /////////////////////////////////////////////////////////////////////////////<BR>// COpenGL message handlers<BR>//设置像素格式<BR>int COpenGL::MySetPixelFormat(HDC hdc)<BR>{<BR> PIXELFORMATDESCRIPTOR pfd = { <BR> sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小 <BR> 1, // 版本号 <BR> PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图 <BR> PFD_SUPPORT_OPENGL | // 支持 OpenGL <BR> PFD_DOUBLEBUFFER, // 双缓存模式 <BR> PFD_TYPE_RGBA, // RGBA 颜色模式 <BR> 24, // 24 位颜色深度 <BR> 0, 0, 0, 0, 0, 0, // 忽略颜色位 <BR> 0, // 没有非透明度缓存 <BR> 0, // 忽略移位位 <BR> 0, // 无累加缓存 <BR> 0, 0, 0, 0, // 忽略累加位 <BR> 32, // 32 位深度缓存 <BR> 0, // 无模板缓存 <BR> 0, // 无辅助缓存 <BR> PFD_MAIN_PLANE, // 主层 <BR> 0, // 保留 <BR> 0, 0, 0 // 忽略层,可见性和损毁掩模 <BR> }; <BR> <BR> int iPixelFormat; <BR> <BR> // 为设备描述表得到最匹配的像素格式 <BR> if((iPixelFormat = ChoosePixelFormat(hdc, &amp;pfd)) == 0)<BR> {<BR> MessageBox("ChoosePixelFormat Failed", NULL, MB_OK);<BR> return 0;<BR> }<BR> <BR> // 设置最匹配的像素格式为当前的像素格式 <BR> if(SetPixelFormat(hdc, iPixelFormat, &amp;pfd) == FALSE)<BR> {<BR> MessageBox("SetPixelFormat Failed", NULL, MB_OK);<BR> return 0;<BR> }<BR><BR> return 1;<BR>}<BR>int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct) <BR>{<BR> if (CWnd::OnCreate(lpCreateStruct) == -1)<BR> return -1;<BR> <BR> // 设置当前的绘图像素格式<BR> MySetPixelFormat(::GetDC(m_hWnd));<BR><BR> // 获得绘图描述表<BR> hdc = ::GetDC(m_hWnd);<BR> // 创建渲染描述表<BR> hglrc = wglCreateContext(hdc);<BR> // 使绘图描述表为当前调用现程的当前绘图描述表 <BR> wglMakeCurrent(hdc, hglrc); <BR> return 0;<BR>}<BR><BR>void COpenGL::OnPaint() <BR>{<BR>// CPaintDC dc(this); // device context for painting<BR> <BR> // TODO: Add your message handler code here<BR> //调用OpenGL绘图函数进行图形绘制<BR>// glClearColor(0.0,1.0,0.0,1.0);<BR> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色缓存和深度缓存<BR><BR> s+=0.005;<BR> if(s&gt;1.0)<BR> s=0.1;<BR> step = step + 1.0;<BR> if (step &gt; 360.0)<BR> step = step - 360.0;<BR> glPushMatrix();<BR> glScalef(s,s,s);<BR> glRotatef(step,0.0,1.0,0.0);<BR> glRotatef(step,0.0,0.0,1.0);<BR> glRotatef(step,1.0,0.0,0.0);<BR> DrawColorBox();<BR> glPopMatrix();<BR> glFlush();<BR><BR> SwapBuffers(hdc);<BR> <BR> // Do not call CWnd::OnPaint() for painting messages<BR>}<BR><BR>void COpenGL::DrawColorBox(void)<BR>{<BR> GLfloat p1[]={0.5,-0.5,-0.5}, p2[]={0.5,0.5,-0.5},<BR> p3[]={0.5,0.5,0.5}, p4[]={0.5,-0.5,0.5},<BR> p5[]={-0.5,-0.5,0.5}, p6[]={-0.5,0.5,0.5},<BR> p7[]={-0.5,0.5,-0.5}, p8[]={-0.5,-0.5,-0.5};<BR><BR> GLfloat m1[]={1.0,0.0,0.0}, m2[]={-1.0,0.0,0.0},<BR> m3[]={0.0,1.0,0.0}, m4[]={0.0,-1.0,0.0},<BR> m5[]={0.0,0.0,1.0}, m6[]={0.0,0.0,-1.0};<BR><BR> <BR> GLfloat c1[]={0.0,0.0,1.0}, c2[]={0.0,1.0,1.0},<BR> c3[]={1.0,1.0,1.0}, c4[]={1.0,0.0,1.0},<BR> c5[]={1.0,0.0,0.0}, c6[]={1.0,1.0,0.0},<BR> c7[]={0.0,1.0,0.0}, c8[]={1.0,1.0,1.0};<BR> <BR> <BR> glBegin (GL_QUADS); //绘制多个四边形<BR> <BR> glColor3fv(c1);<BR> glNormal3fv(m1);<BR> glVertex3fv(p1);<BR> glColor3fv(c2);<BR> glVertex3fv(p2);<BR> glColor3fv(c3);<BR> glVertex3fv(p3);<BR> glColor3fv(c4);<BR> glVertex3fv(p4);<BR><BR> glColor3fv(c5);<BR> glNormal3fv(m5);<BR> glVertex3fv(p5);<BR> glColor3fv(c6);<BR> glVertex3fv(p6);<BR> glColor3fv(c7);<BR> glVertex3fv(p7);<BR> glColor3fv(c8);<BR> glVertex3fv(p8);<BR><BR> glColor3fv(c5);<BR> glNormal3fv(m3);<BR> glVertex3fv(p5);<BR> glColor3fv(c6);<BR> glVertex3fv(p6);<BR> glColor3fv(c3);<BR> glVertex3fv(p3);<BR> glColor3fv(c4);<BR> glVertex3fv(p4);<BR><BR> glColor3fv(c1);<BR> glNormal3fv(m4);<BR> glVertex3fv(p1);<BR> glColor3fv(c2);<BR> glVertex3fv(p2);<BR> glColor3fv(c7);<BR> glVertex3fv(p7);<BR> glColor3fv(c8);<BR> glVertex3fv(p8);<BR><BR> glColor3fv(c2);<BR> glNormal3fv(m5);<BR> glVertex3fv(p2);<BR> glColor3fv(c3);<BR> glVertex3fv(p3);<BR> glColor3fv(c6);<BR> glVertex3fv(p6);<BR> glColor3fv(c7);<BR> glVertex3fv(p7);<BR><BR> glColor3fv(c1);<BR> glNormal3fv(m6);<BR> glVertex3fv(p1);<BR> glColor3fv(c4);<BR> glVertex3fv(p4);<BR> glColor3fv(c5);<BR> glVertex3fv(p5);<BR> glColor3fv(c8);<BR> glVertex3fv(p8);<BR><BR> glEnd();<BR><BR>}<BR><BR> h、在文件MyDlgOpenGLDlg.h中加入如下源代码。<BR>////////////////////////////////////////////////////<BR>//添加类COpenGL的头的说明文件<BR>#include "OpenGL.h"<BR>//////////////////////////////////////////////////////////////////////////<BR><BR>在class CMyDlgOpenGLDlg : public CDialog中添加<BR></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200832031446360</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200832031446360</guid>
    <pubDate>Sun, 20 Apr 2008 15:14:46 +0800</pubDate>
    <dcterms:modified>2008-04-20T15:14:46+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 MFC中获取各种类指针]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200832031345495</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://pomelox.blog.163.com/" target=_blank>柚子</A> 的 <A href="http://pomelox.blog.163.com/blog/static/204769332007542426816" target=_blank>MFC中获取各种类指针</A><BR>
<P>1、获取应用程序指针<BR>　　CMyApp* pApp=(CMyApp*)AfxGetApp();</P>
<P>2、获取主框架指针<BR>　　CWinApp 中的公有成员变量 m_pMainWnd 就是主框架的指针<BR>　　CMainFrame* pMainFrame = (CMainFrame*)(AfxGetApp()-&gt;m_pMainWnd);<BR>　　或者<BR>　　CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();</P>
<P>３、获取菜单指针<BR>　　CMenu* pMenu = AfxGetMainWnd()-&gt;GetMenu();</P>
<P>４、获取工具栏、状态栏指针<BR>　　主框架中可以直接使用m_wndToolBar、m_wndStatusBar<BR>　　其他：<BR>　　CToolBar* pToolBar = (CToolBar*)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_TOOLBAR);<BR>　　CStatusBar* pStatusBar = (CStatusBar*)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_STATUS_BAR);</P>
<P>5、获取控件指针<BR>　　先用 GetDlgItem() 再转换，如：<BR>　　CButton* pButton = (CButton*)GetDlgItem(IDC_MYBUTTON);</P>
<P>6、获取文档、视图指针</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P>SDI:<BR>CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();<BR>CYourDoc* pDoc = (CYourDoc*)pMainFrame-&gt;GetActiveDocument();<BR>CYourView* pView = (CYourView*)pMainFrame-&gt;GetActiveView();</P>
<P>MDI:<BR>CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();<BR>CChildFrame* pChildFrame = (CChildFrame*)pMainFrame-&gt;GetActiveFrame();<BR>CYourDoc* pDoc = (CYourDoc*)pChildFrame-&gt;GetActiveDocument();<BR>CYourView* pView = (CYourView*)pChildFrame-&gt;GetActiveView();</P></BLOCKQUOTE>
<P>7、文档、视图</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P>从视图获取文档指针：<BR>CYourDoc* pDoc = GetDocument();</P>
<P>从文档获取视图指针：<BR>利用成员函数 GetFirstViewPosition() 和 GetNextView() 遍历<BR>virtual POSITION GetFirstViewPosition() const;<BR>virtual CView* GetNextView(POSITION&amp; rPosition) const;</P>
<P>SDI:<BR>CYourView* pView;<BR>POSITION pos = GetFirstViewPosition();<BR>pView = GetNextView(pos);</P>
<P>MDI:<BR>定义函数<BR>CView* CYourDoc::GetView(CRuntimeClass* pClass)<BR>{<BR>&nbsp;&nbsp;&nbsp; CView* pView;<BR>&nbsp;&nbsp;&nbsp; POSITION pos=GetFirstViewPosition();<BR>&nbsp;&nbsp;&nbsp; while(pos!=NULL)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; pView=GetNextView(pos);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if(!pView-&gt;IsKindOf(pClass))<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; if(!pView-&gt;IsKindOf(pClass))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("Connt Locate the View.");<BR>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;return NULL;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return pView;<BR>}<BR>使用如下：<BR>CYourView* pView=(CYourView*)GetView(RUNTIME_CLASS(CYourView));</P></BLOCKQUOTE>
<P dir=ltr>8、文档模版、文档</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P>从文档获取文档模版指针：<BR>CDocTemplate* GetDocTemplate() const;</P>
<P>从文档模版获取文档指针：<BR>viaual POSITION GetFirstDocPosition( ) const = 0; <BR>visual CDocument* GetNextDoc(POSITION &amp; rPos) const = 0;</P></BLOCKQUOTE>
<P dir=ltr>9、获取分割视图中各个视图的指针</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P dir=ltr>主框架中定义：CSplitterWnd m_wndSplitter;</P>
<P dir=ltr>定义两个View类：CView1、CView2</P>
<P dir=ltr>框架类中重载：<BR>BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext)<BR>{<BR>&nbsp;&nbsp;&nbsp; VERIFY(m_splitter.CreateStatic(this,2,1)); //分割成两行一列<BR>&nbsp;&nbsp;&nbsp; VERIFY(m_splitter.CreateView(0,0,RUNTIME_CLASS(CView1),CSize(100,100),pContext));<BR>&nbsp;&nbsp;&nbsp; VERIFY(m_splitter.CreateView(1,0,RUNTIME_CLASS(CView2),CSize(100,100),pContext));<BR>&nbsp;&nbsp;&nbsp; return TRUE;<BR>}</P>
<P dir=ltr>获取分割视图指针<BR>CView1* pView1&nbsp;= (CView1*)m_wndSplitter.GetPane(0,0);<BR>CView2* pView2&nbsp;= (CView2*)m_wndSplitter.GetPane(1,0);</P></BLOCKQUOTE>
<P dir=ltr>10、通过鼠标获得子窗口指针</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P dir=ltr>CWnd* ChildWindowFromPoint(POINT point) const;<BR>CWnd* ChildWindowFromPoint(POINT point,UINT nFlags) const;<BR>用于确定包含指定点的子窗口<BR>如果指定点在客户区之外，函数返回NULL；<BR>如果指定点在客户区内，但是不属于任何一个子窗口，函数返回该CWnd的指针；<BR>如果有多个子窗口包含指定点，则返回第一个子窗口的指针。<BR>还要注意的是，该函数返回的是一个伪窗口指针，不能将它保存起来供以后使用。<BR>对于第二个参数nFlags有几个含义：<BR>CWP_ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file://不忽略任何子窗口<BR>CWP_SKIPNIVSIBLE&nbsp;&nbsp;&nbsp; file://忽略不可见子窗口<BR>CWP_SKIPDISABLED&nbsp;&nbsp;&nbsp; file://忽略禁止的子窗口<BR>CWP_SKIPRANSPARENT&nbsp; file://忽略透明子窗口</P></BLOCKQUOTE></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200832031345495</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200832031345495</guid>
    <pubDate>Sun, 20 Apr 2008 15:13:45 +0800</pubDate>
    <dcterms:modified>2008-04-20T15:13:45+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[mfc 中的 指针调用]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200831955833178</link>
    <description><![CDATA[<div><P>1.怎样在我对话框类中获得视图类的指针？</P>
<P>((CMainFrame*)AfxGetMainWnd())-&gt;GetActiveView()&nbsp;&nbsp; ;</P>
<P>MID:&nbsp;</P>
<P>&nbsp;CChildFrame &nbsp; * &nbsp; pChildFrame &nbsp; = &nbsp; ((CMainFrame*)AfxGetMainWnd())-&gt;GetActiveFrame(); &nbsp; <BR>&nbsp; C***View &nbsp; * &nbsp; pView &nbsp; = &nbsp; (C***View &nbsp; *)pChildFrame-&gt;GetActiveView();</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200831955833178</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200831955833178</guid>
    <pubDate>Sat, 19 Apr 2008 17:58:33 +0800</pubDate>
    <dcterms:modified>2008-04-19T17:58:33+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[基于GIS 的小城镇洪灾淹没分析与应急决策系统（转载]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200831812210395</link>
    <description><![CDATA[<div>近年来，将GIS 技术与水文模型相结合，再根据数字高程模型DEM 预测、模拟显示洪水淹没区，并进行灾害评估，已成为GIS 应用和水利领域一个研究热点。笔者介绍了利用GIS 技术建立的小城镇洪灾<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>与应急决策系统的构架、数据库的建设及其实现的功能等内容。该系统解决了一系列关键技术：小城镇空间数据库的建库技术及三维可视化、洪水淹没范围的确定以及洪水淹没实时动态演示等，能够对洪水灾害及其损失进行分析预测，对洪水灾情进行快速评估，是小城镇政府部门科学地制定防洪和减灾对策，迅速有效地采取抗洪救灾措施的保障手段。该系统适合我国现有国情，有利于维护小城镇社会经济持续稳定发展，具有很强的现实意义。<BR>洪水模拟及灾害评估研究是国际上普遍关注的课题。特别是近几年来，利用计算机和信息管理技术研究洪水灾害，将GIS 技术与水文模型相结合，再根据数字高程模型DEM（Digital Elevation Models）预测、模拟显示洪水淹没区，并进行灾害评估，已成为GIS 应用和水利领域一个非常前沿的研究课题。但大多数研究仍然是基于二维平面的GIS 技术，具体研究淹没三维可视化方法及计算机编程的却很少。小城镇是农村一定区域内的政治、经济、文化中心，小城镇在城市化进程中有着不可替代的作用，按照 “小城镇，大战<BR>略”的部署，我国已进入城镇化发展的关键时期［3］。但与城市相比，小城镇在防洪减灾方面缺少应有的关注和重视，然而实际上小城镇由于其历史发展的原因，往往建成区与农田相互交错，基础设施不足，公共设施标准较低，没有明显的功能分区，防洪排涝系统不健全，甚至完全不设防等，使得小城镇在洪灾面前更脆弱，受灾的影响面也更广，灾后重建难度更大。1998 年长江发生了继1954 年以来又一次全流域性大洪水，长江流域的四川、重庆、湖南、湖北、江西、安徽、江苏等省市，城镇进水的县就达481 个，仅四川省就达327 个，损失十分严重［6］。因此，运用现代化手段建立小城镇洪灾<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>与应急决策系统是非常紧迫和必要的，是小城镇政府部门提前进行区域内的洪水淹没仿真分析、提前组织人员疏散、受灾预测和抢险救灾任务必不可少的重要手段。<BR>系统技术框架<BR>小城镇洪灾<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>与应急决策系统是利用各种信息技术和模型知识，通过人机交互方式辅助人们解决防洪工作中<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>和应急指挥救援等复杂问题，更好地满足防洪减<BR>灾决策对空间信息的需求。对于选取小城镇规模的小型流域，系统要具有简单实用、快速方便的特点。该系统的总体目标是对洪水灾害及其损失进行分析预测，对洪水灾情进行<BR>快速评估，科学地制定防洪和减灾对策，迅速地采取有效的抗洪救灾措施，以维护小城镇社会经济持续稳定发展。系统结构如图1 所示。<BR><BR>
<P align=left>小城镇空间数据库的建库技术</P><BR><BR>
<P align=left><FONT size=2>数据的丰富性、正确性及现势性直接关系到系统的应用效果。为克服空间数据建库的各种局限性，采用基于高分辨率影像图进行屏幕矢量化，综合各种历史资料，构建小城镇空间数据库的技术方案。它充分利用GIS 软件的多源数据集成能力，集成高分辨率影像、高精度GPS 数据、历史规划设计数据和社会经济统计数据，快速建立高质量的空间数据库。其技术流程如图2 </FONT><FONT size=2>所示</FONT>。</P>
<P align=left></P><BR><BR>系统功能<BR>1.洪灾损失预测和评估<BR>&nbsp; &nbsp;科学而精确地预测和评估洪灾经济损失，是防洪减灾中的一项重要工作。通过使用该功能，可以在灾害发生前，大致预测灾害发生地点及其淹没水深，且利用已有的易损性信息数据和社会经济数据，对洪水灾害损失进行预测性的快速评估，从而在洪水来临之前就做好一系列的防范措施（见图3）<BR><BR>2.洪灾三维演示模拟<BR>&nbsp; &nbsp;洪水淹没动态演示是在地形和建筑物三维可视化的基础之上，动态演示不同水位下洪水淹没的时空变化，重现或是预演小城镇洪灾下的全过程。系统通过对防洪减灾策略作试演和模拟，提供用以决策的科学依据，以评价策略的有效性，达到减少人力、物力投入，进而减小防洪减灾策略的盲目性。为了响应时触发事件，达到动态演示效果，首先需要在编程实现时插入计时器变量，按照一定的interval 时间间隔触发系统按新的高度重新绘制淹没后的水面，每一次重绘就是演示的下一帧动画，从而实现洪水水面的动态地上涨或下降，其中水体颜色赋为浅蓝色。为节约内存空间，地形与建筑物却不必重绘（见图4）。<BR>&nbsp;&nbsp;首先，要选择合适的安置点，确保不受洪水的袭击，不能让灾民做多次搬迁；其次，要合理地将各个灾区的人员、财产分配到各个安置点，不能简单地就近安置，因为每个安置点都有一定容量，而不能无限制接纳灾民；最后，是选择最佳撤退路径。用整个小城镇区域与洪灾淹没区域做减运算，即可得到避难场（见图6），洪灾的避难场地理所当然是位于高处，不能遭受水淹，否则就失去了灾民搬迁的意义了。<BR>3.洪水淹没范围的快速确定<BR>&nbsp; &nbsp;运用GIS 技术快速、准确地模拟洪水淹没区域，是与当地各种专题图层进行叠加分析得出有关决策指标的前提，因此，对于确定人员疏散规模与灾害评估都具有十分重要的意义。基于DEM 计算给定的洪水水位下的淹没区，其水位高度值通过参照汛情预报获得。按给定水位计算淹没范围，实际上是假定淹没过程中，淹没区为“静态水平面”。这种淹没范围的近似计算模型实用、简单、快捷，能综合考虑降水淹没<BR>和洪水淹没，有利于在防洪减灾中迅速做出决策，且偏于安全。<BR>该技术快速实现步骤为：首先，人机交互输入淹没水面高度值；其次，对DEM 图层进行过滤计算得到水面高度值以下的区域，后将受淹区域导入跟踪层，并按照一定的风格显示在地图窗口中；最后，以此为基础与其他矢量图层进行求交或其他叠加运算（见图5）。<BR>4.选择避难场地<BR>&nbsp; &nbsp;洪水来临前，组织灾民及财产安全转移是决策者必须考虑的问题之一。尤其是当运用GIS 技术模拟、预测出洪水淹没范围之后，如何安全快速地转移淹没区内的人员与财产，更是减少灾害损失的重要对策。这是一件非常复杂的工作，在执行过程中需考虑很多因素。<BR>所以通过GIS 应用，将GIS 技术与水文模型相结合，初步建立了小城镇洪灾<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>与应急决策系统并有如下结论：<BR>（1）通过建立小城镇洪灾<STRONG><FONT color=#ff0000>淹没分析</FONT></STRONG>与应急决策系统，从而保障小城镇政府部门提前进行区域内的洪水淹没仿真分析、提前组织人员疏散、受灾预测和抢险救灾任务。<BR>（2）依据洪水水位确定淹没范围后，利用综合数据库，对可能受淹地区的农业、水产、房屋、人口等数据进行快速评估，从而定量地预测某一地区未来洪水发生的强度、分布，并进一步预测可能造成的人员伤亡、经济损失以及社会影响等。<BR>（3）快速高效构建小城镇空间数据库及三维可视化的技术方案，切合我国小城镇信息化的现状。<BR>（4）基于静态水平面的淹没范围的近似计算模型，可以<BR>有效迅速准确地计算出某一水位下洪水淹没范围，有利于在<BR>防洪减灾中的迅速决策，且偏于安全</div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200831812210395</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200831812210395</guid>
    <pubDate>Fri, 18 Apr 2008 13:22:10 +0800</pubDate>
    <dcterms:modified>2008-04-18T13:22:10+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[VC++中OPENGL种子填充算法]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/4303660120083189929228</link>
    <description><![CDATA[<div>#include &nbsp; &lt;windows.h&gt; &nbsp; <BR>&nbsp; //#include &nbsp; &lt;graphics.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;GL/gl.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;GL/glu.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;GL/glaux.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;math.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;iostream.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;stdio.h&gt; &nbsp; <BR>&nbsp; #include &nbsp; &lt;malloc.h&gt; &nbsp; <BR>&nbsp; #pragma &nbsp; comment(lib,"opengl32.lib") &nbsp; <BR>&nbsp; #pragma &nbsp; comment(lib,"glu32.lib") &nbsp; <BR>&nbsp; #pragma &nbsp; comment(lib,"glaux.lib") &nbsp; <BR>&nbsp; #define &nbsp; NULL &nbsp; 0 &nbsp; <BR>&nbsp; #define &nbsp; MAXSIZE &nbsp; 10000 &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; int &nbsp; fill_color=RGB(1.0,1.0,0.0); &nbsp; <BR>&nbsp; int &nbsp; boundary_color=RGB(1.0,0.0,0.0); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; struct &nbsp; node{ &nbsp; <BR>&nbsp; float &nbsp; x,y; &nbsp; <BR>&nbsp; int &nbsp; color; &nbsp; <BR>&nbsp; }a[MAXSIZE]; &nbsp; <BR>&nbsp; int &nbsp; top=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //栈顶指针 &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; float &nbsp; m=300.0f; //圆的半径及圆心 &nbsp; <BR>&nbsp; float &nbsp; n=300.0f; &nbsp; <BR>&nbsp; float &nbsp; radiu=200.0f; &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; void &nbsp; draw(float &nbsp; x,float &nbsp; y) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //画点 &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; glColor3f(1.0,1.0,0.0); &nbsp; &nbsp; &nbsp; &nbsp; //与boundary_color一致 &nbsp; <BR>&nbsp; glBegin(GL_POINTS); &nbsp; <BR>&nbsp; glVertex2f(x,y); &nbsp; <BR>&nbsp; glEnd(); &nbsp; <BR>&nbsp; glFlush(); &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; void &nbsp; pushpixel(float &nbsp; x,float &nbsp; y) &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; int &nbsp; i; &nbsp; <BR>&nbsp; for &nbsp; (i=0;i&lt;top;i++) &nbsp; <BR>&nbsp; if &nbsp; (x==a[top].x &nbsp; &amp;&amp; &nbsp; y==a[top].y) &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //已在栈中 &nbsp; <BR>&nbsp; a[top].x=x; &nbsp; <BR>&nbsp; a[top].y=y; &nbsp; <BR>&nbsp; if &nbsp; (x*x+y*y==radiu*radiu) &nbsp; a[top].color=boundary_color; &nbsp; &nbsp; //边界点 &nbsp; <BR>&nbsp; else &nbsp; a[top].color=-1; //未被画过 &nbsp; <BR>&nbsp; top++; &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; struct &nbsp; node &nbsp; poppixel() &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; struct &nbsp; node &nbsp; p; &nbsp; <BR>&nbsp; p.x=a[top].x; &nbsp; <BR>&nbsp; p.y=a[top].y; &nbsp; <BR>&nbsp; p.color=a[top].color; &nbsp; <BR>&nbsp; top--; &nbsp; <BR>&nbsp; return(p); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; void &nbsp; seedfilling(float &nbsp; x,float &nbsp; y) &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; struct &nbsp; node &nbsp; p; &nbsp; <BR>&nbsp; int &nbsp; c; &nbsp; <BR>&nbsp; if &nbsp; ((x-m)*(x-m)+(y-n)*(y-n)&lt;=radiu*radiu) &nbsp; &nbsp; <BR>&nbsp; pushpixel(x,y);/*当前点压栈*/ &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; while &nbsp; (top!=-1) &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; p=poppixel(); &nbsp; <BR>&nbsp; c=p.color; &nbsp; <BR><CLK>&nbsp; if &nbsp; ((c!=boundary_color) &nbsp; &amp;&amp; &nbsp; (c!=fill_color)) &nbsp; /*<NOBR false;" this);" style="BACKGROUND: url(http://control.clickeye.com.cn/images/line5.gif) repeat-x 50% bottom; PADDING-BOTTOM: 2px; COLOR: #6600ff" kwC(event,1)" target="_blank">如果颜色为边界色则不填充*/ &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; draw(p.x,p.y);/*当前点出栈,画点*/ &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; if &nbsp; ((x+1-m)*(x-m)+(y-n)*(y-n)&lt;=radiu*radiu) &nbsp; seedfilling(x+1,y); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; if &nbsp; ((x-1-m)*(x-m)+(y-n)*(y-n)&lt;=radiu*radiu) &nbsp; seedfilling(x-1,y); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; if &nbsp; ((x-m)*(x-m)+(y+1-n)*(y+1-n)&lt;=radiu*radiu) &nbsp; seedfilling(x,y+1); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; if &nbsp; ((x-m)*(x-m)+(y-1-n)*(y-1-n)&lt;=radiu*radiu) &nbsp; seedfilling(x,y-1); &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; void &nbsp; CALLBACK &nbsp; fillseed(void) &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; glClear(GL_COLOR_BUFFER_BIT); &nbsp; <BR>&nbsp; seedfilling(m,n); &nbsp; <BR>&nbsp; } &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; void &nbsp; main() &nbsp; <BR>&nbsp; { &nbsp; <BR>&nbsp; &nbsp; auxInitDisplayMode(AUX_SINGLE &nbsp; | &nbsp; AUX_RGBA); &nbsp; <BR>&nbsp; auxInitPosition(50,50,700,600); &nbsp; <BR>&nbsp; auxInitWindow("An &nbsp; Example &nbsp; of &nbsp; OpenGL"); &nbsp; <BR>&nbsp; auxMainLoop(fillseed); &nbsp; <BR>&nbsp; } </div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/4303660120083189929228</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/4303660120083189929228</guid>
    <pubDate>Fri, 18 Apr 2008 09:09:29 +0800</pubDate>
    <dcterms:modified>2008-04-18T09:09:29+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[C语言实现的扫描线种子填充算法]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200831885421980</link>
    <description><![CDATA[<div>本程序实现区域填充功能，首先输入多边形顶点的个数,回车， <BR>然后依次输入各顶点的坐标格式如下：100,123回车 <BR>一定要在中间用逗号隔开噢，输完最后一个点后，屏幕上会依次 <BR>画出各条边，最后填充满. <BR>程序还不完善，比如颜色值应该用变量表示以易于修改，画多边形和求种子点 <BR>应该做成独立的函数等等，以后再做上吧，这是细节的问题 <BR><BR>******************************************************************/ <BR><BR>#include &lt;graphics.h&gt; <BR>#include &lt;stdio.h&gt; <BR>#include &lt;alloc.h&gt; <BR>#include &lt;dos.h&gt; <BR>#include &lt;conio.h&gt; <BR>//creat a stack <BR>struct stack_node <BR>{ <BR>int x; <BR>int y; <BR>struct stack_node *next; <BR>}; <BR>typedef stack_node stack_list; <BR>typedef stack_list *link; <BR>link stack = 0; <BR><BR>//push an element <BR>void push(int xx,int yy) <BR>{ <BR>link new_node; <BR>new_node=(stack_list *)malloc(sizeof(stack_list)); <BR>new_node-&gt;x=xx; <BR>new_node-&gt;y=yy; <BR>new_node-&gt;next=stack; <BR>stack=new_node; <BR>} <BR><BR>//pop an element <BR>void pop(int &amp;xx,int &amp;yy) <BR>{ <BR>link top; <BR>top=stack; <BR>xx=stack-&gt;x; <BR>yy=stack-&gt;y; <BR>stack=stack-&gt;next; <BR>free(top); <BR>} <BR><BR><BR>//fill the plot <BR>void fill(int x,int y) <BR>{ <BR>int x0,y0,xl,xr,xlold,xrold;/*x0,y0用来标记x,y的值,xl记录x的最左值,xr记录x的最右值*/ <BR>int go=0,go2=0; <BR>int i=0; <BR>push(x,y);//种子像素入栈 <BR>while(stack!=0)//如果栈不空则循环，stack==0表示栈空 <BR>{ <BR>&nbsp;go=0;//go 只是一个标记 <BR>&nbsp;pop(x,y); <BR>&nbsp;putpixel(x,y,4); <BR>&nbsp;x0=x+1; <BR>&nbsp;while(getpixel(x0,y)!=4)//fill right 填充右边 <BR>&nbsp;{ <BR>&nbsp; putpixel(x0,y,4); <BR>&nbsp; x0=x0+1; <BR>&nbsp;} <BR>&nbsp;xr=x0-1;//记录最右值 <BR>&nbsp;xrold=xr;//再记录一次最右值，以备后用 <BR>&nbsp;x0=x-1; <BR>&nbsp;while(getpixel(x0,y)!=4)//fill right 填充左边 <BR>&nbsp;{ <BR>&nbsp; putpixel(x0,y,4); <BR>&nbsp; x0=x0-1; <BR>&nbsp;} <BR>&nbsp;xl=x0+1;//记录最左值 <BR>&nbsp;xlold=xl;//再记录一次最左值，以备后用 <BR>&nbsp;y0=y+1;//go up 向上移一条扫描线 <BR>&nbsp;go2=0;//go2 也只是一个用来标记的变量 <BR>&nbsp;while(xr&gt;xl&amp;&amp;go==0)//查找上一条线的最右值,并记录为xr <BR>&nbsp;{ <BR>&nbsp; if(getpixel(xr,y0)==4) <BR>&nbsp; { <BR>&nbsp; &nbsp;xr=xr-1; <BR>&nbsp; } <BR>&nbsp; else <BR>&nbsp; { <BR>&nbsp; &nbsp;go=1;//若go=1这句执行的话就说明找到了最右值，并在while中的go==0中判断并退出while <BR>&nbsp; } <BR>&nbsp;} <BR>&nbsp;while(xl&lt;xr&amp;&amp;go2==0)//查找上一条线的最左值，并记录为xl <BR>&nbsp;{ <BR>&nbsp; if(getpixel(xl,y0)==4) <BR>&nbsp; xl=xl+1; <BR>&nbsp; else <BR>&nbsp; go2=1;//go2=1这句执行就说明找到了最左值，并在此while中的go2==0中退出while <BR>&nbsp;} <BR>&nbsp;if(go==1&amp;&amp;go2==1)//如果找到了最左值各最右值，则执行下面的语句 <BR>&nbsp;{ <BR>&nbsp; push(xr,y0);//先将上一条线上的最右点作为种子点入栈 <BR>&nbsp; for(i=xl;i&lt;xr;i++)//从最左到最右循环，在每个连续区间上找一个种子点入栈 <BR>&nbsp; { <BR>&nbsp; &nbsp;if(getpixel(i,y0)!=4)//如果不是边界点，什么也不做 <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp;} <BR>&nbsp; &nbsp;else if(getpixel(i-1,y0)!=4)//如果是边界点，则看它左边的点是不是边界点，如果不是，则入栈 <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp; push(i-1,y0); <BR>&nbsp; &nbsp;} <BR>&nbsp; } <BR><BR>&nbsp;} <BR><BR>&nbsp;y0=y-1;//go down;//向下移一条扫描线 <BR>&nbsp;go=0; <BR>&nbsp;go2=0; <BR>&nbsp;xl=xlold;//还原最左，最右 <BR>&nbsp;xr=xrold; <BR><BR>&nbsp;while(xr&gt;xl&amp;&amp;go==0)//找下一条线的最右 <BR>&nbsp;{ <BR>&nbsp; if(getpixel(xr,y0)!=4) <BR>&nbsp; { <BR>&nbsp; &nbsp;go=1; <BR>&nbsp; } <BR>&nbsp; else <BR>&nbsp; { <BR>&nbsp; &nbsp;xr--; <BR>&nbsp; } <BR><BR>&nbsp;} <BR>&nbsp;while(xl&lt;xr&amp;&amp;go2==0)//找下一条线的最左 <BR>&nbsp;{ <BR>&nbsp; if(getpixel(xl,y0)!=4) <BR>&nbsp; go2=1; <BR>&nbsp; else <BR>&nbsp; xl++; <BR>&nbsp;} <BR>&nbsp;if(go==1&amp;&amp;go2==1)//如果找到最左和最右，则执行 <BR>&nbsp;{ <BR>&nbsp; //push(xl,y0); <BR>&nbsp; push(xr,y0); <BR>&nbsp; for(i=xl;i&lt;=xr;i++) <BR>&nbsp; { <BR>&nbsp; &nbsp;if(getpixel(i,y0)!=4) <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp;} <BR>&nbsp; &nbsp;else if(getpixel(i-1,y0)!=4) <BR>&nbsp; &nbsp;{ <BR>&nbsp; &nbsp; push(i-1,y0); <BR>&nbsp; &nbsp;} <BR>&nbsp; } <BR>&nbsp;} <BR>} <BR>} <BR><BR><BR><BR><BR><BR><BR>void main() <BR>{ <BR>void fill(int x,int y); <BR>int gdriver,gmode;/*显示模式*/ <BR>int i,j; <BR>int n,px,py,px0,py0,px1,py1; <BR>int ya=0,yi=getmaxy(); <BR>printf("pleas input the number of the top points:"); <BR>scanf("%d",&amp;n); <BR>for(i=0;i&lt;n;i++)//从键盘接受各顶点的坐标，依次入栈，并记录最大Y值和最小Y值 <BR>{ <BR>&nbsp;printf("please input the coordinate of the points--like:100,200 &nbsp;:"); <BR>&nbsp;scanf("%d,%d",&amp;px,&amp;py); <BR>&nbsp;if(ya&lt;py) <BR>&nbsp;ya=py;//ya是最大Y值 <BR>&nbsp;if(yi&gt;py) <BR>&nbsp;yi=py;//yi是最小Y值 <BR>&nbsp;push(px,py); <BR>} <BR>detectgraph(&amp;gdriver,&amp;gmode); <BR>initgraph(&amp;gdriver,&amp;gmode,"c:\\bc31\\bgi"); <BR>setbkcolor(0); <BR>cleardevice(); <BR>setcolor(4); <BR><BR>pop(px0,py0);//输入的最后一个顶点出栈 <BR>px=px0; <BR>py=py0;//记录最后一个顶点 <BR>//draw the plot <BR>while(stack != 0) <BR>{ <BR>&nbsp;pop(px1,py1); <BR>&nbsp;line(px0,py0,px1,py1); <BR>&nbsp;px0=px1; <BR>&nbsp;py0=py1; <BR>delay(500); <BR>} <BR>line(px0,py0,px,py);//依次画线，画出多边形 <BR><BR>//画完多边形后，栈为空 <BR><BR>//find the y value <BR>j=(ya+yi)/2;//找Y的中间值,就是第一个种子点的Y值 <BR>i=0; <BR>n=0;//记录入栈个数 <BR>//find the seed element <BR>while(i&lt;getmaxx()&amp;&amp;n!=2)//按X值从0到X最大值依次查找，并在入栈个数为2的时候退出 <BR>{ <BR>&nbsp;if(getpixel(i,j)==4)//如果是多边形上的点，则入栈，用n记录入栈的个数 <BR>&nbsp;{ <BR>&nbsp; push(i,j); <BR>&nbsp; n=n+1; <BR>&nbsp;} <BR>&nbsp;i=i+1;//i是记录当前的X值 <BR>} <BR>pop(i,j);//第二个交点出栈 <BR>pop(n,j);//第一个交点出栈，虽然覆盖了Y值，但这不重要，我们要的是X值 <BR>i=(i+n)/2;//现在i是我们要找的种子点的X值 <BR>//fill the plot <BR>fill(i,j);//将种子点作为参数传入fill()方法 <BR>delay(1000); <BR>outtextxy(100,410,"the red line was drawing,fill over"); <BR>getch(); <BR>closegraph(); <BR>} <BR></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200831885421980</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200831885421980</guid>
    <pubDate>Fri, 18 Apr 2008 08:54:21 +0800</pubDate>
    <dcterms:modified>2008-04-18T08:54:21+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[用C实现多边形的种子填充算法.]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/4303660120083188521162</link>
    <description><![CDATA[<div><P>#include &lt;graphics.h&gt;<BR>#include &lt;stdio.h&gt;<BR>#include &lt;alloc.h&gt;<BR>#include &lt;dos.h&gt;<BR>#include &lt;conio.h&gt;<BR>//creat a stack<BR>struct stack_node<BR>{<BR>&nbsp;int x;<BR>&nbsp;int y;<BR>&nbsp;struct stack_node *next;<BR>};<BR>typedef stack_node stack_list;<BR>typedef stack_list *link;<BR>link stack = 0;</P>
<P>//push an element<BR>void push(int xx,int yy)<BR>{<BR>&nbsp;link new_node;<BR>&nbsp;new_node=(stack_list *)malloc(sizeof(stack_list));<BR>&nbsp;new_node-&gt;x=xx;<BR>&nbsp;new_node-&gt;y=yy;<BR>&nbsp;new_node-&gt;next=stack;<BR>&nbsp;stack=new_node;<BR>}</P>
<P>//pop an element<BR>void pop(int &amp;xx,int &amp;yy)<BR>{<BR>&nbsp;link top;<BR>&nbsp;top=stack;<BR>&nbsp;xx=stack-&gt;x;<BR>&nbsp;yy=stack-&gt;y;<BR>&nbsp;stack=stack-&gt;next;<BR>&nbsp;free(top);<BR>}</P>
<P><BR>//fill the plot<BR>void fill(int x,int y)<BR>{<BR>&nbsp;int x0,y0,xl,xr,xlold,xrold;/*x0,y0用来标记x,y的值,xl记录x的最左值,xr记录x的最右值*/<BR>&nbsp;int go=0,go2=0;<BR>&nbsp;int i=0;<BR>&nbsp;push(x,y);//种子像素入栈<BR>&nbsp;while(stack!=0)//如果栈不空则循环，stack==0表示栈空<BR>&nbsp;{<BR>&nbsp;&nbsp;go=0;//go 只是一个标记<BR>&nbsp;&nbsp;pop(x,y);<BR>&nbsp;&nbsp;putpixel(x,y,4);<BR>&nbsp;&nbsp;x0=x+1;<BR>&nbsp;&nbsp;while(getpixel(x0,y)!=4)//fill right 填充右边<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;putpixel(x0,y,4);<BR>&nbsp;&nbsp;&nbsp;x0=x0+1;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;xr=x0-1;//记录最右值<BR>&nbsp;&nbsp;xrold=xr;//再记录一次最右值，以备后用<BR>&nbsp;&nbsp;x0=x-1;<BR>&nbsp;&nbsp;while(getpixel(x0,y)!=4)//fill right 填充左边<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;putpixel(x0,y,4);<BR>&nbsp;&nbsp;&nbsp;x0=x0-1;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;xl=x0+1;//记录最左值<BR>&nbsp;&nbsp;xlold=xl;//再记录一次最左值，以备后用<BR>&nbsp;&nbsp;y0=y+1;//go up 向上移一条扫描线<BR>&nbsp;&nbsp;go2=0;//go2 也只是一个用来标记的变量<BR>&nbsp;&nbsp;while(xr&gt;xl&amp;&amp;go==0)//查找上一条线的最右值,并记录为xr<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(getpixel(xr,y0)==4)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;xr=xr-1;<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;go=1;//若go=1这句执行的话就说明找到了最右值，并在while中的go==0中判断并退出while<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;while(xl&lt;xr&amp;&amp;go2==0)//查找上一条线的最左值，并记录为xl<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(getpixel(xl,y0)==4)<BR>&nbsp;&nbsp;&nbsp;xl=xl+1;<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;go2=1;//go2=1这句执行就说明找到了最左值，并在此while中的go2==0中退出while<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;if(go==1&amp;&amp;go2==1)//如果找到了最左值各最右值，则执行下面的语句<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;push(xr,y0);//先将上一条线上的最右点作为种子点入栈<BR>&nbsp;&nbsp;&nbsp;for(i=xl;i&lt;xr;i++)//从最左到最右循环，在每个连续区间上找一个种子点入栈<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(getpixel(i,y0)!=4)//如果不是边界点，什么也不做<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;else if(getpixel(i-1,y0)!=4)//如果是边界点，则看它左边的点是不是边界点，如果不是，则入栈<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push(i-1,y0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;y0=y-1;//go down;//向下移一条扫描线<BR>&nbsp;&nbsp;go=0;<BR>&nbsp;&nbsp;go2=0;<BR>&nbsp;&nbsp;xl=xlold;//还原最左，最右<BR>&nbsp;&nbsp;xr=xrold;</P>
<P>&nbsp;&nbsp;while(xr&gt;xl&amp;&amp;go==0)//找下一条线的最右<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(getpixel(xr,y0)!=4)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;go=1;<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;xr--;<BR>&nbsp;&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;while(xl&lt;xr&amp;&amp;go2==0)//找下一条线的最左<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(getpixel(xl,y0)!=4)<BR>&nbsp;&nbsp;&nbsp;go2=1;<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;xl++;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;if(go==1&amp;&amp;go2==1)//如果找到最左和最右，则执行<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;//push(xl,y0);<BR>&nbsp;&nbsp;&nbsp;push(xr,y0);<BR>&nbsp;&nbsp;&nbsp;for(i=xl;i&lt;=xr;i++)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(getpixel(i,y0)!=4)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;else if(getpixel(i-1,y0)!=4)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push(i-1,y0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>}</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P><BR>void main()<BR>{<BR>&nbsp;void fill(int x,int y);<BR>&nbsp;int gdriver,gmode;/*显示模式*/<BR>&nbsp;int i,j;<BR>&nbsp;int n,px,py,px0,py0,px1,py1;<BR>&nbsp;int ya=0,yi=getmaxy();<BR>&nbsp;printf("pleas input the number of the top points:");<BR>&nbsp;scanf("%d",&amp;n);<BR>&nbsp;for(i=0;i&lt;n;i++)//从键盘接受各顶点的坐标，依次入栈，并记录最大Y值和最小Y值<BR>&nbsp;{<BR>&nbsp;&nbsp;printf("please input the coordinate of the points--like:100,200&nbsp; :");<BR>&nbsp;&nbsp;scanf("%d,%d",&amp;px,&amp;py);<BR>&nbsp;&nbsp;if(ya&lt;py)<BR>&nbsp;&nbsp;ya=py;//ya是最大Y值<BR>&nbsp;&nbsp;if(yi&gt;py)<BR>&nbsp;&nbsp;yi=py;//yi是最小Y值<BR>&nbsp;&nbsp;push(px,py);<BR>&nbsp;}<BR>&nbsp;detectgraph(&amp;gdriver,&amp;gmode);<BR>&nbsp;initgraph(&amp;gdriver,&amp;gmode,"c:\\bc31\\bgi");<BR>&nbsp;setbkcolor(0);<BR>&nbsp;cleardevice();<BR>&nbsp;setcolor(4);</P>
<P>&nbsp;pop(px0,py0);//输入的最后一个顶点出栈<BR>&nbsp;px=px0;<BR>&nbsp;py=py0;//记录最后一个顶点<BR>&nbsp;//draw the plot<BR>&nbsp;while(stack != 0)<BR>&nbsp;{<BR>&nbsp;&nbsp;pop(px1,py1);<BR>&nbsp;&nbsp;line(px0,py0,px1,py1);<BR>&nbsp;&nbsp;px0=px1;<BR>&nbsp;&nbsp;py0=py1;<BR>&nbsp;delay(500);<BR>&nbsp;}<BR>&nbsp;line(px0,py0,px,py);//依次画线，画出多边形</P>
<P>&nbsp;//画完多边形后，栈为空</P>
<P>&nbsp;//find the y value<BR>&nbsp;j=(ya+yi)/2;//找Y的中间值,就是第一个种子点的Y值<BR>&nbsp;i=0;<BR>&nbsp;n=0;//记录入栈个数<BR>&nbsp;//find the seed element<BR>&nbsp;while(i&lt;getmaxx()&amp;&amp;n!=2)//按X值从0到X最大值依次查找，并在入栈个数为2的时候退出<BR>&nbsp;{<BR>&nbsp;&nbsp;if(getpixel(i,j)==4)//如果是多边形上的点，则入栈，用n记录入栈的个数<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;push(i,j);<BR>&nbsp;&nbsp;&nbsp;n=n+1;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;i=i+1;//i是记录当前的X值<BR>&nbsp;}<BR>&nbsp;pop(i,j);//第二个交点出栈<BR>&nbsp;pop(n,j);//第一个交点出栈，虽然覆盖了Y值，但这不重要，我们要的是X值<BR>&nbsp;i=(i+n)/2;//现在i是我们要找的种子点的X值<BR>&nbsp;//fill the plot<BR>&nbsp;fill(i,j);//将种子点作为参数传入fill()方法<BR>&nbsp;delay(1000);<BR>&nbsp;outtextxy(100,410,"the red line was drawing,fill over");<BR>&nbsp;getch();<BR>&nbsp;closegraph();<BR>}</P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/4303660120083188521162</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/4303660120083188521162</guid>
    <pubDate>Fri, 18 Apr 2008 08:52:11 +0800</pubDate>
    <dcterms:modified>2008-04-18T08:52:11+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[用C实现多边形的种子填充算法]]></title>	
    <link>http://blog.163.com/liuguangqian_866/blog/static/43036601200831884614180</link>
    <description><![CDATA[<div>这个算法终于实现了,在运行这个程序的时侯,&nbsp;&nbsp;&nbsp;不停的按回车键,可以看到种子填充的路径.呵呵挺好玩的.<BR><BR><BR>/* WIN-TC BGI 图形编程模板 */
<P>#include "Conio.h"<BR>#include "graphics.h"<BR>#define closegr closegraph</P>
<P>void initgr(void) /* BGI初始化 */<BR>{int gd=DETECT,gm=0; /* 和gd=VGA,gm=VGAHI是同样效果 */<BR>&nbsp;registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */<BR>&nbsp;initgraph(&amp;gd,&amp;gm,"");<BR>}<BR>void seedfilling(x,y,fill_color,boundary_color)</P>
<P>int x,y,fill_color,boundary_color;</P>
<P>{</P>
<P>int c;</P>
<P>c=getpixel(x,y); /*获取当前点的颜色*/</P>
<P>if((c!=boundary_color)&amp;&amp;(c!=fill_color))&nbsp; /*如果颜色为边界色则不填充*/</P>
<P>{</P>
<P>putpixel(x, y, fill_color); /*画点*/<BR>getch();&nbsp; /*加上这条语句可以显示填充状态 */</P>
<P>seedfilling(x+1,y, fill_color, boundary_color);</P>
<P>seedfilling(x-1,y, fill_color, boundary_color);</P>
<P>seedfilling(x, y+1, fill_color, boundary_color);</P>
<P>seedfilling(x, y-1, fill_color, boundary_color);</P>
<P>}</P>
<P>}</P>
<P>void main()<BR>{<BR>&nbsp;int a,b,color;</P>
<P>&nbsp;int gd=DETECT , gm;<BR>&nbsp;int poly[10];<BR>&nbsp;a=150&nbsp; ;<BR>&nbsp;b=140;<BR>&nbsp;color=4;<BR>&nbsp;initgraph(&amp;gd , &amp;gm , "");</P>
<P>&nbsp;poly[0] = 110;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 第一个点的x坐标以及y坐标 */<BR>&nbsp;poly[1] = 110;</P>
<P>&nbsp;poly[2] = 200;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 第二点 */<BR>&nbsp;poly[3] = 105;</P>
<P><BR>&nbsp;poly[4] = 170;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 第三点 */<BR>&nbsp;poly[5] = 120;</P>
<P>&nbsp;poly[6]=150;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*第四点*/<BR>&nbsp;poly[7]=170;</P>
<P>&nbsp;poly[8]=110;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*多边形的起点与终点一样*/<BR>&nbsp;poly[9]=110;<BR>&nbsp;drawpoly(5,poly);/* 显示各点连接起来的多边形 */<BR>&nbsp;seedfilling(a,b,color,15);&nbsp; /*种子填充多边形*/</P>
<P>&nbsp;getch();<BR>&nbsp;closegraph();<BR>} </P></div>]]></description>
	    <author><![CDATA[流光]]></author>
	    <comments>http://blog.163.com/liuguangqian_866/blog/static/43036601200831884614180</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/blog/static/43036601200831884614180</guid>
    <pubDate>Fri, 18 Apr 2008 08:46:14 +0800</pubDate>
    <dcterms:modified>2008-04-18T08:46:14+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  17_RkjrCFQwQwCE]]></title>	
    <link>http://img.bimg.126.net/photo/-ZcBP_qfR_ElOq8YiAFSow==/5087660204045437756.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/-ZcBP_qfR_ElOq8YiAFSow==/5087660204045437756.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/-ZcBP_qfR_ElOq8YiAFSow==/5087660204045437756.jpg" border="0" width="240" height="188" alt="17_RkjrCFQwQwCE  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/-ZcBP_qfR_ElOq8YiAFSow==/5087660204045437756.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:59 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:59+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  15_BwFxH66up4AO]]></title>	
    <link>http://img.bimg.126.net/photo/Ng79Nn6KuPikfqENZfQpQg==/4524991725600831738.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/Ng79Nn6KuPikfqENZfQpQg==/4524991725600831738.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/Ng79Nn6KuPikfqENZfQpQg==/4524991725600831738.jpg" border="0" width="240" height="163" alt="15_BwFxH66up4AO  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/Ng79Nn6KuPikfqENZfQpQg==/4524991725600831738.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:58 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:58+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  14_J46v1dJbieFu]]></title>	
    <link>http://img.bimg.126.net/photo/pQXbDvYUkAZo35CGeL8Hww==/5086534304138595227.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/pQXbDvYUkAZo35CGeL8Hww==/5086534304138595227.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/pQXbDvYUkAZo35CGeL8Hww==/5086534304138595227.jpg" border="0" width="240" height="151" alt="14_J46v1dJbieFu  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/pQXbDvYUkAZo35CGeL8Hww==/5086534304138595227.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:58 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:58+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  小样]]></title>	
    <link>http://img.bimg.126.net/photo/V4BKlgs5Lldl668tRRaPfw==/5087660204045437752.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/V4BKlgs5Lldl668tRRaPfw==/5087660204045437752.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/V4BKlgs5Lldl668tRRaPfw==/5087660204045437752.jpg" border="0" width="168" height="240" alt="小样  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/V4BKlgs5Lldl668tRRaPfw==/5087660204045437752.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:57 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:57+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  搞笑图画]]></title>	
    <link>http://img.bimg.126.net/photo/TAF_wKfa2CU-CluWS5RN_g==/330451622658761764.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/TAF_wKfa2CU-CluWS5RN_g==/330451622658761764.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/TAF_wKfa2CU-CluWS5RN_g==/330451622658761764.jpg" border="0" width="240" height="180" alt="搞笑图画  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/TAF_wKfa2CU-CluWS5RN_g==/330451622658761764.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:56 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:56+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  搞笑图画]]></title>	
    <link>http://img.bimg.126.net/photo/o6y0yPvtG_sQGFXu4QtwOg==/2581969961367282092.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/o6y0yPvtG_sQGFXu4QtwOg==/2581969961367282092.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/o6y0yPvtG_sQGFXu4QtwOg==/2581969961367282092.jpg" border="0" width="240" height="204" alt="搞笑图画  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/o6y0yPvtG_sQGFXu4QtwOg==/2581969961367282092.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:55 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:55+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  9_vJaT2dIMm6zN]]></title>	
    <link>http://img.bimg.126.net/photo/8-wZ3WdJaTS8_4LzgrB1XQ==/1127870231679953539.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/8-wZ3WdJaTS8_4LzgrB1XQ==/1127870231679953539.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/8-wZ3WdJaTS8_4LzgrB1XQ==/1127870231679953539.jpg" border="0" width="240" height="240" alt="9_vJaT2dIMm6zN  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/8-wZ3WdJaTS8_4LzgrB1XQ==/1127870231679953539.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:55 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:55+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  8_MDBzMuXvQcGd]]></title>	
    <link>http://img.bimg.126.net/photo/ALTQ1dVDcxH-tVLwHNPNYw==/2819253366734322383.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/ALTQ1dVDcxH-tVLwHNPNYw==/2819253366734322383.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/ALTQ1dVDcxH-tVLwHNPNYw==/2819253366734322383.jpg" border="0" width="190" height="240" alt="8_MDBzMuXvQcGd  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/ALTQ1dVDcxH-tVLwHNPNYw==/2819253366734322383.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:55 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:55+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  7_UXvXn6mdk62t]]></title>	
    <link>http://img.bimg.126.net/photo/5z8LHETd86QzMHXPWOkQcw==/330451622658761775.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/5z8LHETd86QzMHXPWOkQcw==/330451622658761775.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/5z8LHETd86QzMHXPWOkQcw==/330451622658761775.jpg" border="0" width="240" height="240" alt="7_UXvXn6mdk62t  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/5z8LHETd86QzMHXPWOkQcw==/330451622658761775.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:54 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:54+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  6_cgrSFFlbhC09]]></title>	
    <link>http://img.bimg.126.net/photo/-YSoTD8pgO3-Q3eGPonZwg==/4524991725600831733.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/-YSoTD8pgO3-Q3eGPonZwg==/4524991725600831733.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/-YSoTD8pgO3-Q3eGPonZwg==/4524991725600831733.jpg" border="0" width="240" height="146" alt="6_cgrSFFlbhC09  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/-YSoTD8pgO3-Q3eGPonZwg==/4524991725600831733.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:54 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:54+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  悲哀]]></title>	
    <link>http://img.bimg.126.net/photo/73h3CAqkPTVdxsKhQZ_y5Q==/4016929392638236703.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/73h3CAqkPTVdxsKhQZ_y5Q==/4016929392638236703.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/73h3CAqkPTVdxsKhQZ_y5Q==/4016929392638236703.jpg" border="0" width="240" height="165" alt="悲哀  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/73h3CAqkPTVdxsKhQZ_y5Q==/4016929392638236703.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:53 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:53+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  3_Dprg9gwCIhmM]]></title>	
    <link>http://img.bimg.126.net/photo/rw5_Hrz6BumLN15CLLHXRg==/632474272669181253.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/rw5_Hrz6BumLN15CLLHXRg==/632474272669181253.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/rw5_Hrz6BumLN15CLLHXRg==/632474272669181253.jpg" border="0" width="179" height="240" alt="3_Dprg9gwCIhmM  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/rw5_Hrz6BumLN15CLLHXRg==/632474272669181253.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:53 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:53+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  2_keQbH46B7otI]]></title>	
    <link>http://img.bimg.126.net/photo/XUVeufqMZP_vWF9P6zSF0Q==/4575094271455415562.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/XUVeufqMZP_vWF9P6zSF0Q==/4575094271455415562.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/XUVeufqMZP_vWF9P6zSF0Q==/4575094271455415562.jpg" border="0" width="240" height="238" alt="2_keQbH46B7otI  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/XUVeufqMZP_vWF9P6zSF0Q==/4575094271455415562.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:44:52 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:44:52+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  网恋]]></title>	
    <link>http://img.bimg.126.net/photo/FrWOWkhDfRak2qZ3DxJtvg==/5072742030279673035.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/FrWOWkhDfRak2qZ3DxJtvg==/5072742030279673035.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/FrWOWkhDfRak2qZ3DxJtvg==/5072742030279673035.jpg" border="0" width="220" height="240" alt="网恋  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/FrWOWkhDfRak2qZ3DxJtvg==/5072742030279673035.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:43:23 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:43:23+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  网恋]]></title>	
    <link>http://img.bimg.126.net/photo/SCw1DmYPNhrKKsnzeTSxKA==/5072742030279673034.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/SCw1DmYPNhrKKsnzeTSxKA==/5072742030279673034.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/SCw1DmYPNhrKKsnzeTSxKA==/5072742030279673034.jpg" border="0" width="188" height="240" alt="网恋  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/SCw1DmYPNhrKKsnzeTSxKA==/5072742030279673034.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:43:22 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:43:22+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  网恋]]></title>	
    <link>http://img.bimg.126.net/photo/QOy53zTdF6xNCNAbhT3Icw==/5087660204045437742.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/QOy53zTdF6xNCNAbhT3Icw==/5087660204045437742.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/QOy53zTdF6xNCNAbhT3Icw==/5087660204045437742.jpg" border="0" width="232" height="240" alt="网恋  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/QOy53zTdF6xNCNAbhT3Icw==/5087660204045437742.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:43:22 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:43:22+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  网恋只会让寂寞的人更寂寞]]></title>	
    <link>http://img.bimg.126.net/photo/Lk6dtw3q6cfCd6y6rKB3Gw==/5086534304138595208.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/Lk6dtw3q6cfCd6y6rKB3Gw==/5086534304138595208.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/Lk6dtw3q6cfCd6y6rKB3Gw==/5086534304138595208.jpg" border="0" width="220" height="240" alt="网恋只会让寂寞的人更寂寞  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/Lk6dtw3q6cfCd6y6rKB3Gw==/5086534304138595208.jpg</guid>
    <pubDate>Tue, 9 Oct 2007 08:43:20 +0800</pubDate>
    <dcterms:modified>2007-10-09T08:43:20+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  我不后悔．爱你．]]></title>	
    <link>http://img.bimg.126.net/photo/RCQPGn8J_xY1wfdVTbIPGw==/4302907968976125480.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/RCQPGn8J_xY1wfdVTbIPGw==/4302907968976125480.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/RCQPGn8J_xY1wfdVTbIPGw==/4302907968976125480.jpg" border="0" width="240" height="184" alt="我不后悔．爱你．  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/RCQPGn8J_xY1wfdVTbIPGw==/4302907968976125480.jpg</guid>
    <pubDate>Fri, 5 Oct 2007 14:34:40 +0800</pubDate>
    <dcterms:modified>2007-10-05T14:34:40+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  回到了一个人的季节．]]></title>	
    <link>http://img.bimg.126.net/photo/YPDokOFi1jv_dmPLx6XLIQ==/333266372425744088.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/YPDokOFi1jv_dmPLx6XLIQ==/333266372425744088.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/YPDokOFi1jv_dmPLx6XLIQ==/333266372425744088.jpg" border="0" width="240" height="181" alt="回到了一个人的季节．  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/YPDokOFi1jv_dmPLx6XLIQ==/333266372425744088.jpg</guid>
    <pubDate>Fri, 5 Oct 2007 14:34:40 +0800</pubDate>
    <dcterms:modified>2007-10-05T14:34:40+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  风景]]></title>	
    <link>http://img.bimg.126.net/photo/uEWi4viiailB4CMr1xdJHw==/2306968909120858082.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.bimg.126.net/photo/uEWi4viiailB4CMr1xdJHw==/2306968909120858082.jpg" target="_blank">
	<img src="http://img.bimg.126.net/photo/uEWi4viiailB4CMr1xdJHw==/2306968909120858082.jpg" border="0" width="240" height="180" alt="风景  "/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/uEWi4viiailB4CMr1xdJHw==/2306968909120858082.jpg</guid>
    <pubDate>Fri, 5 Oct 2007 14:32:51 +0800</pubDate>
    <dcterms:modified>2007-10-05T14:32:51+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[web:  我的收藏]]></title>	
    <link>http://blog.163.com/liuguangqian_866/prevResource.do?selectId=fks_084064081094088071085080074071087086082069082086087</link>
    <description><![CDATA[<ul>
	<li>
	<a href="http://hncswcq.blog.163.com" target="_blank">沙漠雨 的网易博客</a>
	: 沙漠雨 的网易博客</li>

	<li>
	<a href="http://tomleesj.blog.163.com" target="_blank">雪儿 的网易博客</a>
	: 雪儿 的网易博客</li>

	<li>
	<a href="http://blog.163.com/shiliju_123" target="_blank">等候～～ 的网易博客</a>
	: 等候～～ 的网易博客</li>
</ul>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">collection/static/fks_084064081094088071085080074071087086082069082086087</guid>
    <pubDate>Mon, 12 Nov 2007 15:09:48 +0800</pubDate>
    <dcterms:modified>2007-11-12T15:09:48+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[rss:  我的订阅]]></title>	
    <link>http://blog.163.com/liuguangqian_866/prevResource.do?selectId=fks_084064081094088071085083074071087086082069082086087</link>
    <description><![CDATA[<ul>
	<li>
	<a href="http://zhouguoling523.blog.163.com/rss/" target="_blank">雪上飘 的网易博客</a>
	: 雪上飘 的网易博客</li>

	<li>
	<a href="http://yuqinga.blog.163.com/rss/" target="_blank">蓝猫 的网易博客</a>
	: 蓝猫 的网易博客</li>

	<li>
	<a href="http://blog.163.com/shiliju_123/rss/" target="_blank">等候～～ 的网易博客</a>
	: 等候～～ 的网易博客</li>
</ul>]]></description>
	    <author><![CDATA[liuguangqian_866]]></author>
    <guid isPermaLink="false">collection/static/fks_084064081094088071085083074071087086082069082086087</guid>
    <pubDate>Mon, 12 Nov 2007 15:09:35 +0800</pubDate>
    <dcterms:modified>2007-11-12T15:09:35+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[流光关注的博友]]></title>	
    <link>http://blog.163.com/liuguangqian_866/friends</link>
    <description><![CDATA[<div>
			<a href="http://liman169.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/XdDUEX9cZCfwlFiCneP4-w==/171418260817206741.jpg" border="0" />微雨潇潇</a>
			<a href="http://kjhkdx2005.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/cywoHg-ay99EmudIg78eFg==/178173660258116767.jpg" border="0" />蓝天上的骑兵</a>
			<a href="http://sunnytianrui.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/pW-6PWPrH2rPWMMhqkv8ZA==/171699735794580317.jpg" border="0" />藏东爱心传递......</a>
			<a href="http://2008beijingnet.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/aX4bWMQgUJTTzwRUbr6bwg==/210824757556649658.jpg" border="0" />纯情少女</a>
			<a href="http://xinchenfeicll.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/7QKq9dCdyOA4s7PZXFk6DA==/170010885935558421.jpg" border="0" />╰☆清水淡荷</a>
			<a href="http://heuly2008.blog.163.com/" target="_blank"><img src="http://ava.bimg.126.net/photo/avZfumovrnZnwftiuf7JNQ==/198439858581203751.jpg" border="0" />国防卫士</a>
</div>]]></description>
    <guid isPermaLink="true">http://blog.163.com/liuguangqian_866/friends</guid>
    <pubDate>Tue, 1 Jan 2008 00:00:00 +0800</pubDate>
    <dcterms:modified>2008-01-01T00:00:00+08:00</dcterms:modified>
  </item>    
 </channel>
</rss>