﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-深海拾贝-随笔分类-VC++</title><link>http://www.cppblog.com/coloerful/category/10640.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 30 Jul 2009 19:09:54 GMT</lastBuildDate><pubDate>Thu, 30 Jul 2009 19:09:54 GMT</pubDate><ttl>60</ttl><item><title>用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置 </title><link>http://www.cppblog.com/coloerful/archive/2009/07/31/91756.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Thu, 30 Jul 2009 16:20:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/07/31/91756.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/91756.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/07/31/91756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/91756.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/91756.html</trackback:ping><description><![CDATA[<p>用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。</p>
<p>void MoveWindow(int x,int y,int nWidth,int nHeight);<br>void MoveWindow(LPCRECT lpRect);<br>第一种用法需给出控件新的坐标和宽度、高度；<br>第二种用法给出存放位置的CRect对象；<br>例：<br>CWnd *pWnd;<br>pWnd = GetDlgItem( IDC_EDIT1 );&nbsp;&nbsp;&nbsp; //获取控件指针，IDC_EDIT1为控件ID号<br>pWnd-&gt;MoveWindow( CRect(0,0,100,100) );&nbsp;&nbsp;&nbsp; //在窗口左上角显示一个宽100、高100的编辑控件</p>
<p>SetWindowPos()函数使用更灵活，多用于只修改控件位置而大小不变或只修改大小而位置不变的情况：<br>BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);<br>第一个参数我不会用，一般设为NULL;<br>x、y控件位置；cx、cy控件宽度和高度；<br>nFlags常用取值：<br>SWP_NOZORDER：忽略第一个参数；<br>SWP_NOMOVE：忽略x、y，维持位置不变；<br>SWP_NOSIZE：忽略cx、cy，维持大小不变；<br>例：<br>CWnd *pWnd;<br>pWnd = GetDlgItem( IDC_BUTTON1 );&nbsp;&nbsp;&nbsp; //获取控件指针，IDC_BUTTON1为控件ID号<br>pWnd-&gt;SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE );&nbsp;&nbsp;&nbsp; //把按钮移到窗口的(50,80)处<br>pWnd = GetDlgItem( IDC_EDIT1 );<br>pWnd-&gt;SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE );&nbsp;&nbsp;&nbsp; //把编辑控件的大小设为(100,80)，位置不变<br>pWnd = GetDlgItem( IDC_EDIT1 );<br>pWnd-&gt;SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER );&nbsp;&nbsp;&nbsp; //编辑控件的大小和位置都改变<br>以上方法也适用于各种窗口。</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/91756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-07-31 00:20 <a href="http://www.cppblog.com/coloerful/archive/2009/07/31/91756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc 鼠标右击事件</title><link>http://www.cppblog.com/coloerful/archive/2009/07/30/91755.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Thu, 30 Jul 2009 15:47:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/07/30/91755.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/91755.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/07/30/91755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/91755.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/91755.html</trackback:ping><description><![CDATA[<p>#define ID_MENUITEM_OPEN&nbsp;&nbsp;1001<br>#define ID_MENUITEM_DISPLAY&nbsp;&nbsp;1002<br>#define ID_MENUITEM_DELETE&nbsp;&nbsp;1003<br>#define ID_MENUITEM_EXIT&nbsp;&nbsp;1004&nbsp;<br><br><br>CPoint point; <br>&nbsp;&nbsp;GetCursorPos(&amp;point); </p>
<p>&nbsp;&nbsp;CMenu menuPopup; </p>
<p>&nbsp;&nbsp;menuPopup.CreatePopupMenu(); <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_STRING, ID_MENUITEM_OPEN, "打开" ); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_SEPARATOR ); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_STRING, ID_MENUITEM_DISPLAY, "显示" ); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_SEPARATOR ); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_STRING, ID_MENUITEM_DELETE, "删除"); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_SEPARATOR ); <br>&nbsp;&nbsp;menuPopup.AppendMenu( MF_STRING, ID_MENUITEM_EXIT, "退出"); </p>
<p><br>&nbsp;&nbsp;int nCmd = ( int ) menuPopup.TrackPopupMenu(&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TPM_LEFTALIGN&nbsp; | TPM_LEFTBUTTON&nbsp; | TPM_RIGHTBUTTON&nbsp; | TPM_RETURNCMD,&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; point.x, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.y,&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxGetMainWnd() ); </p>
<p>&nbsp;&nbsp;switch( nCmd ) <br>&nbsp;&nbsp;{ <br>&nbsp;&nbsp;case ID_MENUITEM_OPEN:<br>&nbsp;&nbsp;&nbsp;OnOpenButton() ;<br>&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;case ID_MENUITEM_DISPLAY: <br>&nbsp;&nbsp;&nbsp;OnChartButton();<br>&nbsp;&nbsp;&nbsp;break; <br>&nbsp;&nbsp;case ID_MENUITEM_DELETE: <br>&nbsp;&nbsp;&nbsp;OnDeleteButton();<br>&nbsp;&nbsp;&nbsp;break; <br>&nbsp;&nbsp;case ID_MENUITEM_EXIT: <br>&nbsp;&nbsp;&nbsp;exit(0);&nbsp;&nbsp; <br>&nbsp;&nbsp;}</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/91755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-07-30 23:47 <a href="http://www.cppblog.com/coloerful/archive/2009/07/30/91755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC 保存对话框为图片</title><link>http://www.cppblog.com/coloerful/archive/2009/07/30/91751.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Thu, 30 Jul 2009 15:33:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/07/30/91751.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/91751.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/07/30/91751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/91751.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/91751.html</trackback:ping><description><![CDATA[<p>#include "WINDOWSX.H"<br><br>&nbsp;CClientDC SHDC(this);//取得客户区内存DC<br>&nbsp;CPaintDC&nbsp;&nbsp; dc(this);<br>&nbsp;CDC memDC;<br>&nbsp;CRect rect;<br>&nbsp;GetClientRect(rect);</p>
<p>&nbsp;memDC.CreateCompatibleDC(&amp;SHDC);<br>&nbsp;CBitmap bm;<br>&nbsp;int Width = rect.Width();//<br>&nbsp;int Height = rect.Height();//<br>&nbsp;bm.CreateCompatibleBitmap(&amp;SHDC, Width, Height);<br>&nbsp;CBitmap*&nbsp; pOld = memDC.SelectObject(&amp;bm);<br>&nbsp;memDC.BitBlt(0, 0, Width, Height, &amp;SHDC, 0, 0, SRCCOPY);<br>&nbsp;memDC.SelectObject(pOld);<br>&nbsp;BITMAP&nbsp; btm;<br>&nbsp;bm.GetBitmap(&amp;btm);<br>&nbsp;DWORD&nbsp; size = btm.bmWidthBytes * btm.bmHeight;<br>&nbsp;LPSTR lpData =(LPSTR)GlobalAllocPtr(GPTR, size);<br>&nbsp;BITMAPFILEHEADER&nbsp;&nbsp; bfh;<br>/////////////////////////////////////////////<br>&nbsp;BITMAPINFOHEADER&nbsp; bih;<br>&nbsp;bih.biBitCount = btm.bmBitsPixel;<br>&nbsp;bih.biClrImportant = 0;<br>&nbsp;bih.biClrUsed = 0;<br>&nbsp;bih.biCompression = 0;<br>&nbsp;bih.biHeight = btm.bmHeight;<br>&nbsp;bih.biPlanes = 1;<br>&nbsp;bih.biSize = sizeof(BITMAPINFOHEADER);<br>&nbsp;bih.biSizeImage = size;<br>&nbsp;bih.biWidth = btm.bmWidth;<br>&nbsp;bih.biXPelsPerMeter = 0;<br>&nbsp;bih.biYPelsPerMeter = 0;<br>&nbsp;GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&amp;bih,DIB_RGB_COLORS);<br>&nbsp;bfh.bfReserved1 = bfh.bfReserved2 = 0;<br>&nbsp;bfh.bfType = ((WORD)('M'&lt;&lt; 8)|'B');<br>&nbsp;bfh.bfSize = 54 + size;<br>&nbsp;bfh.bfOffBits = 54;</p>
<p>&nbsp;CFileDialog dlg(false,_T("BMP"),_T("*.bmp"),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("*.bmp|*.bmp|*.*|*.*|"));<br>&nbsp;if (dlg.DoModal()==IDOK)<br>&nbsp;{<br>&nbsp;&nbsp;CFile&nbsp; bf;<br>&nbsp;&nbsp;CString ss=dlg.GetPathName();<br>&nbsp;&nbsp;if(bf.Open(ss, CFile::modeCreate | CFile::modeWrite))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;bf.WriteHuge(&amp;bfh, sizeof(BITMAPFILEHEADER));<br>&nbsp;&nbsp;&nbsp;bf.WriteHuge(&amp;bih, sizeof(BITMAPINFOHEADER));<br>&nbsp;&nbsp;&nbsp;bf.WriteHuge(lpData, size);<br>&nbsp;&nbsp;&nbsp;bf.Close();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;GlobalFreePtr(lpData);<br>&nbsp;}</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/91751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-07-30 23:33 <a href="http://www.cppblog.com/coloerful/archive/2009/07/30/91751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CString 与其他数据类型的转换（转）</title><link>http://www.cppblog.com/coloerful/archive/2009/06/07/87018.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Sun, 07 Jun 2009 13:44:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/06/07/87018.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/87018.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/06/07/87018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/87018.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/87018.html</trackback:ping><description><![CDATA[<div><font color=#cc6633><strong>1 CString,int,string,char*之间的转换</strong> <br>string 转 CString <br>CString.format("%s", string.c_str()); <br>char 转 CString <br>CString.format("%s", char*); <br>char 转 string <br>string s(char *); <br>string 转 char * <br>char *p = string.c_str(); <br>CString 转 string <br>string s(CString.GetBuffer()); <br>1，string -&gt; CString <br>CString.format("%s", string.c_str()); <br>用c_str()确实比data()要好. <br>2，char -&gt; string <br>string s(char *); <br>你的只能初始化，在不是初始化的地方最好还是用assign(). <br>3,CString -&gt; string <br>string s(CString.GetBuffer()); <br>GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间. <br><br>《C++标准函数库》中说的 <br>有三个函数可以将字符串的内容转换为字符数组和C—string <br>1.data(),返回没有&#8221;\0&#8220;的字符串数组 <br>2,c_str()，返回有&#8221;\0&#8220;的字符串数组 <br>3，copy() <br><br>CString互转int <br>将字符转换为整数，可以使用atoi、_atoi64或atol。 <br>而将数字转换为CString变量，可以使用CString的Format函数。如 <br>CString s; <br>int i = 64; <br>s.Format("%d", i) <br>Format函数的功能很强，值得你研究一下。 <br>void CStrDlg::OnButton1() <br>{ <br>// TODO: Add your control notification handler code here <br>CString <br>ss="1212.12"; <br>int temp=atoi(ss); <br>CString aa; <br>aa.Format("%d",temp); <br>AfxMessageBox("var is " + aa); <br>} <br>sart.Format("%s",buf); <br>CString互转char* <br>///char * TO cstring <br>CString strtest; <br>char * charpoint; <br>charpoint="give string a value"; <br>strtest=charpoint; <br><br>///cstring TO char * <br>charpoint=strtest.GetBuffer(strtest.GetLength()); <br>标准C里没有string,char *==char []==string <br>可以用CString.Format("%s",char *)这个方法来将char *转成CString。要把CString转成char *，用操作符（LPCSTR）CString就可以了。 <br><br>CString转换 char[100] <br>char a[100]; <br>CString str("aaaaaa"); <br>strncpy(a,(LPCTSTR)str,sizeof(a)); <br></font><font color=#cc6633><strong>2 CString类型的转换成int <br></strong>CString类型的转换成int <br>将字符转换为整数，可以使用atoi、_atoi64或atol。 <br>//CString aaa = "16" ; <br>//int int_chage = atoi((lpcstr)aaa) ; <br><br>而将数字转换为CString变量，可以使用CString的Format函数。如 <br>CString s; <br>int i = 64; <br>s.Format("%d", i) <br>Format函数的功能很强，值得你研究一下。 <br>如果是使用char数组，也可以使用sprintf函数。 <br>//CString ss="1212.12"; <br>//int temp=atoi(ss); <br>//CString aa; <br>//aa.Format("%d",temp); <br><br>数字-&gt;字符串除了用CString::Format，还有FormatV、sprintf和不需要借助于Afx的itoa <br><br><strong>3 char* 在装int</strong> <br>#include &lt;stdlib.h&gt; <br><br>int atoi(const char *nptr); <br>long atol(const char *nptr); <br>long long atoll(const char *nptr); <br>long long atoq(const char *nptr); <br><br><strong>4 CString,int,string,char*之间的转换</strong> <br>string aa("aaa"); <br>char *c=aa.c_str(); <br><br>cannot convert from 'const char *' to 'char *' <br>const char *c=aa.c_str(); <br><br></font><font color=#cc6633><strong>5 CString,int,string,char*之间的转换 <br></strong>string.c_str()只能转换成const char *, <br>要转成char *这样写: <br>string mngName； <br>char t[200]; memset(t,0,200); strcpy(t,mngName.c_str()); </font></div>
<div><font color=#cc6633></font>&nbsp;</div>
<div><font color=#cc6633></font>&nbsp;</div>
<div><font color=#cc6633></font>&nbsp;</div>
<div><font color=#cc6633>UpdateData(TRUE) <br>//比如CEDIT 控件连接的变量叫m_strEditString; <br>if (m_strEditString.GetLength()&gt;=500) <br>{ <br>MessageBox(_T("长度不够"_,_T(""),MB_ICONSTOP)//ERROR <br>} <br>else <br>{ <br>strcpy(st,m_strEditString.GetBuffer(0)); <br>} <br>//以下是转换 <br>1、CString::GetBuffer(0);//取得CString的char* <br>2、int intv=atoi(CString::GetBuffer(0));//CString to Int <br>3、float floatv=(float)atof(CString::GetBuffer(0));//CString to float <br>4、long longvv=atol(CString::GetBuffer(0));//CString to Long <br>5、double doublev=atof(CString::GetBuffer(0));//CString to Double <br>6、CString::Format(_T("%d,%f,%ld,%lf,%c,%s"),int,float,long,double,char,char*)//各类型到CString</font></div>
<img src ="http://www.cppblog.com/coloerful/aggbug/87018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-06-07 21:44 <a href="http://www.cppblog.com/coloerful/archive/2009/06/07/87018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc 用法汇总（转）</title><link>http://www.cppblog.com/coloerful/archive/2009/06/02/86603.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Tue, 02 Jun 2009 15:31:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/06/02/86603.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/86603.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/06/02/86603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/86603.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/86603.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: VC用法汇总（1）如何通过代码获得应用程序主窗口的指针?主窗口的指针保存在CWinThread::m_pMainWnd中,调用AfxGetMainWnd实现。AfxGetMainWnd() -&gt;ShowWindow(SW_SHOWMAXMIZED)//使程序最大化.（2）确定应用程序的路径Use GetModuleFileName 获得应用程序的路径，然后去掉可执行文件名。Example...&nbsp;&nbsp;<a href='http://www.cppblog.com/coloerful/archive/2009/06/02/86603.html'>阅读全文</a><img src ="http://www.cppblog.com/coloerful/aggbug/86603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-06-02 23:31 <a href="http://www.cppblog.com/coloerful/archive/2009/06/02/86603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC中获取 资源指针的方法</title><link>http://www.cppblog.com/coloerful/archive/2009/06/01/86368.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Mon, 01 Jun 2009 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/06/01/86368.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/86368.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/06/01/86368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/86368.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/86368.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 12pt; COLOR: #f70909">获取工具条的指针</span><span style="FONT-SIZE: 12pt"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt">在缺省状态下，有一个默认的工具条<span>AFX_IDW_TOOLBAR</span>，我们可以根据相应的<span>ID</span>去获取工具条指针，方法如下：<span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CToolBar* pToolBar=(CToolBar*)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_TOOLBAR);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>是不是很简单？<span><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #f70909">获取状态条的指针</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>在缺省状态下，有一个默认的状态条<span>AFX_IDW_STATUS_BAR</span>，我们自然也可以根据相应的<span>ID</span>去获取状态条指针，方法如下：<span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CStatusBar* pToolBar=(CStatusBar*)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_STATUS_BAR);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>是不是同样很简单？<span></span></span>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #ee1111">获取控件的指针 </span><span style="FONT-SIZE: 12pt"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt">这里有两种方法。<span><br>&nbsp;&nbsp;&nbsp;&nbsp;</span>一、调用<span>CWnd: : GetDlgItem</span>，获取一个<span>CWnd*</span>指针调用成员函数。例如，我们想获取<span>CButton</span>指针，方法如下：<span><br>&nbsp;&nbsp;&nbsp;&nbsp; CButton* pButton=(CButton*) GetDlgItem (IDC_MYBUTTON);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span>二、可以使用<span>ClassWizard</span>将控件和成员变量联系起来。在<span>ClassWizard</span>中简单地选择<span>Member Variables</span>标签，然后选择<span>Add Variable ...</span>按钮。如果在对话资源编辑器中，按下<span>Ctrl</span>键并双击控件即可转到<span>Add Member Variable</span>对话。<span></span></span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #f70909">在文档类中调用视图类指针<span><br>&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="FONT-SIZE: 12pt">我们可以利用文档类的成员函数<span>GetFirstView()</span>和<span>GetNextView()</span>遍历视图。<span></span></span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #ee1111">在视图类中调用文档类</span><span style="FONT-SIZE: 12pt"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt">其实，在视图类中有一个现成的成员函数供我们使用，那就是：<span>GetDocument();</span>利用它我们可以很容易的得到文档类指针，我们先看一下<span>GetDocument()</span>函数的实现：<span><br>&nbsp;&nbsp;&nbsp;&nbsp; CColorButtonDoc* CColorButtonView::GetDocument() <br>&nbsp;&nbsp;&nbsp; {<br>ASSERT(m_pDocument-&gt;IsKindOf(RUNTIME_CLASS(CColorButtonDoc)));<br>return (CColorButtonDoc*)m_pDocument;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;</span>这里实际上是将<span>m_pDocument</span>强制转换成<span>CColorButtonDoc*</span>，也就是我们想要的。<span></span></span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #ee1111">在框架类中调用文档类、视图类<span><br>&nbsp;&nbsp;&nbsp;</span></span><span style="FONT-SIZE: 12pt">这里我们可以利用<span>GetActiveXXXXX()</span>去掉用当前激活的文档和视图：<span><br>&nbsp;&nbsp;&nbsp; CMyDoc*&nbsp;&nbsp; pDoc=(CMyDoc*)GetActiveDocument();<br>&nbsp;&nbsp;&nbsp; CMyView* pView=(CMyView*)GetActiveView();</span></span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #ee1111">获得应用程序指针</span><span style="FONT-SIZE: 12pt"><br>&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt">这个很简单，一句话搞定：<span><br>&nbsp;&nbsp;&nbsp; CMyApp* pApp=(CMyApp*)AfxGetApp();</span></span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 12pt; COLOR: #ee1111">获得主框架指针<span><br>&nbsp;&nbsp;&nbsp;</span></span><span style="FONT-SIZE: 12pt">在类<span>CWinThread</span>里面有一个公有的成员变量：<span>CWnd* m_pMainWnd; </span>它存在的主要目的就是提供我们获得<span>CWnd</span>指针，我们可以利用它来达到我们的目的：<span><br>&nbsp;&nbsp;&nbsp; CMainFrame* pFrame=(CMainFrame*)(AfxGetApp()-&gt;m_pMainWnd);<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ee1111">通过鼠标获得子窗口指针</span><span><br>&nbsp;&nbsp;&nbsp;</span>这里我们要用到一个不太常用的函数：<span>ChildWindowFromPoint</span>。他的原型如下：<span><br>&nbsp;&nbsp;&nbsp; CWnd* ChildWindowFromPoint(POINT point) const;<br>&nbsp;&nbsp;&nbsp; CWnd* ChildWindowFromPoint(POINT point,UINT nFlags) const;<br>&nbsp;&nbsp;&nbsp;</span>这个函数用于确定包含指定点的子窗口，如果指定点在客户区之外，函数返回<span>NULL</span>；如果指定点在客户区内，但是不属于任何一个子窗口，函数返回该<span>CWnd</span>的指针；如果有多个子窗口包含指定点，则返回第一个子窗口的指针。不过，这里还要注意的是：该函数返回的是一个伪窗口指针，不能将它保存起来供以后使用。<span><br>&nbsp;&nbsp;&nbsp;</span>对于第二个参数<span>nFlags</span>有几个含义：<span><br>&nbsp;&nbsp;&nbsp; CWP_ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不</span>忽略任何子窗口<span><br>&nbsp;&nbsp;&nbsp; CWP_SKIPNIVSIBLE&nbsp;&nbsp;&nbsp;&nbsp; 忽</span>略不可见子窗口<span><br>&nbsp;&nbsp;&nbsp; CWP_SKIPDISABLED&nbsp;&nbsp;&nbsp;&nbsp; 忽</span>略禁止的子窗口<span><br></span>　<span> CWP_SKIPRANSPARENT&nbsp;&nbsp; 忽</span>略透明子窗口</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">---------------------------------------------------------------------</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">总结：</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; 使用类的继承，自定义的新类同样可以通过强制转换获得一个dlg的指针保存以便提高程序运行速度。如同以上例子中的文档类的CMyDoc，既然同样是个自动生成的继承类，同样也可以避免直接使用GetDlgItem在VC++中不显示函数列表的蔽端。但对控件操作较少的情况下，保存指针会造成程序运算空间增大。（以上适合初学者）</span></p>
<img src ="http://www.cppblog.com/coloerful/aggbug/86368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-06-01 11:13 <a href="http://www.cppblog.com/coloerful/archive/2009/06/01/86368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc ++ ADO数据库访问于FlexGrid控件综合使用的修改</title><link>http://www.cppblog.com/coloerful/archive/2009/05/30/86172.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Sat, 30 May 2009 07:19:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/30/86172.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/86172.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/30/86172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/86172.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/86172.html</trackback:ping><description><![CDATA[<p>今天有弄了一下，发现原来GetCollect（_variant_t(long（Index）)）；就可以一字段的索引作为参数。那这样操作就方便多了。发那些填充GRID控件的代码改为：<br></p>
&nbsp;for(long CurRow = 1; CurRow &lt;= RecordNum ; CurRow++)<br>&nbsp;{<br>&nbsp;&nbsp;CString str;<br>&nbsp;&nbsp;_variant_t vstr;<br>&nbsp;&nbsp;m_DataGrid.SetRow(CurRow);<br>&nbsp;&nbsp;for(int CurCol = 0; CurCol&lt;4; CurCol++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect(_variant_t(long(CurCol)));<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();<br>&nbsp;}
<img src ="http://www.cppblog.com/coloerful/aggbug/86172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-30 15:19 <a href="http://www.cppblog.com/coloerful/archive/2009/05/30/86172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++中基于ADO操作ACCESS数据库，FLEXGRID控件的综合应用</title><link>http://www.cppblog.com/coloerful/archive/2009/05/29/86107.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 29 May 2009 13:37:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/29/86107.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/86107.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/29/86107.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/86107.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/86107.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 8pt">耗费了一下午，研究了一下VC的数据库编程，写了这个测试程序。主要的功能为实现access数据库的添加与删除，同时动态的将数据库数据显示在flexgrid控件中。下面把过程记录下来，以备后用。<br><br><strong>一。ADO简介</strong><br></span><font size=2><span style="FONT-SIZE: 8pt">&nbsp;ADO提供了一组非常简单，将一般通用的数据访问细节进行封装的对象。由于ODBC数据源也提供了一般的OLE DB Privider，所以ADO不仅可以应用自身的OLE DB Privider，而且还可以应用所有的ODBC驱动程序。关于OLE DB和ADO的其它详细情况，读者可以自行查阅相关书籍或MSDN，这里就不一一说明了。让我们直接步入主题，如何掌握ADO这种数据库访问技术ADO的操作方法和前面讲过的DAO的操作在很多方面存在相似之处。<br>二。主要控件的布置<br>程序运行效果如图：<br><img height=439 alt="" src="http://www.cppblog.com/images/cppblog_com/coloerful/database.jpg" width=645 border=0><br><br><strong>1.进入工程向导，建立基于对话框的mfc应用程序。名为databasetest。<br></strong>加入flexgrid控件：工程---&gt;添加到工程-------&gt;components and controls。找到Microsoft Flexgrid control，然后insert。添加几个static box 和editbox，添加两个botton，实现插入和删除的功能。<br>2.打开access2003，建立空数据库Demo.mdb。建立表Table1。设置编号，时间，采样点数，累加次数，数据5个字段，分别为自动编号，时间/日期，数字，数字和备注类型<br>如图：<br><img height=159 alt="" src="http://www.cppblog.com/images/cppblog_com/coloerful/access.jpg" width=626 border=0><br><br><strong>三。数据库操作过程</strong><br>1.用#import指令引入ADO类型库<br>要用#import语句来引用支持ADO的组件类型库(*.tlb)，其中类型库可以作为可执行程序(DLL、EXE等)的一部分被定位在其自身程序中的附属资源里，如：被定位在msado15.dll的附属资源中，只需要直接用 #import引用它既可。可以直接在Stdafx.h文件中加入下面语句来实现：<br><br></span>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td><font size=2>#import "c:\program files\common files\system\ado\msado15.dll" \<br>no_namespace \<br>rename ("EOF", "adoEOF") </font></td>
        </tr>
    </tbody>
</table>
<p><br><font size=2>　　其中路径名可以根据自己系统安装的ADO支持文件的路径来自行设定。当编译器遇到#import语句时，它会为引用组件类型库中的接口生成包装类，#import语句实际上相当于执行了API涵数LoadTypeLib()。#import语句会在工程可执行程序输出目录中产生两个文件，分别为*.tlh(类型库头文件)及*.tli(类型库实现文件)，它们分别为每一个接口产生智能指针，并为各种接口方法、枚举类型，CLSID等进行声明，创建一系列包装方法。语句no_namespace说明ADO对象不使用命名空间，rename ("EOF", "adoEOF")说明将ADO中结束标志EOF改为adoEOF，以避免和其它库中命名相冲突。<br></font><strong>2.COM初始化<br></strong>使用AfxOleInit()来初始化COM库，这项工作通常在CWinApp::InitInstance()的重载函数中完成。代码如下：<br>BOOL CDatabasetestApp::InitInstance()<br>{<br>&nbsp;&nbsp;&nbsp;................................<br>&nbsp;&nbsp;&nbsp;AfxOleInit();<br>..................................<br>}<br><strong>3.CDatabasetestDlg.h中定义个控件类变量</strong>：<br><br>&nbsp;// 定义ADO连接、命令、记录集变量指针<br>&nbsp;_ConnectionPtr&nbsp;m_pConnection;<br>&nbsp;_CommandPtr&nbsp;&nbsp;m_pCommand;<br>&nbsp;_RecordsetPtr&nbsp;m_pRecordset;<br><br>// Dialog Data<br>&nbsp;//{{AFX_DATA(CDatabasetestDlg)<br>&nbsp;enum { IDD = IDD_DATABASETEST_DIALOG };<br>&nbsp;CEdit&nbsp;m_CSamplingTime;<br>&nbsp;CString&nbsp;m_SamplingTime;<br>&nbsp;UINT&nbsp;m_AccNum;<br>&nbsp;UINT&nbsp;m_SamplingNum;<br>&nbsp;CMSFlexGrid&nbsp;m_DataGrid;<br>&nbsp;//}}AFX_DATA</p>
<p>&nbsp;// ClassWizard generated virtual function overrides<br>&nbsp;//{{AFX_VIRTUAL(CDatabasetestDlg)</font></p>
<p><strong><span style="FONT-SIZE: 8pt">4.这样就可以数据库的实际操作了。首先在主应用程序databasetext.cpp中。主对话框弹出之前添加代码，</span><font size=2>创建一个实例指针，再用Open打开一个库连接，它将返回一个IUnknown的自动化接口指针</font></strong>。<br><br>&nbsp;m_pConnection.CreateInstance(__uuidof(Connection));</p>
<p>&nbsp;// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息，<br>&nbsp;// 因为它有时会经常出现一些想不到的错误。jingzhou xu<br>&nbsp;try&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;{&nbsp;<br>&nbsp;&nbsp;// 打开本地Access库Demo.mdb<br>&nbsp;&nbsp;m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;catch(_com_error e)<br>&nbsp;{<br>&nbsp;&nbsp;AfxMessageBox(e.ErrorMessage()); <br>&nbsp;} </p>
<p>注：<font size=2>ConnectionPtr智能指针，通常用于打开、关闭一个库连接或用它的Execute方法来执行一个不返回结果的命令语句(用法和_CommandPtr中的Execute方法类似)。<br><br><strong>5.在databasetestDlg.cpp的前面加入：</strong><br><br>//引用应用类<br>extern CDatabasetestApp theApp;<br><br>在::OnInitDialog()加入代码：<br><br>// 使用ADO创建数据库记录集<br>&nbsp;m_pRecordset.CreateInstance(__uuidof(Recordset));</font></p>
<p><font size=2>&nbsp;// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息，<br>&nbsp;// 因为它有时会经常出现一些想不到的错误。jingzhou xu<br>&nbsp;try<br>&nbsp;{<br>&nbsp;&nbsp;m_pRecordset-&gt;CursorLocation = adUseClient;<br>&nbsp;&nbsp;m_pRecordset-&gt;Open("SELECT * FROM Table1",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 查询DemoTable表中所有字段<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;theApp.m_pConnection.GetInterfacePtr(),&nbsp; // 获取库接库的IDispatch指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adOpenDynamic,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adLockOptimistic,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;adCmdText);<br>&nbsp;}<br>&nbsp;catch(_com_error *e)<br>&nbsp;{<br>&nbsp;&nbsp;AfxMessageBox(e-&gt;ErrorMessage());<br>&nbsp;}</font></p>
<p><font size=2>&nbsp;//显示在GRID控件中<br>&nbsp;CString HeadStr&nbsp; = _T("编号 | 时间 | 采样点数 | 累加次数 |采样数据");//设置grid控件标题<br>&nbsp;m_DataGrid.SetFormatString(HeadStr);<br>&nbsp;m_DataGrid.SetCols(5);//设置列数<br>&nbsp;long RecordNum = m_pRecordset-&gt;GetRecordCount();//得到记录数<br>&nbsp;m_DataGrid.SetRows(RecordNum + 1);//设置行数=记录数+标题行（1行）</font></p>
<p><font size=2>&nbsp;m_DataGrid.SetCellAlignment(6);//对齐方式flexAlignRightTop<br>&nbsp;CRect rect;<br>&nbsp;m_DataGrid.GetWindowRect(&amp;rect);</font></p>
<p><font size=2>&nbsp;m_DataGrid.SetColWidth(0, rect.Width()*2);&nbsp;//设置列宽，开始时用除法但是实际列宽非常小。后用了乘法。为什么用乘法，我还是没弄明白<br>&nbsp;m_DataGrid.SetColWidth(1, rect.Width()*4);<br>&nbsp;m_DataGrid.SetColWidth(2, rect.Width()*2);<br>&nbsp;m_DataGrid.SetColWidth(3, rect.Width()*2);<br>&nbsp;m_DataGrid.SetColWidth(4, rect.Width()*2);<br>&nbsp;</font></p>
<p><font size=2>&nbsp;m_pRecordset-&gt;MoveFirst()//移动记录游标到第一条记录</font></p>
<p><font size=2>&nbsp;&nbsp;for(long CurRow = 1; CurRow &lt;= RecordNum ; CurRow++)//初始化grid控件显示。本想用两重循环，但是没有找以index为形参的SetText函数。<br>&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;CString str;<br>&nbsp;&nbsp;&nbsp;int CurCol = 0;<br>&nbsp;&nbsp;&nbsp;_variant_t vstr;<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetRow(CurRow);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("编号");<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("时间");<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("采样点数");<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("累加次数");<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>/*<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("数据");<br>&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>*/<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();</font></p>
<p><font size=2>&nbsp;}</font></p>
<p><font size=2>&nbsp;SetTimer(1, 1000, NULL);//设置定时器，实现时间编辑框的实时显示。<br><br><strong>6.添加DestroyWindow消息函数。实现退出程序的数据库连接注销。<br></strong>BOOL CDatabasetestDlg::DestroyWindow() <br>{<br>&nbsp;// TODO: Add your specialized code here and/or call the base class<br>&nbsp;// 关闭记录集<br>&nbsp;if(m_pRecordset-&gt;State)<br>&nbsp;m_pRecordset-&gt;Close();<br>&nbsp;m_pRecordset = NULL;<br>&nbsp;&nbsp;<br>&nbsp;return CDialog::DestroyWindow();<br>}<br><br><strong>7.加入插入按钮单击函数：</strong><br>UpdateData(TRUE);<br>&nbsp;if((m_SamplingTime == _T("")) || (m_SamplingNum == 0) || (m_AccNum == 0))<br>&nbsp;{<br>&nbsp;&nbsp;AfxMessageBox("请输入参数！");<br>&nbsp;}<br>&nbsp;else<br>&nbsp;{<br>&nbsp;&nbsp;// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息，<br>&nbsp;&nbsp;// 因为它有时会经常出现一些想不到的错误。jingzhou xu<br>&nbsp;&nbsp;try<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;// 写入各字段值<br>//&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveLast();<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;AddNew();<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;PutCollect("时间", _variant_t(m_SamplingTime));<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;PutCollect("采样点数", _variant_t((long)m_SamplingNum));<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;PutCollect("累加次数", _variant_t((long)m_AccNum));<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;Update();</font></p>
<p><font size=2>//&nbsp;&nbsp;&nbsp;AfxMessageBox("插入成功!");</font></p>
<p><font size=2>&nbsp;&nbsp;}<br>&nbsp;&nbsp;catch(_com_error *e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;AfxMessageBox(e-&gt;ErrorMessage());<br>&nbsp;&nbsp;}</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;long RecordNum = m_pRecordset-&gt;GetRecordCount();<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetRows(RecordNum + 1);//设置行数<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;for(long CurRow = 1; CurRow &lt;= RecordNum ; CurRow++)<br>&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;CString str;<br>&nbsp;&nbsp;&nbsp;&nbsp;int CurCol = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;_variant_t vstr;<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetRow(CurRow);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("编号");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("时间");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("采样点数");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("累加次数");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>/*<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("数据");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>*/<br>&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;m_DataGrid.Refresh();<br>&nbsp;&nbsp;</font></p>
<p><font size=2>&nbsp;}<br><br><strong>8.加入删除按钮单击函数</strong><br><br>m_pRecordset-&gt;MoveFirst();<br>&nbsp;if(m_pRecordset-&gt;adoEOF &amp;&amp; m_pRecordset-&gt;BOF)<br>&nbsp;{<br>&nbsp;&nbsp;AfxMessageBox("数据库中没有数据！");<br>&nbsp;}<br>&nbsp;else<br>&nbsp;{<br>&nbsp;&nbsp;try<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;// 删除当前行记录<br>&nbsp;&nbsp;m_pRecordset-&gt;Delete(adAffectCurrent);<br>&nbsp;&nbsp;m_pRecordset-&gt;Update();</font></p>
<p><font size=2>&nbsp;&nbsp;}<br>&nbsp;&nbsp;catch(_com_error *e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;AfxMessageBox(e-&gt;ErrorMessage());<br>&nbsp;&nbsp;}<br>&nbsp;}</font></p>
<p><font size=2>&nbsp;&nbsp;long RecordNum = m_pRecordset-&gt;GetRecordCount();<br>&nbsp;&nbsp;&nbsp;m_DataGrid.SetRows(RecordNum + 1);//设置行数<br>&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveFirst();</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;for(long CurRow = 1; CurRow &lt;= RecordNum ; CurRow++)<br>&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;CString str;<br>&nbsp;&nbsp;&nbsp;&nbsp;int CurCol = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;_variant_t vstr;<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetRow(CurRow);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("编号");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);//_variant_t&nbsp;到cstring转化<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("时间");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("采样点数");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("累加次数");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>/*<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetCol(++CurCol);<br>&nbsp;&nbsp;&nbsp;&nbsp;vstr = m_pRecordset-&gt;GetCollect("数据");<br>&nbsp;&nbsp;&nbsp;&nbsp;str = (LPCSTR)_bstr_t(vstr);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_DataGrid.SetText(str);<br>*/<br>&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset-&gt;MoveNext();</font></p>
<p><font size=2>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;m_DataGrid.Refresh();<br>&nbsp;<br><strong>9.加入timer函数</strong><br>void CDatabasetestDlg::OnTimer(UINT nIDEvent) <br>{<br>&nbsp;// TODO: Add your message handler code here and/or call default<br>&nbsp;CTime Time = CTime::GetCurrentTime();//得到系统时间<br>&nbsp;CString m_CurTime = Time.Format("%Y-%m-%d %H:%M:%S");//格式化时间格式。形如：2009-5-29 20：34：45<br>&nbsp;m_CSamplingTime.SetWindowText(m_CurTime);<br>&nbsp;<br>&nbsp;CDialog::OnTimer(nIDEvent);<br>}</font></p>
好了，编译一下。就可以看到实际的效果了。<br><br>
<p><strong>附</strong>:<br>1、_variant_t<br>(1)、一般传给这3个指针的值都不是MFC直接支持的数据类型,而要用_variant_t转换一下<br>_variant_t(XX)可以把大多数类型的变量转换成适合的类型传入：<br>(2)、_variant_t var;_variant_t -&gt; long: (long)var;<br>_variant_t -&gt; CString: CString strValue = (LPCSTR)_bstr_t(var);<br>CString -&gt; _variant_t: _variant_t(strSql);<br>2、BSTR宽字符串与CString相互转换</p>
<p>BSTR bstr;<br>CString strSql;<br>CString -&gt; BSTR: bstr = strSql.AllocSysString();<br>BSTR -&gt; CString: strSql = (LPCSTR)bstr;<br>3、_bstr_t与CString相互转换</p>
<p>_bstr_t bstr;<br>CString strSql;<br>CString -&gt; _bstr_t: bstr = (_bstr_t)strSql;<br>_bstr_t -&gt; CString: strSql = (LPCSTR)bstr;<br>4、关于时间<br>Access:表示时间的字符串#2004-4-5#<br>Sql:表示时间的字符串''2004-4-5''<br>DateField(时间字段) select * from my_table where DateField &gt; #2004-4-10#</p>
<p>&#160;</p>
<p>try<br>{<br>m_pCommand-&gt;CommandText = "INSERT INTO tTest(age) VALUES('23f2') ";<br>m_pRecordset = m_pCommand-&gt;Execute(NULL,NULL, adCmdText);&nbsp; <br>}<br>catch(_com_error e)///捕捉异常<br>{<br>CString errormessage;<br>errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());<br>AfxMessageBox(errormessage);///显示错误信息<br>}<br><br><strong>最后转一篇参考文献：</strong><br><br><font size=2>ADO提供了一组非常简单，将一般通用的数据访问细节进行封装的对象。由于ODBC数据源也提供了一般的OLE DB Privider，所以ADO不仅可以应用自身的OLE DB Privider，而且还可以应用所有的ODBC驱动程序。关于OLE DB和ADO的其它详细情况，读者可以自行查阅相关书籍或MSDN，这里就不一一说明了。让我们直接步入主题，如何掌握ADO这种数据库访问技术ADO的操作方法和前面讲过的DAO的操作在很多方面存在相似之处，在这里，笔者为了更有效的说明它的使用方法，用VC6.0做了一个示例程序(AdoRWAccess)，这个示例程序可以直接通过ADO来操作Access数据库，示例程序的运行效果如下图所示： <br><br><img src="http://www.yesky.com/image20010518/47547.jpg" border=1><br><br>　　在示例程序中我们仍采用原库结构，数据库名Demo.mdb，库内表名DemoTable，表内字段名为Name(姓名)和Age(年龄)的两个字段，来构造示例程序操作所需的Access数据库，这也和上两篇文章的示例源码中的库结构相兼容。<br>下面让我们看看ADO数据库访问技术使用的基本步骤及方法：<br><br>　　首先，要用#import语句来引用支持ADO的组件类型库(*.tlb)，其中类型库可以作为可执行程序(DLL、EXE等)的一部分被定位在其自身程序中的附属资源里，如：被定位在msado15.dll的附属资源中，只需要直接用 #import引用它既可。可以直接在Stdafx.h文件中加入下面语句来实现：<br><br></font>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td><font size=2>#import "c:\program files\common files\system\ado\msado15.dll" \<br>no_namespace \<br>rename ("EOF", "adoEOF") </font></td>
        </tr>
    </tbody>
</table>
<br><font size=2>　　其中路径名可以根据自己系统安装的ADO支持文件的路径来自行设定。当编译器遇到#import语句时，它会为引用组件类型库中的接口生成包装类，#import语句实际上相当于执行了API涵数LoadTypeLib()。#import语句会在工程可执行程序输出目录中产生两个文件，分别为*.tlh(类型库头文件)及*.tli(类型库实现文件)，它们分别为每一个接口产生智能指针，并为各种接口方法、枚举类型，CLSID等进行声明，创建一系列包装方法。语句no_namespace说明ADO对象不使用命名空间，rename ("EOF", "adoEOF")说明将ADO中结束标志EOF改为adoEOF，以避免和其它库中命名相冲突。<br><br>　　其次，在程序初始过程中需要初始化组件，一般可以用CoInitialize(NULL);来实现，这种方法在结束时要关闭初始化的COM，可以用下面语句CoUnInitialize();来实现。在MFC中还可以采用另一种方法来实现初始化COM，这种方法只需要一条语句便可以自动为我们实现初始化COM和结束时关闭COM的操作，语句如下所示： AfxOleInit();<br><br>　　接着，就可以直接使用ADO的操作了。我们经常使用的只是前面用#import语句引用类型库时，生成的包装类.tlh中声明的智能指针中的三个，它们分别是_ConnectionPtr、_RecordsetPtr和_CommandPtr。下面分别对它们的使用方法进行介绍：<br><br>　　1. _ConnectionPtr智能指针，通常用于打开、关闭一个库连接或用它的Execute方法来执行一个不返回结果的命令语句(用法和_CommandPtr中的Execute方法类似)。<br><br>　　 打开一个库连接。先创建一个实例指针，再用Open打开一个库连接，它将返回一个IUnknown的自动化接口指针。代码如下所示：<br><br></font>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td><font size=2>_ConnectionPtr m_pConnection;<br>　 // 初始化COM,创建ADO连接等操作<br>AfxOleInit();<br>m_pConnection.CreateInstance(__uuidof(Connection));<br><br>// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息，<br>// 因为它有时会经常出现一些意想不到的错误。jingzhou xu<br>try <br>{ <br>// 打开本地Access库Demo.mdb<br>m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);<br><br>}<br>catch(_com_error e)<br>{<br>AfxMessageBox("数据库连接失败，确认数据库Demo.mdb是否在当前路径下!");<br>return FALSE;<br>}</font></td>
        </tr>
    </tbody>
</table>
<br><font size=2>　　 关闭一个库连接 如果连接状态有效，则用Close方法关闭它并赋于它空值。代码如下所示：<br><br></font>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td><font size=2>if(m_pConnection-&gt;State)<br>m_pConnection-&gt;Close();<br>m_pConnection= NULL; </font></td>
        </tr>
    </tbody>
</table>
</p>
<p><br><font size=2>　　2. _RecordsetPtr智能指针，可以用来打开库内数据表，并可以对表内的记录、字段等进行各种操作。</font></p>
<p><font size=2><strong>&nbsp;&nbsp; 打开数据表</strong> 打开库内表名为DemoTable的数据表，代码如下：<br><br></font>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td><font size=2>_RecordsetPtr m_pRecordset;<br>m_pRecordset.CreateInstance(__uuidof(Recordset));<br><br>// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息，<br>// 因为它有时会经常出现一些意想不到的错误。jingzhou xu<br>try<br>{<br>m_pRecordset-&gt;Open("SELECT * FROM DemoTable", // 查询DemoTable表中所有字段<br>theApp.m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针<br>adOpenDynamic,<br>adLockOptimistic,<br>adCmdText);<br>}<br>catch(_com_error *e)<br>{<br>AfxMessageBox(e-&gt;ErrorMessage());<br>}</font></td>
        </tr>
    </tbody>
</table>
<br><font size=2>　　<strong>读取表内数据</strong> 将表内数据全部读出并显示在列表框内，m_AccessList为列表框的成员变量名。如果没有遇到表结束标志adoEOF，则用GetCollect(字段名)或m_pRecordset-&gt;Fields-&gt;GetItem(字段名)-&gt;Value方法，来获取当前记录指针所指的字段值，然后再用MoveNext()方法移动到下一条记录位置。代码如下所示：<br><br></font><strong>&nbsp;&nbsp;&nbsp;插入记录</strong> 可以先用AddNew()方法新增一个空记录，再用PutCollect(字段名,值)输入每个字段的值，最后再Update()更新到库中数据既可。其中变量m_Name和m_Age分别为姓名及年龄编辑框的成员变量名。代码所下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>try<br>{<br>// 写入各字段值<br>m_pRecordset-&gt;AddNew();<br>m_pRecordset-&gt;PutCollect("Name", _variant_t(m_Name));<br>m_pRecordset-&gt;PutCollect("Age", atol(m_Age));<br>m_pRecordset-&gt;Update();<br><br>AfxMessageBox("插入成功!");<br>}<br>catch(_com_error *e)<br>{<br>AfxMessageBox(e-&gt;ErrorMessage());<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　 移动记录指针 移动记录指针可以通过MoveFirst()方法移动到第一条记录、MoveLast()方法移动到最后一条记录、MovePrevious()方法移动到当前记录的前一条记录、MoveNext()方法移动到当前记录的下一条记录。但我们有时经常需要随意移动记录指针到任意记录位置时，可以使用Move(记录号)方法来实现，注意: Move()方法是相对于当前记录来移动指针位置的，正值向后移动、负值向前移动，如：Move(3)，当前记录是3时，它将从记录3开始往后再移动3条记录位置。代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>try<br>{<br>int curSel = m_AccessList.GetCurSel(); <br>// 先将指针移向第一条记录，然后就可以相对第一条记录来随意移动记录指针<br>m_pRecordset-&gt;MoveFirst();<br>m_pRecordset-&gt;Move(long(curSel));<br><br>}<br>catch(_com_error *e)<br>{<br>AfxMessageBox(e-&gt;ErrorMessage());<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　改记录中字段值 可以将记录指针移动到要修改记录的位置处，直接用PutCollect(字段名，值)将新值写入并Update()更新数据库既可。可以用上面方法移动记录指针，修改字段值代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>try<br>{<br>// 假设对第二条记录进行修改<br>m_pRecordset-&gt;MoveFirst();<br>m_pRecordset-&gt;Move(1); // 从0开始<br>m_pRecordset-&gt;PutCollect("Name", _variant_t(m_Name));<br>m_pRecordset-&gt;PutCollect("Age", atol(m_Age));<br>m_pRecordset-&gt;Update();<br>}<br>catch(_com_error *e)<br>{<br>AfxMessageBox(e-&gt;ErrorMessage());<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　 <strong>删除记录</strong> 删除记录和上面修改记录的操作类似，先将记录指针移动到要修改记录的位置，直接用Delete()方法删除它并用Update()来更新数据库既可。代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>try<br>{<br>// 假设删除第二条记录<br>m_pRecordset-&gt;MoveFirst();<br>m_pRecordset-&gt;Move(1); // 从0开始<br>m_pRecordset-&gt;Delete(adAffectCurrent); // 参数adAffectCurrent为删除当前记录<br>m_pRecordset-&gt;Update();<br>}<br>catch(_com_error *e)<br>{<br>AfxMessageBox(e-&gt;ErrorMessage());<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　 <strong>关闭记录集</strong> 直接用Close方法关闭记录集并赋于其空值。代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>m_pRecordset-&gt;Close();<br>m_pRecordset = NULL;</td>
        </tr>
    </tbody>
</table>
<br>　　3. CommandPtr智能指针，可以使用_ConnectionPtr或_RecordsetPtr来执行任务，定义输出参数，执行存储过程或SQL语句。<br><br>　　 <strong>执行SQL语句</strong> 先创建一个_CommandPtr实例指针，再将库连接和SQL语句做为参数，执行Execute()方法既可。代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>_CommandPtr m_pCommand;<br>m_pCommand.CreateInstance(__uuidof(Command));<br>m_pCommand-&gt;ActiveConnection = m_pConnection; // 将库连接赋于它<br>m_pCommand-&gt;CommandText = "SELECT * FROM DemoTable"; // SQL语句<br>m_pRecordset = m_pCommand-&gt;Execute(NULL, NULL,adCmdText); // 执行SQL语句，返回记录集 </td>
        </tr>
    </tbody>
</table>
<br>　　 <strong>执行存储过程</strong> 执行存储过程的操作和上面执行SQL语句类似，不同点仅是CommandText参数中不再是SQL语句，而是存储过程的名字，如Demo。另一个不同点就是在Execute()中参数由adCmdText(执行SQL语句)，改为adCmdStoredProc来执行存储过程。如果存储过程中存在输入、输出参数的话，需要使用到另一个智能指针_ParameterPtr来逐次设置要输入、输出的参数信息，并将其赋于_CommandPtr中Parameters参数来传递信息，有兴趣的读者可以自行查找相关书籍或MSDN。执行存储过程的代码如下所示：<br><br>
<table cellPadding=0 bgColor=#ffffff border=0>
    <tbody>
        <tr>
            <td>_CommandPtr m_pCommand;<br>m_pCommand.CreateInstance(__uuidof(Command));<br>m_pCommand-&gt;ActiveConnection = m_pConnection; // 将库连接赋于它<br>m_pCommand-&gt;CommandText = "Demo"; <br>m_pCommand-&gt;Execute(NULL,NULL, adCmdStoredProc);</td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/86107.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-29 21:37 <a href="http://www.cppblog.com/coloerful/archive/2009/05/29/86107.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言文件操作函数大全</title><link>http://www.cppblog.com/coloerful/archive/2009/05/25/85748.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Mon, 25 May 2009 13:27:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/25/85748.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85748.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/25/85748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85748.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85748.html</trackback:ping><description><![CDATA[<div>clearerr（清除文件流的错误旗标）<br>相关函数 feof<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 void clearerr(FILE * stream);<br>函数说明 clearerr（）清除参数stream指定的文件流所使用的错误旗标。<br>返回值<br>　<br>fclose（关闭文件）<br>相关函数 close，fflush，fopen，setbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fclose(FILE * stream);<br>函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中，并释放系统所提供的文件资源。<br>返回值 若关文件动作成功则返回0，有错误发生时则返回EOF并把错误代码存到errno。<br>错误代码 EBADF表示参数stream非已打开的文件。<br>范例 请参考fopen（）。<br>　<br>fdopen（将文件描述词转为文件指针）<br>相关函数 fopen，open，fclose<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 FILE * fdopen(int fildes,const char * mode);<br>函数说明 fdopen()会将参数fildes 的文件描述词，转换为对应的文件指针后返回。参数mode 字符串则代表着文件指针的流形态，此形态必须和原先文件描述词读写模式相同。关于mode 字符串格式请参考fopen()。<br>返回值 转换成功时返回指向该流的文件指针。失败则返回NULL，并把错误代码存在errno中。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp =fdopen(0,&#8221;w+&#8221;);<br>fprintf(fp,&#8221;%s\n&#8221;,&#8221;hello!&#8221;);<br>fclose(fp);<br>}</div>
<div>执行 hello!</div>
<div>feof（检查文件流是否读到了文件尾）<br>相关函数 fopen，fgetc，fgets，fread<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int feof(FILE * stream);<br>函数说明 feof()用来侦测是否读取到了文件尾，尾数stream为fopen（）所返回之文件指针。如果已到文件尾则返回非零值，其他情况返回0。<br>返回值 返回非零值代表已到达文件尾。<br>　<br>fflush（更新缓冲区）<br>相关函数 write，fopen，fclose，setbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fflush(FILE* stream);<br>函数说明 fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数stream为NULL，fflush()会将所有打开的文件数据更新。<br>返回值 成功返回0，失败返回EOF，错误代码存于errno中。<br>错误代码 EBADF 参数stream 指定的文件未被打开，或打开状态为只读。其它错误代码参考write（）。<br>　<br>fgetc（由文件中读取一个字符）<br>相关函数 open，fread，fscanf，getc<br>表头文件 include&lt;stdio.h&gt;<br>定义函数 nt fgetc(FILE * stream);<br>函数说明 fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。<br>返回值 getc()会返回读取到的字符，若返回EOF则表示到了文件尾。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE *fp;<br>int c;<br>fp=fopen(&#8220;exist&#8221;,&#8221;r&#8221;);<br>while((c=fgetc(fp))!=EOF)<br>printf(&#8220;%c&#8221;,c);<br>fclose(fp);<br>}</div>
<div>fgets（由文件中读取一字符串）<br>相关函数 open，fread，fscanf，getc<br>表头文件 include&lt;stdio.h&gt;<br>定义函数 har * fgets(char * s,int size,FILE * stream);<br>函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间，直到出现换行字符、读到文件尾或是已读了size-1个字符为止，最后会加上NULL作为字符串结束。<br>返回值 gets()若成功则返回s指针，返回NULL则表示有错误发生。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>char s[80];<br>fputs(fgets(s,80,stdin),stdout);<br>}</div>
<div>执行 this is a test /*输入*/<br>this is a test /*输出*/</div>
<div>　<br>fileno（返回文件流所使用的文件描述词）<br>相关函数 open，fopen<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fileno(FILE * stream);<br>函数说明 fileno()用来取得参数stream指定的文件流所使用的文件描述词。<br>返回值 返回文件描述词。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp;<br>int fd;<br>fp=fopen(&#8220;/etc/passwd&#8221;,&#8221;r&#8221;);<br>fd=fileno(fp);<br>printf(&#8220;fd=%d\n&#8221;,fd);<br>fclose(fp);<br>}</div>
<div>执行 fd=3</div>
<div>　<br>fopen（打开文件）<br>相关函数 open，fclose<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 FILE * fopen(const char * path,const char * mode);<br>函数说明 参数path字符串包含欲打开的文件路径及文件名，参数mode字符串则代表着流形态。<br>mode有下列几种形态字符串:<br>r 打开只读文件，该文件必须存在。<br>r+ 打开可读写的文件，该文件必须存在。<br>w 打开只写文件，若文件存在则文件长度清为0，即该文件内容会消失。若文件不存在则建立该文件。<br>w+ 打开可读写文件，若文件存在则文件长度清为零，即该文件内容会消失。若文件不存在则建立该文件。<br>a 以附加的方式打开只写文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾，即文件原先的内容会被保留。<br>a+ 以附加方式打开可读写的文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾后，即文件原先的内容会被保留。<br>上述的形态字符串都可以再加一个b字符，如rb、w+b或ab＋等组合，加入b 字符用来告诉函数库打开的文件为二进制文件，而非纯文字文件。不过在POSIX系统，包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限，此文件权限也会参考umask值。<br>返回值 文件顺利打开后，指向该流的文件指针就会被返回。若果文件打开失败则返回NULL，并把错误代码存在errno 中。<br>附加说明 一般而言，开文件后会作一些文件读取或写入的动作，若开文件失败，接下来的读写动作也无法顺利进行，所以在fopen()后请作错误判断及处理。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp;<br>fp=fopen(&#8220;noexist&#8221;,&#8221;a+&#8221;);<br>if(fp= =NULL) return;<br>fclose(fp);<br>}</div>
<div>fputc（将一指定字符写入文件流中）<br>相关函数 fopen，fwrite，fscanf，putc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fputc(int c,FILE * stream);<br>函数说明 fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。<br>返回值 fputc()会返回写入成功的字符，即参数c。若返回EOF则代表写入失败。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp;<br>char a[26]=&#8221;abcdefghijklmnopqrstuvwxyz&#8221;;<br>int i;<br>fp= fopen(&#8220;noexist&#8221;,&#8221;w&#8221;);<br>for(i=0;i&lt;26;i++)<br>fputc(a,fp);<br>fclose(fp);<br>}</div>
<div>fputs（将一指定的字符串写入文件内）<br>相关函数 fopen，fwrite，fscanf，fputc，putc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fputs(const char * s,FILE * stream);<br>函数说明 fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。<br>返回值 若成功则返回写出的字符个数，返回EOF则表示有错误发生。<br>范例 请参考fgets（）。<br>fread（从文件流读取数据）<br>相关函数 fopen，fwrite，fseek，fscanf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);<br>函数说明 fread()用来从文件流中读取数据。参数stream为已打开的文件指针，参数ptr 指向欲存放读取进来的数据空间，读取的字符数以参数size*nmemb来决定。Fread()会返回实际读取到的nmemb数目，如果此值比参数nmemb 来得小，则代表可能读到了文件尾或有错误发生，这时必须用feof()或ferror()来决定发生什么情况。<br>返回值 返回实际读取到的nmemb数目。<br>附加说明<br>范例<br>#include&lt;stdio.h&gt;<br>#define nmemb 3<br>struct test<br>{<br>char name[20];<br>int size;<br>}s[nmemb];<br>int main(){<br>FILE * stream;<br>int i;<br>stream = fopen(&#8220;/tmp/fwrite&#8221;,&#8221;r&#8221;);<br>fread(s,sizeof(struct test),nmemb,stream);<br>fclose(stream);<br>for(i=0;i&lt;nmemb;i++)<br>printf(&#8220;name[%d]=%-20s:size[%d]=%d\n&#8221;,i,s.name,i,s.size);<br>}</div>
<div>执行<br>name[0]=Linux! size[0]=6<br>name[1]=FreeBSD! size[1]=8<br>name[2]=Windows2000 size[2]=11</div>
<div>　<br>freopen（打开文件）<br>相关函数 fopen，fclose<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 FILE * freopen(const char * pathconst char * mode,FILE * stream);<br>函数说明 参数path字符串包含欲打开的文件路径及文件名，参数mode请参考fopen()说明。参数stream为已打开的文件指针。Freopen()会将原stream所打开的文件流关闭，然后打开参数path的文件。<br>返回值 文件顺利打开后，指向该流的文件指针就会被返回。如果文件打开失败则返回NULL，并把错误代码存在errno 中。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp;<br>fp=fopen(&#8220;/etc/passwd&#8221;,&#8221;r&#8221;);<br>fp=freopen(&#8220;/etc/group&#8221;,&#8221;r&#8221;,fp);<br>fclose(fp);<br>}</div>
<div>fseek（移动文件流的读写位置）<br>相关函数 rewind，ftell，fgetpos，fsetpos，lseek<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int fseek(FILE * stream,long offset,int whence);<br>函数说明 fseek()用来移动文件流的读写位置。参数stream为已打开的文件指针，参数offset为根据参数whence来移动读写位置的位移数。<br>参数 whence为下列其中一种:<br>SEEK_SET从距文件开头offset位移量为新的读写位置。SEEK_CUR 以目前的读写位置往后增加offset个位移量。<br>SEEK_END将读写位置指向文件尾后再增加offset个位移量。<br>当whence值为SEEK_CUR 或SEEK_END时，参数offset允许负值的出现。<br>下列是较特别的使用方式:<br>1) 欲将读写位置移动到文件开头时:fseek(FILE *stream,0,SEEK_SET);<br>2) 欲将读写位置移动到文件尾时:fseek(FILE *stream,0,0SEEK_END);<br>返回值 当调用成功时则返回0，若有错误则返回-1，errno会存放错误代码。<br>附加说明 fseek()不像lseek()会返回读写位置，因此必须使用ftell()来取得目前读写的位置。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * stream;<br>long offset;<br>fpos_t pos;<br>stream=fopen(&#8220;/etc/passwd&#8221;,&#8221;r&#8221;);<br>fseek(stream,5,SEEK_SET);<br>printf(&#8220;offset=%d\n&#8221;,ftell(stream));<br>rewind(stream);<br>fgetpos(stream,&amp;pos);<br>printf(&#8220;offset=%d\n&#8221;,pos);<br>pos=10;<br>fsetpos(stream,&amp;pos);<br>printf(&#8220;offset = %d\n&#8221;,ftell(stream));<br>fclose(stream);<br>}</div>
<div>执行 offset = 5<br>offset =0<br>offset=10</div>
<div>　<br>ftell（取得文件流的读取位置）<br>相关函数 fseek，rewind，fgetpos，fsetpos<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 long ftell(FILE * stream);<br>函数说明 ftell()用来取得文件流目前的读写位置。参数stream为已打开的文件指针。<br>返回值 当调用成功时则返回目前的读写位置，若有错误则返回-1，errno会存放错误代码。<br>错误代码 EBADF 参数stream无效或可移动读写位置的文件流。<br>范例 参考fseek()。<br>　<br>fwrite（将数据写至文件流）<br>相关函数 fopen，fread，fseek，fscanf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);<br>函数说明 fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针，参数ptr 指向欲写入的数据地址，总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。<br>返回值 返回实际写入的nmemb数目。<br>范例<br>#include&lt;stdio.h&gt;<br>#define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);}<br>#define nmemb 3<br>struct test<br>{<br>char name[20];<br>int size;<br>}s[nmemb];<br>main()<br>{<br>FILE * stream;<br>set_s(0,&#8221;Linux!&#8221;);<br>set_s(1,&#8221;FreeBSD!&#8221;);<br>set_s(2,&#8221;Windows2000.&#8221;);<br>stream=fopen(&#8220;/tmp/fwrite&#8221;,&#8221;w&#8221;);<br>fwrite(s,sizeof(struct test),nmemb,stream);<br>fclose(stream);<br>}</div>
<div>执行 参考fread（）。<br>　<br>getc（由文件中读取一个字符）<br>相关函数 read，fopen，fread，fgetc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int getc(FILE * stream);<br>函数说明 getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。虽然getc()与fgetc()作用相同，但getc()为宏定义，非真正的函数调用。<br>返回值 getc()会返回读取到的字符，若返回EOF则表示到了文件尾。<br>范例 参考fgetc()。<br>　<br>getchar（由标准输入设备内读进一字符）<br>相关函数 fopen，fread，fscanf，getc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int getchar(void);<br>函数说明 getchar()用来从标准输入设备中读取一个字符。然后将该字符从unsigned char转换成int后返回。<br>返回值 getchar()会返回读取到的字符，若返回EOF则表示有错误发生。<br>附加说明 getchar()非真正函数，而是getc(stdin)宏定义。<br>范例<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>FILE * fp;<br>int c,i;<br>for(i=0li&lt;5;i++)<br>{<br>c=getchar();<br>putchar(c);<br>}<br>}</div>
<div>执行 1234 /*输入*/<br>1234 /*输出*/</div>
<div>gets（由标准输入设备内读进一字符串）<br>相关函数 fopen，fread，fscanf，fgets<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 char * gets(char *s);<br>函数说明 gets()用来从标准设备读入字符并存到参数s所指的内存空间，直到出现换行字符或读到文件尾为止，最后加上NULL作为字符串结束。<br>返回值 gets()若成功则返回s指针，返回NULL则表示有错误发生。<br>附加说明 由于gets()无法知道字符串s的大小，必须遇到换行字符或文件尾才会结束输入，因此容易造成缓冲溢出的安全性问题。建议使用fgets()取代。<br>范例 参考fgets()<br>　<br>mktemp（产生唯一的临时文件名）<br>相关函数 tmpfile<br>表头文件 #include&lt;stdlib.h&gt;<br>定义函数 char * mktemp(char * template);<br>函数说明 mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符必须是XXXXXX。产生后的文件名会借字符串指针返回。<br>返回值 文件顺利打开后，指向该流的文件指针就会被返回。如果文件打开失败则返回NULL，并把错误代码存在errno中。<br>附加说明 参数template所指的文件名称字符串必须声明为数组，如:<br>char template[ ]=&#8221;template-XXXXXX&#8221;；<br>不可用char * template=&#8221;template-XXXXXX&#8221;；<br>范例<br>#include&lt;stdlib.h&gt;<br>main()<br>{<br>char template[ ]=&#8221;template-XXXXXX&#8221;;<br>mktemp(template);<br>printf(&#8220;template=%s\n&#8221;,template);<br>}</div>
<div>　<br>putc（将一指定字符写入文件中）<br>相关函数 fopen，fwrite，fscanf，fputc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int putc(int c,FILE * stream);<br>函数说明 putc()会将参数c转为unsigned char后写入参数stream指定的文件中。虽然putc()与fputc()作用相同，但putc()为宏定义，非真正的函数调用。<br>返回值 putc()会返回写入成功的字符，即参数c。若返回EOF则代表写入失败。<br>范例 参考fputc（）。<br>　<br>putchar（将指定的字符写到标准输出设备）<br>相关函数 fopen，fwrite，fscanf，fputc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int putchar (int c);<br>函数说明 putchar()用来将参数c字符写到标准输出设备。<br>返回值 putchar()会返回输出成功的字符，即参数c。若返回EOF则代表输出失败。<br>附加说明 putchar()非真正函数，而是putc(c，stdout)宏定义。<br>范例 参考getchar()。<br>　<br>rewind（重设文件流的读写位置为文件开头）<br>相关函数 fseek，ftell，fgetpos，fsetpos<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 void rewind(FILE * stream);<br>函数说明 rewind()用来把文件流的读写位置移至文件开头。参数stream为已打开的文件指针。此函数相当于调用fseek(stream,0,SEEK_SET)。<br>返回值<br>范例 参考fseek()</div>
<div>setbuf（设置文件流的缓冲区）<br>相关函数 setbuffer，setlinebuf，setvbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 void setbuf(FILE * stream,char * buf);<br>函数说明 在打开文件流后，读取内容之前，调用setbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流，参数buf指向自定的缓冲区起始地址。如果参数buf为NULL指针，则为无缓冲IO。Setbuf()相当于调用:setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ)<br>返回值<br>　<br>setbuffer（设置文件流的缓冲区）<br>相关函数 setlinebuf，setbuf，setvbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 void setbuffer(FILE * stream,char * buf,size_t size);<br>函数说明 在打开文件流后，读取内容之前，调用setbuffer()可用来设置文件流的缓冲区。</div>
<div>参数stream为指定的文件流，参数buf指向自定的缓冲区起始地址，参数size为缓冲区大小。<br>返回值</div>
<div>setlinebuf（设置文件流为线性缓冲区）<br>相关函数 setbuffer，setbuf，setvbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 void setlinebuf(FILE * stream);<br>函数说明 setlinebuf()用来设置文件流以换行为依据的无缓冲IO。相当于调用:setvbuf(stream,(char * )NULL,_IOLBF,0);请参考setvbuf()。<br>返回值</div>
<div>setvbuf（设置文件流的缓冲区）<br>相关函数 setbuffer，setlinebuf，setbuf<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int setvbuf(FILE * stream,char * buf,int mode,size_t size);<br>函数说明 在打开文件流后，读取内容之前，调用setvbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流，参数buf指向自定的缓冲区起始地址，参数size为缓冲区大小，参数mode有下列几种<br>_IONBF 无缓冲IO<br>_IOLBF 以换行为依据的无缓冲IO<br>_IOFBF 完全无缓冲IO。如果参数buf为NULL指针，则为无缓冲IO。<br>返回值</div>
<div>ungetc（将指定字符写回文件流中）<br>相关函数 fputc，getchar，getc<br>表头文件 #include&lt;stdio.h&gt;<br>定义函数 int ungetc(int c,FILE * stream);<br>函数说明 ungetc()将参数c字符写回参数stream所指定的文件流。这个写回的字符会由下一个读取文件流的函数取得。<br>返回值 成功则返回c 字符，若有错误则返回EOF。<br></div>
<a class=hidden href="http://redwolf.blog.51cto.com/427621/154255"><u><font color=#810081>本文出自 51CTO.COM技术博客</font></u></a>
<img src ="http://www.cppblog.com/coloerful/aggbug/85748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-25 21:27 <a href="http://www.cppblog.com/coloerful/archive/2009/05/25/85748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSting转unsined char 的数组</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85433.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 09:08:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85433.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85433.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85433.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85433.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85433.html</trackback:ping><description><![CDATA[<font color=#0000ff>&nbsp;</font>
<p>void CEx0625Dlg::OnButton1()</p>
<p>{</p>
<p>UpdateData();</p>
<p><font color=#0000ff>int</font> iLeng = m_edit.GetLength();</p>
<p>BYTE * pBuff = new <font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>[iLeng] ;</p>
<p>memcpy(pBuff,m_edit.GetBuffer(iLeng),<font color=#0000ff>sizeof</font>(<font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>)*iLeng);</p>
<p><font color=#009900>//使用</p>
</font>
<p><font color=#0000ff>delete</font> [] pBuff ;</p>
<p>}</p>
<br>
<img src ="http://www.cppblog.com/coloerful/aggbug/85433.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 17:08 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85433.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC常用数据类型的使用</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85431.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 09:03:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85431.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85431.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85431.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85431.html</trackback:ping><description><![CDATA[<h2>关键字 VC常用数据类型的使用</h2>
VC常用数据类型的使用<br><br>刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解，本文将介绍一些常用数据类型的使用。<br><br>我们先定义一些常见类型变量借以说明<br><br>int i = 100;<br>long l = 2001;<br>float f=300.2;<br>double d=12345.119;<br>char username[]="程佩君";<br>char temp[200];<br>char *buf;<br>CString str;<br>_variant_t v1;<br>_bstr_t v2;<br><br>一、其它数据类型转换为字符串<br><br><br>短整型(int)<br>itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制<br>itoa(i,temp,2); ///按二进制方式转换 <br>长整型(long)<br>ltoa(l,temp,10); <br>浮点数(float,double)<br>用fcvt可以完成转换,这是MSDN中的例子:<br>int decimal, sign; <br>char *buffer; <br>double source = 3.1415926535; <br>buffer = _fcvt( source, 7, &amp;decimal, &amp;sign ); <br>运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0<br>decimal表示小数点的位置,sign表示符号:0为正数，1为负数 <br>CString变量<br>str = "2008北京奥运";<br>buf = (LPSTR)(LPCTSTR)str; <br>BSTR变量<br>BSTR bstrValue = ::SysAllocString(L"程序员"); <br>char * buf = _com_util::ConvertBSTRToString(bstrValue); <br>SysFreeString(bstrValue); <br>AfxMessageBox(buf); <br>delete(buf); <br>CComBSTR变量<br>CComBSTR bstrVar("test"); <br>char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); <br>AfxMessageBox(buf); <br>delete(buf); <br><br>_bstr_t变量<br>_bstr_t类型是对BSTR的封装，因为已经重载了=操作符，所以很容易使用<br>_bstr_t bstrVar("test"); <br>const char *buf = bstrVar;///不要修改buf中的内容 <br>AfxMessageBox(buf); <br><br><br>通用方法(针对非COM数据类型)<br>用sprintf完成转换<br>char buffer[200];<br>char c = '1';<br>int i = 35;<br>long j = 1000;<br>float f = 1.7320534f;<br>sprintf( buffer, "%c",c);<br>sprintf( buffer, "%d",i);<br>sprintf( buffer, "%d",j);<br>sprintf( buffer, "%f",f);<br><br>二、字符串转换为其它数据类型<br>strcpy(temp,"123"); <br><br>短整型(int)<br>i = atoi(temp); <br>长整型(long)<br>l = atol(temp); <br>浮点(double)<br>d = atof(temp); <br>CString变量<br>CString name = temp; <br>BSTR变量 <br>BSTR bstrValue = ::SysAllocString(L"程序员"); <br>...///完成对bstrValue的使用<br>SysFreeString(bstrValue); <br><br>CComBSTR变量<br>CComBSTR类型变量可以直接赋值<br>CComBSTR bstrVar1("test");<br>CComBSTR bstrVar2(temp);<br><br>_bstr_t变量<br>_bstr_t类型的变量可以直接赋值<br>_bstr_t bstrVar1("test"); <br>_bstr_t bstrVar2(temp); <br><br><br>三、其它数据类型转换到CString<br>使用CString的成员函数Format来转换,例如:<br><br><br>整数(int)<br>str.Format("%d",i); <br>浮点数(float)<br>str.Format("%f",i); <br>字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值<br>str = username; <br>对于Format所不支持的数据类型，可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *，然后赋值给CString变量。<br><br>四、BSTR、_bstr_t与CComBSTR<br><br><br>CComBSTR 是ATL对BSTR的封装，_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。<br>char *转换到BSTR可以这样: <br>BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib<br>SysFreeString(bstrValue); <br>反之可以使用<br>char *p=_com_util::ConvertBSTRToString(b);<br>delete p;<br>具体可以参考一，二段落里的具体说明。<br><br>CComBSTR与_bstr_t对大量的操作符进行了重载，可以直接进行=,!=,==等操作，所以使用非常方便。<br>特别是_bstr_t,建议大家使用它。<br><br><br>五、VARIANT 、_variant_t 与 COleVariant<br><br><br>VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。<br>对于VARIANT变量的赋值：首先给vt成员赋值，指明数据类型，再对联合结构中相同数据类型的变量赋值，举个例子：<br>VARIANT va;<br>int a=2001;<br>va.vt=VT_I4;///指明整型数据<br>va.lVal=a; ///赋值<br><br>对于不马上赋值的VARIANT，最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:<br><br>Byte bVal; // VT_UI1. <br>Short iVal; // VT_I2. <br>long lVal; // VT_I4. <br>float fltVal; // VT_R4. <br>double dblVal; // VT_R8. <br>VARIANT_BOOL boolVal; // VT_BOOL. <br>SCODE scode; // VT_ERROR. <br>CY cyVal; // VT_CY. <br>DATE date; // VT_DATE. <br>BSTR bstrVal; // VT_BSTR. <br>DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL. <br>IUnknown FAR* punkVal; // VT_UNKNOWN. <br>IDispatch FAR* pdispVal; // VT_DISPATCH. <br>SAFEARRAY FAR* parray; // VT_ARRAY|*. <br>Byte FAR* pbVal; // VT_BYREF|VT_UI1. <br>short FAR* piVal; // VT_BYREF|VT_I2. <br>long FAR* plVal; // VT_BYREF|VT_I4. <br>float FAR* pfltVal; // VT_BYREF|VT_R4. <br>double FAR* pdblVal; // VT_BYREF|VT_R8. <br>VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL. <br>SCODE FAR* pscode; // VT_BYREF|VT_ERROR. <br>CY FAR* pcyVal; // VT_BYREF|VT_CY. <br>DATE FAR* pdate; // VT_BYREF|VT_DATE. <br>BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR. <br>IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN. <br>IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH. <br>SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*. <br>VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT. <br>void FAR* byref; // Generic ByRef. <br>char cVal; // VT_I1. <br>unsigned short uiVal; // VT_UI2. <br>unsigned long ulVal; // VT_UI4. <br>int intVal; // VT_INT. <br>unsigned int uintVal; // VT_UINT. <br>char FAR * pcVal; // VT_BYREF|VT_I1. <br>unsigned short FAR * puiVal; // VT_BYREF|VT_UI2. <br>unsigned long FAR * pulVal; // VT_BYREF|VT_UI4. <br>int FAR * pintVal; // VT_BYREF|VT_INT. <br>unsigned int FAR * puintVal; //VT_BYREF|VT_UINT. <br><br><br>_variant_t是VARIANT的封装类，其赋值可以使用强制类型转换，其构造函数会自动处理这些数据类型。<br>使用时需加上#include <comdef.h><br>例如：<br>long l=222;<br>ing i=100;<br>_variant_t lVal(l);<br>lVal = (long)i;<br><br><br>COleVariant的使用与_variant_t的方法基本一样，请参考如下例子：<br>COleVariant v3 = "字符串", v4 = (long)1999;<br>CString str =(BSTR)v3.pbstrVal;<br>long i = v4.lVal;<br><br><br>六、其它一些COM数据类型<br><br>根据ProgID得到CLSID<br>HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);<br>CLSID clsid;<br>CLSIDFromProgID( L"MAPI.Folder",&amp;clsid);<br><br>根据CLSID得到ProgID<br>WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); <br>例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID<br>LPOLESTR pProgID = 0;<br>ProgIDFromCLSID( CLSID_IApplication,&amp;pProgID);<br>...///可以使用pProgID <br>CoTaskMemFree(pProgID);//不要忘记释放 <br><br>七、ANSI与Unicode<br>Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。<br><br>将ANSI转换到Unicode<br>(1)通过L这个宏来实现，例如: CLSIDFromProgID( L"MAPI.Folder",&amp;clsid);<br>(2)通过MultiByteToWideChar函数实现转换,例如:<br>char *szProgID = "MAPI.Folder";<br>WCHAR szWideProgID[128];<br>CLSID clsid;<br>long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));<br>szWideProgID[lLen] = '\0'; <br>(3)通过A2W宏来实现,例如: <br>USES_CONVERSION; <br>CLSIDFromProgID( A2W(szProgID),&amp;clsid); <br>将Unicode转换到ANSI<br>(1)使用WideCharToMultiByte,例如:<br>// 假设已经有了一个Unicode 串 wszSomeString... <br>char szANSIString [MAX_PATH]; <br>WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); <br>(2)使用W2A宏来实现,例如:<br>USES_CONVERSION;<br>pTemp=W2A(wszSomeString); <br>八、其它<br><br>对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据（DWORD)分解成两个16位数据（WORD),例如：<br>LPARAM lParam;<br>WORD loValue = LOWORD(lParam);///取低16位<br>WORD hiValue = HIWORD(lParam);///取高16位<br><br><br>对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:<br>WORD wValue;<br>BYTE loValue = LOBYTE(wValue);///取低8位<br>BYTE hiValue = HIBYTE(wValue);///取高8位<br><br><br>两个16位数据（WORD）合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)<br>LONG MAKELONG( WORD wLow, WORD wHigh );<br>WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); <br>LPARAM MAKELPARAM( WORD wLow, WORD wHigh );<br>LRESULT MAKELRESULT( WORD wLow, WORD wHigh ); <br><br><br>两个8位的数据(BYTE)合成16位的数据(WORD)<br>WORD MAKEWORD( BYTE bLow, BYTE bHigh ); <br><br><br>从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值<br>COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );<br>例如COLORREF bkcolor = RGB(0x22,0x98,0x34);<br><br><br>从COLORREF类型的颜色值得到RGB三个颜色值<br>BYTE Red = GetRValue(bkcolor); ///得到红颜色<br>BYTE Green = GetGValue(bkcolor); ///得到绿颜色<br>BYTE Blue = GetBValue(bkcolor); ///得到兰颜色<br><br><br>九、注意事项<br>假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )<br>
<img src ="http://www.cppblog.com/coloerful/aggbug/85431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 17:03 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC常用虚拟键</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85430.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 09:02:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85430.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85430.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85430.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85430.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85430.html</trackback:ping><description><![CDATA[<h2>关键字 VC常用虚拟键</h2>
VC常用虚拟键<br><br>Symbolic constant name Value(hexadecimal) Mouse or keyboard equivalent<br>VK_LBUTTON 01 Left mouse button <br>VK_RBUTTON 02 Right mouse button <br>VK_CANCEL 03 Control-break processing <br>VK_MBUTTON 04 Middle mouse button (three-button mouse) <br>VK_BACK 08 BACKSPACE key <br>VK_TAB 09 TAB key <br>VK_CLEAR 0C CLEAR key <br>VK_RETURN 0D ENTER key <br>VK_SHIFT 10 SHIFT key <br>VK_CONTROL 11 CTRL key <br>VK_MENU 12 ALT key <br>VK_PAUSE 13 PAUSE key <br>VK_CAPITAL 14 CAPS LOCK key <br>&#190; 15-19 Reserved for Kanji systems <br>&#190; 1A Undefined <br>VK_ESCAPE 1B ESC key <br>VK_SPACE 20 SPACEBAR <br>VK_PRIOR 21 PAGE UP key <br>VK_NEXT 22 PAGE DOWN key <br>VK_END 23 END key <br>VK_HOME 24 HOME key <br>VK_LEFT 25 LEFT ARROW key <br>VK_UP 26 UP ARROW key <br>VK_RIGHT 27 RIGHT ARROW key <br>VK_DOWN 28 DOWN ARROW key <br>VK_SELECT 29 SELECT key <br>&#190; 2A Original equipment manufacturer (OEM) specific <br>VK_EXECUTE 2B EXECUTE key <br>VK_SNAPSHOT 2C PRINT SCREEN key for Windows 3.0 and later <br>VK_INSERT 2D INS key <br>VK_DELETE 2E DEL key <br>VK_HELP 2F HELP key <br>VK_0 30 0 key <br>VK_1 31 1 key <br>VK_2 32 2 key <br>VK_3 33 3 key <br>VK_4 34 4 key <br>VK_5 35 5 key <br>VK_6 36 6 key <br>VK_7 37 7 key <br>VK_8 38 8 key <br>VK_9 39 9 key <br>VK_A 41 A key <br>VK_B 42 B key <br>VK_C 43 C key <br>VK_D 44 D key <br>VK_E 45 E key <br>VK_F 46 F key <br>VK_G 47 G key <br>VK_H 48 H key <br>VK_I 49 I key <br>VK_J 4A J key <br>VK_K 4B K key <br>VK_L 4C L key <br>VK_M 4D M key <br>VK_N 4E N key <br>VK_O 4F O key <br>VK_P 50 P key <br>VK_Q 51 Q key <br>VK_R 52 R key <br>VK_S 53 S key <br>VK_T 54 T key <br>VK_U 55 U key <br>VK_V 56 V key <br>VK_W 57 W key <br>VK_X 58 X key <br>VK_Y 59 Y key <br>VK_Z 5A Z key <br>VK_LWIN 5B Left Windows key (Microsoft Natural Keyboard) <br>VK_RWIN 5C Right Windows key (Microsoft Natural Keyboard) <br>VK_APPS 5D Applications key (Microsoft Natural Keyboard) <br>VK_NUMPAD0 60 Numeric keypad 0 key <br>VK_NUMPAD1 61 Numeric keypad 1 key <br>VK_NUMPAD2 62 Numeric keypad 2 key <br>VK_NUMPAD3 63 Numeric keypad 3 key <br>VK_NUMPAD4 64 Numeric keypad 4 key <br>VK_NUMPAD5 65 Numeric keypad 5 key <br>VK_NUMPAD6 66 Numeric keypad 6 key <br>VK_NUMPAD7 67 Numeric keypad 7 key <br>VK_NUMPAD8 68 Numeric keypad 8 key <br>VK_NUMPAD9 69 Numeric keypad 9 key <br>VK_MULTIPLY 6A Multiply key <br>VK_ADD 6B Add key <br>VK_SEPARATOR 6C Separator key <br>VK_SUBTRACT 6D Subtract key <br>VK_DECIMAL 6E Decimal key <br>VK_DIVIDE 6F Divide key <br>VK_F1 70 F1 key <br>VK_F2 71 F2 key <br>VK_F3 72 F3 key <br>VK_F4 73 F4 key <br>VK_F5 74 F5 key <br>VK_F6 75 F6 key <br>VK_F7 76 F7 key <br>VK_F8 77 F8 key <br>VK_F9 78 F9 key <br>VK_F10 79 F10 key <br>VK_F11 7A F11 key <br>VK_F12 7B F12 key <br>VK_F13 7C F13 key <br>VK_F14 7D F14 key <br>VK_F15 7E F15 key <br>VK_F16 7F F16 key <br>VK_F17 80H F17 key <br>VK_F18 81H F18 key <br>VK_F19 82H F19 key <br>VK_F20 83H F20 key <br>VK_F21 84H F21 key <br>VK_F22 85H F22 key <br>VK_F23 86H F23 key <br>VK_F24 87H F24 key <br>VK_NUMLOCK 90 NUM LOCK key <br>VK_SCROLL 91 SCROLL LOCK key <br>VK_ATTN F6 Attn key<br>VK_CRSEL F7 CrSel key<br>VK_EXSEL F8 ExSel key<br>VK_EREOF F9 Erase EOF key<br>VK_PLAY FA Play key<br>VK_ZOOM FB Zoom key<br>VK_NONAME FC Reserved for future use. <br>VK_PA1 FD PA1 key<br>VK_OEM_CLEAR FE Clear key<br>
<img src ="http://www.cppblog.com/coloerful/aggbug/85430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 17:02 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编辑框限制16进制输入</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85429.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 09:00:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85429.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85429.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85429.html</trackback:ping><description><![CDATA[在对应.h文件中加入 BOOL PreTranslateMessage(MSG* pMsg) ；声明。<br>在.cpp文件中从新定义成员函数<br><br><br>BOOL CTestdemoDlg::PreTranslateMessage(MSG* pMsg) <br>{ <br>if((WM_CHAR == pMsg-&gt;message) &amp;&amp; (::GetDlgCtrlID(pMsg-&gt;hwnd) == IDC_FINE_UPPER_THRESHOLD_EDIT)) <br>{ <br>if(p-&gt;wParam == VK_BACK)//相应back键<br>return CDialog::PreTranslateMessage(pMsg); <br>TCHAR ch = (TCHAR)pMsg-&gt;wParam; <br>if((ch &gt;= '0' &amp;&amp; ch &lt;= '9')) <br>return CDialog::PreTranslateMessage(pMsg); <br>if((ch &gt;= 'A' &amp;&amp; ch &lt;= 'F')) <br>return CDialog::PreTranslateMessage(pMsg); <br><br>return TRUE; <br>} <br>return CDialog::PreTranslateMessage(pMsg); <br>} <br><br><br><span style="FONT-SIZE: 10pt">MFC</span><span style="FONT-SIZE: 10pt">消息控制流最具特色的地方是</span><span style="FONT-SIZE: 10pt">CWnd</span><span style="FONT-SIZE: 10pt">类的虚拟函数</span><span style="FONT-SIZE: 10pt">PreTranslateMessage()</span><span style="FONT-SIZE: 10pt">，通过重载这个函数，我们可以改变</span><span style="FONT-SIZE: 10pt">MFC</span><span style="FONT-SIZE: 10pt">的消息控制流程，甚至可以作一个全新的控制流出来。只有穿过消息队列的消息才受</span><span style="FONT-SIZE: 10pt">PreTranslateMessage()</span><span style="FONT-SIZE: 10pt">影响，采用</span><span style="FONT-SIZE: 10pt">SendMessage()</span><span style="FONT-SIZE: 10pt">或其他类似的方式向窗口直接发送的而不经过消息队列的消息根本不会理睬</span><span style="FONT-SIZE: 10pt">PreTranslateMessage()</span><span style="FONT-SIZE: 10pt">的存在。</span>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 10pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 10pt">一、是否调用</span><span style="FONT-SIZE: 10pt">TranslateMessage()</span><span style="FONT-SIZE: 10pt">和</span><span style="FONT-SIZE: 10pt">DispatchMessage()</span><span style="FONT-SIZE: 10pt">是由一个名称为</span><span style="FONT-SIZE: 10pt">PreTranslateMessage()</span><span style="FONT-SIZE: 10pt">函数的返回值决定的，如果该函数返回</span><span style="FONT-SIZE: 10pt">TRUE</span><span style="FONT-SIZE: 10pt">，则不会把该消息分发给窗口函数处理。</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 10pt">二、传给</span><span style="FONT-SIZE: 10pt">PreTranslateMessage()</span><span style="FONT-SIZE: 10pt">的消息是未经翻译过的消息，它没有经过</span><span style="FONT-SIZE: 10pt">TranslateMessage()</span><span style="FONT-SIZE: 10pt">处理。可以在该函数中使用</span><span style="FONT-SIZE: 10pt">(pMsg-&gt;wParam==VK_RETURN)</span><span style="FONT-SIZE: 10pt">来拦截回车键。</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 10pt">三、在</span><span style="FONT-SIZE: 10pt">WindowProc</span><span style="FONT-SIZE: 10pt">里不能处理</span><span style="FONT-SIZE: 10pt">WM_Char</span><span style="FONT-SIZE: 10pt">消息。</span></p>
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 10pt">四、</span><span style="FONT-SIZE: 10pt">SetWindowText</span><span style="FONT-SIZE: 10pt">会发送</span><span style="FONT-SIZE: 10pt">WM_Char</span><span style="FONT-SIZE: 10pt">给窗口。</span></p>
<p style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span style="FONT-SIZE: 10pt">五、</span><span style="FONT-SIZE: 10pt">PeekMessage</span><span style="FONT-SIZE: 10pt">和</span><span style="FONT-SIZE: 10pt">GetMessage</span><span style="FONT-SIZE: 10pt">的区别：</span></p>
<p style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span>GetMessage</span><span>在没有消息的时候等待消息，</span><span>cpu</span><span>当然低</span></p>
<p style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span>PeekMessage</span><span>没有消息的时候立刻返回，所以</span><span>cpu</span><span>占用率高。</span></p>
<p style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><span>因为游戏不能靠</span><span>windows</span><span>消息驱动，所以要用</span><span>PeekMessage();</span></p>
<br>在MFC中，PreTranslateMessage是虚函数，我们可以重载它来处理键盘和鼠标消息。在sdk中，这又有所不同，我们必须在回调函数中LRESULT &nbsp; CALLBACK &nbsp; WndProc(HWND &nbsp; hWnd, &nbsp; UINT &nbsp; message, &nbsp; WPARAM &nbsp; wParam, &nbsp; LPARAM &nbsp; lParam)处理消息：它和PreTranslateMessage起的作用是类似的。只是MFC封装的更好而已。<br><br>重载该函数可以实现窗口消息在派发给窗口函数TrnaslateMessage和DispatchMessae()之前的过滤.缺省的实现是完成加速键的翻译.因为您必须在你的重载版本中调用CWinApp:PreTranslateMessage()函数.很显然,在SDK中在TranslateMassage()函数之前来实现该功能.
<img src ="http://www.cppblog.com/coloerful/aggbug/85429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 17:00 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序路径创建不存的文件夹</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85401.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:41:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85401.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85401.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85401.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85401.html</trackback:ping><description><![CDATA[<p>//当前程序目录创建samplingdata文件夹<br>&nbsp;char pFolderpath[MAX_PATH];<br>&nbsp;//得到当前路径<br>&nbsp;TCHAR tchBuffer[MAX_PATH ]; <br>&nbsp;LPTSTR lpszCurDir;<br>&nbsp;lpszCurDir = tchBuffer; <br>&nbsp;GetCurrentDirectory(MAX_PATH , lpszCurDir);<br>//&nbsp;MessageBox(lpszCurDir);</p>
<p>&nbsp;CString CurPath = lpszCurDir;<br>&nbsp;CString FolderPath = CurPath + "<a href="file://samplingdata/">\\SamplingData</a>" ;<br>&nbsp;for(int i=0;i&lt;FolderPath.GetLength();i++)<br>&nbsp;{<br>&nbsp;&nbsp;pFolderpath[i] = FolderPath.GetAt(i);<br>&nbsp;}<br>&nbsp;pFolderpath[i] = '\0';//路径结尾</p>
<p>&nbsp;DWORD dwAttr=GetFileAttributes(pFolderpath);<br>//若文件夹不存在，创建文件夹<br>&nbsp;if(dwAttr==0xFFFFFFFF) <br>&nbsp;{<br>&nbsp;&nbsp;CreateDirectory(pFolderpath,NULL);<br>&nbsp;}</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:41 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc将系统时间作为文件名</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85400.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:40:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85400.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85400.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85400.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85400.html</trackback:ping><description><![CDATA[<p>&nbsp;char pFilePath[MAX_PATH];<br>&nbsp;CFile *datafile;</p>
<p>&nbsp;TCHAR tchBuffer[MAX_PATH ]; <br>&nbsp;LPTSTR lpszCurDir;<br>&nbsp;lpszCurDir = tchBuffer; <br>&nbsp;GetCurrentDirectory(MAX_PATH , lpszCurDir);//得到当前程序路径<br>//&nbsp;MessageBox(lpszCurDir);</p>
<p>&nbsp;COleDateTime timeNow, dateNow;<br>&nbsp;timeNow = COleDateTime::GetCurrentTime();&nbsp;&nbsp;&nbsp;&nbsp; // 获取当前日期时间<br>&nbsp;dateNow = COleDateTime::GetCurrentTime();&nbsp;&nbsp;&nbsp;&nbsp; // 同样获取当前日期时间<br>&nbsp;CString sTime = timeNow.Format(VAR_TIMEVALUEONLY);&nbsp;&nbsp;&nbsp;&nbsp; // 获取当前时间<br>&nbsp;CString sDate = dateNow.Format(VAR_DATEVALUEONLY);&nbsp;&nbsp;&nbsp;&nbsp; // 获取当前日期</p>
<p>&nbsp;CString FileName = sDate + "_" + sTime + ".txt";&nbsp;&nbsp;&nbsp;&nbsp; // 文件名 = 日期_时间.txt</p>
<p>&nbsp;CString Filep = lpszCurDir;<br>&nbsp;CString Filepath = Filep + "<a href="file://samplingdata//">\\SamplingData\\</a>" + FileName;<br>&nbsp;<br>&nbsp;int&nbsp;FilePathLength = Filepath.GetLength();&nbsp;&nbsp;&nbsp;&nbsp; // 获得文件名长度，CFile不能用CString，只能用string做参数，要做转换<br>&nbsp;for(int i=0; i &lt; FilePathLength ; i++)<br>&nbsp;{<br>&nbsp;&nbsp; pFilePath[i] = Filepath.GetAt(i);&nbsp;&nbsp;&nbsp;&nbsp; // CString -&gt; string<br>&nbsp;&nbsp; if( (pFilePath[i] == ':') &amp;&amp; (i != 1))&nbsp;&nbsp;&nbsp;&nbsp; // 剔除':'等不能作为文件名的符号,并保留根目录后的冒号<br>&nbsp;&nbsp; pFilePath[i] = '-';<br>&nbsp;}<br>&nbsp;pFilePath[i] = '\0';&nbsp;&nbsp;&nbsp;&nbsp; // 文件名结束</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:40 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解读VC++程序开发中的文件操作API和CFile类</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85398.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:36:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85398.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85398.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85398.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85398.html</trackback:ping><description><![CDATA[在VC编程中，操作文件的方法主要有两种：利用API函数和MFC的CFile类。微软在其中封装了文件的一般操作，下面我就介绍一下如何利用这两种方法实现文件操作。<br><br>　　<strong>1．创建或打开一个文件 </strong><br><br>　　API函数CreateFile可打开和创建文件、管道、邮槽、通信服务、设备以及控制台，但是在此时只是介绍用这个函数怎么实现创建和打开一个文件。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>HANDLE CreateFile(<br>　LPCTSTR lpFileName, // 要打开的文件名<br>　DWORD dwDesiredAccess, // 文件的操作属性<br>　DWORD dwShareMode, // 文件共享属性 <br>　LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性<br>　DWORD dwCreationDisposition, //文件操作<br>　DWORD dwFlagsAndAttributes, // 文件属性<br>　HANDLE hTemplateFile // 如果不为零，则指定一个文件句柄。新文件将从这个文件中复制扩展属性 <br>);</td>
        </tr>
    </tbody>
</table>
<br>　　文件的操作属性：如果为零，表示只允许获取与一个设备有关的信息，GENERIC_READ 表示允许对设备进行读访问；如果为 GENERIC_WRITE 表示允许对设备进行写访问（可组合使用）；<br><br>　　文件的共享属性：零表示不共享； FILE_SHARE_READ 或 FILE_SHARE_WRITE 表示允许对文件进行读/写共享访问；<br><br>　　文件的操作有：<br><br>　　&#183;CREATE_NEW：创建文件；如文件存在则会出错<br>　　&#183;CREATE_ALWAYS：创建文件，会改写前一个文件<br>　　&#183;OPEN_EXISTING：文件必须已经存在。
<table cellSpacing=0 cellPadding=0 align=left border=0>
    <tbody>
        <tr>
            <td vAlign=top>
            <table cellSpacing=4 cellPadding=0 width=350 align=left border=0>
                <tbody>
                    <tr>
                        <td></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
        <tr>
            <td></td>
        </tr>
    </tbody>
</table>
由设备提出要求<br>　　&#183;OPEN_ALWAYS：如文件不存在则创建它<br>　　&#183;TRUNCATE_EXISTING：将现有文件缩短为零长度<br><br>　　文件属性有：<br><br>　　&#183;FILE_ATTRIBUTE_ARCHIVE：标记归档属性<br>　　&#183;FILE_ATTRIBUTE_COMPRESSED：将文件标记为已压缩，或者标记为文件在目录中的默认压缩方式<br>　　&#183;FILE_ATTRIBUTE_NORMAL：默认属性<br>　　&#183;FILE_ATTRIBUTE_HIDDEN：隐藏文件或目录<br>　　&#183;FILE_ATTRIBUTE_READONLY：文件为只读<br>　　&#183;FILE_ATTRIBUTE_SYSTEM：文件为系统文件<br>　　&#183;FILE_FLAG_WRITE_THROUGH：操作系统不得推迟对文件的写操作<br>　　&#183;FILE_FLAG_OVERLAPPED：允许对文件进行重叠操作<br>　　&#183;FILE_FLAG_NO_BUFFERING：禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块<br>　　&#183;FILE_FLAG_RANDOM_ACCESS：针对随机访问对文件缓冲进行优化<br>　　&#183;FILE_FLAG_SEQUENTIAL_SCAN：针对连续访问对文件缓冲进行优化<br>　　&#183;FILE_FLAG_DELETE_ON_CLOSE：关闭了上一次打开的句柄后，将文件删除。特别适合临时文件<br><br>　　可以组合的属性有：FILE_FLAG_WRITE_THROUGH，FILE_FLAG_OVERLAPPED，FILE_FLAG_NO_BUFFERING，FILE_FLAG_RANDOM_ACCESS，FILE_FLAG_SEQUENTIAL_SCAN，FILE_FLAG_DELETE_ON_CLOSE，FILE_FLAG_BACKUP_SEMANTICS，FILE_FLAG_POSIX_SEMANTICS，FILE_FLAG_OPEN_REPARSE_POINT，FILE_FLAG_OPEN_NO_RECALL<br><br>　　如果成功返回一个打开文件得句柄，如果调用函数之前文件存在，文件操作属性为：CREATE_ALWAYS 或 OPEN_ALWAYS，使用GetLastError函数返回的是ERROR_ALREADY_EXISTS（包括函数操作成功），如果之前函数不存在，则返回0。使用失败返回INVALID_HANDLE_VALUE，要取得更多的信息，使用GetLastError函数。<br><br>　　文件关闭用：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL CloseHandle(HANDLE hObject // handle to object to close);</td>
        </tr>
    </tbody>
</table>
<br>　　例子1、在当前目录下面创建一个文件：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>HANDLE handle;<br>DWORD Num;<br>handle= ::CreateFile("new.tmp",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE_ON_CLOSE,NULL);<br>if(INVALID_HANDLE_VALUE!= handle )<br>{<br>　::SetFilePointer(handle,0,0,FILE_BEGIN);<br>　char Buffer[] = "这是个刚创建的文件";<br>　::WriteFile(handle,Buffer,sizeof(Buffer),&amp;Num,NULL);<br>　ZeroMemory(Buffer,sizeof(Buffer));<br>　::SetFilePointer(handle,0,0,FILE_BEGIN);<br>　::ReadFile(handle,Buffer,sizeof(Buffer),&amp;Num,NULL);<br>　MessageBox(Buffer);<br>　::CloseHandle(handle); <br>}</td>
        </tr>
    </tbody>
</table>
<br>　　可以改变上面的创建文件的属性和操作看下不同效果。<br><br>　　CFile创建和打开一个文件：<br><br>　　创建文件和打开文件的方法有很多种，下面简单介绍下几个构造函数：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFile( LPCTSTR lpszFileName, UINT nOpenFlags );<br>throw( CFileException );<br>CFile( );<br>BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );</td>
        </tr>
    </tbody>
