'PROGRAMING'에 해당되는 글 1건

  1. 2010.03.04 [VB 6.0] DoEvents 명령어 1

[6.0] 유용한 함수 - #6. DoEvents - 창의 표시를 위한 시간을 CPU에게 제공한다.

단일 쓰레드 환경인 Visual Basic은 안타깝게도 한 작업 도중 다른 작업을 할수가 없습니다.. 그러나.

DoEvents를 이용하면 그 사이에 창의 내용이 표시되어 마치 '다중 쓰레드'인것처럼
사용자에게 상황을 보여줄 수 있습니다.

(DoEvents를 사용하지 않으면 창이 (응답 없음) 모드로 변합니다.)

이 DoEvents가 하는 일은 그렇다면 무엇일까요?

답은 간단합니다.
창에 쌓인 메시지를 처리하는 일뿐입니다.

따라서, 모듈로만 이루어진 프로그램에서 CPU의 부담을 줄인다고
DoEvents를 사용하는 것은, 오히려 프로그램의 성능을 저하시킬 뿐입니다.

그렇다면 왜 'DoEvents'일까요?

VB는 다중 쓰레드 같은것은 지원하지 않습니다.(호환이 안된다고 보는게 맞겠군요.) 

타이머는 다중 쓰레드같지만
실질적으로 SetTimer api와 WM_TIMER 메시지를 이용해서 구현되었습니다.
(Spy++로 보시면 알겠지만 별도의 타이머 창이 존재함을 알수있습니다.)

즉, 창의 메시지를 처리하면, 그 사이에 이벤트를 처리할 수 있다. 이말이 되겠습니다.

강좌의 내용은 이것이 전부이지만, 약간 미흡한 것 같아서..
DoEvents를 api로 직접 구현하는 방법을 간단하게 써보겠습니다.

어떤 창이 메시지를 처리하는 과정은 단순합니다.

1. GetMessage 함수로 메시지 큐에서 메시지를 하나 꺼냅니다.

2. TranslateMessage 함수를 호출하여 메시지를 해석합니다.
    (이 함수는 필요없는데, 어떤 메시지는 이 것이 필요하더라군요.)

3. DispatchMessage 함수로 창에게 메시지 처리를 넘깁니다. 
   (정확히 말하면 특정 창의 윈도우 프로시저를 호출한다고 보는게 맞겠네요.)

그렇다면 구현해볼까요?

아래는 직접 DoEvents를 vb 소스로 구현한 'MyDoEvents'입니다.

Private Type MSG
    hwnd As Long
    message As Long
    wParam As Long
    lParam As Long
    time As Long
    ptx As Long ' POINTAPI
    pty As Long ' POINTAPI
End Type
Private Declare Function GetMessage Lib "user32.dll" Alias "GetMessageA" (ByRef lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long
Private Declare Function TranslateMessage Lib "user32.dll" (ByRef lpMsg As MSG) As Long
Private Declare Function DispatchMessage Lib "user32.dll" Alias "DispatchMessageA" (ByRef lpMsg As MSG) As Long

Sub MyDoEvents()
    Dim gMsg As MSG
    If GetMessage(gMsg, 0, 0, 0) Then
        TranslateMessage gMsg
        DispatchMessage gMsg
    End If
End Sub

출처 :  http://blog.daum.net/sadest/15853414

Posted by 스왓
이전버튼 1 이전버튼