2016-07-26 2 views
0

저는 자유 시간에 MS-DOS 용 자체 GUI 라이브러리를 만들려고 노력하고 있었고 GUI 요소의 구조를 포함 할 배열을 구현할 수있는 방법을 고수했습니다.C로 구조체를 포함하는 배열 만들기

지금까지는 창 자체를 그릴 수 있었지만 텍스트 상자, 텍스트 레이블, 단추 등의 요소를 창 내부에 그려 넣어야했습니다. 이것은 단지 내 취미입니다, 내가 MS-DOS는 꽤 오래 알고

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

:

여기에 내 현재 코드입니다. 현재 Open Watcom을 제 컴파일러로 사용하고 있습니다.

+0

같이 할 것입니다,하지만 난 여전히 노력하고

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 

으로 창에 추가 할 수 더 깔끔한 솔루션을 찾으십시오. 내 현재 옵션은 배열을 제대로 사용하기 위해 스크립트를 c에서 C++로 변경하는 것이지만 여전히 window_structure 아래 모든 GUI 요소 유형을 선언해야합니다. –

+0

FWIW, DOS 용 UI 라이브러리 인 TurboVision에서 영감을 얻을 수 있습니다. http://tvision.sourceforge.net. –

+0

처음부터 내 자신을 만들 수 있는지 확인하는 것이 핵심이었습니다. 유일한 문제는 내 프로그램이 이미 "스택 오버플로"오류를 일으키는 640k 제한에 도달하고 있다는 것입니다. –

답변

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 element

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

초기화한다은

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

의 요소, 예로서 정의 될 수있다. 지. text_button는 다음이 다음

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 */ 
     } 
나는 거친 대안을 발견했다