강좌,팁

[강좌:41] Prototype 프로그램 CISDEFPROG 소개

조회 수 8670 추천 수 0 2012.01.03 23:53:00

업무에 쫓기긴 해도, CIS Project에 대한 소개는 매우 중요하다고 생각하여 오늘도 과감한 시간 투자를 단행합니다.


(이번 강좌를 작성하고 나서 다시 보니, 많은 분들이 좀 어렵게 느끼실 것 같습니다. 이번 강좌는 주관적인 부분이 많이 들어가서 모든 것을 다 이해하시려고 들면 힘드실 것 같고, 그냥 부담없이 쭉 읽어본다고 생각하시면 좋을 것 같습니다. 이번 강좌에서 소개하는 CIS Programming Style 규칙들은 절대불변의 규칙은 아닙니다. 보다 나은 방법이 있으면 언제든 변경될 수 있다고 생각하시기 바랍니다.)

---------------------------------------------------------------------------------------

[강좌:41] Prototype 프로그램 CISDEFPROG 소개


이용된 CVI 버전: LabWindows/CVI 9.0.1 (375)
강좌분류: 개요설명
등급: 중급


차례
서론
1. CISDEFPROG의 실행
2. CISDEFPROG의 프로젝트 파일 구성
   2.1 조건컴파일 헤더파일
   2.2 통합헤더파일
   2.3 초기화, INI, 마무리 과정 처리파일
   2.4 전역구조체 변수 관련 파일
   2.5 기타 파일
      2.5.1 main() 함수 파일
      2.5.2 MENU 콜백 파일
      2.5.3 Panel, Control 콜백 파일
      2.5.4 사용자 추가 파일
마무리

 

서론
CIS Project의 구체화된 프로그램이며, CIS Prototype Program의 대표적인 예로서 CISDEFPROG 프로그램을 만들었습니다. 극동테크에서 사용해온 Prototype 프로그램인 DEFPROG 프로그램을 손질하여, 기본적인 부분만 옮겨와 새로 구성하였습니다. 앞으로도 CISDEFPROG 프로그램은 조금씩 추가되고 업데이트될 것입니다만, 큰 틀은 별로 바뀌지 않을 것으로 예상합니다.

 

이번 강좌에서는 이 CISDEFPROG를 개략적으로 소개하게 되는데, 앞으로의 강좌에서 사용하게 될 예제 프로그램의 원형으로서도 큰 의미를 가지게 됩니다.

 

1. CISDEFPROG의 실행
프로그램의 소스 구조를 파악하기에 앞서 실행부터 시켜보는 것이 가장 빠른 접근이라고 생각됩니다. 자료실의 "[CIS Project] CISDEFPROG v1.0.001(2011.12.23)"라는 제목의 글을 찾아 첨부파일을 다운로드받으십시오.
그리고, AAA05_CISDEFPROG_v1.0.001_20111223_1327.zip 라는 파일의 압축을 해제하여, CISDEFPROG.exe 파일을 찾아서 실행해보십시오.
(단, 현재 여러분의 PC에 LabWindows/CVI 9.0.1 이상의 버전이 설치되어 있어야 합니다. 그 이전 버전의 CVI가 설치되어 있다면, NI 사이트에서 CVI RunTime Engine을 다운로드 받아서 설치하십시오. 현재(2012.1.2)는 LabWindows/CVI Run-Time Engine 2010 SP1까지 나와있습니다.)

 

그림 1.1 CISDEFPROG v1.0.001 실행화면

 

그림 1.1에 CISDEFPROG v1.0.001의 실행화면을 보였습니다. 조촐하게 메뉴와 일시표시 text message, String 컨트롤, binary Switch, LED, 그리고 수치 컨트롤이 표시되고 있습니다. 여기서 사용자가 수정할 수 있는 값은 String 컨트롤의 문자열, POWER 스위치, 그리고 Setting Time이라고 이름 붙여진 수치 컨트롤의 값입니다. 이들 값들을 변경하고, 프로그램을 종료한 후 다시 실행하면, 변경된 그 정보가 그대로 유지됩니다.


특별히 String 컨트롤에 한글 문자를 입력해보면, 그림 1.2와 같이 한글 문자 조합이 해당 위치에서 표시되는 것을 보시게 될 것입니다. 일반적인 프로그램에서는 당연한 것인데, LabWindows/CVI는 외국언어에 대한 IME  창 위치처리를 기본적으로 해주지 않는 것 같습니다. 그래서 IME 창의 위치를 조절하는 Windows API 함수를 사용하여 그럴듯하게 보이도록 처리하였습니다.


그림 1.2 한글 IME 표시창

 

옵션 메뉴의 서브메뉴인 "설정하기..."를 선택하여 봅니다. 그러면, 그림 1.3과 같은 화면이 나타납니다.

 

그림 1.3 CISDEFPROG v1.0.001의 옵션화면

 

옵션 창에는 3가지 종류의 옵션 항목 예가 보입니다. Opt1이라는 체크박스, 옵션타임이라는 수치컨트롤, 프로그램 종료시에 물어보기 라는 체크박스입니다. 이들 값들도 수정한 후, 확인이나 적용 버튼을 누르면, 다음 프로그램 실행시에 이 옵션이 유지가 됩니다. 그림 1.4와 같이 "프로그램 종료시에 물어보기"라는 옵션을 체크한 후, 확인 버튼을 눌러 빠져나가 봅시다.

 

그림 1.4 "프로그램 종료시에 물어보기" 체크

 

