我一直在空闲时间为MS-DOS创建自己的GUI库,但我一直在思考如何实现一个包含GUI元素结构的数组。
到目前为止,我能够让它自己绘制窗口,但我需要一种方法来绘制窗口内的元素,如文本框、文本标签、按钮等。
这是我当前的代码:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include "graph.h" //Watcom graphics library
#define false 0
#define true 1
#define border_none 0
#define border_out 1
#define border_in 2
struct text_button {
char text[128];
int pos_x;
int pos_y;
int size_x;
int size_y;
int text_color;
int button_color;
};
struct window_structure {
char title[128];
int pos_x;
int pos_y;
int pre_pos_x;
int pre_pos_y;
int size_x;
int size_y;
int min_size_x;
int min_size_y;
int max_size_x;
int max_size_y;
int show_tab;
int border_type;
int focused;
//Right here is where I would add the array containing the elements.
};
void draw_border(int type,int pos_x,int pos_y,int size_x,int size_y) {
int c_1,c_2;
if (type==1) {
c_1=15;
c_2=0;
} else if (type==2) {
c_1=0;
c_2=15;
}
if (type!=0) {
_setcolor(c_1);
_moveto(pos_x,pos_y);
_lineto(pos_x+size_x,pos_y);
_moveto(pos_x,pos_y);
_lineto(pos_x,pos_y+size_y);
_setcolor(c_2);
_moveto(pos_x+size_x,pos_y+size_y);
_lineto(pos_x+size_x,pos_y);
_moveto(pos_x+size_x,pos_y+size_y);
_lineto(pos_x,pos_y+size_y);
}
}
void draw_box(int type,int color,int pos_x,int pos_y,int size_x,int size_y) {
_setcolor(color);
_rectangle(_GFILLINTERIOR,pos_x,pos_y,pos_x+size_x,pos_y+size_y);
draw_border(type,pos_x-1,pos_y-1,size_x+2,size_y+2);
}
struct window_structure create_window(
char title[],
int pos_x,
int pos_y,
int size_x,
int size_y,
int min_size_x,
int min_size_y,
int max_size_x,
int max_size_y,
int show_tab,
int border_type
) {
struct window_structure window;
strcpy(window.title,title);
window.pos_x=pos_x;
window.pos_y=pos_y;
window.pre_pos_x=pos_x;
window.pre_pos_y=pos_y;
window.size_x=size_x;
window.size_y=size_y;
window.min_size_x=min_size_x;
window.min_size_y=min_size_y;
window.max_size_x=max_size_x;
window.max_size_y=max_size_y;
window.show_tab=show_tab;
window.border_type=border_type;
window.focused=true;
return window;
}
void draw_window(struct window_structure window) {
int offset_x,offset_y;
if (window.size_x<window.min_size_x) {
window.size_x=window.min_size_x;
} else if (window.size_x>window.max_size_x) {
window.size_x=window.max_size_x;
}
if (window.size_y<window.min_size_y) {
window.size_y=window.min_size_y;
} else if (window.size_y>window.max_size_y) {
window.size_y=window.max_size_y;
}
if (window.show_tab==true) {
int tab_color;
if (window.focused==true) {
tab_color=9;
} else {
tab_color=8;
}
draw_box(
window.border_type,
tab_color,
window.pos_x,
window.pos_y-1,
window.size_x-1,
18
);
offset_x=0;
offset_y=20;
}
draw_box(
window.border_type,
7,
window.pos_x+offset_x,
window.pos_y+offset_y,
window.size_x-1,
window.size_y-1
);
//Once the window has been drawn, the next part it would do here is draw the elements
window.pre_pos_x=window.pos_x;
window.pre_pos_y=window.pos_y;
}
我知道MS-DOS已经过时了,这只是我的爱好。我目前正在使用Open Watcom作为我的编译器。
//Right here is where I would add the array containing the elements.
你知道,因为你有一个可变数量的元素,你不能在这里声明一个固定大小的数组,所以你可以声明一个指针,并根据需要分配数组。您还需要存储分配的元素数量。
struct window_structure
{
…
int nelem; // how many elements are there
struct element *elements; // pointer to allocated elements
};
两者都应初始化为0。
struct window_structure create_window(…)
{
…
window.nelem = 0;
window.elements = NULL;
return window;
}
struct element
类型可以定义为
struct element
{ enum elemtype { text_button, /* add other types here */ } elemtype;
union
{ struct text_button tb;
/* add other types here */
} u;
};
一个元素,例如text_button,然后可以添加到具有的窗口中
struct element *new;
new = realloc(window.elements, (window.nelem+1) * sizeof *new);
if (!new) exit(1); // or some better error handling
window.elements = new;
window.elements[window.nelem].elemtype = text_button;
window.elements[window.nelem].u.tb = your_text_button_to_add;
++window.nelem;
//Once the window has been drawn, the next part it would do here is draw the elements
这将像一样完成
int i;
for (i = 0; i < window.nelem; ++i)
switch (window.elements[i].elemtype)
{
case text_button:
/* draw the text_button window.elements[i].u.tb here */
break;
/* add cases for other element types here */
}