강좌,팁

허창원 *.59.121.121

[강좌:010] 따라하기 7. CVI에서 Win32 API 함수 이용하기:사운드

자주 현금자동지급기를 이용하면서 터치스크린으로 조작하는 그 프로그램을 어떻게만들었는지를 생각해 보곤 했었죠! 그러던 중 언젠가 그 현금자동지급기를 부팅하는걸 봤는데, Windows 2000이 실행되더군요. 드디어 저한테 들켜 버리고 만겁니다.저런 식이라면 나도 만들 수 있겠다고 생각했죠!

그런데 한가지 곤란한 것은 화면에 나타난 버튼을 누를 때마다 나는 경쾌한 소리를CVI에서 어떻게 처리해야할지 바로 떠오르지 않더군요. CVI의 Function Panel tree를뒤져봐도 사운드나 멀티미디어에 대한 내용은 없더군요. 참, 옥의 티가 다 있네~라고 생각하는 순간, 문득 든 생각은 Win32 API를 CVI에서도 이용할 수 있다면 간단하겠다는것이었습니다.

그래서 매뉴얼을 찾아보고 테스트 해보면서 드디어 해결하게 되었습니다.

오늘 강좌는 Win32 API 함수 중 사운드파일을 플레이하는 함수 하나를 이용하게됩니다만, 이것을 응용하면 어떤 API 함수도 필요에 따라 이용가능하다는 것입니다.이런 응용은 여러분들에게 맡기도록 하고, 여기서는 아주 간단한 예만 보이도록 하겠습니다.

Win32 API 함수를 이용하기 전에 우선 현금자동지급기의 화면 하나를 만들어보도록하겠습니다. 즉, 0부터 9까지의 숫자 버튼이 있고, Back space에 해당되는 버튼 하나,Reset에 해당되는 정정 버튼, 그리고 결과를 보기 위한 확인 버튼을 둡니다. 참,숫자를 누를 때마다 눌러진 숫자를 보여주는 컨트롤도 있어야겠군요. 우선 이 프로그램부터만든 후에 Win32 API 함수를 적용하겠습니다.

1. Project 파일, 그리고 초기 UIR 파일 저장
이번의 Project 파일명은 L010_Sound.prj로 하고, UIR 파일도 L010_Sound.uir 로 작업 전에 저장, 프로젝트에 추가를 합니다.

2. 화면구성
화면구성을 그림 10.1과 같이 합니다. 그림을 보시면 직감적으로아시겠죠? 버튼을 누를 때마다 위쪽의 String 컨트롤에 숫자가 표시되고, 왼쪽 화살표키를 누르면 입력된 숫자의 아래자리부터 하나씩 지워지게 됩니다. 정정 버튼은 입력된숫자를 모두 지우게 되고, 확인 버튼을 누르면 입력된 숫자를 메시지 팝업 창에 표시한후, String 컨트롤을 초기화 합니다.

그림 10.1 화면구성

Panel과 각 control의 속성을 표 10.1과 표 10.2에 나타내었습니다.

표 10.1 Panel 속성 설정

속성

내용

Constant Name

PANEL

Callback Function

Panel_Proc

Panel Title

금액을 입력하세요

 

체크 Auto-Center Vertically (when loaded)

 

체크 Auto-Center Horizontally (when loaded)

 

표 10.2 컨트롤의 속성 설정

컨트롤 종류

Constant
Name

Callback Function

Label

Default Value 혹은 InitialState

Text Message

TEXTMSG

 

 

금액을 입력하세요.

String

strDisplay

 

 원

 

Command Button

cmdButton0

cmdButtonNum

0

 

Command Button

cmdButton1

cmdButtonNum

1

 

Command Button

cmdButton2

cmdButtonNum

2

 

Command Button

cmdButton3

cmdButtonNum

3

 

Command Button

cmdButton4

cmdButtonNum

4

 

Command Button

cmdButton5

cmdButtonNum

5

 

Command Button

cmdButton6

cmdButtonNum

6

 

Command Button

cmdButton7

cmdButtonNum