그리고, 프로그램을 종료하기 위해 파일 메뉴의 "끝내기" 서브메뉴나, 프로그램의 닫기 버튼을 누르면, 그림 1.5와 같은 대화 상자가 나타납니다.

 

그림 1.4 종료 대화상자

 

여기까지 간단히 CISDEFPROG 프로그램의 실행화면을 살펴보았습니다.
다음 절부터는 본 프로그램을 구성하는 파일들을 전체적으로 살펴보고, 개별적인 파일들도 개략적으로 살펴보겠습니다.

 

2. CISDEFPROG의 프로젝트 파일 구성
그림 2.1에는 CISDEFPROG 프로젝트 파일을 보였습니다. 별 대수롭지 않은 프로그램이 소스파일은 왜 이리 많나 라고 생각하실 분들이 있으실 것입니다. 기능별로 파일을 구분하였으므로, 조금만 더 사용하시다보면 익숙해 지실 것입니다. 파일명이 주로 CISDEFPROG로 시작된다는 것을 주목하십시오. 만약 ABCD라는 프로젝트를 새로 시작한다면, 그 프로젝트 구성 파일들은 ABCD라는 문자열로 파일명이 부여될 것입니다.[CIS Programming Style의 프로젝트 구성 파일명 부여규칙]

 

그림 2.1 CISDEFPROG의 프로젝트 파일

 

그림 2.1의 CISDEFPROG 프로젝트 파일에 설명을 위해 번호를 표시해두었습니다.
①번은 uir 파일을 표시하였는데, CISDEFPROG.uir 파일에는 다시 3개의 Panel이 포함되어 있고, CISDEFPROG_PNLAbout.uir 파일에는 하나의 Panel이 있을 것입니다. CISDEFPROG.uir 파일의 파일명은 프로젝트 파일명과 같은 CISDEFPROG 이므로, 주요 메인 Panel이 있을 것이라고 유추할 수 있습니다.
CISDEFPROG_PNLAbout.uir 파일의 파일명을 주목하여 보십시오. CISDEFPROG 프로젝트의 PNLAbout 라는 의미를 나타내도록 붙인 파일이름입니다.
PNLAbout 라는 이름은 CISDEFPROG_PNLAbout.uir 파일 내의 Panel의 Constant Name과 같다는 것을 그림 2.2를 보시면 알 수 있을 것입니다.


그림 2.2 PNLAbout Panel의 등록정보

 

CISDEFPROG_PNLAbout.uir 파일을 불러온 uir 창에서 Panel을 클릭한 후, 메뉴의 Edit-Panel을 선택하여 Panel의 등록정보를 봅니다. (원래 Panel의 등록정보는 해당 Panel의 바탕을 더블클릭하면 나타납니다만, 이 PNLAbout Panel에는 투명한 Canvas 컨트롤을 전체 Panel의 위에 올려 두었기 때문에, Panel을 더블클릭하면 이 투명 Canvas의 등록정보가 나타납니다.)


CISDEFPROG_PNLAbout.uir 파일 내의 유일한 이 Panel의 Constant Name이 PNLAbout입니다. 여기서 저희 CIS Project의 Programming Style에 해당되는 파일명 부여규칙과 Panel Constant Name 부여규칙이 잠깐 설명드리겠습니다.


UIR 파일의 파일명은 해당 프로젝트의 프로젝트명과 uir 파일 내의 대표적인 Panel의 Constant Name을 조합하여 명명되었습니다. 앞으로도 새로운 UIR 파일을 만들게 되면, 이런 식으로 UIR 파일명은 부여하도록 하겠습니다.[CIS Programming Style의 UIR 파일명 부여규칙]


그리고, UIR 파일 내의 Panel에 부여된 Constant Name을 잘 보시면, PNLAbout라고 되어 있습니다. Panel의 Constant Name으로 사용될 수 있는 길이는 10자로 제한됩니다.(CVI 9.0.1까지의 버전에서는)


그래서 Panel 의 Constant Name에도 함축적인 요약이 필요한데, Panel을 PNL 이라고 줄인 접두어와 함께 그 Panel의 성격을 나타낼 수 있는 단어를 붙여서 사용합니다.[CIS Programming Style의 Panel Constant Name 부여규칙]

 

그림 2.1의 ②번의 파일들은 초기화, INI, 마무리 과정의 처리를 위한 파일들입니다. 파일명 중간에 보면, AAAXX라는 문자열이 들어가 있습니다. 이렇게 한 이유는 프로그램 개발시에 초기화, INI, 마무리를 위한 파일들을 수정하는 경우가 많이 생기게 되고, 이러한 파일들은 프로젝트 창에서 파일명순으로 비교적 위쪽에 위치할 수 있도록 파일명에 추가적인 문자열을 부여한 것입니다.[CIS Programming Style의 프로젝트 구성파일명 부여규칙]


초기화와 관련된 Init 파일들을 별도로 살펴보면, 아래와 같습니다.
    CISDEFPROG_AAA20_Init.c
    CISDEFPROG_AAA20_Init_GloVar.c
    CISDEFPROG_AAA20_Init_LoadPanel.c


..._Init 라는 이름 뒤에 _GloVar 이 붙든지, _LoadPanel 이라는 문자열이 추가적으로 붙어 있는 것을 보게 됩니다. 의미는 CISDEFPROG_AAA20_Init.c 파일은 초기화와 관련된 전반적인 함수들이 있고, 그 중에서도 GloVar 과 관련한 함수들은 CISDEFPROG_AAA20_Init_GloVar.c 파일 내에 있을 것이라고 유추할 수 있습니다. (GloVar 전역구조체변수와 관련된 것으로 나중에 설명됩니다.)