</table>
<br>　　lpszFileName:文件名称，可以是相对路径，绝对路径或网络路径<br><br>　　nOpenFlags：打开方式有：<br><br>　　&#183;CFile::modeCreate 调用构造函数构造一个新文件，如果文件已存在，则长度变成0。<br><br>　　&#183;CFile::modeNoTruncate 此值与modeCreate组合使用。如果所创建的文件已存在则其长度不变为0。因而此文件被打开，或者作为一个新文件或者作为一个已存在的文件。这将是很有用的，例如当打开一个可能存在也可能不存在的文件时。<br><br>　　&#183;CFile::modeRead 打开文件仅供读。<br><br>　　&#183;CFile::modeReadWrite 打开文件供读写。<br><br>　　&#183;CFile::modeWrite 打开文件仅供写。<br><br>　　&#183;CFile::modeNoInherit 阻止文件被子进程继承。<br><br>　　&#183;CFile::ShareDenyNone 不禁止其它进程读或写访问，打开文件。如果文件已被其它进程以兼容模式打开，则Create失败。<br><br>　　&#183;CFile::ShareDenyRead 打开文件，禁止其它进程读此文件。如果文件已被其它进程以兼容模式打开，或被其它进程读，则Create失败。<br><br>　　&#183;CFile::ShareDenyWrite 打开文件，禁止其它进程写此文件。如果文件已被其它进程以兼容模式打开，或被其它进程写，则Create失败。<br><br>　　&#183;CFile::ShareExclusive 以独占模式打开文件，禁止其它进程对文件的读写。如果文件已经以其它模式打开读写（即使被当前进程），则构造失败。<br><br>　　&#183;CFile::ShareCompat 此标志在32位MFC中无效。此标志在使用CFile:: Open时映射为CFile::ShareExclusive。<br><br>　　&#183;CFile::typeText 对回车换行设置特殊进程（仅用于派生类）。<br><br>　　&#183;CFile::typeBinary 设置二进制模式（仅用于派生类）。<br><br>　　下面给出MSDN中的一个例子：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>char* pFileName = "test.dat";<br>TRY<br>{<br>　CFile f( pFileName, CFile::modeCreate | CFile::modeWrite );<br>}<br>CATCH( CFileException, e )<br>{<br>　#ifdef _DEBUG<br>　　afxDump &lt;&lt; "File could not be opened " &lt;&lt; e-&gt;m_cause &lt;&lt; "\n";<br>　#endif<br>}<br>END_CATCH <br>CFile fileTest;<br>char* pFileName = "test.dat";<br>TRY<br>{<br>　fileTest.Open(pFileName, CFile::modeCreate |CFile::modeWrite);<br>}<br>CATCH_ALL(e)<br>{<br>　fileTest.Abort( );<br>　THROW_LAST ( );<br>}<br>END_CATCH_ALL</td>
        </tr>
    </tbody>