7

 

Command Button

cmdButton8

cmdButtonNum

8

 

Command Button

cmdButton9

cmdButtonNum

9

 

Command Button

cmdReset

cmdReset

정정

 

Command Button

cmdOK

cmdOK

확인

 

Picture Button

picbtnBack

picbtnBack

 

 

 

Picture Button에 올려놓은 그림은 파워포인트로 적당히 그렸습니다. 그리기 귀찮으신분은 여기를 클릭하여 그림을 다운로드 받아 이용하시면되겠습니다.

 

3. 기초 소스코드 생성(UIR 창에서 Code-Generate-All code... 메뉴)
그림10.2에 표시된 것처럼 체크한 후에, OK를 누릅니다.

그림 10.2 기초 소스코드 생성

새로 나타나는 편집 창의 소스 코드를 L010_Sound.c로 저장합니다.그리고 Project 파일에 포함시킵니다. uir 파일 저장시에 생성된 L010_Sound.h 파일도Project에 포함시킵니다.

Project 파일 내의 파일들을 정리해 봅니다. 이제 만들게 될 파일까지미리 말입니다.

표 10.3 Project 파일 내의 파일들

파일명

설명

L010_Sound.c

콜백 함수 위주의 소스 파일

L010_Sound.h

자동생성 헤더파일

L010_Sound.uir

화면 구성 UIR 파일

L010_Sound_common.c

사용자 정의 함수 파일

L010_Sound_common.h

사용자 정의 헤더 파일

L010_Sound_DEF.h

통합 헤더파일

 

4. 상태 구조체 정의, 전역변수 선언
늘 해오던 습관대로상태 구조체를 L010_Sound_common.h 에 정의합니다. 어떤 상태값이 필요할까요?
제생각에는 숫자 버튼을 누를 때마다 해당 되는 숫자 문자를 문자열(Buffer)에 저장해야하고,또 1000단위 기호도 넣어서 출력하는 것도 좋을 것 같아 별도의 문자열(StringDisplay)도필요하겠군요. 그리고 최초 문자열의 인덱스 정보도 있으면 유용할 것 같아요.

그래서 그림 10.3과 같이 우선 정의합니다.

그림 10.3 STATUS 구조체 정의

구조체는 이렇게 정의하였는데, 구조체 변수의 선언은 L010_Status_common.c에다가하려고 합니다. 헤더 파일에 하지 않는 이유는, 될 수 있는 한 헤더파일에는 메모리를할당하지 않고 선언문 위주로 구성하려고 하기 때문입니다. 단지 헤더파일에는 외부변수선언만 해줄 것입니다.

그리고, L010_Sound.c에 자동으로 생성된 코드 중에 panel handle에대한 변수가 static으로 선언되어 있는데, 이것도 L010_Sound_common.c에 전역변수로선언할 것이고, L010_Sound_common.h에는 외부변수로 선언할 것입니다. 정적변수로선언되면 외부변수로 이용할 수가 없거든요.(이런 내용은 C 문법에 의거, 정석대로처리하기 위함이므로 C 문법을 참고하시기 바랍니다.)

다시 L010_Status_common.h와 L010_Status_common.c를 그림 10.4와10.5에 보였습니다. 상태 구조체 변수 초기화 함수까지 만들어 보입니다.

그림 10.4 L010_Sound_common.h 파일 내의 변수 선언

 

그림 10.5 L010_Sound_common.c 파일 내의 변수 선언 및 초기화함수

참, 그리고 L010_Sound_common.c 의 윗부분에 보면 통합 헤더파일을include 한 것을 볼 수 있습니다. 자질 구레한 헤더 파일들을 이 하나의 헤더 파일내에 모아 두어 이용하면 편하죠!

또, status 초기화 함수도 별다른 내용은 없죠? 멤버 변수를 초기화하는과정입니다.

5. main 함수 내에 초기화 함수 추가
main() 함수 내에위에서 정의한 초기화 함수를 추가합니다. 그리고, static으로 선언된 panel handle변수도 제거하는 것 잊지 말구요. 헤더 파일 include 부분도 그림 10.6과 같이 수정합니다.

