这里的两个答案都很好,但忽略了我认为真正有趣的部分(包括一些你没有直接问的,但无论如何你可能会感兴趣),所以这是我的 2c:
绘制控件
理想情况下,您只需继续创建控件的常规实例。你想要一个看起来像按钮的东西吗?创建一个真正的按钮。棘手的事情是阻止它表现得像一个按钮:您希望单击以激活它以进行移动,而不是实际“单击”它。
处理此问题的一种方法 - 假设所讨论的控件是“基于 HWND”的(例如,标准窗口集的按钮、编辑、静态、列表框、树视图等) - 是创建控件,然后创建子类它 - 即。使用 SetWindowLongPtr(GWLP_WNDPROC, ...) 覆盖 wndproc,以便设计器代码可以拦截鼠标和键盘输入并使用它来启动移动,例如,而不是让鼠标输入通过实际的按钮代码,这而是将其解释为“点击”事件。
子类化的另一种方法是在按钮上方放置一个不可见的窗口来捕获输入。拦截输入的想法相同,只是实现不同。
以上适用于托管(VB.Net、C#)和非托管(C/C++)控件;它们本质上都是股票窗口 HWND;托管版本只有一个托管包装代码移交给底层的非托管控件。
在.Net VB 之前使用的旧的(预管理代码)ActiveX 控件是完全不同的球类游戏。ActiveX 容器和其中的 ActiveX 控件之间存在相当复杂的关系,许多 COM 接口处理诸如属性协商、事件、绘制等事务。(有一组接口允许 ActiveX 控件接收输入并在没有自己的 HWND 的情况下自行绘制。)但是,您从这种复杂性中获得的一个好处是 ActiveX 控件具有明确的“设计模式”。所以控件知道在这种情况下做出适当的响应,并且可以与整个过程合作。
表格本身...
所以基本上这些控件只是常规控件。所以您希望表单本身是常规表单?- 几乎。据我所知,它只是另一个基于 HWND 的窗口,它是设计器的子窗口(因此它会被剪辑,并且可以在其中滚动);但我认为设计师在这里做了一些“作弊”,因为通常 Windows 只绘制框架,例如 - 带有用于实际顶级窗口的标题栏和最小/最大按钮。我不知道他们在这里使用的确切技术,但一些选项可能包括:手动绘制以模仿 Windows 外观;使用 Windows“主题”API,它允许您访问用于标题栏的点点滴滴的图形元素,并在任何您想要的地方绘制它们;或者,可能不太可能,将窗口设置为“MDI 子窗口”
可拖动手柄
这里最简单的方法是让设计人员创建八个没有标题栏的小方形弹出窗口,这些窗口位于所有其他元素之上——当它们被点击时,它们会启动适当的调整大小代码。当用户从一个控件单击到另一个控件时,只需将拖动句柄窗口移动到当前活动的控件。(请注意,在上述所有内容中,Windows 本身都在确定谁被点击了,您不必实际比较鼠标坐标与元素矩形坐标并自己计算出来。)
保存和重建
对于非托管 C/C++ 使用的普通 Windows 系统控件,它相对容易:有一种众所周知的基于文本的文件格式 - .rc - 描述控件和位置。让设计人员吐出它(也可能是一个 resource.h 文件),你就完成了:任何 C/C++ 项目都可以获取这些文件并编译它们。托管代码(C#、VB.Net)有更多复杂的方案,但它仍然是相同的基本思想:以托管工具所期望的样式写出描述,他们会很高兴地编译并使用它。
(ActiveX 控件 - 你已经猜到了 - 完全是另一回事。我知道没有标准格式,因此使用数据的表单编辑器和运行时将紧密联系在一起 - 例如。 pre-.Net VB6 的表单编辑器生成只有 VB 才能使用的表单。-我想。已经有一段时间了......)
至于重新创建表单:如果您有一个 .rc 文件,它会被编译为对话框资源,Windows 已经内置支持重新创建这些文件。同样,托管代码支持库知道如何从特定格式重新创建表单。两者都基本上解析描述,并为每个项目创建适当类的元素,并按指定设置适当的样式、文本和其他属性。它没有做任何你自己做不到的事情,它只是帮助实用程序代码。
处理焦点
对于任何容器中的 HWND 集合,无论是在“测试”模式下还是在实际应用程序中实际运行,无论您是让 Windows 或 Winforms 处理表单创建还是您自己创建每个 HWND,您都可以通过以下方式添加选项卡支持在消息循环中调用IsDialogMessage:有关详细信息,请参阅 MSDN 页面备注部分。(虽然 WinForms 可以做到这一点,但我认为它实际上做了自己的焦点处理,因此它可以具有独立于视觉堆叠 Z-Order 的 Tab 键顺序。)
其他要探索的东西...
与 Spy++ 应用(SDK 的一部分,随 Visual Studio 一起安装)交朋友。如果您打算使用托管或非托管 HWND 做任何事情,那么了解如何使用此工具是一个真正的好主意:您可以将它指向 Windows 上的任何 UI,并查看它是如何从一棵树构建的不同类型的 HWND。将它指向 VB 设计器,看看自己真正发生了什么。(单击工具栏上的“双筒望远镜”图标,然后将十字准线拖动到您感兴趣的窗口。)
还要看一下设计器吐出的资源文件。您可以在表单设计器中调整、移动或编辑的所有内容都对应于其中一个资源文件中的某个项目。复制它们,调整一些设置,然后对两组进行文件比较,看看有什么变化。尝试手动更改文件中的一些内容(我认为它们几乎都是文本),重新加载,看看设计师是否接受了您的更改。
其他注意事项...
上面的大部分内容都是针对 Windows 的——特别是因为我们使用的是 Window 自己的构建块——HWND——我们可以让 Windows 本身为我们做一些艰苦的工作:它为我们提供了重用控件本身的工具在设计时,我们不必绘制模型;拦截其他控件上的输入,以便我们可以单击移动或我们想要的任何其他操作,或者找出单击了哪个控件,而无需自己进行位置数学运算。如果这是其他一些 UI 框架(例如 Flash)的设计者,它在内部不使用 HWND,它可能会改为使用
该框架自己的内部设施来完成类似的工作。
此外,如果您将调色板中的控件数量限制为一个小的有限集,至少在开始时会更容易。如果您想允许任何控件被拖入 - 例如。第 3 方,或您在另一个项目中使用过的;您通常首先需要某种方法来“注册”该控件,以便设计人员首先知道它是可用的。您可能还需要一些方法来发现它在工具栏中使用的图标、它的名称、它支持的属性等等。
尽情探索吧!