1. 동적으로 컨트롤을 생성하는 방법은 ?
폼위에 동적으로 컨트롤을 생성하여 사용하는 방법을 알고 싶습니다.
VB 6.0을 사용하고 있다면 Form(UserControl, UserDocument) 객체의 Controls 컬렉션을
사용하면 됩니다. Controls 컬렉션에는 Add, Remove 등의 메소드가 있는데 이를 이용해 동적으로 생성할 수
있습니다. CreateObject 를 사용해 생성할 수도 있지만 ActiveX 컨트롤의 경우에는 이를 사용해서 생성할 경우에
모양이 보이지 않습니다. 생성방법은 Intrinsic 컨트롤이냐 아니면 ActiveX 컨트롤이냐에 따라 다른데 이에 대해 간단히
살펴보면 다음과 같습니다.
먼저 ActiveX 컨트롤은 다음과 같습니다.
' WithEvents를 써주면 이벤트도 받아서 처리할 수 있습니다.이렇게 만들어진 컨트롤을 삭제하려면 다음 코드를 사용합니다.
Dim WithEvents gCtObj As VBControlExtender ' Content 컨트롤을 가리키는 객체
' Add의 첫번째 인자는 생성하려는 컨트롤의 ProgID
' 두번째 인자는 생성하려는 컨트롤의 이름
' 세번째 인자는 생성되는 컨트롤이 올라갈 폼
Set gCtObj = Controls.Add("SIMGCTL.SimgctlCtrl.1", "myctl", Me)
Controls.Remove "myctl"이렇게 만들어진 컨트롤에서 발생하는 이벤트를 받으려면 ObjectEvent라는 함수를 정의해주면 됩니다. 변수이름_ObjectEvent 형태로 이름이 만들어진다는 점에 주의하시기 바랍니다.
Private Sub gCtObj_ObjectEvent(Info As EventInfo)다음은 Intrinsic 컨트롤입니다. Intrinsic 컨트롤의 타입은 VB.TextBox, VB.Label등과 같이 줄 수 있습니다. 다음 예를 참조하시기 바랍니다.
' 인자인 Info의 Name 필드로 이벤트 이름이 들어옵니다.
If Info.Name = "Click" Then
.........
End If
End Sub
// 다음 예는 텍스트 컨트롤을 하나 생성하고 그것의 내용으로 Sample을 올린다.이렇게 만들어진 컨트롤에서 발생하는 이벤트를 받으려면 해당 컨트롤이 디자인 타임에 form위에 추가된 것처럼 이벤트 처리 함수를 만들어 주면 됩니다. 예를 들어 위의 경우에서 Click 이벤트를 처리하려면 다음과 같은 함수를 만듭니다.
Dim WithEvents gEdit As VB.TextBox
Set gEdit = Controls.Add("VB.TextBox", "text1", Form1)
gEdit.Text = "Sample"
gEdit.Move 0, 0, 3000, 300
gEdit.Visible = True
Private Sub gEdit_Click()
MsgBox "Clicked#1"
End Sub
2. 전역 변수와 API 선언문의 위치는 ?
전체 form에서 공유되는 변수와 API의 선언은 어디에서 해주는 것이 가장 좋습니까 ?
그런 용도로 가장 좋은 것은 모듈(Module) 파일입니다. 모듈 파일에 API 선언을 해주면 그 API를 사용하는 폼마다 매번 API 선언을 해줄 필요가 없습니다. 마찬가지로 모듈 파일에 선언한 변수는 프로젝트내의 어느 폼에서든지 사용할 수 있습니다. 모듈 파일을 프로젝트에 추가하려면 프로젝트 메뉴에서 "모듈 추가" 명령을 선택하면 됩니다.
3. 컴포넌트 생성 방법
New 키워드와 CreateObject를 이용하는 컴포넌트 생성 방법 간의 차이점을 알고 싶습니다.
New 키워드를 이용한 컴포넌트 생성은 Early Binding이 됩니다. 즉 컴포넌트 변수의 정의와 동시에 컴포넌트를 생성합니다. 반면에 CreateObject 함수를 이용한 컴포넌트 생성은 Late Binding이 되며 변수의 정의와 생성시점은 별개가 됩니다. 또한 CreateObject는 Dispatch 인터페이스를 통한 호출이 가능하기 때문에 호출하려는 컴포넌트에 대해 미리 몰라도 관계없습니다. 예를 들어 보겠습니다. 다음은 New 키워드의 사용 예입니다.
Dim ie As New InternetExplorer ' 변수의 정의와 동시에 컴포넌트를 생성한다.
ie.Visible = True
다음은 CreateObject의 사용 예(1)입니다. 여기서는 변수를 미리 InternetExplorer 타입으로 정의해 놓고 컴포넌트를 생성했기 때문에 호출시에 이름 결정(Name resolution)이 일어나지 않기 때문에 호출 속도가 빠릅니다.
Dim ie As InternetExplorer
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
다음은 CreateObject의 사용 예(2)입니다. 여기서는 변수가 범용 컴포넌트를 나타내는 Object 타입으로 정의해 놓고 컴포넌트를 생성했기 때문에 호출시에 이름 결정 과정이 추가되기 때문에 호출 속도가 앞의 예(1)에 비해 느립니다. 이름 결정 과정이란 컴포넌트에 실제로 호출하려는 메소드나 프로퍼티가 존재하는지 살펴보고 그것을 부른다는 의미로 실제 호출에 앞서 이 과정이 들어가기 때문에 느려지게 됩니다. 또한 실행시간에 존재여부를 따지기 때문에 에러가 발생할 수 있습니다.
4. VB 프로그램의 최적화 방법
VB 프로그램을 최적화하기 위해 신경써야할 항목으로는 어떤 것이 있습니까 ?
코드 최적화에 관한 이야기를 계속 하기에 앞서 한마디만 하자면 코드를 부분적으로 최적화하여 사용하는 것도 중요하지만 제일 중요한 것은 올바른 구조를 잡는 것입니다.
- 적절한 타입의 변수를 선언해 사용한다.
- Const 키워드를 자주 사용한다.
- Splash 스크린을 적절히 사용한다.
- 자주 사용되는 폼만 메모리에 로드해둔다.
- 사용되는 컨트롤의 수를 최소화한다. - Advanced 버튼의 사용
- 폼의 수를 최소화한다.
- COM 객체 사용시 Early-bind한다.
- 배열은 되도록이면 사용하지 않는다.
- 사용되지 않는 코드를 제거한다.
- 작업이 긴 시간동안 지속될 경우에는 사용자에게 비주얼한 피드백을 제공한다.
5. IE상의 컨트롤에서 HTML의 Document Object Model 접근 방법
IE상의 컨트롤에서 자신이 올라가 있는 Document Object Model을 접근할 수 있는지 있다면 어떻게 해야하는지 그 방법을 알고 싶습니다.
UserControl의 Parent 프로퍼티로 현재 컨트롤을 포함하고 있는 웹브라우저 컨트롤에 접근할 수 있습니다. 웹 브라우저 컨트롤에는 Document 프로퍼티가 있어 이를 이용하면 웹 페이지의 내용을 접근할 수 있습니다.
6. 모니터 화면의 해상도 알아내기
현재 화면의 해상도를 알아내려면 어떻게 해야 합니까 ?
API 프로그래밍을 할 때는 GetDeviceCaps라는 함수를 사용하면 알아낼 수 있습니다. VB 프로그래밍을 할 때는 Screen이라는 전역 객체를 이용하면 됩니다. Screen 객체에는 유용하게 써먹을 수 있는 다양한 프로퍼티들이 존재합니다.
ActiveControl | 현재 포커스를 갖고 있는 컨트롤에 대한 레퍼런스 |
ActiveForm | 현재 활성화되어 있는 폼에 대한 레퍼런스 |
Height, Width | 현재 화면의 높이와 폭(픽셀 단위). 읽기 전용 |
MouseIcon | 커스텀 마우스 포인터의 모양을 지정한다.. LoadPicture와 같은 함수로 설정 가능 |
MousePointer | 마우스 포인터의 모양을 지정한다. MouseIcon으로 지정한 모양을 쓰려면 99를 지정 |
TwipsPerPixelX, TwipsPerPixelY | 한 픽셀당 트윕의 수(가로 방향, 세로 방향) |
7. VB로 만든 프로그램에서 자신의 버전 정보 보기
VB로 만든 프로그램에서 실행 중의 자신의 버전 정보를 보려면 어떻게 해야합니까 ?
6에서 본 Screen이라는 전역 객체 이외에도 VB에는 App, Err 등의 전역 객체가 존재합니다. App는 이 질문의 답을 제공해 주는 객체로 현재 프로그램의 버전 관련 정보와 기타 OLE 관련 정보를 제공해줍니다. 참고로 Err 객체는 가장 최근에 발생한 에러에 대한 정보를 제공해줍니다. App 객체에는 Major와 Minor, Revision라는 프로퍼티가 있는데 그 값을 쓰면 됩니다.
8. RDS를 이용한 원격 객체 생성
RDS를 이용해서 원격 객체를 사용할 때 HTTP 뿐만 아니라 DCOM도 사용할 수 있다고 알고 있습니다. 어떻게 해야합니까 ?
RDS는 HTTP, HTTPS, DCOM의 세 가지 프로토콜을 통해 원격 객체를 사용할 수 있도록 해줍니다. 사용하는 프로토콜에 따라 원격 객체를 생성하는 방식이 조금씩 달라집니다.
Dim iBLL As Object
' HTTP로 연결시
Set iBLL = CreateObject("Bank.Application", "HTTP://www.koreabank.com")
' HTTPS로 연결시
Set iBLL = CreateObject("Bank.Application", "HTTPS://www.koreabank.com")
' DCOM으로 연결시. MyServer는 서버의 컴퓨터 이름
Set iBLL = CreateObject("Bank.Application", "MyServer")
9. 조건부 컴파일 방법
VB에서 조건부 컴파일하는 방법을 알고 싶습니다.
#Const문으로 상수를 정의하고 그 상수에 따라 조건부 컴파일을 할 수 있다. #Const문은 모듈 파일에 넣어주는 것이 좋습니다.
#Const DebugVersion = 1
' DebugVersion이 TRUE가 되면
#If DebugVersion Then
'. 디버깅 코드를 실행한다.
'.
'.
#Else
'. 실행 코드를 집어넣는다.
'.
'.
#End If
#const 문을 사용하지 않는 방법도 있습니다. VB의 주메뉴 '프로젝트(P)'->'<프로젝트 이름> 속성(E)'에서 두번째 탭의 '만들기'에서 '조건부 컴파일 인수(D)'를 지정하셔도 됩니다.
10. RDS를 이용한 컴포넌트 생성시 컴포넌트의 타입
RDS를 이용해 원격 컴퓨터에 있는 컴포넌트를 생성하여 사용하고 있습니다. 그런데 원격 컴포넌트의 타입으로 Object를 주면 아무런 에러가 없고 원격 컴포넌트의 원래 타입을 주면 CreateObject에서부터 에러가 발생합니다. RDS를 사용해 생성하는 컴포넌트는 Object 타입을 사용할 수 밖에 없는가요 ?
그렇습니다. RDS를 통해 생성한 원격 컴포넌트를 생성할 경우 RDS는 로컬 시스템에 프록시 객체를 만들어주는데 현재 버전의 RDS(2.1)는 프록시 객체의 타입으로 Object 타입만을 지원합니다.
11. 레지스트리 관련 함수
애플리케이션에서 사용 중인 정보를 레지스트리에 기록하고자 합니다. 레지스트리 관련 API를 VB용으로 선언해서 사용하는 것 말고 VB 자체에서 지원하는 레지스트리 관련 함수는 없습니까 ?
GetSetting, SaveSetting, GetAllSettings, DeleteSetting 같은 함수가 있습니다. 이 함수들은 레지스트리의 아무 영역이나 건드릴 수 있는 것은 아니고 HKEY_CURRENT_USER\Software\VB and VBA Program Settings아래에 놓이는 키만 건드릴 수 있습니다. 이 아래에 \appname\section\key와 같은 형식으로 키가 놓입니다. MFC에도 이런 식으로 애플리케이션에서 사용 중인 정보를 레지스트리에 기록해주는 함수들이 있는데 이에 대해서는 다음을 참고하기 바랍니다.
12. Date 타입 관련 함수
VB의 Date 관련 함수들에 대해 알고 싶습니다.
VB에는 Date 타입과 관련하여 많은 내장 함수들이 존재합니다.
이름 | 기능 |
---|---|
Now | 컴퓨터의 현재 시간과 날짜를 얻어옵니다. |
Time | 컴퓨터의 현재 시간을 얻어옵니다. |
Date | 컴퓨터의 현재 날짜를 얻어옵니다. |
Year | Date 타입에서 년도만 얻어옵니다. |
Month | Date 타입에서 달만 얻어옵니다. |
Day | Date 타입에서 일자만 얻어옵니다. |
Weekday | Date 타입이 가리키는 날이 무슨 요일인지 얻어옵니다.(1=일요일,...,7=토요일) |
Hour | Date 타입에서 시간만 얻어옵니다. |
Minute | Date 타입에서 분만 얻어옵니다. |
Second | Date 타입에서 초만 얻어옵니다. |
DateValue | 특정 날짜를 몇 일을 더하면 어떤 날짜가 되는지 계산할 때 사용합니다. |
위에서 DateValue 함수에 대해서만 조금 더 부연 설명을 하겠습니다. 어떤 날짜에 몇 일을 더하면 무슨 날짜가 되는지 알고 싶을때 사용합니다. 예를 들어 Date의 dt가 가리키는 날짜에 20일을 더하면 무슨 날짜가 되는지 알고 싶다면 다음과 같이 합니다.
lblNextDate.Caption = CStr(DateValue(dt, 20))
Date 타입이 가리키는 날짜를 문자열로 변경하고자 할 때는 해당 Date 타입을 CStr 함수의 인자로 지정해주면 됩니다. 그런데 이는 기본적으로 년도를 두자리만 표기해주기 때문에 2000년 이상의 연도를 표기할 때는 00으로 나타나는 문제가 있습니다. 이를 해결하려면 다음과 같이 합니다. dt를 Date 타입의 변수라고 하겠습니다.
lblDate.Caption = CStr(dt) ' 연도를 두 자리만 표기
lblDate.Caption = CStr(Format(dt, "Long Date")) ' 연도를 네 자리 모두 표기
13. 체크 박스 두번 눌림 감지
체크 박스를 이용해 프로그래밍을 하고 있는데 같은 체크 박스를 계속 클릭하면 처음 한번만 Click 이벤트가 뜨고 그 뒤로는 Click 이벤트가 뜨지 않습니다. 이를 어떻게 감지해야 할까요 ?
체크 박스의 GotFocus 이벤트를 처리하면 됩니다. 여기에 Click시와 같은 코드를 넣어두면 됩니다.
14. 폼의 캡션바 없애기
폼에서 캡션바를 없애고 싶습니다. 어떻게 해야하나요.
폼의 윈도우 스타일을 변경하면 되는데 이를 수행하려면 윈도우 API를 이용해야 합니다. 다음 코드를 참조하시기 바랍니다.
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const WS_CAPTION = &HC00000
Private Const GWL_STYLE = (-16)
Option Explicit
Private Sub Form_Load()
Dim lStyle As Long
lStyle = GetWindowLong(hwnd, GWL_STYLE)
lStyle = lStyle And (Not WS_CAPTION)
SetWindowLong hwnd, GWL_STYLE, lStyle
End Sub
15. 통합 환경과 단독 실행시의 구분 코딩 방법
VB의 통합 환경위에서 동작할 때와 실행 파일로 만들어져 단독으로 실행되느냐에 따라 다른 코드를 실행하도록 하고 싶습니다. 쉽게 하는 방법이 없을까요 ?
앞에서 설명드린 적 있는 App 객체의 Revision이란 프로퍼티를 이용하면 됩니다. App.Revision이 TRUE이면 통합 환경에서 실행 중인 것입니다.
16. VB에서 파일 I/O 방법
VB에서 FileSystemObject 객체를 사용하여 파일 I/O를 하는 방법을 알고 싶습니다.
FileSystemObject를 이용해 텍스트 파일 쓰기를 하는 방법은 다음과 같습니다.
Set fso = CreateObject("Scripting.FileSystemObject")
Set a = fso.CreateTextFile("c:\testfile.txt", True)
a.Write("테스트하는 중입니다.") ' 한줄만 쓰고 싶으면 Writeln 함수를 사용한다.
a.Close
17. 윤년을 고려한 일수 계산
다음은 인자 Year와 Month로 지정한 달의 일 수를 리턴해주는 함수입니다.
Public Function GetDays(ByVal Year As Integer, ByVal Month As Integer) As Integer
' --- 먼저 Year가 윤년인지 따진다.
If Month = 2 Then
If (Year Mod 4 = 0 And Year Mod 100 <> 0) Then
GetDays = 29
Else
GetDays = 28
End If
Else
If Month = 1 Or Month = 3 Or Month = 5 Or Month = 7 Or _
Month = 8 Or Month = 10 Or Month = 12 Then
GetDays = 31
Else
GetDays = 30
End If
End If
End Function
Copyright 1999© 한기용 | Last updated: 11/14/2006 11:18:08 |
'개발 > VB' 카테고리의 다른 글
Internet Explorer Navigate 사용 팁 (0) | 2008.05.28 |
---|---|
비정상적 접근이 차단된 페이지 HTML소스 얻기 (0) | 2008.05.27 |
[MSDN] HOWTO: Automate Internet Explorer to POST Form Data (0) | 2008.05.27 |
[MSDN] Reference for Visual Basic Developers (0) | 2008.05.27 |
[MSDN] Reusing the WebBrowser Control (0) | 2008.05.27 |