2008-10-17 3 views
6

내 응용 프로그램은 VB6 실행 파일이지만 시스템의 일부 최신 양식은 C#으로 작성되었습니다. C# 양식의 소유자 속성을 주 응용 프로그램 창 핸들을 사용하여 설정하여 대화 상자가 내 응용 프로그램과 다른 응용 프로그램 사이를왔다 갔다 할 때 맨 위에 놓 이도록하고 싶습니다.hwnd/NativeWindow를 사용하여 WinForms 양식의 소유자를 설정하는 동작을 가져올 수 있습니까?

주 응용 프로그램 창의 hwnd를 가져올 수 있습니다. 내가 여기서 무엇을 할 수 있는지 잘 모르겠다.


UPDATE 17시 6분에서 10월 20일 '08 :

스콧, 응답에 대한

감사합니다. Show/ShowDialog 메서드 매개 변수가 Form 형식이 아니라는 점을 간과했습니다. Owner 속성에서만 찾고있었습니다.

위 코드에서 약간 수정했습니다. 우리는 일반적으로 Forms를로드하고 ShowDialog를 호출하는 구성 요소를 가지고 있습니다. 내 코드는 다음과 같습니다

private IWin32Window GetWindowFromHost(int hwnd) 
{ 
    IWin32Window window = null; 
    IntPtr handle = new IntPtr(hwnd); 

    try 
    { 
     NativeWindow nativeWindow = new NativeWindow(); 
     nativeWindow.AssignHandle(handle); 
     window = nativeWindow; 
    } 
    finally 
    { 
     handle = IntPtr.Zero; 
    } 

    return window; 
} 

불행하게도 이것은 내가 기대했던 일을하지 않습니다 :

Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form loader 
launchTarget.StartPosition = FormStartPosition.CenterParent; 
IWin32Window parentWindow = GetWindowFromHwnd(hwnd); 

launchTarget.ShowDialog(parentWindow); 

GetWindowFromHwnd는 코드의 방법 포장 된 버전입니다. 양식은 모달로 표시되지만 올바른 위치에 표시되지 않으며 탭을 비운 후 부모 창으로 돌아 가면 여전히 위에 위치하지 않습니다. 모달은 작업 표시 줄에 작업을 표시하지 않으므로 Alt 키를 누른 상태에서도 Alt 키를 누르면 사라집니다. 저에게 저것은 나가 적당한 hwnd가 있지 않을지도 모르다는 것을 나타낸다. 다른 제안 사항이 있으면 회신 해주십시오. 다시 한번 감사드립니다.


16시 25분

한 후속 발언에서 UPDATE 11월 10일 '08 - 당신은 시도/마침내, 스콧의 두번째 게시물로 통화에 메서드 호출로를 고려하는 경우 finally 블록에 있어야합니다 :

그래서 당신은 당신은 아마 중 하나 Show() 또는 ShowDialog()을 사용하는 것을 의미 VB6에서 C# 윈도우 폼 클래스를 호출하는
parentWindow.ReleaseHandle(); 
+0

Scott - 오랜 시간 지연되어 미안하지만, 다른 것들에 끌려갔습니다. 원래 제출 한 답변이 효과적입니다. Form.Owner를 설정하는 대신 ShowDialog를 통해 NativeWindow를 전달해야했습니다. 내 다른 문제는 첫 번째 장소에서 올바른 hWnd를 전달하지 않는 호출 코드입니다. 감사합니다 – mcw0933

+0

FYI, 위의 두 문제 모두 해결할 수 있습니다 - centeredness 설정해야합니다 : "form.StartPosition = FormStartPosition.CenterParent"- toppyness 설정 : form.TopMost = true; - btw, ReleaseHandle()에 대한 정보 주셔서 감사합니다! :-) – BrainSlugs83

답변

9

, 맞습니까? 이러한 메서드는 모두 Handle이라는 IntPtr 속성을 반환하는 개체를 정의하는 IWin32Window 매개 변수도 가져옵니다.

그래서 ... 폼에 VB6 hwnd를 전달할 수 있도록 long을 매개 변수로 사용하는 Windows Forms 클래스에 대한 오버로드 된 생성자 (또는 ShowDialog 메서드)를 추가해야합니다. 일단 C# 코드 안에 hwnd에서 IntPtr을 만들고 NativeWindow 개체에 할당 한 다음 소유자로 전달해야합니다. 이 해야 일 같은

뭔가가 검증되지 않은 비록 :

public DialogResult ShowDialog(long hwnd) 
{ 
    IntPtr handle = new IntPtr(hwnd); 
    try 
    { 
     NativeWindow nativeWindow = new NativeWindow(); 

     nativeWindow.AssignHandle(handle); 
     return this.ShowDialog(nativeWindow); 
    } 
    finally 
    { 
     handle = IntPtr.Zero; 
    } 
} 
2

이 주석으로 게시 너무 길어서 ...

나는 당신이로 실행하는 문제가 생각 방법은 ShowDialog 과부하에서 제시 한 코드를 래핑했습니다.GetWindowFromHost 코드를 따르는 경우 다음 단계를 수행합니다.

  1. 주어진 hwnd에서 새 IntPtr을 만듭니다.
  2. 새 NativeWindow 객체를 만들고 그 핸들을 IntPtr로 지정합니다.
  3. IntPtr (finally 블록에 있음)을 IntPtr.Zero로 설정합니다.

나는 이것이 결국 당신에게 문제를 일으키는 블록이라고 생각합니다. 내 코드에서 finally 블록은 this.ShowDialog(nativeWindow) 호출이 완료된 후에 실행됩니다. 이 시점에서 핸들 (IntPtr)은 더 이상 사용되지 않습니다. 귀하의 코드에서 IWin32Window은 여전히 ​​그 IntPtr에 대한 참조를 보유하고 있습니다. launchTarget.ShowDialog(parentWindow)은 IntPtr.Zero입니다. 다음과 같이 귀하의 코드를 변경

시도 :

private NativeWindow GetWindowFromHost(int hwnd) 
{ 
    IntPtr handle = new IntPtr(hwnd); 
    NativeWindow nativeWindow = new NativeWindow(); 
    nativeWindow.AssignHandle(handle); 
    return window; 
} 

그리고는 다음과 같이 당신의 호출 코드를 변경 :

Form launchTarget = FormFactory.GetForm(xxx); // psuedo-code for generic form 
loaderlaunchTarget.StartPosition = FormStartPosition.CenterParent; 
NativeWindow parentWindow = GetWindowFromHwnd(hwnd); 

try 
{ 
    launchTarget.ShowDialog(parentWindow); 
} 
finally 
{ 
    parentWindow.DestroyHandle(); 
} 

이러한 변화는 작동해야하지만 다시는 검증되지 않은 것입니다.