0

我一直致力于在空闲时间为 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 作为我的编译器。

4

1 回答 1

0
//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 */
        }
于 2016-08-09T08:45:34.173 回答