만약, CISDEFPROG_AAA20_Init_LoadPanel.c 파일의 내용이 너무 많아지거나 복잡해지면, 파일명에 또다시 문자열을 추가하여 좀더 세분화된 파일들을 만들면 될 것입니다. 예를 들면, LoadPanel 함수들 중에서 모터와 관련된 Panel을 Load하는 함수를 별도의 파일에 만들고 싶다면, CISDEFPROG_AAA20_Init_LoadPanel_Motor.c 이런 식으로 파일명을 연장해 나가면 될 것입니다.[CIS Programming Style의 프로젝트 구성파일명 부여규칙]

 


그림 2.1의 ③번의 파일들은 Panel 과 그 Panel 내의 Control 들의 Callback 함수들을 모아두는 파일입니다.
메인 Panel 하나는 예외적으로 PANEL 이라는 Panel Constant Name을 사용하도록 합니다만, 일반적인 Panel의 Constant Name을 부여할 때, PNL 이라는 접두어를 사용하도록 합니다.[CIS Programming Style의 Panel 명 부여규칙]


그림 2.1의 ④번 파일들은 중간에 u 라는 단어를 사용하였습니다. 이것은 사용자 정의 함수들이 정의된 파일이라는 의미로 사용하였습니다.[CIS Programming Style의 프로젝트 구성파일명 부여규칙]


이제 주요 파일들을 하나씩 좀더 자세히 들여다 보겠습니다.

 

2.1 조건컴파일 헤더파일(CISDEFPROG_AAA10_DEF_CC.h)
그림 2.1.1에는 조건컴파일 헤더파일의 소스를 보였습니다.


그림 2.1.1 CISDEFPROG의 조건컴파일 헤더파일

 

조건 컴파일(Conditional Compile)을 이용하면, 이미 모든 기능을 구현해둔 Prototype 프로그램 소스상에서 특정한 기능을 소스 레벨에서 활성화하거나 비활성화하기 쉽습니다. 모든 기능에 대해 조건 컴파일을 적용할 필요는 없겠지만, 프로젝트에 따라 사용되기도 하고, 사용되지 않는 기능들에 대해 미리 지정해서 사용하면 편리할 것입니다. 그림 2.1.1에는 조건컴파일을 위한 매크로 상수 정의 부분을 보였습니다.


그림 2.1.2에 조건컴파일을 적용하는 예를 보였습니다. Panel을 Load 할지 여부를 조건 컴파일 매크로 상수에 의해 판단하여 컴파일에 포함시킬지 여부를 판단하는 예를 보인 것입니다.

 

그림 2.1.2 조건컴파일 적용예

 

2.2 통합 헤더파일(CISDEFPROG_AAA10_DEF.h)
그림 2.2.1에는 통합 헤더파일의 소스를 보였습니다. 각 소스파일에 include 시켜야할 헤더 파일이 많아지면, 복잡하기도 하고, 번거롭기도 합니다. 그래서 하나의 헤더파일로 통합한 다음, 이 통합 헤더파일만 include하기 위함입니다.


그림 2.2.1 CISDEFPROG의 통합 헤더파일

 

그림 2.2.2에는 이 통합 헤더파일을 include 한 예를 보였습니다.

 

그림 2.2.2 통합 헤더파일을 include 한 예

 

2.3 초기화, INI, 마무리 과정 처리 파일
그림 2.1의 ②번 파일들이 초기화(Init), INI, 마무리(Finish) 과정을 담당하는 파일들입니다. 초기설정파일(.ini 파일)을 처리하기 위한 INI 모듈은 초기화 과정에서도 사용되고, 마무리 과정에서도 사용됩니다.


그림 2.3.1에 CISDEFPROG의 초기화와 INI, 그리고 마무리 처리 함수들의 개략적인 상관관계를 pseudo code 형식으로 보였습니다.


그림 2.3.1 CISDEFPROG의 초기화와 INI, 그리고 마무리 처리 함수들의 개략적인 상관관계

 

Proc_PreInit() 라는 함수는 초기화면이 표시되기 전에 호출되는 초기화 함수이며, Proc_PostInit()는 초기화면이 표시된 후에 호출되는 초기화 함수입니다. 그리고, Proc_PreInit() 함수 내에서는 초기설정파일 처리를 위한 INI 초기화 과정이 호출됩니다.
Proc_INI_Initialize() 라는 함수 내에서 초기설정파일과 관련된 일련의 처리가 수행되는데, 프로그램 개발시에 옵션 항목이 추가되면, 연달아 수정되는 부분들입니다. 왜냐하면, 그 추가된 옵션항목의 값은 프로그램이 종료되었다가 다시 실행될 때에도 유지되어야하기 때문입니다.


그림 2.3.2에는 CISDEFPROG_AAA30_INI.c 파일의 일부를 보였습니다. 새로운 옵션 항목이 추가되더라도 이 소스를 참고하여 유사한 방법으로 관리 항목을 추가할 수 있습니다.

 

그림 2.3.2 CISDEFPROG_AAA30_INI.c 파일의 일부

 

간단히 예를 하나 들면, 메인 Panel에 그 값이 double 형인 수치 컨트롤이 하나 추가되었는데, 이 수치 컨트롤의 Constant Name이 numWindow 라고 가정합시다. 그러면, numWindow라는 변수를 해당 구조체 내에 선언한 다음, 아래와 같은 라인을 추가하면 됩니다.

 