그림 10.6 수정된 main() 함수와 변수 선언부분 등

6. 숫자 버튼 콜백 함수
숫자 버튼을 누를 때마다 상태구조체 내의 Buffer 문자열 내에 숫자 문자를 하나씩 추가하는 콜백 함수 내용을작성합니다. 그림 10.7에 cmdButtonNum() 콜백 함수를 보였습니다. L010_Sound.c에있는 함수입니다.

그림 10.7 cmdButtonNum() 콜백 함수

숫자 버튼 각각 하나씩의 콜백 함수를 만드는 것보다 하나의 콜백함수 내에서 해당 버튼의 컨트롤 ID에 따라 처리를 하는 것이 더 좋을 것 같죠?

문자 '0'이 처음에 입력되는 것은 필요 없으므로 그대로 통과시키도록한 부분이 구별되어 보입니다.

그리고, 마지막 부분에 Refresh_Display() 함수가 있는데, 이건이제 만들어야겠죠? 입력된 문자열을 적절히 처리해서 String 컨트롤에 표시하는기능을 갖습니다. 여기서 적절히 처리를 한다는 것은 1000단위 구분기호, 즉 코머를적절히 찍어서 표현하는 것을 말합니다.

7. 입력받은 숫자 문자열을 처리하여 출력
Refresh_Display()함수는버튼이 눌러질 때마다 현재 입력된 문자열(숫자 정보)을 String 컨트롤에 표시해주는 함수입니다. 이 함수는 그림 10.8과 같이 구성될 수 있습니다. L010_Sound_common.c에정의하였습니다.

그림 10.8 Refresh_Display() 함수

여기서 Convert_comma_format_number() 라고 길게 이름 붙여진 함수도만들어야되는 함수입니다. 이 함수의 기능은 숫자만 입력된 문자열로부터 1000단위구분 기호인 코머를 적절한 위치에 첨가시켜서 새로운 문자열을 만드는 함수입니다.

실전 프로그래밍을 하다보면, 이런 류의 함수를 만드는 일이 의외로자주 나옵니다. 즉, 문자열 처리에 관한 함수지요. 약간은 복잡할 수 있는 기능을구현해야 되는 데, 이런 식의 프로그램을 잘하면 알고리즘을 프로그래밍화 하는 데많은 도움이 될 겁니다.

 혹시 이미 만들어져 있는 기능을 따로 만드는 건 아닌지 모르겠습니다.없을 것 같아 제가 만들어 보았습니다. 그림 10.9에 Convert_comma_format_number()함수를 보였습니다. 설명은 코멘트로만 대체합니다. 역시 L010_Sound_common.c에정의하였습니다.

그림 10.9 숫자 문자열에 1000단위 구분기호를 추가하는 함수

이렇게 함수를 정의하였으므로, 함수의 프로토타입 선언도 뒤따라야겠죠!그림 10.10에 함수 선언이 추가된L010_Sound_common.h 파일을 보였습니다.

그림 10.10 함수 선언이 추가된 L010_Sound_common.h 파일

8. 정정 버튼, 뒤로 버튼, 확인 버튼 콜백 함수
정정버튼과 Back Space 버튼에 대한 콜백 함수는 위에서 만들어진 함수들의 조합으로구현할 수 있습니다.
정정 버튼은 입력된 문자열을 초기화하여 비어있는 문자열을표시하도록 하면 됩니다.
Back Space 버튼은 현재까지 입력된 문자열의 제일 뒤쪽숫자 문자를 하나 제거하여 표시합니다. 그림 10.11과 그림 10.12에 정정 버튼 콜백함수와Back Space 버튼 콜백 함수를 보였습니다.

그림 10.11 정정 버튼 콜백함수

그림 10.12 Back Space 버튼 콜백함수

확인 버튼을 누르면, 메시지 팝업 창이 뜨면서 현재까지 입력된금액 문자열을 보여줍니다. 아래 그림 10.13에 적절한 코드를 보였습니다.

