﻿<?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++博客-xbgs</title><link>http://www.cppblog.com/xbgs/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 09:52:06 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 09:52:06 GMT</pubDate><ttl>60</ttl><item><title>MFC中自由使用自定义消息</title><link>http://www.cppblog.com/xbgs/archive/2008/12/17/69647.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Wed, 17 Dec 2008 05:18:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2008/12/17/69647.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/69647.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2008/12/17/69647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/69647.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/69647.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄，可当我们需要完成其它的任务，需要自定义消息，就遇到了一些困难。<br>&nbsp;&nbsp;&nbsp; 在MFC ClassWizard中不允许添加用户自定义消息，所以我们必须在程序中添加相应代码，以便可以象处理其它消息一样处理自定义消息。通常的做法是采取以下步骤: <br><strong><font color="#0000ff">第一步:定义消息。</font></strong><br>　推荐用户自定义消息至少是WM_USER+100，因为很多新控件也要使用WM_USER消息。<br><font color="#990000">#define WM_MY_MESSAGE (WM_USER+100)&nbsp; <br></font><font color="#0000ff"><strong>第二步:实现消息处理函数。</strong></font><br>该函数使用WPRAM和LPARAM参数并返回LPESULT。 <br><font color="#990000">LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam) <br>{ <br>&nbsp;&nbsp;&nbsp; // TODO: 处理用户自定义消息 <br>&nbsp;&nbsp;&nbsp; ... <br>&nbsp;&nbsp;&nbsp; return 0; <br>}&nbsp; <br></font><font color="#0000ff"><strong>第三步:在类头文件的AFX_MSG块中说明消息处理函数:<br></strong></font><font color="#990000">class CMainFrame:public CMDIFrameWnd <br>{ <br>&nbsp;&nbsp;&nbsp; ... <br>&nbsp;&nbsp;&nbsp; // 一般消息映射函数 <br>&nbsp;&nbsp;&nbsp; protected: <br>&nbsp;&nbsp;&nbsp; // {{AFX_MSG(CMainFrame) <br>&nbsp;&nbsp;&nbsp; afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); <br>&nbsp;&nbsp;&nbsp; afx_msg void OnTimer(UINT nIDEvent); <br>&nbsp;&nbsp;&nbsp; afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); <br>&nbsp;&nbsp;&nbsp; //}}AFX_MSG <br>&nbsp;&nbsp;&nbsp; DECLARE_MESSAGE_MAP() <br>} <br></font><font color="#0000ff"><strong>第四步:在用户类的消息块中，使用ON_MESSAGE宏指令将消息映射到消息处理函数中。</strong></font> <br><font color="#990000">BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) <br>//{{AFX_MSG_MAP(CMainFrame) <br>&nbsp;&nbsp;&nbsp; ON_WM_CREATE() <br>&nbsp;&nbsp;&nbsp; ON_WM_TIMER() <br>&nbsp;&nbsp;&nbsp; ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage) <br>//}}AFX_MSG_MAP <br>END_MESSAGE_MAP()</font> <br>&nbsp;<br>　　如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数<font color="#0000ff">RegisterWindowMessage定义消息:<br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("User");</font> <br>　　并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。<br>　　当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessage发送消息<font color="#990000">PoseMessage(WM_MY_MESSAGE,O,O);</font> <br>如果向其他进程发送消息可通过如下方法发送消息:<br><font color="#990000">DWORD result;<br>SendMessageTimeout(wnd-&gt;m_hWnd, // 目标窗口<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WM_MY_MESSAGE, // 消息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, // WPARAM<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, // LPARAM<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SMTO_ABORTIFHUNG |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SMTO_NORMAL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TIMEOUT_INTERVAL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;result); <br></font>以避免其它进程如果被阻塞而造成系统死等状态。<br>&nbsp;&nbsp;&nbsp; 可是如果需要向其它类 (如主框架、子窗口、视类、对话框、状态条、工具条或其他控件等
发送消息时上述方法显得无能为力，而在编程过程中往往需要获取其它类中的某个识别信号
框架给我们造成了种种限制,但是可以通过获取某个类的指针而向这个类发送消息，
而自定义消息的各种动作则在这个类中定义，这样就可以自由自在的向其它类发送消息了。&nbsp;</p>
<p><br>　　下面举的例子叙述了向视类和框架类发送消息的方法：<br><font color="#660099" size="3"><strong>★在主框架类中向视类发送消息：<br></strong></font>1.视类中定义消息：<br><font color="#990000">ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage)</font> //定义消息映射</p>
<p>2.视类定义消息处理函数：<br><font color="#990000">LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)<br>{<br>&nbsp;&nbsp;&nbsp; // TODO: 处理用户自定义消息 <br>&nbsp;&nbsp;&nbsp; ... <br>&nbsp;&nbsp;&nbsp; return 0;<br>} <br></font>3.发送消息的测试函数<br><font color="#990000">void CMainFrame::OnTest()<br>{<br>&nbsp;&nbsp;&nbsp; CView * active = GetActiveView();//获取当前视类指针<br>&nbsp;&nbsp;&nbsp; if(active != NULL)<br>&nbsp;&nbsp;&nbsp; active-&gt;PostMessage(WM_MY_MESSAGE,0,0);<br>} <br></font><font color="#660099" size="3"><strong>★在其它类中向视类发送消息：<br></strong></font>//发送消息的测试函数<br><font color="#990000">void CMyDialog::OnTest()<br>{<br>&nbsp;&nbsp;&nbsp; CMDIFrameWnd *pFrame;<br>&nbsp;&nbsp;&nbsp; CMDIChildWnd *pChild;<br>&nbsp;&nbsp;&nbsp; CView *pView;<br>&nbsp;&nbsp;&nbsp; //获取主窗口指针<br>&nbsp;&nbsp;&nbsp; pFrame =(CMDIFrameWnd*)AfxGetApp()-&gt;m_pMainWnd;<br>&nbsp;&nbsp;&nbsp; // 获取子窗口指针<br>&nbsp;&nbsp;&nbsp; pChild = (CMDIChildWnd *) pFrame-&gt;GetActiveFrame();<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">//获取视类指针<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">pView = pChild-&gt;GetActiveView();<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">if(pView != NULL)<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">pView-&gt;PostMessage(WM_MY_MESSAGE,0,0);//发送消息<br>} <br></font>其余步骤同上。<br><font color="#660099" size="3"><strong>★在视类中向主框架发送消息:</strong></font><br>首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下<br>//发送消息的测试函数<br><font color="#990000">void CMessageView::OnTest()<br>{<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">CFrameWnd * active = GetActiveFrame();//获取当前主窗口框架指针<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">if(active != this)<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">active-&gt;PostMessage(WM_MY_MESSAGE,0,0);<br></font><font color="#990000">&nbsp;&nbsp;&nbsp; </font><font color="#990000">return 0;<br>} <br></font>　　在其它类中向不同的类发送消息可依次方法类推，这样我们的程序就可以的不受限制向其它类和进程发送消息，而避免了种种意想不到的风险。<br>&nbsp;<br><font color="#0000ff" size="2"><strong>【实例】:</strong></font><br>　　下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消息的具体过程。<br>　　实现步骤：</p>
第一步：在VC++中新建工程Message，所有ClassWizard步骤选项均为缺省,完成。<br>第二步：在主菜单中添加测试菜单为调出对话框，在框架类中建立相应函数OnTest().<br>第三步：在资源中建立对话框，通过ClassWizard添加新类TestDialog,添加测试按钮, 在对话框类中建立相应函数OnDialogTest()<br>//通过对话框按钮发送消息的函数<br>void TestDialog::OnDialogTest()<br>{<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>CMDIFrameWnd *pFrame;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>CMDIChildWnd *pChild;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>CView *pView;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>//获取主窗口指针<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>pFrame =(CMDIFrameWnd*)AfxGetApp()-&gt;m_pMainWnd;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>// 获取子窗口指针<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>pChild = (CMDIChildWnd *) pFrame-&gt;GetActiveFrame();<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>//获取视类指针<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>pView = pChild-&gt;GetActiveView();<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>if(pView != NULL)<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>pView -&gt;PostMessage(WM_MY_MESSAGE,0,0);//发送消息<br>} <br>　　在Message.h头文件中添加如下语句：<br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message"); <br>第四步:在视类中添加自定义消息:<br>在头文件MessageView.h中添加消息映射<br>protected:<br>//{{AFX_MSG(CMessageView)<br>//}}AFX_MSG<br>afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行为添加代码<br>DECLARE_MESSAGE_MAP()<br>在视类文件MessageView.cpp中的消息映射中添加自定义消息映射<br>BEGIN_MESSAGE_MAP(CMessageView, CView)<br>//{{AFX_MSG_MAP(CMessageView)<br>//}}AFX_MSG_MAP<br>// Standard printing commands<br>ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行添加代码定义唯一消息<br>END_MESSAGE_MAP() <br>添加相应的0消息处理函数<br>LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)<br>{<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>CRect rect;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>GetClientRect(&amp;rect);<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>InvalidateRect(&amp;rect);<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>test=!test;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>return 0;<br>} <br>在MessageView.h中添加布尔变量 public:BOOL test;<br>在视类构造函数中初始化 test变量:test=FALSE;<br>修改CMessageView::OnDraw()函数<br>void CMessageView::OnDraw(CDC* pDC)<br>{<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>CMessageDoc* pDoc = GetDocument();<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>ASSERT_VALID(pDoc);<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>// 以下程序显示消息响应效果<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>if(test)<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>pDC-&gt;TextOut(0,0,"消息响应!");<br>} <br>第五步：显示测试对话框<br>在MainFrame类中包含对话框头文件：<br>#include "TestDialog.h";<br>OnTest()函数中添加代码<br>void CMainFrame::OnTest()<br>{<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>TestDialog dialog;<br><font color="#990000">&nbsp;&nbsp;&nbsp; </font>dialog.DoModal();<br>} <br>运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果<img src ="http://www.cppblog.com/xbgs/aggbug/69647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2008-12-17 13:18 <a href="http://www.cppblog.com/xbgs/archive/2008/12/17/69647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WM_CTLCOLOR消息的用法</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8940.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:21:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8940.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8940.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8940.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8940.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8940.html</trackback:ping><description><![CDATA[
		<div>
				<table align="center" border="0" cellpadding="2" cellspacing="0" width="775">
						<tbody>
								<tr>
										<!--左侧页面-->
										<td valign="top" width="574">
												<div>
														<table align="center" border="0" cellpadding="2" cellspacing="0" width="775">
																<tbody>
																		<tr>
																				<!--左侧页面-->
																				<td valign="top" width="574">很多人都觉得自己的程序的界面不那么美观，往往VC默认产生的对话框比较单调，因此很多人往往找到很多其它的控件对对话框进行美化修饰，例如给静态控件设置字体，设置背景颜色等等， 其实这些完全可以由VC自己的WM_CTLCOLOR消息来完成！ 
<p>WM_CTLCOLOR消息用来完成对EDIT、STATIC、BUTTON等控件设置背景和字体颜色，其用法如下：</p><p>1.首先在自己需要设置界面的对话框上点击右键--&gt;建立类向导--&gt;加入WM_CTLCOLOR消息--&gt;自动生成OnCtlColor（）函数，此函数可以对本对话框的控件的界面外观做修饰，用法如下：<br />将类向导产生的函数做如下修改：<br /></p><pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">HBRUSH CDialogColor::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) <br />{<br />    HBRUSH hbr = CDialog::OnCtlColor(pDC,pWnd, nCtlColor);<br />    // TODO: Change any attributes of theDC here<br />    //设置显示字体<br />    CFont * cFont=new CFont;<br />    cFont-&gt;CreateFont(16,0,0,0,FW_SEMIBOLD,FALSE,FALSE,0, <br />                                          ANSI_CHARSET,OUT_DEFAULT_PRECIS,<br />                                          CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,<br />                                          DEFAULT_PITCH&amp;FF_SWISS,"Arial");<br />    //对特定的控件做修改<br />    switch()<br />    {<br />       case CTLCOLOR_STATIC: //对所有静态文本控件的设置<br />      {<br />          pDC-&gt;SetBkMode(TRANSPARENT); <br />          //设置背景为透明<br />          pDC-&gt;SetTextColor(RGB(255,255,0)); //设置字体颜色<br />          pWnd-&gt;SetFont(cFont); //设置字体<br />          HBRUSH B = CreateSolidBrush(RGB(125,125,255)); <br />          //创建画刷<br />          return (HBRUSH) B; //返回画刷句柄<br />      }<br />      case CTLCOLOR_EDIT: //对所有编辑框的设置<br />     {<br />          pDC-&gt;SetBkMode(TRANSPARENT); <br />          pDC-&gt;SetTextColor(RGB(255,255,0)); <br />          pWnd-&gt;SetFont(cFont); <br />          HBRUSH B = CreateSolidBrush(RGB(125,125,255)); <br />          return (HBRUSH) B; <br />      }<br />      default:<br />      return CDialog::OnCtlColor(pDC,pWnd, nCtlColor);<br />    }<br />}<br /></pre><br />注：case的类别有以下几种：<br />CTLCOLOR_BTN 按钮控件<br />CTLCOLOR_DLG 对话框<br />CTLCOLOR_EDIT 编辑框<br />CTLCOLOR_LISTBOX 列表框<br />CTLCOLOR_MSGBOX 消息框<br />CTLCOLOR_SCROLLBAR 滚动条<br />CTLCOLOR_STATIC 静态文本 <br /><br />2.你可能觉得对所有的控件使用统一的界面设置觉得不自由，其实VC同样可以对特定的ID的控件进行设置，方法如下： 
<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px=""><br /><br />            switch (pWnd-&gt;GetDlgCtrlID()) <br />            { <br />            //针对ID为IDC_CTL1、IDC_CTL2和IDC_CTL3的控件进行同样的设置<br />            case IDC_CTL1:<br />            case IDC_CTL2:<br />            case IDC_CTL3: <br />            {<br />            pDC-&gt;SetBkMode(TRANSPARENT);<br />            pDC-&gt;SetTextColor(RGB(255,255, 0));<br />            pWnd-&gt;SetFont(cFont);<br />            HBRUSH B = CreateSolidBrush(RGB(125,125,255));<br />            return (HBRUSH) B;<br />            }<br />            default:<br />            return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);<br />            }   <br /></pre></td>
																		</tr>
																</tbody>
														</table>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
<img src ="http://www.cppblog.com/xbgs/aggbug/8940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:21 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对话框中直接打印且保证打印内容连续的方法</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8939.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8939.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8939.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8939.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8939.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8939.html</trackback:ping><description><![CDATA[
		<div>   
在对话框程序的打印功能中，如果使用针式打印机，那么你可能希望连续打印的多个表中不换页。我们知道，在使用打印功能的时候，每当
dc.startpage()就会开始一页的打印，而dc.endpage()就会结束一页的打印，那么如何能使多个dc.startpage()与
dc.endpage()不换页而实现连续打印呢，方法如下： <font color="#990000">假设我们要打印m_nTotalNum个表，每个表有m行，那么要实现m_nTotalNum个表连续打印不换页可以如下实现：(由于打印机制问题，在打满一张后是必须要换页的，我们的做法是在换页的地方让给它留出一定的空白，不太影响表的连续性) <br /></font></div>
		<div>
				<strong>/////////////主函数</strong>
		</div>
		<div>
				<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">void CDlgTest::PrintOneNum() <br />{<br />    CDC dc;<br />    CPrintDialog printDlg(FALSE);<br />    CPrintInfo Info;<br />    printDlg.GetDefaults(); <br />    dc.Attach(printDlg.GetPrinterDC());<br />    dc.m_bPrinting=TRUE;<br />    CString strTitle;<br />    strTitle.LoadString(AFX_IDS_APP_TITLE);<br />    DOCINFO di;<br />    ::ZeroMemory(&amp;di,sizeof(DOCINFO));<br />    di.cbSize=sizeof(DOCINFO);<br />    di.lpszDocName=strTitle;<br />    if(dc.m_hDC)<br />    {<br />      BOOL bPrintingOk=dc.StartDoc(&amp;di); <br />      CPrintInfo Info; <br />      m_nCurrentNum_WhenPrint=1; <font color="#009900">//当前表数为1,这个用来控制打印的表数</font><br />       int nPageTotalScale=0; <font color="#009900">//初始化从0开始</font><br />       Info.m_nCurPage=1; <font color="#009900">//从第一页开始</font><br />       dc.StartPage(); <font color="#009900">//开始打印页</font><br />       for(;;)<br />      {<br /><font color="#009900">//打印完需要的表数m_nTotalNum则退出循环</font><br />          if(m_nCurrentNum_WhenPrint &gt;m_nTotalNum) break;<br />         else <font color="#009900">//打印一张表</font><br />          { <br />            nPageTotalScale=<font color="#ff0000"><strong>OnPrintReport</strong></font>  (&amp;dc,&amp;Info,nPageTotalScale, m_nCurrentNum_WhenPrint);<br />            m_nCurrentNum_WhenPrint ++; <br />            nPageTotalScale+=30; <font color="#009900">//打印下一张表的行距从＋30开始</font><br />          }<br />      }<br />      bPrintingOk=(dc.EndPage()&gt;0); <font color="#009900">//结束一页</font><br />       m_nCurrentNum_WhenPrint =0;<br />      if(bPrintingOk) <br />      dc.EndDoc();<br />      else <br />      dc.AbortDoc();<br />   }<br />   else<br />   {<br />      MessageBox("请检查打印机是否连接完好？","我的程 序",MB_ICONEXCLAMATION);<br />   }<br />   dc.Detach();<br />}</pre>
				<br />
				<strong>/////////////打印函数</strong>
				<br />
				<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">int CdlgTest::<font color="#ff0000"><strong>OnPrintReport</strong></font>(CDC *pDC, CPrintInfo *pInfo, <br />   int nXBasePointWhenPrint, int m_nCurrentNum_WhenPrint)<br />{<br />    int nXCurrentPoint=nXBasePointWhenPrint; <font color="#009900">//进行行控制的变量</font><br /><font color="#009900">//--------换页---------</font><br />    if(nXCurrentPoint+210&gt; 2000) <font color="#009900">//210为将要占用的长度</font><br />    {<br />        pDC-&gt;EndPage();<br />        pDC-&gt;StartPage();<br />        nXCurrentPoint=0;<br />        pInfo-&gt;m_nCurPage++;<br />    }<br />    nXCurrentPoint+=210;<br />    pDC-&gt;TextOut(0,nXCurrentPoint,"我的报表内容，从0－210的表长度 ");<br /><font color="#009900">//每当打印的输出要换行的时候就要判断if(nXCurrentPoint+将要使用的高度&gt; 2000)2000为规定的一张纸的高度。 如果大于纸张高度就要换页。这样就保证打印内容连续。</font><br />    return nXCurrentPoint; <font color="#009900">//最后返回打印完当前表时当前的页面高度，<br />                        以便下一张表接着这个高度打印</font><br />}<br /></pre>
		</div>
<img src ="http://www.cppblog.com/xbgs/aggbug/8939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:18 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GridCtrl使用详解</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8936.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:16:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8936.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8936.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8936.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8936.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8936.html</trackback:ping><description><![CDATA[
		<div>
				<p>
						<strong> <font color="#9900cc" size="4">在单文档中的使用方法</font><font size="4"><br /></font></strong>
						<font color="#990000" face="宋体" size="3">步骤一　初始化</font>
						<strong>
								<br />
								<br />
						</strong>
						<font color="#000000" size="2">在CView类的.h头文件中包含文件:<br />    <font color="#0000ff">#include "Gridctrl.h"</font><br /><br />并且手写加入如下的成员函数: <br />   <font color="#0000ff"> CGridCtrl * m_pGridCtrl;</font></font>
				</p>
				<p>
						<font color="#990000" face="宋体" size="3">步骤二　构造与析构</font>
						<font size="3">
								<br />
						</font>
						<br />构造函数中: <br /><font color="#0000ff">   m_pGridCtrl = NULL;</font><br />析构函数中:<br /><font color="#0000ff">   if(m_pGridCtrl)<br />       delete m_pGridCtrl;</font><br /><br /><font color="#990000" face="宋体" size="3">步骤三 如果需要打印功能的话添加同名打印函数代码</font><br /><br />在CView类的OnBeginPrinting()函数中添加如下代码:<br /><font color="#0000ff">if(m_pGridCtrl)<br />    m_pGridCtrl-&gt;OnBeginPrinting(pDC,pInfo);</font> //简单吧,这就是类的好处<br /><br />其它两个打印函数也一样的做法.<br /><br /><font color="#990000" face="宋体" size="3">步骤四 在OnInitaUpdate()函数中或者你自己添加的要显示Grid的消息函数中如下初始化:</font></p>
				<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">   //创建非模式对话框<br />   CDlg *dlg;<br />   dlg=new CDlg();<br />   dlg-&gt;Create(IDD_Dlg,this); <br /><br />   //初始化GridCtrl控件<br />   if(m_pGridCtrl!=NULL)<br />   {<br />   delete m_pGridCtrl;<br />   m_pGridCtrl=NULL;<br />   }<br />   if (m_pGridCtrl == NULL)<br />   {<br />  // Create the Gridctrl object<br />  m_pGridCtrl = new CGridCtrl;<br />  if (!m_pGridCtrl) return 0;<br />  // Create the Gridctrl window<br />  CRect rect;<br />  GetClientRect(rect);<br />  m_pGridCtrl-&gt;Create(rect, this, 100);<br />  // fill it up with stuff<br />  m_pGridCtrl-&gt;SetEditable(false);<br />  m_pGridCtrl-&gt;SetTextBkColor(RGB(0xFF, 0xFF, 0xE0)); //黄色背景<br />  m_pGridCtrl-&gt;EnableDragAndDrop(false);<br />  try {<br />   m_pGridCtrl-&gt;SetRowCount(k); //设置行数为k行<br />   m_pGridCtrl-&gt;SetColumnCount(4);   //k列<br />   m_pGridCtrl-&gt;SetFixedRowCount(1);   //标题行为一行<br />   m_pGridCtrl-&gt;SetFixedColumnCount(1);  //同上<br />  }<br />  catch (CMemoryException* e)<br />  {<br />   e-&gt;ReportError();<br />   e-&gt;Delete();<br />   return 0;<br />  }<br />  //填充列标题<br />  int row=0;<br />  for(int col=0;col&lt;4;col++)<br />  {<br />         GV_ITEM Item;<br />   Item.mask = GVIF_TEXT|GVIF_FORMAT;<br />   Item.row = row;<br />   Item.col = col;<br />   if(col==0){<br />                Item.nFormat = DT_CENTER|DT_WORDBREAK;<br />    Item.strText.Format(_T("【类别】"),col);<br />   }<br />   else if(col==1){<br />                Item.nFormat = DT_LEFT|DT_WORDBREAK;<br />       Item.strText.Format(_T("第一列"),col);<br />   }<br />   else if(col==2){<br />    Item.nFormat = DT_LEFT|DT_WORDBREAK;<br />       Item.strText.Format(_T("第二列"),col);<br />   }<br />   m_pGridCtrl-&gt;SetItem(&amp;Item);<br />  }<br />   // fill rows/cols with text<br />  for (row = 1; row &lt; k; row++)<br />   for (col = 0; col &lt; h; col++)<br />   { <br />    GV_ITEM Item;<br />    Item.mask = GVIF_TEXT|GVIF_FORMAT;<br />    Item.row = row;<br />    Item.col = col;<br />    if (col &lt; 1) {  //行标题头<br />     Item.nFormat = DT_CENTER|DT_VCENTER<br />     |DT_SINGLELINE|DT_END_ELLIPSIS<br />     |DT_NOPREFIX;<br />     Item.strText.Format(_T("%d"),row);<br />    } <br />    else if(col==1){  //第一列的值<br />     Item.nFormat = DT_CENTER|DT_VCENTER<br />     |DT_SINGLELINE|DT_END_ELLIPSIS<br />     |DT_NOPREFIX;<br />        str="aa";<br />         Item.strText.Format(_T("%s"),str);<br />    }else if(col==2){ //第二列第值<br />     Item.nFormat = DT_CENTER|DT_VCENTER<br />     |DT_SINGLELINE|DT_END_ELLIPSIS<br />     |DT_NOPREFIX;<br />        CString str;<br />        str="bb";<br />         Item.strText.Format(_T("%s"),str);<br />    }<br />    m_pGridCtrl-&gt;SetItem(&amp;Item);<br />   }<br />  m_pGridCtrl-&gt;AutoSize();<br /><br />  //--------------设置行列距------------------<br />  for(int a=1;a&lt;m;a++)<br />   m_pGridCtrl-&gt;SetRowHeight(a,21);  //设置各行高<br />        m_pGridCtrl-&gt;SetRowHeight(0,24);  //设置0行高<br />  m_pGridCtrl-&gt;SetColumnWidth(1,110); //设置2列宽<br />  m_pGridCtrl-&gt;SetColumnWidth(2,160); //设置3列宽<br />  m_pGridCtrl-&gt;SetColumnWidth(3,100); //设置4列宽<br />   }</pre>
上例取自实际工程,稍有修改!<br />部分注释: <br /><font color="#000000" face="Fixedsys" size="3">void SetVirtualMode(TRUE)</font><font color="#0000ff" face="Fixedsys" size="3">　<font color="#006600">//设为虚模式</font><br /><font color="#000000">BOOL SetRowCount(int nRows) </font><font color="#006600">//设置总的行数。</font><br /><font color="#000000">BOOL SetFixedRowCount(int nFixedRows = 1)</font><font color="#006600">//设置固定的行数据</font><br /><font color="#000000">BOOL SetColumnCount(int nCols) </font><font color="#006600">//设置列数</font><br /><font color="#000000">BOOL SetFixedColumnCount(int nFixedCols = 1)</font><font color="#006600">//设置固定的列数</font></font><p><br /><font color="#990000" face="宋体" size="3">步骤五: 添加WM_SIZE消息,调整控件的界面占屏幕大小</font><br /><br />  if(m_pGridCtrl-&gt;GetSafeHWnd())<br />   {<br />      CRect rect;<br />     GetClientRect(rect);<br />     m_pGridCtrl-&gt;MoveWindow(rect);<br />   } <br /><br /></p><hr color="#cc3333" size="2" /><br /><font color="#6600cc" face="楷体_GB2312" size="5"><strong></strong></font> <font color="#9900cc" face="宋体" size="4"><strong>在对话框中的使用方法</strong></font><br /><br /><font color="#990000" face="宋体" size="3">步骤一　创建数据显示表格对话框</font><font face="宋体" size="3"></font><p>在资源管理器中新创建一个对话框，假设为CDlgTestReportBox。 从工具箱中加入Custom Control，就是人头像的那个，将其区域拉伸至要显示数据表格的大小，充满整个对话框。</p><p>在CDlgTestReportBox类的头文件中：</p><p><font color="#0000ff" face="Fixedsys">#include "GridCtrl.h" </font></p><p>再定义成员变量：</p><p><font color="#0000ff" face="Fixedsys">CGridCtrl* m_pGrid;</font></p><p>添加OnShowWindow()消息处理函数如下：</p><pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">void CDlgTestReportBox::OnShowWindow(BOOL bShow, UINT nStatus) <br />{<br />    CDialog::OnShowWindow(bShow, nStatus);<br />    // TODO: Add your message handler code here<br />    if(m_pGrid!=NULL)<br />    {<br />        delete m_pGrid;<br />        m_pGrid=NULL;<br />     } <br />  if(m_pGrid==NULL)<br />     {<br />        m_pGrid=new CGridCtrl;<br />        CRect rect;<br />        GetDlgItem(IDC_ReportAera)-&gt;GetWindowRect(rect); //得到显示区域<br />        ScreenToClient(&amp;rect);<br />        m_pGrid-&gt;Create(rect,this,100);<br />        m_pGrid-&gt;SetEditable(false);<br />        m_pGrid-&gt;SetTextBkColor(RGB(0xFF, 0xFF, 0xE0)); //黄色背景<br />        try <br />        {<br />            m_pGrid-&gt;SetRowCount(10); //初始为10行<br />            m_pGrid-&gt;SetColumnCount(11); //初始化为11列<br />            m_pGrid-&gt;SetFixedRowCount(1); //表头为一行<br />            m_pGrid-&gt;SetFixedColumnCount(1); //表头为一列 <br />        }<br />        catch (CMemoryException* e)<br />        {<br />            e-&gt;ReportError();<br />            e-&gt;Delete();<br />            // return FALSE;<br />        }<br />        for (int row = 0; row &lt; m_pGrid-&gt;GetRowCount(); row++)<br />        for (int col = 0; col &lt; m_pGrid-&gt;GetColumnCount(); col++)<br />        { <br />            //设置表格显示属性<br />            GV_ITEM Item; <br />            Item.mask = GVIF_TEXT|GVIF_FORMAT;<br />            Item.row = row;<br />            Item.col = col;<br />            if(row==0&amp;&amp;col==0) //第(0，0)格<br />            {<br />                Item.nFormat = DT_CENTER|DT_WORDBREAK;<br />                Item.szText.Format(_T("报表显示"),col);<br />            }<br />            else if (row &lt; 1) //设置0行表头显示<br />            {        <br />                Item.nFormat = DT_CENTER|DT_WORDBREAK;<br />                Item.szText.Format(_T(" 项目%d"),col);<br />            }<br />            else if (col &lt; 1) //设置0列表头显示<br />            {<br />                if(row&lt; m_pGrid-&gt;GetRowCount()-4)<br />                {<br />                    Item.nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;<br />                    Item.szText.Format(_T("第%d次"),row);<br />                }<br />            }<br />            else<br />            {<br />                Item.nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS;<br />                Item.szText.Format(_T(""),2);<br />            }<br />            m_pGrid-&gt;SetItem(&amp;Item); <br />        }<br />        m_pGrid-&gt;Invalidate();<br />    }<br />    //--------------设置行列距------------------<br />    for(int a=0;a<m_pgrid->GetRowCount();a++)<br />         m_pGrid-&gt;SetRowHeight(a,16); //设置各行高 <br />         m_pGrid-&gt;SetColumnWidth(0,58); //设置0列宽<br />    for(int b=1;b<m_pgrid->GetColumnCount();b++)<br />        m_pGrid-&gt;SetColumnWidth(b,59); //设置各列宽<br />}</m_pgrid-></m_pgrid-></pre><p> </p><p><font color="#990000" face="宋体" size="3">步骤二　嵌入上面的对话框 显示数据</font></p><p>在你需要显示数据的对话框上的头文件中，假设为CDlgTest，加入</p><p><font color="#0000ff" face="Fixedsys">#include "GridCtrl.h"</font></p><p><font color="#0000ff" face="Fixedsys">CDlgTestReportBox* m_pTestReportBox;</font></p><p>将数据显示对话框放入你的对话框相应位置上，在CDlgTest::OnInitDialog() 中： </p><p><font color="#0000ff" face="Fixedsys">if(!m_pTestReportBox)<br />{<br />     m_pTestReportBox=new CDlgTestReportBox(this);<br />}</font></p><p><font color="#0000ff" face="Fixedsys">m_pTestReportBox-&gt;Create(IDD_DlgTestReportBox,this);</font></p><p><font color="#006600" face="Fixedsys">//定义区域变量</font><font color="#0000ff" face="Fixedsys"><br />CRect rectDraw;<br />GetDlgItem(IDC_AeraReport)-&gt;GetWindowRect(rectDraw);<br />ScreenToClient(&amp;rectDraw); <font color="#006600">//动态测试数据显示区域rectDraw</font></font></p><p><font color="#0000ff" face="Fixedsys"><font color="#006600">//将对应的对话框放到指定区域</font><br />m_pTestReportBox-&gt;MoveWindow(rectDraw);<br />m_pTestReportBox-&gt;ShowWindow(SW_SHOW);</font></p><p>自定义填充数据的函数：CDlgTest::FillGrid() 如下：</p><pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">CGridCtrl* pGrid=m_pTestReportBox-&gt;m_pGrid;<br />for (int row = pGrid-&gt;GetRowCount()-1; row &gt;= pGrid-&gt;GetRowCount()-3; row--)<br />{<br />   for (int col = 1; col &lt;= pGrid-&gt;GetColumnCount(); col++)<br />   { <br />      GV_ITEM Item;<br />      Item.mask = GVIF_TEXT|GVIF_FORMAT;<br />      Item.row = row;<br />      Item.col = col;<br />      if(row==pGrid-&gt;GetRowCount()-3&amp;&amp;col&gt;0) //平均值<br />      {<br />         if(col==10){<br />         Item.nFormat = DT_CENTER|DT_WORDBREAK;<br />         Item.szText.Format(_T(" %6.2f "),avjch);<br />      }<br />      else{<br />         Item.nFormat = DT_CENTER|DT_WORDBREAK;<br />         Item.szText.Format(_T(" %6.2f "),av[col-1]);<br />      }<br />   }<br />   pGrid-&gt;SetItem(&amp;Item); //提交数据<br />   if(row==0||col==0)<br />   {<br />      COLORREF clr = RGB(0, 0, 0);<br />      pGrid-&gt;SetItemBkColour(row, col, clr);<br />      pGrid-&gt;SetItemFgColour(row, col, RGB(255,0,0));<br />   }<br />  }//循环结束<br />  pGrid-&gt;Invalidate();<br />} </pre>
好累啊,忙了一天时间终于写完了! 
<p><br /></p></div>
<img src ="http://www.cppblog.com/xbgs/aggbug/8936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:16 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC用ADO访问数据库全攻略</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8935.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:14:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8935.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8935.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8935.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8935.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8935.html</trackback:ping><description><![CDATA[
		<div>一、ADO概述<br />ADO是Microsoft为最新和最强大的数据访问范例 OLE DB
而设计的，是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE. DB 提供者访问和操作数据库服务器中的数据。ADO
最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO
在关键的应用方案中使用最少的网络流量，并且在前端和数据源之间使用最少的层数，所有这些都是为了提供轻量、高性能的接口。之所以称为
ADO，是用了一个比较熟悉的暗喻，OLE 自动化接口。</div>
		<div>OLE DB是一组”组件对象模型”(COM)
接口，是新的数据库低层接口，它封装了ODBC的功能，并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft
UDA(Universal Data Access)策略的技术基础。OLE DB
为任何数据源提供了高性能的访问，这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说，OLE DB
并不局限于 ISAM、Jet
甚至关系数据源，它能够处理任何类型的数据，而不考虑它们的格式和存储方法。在实际应用中，这种多样性意味着可以访问驻留在 Excel
电子数据表、文本文件、电子邮件/目录服务甚至邮件服务器，诸如 Microsoft Exchange 中的数据。但是，OLE DB
应用程序编程接口的目的是为各种应用程序提供最佳的功能，它并不符合简单化的要求。您需要的API 应该是一座连接应用程序和OLE DB
的桥梁，这就是 ActiveX Data Objects (ADO)。 </div>
		<div>二、在VC中使用ADO(开发步骤好下：) </div>
		<div>1、引入ADO库文件 </div>
		<div>使用ADO前必须在工程的stdafx.h头文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示： </div>
		<div>用#import引入ADO库文件</div>
		<div> </div>
		<div>
				<font color="#660099" face="Verdana">
						<strong>#import "c:\program files\common files\system\ado\msado15.dll"no_namespaces rename("EOF" adoEOF")</strong>
				</font>
		</div>
		<div> </div>
		<div>这行语句声明在工程中使用ADO，但不使用ADO的名字空间，并且为了避免常数冲突，将常数EOF改名为adoEOF。现在不需添加另外的头文件，就可以使用ADO接口了。 </div>
		<div>2、初始化OLE/COM库环境<br />必须注意的是，ADO库是一组COM动态库，这意味应用程序在调用ADO前，必须初始化OLE/COM库环境。在MFC应用程序里，一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。</div>
		<div> </div>
		<div>
				<strong>
						<font color="#660099" face="Georgia">BOOL CMyAdoTestApp：：InitInstance()<br />{<br />if(!AfxOleInit())//这就是初始化COM库<br />{<br />AfxMessageBox(“OLE初始化出错!”);<br />return FALSE;<br />} </font>
				</strong>
		</div>
		<div>
				<strong>
						<font color="#660099" face="Georgia">…… </font>
				</strong>
		</div>
		<div>
				<strong>
						<font color="#660099" face="Georgia">}</font>
				</strong>
		</div>
		<div> </div>
		<div>3、ADO接口简介 </div>
		<div>ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。<br />_ConnectionPtr
接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句，如一个存储过程。使用
_ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用
_ConnectionPtr操作时要想得到记录条数得遍历所有记录，而用_RecordserPtr时不需要。 </div>
		<div>_CommandPtr
接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时，你可以利用全局
_ConnectionPtr接口，也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作，后者是比较好的选择。但
如果你要频繁访问数据库，并要返回很多记录集，那么，你应该使用全局_ConnectionPtr接口创建一个数据连接，然后使用_CommandPtr
接口执行存储过程和SQL语句。 </div>
		<div>_RecordsetPtr是一个记录集对象。与以上两种对象相比，它对记录集提供了更多的控制功能，如记录锁定，游标控制等。同
_CommandPtr接口一样，它不一定要使用一个已经创建的数据连接，可以用一个连接串代替连接指针赋给
_RecordsetPtr的connection成员变量，让它自己创建数据连接。如果你要使用多个记录集，最好的方法是同Command对象一样使用
已经创建了数据连接的全局_ConnectionPtr接口<br />，然后使用_RecordsetPtr执行存储过程和SQL语句。　</div>
		<div>4、使用_ConnectionPtr接口<br />_ConnectionPtr主要是一个连接接口，取得与数据库的连接。它的连接字符串可以是自己直接写，也可以指向一个ODBC　DSN。</div>
		<div> </div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>_ConnectionPtr pConn;<br />if (FAILED(pConn.CreateInstance("ADODB.Connection")))<br />{<br />AfxMessageBox("Create Instance failed!");<br />return;<br />}</strong>
				</font>
		</div>
		<div>
				<br />
				<font color="#660099" face="Georgia">
						<strong>CString strSRC;<br />strSRC="Driver=SQL Server;Server=";<br />strSRC+="suppersoft";<br />strSRC+=";Database=";<br />strSRC+="mydb";<br />strSRC+=";UID=SA;PWD=";</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>CString strSQL = "Insert into student(no,name,sex,address) values(3,'aaa','male','beijing')";</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>_variant_t varSRC(strSRC);<br />_variant_t varSQL(strSQL);<br />_bstr_t bstrSRC(strSRC);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>if (FAILED(pConn-&gt;Open(bstrSRC,"","",-1)))<br />{<br />AfxMessageBox("Can not open Database!");<br />pConn.Release();<br />return;<br />}</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>pConn-&gt;Execute(_bstr_t(strSQL),&amp;vtOptional,-1);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>pConn.Release();</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>AfxMessageBox("ok!");</strong>
				</font>
		</div>
		<div>
				<strong>
				</strong> </div>
		<div>5、使用_RecordsetPtr接口(以连接SQL Server为例)</div>
		<div>
				<br />
				<font color="#660099" face="Georgia">
						<strong>_RecordsetPtr pPtr;<br />if (FAILED(pPtr.CreateInstance("ADODB.Recordset")))<br />{<br />AfxMessageBox("Create Instance failed!");<br />return FALSE;<br />}</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>CString strSRC;<br />strSRC="Driver=SQL Server;Server=";<br />strSRC+="210.46.141.145";<br />strSRC+=";Database=";<br />strSRC+="mydb";<br />strSRC+=";UID=sa;PWD=";<br />strSRC+="sa";</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>CString strSQL = "select id,name,gender,address from personal";</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>_variant_t varSRC(strSRC);<br />_variant_t varSQL(strSQL);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>if(FAILED(pPtr-&gt;Open(varSQL,varSRC,adOpenStatic,adLockOptimistic,adCmdText)))<br />{<br />AfxMessageBox("Open table failed!");<br />pPtr.Release();<br />return FALSE;<br />}</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>while(!pPtr-&gt;GetadoEOF())<br />{<br />_variant_t varNo;<br />_variant_t varName;<br />_variant_t varSex;<br />_variant_t varAddress;</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>varNo = pPtr-&gt;GetCollect ("id");<br />varName = pPtr-&gt;GetCollect ("name");<br />varSex = pPtr-&gt;GetCollect ("gender");<br />varAddress = pPtr-&gt;GetCollect ("address");</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>CString strNo =(char *)_bstr_t(varNo);<br />CString strName =(char *)_bstr_t(varName);<br />CString strSex =(char *)_bstr_t(varSex);<br />CString strAddress =(char *)_bstr_t(varAddress);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>strNo.TrimRight();<br />strName.TrimRight();<br />strSex.TrimRight();<br />strAddress.TrimRight();</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>int nCount = m_list.GetItemCount();<br />int nItem = m_list.InsertItem (nCount,_T(""));<br />m_list.SetItemText (nItem,0,strNo);<br />m_list.SetItemText (nItem,1,strName);<br />m_list.SetItemText (nItem,2,strSex);<br />m_list.SetItemText (nItem,3,strAddress);</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>pPtr-&gt;MoveNext();<br />}</strong>
				</font>
		</div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>pPtr-&gt;Close();<br />pPtr.Release();</strong>
				</font>
		</div>
		<div> </div>
		<div>6、使用_CommandPtr接口<br />_CommandPtr接口返回一个Recordset对象，并且提供了更多的记录集控制功能，以下代码示例了使用_CommandPtr接口的方法： </div>
		<div>代码11:使用_CommandPtr接口获取数据</div>
		<div> </div>
		<div>
				<font color="#660099" face="Georgia">
						<strong>_CommandPtr pCommand;<br />_RecordsetPtr pRs;<br />pCommand.CreateInstance(__uuidof(Command));<br />pCommand-&gt;ActiveConnection=pConn;<br />pCommand-&gt;CommandText="select * from student";<br />pCommand-&gt;CommandType=adCmdText;<br />pCommand-&gt;Parameters-&gt;Refresh();<br />pRs=pCommand-&gt;Execute(NULL,NULL,adCmdUnknown);<br />_variant_t varValue = pRs-&gt;GetCollect("name");<br />Cstring strValue=(char*)_bstr_t(varValue);</strong>
				</font>
		</div>
		<div> </div>
		<div>7、关于数据类型转换由于COM对象是跨平台的，它使用了一种通用的方法来处理各种类型的数据，<br />因此Cstring 类和COM对象是不兼容的，我们需要一组API来转换COM对象和C++类型的数据。_vatiant_t和_bstr_t就是这样两种对象。它们提供了通用的方法转换COM对象和C++类型的数据。</div>
<img src ="http://www.cppblog.com/xbgs/aggbug/8935.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:14 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8935.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Forms2.0系列的控件无法在未安装OFFICE的机器上运行</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8934.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:11:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8934.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8934.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8934.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8934.html</trackback:ping><description><![CDATA[
		<div>    Forms2.0系列的控件，如: <font color="#000000"><font color="#660099">Microsoft forms 2.0 label</font> ，</font><font color="#660099">Microsoft forms 2.0 commandbutton</font>等,其依赖的动态链接库为<font color="#660099">Fm20.dlls</font><font color="#000000">。在使用过程中我发现，如果</font>在发布软件的时候，用户的客户机上没有安装word的话，程序就不能运行(虽然程序运行了，但是看不到界面出现)。 后来在网上搜索了很多资料，终于找到了问题的关键，在微软网站上找到关于这个问题的解释为： <font color="#660099">Fm20.dlls 不是可以重分配的，你必须安装一个象OFFICE97那样的系统在你的目标客户机上作为你软件分发的一部分。 如果不安装Microsoft Office 97那样的系统的话，即使你使用regsvr32注册都没有作用</font><font color="#000000">(我翻译的,有点不通顺哦^_^)。</font></div>
		<div>    最终的解决办法就是，做为Microsoft Office 97的替代，你可以免费下载和安装<font color="#0000ff">Microsoft ActiveX Control Pad</font>. 安装完毕，客户机上就可以无需安装office而使用你的程序了<font color="#009900">。[需要的请留下email,我会发给你的]</font></div>
<img src ="http://www.cppblog.com/xbgs/aggbug/8934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:11 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CTypedPtrMap模板指针类的用法</title><link>http://www.cppblog.com/xbgs/archive/2006/06/23/8933.html</link><dc:creator>让心飞翔</dc:creator><author>让心飞翔</author><pubDate>Fri, 23 Jun 2006 15:07:00 GMT</pubDate><guid>http://www.cppblog.com/xbgs/archive/2006/06/23/8933.html</guid><wfw:comment>http://www.cppblog.com/xbgs/comments/8933.html</wfw:comment><comments>http://www.cppblog.com/xbgs/archive/2006/06/23/8933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xbgs/comments/commentRss/8933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xbgs/services/trackbacks/8933.html</trackback:ping><description><![CDATA[
		<p>下面是我在编程中运用CTypedPtrMap指针模板类的方法，其存储结构占用物理空间小，比单纯的用数组结构存储的文件将小很多，所以是一种非常推荐的存储及读取文件的方法。</p>
		<p>你必须在stdafx.h文件中 包含  #include &lt;afxtempl.h&gt;    // MFC templates<br />在头文件中包含  #include &lt;io.h&gt;</p>
		<p>其中 <font color="#0000ff"><strong>CBank.h</strong></font>文件如下：<br /></p>
		<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">class CBank : public CObject  <br />{<br />DECLARE_SERIAL(CBank)   //声明序列化存储<br />public:<br />       CBank();<br />       CBank(CString str){ m_bankname = str; }<br />       CBank(const CBank &amp;b){ m_bankname= b.m_bankname;} //拷贝构造函数<br />        virtual ~CBank();<br />private:<br />       CString  m_bankname;<br />public:<br />    virtual void Serialize(CArchive&amp; ar);<br />};<p></p><p>typedef CTypedPtrMap&lt;CMapStringToOb, </p><p>                     CString,</p><p>                     CBank*&gt;CBanktmp;  //这个才是我们根据此类生成的类型</p></pre>
		<p>它的实现文件<strong><font color="#0000ff">.cpp</font></strong>如下：<br /></p>
		<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">IMPLEMENT_SERIAL(CBank, CObject, 1)   //实现序列化存储<br />CBank::CBank()<br />{<br />     m_bankname="";<br />}<br />CBank::~CBank()<br />{<p></p><p>}<br />void CBank::Serialize(CArchive&amp; ar)<br />{<br />    if (ar.IsLoading())<br />    {<br />        ar &gt;&gt; m_bankname;<br />    }<br />    else<br />    {<br />        ar &lt;&lt; m_bankname;<br />    }<br />}</p></pre>
		<p>/*----------------------------------------------------<br /> 从文件中读取参数：<br />注意： 其中的m_map是这样定义的：<font color="#0000ff"><strong>CBanktmp  m_map;</strong></font><br />-------------------------------------------------*/<br /></p>
		<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">void CDlgBankIn::LoadBankName()<br />{<br />       UINT  nFlags = CFile::typeBinary |CFile::modeReadWrite;<br />       if(_access(_T("BankName.dat"),0))<br />       {<br />              nFlags |= CFile::modeCreate;<br />       }<br />       CFile file;<br />       CFileException fe;<br />       if (file.Open(_T("BankName.dat"),nFlags, &amp;fe))<br />       {<br />           if(file.GetLength()==0)   //如果文件为空则不进行读取操作<br />           {<br />           }<br />           else<br />           {<br />                CArchive ar(&amp;file, CArchive::load);<br />                m_map.Serialize(ar);   //读取文件<br />               //根据文件内容填充列表框<br />                POSITION   pos;<br />                CString    strKey;<br />                CBank   *pB=NULL;<br />                for( pos = m_map.GetStartPosition(); pos != NULL; )<br />                {<br />                    m_map.GetNextAssoc(pos,strKey,(CBank*)pB);<br />                    m_CmbBank.AddString(strKey);<br />                }<br />                delete  pB;<br />              }<br />       }<br />       file.Close();<br />}<p></p></pre>
		<p>/*-------------------------------------------------<br />功能: 先打开文件,然后查找文件中是否有与编辑框关键字相同的内容,<br />       如果有相同内容则不添加,如果没有相同内容则写文件.<br />------------------------------------- ------------*/<br /></p>
		<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">void CDlgBankList::OnBtnAdd() <br />{<br />       // TODO: Add your control notification handler code here<br />       CString  strKey;<br />       GetDlgItemText(IDC_EDITBank,strKey);<br />       if (0 != strKey.GetLength())<br />       {<br />          CBank  *pB;<br />          //打开文件<br />         UINT  nFlags = CFile::typeBinary |CFile::modeRead;<br />          CFile file;<br />          CFileException fe;<br />          if (file.Open(_T("BankName.dat"),nFlags, &amp;fe))<br />          {<br />                 if(file.GetLength()==0)  //如果文件为空则不进行序列化操作<br />                 {<p></p><p>                 }<br />                 else<br />                 {<br />                  CArchive ar(&amp;file, CArchive::load);<br />                  m_map.Serialize(ar); <br />                 }<br />               //分析文件并给文件添加编辑框的内容<br />                if(!m_map.Lookup(strKey,(CBank*)pB))  //当不存在时才需要添加<br />                  {<br />                      if (CB_ERR != m_ListBox.AddString(strKey))<br />                      {<br />                         m_map.SetAt(strKey, new CBank(strKey));  //给关键字strKey赋值<br />                      }<br />                 }<br />          }<br />       file.Close();</p><p>       //存储文件<br />       nFlags = CFile::typeBinary |CFile::modeWrite;<br />       if (file.Open(_T("BankName.dat"),nFlags, &amp;fe))<br />       {<br />            CArchive ar(&amp;file, CArchive::store);<br />            m_map.Serialize(ar);   //序列化存储<br />       }<br />    }<br />}</p></pre>
		<p>/*-------------------------------------------------<br />功能: 先打开文件,然后查找文件中的关键字,<br />    找到后则删除此关键字, 但是注意关键字对应的内容仍然没有删除，这点期待改进. <br />-------------------------------------------------*/<br /></p>
		<pre style="font-size: 9pt; color: rgb(51, 102, 153); background-color: rgb(255, 255, 234);" cccc="" solid="" 宋体?;border:1px="">void CDlgBankList::OnBtnDel() <br />{<br />       // TODO: Add your control notification handler code here<br />       int iIndex;       <br />       CString  strKey;<br />       if(LB_ERR!=m_ListBox.GetCurSel())<br />       {<br />        //打开文件<br />     &amp; nbsp;     UINT  nFlags = CFile::typeBinary |CFile::modeRead;<br />           CFile file;<br />           CFileException fe;<br />           if (file.Open(_T("BankName.dat"),nFlags, &amp;fe))<br />           {<br />              CArchive ar(&amp;file, CArchive::load);<br />              m_map.Serialize(ar);  <br />              iIndex=m_ListBox.GetCurSel();<br />              m_ListBox.GetText(iIndex,strKey);<br />              m_ListBox.DeleteString(iIndex);<br />              //分析文件并给文件添加编辑框的内容<br />               CBank  *pB=NULL;<br />              if(m_map.Lookup(strKey,(CBank*)pB))<br />              {<br />                  m_map.RemoveKey(strKey);   //删除关键字,但没有删除关键字对应的内容<br />               }<br />            }<br />            file.Close();<br />            //存储文件<br />           nFlags = CFile::typeBinary |CFile::modeWrite;<br />           if (file.Open(_T("BankName.dat"),nFlags, &amp;fe))<br />           {<br />                CArchive ar(&amp;file, CArchive::store);<br />                m_map.Serialize(ar);   //序列化存储<br />           }<br />       }<br />}<p></p><pre></pre></pre>
<img src ="http://www.cppblog.com/xbgs/aggbug/8933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xbgs/" target="_blank">让心飞翔</a> 2006-06-23 23:07 <a href="http://www.cppblog.com/xbgs/archive/2006/06/23/8933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>