1

VB.NET MDI フォーム内で notepad.exe などの外部アプリケーションを開く必要があります。また、この実行中のコピーが常に 1 つだけであることを確認する必要があります。

以下のコードを使用しましたが、まったく何もしません。SetParent が宣言されておらず、findWindow が宣言されていないというエラーが表示されます

Dim myProcess As Process = New Process()
Dim MyHandle As IntPtr
myProcess.StartInfo.FileName = "Notepad.exe"
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.Start()
MyHandle = FindWindow(vbNullString, "C:\Windows\Notepad.exe")
SetParent(MyHandle, Me.Handle)
myProcess.WaitForExit()

これは、1 つのインスタンスのみが実行されていることを確認するために使用したコードです。

If (System.Diagnostics.Process.GetProcesses.Equals("notepad.exe")) Then
        MsgBox("Only One Instance!")
    Else
        Dim p As New System.Diagnostics.Process
        p.StartInfo.FileName = "notepad.exe"
        p.Start()
    End If 

このコードは notepad.exe を開いていますが、以前のインスタンスをチェックしていません。ボタンをクリックするたびに、新しいメモ帳が開きます

4

2 に答える 2

5

SetParent と FindWindow は、使用する前に宣言する必要があるため、エラーが発生します。GetProcesses は個々のプロセスではなくコレクションを返すため、メモ帳の既存のインスタンスを見つけるのにも問題があります。試している方法を使用するには、コレクション全体をループして、一致するものが含まれているかどうかを確認するか、.Contains を使用する必要があります。この例では FindWindow を使用しませんでしたが、将来必要になる場合に備えて、その宣言を含めました。コード例では、使用するフォームのタイトルが Form1 であり、コードが Button1 でアクティブ化されていることを前提としています。

コード:

    Imports System.Runtime.InteropServices

    Public Class Form1
        <DllImport("User32", CharSet:=CharSet.Auto, ExactSpelling:=True)> Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndParent As IntPtr) As IntPtr
        End Function

        Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal  lpClassName As String, ByVal lpWindowName As String) As Integer

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim PROCHANDLE As System.IntPtr = -1
            For Each proc In Process.GetProcesses
                If LCase(proc.ProcessName) = "notepad" Then
                    PROCHANDLE = proc.Handle
                End If
            Next
            If PROCHANDLE = -1 Then
                PROCHANDLE = Process.Start("C:\windows\notepad.exe").Handle
                SetParent(PROCHANDLE, Me.Handle)
            End If
        End Sub
     End Class
于 2012-05-31T14:50:51.410 に答える
0

これは非常にうまく機能します。試してみました。新しい Windows フォーム プロジェクトを作成し、このコードを form1 の既定のコードの代わりに貼り付けるだけで十分です。

Public Class Form1 Dim myProcess As Process = New Process() Public WithEvents thb As Button = New System.Windows.Forms.Button Public Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As System.IntPtr Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles thb.Click myProcess.Start() myProcess.WaitForInputIdle() SetParent(myProcess.MainWindowHandle, Me.Handle) thb.Text = "Open Notepad Again" End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load WindowState = FormWindowState.Maximized MaximizeBox = False ShowIcon = False Text = "Notepad Opener" thb.Location = New System.Drawing.Point(20, 20) thb.Name = "thb" thb.Size = New System.Drawing.Size(200, 23) thb.TabIndex = 1 thb.Text = "Open Notepad" thb.UseVisualStyleBackColor = True Controls.Add(Me.thb) IsMdiContainer = True myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal myProcess.StartInfo.FileName = "notepad.exe" End Sub End Class

于 2016-10-16T21:44:07.660 に答える