Создать массив, содержащий структуры в C
В свободное время я работал над созданием собственной библиотеки GUI для MS-DOS, и я застрял в том, как реализовать массив, который будет содержать структуры элементов 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 в качестве моего компилятора.
1 ответ
//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 */
}