2012-09-22 4 views
2

interop를 통해 C# 형식을 표시하는 VB6 응용 프로그램과 관련이 있습니다.대화 상자가 보이면 양식이 사라집니다.

C# 형식의 이벤트로 인해 VB6 응용 프로그램 양식 중 하나가 표시됩니다.

일반적으로이 VB6 양식을 숨길 경우 (Form.Hide) 기본 C# 양식이 앞으로 가져옵니다.

그러나 평생 동안 VB6 양식이 MsgBox을 표시하면 VB6 양식을 숨길 때 기본 C# 양식이 맨 앞에 표시되지 않습니다.

왜 이런 일이 발생합니까? MsgBox이 양식의 Z- 주문을 변경하는 것과 같습니다.

답변

1

"VB6이 숨겨진 후에 C# 형식을 어떻게 표시합니까? 창 핸들을 사용해야합니까?"

고아가 된 msgbox가 열린 상태로 유지되는 것으로 가정하면

public static int FindWindow(string windowName, bool wait) 
{ 
    int hWnd = FindWindow(null, windowName); 
    while (wait && hWnd == 0) 
    { 
     System.Threading.Thread.Sleep(500); 
     hWnd = FindWindow(null, windowName); 
    } 

    return hWnd; 
} 

는 다음 상단에 C#을 창을 가지고 :

[DllImport("user32.dll", SetLastError = true)] 
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

// When you don't want the ProcessId, use this overload and pass IntPtr.Zero for the second parameter 
[DllImport("user32.dll")] 
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); 

[DllImport("kernel32.dll")] 
public static extern uint GetCurrentThreadId(); 

/// <summary>The GetForegroundWindow function returns a handle to the foreground window.</summary> 
[DllImport("user32.dll")] 
public static extern IntPtr GetForegroundWindow(); 

[DllImport("user32.dll")] 
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); 

[DllImport("user32.dll", SetLastError = true)] 
public static extern bool BringWindowToTop(IntPtr hWnd); 

[DllImport("user32.dll", SetLastError = true)] 
public static extern bool BringWindowToTop(HandleRef hWnd); 

[DllImport("user32.dll")] 
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow); 

private static void ForceForegroundWindow(IntPtr hWnd) 
{ 
    uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero); 
    uint appThread = GetCurrentThreadId(); 
    const uint SW_SHOW = 5; 

    if (foreThread != appThread) 
    { 
     AttachThreadInput(foreThread, appThread, true); 
     BringWindowToTop(hWnd); 
     ShowWindow(hWnd, SW_SHOW); 
     AttachThreadInput(foreThread, appThread, false); 
    } 
    else 
    { 
     BringWindowToTop(hWnd); 
     ShowWindow(hWnd, SW_SHOW); 
    } 
} 

참조 : SetForegroundWindow Win32-API not always works on Windows-7

+0

'NativeWindow'클래스는 아래쪽에 있습니다. http://social.msdn.microsoft.com/Forums/lt/vbinterop/thread/2692df26-317c-4415-816b-d08fe6854df8 – CJ7

+0

+1 윈도우 개발자 인 Raymond Chen은이 상황에서이'AttachThreadInput' 해결 방법은 [프로그램이 응답을 멈추게 할 수 있습니다] (http://stackoverflow.com/a/8081858/15639)라고 지적합니다. 그러나 나는이 벌레들을 직접 만나 본 적이 없다. YMMV. – MarkJ

+0

@ MarkJ : 위의 내 의견에서 취한 접근은 어떻습니까? – CJ7

1

내가 가진 VB6 양식이 숨겨진 경우에는 창 핸들을 얻기 위해 이벤트를 발생합니다 이 스레드의 마지막 답변 다음에 NativeWindow 클래스를 사용하여 작업 할 수 있습니다. http://social.msdn.microsoft.com/Forums/en-US/2692df26-317c-4415-816b-d08fe6854df8/vbnet-vb6-win32-api-problems?forum=vbinterop

해당 코드는를 사용합니다.

public void ShowDotNetForm(IntPtr hwndMain) 
{ 
    NativeWindow vb6Window = new NativeWindow(); 
    vb6Window.AssignHandle(hwndMain); 
    f.Show(vb6Window); 
} 

VB6 형태의 코드는 다음과 같습니다 :

dotNetObj.ShowDotNetForm Me.hWnd 
당신은 단순히 .NET 형태로 VB6 윈도우의 핸들을 전달 할 수 있기 때문에은 불필요한입니다 VB6 윈도우의 핸들을 얻을 수 있습니다

FindWindowEx 핸들을 얻으려면 창 제목의 텍스트를 알아야하므로 창 핸들을 VB6으로 전달하는 것이 좋습니다.

관련 문제