问题是这样的,我想用delphi开发一个UI编辑器,就是使用者可以利用它按照自己的意图设计一个界面,使用者可以从UI编辑器中拖放Form Button Edit等常用元件(可视化),并且可以对拖放的元件进行常用的属性(大小、颜色等)设置,设计完成后保存成某个类型(如dat)的文件,之后如需要此界面,只要导入对应的文件即可。
我如何使UI编辑器中的元件可视化,可由用户自行拖放,譬如我们拖放delphi工具栏上的Button组件一样(因为客户可能是不知道delphi知识的,总不能让他安装delphi吧),请大家讨论,并指点我一下该如何做,有Demo更好,或Code。谢谢...

解决方案 »

  1.   

    去看VCLSkin的Skin Builder程序是怎么做的.不是个简单活!
      

  2.   

    网上有用Delphi开发的Delphi,好像韩国人做的,不知有没有源码。
      

  3.   

    如果这个dat文件也是需要被加载到程序里作为form显示的,为什么不直接给用户一套免费的delphi express?
    另外,单单form,没有事件代码的吗?运行时加载外部的dfm+pas文件,我倒正好做过——不过设计、编码、调试还是直接使用delphi好了
    http://szhaitao.blog.hexun.com/12121564_d.html
    实现一个基于delphi的win32客户端+delphi语法脚本的Notes:
    http://www.cndev.org/.imgdb/sn10100/GUID-CDCDBE17-AB26-4732-81C1-AF47E54D958E.jpg
    (它其实是一个rar包,下载了转存为xxx.rar即可解压,执行里面的testLoadFormApp.exe即可,unit1.pas/dfm和unit2.pas/dfm就是2个实例,
    testLoadFormApp.exe就是delphi的win32客户端,它可以加载硬盘里的pas/dfm文件,并把dfm对应的form显示出来,而且实现pas里的事件响应
    就好像外部的pas/dfm是预先被编译进exe的一样!唯一的差别是,你修改了硬盘里的pas/dfm文件,让exe重新加载,即可看到你新改的代码的效果!
    这才证明外部的pas/dfm不是预先被编译进exe的!)
    很欣赏notes的架构:业务数据、业务表单、业务脚本都存储在后台的数据库,使用时加载到前台
    只是一直受不了notes客户端的庞大、不稳定,也不喜欢它的basic脚本,所以很想全部使用delphi实现类似的架构
    上面的例子就是第一步,把外部的pas/dfm文件改进为从webserver后台动态下载加载,就做到了:业务数据、业务表单、业务脚本都存储在后台,使用时加载到前台!
    而设计这些业务表单,编写调试这些业务脚本,都可以通过delphi来进行,只有调试通过了,才把它们的源代码(有必要可以先加密)发布到webserver,供已经在客户电脑安家的exe来取得运行 gif演示动画:
    http://www.cndev.org/.imgdb/sn10087/GUID-56451A8B-5DC4-4706-B87D-C89CC1EEE642.jpg
    http://www.cndev.org/.imgdb/sn10087/GUID-C6729A9D-3DFA-41D1-9D11-D550F7D5DCAE.jpg
      

  4.   

    给客户装个delphi好了,直接用delphi的dfm文件,只要你解一下它的格式就ok(是个文本)
      

  5.   

    不是容易的事情,有朋友搞过,可能光实现拖放这里也有得你搞了。记得好像有人做过个单元来hook这些控件,具体不大懂。
      

  6.   

    楼主,我建议你下一个FASTREPORT研究一下,开源的。放心,里面就有你想要的结果。
      

  7.   


    呵呵,做的最彻底,就是一个脚本化的delphi了!
    我已经初步实现了:运行时外部(文件或http流)加载dfm+pas,实现界面+事件代码的全动态
    http://szhaitao.blog.hexun.com/12121564_d.html
      

  8.   

    我也建议简化功能吧,除非你们是打算做IDE或者二次开发工具。如果是给一般用户用的话就没什么必要了,大部份用户根本就不会用这么高级的功能,反而有可能会责怪你们把东西搞得那么复杂,害他们不会用。你可以说明难度和所需时间,上面自会评审是否有必要把这么多精力放在一个用户可能并不常使用的功能上。如果别人还是觉得有必要,那就没办法了,只好上咯。
      

  9.   

      如果不要实现事件机制,只是界面设计,我有个粗略的想法,你参考看看:
    1. 先定义一些类, TCustomGUI: 这个是基类,可以从TPersistent继承,它的子类TGUIButton, TGUILabel分别代表你要设计的控件
    例子:
      TWinControlClass = class of TWinControl;  TCustomGUI = class(TPersistent)
      private
        FInnerControl: TWinControlClass; //这个是真正的GUI控件,从面板上拖出来的时候,就实例化它绘制在窗体上。
         FinnerControlHandle: THandle; //GUI控件,可以对其发消息,截获消息     FParent: TControl; //容器,可以是一个TFrom,或者TPanel
         ...
      public
        //一些属性,根据你的需要去设计,注意和FInnerControl对应的属性同步
        property Color: TColor read .. write ..;
        property Width: Integer read .. wirte ..;
        constructor Create(AInner: TControlClass); 
        function GetGUIInstant: THandle; //实例化控件的方法,返回其Handle, 和FInnerControlHandle同步
      end;
      2. 然后你准备一些图标,分别代表按钮,标签之类的GUI控件,在一个ToolBar上把这些图标显示出来。3. 实现绘制,拖放
       绘制比较容易,用一个TPanel做容器,响应鼠标事件,在对应的位置上把控件实例化,设定他的FParent, 以及大小属性。
       拖动这些控件比较繁杂一点,当选中(用hook技术去实现,当选中时通知)的控件拖动的时候,把选中的那个控件释放掉,也就是某个FInnerControl释放掉(FInnerControlHandel也要=0), 当放下的时候,在新的位置重新实例化,在这个过程中,鼠标光标要显示一个虚框。就是在Delphi中设计时一样。4. 你还需要一个属性面板, 当某个控件被选中的时候,也要同步属性面板上的东东,属性变动时,也要改变对应的控件。控件有哪些属性可以用RTTI技术,建议第一版本先简单点。5. 因为你要知道当前编辑的控件对应List中那个TCustomGUI, 所以需要一个List去维护它们。6. 持久化, 就是把设计好的保存起来,其实就是把第5点的List中的TCustomGUI中数据保存到文件中。7. 实现从文件中读内容并显示。因为我也没有做过,所以不能给更详细的东西了,希望以上对你有帮助。  
      
      

  10.   

    用图片只是简化点的做法,如果想做到在编辑Caption属性时同时LABEL要有显示就不行了。