Gini.AddItemDouble(&Gini, SectionName, iniGroup, &(glovar.General.numWindow), "numWindow", 0.0, GphPANEL, PANEL_numWindow);

 

INI에 대한 좀더 구체적인 사용법은 별도의 강좌에서 소개하도록 하겠습니다.

 

2.4 전역구조체 변수 관련 파일
프로그램을 작성하다보면, 전역변수를 사용하는 것이 필요한 경우가 많이 있습니다. 이럴 경우, 전역변수의 명칭과 종류 등을 이해하기 쉽게 관리하기가 쉽지가 않은데, 저는 전역 구조체 변수를 하나 선언하고, 그 구조체 내에 종류별로 분류한 서브 구조체를 만들고, 그 서브 구조체 내에 필요한 변수들을 만들어서 사용합니다.[CIS Programming Style의 전역구조체변수]


우선, CISDEFPROG_AAA21_Init_GloVar.h 파일의 일부 내용을 보도록 합시다. 그림 2.4.1에 보였습니다.

 

그림 2.4.1 CISDEFPROG의 전역 구조체

 

GloVar 이라는 구조체 명칭은 Global Variable을 약어로 만들었습니다. 전역변수라는 의미를 담고 있는데, 이 전역 구조체의 변수는 프로그램 전체에 걸쳐서 유일하게 하나의 변수를 선언합니다. 소문자로 glovar입니다. 대문자가 포함된 GloVar은 구조체 명칭이고, 소문자로만 이루어진 glovar 이 구조체 변수입니다. 전역에 걸쳐 사용될 것이기 때문에 전역구조체를 선언하고 있는 헤더파일인 CISDEFPROG_AAA21_Init_GloVar.h 파일에서는 extern 이라는 수식어를 사용하여 선언하였고, 실제 구조체 변수는 CISDEFPROG_AAA21_Init_GloVar.c 파일에 선언되어 있습니다.


GloVar 이라는 구조체 내에 S_Base, S_Panel 등의 서브 구조체에 대해 각각 구조체 변수가 선언되어 있습니다. 서브 구조체라는 의미로 접두어로 S_를 붙였습니다. S_Base 구조체 변수인 Base는 프로그램의 기본적인 변수에 대한 멤버 변수들을 갖고 있고, S_Panel 구조체 변수인 Panel은 프로그램 내의 Panel 관련한 멤버 변수들을 갖고 있다고 쉽게 유추할 수 있습니다.


S_General 구조체 변수인 General 에는 그냥 일반적인 옵션값, 프로그램 운영에 필요한 변수 등을 멤버 변수로 가지도록 구성하게 됩니다.
CIS_INI 구조체 변수인 ini 에는 초기설정파일과 관련된 멤버 변수들을 갖고 있을 것입니다.


전역 구조체인 GloVar 내의 서브 구조체는 어떤 모양을 갖고 있는지는 그림 2.4.1의 8라인에서 include 하고 있는 CISDEFPROG_AAA21_Init_SubStruct.h 파일을 보면 알 수 있습니다. 그림 2.4.2를 보십시오.

 

그림 2.4.2 CISDEFPROG의 서브 구조체 파일

 

S_Base 구조체 내에는 프로그램의 이름, 버전명, Title 등의 정보들을 갖고 있을 문자열 변수(문자배열)가 선언되어 있습니다. S_Panel 구조체 내에는 Panel의 Handle 값, Panel의 title 정보 등을 갖고 있을 변수들이 선언되어 있습니다.


이렇게 전역 구조체 변수의 멤버에 접근하려면 glovar.Base.ProgName, glovar.Panel.phPANEL, 이런 식으로 표기하면 됩니다.


그림 2.4.3에는 서브 구조체 중 S_General 구조체를 보였습니다.

 

그림 2.4.3 CISDEFPROG의 S_General 서브 구조체

 

S_General 구조체의 멤버 변수로는 CISDEFPROG 프로그램의 옵션창에서 사용된 컨트롤의 값을 저장할 변수들과, 메인 화면에서 사용된 컨트롤의 값을 저장할 변수들을 포함하고 있습니다. 옵션 창이나 메인 화면에서 사용될 컨트롤이 추가되어 그 값을 전역으로 참조할 필요가 있을 때에는 이 S_General 구조체 내에 멤버 변수를 추가해 주고, 연관된 다른 파일에서 부가적인 조치를 취해주면 되겠습니다.


역시, 이들 변수에 접근하려면, CISDEFPROG 프로그램의 어떤 소스에서건 glovar.General.chkOpt1, glovar.General.bsPower 이런 식으로 표기하면 되겠습니다.


여기서, 한가지 불편한 점이 예상되지 않습니까? 전역 구조체 변수의 각 멤버 변수를 지칭하는 위의 방법이 의미는 쉽게 이해되지만, 너무 길다고 생각되지 않습니까? 빈번하게 사용되는 멤버변수의 경우에 매번 glovar.General.... 이런 식으로 써 나가려니 불편합니다. 그래서 저는 자주 사용하는 전역 구조체 변수의 멤버 변수는 매크로 상수로 짧게 선언하여 사용합니다.[CIS Programming Style의 전역구조체변수]


그림 2.4.4에 CISDEFPROG_AAA21_Init_GloVar.h 파일의 일부를 보였습니다.

 

그림 2.4.4 전역 구조체 변수의 멤버 변수를 매크로 상수로 선언한 예

 

