Delphi 开发易语言支持库再获重大进展,支持窗口控件了

声明1:以本人名义发布的消息从来都不代表易语言官方消息。其实这何需声明,明摆的事嘛,可是我被某些人吓怕了,诚惶诚恐,特此声明。

声明2:未经本人(liigo)同意,此文禁止转载。


Delphi 开发易语言支持库再获重大进展,支持窗口控件了

Delphi 开发易语言支持库再获重大进展,经初步研究已经可以支持窗口控件。

易语言将再次拥抱Delphi,拥抱VCL。

易语言之福,易友之福。

2008年4月3日,请记住这个节日。

  众所周知,易语言支持库开发接口中,早已将窗口控件的数据类型固定为MFC中的 CWnd*,要用MFC之外的技术开发易语言窗口控件,有可能吗?很多人早已在潜意识中就否定了这种可能性。包括本人(liigo), 在三年前(2004.9)将易语言支持库C/C++开发接口转换为Pascal接口(第二版)时,就曾经写下这样一段话:“用Delphi编写带窗口组件的易语言支持库是几乎不可能的(我没有说的很死),……”现在我很庆幸当时用了括号,没有把话说绝,还留下了一丝可以回旋的余地,否则今日岂不无地自容?。“‘说不清’是一句极有用的话。……即使和讨饭的女人说话,也是万不可省的。”(鲁迅《祝福》)

下面是小道消息。

  前天(2008年4月2日)晚上,吴涛再次提出封装VCL窗口控件的想法(上次提出封装VCL是在三年之前,当时想按照封装ActiveX的思路进行,未果),并给出了将VCL控件之外再套一个MCF窗口的实现思路。昨天(2008年4月3日),研究此思路是否可行的重任交到了海洋肩上。 在研究了一整天之后,终于得到了可喜的结果。最终结果与吴涛的思路完全契合,只是稍有变通:将VCL窗口控件直接创建到易语言的窗口或容器组件上,同时给该VCL窗口控件“伪造”一个 CWnd* 对象(这一功能由易语言核心库提供接口),让易语言窗口系统认为它也是一个“合法”的易语言窗口控件。在事件处理方面,我们发现,如果将VCL控件直接作为易语言窗口或控件的子窗口,则VCL控件有时不能触发其自身事件。这其实与Windows消息机制有关,有些消息并不是直接发送给窗口(HWND)自身,而是发送给其父窗口。解决办法也很简单,只要让“需要接收事件的VCL控件”不作为易语言窗口的“直接子窗口”就可以了。例如:要处理“VCL按钮”的被单击事件,需要先在易语言窗口(或其它容器窗口)上放一个“VCL面板”,再在“VCL面板”上放“VCL”按钮。反之,易语言窗口控件要接收事件的话也不能作为VCL窗口控件的直接子窗口。已经比较理想了,MFC和VCL混用,做到这一步,至少我(liigo)很满意。易语言的广大用户,能用上丰富多采的VCL控件,应该也会很满意吧?

  吴涛不愧是易语言之父,别人不敢想的他敢想,别人做不了的他做了,技术嗅觉异常敏感。海洋不愧是最早的一批易友,易语言熟,C++熟,Delphi也熟,技术非常扎实,思路非常开阔。

  现在感觉,我4年前(2003.5)定制的Delphi开发易语言支持库的框架,结构太丑陋,(为什么当时就认为比较理想呢?),尤其是支持库大了之后,代码堆积在一起不说,仅定义一个函数就要把代码分散在多处,难以维护。我希望能再找一段时间,把这个框架好好调整一下,至于能不能找到更好的结果……我“说不清”。“易语言.飞扬”的C/C++开发接口的定义形式值得参考,考虑到与Pascal语言的差异,也未必可以行得通,但不妨一试。

附,之前的Delphi的易语言支持库开发框架(部分代码):


//  初始化库信息
procedure InitLibInfo;
begin
  LibInfo.m_dwLibFormatVer:
= LIB_FORMAT_VER;
  LibInfo.m_szGuid:
