다음을 통해 공유


연습: 공유 스레드에서 Windows Forms을 표시하여 COM Interop 지원

Application..::..Run 메서드를 사용하여 만들어지는 .NET Framework 메시지 루프에 폼을 표시하여 COM 상호 운용성 문제를 해결할 수 있습니다.

COM 클라이언트 응용 프로그램에서 Windows Form이 올바르게 작동하도록 하려면 응용 프로그램을 Windows Forms 메시지 루프에서 실행해야 합니다. 이렇게 하려면 다음 방법 중 하나를 사용합니다.

다음 절차에서는 공유 메시지 루프를 가진 새 스레드에서 Windows Form을 표시하는 방법을 보여 줍니다.

이 항목의 코드를 단일 목록으로 복사하려면 방법: 공유 스레드에서 Windows Forms을 표시하여 COM Interop 지원을 참조하십시오.

절차

이 방법은 연습: 각 Windows Form을 별개의 스레드에서 표시하여 COM Interop 지원에서 설명한 방법과 유사합니다. 그러나 이 방법의 경우 자체 메시지 루프를 사용하여 자체 스레드에서 각 폼을 표시하는 대신 .NET Framework 구성 요소에 있는 단 하나의 새 스레드에서 실행되는 공유 메시지 루프를 만듭니다.

이 방법은 표준 Windows Forms 응용 프로그램의 동작을 보다 정확하게 나타냅니다. 또한 이 방법은 같은 스레드에서 모든 폼이 실행되기 때문에 여러 폼에서 리소스를 더욱 쉽게 공유할 수 있습니다. 연습: 각 Windows Form을 별개의 스레드에서 표시하여 COM Interop 지원 의 솔루션은 각 폼에 대해 새 스레드를 만듭니다. 이 솔루션을 실행하려면 서로 다른 폼 간에 리소스를 공유하기 위한 추가 스레드 동기화 코드가 필요합니다.

이 방법은 Windows Forms 응용 프로그램과 더욱 비슷하게 작동하므로 클라이언트 응용 프로그램에서 열리는 .NET Framework Windows Forms는 .NET Framework 메시지 루프가 중지될 때 닫힙니다. 이 동작은 사용자가 ApplicationContext의 기본 폼으로 지정된 폼을 닫을 때 발생합니다. ApplicationContext 는 메시지 루프를 시작하는 데 사용합니다.

다음 코드 예제에서는 ApplicationContext의 기본 폼을 클라이언트 응용 프로그램에서 처음으로 열리는 폼으로 설정합니다. 그러므로 사용자가 해당 폼 인스턴스를 닫으면 .NET Framework 메시지 루프가 종료되고 다른 모든 Windows Forms도 닫힙니다.