그림 2.4.4에 보면 glovar.Base.ProgName 라는 전역구조체 변수의 멤버 변수는 GProgName 이라는 이름으로 간단하게 재정의되었습니다. 그래서 프로그램 중에 간단하게 GProgName 이라고 표기하면, 전처리기가 glovar.Base.ProgName 이라고 변경하여 컴파일되도록 하게 됩니다. 이렇게 자주 사용하는 전역구조체 변수의 멤버 변수는 매크로 상수로 정의하면 편리합니다. 단, 명칭에서부터 쉽게 구분하기 위해 Global 이라는 의미의 "G"라는 문자를 앞에 붙이도록 합니다.[CIS Programming Style의 전역구조체변수의 매크로 상수 선언]


그림 2.4.5에는 Panel의 Handle 변수를 매크로 상수로 대체하여 사용한 예를 보였습니다.

 

그림 2.4.5 전역 구조체 변수의 멤버 변수에 대한 매크로 상수를 사용한 예

 

Option 창에 대한 Panel Handle 값을 갖는 변수는 원래 glovar.Panel.phPNLOption 이라고 표기해야겠지만, 매크로 상수 정의에 의해 간단히 GphPNLOption 이라고 표기할 수 있겠습니다.


Panel Handle에 대한 명칭을 부여하는 데에도 나름대로의 CIS Programming Style 규칙을 두고 있는데, Panel의 Constant Name 앞에 소문자로 ph를 덧붙입니다. panel handle 의 첫글자이지요. 이렇게 Panel의 Constant Name과 Panel Handle 변수가 유사하도록 함으로써 프로그램 코딩시에 혼동을 줄이고 쉽게 유추하여 타이핑할 수 있습니다. 이렇게 함으로써 얻는 이점은 생각보다 훨씬 큽니다. 하나 더 덧붙이면, Panel의 Callback 함수는 Panel Constant Name 뒤에 Callback 이라는 의미의 "CB"를 덧붙여서 표기합니다. [CIS Programming Style의 Panel명 부여규칙]


예를 들면, PNLOption Panel의 콜백함수명은 PNLOptionCB()입니다. PNLAbout Panel의 콜백함수명은 PNLAboutCB() 로 지정하면 되겠죠.


이렇게 Panel과 관련하여 Constant Name, Callback 함수명, Panel Handle 변수, 또 Panel Handle 변수에 대한 매크로 상수 등이 일관성있고, 또 쉽게 유추가 가능하도록 하면, 프로그램 코딩시에 굉장히 편리합니다. 그만큼 코딩 시간도 줄일 수 있고, 덜 복잡해지므로 작업능률을 많이 올릴 수가 있습니다.[CIS Programming Style의 Panel명 부여규칙]

 

2.5 기타 파일
CISDEFPROG 프로그램에서 아직 설명되지 않은 몇가지 파일에 대해서 설명드리겠습니다.

 

2.5.1 main() 함수 파일(CISDEFPROG.c)
CISDEFPROG 프로그램에서 CISDEFPROG.c 파일에는 main() 함수가 주인이라고 할 수 있겠습니다. 프로젝트명과 동일한 .c 소스 파일이므로, 그야말로 메인이죠. 그림 2.5.1.1에 CISDEFPROG.c 파일의 일부를 보였는데요, 메인 Panel의 콜백함수도 있네요.

 

그림 2.5.1.1 CISDEFPROG.c의 일부

 

메인 Panel 의 콜백함수인 PanelCB()는 CISDEFPROG_PANEL.c 라는 파일에 있는 것이 적절하겠다고 생각되네요. 이것은 약간의 예외로 볼 수 있는데, CISDEFPROG.c에 main() 함수가 외로이 있으니, 메인 Panel의 콜백만이라도 같이 있어줘야겠다라고 이해하면 어떨까요? 애초에 Panel 별로 별도의 파일을 두지 않았을 때의 습관이 아직 정리되지 않고 남아 있는 것으로 이해해 주시기를 바랍니다.


여기서 메인 Panel과 관련한 예외적인 사항을 언급하자면, CVI에서 전통적으로 메인 Panel의 Constant Name은 PANEL 이죠. 그리고, 기본 Panel Handle 변수명은 panelHandle 이죠! 이 부분을 CIS Programming Style에서 어느 정도까지 CIS Programming Style 원칙을 따를지 약간 고민은 했었는데, 사용해 오던 습관도 있고 해서 약간의 타협을 하기로 했습니다.


그래서 메인 Panel의 Constant Name은 PANEL 로 그대로 하기로 했고, Panel Handle 명은 phPANEL 로 하기로 하고, 단 Callback 함수 명은 습관대로 PanelCB()로  하기로 합니다. Panel Handle은 엄밀히 말하면, glovar.Panel.phPANEL 이고, 매크로 상수 GphPANEL 로 정의되어 있습니다.
일반적인 Panel의 Constant Name 명칭은 PNL 로 시작한다는 큰 원칙이 있지만, 메인 Panel에 대해서만큼은 일단 예외로 하겠습니다.[CIS Programming Style의 Panel명 부여 예외규칙] 

 

 

2.5.2 MENU 콜백 파일(CISDEFPROG_Menu.c)
그림 2.5.2.1에는 CISDEFPROG 프로그램의 Menu 설정을 보여주고 있습니다. 현재는 MENU 라는 이름의 Menu Bar 만 존재합니다. 이 MENU 내의 Menu Item에 대한 콜백 함수들이 존재하게 되는데, 그림 2.5.2.2에 이들 Menu Callback 함수들이 정의된 CISDEFPROG_MENU.c 파일의 일부를 보였습니다.

 

그림 2.5.2.1 CISDEFPROG의 Menu

 

그림 2.5.2.2 CISDEFPROG의 Menu Callback 함수들(CISDEFPROG_MENU.c)

 