그림 10.13 확인 버튼 콜백함수

 

9. 통합 헤더파일
여러 헤더파일을 통합한 통합 헤더파일을 그림 10.14와 같이 작성합니다.

그림 10.14 통합헤더파일

컴파일을 할 때, 넣어야 된다고 알려주는 것은 모두 다 넣습니다.

10. 중간 실행 결과
이제 컴파일하여 실행해볼까요?

그림 10.15 첫 실행화면


케이

2006.09.29 17:13:07
*.104.133.155

잘 보았습니다. 감사합니다

수정할 것

2007.01.12 13:49:11
*.46.32.24

그림 10.8에서
SetCtrlVal(panelHandle, PANEL_strDisplay, status.StringDisplay);
는 SetCtrlVal(panelHandle, PANEL_STRING, status.StringDisplay);
로 바뀌어야 맞는 것 같습니다.
그리고 그림10.9에서는
str2[index_str2]=0;
가 str2[index_str2++]=0;
로 바뀌어야 겠구요.

지재남

2011.01.25 13:30:56
*.107.87.103

음....#define MAX_NUM 10 을 왜 정의한거일까요?


없어도 되는거 보니 쓰인데는 없는듯한데..;;


너무 늦게 시작했나 ㅎ벌써 2011년인데 봐주실분이 있을지;;


강좌는 잘보고 배워가고 있습니다 감사합니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
36 [강좌:014] 따라하기 9. 터치스크린에서 숫자 입력하기 (2) 허창원 2003-01-15 12962
35 [강좌:014] 따라하기 9. 터치스크린에서 숫자 입력하기 (1) 허창원 2003-01-15 14488
34 [강좌:013] 샘플 분석 2. Table 컨트롤 이용하기(colview) (2) [1] 허창원 2003-01-04 12785
33 [강좌:013] 샘플 분석 2. Table 컨트롤 이용하기(colview) (1) 허창원 2003-01-04 27274
32 [퍼온칼럼] 전병선 컬럼-프로그래머의 자세 허창원 2002-12-21 11659
31 [야리팁001]이거..블럭모드 지정..야리만 아는 팁(?)인가요? 야리싸내 2002-12-20 14388
30 [팁:002] panel을 Modal dialog box로 띄우기 [3] 허창원 2002-12-12 20175
29 RemovePopup()과 DiscardPanel()의 차이 허창원 2002-12-12 15477
28 Re: RemovePopup()과 DiscardPanel()의 차이 야리싸내 2002-12-13 13255
27 [강좌:012] 샘플 분석 1. 한 그래프에서 2개의 Y축 이용하기(2yaxis) [1] 허창원 2002-11-26 16441
26 [강좌:011] 따라하기 8. UI는 CVI로, 코딩은 VC++로 하기 [4] 허창원 2002-11-21 20719
25 [강좌:010] 따라하기 7. CVI에서 Win32 API 함수 이용하기:사운드(2) [1] 허창원 2002-10-30 17543
» [강좌:010] 따라하기 7. CVI에서 Win32 API 함수 이용하기:사운드(1) [3] 허창원 2002-10-30 21911
23 [강좌:009] 따라하기 6. 데이터 뷰어2 프로그램 제작 (4) 허창원 2002-10-09 16251
22 [강좌:009] 추가 보충설명 허창원 2003-02-14 12704
21 [강좌:009] 따라하기 6. 데이터 뷰어2 프로그램 제작 (3) [1] 허창원 2002-10-09 15527
20 [강좌:009] 따라하기 6. 데이터 뷰어2 프로그램 제작 (2) 허창원 2002-10-09 15682
19 [강좌:009] 따라하기 6. 데이터 뷰어2 프로그램 제작 (1) 허창원 2002-10-09 18386
18 [강좌:008] 따라하기 5. 데이터 뷰어(그래프) 프로그램 제작 (2) [1] 허창원 2002-09-01 23730
17 [강좌:008] 따라하기 5. 데이터 뷰어(그래프) 프로그램 제작 (1) (1차수정) [3] 허창원 2002-09-01 35872