= PChar( ' 94BF81E432384A65867F69EF07C71D6D ' );   //  在Delphi中按下[Ctrl+Shift+G]即可得到一个全球唯一的GUID字串。一旦支持库发布,就不要更改此GUID了。  ——liigo注
  LibInfo.m_nMajorVersion: = 2 ;    //  主版本号
  LibInfo.m_nMinorVersion: = 0 ;    //  次版本号
  LibInfo.m_nBuildNumber: = 0 ;     //  构建版本号
  LibInfo.m_nRqSysMajorVer: = 3 ;
  LibInfo.m_nRqSysMinorVer:
= 0 ;
  LibInfo.m_nRqSysKrnlLibMajorVer:
= 3 ;
  LibInfo.m_nRqSysKrnlLibMinorVer:
= 0 ;
  LibInfo.m_szName:
= PChar( ' Delphi写的支持库,liigo* ' );   //  支持库名称
  LibInfo.m_nLanguage: = __GBK_LANG_VER;
  LibInfo.m_szExplain:
= PChar( ' 用Delphi写的易支持库,仅仅是做一下测试而已,博君一笑。现在急着拿出这个预览版,不是为了哗众取宠,而是因为我这几天做了一些比较有益的事情(把易支持库开发文档中的C++声明文件转换成了Pascal声明文件,花了很多心思的^_^), '   +   ' 希望把这个成果拿出来和易友们共同分享,希望大家有更多的方式开发易语言支持库,希望易语言越走越好!希望大家开开心心!! '   +   ' 安装了本支持库,在易主窗口“工具”菜单下应该会出现“关于liigo的支持库”一项(前提是您打开或新建了一个程序)。 '   +  # 13 + # 10   +   '     下一步Liigo将推出更多有实用价值的易语言支持库,敬请关注! ' );
  LibInfo.m_dwState:
= 0 ;

  LibInfo.m_szAuthor:
= PChar( ' liigo ' );         //  作者
  LibInfo.m_szZipCode: = nil;
  LibInfo.m_szAddress:
= nil;
  LibInfo.m_szPhoto:
= nil;
  LibInfo.m_szFax:
= nil;
  LibInfo.m_szEmail:
= PChar( ' liigo@sina.com ' );
  LibInfo.m_szHomePage:
= nil;
  LibInfo.m_szOther:
= nil;

  LibInfo.m_nDataTypeCount :
=  DatatypeCount;
  LibInfo.m_pDataType :
=  @DatatypeInfo;
  LibInfo.m_nCategoryCount:
= 1 ;
  LibInfo.m_szzCategory:
= PChar( ' 0000命令分类(1) ' + # 0 );
  LibInfo.m_nCmdCount:
= CommandsCount;
  LibInfo.m_pBeginCmdInfo:
= @CommandsInfo;
  LibInfo.m_pCmdsFunc:
= @ImpCommands;
  LibInfo.m_pfnRunAddInFn:
= AddInFunction;
  LibInfo.m_szzAddInFnInfo:
= PChar( ' 关于liigo的支持库 ' + # 0 + ' 具体的我也不说了,反正是预览版,没什么可讲! ' + # 0 );
  LibInfo.m_pfnNotify:
= ProsessNotify;
  LibInfo.m_pfnSuperTemplate:
= nil;
  LibInfo.m_szzSuperTemplateInfo:
= nil;
  LibInfo.m_nLibConstCount:
= ConstsCount;
  LibInfo.m_pLibConst:
= @ConstsInfo;
  LibInfo.m_szzDependFiles:
= nil;
end;


//  初始化命令信息
//  为保证支持库的向后兼容,请尽量在已有命令的后面添加新的命令。如果在中间插入新的命令,可能会影响使用本支持库的易语言程序。
procedure InitCommandsInfo;
var i:Integer;
begin
  
//  采用for+case的结构,可使新增一个命令或常量时,在复制、粘贴之后,尽可能减少修改代码的次数。下同。
   for  i: = 0  to High(CommandsInfo)  do   case  i + 1  of
  
  
1 : //  第一个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 求两数和 ' );
      m_szEGName:
= PChar( ' SumNum ' );
      m_szExplain:
= PChar( ' 这是对“求两数和”命令的介绍,简单加法……(liigo删削888字,和和)。 ' );
      m_shtCategory:
=   1 ;
      m_wState:
= 0 ;
      m_dtRetType:
= SDT_INT;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
2 : //  第二个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 新版信息框 ' );
      m_szEGName:
= PChar( ' Msg ' );
      m_szExplain:
= PChar( ' 调用API函数MessageBox产生的信息框窗口。 ' );
      m_shtCategory:
= 1 ;
      m_wState:
= 0 ;
      m_dtRetType:
= _SDT_NULL;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
3 : //  第三个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 关于 ' );
      m_szEGName:
= PChar( ' AboutMe ' );
      m_szExplain:
= PChar( ' 这是对“关于”命令的介绍,弹出一个有Delphi特色的窗口。本库上一版太大了,是因为里面包含了delphi窗体,这一版把窗体取消了,支持库的尺寸也小多了。 ' );
      m_shtCategory:
= 1 ;
      m_wState:
= 0 ;
      m_dtRetType:
= _SDT_NULL;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
4 : //  第四个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 播放Flash ' );
      m_szEGName:
= PChar( ' PlayFlash ' );
      m_szExplain:
= PChar( ' 弹出一个窗口,在其中播放指定的SWF文件。本库上一版太大了,是因为里面包含了delphi窗体,这一版把窗体取消了,支持库的尺寸也小多了。 ' );
      m_shtCategory:
= 1 ;
      m_wState:
= 0 ;
      m_dtRetType:
= _SDT_NULL;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
5 : //  第五个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 构造函数 ' );
      m_szEGName:
= PChar( ' Init ' );
      m_szExplain:
= PChar( '' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState : =   512   +   4 // 512表示这是构造函数,4表示隐藏。一般人我不告诉他。(liigo)
      m_dtRetType: = _SDT_NULL;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
6 : //  第六个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 析构函数 ' );
      m_szEGName:
= PChar( ' Free ' );
      m_szExplain:
= PChar( '' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState : =   256   +   4 // 256表示这是析构函数,4表示隐藏。一般人我不告诉他。(liigo)
      m_dtRetType: = SDT_INT;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
7 : //  第七个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 置数值 ' );
      m_szEGName:
= PChar( ' SetValue ' );
      m_szExplain:
= PChar( '' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState: = 0 ;
      m_dtRetType:
= _SDT_NULL;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
8 : //  第八个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 取数值 ' );
      m_szEGName:
= PChar( ' GetValue ' );
      m_szExplain:
= PChar( ' 返回“置数值”所写入的数值 ' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState: = 0 ;
      m_dtRetType:
= SDT_INT;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
9 : //  第九个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 取测试字节集 ' );
      m_szEGName:
= PChar( ' Method1 ' );
      m_szExplain:
= PChar( '' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState: = 0 ;
      m_dtRetType:
= SDT_BIN;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;

  
10 : //  第十个命令的信息---------------------------------------------------------
    with CommandsInfo[i]  do  begin
      m_szName:
= PChar( ' 取测试文本 ' );
      m_szEGName:
= PChar( ' Method1 ' );
      m_szExplain:
= PChar( '' );
      m_shtCategory :
=   - 1 // -1表示本命令是某数据类型的方法
      m_wState: = 0 ;
      m_dtRetType:
= SDT_TEXT;
      m_wReserved:
= 0 ;
      m_shtUserLevel:
= LVL_HIGH;
      m_shtBitmapIndex:
= 0 ;
      m_shtBitmapCount:
= 0 ;
      m_nArgCount:
= High(ArgumentsInfo[i]) + 1 ;
      m_pBeginArgInfo:
= pARG_INFO(ArgumentsInfo[i]);
    end;
  
//  在此添加其它命令信息

  end; 
//  end of case and for
end;


//  初始化参数信息
procedure InitArgumentsInfo;
var i,j,count:Integer;
begin
  
for  i: = 0  to High(ArgumentsInfo)  do   case  i + 1  of

  
1 : // 以下是第一个命令的参数信息================================================
      begin
      count:
= 2 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
for  j: = 0  to High(ArgumentsInfo[i])  do   case  j + 1  of
      
1 :   // 第一个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 加数一 ' );
            m_szExplain:
= PChar( ' 加数一的介绍…… ' );
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_INT;
            m_nDefault:
= 0 ;
            m_dwState:
= AS_HAS_DEFAULT_VALUE;
          end;
      
2 :   // 第二个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 加数二 ' );
            m_szExplain:
= nil;
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_INT;
            m_nDefault:
= 0 ;
            m_dwState:
= AS_HAS_DEFAULT_VALUE;
          end;
      end; 
//  end of case j+1 and for
      end;  //  end of case i+1

  
2 : // 以下是第二个命令的参数信息================================================
      begin
      count:
= 3 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
for  j: = 0  to High(ArgumentsInfo[i])  do   case  j + 1  of
      
1 :   // 第一个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 提示文本 ' );
            m_szExplain:
= nil;
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_TEXT;
            m_nDefault:
= Integer(PChar( '' ));
            m_dwState:
= AS_HAS_DEFAULT_VALUE;
          end;
      
2 :   // 第二个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 按钮 ' );
            m_szExplain:
= PChar( ' 与“信息框”中同名参数取值相同 ' );
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_INT;
            m_nDefault:
= 0 ;
            m_dwState:
= AS_HAS_DEFAULT_VALUE;
          end;
      
3 :   // 第三个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 窗口标题 ' );
            m_szExplain:
= nil;
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_TEXT;
            m_nDefault:
= Integer(PChar( ' 信息: ' ));
            m_dwState:
= AS_HAS_DEFAULT_VALUE;
          end;
      end; 
//  end of case j+1 and for
      end;  //  end of case i+1

  
3 : // 以下是第三个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第三个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;

  
4 : // 以下是第四个命令的参数信息================================================
      begin
      count:
= 1 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
for  j: = 0  to High(ArgumentsInfo[i])  do   case  j + 1  of
      
1 :   // 第一个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' SWF文件名(*.swf) ' );
            m_szExplain:
= PChar( ' 需要指定包括完整路径和扩展名的*.swf文件,如c:liigo.swf ' );
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_TEXT;
            m_nDefault:
= 0 ;
            m_dwState:
= 0 ;
          end;
      end; 
//  end of case j+1 and for
      end;  //  end of case i+1

  
5 : // 以下是第五个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第五个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;
  
6 : // 以下是第六个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第六个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;

  
7 : // 以下是第七个命令的参数信息================================================
      begin
      count:
= 1 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
for  j: = 0  to High(ArgumentsInfo[i])  do   case  j + 1  of
      
1 :   // 第一个参数----------------------------------------------------------
          with ArgumentsInfo[i][j]  do  begin
            m_szName:
= PChar( ' 数值 ' );
            m_szExplain:
= PChar( '' );
            m_shtBitmapIndex:
= 0 ;
            m_shtBitmapCount:
= 0 ;
            m_dtDataType:
= SDT_INT;
            m_nDefault:
= 0 ;
            m_dwState:
= 0 ;
          end;
      end; 
//  end of case j+1 and for
      end;  //  end of case i+1

  
8 : // 以下是第八个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第八个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;
  
9 : // 以下是第九个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第九个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;
  
10 : // 以下是第十个命令的参数信息================================================
      begin
      count:
= 0 ;   // !!! 本命令的参数个数
      SetLength(ArgumentsInfo[i],count);
      
// !!! 第十个命令没有参数(!!!注意:没有参数的,也必须有以上两行代码!)
      end;

  
//  在此添加其它命令的参数信息

  end; 
//  end of case i+1 and for
end;


//  初始化命令实现信息
procedure InitImpCommands;
begin
  ImpCommands[
0 ]: = AddNum;
  ImpCommands[
1 ]: = Msg;
  ImpCommands[
2 ]: = AboutMe;
  ImpCommands[
3 ]: = PlayFlash;

  ImpCommands[
4 ]: = Datatype1_Init;
  ImpCommands[
5 ]: = Datatype1_Free;
  ImpCommands[
6 ]: = Datatype1_SetValue;
  ImpCommands[
7 ]: = Datatype1_GetValue;
  ImpCommands[
8 ]: = Datatype1_Method1;
  ImpCommands[
9 ]: = Datatype1_Method2;
end;


//  初始化常量信息
procedure InitConstInfo;
var i:Integer;
begin
  
for  i: = 0  to High(ConstsInfo)  do   case  i + 1  of

  
1 : // 第一个常量----------------------------------------------------------------
      with ConstsInfo[i]  do  begin
        m_szName:
= PChar( ' 常量一 ' );
        m_szEGName:
= PChar( ' Const1 ' );
        m_szExplain:
= nil;
        m_shtReserved:
= 1 ;
        m_shtType:
= CT_TEXT;
        m_szText:
= PChar( ' Hi, liigo! ' );
        m_dbValue:
= 0 ;
      end;

  
// 在此添加其它常量信息

  end; 
//  end of case and for
end;


//  初始化数据类型信息
procedure InitDatatypesInfo;
var i,j,ElementCount,CmdCount:Integer;
begin
  
for  i : =   0  to (DatatypeCount  -   1 do   case  i + 1  of
  
1 // 第一个数据类型-----------------------------------------------------------
     begin
       
// 定义数据类型的成员信息
       ElementCount : =   1 ;
       SetLength(DatatypeElementInfo[i], ElementCount);
       
for  j : =   0  to ElementCount - 1   do   case  j + 1  of
         
1 // 第一个成员
            with DatatypeElementInfo[i,j]  do  begin
              m_dtDataType :
=  SDT_INT;  // 整数型,正好可以存储一个指针。我们用它存储一个Delphi类对象的指针(而这个对象是可以存储任意数据并提供各项功能的)。
              m_pArySpec : =  nil;
              m_szName :
=  PChar( ' self ' );
              m_szEGName :
=  nil;
              m_szExplain :
=  PChar( ' 本成员已被隐藏,仅用作存储内部数据 ' );
              m_dwState :
=   2 // 2表示隐藏本成员!!! 一般人我不告诉他。(liigo)
              m_nDefault : =   0 ;
            end;

         
// 在此添加其它成员
       end;

       
// 定义数据类型的方法(数据类型的方法跟全局函数一样定义于InitCommandsInfo内)
       CmdCount : =   6 // !!! 本数据类型的方法个数
       SetLength(DatatypeCmdIndex[i], CmdCount);
       DatatypeCmdIndex[i,
0 ] : =   4 // 在此指定索引为4的命令(即第五个命令)为本数据类型的第一个方法
       DatatypeCmdIndex[i, 1 ] : =   5 // 同上. 如果还有其它方法,按类似的方法顺序对数组DatatypeCmdIndex[i]赋值
       DatatypeCmdIndex[i, 2 ] : =   6 ;
       DatatypeCmdIndex[i,
3 ] : =   7 ;
       DatatypeCmdIndex[i,
4 ] : =   8 ;
       DatatypeCmdIndex[i,
5 ] : =   9 ;
       
// ...

       
// 定义数据类型基本信息
       with DatatypeInfo[i]  do  begin
         m_szName :
=  PChar( ' 数据类型一 ' );
         m_szEGName :
=  PChar( ' Datatype1 ' );
         m_szExplain :
=  PChar( ' 关于数据类型一的说明 ' );
         m_nCmdCount :
=  CmdCount;
         m_pnCmdsIndex :
=  @DatatypeCmdIndex[i, 0 ];
         m_dwState :
=   0 ;
         m_dwUnitBmpID :
=   0 ;
         m_nEventCount :
=   0 ;
         m_pEventBegin :
=  nil;
         m_nPropertyCount :
=   0 ;
         m_pPropertyBegin :
=  nil;
         m_pfnGetInterface :
=  nil;
         m_nElementCount :
=  ElementCount;
         m_pElementBegin :
=  @DatatypeElementInfo[i, 0 ];
       end;

     end;
  
// 在此添加其它数据类型定义


  end;
end;

procedure InitDatatypeElementsInfo;
begin

end;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值