</table>
<strong>2．文件的读写定位<br><br></strong>　　定位文件中的数据是很重要的，这决定了写入的数据在文件中的位置。API函数<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>DWORD SetFilePointer(<br>　HANDLE hFile, //文件的句柄<br>　LONG lDistanceToMove, //字节偏移量r<br>　PLONG lpDistanceToMoveHigh, //指定一个长整数变量，其中包含了要使用的一个高双字偏移（一般用来操作大型文件）。可设为零，表示只使用lDistanceToMove <br>　DWORD dwMoveMethod //文件定位<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　dwMoveMethod文件定位的方式有三种：<br><br>　　&#183;FILE_BEGIN：从文件开始处。<br><br>　　&#183;FILE_CURRENT：从当前位置。<br><br>　　&#183;FILE_END：从文件的末尾。<br><br>　　此函数可以用来定位大型文件，lpDistanceToMoveHigh是高32位，lDistanceToMove是低32位。如果lpDistanceToMoveHigh为NULL时，函数操作成功，返回的是当前文件数据的偏移量，如果lpDistanceToMoveHigh不NULL，则返回数据的偏移量高32位放在 lpDistanceToMoveHigh中，函数调用失败返回的是0xffffffff.<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL SetEndOfFile(HANDLE hFile //文件的句柄);</td>
        </tr>
    </tbody>
</table>
<br>　　CFile类的文件数据定位函数有：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>LONG Seek(LONG lOff,UINT nFrom);<br>throw(CFileException);</td>
        </tr>
    </tbody>
</table>
<br>　　如果要求的位置合法，则Seek返回从文件开始起的新字节偏移量 <br><br>　　lOff：指针移动的字节数。<br><br>　　nFrom：指针移动的模式。可以是CFile::begin，CFile::current，CFile::end<br>void SeekToBegin( );<br><br>　　DWORD SeekToEnd( );//返回文件长度（字节数）。<br><br>　　下面是一个读取位图文件的信息的例子：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFile file;<br>BITMAPINFOHEADER bmpinfo;<br>try<br>{<br>　file.Open("D:\\ToolBar.bmp",CFile::modeRead);<br>　file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);<br>　file.Read(&amp;bmpinfo,sizeof(BITMAPINFOHEADER ));<br>　CString str;<br>　str.Format("位图文件的长是%d,高%d",bmpinfo.biWidth,bmpinfo.biHeight);<br>　MessageBox(str);<br>　file.Close();<br>}<br>catch(CFileException *e)<br>{<br>　CString str;<br>　str.Format("读取数据失败的原因是:%d",e-&gt;m_cause);<br>　MessageBox("str");<br>　file.Abort();<br>　e-&gt;Delete();<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　读取数据：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL ReadFile(<br>　HANDLE hFile, //文件的句柄<br>　LPVOID lpBuffer, //用于保存读入数据的一个缓冲区<br>　DWORD nNumberOfBytesToRead, //要读入的字符数<br>　LPDWORD lpNumberOfBytesRead, //从文件中实际读入的字符数<br>　LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED，那么必须，用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则，应将这个参数设为NULL<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　CFile的成员函数有：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>UINT Read (void* lpBuf,UINT nCount); <br>throw(CFileException);// 返回值是传输到缓冲区的字节数。</td>
        </tr>
    </tbody>
</table>
<br>　　写入数据：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL WriteFile(<br>　HANDLE hFile, //文件的句柄<br>　LPCVOID lpBuffer, //要写入的一个数据缓冲区<br>　DWORD nNumberOfBytesToWrite, //要写入数据的字节数量。如写入零字节，表示什么都不写入，但会更新文件的"上一次修改时间"。<br>　LPDWORD lpNumberOfBytesWritten, //实际写入文件的字节数量<br>　LPOVERLAPPED lpOverlapped // OVERLAPPED，倘若在指FILE_FLAG_OVERLAPPED的前提下打开文件，这个参数就必须引用一个特殊的结构。该结构定义了一次异步写操作。否则，该参数应置为NULL<br>);<br>void Write(const void* lpBuf,UINT nCount);<br>throw (CFileException);</td>
        </tr>
    </tbody>
</table>
<br>　　lpBuf：指向用户提供的缓冲区，包含将写入文件中的数据<br><br>　　nCount：从缓冲区内传输的字节数。对文本模式的文件，回车换行作为一个字符。<br><br>　　下面是象一个文件中写入数据的例子：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFile file;<br>try<br>{<br>　file.Open("d:/my.dat",CFile::modeCreate|CFile::modeWrite);<br>　file.SeekToBegin();<br>　char Data[] = "111111111\n1111111111";<br>　file.Write(Data,sizeof(Data));<br>　file.Flush();<br>　file.Close();<br>}<br>catch(CFileException *e)<br>{<br>　CString str;<br>　str.Format("读取数据失败的原因是:%d",e-&gt;m_cause);<br>　MessageBox("str");<br>　file.Abort();<br>　e-&gt;Delete();<br>}</td>
        </tr>
    </tbody>
</table>
<strong>3．取得和设置文件的创建时间、最后访问时间、最后写时间<br><br></strong>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL GetFileTime(<br>　HANDLE hFile, // 文件句柄<br>　LPFILETIME lpCreationTime, // 创建时间<br>　LPFILETIME lpLastAccessTime, // 最后访问时间<br>　LPFILETIME lpLastWriteTime // 最后写时间 <br>);<br>BOOL SetFileTime(<br>　HANDLE hFile, <br>　CONST FILETIME *lpCreationTime, <br>　CONST FILETIME *lpLastAccessTime, <br>　CONST FILETIME *lpLastWriteTime <br>);<br>typedef struct _FILETIME { <br>　DWORD dwLowDateTime; <br>　DWORD dwHighDateTime; <br>} FILETIME;</td>
        </tr>
    </tbody>
</table>
<br>　　取得三个参数都是FILETIME结构，得到的都是UTC时间，可以通过API函数FileTimeToLocalFileTime（）和FileTimeToSystemTime()将他们转换为本地时间和系统时间格式，也可以通过LocalFileTimeToFileTime 和SystemTimeToFileTime()转换回来，通过SetFileTime设置文件的创建时间、最后访问时间、最后写时间。由于使用的时候要先打开文件，而且取得的最后访问时间就是当前时间，没有多大意义，且比较麻烦，下面介绍CFile类中的静态方法。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>static BOOL PASCAL GetStatus( LPCTSTR lpszFileName, CFileStatus&amp; rStatus );<br>static void SetStatus( LPCTSTR lpszFileName, const CFileStatus&amp; status );<br>throw( CFileException );</td>
        </tr>
    </tbody>
</table>
<br>　　返回的是一个CfileStatus对象，这个结构的具体的成员变量包括：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>struct CFileStatus<br>{<br>　CTime m_ctime; // 文件创建时间<br>　CTime m_mtime; // 文件最近一次修改时间<br>　CTime m_atime; // 文件最近一次访问时间<br>　LONG m_size; // 文件大小<br>　BYTE m_attribute; // 文件属性<br>　BYTE _m_padding; // 没有实际含义，用来增加一个字节<br>　TCHAR m_szFullName[_MAX_PATH]; //绝对路径<br>　#ifdef _DEBUG<br>　　//实现Dump虚拟函数，输出文件属性<br>　　void Dump(CDumpContext&amp; dc) const;<br>　#endif<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　下面就举一个例子来实现：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFileStatus status;<br>char *path = "D:\\VSS";<br>if(CFile::GetStatus( path, status ))<br>{<br>　CString cTime,mTime,aTime;<br>　cTime = status.m_ctime.Format("文件建立时间：%Y年%m月%d日 %H时%M分%S秒");<br>　mTime = status.m_mtime.Format("文件最近修改时间：%Y年%m月%d日 %H时%M分%S秒");<br>　aTime = status.m_atime.Format("文件最近访问时间：%Y年%m月%d日 %H时%M分%S秒");<br>　CString str;<br>　str = cTime + "\n" + mTime +"\n" + aTime ;<br>　MessageBox(str);<br><br>}</td>
        </tr>
    </tbody>
</table>
<br>　　<strong>4．取得和设置文件的属性</strong><br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>DWORD GetFileAttributes(<br>　LPCTSTR lpFileName //文件或文件夹路经<br>);<br>BOOL SetFileAttributes(<br>　LPCTSTR lpFileName, // 文件名<br>　DWORD dwFileAttributes // 要设置的属性<br>);</td>
        </tr>
    </tbody>
</table>
<br>　　取得的文件属性包括：FILE_ATTRIBUTE_ARCHIVE，FILE_ATTRIBUTE_HIDDEN，FILE_ATTRIBUTE_NORMAL，FILE_ATTRIBUTE_OFFLINE，FILE_ATTRIBUTE_READONLY，FILE_ATTRIBUTE_SYSTEM，FILE_ATTRIBUTE_TEMPORARY<br><br>　　不能设置的文件属性包括有：FILE_ATTRIBUTE_COMPRESSED，FILE_ATTRIBUTE_DIRECTORY，FILE_ATTRIBUTE_ENCRYPTED，FILE_ATTRIBUTE_REPARSE_POINT，FILE_ATTRIBUTE_SPARSE_FILE，FILE_ATTRIBUTE_SYSTEM。<br><br>　　CFileStatus中也定义了一组属性：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>enum Attribute { <br>　normal,<br>　readOnly,<br>　hidden,<br>　system,<br>　volume,<br>　directory,<br>　archive<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　可以通过if((status. m_attribute&amp; readOnly) = =FILE_ATTRIBUTE_READONLY)来判断，这里利用另外的API来实现获得文件的详细信息：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>HANDLE FindFirstFile(<br>　LPCTSTR lpFileName, //文件或文件夹路经r<br>　LPWIN32_FIND_DATA lpFindFileData <br>);<br>BOOL FindNextFile(<br>　HANDLE hFindFile,<br>　LPWIN32_FIND_DATA lpFindFileData <br>);<br>BOOL FindClose(HANDLE hFindFile );</td>
        </tr>
    </tbody>
</table>
<br>　　取得的是一个WIN32_FIND_DATA结构;<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>typedef struct _WIN32_FIND_DATA {<br>　DWORD dwFileAttributes; //文件属性<br>　FILETIME ftCreationTime; // 文件创建时间<br>　FILETIME ftLastAccessTime; // 文件最后一次访问时间<br>　FILETIME ftLastWriteTime; // 文件最后一次修改时间<br>　DWORD nFileSizeHigh; // 文件长度高32位<br>　DWORD nFileSizeLow; // 文件长度低32位<br>　DWORD dwReserved0; // 系统保留<br>　DWORD dwReserved1; // 系统保留<br>　TCHAR cFileName[ MAX_PATH ]; // 长文件名<br>　TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名<br>} WIN32_FIND_DATA, *PWIN32_FIND_DATA;</td>
        </tr>
    </tbody>
</table>
<br>　　也可以利用另外一个函数来取得文件的信息:<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>BOOL GetFileInformationByHandle(<br>HANDLE hFile, // 文件的句柄 <br>LPBY_HANDLE_FILE_INFORMATION lpFileInformation <br>);</td>
        </tr>
    </tbody>
</table>
<br>　　函数填充的是BY_HANDLE_FILE_INFORMATION结构体:<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>typedef struct _BY_HANDLE_FILE_INFORMATION { <br>　DWORD dwFileAttributes; <br>　FILETIME ftCreationTime; <br>　FILETIME ftLastAccessTime; <br>　FILETIME ftLastWriteTime; <br>　DWORD dwVolumeSerialNumber; // 文件所在的磁盘的序列号<br>　DWORD nFileSizeHigh; <br>　DWORD nFileSizeLow; <br>　DWORD nNumberOfLinks; //链接的数目<br>　DWORD nFileIndexHigh; <br>　DWORD nFileIndexLow; <br>} BY_HANDLE_FILE_INFORMATION;</td>
        </tr>
    </tbody>
</table>
<br>　　下面就举一个例子来实现： <br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>HANDLE handle;<br>WIN32_FIND_DATA find_data;<br>handle = :: FindFirstFile("D:\\VSS",&amp;find_data);<br>FindClose(handle);<br>find_data.dwFileAttributes = find_data.dwFileAttributes|FILE_ATTRIBUTE_READONLY;<br>::SetFileAttributes("D:\\VSS",find_data.dwFileAttributes);</td>
        </tr>
    </tbody>
</table>
<br>　　在上面的介绍中,除了可以设置文件的属性之外，在操作的过程当中也可以取得文件的其他一些信息，可以根据具体的需要来实现。<br><br><strong>5．获取文件名,文件类型,文件长度,文件路径<br><br></strong>　　用利用CFile打开一个文件时,可以在利用成员函数<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>virtual CString GetFileName( ) const, <br>virtual CString GetFileTitle( ) const, <br>virtual CString GetFilePath( ) const, <br>virtual DWORD GetLength( ) const;throw( CFileException );</td>
        </tr>
    </tbody>
</table>
<br>　　来取得相关信息,如果一个文件的全路经是: c:\windows\write\myfile.wri,则每个函数取得的是: myfile.wri, myfile, c:\windows\write\myfile.wri. GetLength取得文件大小是按字节为单位的。<br><br>　　也可以利用：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>virtual void SetLength( DWORD dwNewLen );throw( CFileException );<br>virtual void SetFilePath( LPCTSTR lpszNewName );</td>
        </tr>
    </tbody>
</table>
<br>　　来设置文件的长度和路径。<br><br>　　在当前的文件下面新建一个Text.txt文件，在里面写点东西，然后运行下面程序：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFile file("Text.txt",CFile::modeReadWrite);<br>ULONGLONG length;<br>CString strFilePath;<br>length = file.GetLength();<br>length = length + 1024*10;<br>file.SetLength(length);<br>file.SetFilePath("D:\\Text.txt");<br>strFilePath = file.GetFilePath();<br>MessageBox(strFilePath);<br>file.Close();</td>
        </tr>
    </tbody>
</table>
<br>　　最后发现文件的路径变了，但是在D盘下面并没有找到Text.txt，原因是SetFilePath只能指定一个路径给文件，SetFilePath并不能做为移动文件来使用。<br><br>　　CFile并没有给出取得文件类型的函数，有了上面基础，这个很容易实现。<br><br>　　API函数中也有获得文件路径的操作，这里只是做简单介绍，可以参照MSDNN的说明：GetFileSize可以获得文件的大小，GetFullPathName 函数获取文件的完整路径名，只有当该文件在当前目录下，结果才正确。GetModuleFileName函数获取文件的完整路径名，这些函数有些用到文件句柄的。<br><br>　　用CFileDialog打开的文件,可以使用它的成员变量m_ofn,或者成员函数GetFileName, GetFileTitle, GetFilePath, GetFileExt来取得相关信息.<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );</td>
        </tr>
    </tbody>
</table>
<br>　　各个参数如下：<br><br>　　&#183;bOpenFileDialog 为TRUE为打开对话框，为FALSE为保存对话文件对话框<br><br>　　&#183;lpszDefExt 指定默认的文件扩展名。 <br><br>　　&#183;lpszFileName 指定默认的文件名。 <br><br>　　&#183;dwFlags 指明一些特定风格。 <br><br>　　&#183;lpszFilter它指明可供选择的文件类型和相应的扩展名。参数格式如： <br><br>　　"Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";文件类型说明和扩展名间用 | 分隔，同种类型文件的扩展名间可以用 ; 分割，每种文件类型间用 | 分隔，末尾用 || 指明。 <br><br>　　pParentWnd 为父窗口指针<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>CString FileFilter = "所有文件(*.*)|*.*||";<br>CFileDialog FileDialog(true,NULL,NULL,OFN_HIDEREADONLY,FileFilter,NULL);<br>FileDialog.DoModal();<br>MessageBox(FileDialog.GetFileName());</td>
        </tr>
    </tbody>
</table>
<br>　　<strong>6．小结</strong><br><br>　　在实际中还有很多其他操作文件的方法，上面介绍的只是简单的几种，希望通过上面的简单介绍，在加上具体实践，能够找到解决问题的最好办法！ 
<img src ="http://www.cppblog.com/coloerful/aggbug/85398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:36 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++之对话框中添加状态栏</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85396.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:33:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85396.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85396.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85396.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85396.html</trackback:ping><description><![CDATA[<p>一、<br>（1）在要添加状态栏的对话框类的类定义中 CStatusBarCtrl&nbsp;&nbsp;&nbsp;&nbsp; *m_StatBar;<br>（2）在OnInitDialog中或其它合适的消息响应中加如下代码：（函数可查看MSDN）<br>&nbsp;m_StatBar=new&nbsp;&nbsp; CStatusBarCtrl;<br>&nbsp;RECT&nbsp;&nbsp;&nbsp;&nbsp; m_Rect;&nbsp;&nbsp; <br>&nbsp;&nbsp; GetClientRect(&amp;m_Rect);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取对话框的矩形区域<br>&nbsp;&nbsp; m_Rect.top=m_Rect.bottom-20;&nbsp;&nbsp;&nbsp; //设置状态栏的矩形区域<br>&nbsp;&nbsp; m_StatBar-&gt;Create(WS_BORDER|WS_VISIBLE|CBRS_BOTTOM,m_Rect,this,3);&nbsp;&nbsp; </p>
<p>&nbsp;int nParts[4]= {100, 200, 300,-1};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //分割尺寸<br>&nbsp;m_StatBar-&gt;SetParts(4, nParts);&nbsp; //分割状态栏<br>&nbsp;m_StatBar-&gt;SetText("这是第一个指示器",0,0); //第一个分栏加入"这是第一个指示器"<br>&nbsp;m_StatBar-&gt;SetText("这是第二个指示器",1,0); //以下类似<br>&nbsp;/*也可使用以下方式加入指示器文字<br>&nbsp;m_StatBar.SetPaneText(0,"这是第一个指示器",0);<br>&nbsp;其他操作：m_StatBar-&gt;SetIcon(3,SetIcon(AfxGetApp()-&gt;LoadIcon(IDI_ICON3),FALSE));<br>&nbsp;//在第四个分栏中加入ID为IDI_ICON3的图标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *********************************************/</p>
<p>&nbsp;m_StatBar-&gt;ShowWindow(SW_SHOW); <br>二、<br>（1）在对话框类的.cpp源文件的开头加上如下代码：<br>&nbsp;static UINT BASED_CODE indicators[]=&nbsp;&nbsp; <br>&nbsp;//状态栏的指示器列表，如有未定义的字符串名，需在Resource View的String Table中添加定义<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ID_INDICATOR_CAPS,<br>&nbsp;&nbsp;&nbsp;&nbsp; ID_INDICATOR_NUM,<br>&nbsp; ID_INDICATOR_USER,//需在Resource View的String Table中添加定义<br>&nbsp;&nbsp; };<br>（2）在要添加状态栏的对话框类的类定义中 CStatusBarCtrl&nbsp; m_StatusBar;<br>（3）在OnInitDialog中或其它合适的消息响应中加如下代码：<br>&nbsp;//不能是突出和无边框风格<br>&nbsp;m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,AFX_IDW_STATUS_BAR );<br>&nbsp;m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));//设置指示器数量<br>&nbsp; CRect rect;<br>&nbsp;&nbsp;&nbsp;&nbsp; GetClientRect(&amp;rect);</p>
<p>&nbsp; m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/3);//设置指示器窗口的有关信息<br>&nbsp;&nbsp; m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/3);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_CAPS);//很重要****<br>&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,20,180));//设置背景<br>&nbsp; m_StatusBar.SetPaneText(0,"指示器1",0);<br>&nbsp; m_StatusBar.SetPaneText(1,"指示器2",0);&nbsp; </p>
<p>文章出处：<a href="http://www.diybl.com/course/3_program/vc/vc_js/2008215/99842.html">http://www.diybl.com/course/3_program/vc/vc_js/2008215/99842.html</a></p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:33 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对话框中工具栏，状态栏随对话框变化而变化</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85395.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85395.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85395.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85395.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85395.html</trackback:ping><description><![CDATA[<p>添加窗体的Onsize事件：<br>void CStatusbartestDlg::OnSize(UINT nType, int cx, int cy) <br>{<br>&nbsp;CDialog::OnSize(nType, cx, cy);<br>&nbsp;<br>&nbsp;// TODO: Add your message handler code here<br>&nbsp;CRect&nbsp;&nbsp; rectMain;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; CPaintDC&nbsp;&nbsp; dc(this);&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; this-&gt;GetClientRect(rectMain); <br>&nbsp;CRect rectBar;</p>
<p>&nbsp;CToolBar *pToolBar = (CToolBar *)AfxGetApp()-&gt;m_pMainWnd-&gt;GetDescendantWindow(AFX_IDW_TOOLBAR); <br>&nbsp;if(pToolBar != NULL)<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;pToolBar-&gt;GetClientRect(&amp;rectBar);&nbsp;&nbsp; <br>&nbsp;&nbsp;pToolBar-&gt;MoveWindow(0,0,rectMain.Width(),rectBar.Height()+9); <br>&nbsp;&nbsp;CWnd *pStaticToolBar = GetDlgItem(IDC_STATIC_ToolBar);//IDC_STATIC_ToolBar为picture控件，模拟工具栏的分隔条<br>&nbsp;&nbsp;if(pStaticToolBar != NULL)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;pToolBar-&gt;GetClientRect(&amp;rectBar);&nbsp; <br>&nbsp;&nbsp;&nbsp;pStaticToolBar-&gt;MoveWindow(0,rectBar.Height()+10,rectMain.Width(),2);<br>&nbsp;&nbsp;&nbsp;pStaticToolBar-&gt;ShowWindow(SW_SHOW);<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p>&nbsp;CStatusBarCtrl *pStatusBar = (CStatusBarCtrl *)AfxGetApp()-&gt;m_pMainWnd-&gt;GetDescendantWindow(AFX_IDW_STATUS_BAR);//取得窗口指针<br>&nbsp;&nbsp;&nbsp; if(pStatusBar != NULL)<br>&nbsp;{<br>&nbsp;<br>&nbsp;&nbsp;pStatusBar-&gt;GetClientRect(&amp;rectBar);<br>&nbsp;&nbsp;pStatusBar-&gt;MoveWindow(0,cy-rectBar.Height(),rectMain.Width(),rectBar.Height());<br>&nbsp;&nbsp;pStatusBar-&gt;GetClientRect(&amp;rectBar);<br>&nbsp;&nbsp;int nParts[4]= {rectMain.Width()/rectBar.Width()*100, rectMain.Width()/rectBar.Width()*200, rectMain.Width()/rectBar.Width()*400,-1};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //分割尺寸<br>&nbsp;&nbsp;pStatusBar-&gt;SetParts(4, nParts);&nbsp; //分割状态栏<br>&nbsp;&nbsp;CWnd *pStaticBar = GetDlgItem(IDC_STATIC_BAR);//picture控件ID<br>&nbsp;&nbsp;if(pStaticBar != NULL)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;pStaticBar-&gt;MoveWindow(0,rectMain.Height() - rectBar.Height()-1,rectMain.Width(),2);<br>&nbsp;&nbsp;&nbsp;pStaticBar-&gt;ShowWindow(SW_SHOW);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp; //绘制背景色&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; dc.FillSolidRect(rectMain,RGB(255,255,255));&nbsp;&nbsp;&nbsp;&nbsp; //设置为白色&nbsp; <br>&nbsp;}<br>&nbsp;<br>}</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:32 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于对话框程序，自定义状态栏</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85393.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:27:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85393.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85393.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85393.html</trackback:ping><description><![CDATA[<p>1.使用CStatusBar类。步骤如下：</p>
<p>&nbsp;&nbsp;&nbsp; (1)在C***Dlg类为添加成员变量：CStatusBar m_StatusBar<br>&nbsp;&nbsp; (2)在String Table中添加一些要显示在状态栏上的字符串。<br>&nbsp;&nbsp; (3)在C***Dlg源文件中定义一个全局数组：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static UINT indicators[]={<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; ID_SEPARATOR,<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; IDS_COMPANY,<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; IDS_MICROSOFT,<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; IDS_TIME<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp; (4)在OnInitDialog()函数中添加如下代码：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRect Rect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetClientRect(&amp;Rect);&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!m_StatusBar.Create(this) || !m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE0("Failed to create status bar\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.MoveWindow(0,Rect.bottom-20,Rect.right,20);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置状态栏位置</p>
<p>2.使用CStatusBarCtrl类。步骤如下：</p>
<p>&nbsp;&nbsp; (1)在C***Dlg类为添加成员变量：CStatusBarCtrl m_StatusBar<br>&nbsp;&nbsp; (2)在OnInitDialog()函数中添加如下代码：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRect Rect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this-&gt;GetClientRect(&amp;Rect);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取客户区域</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.Create(WS_CHILD | WS_VISIBLE,CRect(0,0,0,0),this,IDR_STATUSBAR);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int width[5];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width[0]=Rect.Width()*0.1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width[1]=Rect.Width()*0.4;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width[2]=Rect.Width()*0.6;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width[3]=Rect.Width()*0.8;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width[4]=Rect.Width();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.SetParts(5,width);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.SetText("公司",0,0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.SetText("微软(中国)有限公司",1,0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.SetText("系统时间",3,0);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetTimer(1,1000,NULL);&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; //设置定时器<br>&nbsp;&nbsp; (3)在C***Dlg类上添加WM_TIMER消息响应，编写响应函数OnTimer(UINT nIDEvent)：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTime time=CTime::GetCurrentTime();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取当前时间<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CString str=time.Format("%H:%M:%S");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //时间格式化为字符串</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_StatusBar.SetText(str,4,0);</p>
<p><strong>最终效果：</strong></p>
<p align=center forimg="1"><img class=blogimg src="http://hiphotos.baidu.com/ewook/pic/item/0234758d8b35cc0cb31bbafd.jpg" border=0 small="0"></p>
<p align=left forimg="1"><strong>注解：</strong>SetParts函数的原型如下：</p>
<p><strong>BOOL</strong> <strong>SetParts(</strong> <strong>int</strong> <em>nParts</em><strong>,</strong> <strong>int*</strong> <em>pWidths</em> <strong>);</strong></p>
<p>其中nParts指示将状态栏分为多少个部分；pWidths指向一个int型的数组，数组中每一个元素指示状态栏各部分相对于客户区域的右边界。</p>
<p>SetText函数的原型如下：</p>
<p><strong>BOOL</strong> <strong>SetText(</strong> <strong>LPCTSTR</strong> <em>lpszText</em><strong>,</strong> <strong>int</strong> <em>nPane</em><strong>,</strong> <strong>int</strong> <em>nType</em> <strong>);</strong></p>
<p>其中lpszText指向状态栏字符串；nPane指示要设置文本的状态栏部分的索引号；nType指示绘画操作的类型。</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:27 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用MFC创建文件夹</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85392.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:24:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85392.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85392.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85392.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85392.html</trackback:ping><description><![CDATA[CString strFolderPath="c:\\test" <br>// 判断路径是否存在 <br>if (!PathIsDirectory(m_strFolderPath) ) <br>{ <br>CString strMsg; <br>strMsg.Format ("指定路径\"%s\"不存在，是否创建?", m_strFolderPath); <br>if (AfxMessageBox(strMsg, MB_YESNO) == IDYES) <br>{ <br>if (!CreateDirectory(m_strFolderPath, NULL ) ) <br>{ <br>strMsg.Format ("创建路径\"%s\"失败！是否继续?", m_strFolderPath); <br>if (AfxMessageBox(strMsg, MB_YESNO) == IDYES) <br>return; <br>} <br>} <br>} <br>------------------------------------------------------- <br>CreateDirectory(LPCTSTR lpPathName, //irectory name <br>LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD <br><br>}<br>&nbsp;<br>-----------------------------------------------------------------------------------------------------------<br>
<div>
<p><font size=3><font face=system><span>在程序里，将数据保存在以下路径中</span><span>d:\YourFloder\</span></font></font></p>
<p><font size=3><font face=system><span>如果没有该文件夹，就创建此文件夹。</span></font></font></p>
<p><span><font face=system size=3></font></span></p>
<p><span><font face=system size=3>&nbsp;</font></span></p>
<p><span><font face=system size=3>DWORD dwAttr=GetFileAttributes("d:\\YourFloder");</font></span></p>
<p><font size=3><font face=system><span>//</span><span>若文件夹不存在，创建文件夹</span></font></font></p>
<p><span><font size=3><font face=system>if(dwAttr==0xFFFFFFFF) </font></font></span></p>
<p><span><font face=system size=3>CreateDirectory("d:\\YourFloder",NULL);</font></span></p>
<p><font size=3><font face=system><span>//</span><span>文件夹存在</span></font></font></p>
<p><span><font size=3><font face=system>else if(dwAttr &amp; FILE_ATTRIBUTE_DIRECTORY){</font></font></span></p>
<p><span><font size=3><font face=system>&nbsp;<span>//do something</span></font></font></span></p>
<p><span><font face=system size=3>}</font></span></p>
</div>
<img src ="http://www.cppblog.com/coloerful/aggbug/85392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:24 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC中建立一个文件，文件名为当前日期</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85391.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85391.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85391.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85391.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85391.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85391.html</trackback:ping><description><![CDATA[&nbsp;<span>/*&nbsp;</span><span>建立一个文件，文件名为当前日期<span>&nbsp;*/<br></span></span><span>&nbsp;char&nbsp;pFileName[30];</span>
<p align=left><span>&nbsp;COleDateTime timeNow, dateNow;<br>&nbsp;timeNow = COleDateTime::GetCurrentTime();&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>获取当前日期时间<span><br></span></span><span>&nbsp;dateNow = COleDateTime::GetCurrentTime();&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>同样获取当前日期时间，这么写只是为了清晰<span><br></span></span><span>&nbsp;CString sTime = timeNow.Format(VAR_TIMEVALUEONLY);&nbsp; &nbsp;&nbsp; </span><span>// </span><span>获取当前时间<span><br></span></span><span>&nbsp;CString sDate = dateNow.Format(VAR_DATEVALUEONLY);&nbsp;&nbsp; &nbsp; </span><span>// </span><span>获取当前日期<span><br></span></span><span>&nbsp;CString FileName = sDate + "_" + sTime + ".txt";&nbsp;&nbsp;&nbsp; &nbsp;</span><span>// </span><span>文件名<span> = </span>日期<span>_</span>时间<span>.txt<br></span></span><span>&nbsp;<br>&nbsp;fileNameLength = FileName.GetLength();&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>获得文件名长度，<span>CFile</span>不能用<span>CString</span>，只能用<span>string</span>做参数，要做转换<span><br></span></span><span>&nbsp;for(i=0; i &lt; fileNameLength ; i++)<br>&nbsp;{<br>&nbsp;&nbsp;pFileName[i] = FileName.GetAt(i);&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// CString -&gt; string<br></span><span>&nbsp;&nbsp;if( pFileName[i] == ':')&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>剔除<span>':'</span>等不能作为文件名的符号<span><br></span></span><span>&nbsp;&nbsp;&nbsp;pFileName[i] = '-';<br>&nbsp;}<br>&nbsp;pFileName[i] = '\0';&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>文件名结束，一定要加，不然有错</span></p>
<p align=left><span>&nbsp;CFile f;<br>&nbsp;if( !f.Open( pFileName, CFile::modeCreate | CFile::modeWrite, &amp;e ) )&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span><span>通过<span>CFile</span>的<span>class member</span>建立文件<span><br></span></span><span>&nbsp;{<br>&nbsp;&nbsp;AfxMessageBox("File can't be opened.");<br>&nbsp;}&nbsp;&nbsp;<br></span></p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:23 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置 </title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85390.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:22:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85390.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85390.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85390.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85390.html</trackback:ping><description><![CDATA[<p>用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。</p>
<p>void MoveWindow(int x,int y,int nWidth,int nHeight);<br>void MoveWindow(LPCRECT lpRect);<br>第一种用法需给出控件新的坐标和宽度、高度；<br>第二种用法给出存放位置的CRect对象；<br>例：<br>CWnd *pWnd;<br>pWnd = GetDlgItem( IDC_EDIT1 );&nbsp;&nbsp;&nbsp; //获取控件指针，IDC_EDIT1为控件ID号<br>pWnd-&gt;MoveWindow( CRect(0,0,100,100) );&nbsp;&nbsp;&nbsp; //在窗口左上角显示一个宽100、高100的编辑控件</p>
<p>SetWindowPos()函数使用更灵活，多用于只修改控件位置而大小不变或只修改大小而位置不变的情况：<br>BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);<br>第一个参数我不会用，一般设为NULL;<br>x、y控件位置；cx、cy控件宽度和高度；<br>nFlags常用取值：<br>SWP_NOZORDER：忽略第一个参数；<br>SWP_NOMOVE：忽略x、y，维持位置不变；<br>SWP_NOSIZE：忽略cx、cy，维持大小不变；<br>例：<br>CWnd *pWnd;<br>pWnd = GetDlgItem( IDC_BUTTON1 );&nbsp;&nbsp;&nbsp; //获取控件指针，IDC_BUTTON1为控件ID号<br>pWnd-&gt;SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE );&nbsp;&nbsp;&nbsp; //把按钮移到窗口的(50,80)处<br>pWnd = GetDlgItem( IDC_EDIT1 );<br>pWnd-&gt;SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE );&nbsp;&nbsp;&nbsp; //把编辑控件的大小设为(100,80)，位置不变<br>pWnd = GetDlgItem( IDC_EDIT1 );<br>pWnd-&gt;SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER );&nbsp;&nbsp;&nbsp; //编辑控件的大小和位置都改变<br>以上方法也适用于各种窗口。</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:22 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dialog中使用Toolbar</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85389.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:21:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85389.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85389.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85389.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85389.html</trackback:ping><description><![CDATA[1.先在XXXXDlg.h加入CToolBar m_pToolBar；<br>2. 在XXXXDlg.cpp 中加入如下代码：<br><br>if(!(m_pToolBar.Create(this)) || !(m_pToolBar.LoadToolBar(IDR_TOOLBAR1)))<br>{<br>TRACE0("Failed to Create Dialog Toolbar");<br>EndDialog(IDCANCEL);<br>}<br>CRect rcClientOld; // Old Client Rect<br>CRect rcClientNew; // New Client Rect with Tollbar Added<br>GetClientRect(rcClientOld); // Retrive the Old Client WindowSize<br>// Called to reposition and resize control bars in the client area of a window<br>// The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.<br>// And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.<br>RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew);<br>// All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover them up.<br>// Offest to move all child controls after adding Tollbar<br>CPoint ptOffset(rcClientNew.left-rcClientOld.left,rcClientNew.top-rcClientOld.top);<br>CRect rcChild;<br>CWnd* pwndChild = GetWindow(GW_CHILD); //Handle to the Dialog Controls<br>while(pwndChild) // Cycle through all child controls<br>{<br>pwndChild-&gt;GetWindowRect(rcChild); // Get the child control RECT<br>ScreenToClient(rcChild); <br>rcChild.OffsetRect(ptOffset); // Changes the Child Rect by the values of the claculated offset<br>pwndChild-&gt;MoveWindow(rcChild,FALSE); // Move the Child Control<br>pwndChild = pwndChild-&gt;GetNextWindow();<br>}<br>CRect rcWindow;<br>GetWindowRect(rcWindow); // Get the RECT of the Dialog<br>rcWindow.right += rcClientOld.Width() - rcClientNew.Width(); // Increase width to new Client Width<br>rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height(); // Increase height to new Client Height<br>MoveWindow(rcWindow,FALSE); // Redraw Window<br>// Now we REALLY Redraw the Toolbar<br>RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
<img src ="http://www.cppblog.com/coloerful/aggbug/85389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:21 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC中自动改变控件位置和大小的对话框类</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85388.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:18:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85388.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85388.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85388.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85388.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85388.html</trackback:ping><description><![CDATA[<p>在用VC开发应用程序时，经常会要做一些可以改变大小的对话框，而这个时候就要求对话框上的控件会随着对话框大小的改变而改变自己的位置和大小。如果控件比较少，那可以在对话框的OnSize()事件里面添加代码，通过计算来调整各个控件的位置和大小；但是，如果对话框上的控件比较多的话，那这将是一件非常痛苦的事情！要是程序中又有很多可以改变大小的对话框，那一个一个的OnSize()写下来，那会使程序员崩溃的！</p>
<p>　　为了解决这个问题，我写了一个自动改变控件位置和大小的对话框类ClxDialog。从这个类继承的对话框类，只要在OnInitDialog()里对控件做一些简单的设置，对话框上的控件就会随着对话框大小的改变而改变自己的位置和大小。</p>
<p>　　为了保存控件信息，我定义了一个结构：</p>
<p><code>typedef struct _dlgControlTag<br>{<br>　int iId; // 控件ID<br>　int iFlag; // 标志，表示怎样改变控件的位置或者大小<br>　int iPercent; // 改变值占对话框改变值的百分比<br>} DLGCTLINFO, *PDLGCTLINFO;</code></p>
<p>　　这里要对结构中的iFlag和iPercent进行一些解释。其中iFlag是下面的枚举值：</p>
<p><code>enum<br>{<br>　MOVEX = 0, // 控件在X方向（左右）移动<br>　MOVEY, // 控件在Y方向（上下）移动<br>　MOVEXY, // 控件在X方向和Y方向同时移动<br>　ELASTICX, // 控件在X方向（宽度）改变大小<br>　ELASTICY, // 控件在Y方向改（高度）改变大小<br>　ELASTICXY // 控件在X方向和Y方向同时改变大小<br>};</code></p>
<p>　　iPercent表示改变值占对话框改变值的百分比。例如，一个控件的iPercent值为100，iFlag值为MOVEX，那么当对话框的宽度改变100个单位的时候，这个控件就在X方向移动100个单位；又如，一个控件的iPercent值为100，iFlag值为ELASTICXY，那么当对话框的宽度和高度分别改变100个单位的时候，控件的高度和宽度也相应的改变100个单位。</p>
<p>&nbsp;</p>
<p><code>BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);</code></p>
<p>　　使用起来非常简单，在对话框的OnInitDialog()函数里面添加类似下面的代码就行了：</p>
<p><code>// 控件信息数组<br>static DLGCTLINFO dcMenuGroup[] =<br>{<br>　{IDOK, MOVEX, 100},<br>　{IDCANCEL, MOVEX, 100},<br>　{IDC_BUTTON1, MOVEX, 50},<br>　{IDC_BUTTON1, MOVEY, 100},<br>　{IDC_EDIT1, ELASTICX, 100},<br>　{IDC_EDIT2, ELASTICX, 50},<br>　{IDC_EDIT3, ELASTICX, 50},<br>　{IDC_EDIT3, MOVEX, 50},<br>　{IDC_EDIT4, ELASTICY, 100},<br>　{IDC_EDIT5, ELASTICX, 100},<br>　{IDC_EDIT5, ELASTICY, 50},<br>　{IDC_EDIT6, ELASTICX, 100},<br>　{IDC_EDIT6, ELASTICY, 50},<br>　{IDC_EDIT6, MOVEY, 50},<br>};<br>// 设置控件信息<br>SetControlProperty(dcMenuGroup, sizeof(dcMenuGroup)/sizeof(DLGCTLINFO));</code></p>
<p>　　下面就是使用上面这段代码的对话框改变大小前后的效果图：</p>
<p><img onclick=get_larger(this) alt=VC中自动改变控件位置和大小的对话框类 src="http://img.ddvip.com/2008_11_12/1226481590_ddvip_8564.jpg"></p>
<p><img onclick=get_larger(this) alt=VC中自动改变控件位置和大小的对话框类 src="http://img.ddvip.com/2008_11_12/1226481590_ddvip_7627.jpg">　 </p>
<p>　　对两张截图的比较我们可以很容易的理解上面那段代码。</p>
<p>　　我还提供了一个函数：</p>
<p><code>void ShowSizeIcon(BOOL bShow = TRUE);</code> </p>
<p>　　来设置是否显示对话框右下角表示可以改变大小的图标。这个图标是从系统中读取的，我上面的截图是Windows2000下的，在WindowsXP中就会自动变成XP风格的。</p>
<!-- 分页 -->
<p>&nbsp;</p>
<p>好了，闲话不多说了，下面贴出该对话框类ClxDialog的源代码，里面有详细的注释：</p>
<p><code>lxDialog.h文件：<br>/////////////////////////////////////////////////////////////////////////////////////<br>// 自动改变控件位置和大小的对话框类<br>// 文件名：lxDialog.h<br>// 作者：StarLee(coolstarlee@sohu.com)<br>/////////////////////////////////////////////////////////////////////////////////////<br>class ClxDialog : public CDialog<br>{<br>public:<br>ClxDialog(UINT nID, CWnd* pParent = NULL);<br>typedef struct _dlgControlTag<br>{<br>　int iId;<br>　int iFlag;<br>　int iPercent;<br>} DLGCTLINFO, *PDLGCTLINFO;<br>enum<br>{<br>　MOVEX = 0,<br>　MOVEY,<br>　MOVEXY,<br>　ELASTICX,<br>　ELASTICY,<br>　ELASTICXY<br>};<br>// 设置控件信息<br>BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);<br>// 是否在对话框右下角显示表示可改变大小的图标<br>void ShowSizeIcon(BOOL bShow = TRUE);<br>protected:<br>　virtual BOOL OnInitDialog();<br>　afx_msg void OnSize(UINT nType, int cx, int cy);<br>　afx_msg void OnSizing(UINT nSide, LPRECT lpRect);<br>　DECLARE_MESSAGE_MAP()<br>private:<br>　int m_iClientWidth; // 对话框client区域的宽度<br>　int m_iClientHeight; // 对话框client区域的高度<br>　int m_iMinWidth; // 对话框的最小宽度<br>　int m_iMinHeight; // 对话框的最小高度<br>　PDLGCTLINFO m_pControlArray; // 控件信息数组指针<br>　int m_iControlNumber; // 设置控件信息的控件个数<br>　BOOL m_bShowSizeIcon; // 是否显示表示可改变大小的图标<br>　CStatic m_wndSizeIcon; // 放图标的静态控件<br>　// 保存图标的bitmap<br>　CBitmap m_bmpSizeIcon;<br>　BITMAP m_bitmap;<br>};<br>lxDialog.cpp文件:<br>//////////////////////////////////////////////////////////////////////<br>// 自动改变控件位置和大小的对话框类<br>// 文件名：lxDialog.cpp<br>// 作者：StarLee(coolstarlee@sohu.com)<br>//////////////////////////////////////////////////////////////////////<br>#include "stdafx.h"<br>#include "lxDialog.h"<br>// 表示可改变大小的图标ID<br>#ifndef OBM_SIZE<br>#define OBM_SIZE 32766<br>#endif<br>ClxDialog::ClxDialog(UINT nID, CWnd* pParent /*=NULL*/)<br>: CDialog(nID, pParent)<br>, m_iClientWidth(0)<br>, m_iClientHeight(0)<br>, m_iMinWidth(0)<br>, m_iMinHeight(0)<br>, m_pControlArray(NULL)<br>, m_iControlNumber(0)<br>, m_bShowSizeIcon(TRUE)<br>{}<br>BEGIN_MESSAGE_MAP(ClxDialog, CDialog)<br>　ON_WM_SIZE()<br>　ON_WM_SIZING()<br>END_MESSAGE_MAP()<br>BOOL ClxDialog::OnInitDialog()<br>{<br>　CDialog::OnInitDialog();<br>　// 设置对话框为可变大小的<br>　ModifyStyle(0, WS_SIZEBOX);<br>　// 以对话框的初始大小作为对话框的宽度和高度的最小值<br>　CRect rectDlg;<br>　GetWindowRect(rectDlg);<br>　m_iMinWidth = rectDlg.Width();<br>　m_iMinHeight = rectDlg.Height();<br>　// 得到对话框client区域的大小<br>　CRect rectClient;<br>　GetClientRect(rectClient);<br>　m_iClientWidth = rectClient.Width();<br>　m_iClientHeight = rectClient.Height();<br>　// Load图标<br>　m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE);<br>　m_bmpSizeIcon.GetBitmap(&amp;m_bitmap);<br>　// 创建显示图标的静态控件并放在对话框右下角<br>　m_wndSizeIcon.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0);<br>　m_wndSizeIcon.SetBitmap(m_bmpSizeIcon);<br>　m_wndSizeIcon.MoveWindow(m_iClientWidth - m_bitmap.bmWidth, m_iClientHeight - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);<br>　// 显示图标<br>　m_wndSizeIcon.ShowWindow(m_bShowSizeIcon);<br>　return TRUE;<br>}<br>void ClxDialog::OnSize(UINT nType, int cx, int cy)<br>{<br>　CDialog::OnSize(nType, cx, cy);<br>　// 对话框宽度和高度的增量<br>　int iIncrementX = cx - m_iClientWidth;<br>　int iIncrementY = cy - m_iClientHeight;<br>　// 最小化时增量为0<br>　if (nType == SIZE_MINIMIZED)<br>　{<br>　　iIncrementX = iIncrementY = 0;<br>　}<br>　for (int i = 0; i &lt; m_iControlNumber; i++)<br>　{<br>　　CWnd *pWndCtrl = NULL;<br>　　int iId = m_pControlArray[i].iId;<br>　　int iFlag = m_pControlArray[i].iFlag;<br>　　int iPercent = m_pControlArray[i].iPercent;<br>　　// 无效值<br>　　if ((iPercent &lt; 0) || (iPercent &gt; 100))<br>　　　continue;<br>　　// 得到控件指针<br>　　pWndCtrl = GetDlgItem(iId);<br>　　if ((NULL != pWndCtrl) &amp;&amp; IsWindow(pWndCtrl-&gt;GetSafeHwnd()))<br>　　{<br>　　　CRect rectCtrl;<br>　　　pWndCtrl-&gt;GetWindowRect(rectCtrl);<br>　　　ScreenToClient(rectCtrl);<br>　　　int iLeft = rectCtrl.left;<br>　　　int iTop = rectCtrl.top;<br>　　　int iWidth = rectCtrl.Width();<br>　　　int iHeight = rectCtrl.Height();<br>　　　switch (iFlag)<br>　　　{<br>　　　　case MOVEX: // X方向移动<br>　　　　　iLeft += (iIncrementX * iPercent / 100);<br>　　　　　break;<br>　　　　case MOVEY: // Y方向移动<br>　　　　　iTop += (iIncrementY * iPercent / 100);<br>　　　　　break;<br>　　　　case MOVEXY: // X方向和Y方向同时移动<br>　　　　　iLeft += (iIncrementX * iPercent / 100);<br>　　　　　iTop += (iIncrementY * iPercent / 100);<br>　　　　　break;<br>　　　　case ELASTICX: // X方向改变大小<br>　　　　　iWidth += (iIncrementX * iPercent / 100);<br>　　　　　break;<br>　　　　case ELASTICY: // Y方向改变大小<br>　　　　　iHeight += (iIncrementY * iPercent / 100);<br>　　　　　break;<br>　　　　case ELASTICXY: // X方向和Y方向同时改变大小<br>　　　　　iWidth += (iIncrementX * iPercent / 100);<br>　　　　　iHeight += (iIncrementY * iPercent / 100);<br>　　　　　break;<br>　　　　default:<br>　　　　　;<br>　　　}<br>　　　// 把控件移动到新位置<br>　　　pWndCtrl-&gt;MoveWindow(iLeft, iTop, iWidth, iHeight);<br>　　}<br>　}<br>　// 把图标移动到对话框右下角<br>　if (IsWindow(m_wndSizeIcon.GetSafeHwnd()))<br>　　m_wndSizeIcon.MoveWindow(cx - m_bitmap.bmWidth, cy - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);<br>　// 记录对话框client区域的大小<br>　if (nType != SIZE_MINIMIZED)<br>　{<br>　　m_iClientWidth = cx;<br>　　m_iClientHeight = cy;<br>　}<br>}<br>void ClxDialog::OnSizing(UINT nSide, LPRECT lpRect)<br>{<br>　CDialog::OnSizing(nSide, lpRect);<br>　// 对话框不能小于初始大小<br>　int iWidth = lpRect-&gt;right - lpRect-&gt;left;<br>　int iHeight = lpRect-&gt;bottom - lpRect-&gt;top;<br>　if (iWidth &lt;= m_iMinWidth)<br>　　lpRect-&gt;right = lpRect-&gt;left + m_iMinWidth;<br>　if(iHeight &lt;= m_iMinHeight)<br>　　lpRect-&gt;bottom = lpRect-&gt;top + m_iMinHeight;<br>}<br>BOOL ClxDialog::SetControlProperty(PDLGCTLINFO lp, int nElements)<br>{<br>　// 设置控件数组信息<br>　if (NULL == lp)<br>　　return FALSE;<br>　if (nElements &lt;= 0)<br>　　return FALSE;<br>　m_pControlArray = lp;<br>　m_iControlNumber = nElements;<br>　return TRUE;<br>}<br>void ClxDialog::ShowSizeIcon(BOOL bShow /*=NULL*/)<br>{<br>　m_bShowSizeIcon = bShow;<br>}</code></p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:18 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++在对话框中加入属性页</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85387.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:17:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85387.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85387.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85387.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85387.html</trackback:ping><description><![CDATA[<p>当一个基于对话框的<a href="http://www.programbbs.com/doc/"><u><font color=#0000ff>程序</font></u></a>中有相当多的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>时，你一定会想到使用属性页来将这些<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>分类放置。本文针对这种方法来讨论几种可能实现的方案。</p>
<p>方案一<br>本方案的例子请见源代码打包文件中的Property1部分</p>
<p>在对话框上放置一个Tab Control的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，再在对话框上放置所需的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>（本例放置了2个按钮，试图在每个标签中显示一个）。然后利用Class Wizard来为Tab Control<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>创建一个<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量，该变量是CTabCtrl类的，再为其他<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>也创建相应的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>类。 在主对话框的初始函数中CProperty1Dlg::OnInitDialog()加入如下代码：<br>//本例插入两个标签，实际运用中可通过循环插入所需个数的标签，运行后默认第一个标签被选中<br>m_tab.InsertItem( 0, _T("Tab1") );<br>m_tab.InsertItem( 1, _T("Tab2") );<br>//将不是第一个标签的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>隐藏掉，只留下你要的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a><br>m_button2.ShowWindow( SW_HIDE );<br>再利用ClassWizard处理Tab Control的 TCN_SELCHANGE 的消息。在消息处理函数中，利用CWnd::ShowWindow来使相应的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>显示和隐藏。 <br>void CProperty1Dlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) <br>{<br>//GetCurSel返回当前被选中的标签的索引号（以0为基础算起）<br>int sel = m_tab.GetCurSel();</p>
<p>switch(sel)<br>{<br>case 0:<br>m_button1.ShowWindow( SW_SHOW );<br>m_button2.ShowWindow( SW_HIDE );<br>break;<br>case 1:<br>m_button2.ShowWindow( SW_SHOW );<br>m_button1.ShowWindow( SW_HIDE );<br>break;<br>}</p>
<p>*pResult = 0;<br>}<br>这样做以后就可以使界面上的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>在不同的标签中显示了，但是这个方案也有很多弊病。 </p>
<p>所有的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>仍然在一个对话框内，在使用对话框编辑器进行编辑时，操作很不方便。 <br>为了能分类显示<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，必须用ClassWizard为每一个<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>创建一个<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量，以便利用各<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量的CWnd基类的ShowWindow函数来显示和隐藏。有时为了使用DDX和DDV机制来进行数据交换，还要创建一些存放值的变量，这样就使得整个对话框类变得相当庞大难以操作。 <br>当然你也可以使用数组来存放那些<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量或值变量，但是这样并不是最好，有时一些不相关的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量放入一个数组中，通过没有实际意义的数组索引号来访问<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，对<a href="http://www.programbbs.com/doc/"><u><font color=#0000ff>程序</font></u></a>的编写会造成麻烦。 最好能将所有<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>进行分类，放入不通对话框类中，这些对话框作为子对话框出现在主对话框中。可以。现在看看方案二。</p>
<p>方案二<br>本方案的例子请见源代码打包文件中的Property2部分<br>这个方案中，我将使用MFC中现成的CPropertySheet和CPropertyPage类来完成将<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>分散到各个对话框类中。 </p>
<p>首先加入两个（或数个）对话框资源。修改各对话框资源的属性，将对话框的Caption属性改为你要在标签上所显示的文字。将对话框的Style属性改为：Child， Border属性改为：Thin， 只选中Title Bar复选框，去掉其他复选框。然后你可以在这些对话框中加入要分开显示的各个<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>。</p>
<p>为上述对话框资源分别制作一个对话框类，该对话框类是从CPropertyPage继承。这样一来各子对话框类就好了，主对话框类可以直接使用CPropertySheet类。使用如下代码即可： <br>CPropertySheet sheet("属性页对话框");<br>CPage1 page1;<br>CPage2 page2;<br>//加入子对话框作为一个属性页<br>sheet.AddPage(&amp;page1);<br>sheet.AddPage(&amp;page2);<br>//产生一个模态对话框，也可以使用Create方法来产生一个非模态对话框（具体参见MSDN）<br>sheet.DoModal();</p>
<p>这样这个对话框效果如下：</p>
<p><img src="http://www.programbbs.com/doc/resource/0/525_dip1.gif"></p>
<p>但是会有人问，如何在主对话框中放置其他<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>呢？如果直接使用CPropertySheet的话，是不可以的，但是别忘了我们可以从CPropertySheet类继承自己的类啊！下面来看看方案三的做法。 </p>
<p>方案三<br>本方案的例子请见源代码打包文件中的Property3部分</p>
<p>首先还是要创建那些要在属性页中的显示的子对话框类，创建步骤和方案二一样，都是从CPropertyPage继承。 </p>
<p>这次我们将从CPropertySheet类继承自己的类（假设类名为CMySheet）。我们要在这里放上一个button<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>。那么现在先在CMySheet中加入一个CButton类的成员变量m_button。</p>
<p>在CMySheet类中的OnInitDialog()函数里，这样写：<br>BOOL bResult = CPropertySheet::OnInitDialog();</p>
<p>//取得属性页的大小<br>CRect rectWnd;<br>GetWindowRect(rectWnd);<br>//调整对话框的宽度<br>SetWindowPos(NULL, 0, 0,rectWnd.Width() + 100,rectWnd.Height(),SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);<br>CRect rectButton(rectWnd.Width() + 25, 25,rectWnd.Width()+75, 75);<br>//用<a href="http://www.programbbs.com/doc/"><u><font color=#0000ff>程序</font></u></a>创建一个按钮<br>m_button.Create("Button", BS_PUSHBUTTON, CRect(rectWnd.Width(), 25,rectWnd.Width()+75, 50) , this, 1);<br>//显示这个按钮<br>m_button.ShowWindow( SW_SHOW );<br>CenterWindow();<br>return bResult;<br>效果如下：</p>
<p><img src="http://www.programbbs.com/doc/resource/0/525_dip2.gif"> </p>
使用方案三虽然能在主对话框中加入<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，但是也比较麻烦，首先所加的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>只能在属性页的右边或下边。并且用<a href="http://www.programbbs.com/doc/"><u><font color=#0000ff>程序</font></u></a>来产生<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>比较烦琐，位置与大小不易控制。那么还有其他方法，既能在对话框中加入属性页，又能在主对话框随意添加<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>？还是有的，看看方案四。
<p>&#160;</p>
<p>方案四<br>本方案的例子请见源代码打包文件中的Property4部分</p>
<p>这次我们不从CPropertySheet继承自己的类，还是直接使用它。各属性页的子对话框类还是需要的，创建方法和上述两个方案相同。 </p>
<p>首先我们新建一个基于对话框的工程。在编辑已有的一个主对话框中可以自由加一些所需的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，但是得留出一定的空间用于放置属性页。</p>
<p>在主对话框类里加入一个CPropertySheet类的一个成员变量（m_sheet）代表整个属性页。再加入一些各子对话框类的实例作为成员变量（m_page1、m_page2&#8230;&#8230;）。</p>
<p>在主对话框类的OnInitDialog()函数中加入：<br>//加入标签，标签名由各个子对话框的标题栏决定<br>m_sheet.AddPage(&amp;m_page1);<br>m_sheet.AddPage(&amp;m_page2);<br>//用Create来创建一个属性页<br>m_sheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);</p>
<p>RECT rect;<br>m_sheet.GetWindowRect(&amp;rect);<br>int width = rect.right - rect.left;<br>int height = rect.bottom - rect.top;</p>
<p>//调整属性页的大小和位置<br>m_sheet.SetWindowPos(NULL, 20, 50, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);</p>
<p>效果如下：</p>
<p><img src="http://www.programbbs.com/doc/resource/0/525_dip3.gif"></p>
这个方案可以自由在主对话框中加一些必要的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>，而且属性页中的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>也都分散在了各个子对话框类中，使用非常方便。
<p>&#160;</p>
<p>但是这样也有一些缺陷：主对话框不能处理属性页上标签的消息，即点击标签时无法通知主对话框。（可能笔者水平有限，理论上应该可以，但笔者尚未解决这个问题）</p>
<p>方案五<br>本方案的例子请见源代码打包文件中的Property5部分</p>
<p>这次我们仍然要使用Tab Control，并且从CTabCtrl<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>类继承自己的类（CTabSheet）来处理。（此方法来自CodeGuru的一篇文章，本人稍做修改使其使用更简便） </p>
<p>首先我先介绍一下如何使用CTabSheet。</p>
<p>先要制作子对话框类，这次的子对话框类不要从CPropertyPage继承，而是直接从CDialog继承。并且各个子对话框资源的属性应设置为：Style为Child， Border为None。</p>
<p>在主对话框资源中，加入一个Tab Control，并且适当调整位置和大小。利用ClassWizard来为这个Tab Control创建一个CTabSheet的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>变量。</p>
<p>在主对话框的OnInitDialog()加入：<br>m_sheet.AddPage("tab1", &amp;m_page1, IDD_DIALOG1);<br>m_sheet.AddPage("tab2", &amp;m_page2, IDD_DIALOG2);<br>m_sheet.Show();<br>就这样就可以在对话框上制作出一个完美的属性页了。效果和上图完全一样。 </p>
<p>下面我就来讲讲CTabSheet类的细节内容。</p>
<p>CTabSheet是从CTabCtrl继承来的，用于Tab Control的<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>类。在类中有一个成员变量用来记录各子对话框的指针CDialog* m_pPages[MAXPAGE]; MAXPAGE是该类所能加载的标签的最大值。</p>
<p>类中有一个AddPage方法，用于记录子对话框的指针和所使用对话框资源的ID号。<br>BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)<br>{<br>if( MAXPAGE == m_nNumOfPages )<br>return FALSE;</p>
<p>//保存目前总的子对话框数<br>m_nNumOfPages++;</p>
<p>//记录子对话框的指针、资源ID、要在标签上显示的文字<br>m_pPages[m_nNumOfPages-1] = pDialog;<br>m_IDD[m_nNumOfPages-1] = ID;<br>m_Title[m_nNumOfPages-1] = title;</p>
<p>return TRUE;<br>}</p>
<p>在使用AddPage加入了若干子对话框后，必须调用CTabSheet的Show方法来真正生成标签和子对话框。 <br>void CTabSheet::Show()<br>{<br>//利用CDialog::Create来创建子对话框，并且使用CTabCtrl::InsertItem来加上相应的标签<br>for( int i=0; i &lt; m_nNumOfPages; i++ )<br>{<br>m_pPages[i]-&gt;Create( m_IDD[i], this );<br>InsertItem( i, m_Title[i] );<br>}</p>
<p>//由于对话框显示时默认的是第一个标签被选中，所以应该让第一个子对话框显示，其他子对话框隐藏<br>m_pPages[0]-&gt;ShowWindow(SW_SHOW);<br>for( i=1; i &lt; m_nNumOfPages; i++)<br>m_pPages[i]-&gt;ShowWindow(SW_HIDE);</p>
<p>SetRect();</p>
<p>}</p>
<p>生成好标签和子对话框后，调用CTabSheet::SetRect来计算并调整属性页的大小。<br>void CTabSheet::SetRect()<br>{<br>CRect tabRect, itemRect;<br>int nX, nY, nXc, nYc;</p>
<p>//得到Tab Control的大小<br>GetClientRect(&amp;tabRect);<br>GetItemRect(0, &amp;itemRect);</p>
<p>//计算出各子对话框的相对于Tab Control的位置和大小<br>nX=itemRect.left;<br>nY=itemRect.bottom+1;<br>nXc=tabRect.right-itemRect.left-2;<br>nYc=tabRect.bottom-nY-2;</p>
<p>//利用计算出的数据对各子对话框进行调整<br>m_pPages[0]-&gt;SetWindowPos(&amp;wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);<br>for( int nCount=1; nCount &lt; m_nNumOfPages; nCount++ )<br>m_pPages[nCount]-&gt;SetWindowPos(&amp;wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);</p>
<p>}</p>
<p>在单击标签栏后，应该是相应的子对话框显示，正在显示的子对话框应该隐藏。因此利用ClassWizard来处理WM_LBUTTONDOWN消息。<br>void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) <br>{<br>CTabCtrl::OnLButtonDown(nFlags, point);</p>
<p>//判断是否单击了其他标签<br>if(m_nCurrentPage != GetCurFocus())<br>{<br>//将原先的子对话框隐藏<br>m_pPages[m_nCurrentPage]-&gt;ShowWindow(SW_HIDE);<br>m_nCurrentPage=GetCurFocus();<br>//显示当前标签所对应的子对话框<br>m_pPages[m_nCurrentPage]-&gt;ShowWindow(SW_SHOW);<br>}</p>
<p>}</p>
<p>这样利用CTabSheet这个类就可以轻松地在对话框上放置自己的属性页了，并且<a href="http://www.programbbs.com/com/"><u><font color=#0000ff>控件</font></u></a>都分散在各子对话框类中，符合对象封装的思想。而且用这个方法来制作属性页就可以利用ClassWizard来轻松地生成消息映射处理Tab Control的消息了。例如：可以处理TCN_SELCHANGE消息来对切换了标签时进行一些动作。 </p>
<a title=下载代码链接 href="http://www.programbbs.com/doc/resource/0/525_PropertyInDlg.zip">下载代码链接</a>
<img src ="http://www.cppblog.com/coloerful/aggbug/85387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:17 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tab Control控件使用的例子</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85386.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:13:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85386.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85386.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85386.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85386.html</trackback:ping><description><![CDATA[<p>1、首先创建一个MFC对话框框架，在对话框资源上从工具箱中添加上一个Tab Control 控件，根据需要修改一下属性，然后右击控件，为这个控件添加一个变量，将此控件跟一个CTabCtrl类变量绑定在一起，这里设为m_tabctrl<br>2、创建两个新的对话框资源，其属性作如下修改：<br>Border：none //边界为空,这样它就没了标题栏<br>Style ：Child // 这样这个模板就可以当作另一个窗口的子窗口了。<br>&nbsp;&nbsp; 其它如果没有必要，就不用改了。<br>在上面加一些控件什么的，具体操作跟普通对话框没有区别。<br>完成后从这两个对话框模板生成两个新的对话框类。<br>3、在主对话框中为新添加进来的两个类增加两个变量：<br>如：CDialog1 m_mm1;<br>CDialog2 m_mm2;<br>4、在主对话框的OnInitDialog()函数中添加如下类似的代码：<br>&nbsp;&nbsp;&nbsp; TCITEM item;<br>item.mask = TCIF_TEXT;<br>item.pszText = "第一页";</p>
<p>m_tabctrl.InsertItem (0,&amp;item);<br>item.pszText ="第二页";<br>m_tabctrl.InsertItem (1,&amp;item);</p>
<p>m_mm1.Create (IDD_DIALOG1,&amp;m_tabctrl);<br>m_mm2.Create (IDD_DIALOG2,&amp;m_tabctrl);</p>
<p>m_mm1.SetWindowPos (NULL,10,30,400,100,SWP_SHOWWINDOW);<br>m_mm2.SetWindowPos (NULL,10,30,400,100,SWP_HIDEWINDOW );&nbsp; <br>解释如下：<br>两个InsertItem函数的调用是为了给标签控件增加两个标签页面，文本是标题。<br>SetWindowPos()函数设置这两个对话框在Z顺序中的位置，显示或隐藏状态.。<br>5、在主对话中为标签控件添加一个标签选择改变（TCN_SELCHANGE）的控件通知消息，以便在用户选择标签时通知主对话框。在主对话框的编辑界面右击标签控件，选择添加一个事件可以完成这个操作。<br>在事件处理中添加如下代码，如下例：<br>void CtabdialogDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)<br>{<br>CRect r;<br>m_tabctrl.GetClientRect (&amp;r);</p>
<p>switch(m_tabctrl.GetCurSel())<br>{<br>case 0:<br>m_mm1.SetWindowPos (NULL,10,30,r.right -20,r.bottom -40,SWP_SHOWWINDOW);<br>m_mm2.SetWindowPos (NULL,10,30,r.right -20,r.bottom -40,SWP_HIDEWINDOW );&nbsp; <br>break;<br>case 1:<br>m_mm1.SetWindowPos (NULL,10,30,r.right -20,r.bottom -40,SWP_HIDEWINDOW);<br>m_mm2.SetWindowPos (NULL,10,30,r.right -20,r.bottom -40,SWP_SHOWWINDOW );&nbsp; <br>break;<br>}<br>*pResult = 0;<br>}<br>要想知道用户选择那个标签页，要通过m_tabctrl.GetCurSel() 函数。为了不使显示的子对话框覆盖标签控件的显示，所以要获得标签控件的尺寸然后设置各页面的尺寸。</p>
<p>或者：</p>
<p>&nbsp;&nbsp;&nbsp; m_Tab.InsertItem(0,"第一页");<br>&nbsp;&nbsp;&nbsp; m_Tab.InsertItem(1,"第二页");<br>&nbsp;&nbsp;&nbsp; m_Tab.InsertItem(2,"第三页");<br>&nbsp;&nbsp;&nbsp; m_Tab.InsertItem(3,"第四页");</p>
<p><br>&nbsp;&nbsp;&nbsp; m_PageA.Create(IDD_PROPPAGE_A,&amp;m_Tab);<br>&nbsp;&nbsp;&nbsp; m_PageB.Create(IDD_PROPPAGE_B,&amp;m_Tab);<br>&nbsp;&nbsp;&nbsp; m_PageC.Create(IDD_PROPPAGE_C,&amp;m_Tab);<br>&nbsp;&nbsp;&nbsp; m_PageD.Create(IDD_PROPPAGE_D,&amp;m_Tab);</p>
<p>&nbsp;&nbsp;&nbsp; m_PageA.ShowWindow(SW_SHOW);<br>&nbsp;&nbsp;&nbsp; m_PageB.ShowWindow(SW_HIDE);<br>&nbsp;&nbsp;&nbsp; m_PageC.ShowWindow(SW_HIDE);<br>&nbsp;&nbsp;&nbsp; m_PageD.ShowWindow(SW_HIDE);</p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:13 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++之对话框中添加状态栏</title><link>http://www.cppblog.com/coloerful/archive/2009/05/22/85385.html</link><dc:creator>小猪</dc:creator><author>小猪</author><pubDate>Fri, 22 May 2009 07:12:00 GMT</pubDate><guid>http://www.cppblog.com/coloerful/archive/2009/05/22/85385.html</guid><wfw:comment>http://www.cppblog.com/coloerful/comments/85385.html</wfw:comment><comments>http://www.cppblog.com/coloerful/archive/2009/05/22/85385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/coloerful/comments/commentRss/85385.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/coloerful/services/trackbacks/85385.html</trackback:ping><description><![CDATA[<p>对话框中添加状态栏方法： <br>&nbsp;&nbsp;&nbsp; 通过网上查资料和自己试验，发现以下两种方法：<br>一、<br>（1）在要添加状态栏的对话框类的类定义中 CStatusBarCtrl&nbsp;&nbsp;&nbsp;&nbsp; *m_StatBar;<br>（2）在OnInitDialog中或其它合适的消息响应中加如下代码：（函数可查看MSDN）<br>&nbsp;m_StatBar=new&nbsp;&nbsp; CStatusBarCtrl;<br>&nbsp;RECT&nbsp;&nbsp;&nbsp;&nbsp; m_Rect;&nbsp;&nbsp; <br>&nbsp; &nbsp;GetClientRect(&amp;m_Rect);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //获取对话框的矩形区域<br>&nbsp; &nbsp;m_Rect.top=m_Rect.bottom-20;&nbsp;&nbsp;&nbsp; //设置状态栏的矩形区域<br>&nbsp; &nbsp;m_StatBar-&gt;Create(WS_BORDER|WS_VISIBLE|CBRS_BOTTOM,m_Rect,this,3);&nbsp;&nbsp; </p>
<p>&nbsp;int nParts[4]= {100, 200, 300,-1};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //分割尺寸<br>&nbsp;m_StatBar-&gt;SetParts(4, nParts); &nbsp;//分割状态栏<br>&nbsp;m_StatBar-&gt;SetText("这是第一个指示器",0,0); //第一个分栏加入"这是第一个指示器"<br>&nbsp;m_StatBar-&gt;SetText("这是第二个指示器",1,0); //以下类似<br>&nbsp;/*也可使用以下方式加入指示器文字<br>&nbsp;m_StatBar.SetPaneText(0,"这是第一个指示器",0);<br>&nbsp;其他操作：m_StatBar-&gt;SetIcon(3,SetIcon(AfxGetApp()-&gt;LoadIcon(IDI_ICON3),FALSE));<br>&nbsp;//在第四个分栏中加入ID为IDI_ICON3的图标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *********************************************/</p>
<p>&nbsp;m_StatBar-&gt;ShowWindow(SW_SHOW); <br>二、<br>（1）在对话框类的.cpp源文件的开头加上如下代码：<br>&nbsp;static UINT BASED_CODE indicators[]=&nbsp;&nbsp; <br>&nbsp;//状态栏的指示器列表，如有未定义的字符串名，需在Resource View的String Table中添加定义<br>&nbsp; &nbsp;{<br>&nbsp;&nbsp;&nbsp; &nbsp; ID_INDICATOR_CAPS,<br>&nbsp;&nbsp; &nbsp; ID_INDICATOR_NUM,<br>&nbsp; ID_INDICATOR_USER,//需在Resource View的String Table中添加定义<br>&nbsp; &nbsp;};<br>（2）在要添加状态栏的对话框类的类定义中 CStatusBarCtrl&nbsp; m_StatusBar;<br>（3）在OnInitDialog中或其它合适的消息响应中加如下代码：<br>&nbsp;//不能是突出和无边框风格<br>&nbsp;m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,AFX_IDW_STATUS_BAR );<br>&nbsp;m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));//设置指示器数量<br>&nbsp;&nbsp;CRect rect;<br>&nbsp;&nbsp;&nbsp; &nbsp;GetClientRect(&amp;rect);</p>
<p>&nbsp;&nbsp;m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/3);//设置指示器窗口的有关信息<br>&nbsp; &nbsp;m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/3);</p>
<p>&nbsp;&nbsp;&nbsp; &nbsp;RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_CAPS);//很重要****<br>&nbsp;&nbsp;&nbsp; &nbsp;m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,20,180));//设置背景<br>&nbsp;&nbsp;m_StatusBar.SetPaneText(0,"指示器1",0);<br>&nbsp;&nbsp;m_StatusBar.SetPaneText(1,"指示器2",0); </p>
<img src ="http://www.cppblog.com/coloerful/aggbug/85385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/coloerful/" target="_blank">小猪</a> 2009-05-22 15:12 <a href="http://www.cppblog.com/coloerful/archive/2009/05/22/85385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>