2008. 4. 11. 11:30

CVI Ring control의 간단한 예



CVI 프로그래밍을 하면 일반적인 GUI프로그래밍을 하는것과 거의 유사하다.
수많은 컨트롤들이 있고, 그에 따른 속성들과 함수들이 제공된다. 이를 모르면 그야말로 캐삽질!!!

작업량이 많아 간간히 CVI를 하는 실정이다. 뭐 이리저리 문서를 찾아는 보지만 적당히 볼만큼의 문서는 눈을 씻고 찾아볼래야 찾아볼 수가 없다. 그래도 어쩌겠는가... 일단 하기는 해야하는데.. -_-

하는 작업들은 거의 대부분이 CVI에서 제공하는 예제들과 NI LabWindows/CVI Help를 참고하고 있다.
뭐 다른 사람들도 다 마찬가지겠지만.. ^^;

"RING"라는 컨트롤이 있다.

사용자 삽입 이미지

CVI에서 말하는 "RING"이라는 녀석이다.

그 중에서 빨간 밑줄을 그은 녀석.. 일반적으로 다른 GUI에서 "콤보박스"라고 부르는 녀석에 대해서 알아보려한다.
CVI에서는 "Recessed Menu Ring"라고 부르는 듯하다. 뭐 그리 적혀있으니...
기능을 대충 보아하니 완전 콤보박스다. 괜히 이름만 다르게 불러 사람을 헷갈리게 하고 있다.

하는 일은 여러 메뉴(?)를 가지고 있으면서 공간이 모자라는 듯한 곳에 위치해 컨트롤을 한 번 클릭하게 되면 리스트가 펴지면서 원하는 메뉴를 선택할 수 있게 하는 것이다.
사용자 삽입 이미지

여기서 보일 예제는 RING에서 어떤 항목을 선택하게 되면 옆에 리스트박스(ListBox)라는 녀석에 해당하는 하위 리스트를 보여주는 것이다.
왠지 꽤 사용성이 짙어보이긴 하는데... -_-;

간단하게 위의 그림과 같이 UI를 작성하자.
그리고 RING의 속성을 대충 채워 넣는다.
*.uir파일에서 Ring 컨트롤을 더블클릭하면 아래와 같은 에디트 창이 뜬다
사용자 삽입 이미지

Ring에 들어갈 세부 항목을 선택하기 위해서 "Label/Value Pairs..."를 클릭한다.
사용자 삽입 이미지
사용하려 하는 항목과 값을 대충 넣는다.

이로서 일단 RING에대한 준비작업은 끝났다.
여기서 중요한 것은 Data Type이다. Value의 값이 Data Type의 값과 일치해야한다. 만일 Data Type를 char나 다른 값으로 바꾸어보며 작업을 해보면... 대충 감을 잡을 것이다.

List Box의 경우도 동일하게 작업을 해준다. List Box의 Label/Value Pairs..는 일단 Data Type만 정의해주고 나머지는 비워둔다. RING에서 선택된 값을 나중에 넣어줄 것이므로..

이제 만들어진 uir를 이용하여 소스 프레임을 생성한다.
메뉴에서 Code > Generate > All Code...

음.. 이제 소스부분으로 슬슬 넘어가 보겠다.

일단 List Box에 들어갈 데이터를 정의해야겠다.
List Box는 Label과 Value로 이루어져있다. 그래서 데이터도 Label과 Value의 쌍으로 된 녀석을 만들어준다.
typedef struct {
    char name[20];
    int id;
}datatype;

datatype fluit[4] = {{"사과", 0},
                           {"딸기", 2},
                           {"바나나", 3},
                           {"오렌쥐", 5}};

datatype vegetable[2] = {{"오이", 0},
                                    {"당근~당근!!", 1}};
간단하게 위와 같이 만들었다.
RING에서는 과일과 채소라는 항목을 만들었고, 과일이라는 항목을 선택했을 때 List Box에 fluit라는 녀석을 보여줄 것이다. 음.. 채소를 선택했다면... vegetable라는 녀석을 보여줄것이고..

다음은 RING 컨트롤을 생성할 때 같이 생성한 cmdRING라는 함수의 내용을 채워넣어야 한다.
cmdRING는 위쪽에 RING의 속성을 채워넣는 부분에서 CallBack Function이라는 항목에 넣었던 부분이다.
CallBack Function이라는 부분에 cmdRING라는 녀석을 넣어주면 자동으로 아래와 같은 부분이 생성된다.
int CVICALLBACK cmdRing (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
     switch (event)
    {
        case EVENT_COMMIT:
             break;
    }
    return 0;
}
이 내부에 원하는 부분을 채워 넣기만 하면 된다.

본인의 경우 아래와 같이 채워 넣었다.
사용자 삽입 이미지
흠.. 흠.. 타이핑하기 귀찮아서... -_-

RING에서 선택된 항목은 Value값에 의해서 switch-case의 해당하는 부분으로 점프한다.
과일을 선택하면 case 0:에 걸리고, 채소를 선택하면 case 1:에걸리고.. 이건... C에 나오는 부분이니 대충 패스!!
각 선택되었을 때 미리 생성해 놓은 데이터의 크기(리스트의 개수)만큼 루프를 돌면서 List Box에 추가시켜주는 간단한 예이다.

List Box에 새로운 아이템을 추가할 때에는 InsertListItem()이라는 함수를 사용하게 된다.

InsertListItem

int InsertListItem (int panelHandle, int controlID, int itemIndex, char itemLabel[], ...);

Purpose

Inserts a label/value pair into a list or ring control at a specific zero-based index.

Inserting the new pair causes the indices of existing label/value pairs at and beyond the insertion point to increase by one.

You can create columns in a list box control by embedding escape codes in the itemLabel parameter.

......

더 자세한 사항은 NI LabWindows/CVI Help를 참조하면 될 듯 하다.