창을열자
창을열자 비주얼 베이직 프로그래밍
최상환
지난호까지 비주얼 베이직에 대해 간략히 알아보았다. 이번호에서는 간단한 에디터를 통해서 비주얼 베이직 프로그래밍에 대해 알아보도록 하겠다. 이 에디터 프로그램은 피터 노턴의 책에 있는 예제를 약간 참고한 것이다. 현재 비주얼 베이직에 관한 책이 몇 권 나왔다. 원서가 대부분이라서 아쉽기는 하다. 한글 윈도우에 있는 메모장같은 간단한 에디터는 윈도우의 에디트 콘트롤을 이용하는 것이다. 비주얼 베이직에서는 텍스트 박스 콘트롤에 해당되는 것이다. 간략한 에디터를 만들려면 이 텍스트 박스 콘트롤에 대해 알고 넘어가야 할 것이다. 텍스트 박스 콘트롤은 윈도우내에 이미 만들어져 있는 것이다. 기본적인 편집 기능들은 이미 구현되어 있는 것이므로 가져다 쓰기만 하면 된다. 한가지 단점은 32KB가 넘는 파일은 읽어 넣을 수가 없다는 것이다. 아주 큰 파일을 편집하기 위해서는 사용할 수가 없지만 작은 파일을 읽고 편집할 수 있는 에디터를 만드는데는 아주 편리하다. 이 에디터는 메뉴와 텍스트 박스만이 존재한다. 텍스트 박스의 크기가 좀 작게 되어있는데, 이는 프로그램을 실행하는 동안에 윈도우의 크기와 일치하도록 할 것이므로 걱정하지 않아도 된다. <화면 1>의 프로젝트 윈도우를 보면, 이 에디터를 구성하는 폼이 AboutForm, Form1, OpenForm, SaveForm 그리고 Edit.bas 5개의 파일로 구성되어있음을 알 수 있을 것이다.
메뉴 디자인
에디터의 메뉴는 크게 File, Edit, Help 세가지로 되어있다. 먼저 모든 항목을 입력한 다음, 정리를 하면 쉽게 만들 수 있다. File 메뉴에는 New(새로 작성하기), 불러오기Open, 저장하기Save, 새이름으로Save As, 그리고 끝내기Exit의 5가지 항목이 있다. Edit 메뉴는 클립보드를 이용하는 기능들로 잘라내기Cut, 복사하기Copy, 붙이기Paste의 세가지 기능을 지원한다. Help메뉴에서는 이 프로그램을 소개하는 About 메뉴 만을 지원하도록 하였다. 아마도 이렇게 만든 메뉴와 프로그램의 코드를 어떻게 연결시키느냐 하는 것이 궁금한 독자들도 있을 것이다. 폼에서 File의 New를 선택하면 바로 코드 작성 윈도우가 나타날 것이다. 여기에 메뉴 항목에 맞는 코드를 작성해 주면된다.
[화면 3]메뉴에 연결되는 코드 작성- FileNew.pcx
<화면 3>은 코드까지 입력한 화면이다. 우선 메뉴를 모두 만든 다음 나중에 메뉴와 연결시키도록 하자.
MEdit.bas
이 파일은 각 폼에서 공유하는 전역 변수나 상수 같은 것을 선언하는데 사용된다. 이 에디터에서는 편집하고 있는 파일이 수정이 되었나 그렇지 않은가를 검사하는데 사용될 TextChanged같은 변수를 선언하고 있다트 1>.
[리스트 1] Medit.bas
텍스트 박스와 폼
이 프로그램에서 가장 주가 되는 것이 텍스트 박스이다. 위에서 이야기했듯이 이 프로그램에서는 간단하게 윈도우가 제공하는 텍스트 박스를 사용하도록 한다. 기본값으로 사용되지 않는 속성들은 리스트에서 참조하여 바꾸어주든지 아니면 리스트를 타이핑해 넣어서 읽어들이든지 해야 한다. 텍스트 박스의 크기를 조절하는 방법은 아주 간단하다. 텍스트 박스의 속성을 살펴보면(도움말을 뒤져보아도 된다.), Height와 Width라는 속성이 있다. 이 속성들을 폼의 ScaleHeight와 ScaleWidth라고 하는 속성의 값으로 설정해 주면된다.
Text1.Width = Form1.ScaleWidth
Text1.Height = Form1.ScaleHeight
이것은 맨 처음 폼이 로드 될 때나 폼의 크기가 변할 때만 이와 같은 처리를 해주면 폼의 크기가 변하거나 위치가 변할 때마다, 텍스트 박스의 크기도 거기에 맞게 일치된다. 폼의 Width나 Height를 쓰지 않고 ScaleWidth와 ScaleHeight를 쓰는 이유는 당연하지만 폼의 Width와 Height는 폼 자체의 크기의 폼의 작업 영역(Client Area, 제목과 메뉴 바 부분을 뺀 영역)의 크기를 나타내지는 않기 때문이다. 작업 영역의 크기를 나타내는 것이 바로 ScaleWidth와 ScaleHeight라 할 수 있다. 좀 더 자세히 이야기 해야 겠지만, 일단은 이렇게만 이야기 해 두도록 하자. 그래서 위 두행은 폼의 Load와 Resize 프로시저에 넣었다<리스트 2의 Form1_Load, Form1_Resize 부분 참고>. 폼이나 콘트롤을 선택하고 그 폼이나 콘트롤의 사건에 맞는 프로시저를 선택하여 작성하면 된다. 일단 이렇게 설정된 텍스트 박스는 더 이상 손댈 것이 없다. 편집 기능은 윈도우에서 맡아 하기 때문이다. 단지 텍스트가 변했나를 검사하는 부분이 필요하다. 텍스트 박스에는 Change라는 프로시저가 있다. 이 Change라는 프로시저는 텍스트 박스의 내용이 바뀌면 호출되게 된다. 그러므로 여기에 파일이 변경되었음을 알 수 있도록 하는 루틴을 넣어주면 된다<리스트 2의 Text1_Change 부분 참고>. 텍스트 박스의 그 밖에 중요한 속성을 보면, 먼저 내용을 나타내는 text 속성, 내용 중에서 선택된 영역을 나타내는 SelText같은 것과 여러줄을 편집한다는 속성인 Multiline, 스크롤 바의 형태를 지정하는 ScrollBars 같은 속성 등은 눈여겨 보아야 할 것이다. 에디터에서는 Mulitline은 True, ScrollBars는 수직, 수평 모두 사용하는 3 – Both로 설정하고 있다. 또 파일이 수정이 되었는지의 여부를 결정하기 위해 TextChanged라는 변수를 사용하고 있는데 내용이 파일이 수정이 되면 이 변수의 값을 1로 설정하여 파일이 변경되었음을 나타낸다. 이는 현재 작업 중인 파일을 저장하지 않고 프로그램을 끝낸다든지 다른 파일을 읽어들이는 경우 저장할 것인지를 묻기 위해 사용된다. MenuNew와 MenuOpen, MenuExit에 관련된 루틴을 살려보면 알 수 있을 것이다.
Sub Text1_Change ()
TextChanged = 1
End Sub
클립보드
윈도우 장점 중의 하나가 클립보드를 통해서 프로그램간에 자료를 주고 받을 수 있다는 것이다. 프로그램 자체에서도 이용할도 있는데 우선 클립보드를 사용하는 방법을 알아보자. 클립보드로 자료를 넣기 위해서는 먼저 Clear라는 메쏘드를 사용하여 클립보드의 내용을 지워야 한다.
Clipboard.Clear
클립보드에 자료를 넣는데에는 SetData와 SetText 두가지 방식를 사용할 수 있다. SetData가 비트맵같은 자료도 넣을 수 있지만 쓰는 방법이 조금은 복잡하다. 에디터는 텍스트만을 다루는 것이므로 SetText를 중심으로 이야기 하겠다.
Clipboard.SetText Text1.SelText
이렇게하면 선택된 텍스트를 클립보드로 복사해 주는 것이다. 다음에 잘라내기Cut 명령을 실행하는 경우라면 선택된 텍스트를 지워주어야 한다.
Text1.SelText = “”
클립보드에서 텍스트를 가져오는 것도 비슷하다. 먼저 GetFormat 메쏘드로 클립보드에 자료가 있는지 알아보아야 한다.
If Clipboard.GetFormat(CF_TEXT) then
‘텍스트가 있을 때의 처리
else
‘ 텍스트가 없을 때의 처리
End If
CF_TEXT는 클립보드 자료형식 중 텍스트 형식을 나타내는 상수인데, 이는 constant.txt라는 파일에 들어있다. 이 파일을 폼 파일이나 모듈(.BAS파일)에 포함시켜서 사용하면 된다. edit.bas라는 파일에 클립보드에 관련된 상수들만을 넣어두었다. 텍스트 데이터가 있다면 가져오는 것도 쉽다.
Text1.SelText = Clipboard.GetText()
이렇게 하면 바로 붙이기Paste기능을 수행한 것이 된다. 실제로 클립보드를 이용하여 자료를 옮기는 것은 <리스트 2>의 클립보드에 관련된 부분(Edit 메뉴의 항목에 관련된 부분들)을 참고하기 바란다.
읽어들이기 저장하기
프로그램에서 필요한 것이 바로 파일에 관련된 기능이다. 읽어들이기와 저장하기 기능에 대해 알아보자. 에디터는 텍스트만을 사용하는 프로그램이므로 아주 간단히 할 수 있다. 파일 읽기에는 OpenForm.frm이 저장에는 SaveForm.frm이 사용된다. OpenForm에 보면 파일 리스트 박스, 디렉토리 리스트 박스, 드라이브 리스트 박스 등이 사용되고 있는데, 이들에 대한 코드는 거의 신경쓸 것이다. 대부분 비주얼 베이직이 알아서 하기 때문이다. 우리가 코드로 작성해서 해야 할 곳은 사용자가 드라이브나 디렉토리를 바꾸었을 때이다. 드라이브를 바꾼 경우는 디렉토리 리스트를 변경해 주면되고, 디렉토리 리스트가 바뀌면 파일리스트를 변경해 주면된다. 먼저 드라이브 리스트의 경우이다.
Sub Drive1_Change ()
Dir1.Path = Drive.Drive
End Sub
생각보다 쉽다는 느낌이 들것이다. 다음에는 디렉토리 리스트가 바뀐 경우이다.
Sub Dir1_Change ()
File1.Path = Dir1.Path
End Sub
마찬가지로 어렵지 않다. 다음은 파일 리스트 박스인데 이것이 약간 신경을 써야 한다. 사용자가 파일 리스트 박스에서 파일을 선택한 후 OK 버튼을 선택할 수 있고, 또 바로 더블 클릭할 수 도 있기 때문이다. 두가지 경우 모두에 대한 코드를 써 주어야 한다.
Sub File1_Click ()
NameText.Text = File1.Filename
End sub
사용자가 파일 리스트 박스에서 파일을 클릭한 경우이다. 텍스트 박스에 파일 이름을 써넣어 주기만 하면 된다.
Sub File1_Dblclick
OKButton_Click
End Sub
실제로 파일을 읽어들이는 처리는 OKButton이 눌렸을 때 하게 되므로 이 프로시저를 호출하기만 한다. 한번 생각을 해보자. 사용자가 드라이브를 바꾸면 드라이브 리스트 콘트롤이 디렉토리 리스트의 경로를 바꾸어 주고, 디렉토리 리스트가 파일 리스트의 경로를 바꾸어 주고 파일 리스트가 그 경로에 있는 파일을 표시하게 된다. 어떻게 생각하면 아주 당연한 것이다. 그러면 실재로 읽어들이는 기능을 맡고 있는 OKButton_Click 프로시저를 보자. 사용자가 OKButton을 누르면 호출된다. 파일 리스트에서 파일을 더블클릭한 경우도 마찬가지이다.
Sub OKButton_Click ()
Dim rc As Integer
On Error GoTo FileError
If TextChanged = 1 Then ‘ TextChanged는 파일의 수정 여부
‘ 파일이 수정된 후에 저장되지 않은 경우 저장할 것인지 물음
rc = MsgBox(File not saved, Save it ?, 3)
Select Case rc
Case 6 ‘ ID_YES
SaveForm.Show ‘ 저장
Case 7 ‘ ID_NO
Case 2 ‘ ID_CANCEL
Exit Sub
End Select
End If
‘ 파일을 읽어들인다.
‘ 파일 이름은 NameText.Text에 들어있다.
If (Right$(Dir1.Path, 1) = \) Then
FileName$ = Dir1.Path + NameText.Text
Else
FileName$ = Dir1.Path + \ + NameText.Text
End If
Open FileName$ For Input As #1
Form1.Text1.Text = Input$(LOF(1), #1)
Close #1
TextChanged = 0
OpenForm.Hide
Exit Sub
FileError: ‘파일 입출력에서 에러가 발생한 경우
MsgBox File Error + Str$Err, 48, Editor
End Sub
위의 예를 보면 텍스트 파일을 읽어들이는 방법이 아주 간단하다는 것을 알 수 있다. MsgBox라는 함수와 프로시저를 눈여겨 봐두기 바란다. 간단한 메시지를 출력하는 데 사용된다. 사용형식은
MsgBox(msg, type, title) ‘ 함수인 경우
MsgBox msg, type, title ‘ 프로시저인 경우
type과 title은 필요에 따라 생략해도 된다. 함수의 경우는 어떤 버튼이 눌렸는지 그 값을 되돌린다. 위의 예에도 함수인 경우와 프로시저인 경우가 모두 쓰이고 있다. type이나 리턴값에 대한 설명은 생략하기로 한다. 매뉴얼이나 도움말을 참고로 하길 바란다. ID_OK같은 이름을 사용하려면 constant.txt를 모듈 파일같은데 포함시켜서 사용하면 된다. 파일 저장의 폼은 아주 간단히 만들었다. 역시 OKButton에 대한 처리가 필요할 뿐이다.
Sub OKButton_Click ()
On Error Goto FileError
Open NameBox.Text For Output As #1
Print #1, Form1.Text1.Text
Close #1
SaveForm.Hide
TextChanged = 0 ‘ 저장했으므로 변경이 되지 않은 것으로 설정
Exit Sub
FileError:
MsgBox File Error, 48, Edit
End Sub
Print 명령을 이용하여 파일에 기록한다.
도움말 메뉴
도움말에서는 프로그램에 대한 소개를 하는 About 메뉴만을 넣었다. 폼도 간단하고 프로그래머나 목적같은 것을 간단히 적어 소개하는 목적으로 사용된다. 그림에 About 폼을 두었다. OK 버튼을 누르면 폼을 닫도록 하였다.
Sub Command1_Click ()
AboutForm.Hide
End Sub
[화면 7]About Form- Aboutfor.pcx>
메뉴와의 연결
미리 이야기를 했지만, 메뉴와 프로그램을 연결하는 것은 어렵지 않다. 이 프로그램에서 사용되는 모든 메뉴항목들의 이름은 Menu…로 시작되므로 리스트에서 찾아보기에 그리 어렵지 않을 것이다. 예를 파일 읽어오기(File|Open) 메뉴는 OpenForm을 불러낸다. 그러므로 다음과 같은 코드가 될 것이다.
Sub MenuFileOpen_Click ()
OpenForm.Show
End Sub
폼의 메뉴에서 File|Open을 선택하면 이 메뉴에 연결되는 코드를 작성할 수 있다. 메뉴에 대한 모든 코드는 MEdit.frm이라는 파일에 모두 저장되어있다. 편집Edit 메뉴의 Cut을 살펴보자. 클립보드에서 이야기 했던 코그가 그대로 들어간다.
Sub MenuCut_Click ()
Clipboard.Clear
Clipboard.SetText Text1.SelText
Text1.SelText = “” ‘선택된 텍스트를 지운다.
End Sub
[리스트 2] form1.frm
[리스트 3] OpenForm.frm
[리스트 4] SaveForm.frm
[리스트 5] Aboutfor.frm