여기서, Menu  Item 명칭의 부여 규칙도 잠깐은 언급하겠습니다. 메뉴의 "파일", "옵션", "폴더", "도움말" 항목의 Constant Name은 File, Option, Folder, Help  이런 식으로 붙였다면, 그 서브메뉴의 Constant Name은 상위 메뉴의 첫글자를 앞에 덧붙여서 "끝내기" 서브메뉴의 Constant Name은 FExit, "설정하기.." 서브메뉴의 Name은 OSettings로 붙입니다. 그리고, 메뉴 Callback 함수의 명칭은 메뉴의 Constant Name 앞에 "mnu"를 덧붙입니다. [CIS Programming Style의 Menu 콜백함수명 부여규칙] 


그래서, "설정하기..." 메뉴의 콜백함수명은 mnuOSettings() 로 명명되게 됩니다.

 

 

휴~, Panel 명이나 컨트롤명, 함수명을 짓는 데에도 이런 규칙을 만든다는 것이 자신에게는 좋겠지만, 남들에게까지 강요할 수는 없습니다. 저도 그렇게 생각합니다. 이 글을 읽는 개발자 분들께서도 자신만의 좋은 명칭부여규칙이 있다면, 그것을 잘 활용하시는 것이 최고라고 생각합니다. (그리고 그것도 많은 분들께 소개해 주시면 좋겠구요.)
단, 자신만의 명칭부여규칙이 아직 정립되지 않으신 분들은 제가 제시하는 부여규칙도 쓸 만하실 것입니다. 제 나름으로 이런 규칙들은 오랜 시일을 거치면서 보다더 쉽고 효율적인 방법을 찾으면서 하나씩 정립해 나온 것이기 때문입니다. 부족하긴 해도, CVI 개발자들 간에 공감이 이루어진 규칙을 사용함으로써 소스 코드의 호환성과 가독성을 높일 수 있는 계기가 될 수 있다는 것입니다.
CISDEFPROG Prototype Program 소스가 이 첫버전부터 완벽하게 정립된 것이라고 할 수 없으므로, 좋은 아이디어가 있으시면, 제안해 주시면 좋겠습니다.

 

2.5.3 Panel, Control 콜백 파일
Panel 내에는 여러 Control 들이 존재하고, 이 Control 들 중에는 Callback 함수를 가진 것들이 있습니다. 메인 Panel인 PANEL panel의 Control들의 콜백함수는 CISDEFPROG_PANEL.c 파일에 있습니다. 프로젝트 명과 Panel의 Constant Name을 그대로 조합한 파일명입니다.
PNLOption Panel의 콜백함수들은 예상대로 CISDEFPROG_PNLOption.c 파일에 있습니다. 그림 2.5.3.1과 그림 2.5.3.2에 각각 CISDEFPROG_PANEL.c 파일, CISDEFPROG_PNLOption.c 파일의 일부를 보였습니다.

 

그림 2.5.3.1 CISDEFPROG_PANEL.c 파일의 일부

 

 

그림 2.5.3.2 CISDEFPROG_PNLOption.c 파일의 일부

 

그림 2.5.3.1의 함수명을 보면, 컨트롤의 Constant Name과 똑같다는 것을 알 수 있습니다. 가장 먼저 나오는 strSTRING() 함수와 관련된 컨트롤의 속성을 그림 2.5.3.3에 보였습니다.

 

그림 2.5.3.3 string 컨트롤의 등록정보(속성)

 

여기서, Control에 대한 Constant Name과 Callback 함수명 부여규칙을 잠깐 언급하겠습니다. Control의 Constant Name을 부여할 때, 접두어로서 컨트롤의 종류를 알 수 있는 약어를 붙입니다. String 컨트롤에 대해서 "str"이라는 문자열이 사용되었습니다. 그 이후의 이름은 Control의 용도에 따라 자유롭게 붙이면 되겠습니다. 그리고, Callback 함수명도 특이하게도 Constant Name과 똑같게 부여하였습니다. 이것이 CIS Programming Style에서 제시하는 중요한 포인트입니다. 거기다가 이 String 컨트롤의 값을 저장할 전역 구조체 변수의 멤버 변수 명칭도 strSTRING입니다. 그림 2.4.3에서 100번째 라인을 보시면, 똑같은 이름으로 문자배열이 선언되어 있지요?


이렇게 하나의 Control에 대해 Constant Name, Callback 함수명, 전역 구조체 변수의 멤버 변수 명칭을 같게 만들면 여러 가지 이점이 생깁니다. 해당 컨트롤과 관련된 코딩이 진행될 때, Constant Name만 알고 있으면, 다른 것은 찾아볼 필요도 없이 유추가 가능하다는 것이 실전에서 굉장히 편리함을 가져다 줍니다. 그림 2.5.3.4에 strSTRING() 콜백 함수를 다시 보였습니다.

 

그림 2.5.3.4 strSTRING() 콜백 함수

 

strSTRING 컨트롤의 Constant Name만으로, strSTRING() 콜백 함수를 별다른 참조없이 코딩할 수 있습니다. String 컨트롤이라 특별하게 "한글 IME를 위한 처리" 부분이 들어가서 약간 복잡해졌지만, 다른 컨트롤이라면 안보고도 구성할 수 있을 정도입니다.