모든 폼에서 사용할 수 있도록 새 스레드에서 공유 메시지 루프를 만들려면

  1. 새 클래스 라이브러리 프로젝트를 만들고 이름을 COMWinform으로 지정합니다.

  2. 기본 Class1.vb 파일을 삭제합니다.

  3. 프로젝트 메뉴에서 클래스 추가를 클릭합니다.

  4. COM 클래스 템플릿을 선택합니다.

  5. 이름 상자에 COMForm.vb를 입력한 다음 추가를 클릭합니다.

  6. 다음 코드 문을 COMForm 파일의 위쪽, 클래스 정의 앞에 붙여넣습니다.

    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    
  7. COMForm 클래스 정의에서 생성자 정의 아래에 다음 코드를 붙여넣습니다.

    Private WithEvents frmManager As FormManager
    
    Public Sub ShowForm1()
        ' Call the StartForm method by using a new instance
        ' of the Form1 class.
        StartForm(New Form1)
    End Sub
    
    Private Sub StartForm(ByVal frm As Form)
    
        ' This procedure is used to show all forms
        ' that the client application requests. When the first form
        ' is displayed, this code will create a new message
        ' loop that runs on a new thread. The new form will
        ' be treated as the main form.
    
        ' Later forms will be shown on the same message loop.
        If IsNothing(frmManager) Then
            frmManager = New FormManager(frm)
        Else
            frmManager.ShowForm(frm)
        End If
    End Sub
    
    Private Sub frmManager_MessageLoopExit() Handles frmManager.MessageLoopExit
        'Release the reference to the frmManager object.
        frmManager = Nothing
    End Sub
    
  8. 프로젝트 메뉴에서 클래스 추가를 클릭하고 클래스 템플릿을 선택합니다.

  9. 이름 상자에 FormManager.vb를 입력한 다음 추가를 클릭합니다.

  10. FormManager 파일의 내용을 다음 코드로 변경합니다.

    Imports System.Runtime.InteropServices
    Imports System.Threading
    Imports System.Windows.Forms
    
    <ComVisible(False)> _
    Friend Class FormManager
        ' This class is used so that you can generically pass any
        ' form that you want to the delegate.
    
        Private WithEvents appContext As ApplicationContext
        Private Delegate Sub FormShowDelegate(ByVal form As Form)
        Event MessageLoopExit()
    
        Public Sub New(ByVal MainForm As Form)
            Dim t As Thread
            If IsNothing(appContext) Then
                appContext = New ApplicationContext(MainForm)
                t = New Thread(AddressOf StartMessageLoop)
                t.IsBackground = True
                t.SetApartmentState(ApartmentState.STA)
                t.Start()
            End If
        End Sub
    
        Private Sub StartMessageLoop()
            ' Call the Application.Run method to run the form on its own message loop.
            Application.Run(appContext)
        End Sub
    
        Public Sub ShowForm(ByVal form As Form)
    
            Dim formShow As FormShowDelegate
    
            ' Start the main form first. Otherwise, focus will stay on the 
            ' calling form.
            appContext.MainForm.Activate()
    
            ' Create a new instance of the FormShowDelegate method, and
            ' then invoke the delegate off the MainForm object.
            formShow = New FormShowDelegate(AddressOf ShowFormOnMainForm_MessageLoop)
            appContext.MainForm.Invoke(formShow, New Object() {form})
        End Sub
    
        Private Sub ShowFormOnMainForm_MessageLoop(ByVal form As Form)
            form.Show()
        End Sub
    
        Private Sub ac_ThreadExit(ByVal sender As Object, ByVal e As System.EventArgs) Handles appContext.ThreadExit
            appContext.MainForm.Dispose()
            appContext.MainForm = Nothing
            appContext.Dispose()
            appContext = Nothing
            RaiseEvent MessageLoopExit()
        End Sub
    End Class
    
  11. 프로젝트 메뉴에서 Windows Form 추가를 클릭한 다음 추가를 클릭합니다.

  12. 폼에 일부 TextBox 컨트롤과 Button 컨트롤을 추가합니다.

  13. Button1 을 두 번 클릭하여 Click 이벤트 처리기를 추가합니다.

  14. Click 이벤트 처리기에 다음 코드를 추가합니다.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MessageBox.Show("Clicked button")
    End Sub
    
  15. 솔루션을 빌드합니다.

    또한 이 단계에서는 COM interop 프로젝트를 이 컴퓨터에 등록합니다.

COM interop를 보여 주는 실행 파일을 만들려면

  1. Microsoft Visual Basic 6.0을 시작합니다.

  2. 새 표준 EXE 프로젝트를 만듭니다.

  3. 프로젝트 메뉴에서 참조를 클릭합니다.

  4. Visual Basic 2005 솔루션을 빌드할 때 생성된 COMWinform 형식 라이브러리에 참조를 추가합니다.

    -또는-

    해당 라이브러리가 목록에 없으면 찾아보기를 클릭하여 형식 라이브러리 파일(.tlb)을 직접 찾습니다.

  5. 폼에 단추를 추가합니다.

  6. 보기 메뉴에서 코드를 클릭하고 다음 코드를 폼 모듈에 추가합니다.

Option Explicit

Private Sub Command1_Click()
    Dim frm As COMWinform.COMForm
    Set frm = New COMWinform.COMForm
    frm.ShowForm1
End Sub
  1. 파일 메뉴에서 EXE 만들기를 클릭하여 프로젝트를 컴파일합니다.

  2. 컴파일된 Visual Basic 6.0 실행 파일을 실행합니다.

  3. 단추를 클릭하여 앞에서 만든 클래스 라이브러리의 Windows Form을 표시합니다.

  4. Windows Form의 TextBox 컨트롤 중 하나에 포커스를 설정한 다음 Tab 키를 눌러 컨트롤 사이를 이동합니다.

    Tab 키를 누르면 컨트롤에서 컨트롤로 포커스가 이동하고 Enter 키를 누르면 단추의 Click 이벤트가 발생합니다.

참고 항목

작업

방법: ShowDialog 메서드로 Windows Form을 표시하여 COM Interop 지원

연습: 각 Windows Form을 별개의 스레드에서 표시하여 COM Interop 지원

개념

.NET Framework 구성 요소를 COM에 노출

COM에서 사용할 어셈블리의 패키징

COM에 어셈블리 등록

Windows Forms 및 관리되지 않는 응용 프로그램 개요