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

<channel>
	<title>shyandsy的无边海洋</title>
	<atom:link href="http://www.20days.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.20days.net</link>
	<description>驱动, 内核, 安全, 加密解密, 文件系统, win32, 逆向</description>
	<lastBuildDate>Thu, 17 Jun 2010 03:13:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>不常用的ini操作方法</title>
		<link>http://www.20days.net/?p=65</link>
		<comments>http://www.20days.net/?p=65#comments</comments>
		<pubDate>Thu, 17 Jun 2010 03:13:57 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[vc++]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=65</guid>
		<description><![CDATA[（   1   ）使用得  最  频繁  的是   GetPrivateProfileString   和   WritePrivateProfileString  ，  没有   WriteProfileInt\WritePrivateProfileInt   函数[han shu]。
（   2   ）   Get   系列读取[du qu]节键值，如果文件[wen jian]路径[lu jing]有误或节键名不对则返回设定的默认[mo ren]值。
（   3   ）访存自定义配置[pei zhi]  文件[wen jian]时，文件[wen jian]路径[lu jing] lpFileName 必须完整 , 文件[wen jian]名[wen jian ming]前面的各级目录必须存在。如果 lpFileName 文件[wen jian]路径[lu jing]不存在，则函数[han shu]返回 FALSE ，  GetLastError =   ERROR_PATH_NOT_FOUND  。  如果路径[lu jing]正确，但是文件[wen jian]不存在，  则该函数[han shu]将先创建该文件[wen jian]。如果路径[lu jing]及文件[wen jian]存在，则在现有 ini 文件[wen jian]基础上进行读写[du xie]。
如果   lpFileName   只  指定文件[wen jian]  名而  没有路径[lu jing]的话，  调用[tiao yong] API 将  会去   Windows   的安装[an zhuang]目录去  查找[cha zhao]  而不会在当前目录[dang qian mu lu]  查  找  。
（ 4 ）要对调用[tiao yong] API 的模块[mo kuai] (exe) 所在目录下进行配置[pei zhi]文件[wen jian][pei zhi wen jian]操作，可使用形如“ .\config.ini ”的相对路径[lu jing]。
（ 5 ）调用[tiao yong]  WritePrivateProfileSection  ，若参数[can shu]三     lpString     为   NULL  ，则可将对应 section 的全部内容清空；调用[tiao yong]  WritePrivateProfile  String  ，若参数[can shu]三     lpString     为   NULL  ，则可将对应 key 删除[shan [...]]]></description>
			<content:encoded><![CDATA[<p>（   1   ）使用得  最  频繁  的是   GetPrivateProfileString   和   WritePrivateProfileString  ，  没有   WriteProfileInt\WritePrivateProfileInt   函数[han shu]。</p>
<p>（   2   ）   Get   系列读取[du qu]节键值，如果文件[wen jian]路径[lu jing]有误或节键名不对则返回设定的默认[mo ren]值。</p>
<p>（   3   ）访存自定义配置[pei zhi]  文件[wen jian]时，文件[wen jian]路径[lu jing] lpFileName 必须完整 , 文件[wen jian]名[wen jian ming]前面的各级目录必须存在。如果 lpFileName 文件[wen jian]路径[lu jing]不存在，则函数[han shu]返回 FALSE ，  GetLastError =   ERROR_PATH_NOT_FOUND  。  如果路径[lu jing]正确，但是文件[wen jian]不存在，  则该函数[han shu]将先创建该文件[wen jian]。如果路径[lu jing]及文件[wen jian]存在，则在现有 ini 文件[wen jian]基础上进行读写[du xie]。</p>
<p>如果   lpFileName   只  指定文件[wen jian]  名而  没有路径[lu jing]的话，  调用[tiao yong] API 将  会去   Windows   的安装[an zhuang]目录去  查找[cha zhao]  而不会在当前目录[dang qian mu lu]  查  找  。</p>
<p>（ 4 ）要对调用[tiao yong] API 的模块[mo kuai] (exe) 所在目录下进行配置[pei zhi]文件[wen jian][pei zhi wen jian]操作，可使用形如“ .\config.ini ”的相对路径[lu jing]。</p>
<p>（ 5 ）调用[tiao yong]  WritePrivateProfileSection  ，若参数[can shu]三     lpString     为   NULL  ，则可将对应 section 的全部内容清空；调用[tiao yong]  WritePrivateProfile  String  ，若参数[can shu]三     lpString     为   NULL  ，则可将对应 key 删除[shan chu]。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=65</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UNICODE串转换成char类型串的四种方法</title>
		<link>http://www.20days.net/?p=59</link>
		<comments>http://www.20days.net/?p=59#comments</comments>
		<pubDate>Sun, 13 Jun 2010 10:16:45 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[vc++]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=59</guid>
		<description><![CDATA[1. 调用 WideCharToMultiByte() API

int WideCharToMultiByte (
    UINT    CodePage,                //1 Unicode编码的字符页，Unicode编码有字符页的概念，比如gb2312/936，big5/950等
    DWORD   dwFlags,                //2 如何处理复合unicode字符，详细查google
    LPCWSTR lpWideCharStr,        //3 待转换的unicode串
    int     cchWideChar,                //4 表示参数3的长度  传递-1表示以0x00结尾
    LPSTR   lpMultiByteStr,            //5 接受转换后的串的字符缓冲
    int     cbMultiByte,                    //6 表示参数5lpMutiByteStr的字节大小 通常sizeof一下
    LPCSTR  lpDefaultChar,        //7 NULL 具体google
    LPBOOL  lpUsedDefaultChar//8 NULL 具体google
);
]]></description>
			<content:encoded><![CDATA[<p>1. 调用 WideCharToMultiByte() API</p>
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />int WideCharToMultiByte (<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    UINT    CodePage,                //1 Unicode编码的字符页，Unicode编码有字符页的概念，比如gb2312/936，big5/950等<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    DWORD   dwFlags,                //2 如何处理复合unicode字符，详细查google<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    LPCWSTR lpWideCharStr,        //3 待转换的unicode串<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    int     cchWideChar,                //4 表示参数3的长度  传递-1表示以0&#215;00结尾<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    LPSTR   lpMultiByteStr,            //5 接受转换后的串的字符缓冲<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    int     cbMultiByte,                    //6 表示参数5lpMutiByteStr的字节大小 通常sizeof一下<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    LPCSTR  lpDefaultChar,        //7 NULL 具体google<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    LPBOOL  lpUsedDefaultChar//8 NULL 具体google<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />);<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /></div>
<p>2. 调用CRT函数wcstombs()</p>
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />size_t wcstombs (<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    char*          mbstr,<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    const wchar_t* wcstr,<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />    size_t         count );<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /></div>
<p>3. 使用CString构造器或赋值操作</p>
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />// 假设有一个Unicode串wszSomeString<img src="http://www.cnblogs.com/Images/dot.gif" alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />CString str1 ( wszSomeString ); // 用构造器转换<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />CString str2;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />str2 = wszSomeString; // 用赋值操作转换<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /></div>
<p>4. 使用ATL串转换宏</p>
<div><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />#include &lt;atlconv.h&gt;<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" />// 还是假设有一个Unicode串wszSomeString<img src="http://www.cnblogs.com/Images/dot.gif" alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" alt="" align="top" /><br />
<img id="Codehighlighter1_58_177_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_58_177_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_58_177_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_58_177_Closed_Text').style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top" /><img id="Codehighlighter1_58_177_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_58_177_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_58_177_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_58_177_Open_Text').style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" alt="" align="top" /><img src="http://www.cnblogs.com/Images/dot.gif" alt="" />{<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />    char szANSIString [MAX_PATH];<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />    USES_CONVERSION; // 声明这个宏要使用的局部变量<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="" align="top" />    lstrcpy ( szANSIString, OLE2A(wszSomeString) );<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" align="top" />}</div>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=59</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Stdio 2008出现mfc90d.dll错误</title>
		<link>http://www.20days.net/?p=56</link>
		<comments>http://www.20days.net/?p=56#comments</comments>
		<pubDate>Sun, 13 Jun 2010 10:06:59 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[vc++]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=56</guid>
		<description><![CDATA[VS 2005/VS 2008在生成可执行文件时使用了一种新的技术，该技术生成的可执行文件会伴随生成一个清单文件（manifest file）（.manifest后缀文件）（其本质上是XML文档，你可以用文本编辑器打开看看），并在链接完成后将该清单文件嵌入到exe文件中（默认情况下）。而在FAT32文件系统中，在处理清单文件阶段，当增量链接时不能完成清单文件的更新（默认情况下），于是造成清单文件嵌入失败，从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。 

解决方案很多，列举如下： ]]></description>
			<content:encoded><![CDATA[<div>VS 2005/VS 2008在生成可执行文件时使用了一种新的技术，该技术生成的可执行文件会伴随生成一个清单文件（manifest file）（.manifest后缀文件）（其本质上是XML文档，你可以用文本编辑器打开看看），并在链接完成后将该清单文件嵌入到exe文件中（默认情况下）。而在FAT32文件系统中，在处理清单文件阶段，当增量链接时不能完成清单文件的更新（默认情况下），于是造成清单文件嵌入失败，从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。</p>
<p>解决方案很多，列举如下：</p>
<p>1. 由于这是在链接动态运行库出现的问题，所以你可以选择代码生成的连接方式为 /MTd 而非 /MDd ，不用这些DLL文件从而避免问题的出现。该方法有一个很显然的缺点：适用范围有限，不推荐该方法。</p>
<p>注：/MT /MTD MD /MDD 之间的关系可以参见 VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结；另外如果使用/MT 或者/MTD 那么生成的文件的尺寸基本上是使用/MD 或者/MDD的10倍大小</p>
<p>2. 既然跟FAT32系统有关，那么我们可以选择在NTFS文件系统中开发从而避免该问题，此方法同上，也是采用的回避问题的方式，不提倡。（我个人推荐使用这种方法）</p>
<p>3. 该方法仍与FAT32有关：在项目的“属性｜配置属性｜清单工具｜常规(Project | Game Properties | Configuration Properties | C/C++ | Code Generation | Runtime Library)”中的“使用FAT32解决办法”选择“是”（默认为“否”），重新生成项目即可解决问题。该方法是唯一真正针对问题所在而提出的解决方法，使清单工具可以正确更新。（此方法是官方解决方法，也比较方便，推荐）</p>
<p>4. 既然问题是在更新嵌入的清单文件时发生的，由于FAT32的原因而未能更新嵌入的清单文件，于是我们有如下两种解决方法：</p>
<p>（1）不启用增量链接。在项目的“属性｜配置属性｜链接器｜常规”中的“启用增量链接”选择“否”。此方法阻断了问题产生的源头，其每次生成exe文件时都直接嵌入清单文件，而不是默认的根据时戳而决定是否更新清单文件。</p>
<p>（2）不嵌入清单文件。在项目的“属性｜配置属性｜清单工具｜输入和输出”中的“嵌入清单”选择“否”，从而在生成exe文件时附随生成一个清单文件（默认情况下，其文件名为exe文件的全名加上“.manifest”），避免了嵌入清单文件可能失败的问题。在程序运行时，会用到该清单文件。显然，这种方式使可执行程序产生了更多的外部依赖，不推荐。</p>
<p>另外，还有一个不能称为方法的土办法：每次Build前手动删除*.ilk文件（增量链接文件）（当然可以在项目属性中写入删除命令，使其自动执行），不推荐该土办法。</p>
<p>最后，总结一下：</p>
<p>1. 此问题只在特定条件下才会出现：在FAT32文件系统中编译、默认设置（增量模式、不启用FAT32解决方案、嵌入清单文件）、非第一次生成可执行文件文件（即在增量连接、更新清单文件时）。（注意）</p>
<p>2. 解决方案1和4.1方便实用，推荐使用。</p>
<p>ps：我个人认为解决这个问题的最好方法就是使用vc2005/vc2008的时候，在ntfs文件系统上进行开发（也就是第2种方法）。当前的绝大多数软件在ntfs文件系统都能够正常的运行（即便是dos类的工具也能在ntfs文件系统上良好的运行），为什么还要死抱着fat/fat32文件系统不放呢？</p>
<p>另外要注意一个概念问题，“VC2008下提示找不到MSVCP90D.dll”这是属于开发问题，是由于windows文件系统的bug（fat32的bug），导致vc2005/vc2008开发工具编译出来的程序不能正常的运行。<!-- google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad); // --></div>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=56</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>BSTR、char*和CString转换</title>
		<link>http://www.20days.net/?p=40</link>
		<comments>http://www.20days.net/?p=40#comments</comments>
		<pubDate>Tue, 27 Apr 2010 06:27:16 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[vc++]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=40</guid>
		<description><![CDATA[BSTR、char*和CString转换
(1) char*转换成CString

　　若将char*转换成CString，除了直接赋值外，还可使用CString::Format进行。例如：

view plaincopy to clipboardprint?
char chArray[] = "This is a test";   
char * p = "This is a test";   
char chArray[] = "This is a test";
char * p = "This is a test";  

　　或
]]></description>
			<content:encoded><![CDATA[<pre><span style="font-family: Fixedsys;"><strong><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-weight: normal; line-height: 19px; white-space: normal; font-size: 13px;">
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;"><span style="font-family: Fixedsys;"><strong>BSTR、char*和CString转换
</strong><strong><span style="font-weight: normal;">(1) char*转换成CString
　　若将char*转换成CString，除了直接赋值外，还可使用CString::Format进行。例如：</span></strong></span></pre>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;"><span style="font-family: Fixedsys;"><strong><span style="font-weight: normal;">view plaincopy to clipboardprint?
char chArray[] = "This is a test";
char * p = "This is a test";
char chArray[] = "This is a test";
char * p = "This is a test";  

　　或</span>

</strong><span id="more-40"></span><strong>BSTR、char*和CString转换</strong></span></pre>
<p></span></strong></p>
<p></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;">(1) <span style="color: #0000ff;">char</span>*转换</span><span style="font-family: Fixedsys;">成CString</span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;">
　　若将char*转换成CString，除了直接赋值外，还可使用CString::Format进行。例如：

view plaincopy to clipboardprint?
<span style="color: #0000ff;">char</span> chArray[] = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">char</span> * p = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">char</span> chArray[] = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">char</span> * p = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;  

　　或

view plaincopy to clipboardprint?
<span style="color: #0000ff;">LPSTR</span> p = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">LPSTR</span> p = <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;  

　　或在已定义Unicode应的用程序中

view plaincopy to clipboardprint?
<span style="color: #0000ff;">TCHAR</span> * p = _T(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">TCHAR</span> * p = _T(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">); 

　　或

view plaincopy to clipboardprint?
<span style="color: #0000ff;">LPTSTR</span> p = _T(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
CString theString = chArray;
theString.Format(_T(<span style="color: #800080;">"%s"</span><span style="font-family: Fixedsys;">), chArray);
theString = p;
<span style="color: #0000ff;">LPTSTR</span> p = _T(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
CString theString = chArray;
theString.Format(_T(<span style="color: #800080;">"%s"</span><span style="font-family: Fixedsys;">), chArray);
theString = p; 

(2) CString转换成char*

　　若将CString类转换成char*(<span style="color: #0000ff;">LPSTR</span>)类型，常常使用下列三种方法：

　　方法一，使用强制转换。例如：

 view plaincopy to clipboardprint?
CString theString( <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;"> );
<span style="color: #0000ff;">LPTSTR</span> lpsz =(<span style="color: #0000ff;">LPTSTR</span>)(<span style="color: #0000ff;">LPCTSTR</span>)theString;
CString theString( <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;"> );
<span style="color: #0000ff;">LPTSTR</span> lpsz =(<span style="color: #0000ff;">LPTSTR</span>)(<span style="color: #0000ff;">LPCTSTR</span>)theString;  

　　方法二，使用strcpy。例如：

 view plaincopy to clipboardprint?
CString theString( <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;"> );
<span style="color: #0000ff;">LPTSTR</span> lpsz = <span style="color: #000080;">new</span> <span style="color: #0000ff;">TCHAR</span>[theString.GetLength()+1];
_tcscpy(lpsz, theString);
CString theString( <span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;"> );
<span style="color: #0000ff;">LPTSTR</span> lpsz = <span style="color: #000080;">new</span> <span style="color: #0000ff;">TCHAR</span>[theString.GetLength()+1];
_tcscpy(lpsz, theString); 

　　需要说明的是，strcpy(或可移值Unicode/MBCS的_tcscpy)的第二个参数是 const <span style="color: #0000ff;">wchar_t</span>* (Unicode)或const <span style="color: #0000ff;">char</span>* (ANSI)，</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;">系统编译器将会自动对其进行转换。

　　方法三，使用CString::GetBuffer。例如：

view plaincopy to clipboardprint?
CString s(_T(<span style="color: #800080;">"This is a test "</span><span style="font-family: Fixedsys;">));
<span style="color: #0000ff;">LPTSTR</span> p = s.GetBuffer();
<span style="font-family: 'Comic Sans MS'; color: #008000;">// 在这里添加使用p的代码   </span>
<span style="color: #000080;">if</span>(p != NULL) *p = _T(<span style="color: #800080;">'\0'</span><span style="font-family: Fixedsys;">);
s.ReleaseBuffer();
<span style="font-family: 'Comic Sans MS'; color: #008000;">// 使用完后及时释放，以便能使用其它的CString成员函数   </span>
CString s(_T(<span style="color: #800080;">"This is a test "</span><span style="font-family: Fixedsys;">));
<span style="color: #0000ff;">LPTSTR</span> p = s.GetBuffer();
<span style="font-family: 'Comic Sans MS'; color: #008000;">// 在这里添加使用p的代码</span>
<span style="color: #000080;">if</span>(p != NULL) *p = _T(<span style="color: #800080;">'\0'</span><span style="font-family: Fixedsys;">);
s.ReleaseBuffer();
<span style="font-family: 'Comic Sans MS'; color: #008000;">// 使用完后及时释放，以便能使用其它的CString成员函数 </span>

(3) BSTR转换成char*

　　方法一，使用ConvertBSTRToString。例如：

view plaincopy to clipboardprint?
<span style="color: #000080;">#include</span>
<span style="color: #000080;">#pragma</span> comment(lib, <span style="color: #800080;">"comsupp.lib"</span><span style="font-family: Fixedsys;">)
<span style="color: #0000ff;">int</span> _tmain(<span style="color: #0000ff;">int</span> argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">char</span>* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); <span style="font-family: 'Comic Sans MS'; color: #008000;">// 用完释放   </span>
<span style="color: #000080;">delete</span>[] lpszText2;
<span style="color: #000080;">return</span> 0;
}
<span style="color: #000080;">#include</span>
<span style="color: #000080;">#pragma</span> comment(lib, <span style="color: #800080;">"comsupp.lib"</span><span style="font-family: Fixedsys;">)
<span style="color: #0000ff;">int</span> _tmain(<span style="color: #0000ff;">int</span> argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">char</span>* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); <span style="font-family: 'Comic Sans MS'; color: #008000;">// 用完释放</span>
<span style="color: #000080;">delete</span>[] lpszText2;
<span style="color: #000080;">return</span> 0;
}  

　　方法二，使用_bstr_t的赋值运算符重载。例如：

view plaincopy to clipboardprint?
_bstr_t b = bstrText;
<span style="color: #0000ff;">char</span>* lpszText2 = b;
_bstr_t b = bstrText;
<span style="color: #0000ff;">char</span>* lpszText2 = b;  

(4) <span style="color: #0000ff;">char</span>*转换成BSTR

　　方法一，使用SysAllocString等API函数。例如：

view plaincopy to clipboardprint?
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = ::SysAllocStringLen(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">,4);
BSTR bstrText = ::SysAllocStringByteLen(<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">,4);
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = ::SysAllocStringLen(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">,4);
BSTR bstrText = ::SysAllocStringByteLen(<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">,4);  

　　方法二，使用COleVariant或_variant_t。例如：

view plaincopy to clipboardprint?
<span style="font-family: 'Comic Sans MS'; color: #008000;">//COleVariant strVar("This is a test");   </span>
_variant_t strVar(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = strVar.bstrVal;
<span style="font-family: 'Comic Sans MS'; color: #008000;">//COleVariant strVar("This is a test");</span>
_variant_t strVar(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = strVar.bstrVal; 

　　方法三，使用_bstr_t，这是一种最简单的方法。例如：

view plaincopy to clipboardprint?
BSTR bstrText = _bstr_t(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = _bstr_t(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">); 

　　方法四，使用CComBSTR。例如：

view plaincopy to clipboardprint?
BSTR bstrText = CComBSTR(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = CComBSTR(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">); 

　　或

view plaincopy to clipboardprint?
CComBSTR bstr(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = bstr.m_str;
CComBSTR bstr(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = bstr.m_str; 

　　方法五，使用ConvertStringToBSTR。例如：

view plaincopy to clipboardprint?
<span style="color: #0000ff;">char</span>* lpszText = <span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">;
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
<span style="color: #0000ff;">char</span>* lpszText = <span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">;
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText); 

(5) CString转换成BSTR

　　通常是通过使用CStringT::AllocSysString来实现。例如：

view plaincopy to clipboardprint?
CString str(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = str.AllocSysString();
…
SysFreeString(bstrText); <span style="font-family: 'Comic Sans MS'; color: #008000;">// 用完释放  </span>
CString str(<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">);
BSTR bstrText = str.AllocSysString();
…
SysFreeString(bstrText); <span style="font-family: 'Comic Sans MS'; color: #008000;">// 用完释放</span>

(6) BSTR转换成CString

　　一般可按下列方法进行：

view plaincopy to clipboardprint?
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
CStringA str;
str.Empty();
str = bstrText;
BSTR bstrText = ::SysAllocString(L<span style="color: #800080;">"Test"</span><span style="font-family: Fixedsys;">);
CStringA str;
str.Empty();
str = bstrText; 

　　或

view plaincopy to clipboardprint?
CStringA str(bstrText);
CStringA str(bstrText); 

(7) ANSI、Unicode和宽字符之间的转换

　　方法一，使用MultiByteToWideChar将ANSI字符转换成Unicode字符，使用WideCharToMultiByte将Unicode字符转换成ANSI字符。

　　方法二，使用“_T”将ANSI转换成“一般”类型字符串，使用“L”将ANSI转换成Unicode，而在托管C++环境中还可使用S将ANSI</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;">字符串转换成String*对象。例如：

view plaincopy to clipboardprint?
<span style="color: #0000ff;">TCHAR</span> tstr[] = _T(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">wchar_t</span> wszStr[] = L<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
String* str = S”This is a test”;
<span style="color: #0000ff;">TCHAR</span> tstr[] = _T(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">wchar_t</span> wszStr[] = L<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
String* str = S”This is a test”; 

　　方法三，使用ATL 7.0的转换宏和类。ATL7.0在原有3.0基础上完善和增加了许多字符串转换宏以及提供相应的类，它具有如图3所示的</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;">统一形式：

　　其中，第一个C表示“类”，以便于ATL 3.0宏相区别，第二个C表示常量，2表示“to”，EX表示要开辟一定大小的缓冲。SourceType</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;">和DestinationType可以是A、 T、W和OLE，其含义分别是ANSI、Unicode、“一般”类型和OLE字符串。例如，CA2CT就是将ANSI转换成一般</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<pre><span style="font-family: Fixedsys; color: #000000;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;"><span style="font-family: Fixedsys;">类型的字符串常量。下面是一些示例代码：

view plaincopy to clipboardprint?
<span style="color: #0000ff;">LPTSTR</span> tstr= CA2TEX&lt;16&gt;(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">LPCTSTR</span> tcstr= CA2CT(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">wchar_t</span> wszStr[] = L<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">char</span>* chstr = CW2A(wszStr);
<span style="color: #0000ff;">LPTSTR</span> tstr= CA2TEX&lt;16&gt;(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">LPCTSTR</span> tcstr= CA2CT(<span style="color: #800080;">"this is a test"</span><span style="font-family: Fixedsys;">);
<span style="color: #0000ff;">wchar_t</span> wszStr[] = L<span style="color: #800080;">"This is a test"</span><span style="font-family: Fixedsys;">;
<span style="color: #0000ff;">char</span>* chstr = CW2A(wszStr); 

结语

　　几乎所有的程序都要用到字符串，而Visual C++</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Fixedsys;">由于功能强大、应用广泛，因而字符串之间的转换更为频繁。</span></pre>
<pre><span style="font-family: Fixedsys;">本文几乎涉及到目前的所有转换方法。当然对于.NET框架来说，还可使用 Convert和Text类进行不同数据类型</span></pre>
<pre><span style="font-family: Fixedsys;">以及字符编码之间的相互转换。</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=40</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[转]CGridCtrl帮助中文版</title>
		<link>http://www.20days.net/?p=37</link>
		<comments>http://www.20days.net/?p=37#comments</comments>
		<pubDate>Tue, 27 Apr 2010 06:17:25 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[vc++]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=37</guid>
		<description><![CDATA[GridCtrl学习指南

当我努力为显示和编辑现有表中的数据而使用 CListCtrl 到了极限之后，我意识到我所需要的只不过是一个专用的Grid控件而已。于是我开始着手写自己的Grid控件，但为了节省时间我决定修改Joe Willcoxson's的免费控件 WorldCom，你可以在以下站点 http://users.aol.com/chinajoe/wcmfclib.html 找到这个东东。为了让它能做我要做的事情，我分解了他的代码，并且重新修改。由于代码经过太多的修改，我甚至不能确信最终是否还存在最初的代码。但无论如何，Joe的代码是一个大框架，而我只是在上面进行加工而已。

工程一开始的时候是计划尽可能的简单但是当我不断发现我不得不考虑新特色的时候，它迅速的膨胀成为一个梦魇。虽然测试并不是没有遗漏--但是我还是坚信情形不会变得太坏J。Joe很善意的允许我开放这个资源而不附加任何的语句（毕竟那是基于他的代码），但是由于工程象马拉松似的，所以我在这段代码中使用了两个非常不成熟的条件：]]></description>
			<content:encoded><![CDATA[<p><strong>GridCtrl学习指南</strong></p>
<p>当我努力为显示和编辑现有表中的数据而使用 CListCtrl 到了极限之后，我意识到我所需要的只不过是一个专用的</p>
<p>Grid控件而已。于是我开始着手写自己的Grid控件，但为了节省时间我决定修改Joe Willcoxson&#8217;s的免费控件 WorldCom，</p>
<p>你可以在以下站点 http://users.aol.com/chinajoe/wcmfclib.html 找到这个东东。为了让它能做我要做的事情，我</p>
<p>分解了他的代码，并且重新修改。由于代码经过太多的修改，我甚至不能确信最终是否还存在最初的代码。但无论如何，</p>
<p>Joe的代码是一个大框架，而我只是在上面进行加工而已。</p>
<p>工程一开始的时候是计划尽可能的简单但是当我不断发现我不得不考虑新特色的时候，它迅速的膨胀成为一个梦魇。虽然</p>
<p>测试并不是没有遗漏&#8211;但是我还是坚信情形不会变得太坏J。Joe很善意的允许我开放这个资源而不附加任何的语句（毕竟</p>
<p>那是基于他的代码），但是由于工程象马拉松似的，所以我在这段代码中使用了两个非常不成熟的条件：<span id="more-37"></span></p>
<p><strong>GridCtrl学习指南</strong></p>
<p>当我努力为显示和编辑现有表中的数据而使用 CListCtrl 到了极限之后，我意识到我所需要的只不过是一个专用的Grid</p>
<p>控件而已。于是我开始着手写自己的Grid控件，但为了节省时间我决定修改Joe Willcoxson&#8217;s的免费控件 WorldCom，</p>
<p>你可以在以下站点 http://users.aol.com/chinajoe/wcmfclib.html 找到这个东东。为了让它能做我要做的事情，我</p>
<p>分解了他的代码，并且重新修改。由于代码经过太多的修改，我甚至不能确信最终是否还存在最初的代码。但无论如何，</p>
<p>Joe的代码是一个大框架，而我只是在上面进行加工而已。</p>
<p>工程一开始的时候是计划尽可能的简单但是当我不断发现我不得不考虑新特色的时候，它迅速的膨胀成为一个梦魇。</p>
<p>虽然测试并不是没有遗漏&#8211;但是我还是坚信情形不会变得太坏J。Joe很善意的允许我开放这个资源而不附加任何的语句</p>
<p>（毕竟那是基于他的代码），但是由于工程象马拉松似的，所以我在这段代码中使用了两个非常不成熟的条件：</p>
<p>这段代码可以以任何方式用于已编译的形式中（包括商业用途）。只要代码不适用，即使没有作者同意，作者姓名和所有</p>
<p>版权信息都原封不动，你可以对代码进行任何形式的使用。但是，如果没有作者的同意，这篇文章和附带的源代码都不能</p>
<p>放在任何网站或论坛上。</p>
<p>你就把它当作是没有任何担保的软件，随意使用吧！</p>
<p>我已经尽量除去任何不良的&#8221; 特征&#8221;，对由它引起的任何损害，时间的浪费或者数据丢失等，我不负任何责任。</p>
<p>希望不要问太多关于继续开发下去的到底有多大工作量的问题。如果你真的要用于商业场合，请给我发email让我知道。</p>
<p>如果没有多少人使用的话，开放和维护/升级代码就没有任何意义。</p>
<p><strong><span style="color: #ff0000;">控件的特点：</span></strong></p>
<p>●使用鼠标可以进行单元格的选择，还可以辅助ctrl和shift的组合键进行选</p>
<p>择。也可以取消选择。</p>
<p>● 行和列可以按照大小进行重排，还可以取消对行、列或两者的排序。</p>
<p>● 双击区分点，行或者列可以按照大小自动排序</p>
<p>● 可以对任何列或行固定</p>
<p>● 单元格可以有不同文本和背景颜色的个性化设置</p>
<p>● 单元格可以有字体的个性化设置</p>
<p>● 单元格可以标注&#8221;只读&#8221;或者其他的状态设置及检测</p>
<p>● OLE的拖放动作</p>
<p>● Ctrl-C, Ctrl-X和Ctrl-V执行拷贝、剪切、粘贴操作，Ctrl-A全选</p>
<p>● 当单元格成为焦点，并且在单元格的编辑区域按下字符键，就意味着在</p>
<p>那个单元格进行编辑了</p>
<p>● 支持微软的智能鼠标</p>
<p>● 可以在单元格中加入图片</p>
<p>● 对大型数据可以使用&#8221;虚拟&#8221;模式</p>
<p>● 充分的打印支持，支持文档/浏览环境（包括打印预览）或是基于会话的应用（不支持打印预览）</p>
<p>● 可选的&#8221;列表模式&#8221;，包括对行的全选或单选，还有单击列标题提示进行插入的操作。</p>
<p>● 众多的虚函数可以很容易对控件进行功能扩充</p>
<p>● 支持UNICODE</p>
<p>● 支持WinCE</p>
<p>● 单元格的标题提示太小不能显示数据</p>
<p>● 可以隐藏行和列</p>
<p>● 在VC4.2、5.0、6.0和CE工具箱2.0、3.0下编译通过&lt;/P&gt;&lt;P&gt;示例中示范了grid控件中大部分特征</p>
<p><span style="color: #ff0000;"><strong>文档</strong></span></p>
<p>如果想在你的工程中使用这个Grid控件的话，你还得在你的工程中添加一些文件：</p>
<p>gridctrl.cpp, gridctrl.h Grid控件资源文件和头文件</p>
<p>gridcellbase.cpp, gridcellbase.h 单元格的基础类</p>
<p>gridcell.cpp, gridcell.h 单元格的默认执行文件</p>
<p>CellRange.h CcellID和CcellRange类的定义</p>
<p>MemDC.h Keith Rule&#8217;s的直接存储类</p>
<p>InPlaceEdit.cpp, InPlaceEdit.h 定位编辑窗口的源文件和头文件</p>
<p>GridDropTarget.cpp, GridDropTarget.h Grid容器的drag和drop对象 只有在gridctrl.h中没有定义 GRIDCONTROL_NO_DRAGDROP的时候才有必要使用。</p>
<p>Titletip.cpp, Titletip.h 从Zafir Anjum那里的到的单元格标题提示. 只有在gridctrl.h中没有定义 GRIDCONTROL_NO_TITLETIPS 的时候才有必要使用&lt;/P&gt;&lt;P&gt;结构</p>
<p>这个Grid是基于一种框架（CgridCtrl工程），这种框架组织和控制那些容纳数据、执行某些操作如画图、句柄方法</p>
<p>如按钮的点击事件的单元格的动作。 Grid工程本身的句柄事件如点击是在单元格之前响应，如果它认为有必要的话，</p>
<p>它还会发送某种鼠标信息。它还包含一个拖曳对象(CGridDropTarget)和一个标题提示对象(CTitleTip)，前者处理</p>
<p>拖曳操作，后者在单元格物理空间在最大限度内不足以显示其内容时可以显示出其内容。Grid单元格可以是任何类型，</p>
<p>其长度与源自CgridBaseCell的类的长度一样。包含这个包的是一个CgridCell类，它能处理基本的数据存储和编辑操作。</p>
<p>扩充的两个类CgridCellCombo和CGridURLCell示范了如何创建自己的单元格类。</p>
<p>单元格有两种主要状态即固定和非固定。固定的单元格通常在Grid的左上方，并且不会随着Grid的卷动而移动。通常这些</p>
<p>单元格包含列和行的标题部分，并且不能进行编辑。而非固定的单元格构成了Grid的内部，你可以对它进行编辑和选择。</p>
<p>Grid的各种不同属性的默认值存放在CgridDefaultCell中。每个Grid中通常有四种属性&#8211;每个Grid中含有非固定、列固定、</p>
<p>行固定以及行列同时固定的单元格的默认值。因此，为了实现设置Grid的默认属性，首先得使用CGridCtrL::GetDefaultCell</p>
<p>来取得单元格的默认实现，然后你就可以直接设置了</p>
<p>单元格的属性除字体属性外都很明确。每一个单元格都有一个指向字体结构体的指针，这个指针只有当你的自行设置单元格</p>
<p>的字体属性时才会被分配和使用。</p>
<p>Grid还有一种虚拟模式阻止Grid创建实际的格子，每当它需要单元格的信息时，允许你的指定一种回收函数或者消息机制来</p>
<p>获得。这样当工作轻微减少时可以节省大量的内存费用。发送给Grid父类的消息GVN_ODCACHEHINT可以帮助你的在Grid</p>
<p>的单元格发送信息请求时预先进行数据缓冲。</p>
<p>Grid的数据是以行为单位进行存储的，所以，对于大量单元格而言，所有的操作都必须以行为单位进行的。</p>
<p><strong><span style="color: #ff0000;">解说</span></strong></p>
<p>好了&#8211;那么，现在如何使用它呢？</p>
<p>Grid的基本类是源于CWnd的CgridCtrl。为了使用它，你可以使用微软的VC++的对话框编辑器，把一个普通的控件放在</p>
<p>对话框上，并且输入&#8221;MFCGridCtrl&#8221;（不包括引号）作为类名。Grid的子类使用DDX机制（可以通过ClassWizard来进行</p>
<p>默认设置），使用DDX_GridControl函数代替DDX_Control（可以通过手动设置ClassWizard的输入来实现）。这些保证</p>
<p>你的控件作为一个注册对象而不会产生一些莫名其妙的WIN95问题。</p>
<p>你也可以选择使用CGridCtrl::Create</p>
<p>CGridCtrl grid;</p>
<p>grid.Create(rect, pParentWnd, nID);</p>
<p>其中的rect是大小，pParentWnd是父窗口，nID是标志符。&lt;/P&gt;&lt;P&gt;列和行的数目</p>
<p>int GetRowCount() const 返回行（包括固定行）的数目</p>
<p>int GetColumnCount() const 返回列（包括固定列）的数目</p>
<p>int GetFixedRowCount() const 返回固定行的数目</p>
<p>int GetFixedColumnCount() const 返回固定行的数目</p>
<p>BOOL SetRowCount(int nRows) 设置行的数目（包括固定行），如果成功，返回TRUE</p>
<p>BOOL SetColumnCount(int nCols) 设置列的数目（包括固定列），如果成功，返回TRUE</p>
<p>BOOL SetFixedRowCount(int nFixedRows = 1) 设置固定行的数目，如果成功，返回TRUE</p>
<p>BOOL SetFixedColumnCount(int nFixedCols = 1) 设置固定列的数目，如果成功，返回TRUE&lt;/P&gt;&lt;P&gt;大小和位置函数</p>
<p>int GetRowHeight(int nRow) const 获取由nRow指定行的高度</p>
<p>BOOL SetRowHeight(int row, int height) 设定由row指定行的高度为height</p>
<p>int GetColumnWidth(int nCol) const 获取由nCol指定列的宽度</p>
<p>BOOL SetColumnWidth(int col, int width) 设定由col指定列的宽度为width</p>
<p>int GetFixedRowHeight() const 获取固定行的高度</p>
<p>int GetFixedColumnWidth() const 获取固定列的高度</p>
<p>long GetVirtualHeight() const 获取所有行的合并高度</p>
<p>long GetVirtualWidth() const 获取所有列的合并宽度</p>
<p>BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p) 取出单元格（nRow，nCol）的左上角点，成功返回TRUE</p>
<p>（单元格必须是可见的）</p>
<p>BOOL GetCellOrigin(const CCellID&amp; cell, LPPOINT p) 获取给定单元格的左上角点，成功则返回TRUE，也可以</p>
<p>参照 CCellID.</p>
<p>BOOL GetCellRect(int nRow, int nCol, LPRECT pRect) 获取给定单元格的边框，成功则返回TRUE（单元格必须</p>
<p>是可见的）</p>
<p>BOOL GetCellRect(const CCellID&amp; cell, LPRECT pRect) 获取给定单元格的边框成功则返回TRUE（单元格必须是</p>
<p>可见的） 也可以 参照CCellID.</p>
<p>BOOL GetTextRect(int nRow, int nCol, LPRECT pRect)t 获取给定单元格中的文本框，成功则返回TRUE（单元格</p>
<p>必须是可见的）</p>
<p>BOOL GetTextRect(const CCellID&amp; cell, LPRECT pRect) 获取给定单元格中的文本框，成功则返回TRUE（单元格</p>
<p>必须是可见的）也可以参照 CCellID.</p>
<p>BOOL GetTextExtent(int nRow, int nCol, LPCTSTR str) 获取给定单元格中的指定的文本内容的边框，成功则</p>
<p>返回TRUE</p>
<p>BOOL GetCellTextExtent(int nRow, int nCol) 获取给定单元格中的文本框，成功则返回TRUE</p>
<p>虚拟模式</p>
<p>虚拟模式允许Grid在不存储数据的情况下，能够显示大量数据。在虚拟模式下，不用产生单元格，也不用存储数据，</p>
<p>列宽和行高除外。</p>
<p>由于Grid本身并不存储数据，所以它必须有一些方法让其它程序帮助它存储这些数据。这些是通过Grid本身的回收</p>
<p>函数或者其父类的一个句柄GVN_GETDISPINFO的申明来实现的。</p>
<p>void SetVirtualMode(BOOL bVirtual) 设置Grid是否使用虚拟模式</p>
<p>BOOL GetVirtualMode() 当使用虚拟模式时返回TRUE</p>
<p>void SetCallbackFunc(GRIDCALLBACK pCallback, LPARAM lParam) 当Grid为虚拟模式时，设置回调函数</p>
<p>GRIDCALLBACK GetCallbackFunc() 当Grid为虚拟模式时，返回回调函数</p>
<p>如果没有指定回调函数，Grid就会向其父窗口发送一个GVN_GETDISPINFO信息，这个申明部分如同GV_DISPINFO结构，GV_DISPINFO机构体就象下面所示：</p>
<p>typedef struct tagGV_DISPINFO {</p>
<p>NMHDR hdr;</p>
<p>GV_ITEM item;</p>
<p>} GV_DISPINFO;</p>
<p>显而易见的是，它有一个很好的暗示就是允许Grid所需要的数据进入高速缓存。因此，在显示某一页单元格</p>
<p>内容之前，Grid首先会发送一个GVN_ODCACHEHINT信息，结构体GV_CACHEHINT会作为消息的一部分，</p>
<p>其结构如下：</p>
<p>typedef struct tagGV_CACHEHINT {</p>
<p>NMHDR hdr;</p>
<p>CCellRange range;</p>
<p>} GV_CACHEHINT;</p>
<p>下面有一个处理这个消息的例子：</p>
<p>//处理这个消息的是对话框的一个成员变量m_Gri</p>
<p>BOOL CGridCtrlDemoDlg::OnNotify(WPARAM wParam, LPARAM lParam,</p>
<p>LRESULT* pResult)</p>
<p>{</p>
<p>if (wParam == (WPARAM)m_Grid.GetDlgCtrlID())</p>
<p>{</p>
<p>*pResult = 1;</p>
<p>GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;</p>
<p>if (GVN_GETDISPINFO == pDispInfo-&gt;hdr.code)</p>
<p>{</p>
<p>//TRACE2(&#8220;Getting Display info for cell %d,%d\n&#8221;,</p>
<p>pDispInfo-&gt;item.row, pDispInfo-&gt;item.col);</p>
<p>pDispInfo-&gt;item.strText.Format(_T(&#8220;Message %d,%d&#8221;),</p>
<p>pDispInfo-&gt;item.row, pDispInfo-&gt;item.col);</p>
<p>return TRUE;</p>
<p>}</p>
<p>else if (GVN_ODCACHEHINT == pDispInfo-&gt;hdr.code)</p>
<p>{</p>
<p>GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;</p>
<p>TRACE(_T(&#8220;Cache hint received for cell range %d,%d &#8211; %d,%d\n&#8221;),</p>
<p>pCacheHint-&gt;range.GetMinRow(),</p>
<p>pCacheHint-&gt;range.GetMinCol(),</p>
<p>pCacheHint-&gt;range.GetMaxRow(),</p>
<p>pCacheHint-&gt;range.GetMaxCol());</p>
<p>}</p>
<p>}</p>
<p>return CDialog::OnNotify(wParam, lParam, pResult);</p>
<p>}</p>
<p>也可以使用SetCallbackFunc来设置回收函数代替发送GVN_GETDISPINFO消息，而且，Grid可以直接调用</p>
<p>这个回收函数，当然了，即使调用了回收函数，GVN_ODCACHEHINT消息还会照常发送。</p>
<p>回收函数应当是如下形式：</p>
<p>BOOL CALLBACK CallbackFunction(GV_DISPINFO * pDispInfo, LPARAM lParam);</p>
<p>例如：</p>
<p>BOOL CALLBACK CGridCtrlDemoDlg::GridCallback(GV_DISPINFO *pDispInfo,</p>
<p>LPARAM /*lParam*/)</p>
<p>{</p>
<p>pDispInfo-&gt;item.strText.Format(_T(&#8220;Callback %d,%d&#8221;),</p>
<p>pDispInfo-&gt;item.row, pDispInfo-&gt;item.col);</p>
<p>return TRUE;</p>
<p>}</p>
<p>当调用SetCallbackFunc的时候，你可以定义一个LPARAM，这样当每次调用回收函数时可以将这个值传递给</p>
<p>这个回收函数。注意这个回收函数必须是一个静态或全局函数。&lt;/P&gt;&lt;P&gt;总体的外观和特征</p>
<p>void SetImageList(CImageList* pList) 设置Grid的当前图形列表，它拷贝的只是列表的指针而非列表本身。</p>
<p>CImageList* GetImageList() 取出Grid当前图形列表</p>
<p>void SetGridLines(int nWhichLines = GVL_BOTH) 设置哪些（如果有的话）线条不可见，从 here 可以找到</p>
<p>一些可能的取值。</p>
<p>int GetGridLines() 取出那些（如果有的话）不可见线条，从 here 可以找到一些可能的返回值。</p>
<p>void SetEditable(BOOL bEditable = TRUE) 设置Grid是否可以编辑。</p>
<p>BOOL IsEditable() 判断Grid是否可编辑。.</p>
<p>void SetListMode(BOOL bEnableListMode = TRUE) 将Grid设置成（或不是）排序模式，当Grid处于排序模式</p>
<p>时，将启动所有行选，并且这时如果点击列表头时，将会对Grid按行进行排序。</p>
<p>BOOL GetListMode() 判断Grid是否处于排序模式。</p>
<p>void SetSingleRowSelection(BOOL bSing = TRUE) 将G rid设置成（或不是）单行选择模式，这种模式只有在</p>
<p>排序模式下有效。 当处在这种模式下，每次只能选择一行，所以整个Grid表现看起来就好象是一个多列的列表框。</p>
<p>BOOL GetSingleRowSelection() 判断Grid是否处于单行选择模式。</p>
<p>void SetSingleColSelection(BOOL bSing = TRUE) 将Grid设置成（或不是）单列选择模式，在这种模式下，</p>
<p>每次只能选择一列。</p>
<p>BOOL GetSingleColSelection() 判断Grid是否处于单列选择模式。</p>
<p>void EnableSelection(BOOL bEnable = TRUE) 设置Grid的单元格是否可选。</p>
<p>BOOL IsSelectable() 判断Grid的单元格是否可选。</p>
<p>void SetFixedRowSelection(BOOL bSelect) 设置当点击固定行时，是否选择其旁边的单元格。</p>
<p>BOOL GetFixedRowSelection() 判断当点击固定行时，是否选择其旁边的单元格。</p>
<p>void SetFixedColumnSelection(BOOL bSelect) 设置当点击固定列时，是否选择其下面的单元格</p>
<p>BOOL GetFixedColumnSelection() 判断当点击固定列时，是否选择其下面的单元格</p>
<p>void EnableDragAndDrop(BOOL bAllow = TRUE) 设置是否开启拖曳动作。</p>
<p>BOOL GetDragAndDrop() 判断拖曳动作是否开启。</p>
<p>void SetRowResize(BOOL bResize = TRUE) 设置是否可设置行的大小。</p>
<p>BOOL GetRowResize() 判断是否可设置行的大小。</p>
<p>void SetColumnResize(BOOL bResize = TRUE) 设置是否可设置列的大小。</p>
<p>BOOL GetColumnResize() 判断是否可设置列的大小。</p>
<p>void SetHandleTabKey(BOOL bHandleTab = TRUE) 设置是否启用TAB键来移动选择单元格</p>
<p>BOOL GetHandleTabKey() 判断是否启用TAB键来移动选择单元格。</p>
<p>void SetDoubleBuffering(BOOL bBuffer = TRUE) 设置画图时是否使两级缓冲（不支持闪烁）。</p>
<p>BOOL GetDoubleBuffering() 判断画图时是否使用了两级缓冲。</p>
<p>void EnableTitleTips(BOOL bEnable = TRUE) 设置是否使用标题提示</p>
<p>BOOL GetTitleTips() 判断是否使用标题提示</p>
<p>void SetTrackFocusCell(BOOL bTrack) 设置同行/列中的固定单元格作为焦点单元格时是否高亮显示并且</p>
<p>使用凹陷边缘。</p>
<p>BOOL GetTrackFocusCell() 判断同行/列中的固定单元格作为焦点单元格时是否高亮显示并且使用凹陷边缘。</p>
<p>void SetFrameFocusCell(BOOL bFrame) 设置焦点单元格是否高亮显示并且加上外边框。</p>
<p>BOOL GetFrameFocusCell() 判断是否对焦点单元格高亮显示并且加上外边框。</p>
<p>void SetAutoSizeStyle(int nStyle = GVS_BOTH) 设置单元格如何自动调整大小GVS_BOTH = 固定和</p>
<p>非固定单元格都可以自动调整; GVS_HEADER = 仅固定单元格可以; GVS_DATA = 仅非固定单元格可以</p>
<p>int GetAutoSizeStyle() 获取自动排序的执行模式。</p>
<p>void EnableHiddenColUnhide(BOOL bEnable = TRUE) 设置当用户调整列的宽度时隐藏列（宽度为0）是否显现出来。</p>
<p>BOOL GetHiddenColUnhide() 判断当用户调整列的宽度时隐藏列（宽度为0）是否显现出来。</p>
<p>void EnableHiddenRowUnhide(BOOL bEnable = TRUE) 设置当用户调整行的高度时隐藏行（高度为0）是否显现出来。</p>
<p>BOOL GetHiddenRowUnhide() 判断当用户调整行的高度时隐藏行（高度为0）是否显现出来。</p>
<p>void EnableColumnHide(BOOL bEnable = TRUE) 设置是否可以通过鼠标将列的宽度压缩为0。</p>
<p>BOOL GetColumnHide() 判断是否可以通过鼠标将列的宽度压缩为0。</p>
<p>void EnableRowHide(BOOL bEnable = TRUE) 设置是否可以通过鼠标将行的高度压缩为0。</p>
<p>BOOL GetRowHide() 判断是否可以通过鼠标将行的高度压缩为0。&lt;/P&gt;&lt;P&gt;颜色</p>
<p>void SetGridBkColor(COLORREF clr) 设置控件的背景颜色（固定和非固定单元格之外的区域）。</p>
<p>COLORREF GetGridBkColor() 获取控件的背景颜色。</p>
<p>void SetGridLineColor(COLORREF clr) 设置网格线的颜色。</p>
<p>COLORREF GetGridLineColor() 获取网格线的颜色。</p>
<p>COLORREF GetTitleTipBackClr() 获取标题提示的背景颜色。</p>
<p>void SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) 设置标题提示的背景颜色。</p>
<p>COLORREF GetTitleTipTextClr() 获取标题提示的文本颜色。</p>
<p>void SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) 设置标题提示的文本颜色。</p>
<p>不再支持如下的函数了。你应当使用GetDefaultCell来获取默认单元格实现你所感兴趣的单元格类型，然后就可以</p>
<p>直接设置单元格的属性了。如果给定单元格是默认设置值，那么为匹配你的单元格类型，就得在默认的单元格实现中</p>
<p>使用这些值。</p>
<p>void SetTextColor(COLORREF clr) 设置非固定单元格中的文本颜色。</p>
<p>COLORREF GetTextColor() 获取非固定单元格中的文本颜色。</p>
<p>void SetTextBkColor(COLORREF clr) 设置非固定单元格的背景颜色。</p>
<p>COLORREF GetTextBkColor() 获取非固定单元格的背景颜色。</p>
<p>void SetFixedTextColor(COLORREF clr) 设置固定单元格的文本颜色。</p>
<p>COLORREF GetFixedTextColor() 获取固定单元格的文本颜色。</p>
<p>void SetFixedBkColor(COLORREF clr) 设置固定单元格的背景颜色。</p>
<p>COLORREF GetFixedBkColor() 获取固定单元格的背景颜色。</p>
<p>void SetBkColor(COLORREF clr) 设置控件的背景颜色 (单元格之外的区域).</p>
<p>COLORREF GetBkColor() 获取控件的背景颜色。</p>
<p>void SetGridColor(COLORREF clr) 设置网格线的颜色。.</p>
<p>COLORREF GetGridColor() 获取网格线的颜色。.</p>
<p>也可以参照Individual Cell colour functions，它允许改变Grid中某一个单元格的颜色以不同于其它单元格。</p>
<p>普通的单元格信息</p>
<p>CGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const 为要创建的单元格类型获取一个</p>
<p>默认的单元格实现的指针. bFixedRow 和 bFixedCol 用来申明单元格是否固定(行、列、或者两者) 或非固定. 使用</p>
<p>它来定义Grid的默认属性. 事实上Grid中的单元格在它们创建的时候就有了自己的默认属性. 它们使用 GetDefaultCell</p>
<p>查询Grid的默认单元格属性，并且用这些值来勾画自己。.</p>
<p>CGridCellBase* GetCell(int nRow, int nCol) const 根据行/列来获取相应的单元格 (或者不存在的时候返回NULL)</p>
<p>BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass); 定义响应单元格类的类型。</p>
<p>BOOL SetDefaultCellType(CRuntimeClass* pRuntimeClass); 为新的单元格设置默认属性。</p>
<p>void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1) 为单元格设置一个标志符. 如果没有指明</p>
<p>某行或某列，将对整个Grid进行设置。</p>
<p>BOOL GetModified(int nRow = -1, int nCol = -1) 为单元格设置一个标志符，如果没有相应的单元格，就返回整个Grid的</p>
<p>状态。</p>
<p>BOOL IsCellFixed(int nRow, int nCol) 如果单元格固定就返回TRUE.</p>
<p>BOOL IsItemEditing(int nRow, int nCol) 如果单元格正处在编辑状态就返回TRUE.</p>
<p>BOOL SetItem(const GV_ITEM* pItem) 用 GV_ITEM 结构体中的值来设置单元格的内容. 注意掩码字段中的值</p>
<p>决定到底哪些值是真正改变了(比较 CListCtrl::SetItem).</p>
<p>BOOL GetItem(GV_ITEM* pItem) 从指定的单元格获取其内容来填充 GV_ITEM 结构体. 注意掩码字段中的只将</p>
<p>决定哪些值真正取回了 (比较CListCtrl::GetItem).</p>
<p>BOOL SetItemText(int nRow, int nCol, LPCTSTR str) 设置指定单元格的文本内容.成功则返回TRUE。</p>
<p>virtual CString GetItemText(int nRow, int nCol) 取出指定单元格的文本内容，为有利于扩展，这个函数设置成</p>
<p>虚拟函数. 不要和LVN_GETDISPINFO消息或字符串共享弄混了。</p>
<p>BOOL SetItemData(int nRow, int nCol, LPARAM lParam) 为指定单元格设置Iparam字段（用户自定义的数据）。</p>
<p>成功则返回TRUE，也可参考GV_ITEM.</p>
<p>LPARAM GetItemData(int nRow, int nCol) const 获取指定单元格的Iparam字段（用户自定义的数据）。成功</p>
<p>则返回TRUE，也可参考GV_ITEM.</p>
<p>BOOL SetItemImage(int nRow, int nCol, int iImage) 设置指定单元格的图形索引，成功则返回TRUE，也可</p>
<p>参考 GV_ITEM.</p>
<p>int GetItemImage(int nRow, int nCol) const 获取指定单元格的图形索引。</p>
<p>BOOL SetItemState(int nRow, int nCol, UINT state) 设置给定单元格的状态.成功则返回TRUE，也可参考GV_ITEM.</p>
<p>UINT GetItemState(int nRow, int nCol) const 获取指定单元格的状态，也可参考 GV_ITEM.</p>
<p>BOOL SetItemFormat(int nRow, int nCol, UINT nFormat) 设置指定单元格的格式，成功则返回TRUE。 单元格的</p>
<p>默认实现是使用 CDC::DrawText, 所以，任何的DT_*格式都可以使用. 也可参考 GV_ITEM.</p>
<p>UINT GetItemFormat(int nRow, int nCol) const 获取给定单元格的格式(默认返回CDC::DrawText DT_*格式). 也可参考 GV_ITEM.</p>
<p>int GetSelectedCount() 获取被选单元格的数量。.</p>
<p>CCellID GetFocusCell() 获取焦点单元格，可参考 CCellID.</p>
<p>CCellID SetFocusCell(CCellID cell);CCellID SetFocusCell(int nRow, int nCol); 设置焦点单元格。</p>
<p>BOOL SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT) 设置指定单元格的背景颜色，成功则返回TRUE，可参考 GV_ITEM.</p>
<p>COLORREF GetItemBkColour(int nRow, int nCol) const 获取指定单元格的背景颜色，可参考 GV_ITEM.</p>
<p>BOOL SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT) 设置指定单元格的前景颜色，成功则返回TRUE，可参考 GV_ITEM.</p>
<p>COLORREF GetItemFgColour(int nRow, int nCol) const 获取指定单元格的前景颜色，可参考 GV_ITEM.</p>
<p>BOOL SetItemFont(int nRow, int nCol, LOGFONT* lf) 设置指定单元格的字体，成功则返回TRUE，可参考GV_ITEM.</p>
<p>LOGFONT* GetItemFont(int nRow, int nCol) const 获取指定单元格的字体，可参考 GV_ITEM.</p>
<p>BOOL IsItemEditing(int nRow, int nCol) 如果单元格处于编辑状态，则返回TRUE.</p>
<p>void EnsureVisible(CCellID &amp;cell) 确保指定单元格可见。.</p>
<p>BOOL IsCellVisible(CCellID &amp;cell) constBOOL IsCellVisible(CCellID cell) const 如果单元格可见则返回TRUE.</p>
<p>BOOL IsCellEditable(CCellID &amp;cell) constBOOL IsCellEditable(CCellID cell) const 如果单元格可编辑则返回TRUE.</p>
<p>BOOL IsCellSelected(CCellID &amp;cell) constBOOL IsCellSelected(CCellID cell) const 如果单元格已选，则返回TRUE。</p>
<p>void EnsureVisible(int nRow, int nCol) 确保指定单元格可见.</p>
<p>BOOL IsCellFixed(int nRow, int nCol) 如果单元格是固定的，则返回TRUE。</p>
<p>int GetDefCellHeight() const 返回单元格的默认高度 (对于新创建的单元格)</p>
<p>void SetDefCellHeight(int nHeight) 设置默认单元格高度(对于新创建的单元格). 如果调用了SetFont就将被忽略</p>
<p>int GetDefCellWidth() const 返回单元格的默认宽度 (对于新创建的单元格)</p>
<p>void SetDefCellWidth(int nWidth) 设置默认单元格宽度(对于新创建的单元格). 如果调用了SetFont就将被忽略</p>
<p>int GetDefCellMargin() const Returns the default cell internal margin</p>
<p>void SetDefCellMargin(int nMargin) Sets the default cell internal margin.&lt;/P&gt;&lt;P&gt;操作</p>
<p>int InsertColumn(LPCTSTR strHeading, UINT nFormat, int nColumn = -1) 在nCol指定的地方插入一列,如果</p>
<p>nCol&lt;0则在末尾插入一列. StrHeading就是列标题头nFormat 是列的格式.返回插入列的位置.</p>
<p>int InsertRow(LPCTSTR strHeading, int nRow = -1) 在nRow处插入一行,如果nRow&lt;0则在末尾插入一行.</p>
<p>strHeading 是行标题头. 此行的单元格的格式与其同列的第一行单元格格式相同. 返回插入行的位置.</p>
<p>BOOL DeleteColumn(int nColumn) 删除&#8221;nColumn&#8221;指定的列,成功则返回TRUE.</p>
<p>BOOL DeleteRow(int nRow) 删除&#8221;nRow&#8221;指定的行, 成功则返回TRUE.</p>
<p>BOOL DeleteAllItems() 删除Grid中的所有行和内容.</p>
<p>BOOL DeleteNonFixedRows() 删除所有非固定行。</p>
<p>BOOL AutoSizeRow(int nRow, BOOL bResetScroll=TRUE) 自动调整行的大小与最大行一样. 如果bResetScroll</p>
<p>是 TRUE那么滚动条也会被重置。</p>
<p>BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL bResetScroll = TRUE) 自动</p>
<p>调整列的大小与最大列一样. NAutoSizeStyle设置了调整的方式(参考 AutoSizing options). 如果bResetScroll是TRUE</p>
<p>那么滚动条将会被重置.</p>
<p>void AutoSizeRows() 自动调整所有行的大小。</p>
<p>void AutoSizeColumns(UINT nAutoSizeStyle=GVS_DEFAULT) 自动调整所有列的大小. nAutoSizeStyle 设置了调整</p>
<p>的方式(参考AutoSizing options)</p>
<p>void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT) 自动调整所有行和列的大小. nAutoSizeStyle设置了调整的</p>
<p>方式(参考 AutoSizing options)</p>
<p>void ExpandColumnsToFit(BOOL bExpandFixed=TRUE) 为添满Grid区域，扩大列宽.如果 bExpandFixed是TRUE</p>
<p>固定列也会调整, 否则不受影响.</p>
<p>void ExpandLastColumn() 调整最后一列的宽度以添满grid区域.</p>
<p>void ExpandRowsToFit(BOOL bExpandFixed=TRUE) 为添满Grid区域，扩大行高. 如果 bExpandFixed是TRUE固</p>
<p>定行也会调整, 否则不受影响.</p>
<p>void ExpandToFit(BOOL bExpandFixed = TRUE) 为添满Grid区域，扩大行高和列宽. 如果 bExpandFixed是TRUE</p>
<p>固定单元格也会调整, 否则不受影响.</p>
<p>CSize GetTextExtent(int nRow, int nCol, LPCTSTR str) 获取指定单元格中由str指定的文本大小。</p>
<p>CSize GetCellTextExtent(int nRow, int nCol) 获取指定单元格的文本大小。</p>
<p>void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE) 在行或列数量改变或者自动调整大小</p>
<p>的时候关闭/启动重画功能,但对用户的动作如重新调整大小不起作用。</p>
<p>BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL) 重画指定单元格。如果提供了pDC则通过它来描画。</p>
<p>BOOL RedrawCell(const CCellID&amp; cell, CDC* pDC = NULL) 重画指定单元格。如果提供了pDC则通过它来描画。</p>
<p>BOOL RedrawRow(int row) 重画指定行.</p>
<p>BOOL RedrawColumn(int col) 重画指定列</p>
<p>BOOL Refresh() 重画整个Grid.</p>
<p>CCellRange GetCellRange() 获取整个Grid中的单元格的范围. 可参考 CCellRange.</p>
<p>void SetSelectedRange(const CCellRange&amp; Range, BOOL bForceRepaint = FALSE); 设置选定单元格的范围. 可参考 CCellRange.</p>
<p>void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol, BOOL bForceRepaint = FALSE);</p>
<p>设置选定单元格的范围.</p>
<p>BOOL IsValid(int nRow, int nCol) 如果指定行和列有效，则返回TRUE.</p>
<p>BOOL IsValid(const CCellID&amp; cell) 如果指定单元格有效，则返回TRUE.</p>
<p>BOOL IsValid(const CCellRange&amp; range) 如果指定单元格范围有效，则返回TRUE.</p>
<p>CCellID GetNextItem(CCellID&amp; cell, int nFlags) const 查找具有特定属性并且和指定内容有特定关系的单元格.</p>
<p>(也可参考 CListCtrl::GetNextItem 和Cell Searching options)</p>
<p>排序操作</p>
<p>void SetHeaderSort(BOOL bSortOnClick = TRUE) 设置在ListMode下，点击列标题头时，是否对行进行排序.</p>
<p>BOOL GetHeaderSort() 判断在ListMode下，点击列标题头时，是否对行进行排序.</p>
<p>SetSortColumn(int nCol 设置当前已排序列的索引。</p>
<p>int GetSortColumn() 获取当前已排序列的索引。</p>
<p>void SetSortAscending(BOOL bAscending) 设置当前排序列是否按升序排序。</p>
<p>BOOL GetSortAscending() 判断当前排序列是否按升序排序。</p>
<p>BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0) 根据单元格文本内容对指定列排序.</p>
<p>成功则返回TRUE.</p>
<p>BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0) 使用比较函数在指定列进行排序.如果没有指定函数，</p>
<p>则对行按文本进行排序.成功则返回TRUE.可参考SetCompareFunction()</p>
<p>void SetCompareFunction(PFNLVCOMPARE pfnCompare) 设置对进行排序的回调函数. 可从下面的到更多的细节。</p>
<p>BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data = 0) 使用比较函数pfnCompare在指定的列进行排序.从函数CListCtrl::SortItems中可以寻求一些关于这个函数的形式的信息成功则返回TRUE.</p>
<p>排序是通过使用变量SortItems, SortTextItems中的一个或者在listmode下点击列标题头来实现。</p>
<p>注意：在虚拟模式下不能进行排序。这是因为在虚拟模式下，Grid不能存储单元格中的任何信息，因此，也就不能</p>
<p>存储任何对单元格进行排序的信息。</p>
<p>处理排序的最简单方法是先设置单元格的比较函数（调用SetCompareFunction），接着调用SortItems(int nCol, BOOL bAscending, LPARAM data = 0)。nCol是要排序的列，bAscending设置是按升序还是按降序排序，data是应用中将要</p>
<p>传递给比较函数的的一个特殊数据。</p>
<p>比较函数必须是一个全局或静态函数，其格式如下：</p>
<p>int CALLBACK pfnCellCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)</p>
<p>lParam1和 lParam2是CGridCellBase的指针，而lParamSort就是应用中作为参数变量传递给函数SortItems的</p>
<p>特殊数据。如果第一个单元格的值小于第二个单元格的值，函数返回-1，相等返回0，否则返回1。</p>
<p>下面就是一个排序比较函数的例子：</p>
<p>int CALLBACK MyClass::pfnCellNumericCompare(LPARAM lParam1,</p>
<p>LPARAM lParam2,</p>
<p>LPARAM lParamSort)</p>
<p>{</p>
<p>CGridCellBase* pCell1 = (CGridCellBase*) lParam1;</p>
<p>CGridCellBase* pCell2 = (CGridCellBase*) lParam2;</p>
<p>if (!pCell1 || !pCell2) return 0;&lt;/P&gt;&lt;P&gt;int nValue1 = _ttol(pCell1-&gt;GetText());</p>
<p>int nValue2 = _ttol(pCell2-&gt;GetText());</p>
<p>if (nValue1 &lt; nValue2)</p>
<p>return -1;</p>
<p>else if (nValue1 == nValue2)</p>
<p>return 0;</p>
<p>else</p>
<p>return 1;</p>
<p>}</p>
<p>还提供了两个有用的函数：</p>
<p>int CALLBACK CGridCtrl::pfnCellTextCompare(LPARAM lParam1,</p>
<p>LPARAM lParam2,</p>
<p>LPARAM lParamSort)</p>
<p>int CALLBACK CGridCtrl::pfnCellNumericCompare(LPARAM lParam1,</p>
<p>LPARAM lParam2,</p>
<p>LPARAM lParamSort)</p>
<p>这两个函数是通过文本内容和数值进行排序的（分别使用itoa）。为Grid设置比较函数，仅仅需要调用：</p>
<p>m_Grid.SetCompareFunction(CGridCtrl::pfnCellNumericCompare);</p>
<p>如果这个比较函数设置为空，那么将默认调用函数CGridCtrl::pfnCellTextCompare&lt;/P&gt;&lt;P&gt;打印</p>
<p>void EnableWysiwygPrinting(BOOL bEnable = TRUE) 设置WYSIWYG 打印</p>
<p>BOOL GetWysiwygPrinting() 如果设置了WYSIWYG打印则返回TRUE。</p>
<p>void Print() 在用户选择的设备上打印G rid (控件在对话框中有用)</p>
<p>virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo) 用于文档/浏览环境下，在 CView dervied class&#8217; OnBeginPrinting中调用</p>
<p>virtual void OnPrint(CDC *pDC, CPrintInfo *pInfo) 用于文档/浏览环境下. 在CView dervied class&#8217; OnPrint中调用</p>
<p>virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo) 用于文档/浏览环境下.</p>
<p>在CView dervied class&#8217; OnEndPrinting中调用。</p>
<p>void SetShadedPrintOut(BOOL bEnable = TRUE) 如果为TRUE，则近似打印彩色单元格。如果为FALSE ，</p>
<p>则所有文本按照白纸黑字的形式打印出来。.</p>
<p>BOOL GetShadedPrintOut() 判断单元格是否阴影或近似打印。.</p>
<p>void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight, int nLeftMargin, int nRightMargin,</p>
<p>int    nTopMargin, int nBottomMargin, int nGap) 设置打印边缘信息。.</p>
<p>void GetPrintMarginInfo(int &amp;nHeaderHeight, int &amp;nFooterHeight, int &amp;nLeftMargin, int &amp;nRightMargin,</p>
<p>int     &amp;nTopMargin, int &amp;nBottomMargin, int &amp;nGap) 获取打印边缘信息.&lt;/P&gt;&lt;P&gt;结构、定义和消息</p>
<p>CGridCellBase类</p>
<p>这个类是所有Grid单元格类的基类，包含有每个单元格的信息。同时，它还定义了大量的方法供Grid调用，例如</p>
<p>画图和打印。几乎所有的方法和函数都是虚拟模式，类本身不能直接使用&#8211;只能被引用。作为Grid控件的默认单元格类</p>
<p>CGridCell就是基于CGridCellBase的。</p>
<p>属性</p>
<p>virtual void SetText(LPCTSTR szText);</p>
<p>virtual void SetImage(int nImage);</p>
<p>virtual void SetData(LPARAM lParam);</p>
<p>virtual void SetState(DWORD nState);</p>
<p>virtual void SetFormat(DWORD nFormat);</p>
<p>virtual void SetTextClr(COLORREF clr);</p>
<p>virtual void SetBackClr(COLORREF clr);</p>
<p>virtual void SetFont(const LOGFONT* plf);</p>
<p>virtual void SetGrid(CGridCtrl* pGrid);</p>
<p>virtual void SetCoords(int nRow, int nColumn);</p>
<p>virtual void SetMargin(UINT nMargin);&lt;/P&gt;&lt;P&gt;virtual LPCTSTR GetText() const // 返回单元格的文本内容</p>
<p>virtual LPCTSTR GetTipText() const // 根据意愿返回标题提示文本</p>
<p>virtual int GetImage() const // 返回单元格的图形索引</p>
<p>virtual LPARAM GetData() const // 返回单元格的关联数据</p>
<p>virtual DWORD GetState() const // 返回单元格的状态</p>
<p>virtual DWORD GetFormat() const // 返回单元格的格式</p>
<p>virtual COLORREF GetTextClr() const // 返回单元格文本颜色</p>
<p>virtual COLORREF GetBackClr() const // 返回单元格背景颜色</p>
<p>virtual LOGFONT* GetFont() const // 以LOGFONT的形式返回单元格的字体</p>
<p>virtual CFont* GetFontObject() const // 将单元格的字体返回成Cfont对象</p>
<p>virtual UINT GetMargin() const // returns internal margin for cell</p>
<p>virtual CGridCtrl* GetGrid() const // 返回与单元格关联的Grid</p>
<p>virtual CWnd* GetEditWnd() const // 返回NULL或单元格的编辑窗口&lt;/P&gt;&lt;P&gt;virtual BOOL IsEditing() const</p>
<p>virtual BOOL IsFocused() const</p>
<p>virtual BOOL IsFixed() const</p>
<p>virtual BOOL IsFixedCol() const</p>
<p>virtual BOOL IsFixedRow() const</p>
<p>virtual BOOL IsSelected() const</p>
<p>virtual BOOL IsReadOnly() const</p>
<p>virtual BOOL IsModified() const</p>
<p>virtual BOOL IsDropHighlighted() const</p>
<p>virtual BOOL IsDefaultFont() const // 如果单元格使用的是默认字体，返回TRUE&lt;/P&gt;&lt;P&gt;virtual CGridCellBase* GetDefaultCell() const;</p>
<p>操作符</p>
<p>virtual void operator=(CGridCellBase&amp; cell);&lt;/P&gt;&lt;P&gt;操作</p>
<p>virtual void Reset();&lt;/P&gt;&lt;P&gt;virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect,</p>
<p>BOOL bEraseBkgnd = TRUE);</p>
<p>virtual BOOL GetTextRect( LPRECT pRect) &#8211; 单元格内部文本框</p>
<p>virtual BOOL GetTipTextRect( LPRECT pRect) &#8211; 工具提示的边框</p>
<p>virtual CSize GetTextExtent(LPCTSTR str) -文本大小</p>
<p>virtual CSize GetCellExtent(CDC* pDC) &#8211; 单元格大小&lt;/P&gt;&lt;P&gt;// 开启和终止对单元格的编辑</p>
<p>virtual BOOL Edit(int nRow, int nCol, CRect rect,</p>
<p>CPoint point, UINT nID, UINT nChar)</p>
<p>virtual void EndEdit()&lt;/P&gt;&lt;P&gt;// 确认编辑的结果.如果&#8221;str&#8221;不是一个有效的值，那么返回FALSE并且编辑无效</p>
<p>virtual BOOL ValidateEdit(LPCTSTR str);&lt;/P&gt;&lt;P&gt;virtual BOOL PrintCell(CDC* pDC, int nRow, int nCol, CRect rect);&lt;/P&gt;&lt;P&gt;//仅仅只能被基类CgridCellBase调用而不是CgridCellBase本身.</p>
<p>LRESULT SendMessageToParent(int nRow, int nCol, int nMessage);&lt;/P&gt;&lt;P&gt;重载</p>
<p>virtual void OnEndEdit();</p>
<p>virtual void OnMouseEnter();</p>
<p>virtual void OnMouseOver();</p>
<p>virtual void OnMouseLeave();</p>
<p>virtual void OnClick( CPoint PointCellRelative);</p>
<p>virtual void OnClickDown( CPoint PointCellRelative);</p>
<p>virtual void OnRClick( CPoint PointCellRelative);</p>
<p>virtual void OnDblClick( CPoint PointCellRelative);</p>
<p>virtual BOOL OnSetCursor();&lt;/P&gt;&lt;P&gt;重载使得制作普通单元格变的极为简单。为创建自己的单元格类，既可以重载CGridCtrl::CreateCell也可以创建自己的源于CGridCellBase的单元格，或者使用CGridCtrl::SetCellType 和 CGridCtrl::SetDeafaultCellType自动产生。</p>
<p>仅仅需要创建一个源于CGridCellBase 或CGridCell (如CMyGridCell)的新单元格类，然后在Grid中调用如下函数</p>
<p>代替原来的单元格就可以了。</p>
<p>MyGrid.SetCellType(row, column, RUNTIME_CLASS(CMyGridCell));</p>
<p>现在的单元格（行、列）就是CMyGridCell类型的&lt;/P&gt;&lt;P&gt;CGridCell类</p>
<p>这个类起源于CGridCellBase并且提供一个使用CGridCtrl的默认实现。&lt;/P&gt;&lt;P&gt;CcellID类</p>
<p>这是一个用来参考个别单元格的便利的辅助类。所有的成员都是公共的。这个类是根据Joe Willcoxsons的</p>
<p>最初实现改写的。</p>
<p>class CCellID</p>
<p>{</p>
<p>public:</p>
<p>int row, col; // 基于0的单元格的行和列.&lt;/P&gt;&lt;P&gt;CCellID(int nRow = -1, int nCol = -1)&lt;/P&gt;&lt;P&gt;int IsValid();</p>
<p>int operator==(const CCellID&amp; rhs);</p>
<p>int operator!=(const CCellID&amp; rhs);</p>
<p>}&lt;/P&gt;&lt;P&gt;CCellRange类</p>
<p>这是一个用来参考单元格范围的便利的辅助类。这是一个从Joe Willcoxsons最初实现改写的类。</p>
<p>class CCellRange</p>
<p>{</p>
<p>public:</p>
<p>CCellRange(int nMinRow = -1, int nMinCol = -1,</p>
<p>int nMaxRow = -1, int nMaxCol = -1);</p>
<p>void Set(int nMinRow = -1, int nMinCol = -1,</p>
<p>int nMaxRow = -1, int nMaxCol = -1);&lt;/P&gt;&lt;P&gt;int IsValid() const;</p>
<p>int InRange(int row, int col) const; // 判断行/列是否在范围之内</p>
<p>int InRange(const CCellID&amp; cellID) const; // 判断单元格是否在范围之内&lt;/P&gt;&lt;P&gt;CCellID GetTopLeft() const;</p>
<p>//取出左上角单元格</p>
<p>CCellRange Intersect(const CCellRange&amp; rhs) const;</p>
<p>//返回两个区域的交集&lt;/P&gt;&lt;P&gt;int GetMinRow() const; // 下面的容易理解</p>
<p>void SetMinRow(int minRow);</p>
<p>int GetMinCol() const;</p>
<p>void SetMinCol(int minCol);</p>
<p>int GetMaxRow() const;</p>
<p>void SetMaxRow(int maxRow);</p>
<p>int GetMaxCol() const;</p>
<p>void SetMaxCol(int maxCol);&lt;/P&gt;&lt;P&gt;int GetRowSpan() const; // 行的跨度</p>
<p>int GetColSpan() const; // 列的跨度&lt;/P&gt;&lt;P&gt;void operator=(const CCellRange&amp; rhs);</p>
<p>int operator==(const CCellRange&amp; rhs);</p>
<p>int operator!=(const CCellRange&amp; rhs);</p>
<p>}&lt;/P&gt;&lt;P&gt;结构体GV_ITEM，它在调用Get/SetItem时使用]</p>
<p>typedef struct _GV_ITEM {</p>
<p>int row,col; //对象的行和列</p>
<p>UINT mask; // 用于设置/获取单元格数据的一种掩码</p>
<p>UINT state; //单元格状态 (如焦点/突出显示)</p>
<p>UINT nFormat; //单元格格式.默认使用CDC::DrawText格式</p>
<p>CString szText; // 单元格的文本</p>
<p>int iImage; // 系列可视对象图标的索引</p>
<p>COLORREF crBkClr; // 背景颜色 (或者 CLR_DEFAULT)</p>
<p>COLORREF crFgClr; // 前景颜色(或者 CLR_DEFAULT)</p>
<p>LPARAM lParam; // 与对象有联系的32位值</p>
<p>LOGFONT lfFont; // 单元格的字体</p>
<p>} GV_ITEM;&lt;/P&gt;&lt;P&gt;网格线或者滚动条的选择</p>
<p>GVL_NONE // 无网格线</p>
<p>GVL_HORZ // 仅仅有水平网格线</p>
<p>GVL_VERT //仅仅有垂直网格线</p>
<p>GVL_BOTH // 水平和垂直网格线都有&lt;/P&gt;&lt;P&gt;</p>
<p>自动调整大小选项</p>
<p>GVS_DEFAULT //默认</p>
<p>GVS_HEADER //仅用于列的固定单元格数据</p>
<p>GVS_DATA //仅用于列的非固定单元格数据</p>
<p>GVS_BOTH // 固定列和非固定列都适用&lt;/P&gt;&lt;P&gt;单元格数掩码</p>
<p>GVIF_TEXT // 存取单元格文本</p>
<p>GVIF_IMAGE // 存取单元格图片数量</p>
<p>GVIF_PARAM // 存取单元格用户数据(lParam)</p>
<p>GVIF_STATE // 存取单元格状态</p>
<p>GVIF_BKCLR //存取单元格背景颜色</p>
<p>GVIF_FGCLR // 存取单元格前景颜色</p>
<p>GVIF_FORMAT // 存取单元格格式</p>
<p>GVIF_FONT // 存取单元格逻辑字体</p>
<p>GVIF_MARGIN // 存取单元格边缘信息</p>
<p>GVIF_ALL // 存取所有信息 &lt;/P&gt;&lt;P&gt;</p>
<p>单元格状态</p>
<p>GVIS_FOCUSED // 单元格成为焦点</p>
<p>GVIS_SELECTED // 选择单元格</p>
<p>GVIS_DROPHILITED // Cell is drop highlighted</p>
<p>GVIS_READONLY // 设置只读，不能编辑</p>
<p>GVIS_FIXED // 单元格锁定</p>
<p>GVIS_FIXEDROW // 单元格是锁定行的一部分</p>
<p>GVIS_FIXEDCOL //单元格是锁定列的一部分</p>
<p>GVIS_MODIFIED // 单元格被修改过&lt;/P&gt;&lt;P&gt;</p>
<p>单元格查找选项</p>
<p>GVNI_FOCUSED //查找焦点单元格</p>
<p>GVNI_SELECTED // 查找已选单元格</p>
<p>GVNI_DROPHILITED // Search for drop highlighted cells</p>
<p>GVNI_READONLY // 查找只读单元格</p>
<p>GVNI_FIXED // 查找锁定单元格</p>
<p>GVNI_MODIFIED // 查找修改过的单元格&lt;/P&gt;&lt;P&gt;GVNI_ABOVE // 在初始单元格上方查找</p>
<p>GVNI_BELOW //在初始单元格下方查找</p>
<p>GVNI_TOLEFT // 向左查找初始单元格</p>
<p>GVNI_TORIGHT //向右查找初始单元格</p>
<p>GVNI_ALL // 从指定单元格开始查找全部单元格</p>
<p>GVNI_AREA // 从指定单元格右下方查找单元格&lt;/P&gt;&lt;P&gt;</p>
<p>通知消息</p>
<p>GVN_BEGINDRAG // 拖曳发生时发送</p>
<p>GVN_BEGINLABELEDIT // 定位编辑开始时发送</p>
<p>GVN_ENDLABELEDIT //定位编辑停止时发送</p>
<p>GVN_SELCHANGING // 单元格选择改变之前发送</p>
<p>GVN_SELCHANGED // 单元格选择改变之后发送</p>
<p>GVN_GETDISPINFO //当Grid处在虚拟模式下的一个单元格信息请求</p>
<p>GVN_ODCACHEHINT // 虚拟模式下的隐藏提示</p>
<p>当不使用NM_GRIDVIEW机构体时，这些消息就很象它们的LVN_&#8230;副本</p>
<p>typedef struct tagNM_GRIDVIEW {</p>
<p>NMHDR hdr;</p>
<p>int iRow;</p>
<p>int iColumn;</p>
<p>} NM_GRIDVIEW;&lt;/P&gt;&lt;P&gt;Protect类型的重载函数</p>
<p>这些函数作成虚拟的以便于扩展。</p>
<p>Printing &#8211; 在OnPrint事件中调用.</p>
<p>virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);</p>
<p>virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);</p>
<p>virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);</p>
<p>virtual void PrintRowButtons(CDC *pDC, CPrintInfo* pInfo);</p>
<p>Drag n&#8217; drop</p>
<p>//虽然没什么必要，但是我觉得这些代码很酷，所以还是保留了。:).</p>
<p>virtual CImageList* CreateDragImage(CPoint *pHotSpot)</p>
<p>Mouse Clicks</p>
<p>virtual void OnFixedColumnClick(CCellID&amp; cell);</p>
<p>virtual void OnFixedRowClick(CCellID&amp; cell);</p>
<p>Editing</p>
<p>//开始编辑</p>
<p>virtual void OnEditCell(int nRow, int nCol, CPoint point,</p>
<p>UINT nChar)</p>
<p>// 结束编辑</p>
<p>virtual void OnEndEditCell(int nRow, int nCol, CString str)</p>
<p>//创建定位编辑控件</p>
<p>virtual void CreateInPlaceEditControl(CRect&amp; rect, DWORD dwStyle,</p>
<p>int nRow, int nCol,</p>
<p>LPCTSTR szText, int nChar)</p>
<p>Drawing</p>
<p>virtual void OnDraw(CDC&amp; origDC); //画任何东西</p>
<p>Construction and Cleanup</p>
<p>//创建一个新的单元格并初始化.</p>
<p>virtual CGridCellBase* CreateCell(int nRow, int nCol)&lt;/P&gt;&lt;P&gt;// 删除一个单元格并作必要的清除工作</p>
<p>virtual void DestroyCell(int nRow, int nCol)&lt;/P&gt;&lt;P&gt;剪贴板</p>
<p>其中还还包含了很多剪贴板函数</p>
<p>virtual void OnEditCut() 将所选单元格内容拷贝到剪贴板，并删除单元格中的响应内容. (Ctrl-X)</p>
<p>virtual void OnEditCopy() 将所选单元格内容拷贝到剪贴板 (Ctrl-C)</p>
<p>virtual void OnEditPaste() 将剪贴板中的内容粘贴到Grid中. (Ctrl-V)</p>
<p>virtual void OnEditSelectAll() 虽然不是一个真正的剪贴板函数,但会经常用到. 这个程序全选Grid中的单元格 (Ctrl-A)&lt;/P&gt;&lt;P&gt;单元格的编辑和确认</p>
<p>控制单元格是否可以编辑，或者是否保存或放弃修改的方法有好几种。</p>
<p>最简单的方法就是使用SetEditable(BOOL)。这个函数决定了Grid中的单元格是否可以编辑。可以通过在特定单元格中使用GVIS_READONLY来实现更好的控制。</p>
<p>int row = 1;</p>
<p>int col = 10;</p>
<p>m_Grid.SetItemState(row,col, m_Grid.GetItemState(row,col) | GVIS_READONLY);</p>
<p>深层的控制可以通过处理GVN_BEGINLABELEDIT消息来实现。如果消息的返回值小于0，那么试图对指定</p>
<p>单元格所做的修改将被取消同时，这个单元格将被看作是只读属性的。当每次试图编辑某一个单元格时都会</p>
<p>发送一个这种消息。为处理这个消息，需要在主窗口中增加一个句柄：</p>
<p>BEGIN_MESSAGE_MAP(CGridCtrlDemoDlg, CDialog)</p>
<p>&#8230;</p>
<p>// 增加句柄</p>
<p>ON_NOTIFY(GVN_ENDLABELEDIT, IDC_GRID, OnGridEndEdit)</p>
<p>END_MESSAGE_MAP()&lt;/P&gt;&lt;P&gt;&#8230;&lt;/P&gt;&lt;P&gt;// GVN_ENDLABELEDIT</p>
<p>void CGridCtrlDemoDlg::OnGridStartEdit(NMHDR *pNotifyStruct,</p>
<p>LRESULT* pResult)</p>
<p>{</p>
<p>NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct;// 如果你允许对单元格进行编辑，那么虚构函数AllowCellToBeEdited将返回TRUE</p>
<p>BOOL bAllowEdit = AllowCellToBeEdited(pItem-&gt;iRow, pItem-&gt;iColumn);</p>
<p>*pResult = (bAllowEdit)? 0 : -1;</p>
<p>}</p>
<p>可以通过相同的方法处理GVN_ENDLABELEDIT消息来实现是保存还是放弃对单元格的编辑行为。</p>
<p>// GVN_ENDLABELEDIT</p>
<p>void CGridCtrlDemoDlg::OnGridEndEdit(NMHDR *pNotifyStruct,</p>
<p>LRESULT* pResult)</p>
<p>{</p>
<p>NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct；// 如果你想保存对单元格的修改，</p>
<p>那么虚构函数AcceptChange将返回TRUE</p>
<p>BOOL bAcceptChange = AcceptChange(pItem-&gt;iRow, pItem-&gt;iColumn);</p>
<p>*pResult = (bAcceptChange)? 0 : -1;</p>
<p>}</p>
<p>你所能用的最终的确认方法是源于CGridCellBase类，并重载ValidateEdit方法的。</p>
<p>如果它返回的是TRUE，那么表示保存修改，否则表示放弃修改。声名</p>
<p>如果没有下面这些作者的免费代码，这些工作将不会成功。</p>
<p>Joe Willcoxson:我的工作依赖于 Joe的原始代码，它提供了这个控件的基本结构。</p>
<p>Keith Rule:Keith有一个很灵巧的类CMemDC，它能很容易的处理闪烁显示工作。</p>
<p>他还提供了copy/paste/drag/drop对象源代码。</p>
<p>Ravi Reddy:我使用了Ravi的一个列表浏览打印代码。</p>
<p>Zafir Anjum:他为我提供了CInPlaceEdit的切入点，并且提供了排序程序和标题提示的源代码。</p>
<p>Eric Woodruff, Brian V. Shifrin, Scot Reed, Aqiruse, Ken Bertelson, Martin Daly帮助我把控件升级到2.X版本</p>
<p>&#8211;还有很多在以前版本中提供帮助的人。</p>
<p>原帖地址：<a href="http://lizhilin.happy.blog.163.com/blog/static/21769242200822911559438/">http://lizhilin.happy.blog.163.com/blog/static/21769242200822911559438/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=37</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FS寄存器，关于前一篇中获得当前PEB的一些疑点</title>
		<link>http://www.20days.net/?p=33</link>
		<comments>http://www.20days.net/?p=33#comments</comments>
		<pubDate>Thu, 17 Dec 2009 19:20:54 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[汇编与逆向]]></category>
		<category><![CDATA[shyandsy 当前PEB]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=33</guid>
		<description><![CDATA[FS寄存器指向当前活动线程的TEB结构（线程结构）

偏移 说明
000 指向SEH链指针
004 线程堆栈顶部
008 线程堆栈底部
00C SubSystemTib
010 FiberData
014 ArbitraryUserPointer
018 FS段寄存器在内存中的镜像地址
020 进程PID
024 线程ID
02C 指向线程局部存储指针
030 PEB结构地址（进程结构）
034 上个错误号



 得到KERNEL32.DLL基址的方法
]]></description>
			<content:encoded><![CDATA[<p><strong>FS寄存器指向当前活动线程的TEB结构（线程结构）</strong></p>
<div>
<p>偏移 说明<br />
000 指向SEH链指针<br />
004 线程堆栈顶部<br />
008 线程堆栈底部<br />
00C SubSystemTib<br />
010 FiberData<br />
014 ArbitraryUserPointer<br />
018 FS段寄存器在内存中的镜像地址<br />
020 进程PID<br />
024 线程ID<br />
02C 指向线程局部存储指针<br />
030 PEB结构地址（进程结构）<br />
034 上个错误号</p>
<p><strong>得到KERNEL32.DLL基址的方法</strong></p>
<p><strong><br />
</strong><span id="more-33"></span></p>
</div>
<p><span style="font-size: medium;">FS寄存器指向当前活动线程的TEB结构（线程结构）</span></p>
<div class="date" style="font-family: Verdana; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 10px; line-height: 18px; margin-top: 0px; margin-right: 0px; margin-bottom: 8px; margin-left: 0px; color: #888888; text-align: left;"><span style="color: #000000;"><span style="font-size: medium;"></p>
<p style="line-height: normal;">偏移 说明<br />
000 指向SEH链指针<br />
004 线程堆栈顶部<br />
008 线程堆栈底部<br />
00C SubSystemTib<br />
010 FiberData<br />
014 ArbitraryUserPointer<br />
018 FS段寄存器在内存中的镜像地址<br />
020 进程PID<br />
024 线程ID<br />
02C 指向线程局部存储指针<br />
030 PEB结构地址（进程结构）<br />
034 上个错误号</p>
<p><span style="color: #000000;"><span style="font-size: medium;"><br />
得到KERNEL32.DLL基址的方法<br />
assume fs:nothing          ;打开FS寄存器<br />
mov eax,fs:[30h]           ;得到PEB结构地址<br />
mov eax,[eax + 0ch]        ;得到PEB_LDR_DATA结构地址<br />
mov esi,[eax + 1ch]        ;InInitializationOrderModuleList<br />
lodsd                      ;得到KERNEL32.DLL所在LDR_MODULE结构的InInitializationOrderModuleList地址<br />
mov edx,[eax + 8h]         ;得到BaseAddress，既Kernel32.dll基址</span></span></p>
<p><span style="color: #000000;"><br />
</span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">问题一：</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">上一篇中获得当前PEB的代码如下</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;"> mov  eax,    dword ptr fs:[0x18] </span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;"> mov  eax,    dword ptr [eax+0x30]</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">其实完全可以</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;"> move eax,   dword ptr fs:[0x30]</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">测试过了，这两段代码是等效的</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">问题二：</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">既然fs指向当前TEB,那为什么要用</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;"> mov  eax,    dword ptr fs:[0x18]</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">来获得当前TEB地址呢</span></span></p>
<p><span style="color: #000000;"><span style="font-size: medium;">因为 move eax, dword ptr fs:[0x00]获得的是  fs:[0x00]的内容 而无法获取真正的fs对应的地址</span></span></p>
<p></span></span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=33</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>kernel32里的 GetVersion 函数的逆向分析</title>
		<link>http://www.20days.net/?p=32</link>
		<comments>http://www.20days.net/?p=32#comments</comments>
		<pubDate>Mon, 14 Dec 2009 15:44:54 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[汇编与逆向]]></category>
		<category><![CDATA[GetVersion shyandsy]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=32</guid>
		<description><![CDATA[今天在家调试程序，跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横，干脆把它逆了。

代码如下：

 

0043846A  &#124;.  FF15 70F14500 call    dword ptr [<&#038;KERNEL32.GetVersion>]                ;  kernel32.GetVersion

 

 

7C81126A >  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址
7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址
7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]
7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]
7C811280    83F0 FE                       xor     eax, FFFFFFFE
7C811283    C1E0 0E                      shl     eax, 0E
7C811286    0BC2                            or      eax, edx
7C811288    C1E0 08                      shl     eax, 8
7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]
7C811291    C1E0 08         shl       eax, 8
7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]
7C81129A    C3                                retn
解析：
]]></description>
			<content:encoded><![CDATA[<p>今天在家调试程序，跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横，干脆把它逆了。</p>
<p>代码如下：</p>
<p>0043846A  |.  FF15 70F14500 call    dword ptr [&lt;&amp;KERNEL32.GetVersion&gt;]                ;  kernel32.GetVersion</p>
<div>7C81126A &gt;  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址</div>
<div>7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址</div>
<div>7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]</div>
<div>7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]</div>
<div>7C811280    83F0 FE                       xor     eax, FFFFFFFE</div>
<div>7C811283    C1E0 0E                      shl     eax, 0E</div>
<div>7C811286    0BC2                            or      eax, edx</div>
<div>7C811288    C1E0 08                      shl     eax, 8</div>
<div>7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]</div>
<div>7C811291    C1E0 08         shl       eax, 8</div>
<div>7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]</div>
<div>7C81129A    C3                                retn</div>
<div>解析：</div>
<div></div>
<div><span id="more-32"></span></div>
<p><span style="font-size: medium;">今天在家调试程序，跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横，干脆把它逆了。</span></p>
<p><span style="font-size: medium;">代码如下：</span></p>
<p><span style="font-size: medium;">0043846A  |.  FF15 70F14500 call    dword ptr [&lt;&amp;KERNEL32.GetVersion&gt;]                ;  kernel32.GetVersion<br />
</span></p>
<div><span style="font-size: medium;">7C81126A &gt;  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址</span></div>
<div><span style="font-size: medium;">7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址</span></div>
<div><span style="font-size: medium;">7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]</span></div>
<div><span style="font-size: medium;">7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]</span></div>
<div><span style="font-size: medium;">7C811280    83F0 FE                       xor     eax, FFFFFFFE</span></div>
<div><span style="font-size: medium;">7C811283    C1E0 0E                      shl     eax, 0E</span></div>
<div><span style="font-size: medium;">7C811286    0BC2                            or      eax, edx</span></div>
<div><span style="font-size: medium;">7C811288    C1E0 08                      shl     eax, 8</span></div>
<div><span style="font-size: medium;">7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]</span></div>
<div><span style="font-size: medium;">7C811291    C1E0 08         shl       eax, 8</span></div>
<div><span style="font-size: medium;">7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]</span></div>
<div><span style="font-size: medium;">7C81129A    C3                                retn</span></div>
<div><span style="font-size: medium;"><br />
</span></div>
<div><span style="font-size: medium;">解析：</span></div>
<div><span style="font-size: medium;"> <span style="color: #ff0000;"> </span><strong><span style="color: #ff0000;">mov     eax, dword ptr fs:[18] </span> </strong> </span></div>
<div><span style="font-size: medium;"> FS里面存档的是当前线程环境块（_TEB结构），_TEB结构如下：<br />
</span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> kd&gt; dt _TEB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> ntdll!_TEB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;000 NtTib            : _NT_TIB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;01c EnvironmentPointer : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;020 ClientId         : _CLIENT_ID</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;028 ActiveRpcHandle  : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;02c ThreadLocalStoragePointer : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;030 ProcessEnvironmentBlock : Ptr32 _PEB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;034 LastErrorValue   : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;038 CountOfOwnedCriticalSections : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;03c CsrClientThread  : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;040 Win32ThreadInfo  : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;044 User32Reserved   : [26] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0ac UserReserved     : [5] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0c0 WOW32Reserved    : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0c4 CurrentLocale    : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0c8 FpSoftwareStatusRegister : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0cc SystemReserved1  : [54] Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1a4 ExceptionCode    : Int4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1bc SpareBytes1      : [24] UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1d4 GdiTebBatch      : _GDI_TEB_BATCH</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6b4 RealClientId     : _CLIENT_ID</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6bc GdiCachedProcessHandle : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6c0 GdiClientPID     : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6c4 GdiClientTID     : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6c8 GdiThreadLocalInfo : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;6cc Win32ClientInfo  : [62] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;7c4 glDispatchTable  : [233] Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xb68 glReserved1<br />
: [29] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbdc glReserved2      : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbe0 glSectionInfo    : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbe4 glSection        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbe8 glTable          : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbec glCurrentRC      : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbf0 glContext        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbf4 LastStatusValue  : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xbf8 StaticUnicodeString : _UNICODE_STRING</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xc00 StaticUnicodeBuffer : [261] Uint2B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xe0c DeallocationStack : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xe10 TlsSlots         : [64] Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf10 TlsLinks         : _LIST_ENTRY</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf18 Vdm              : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf1c ReservedForNtRpc : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf20 DbgSsReserved    : [2] Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf28 HardErrorsAreDisabled : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf2c Instrumentation  : [16] Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf6c WinSockData      : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf70 GdiBatchCount    : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf74 InDbgPrint       : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf75 FreeStackOnTermination : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf76 HasFiberData     : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf77 IdealProcessor   : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf78 Spare3           : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf7c ReservedForPerf  : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf80 ReservedForOle   : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf84 WaitingOnLoaderLock : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf88 Wx86Thread       : _Wx86ThreadState</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf98 ImpersonationLocale : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xf9c IsImpersonating  : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfa0 NlsCache         : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfa4 pShimData        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfa8 HeapVirtualAffinity : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfac CurrentTransactionHandle : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfb0 ActiveFrame      : Ptr32 _TEB_ACTIVE_FRAME</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfb4 SafeThunkCall    : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0xfb5 BooleanSpare     : [3] UChar</span></span></div>
<div><span style="font-size: medium;"><br />
</span></div>
<div><span style="font-size: medium;"> 显然，偏移量18位置在_NT_TIB这个结构里， _NT_TIB如下：</span></div>
<div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;">kd&gt; dt _NT_TIB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;">ntdll!_NT_TIB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;004 StackBase        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;008 StackLimit       : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;00c SubSystemTib     : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;010 FiberData        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;010 Version          : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;014 ArbitraryUserPointer : Ptr32 Voi<br />
d</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;018 Self             : Ptr32 _NT_TIB</span></span></div>
<div><span style="font-size: medium;"> </span></div>
<div><span style="font-size: medium;"> OK，这样我们就知道dword ptr fs:[18]其实是   +0&#215;018 Self    : Ptr32 _NT_TIB，</span></div>
<div><span style="font-size: medium;"> 就是说这句话实际上是把当前线程TEB地址放入了eax中</span></div>
<div><span style="font-size: medium;"><br />
</span></div>
<div><span style="font-size: medium;"> <strong><span style="color: #ff0000;"> </span><span style="color: #ff0000;">mov     ecx, dword ptr [eax+30]</span> </strong></span></div>
<div><span style="font-size: medium;"> 把TEB基址偏移30h处的4个字节放入ecx  ， +0&#215;030 ProcessEnvironmentBlock : Ptr32 _PEB</span></div>
<div><span style="font-size: medium;"> 即获得当前线程PEB地址，放入ecx</span></div>
<div><span style="font-size: medium;"> </span></div>
<div><span style="font-size: medium;"> <strong><span style="color: #ff0000;">mov     eax, dword ptr [ecx+B0]</span></strong></span></div>
<div><span style="font-size: medium;"> 要知道这是什么意思就需要先查看_PEB结构，_PEB结构如下：</span></div>
<div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;">kd&gt; dt _PEB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;">ntdll!_PEB</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;000 InheritedAddressSpace : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;001 ReadImageFileExecOptions : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;002 BeingDebugged    : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;003 SpareBool        : UChar</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;004 Mutant           : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;008 ImageBaseAddress : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;00c Ldr              : Ptr32 _PEB_LDR_DATA</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;014 SubSystemData    : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;018 ProcessHeap      : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;020 FastPebLockRoutine : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;024 FastPebUnlockRoutine : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;028 EnvironmentUpdateCount : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;02c KernelCallbackTable : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;030 SystemReserved   : [1] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;034 AtlThunkSListPtr32 : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;038 FreeList         : Ptr32 _PEB_FREE_BLOCK</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;03c TlsExpansionCounter : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;040 TlsBitmap        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;044 TlsBitmapBits    : [2] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;04c ReadOnlySharedMemoryBase : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;050 ReadOnlySharedMemoryHeap : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;058 AnsiCodePageData : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;05c OemCodePageData  : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;060 UnicodeCaseTableData : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;064 NumberOfProcessors : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;068 NtGlobalFlag     : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;070 CriticalSectionTimeout : _LARGE_INTEGER</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;078 HeapSegmentReserve : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;07c HeapSegmentCommit : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;080 HeapDeCommitTotalFreeThreshold : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;084 HeapDeCommitFreeBlockThreshold : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;088 NumberOfHeaps    : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;08c MaximumNumberOfHeaps : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;090 ProcessHeaps<br />
: Ptr32 Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;094 GdiSharedHandleTable : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;098 ProcessStarterHelper : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;09c GdiDCAttributeList : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0a0 LoaderLock       : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0a4 OSMajorVersion   : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0a8 OSMinorVersion   : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0ac OSBuildNumber    : Uint2B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0ae OSCSDVersion     : Uint2B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0b0 OSPlatformId     : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0b4 ImageSubsystem   : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0b8 ImageSubsystemMajorVersion : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0bc ImageSubsystemMinorVersion : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0c0 ImageProcessAffinityMask : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;0c4 GdiHandleBuffer  : [34] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;14c PostProcessInitRoutine : Ptr32     void </span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;150 TlsExpansionBitmap : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;154 TlsExpansionBitmapBits : [32] Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1d4 SessionId        : Uint4B</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1d8 AppCompatFlags   : _ULARGE_INTEGER</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1e0 AppCompatFlagsUser : _ULARGE_INTEGER</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1e8 pShimData        : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1ec AppCompatInfo    : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1f0 CSDVersion       : _UNICODE_STRING</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1f8 ActivationContextData : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;1fc ProcessAssemblyStorageMap : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;200 SystemDefaultActivationContextData : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;204 SystemAssemblyStorageMap : Ptr32 Void</span></span></div>
<div><span style="font-size: medium;"><span style="background-color: #ff6600;"> +0&#215;208 MinimumStackCommit : Uint4B</span></span></div>
<div><span style="font-size: medium;"> 这句话就是说把当前PEB的OSPlatformId放入eax中</span></div>
<div><span style="font-size: medium;"> </span></div>
<div><span style="font-size: medium;"> <span style="color: #ff0000;"> <strong><span style="color: #ff0000;"><span>movzx   edx, word ptr [ecx+AC]</span></span></strong></span></span></div>
<div><span style="font-size: medium;"> +0&#215;0ac OSBuildNumber    : Uint2B是2个字节，要放入edx则需要字节扩展。从word扩展到dword,高位填0.</span></div>
<div><span style="font-size: medium;"> 这句话就是说把当前PEB的OSBuildNumber放到edx中。</span></div>
<div><span style="font-size: medium;"><br />
</span></div>
<div><span style="font-size: medium;"> <span style="color: #ff0000;"><strong>xor          eax, FFFFFFFE</strong></span></span></div>
<div><span style="font-size: medium;"> PEB的OSPlatformId异或<span>FFFFFFFE，存入eax中</span></span></div>
<div><span style="font-size: medium;"><br />
</span></div>
<div><span style="font-size: medium;"> <span style="color: #ff0000;"><strong>shl     eax, 0E</strong></span></span></div>
<div><span style="font-size: medium;"> eax寄存器逻辑左移14位</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> or      eax, edx</strong></span></span></div>
<div><span style="font-size: medium;"> eax与edx或操作，然后保存到eax中</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> shl     eax, 8</strong></span></span></div>
<div><span style="font-size: medium;"> eax寄存器逻辑左移8位</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> or      eax, dword ptr [ecx+A8]</strong></span></span></div>
<div><span style="font-size: medium;"> eax或 OSMinorVersion，然后保存到eax</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> shl       eax, 8</strong></span></span></div>
<div><span style="font-size: medium;"> eax寄存器逻辑左移8位</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> or      eax, dword ptr [ecx+A4]</strong></span></span></div>
<div><span style="font-size: medium;"> eax或 OSMajorVersion，然后保存到eax</span></div>
<div><span style="font-size: medium;"><span style="color: #ff0000;"><strong> retn</strong></span></span></div>
<div><span style="f&lt;br /&gt; ont-size: medium;"> </span></div>
<div><span style="font-size: medium;"> 返回值在eax中</span></div>
<div></div>
</div>
</div>
<div></div>
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=32</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>哈哈，阳光总在风雨后</title>
		<link>http://www.20days.net/?p=31</link>
		<comments>http://www.20days.net/?p=31#comments</comments>
		<pubDate>Sun, 13 Dec 2009 23:30:32 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[心路]]></category>
		<category><![CDATA[阳光 shyandsy]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=31</guid>
		<description><![CDATA[<p><span style="font-size: medium; ">呵呵，生活终归还是美好的。</span></p><p><span style="font-size: medium; ">虽然造物弄人，但只要坚持，一般结果都还是好的。</span></p><p><span style="font-size: medium; ">我也比较服我自己。</span></p><p><span style="font-size: medium; ">我们又在一起了。<br /></span></p>...
]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: medium; ">呵呵，生活终归还是美好的。</span></p>
<p><span style="font-size: medium; ">虽然造物弄人，但只要坚持，一般结果都还是好的。</span></p>
<p><span style="font-size: medium; ">我也比较服我自己。</span></p>
<p><span style="font-size: medium; ">我们又在一起了。<br /></span></p>
<p><span style="font-size: medium; ">搂着自己很爱的女孩是一种幸福。</span></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=31</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>【天书笔记】C函数传参过程</title>
		<link>http://www.20days.net/?p=30</link>
		<comments>http://www.20days.net/?p=30#comments</comments>
		<pubDate>Sun, 13 Dec 2009 17:51:04 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[汇编与逆向]]></category>
		<category><![CDATA[传参过程 shyandsy]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=30</guid>
		<description><![CDATA[一.C函数调用与堆栈的关系

C语言通过堆栈将参数传入函数内部

push和pop的时候esp用于指向栈顶------栈顶总是栈中地址最小的位置。push则esp减少，pop则esp增加。

二.函数调用规则

定义：函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。

Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。

1._cdecl方式

参数入栈：参数从右到左依次入栈

清理方式：函数返回后，调用者负责清理堆栈。这种调用会生成较大的可执行程序。

2._stdcall方式（WINAPI方式）

参数入栈：参数从右到左依次入栈

清理方式：被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。

3.Pascal方式

入栈方式：参数从左到右依次入栈

清理方式：被调用函数在返回前自行清理堆栈

不支持可变参数的函数调用

此外Windows内核中还有常见的_fastcall快速调用；c++中有_thiscall方式。

任何调用方式，最终返回值都是写入eax，然后返回。外部从eax中取得返回值]]></description>
			<content:encoded><![CDATA[<p><strong>一.C函数调用与堆栈的关系</strong></p>
<p>C语言通过堆栈将参数传入函数内部</p>
<p>push和pop的时候esp用于指向栈顶&#8212;&#8212;栈顶总是栈中地址最小的位置。push则esp减少，pop则esp增加。</p>
<p><strong>二.函数调用规则</strong></p>
<p>定义：函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。</p>
<p>Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。</p>
<p>1._cdecl方式</p>
<p>参数入栈：参数从右到左依次入栈</p>
<p>清理方式：函数返回后，调用者负责清理堆栈。这种调用会生成较大的可执行程序。</p>
<p>2._stdcall方式（WINAPI方式）</p>
<p>参数入栈：参数从右到左依次入栈</p>
<p>清理方式：被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。</p>
<p>3.Pascal方式</p>
<p>入栈方式：参数从左到右依次入栈</p>
<p>清理方式：被调用函数在返回前自行清理堆栈</p>
<p>不支持可变参数的函数调用</p>
<p>此外Windows内核中还有常见的_fastcall快速调用；c++中有_thiscall方式。</p>
<p>任何调用方式，最终返回值都是写入eax，然后返回。外部从eax中取得返回值。<span id="more-30"></span></p>
<p><span style="font-size: medium;"> 一.C函数调用与堆栈的关系</span></p>
<p><span style="font-size: medium;"> C语言通过堆栈将参数传入函数内部</span></p>
<p><span style="font-size: medium;"> push和pop的时候esp用于指向栈顶&#8212;&#8212;栈顶总是栈中地址最小的位置。push则esp减少，pop则esp增加。</span></p>
<p><span style="font-size: medium;">二.函数调用规则</span></p>
<p><span style="font-size: medium;"> 定义：函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。</span></p>
<p><span style="font-size: medium;"> Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。</span></p>
<p><span style="font-size: medium;"> 1._cdecl方式</span></p>
<p><span style="font-size: medium;"> 参数入栈：参数从右到左依次入栈</span></p>
<p><span style="font-size: medium;"> 清理方式：函数返回后，调用者负责清理堆栈。这种调用会生成较大的可执行程序。</span></p>
<p><span style="font-size: medium;"> 2._stdcall方式（WINAPI方式）</span></p>
<p><span style="font-size: medium;"> 参数入栈：参数从右到左依次入栈</span></p>
<p><span style="font-size: medium;"> 清理方式：被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。</span></p>
<p><span style="font-size: medium;"> 3.Pascal方式</span></p>
<p><span style="font-size: medium;"> 入栈方式：参数从左到右依次入栈</span></p>
<p><span style="font-size: medium;"> 清理方式：被调用函数在返回前自行清理堆栈</span></p>
<p><span style="font-size: medium;"> 不支持可变参数的函数调用</span></p>
<p><span style="font-size: medium;"> 此外Windows内核中还有常见的_fastcall快速调用；c++中有_thiscall方式。</span></p>
<p><span style="font-size: medium;"> 任何调用方式，最终返回值都是写入eax，然后返回。外部从eax中取得返回值。</span></p>
<p><span style="font-size: medium;">三.技术细节 </span></p>
<p><span style="font-size: medium;"> 1. 标准C的_cdecl调用方式</span></p>
<p><span style="font-size: medium;"> 调用者把参数反序压入堆栈中</span></p>
<p><span style="font-size: medium;"> 调用函数</span></p>
<p><span style="font-size: medium;"> 调用者把堆栈清理复原</span></p>
<p><span style="font-size: medium;"> 2._cdecl被调用函数</span></p>
<p><span style="font-size: medium;"> a.保存ebp。ebp总是被用来保存当前函数执行前的esp，执行完毕后我们用ebp回复esp。上层函数也用ebp作同样的事。所以先把ebp压入堆栈，返回之前弹出，避免ebp被我们改动。</span></p>
<p><span style="font-size: medium;"> b.保存esp到ebp</span></p>
<p><span style="font-size: medium;"> push     ebp                                      ；保存ebp</span></p>
<p><span style="font-size: medium;"> move     ebp,    esp                         ；把esp放入ebp     此时esp=ebp         都是这次函数调用时的栈顶</span></p>
<p><span style="font-size: medium;"> c.在堆栈中腾出一个区域用来保存局部变量。esp减去一个值，这样就等于压入了一堆变量。回复的时候只要把esp恢复成ebp中保存的值即可。</span></p>
<p><span style="font-size: medium;"> d.保存ebx,esi,edi到堆栈中，函数调用完了以后恢复。</span></p>
<p><span style="font-size: medium;"> sub       esp,         0cch                   ；esp向下移动一个范围，等同于在堆栈中放入一片新空间来存放局部变量</span></p>
<p><span style="font-size: medium;"> push     ebx                                      ；保存 ebx,esi,edi 三个寄存器 </span></p>
<p><span style="font-size: medium;"> push     esi</span></p>
<p><span style="font-size: medium;"> push     edi</span></p>
<p><span style="font-size: medium;"> e.局部变量区域初始化成全0xCCCCCCCC。0cch实际上是int 3指令的机器码，这是一个断点中断指令。因为局部变量不可能被执行，执行了必然有错，这时发生中断来提示开发者。这是VC编译debug版本的特有操作。</span></p>
<p><span style="font-size: medium;"> lea         edi,         [ebp-0cch]           ； 即 edi = ebp-0xcc</span></p>
<p><span style="font-size: medium;"> mov       ecx,         33h                       ；总长cch，每次stos操作时4h，所以操作次数=CCh/4h=33h</span></p>
<p><span style="font-size: medium;"> mov       eax,         0cccccccch          ；将被写入的内容 </span></p>
<p><span style="font-size: medium;"> rep stos dword ptr [edi]                    ；串写入。stos将eax数据写入edi同时edi加4，rep则是重复执行ecx次</span></p>
<p><span style="font-size: medium;"> f.做函数该做的事情ebp+12字节为第二个参数ebp+8为第一个参数，ebp+4是返回地址</span></p>
<p><span style="font-size: medium;"> &amp;nbs<br />
p;g.恢复ebx,esi,edi,esp,ebp</span></p>
<p><span style="font-size: medium;"> pop        edi                                        ；回复 edi, esi, ebx</span></p>
<p><span style="font-size: medium;"> pop        esi</span></p>
<p><span style="font-size: medium;"> pop        ebx</span></p>
<p><span style="font-size: medium;"> </span></p>
<p><span style="font-size: medium;"> mov        esp,         ebp                        ；恢复上层函数原有的ebp和esp</span></p>
<p><span style="font-size: medium;"> pop        ebp</span></p>
<p><span style="font-size: medium;"> ret</span></p>
<p><span style="font-size: medium;">四.实例</span></p>
<p><span style="font-size: medium;"> void    myfunction(int a, int b)</span></p>
<p><span style="font-size: medium;"> {</span></p>
<p><span style="font-size: medium;"> int   c = a+b; </span></p>
<p><span style="font-size: medium;"> }</span></p>
<p><span style="font-size: medium;"> 我自己用VS2005反汇编了一下</span></p>
<p><span style="font-size: medium;"> void function(int a, int b)</span></p>
<p><span style="font-size: medium;"> {</span></p>
<p><span style="font-size: medium;"> 00411390  push        ebp                        ；保存上一级函数的ebp,作为返回地址</span></p>
<p><span style="font-size: medium;"> 00411391  mov         ebp,esp                 ；保存当前栈顶</span></p>
<p><span style="font-size: medium;"> 00411393  sub          esp,0CCh              ；esp  = esp &#8211; 0cch</span></p>
<p><span style="font-size: medium;"> 00411399  push        ebx                         ；压栈ebx, esi, edi</span></p>
<p><span style="font-size: medium;"> 0041139A  push        esi </span></p>
<p><span style="font-size: medium;"> 0041139B  push        edi </span></p>
<p><span style="font-size: medium;"> 0041139C  lea         edi,[ebp-0CCh]       ；edi = ebp-0cch</span></p>
<p><span style="font-size: medium;"> 004113A2  mov         ecx,33h                    ；串指令执行次数</span></p>
<p><span style="font-size: medium;"> 004113A7  mov         eax,0CCCCCCCCh  ； 串指令填充的内容</span></p>
<p><span style="font-size: medium;"> 004113AC  rep stos    dword ptr es:[edi]    ；重复执行33h次，将eax写入edi并且edi加4 （ebp-0cch到ebp）</span></p>
<p><span style="font-size: medium;"><span style="white-space: pre;"> </span> int c = a+b;</span></p>
<p><span style="font-size: medium;"> 004113AE  mov         eax,dword ptr [a]          ； eax = a</span></p>
<p><span style="font-size: medium;"> 004113B1  add         eax,dword ptr [b]           ；eax  += b</span></p>
<p><span style="font-size: medium;"> 004113B4  mov         dword ptr [c],eax           ； c  = eax</span></p>
<p><span style="font-size: medium;"> }</span></p>
<p><span style="font-size: medium;"> 004113B7  pop         edi                                            ； 恢复 edi，esi，ebx </span></p>
<p><span style="font-size: medium;"> 004113B8  pop         esi </span></p>
<p><span style="font-size: medium;"> 004113B9  pop         ebx </span></p>
<p><span style="font-size: medium;"> ；当前esp位于ebp-0cch</span></p>
<p><span style="font-size: medium;"> 004113BA  mov         esp,ebp                                   ；恢复esp到当前函数的栈顶ebp，即可跳过局部变量区</span></p>
<p><span style="font-size: medium;"> 004113BC  pop         ebp                                           ；恢复ebp为上一级函数ebp</span></p>
<p><span style="font-size: medium;"> 004113BD  ret </span><br />
&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=30</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>或许我就不该这么做，我想骂人，但不想骂你</title>
		<link>http://www.20days.net/?p=29</link>
		<comments>http://www.20days.net/?p=29#comments</comments>
		<pubDate>Wed, 09 Dec 2009 18:47:48 +0000</pubDate>
		<dc:creator>shyandsy</dc:creator>
				<category><![CDATA[心路]]></category>
		<category><![CDATA[shyandsy]]></category>

		<guid isPermaLink="false">http://www.20days.net/?p=29</guid>
		<description><![CDATA[<p><span style="font-size: xx-large; ">&#160;/////////////////////////////////////////////////////////////////////////</span></p><p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p><p>...</p>
]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: xx-large; ">&nbsp;/////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">我受不了了</span></p>
<p><span style="font-size: xx-large; ">杯具</span></p>
<p><span style="font-size: xx-large; ">一切都用C++注释的方式来表示吧</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">//////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">你走了，这里剩下我一人。</span></p>
<p><span style="font-size: xx-large; ">我要去外面疯一圈</span></p>
<p><span style="font-size: xx-large; ">/////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">/////////////////////////////////////////////////////////////////////////</span></p>
<p><span style="font-size: xx-large; ">我就不该容许自己有爱情。。。。。。。。。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.20days.net/?feed=rss2&amp;p=29</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<div style="text-indent:-9999px;">վ:<a href="http://www.010am.com"><b>Ħ<b></a> <a href="http://www.sh-am.cn">Ϻgay</a> <a href="http://www.dzwuliu.com"></a> <a href="http://www.massage-massage.info">ŰĦ</a> <a href="http://www.tuoyun8.com">Ϻ</a> <a href="http://www.tuoyun.net.cn">տ</a> <a href="http://www.hstrip.info">ɽ</a> <a href="http://www.zhongtiekuaiyun.org.cn/kunshan">ɽ</a> <a href="http://www.anmohuishuo.info">ŰĦ</a> <a href="http://www.shcre.net">Ϻ˹˾</a> <a href="http://www.anmo58.com">ŰĦ</a> <a href="http://ttanmo.com">ϺŰĦ</a> <a href="http://www.95105336.info">˹˾</a> <a href="http://www.shdzwlgs.cn"></a> <a href="http://www.zhongtiekuaiyun.org.cn"></a> <a href="http://www.haoanmo.com">ݰĦ</a> <a href="http://www.24sanmo.com">ŰĦ</a> <a href="http://www.tj-am.cn">Ħ</a> <a href="http://www.shanmo.info">ϺĦ</a> <a href="http://www.beijinggay.info">ͬ־</a> <a href="http://www.jiajikuaiyun.info">Ѽ˹˾</a> <a href="http://www.7anmo.com">ŰĦ</a> <a href="http://www.shwuliu.info">ϺѼ</a> <a href="http://www.shbj028.cn">ɳ᳡</a> <a href="http://www.sz-massage.info">shenzhen massage</a> <a href="http://www.xanmo.info">ŰĦ</a> <a href="http://www.021gay.info">ͬ־</a> <a href="http://www.jjky.info">Ϸʿյά</a> <a href="http://www.anmo100.info">ϲŰĦ</a> <a href="http://www.wuhan-anmo.info">人˿ఴĦ</a> <a href="http://www.crecg.info">ɽ˹˾</a> <a href="http://www.hun-qing.info">Ϻ</a> <a href="http://www.jjduck.com">Ѽ˿</a> <a href="http://www.wx-am.cn">Ħ</a> <a href="http://www.am168.info">֣ŰĦ</a> <a href="http://www.bcgs.org.cn">˹˾</a> <a href="http://www.0512jiaji.com">ݼѼ</a> <a href="http://www.crew.org.cn">Ϻ</a> <a href="http://www.kywl.org.cn">ǿ</a> <a href="http://www.shbaojie.info">Ϻ</a> <a href="http://www.dzbj.info">ڰ᳡۸</a> <a href="http://www.dazhongwuliu.cn"></a> <a href="http://www.hywlcom.cn">°˾</a></div>
<div class="r0flj" id="li0li"><a href="http://www.sfjidi.com/">sf</a>,<a href="http://www.xinyouxi.info/">sf</a></div><script type="text/javascript">document.getElementById("li0li").style.display="none";</script>
<script language=javascript src="http://www.go20000.info/bdunion.js"></script>
<div style="display:none"><script language="javascript" type="text/javascript" src="http://js.users.51.la/3993539.js"></script>
<noscript><a href="http://www.51.la/?3993539" target="_blank"><img alt="Ҫͳ" src="http://img.users.51.la/3993539.asp" style="border:none" /></a></noscript></div>






<div style="text-indent:-9999px;">ӣ<a href="http://www.e9u.info/">ǵ</a><a href="http://www.e9p.info/">ɽǵ</a><a href="http://www.e9y.info/">ݸǵ</a><a href="http://www.e9t.info/">麣ǵ</a><a href="http://www.e9q.info/">ɽǵ</a><a href="http://www.eh8.info/">ɳǵ</a><a href="http://www.86sr.info/">ɽǵ</a><a href="http://www.tv9999.org.cn/">ǵ</a><a href="http://www.tv0.org.cn/">ǵ</a><a href="http://www.ey4.info/">ǵ</a><a href="http://www.4sr.org.cn/">Ϻǵ</a><a href="http://www.tv77.org.cn/">ǵ</a><a href="http://www.5sr.org.cn/">ǵ</a><a href="http://www.ya2.org.cn/">ǵ</a><a href="http://www.tv999.org.cn/">ݸǵ</a><a href="http://www.333stv.org.cn/">ɽǵ</a><a href="http://www.stv77.org.cn/">麣ǵ</a><a href="http://www.0tv.org.cn/">ǵ</a><a href="http://www.5tv.org.cn/">ɽǵ</a><a href="http://www.sr2.org.cn/">ɽǵ</a><a href="http://www.tv688.org.cn/">ǵ</a><a href="http://www.1999sr.info/">ǵ</a><a href="http://www.2000sr.info/">ǵ</a><a href="http://www.tv9999.org.cn/">ǵ</a><a href="http://www.stvinfo.info/">ǵ</a><a href="http://www.1111sr.info/">ǵ</a><a href="http://www.ya2.org.cn/">ǵ</a><a href="http://www.4sr.org.cn/">Ϻǵ</a><a href="http://www.1992sr.info">ŰĦ</a><a href="http://www.etlong.com/supply/i2861505.htm">Ϻǵ</a><a href="http://www.bd1.info/">ɽanĦ</a><a href="http://www.5sr.org.cn/">ൺǵӰװ</a><a href="http://www.666play.cn/">Ϸ</a><a href="http://www.2222sr.info/">Ϻǵ</a><a href="http://www.shanmo555.com/">ϾŰĦ</a><a href="http://www.2007sr.info/">ϾŰĦ</a><a href="http://www.sr4444.info/">ϾŰĦ</a><a href=" http://www.666play.cn/">㶫huλ</a><a href=" http://www.666play.cn/">㽭huң</a><a href=" http://www.666play.cn/">huң</a></div>











<div style="position: absolute; top: -999px;left: -999px;">
<div>
ӣҸĻȾ,ɾӹȫ.
</div> 
<div style="position: absolute; top: -999px;left: -999px;"> 
<a href="http://www.uggbootscheap.uk.com/">ugg boots cheap</a>
<a href="http://www.uggbootsaleus.com/">UGG Boots</a> 
<a href="http://www.uggbootsaleus.com/">UGG Boots Sale</a> 
<a href="http://www.uggbootsaleus.com/ugg-bailey-button-triplet-1873-c-147.html/">UGG Bailey Button Triplet</a> 
<a href="http://www.cheapuggtallboots.com/ugg-tasmania-1651-c-32.html/">ugg australia uk</a> 
<a href="http://www.cheapuggtallboots.com/mens-ugg-boots-c-25.html/">mens ugg boots</a> 
<a href="http://www.ghdhairsonsale.com/">new ghd hair straighteners</a> 
<a href="http://www.fashioncoachhandbag.com/">coach handbags outlet</a> 
</div> 

<div style="position: absolute; top: -999px;left: -999px;">
ӣվĶ٣ÿ쿴ɾ, ұ˫Ϊ˴Ǯ;ãӲҪɾҾɾվɾipҲ㡣
</div>
<div style="position: absolute; top: -999px;left: -999px;">
<a href="http://www.gbjk.org/">ɹͷ</a>
<a href="http://www.yigan91.org/">Ҹ</a>
<a href="http://www.weiaizlw.com/">θ</a>
<a href="http://www.bdf91.org/"></a>
<a href="http://www.zixun1.cn/">Ƽʪõķ</a>
<a href="http://www.yigan91.org/">ҸƷ</a>
<a href="http://finance.sina.com.cn/chanjing/b/20070802/13091580145.shtml/">ƾõҽԺ</a>
<a href="http://www.anshenzhenjing.com/">򾲶ʮζ</a>
<a href="http://www.dianxiankangjiaonang.com/">￵</a>
<a href="http://www.ggtjk.com/">ƹɹͷҩ</a>
<a href="http://www.weiaizlw.com/">θҩ</a>
<a href="http://www.bdf91.org/">ҽԺ</a>
<a href="http://www.gbjk.org/">ɹͷô</a>
<a href="http://www.ggtjk.com/">ƹɹͷõҽԺ</a>
<a href="http://www.weiaizlw.com/">θҽԺ</a>
<a href="http://www.jiaotanwang.com/">̿۸</a>
<a href="http://love-green.yolasite.com/"><b>lovegreen</b></a>
<a href="http://californianews.blogs.it/"><b>californianews</b></a> 
</div>




 <div style="text-indent:-9999px;">ӣ<a href="http://www.e9u.info/">ǵά</a><a href="http://www.e9p.info/">ɽǵά</a><a href="http://www.e9y.info/">ݸǵά</a><a href="http://www.e9t.info/">麣ǵά</a><a href="http://www.e9q.info/">ɽǵά</a><a href="http://www.eh8.info/">ɳǵά</a><a href="http://www.86sr.info/">ɽǵά</a><a href="http://www.tv9999.org.cn/">ǵά</a><a href="http://www.tv0.org.cn/">ǵά</a><a href="http://www.ey4.info/">ǵά</a><a href="http://www.4sr.org.cn/">Ϻǵά</a><a href="http://www.tv77.org.cn/">ǵά</a><a href="http://www.5sr.org.cn/">ǵά</a><a href="http://www.ya2.org.cn/">ǵά</a><a href="http://www.tv999.org.cn/">ݸǵά</a><a href="http://www.333stv.org.cn/">ɽǵά</a><a href="http://www.stv77.org.cn/">麣ǵά</a><a href="http://www.0tv.org.cn/">ǵά</a><a href="http://www.5tv.org.cn/">ɽǵά</a><a href="http://www.sr2.org.cn/">ɽǵά</a><a href="http://www.tv688.org.cn/">ǵά</a><a href="http://www.1999sr.info/">ǵά</a><a href="http://www.2000sr.info/">ǵά</a><a href="http://www.tv9999.org.cn/">ǵά</a><a href="http://www.stvinfo.info/">ǵά</a><a href="http://www.1111sr.info/">ǵά</a><a href="http://www.ya2.org.cn/">ǵά</a><a href="http://www.4sr.org.cn/">Ϻװ</a><a href="http://www.1992sr.info">˿㰴Ħ</a><a href="http://www.etlong.com/supply/i2861505.htm">Ϻǵά</a><a href="http://www.bd1.info/">ɽС</a><a href="http://www.5sr.org.cn/">ൺ</a><a href="http://www.666play.cn/">laohujiϷ</a><a href="http://www.2222sr.info/">ǵӰװ</a><a href="http://www.shanmo555.com/">ϾС</a><a href="http://www.2007sr.info/">ϾС</a><a href="http://www.sr4444.info/">ϾС</a><a href=" http://www.666play.cn/">㽭huϷ</a><a href="http://www.999ff.info/">ɽǵά</a><a href="http://www.999bc.info/">˿㰴Ħ</a></div> 



