在C中设计一个简单的GUI框架

时间:2015-08-10 12:53:24

标签: c user-interface design-patterns

我需要为学校项目设计一个非常简单的 GUI框架,该框架需要支持以下控件/窗口小部件:窗口,面板,图像,标签和按钮。

  • 我想到的第一个问题是public static Task<T> SwallowExceptions<T>(this Task<T> task) { return task.ContinueWith(completedTask => completedTask.IsFaulted ? default(T) : completedTask.Result); } 是否应该成为一个控件。我认为这是假设的。
  • 我们有WindowWindow,其中包含其他控件。 PanelButtonLabel不能。所以我们需要两种基本类型的控件;一个是容器而另一个不是(我在Gtk实现中看到后者也是一个容器,但只能包含一个孩子。它叫做GtkBin。我认为这是我的简单开销项目
  • 我遇到的第三个问题是:我需要遍历UI树(对于绘图),但由于C中没有多态性机制,因此它变得有些问题。

我考虑了以下解决方案,使用Image。基本上我需要一些函数来将泛型union转换为它的实际类型。

Control

所以我想了解一下我所介绍的问题以及对我当前战略的看法(我寻找实施,而不是想法/想法等)

感谢。

2 个答案:

答案 0 :(得分:2)

你应该在每个“GUI类”的布局中放置一个void *,它将指向为每种类型手动实现的v-tables。每个类型的v表中的第一个函数可以是一个,为每个类型返回一个唯一的整数(或者只是一个唯一的整数),这样你就可以知道什么是什么,并实现了一些类型安全。虽然没有必要,但您可以使用v-table指针值来确定类型(因为它将是唯一的),这将节省内存,但不太明显。在对象销毁中使用虚拟主义也是至关重要的,因此用于处理每个唯一类型内部的析构函数及其在v表中的位置是一致的也是必须的。虽然对于你的任务来说,这可能实际上是可以避免的,但对于生产来说这是必须的。

对于实际的树,这应该建立在一个简单的父子关系上,围绕一个叶子和节点接口,叶子只有一个指向父节点的指针,该节点还包括一个动态列表类型你还必须实行。然后遍历树是相当简单的。

你可以通过使用“接口”结构和聚合代替继承来模块化一些,但是与单独实现每个类型相比,只要你保持v表指针,就不会省去太多的努力。类型布局中的第一个对象,以便您知道您正在使用什么以及如何使用它。只要您知道类型并将指针强制转换为适当的结构类型,其余的布局对于遵循任何准则并不是至关重要的。但是因为每个对象都有一个父对象,甚至是根,它的父对象可以识别为0,所以你真的应该把父对象放在v表指针之后,这样你可以避免在你需要访问的时候进行转换。父母。

您可以从中受益的另一件事是使用信号,就像在每个按钮中都有另一个指针一样,因此您可以将其分配给在“单击”按钮时执行的功能。

答案 1 :(得分:0)

这里有两个不同的问题:GUI的概念及其在C中的实现。如果OO模型中的概念更简单,那就这样写吧。由于第一个C ++编译器只是C代码的预处理器,C 可以使用vtable实现OO建模。

首先明确定义您的对象(类):可以是容器,它们是可绘制的,可以对鼠标或键盘事件做出反应。它们的属性是什么:文本,x-y坐标,位图以及可能的z坐标。在该阶段结束时,您应该有一个具有属性和方法的类的层次结构,以及子类中可能的覆盖 - 如果您已经学习了它,UML可以为该部分提供帮助。

其次,你必须在C中实现它。不要担心它。你不会有免费的复制和移动构造函数的语法糖,也不会有public,private和protected属性的概念,但是struct可以包含子对象,指向其他结构的指针和指向函数的指针。

您只需要一个词典来翻译C中的OO工具:

  • class:struct
  • 类的字段:struct的字段
  • 类的方法:第一个属性是指向struct
  • 实例的指针的函数
  • 虚方法:指向方法的指针
  • 构造函数和析构函数:必须明确调用的特殊方法 - 如果结构超出范围则不会自动销毁

非final类(包含虚方法)应包含VTABLE,它只是指向虚方法的指针数组。这个VTABLE应该是struct的第一个元素,以简化类指针的转换。派生类首先包含它自己的vtable(如果它不是final),然后是它的属性,然后是它的父实例。从父项到派生指针的强制转换只是添加偏移量的问题。如果需要多重继承,则在结构中的第一个之后添加其他父项。虚拟继承实现起来会稍微困难一些,因为它涉及VTABLE中的指针。如果需要类感知对象,只需在VTABLE中添加常量即可。但我不认为您需要所有这些以满足您的要求。

如果你真的想要更难的位,那么看两遍:多重继承和类感知对象,然后只在其.h + .c文件中实现每个类。你甚至可以获得免费的私有方法:它们只是静态函数。