2016-07-26 1 views
0

J'ai travaillé sur la création de ma propre bibliothèque GUI pour MS-DOS pendant mon temps libre et je suis resté bloqué sur la façon dont je peux implémenter un tableau qui contiendrait des structures d'éléments GUI. Jusqu'à présent, j'étais capable de faire dessiner la fenêtre elle-même, mais j'avais besoin d'un moyen de dessiner les éléments à l'intérieur de la fenêtre tels que les zones de texte, les étiquettes de texte, les boutons, ect.Créer un tableau contenant des structures en C

Voici mon code actuel:

#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; 
} 

Je sais que MS-DOS est tout à fait obsolète, cela est juste pour mon passe-temps. J'utilise actuellement Open Watcom comme compilateur.

+0

J'ai trouvé une alternative difficile, mais je suis encore à essayer pour trouver une solution beaucoup plus propre. Mon option actuelle était de changer le script de c en C++ pour utiliser correctement un tableau, mais je dois quand même déclarer tous les types d'éléments GUI sous window_structure. –

+0

FWIW, vous pouvez vous inspirer de TurboVision, une bibliothèque d'interface utilisateur pour DOS. http://tvision.sourceforge.net. –

+0

Le point était de voir si je pouvais faire le mien à partir de zéro. Le seul autre problème que j'ai est que mon programme atteint déjà la limite de 640k causant une erreur de "débordement de pile". –

Répondre

0
//Right here is where I would add the array containing the elements. 

Vous savez, puisque vous aurez un nombre variable d'éléments, vous ne pouvez pas déclarer un tableau de taille fixe ici, donc vous pouvez simplement déclarer un pointeur et allouer le tableau selon les besoins . Vous devrez également stocker le nombre d'éléments alloués.

struct window_structure 
{ 
    … 
    int nelem;     // how many elements are there 
    struct element *elements; // pointer to allocated elements 
}; 

Les deux sont initialisés à 0.

struct window_structure create_window(…) 
{ 
    … 
    window.nelem = 0; 
    window.elements = NULL; 
    return window; 
} 

Le type struct element pourrait être défini comme

struct element 
{ enum elemtype { text_button, /* add other types here */ } elemtype; 
    union 
    { struct text_button tb; 
     /* add other types here */ 
    } u; 
}; 

Un élément, e. g. un text_button, pourrait alors être ajouté à la fenêtre avec

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 

Ce serait alors fait comme

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 */ 
     }