이렇게 Control과 관련된 명칭(Constant Name, Callback 함수명, Control ID, 전역 구조체 변수의 멤버 변수명)을 뒤적거리며 찾아보지도 않고 바로 코딩할 수 있다는 것이 실전 코딩시에 굉장히 편리합니다. 편리할 뿐만 아니라, 코딩 작업을 아주 단순한 작업으로 만들어 줍니다. 안그래도 머리가 복잡한데, 이러한 명칭 하나하나가 애를 먹이면 안되겠죠!

 

한가지 더 언급하고 넘어가겠습니다. CISDEFPROG_PANEL.c 파일은 메인 화면의 컨트롤에 대한 콜백 함수들이고, 이들 메인 화면의 컨트롤의 값을 변경하게 되면, 해당 컨트롤의 콜백함수가 호출되어 그 컨트롤의 값을 획득합니다.
이에 반해, CISDEFPROG_PNLOption.c 파일은 옵션창의 컨트롤 콜백함수들인데, 특이하게도 각 옵션값을 갖는 컨트롤의 콜백함수는 별도로 두지 않고, cmdSetApply() 콜백함수 내에서 일괄적으로 각 컨트롤의 값을 읽어오도록 하였습니다. 이것은 여러분들도 아시다시피 옵션창의 값을 변경하다가 마지막에 "취소" 버튼을 누를 수도 있기 때문에 컨트롤의 값을 바꿀 때마다 전역 구조체 변수의 해당 멤버 변수의 값을 변경할 필요가 없기 때문입니다. 하지만, Option 창이라도 컨트롤의 값이 바뀔 때마다 해당 컨트롤의 콜백함수를 둘 필요가 있는 경우도 있습니다. 그렇더라도 해당 컨트롤과 관련된 전역 구조체 변수의 멤버 변수는 cmdSetApply() 함수 내에서 획득하는 것이 적절한 경우가 많습니다.


cmdSetApply() 라는 콜백함수명을 눈여겨 보면, 이것은 cmd로 시작하므로 Command Button 의 콜백함수임을 유추할 수 있습니다. (저는 그렇게 사용해 왔기 때문에 그렇겠지만요). 여기서 컨트롤들의 Constant Name이나 Callback 함수명, 또 연관된 전역 구조체 변수의 멤버 변수명에 사용되는 컨트롤의 접두어를 정리하고 넘어가겠습니다.[CIS Programming Style의 컨트롤명 부여규칙] 

 

표 2.5.3.1 Control 명칭부여시 접두어 예[CIS Programming Style의 컨트롤명 부여규칙] 

Control 분류

Control 종류

접두어

Numeric

Numeric num
Color Numeric num, cn
Numeric Thermometer num
Numeric Tank num
Numeric Slide num, ns
Numeric Knob num, nk
Numeric Dial num
Numeric Gauge num, ng
Numeric Meter num

Text

String txt, str
Text Message txt, tm
Text Box txt, tb

Command Button

Command Button cmd
Picture Button picbtn

Toggle Button

Square Button tog, togbtn
Square Push Button tog, togbtn
Square Text Button tog, togbtn
Round Push Button tog, togbtn
Round Push Button 2 tog, togbtn
Square Push Button tog, togbtn

Square Push Button 2

tog, togbtn
Round Radio Button rd, radio
Square Radio Button rd, radio
Check Box chk

LED

Round LED led, LED
Square LED led, LED

Binary Switch

Binary Switch bs

Ring

Ring ring
Menu Ring ring
Recessed Menu Ring ring
Popup Menu Ring ring
Picture Ring ring
Vertical Pointer Slide ring, rs
Vertical Level Slide ring, rs
Ring Knob ring
Ring Dial ring
Horizontal Pointer Slide ring
Horizontal Level Slide ring
Ring Tank ring
Ring Thermometer ring
Ring Gauage ring
Ring Meter ring

Lists & Tables

List Box lb, list
Tree tree
Table tab, tbl

Decoration

모든 Decoration Control deco

Graph

Graph grp, graph
Strip Chart sc
Digital Graph dgrp, diggrp

Picture

Picture pic

Timer

Timer timer

Canvas

Canvas can

Splitter

Vertical Splitter split
Horizontal Splitter split

Tab

Tab tab, TAB

 

컨트롤의 접두어를 위의 표로 정리하다보니, 좀더 고민할 필요를 느낍니다. 이때까지 전체적으로 정리하지 않고 사용해왔는데, Table과 Tab 컨트롤의 접두어가 같았었네요.


위의 표에서 제안하는 접두어는 제가 주로 사용해오던 것인데, 여러분들도 꼭 이렇게 써야한다는 법은 없습니다만, 컨트롤명을 부여할 때 접두어가 있는 것이 프로그램 코딩시에 도움이 된 것은 부인할 수 없는 사실입니다. 이 접두어로 인해 컨트롤명과 컨트롤 콜백함수명, 컨트롤의 값을 전역적으로 갖고 있는 전역 구조체 변수의 멤버 변수명 등, 여러 종류의 이름에서 좀더 명확한 의미를 갖게 되기 때문이었던 것 같습니다.

 

2.5.4 사용자 추가 파일
CISDEFPROG 프로그램에서 사용자 정의 함수들을 모아두는 파일들은 그림 2.1의 ④번처럼 "u"라는 문자로 쉽게 구분되도록 파일명을 부여하였습니다. 그리고 프로젝트 창에서 이름순으로 파일명이 정렬될 때, Panel 관련 콜백함수 파일들 다음에 오도록 한 의도도 포함되어 있습니다.


이들 파일 중 날짜와 시각 문자열 관련한 CISDEFPROG_u_DateTime.c 파일의 일부를 그림 2.5.4.1 에 보였습니다.

 

