<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>joinclear的博客</title>
<link>http://blogger.org.cn/blog/blog.asp?name=joinclear</link>
<description>joinclear的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[VC文件目录选择对话框(任意目录)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=15268</link>
<author>joinclear</author>
<pubDate>2006/6/8 22:46:48</pubDate>
<description><![CDATA[转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=48" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=48</A><BR>
<P>使用目录选择对话框时,如何让其弹出后自动打开指定目录？</P>
<P>是的当用目录选择对话框时，用如下的结构打开。<BR>typedef struct _browseinfo { <BR>HWND hwndOwner; <BR>LPCITEMIDLIST pidlRoot; <BR>LPSTR pszDisplayName; <BR>LPCSTR lpszTitle; <BR>UINT ulFlags; <BR>BFFCALLBACK lpfn; <BR>LPARAM lParam; <BR>int iImage; <BR>} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; </P>
<P>LPCITEMIDLIST pidlRoot; 这个就是　默认为桌面。</P>
<P><BR>还有可以通过这种方式实现，如下：<BR>LPMALLOC pMalloc; &nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if ( SUCCEEDED( SHGetSpecialFolderLocation (NULL, CSIDL_DRIVES, &amp;pidl))) <BR>&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SHELLEXECUTEINFO sei; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ZeroMemory(&amp;sei, sizeof(sei)); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.cbSize = sizeof(sei); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.fMask = SEE_MASK_IDLIST; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.lpIDList = pidl; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.lpVerb = "open"; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.hwnd = AfxGetMainWnd()-&gt;GetSafeHwnd(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sei.nShow = BIF_RETURNONLYFSDIRS; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShellExecuteEx(&amp;sei); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SUCCEEDED( SHGetMalloc (&amp;pMalloc))) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pMalloc-&gt;Free ( pidl ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pMalloc-&gt;Release(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp; } </P>
<P>其中：//CSIDL_DRIVES是我的电脑<BR>参数有好些，<BR>CSIDL_BITBUCKET 回收站 <BR>CSIDL_CONTROLS 控制面板 <BR>CSIDL_DESKTOP Windows 桌面Desktop <BR>CSIDL_DESKTOPDIRECTORY Desktop的目录 <BR>CSIDL_DRIVES 我的电脑 <BR>CSIDL_FONTS 字体目录 <BR>CSIDL_NETHOOD 网上邻居 <BR>CSIDL_NETWORK 网上邻居虚拟目录 <BR>CSIDL_PERSONAL 我的文档 <BR>CSIDL_PRINTERS 打印机 <BR>CSIDL_PROGRAMS 程序组 <BR>CSIDL_RECENT 最近打开的文档 <BR>CSIDL_SENDTO “发送到”菜单项 <BR>CSIDL_STARTMENU 任务条启动菜单项 <BR>CSIDL_STARTUP 启动目录 <BR>CSIDL_TEMPLATES 文档模板 <BR>还有的看　MSDN吧。</P>
<P>现在像论坛上的朋友，他要实现的是要打开　如：f:,f:\\site等这样的目录。<BR>很明显这样的字符串是不被支持的，所以必须要转成　LPCITEMIDLIST 这种结构的才支持。<BR>但微软好像没有类似的函数实现这样的功能。于是就写了一个如下：</P>
<P>//文件目录转成LPITEMIDLIST<BR>LPITEMIDLIST CTestBrowseDlg::ParsePidlFromPath(LPCSTR path)<BR>{&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OLECHAR szOleChar[MAX_PATH];&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPSHELLFOLDER IpsfDeskTop;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPITEMIDLIST lpifq;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;ULONG ulEaten, ulAttribs;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT hres;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;SHGetDesktopFolder(&amp;IpsfDeskTop);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,path,-1,szOleChar,sizeof(szOleChar));&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;hres = IpsfDeskTop -&gt;ParseDisplayName(NULL, NULL, szOleChar, &amp;ulEaten, &amp;lpifq, &amp;ulAttribs);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;hres=IpsfDeskTop-&gt;Release( );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(FAILED(hres))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return lpifq;<BR>}</P>
<P>如这样写：&nbsp;&nbsp;&nbsp;&nbsp;<BR>方法1：<BR>LPITEMIDLIST pidl; <BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; LPMALLOC pMalloc; <BR>&nbsp;&nbsp;&nbsp;&nbsp; pidl = ParsePidlFromPath("F:\\site");//请先确定f:下有这个文件夹<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; SHELLEXECUTEINFO sei; <BR>&nbsp;&nbsp;&nbsp;&nbsp; ZeroMemory(&amp;sei, sizeof(sei)); <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.cbSize = sizeof(sei); <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.fMask = SEE_MASK_IDLIST; <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.lpIDList = pidl; <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.lpVerb = "open"; <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.hwnd = AfxGetMainWnd()-&gt;GetSafeHwnd(); <BR>&nbsp;&nbsp;&nbsp;&nbsp; sei.nShow = BIF_RETURNONLYFSDIRS; <BR>&nbsp;&nbsp;&nbsp;&nbsp; ShellExecuteEx(&amp;sei); <BR>&nbsp;&nbsp;&nbsp;&nbsp; if (SUCCEEDED( SHGetMalloc (&amp;pMalloc))) <BR>&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pMalloc-&gt;Free ( pidl ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pMalloc-&gt;Release(); <BR>&nbsp;&nbsp;&nbsp;&nbsp; } <BR>就可以打开F:\site</P>
<P>方法2：<BR>&nbsp;&nbsp;&nbsp;&nbsp;CString str;<BR>&nbsp;&nbsp;&nbsp;&nbsp;BROWSEINFO bi;<BR>&nbsp;&nbsp;&nbsp;&nbsp;char name[MAX_PATH];<BR>&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(&amp;bi,sizeof(BROWSEINFO));&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;bi.pidlRoot = ParsePidlFromPath("F:\\");<BR>&nbsp;&nbsp;&nbsp;&nbsp;bi.hwndOwner=GetSafeHwnd();<BR>&nbsp;&nbsp;&nbsp;&nbsp;bi.pszDisplayName=name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;bi.lpszTitle="S浏览文件夹";<BR>&nbsp;&nbsp;&nbsp;&nbsp;bi.ulFlags=BIF_RETURNONLYFSDIRS; <BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPITEMIDLIST idl=SHBrowseForFolder(&amp;bi);<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(idl==NULL)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>就能打开f:</P>
<P>由于此文章是工作时间仓促写就，所以文辞方面就没考虑，具体的看源代码吧。<BR><BR></P>]]></description>
</item><item>
<title><![CDATA[(J2ME入门二)J2ME　HelloWorld程序(Eclipse)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14449</link>
<author>joinclear</author>
<pubDate>2006/5/16 17:51:07</pubDate>
<description><![CDATA[转载自: <A href="http://www.vclife.net/mobile/mob_view.asp?mobid=4" target=_blank>http://www.vclife.net/mobile/mob_view.asp?mobid=4</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[(J2ME入门一)Eclipse配置J2ME开发环境]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14448</link>
<author>joinclear</author>
<pubDate>2006/5/16 17:50:24</pubDate>
<description><![CDATA[转载自: <A href="http://www.vclife.net/mobile/mob_view.asp?mobid=3" target=_blank>http://www.vclife.net/mobile/mob_view.asp?mobid=3</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[(二)VC保存和显示数据库图像(JPG、JPEG)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14377</link>
<author>joinclear</author>
<pubDate>2006/5/13 18:08:13</pubDate>
<description><![CDATA[<P>转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=18" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=18</A><BR></P>
<P>简述关键代码如下：</P>
<P>1、保存图片数据到数据库</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;//JPG图片保存到数据库<BR>&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr&nbsp;&nbsp;&nbsp;&nbsp;pRecordset;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset.CreateInstance(__uuidof(Recordset));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Open("SELECT * FROM jpg",_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;AddNew();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Fields-&gt;Item["jpgid"]-&gt;Value = (_variant_t)m_JPGId;//jpgid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARIANT pvList;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetPictureToVariant(pvList,(unsigned char *)m_pJPGBuffer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Fields-&gt;Item["jpgimage"]-&gt;AppendChunk(pvList); //JPG图像文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VariantClear(&amp;pvList);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Update();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("JPG图像保存成功！");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_JPGId == "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateData(false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch(...)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("数据库读取失败");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>其中SetPictureToVariant如下：<BR>&nbsp;&nbsp;&nbsp;&nbsp;void CBMPinDBDlg::SetPictureToVariant(VARIANT &amp;pvList, unsigned char *sPicture)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAFEARRAYBOUND saBound[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saBound[0].cElements = m_nFileLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saBound[0].lLbound = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, saBound);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (long l = 0; l &lt; (long)m_nFileLen; l ++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SafeArrayPutElement( pSA, &amp;l, (void*)&amp;sPicture[l]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VariantClear(&amp;pvList);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pvList.vt = VT_UI1 | VT_ARRAY;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pvList.parray = pSA;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>2、从数据库读取图像文件并且显示在界面</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;//从数据库里取JPG图像文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr&nbsp;&nbsp;&nbsp;&nbsp;pRecordset;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char sSql[129];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(sSql,"SELECT *FROM jpg WHERE jpgid='%s'",m_JPGId);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset.CreateInstance(__uuidof(Recordset));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Open(sSql,_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pRecordset-&gt;adoEOF)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CString str;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str.Format("没有JPGid为: %s 的JPG图像!",m_JPGId );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(str);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invalidate();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_JPGId = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateData(false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_EidtJPGId.SetFocus();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_variant_t pvList ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long lDataSize = pRecordset-&gt;GetFields()-&gt;GetItem("jpgimage")-&gt;ActualSize;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen = (DWORD)lDataSize;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(lDataSize &gt; 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;varBLOB;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;varBLOB = pRecordset-&gt;GetFields()-&gt;GetItem("jpgimage")-&gt;GetChunk(lDataSize);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//把二进制格式的图片转为图片格式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&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;if(varBLOB.vt == (VT_ARRAY | VT_UI1))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;if(m_pJPGBuffer = new char[lDataSize+1])&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *pBuf = NULL;<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;SafeArrayAccessData(varBLOB.parray,(void **)&amp;pBuf);<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;memcpy(m_pJPGBuffer,pBuf,lDataSize);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SafeArrayUnaccessData (varBLOB.parray);<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;m_nFileLen = lDataSize;<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;<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;//m_pJPGBuffer -&gt; pPicture&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen );<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;LPVOID lpBuf = ::GlobalLock( hMem );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(lpBuf,m_pJPGBuffer,m_nFileLen);<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;<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;::GlobalUnlock( hMem );<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;<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;if ( CreateStreamOnHGlobal( hMem, TRUE, &amp;pStream ) !=S_OK ) &nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ;<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;<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;if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&amp;pPicture ) !=S_OK )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ;<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;<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;Invalidate();//在界面显示&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch(...)<BR>&nbsp;&nbsp;&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;AfxMessageBox("从数据库中读取jpg图像有错！");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch(...)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("数据库读取失败");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P><BR>具体的程序请参考附带的例子，例子里面有详细的注释。<BR></P>]]></description>
</item><item>
<title><![CDATA[(一)VC保存和显示数据库图像(BMP)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14376</link>
<author>joinclear</author>
<pubDate>2006/5/13 18:06:09</pubDate>
<description><![CDATA[<P>转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=17" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=17</A><BR></P>
<P>简述关键代码如下：</P>
<P>1、保存图片数据到数据库</P>
<P>//BMP图片保存到数据库<BR>&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr&nbsp;&nbsp;&nbsp;&nbsp;pRecordset;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset.CreateInstance(__uuidof(Recordset));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Open("SELECT * FROM bmp",_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;AddNew();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Fields-&gt;Item["bmpid"]-&gt;Value = (_variant_t)m_BMPId;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//bmpid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VARIANT pvList;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetPictureToVariant(pvList,(unsigned char *)m_pBMPBuffer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Fields-&gt;Item["bmpimage"]-&gt;AppendChunk(pvList);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//BMP图像文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VariantClear(&amp;pvList);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Update();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("BMP图像保存成功！");<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch(...)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("数据库读取失败");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>其中SetPictureToVariant如下：<BR>&nbsp;&nbsp;&nbsp;&nbsp;void CBMPinDBDlg::SetPictureToVariant(VARIANT &amp;pvList, unsigned char *sPicture)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAFEARRAYBOUND saBound[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saBound[0].cElements = m_nFileLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saBound[0].lLbound = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, saBound);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (long l = 0; l &lt; (long)m_nFileLen; l ++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SafeArrayPutElement( pSA, &amp;l, (void*)&amp;sPicture[l]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VariantClear(&amp;pvList);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pvList.vt = VT_UI1 | VT_ARRAY;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pvList.parray = pSA;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>2、从数据库读取图像文件并且显示在界面</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;//从数据库里取BMP图像文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr&nbsp;&nbsp;&nbsp;&nbsp;pRecordset;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char sSql[129];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(sSql,"SELECT *FROM bmp WHERE bmpid='%s'",m_BMPId);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset.CreateInstance(__uuidof(Recordset));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pRecordset-&gt;Open(sSql,_variant_t((IDispatch*)pConnection),adOpenStatic,adLockOptimistic,adCmdText);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pRecordset-&gt;adoEOF)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CString str;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str.Format("没有BMPid为: %s 的BMP图像!",m_BMPId );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(str);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DestroyPhoto();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invalidate();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_BMPId = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateData(false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_EidtBMPId.SetFocus();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_variant_t pvList ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long lDataSize = pRecordset-&gt;GetFields()-&gt;GetItem("bmpimage")-&gt;ActualSize;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen = (DWORD)lDataSize;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(lDataSize &gt; 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;varBLOB;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;varBLOB = pRecordset-&gt;GetFields()-&gt;GetItem("bmpimage")-&gt;GetChunk(lDataSize);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//把二进制格式的图片转为图片格式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(varBLOB.vt == (VT_ARRAY | VT_UI1))<BR>&nbsp;&nbsp;&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;if(m_pBMPBuffer = new char[lDataSize+1])&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;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *pBuf = NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SafeArrayAccessData(varBLOB.parray,(void **)&amp;pBuf);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(m_pBMPBuffer,pBuf,lDataSize);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;SafeArrayUnaccessData (varBLOB.parray);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen = lDataSize;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_hBitmap = BufferToHBITMAP();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invalidate();//在界面显示&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;catch(...)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox("数据库读取失败");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P>上次写了两篇关于在VC界面显示图片(BMP、JPG)的文章，但是并没有涉及到数据库，所以这次补写了这两篇有关数据库的文章，这两篇文章用的是access的数据库，其它的数据库操作道理是一样的。</P>
<P>具体的程序请参考附带的例子，例子里面有详细的注释。 <BR></P>
<P>文章为我原创，更多文章请到我的网站查看(<A href="http://www.vclife.net">www.vclife.net</A>).<BR></P>]]></description>
</item><item>
<title><![CDATA[(二)VC界面显示图片(JPG JPEG GIF)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14375</link>
<author>joinclear</author>
<pubDate>2006/5/13 18:04:27</pubDate>
<description><![CDATA[<P>转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=7" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=7</A><BR></P>
<P>简述实现步骤如下： </P>
<P></P>
<P>1、通过点击浏览按钮选择JPG图像文件<BR>点击浏览按钮打开文件对话框选择JPG图像文件，得到文件所在的路径目录。<BR>关键代码如下：<BR>char szFilter[] = "JPG Files (*.jpg)|*.jpg|JPEG Files (*.jpeg)|*.jpeg|GIF Files (*.gif)|*.gif|All Files (*.*)|*.*||";<BR>CFileDialog dlg(TRUE,"jpg|jpeg|gif",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);<BR>if(dlg.DoModal() == IDOK)<BR>{<BR>CString strPathName = dlg.GetPathName();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>}</P>
<P>2、加载JPG文件到内存<BR>主要通过COM类—IPicture实现。<BR>关键代码如下：<BR>BOOL CShowJPGDlg::LoadJPGFile(const char *pPathname)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;CFile file;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if( !file.Open( pPathname, CFile::modeRead) )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen = file.GetLength();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen );<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPVOID lpBuf = ::GlobalLock( hMem );<BR>&nbsp;&nbsp;&nbsp;&nbsp;if( file.ReadHuge( lpBuf, m_nFileLen ) != m_nFileLen )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;file.Close();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;::GlobalUnlock( hMem );</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;if ( CreateStreamOnHGlobal( hMem, TRUE, &amp;pStream ) !=S_OK ) &nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&amp;pPicture ) !=S_OK )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;<BR>}</P>
<P>3、在屏幕上显示JPG图像<BR>主要通过Render函数实现显示JPG图像。<BR>Render函数说明<BR>HRESULT Render( HDC hdc,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设备环境句柄<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long x,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在hdc上的水平坐标<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long y,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在hdc上的垂直坐标<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long cx,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//图像宽度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long cy,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//图像高度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_XPOS_HIMETRIC xSrc,&nbsp;&nbsp;&nbsp;&nbsp;//在源图像上的水平偏移<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_YPOS_HIMETRIC ySrc,&nbsp;&nbsp;&nbsp;&nbsp;//在源图像上的垂直偏移<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_XSIZE_HIMETRIC cxSrc,&nbsp;&nbsp;&nbsp;&nbsp;//在源图像上水平拷贝的数量<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_YSIZE_HIMETRIC cySrc,&nbsp;&nbsp;&nbsp;&nbsp;//在源图像上垂直拷贝的数量<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCRECT prcWBounds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//指向目标图元设备环境句柄的指针<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<BR>关键代码如下：<BR>void CShowJPGDlg::DrawImage(int x, int y, CDC *pDC)<BR>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (pPicture != NULL) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long nWidth,nHeight; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pPicture-&gt;get_Width( &amp;nWidth ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pPicture-&gt;get_Height( &amp;nHeight ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//图片原大显示<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSize sz( nWidth, nHeight );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;HIMETRICtoDP( &amp;sz );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pPicture-&gt;Render(pDC-&gt;m_hDC,0,0,sz.cx,sz.cy,0,nHeight,nWidth,-nHeight,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;*/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//按窗口尺寸显示<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRect rect;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetClientRect(&amp;rect);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pPicture-&gt;Render(pDC-&gt;m_hDC,x,y,rect.Width(),rect.Height(),0,nHeight,nWidth,-nHeight,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</P>
<P>注意：由于是主要通过COM类—IPicture实现的，不要忘记了CoInitialize(NULL);，用完了CoUninitialize();。<BR>显示JPEG、GIF和JPG是一样的。<BR>相比较BMP图像，JPG、JPEG、GIF图像有很多优点。但BMP图像在VC中的处理好像更理所当然一点，相信这种COM实现显示JPG、JPEG、GIF图像的处理让我们更是耳目一新。</P>
<P>具体的程序请参考附带的例子，例子里面有详细的注释。<BR></P>
<P><BR>&nbsp;</P>]]></description>
</item><item>
<title><![CDATA[(一)VC界面显示图片(BMP)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14374</link>
<author>joinclear</author>
<pubDate>2006/5/13 18:01:54</pubDate>
<description><![CDATA[转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=6" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=6</A><BR>简述实现步骤如下： 
<P></P>
<P>1、通过点击浏览按钮选择BMP图像文件<BR>点击浏览按钮打开文件对话框选择BMP图像文件，得到文件所在的路径目录。<BR>关键代码如下：<BR>char szFilter[] = "BMP Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";<BR>CFileDialog dlg( TRUE,"BMP",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter );<BR>if(dlg.DoModal() == IDOK)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;CString strPathName = dlg.GetPathName();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>}</P>
<P>2、加载BMP文件到内存<BR>通过得到的BMP图像文件路径目录，加载BMP图像文件到内存中。<BR>关键代码如下：<BR>BOOL CShowBMPDlg::LoadShowBMPFile(const char *pPathname)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;CFile file;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if( !file.Open( pPathname, CFile::modeRead) )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;m_nFileLen = file.GetLength();<BR>&nbsp;&nbsp;&nbsp;&nbsp;m_pBMPBuffer = new char[m_nFileLen + 1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(!m_pBMPBuffer)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if(file.ReadHuge(m_pBMPBuffer,m_nFileLen) != m_nFileLen)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;<BR>}</P>
<P>3、将内存中的BMP文件内容转换到HBITMAP<BR>将内存中的BMP文件内容转换成位图句柄。<BR>关键代码如下：<BR>HBITMAP CShowBMPDlg::BufferToHBITMAP()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;HBITMAP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hShowBMP;<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPSTR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hDIB,lpBuffer = m_pBMPBuffer;<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpDIBBits;<BR>&nbsp;&nbsp;&nbsp;&nbsp;BITMAPFILEHEADER&nbsp;&nbsp;&nbsp;&nbsp; bmfHeader;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bmfHeaderLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;bmfHeaderLen = sizeof(bmfHeader);<BR>&nbsp;&nbsp;&nbsp;&nbsp;strncpy((LPSTR)&amp;bmfHeader,(LPSTR)lpBuffer,bmfHeaderLen);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;if (bmfHeader.bfType != (*(WORD*)"BM")) return NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;hDIB = lpBuffer + bmfHeaderLen;<BR>&nbsp;&nbsp;&nbsp;&nbsp;BITMAPINFOHEADER &amp;bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;<BR>&nbsp;&nbsp;&nbsp;&nbsp;BITMAPINFO &amp;bmInfo = *(LPBITMAPINFO)hDIB ;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;lpDIBBits=(lpBuffer)+((BITMAPFILEHEADER *)lpBuffer)-&gt;bfOffBits;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CClientDC dc(this);<BR>&nbsp;&nbsp;&nbsp;&nbsp;hShowBMP = CreateDIBitmap(dc.m_hDC,&amp;bmiHeader,CBM_INIT,lpDIBBits,&amp;bmInfo,DIB_RGB_COLORS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return hShowBMP;<BR>}</P>
<P>4、在屏幕上显示BMP图像<BR>双缓冲实现BMP位图显示在屏幕上。<BR>关键代码如下：<BR>void CShowBMPDlg::DrawImage(int x, int y, CDC *pDC)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;HBITMAP OldBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CDC MemDC;<BR>&nbsp;&nbsp;&nbsp;&nbsp;MemDC.CreateCompatibleDC(pDC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;OldBitmap=(HBITMAP)MemDC.SelectObject(m_hBitmap);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;CRect rect;<BR>&nbsp;&nbsp;&nbsp;&nbsp;GetClientRect(&amp;rect);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(x,y,rect.Width(),rect.Height(),&amp;MemDC,0,0,SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;MemDC.SelectObject(OldBitmap);<BR>}</P>
<P>以上是本人对位图显示资料的一个整理，对你而言也许很简单，但这只是我个人的一个整理总结。一方面整理总结一个自己认为不错的知识点，另一方面也希望能够帮助一些需要帮助的人。</P>
<P>具体的程序请参考附带的例子，例子里面有详细的注释。<BR></P>
<P>源代码 请到转载的网上下载(<A href="http://www.vclife.net">www.vclife.net</A>)<BR></P>]]></description>
</item><item>
<title><![CDATA[美化VC界面(用户登录界面)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=14373</link>
<author>joinclear</author>
<pubDate>2006/5/13 17:45:16</pubDate>
<description><![CDATA[
<P>转载自: <A href="http://www.vclife.net/articles/article_view.asp?atlid=8" target=_blank>http://www.vclife.net/articles/article_view.asp?atlid=8</A><BR></P>
<P>VC开发程序单调的界面相信大家都是深有感触，提到界面美化编程，人们都会说做界面不要用VC写，太难了。<BR>一句俗语：难者不会，会者不难。VC的美化界面编程并没有人们想像的那么难。这篇文章是我写的一个用户登录界面，但界面被我美化了，我将一步一步的来讲解它的美化界面的实现步骤。相信有了这篇文章，你的VC界面从此也能绚丽多彩。 </P>
<P></P>
<P>实现步骤：</P>
<P>第一步：美化界面的非客户区(重绘标题栏和界面边框)。<BR>关键代码如下：<BR>// 函 数 名：DrawTitleBar<BR>// 功能描述：绘制标题栏、边框颜色，绘制标题内容、图标和按钮<BR>// 输入参数：pDC：设备指针<BR>// 输出参数：void<BR>// 创建日期：2006-2-20<BR>// 修改日期：2006-2-20<BR>// 作 者：joinclear<BR>// 附加说明：无<BR>void CTitleBarColorDlg::DrawTitleBar(CDC *pDC)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (m_hWnd)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBrush Brush(RGB(187,200,143));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBrush* pOldBrush = pDC-&gt;SelectObject(&amp;Brush);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRect rtWnd, rtTitle, rtButtons;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(&amp;rtWnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//取得标题栏的位置<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //SM_CXFRAME 窗口边框的边缘宽度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //SM_CYFRAME 窗口边框的边缘高度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //SM_CXSIZE 窗口标题栏宽度<BR>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //SM_CYSIZE 窗口标题栏高度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.left = GetSystemMetrics(SM_CXFRAME); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.top = GetSystemMetrics(SM_CYFRAME); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.right = rtWnd.right - rtWnd.left - GetSystemMetrics(SM_CXFRAME);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPoint point;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//填充顶部框架<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.x = rtWnd.Width();&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.y = GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYFRAME) + 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;PatBlt(0, 0, point.x, point.y, PATCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//填充左侧框架<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.x = GetSystemMetrics(SM_CXFRAME) -1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.y = rtWnd.Height()- 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;PatBlt(0, 0, point.x, point.y, PATCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//填充底部框架<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.x = rtWnd.Width(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.y = GetSystemMetrics(SM_CYFRAME);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//填充右侧框架<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.x = GetSystemMetrics(SM_CXFRAME);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point.y = rtWnd.Height();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//重画标题栏图标<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.left = rtTitle.left ;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.top = rtTitle.top;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.right = m_rtIcon.left + 16;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.bottom = m_rtIcon.top + 15;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::DrawIconEx(pDC-&gt;m_hDC, m_rtIcon.left, m_rtIcon.top, AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME), <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.Width(), m_rtIcon.Height(), 0, NULL, DI_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtIcon.OffsetRect(rtWnd.TopLeft());<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBitmap* pBitmap = new CBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBitmap* pOldBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDC* pDisplayMemDC=new CDC;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;CreateCompatibleDC(pDC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//重画关闭button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.left = rtTitle.right - 16;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.top = rtTitle.top - 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.right = rtButtons.left + 16;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.bottom = rtButtons.top + 15;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_EXIT_FOCUS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, </P>
<P>0, SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtExit = rtButtons;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtExit.OffsetRect(rtWnd.TopLeft()); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//重画最大化/恢复button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.right = rtButtons.left - 3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.left = rtButtons.right - 16;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (IsZoomed())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_RESTORE_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MAX_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, </P>
<P>0, SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtMax = rtButtons;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtMax.OffsetRect(rtWnd.TopLeft());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//重画最小化button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.right = rtButtons.left - 3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButtons.left = rtButtons.right - 16;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MIN_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, </P>
<P>0, SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtMin = rtButtons;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_rtButtMin.OffsetRect(rtWnd.TopLeft());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//重画caption<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nOldMode = pDC-&gt;SetBkMode(TRANSPARENT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COLORREF clOldText=pDC-&gt;SetTextColor(RGB(255, 255, 255));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CFont m_captionFont;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_captionFont.CreateFont(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;18, // 字体的高度&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, // 字体的宽度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, // 字体显示的角度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, // 字体的角度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FW_BOLD, // 字体的磅数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FALSE, // 斜体字体<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FALSE, // 带下划线的字体<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, // 带删除线的字体<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ANSI_CHARSET, // 所需的字符集<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OUT_DEFAULT_PRECIS, // 输出的精度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLIP_DEFAULT_PRECIS, // 裁减的精度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT_QUALITY, // 逻辑字体与输出设备的实际字体之间的精度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFAULT_PITCH | FF_SWISS, // 字体间距和字体集<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_T("Arial")); // 字体名称<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CFont* pOldFont = NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldFont = pDC-&gt;SelectObject(&amp;m_captionFont);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.left += m_rtIcon.Width ()+3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.top = rtTitle.top;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtTitle.bottom = rtTitle.top + 30;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CString m_strTitle;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowText(m_strTitle);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;DrawText(m_strTitle, &amp;rtTitle, DT_LEFT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;SetBkMode(nOldMode);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;SetTextColor(clOldText);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReleaseDC(pDisplayMemDC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete pDisplayMemDC;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete pBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</P>
<P>还有在非客户区 绘制鼠标的消息。分别为：<BR>void CTitleBarColorDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (m_rtButtExit.PtInRect(point)) //关闭<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(WM_CLOSE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;else if (m_rtButtMin.PtInRect(point)) //最小化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));<BR>&nbsp;&nbsp;&nbsp;&nbsp;else if (m_rtButtMax.PtInRect(point))<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (IsZoomed()) //最大化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRect rtWnd;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(&amp;rtWnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRgn rgn;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetWindowRgn((HRGN)rgn,true); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invalidate();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRect rtWnd;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(&amp;rtWnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CRgn rgn;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetWindowRgn((HRGN)rgn,true); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Invalidate();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;else if (!IsZoomed())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Default();<BR>}<BR>void CTitleBarColorDlg::OnNcMouseMove(UINT nHitTest, CPoint point) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;CWindowDC dc(this);<BR>&nbsp;&nbsp;&nbsp;&nbsp;CWindowDC* pDC = &amp;dc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CDC* pDisplayMemDC=new CDC;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;CreateCompatibleDC(pDC);<BR>&nbsp;&nbsp;&nbsp;&nbsp;CBitmap* pBitmap = new CBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CBitmap* pOldBitmap;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CRect rtWnd, rtButton;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (pDC)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(&amp;rtWnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//关闭button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (m_rtButtExit.PtInRect(point))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_EXIT_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_EXIT_FOCUS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton = m_rtButtExit;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, </P>
<P>SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//最大化/恢复button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (m_rtButtMax.PtInRect(point))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (IsZoomed())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_RESTORE_FOCUS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MAX_FOCUS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (IsZoomed())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_RESTORE_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MAX_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton = m_rtButtMax;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, </P>
<P>SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//最小化button<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (m_rtButtMin.PtInRect(point))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MIN_FOCUS);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;LoadBitmap(IDB_MIN_NORMAL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton = m_rtButtMin;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOldBitmap=(CBitmap*)pDisplayMemDC-&gt;SelectObject(pBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, </P>
<P>SRCCOPY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;SelectObject(pOldBitmap);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBitmap-&gt;DeleteObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pDisplayMemDC-&gt;DeleteDC();<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;delete pDisplayMemDC;<BR>&nbsp;&nbsp;&nbsp;&nbsp;delete pBitmap;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;CDialog::OnNcMouseMove(nHitTest, point);<BR>}<BR>大部分实现如上代码所示具体实现请参照程序附带的源代码。</P>
<P>第二步：改变窗口边框为圆角。<BR>关键代码如下：<BR>int CTitleBarColorDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (CDialog::OnCreate(lpCreateStruct) == -1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;CRect rtWnd;<BR>&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(&amp;rtWnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;CRgn rgn;<BR>&nbsp;&nbsp;&nbsp;&nbsp;rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);<BR>&nbsp;&nbsp;&nbsp;&nbsp;SetWindowRgn((HRGN)rgn,true); </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>}</P>
<P>第三步：填充背景。<BR>关键代码如下：<BR>BOOL CTitleBarColorDlg::OnEraseBkgnd(CDC* pDC) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;BOOL retValue= CDialog::OnEraseBkgnd(pDC);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;CRect rc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;GetClientRect(&amp;rc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;pDC-&gt;FillSolidRect(&amp;rc,RGB(236,233,216));<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return retValue;<BR>}</P>
<P>第四步：绘制按钮。<BR>具体请参考源代码中类CXPButton.h、CXPButton.cpp</P>
<P>第五步：绘制编辑框。<BR>具体请参考源代码中类COwnerEdit.h、COwnerEdit.cpp</P>
<P>第六步：绘制静态字体和颜色。<BR>这一步本来也写了一个类的，但想想用OnCtlColor()还是能很好的实现的，就没写。具体实现请看OnCtlColor()中的实现。</P>
<P>以上代码具体实现的细节问题，你可以下载例子代码，仔细查看其源码实现(内有详细注释)。<BR><BR></P>]]></description>
</item><item>
<title><![CDATA[从Windows消息的角度看窗口应用程序的运行过程]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11850</link>
<author>joinclear</author>
<pubDate>2006/2/20 13:43:49</pubDate>
<description><![CDATA[转载自: <A href="http://doc.4kiki.net/content/1/7/200505/01/0cb2559898848981.html" target=_blank>http://doc.4kiki.net/content/1/7/200505/01/0cb2559898848981.html</A><BR>一个典型的Win32窗口应用程序的框架是这样的：<BR>&nbsp;&nbsp;&nbsp; 程序入口点（WinMain函数）－－&gt;注册窗口类（调用RegisterClass函数或RegisterClassEx函数）－－&gt;创建主窗口（调用CreateWindow函数或CreateWindowEx函数）－－&gt;显示主窗口（调用ShowWindow函数）－－&gt;更新主窗口（调用UpdateWindow函数）－－&gt;进入消息循环（GetMessage、TranslateMessage、DispatchMessage）并处理各种Windows消息（窗口过程函数）－－&gt;程序出口点（WinMain返回）。就像下面这个例子一样：
<P>#include&lt;windows.h&gt;<BR>#include&lt;tchar.h&gt;<BR>//窗口类名和窗口标题<BR>TCHAR szWindowClass[]=_T("HELLOWINDOWS");<BR>TCHAR szWindowTitle[]=_T("This is the MAIN window");<BR>//窗口过程函数<BR>LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)<BR>{<BR>&nbsp;//LogMessage(logfile,msg,wParam,lParam);//<BR>&nbsp;switch(msg)<BR>&nbsp;{<BR>&nbsp;case WM_DESTROY:<BR>&nbsp; PostQuitMessage(0);<BR>&nbsp; return 0;<BR>&nbsp;default:<BR>&nbsp; return DefWindowProc(hWnd,msg,wParam,lParam);<BR>&nbsp;}<BR>}</P>
<P>int WINAPI _tWinMain( HINSTANCE hInstance,HINSTANCE,LPTSTR lpCmdLine,int nCmdShow)<BR>{<BR>&nbsp;//注册窗口类<BR>&nbsp;WNDCLASSEX wcex;<BR>&nbsp;wcex.cbSize&nbsp;&nbsp; = sizeof(WNDCLASSEX); <BR>&nbsp;wcex.style&nbsp; = CS_HREDRAW | CS_VREDRAW;<BR>&nbsp;wcex.lpfnWndProc = (WNDPROC)WndProc;<BR>&nbsp;wcex.cbClsExtra&nbsp; = 0;<BR>&nbsp;wcex.cbWndExtra&nbsp; = 0;<BR>&nbsp;wcex.hInstance&nbsp; = hInstance;<BR>&nbsp;wcex.hIcon&nbsp;&nbsp; = NULL;<BR>&nbsp;wcex.hCursor&nbsp; = LoadCursor(NULL, IDC_ARROW);<BR>&nbsp;wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);<BR>&nbsp;wcex.lpszMenuName = NULL;<BR>&nbsp;wcex.lpszClassName = szWindowClass;<BR>&nbsp;wcex.hIconSm&nbsp; = NULL;<BR>&nbsp;RegisterClassEx(&amp;wcex);<BR>&nbsp;//创建主窗口<BR>&nbsp;HWND hWnd = CreateWindowEx(0,szWindowClass, szWindowTitle, WS_OVERLAPPEDWINDOW,<BR>&nbsp; 128, 96, 512, 480, HWND_DESKTOP, NULL, hInstance, NULL);<BR>&nbsp;<BR>&nbsp;if (!hWnd)<BR>&nbsp; return FALSE;<BR>&nbsp;//显示并更新主窗口<BR>&nbsp;ShowWindow(hWnd,nCmdShow);<BR>&nbsp;UpdateWindow(hWnd);<BR>&nbsp;// 进入消息循环<BR>&nbsp;MSG msg;<BR>&nbsp;while (GetMessage(&amp;msg, NULL, 0, 0)) <BR>&nbsp;{<BR>&nbsp; TranslateMessage(&amp;msg);<BR>&nbsp; DispatchMessage(&amp;msg);<BR>&nbsp;}<BR>&nbsp;return msg.wParam;<BR>&nbsp;//程序退出<BR>}</P>
<P>&nbsp;&nbsp;&nbsp; 这个例子很十分简单，只是显示一个窗口就完事了；不过麻雀虽小，五脏俱全，它基本上可以作为一个Win32窗口程序的框架了。<BR>下面来看它的窗口过程WndProc,它只处理了一个消息：WM_DESTROY，其余的消息都交给了Windows去处理（调用DefWindowProc）。对于一个实际的Windows程序来说，要在窗口过程中处理的消息会很多；然而Windows消息成百上千，无论你处理多少消息，剩下的你还是得调用DefWindowProc交给Windows系统去处理。这次我们就来看看，从程序启动到退出，DefWindowProc到底要帮我们做多少的工作。<BR>&nbsp;&nbsp;&nbsp; 实验的思想很简单，把所有传递给窗口过程的消息都记录在一个Log文件中，我们就可以察看在一个程序的生命过程中的所有消息了。在上面的例子中，我们在窗口函数WndProc的最开始调用一个方法（形如注释掉的那一行：LogMessage(logfile,msg,wParam,lParam)），把传递来的消息类型，WPARAM参数，LPARAM参数顺序都记录下来，就会形成一个WIndows消息Log文件了。<BR>&nbsp;&nbsp;&nbsp; 下面是两次实验的结果（假设上面的例子编译后得到HelloWin.EXE）：<BR>&nbsp;&nbsp;&nbsp;&nbsp; 实验一：在文件管理其中选中HelloWin.EXE，按回车键启动，显示主窗口后马上按下ALT+F4把它关闭，得到的LOG文件如下：</P>
<P>时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 消息码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述<BR>HH:MM:SS.MSS&nbsp;&nbsp;&nbsp; MSG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WPARAM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPARAM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECRIPTION<BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0024&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F910&nbsp;&nbsp;&nbsp;&nbsp; WM_GETMINMAXINFO&nbsp; 获取最大化最小化信息<BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0081&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F908&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCREATE&nbsp;&nbsp;窗口非客户区被创建<BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0083&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F930&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCALCSIZE&nbsp;&nbsp;计算非客户区的大小<BR>（WPARAM：FALSE-&gt;不必指出窗口客户区的有效区域）<BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F8D4&nbsp;&nbsp;&nbsp;&nbsp; WM_CREATE&nbsp;&nbsp;主窗口被创建<BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0018&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_SHOWWINDOW&nbsp;&nbsp;<BR>（WPARAM：TRUE-&gt;显示窗口 LPARAM：0-&gt;指出这个消息是调用ShowWindow函数发来的） <BR>03:21:39.187&nbsp;&nbsp;&nbsp; 0x0046&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012FEB0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGING&nbsp;窗口位置（包括大小）正在改变<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x001C&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000584&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATEAPP&nbsp;&nbsp;窗口进程激活状态改变<BR>（WPARAM：TRUE-&gt;Activate激活 LPARAM：线程ID=0x0584）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x0086&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCACTIVATE&nbsp;&nbsp;非客户区的激活状态需要改变<BR>（WPARAM：TRUE-&gt;Activate激活）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;获取小图标2<BR>（WPARAM：2----&gt;ICON_SMALL2）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;获取小图标<BR>（WPARAM：0----&gt;ICON_SMALL）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;获取大图标<BR>（WPARAM：1----&gt;ICON_BIG）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x0006&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATE&nbsp;&nbsp;窗口激活状态改变<BR>（WPARAM：1----&gt;WA_ACTIVE激活）<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x0281&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0xC000000F&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_SETCONTEXT&nbsp;输入法TRUE-&gt;Active&nbsp;<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x0282&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_NOTIFY&nbsp;&nbsp;输入法IMN_OPENSTATUSWINDOW<BR>03:21:39.203&nbsp;&nbsp;&nbsp; 0x0007&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_SETFOCUS&nbsp;&nbsp;窗口获得输入焦点<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0085&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCPAINT&nbsp;&nbsp;非客户区需要重画<BR>（WPARAM：1----&gt;整个窗口（Window Frame）都需要重画<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0014&nbsp;&nbsp;&nbsp; 0x0101005D&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ERASEBKGND&nbsp;&nbsp;擦除背景<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0047&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012FEB0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGED&nbsp;窗口位置（包括大小）已经改变<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0083&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x0012FAEC&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCALCSIZE&nbsp;&nbsp;计算非客户区的大小<BR>（WPARAM：TRUE-&gt;NCCALCSIZE_PARAMS参数有效（根据该参数来计算重画区域）<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0085&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCPAINT&nbsp;&nbsp;非客户区需要重画<BR>（WPARAM：1----&gt;整个窗口（Window Frame）都需要重画<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0014&nbsp;&nbsp;&nbsp; 0x890109B8&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ERASEBKGND&nbsp;&nbsp;擦除背景<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0005&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x01BE01F8&nbsp;&nbsp;&nbsp;&nbsp; WM_SIZE&nbsp;&nbsp;&nbsp;窗口大小已经改变<BR>（WPARAM：0-&gt;SIZE_RESTORED 既不是最大化也不是最小化（MSDN如此说……））<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x0003&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x007E0084&nbsp;&nbsp;&nbsp;&nbsp; WM_MOVE&nbsp;&nbsp;&nbsp;窗口已被移动<BR>（LPARAM：x=84[132] y=7e[126] 指出了窗口客户区的新坐标）<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x000F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_PAINT&nbsp;&nbsp;&nbsp;窗口客户区需要重画<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;2----&gt;ICON_SMALL2<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;0----&gt;ICON_SMALL<BR>03:21:39.218&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON&nbsp;&nbsp;1----&gt;ICON_BIG<BR>===================================================================================<BR>03:21:39.375&nbsp;&nbsp;&nbsp; 0x0101&nbsp;&nbsp;&nbsp; 0x0000000D&nbsp;&nbsp;&nbsp; 0xC01C0001&nbsp;&nbsp;&nbsp;&nbsp; WM_KEYUP&nbsp;&nbsp;&nbsp;键盘有按键被按下<BR>（WPARAM：0D---&gt;VK_RETURN（回车键） LPARAM：RECNT:1;SCCODE:1C;NON-EXKEY）<BR>03:21:41.000&nbsp;&nbsp;&nbsp; 0x0104&nbsp;&nbsp;&nbsp; 0x00000012&nbsp;&nbsp;&nbsp; 0x20380001&nbsp;&nbsp;&nbsp;&nbsp; WM_SYSKEYDOWN&nbsp;&nbsp;系统键被按下<BR>（WPARAM：12---&gt;VK_MENU（ALT键）&nbsp;&nbsp;&nbsp; LPARAM：RECNT:1;SCCODE:38;ALT-DOWN）<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0104&nbsp;&nbsp;&nbsp; 0x00000073&nbsp;&nbsp;&nbsp; 0x203E0001&nbsp;&nbsp;&nbsp;&nbsp; WM_SYSKEYDOWN&nbsp;&nbsp;系统键被按下<BR>（WPARAM：73---&gt;VK_F4（F4键）&nbsp;&nbsp;&nbsp;&nbsp; LPARAM：RECNT:1;SCCODE:3E;ALT-DOWN（ALT键同时被按下））<BR>=======================================================================================<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0112&nbsp;&nbsp;&nbsp; 0x0000F060&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_SYSCOMMAND&nbsp;&nbsp;系统命令<BR>（WPARAM：F060-&gt;SC_CLOSE）<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0010&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_CLOSE&nbsp;&nbsp;&nbsp;窗口需要被关闭<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0046&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F8A0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGING&nbsp;窗口位置（包括大小）正在改变<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0047&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F8A0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGED&nbsp;窗口位置（包括大小）已经改变<BR>03:21:41.609&nbsp;&nbsp;&nbsp; 0x0086&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCACTIVATE&nbsp;&nbsp;窗口非客户区激活状态改变<BR>（WPARAM：FALSE-&gt;InActivate非激活状态）<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0006&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATE&nbsp;&nbsp;窗口激活状态改变<BR>（WPARAM：0-----&gt;WA_INACTIVATE非激活状态）<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x001C&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000584&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATEAPP&nbsp;&nbsp;窗口进程激活状态改变<BR>（WPARAM：FALSE-&gt;InActivate&nbsp;&nbsp; TID=0584）<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0008&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_KILLFOCUS&nbsp;&nbsp;窗口失去输入焦点<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0281&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0xC000000F&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_SETCONTEXT&nbsp;输入法FALSE-&gt;InActivate<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0282&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_NOTIFY&nbsp;&nbsp;输入法IMN_CLOSESTATUSWINDOW<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_DESTROY&nbsp;&nbsp;窗口被销毁&nbsp;<BR>03:21:41.625&nbsp;&nbsp;&nbsp; 0x0082&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCDESTROY&nbsp;&nbsp;窗口非客户区被销毁</P>
<P>&nbsp;&nbsp; 实验二：在文件管理其中用鼠标双击HelloWin.EXE启动程序，显示主窗口后马上移动鼠标到窗口右上角的关闭按钮把它关闭，得到的LOG文件如下：</P>
<P>时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 消息码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;参数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;参数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;描述<BR>HH:MM:SS.MSS&nbsp;&nbsp;&nbsp; MSG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WPARAM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPARAM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECRIPTION<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0024&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F910&nbsp;&nbsp;&nbsp;&nbsp; WM_GETMINMAXINFO<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0081&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F908&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCREATE<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0083&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F930&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCALCSIZE<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F8D4&nbsp;&nbsp;&nbsp;&nbsp; WM_CREATE<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0018&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_SHOWWINDOW<BR>04:29:01.421&nbsp;&nbsp;&nbsp; 0x0046&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012FEB0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGING<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x001C&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000584&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATEAPP<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0086&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCACTIVATE<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0006&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATE<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0281&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0xC000000F&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_SETCONTEXT<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0282&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_NOTIFY<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0007&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_SETFOCUS<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0085&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCPAINT<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0014&nbsp;&nbsp;&nbsp; 0x840108B2&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ERASEBKGND<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0047&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012FEB0&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGED<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0083&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x0012FAEC&nbsp;&nbsp;&nbsp;&nbsp; WM_NCCALCSIZE<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0085&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCPAINT<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0014&nbsp;&nbsp;&nbsp; 0x0F01093A&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ERASEBKGND<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0005&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x01BE01F8&nbsp;&nbsp;&nbsp;&nbsp; WM_SIZE<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x0003&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x007E0084&nbsp;&nbsp;&nbsp;&nbsp; WM_MOVE<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x000F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_PAINT<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>04:29:01.437&nbsp;&nbsp;&nbsp; 0x007F&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_GETICON<BR>========================================================================================<BR>04:29:01.828&nbsp;&nbsp;&nbsp; 0x0084&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x009E0266&nbsp;&nbsp;&nbsp;&nbsp; WM_NCHITTEST&nbsp;光标移动或鼠标键被按下&nbsp;<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=0266[614] y=009E[236]）<BR>04:29:01.828&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp;&nbsp; 0x00A40268&nbsp;&nbsp;&nbsp; 0x02000001&nbsp;&nbsp;&nbsp;&nbsp; WM_SETCURSOR&nbsp;鼠标导致的光标移动<BR>（LPARAM：Hit-Test码:01-&gt;HTCLIENT在客户区&nbsp;鼠标消息码:0200-&gt;MOUSEMOVE鼠标移动）<BR>04:29:01.828&nbsp;&nbsp;&nbsp; 0x0200&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x002001E2&nbsp;&nbsp;&nbsp;&nbsp; WM_MOUSEMOVE&nbsp;鼠标移动<BR>（LPARAM：鼠标当前位置 x=01E2[482] y=0020[32]）<BR>*************此处省略N个[WM_NCHITTEST-WM_SETCURSOR-WM_MOUSEMOVE]消息***************<BR>04:29:01.984&nbsp;&nbsp;&nbsp; 0x0084&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x007F0268&nbsp;&nbsp;&nbsp;&nbsp; WM_NCHITTEST&nbsp;<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=0268[616] y=007F[127]）<BR>04:29:01.984&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp;&nbsp; 0x00A40268&nbsp;&nbsp;&nbsp; 0x02000001&nbsp;&nbsp;&nbsp;&nbsp; WM_SETCURSOR&nbsp;<BR>（LPARAM：Hit-Test码:01-&gt;HTCLIENT在客户区&nbsp;鼠标消息码:0200-&gt;MOUSEMOVE鼠标移动）<BR>04:29:01.984&nbsp;&nbsp;&nbsp; 0x0200&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x000101E4&nbsp;&nbsp;&nbsp;&nbsp; WM_MOUSEMOVE&nbsp;<BR>（LPARAM：鼠标当前位置x=01E4[484] y=0001[1]）<BR>04:29:02.000&nbsp;&nbsp;&nbsp; 0x0084&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x007D0269&nbsp;&nbsp;&nbsp;&nbsp; WM_NCHITTEST&nbsp;<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=0269[617] y=007D[125]）<BR>04:29:02.000&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp;&nbsp; 0x00A40268&nbsp;&nbsp;&nbsp; 0x02000002&nbsp;&nbsp;&nbsp;&nbsp; WM_SETCURSOR&nbsp;鼠标导致的光标移动<BR>（LPARAM：Hit-Test码:02-&gt;HTCAPTION在标题区&nbsp;鼠标消息码:0200-&gt;MOUSEMOVE鼠标移动）<BR>04:29:02.000&nbsp;&nbsp;&nbsp; 0x00A0&nbsp;&nbsp;&nbsp; 0x00000002&nbsp;&nbsp;&nbsp; 0x007D0269&nbsp;&nbsp;&nbsp;&nbsp; WM_NCMOUSEMOVE&nbsp;非客户区的鼠标移动<BR>（WPARAM：Hit-Test码:02-&gt;HTCAPTION&nbsp;LPARAM：光标位置：x=0269[617] y=007D[125]）<BR>************此处省略N个[WM_NCHITTEST-WM_SETCURSOR-WM_MOUSEMOVE]消息******************<BR>04:29:02.234&nbsp;&nbsp;&nbsp; 0x0084&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0075026D&nbsp;&nbsp;&nbsp;&nbsp; WM_NCHITTEST&nbsp;<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=026D[621] y=0075[117]）<BR>04:29:02.234&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp;&nbsp; 0x00A40268&nbsp;&nbsp;&nbsp; 0x02000014&nbsp;&nbsp;&nbsp;&nbsp; WM_SETCURSOR&nbsp;<BR>（LPARAM：Hit-Test码:14-&gt;HTTOPRIGHT在右上角&nbsp;鼠标消息码:0200-&gt;MOUSEMOVE鼠标移动）<BR>04:29:02.234&nbsp;&nbsp;&nbsp; 0x00A0&nbsp;&nbsp;&nbsp; 0x00000014&nbsp;&nbsp;&nbsp; 0x0075026D&nbsp;&nbsp;&nbsp;&nbsp; WM_NCMOUSEMOVE&nbsp;<BR>（WPARAM：Hit-Test码:14-&gt;HTTOPRIGHT&nbsp;&nbsp;&nbsp;&nbsp; LPARAM：光标位置：x=026D[621] y=0075[117]<BR>04:29:02.296&nbsp;&nbsp;&nbsp; 0x0084&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0075026D&nbsp;&nbsp;&nbsp;&nbsp; WM_NCHITTEST&nbsp;<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=026D[621] y=0075[117]）<BR>04:29:02.296&nbsp;&nbsp;&nbsp; 0x0020&nbsp;&nbsp;&nbsp; 0x00A40268&nbsp;&nbsp;&nbsp; 0x02010014&nbsp;&nbsp;&nbsp;&nbsp; WM_SETCURSOR&nbsp;<BR>（LPARAM：Hit-Test码:14-&gt;HTTOPRIGHT在右上角&nbsp;鼠标消息码:0201-&gt;LBUTTONDOWN 鼠标左键被按下<BR>04:29:02.296&nbsp;&nbsp;&nbsp; 0x00A1&nbsp;&nbsp;&nbsp; 0x00000014&nbsp;&nbsp;&nbsp; 0x0075026D&nbsp;&nbsp;&nbsp;&nbsp; WM_NCLBUTTONDOWN&nbsp; 鼠标左键在非客户区按下<BR>（LPARAM：当前光标位置（相对于屏幕左上角）x=026D[621] y=0075[117]）<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0215&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_CAPTURECHANGED&nbsp;&nbsp; 正在失去鼠标捕获 <BR>（LPARAM：0----&gt;HWND_DESKTOP 桌面将要获得鼠标）<BR>===========================================================================================<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0112&nbsp;&nbsp;&nbsp; 0x0000F060&nbsp;&nbsp;&nbsp; 0x0075026D&nbsp;&nbsp;&nbsp;&nbsp; WM_SYSCOMMAND&nbsp;F060--&gt;SC_CLOSE<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0010&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_CLOSE<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0046&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F5E4&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGING<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0047&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x0012F5E4&nbsp;&nbsp;&nbsp;&nbsp; WM_WINDOWPOSCHANGED<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0086&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCACTIVATE<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0006&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATE<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x001C&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000584&nbsp;&nbsp;&nbsp;&nbsp; WM_ACTIVATEAPP<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0008&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_KILLFOCUS<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0281&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0xC000000F&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_SETCONTEXT<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0282&nbsp;&nbsp;&nbsp; 0x00000001&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_IME_NOTIFY<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0002&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_DESTROY<BR>04:29:02.484&nbsp;&nbsp;&nbsp; 0x0082&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;&nbsp;&nbsp; WM_NCDESTROY<BR>&nbsp;&nbsp;&nbsp;&nbsp; 在实验二中，打星号（*）的部分省略了很多个[WM_NCHITTEST-WM_SETCURSOR-WM_MOUSEMOVE]消息，鼠标移动过程中它们一直产生，唯一不同的是指示的鼠标位置不同。<BR>&nbsp;&nbsp;&nbsp;&nbsp; 由上两个LOG文件记录的Windows消息可以对比看出，从我们开始启动程序（无论是从键盘还是鼠标双击启动）到主窗口最终显示在我们面前，Windows已经处理了从开始的WM_GETMINMAXINFO消息到第一条双划线前的WM_GETICON消息；而从我们关闭一个窗口（无论是按下ALT+F4还是鼠标点击“关闭”按钮）到程序最后退出，Windows要处理从第二条双划线后的WM_SYSCOMMAND到最后的WM_NCDESTROY消息。而程序在运行过程中产生的消息在两条双划线之间（有上面两个LOG文件可以看出区别来，跟程序的行为相关的）。值得一提的是程序最后收到的一条消息WM_QUIT，是由PostQuitMessage函数发送的，在消息循环中被GetMessage捕获,GetMessage函数捕获到WM_QUIT消息之后返回FALSE，于是WinMain函数退出消息循环，是不交给窗口过程去处理的，所以上面没有记录下来；之后程序便退出了。<BR>&nbsp;&nbsp;&nbsp;&nbsp; 在写windows程序的时候，我们也可以通过记录windows消息的方式去调试程序的，至于怎么来我就不罗嗦啦：）</P><BR>]]></description>
</item><item>
<title><![CDATA[CToolBar(工具条控制的主要功能)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11750</link>
<author>joinclear</author>
<pubDate>2006/2/15 15:53:14</pubDate>
<description><![CDATA[转载自: <A href="http://dev.csdn.net/develop/article/25/25505.shtm" target=_blank>http://dev.csdn.net/develop/article/25/25505.shtm</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[SQL Server导出导入数据方法]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11749</link>
<author>joinclear</author>
<pubDate>2006/2/15 15:20:45</pubDate>
<description><![CDATA[转载自: <A href="http://www.programfan.com/club/showbbs.asp?id=123211" target=_blank>http://www.programfan.com/club/showbbs.asp?id=123211</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[一个SQL的排序问题]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11522</link>
<author>joinclear</author>
<pubDate>2006/2/5 16:15:00</pubDate>
<description><![CDATA[<P>问题：</P>
<P><SPAN id=txtObj_0>table1<BR>------------------------------------<BR>f1&nbsp;&nbsp;&nbsp;&nbsp;f2<BR>aa&nbsp;&nbsp;&nbsp;&nbsp; t<BR>aa&nbsp;&nbsp;&nbsp;&nbsp; h<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; h<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; f<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; f<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; f<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; f<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; w<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; rrr<BR><BR>求结果如下 (sql 2000中）<BR>------------------------------------<BR>f1&nbsp;&nbsp;&nbsp;&nbsp; f2&nbsp;&nbsp;&nbsp;&nbsp;f3<BR>aa&nbsp;&nbsp;&nbsp;&nbsp; t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<BR>aa&nbsp;&nbsp;&nbsp;&nbsp; h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<BR>bb&nbsp;&nbsp;&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; w&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3<BR>cc&nbsp;&nbsp;&nbsp;&nbsp; rrr&nbsp;&nbsp;&nbsp;&nbsp;4<BR></SPAN></P>
<P><SPAN>方法：用临时表实现如下：</SPAN></P>
<P><SPAN>select * ,IDENTITY(smallint, 1, 1) as Seq into Table1Tmp from Table1 order by f1</SPAN></P>
<P><SPAN>select a.f1,a.f2,b.Max-a.Seq+1 as f3 from Table1Tmp a,<BR>(select f1,Max(Seq)as Max,Min(Seq) as Min from Table1Tmp group by f1) b<BR>&nbsp;where a.f1=b.f1 order by a.f1,f3</P></SPAN>]]></description>
</item><item>
<title><![CDATA[远程连接sql server 2000服务器的解决方案]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11416</link>
<author>joinclear</author>
<pubDate>2006/1/24 14:59:49</pubDate>
<description><![CDATA[<P>远程连接sql server 2000服务器的解决方案 <BR>&nbsp;<BR>解决方案步骤：<BR>一 看ping 服务器IP能否ping通。<BR>&nbsp;&nbsp; 这个实际上是看和远程sql server 2000服务器的物理连接是否存在。如果不行，请检查网络，查看配置，当然得确保远程sql server 2000服务器的IP拼写正确。<BR>二 在Dos或命令行下输入telnet 服务器IP 端口，看能否连通。<BR>如telnet 202.114.100.100 1433<BR>通常端口值是1433，因为1433是sql server 2000的对于Tcp/IP的默认侦听端口。如果有问题，通常这一步会出问题。通常的提示是“……无法打开连接,连接失败"。<BR>如果这一步有问题，应该检查以下选项。<BR>&nbsp;&nbsp; 1 检查远程服务器是否启动了sql server 2000服务。如果没有，则启动。<BR>&nbsp;&nbsp; 2 检查服务器端有没启用Tcp/IP协议，因为远程连接（通过因特网）需要靠这个协议。检查方法是，在服务器上打开 开始菜单-&gt;程序-&gt;Microsoft SQL Server-&gt;服务器网络实用工具，看启用的协议里是否有tcp/ip协议，如果没有，则启用它。<BR>&nbsp;&nbsp; 3 检查服务器的tcp/ip端口是否配置为1433端口。仍然在服务器网络实用工具里查看启用协议里面的tcp/ip的属性，确保默认端口为1433，并且隐藏服务器复选框没有勾上。<BR>&nbsp;&nbsp;&nbsp;&nbsp; 事实上，如果默认端口被修改，也是可以的，但是在客户端做telnet测试时，写服务器端口号时必须与服务器配置的端口号保持一致。如果隐藏服务器复选框被勾选，则意味着客户端无法通过枚举服务器来看到这台服务器，起到了保护的作用，但不影响连接，但是Tcp/ip协议的默认端口将被隐式修改为2433，在客户端连接时必须作相应的改变。<BR>&nbsp;&nbsp; 4 如果服务器端操作系统打过sp2补丁，则要对windows防火墙作一定的配置，要对它开放1433端口，通常在测试时可以直接关掉windows防火墙（其他的防火墙也关掉最好）。<BR>&nbsp;&nbsp; 5 检查服务器是否在1433端口侦听。如果服务器没有在tcp连接的1433端口侦听，则是连接不上的。检查方法是在服务器的dos或命令行下面输入 netstat -a -n 或者是netstat -an，在结果列表里看是否有类似 tcp&nbsp;&nbsp; 127.0.0.1 1433&nbsp;&nbsp; listening 的项。如果没有，则通常需要给sql server 2000打上至少sp3的补丁。其实在服务器端启动查询分析器，输入 select @@version 执行后可以看到版本号，版本号在8.0.2039以下的都需要打补丁。<BR>&nbsp;&nbsp; 如果以上都没问题，这时你再做telnet 服务器ip 1433 测试，将会看到屏幕一闪之后光标在左上角不停闪动。恭喜你，你马上可以开始在企业管理器或查询分析器连接了。</P>
<P>三 检查客户端设置<BR>&nbsp;&nbsp;&nbsp; 程序-&gt;Microsoft SQL Server-&gt; 客户端网络使用工具。像在服务器网络实用工具里一样，确保客户端tcp/ip协议启用，并且默认端口为1433（或其他端口，与服务器端保持一致就行）。</P>
<P>四 在企业管理器里或查询分析器连接测试<BR>&nbsp;&nbsp; 企业管理器-&gt;右键SQlserver组-&gt;新建sqlserver注册-&gt;下一步-&gt;写入远程IP-&gt;下一步-&gt;选Sqlserver登陆-&gt;下一步-&gt;写入登陆名与密码（sa,password）-&gt;下一步-&gt;下一步-&gt;完成<BR>&nbsp;&nbsp; 查询分析器-&gt;文件-&gt;连接-&gt;写入远程IP-&gt;写入登录名和密码（sa,password）-&gt;确定<BR>&nbsp;&nbsp; 通常建议在查询分析器里做，因为默认情况下，通过企业管理器注册另外一台SQL Server的超时设置是4秒，而查询分析器是15秒。<BR>&nbsp;&nbsp; 修改默认连接超时的方法：<BR>&nbsp;&nbsp;&nbsp;&nbsp; 企业管理器-&gt;工具-&gt;选项-&gt;在弹出的"SQL Server企业管理器属性"窗口中，点击"高级"选项卡-&gt;连接设置-&gt;在 登录超时（秒） 后面的框里输入一个较大的数字<BR>&nbsp;&nbsp;&nbsp;&nbsp; 查询分析器-&gt;工具-&gt;选项-&gt;连接-&gt;在 登录超时（秒） 后面的框里输入一个较大的数字<BR>&nbsp;&nbsp;&nbsp;&nbsp; 通常就可以连通了，如果提示错误，则进入下一步。<BR>五&nbsp; 错误产生的原因通常是由于SQL Server使用了"仅 Windows"的身份验证方式，因此用户无法使用SQL Server的登录帐户（如 sa ）进行连接。解决方法如下所示：<BR>&nbsp; 　1 在服务器端使用企业管理器，并且选择"使用 Windows 身份验证"连接上 SQL Server。<BR>　　2 展开"SQL Server组"，鼠标右键点击SQL Server服务器的名称，选择"属性"，再选择"安全性"选项卡。<BR>　　3 在"身份验证"下，选择"SQL Server和 Windows "。<BR>　　4 重新启动SQL Server服务。（在dos或命令行下面net stop mssqlserver停止服务，net start mssqlserver启动服务，也是一种快捷的方法）。</P>
<P>注：在连接本地服务器时，通常使用的是命名管道协议（在服务器网络实用工具里可以看到启用的协议有这个），默认端口是445，因此在本地能连通是不能说明什么问题的，连接远程服务器是完全不同的协议）。 <BR></P>]]></description>
</item><item>
<title><![CDATA[关于const的一些总结]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11192</link>
<author>joinclear</author>
<pubDate>2006/1/13 9:16:00</pubDate>
<description><![CDATA[转载自: <A href="http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1374" target=_blank>http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1374</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[关于inline函数的一此总结]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11191</link>
<author>joinclear</author>
<pubDate>2006/1/13 9:12:32</pubDate>
<description><![CDATA[转载自: <A href="http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1397" target=_blank>http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=1397</A><BR><BR>]]></description>
</item><item>
<title><![CDATA[C++将DBGrid中数据导出到Word和Excel.mht]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11190</link>
<author>joinclear</author>
<pubDate>2006/1/13 9:08:29</pubDate>
<description><![CDATA[转载自: <A href="file:///F:/资料/C++将DBGrid中数据导出到Word和Excel.mht" target=_blank>mhtml:file://F:\资料\C++将DBGrid中数据导出到Word和Excel.mht</A><BR>经常看到有网友发帖子询问如何将DBGrid中的内容导出到Excel或Word文档中，于是笔者花了点时间写了以下两个函数，分别实现将DBGrid中数据导出到Word和Excel文档。需要注意的是DBGrid中的数据并不代表数据库中所有的数据，因为数据集在打开的时候有可能进行了筛选，取决于使用者如何打开这个数据集，总之就是DBGrid中显示多少数据，就导出多少。 <BR><BR>　　一、将DBGrid中的内容导出到Word文档<BR><BR>
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
<TBODY>
<TR>
<TD>//---------------------------------------------------------------------------<BR>// 将DBGrid中的数据导出到Word文档<BR>//---------------------------------------------------------------------------<BR>void __fastcall DBGrid2Word(TDBGrid *dbg, String strDocFile)<BR>{<BR>　if(!dbg-&gt;DataSource-&gt;DataSet-&gt;Active) // 数据集没有打开就返回<BR>　　return;<BR>　Variant vWordApp, vTable, vCell;<BR>　try<BR>　{<BR>　　vWordApp = Variant::CreateObject("Word.Application");<BR>　}<BR>　catch(...)<BR>　{<BR>　　MessageBox(0, "启动 Word 出错, 可能是没有安装Word.","DBGrid2Word", MB_<A class=bluekey href="http://www.yesky.com/key/532/595532.html" target=_blank>OK</A> | MB_ICONERROR);<BR>　　vWordApp = Unassigned;<BR>　　return;<BR>　}<BR>　// 隐藏Word界面<BR>　vWordApp.OlePropertySet("Visible", false);<BR>　// 新建一个文档<BR>　vWordApp.OlePropertyGet("Documents").OleFunction("Add");<BR>　Variant vSelect = vWordApp.OlePropertyGet("Selection");<BR>　// 设置一下字体，大小<BR>　vSelect.OlePropertyGet("Font").OlePropertySet("Size", dbg-&gt;Font-&gt;Size);<BR>　vSelect.OlePropertyGet("Font").OlePropertySet("Name", dbg-&gt;Font-&gt;Name.c_str());<BR>　// 要插入表格的行数<BR>　int nRowCount(dbg-&gt;DataSource-&gt;DataSet-&gt;RecordCount + 1);<BR>　nRowCount = nRowCount &lt; 2? 2: nRowCount;<BR>　// 要插入表格的列数<BR>　int nColCount(dbg-&gt;Columns-&gt;Count);<BR>　nColCount = nColCount &lt; 1? 1: nColCount;<BR>　// 在Word文档中插入与DBGrid行数列数基本相同的一个表格<BR>　vWordApp.OlePropertyGet("ActiveDocument").OlePropertyGet("Tables").OleProcedure("Add",<BR>　　　vSelect.OlePropertyGet("Range"),<BR>　　　nRowCount, // 行数<BR>　　　nColCount, // 列数<BR>　　　1, // DefaultTableBehavior:=wdWord9TableBehavior<BR>　　　0); // AutoFitBehavior:=wdAutoFitFixed<BR>　// 操作这个表格<BR>　vTable = vWordApp.OlePropertyGet("ActiveDocument").<BR>　OleFunction("Range").OlePropertyGet("Tables").OleFunction("Item", 1);<BR>　// 设置<A class=bluekey href="http://www.yesky.com/key/1565/441565.html" target=_blank>单元格</A>的宽度<BR>　for(int i=0; i&lt;nColCount; i++)<BR>　{<BR>　　int nColWidth = dbg-&gt;Columns-&gt;Items[i]-&gt;Width;<BR>　　vTable.OlePropertyGet("Columns").OleFunction("Item", i + 1)<BR>　　　　.OlePropertySet("PreferredWidthType", 3); // wdPreferredWidthPoints<BR>　　vTable.OlePropertyGet("Columns").OleFunction("Item", i + 1)<BR>　　　　.OlePropertySet("PreferredWidth", nColWidth);<BR>　}<BR>　// 先将列名写入Word表格<BR>　for(int j=0; j&lt;dbg-&gt;Columns-&gt;Count; j++)<BR>　{<BR>　　vCell = vTable.OleFunction("Cell", 1, j + 1);<BR>　　vCell.OlePropertySet("Range", dbg-&gt;Columns-&gt;Items[j]-&gt;FieldName.c_str());<BR>　　// 列名单元格背景颜色 // wdColorGray125<BR>　　vCell.OlePropertyGet("Shading").OlePropertySet("BackgroundPatternColor", 14737632);<BR>　}<BR>　// 将DBGrid中的数据写入Word表格<BR>　dbg-&gt;DataSource-&gt;DataSet-&gt;First();<BR>　for(int i=0; i&lt;nRowCount; i++)<BR>　{<BR>　　// 63 63 72 75 6E 2E 63 6F 6D<BR>　　for(int j=0; j&lt;dbg-&gt;Columns-&gt;Count; j++)<BR>　　{<BR>　　　vCell = vTable.OleFunction("Cell", i + 2, j + 1);<BR>　　　vCell.OlePropertySet("Range",<BR>　　　　dbg-&gt;DataSource-&gt;DataSet-&gt;FieldByName(<BR>　　　　　dbg-&gt;Columns-&gt;Items[j]-&gt;FieldName)-&gt;AsString.c_str());<BR>　　}<BR>　　dbg-&gt;DataSource-&gt;DataSet-&gt;Next();<BR>　}<BR>　// 保存Word文档并退出<BR>　vWordApp.OlePropertyGet("ActiveDocument").OleProcedure("SaveAs", strDocFile.c_str());<BR>　vWordApp.OlePropertyGet("ActiveDocument").OleProcedure("Close");<BR>　Application-&gt;ProcessMessages();<BR>　vWordApp.OleProcedure("Quit");<BR>　Application-&gt;ProcessMessages();<BR>　vWordApp = Unassigned;<BR>　// 工作结束<BR>　MessageBox(0, "DBGrid2Word 转换结束!","DBGrid2Word", MB_OK | MB_ICONINFORMATION);<BR>}</TD></TR></TBODY></TABLE><BR><BR>　　二、将DBGrid中的内容导出到Excel文档<BR><BR>
<TABLE borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
<TBODY>
<TR>
<TD>//---------------------------------------------------------------------------<BR>// 将DBGrid中的数据导出到Excel文档<BR>//---------------------------------------------------------------------------<BR>void __fastcall DBGrid2Excel(TDBGrid *dbg, String strXlsFile)<BR>{<BR>　if(!dbg-&gt;DataSource-&gt;DataSet-&gt;Active) // 数据集没有打开就返回<BR>　　return;<BR>　Variant vExcelApp, vSheet;<BR>　try<BR>　{<BR>　　vExcelApp = Variant::CreateObject("Excel.Application");<BR>　}<BR>　catch(...)<BR>　{<BR>　　MessageBox(0, "启动 Excel 出错, 可能是没有安装Excel.","DBGrid2Excel", MB_OK | MB_ICONERROR);<BR>　　return;<BR>　}<BR>　// 隐藏Excel界面<BR>　vExcelApp.OlePropertySet("Visible", false);<BR>　// 新建一个工作表<BR>　vExcelApp.OlePropertyGet("Workbooks").OleFunction("Add", 1); // 工作表<BR>　// 操作这个工作表<BR>　vSheet = vExcelApp.OlePropertyGet("ActiveWorkbook").OlePropertyGet("Sheets", 1);<BR>　// 设置Excel文档的字体<BR>　vSheet.OleProcedure("Select");<BR>　vSheet.OlePropertyGet("Cells").OleProcedure("Select");<BR>　vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font").OlePropertySet("Size", dbg-&gt;Font-&gt;Size);<BR>　vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font").OlePropertySet("Name",dbg-&gt;Font-&gt;Name.c_str());<BR>　vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font").OlePropertySet("FontStyle", "常规");<BR>　vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select");<BR>　// 表格的行数<BR>　int nRowCount(dbg-&gt;DataSource-&gt;DataSet-&gt;RecordCount + 1);<BR>　nRowCount = nRowCount &lt; 2? 2: nRowCount;<BR>　// 表格的列数<BR>　int nColCount(dbg-&gt;Columns-&gt;Count);<BR>　nColCount = nColCount &lt; 1? 1: nColCount;<BR>　// 设置单元格的宽度<BR>　for(int i=0; i&lt;nColCount; i++)<BR>　{<BR>　　int nColWidth = dbg-&gt;Columns-&gt;Items[i]-&gt;Width;<BR>　　vExcelApp.OlePropertyGet("Columns", i + 1).OlePropertySet("ColumnWidth", nColWidth / 7);<BR>　}<BR>　// 先将列名写入Excel表格<BR>　for(int j=0; j&lt;dbg-&gt;Columns-&gt;Count; j++)<BR>　{<BR>　　// 标题行的<A class=bluekey href="http://www.yesky.com/key/2023/592023.html" target=_blank>行高</A><BR>　　vExcelApp.OlePropertyGet("Rows", 1).OlePropertySet("RowHeight", 20);<BR>　　vSheet.OlePropertyGet("Cells", 1, j + 1)<BR>　　　.OlePropertySet("Value", dbg-&gt;Columns-&gt;Items[j]-&gt;FieldName.c_str());<BR>　　// 设置列名单元格的背<A class=bluekey href="http://www.yesky.com/key/3079/588079.html" target=_blank>景色</A><BR>　　Variant vInter = vSheet.OlePropertyGet( "Cells", 1, j + 1).OlePropertyGet("Interior");<BR>　　vInter.OlePropertySet("ColorIndex", 15); // 灰色<BR>　　vInter.OlePropertySet("<A class=bluekey href="http://www.yesky.com/key/1102/596102.html" target=_blank>Pattern</A>", 1); // xlSolid<BR>　　vInter.OlePropertySet("PatternColorIndex", -4105); // xlAutomatic<BR>　}<BR>　// 将DBGrid中的数据写入Excel表格<BR>　dbg-&gt;DataSource-&gt;DataSet-&gt;First();<BR>　for(int i=0; i&lt;nRowCount; i++)<BR>　{<BR>　　// 普通数据行的行高16<BR>　　vExcelApp.OlePropertyGet("Rows", i + 2).OlePropertySet("RowHeight", 16);<BR>　　// 63 63 72 75 6E 2E 63 6F 6D<BR>　　for(int j=0; j&lt;dbg-&gt;Columns-&gt;Count; j++)<BR>　　{<BR>　　　vSheet.OlePropertyGet("Cells", i + 2, j + 1).OlePropertySet("Value",<BR>　　　　　dbg-&gt;DataSource-&gt;DataSet-&gt;FieldByName(<BR>　　　　　　dbg-&gt;Columns-&gt;Items[j]-&gt;FieldName)-&gt;AsString.c_str());<BR>　　}<BR>　　dbg-&gt;DataSource-&gt;DataSet-&gt;Next();<BR>　}<BR>　// 保存Excel文档并退出<BR>　vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", strXlsFile.c_str());<BR>　vExcelApp.OleFunction("Quit");<BR>　vSheet = Unassigned;<BR>　vExcelApp = Unassigned;<BR>　// 工作结束<BR>　MessageBox(0, "DBGrid2Excel 转换结束!","DBGrid2Excel", MB_OK | MB_ICONINFORMATION);<BR>}</TD></TR></TBODY></TABLE><BR>]]></description>
</item><item>
<title><![CDATA[在C++ Builder中用Ole控制Excel表]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11189</link>
<author>joinclear</author>
<pubDate>2006/1/13 9:07:42</pubDate>
<description><![CDATA[转载自: <A href="http://www.yesky.com/412/1651912.shtml" target=_blank>http://www.yesky.com/412/1651912.shtml</A><BR>笔者在实际工作中经常用Excel表做数据报表，大多数表格的数据都要从数据库中读取，这样我就用C++Builder做了一个报表程序，方便了很多，现在把它共享给C++Builder爱好者们，就算为丰富C++Builder的文档资料做点事情吧。<BR><BR>　　首先把Excel报表文件保存到一个指定目录下，最好放在可执行程序的子目录下，作为<A class=bluekey href="http://www.yesky.com/key/3739/3739.html" target=_blank>模板</A>文件。可以把报表标题、表头等设置好。这里是保存在trpt子目录下。<BR><BR>　　然后建一个report目录，作为报表目标<A class=bluekey href="http://www.yesky.com/key/2996/2996.html" target=_blank>文件夹</A>，存放填好数据的报表，可以由用户直接操作。<BR><BR>　　首先确定在你的机器中装有Office。这里一Office2000为例。<BR><BR>　　在C++Builder中新建一个工程，在窗体Form1上面放一个两个<A class=bluekey href="http://www.yesky.com/key/4880/4880.html" target=_blank>按钮</A>SaveButton和ReadButton，分别用来保存数据到Excel表和显示刚刚保存的Excel表。<BR><BR>　　在SaveButton按钮的单击事件中把从数据库中取到的数据放入到指定的Excel表中并将改文件拷贝到report目录下。在ReadButto按钮的单击事件中显示report目录下的报表文件，方便用户修改和另外保存。<BR><BR>　　在Form1.h头文件中定义几个变量：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>private:<BR>Variant Ex,Wb,Sheet,ERange,EBorders;</TD></TR></TBODY></TABLE><BR>　　并在文件头中包含如下语句：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>#include "Excel_2K_SRVR.h"<BR>#include <OLESERVER.HPP></TD></TR></TBODY></TABLE><BR>　　在Form1.cpp的文件头中加入<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>#pragma link "Excel_2K_SRVR"</TD></TR></TBODY></TABLE><BR>　　主要代码如下：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>void __fastcall TForm1:: SaveButtonClick(TObject *Sender)<BR>{<BR>try<BR>{<BR>SaveButton-&gt;Enabled = false;<BR>ReadButton-&gt;Enabled = false;//使两个按钮无效<BR><BR>file://取报表文件CardSend.xls的完整目录名<BR>AnsiString ExcelFileName = GetCurrentDir()+"\\trpt\\table.xls"; <BR><BR>if(!FileExists(ExcelFileName))<BR>{<BR><A class=bluekey href="http://www.yesky.com/key/117/5117.html" target=_blank>Application</A>-&gt;MessageBox("报表模板文件不存在,无法打开！",<BR>"错误",MB_ICONSTOP|MB_OK);<BR>return;<BR>}<BR>file://建立Excel的Ole对象Ex<BR>try<BR>{<BR>Ex = Variant::CreateObject("Excel.Application");<BR>}<BR>catch(...)<BR>{<BR>Application-&gt;MessageBox("无法启动Excel","错误",MB_ICONSTOP|MB_OK);<BR>return;<BR>}<BR>file://设置Excel为不可见<BR>Ex.OlePropertySet("Visible",false);<BR>file://打开指定的Excel报表文件。报表文件中最好设定只有一个Sheet。<BR>Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());<BR>Wb = Ex.OlePropertyGet("ActiveWorkBook");<BR>Sheet = Wb.OlePropertyGet("ActiveSheet");//获得当前默认的Sheet<BR><BR>file://清空Excel表，这里是用循环清空到第300行。对于一般的表格已经足够了。<BR>AnsiString strRowTemp; <BR>AnsiString strRange;<BR>int iCols,iRows;//记录列数和行数<BR><BR>/*从第三行开始，到第300行止。一般第一行是表标题，第二行是副标题或者制表日期。*/<BR>for(iRows=3;iRows&lt;300;iRows++)<BR>{ file://假设只有6列。<BR>for (iCols = 1;iCols &lt; 7; iCols++)<BR>{<BR>file://清空行<BR>Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value","");<BR>}<BR>file://去掉表格<A class=bluekey href="http://www.yesky.com/key/2865/2865.html" target=_blank>边框</A><BR>strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);//获取操作范围<BR>ERange = Sheet.OlePropertyGet("Range",strRange.c_str());<BR>EBorders = ERange.OlePropertyGet("Borders");//获取边框对象<BR>EBorders.OlePropertySet("linestyle",xlNone);<BR>}<BR><BR>AnsiString strPtrDate; file://存放当前日期，作为制表日期<BR>DateSeparator = '-';<BR>ShortDateFormat = "yyyy/m/d";//设置为年/月/日格式<BR><BR>strPtrDate = DateToStr(Date());//取当前日期<BR><BR>AnsiString strYear = strPtrDate.SubString(1,4);<BR>strPtrDate = strPtrDate.SubString(6,strPtrDate.Length()-5);<BR>AnsiString strMonth = strPtrDate.SubString(1,strPtrDate.Pos("-")-1);<BR>AnsiString strDay = <BR>strPtrDate.SubString(strPtrDate.Pos("-")+1,<BR>strPtrDate.Length()-strPtrDate.Pos("-"));<BR>strPtrDate = strYear+"年"+strMonth+"月"+strDay+"日";<BR><BR>AnsiString strData = "报表标题";//报表标题<BR>file://将报表标题置于第一行第一列。在此之前，应将报表文件的标题格式设定好。<BR>Sheet.OlePropertyGet("Cells",1,1).OlePropertySet("Value",<BR>strData.c_str());<BR>file://将制表日期置于表格第二行的右侧。<BR>Sheet.OlePropertyGet("Cells",2,5).OlePropertySet("Value",<BR>strPtrDate.c_str());<BR><BR>iRows = 3;//在第三行放置表格的列名<BR>Sheet.OlePropertyGet("Cells",iRows,1).OlePropertySet("Value","列名1");<BR>Sheet.OlePropertyGet("Cells",iRows,2).OlePropertySet("Value","列名2");<BR>Sheet.OlePropertyGet("Cells",iRows,3).OlePropertySet("Value","列名3");<BR>Sheet.OlePropertyGet("Cells",iRows,4).OlePropertySet("Value","列名4");<BR>Sheet.OlePropertyGet("Cells",iRows,5).OlePropertySet("Value","列名5");<BR>Sheet.OlePropertyGet("Cells",iRows,6).OlePropertySet("Value","列名6");<BR>file://画表格边框，在A3：F3之间取范围<BR>strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);<BR>ERange = Sheet.OlePropertyGet("Range",strRange.c_str());<BR>EBorders = ERange.OlePropertyGet("Borders");<BR>EBorders.OlePropertySet("linestyle",xlContinuous);<BR>EBorders.OlePropertySet("weight",xlThin);<BR>EBorders.OlePropertySet("colorindex",xlAutomatic);<BR>iRows++;<BR>file://从数据库中取数据(略)，假设数据集放入Query1中。<BR>Query1-&gt;Open();//打开数据集<BR>file://循环取数<BR>while(!Query1-&gt;Eof)<BR>{ <BR>file://循环取字段的数据放到Excel表对应的行列中<BR>for(iCols=1;iCols&lt;7;iCols++)<BR>{ <BR>strRowTemp = Query1-&gt;Fields-&gt;Fields[iCols-1]-&gt;AsString;<BR>Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value",<BR>strRowTemp.c_str());<BR>}<BR>file://画该行的表格边框<BR>strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);<BR>ERange = Sheet.OlePropertyGet("Range",strRange.c_str());<BR>EBorders = ERange.OlePropertyGet("Borders");<BR>EBorders.OlePropertySet("linestyle",xlContinuous);<BR>EBorders.OlePropertySet("weight",xlThin);<BR>EBorders.OlePropertySet("colorindex",xlAutomatic);<BR>iRows++;<BR>Query1-&gt;Next();<BR>}//while结束<BR><BR>Wb.OleProcedure("Save");//保存表格<BR>Wb.OleProcedure("Close");关闭表格<BR>Ex.OleFunction("Quit");退出Excel<BR>file://定义目标文件名<BR>AnsiString DestinationFile =<BR>GetCurrentDir()+"\\report\\table.xls";<BR>file://将刚刚修改的Excel表格文件table.xls拷贝到report目录下<BR>if(!CopyFile(ExcelFileName.c_str(),DestinationFile.c_str(),false))<BR>{<BR>Application-&gt;MessageBox("复制文件操作失败,Excel文件可能正在使用中！",<BR>"错误",MB_ICONSTOP|MB_OK);<BR>return;<BR>}<BR>Application-&gt;MessageBox("成功完成报表保存！\n可以按\'打开Excel文件\'<BR>按钮进行报表工作","提示",MB_ICONINFORMATION|MB_OK);<BR><BR>SaveButton -&gt;Enabled = true;<BR>ReadButton -&gt;Enabled=true;<BR>}//try结束<BR>catch(...)<BR>{<BR>Application-&gt;MessageBox("操作Excel表格失败！",<BR>"错误",MB_ICONSTOP|MB_OK);<BR>Wb.OleProcedure("Close");<BR>Ex.OleFunction("Quit");<BR>SaveButton -&gt;Enabled = true;<BR>ReadButton -&gt;Enabled=false;<BR>}<BR>}</TD></TR></TBODY></TABLE><BR>　　至此，完成报表数据的写入工作。如果要对完成的Excel表进行操作，可以点击"打开Excel表文件按钮"(ReadButton),进行修改，保存，打印等操作。ReadButton的单击事件如下实现：<BR><BR>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>void __fastcall TForm1:: ReadButtonClick(TObject *Sender)<BR>{<BR>try<BR>{<BR>file://指定report目录下的报表文件用于用户操作<BR>AnsiString ExcelFileName = <BR>GetCurrentDir();+"\\report\\table.xls";<BR><BR>if(!FileExists(ExcelFileName))<BR>{<BR>Application-&gt;MessageBox("Excel表文件不存在,无法打开！",<BR>"错误",MB_ICONSTOP|MB_OK);<BR>return;<BR>}<BR><BR>try<BR>{<BR>Ex = Variant::CreateObject("Excel.Application");<BR>}<BR>catch(...)<BR>{<BR>Application-&gt;MessageBox("无法启动Excel","错误",MB_ICONSTOP|MB_OK);<BR>return;<BR>}<BR>file://使Excel可见<BR>Ex.OlePropertySet("Visible",true);<BR>file://打开Excel表格文件Table.xls<BR>Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());<BR>}<BR>catch(...)<BR>{<BR>Application-&gt;MessageBox("操作Excel表格错误！","错误",MB_ICONSTOP|MB_OK);<BR>Ex.OleFunction("Quit");<BR>}<BR>}<BR></TD></TR></TBODY></TABLE><BR>　　以上关于C++BuilderExcel表格的操作仅作为个人观点和水平呈献给关心此问题的读者，如果有更好的方式方法，敬请指教，不胜感激。<BR><BR>]]></description>
</item><item>
<title><![CDATA[如何用 ADO 方式把数据写到 Excel 表中，以及如何从 Excel 表中读出数据？]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11188</link>
<author>joinclear</author>
<pubDate>2006/1/13 9:04:33</pubDate>
<description><![CDATA[转载自: <A href="http://dev.hackbase.com/hackbase11/how303381.htm" target=_blank>http://dev.hackbase.com/hackbase11/how303381.htm</A><BR>
<TABLE width="100%">
<TBODY>
<TR>
<TD><PRE>如何用 ADO 方式把数据写到 Excel 表中，以及如何从 Excel 表中读出数据？
另外，在写 Excel 表格时，如何控制单元格的格式，如绘制边框线，水平居中，字体等？
</PRE></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=10 bgColor=#f1f5fa></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#3366cc>回复人：<B> lanren_me(阿波) </B></FONT><FONT color=#000000>( ) 信誉：115 </FONT></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#000000>2003-05-29 12:34:43Z </FONT></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#000000>得分:</FONT><FONT color=#000000>25</FONT> </TD></TR>
<TR>
<TD bgColor=#0066cc colSpan=4 height=1></TD></TR>
<TR>
<TD colSpan=4 height=5></TD></TR>
<TR>
<TD><FONT color=#ffffff>?</FONT></TD>
<TD colSpan=3><PRE>要在应用程序中控制Excel2000的运行，首先必须在编制自动化客户程序时使其头文件要包含Comobj.hpp和Utilcls.h。
即：#include&lt;Comobj.hpp&gt;
#include&lt;Utilcls.h&gt;
C++ Builder开发者把Excel自动化对象的功能包装在下面的四个Ole Object Class函数中，应用人员可以很方便地进行调用。
设置对象属性：Variant  OlePropertySet（属性名，参数……）；
        获得对象属性：void  OlePropertyGet（属性名，参数……）；
        调用对象方法：1) Variant  OleFunction（函数名，参数……）；
                    2) void  OleProcedure（过程名，参数……）；
 C++ Builder中使用OLE控制Excel2000，必须掌握Excel2000的自动化对象及Microsoft Word Visual Basic帮助文件中的关于Excel的对象、方法和属性。对象是一个Excel元素，属性是对象的一个特性或操作的一个方面，方法是对象可以进行的动作。
1、Excel中常用的对象是：Application，Workbooks，Worksheets等。
（1）	创建应用对象：如：
Variant ex；
ex=Variant::CreateObject ("Excel.Application");
     或者 ex=CreateOleObject ("Excel.Application");
（2）	创建工作簿对象：
Variant wb；
wb=ex.OlePropertyGet("ActiveWorkBook");
（3）	创建工作表对象：
Variant sheet；
sheet=wb.OlePropertyGet("ActiveSheet");
（4）	创建区域对象：
Variant range；
range=sheet.OlePropertyGet("Range","A1:A10");
2、常用的属性操作：
（1）新建EXCEL文件：
（a）：新建系统模板的工作簿
ex.OlePropertyGet("workbooks").OleFunction("Add")      //默认工作簿
ex.OlePropertyGet("workbooks").OleFunction("Add"，1)   //单工作表
ex.OlePropertyGet("workbooks").OleFunction("Add"，2)   //图表
ex.OlePropertyGet("workbooks").OleFunction("Add"，3)   //宏表
ex.OlePropertyGet("workbooks").OleFunction("Add"，4)   //国际通用宏表
ex.OlePropertyGet("workbooks").OleFunction("Add"，5)   //与默认的相同
ex.OlePropertyGet("workbooks").OleFunction("Add"，6)   //工作簿且只有一个表
（b）：新建自己创建的模板的工作簿
ex.OlePropertyGet("workbooks").OleFunction("Add","C:\\WINDOWS\\Profiles\\test2\\Application Data\\Microsoft\\Templates\\result.xlt");  // 后面写上模板的完全路径，注意“\\”
（2）打开工作簿：
ex.OlePropertyGet("workbooks").OleFunction("open"，"路径名.xls")
（3）保存工作簿：
wb.OleFunction("Save"); //表格保存
       wb..OleFunction("SaveAs","文件名"); //表格保存为，文件路径注意用“\\”
（4）退出EXCEL：
ex.OleFunction ("Quit");
（5）设置字体：
  （a）：设置单元格字体
sheet.OlePropertyGet("Cells",1,1).OlePropertyGet("Font").OlePropertySet("Name","隶书");
      sheet.OlePropertyGet("Cells",2,3).OlePropertyGet("Font").OlePropertySet("size",28);
  （b）：设置所选区域字体
range.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("size",28);      range.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Color",
RGB(0,0,255));
     其中参数的设置：
        Font---Name :  “隶书”               //字体名称
           ----Size :    12                  //字体大小
           ----Color :  RGB(*,*,*)           //颜色
           -----Underline : true/false           //下划线
           -----Italic:   true/false             //斜体
（6）单元格的合并：
（a） range1=sheet.OlePropertyGet("Range", "A1:A2");   //A1和A2单元格合并
（b） AnsiString Str="A"+IntToStr(j)+":"+"C"+IntToStr(j);
        range1=sheet.OlePropertyGet("Range",Str);   //可以用变量控制单元格合并
range1.OleFunction("Merge" , false);
（7）赋值语句：
（a）：指定单元格赋值
sheet.OlePropertyGet("Cells",3,6).OlePropertySet("Value",str);
      sheet.OlePropertyGet("Cells",j,1).OlePropertySet("Value","共查到记录:"+IntToStr(j-6));
（b）：所选区域单元格赋值
range.OlePropertyGet("Cells").OlePropertySet("Value",10);
（c）：所选区域行赋值
range.OlePropertyGet("Rows",1).OlePropertySet("Value",1234);
（d）：工作表列赋值
sheet.OlePropertyGet("Columns",1).OlePropertySet("Value",1234);
（8）取值语句：
AnsiString abc=sheet.OlePropertyGet("Cells",120,1).OlePropertyGet("Value");
（9）区域选择：
range.OlePropertyGet("Cells").OleFunction("Select");
（10）窗口属性：
（a）显示属性
ex.OlePropertySet("Windowstate",3);         //最大化显示
参数  1---------xlNormal                  //正常显示
2---------xlMinimized                //最小化显示
3---------xlMaximized                //最大化显示
（b）状态栏属性
ex.OlePropertySet ("StatusBar","您好，请您稍等。正在查询！");
ex.OlePropertySet ("StatusBar", false);     //还原成默认值
（c）标题属性：
                ex.OlePropertySet("Caption","查询系统");


void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Variant my_excel,all_workbooks,my_workbook,my_worksheet;
   Variant my_range;
   AnsiString columname,residue,cellname,rangename;
   int i,j=1;
   int count;
try
    {
     my_excel=CreateOleObject("excel.Application");//启动Excel
    }
    catch(...)
    {
     MessageBox(GetFocus(),"无法启动Excel","警告",MB_OK|MB_ICONSTOP);
     Abort();
    }
    all_workbooks=my_excel.OlePropertyGet("WorkBooks");
    Procedure Open("Open");

my_excel.OlePropertySet("Visible",(Variant)true); //使Excel启动后可见
    my_workbook=all_workbooks.OleFunction("Add");//新建一个工作薄
    my_workbook=my_excel.OlePropertyGet("ActiveWorkbook");
    my_worksheet=my_workbook.OlePropertyGet("ActiveSheet");
    my_worksheet.OlePropertyGet("Rows",2).OleProcedure("Insert");//插入一行

//根据DBGrid的表头输出Excel表头
   for(i=0;i&lt;DBGridEh1-&gt;FieldCount;++i)
    {
     my_excel.OlePropertyGet("Cells",1,(i+1)).OlePropertySet("Value",DBGridEh1-&gt;Columns-&gt;Items[i]-&gt;Title-&gt;Caption.c_str());
    }
//输出表体
    ADOQuery1-&gt;DisableControls();
    ADOQuery1-&gt;First();
    for(j=2;!ADOQuery1-&gt;Eof;++j)
    {
     for(i=0;i&lt;DBGridEh1-&gt;FieldCount;++i)
     {
      //向表格添加数据
      my_excel.OlePropertyGet("Cells",j,(i+1)).OlePropertySet("Value",DBGridEh1-&gt;Columns-&gt;Items[i]-&gt;Field-&gt;AsString.c_str());
     }
     ADOQuery1-&gt;Next();
    }
    ADOQuery1-&gt;EnableControls();

    my_worksheet.OlePropertyGet("Range","A1:D3").OlePropertyGet("Interior").OlePropertySet("ColorIndex",15); //改表格颜色
  //  my_worksheet.OlePropertyGet("Range","A1:A3").OleProcedure("Merge",0); //合并单元格
    my_worksheet.OlePropertyGet("Range","A1:D1").OlePropertyGet("Columns").OleProcedure("autofit"); //设置自适应列宽
   // my_worksheet.OlePropertyGet("Range","A1:D3").OleProcedure("Merge",1);
    my_worksheet.OlePropertyGet("Range","A1:D3").OlePropertySet("HorizontalAlignment",3);  //居中

   MessageBox(this-&gt;Handle,"请按确定彻底关闭Excel","通知",MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
    my_excel.OleFunction("Quit");


}
</PRE></TD></TR>
<TR>
<TD align=right colSpan=4 height=10><FONT color=#ff6633><B><A href="http://dev.hackbase.com/hackbase11/how303381.htm#top"><FONT color=#3366cc>Top</FONT></A></B></FONT></TD></TR>
<TR>
<TD colSpan=4 height=5></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=10 bgColor=#f1f5fa></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#3366cc>回复人：<B> jukyy(做一大水雷把鬼子炸沉) </B></FONT><FONT color=#000000>( ) 信誉：90 </FONT></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#000000>2003-05-29 13:03:16Z </FONT></TD>
<TD bgColor=#f1f5fa height=25><FONT color=#000000>得分:</FONT><FONT color=#000000>25</FONT> </TD></TR>
<TR>
<TD bgColor=#0066cc colSpan=4 height=1></TD></TR>
<TR>
<TD colSpan=4 height=5></TD></TR>
<TR>
<TD><FONT color=#ffffff>?</FONT></TD>
<TD colSpan=3><PRE>高人呀，学习。我这有一个向Excel里写数据的函数，事先把数据导入到一个ADOTable中，然后调用
DataSetToExcel(ADOTable1,true);
//以下是往Excel里写数据
void DataSetToExcel(TDataSet* DataSet,bool H)
{
    Variant Ex,Wbs,Wb,Sh1;
    int CurrRow,CurrCol;
    CurrCol=0;
    CurrRow=0;
    Screen-&gt;Cursor=crHourGlass;
    if(Ex.IsEmpty())
        try
        {
            Ex=Variant::CreateObject("Excel.Application");
        }
        catch(...)
        {
            Screen-&gt;Cursor=crDefault;
            Application-&gt;MessageBoxA("打开Excel出错，请确认你已经正确安装了Microsoft Office2000!","违章车辆照片管理系统",64);
            return;
        }
    try
    {
        if(Ex.PG("ActiveWorkBook").IsEmpty())
            Ex.PG("WorkBooks").PR("ADD");
        if(Wb.IsEmpty())
            Wb=Ex.PG("ActiveWorkBook");
        Sh1=Wb.PG("Sheets").FN("Add");
        Ex.OlePropertySet("Visible",true);
    }
    catch(...)
    {
        Ex=Ex.Empty();
        Wb=Wb.Empty();
        DataSetToExcel(DataSet,H);
    }
    if(H)                 //PR=OleProcedure,PG=OlePropertyGet,PS=OlePropertySet
    {
        for (int j=0;j&lt;DataSet-&gt;Fields-&gt;Count;j++)
        {
            if(DataSet-&gt;Fields-&gt;Fields[j]-&gt;Visible)
            {
                CurrCol++;
                Sh1.PG("Cells",1,CurrCol).PS("Value",DataSet-&gt;Fields-&gt;Fields[j]-&gt;FieldName);
            }
        }
        DataSet-&gt;First();
        for (int i=0;i&lt;DataSet-&gt;RecordCount;i++)
        {
            CurrCol=0;
            for (int j=0;j&lt;DataSet-&gt;Fields-&gt;Count;j++)
            {
                if(DataSet-&gt;Fields-&gt;Fields[j]-&gt;Visible)
                {
                    CurrCol++;
                    Sh1.PG("Cells",i+2,CurrCol).PS("Value",DataSet-&gt;Fields-&gt;Fields[j]-&gt;AsString);
                }
            }
            DataSet-&gt;Next();
        }
    }
    else
    {
        for (int j=0;j&lt;DataSet-&gt;Fields-&gt;Count;j++)
        {
            if(DataSet-&gt;Fields-&gt;Fields[j]-&gt;Visible)
            {
                CurrRow++ ;
                Sh1.PG("Cells",CurrRow,1).PS("Value",DataSet-&gt;Fields-&gt;Fields[j]-&gt;FieldName);
                DataSet-&gt;First();
                for (int i=0;i&lt;DataSet-&gt;RecordCount;i++)
                {
                    Sh1.PG("Cells",CurrRow,i+2).PS("Value",DataSet-&gt;Fields-&gt;Fields[j]-&gt;AsString);
                    DataSet-&gt;Next();
                }
            }
        }
    }
    Screen-&gt;Cursor=crDefault;
}
</PRE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>]]></description>
</item><item>
<title><![CDATA[c++builder中，DBGrid的行颜色设置]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11105</link>
<author>joinclear</author>
<pubDate>2006/1/9 10:21:29</pubDate>
<description><![CDATA[<P>　设一DBGrid已经和一DataSorce连接，且能显示某一表中的所有记录。</P>
<P>现我要让DBGrid中显示的记录,记录号为奇数时显示一种颜色，记录号为双数时又显示一种颜色。</P>
<P>方法是响应：DBGrid的消息：OnDrawColumnCell</P>
<P>程序如下：</P>
<P>void __fastcall T***::DBGrid1DrawColumnCell(TObject *Sender,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const TRect &amp;Rect, int DataCol, TColumn *Column,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TGridDrawState State)<BR>{<BR>&nbsp; if(DBGrid1-&gt;DataSource-&gt;DataSet-&gt;RecNo % 2 == 0)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Font-&gt;Color = clWindowText;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Brush-&gt;Color =clMoneyGreen;<BR>&nbsp; }<BR>&nbsp; else<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Font-&gt;Color = clWindowText;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Brush-&gt;Color = clCream;<BR>&nbsp; }<BR>&nbsp; DBGrid1-&gt;DefaultDrawColumnCell(Rect,DataCol,Column,State);<BR>}</P>
<P>这时DBGrid显示了颜色，但这时当我选中某一行记录时，没有我以前（option\dgRowSelect=true）选中时的颜色效果了，就是说我这时选中了哪一行，没有颜色提示了。</P>
<P>故下面的程序代码，我又加入这个选中行有颜色标识的提示。而且颜色是可以任意变的。</P>
<P>改后的程序如下：<BR>void __fastcall TfmDrvVeh::DBGrid1DrawColumnCell(TObject *Sender,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const TRect &amp;Rect, int DataCol, TColumn *Column,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TGridDrawState State)<BR>{<BR>&nbsp; if(DBGrid1-&gt;DataSource-&gt;DataSet-&gt;RecNo % 2 == 0)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Font-&gt;Color = clWindowText;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Brush-&gt;Color =clMoneyGreen;<BR>&nbsp; }<BR>&nbsp; else<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Font-&gt;Color = clWindowText;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Brush-&gt;Color = clCream;<BR>&nbsp; }<BR>&nbsp; DBGrid1-&gt;DefaultDrawColumnCell(Rect,DataCol,Column,State);</P>
<P>&nbsp; 　if(State.Contains(gdSelected)||(State.Contains(gdSelected)&amp;&amp;State.Contains(gdFocused)))<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Font-&gt;Color = clWindowText;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;Canvas-&gt;Brush-&gt;Color =TColor RGB(157,167,253);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBGrid1-&gt;DefaultDrawColumnCell(Rect,DataCol,Column,State);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>]]></description>
</item><item>
<title><![CDATA[回车键的使用]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=joinclear&amp;id=11104</link>
<author>joinclear</author>
<pubDate>2006/1/9 10:17:29</pubDate>
<description><![CDATA[<P>在VC中创建一基于对话框的工程，编译运行，成功。面对着刚刚创建的工程，心里那个高兴呀。突然一时心血来潮，按了个回车键，工程一闪而过没了。再编译运行，成功。按了个ESC键，工程一闪而过也没了。<BR>为什么会这样，因为CDialog 中有默认对ENTER和ESC键的处理。<BR>解决这种一按回车和ESC键就关闭工程的正确处理方法是:触发PreTranslateMessage消息，截获ENTER和ESC对对话框的消息。<BR>代码如下：<BR>BOOL CXXX::PreTranslateMessage(MSG* pMsg) <BR>{<BR>&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_RETURN://屏蔽回车键<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_ESCAPE://屏蔽ESC键<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return CDialog::PreTranslateMessage(pMsg);<BR>} </P>
<P>OK了，这下好了。突然我在对话框上加了一个编辑框和一个列表框，我想先在编辑框中输入内容，然后按一下回车键，就把编辑框的内容插入到列表框中。</P>
<P>突然一想还真无从下手，再一想还是在PreTranslateMessage里面做，上面的我是直接return TRUE;的。我在这个return TRUE;上面做就行了。</P>
<P>代码如下：<BR>BOOL CXXX::PreTranslateMessage(MSG* pMsg) <BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp; HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);<BR>&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_RETURN:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateData();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pMsg-&gt;hwnd == h1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; m_list.AddString(m_edit1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_ESCAPE:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; return CDialog::PreTranslateMessage(pMsg);<BR>}<BR>要是两个编辑框呢。在编辑框1中回车，把编辑框1的内容加到列表框，在编辑框2中回车，把编辑框2的内容加到列表框，于是这样。</P>
<P>代码如下：<BR>BOOL CXXX::PreTranslateMessage(MSG* pMsg) <BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp; HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);<BR>&nbsp;&nbsp;&nbsp; HWND h2 = ::GetDlgItem(m_hWnd,IDC_EDIT2);<BR>&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_RETURN:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;UpdateData();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (pMsg-&gt;hwnd == h1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;m_list.AddString(m_edit1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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; if (pMsg-&gt;hwnd == h2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;m_list.AddString(m_edit2);<BR>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_ESCAPE:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; return CDialog::PreTranslateMessage(pMsg);<BR>}</P>
<P>为了下面的使用，先来讲讲VC的窗口类和窗口句柄的转换。<BR>窗口类就是CWnd,窗口句柄就是HWND。CWnd和HWND之间互相转换代码如下：<BR>&nbsp;&nbsp;&nbsp; CWnd *pWnd;<BR>&nbsp;&nbsp;&nbsp; HWND&nbsp; hWnd;<BR>&nbsp;&nbsp;&nbsp; hWnd = pWnd-&gt;GetSafeHwnd();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //CWnd-&gt;HWND<BR>&nbsp;&nbsp;&nbsp; pWnd = CWnd::FromHandle(hWnd); //HWND-&gt;CWnd</P>
<P>则这样上面的两个编辑框的代码，改一下第二个编辑框先得到CWnd，转一下然后和HWnd比较。<BR>改了的代码如下：<BR>BOOL CXXX::PreTranslateMessage(MSG* pMsg) <BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp; HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);<BR>&nbsp;&nbsp;&nbsp; CWnd *h2=GetDlgItem(IDC_EDIT2);<BR>&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;case VK_RETURN:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;UpdateData();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;if (pMsg-&gt;hwnd == h1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;m_list.AddString(m_edit1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pMsg-&gt;hwnd == h2-&gt;GetSafeHwnd()) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.AddString(m_edit2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_ESCAPE:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; return CDialog::PreTranslateMessage(pMsg);<BR>}<BR>完成了，功能一模一样。<BR>好开心！<BR>举一反三，下面别的控件你也可以这样做了。如：列表框<BR>等等。</P>
<P>突然一天，我发现这种做法失效了。失效在组合框上了。<BR>原本的希望却变成了失望。痛苦啊。<BR>程序如下：<BR>BOOL CXXX::PreTranslateMessage(MSG* pMsg) <BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp; HWND h3 = ::GetDlgItem(m_hWnd,IDC_COMBO1);<BR>&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_RETURN:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateData();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pMsg-&gt;hwnd == h3) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P>
<P>&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; m_list.AddString(m_combo1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;case VK_ESCAPE:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; return CDialog::PreTranslateMessage(pMsg);<BR>}<BR>于是用SPY++一看，组合框却有两个句柄，一个是ComboBox,还有一个是Edit的句柄。想想也是呀：组合框的可视部分就是由一个Edit组合成的，而pMsg-&gt;hwnd得到的句柄就是这个Edit所指的句柄(因为回车就是在这个Edit里面敲的),而HWND h3 =::GetDlgItem(m_hWnd,IDC_COMBO1);得到的这个句柄却是ComboBox的句柄，pMsg-&gt;hwnd 和 h3这两个当然不等了。<BR>呵呵，找到了原因就好办了。</P>
<P>这下记起来有个这个函数了吧：CWnd* GetParent() const;<BR>其实ComboBox就是Edit的父窗口(组合框和编辑框都可以看成是窗口)。<BR>哦，既然pMsg-&gt;hwnd是Edit的句柄，ComboBox又是Edit的父窗口，那用个GetParent();就得到父窗口的句柄了，就可以和得到的句柄比较了。<BR>大功告成，于是代码就出来了。</P>
<P>代码如下(举了两个组合框)：</P>
<P>BOOL CEntercomboDlg::PreTranslateMessage(MSG* pMsg) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CWnd *h1=GetDlgItem(IDC_COMBO1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;CWnd *h2=GetDlgItem(IDC_COMBO2);<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CWnd* hh = CWnd::FromHandle(pMsg-&gt;hwnd);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CWnd* hhp = NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(pMsg-&gt;message == WM_KEYDOWN)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;switch(pMsg-&gt;wParam)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;case VK_RETURN:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateData();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;hhp = hh-&gt;GetParent();&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if (hhp == h1) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;m_list.AddString(m_combo1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (hhp == h2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_list.AddString(m_combo2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VK_ESCAPE:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TRUE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;return CDialog::PreTranslateMessage(pMsg);<BR>}</P>
<P>哦，不错。</P>
<P>这只是回车键在VC的应用之一。</P>]]></description>
</item>
</channel>
</rss>