<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>Green1Vfp 原创空间</title>
<link>http://blogger.org.cn/blog/blog.asp?name=lugreen</link>
<description>Green1的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[从XSource中掘金3（个人翻译）]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=14147</link>
<author>lugreen</author>
<pubDate>2006/5/7 11:28:00</pubDate>
<description><![CDATA[<P align=center><STRONG><FONT size=3>从XSource中掘金3</FONT></STRONG></P>
<P align=left><STRONG><FONT size=3>这篇文章介绍两个技术</FONT></STRONG></P>
<UL>
<LI>
<DIV align=left><STRONG><FONT size=3>在应用程序中实现自定义字段</FONT></STRONG></DIV></LI>
<LI>
<DIV align=left><STRONG><FONT size=3>创建自己的生成器</FONT></STRONG></DIV></LI></UL>
<P align=left><IMG src="http://blogger.org.cn/blog/images/file/zip.gif" border=0><A href="http://blogger.org.cn/blog/uploadfile/20065711340991.RAR" target=_blank>从XSource中淘金3.rar</A></P>]]></description>
</item><item>
<title><![CDATA[XSource中淘金2(个人翻译)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=13927</link>
<author>lugreen</author>
<pubDate>2006/4/28 17:46:09</pubDate>
<description><![CDATA[<P>这篇文章中讲了三个技术</P>
<OL>
<LI>在VFP中显示视频</LI>
<LI>在vfp中显示进度条</LI>
<LI>创建outlook风格的工具箱</LI></OL>
<P><IMG src="http://blogger.org.cn/blog/images/file/zip.gif" border=0><A href="http://blogger.org.cn/blog/uploadfile/200642817508621.RAR" target=_blank>从XSource中淘金2.rar</A></P>
<P>希望大家喜欢</P>]]></description>
</item><item>
<title><![CDATA[推荐几个优秀的国外VFP博客]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=13387</link>
<author>lugreen</author>
<pubDate>2006/4/11 21:05:14</pubDate>
<description><![CDATA[<UL>
<LI><A href="http://www.news2news.com/vfp/index.php" target=_blank>http://www.news2news.com/vfp/index.php</A><BR>介绍WIN32API在VFP中的应用，每个API函数都有示例，而且将API函数按功能进行了分类。</LI>
<LI><A href="http://blogs.msdn.com/calvin_hsia/default.aspx" target=_blank>http://blogs.msdn.com/calvin_hsia/default.aspx</A><BR>看看就知道了</LI></UL>
<P>继续搜集中</P>]]></description>
</item><item>
<title><![CDATA[VF中实现统计与明细切换实例]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=13318</link>
<author>lugreen</author>
<pubDate>2006/4/9 14:15:12</pubDate>
<description><![CDATA[
<P>很多场合需要实现实时统计及明细之间转换，达到总体概念和明细切换效果。现我就单位上实现年度统计功能说明一下自己的实现方法的实步思路： 
<P>一、涉及数据库： 
<LI>量具管理总台帐明细(ztz.dbf)、 
<LI>汇总年段(ZJ.DBF)、 
<LI>汇总数据表(ld.dbf) 
<P>二、实现基本思路：</P>
<LI>按选中的汇总年段（zj.dbf）,对总台帐(ztz.dbf)中 ztz.次检日期 ztz.所在班组 的月份和班组分类进行统计记录数（或汇总检定费）后的统计数据存放于年度汇总数据表(ld.dbf)，该数据表以数据环境方式在grid控件中显示。利用GRID控件中Afterrowcolchange事件自动记录下需查询的条件并用变量TJ进行保存，按显示明细就自动根据变量TJ的要求自动调用另一表单(mx.)使其显示具体明细。具体实现过程见附件：年度计划统计.rar 说明：由于该年度计划统计表单目前正在处于进一步的优化和完善中，还存在不足之处,请大家指出 
<P></P></LI>]]></description>
</item><item>
<title><![CDATA[XSource淘金(个人翻译)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=13312</link>
<author>lugreen</author>
<pubDate>2006/4/9 9:20:26</pubDate>
<description><![CDATA[<P align=center>　<STRONG><FONT size=5>XSource淘金</FONT></STRONG></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">VFP</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">随产品提供了大部分“</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Xbase</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">”工具的源码，包括类浏览器，代码引用，工具栏，和任务面板。查看由</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">VFP</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">高手写的代码常常可以使我们洞察新的、力量强大的代码技术。在这篇文章里，这个系列的第一篇文章，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Doung Hennig </SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Xsource </SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">中的各种文件向你展示可以用在你的应用程序中的很酷的方法和代码。这篇文章中你将学到如何使用资源文件保存自定义设置和如何创建面向对象的快捷菜单。</SPAN></P>
<P><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'"><IMG src="http://blogger.org.cn/blog/images/file/zip.gif" border=0><A href="http://blogger.org.cn/blog/uploadfile/20064910333662.RAR" target=_blank>从xSource中淘金.rar</A></SPAN></P>]]></description>
</item><item>
<title><![CDATA[根据显示器分辨率自动调整表单及控件的大小,使软件界面大小与设计时的比例保持一致]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=12667</link>
<author>lugreen</author>
<pubDate>2006/3/18 16:05:35</pubDate>
<description><![CDATA[
<P>有时我们会遇到这样的情况,在1024*768分辨率分设计的程序在800*600的分辨率下运行时窗口界面会变得很不协调</P>
<P>使用下面的代码可以解决这一问题</P>
<P><FONT color=#484848>LOCAL lnHeight, lnWidth, lnHeightdiff, lnWidthdiff <BR><BR>lnHeight = 480 &amp;&amp; 原分辩率下的控件高度 <BR>lnWidth = 640 &amp;&amp; 原分辩率下的控件宽度 <BR>lnHeightdiff = 0 &amp;&amp; 保存不同高度的变量 <BR>lnWidthdiff = 0 &amp;&amp; 保存不同宽度的变量 <BR><BR>IF SYSMETRIC(2) &lt;&gt; lnHeight &amp;&amp; 如果目前不是运行于 640x480 分辩率下 <BR>lnHeightDiff = SYSMETRIC(2) / lnHeight <BR>lnWidthDiff = SYSMETRIC(1) / lnWidth <BR><BR>** 如果是在容器对象(如页框中的页等非表单且具有 ControlsCount 属性的容器)的 Init 事件中, 你需要注 <BR>** 释掉以下代码直到 ENDIF 代码行. <BR><BR>This.Height = This.Height * lnHeightDiff <BR>This.Width = This.Width * lnWidthDiff <BR>This.Top = This.Top * lnHeightDiff <BR>This.Left = This.Left * lnHeightDiff <BR><BR>** 遍历各对象, 重新调整和安排它们. <BR><BR>FOR I = 1 TO This.ControlCount <BR>WITH This.Controls(i) <BR>.Height = .Height * lnHeightdiff <BR>.Width = .Width * lnWidthdiff <BR>.Top = .Top * lnHeightdiff <BR>.Left = .Left * lnWidthdiff <BR><BR>** 你也可以在这里修改 FontSize 属性来重调字体 <BR>** IF TYPE(".FontSize") # "U" <BR>** &amp;&amp; IF 用于确保控件具有 FontSize 属性 <BR>** .FontSize = .FontSize * ((.5 * lnWidthdiff) + (.5 * lnHeightdiff)) <BR>** ENDIF <BR>** 但是, 一些较高的屏幕分辩率会适当地修改字体外观, 因此在试以上代码前应进行测试. <BR><BR>ENDWITH <BR>ENDFOR <BR>ENDIF <BR><BR>ThisForm.Refresh() </FONT><BR></P>]]></description>
</item><item>
<title><![CDATA[通过 MENUHIT 和 MENUCONTEXT 扩展 VFP 9 IDE(转载)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=11777</link>
<author>lugreen</author>
<pubDate>2006/2/16 18:03:29</pubDate>
<description><![CDATA[<P><A><STRONG>　</STRONG></A><STRONG><FONT size=5>通过 MENUHIT 和 MENUCONTEXT 扩展 VFP 9 IDE</FONT></STRONG></P>
<DIV class=date>发布日期： 12/23/2004<SPAN class=datePipe> | </SPAN>更新日期： 12/23/2004</DIV>
<DIV class=overview>
<P><I>Doug Hennig</I></P>
<P><B>VFP 9 中的关键主题之一是可扩展性。您可以通过报告事件扩展报表设计器，以及通过新的 ReportListener 基类扩展报告引擎。而现在，您甚至可以通过捕获系统和快捷菜单点击来扩展 IDE。本月，Doug Hennig 说明了如何用您从未想到过的方式自定义 VFP 9 IDE。</B></P></DIV>
<CENTER><IMG title="" height=6 alt=* src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width=30 border=0></CENTER>
<DIV style="HEIGHT: 18px"></DIV>
<H5 style="PADDING-TOP: 2px">本页内容</H5>
<P>
<TABLE style="MARGIN-TOP: 7px; MARGIN-BOTTOM: 12px" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#ELAA"><IMG height=9 alt=MENUHIT hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#ELAA">MENUHIT</A></TD></TR>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EKAA"><IMG height=9 alt="MENUHIT 前景光明" hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EKAA">MENUHIT 前景光明</A></TD></TR>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EJAA"><IMG height=9 alt=它有什么好处呢？ hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EJAA">它有什么好处呢？</A></TD></TR>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EIAA"><IMG height=9 alt=MENUCONTEXT hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EIAA">MENUCONTEXT</A></TD></TR>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EHAA"><IMG height=9 alt="替换 Project Manager 快捷菜单" hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EHAA">替换 Project Manager 快捷菜单</A></TD></TR>
<TR vAlign=top>
<TD><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EGAA"><IMG height=9 alt=小结 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A></TD>
<TD class=onThisPage><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#EGAA">小结</A></TD></TR></TBODY></TABLE></P>
<P>VFP 长期以来提供了挂钩到交互式开发环境 (IDE) 各方面的方式，并且在每个版本中都得到了改善。FoxPro 2.x 允许我们通过更改系统变量（例如，_GENSCRN 和 _GENMENU）所指向的应用程序的名称，来替换某些 Xbase 组件的功能。VFP 3 为我们提供了生成器，它使我们可以自动执行或简化类和窗体的处理。 </P>
<P>VFP 6 添加了项目钩子，从而使我们可以在用户在 Project Manager 中执行某些操作（例如，添加或删除文件）时接收事件。智能感知是 VFP 7 中的主要新功能之一，我们可以通过数据驱动的方法轻松地对该功能进行扩展。VFP 8 添加了可自定义的工具箱和其他有用的 IDE 增强功能。</P>
<P>但是，在 VFP 9 中，Microsoft 已经开启了 IDE 的先例。因为报表设计器可引发报告事件，所以我们可以完全更改其对话框的外观和行为。通过新的 ReportListener 基类，我们可以在报表运行时接收事件，并且可以提供许多功能，例如，标签旋转、动态格式化以及自定义呈现对象（如图形）。不久，我们还能够通过对 BINDEVENT() 进行的增强来响应 Windows 事件；该功能在本文撰写之际尚不可用，但是将为我们提供对 Windows OS 事件（包含那些与 VFP IDE 有关且涉及到具有 hWnd 的窗口的事件）的更好访问方式。</P>
<P>但是，本文讨论的重点是挂钩到系统菜单点击（即，当用户从 VFP 系统菜单栏选择项时）和系统快捷菜单（那些通过右键单击各种位置 — 例如，“Properties”窗口或数据库设计器 — 而显示的菜单）中。我将首先分析如何完成该工作，然后给出一些实际的示例。</P><A name=ELAA></A>
<H2>MENUHIT</H2>
<P>要捕获系统菜单点击，需要在智能感知表中用 TYPE = "S"（对于 "script"）、ABBREV = "MENUHIT" 以及要在 DATA memo 字段中执行的代码创建一个脚本记录。（智能感知表由 _FOXCODE 系统变量指示；默认情况下，它是 HOME(7) 目录中的 FOXCODE.DBF。）该代码应当接受一个对象作为参数。该对象具有几个属性，但是与 MENUHIT 有关的重要属性则显示在<B>表 1</B> 中。</P>
<P>
<TABLE class=dataTable id=EHLAA cellSpacing=0 cellPadding=0>
<THEAD>
<TR>
<TD class=tableHeader colSpan=2>表 1. 传递到 MENUHIT 脚本的参数对象的属性提供了有关菜单点击的信息。</TD></TR>
<TR class=stdHeader vAlign=top>
<TD id=colEBBHLAA>属性</TD>
<TD id=colEABHLAA style="BORDER-RIGHT: #cccccc 1px solid">说明</TD></TR></THEAD>
<TBODY>
<TR class=record vAlign=top>
<TD>
<P class=lastInCell>UserTyped</P></TD>
<TD style="BORDER-RIGHT: #cccccc 1px solid">
<P class=lastInCell>菜单点击所源自的面板的提示。</P></TD></TR>
<TR class=evenRecord vAlign=top>
<TD>
<P class=lastInCell>MenuItem</P></TD>
<TD style="BORDER-RIGHT: #cccccc 1px solid">
<P class=lastInCell>用户选择的栏的提示。</P></TD></TR>
<TR class=record vAlign=top>
<TD>
<P class=lastInCell>ValueType</P></TD>
<TD style="BORDER-RIGHT: #cccccc 1px solid">
<P class=lastInCell>提供给 VFP 的返回值 — 空值意味着继续执行默认行为，而“V”或“L”意味着禁止默认行为（类似于使用类代码中的 NODEFAULT）。</P></TD></TR></TBODY></TABLE></P>
<DIV class=dataTableBottomMargin></DIV>
<P>下面是一个简单示例（取自 SimpleMenuHit.PRG，它包含在本月的下载文件中）：</P><PRE class=codeSample>text to lcCode noshow
lparameters toParameter
wait window 'Pad: ' + toParameter.UserTyped + ;
  chr(13) + 'Bar: ' + toParameter.MenuItem
endtext
delete from (_foxcode) where TYPE = 'S' and ;
  ABBREV = 'MENUHIT'
insert into (_foxcode) ;
    (TYPE, ABBREV, DATA) ;
  values ;
    ('S', 'MENUHIT', lcCode)
</PRE>
<P>上述代码只是显示所选菜单项的面板提示和栏提示，然后继续执行该项的默认行为。这对于测试很适用，但是在“实际的”代码中，您可能希望禁用默认行为，并将其替换为您自己的行为。在这种情况下，请将参数对象的 ValueType 属性设置为“V”或“L”。（如果您想知道为什么有两个可能的值，这是因为这些值由智能感知管理器用于其他目的，并且 VFP 团队决定对 MENUHIT 使用相同的机制。您具体使用哪一个值并没有什么关系。）</P>
<P>下面这个示例取自 DisableExit.PRG，它禁用了“File”菜单中的“Exit”功能（您也许可以使用它来对某位同事开一个愚人节玩笑）：</P><PRE class=codeSample>text to lcCode noshow
lparameters toParameter
if toParameter.UserTyped = 'File' and ;
  toParameter.MenuItem = 'Exit'
  toParameter.ValueType = 'V'
endif toParameter.UserTyped = 'File' ...
endtext
delete from (_foxcode) where TYPE = 'S' and ;
  ABBREV = 'MENUHIT'
insert into (_foxcode) ;
    (TYPE, ABBREV, DATA) ;
  values ;
    ('S', 'MENUHIT', lcCode)
</PRE>
<P>尽管这看起来是正确的，但当您从“File”菜单中选择“Exit”时，VFP 无论如何都将退出。经研究发现，除了将 ValueType 设置为“V”或“L”以外，某些函数还要求 MENUHIT 代码返回 .T. 以阻止默认行为。在 ENDIF 语句之前添加 RETURN .T. 可防止“Exit”关闭 VFP。</P>
<P>另一个 MENUHIT 问题如下所述：如果您要使用 VFP 的本地化版本（例如，德语版本），该怎么办呢？在这种情况下，检查“File”和“Exit”时不会正常工作，这是因为它们不是出现在菜单中的提示。如果您要将 MENUHIT 脚本分发给其他 VFP 开发人员，则您必须知道这个问题，或者必须让您的目标受众知道这个问题。</P>
<DIV style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top">返回页首</A></DIV><A name=EKAA></A>
<H2>MENUHIT 前景光明</H2>
<P>尽管我们正在讨论将 MENUHIT 脚本分发给其他人的主题，但如果您具有一个能够出色完成任务的脚本，而其他某个人也具有这样的脚本，并且您希望同时使用这两个脚本，那么该怎么办呢？问题在于只能有一个 MENUHIT 记录（如果存在一个以上的记录，则 VFP 将使用智能感知表中的第一个记录）。因此，我认为更好的做法是让 MENUHIT 记录委托给其他某个对象，而不是直接执行所需的 IDE 自定义。 </P>
<P>完成该任务的最简单方式是向智能感知表中添加其他记录，并且让 MENUHIT 记录使用它们来执行实际的任务。尽管可以任意选择，但我觉得带有 TYPE = “M” 的记录应该适合该需要，因为 “M” 代表“菜单”，并且不是该表中当前使用的记录类型。例如，要处理 Exit 功能，可以添加一个带有 TYPE = “M”、ABBREV = “Exit” 的记录，以及要在 DATA 中执行的代码。</P>
<P>要使该方式可行，我们需要一个“标准的”MENUHIT 记录。与该记录对应的代码在表中查找带有 TYPE = “M” 并且将 ABBREV 设置为用户所选栏的提示的记录，如果该记录存在，则在 DATA memo 中执行代码。以下为处理该操作的代码：</P><PRE class=codeSample>lparameters toParameter
local lnSelect, ;
  lcCode, ;
  llReturn
try
  lnSelect = select()
  select 0
  use (_foxcode) again shared order 1
  if seek('M' + padr(upper(toParameter.MenuItem), ;
    len(ABBREV)))
    lcCode = DATA
  endif seek('M' ...
  use
  select (lnSelect)
  if not empty(lcCode)
    llReturn = execscript(lcCode, toParameter)
    if llReturn
      toParameter.ValueType = 'V'
    endif llReturn
  endif not empty(lcCode)
catch
endtry
return llReturn
</PRE>
<P>运行 StandardMenuHit.PRG 以将该代码安装到智能感知表中。关于该代码，有几个有趣的事情。首先，我通常使用 ORDER &lt;tag name&gt; （而不是 ORDER &lt;N&gt;）来设置表的顺序。但是，智能感知表不同寻常：如果您打开该表并使用 ATAGINFO() 来检索有关该表索引的信息，则将看到有两个标记，并且它们都标记为主标记且不具有标记名称。因此，您必须使用 ORDER 1 或 ORDER 2 来设置该表的顺序。 </P>
<P>第二件事情是，将代码包装在 TRY 结构中以防止任何错误，例如，在打开表时出现的问题或者可能存在于另一个记录的代码中的错误。 </P>
<P>第三个问题是，该代码不检查用户的菜单选择所源自的面板的提示，而只检查栏提示。这是因为我出于性能原因而决定进行 SEEK，并且所使用的标记是 UPPER(TYPE + ABBREV)。由于这是一个小表，因此您或许可以将面板提示放到 EXPANDED 列中，并使用 LOCATE FOR TYPE = “M” AND ABBREV = toParameter.MenuItem AND EXPANDED = toParameter.UserTyped 来确保找到确切的记录，而不会产生什么后果。</P>
<P>到本期截止时间为止，Microsoft 尚未决定在默认情况下是否有这样一个“标准的”MENUHIT 记录将存在于智能感知表中。如果没有，则他们可能会提供一种添加此类记录的简单方式，例如，通过解决方案示例添加。（解决方案示例是用于展示各种 VFP 功能的示例，并且可以通过任务窗格管理器轻松地访问。）</P>
<P>下面讨论最后一个 MENUHIT 问题：如果 DATA memo 字段中的代码具有任何编译错误，您将不会获得错误信息 — VFP 将简单地忽略该代码并使用默认行为。当然，这可能是令人讨厌的，因为您可能无法完全确定代码为什么没有执行您期望的操作。</P>
<DIV style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top">返回页首</A></DIV><A name=EJAA></A>
<H2>它有什么好处呢？</H2>
<P>对，这样我们就可以挂钩到 VFP 菜单项中。我们可以使用该机制做什么呢？</P>
<P>我所想到的第一件事情就是替换“New Property”和“New Method”对话框。因为我们现在能够保留自定义属性和方法的大小写以进行显示（请参阅我的 2004 年 6 月刊 <I>FoxTalk 2.0</I> 专栏“MemberData and Custom Property Editors”），所以我宁愿让 VFP 使用我输入到“New Property”或“New Method”对话框中的大小写，以避免启动 MemberData 编辑器并在其中更改大小写的额外步骤。而且，由于我必须单击“Add”按钮来添加新的属性或方法，然后单击“Close”按钮来关闭对话框，因此这总是让我感到苦恼。因为我通常一次只添加一个属性或方法，所以希望看到既能添加成员又能关闭对话框的按钮。</P>
<P>由于 MENUHIT 方法现在允许我们捕获“Form”和“Class”菜单中的“New Property”和“New Method”项，因此我们应当能够创建完全按照我们所希望的方式操作的替换对话框。<A href="http://msdn.microsoft.com/library/en-us/dnfoxtk04/html/409hennig1_FT04i.jpg" target=_blank><B>图 1</B></A> 显示了这样一个对话框，它具有下列功能：</P>
<P>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它可以自动更新 _MemberData 属性（如果需要，则添加该属性），因此将使用为新成员输入的大小写（甚至还将使用为访问和分配方法输入的大小写 — 如果也创建它们的话），并且该成员将显示在“Favorites”选项卡上（如果在对话框中启用了该选项）。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它是非模式对话框。这意味着，您可以使其保持打开状态，添加一些属性或方法，切换到其他界面元素，返回以及添加更多的成员。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它是可停靠的：请尝试通过“Properties”窗口来停靠它。这非常棒！ </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它的大小可以调整，并且可以将它的大小和位置保存到资源 (FOXUSER) 文件中。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它具有一个“Add &amp; Close”按钮，能够通过一次单击执行这两项任务。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>属性的默认值会基于该属性的数据类型自动设置为某个值（如果您使用匈牙利表示法）。例如，lTest 是逻辑类型，因此默认值为 .F.。对于 nTest，默认值为 0。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>它隐藏而不是禁用不适用的控件。由于这个对话框同时用于类设计器和窗体设计器中的“New Property”和“New Method”，因此对于给定实例，某些选项可能不适用。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>当您输入名称而不是单击“Add”或“Add &amp; Close”时，它将拒绝接受无效名称。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>“Add”按钮仅在您输入名称时启用。 </P></TD></TR></TBODY></TABLE></P>
<P>我们将不会考察构成 NewPropertyDialog.APP 的代码。它并不复杂；在核心部分，它调用在类设计器或窗体设计器中编辑的对象的 AddProperty 和 WriteMethod 方法，以便添加新的属性或方法。这两个方法都接受 VFP 9 中的两个新参数：可见性（1 代表公用，2 代表受保护，3 代表隐藏）以及新属性或方法的说明。</P>
<P>要使用替换对话框，只须“执行”NewPropertyDialog.APP 以便在智能感知表中注册它。它会添加前面讨论的 MENUHIT 记录以及两个在 DATA 中具有相同代码的记录（一个用于“New Property”，另一个用于“New Method”），以便使用 NewPropertyDialog 类。在该代码中，“&lt;path&gt;”表示系统中 NewPropertyDialog.APP 的路径（该应用程序在运行时自动插入正确的路径）。</P><PRE class=codeSample>lparameters toParameter
local llReturn, ;
  llMethod, ;
  llClass
try
  llMethod = toParameter.MenuItem  = 'New Method'
  llClass  = toParameter.UserTyped = 'Class'
  release _oNewProperty
  public _oNewProperty
  _oNewProperty = newobject('NewPropertyDialog', ;
    'NewProperty.vcx', ;
    'NewPropertyDialog.app', llMethod, llClass)
  _oNewProperty.Show()
  llReturn = .T.
catch
endtry
return llReturn
</PRE>
<P>现在，当您从“Form”或“Class”菜单中选择“New Property”或“New Method”时，您将获得新的对话框而不是原有的那个。</P>
<DIV style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top">返回页首</A></DIV><A name=EIAA></A>
<H2>MENUCONTEXT</H2>
<P>除了挂钩到 VFP 系统菜单中的选择以外，您还可以捕获系统快捷菜单，例如，当您右键单击“Properties”窗口时显示的那个快捷菜单。这是使用与 MENUHIT 相同的机制完成的，不同之处在于，智能感知表中的 ABBREV 字段包含“MENUCONTEXT”而不是“MENUHIT”。 </P>
<P>与 MENUHIT 一样，MENUCONTEXT 记录的代码应当接受一个对象参数。在这种情况下，有三个需要注意的属性：Item — 显示在快捷菜单中的提示数组；ValueType — 具有与在 MENUHIT 中相同的用途；MenuItem — 快捷菜单的 ID。 </P>
<P>MenuItem 的一些值为：对应于“Command”窗口中的快捷菜单的“24446”，对应于 Project Manager 的快捷菜单的“24447”，以及对应于“Properties”窗口的快捷菜单的“24456”。我是如何发现这些值的？我用只显示 toParameter.MenuItem 值的代码创建了一个 MENUCONTEXT 记录，然后右键单击各个位置。与 MENUHIT 一样，您应当将 ValueType 设置为“V”或“L”，并且返回 .T. 以禁止原生行为（显示快捷菜单）。</P>
<P>MENUCONTEXT 的使用不像 MENUHIT 那么容易，这有多种原因。首先，更改 Item 数组的内容不会更改菜单的显示。例如，下面的代码似乎不会对快捷菜单产生任何作用：</P><PRE class=codeSample>lparameters toParameter
toParameter.Items[1] = 'My Bar'
</PRE>
<P>类似地，以下代码也不会在菜单中产生新栏：</P><PRE class=codeSample>lparameters toParameter
lnItems = alen(toParameter.Items) + 1
dimension toParameter.Items[lnItems]
toParameter.Items[lnItems] = 'My Bar'
</PRE>
<P>其次，当某个栏被选定时，没有办法更改所发生的事情。例如，您可能希望“Command”窗口快捷菜单的“Properties”栏显示您的对话框而不是原生对话框。问题在于，参数对象的属性中没有一个指定当菜单项被选择时应该执行的操作 — 该内容被内置到菜单本身中。</P>
<P>因此，看起来我们更改菜单的唯一方式就是使用我们自己的快捷菜单，并随后禁止原生行为。但是，该方法有一个新问题：由于您必须用自己的菜单替换整个菜单，因此当您的一些菜单项被选择时，您如何告诉 VFP 使用原生行为？在撰写本文之际，似乎没有任何能够完成该任务的办法，因此我怀疑 MENUCONTEXT 将只在极少数情况下使用。</P>
<DIV style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top">返回页首</A></DIV><A name=EHAA></A>
<H2>替换 Project Manager 快捷菜单</H2>
<P>即使存在上述问题，我们还是要尝试一个示例。在我的 2000 年 5 月刊 <I>FoxTalk</I> 文章“Zip it, Zip it Good”中，我介绍了一个能够将所有基于表的文件（例如，VCX、SCX 和 FRX 文件）打包到一个项目中的实用工具，以及另一个能够将某个项目中引用的所有文件压缩到一个 ZIP 文件中的实用工具。在该文章中，这些实用工具是从特定于项目的项目挂钩所显示的工具栏中调用的。让我们改而将它们放到将供任何项目使用的快捷菜单中。</P>
<P>MENUCONTEXT 具有与 MENUHIT 相同的潜在冲突问题，因此我们将使用相同的解决方案：一个简单地委托给特定快捷菜单的另一个记录的“标准”记录。实际上，该标准记录的代码与 MENUHIT 记录的代码完全相同（运行 StandardMenuContext.PRG 来创建 MENUCONTEXT 记录）。但是，我们不是将栏提示放到处理程序记录的 ABBREV 字段中，而是放置菜单 ID。（您可能希望将菜单用途 — 例如“命令窗口”— 放到 EXPANDED 字段中，以表明该记录的用途。）</P>
<P>在创建 MENUCONTEXT 记录之后，我用 TYPE = “M”、ABBREV = "24447"（Project Manager 的快捷菜单的 ID）和 DATA 中的以下代码创建了一个记录：</P><PRE class=codeSample>lparameters toParameter
local loMenu
loMenu = newobject('_ShortcutMenu', ;
  home() + 'ffc\_menu.vcx')
loMenu.AddMenuBar('\&lt; loMenu.ShowMenu() plain?) ?{CTRL+J}? ?keyboard ; \
</PRE>
<P>上述代码使用 FFC（FoxPro 基础类）_ShortcutMenu 类来提供快捷菜单。我在 1999 年 2 月刊 <I>FoxTalk</I> 文章“A Last Look at the FFC”中讨论了该类。运行 ProjectMenu.PRG 以便在智能感知表中创建该记录。</P>
<P>当您右键单击 Project Manager 时，新的自定义菜单将显示三个栏（请参见<A href="http://msdn.microsoft.com/library/en-us/dnfoxtk04/html/409hennig2_FT04i.jpg" target=_blank><B>图 2</B></A>）：Pack Project — 它用当前项目文件的名称调用 PACKPROJ.PRG；Zip Project — 它用当前项目文件的名称调用 ZIPPROJ.PRG；Project Info — 它使用 KEYBOARD 命令来调用“Project”菜单中的“Project Info”对话框。（后一个功能说明，您可以在原生快捷菜单中再现某个栏的功能 — 前提是存在它所调用的系统菜单功能。）</P>
<DIV style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><A href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/langtool/FoxPro/usft04i5.mspx#top">返回页首</A></DIV><A name=EGAA></A>
<H2>小结</H2>
<P>通过新的 MENUHIT 和 MENUCONTEXT 功能，较之以前，我们可以更紧密地挂钩到 VFP IDE 中。除了我在本文中介绍的用法以外，我还可以发现“Edit Property/Method”对话框以及“File”菜单中的“New”、“Import”和“Export”功能的替换方法。我肯定您能够想出用不同于 VFP 9 中的方法实现的 IDE 功能；请让我知道您对于这一出色的新功能都有哪些想法。</P>
<P><B>下载 </B><A href="http://download.microsoft.com/download/5/d/3/5d32aa05-5b4a-4ec7-8a3b-de511fedde38/FT04-09Hennig.exe" target=_blank>409HENNIG.ZIP</A></P>
<P>有关 FoxTalk 和 Pinnacle Publishing 的详细信息，请访问它们位于 http://www.pinpub.com/ 的 Web 站点。</P>
<P>注：这不是 Microsoft Corporation Web 站点。Microsoft 对该 Web 站点的内容不承担责任。</P>
<P>本文是从 FoxTalk 2004 年 9 月刊转载的。版权所有 2004，Pinnacle Publishing, Inc.（除非另行说明）。保留所有权利。FoxTalk 是 Pinnacle Publishing, Inc. 独立发行的产品。未经 Pinnacle Publishing, Inc. 事先同意，不得以任何形式使用或复制本文的任何部分（评论文章中的简短引用除外）。要联系 Pinnacle Publishing, Inc.，请致电 1-800-788-1900。</P>
<P><A href="http://msdn.microsoft.com/vfoxpro/default.aspx?pull=/library/en-us/dnfoxtk04/html/ft04i5.asp" target=_blank>转到原英文页面</A></P>]]></description>
</item><item>
<title><![CDATA[VFP9中的MemberData(个人翻译)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=11746</link>
<author>lugreen</author>
<pubDate>2006/2/15 10:47:55</pubDate>
<description><![CDATA[<P align=center><A><STRONG><FONT size=6>　</FONT></STRONG></A><STRONG><FONT size=6>VFP9中的MemberData</FONT></STRONG></P>
<P dir=ltr style="MARGIN-RIGHT: 0px">VFP9为类的属性和方法提供了扩展的元数据属性。通过这个新的扩展模型，现在你可以增强类的属性和方法的功能，允许你对设计时功能进行增强，如：</P>
<UL>
<LI>指定一个自定义的属性编辑器。</LI>
<LI>把一个属性、事件或方法添加到新的'Favorites'属性窗口标签。</LI>
<LI>控件自定义方法或属性在属性窗口和智能感应窗口中的显示。</LI>
<LI>扩展用户自定义属性</LI></UL>
<P>(待续)</P>]]></description>
</item><item>
<title><![CDATA[纯真IP数据库格式详解(转载)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=10306</link>
<author>lugreen</author>
<pubDate>2005/12/1 20:17:52</pubDate>
<description><![CDATA[
<CENTER>
<H1>纯真IP数据库格式详解(转载)</H1></CENTER>
<CENTER></CENTER>
<BLOCKQUOTE><B>摘要</B> <BR>网络上的IP数据库以纯真版的最为流行，LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础。不过关于其格式的文档却非常之少，后来终于在网上找到了一份文档，得以了解其内幕，不过那份文档寥寥数语，也是颇为耐心才读明白。在这里我重写一份，以此做为LumaQQ开发者文档的一部分，我想还是必要的。本文详细介绍了纯真IP数据库的格式，并且给出了一些Demo以供参考。 
<P><B>Luma, 清华大学<BR></B>修改日期： 2005/01/14</P>
<P>Note: 在此感谢纯真IP数据库作者金狐和那唯一一份文档的作者。</P><B>修改历史:</B><BR>2005-01-14 修改了原来一些表达不清和错误的地方 </BLOCKQUOTE>
<P>
<HR width="100%">

<P>自从有了IP数据库这种东西，QQ外挂的显示IP功能也随之而生，本人见识颇窄，是否还有其他应用不得而知，不过，IP数据库确实是个不错的东西。如今网络上最流行的IP数据库我想应该是纯真版的（说错了也不要扁我），迄今为止其IP记录条数已经接近30000，对于有些IP甚至能精确到楼层，不亦快哉。2004年4、5月间，正逢LumaQQ破土动工，为了加上这个人人都喜欢，但是好像人人都不知道为什么喜欢的显IP功能，我也采用了纯真版IP数据库，它的优点是记录多，查询速度快，它只用一个文件QQWry.dat就包含了所有记录，方便嵌入到其他程序中，也方便升级。</P>
<H3>基本结构</H3>
<P>QQWry.dat文件在结构上分为3块：文件头，记录区，索引区。一般我们要查找IP时，先在索引区查找记录偏移，然后再到记录区读出信息。由于记录区的记录是不定长的，所以直接在记录区中搜索是不可能的。由于记录数比较多，如果我们遍历索引区也会是有点慢的，一般来说，我们可以用二分查找法搜索索引区，其速度比遍历索引区快若干数量级。图1是QQWry.dat的文件结构图。</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/qqwry_dat_overview.gif" border=0><BR><BR>图1. QQWry.dat文件结构</CENTER>
<P>要注意的是，QQWry.dat里面全部采用了little-endian字节序</P>
<H3>一. 了解文件头</H3>
<P>QQWry.dat的文件头只有8个字节，其结构非常简单，首四个字节是第一条索引的绝对偏移，后四个字节是最后一条索引的绝对偏移。</P>
<H3>二. 了解记录区</H3>
<P>每条IP记录都由国家和地区名组成，国家地区在这里并不是太确切，因为可能会查出来“清华大学计算机系”之类的，这里清华大学就成了国家名了，所以这个国家地区名和IP数据库制作的时候有关系。所以记录的格式有点像QName，有一个全局部分和局部部分组成，我们这里还是沿用国家名和地区名的说法。</P>
<P>于是我们想象着一条记录的格式应该是: [IP地址][国家名][地区名]，当然，这个没有什么问题，但是这只是最简单的情况。很显然，国家名和地区名可能会有很多的重复，如果每条记录都保存一个完整的名称拷贝是非常不理想的，所以我们就需要重定向以节省空间。所以为了得到一个国家名或者地区名，我们就有了两个可能：第一就是直接的字符串表示的国家名，第二就是一个4字节的结构，第一个字节表明了重定向的模式，后面3个字节是国家名或者地区名的实际偏移位置。对于国家名来说，情况还可能更复杂些，因为这样的重定向最多可能有两次。</P>
<P>那么什么是重定向模式？根据上面所说，一条记录的格式是[IP地址][国家记录][地区记录]，如果国家记录是重定向的话，那么地区记录是有可能没有的，于是就有了两种情况，我管他叫做模式1和模式2。我们对这些格式的情况举图说明：</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/ip_record_1.gif" border=0><BR><BR>图2. IP记录的最简单形式</CENTER>
<P>图2表示了最简单的IP记录格式，我想没有什么可以解释的</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/ip_record_2.gif" border=0><BR><BR>图3. 重定向模式1</CENTER>
<P>图3演示了重定向模式1的情况。我们看到在模式1的情况下，地区记录也跟着国家记录走了，在IP地址之后只剩下了国家记录的4字节，后面3个字节构成了一个指针，指向了实际的国家名，然后又跟着地址名。模式1的标识字节是0x01。</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/ip_record_3.gif" border=0><BR><BR>图4. 重定向模式2</CENTER>
<P>图4演示了重定向模式2的情况。我们看到了在模式2的情况下（其标识字节是0x02），地区记录没有跟着国家记录走，因此在国家记录之后4个字节之后还是有地区记录。我想你已经明白了模式1和模式2的区别，即：模式1的国家记录后面不会再有地区记录，模式2的国家记录后会有地区记录。下面我们来看一下更复杂的情况。</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/ip_record_5.gif" border=0><BR><BR>图5. 混和情况1</CENTER>
<P>图5演示了当国家记录为模式1的时候可能出现的更复杂情况，在这种情况下，重定向指向的位置仍然是个重定向，不过第二次重定向为模式2。大家不用担心，没有模式3了，这个重定向也最多只有两次，并且如果发生了第二次重定向，则其一定为模式2，而且这种情况只会发生在国家记录上，对于地区记录，模式1和模式2是一样的，地区记录也不会发生2次重定向。不过，这个图还可以更复杂，如图7：</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/ip_record_6.gif" border=0><BR><BR>图6. 混和情况2</CENTER>
<P>图6是模式1下最复杂的混和情况，不过我想应该也很好理解，只不过地区记录也来重定向而已，有一点我要提醒你，如果重定向的地址是0，则表示未知的地区名。</P>
<P>所以我们总结如下：一条IP记录由[IP地址][国家记录][地区记录]组成，对于国家记录，可以有三种表示方式：字符串形式，重定向模式1和重定向模式2。对于地区记录，可以有两种表示方式：字符串形式和重定向，另外有一条规则：重定向模式1的国家记录后不能跟地区记录。按照这个总结，在这些方式中合理组合，就构成了IP记录的所有可能情况。</P>
<H3>设计的理由</H3>
<P>在我们继续去了解索引区的结构之前，我们先来了解一下为何记录区的结构要如此设计。我想你可能想到了答案：字符串重用。没错，在这种结构下，对于一个国家名和地区名，我只需要保存其一次就可以了。我们举例说明，为了表示方便，我们用小写字母代表IP记录，C表示国家名，A表示地区名： 
<OL>
<LI>有两条记录a(C1, A1), b(C2, A2)，如果C1 = C2, A1 = A2，那么我们就可以使用图3显示的结构来实现重用 
<LI>有三条记录a(C1, A1), b(C2, A2), c(C3, A3)，如果C1 = C2, A2 = A3，现在我们想存储记录b，那么我们可以用图6的结构来实现重用 
<LI>有两条记录a(C1, A1), b(C2, A2)，如果C1 = C2，现在我们想存储记录b，那么我们可以采用模式2表示C2，用字符串表示A2 </LI></OL>
<P></P>
<P>你可以举出更多的情况，你也会发现在这种结构下，不同的字符串只需要存储一次。</P>
<H3>了解索引区</H3>
<P>在"了解文件头"部分，我们说明了文件头实际上是两个指针，分别指向了第一条索引和最后一条索引的绝对偏移。如图8所示：</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/header_to_index.gif" border=0><BR><BR>图8. 文件头指向索引区图示</CENTER>
<P>实在是很简单，不是吗？从文件头你就可以定位到索引区，然后你就可以开始搜索IP了！每条索引长度为7个字节，前4个字节是起始IP地址，后三个字节就指向了IP记录。这里有些概念需要说明一下，什么是起始IP，那么有没有结束IP？ 假设有这么一条记录：166.111.0.0 - 166.111.255.255，那么166.111.0.0就是起始IP，166.111.255.255就是结束IP，结束IP就是IP记录中的那头4个字节，这下你应该就清楚了吧。于是乎，每条索引配合一条记录，构成了一个IP范围，如果你要查找166.111.138.138所在的位置，你就会发现166.111.138.138落在了166.111.0.0 - 166.111.255.255 这个范围内，那么你就可以顺着这条索引去读取国家和地区名了。那么我们给出一个最详细的图解吧：</P>
<CENTER><IMG alt="" src="http://lumaqq.linuxsir.org/article/images/1/overall_format.gif" border=0><BR><BR>图9. 文件详细结构</CENTER>
<P>现在一切都清楚了是不是？也许还有一点你不清楚，QQWry.dat的版本信息存在哪里呢？ 答案是：最后一条IP记录实际上就是版本信息，最后一条记录显示出来就是这样：255.255.255.0 255.255.255.255 纯真网络 2004年6月25日IP数据。OK，到现在你应该全部清楚了。</P>
<H3>Demo</H3>
<P>下一步：我给出一个读取IP记录的程序片断，此片断摘录自LumaQQ源文件edu.tsinghua.lumaqq.IPSeeker.java，如果你有兴趣，可以下载源代码详细看看。</P><PRE>	/**
	 * 给定一个ip国家地区记录的偏移，返回一个IPLocation结构
	 * @param offset 国家记录的起始偏移
	 * @return IPLocation对象
	 */
	private IPLocation getIPLocation(long offset) {
		try {
			// 跳过4字节ip
			ipFile.seek(offset + 4);
			// 读取第一个字节判断是否标志字节
			byte b = ipFile.readByte();
			if(b == REDIRECT_MODE_1) {
				// 读取国家偏移
				long countryOffset = readLong3();
				// 跳转至偏移处
				ipFile.seek(countryOffset);
				// 再检查一次标志字节，因为这个时候这个地方仍然可能是个重定向
				b = ipFile.readByte();
				if(b == REDIRECT_MODE_2) {
					loc.country = readString(readLong3());
					ipFile.seek(countryOffset + 4);
				} else
					loc.country = readString(countryOffset);
				// 读取地区标志
				loc.area = readArea(ipFile.getFilePointer());
			} else if(b == REDIRECT_MODE_2) {
				loc.country = readString(readLong3());
				loc.area = readArea(offset + 8);
			} else {
				loc.country = readString(ipFile.getFilePointer() - 1);
				loc.area = readArea(ipFile.getFilePointer());
			}
			return loc;
		} catch (IOException e) {
			return null;
		}
	}	

	/**
	 * 从offset偏移开始解析后面的字节，读出一个地区名
	 * @param offset 地区记录的起始偏移
	 * @return 地区名字符串
	 * @throws IOException 地区名字符串
	 */
	private String readArea(long offset) throws IOException {
		ipFile.seek(offset);
		byte b = ipFile.readByte();
		if(b == REDIRECT_MODE_1 || b == REDIRECT_MODE_2) {
			long areaOffset = readLong3(offset + 1);
			if(areaOffset == 0)
				return LumaQQ.getString("unknown.area");
			else
				return readString(areaOffset);
		} else
			return readString(offset);
	}

	/**
	 * 从offset位置读取3个字节为一个long，因为java为big-endian格式，所以没办法
	 * 用了这么一个函数来做转换
	 * @param offset 整数的起始偏移
	 * @return 读取的long值，返回-1表示读取文件失败
	 */
	private long readLong3(long offset) {
		long ret = 0;
		try {
			ipFile.seek(offset);
			ipFile.readFully(b3);
			ret |= (b3[0] &amp; 0xFF);
			ret |= ((b3[1] &lt;&lt; 8) &amp; 0xFF00);
			ret |= ((b3[2] &lt;&lt; 16) &amp; 0xFF0000);
			return ret;
		} catch (IOException e) {
			return -1;
		}
	}	
	
	/**
	 * 从当前位置读取3个字节转换成long
	 * @return 读取的long值，返回-1表示读取文件失败
	 */
	private long readLong3() {
		long ret = 0;
		try {
			ipFile.readFully(b3);
			ret |= (b3[0] &amp; 0xFF);
			ret |= ((b3[1] &lt;&lt; 8) &amp; 0xFF00);
			ret |= ((b3[2] &lt;&lt; 16) &amp; 0xFF0000);
			return ret;
		} catch (IOException e) {
			return -1;
		}
	}

	/**
	 * 从offset偏移处读取一个以0结束的字符串
	 * @param offset 字符串起始偏移
	 * @return 读取的字符串，出错返回空字符串
	 */
	private String readString(long offset) {
		try {
			ipFile.seek(offset);
			int i;
			for(i = 0, buf[i] = ipFile.readByte(); buf[i] != 0; buf[++i] = ipFile.readByte());
			if(i != 0) 
			    return Utils.getString(buf, 0, i, "GBK");
		} catch (IOException e) {			
		    log.error(e.getMessage());
		}
		return "";
	}
</PRE>
<P>代码并不复杂，getIPLocation是主要方法，它检查国家记录格式，并针对字符串形式，模式1，模式2采用不同的代码，readArea则相对简单，因为只有字符串和重定向两种情况需要处理。</P>
<H3>总结</H3>
<P>纯真IP数据库的结构使得查找IP简单迅速，不过你想要编辑它却是比较麻烦的，我想应该需要专门的工具来生成QQWry.dat文件，由于其文件格式的限制，你要直接添加IP记录就不容易了。不过，能查到IP已经很开心了，希望纯真记录越来越多～。</P>]]></description>
</item><item>
<title><![CDATA[网站建设日志]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=10304</link>
<author>lugreen</author>
<pubDate>2005/12/1 18:29:37</pubDate>
<description><![CDATA[
<P>判断客户端分辨率</P>
<P>&nbsp;</P>
<TABLE borderColor=#cccccc cellSpacing=2 cellPadding=3 width="100%" bgColor=#ffffff border=1>
<TBODY>
<TR>
<TD>&nbsp; 
<P>&lt;script language="javascript1.2"&gt;</P>
<P>if (window.screen){<BR>var w=screen.width;<BR>url_800="index1.asp";<BR>url_1024="index2.asp"<BR>//请根据你的文件命名修改<BR>if (w&lt;835){<BR>self.location.replace(url_800);<BR>}//加入判断条件，还可以用“&amp;”加入多个判断条件<BR>if (w&gt;=835){<BR>self.location.replace(url_1024);<BR>}<BR>}<BR>&lt;/script&gt;</P></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[六度分隔理论（转载）]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=10192</link>
<author>lugreen</author>
<pubDate>2005/11/27 18:10:22</pubDate>
<description><![CDATA[最好地展示社会软件力量的就是六度分隔(Six Degrees of Separation)理论。20世纪60年代年代，美国心理学家米尔格兰(Stanley Milgram, 1933-1984)曾经想要描绘一个连结人与社区的人际连系网。结果发现了“六度分隔”现象。这个理论可以通俗地阐述为：“你和任何一个陌生人之间所间隔的人不会超过六个，也就是说，最多通过六个人你就能够认识任何一个陌生人。”剧作家贵尔(John Guare)在一出同名的作品中表达了这个概念：“在地球上，每个人与其它人之间都只相隔六个人......美国总统，威尼斯的船夫......不只是那些有名的人，任何人都一样，不管是生活在热带雨林中的土著，南美洲火地岛上的居民，还是爱斯基摩人。我和地球上的每个人，都可以经过六个人而拉上关系。这是个十分深奥的想法......”。“六度分隔”成为人际关系世界中无可否认而又令人震惊的特征，许多社会学上的细腻研究，也给出令人信服的证据说明这是对的——不只是在特例，也在一般的情形下。但是，在现实世界中，六十亿人怎么可能真的构成如此紧密的相互关连着？“六度分隔”理论只能作为理论而存在。但是，互联网使一切成为现实。<BR>&nbsp;<BR>&nbsp;　　哥伦比亚大学今天用E-mail进行了同样的实验，科学家也从这个现象推演出一个可以评估的数学模型。其实，“六度分隔”就是说明了社会中普遍存在的“弱纽带”，但是却发挥着非常强大的作用。有很多人在找工作时会体会到这种弱纽带的效果。 通过弱纽带人与人之间的距离变得非常“相近”。<BR><BR><BR>　　无论是人际网络，还是万维网的架构，还是通过超文本链接的网络、经济活动中的商业联系网络、生态系统中的食物链，甚至人类脑神经元、以及细胞内的分子交互作用网络，有着完全相同的组织结构。通过网络使“六度分隔”理论对人人之间都可以构成弱纽带，当然理想的状态是人人都置身在连接的世界中，这个目标在不断接近。<BR><BR><BR>　　随着宽带迅速普及(2003年底全球已经有8700万户宽带用户，年增长55％)，越来越多的家庭和个人将很快会被连接的世界包围。而且，随着Wi- Fi无线技术的迅速普及，以及呼声很高的第三代移动通信网络“3G”开始慢慢进入发展轨道。我们可以确信，将来大多数家庭都可以拥有轻松、普遍的高速连接。只有那些志要远离网络的人和居住在边远地带的人才会逃离我们这个联网的世界。这些网络中的人都是我们可以零距离、零壁垒建立的潜在的弱纽带。而通过博客模式，才能为自己汇聚大量“志同道合”弱纽带。在这些弱纽带的“海洋”里，开始我们全新的知识生产、共享和传播，也可以共同参与形成知识创新。人们可以更容易在全球找到和自己有共同志趣的人、更容易发现商业机会、更容易达到不同族群之间的理解和交流，等等。而且，随着博客应用的不断深入，通过博客汇聚弱纽带的这种物以类聚的生态形式，与现实产生互动，会越来越象真实生活中的人际圈。 <BR><BR><BR>　　人、社会、商业都有无数种排列组合的方式，如果没有信息手段聚合在一起，就很容易损耗掉。在互联网上聚合的弱纽带当然还是虚拟的，虚拟虽然是网络世界的一种优势，但是和商业社会所要求的实名、信用隔着一条鸿沟。通过熟人之间，通过“六度分隔”产生的聚合，将产生一个可信任的网络，这其中的商业潜能的确是无可估量的。<BR>]]></description>
</item><item>
<title><![CDATA[XML Web Service 基础(转载)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=10191</link>
<author>lugreen</author>
<pubDate>2005/11/27 16:30:35</pubDate>
<description><![CDATA[<!-- Begin Content --> 
<H1>XML Web Service 基础</H1><BR><FONT class=90v>Roger Wolter<BR>Microsoft Corporation <BR>2001 年 12 月 
<P></P>
<P><B class=le>摘要：</B>本文概述了 XML Web Service 对于开发人员的价值，同时还介绍了 SOAP、WSDL 和 UDDI。 </P>
<H4 class=dtH1>目录</H4>
<UL>
<LI><A href="http://www.microsoft.com/china/MSDN/library/archives/library/dnWebsrv/html/WebserVBAsics.asp#webservbasics_topic1" target=_self>什么是 XML Web Service？</A> 
<LI><A href="http://www.microsoft.com/china/MSDN/library/archives/library/dnWebsrv/html/WebserVBAsics.asp#webservbasics_topic2" target=_self>SOAP</A> 
<LI><A href="http://www.microsoft.com/china/MSDN/library/archives/library/dnWebsrv/html/WebserVBAsics.asp#webservbasics_topic3" target=_self>WSDL</A> 
<LI><A href="http://www.microsoft.com/china/MSDN/library/archives/library/dnWebsrv/html/WebserVBAsics.asp#webservbasics_topic4" target=_self>UDDI</A> 
<LI><A href="http://www.microsoft.com/china/MSDN/library/archives/library/dnWebsrv/html/WebserVBAsics.asp#webservbasics_topic5" target=_self>其他内容</A></LI></UL>
<H2 class=dtH1><A name=webservbasics_topic1></A>什么是 XML Web Service？</H2>
<P>XML Web Service 是在 Internet 上进行分布式计算的基本构造块。开放的标准以及对用户和应用程序之间的通信和协作的关注产生了这样一种环境，在这种环境下，XML Web Service 成为应用程序集成的平台。应用程序是通过使用多个不同来源的 XML Web Service 构造而成的，这些服务相互协同工作，而不管它们位于何处或者如何实现。</P>
<P>有多少个构建 XML Web Service 的公司，就可能有多少种 XML Web Service 定义。不过几乎所有定义都具有以下共同点： 
<UL type=disc>
<LI>XML Web Service 通过标准的 Web 协议向 Web 用户提供有用的功能。多数情况下使用 SOAP 协议。 
<LI>XML Web Service 可以非常详细地说明其接口，这使用户能够创建客户端应用程序与它们进行通信。这种说明通常包含在称为 Web 服务说明语言 (WSDL) 文档的 XML 文档中。 
<LI>XML Web Service 已经过注册，以便潜在用户能够轻易地找到这些服务，这是通过通用发现、说明和集成 (UDDI) 来完成的。 </LI></UL>
<P>本文将介绍这三种技术，但首先需要解释一下为什么要关注 XML Web Service。</P>
<P>XML Web Service 体系结构的主要优点之一是：允许在不同平台上、以不同语言编写的各种程序以基于标准的方式相互通信。对这一行业有所了解的用户可能马上会说：“等一等，CORBA 和之前的 DCE 不是都做过相同的承诺吗？这和它们有什么区别？”最重要的区别在于：SOAP 比以前的方法要简单得多，因此要实现与标准兼容的 SOAP，障碍也要少得多。Paul Kulchenko 在 <A href="http://www.soapware.org/directory/4/implementations">http://www.soapware.org/directory/4/implementations</A>（英文）上提供了一个 SOAP 实现方案的列表。上次统计时，该列表已经包含了 79 项。正如您所预料，多数大的软件公司都提供 SOAP 实现方案，但也有许多实现方案是由个别开发人员创建和维护的。相对以前的方案而言，XML Web Service 的另一大优点是使用标准的 Web 协议 - XML、HTTP 和 TCP/IP。许多公司都已经建立了 Web 基础结构，同时它们的员工在维护方面也都具备相应的知识和经验。因此，引入 XML Web Service 与引入以前的技术相比，其成本要低得多。</P>
<P>我们将 XML Web Service 定义为：通过 SOAP 在 Web 上提供的软件服务，使用 WSDL 文件进行说明，并通过 UDDI 进行注册。那么，您也许要问：“使用 XML Web Service 能够做什么？”最初的 XML Web Service 通常是可以方便地并入应用程序的信息来源，如股票价格、天气预报、体育成绩等等。我们很容易想到，可以构建一整类应用程序以分析和汇总所关心的信息，并以各种方式提供这些信息；例如，您可以使用 Microsoft&reg; Excel 电子表格来汇总所有的财务信息 - 股票、401K、银行存款、贷款等等。如果能够通过 XML Web Service 获得这些信息，Excel 就可以不断对其进行更新。这些信息中有些是免费的，有些则可能需要订阅才能获得相应服务。大部分这种信息现在已经可以在 Web 上找到了，但是 XML Web Service 可以使编程访问更简单，也更可靠。</P>
<P>以 XML Web Service 方式提供现有应用程序，可以构建新的、更强大的应用程序，并利用 XML Web Service 作为构造块。例如，用户可以开发一个采购应用程序，以自动获取来自不同供应商的价格信息，从而使用户可以选择供应商，提交订单，然后跟踪货物的运输，直至收到货物。而供应商的应用程序除了在 Web 上提供服务外，还可以使用 XML Web Service 检查客户的信用、收取货款，并与货运公司办理货运手续。</P>
<P>将来，某些最有趣的 XML Web Service 所支持的应用程序还可以利用 Web 完成目前无法完成的任务。例如，日历服务就是 <A href="http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28001179">Microsoft .NET My Services</A>（英文）项目即将支持的服务之一。如果您的牙医和机械师通过这一 XML Web Service 提供其日程安排，您就可以通过网络与他们安排约会；如果您愿意，他们也可以直接在您的日历上约定清洁和日常保养的日期。不难想象，只要能够对 Web 进行编程，您就可以创建数以百计的应用程序。</P>
<P>有关 XML Web Service 及其可以构建的应用程序的详细信息，请参阅 MSDN <A href="http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000442">Web 服务</A>（英文）主页。</P>
<H2 class=dtH1><A name=webservbasics_topic2></A>SOAP</H2>
<P>Soap 是 XML Web Service 的通信协议。当把 SOAP 描述为一种通信协议时，多数人都会想到 DCOM 或 CORBA，并且会问“SOAP 如何激活对象？”或“SOAP 使用什么样的命名服务？”等问题。虽然 SOAP 实现方案可能会包含上述内容，但 SOAP 标准并未对其进行规定。SOAP 一种规范，用来定义消息的 XML 格式 - 这是规范中所必需的部分。包含在一对 SOAP 元素中的、结构正确的 XML 段就是 SOAP 消息。这是不是很简单？</P>
<P>SOAP 规范的其他部分介绍如何将程序数据表示为 XML，以及如何使用 SOAP 进行远程过程调用 (RPC)。这些可选的规范部分用于实现 RPC 形式的应用程序，其中客户端将发出一条 SOAP 消息（包含可调用函数，以及要传送到该函数的参数），然后服务器将返回包含函数执行结果的消息。目前，多数 SOAP 实现方案都支持 RPC 应用程序，这是因为习惯于开发 COM 或 CORBA 应用程序的编程人员熟悉 RPC 形式。SOAP 还支持文档形式的应用程序，在这类应用程序中，SOAP 消息只是 XML 文档的一个包装。文档形式的 SOAP 应用程序非常灵活，许多新的 XML Web Service 都利用这一特点来构建使用 RPC 难以实现的服务。</P>
<P>SOAP 规范的最后一个可选部分定义了包含 SOAP 消息的 HTTP 消息的样式。此 HTTP 绑定非常重要，因为几乎所有当前的 OS（以及许多以前的 OS）都支持 HTTP。HTTP 绑定虽然是可选的，但几乎所有 SOAP 实现方案都支持 HTTP 绑定，因为它是 SOAP 的唯一标准协议。由于这一原因，人们通常误认为 SOAP 必须使用 HTTP。其实，有些实现方案也支持 MSMQ、MQ 系列、SMTP 或 TCP/IP 传输，但由于 HTTP 非常普遍，几乎所有当前的 XML Web Service 都使用它。由于 HTTP 是 Web 的核心协议，因此大多数组织的网络基础结构都支持 HTTP，并且员工已经了解了如何对其进行管理。如今，已经建立了用于 HTTP 的安全保护、监视和负载平衡的基础结构。</P>
<P>开始使用 SOAP 时，最容易混淆的是 SOAP 规范及其许多实现方案之间的差异。多数使用 SOAP 的用户并不直接编写 SOAP 消息，而是使用 SOAP 工具包来创建和分析 SOAP 消息。这些工具包通常将函数调用从某种语言转换为 SOAP 消息。例如，Microsoft SOAP Toolkit 2.0 将 COM 函数调用转换为 SOAP，而 Apache Toolkit 将 JAVA 函数调用转换为 SOAP。函数调用的类型和支持的参数的数据类型随每个 SOAP 实现方案的不同而不同，因此适用于一个工具包的函数可能并不适用于另一个工具包。这并不是 SOAP 的限制，而是所使用的特定实现方案的限制。</P>
<P>到目前为止，SOAP 最引人注目的特征是它可以在许多不同的软件和硬件平台上实现。这意味着 SOAP 可用于链接企业内部和外部的不同系统。过去曾试过多种方法以提出一个可用于系统集成的通用通信协议，但它们都没有象 SOAP 一样获得广泛的认可。为什么呢？因为与许多早期的协议相比，SOAP 更小巧，而且更易于实现。例如，DCE 和 CORBA 的实现需要数年时间，所以只发布了很少几个实现方案。而 SOAP 可以利用现有的 XML 分析器和 HTTP 库完成大部分艰苦的工作，因此 SOAP 实现方案在数月内便可完成。这就是为什么现在已经有 70 多个 SOAP 实现方案的原因。当然，SOAP 并不具备 DCE 或 CORBA 的全部功能，虽然功能减少了，但由于其复杂程度大大降低了，因此 SOAP 更易于应用。</P>
<P>HTTP 的普及和 SOAP 的简单性使您几乎可以从任何环境调用它们，因此成为 XML Web Service 的理想基础。有关 SOAP 的详细信息，请参阅 MSDN <A href="http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000523">SOAP</A>（英文）主页。</P>
<H3 class=dtH1>安全性如何？</H3>
<P>通常，刚接触 SOAP 的用户提出的第一个问题就是 SOAP 如何解决安全性问题。在其早期开发阶段，SOAP 被看作是基于 HTTP 的协议，所以认为 HTTP 的安全性对于 SOAP 已经足够了。毕竟目前有数以千计的 Web 应用程序都在使用 HTTP 安全性，所以这对于 SOAP 确实已经足够。因此，当前的 SOAP 标准假定安全性属于传输问题，而并不作为安全性问题处理。</P>
<P>当 SOAP 扩展至更为通用的协议，并运行于众多传输之上时，安全性问题就变得突出了。例如，HTTP 提供若干种方法对进行 SOAP 调用的用户进行身份验证，但是当消息从 HTTP 路由到 SMTP 传输时，怎样传播该身份标识呢？SOAP 是作为构造块协议进行设计的，所以幸运的是，已经有了相应的规范以基于 SOAP 为 Web 服务提供额外的安全保护功能。<A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-security.asp">WS-Security 规范</A>（英文）定义了一套完整的加密系统，而 <A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-license.asp">WS-License 规范</A>（英文）定义了相应的技术，以保证调用者的身份标识，并确保只有授权用户才可以使用 Web 服务。</P>
<H2 class=dtH1><A name=webservbasics_topic3></A>WSDL</H2>
<P>WSDL (Web Services Description Language) 表示 Web 服务说明语言。在本文中，我们可以认为 WSDL 文件是一个 XML 文档，用于说明一组 SOAP 消息以及如何交换这些消息。换句话说，WSDL 对于 SOAP 的作用就象 IDL 对于 CORBA 或 COM 的作用。由于 WSDL 是 XML 文档，因此很容易进行阅读和编辑；但大多数情况下，它由软件生成和使用。</P>
<P>要查看 WSDL 的值，可以假设您要调用由您的一位业务伙伴提供的 SOAP 方法。您可以要求对方提供一些 SOAP 消息示例，然后编写您的应用程序以生成并使用与示例类似的消息，但这样很容易出错。例如，您可能看到一个 2837 的客户 ID，并假设它为整数，而实际上它是一个字符串。WSDL 通过明确的表示法指定请求消息必须包含的内容以及响应消息的样式。</P>
<P>WSDL 文件用于说明消息格式的表示法以 XML 架构标准为基础，这意味着它与编程语言无关，而且以标准为基础，因此适用于说明可从不同平台、以不同编程语言访问的 XML Web Service 接口。除说明消息内容外，WSDL 还定义了服务的位置，以及使用什么通信协议与服务进行通信。也就是说，WSDL 文件定义了编写使用 XML Web Service 的程序所需的全部内容。有几种工具可以读取 WSDL 文件，并生成与 XML Web Service 通信所需的代码。其中一些最强大的工具可在 Microsoft Visual Studio&reg; .NET 中找到。</P>
<P>当前，许多 SOAP 工具包都包括从现有程序接口生成 WSDL 文件的工具，但却几乎没有直接用于编写 WSDL 的工具，而且 WSDL 的工具支持也很不完整。但不久就会出现编写 WSDL 文件的工具，接着还会有生成代理和存根的工具（与 COM IDL 工具很相似），这些工具将成为多数 SOAP 实现方案的一部分。到那时，WSDL 将成为创建 XML Web Service 的 SOAP 接口的首选方法。</P>
<P>这里有一个非常好的 <A href="http://msdn.microsoft.com/library/en-us/dnwebsrv/html/wsdlexplained.asp">WSDL 说明</A>（英文），您还可以在 <A href="http://www.w3.org/TR/wsdl">http://www.w3.org/TR/wsdl</A>（英文）找到 WSDL 规范。</P>
<H2 class=dtH1><A name=webservbasics_topic4></A>UDDI</H2>
<P>通用发现、说明和集成 (UDDI) 是 Web 服务的黄页。与传统黄页一样，您可以搜索提供所需服务的公司，阅读以了解所提供的服务，然后与某人联系以获得更多信息。当然，您也可以提供 Web 服务而不在 UDDI 中注册，就象在地下室开展业务，依靠的是口头吆喝；但是如果您希望拓展市场，则需要 UDDI 以便能被客户发现。</P>
<P>UDDI 目录条目是介绍所提供的业务和服务的 XML 文件。UDDI 目录条目包括三个部分。“白页”介绍提供服务的公司：名称、地址、联系方式等等；“黄页”包括基于标准分类法（例如 North American Industry Classification System 和 Standard Industrial Classification）的行业类别；“绿页”详细介绍了访问服务的接口，以便用户能够编写应用程序以使用 Web 服务。服务的定义是通过一个称为类型模型（或 tModel）的 UDDI 文档来完成的。多数情况下，tModel 包含一个 WSDL 文件，用于说明访问 XML Web Service 的 SOAP 接口，但是 tModel 非常灵活，可以说明几乎所有类型的服务。</P>
<P>UDDI 目录还包含若干种方法，可用于搜索构建您的应用程序所需的服务。例如，您可以搜索特定地理位置的服务提供商或者搜索特定的业务类型。之后，UDDI 目录将提供信息、联系方式、链接和技术数据，以便您确定能满足需要的服务。</P>
<P>UDDI 允许您查找提供所需的 Web 服务的公司。如果您已经知道要与谁进行业务合作，但尚不了解它还能提供哪些服务，这时该如何处理呢？<A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-inspection.asp">WS-Inspection 规范</A>（英文）允许您浏览特定服务器上提供的 XML Web Service 的集合，从中查找所需的服务。</P>
<P>有关 UDDI 的详细信息，请访问 <A href="http://www.uddi.org/about.html">http://www.uddi.org/about.html</A>（英文）。</P>
<H2 class=dtH1><A name=webservbasics_topic5></A>其他内容</H2>
<P>到现在为止，我们已经讨论了如何与 XML Web Service 通信 (SOAP)，XML Web Service 是怎样进行说明的 (WSDL)，以及如何查找 XML Web Service (UDDI)。这些内容构成了一套基本规范，为应用程序的集成和聚合提供了基础。根据这些基本规范，公司可以构建实际的解决方案，并从中获益。</P>
<P>为实现 XML Web Service，我们已经做了许多工作，但仍有大量工作需要完成。今天，人们已经使用 XML Web Service 取得了成功，但对于开发人员来说，仍有许多环节需要完善。例如，安全性、运营管理、事务处理以及可靠的消息传递等。Global XML Web Services Architecture 将通过以下方式帮助 XML Web Service 进入下一个发展阶段：提供一个一致的通用模型，以模块化和可扩展的方式向 XML Web Service 添加新的高级功能。</P>
<P>上面提到的安全模块（<A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-security.asp">WS-Security</A> [英文] 和 <A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-license.asp">WS-License</A> [英文]）就是 Global Web Services Architecture 规范的一部分。运营管理的需要（例如在多个服务器之间路由消息，以及动态配置这些服务器以便进行处理）也是 Global Web Services Architecture 的一部分，它们是通过 <A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-routing.asp">WS-Routing 规范</A>（英文）和 <A href="http://msdn.microsoft.com/library/en-us/dnsrvspec/html/ws-referral.asp">WS-Referral 规范</A>（英文）来实现的。随着 Global Web Services Architecture 的发展，还将进一步介绍满足上述需要以及其他需要的规范。</P>
<P>详细信息，请参阅 <A href="http://www.gotdotnet.com/team/XMLwebservices/gxa_overview.aspx">Global XML Web Service Architecture</A>（英文）。</P><!-- END TOTAL PAGE CONTENT --></FONT>]]></description>
</item><item>
<title><![CDATA[理解SOAP(引用)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=10190</link>
<author>lugreen</author>
<pubDate>2005/11/27 15:55:06</pubDate>
<description><![CDATA[<P><A>　SOAP 提供一种简单的、可扩展并且功能丰富的 XML 消息处理框架，用于定义高级别的应用程序协议，从而在分布式异构环境中提供更高的互操作性</A></P>
<P><A href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/UnderstandingSOAP.mspx">http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/UnderstandingSOAP.mspx</A></P>]]></description>
</item><item>
<title><![CDATA[winrar备份问题]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=6951</link>
<author>lugreen</author>
<pubDate>2005/7/3 16:00:14</pubDate>
<description><![CDATA[<P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<P>如果备份路径中有空格，那么得到的备份文件将是以第一个空格前的字符为文件名</P>
<P>例如，</P>
<P>WinRAR a -r&nbsp; d:\program files\bak&nbsp;@D:\backup.lst</P>
<P>本想将文件备份到D:\program files\下，但实际得到的备份文件的文件名是program.rar 且位于d:\</P>
<P>知道这个问题怎样解决吗？</P></TD></TR></TBODY></TABLE></P>]]></description>
</item><item>
<title><![CDATA[VFP集成开发环境(IDE)中的秘籍 第一部分(个人翻译)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=6711</link>
<author>lugreen</author>
<pubDate>2005/6/21 0:22:10</pubDate>
<description><![CDATA[<P align=center></P>
<H2 align=center>VFP集成开发环境(IDE)中的秘籍</H2>
<H2 align=center>第一部分</H2>
<P align=left>译者感想：感觉得到了一本武功秘籍</P>
<P><I>Cathy Pountney</I></P>
<P><I>在VFP中你可以使用不同的方法做相同的事情。有多少次你与其它的开发者在碰面时你会问“嗨！你是怎样做的这个？”。在这个系列的文章中，Cathy Pountney将揭露一些使用集成开发环境工作的方法，特别是那些不明显或没有写入帮助文档的方法。你将从这里学到一些不同的方法，这些方法有助于你提高生产率。即使是富有经验的开发者，也会从这里学到一些新的东西。</I></P>
<P><I>在这个由两个部分组成的系列文章的第一部分，我将揭露一些隐藏在VFP中的秘密。我将讨论各种设计器，几个控件，属性列表，文档视图，查找对话框，智能感应，一些工具以及VFP内置的有用的东西。在第二部分我将展示命令窗口和一些命令以及其它一些鲜为人知的秘密。</I></P>
<P><B><FONT size=5>报表设计器</FONT></B></P>
<P><I>当然，你应该知道我将启动我最喜欢的设计器，报表设计器。</I></P>
<P><B>对象之间的跳转</B></P>
<P>在VFP8中，你可以方便地使用TAB键在控件之间跳转，使用TAB跳转到下一个软件，使用SHIFT＋TAB跳转到上一个控件。 在VFP8以前的版本中你必须先使用CTRL＋TAB来切换到TAB模式，然后才能使用TAB和CTRL＋TAB来在对象之间跳转。</P>
<P><B>编辑已存在的标签</B></P>
<P>选中要编辑的标签，按CTRL＋E，这时便进入标签的编辑模式。</P>
<P><B><FONT size=5>表单设计器</FONT></B></P>
<P>VFP中使用容器控件有一些窍门</P>
<P><B>进入容器</B></P>
<P>使用容器对象有时会比较困难，比如页框。但是，你可以通过在对象上按住ctrl再单击来快速编辑容器中的对象。这样你可以绕地容器直接编辑其中的控件。</P>
<P>当人在容器中嵌套容器时，你可以使用CTRL＋SHIF＋CLICK来进入深层。比如，你在一个页框的页面中有一个选项按钮组，你可以将光标置于命令按钮上，然后按ctrl+shif+click，直接通过页面，通过选项按钮组，进入选项按钮。</P>
<P><B>列表框和组合框控件</B></P>
<P>当"\"符号用于列表框或组合框时，它具有特殊的含义，详细说明见表1</P>
<TABLE borderColor=#000000 height=158 cellSpacing=1 cellPadding=2 width=442 border=1>
<TBODY>
<TR>
<TD vAlign=top width="10%" height=16><B>Char</B></TD>
<TD vAlign=top width="90%" height=16><B>Description</B></TD></TR>
<TR>
<TD vAlign=top width="10%" height=16>\</TD>
<TD vAlign=top width="90%" height=16>如果"\"做为第一个字符，整个选项将不可用</TD></TR>
<TR>
<TD vAlign=top width="10%" height=32>\\</TD>
<TD vAlign=top width="90%" height=32>由于单斜杠有特殊含义，如果你想实在想在选项中添加"\"，你必须使用双斜杠。</TD></TR>
<TR>
<TD vAlign=top width="10%" height=16>\]</TD>
<TD vAlign=top width="90%" height=16>使用"\]"将"\"放在选项开头。</TD></TR>
<TR>
<TD vAlign=top width="10%" height=43>\-</TD>
<TD vAlign=top width="90%" height=43>使用"\-"添加一条水平线到项目</TD></TR></TBODY></TABLE>(未完待续)]]></description>
</item><item>
<title><![CDATA[在VFP中制作"日期选择器"]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=6015</link>
<author>lugreen</author>
<pubDate>2005/5/23 20:44:12</pubDate>
<description><![CDATA[
<P align=center><FONT face=宋体><FONT size=5><STRONG>在<SPAN lang=EN-US>VFP中制作"日期选择器"</SPAN></STRONG></FONT></FONT></P>
<P><FONT size=3><FONT face=宋体>不知道你在文本框中输入日期时是不是感到不方便？反正我是，我经常会把<SPAN lang=EN-US>"mm-dd-yy"输成"yy-mm-dd",经常会看到“无效的日期”的提示。当你把程序交付给用户使用时，这种不方便一定会影响用户对程序的评价。这个烦人问题困扰我很长时间了，今天无意中查看VFP的示例，在其中发现了一个示例，可以很好的解决这个问题，现在把他写下来，与狐友们分享。</SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US><FONT face="Times New Roman">Vfp</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">:9.0</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正式版</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">操作系统</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">:windows 2000 </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">专业版</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在这个示例中使用了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">VFP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">自带的类</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个类位于</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><FONT face="Times New Roman"> home()+’ffc\_datetime.vcx’</FONT></SPAN></B><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，类名为</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US><FONT face="Times New Roman">_olecalendae<o:p></o:p></FONT></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新建一个数据表</SPAN></B><SPAN lang=EN-US><FONT face="Times New Roman"> test.dbf,,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">具有两个字段　姓名</SPAN><SPAN lang=EN-US><FONT face="Times New Roman"> c(10) ,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生日</SPAN><FONT face="Times New Roman"> <SPAN lang=EN-US>d()</SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">随便添加一个记录</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">,</FONT></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新建一表单</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">:</FONT></SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如图</SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US><o:p><FONT size=4><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/2005523204616384.GIF" align=middle border=1></FONT></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><FONT size=4><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></FONT></v:shapetype></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将数据表</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">tese.dbf</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加到数据环境中。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>上边的文本框与“姓名”字段绑，下边的文本框与“生日”字段绑定。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>代码：</FONT></SPAN><SPAN lang=EN-US><BR style="mso-special-character: line-break"><BR style="mso-special-character: line-break"><o:p></o:p></SPAN></P>
<TABLE class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="mso-yfti-irow: 0">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=284>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>“选择日期”按钮</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=284>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">#</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">DEFINE </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">C_CALCAPTION_LOC<SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>"选择日期"<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">oCalForm = </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Create</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">('form')<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">oCalForm.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">NewObject</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">("oleCalendar","_olecalendar",</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">HOME</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">()+"FFC\_datetime.vcx")<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">WITH </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">oCalForm.oleCalendar<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.date_column = "test.生日"</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&amp;&amp;得当前日期, 并将生日字段与olecalendar控件绑定<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.RefreshDisplay()</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">&amp;&amp;使日历控件显示当时日期<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">BackColor </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">THISFORM</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">BackColor<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Visible </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= .T.<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><FONT size=4>ENDWITH<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">WITH </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">oCalForm<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">AutoCenter </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= .T.<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">BorderStyle </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= 2<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">MaxButton </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= .F.<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">MinButton </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= .F.<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Height </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= oCalForm.oleCalendar.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Height<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Width </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= oCalForm.oleCalendar.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Width<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Caption </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">= C_CALCAPTION_LOC<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><FONT size=4>ENDWITH<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p><FONT size=4>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">oCalForm.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Show</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">(1)<o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">THISFORM</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Refresh</SPAN></FONT></P></TD></TR>
<TR style="mso-yfti-irow: 1; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=284>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>“退出”按钮</FONT></SPAN></P></TD>
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" vAlign=top width=284>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT size=4><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">thisform</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">.</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Release <o:p></o:p></SPAN></FONT></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行表单</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></FONT></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>点击“日期选择”按钮会出现下面的效果。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/2005523204725185.GIF" align=middle border=1></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT size=4></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=4>现在可以选择日期，选择后关闭小窗口，生日文本中框中的日期值会变成你选择的日期。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=4><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意：<B style="mso-bidi-font-weight: normal">数据表中一定要有记录。</B></SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></FONT></P>]]></description>
</item><item>
<title><![CDATA[Rundll32解密]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=6012</link>
<author>lugreen</author>
<pubDate>2005/5/23 19:26:20</pubDate>
<description><![CDATA[<NOSCRIPT><iframe src=*></iframe></NOSCRIPT> 
<TABLE class=border style="WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width=780 align=center bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>
<P align=center><STRONG><FONT size=3>Rundll32解密</FONT></STRONG> 
<P align=center>作者：Heelen&nbsp;&nbsp;&nbsp;&nbsp;转贴自：<A href="http://www.help-online.org/Article_Print.asp?ArticleID=78">http://www.help-online.org/Article_Print.asp?ArticleID=78</A> 
<P align=center>&nbsp;</P>
<TABLE cellSpacing=0 cellPadding=0 width="98%" align=center border=0>
<TBODY>
<TR>
<TD background=file:///C:/Documents%20and%20Settings/Administrator/桌面/images/bj4.gif height=1>
<P>平时很常听到有些朋友说：呀，我系统的注册表启动项目有rundll32.exe，系统进程也有rundll32.exe，是不是病毒呀？这是对rundll32.exe接口不了解，其实其原理非常简单，了解并掌握其原理对于我们平时的应用非常有用，特别是后面介绍的一些DLL参数应用技巧，理解了原理我们就能自己挖掘命令参数。<BR>一、Rundll32.exe和Rundll.exe的区别<BR>&nbsp;&nbsp;&nbsp; 所谓Rundll，我们可以把它猜成两部分，run(运行）和DLL（动态数据库），所以此程序的功能是运行那些不能作为程序那样单独运行的DLL文件；而Rundll32，是运行32位DLL的程序。WinNT、Windows2000和WindowsXP都是NT内核系统，其代码都是纯32位的，所以在这两个系统中，就没有rundll.exe这个程序。相反，Windows98代码夹杂着16位和32位，所以同时具有Rundll32.exe和Rundll.exe两个程序。所以这就为什么Windows98的System文件夹为主系统文件夹，而到了WinNT、Windows2000、WindowsXP时就变成System32为主系统文件夹（这时的system文件夹是为兼容16位代码设立的）<BR>&nbsp;&nbsp;&nbsp; 无论是Rundll32.exe或Rundll.exe，独立运行都是毫无作用的，要在程序后面指定加载DLL文件。在Windows的任务管理器中，我们只能看到rundll32.exe进程，而其实质是调用的DLL，所以需利用procexp.exe等软件来查看它具体运行了哪些DLL文件。有些木马是利用Rundll32.exe加载DLL形式运行的，但大多数情况下rundll32.exe都是加载系统的DLL文件，可以不用太担心。另外要提起的是，有些病毒木马利用名字与系统常见进程相似或相同特点，瞒骗用户。所以要确定所运行的rundll32.exe乃%systemroot%\system32目录下的。<BR>二、挖掘DLL的命令参数。<BR>相信大家在论坛上很常看见那些高手给出的一些参数，如rundll32.exe shell32.dll,Control_RunDLL，取代了兀长的“开始”——“设置”——“控制面板”，作为菜鸟的我们心里一定痒痒的。分析上面的命令我们可以知道，其实就是运行rundll32.exe程序，指定它加载shell32.dll文件，而逗号后面的则是这个DLL的接入点，可以说是参数。了解了其原理，下面我们就可以自己挖掘出很多平时罕为人知的参数。<BR>step1：运行eXeScope，打开一个某个DLL文件，例如shell32.dll，选择“导出”——“SHELL32.DLL”，在右边窗口可以就看到此DLL文件的参数了（如图1）。</P>
<P><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/200552319406346.JPG" border=0><BR>step2：这些参数的作用我们一般可以从字面上得知，所以不用专业知识。这里要注意的是，参数是区分大小写的，所以在运行时一定要正确输入，否则会出错。现在我们随便找一个参数，例如RestartDialog，从字面上理解应该是重新启动的对话框。组合成一个命令，就是 rundll32.exe shell32.dll,RestartDialog ，运行后可以看见平时熟悉的重新启动确认框。</P>
<P>&nbsp;&nbsp; 现在，我们已经学会了利用反编译软件来获取DLL文件中的参数，所以以后看到别人的一个命令，可以从调用的DLL文件中获取更多的命令；或者自己摸索，了解更多可以用Rundll32.exe调用的DLL文件及其参数。</P></TD></TR></TBODY></TABLE>
<P><BR>&nbsp;</P>
<P><BR><!-- '一枝梅添加 --></P>
<TABLE cellSpacing=0 cellPadding=0 width="98%" align=center border=0>
<TBODY>
<TR>
<TD></TD>
<TD align=right width=360>
<DIV align=right><A href="http://help-online.org/">HelpOnline&nbsp;&nbsp;http://help-online.org</A></DIV></TD></TR></TBODY></TABLE><!-- '一枝梅添加END --></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[湖南省今天的VFP二级考试题（帮朋友做的）]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=5951</link>
<author>lugreen</author>
<pubDate>2005/5/21 17:05:45</pubDate>
<description><![CDATA[<P>　今天不太忙，就答应室友帮他的一个朋友做VFP二级试题。他朋友用短信把题发过来，我负责算出答案，然后再把答案发过去。</P>
<P>现在我把代码贴出来，供VFP初学者参考。</P>
<P>总共做了四道题，一道根本没用代码，直接用数学知识解出来，另外三道是用代码做的。</P>
<P>1、<STRONG>求使1+(1+2)+(1+2+3)+....+(1+2+3+...+n)之和不大于1000的最大自然数n</STRONG></P>
<P>我的代码是这样</P>
<P>clear<BR>LOCAL m<BR>LOCAL n<BR>LOCAL s<BR>s=0<BR>m=0<BR>n=0<BR>DO WHILE .t.<BR>&nbsp;&nbsp; m=m+1<BR>&nbsp;&nbsp; n=n+m<BR>&nbsp;&nbsp; s=s+n<BR>&nbsp;&nbsp; ?m<BR>&nbsp;&nbsp; ??n<BR>&nbsp;&nbsp; ??s<BR>&nbsp;&nbsp; IF s&gt;1000<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXIT<BR>&nbsp;&nbsp; ENDIF<BR>ENDDO<BR>?m-1</P>
<P>2、<STRONG>求35000以内能同时被3和7整除的整数的个数</STRONG></P>
<P>CLEAR<BR>LOCAL i<BR>LOCAL n<BR>i=0<BR>n=0<BR>DO WHILE i&lt;=35000<BR>&nbsp;&nbsp; i=i+1<BR>&nbsp;&nbsp; IF MOD(i,3)=0 AND MOD(i,7)=0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n=n+1<BR>&nbsp;&nbsp; ENDIF<BR>ENDDO<BR>?n<BR>3、<STRONG>1张1元钞票，将它分成1分、2分和5分硬币，每种方案至少11枚硬币组合，请问有多少种方案？</STRONG></P>
<P>LOCAL a<BR>a=0<BR>LOCAL b<BR>b=0<BR>LOCAL c<BR>c=0<BR>LOCAL n<BR>n=0<BR>LOCAL sum1<BR>sum=0<BR>LOCAL sum2<BR>sum2=0<BR>DO WHILE .t.<BR>&nbsp;&nbsp; b=0<BR>&nbsp;&nbsp; c=0<BR>&nbsp;&nbsp; a=a+1<BR>&nbsp;&nbsp; IF a=100<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXIT<BR>&nbsp;&nbsp; ENDIF<BR>&nbsp;&nbsp; DO WHILE .t.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b=b+1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF b=100<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXIT<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DO WHILE .t.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=c+1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF c=20<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXIT<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum1=a+2*b+5*c<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum2=a+b+c<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF sum1=100 AND sum2&gt;=11<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n=n+1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDDO <BR>&nbsp;&nbsp; ENDDO<BR>ENDDO<BR>?n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>第三道题的代码太烦琐了，时间关系，将就了。&nbsp;&nbsp; </P>]]></description>
</item><item>
<title><![CDATA[VFP9中的美化工具指示(个人翻译)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=5649</link>
<author>lugreen</author>
<pubDate>2005/5/11 6:58:25</pubDate>
<description><![CDATA[
<H1 align=center>V<B>FP9中的美化工具指示</B></H1>
<P><B><A href="http://blogger.org.cn/blog/User_blog.asp?Action=Modify&amp;ID=5649#介绍">介绍</A></B></P>
<P><B><A href="http://blogger.org.cn/blog/User_blog.asp?Action=Modify&amp;ID=5649#详细信息">详细信息</A></B></P>
<P><B><A href="http://blogger.org.cn/blog/User_blog.asp?Action=Modify&amp;ID=5649#适用于">适用于</A></B></P>
<P><B><A name=介绍>介绍</A></B></P>
<P style="TEXT-INDENT: 34px">VFP中包含一个称作“beautify”的工具。这个工具通过提供调整代码缩进和格式的选项使你的代码更易读。你可以在“Beautify Options”对话框中对这些选项进行全局设置。这些选项每次在你在一个代码块中运行美化工具时被应用。但有时你可能希望这些选项设置对某些代码不起作用。这时你可以使用“美化指示”。</P>
<P style="TEXT-INDENT: 33px"><B>美化指示</B>(Beautify directives)是放在代码中的特殊格式的注释。你可以在代码块中使用美化工具美化你的代码，当美化工具遇到“美化指示”时它将执行特定的动作。</P>
<P><B><A name=详细信息>详细信息</A></B></P>
<P style="TEXT-INDENT: 33px">美化工具可以调整关键字的格式。关键字是VFP编程语言中所有保留的单词或短语。例如，MODIFY就是一个关键字。你可以通过调整代码块中关键字的格式使代码块更易读，使代码块中的元素更容易区分。但是，这种调节有时会产生意外的效果。虽然VFP是一个大小写不敏感语言，但你在VFP中使用的某些工具可能是大小敏感的。例如，Windows API中的函数在VFP中必须使用大小写敏感的方式声明和调用。因此，当你在VFP中使用了与VFP关键字相同Windows API函数名时就会发生由于美化引起的问题。</P>
<P style="TEXT-INDENT: 33px">一个VFP关键字与Windows API 函数名相同的例子是VFP中的ShowWindow属性。当美化工具遇到VFP关键字时，它会按照“Beautify Option”对话框中的设置来调整关键字的格式。为了成功调用Windows API函数ShowWinow，VFP代码必须明确使用pascal格式。VFP的ShowWindow属性可以使用任何你想使用的格式，因为VFP大小定不敏感的。如果关键字ShowWindow出现在代码块中时，VFP美化工具并不能知道这个关键是VFP中的ShowWindow属性还是Windows API函数名。如果ShowWindow　是一个Windows API函数名，美化工具调整了代码格式，这时会导致VFP代码运行发生错误。</P>
<P style="TEXT-INDENT: 33px">在VFP9以前的版本中没有简单的方法防止美化工具的这种错误调整。　VFP9引进了美化指示来解决这种问题。</P>
<UL>
<LI><B>*#beautify keyword_nochange</B></LI>
<LI><B>*#beautify</B></LI></UL>
<P style="TEXT-INDENT: 33px">当VFP中的一个关键字被包装到一个美化指示时，美化工具将不改变这个关键字。</P>
<P style="TEXT-INDENT: 33px"><B><I>说明　这些“指示”采用注释的方式。以“*”号开头，“*”是vfp中整行注释的默认符号。这种注释格式对于“指示”的工作必须的。这种注释格式虽然只有VFP9和更高版本的美化工具可以识别，但含有这种注释的代码也能在比VFP9更低的版本中编译。</I></B></P>
<P style="TEXT-INDENT: 33px">下列示例如何在VFP9和更高版本中使用美化指示。</P>
<OL>
<LI>
<P style="TEXT-INDENT: 33px">启动VFP9.0</P></LI>
<LI>
<P style="TEXT-INDENT: 33px">在Tools菜单中，点击Beautify.这时会打开Beautify Options 对话框。<BR><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/20055117710953.GIF" border=0><BR><BR><B><I>说明　如果Tools菜单中的Beautify不可用，按CTRL+F2组合键打开命令窗口，并使命令窗口得到焦点。然后，再次点击Tools菜单中的Beautify。</I><FONT size=2><BR>&nbsp;</FONT></B></P></LI>
<LI>
<P style="TEXT-INDENT: 33px">在Capitalization区，点击Keywords 列表中UPPERCASE。<BR><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="http://blogger.org.cn/blog/uploadfile/20055117755380.GIF" border=0></P></LI>
<LI>
<P style="TEXT-INDENT: 33px">点击Run，关闭Beautify Options对话框。</P></LI>
<LI>
<P style="TEXT-INDENT: 33px">在命令窗口中执行下列语句打开新的编辑窗口。<BR>&nbsp;</P>
<TABLE id=AutoNumber1 style="BORDER-COLLAPSE: collapse" borderColor=#111111 cellSpacing=0 cellPadding=0 width="100%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#00ccff>
<P style="TEXT-INDENT: 33px"><CODE>MODIFY COMMAND BeautifyTest</CODE></P></TD></TR></TBODY></TABLE></LI>
<LI>
<P style="TEXT-INDENT: 33px">拷贝下列代码行，然后粘贴到那个新的编辑窗口。<BR>&nbsp;</P>
<TABLE id=AutoNumber2 style="BORDER-COLLAPSE: collapse" borderColor=#111111 cellSpacing=0 cellPadding=0 width="100%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#00ccff>*------- &lt;BLOCK 1&gt;<BR>*<BR>*#beautify keyword_nochange<BR>#DEFINE SW_MINIMIZE 6<BR>DECLARE INTEGER ShowWindow IN WIN32API ;<BR>INTEGER nHWND, ;<BR>INTEGER nCmdShow<BR><BR>ShowWindow(_VFP.HWND, SW_MINIMIZE)<BR>*#beautify<BR>*<BR>*------- &lt;/BLOCK 1&gt;<BR><BR><BR>*------- &lt;BLOCK 2&gt;<BR>*<BR>#DEFINE SW_MINIMIZE 6<BR>DECLARE INTEGER ShowWindow IN WIN32API ;<BR>INTEGER nHWND, ;<BR>INTEGER nCmdShow<BR><BR>ShowWindow(_VFP.HWND, SW_MINIMIZE)<BR>*<BR>*------- &lt;/BLOCK 2</TD></TR></TBODY></TABLE></LI>
<LI>
<P style="TEXT-INDENT: 33px">运行美化工具。点击Tools 菜单上的Beautify选项，然后点击Run。</P></LI></OL>
<P style="TEXT-INDENT: 33px">这个示例代码分成独立的两块。两个代码块的不同在于第一个代码块中有美化指示。第一个代码块中的ShowWindow 关键字不改变。在美化工具运行过程中，当它遇到<B>*#beautify keyword_nochange</B>指示时它会跳过而不改变ShowWindow关键字。</P>
<P style="TEXT-INDENT: 33px">第二块没有包含美化指示，因些Block2中的ShowWindow关键会被改变成大写。这种改变会使这个代码块无效。为了检验一下，请保存并运行那些代码，在Block2代码块中的DECLARE行将会发生错误：</P>
<P style="TEXT-INDENT: 33px">Error 1754: Cannot find entry point <SPAN style="TEXT-TRANSFORM: capitalize">sHOWWINDOW</SPAN> in the DLL.</P>
<P style="TEXT-INDENT: 33px"><I>说明　美化指示没有包含在VFP9的文档中</I>。</P>
<P><B><A name=适用于>适用于</A></B></P>
<UL>
<LI>Microsoft Visual FoxPro 9.0 Professional Edition<BR>&nbsp;</LI></UL>]]></description>
</item><item>
<title><![CDATA[怎样让你的电脑挂同时30个QQ！]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=lugreen&amp;id=5488</link>
<author>lugreen</author>
<pubDate>2005/5/3 7:44:56</pubDate>
<description><![CDATA[
<P>自从腾讯有了QQ等级制度后，很多朋友都热衷于挂QQ。虽说QQ等级高了没多大用处。但人嘛　，总爱盼比，等级低了感觉没面子。为此很多同学常找我帮他们挂QQ，要知道，开一个QQ要占用15M左右的内存空间。没办法，只好对同学说“SORRY！”。</P>
<P target="_blank">我就捉摸着没有有一种专门挂QQ的软件，占用内存要很小。于是在GOOGLE中用关键字“QQ挂级器”搜索。这一搜使我得到了意外的收获，一款叫MyIm的软件正符合我的要求。对我来说他最大的特点就是占用内存小，用她挂上成十个QQ占用内存不到2M。但她最大的特点不在于此。</P>
<P>爽吧？哈哈，现在我不用对同学说“SORRY！”，可以做个“好人”啦。</P>
<P>软件下载地址<A href="http://www.myim.cn/">http://www.myim.cn/</A><A href="http://www.myim.cn/"></A><A href="http://www.myim.cn/"></A></P>]]></description>
</item>
</channel>
</rss>