最近写一个程序,要求可按照用户的某些要求自动生成vb代码(生成一个完整工程),遇到几个问题向高手请教:
1.在所生成的frm文件中,有可能要用到一些非标准控件(肯定也是vb安装后带来的),这些控件的使用和注册表有关。例如,我在form1中用了一个richtextbox控件,保存后用记事本打开form1.frm则可看到“Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "RICHTX32.OCX"”,其中的“3B7C8863-D78F-101B-B9B5-04021C009402”应为该控件在注册表中的位置。我看了几台计算机,此控件在注册表中的位置都是“3B7C8863-D78F-101B-B9B5-04021C009402”。但不知windows是否能保证所有计算机的每一个控件的注册位置都相同?望知道的朋友能给以解答?
2.我生成的frm文件中有可能包含某些图像信息,例如我为某一form设置图标,则会生成同名frx文件,不知写此文件应遵循什么规则?另外richtextbox、combobox等控件也可能有些信息存入frx文件,又应遵循什么规则?还有哪些控件有可能要写frx文件?
问题都相对较偏,希望知道的朋友能给以解答,谢谢!

解决方案 »

  1.   

    回复2:
    *.frx由VBIDE集成编译环境自动生成.似乎属于ActiveX控件都回写入*.frx文件.
      

  2.   

    我知道手动创建或打开vb工程时,如编辑某一form,frx文件会根据需要自动生成,但问题是我现在要自动生成代码,所以就只能根据某种规则自己生成frx文件了
      

  3.   

    frm文件是文本,这个就简单了,frx的规则的确让人头疼
      

  4.   

    1)某个版本的控件 CLSID 必定固定,VB 在打开工程时会自动检测版本的兼容性,不用担心。2)完全可以做到不产生 .frx 文件。比如窗体的图标你可以生成以下代码代替
    Private Sub Form_Load()
        Set Me.Icon = LoadPicture(App.Path & "1.ico")
    End Sub
      

  5.   

    手工设置图片才产生.frx 文件
      

  6.   

    谢谢各位朋友的回答。如果 CLSID 必定固定,那么我的第一个问题就解决了。关于第二个问题,如果象Tiger_Zhao朋友说的“Set Me.Icon = LoadPicture(App.Path & "1.ico")”那样写的话,会造成生成的程序不好移植(运行时也必须带着1.ico),而且某些非图片控件也会产生frx文件,例如,我在form1上面放了一个名为aaaa的richtextbox控件,则用记事本打开frm文件可看到下面的内容:
       Begin RichTextLib.RichTextBox aaaa 
          Height          =   615
          Left            =   1980
          TabIndex        =   6
          Top             =   2400
          Width           =   1965
          _ExtentX        =   3466
          _ExtentY        =   1085
          _Version        =   393217
          Enabled         =   -1  'True
          TextRTF         =   $"Form1.frx":0000
       End
    也会导致frx文件的产生
      

  7.   

    打包的时候把使用了那些ACTIVEX控件的位置设置成一样即可
      

  8.   

    任何打包工具都要设置这些ocx的安装位置
    一般是Windows,system32和exe所在文件夹三处
    你在使用的时候可以不考虑这些
    打包(也就是制作安装程序.脱离VB)的时候有选项用来设置
      

  9.   

    我要做的并不是把exe打包,而是要生成可编译出这些exe文件的代码(含vbp、frm、frx、bas等文件类型),用户直接用vb编译生成的代码即可得到可执行文件。所以要考虑怎样生成frm配套的frx文件。
      

  10.   

    还有vbw文件,不知哪位朋友可以解释一下该文件的规则?谢谢!
      

  11.   

    自动生成代码,窗体/控件的话建议用VB插件来做.
    Visual Modeler 就是使用插件的形式自动生成代码的
      

  12.   

    .vbw 文件完全可以不要。
      

  13.   

    vbw文件是保存工程时自动产生的
      

  14.   

    FRX里面存储的是同名窗体所需要的二进制数据.简单看了一下,保存一个图片的格式是:F9 3B 00 00 6C 74 00 00 F1 3B 00 00一共是三个四字节值做头部,后面就是图片文件本身的二进制内容.用VB的类型来描述,就是:type X
        lMaxLen as long   '前四字节为这一段数据的总长度,不包括这四字节
        lUnKnow as long    '未知的四字节值,没找出规律.
        lPicLen as long    '图片文件的长度
        bytePic() as byte   '这里就是整个图片的内容
    end type
    每个图片就是一段这样的内容,你可以用上面的结构直接从FRX里读出图片.其它类型的二进制值就自己分析一下吧,FRX文件未加密,只是一个打包而已.不过有可能类型比较多,有够你分析的........整完了记得分享一下,嘿嘿.
      

  15.   

    TextRTF        =  $"Form1.frx":0000 //这个语法就是说明当前的这个值位于指定FRX文件的0000h偏移处.这个偏移里面有相应的信息能被控件所识别.
      

  16.   

    如果你要生成的FRX文件的内容比较单一,比如只有图片,那还好说些.另,lUnKnow as long这个成员我试了几个图片,好象总是746Ch,有可能是一个标明类型的常量吧.
      

  17.   

    a)安装报就是用来保证程序与必需的外部文件同步发布的。b)所有的控件属性都有默认值,所以你直接将该行删除,完全没有问题。
    只不过默认文本是空白,你还是可以在 Form_Load 中进行设置的。
      

  18.   

    再次感谢各位朋友的热心回答。我要给窗体设置图标一方面是因为各窗体更漂亮,另一方面也是要给最终生成的可执行文件设置图标。例如,我在form1启动时写了“Set Me.Icon = LoadPicture(App.Path & "1.ico")”,这样可以在form1运行时显示所设置的图标,但如我在工程--属性--生成里面将图标设为form1,生成exe的图标还是默认图标。因此,我觉得最好还是将图标写入frx文件中,提前设置好相关属性。
      

  19.   

    还有一点不清楚的地方,如果使用自定义控件,windows如何能保证其clsID必定固定?
      

  20.   

    控件的 CLSID 在编译时写入了相应的 .ocx 文件中(Active DLL 也是一样),因此对于某一个确定的 .ocx 文件,它的 clsID 是确定的。你把这个文件发布给别人,他用 regsvr32 注册(或因加载时被系统自动注册),会从这个文件中读取相应的CLSID 。所以在别人计算机上用这个文件,它的 CLSID 也是相同的。
    但是,如果你把源代码重新编译一次,新生成的 .ocx 的 CLSID 肯定跟原来的不一样。
      

  21.   

    那windows怎样才能保证CLSID不重复呢?例如我自己编了一个ocx,其CLSID为“3119ACCE-F3D8-4ABC-B13A-5197FA70AE2B”,那么到一台新计算机,其CLSID是否也为“3119ACCE-F3D8-4ABC-B13A-5197FA70AE2B”?有没有可能该计算机已经将另一ocx(或其他文件)的CLSID设为“3119ACCE-F3D8-4ABC-B13A-5197FA70AE2B”?如果出现这样的情况,windows又会如何处理?谢谢!
      

  22.   

    CLSID 的格式是传说中的“GUID”--全球唯一标识码。
    据说重复机率好象是(记不清楚了,以前在哪见过) 40万亿分之一。
    要是遇到与当前系统中的某个 CLSID 重复了,重新生成一个就行了。
    第二次生成还出现重复(也可以再生成一次呀)?恐怕比你连续中5期双色球头等奖的可能性还小。  
      

  23.   

    工程编译属性选“二进制兼容”,这样在重新编译时会先读取旧 OCX 中的 TypeLib 信息,如果接口不变就能保证 CLSID 不变。
      

  24.   

    我的意思是说,假设在A计算机上编译了新控件a.ocx,在B计算机上编译了新控件b.ocx,二者都生成了各自的CLSID并写入注册表中,有没有下面这种可能(当然概率极低),a.ocx与b.ocx得CLSID相同?如这种情况发生,我将使用a.ocx的源程序(或编译好的可执行文件)从A计算机复制到B计算机,会出现什么情况?VB6怎样处理?谢谢!
      

  25.   

    1)只复制源程序:源程序不包括注册信息,等于是新建工程,与 b.ocx 无关。
    2)只复制 a.ocx:
      a)如果不注册,则不可用。
      b)如果注册,a.ocx 和 b.ocx 的注册信息除了不同的 CLSID 还有相同的 ProgID,后注册的将覆盖先注册的,先注册的不可用。
    3)同时复制源程序和 a.ocx: 如果设置了二进制兼容,打开工程会字段注册,等同于 2)b) 情形。
      

  26.   

    31楼的朋友的意思是不是说:假设计算机A中建立了工程a.vbp,其中用了本机编译的a.ocx,将其复制到计算机B,假设计算机B中另编译了控件b.ocx,b.ocx与a.ocx得CLSID相同(极低的小概率事件),这时在计算机B打开a.vbp时,系统自动将a.ocx信息写入注册表,发现a.ocx的CLSID已经被b.ocx使用,会自动重写注册表,用a.ocx将b.ocx信息覆盖(也就是说,将此CLSID分配给a.ocx,此后在计算机B上将不能使用b.ocx)。
    是我理解的这个意思吗?谢谢!
      

  27.   

    我也相信这绝对是小概率事件,我一直相信,以概率来说:被雷劈>彩票中大奖>CLSID重复。(开个玩笑)但问题在于我要做的是自动生成程序源代码(有可能使用自定义控件),所以要考虑各种可能性。
      

  28.   

    To 32F:
      老鸟说的应该是那个意思~~~~~~~^_^
      

  29.   

    反正那些 CLSID 都是 MS 的通过某个算法得到的,在不同的计算机之间出现重复的可能性也是是非常小的。
      

  30.   

    CLSID 是身份证号,A、B 不同,不会覆盖。
    ProgID 像是姓名,A、B 可以取名相同,会覆盖。
    所以 B 不一定完全不可用,通过 CLSID 有可能成功引用的,但这种混乱的情况是应该极力避免的,你要把 B 当作完全不可用看待。
      

  31.   

    ProgID 的内容被覆盖(改写),程序加载时的对象就不一样了。
    不同的对象 CLSID 相同,极有可能引起一些意想不到的问题。