IUP的两个补丁

我正计划编写一个SQLite的图形前端。为此我选择IUP作为图形界面库。

IUP具有如下特点符合我的口味,因此被我选作图形界面库:

  1. C语言接口。GUI常用面向对象的方法处理,所以使用C++的图形界面库更常见。IUP使用C语言实现了一套类型系统,并提供了非常简洁的C语言接口。
  2. 跨平台。使用IUP编写的图形界面程序可以运行在Windows和UNIX操作系统上。
  3. 相对GTK+、Qt等大型的图形界面库(Qt应该算作综合工具箱),体积小巧便于发布,配置起来也比较容易。
  4. 控件虽然没有其他工具箱来得丰富,但基本够用。文档比较详细。

IUP目前最新的版本是3.14。它仍然存在一些问题,所以我在这里给出两个补丁。

第一个问题是IupSplit中嵌入的IupMatrix有时候会崩溃。我向IUP的作者反映了这个问题。作者回复说他已经在SVN中修复。所以,IUP的下一个版本中将不会再有这个问题。

补丁:(来自SVN

--- a/srccontrols/matrix/iupmat_edit.c
+++ b/srccontrols/matrix/iupmat_edit.c
@@ -678,6 +678,7 @@
   IupSetAttribute(ih->data->texth, "VALUE",  "");
   IupSetAttribute(ih->data->texth, "VISIBLE", "NO");
   IupSetAttribute(ih->data->texth, "ACTIVE",  "NO");
+  IupSetAttribute(ih->data->texth, "FLOATING", "IGNORE");
 
 
   /******** DROPDOWN *************/
@@ -696,4 +697,5 @@
   IupSetAttribute(ih->data->droph, "MULTIPLE", "NO");
   IupSetAttribute(ih->data->droph, "VISIBLE", "NO");
   IupSetAttribute(ih->data->droph, "ACTIVE",  "NO");
-}
+  IupSetAttribute(ih->data->droph, "FLOATING", "IGNORE");
+}

(注:截至写本文时,本站用于语法高亮的脚本Highlight.js的版本为8.5,它似乎不能正确显示上述代码:最后一部分被作为注释处理了。)

第二个问题是IupTree控件的NAME属性不起作用。即,无法使用IupGetDialogChild找到相应的控件。这是出于兼容性考虑,IupTree控件的NAME属性默认为是TITLE属性的同义词。

IUP的下一个版本也许还会保留这个行为,但我并不需要它。所以我也许应该修改IUP的代码,取消掉这样的兼容行为。要修改这个行为,需要修改平台相关的驱动代码。因为我目前在Windows下开发,所以我只修改了Windows相关的文件。其他平台做类似修改即可。

--- a/src/win/iupwin_tree.c
+++ b/src/win/iupwin_tree.c
@@ -3060,7 +3060,6 @@
   iupClassRegisterAttributeId(ic, "DEPTH",  winTreeGetDepthAttrib,  NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
   iupClassRegisterAttributeId(ic, "KIND",   winTreeGetKindAttrib,   NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
   iupClassRegisterAttributeId(ic, "PARENT", winTreeGetParentAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
-  iupClassRegisterAttributeId(ic, "NAME",   winTreeGetTitleAttrib,  winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
   iupClassRegisterAttributeId(ic, "TITLE",  winTreeGetTitleAttrib,  winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
   iupClassRegisterAttributeId(ic, "CHILDCOUNT", winTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
   iupClassRegisterAttributeId(ic, "COLOR", winTreeGetColorAttrib, winTreeSetColorAttrib, IUPAF_NO_INHERIT);

我不是很确定修改IUP的源码以使它符合我的需求是不是明智的选择。

一旦修改了IUP的源码,那么基本上来说,我应该将IUP静态链接到我的程序中。因为编译出一个修改过的动态链接库似乎并没有什么意义(不能被其他程序共用)。

还有一种做法是绕过IUP现在提供的IupGetDialogChild机制,另外建立一套获取窗体中的控件的机制。IUP传统的机制是为每一个控件指定一个全局的标识符。像IupSetAtt这样的便捷函数就是在鼓励使用这样的机制(也是为了兼容旧的LED窗体描述机制)。这种做法固然简单有效,但我觉得很丑陋。只可惜像IupTree这样的控件出于兼容性考虑还不能支持NAME属性。

我认为每个窗体有一个单独的名字空间才是正确的做法。不知道是不是出于同样的观点,IUP现在提供了一套新的机制,就是使用控件的NAME属性。这样,控件的标识符的作用域就仅限于其所在的窗体。使用IupGetDialogChild(dlg, "NAME")这样的函数调用来获得dlg窗体中标识符为NAME的控件。

继续阅读 →

用gnuplot将数据可视化

今天我做了两件事,其一是了解了样条插值的概念,其二是观察了使用有限差分方法求解的调和场。做这两件事都用到了gnuplot。

Gnuplot是一个可用于作图的免费软件。使用它可以将数值计算的结果以图像的方式呈现,以获得直观的感受。

观察插值函数

试想原本有一个连续函数,由于测量的原因现在只知道其中的个别点的位置。

但是我想知道中间某个点处的函数值,我会这么做:用一条光滑的曲线把这些点连接起来,然后根据图像来找到对应的函数值。这就是科学实验中常用的图解法的原理。

继续阅读 →

Lua语言中的“惊喜”

Lua在有些地方没有采用其他语言(尤其是C)的约定俗成,所以经常给程序编写者带来惊喜(surprise, “gotcha”)。根据我的经验,整理如下:

  1. 不等号是~=,而不是!=
  • 这是我写Lua程序时最常犯的一个笔误。只能说,几乎所有的程序语言,不等号用的都是!=(C家族),还有一部分用<>(Pascal, Basic, SQL)。用~=真的只有Lua一家。
继续阅读 →

发现了MinGW GCC的一个bug

我今天发现MinGW内置的打印函数__mingw_printf在处理%a格式的时候会产生不正确的输出。下面这段程序体现了这个问题。

#include <stdio.h>
#include <stdarg.h>

int main()
{
	printf("%a %a\n", 1.0, 1.1);
	__mingw_printf("%a %a\n", 1.0, 1.1);
	return 0;
}

输出是

0x1.000000p+0 0x1.19999ap+0
0x0p-63 0x8.cccccccccccdp-3

因为浮点数1.0显然不能表示为0x0p-63,所以__mingw_printf是错的。

这个错误我提交在 http://sourceforge.net/p/mingw-w64/bugs/459/ ,过几天我看看有没有人回应。

继续阅读 →