그림 2.5.4.1 CISDEFPROG_u_DateTime.c 파일의 일부

 

함수명에 좀 특이한 접두어가 보이는데, Proc 라는 문자열은 Procedure를 줄여서 썼습니다. C언어에서 함수는 Function 뿐이지만, 파스칼 언어에서는 Function과 Procedure가 있다고 합니다. FORTRAN에서도 Function과 Subroutine 이 있죠!
제가 Proc라고 붙이는 이유는 파스칼 언어에서처럼 함수이긴 함수인데, 반환되는 값이 없거나 있더라도 반환되는 그 값이 큰 의미를 갖지 않는 함수에 대해 사용합니다. 제 나름의 함수명 부여 습관의 일부이므로 알아두시면, 앞으로 계속 소개되는 저의 프로그램 소스를 이해하시는 데에 도움이 되실 것입니다.


제 습관 얘기가 나온 김에 하나만 더 언급하자면, 저는 소스 편집기의 tab 간격을 4로 하고 있고, tab 문자는 모두 space로 변경되도록 편집기 옵션을 설정해두고 있습니다. 이런 것이 어떻게 보면 저의 사소한 습관이긴 하지만, 많은 분들이 통일된 습관을 가지고 있다면, 타인의 소스를 볼 때에도 훨씬 부담이 적으리라 생각합니다. (텍스트편집기의 좀더 세련된 tab 설정을 사용하시는 분이 있으시면 소개해 주세요.)

 

마무리
으아... 지루하네요... CISDEFPROG 프로그램에 대한 개략적인 소개는 여기까지 하겠습니다. 이어지는 여러 강좌들에서 자주 사용하다보면 좀더 익숙해질 수 있을 것입니다.


---------------------------------------------------------------------------------------


이틀에 걸쳐서 총 9시간 가까이 본 강좌 작성에 시간을 투자하였습니다. 이때까지 강좌 글을 작성할 때 이렇게 많은 시간을 투자한 경우가 별로 없었던 것 같습니다. 하지만, 저는 이 CISDEFPROG 프로그램을 소개하는 강좌 글을 작성하는 내내 큰 기대에 부풀어 있습니다. 아직은 많이 부족한 Prototype 프로그램이지만, 앞으로 크게 더 뻗어갈 것에 대해 굳건한 토대가 될 것임을 믿어 의심치 않기 때문입니다.


모든 분들에게 좋은 일들이 많이 일어나기를 바랍니다.

 

본 강좌 문서작성 소요시간: 8시간 56분

2012.1.3 화

극동테크(www.kdtechno.com), CVI 정보나눔(www.cvi.kr) 허창원 드림


엮인글 '1'

http://www.cvi.kr/xe/cvi_lecture/15759/d97/trackback

2019.03.13 08:31

erotic sex - erotic sex

"[...]??????,??? - [??????:41] Prototype ???????????? CISDEFPROG ??????[...]"


정영채

2012.04.05 09:28:19
*.38.167.20

좋은강좌 감사합니다..  cvi를 접한지 얼마 되지 않았는데.. 글을 보며 많이 도움이 됩니다. ^^

List of Articles
번호 제목 글쓴이 날짜 조회 수
116 [팁] 컨트롤의 tooltips 지정하기 file 허창원 2020-05-08 389
115 멀티쓰레드 사용 시, 메모리 관련 참고사항입니다. [1] 요돌이 2017-10-24 1092
114 [팁]타이머 사용시 주의할점. file 이현화 2014-02-13 2535
113 Lable 세로쓰기 [1] 초보 2013-12-21 2668
112 [강좌:45] ini 파일 이용하기(CISManip.dll 활용) [2] 허창원 2013-05-29 3876
111 [강좌:44] ini 파일 이용하기(기본 활용) [1] 허창원 2013-05-29 5159
110 [강좌:43] Panel 크기 변경시에 컨트롤의 위치나 크기 조절하기(CISManip.dll 활용) 허창원 2013-03-12 6457
109 [강좌:42] Panel 크기 변경시에 컨트롤의 위치나 크기 조절하기(기본 활용) 허창원 2013-03-12 7072
108 [팁21] 그래프를 지우고 그릴때의 plotHandle을 구하는 방법 [1] 야리싸내 2012-05-25 7457
» [강좌:41] Prototype 프로그램 CISDEFPROG 소개 [1] [1] 허창원 2012-01-03 8670
106 [강좌:40] CIS Project를 시작하며... [4] 허창원 2011-12-29 8429
105 ------------- 이제 새로운 지평이 열립니다 ------------- 허창원 2011-12-29 8835
104 [팁]그룹명령(고수님들은 패스~ ^^;) file [2] 이현화 2009-06-15 23113
103 [KD스타일규칙] Panel, Control, Function 에 대한 이름부여규칙 file 허창원 2008-10-15 20960
102 [팁]Elaped Time [1] 이현화 2008-10-15 26401
101 [팁:19] 시리얼 포트 모니터링(Serial Port Monitoring) 유틸리티 소개 [9] [1] 허창원 2008-05-12 95072
100 [팁:18] CVI에서 ActiveX 컨트롤 사용하는 절차 file [2] 허창원 2008-04-07 30959
99 [강좌:39] 입맛대로 좀더 편리하게 배포용 설치 프로그램 만들기(CVI 8.5 이용) [1] [1] 허창원 2008-03-14 22994
98 [강좌:38] 배포용 설치 프로그램 만들기(CVI 8.5 이용) 허창원 2008-03-14 22899
97 [팁]간단한 최소화 기능개선입니다. 김민수 2007-10-05 24105