2017-01-30 1 views
-2

내 문제를 설명하기 위해 대신 모든 사람에게 내 메시지를 릴레이 할 수 있도록이 대신 스크린 샷을 시도합니다. 여기 그림에서 MainWinForm이라는 메인 프로젝트와 FirstWinFormApp 및 SecondWinFormApp이라는 두 개의 Windows 프로젝트가 포함 된 솔루션 폴더가 있습니다.다른 WinForm을 MDI 컨테이너 내부에서 실행하고 Program.cs를 사용할 수 있습니까?

enter image description here

MainWinForm 프로젝트는 MDI 컨테이너가 true로 설정하는 Form1.cs 파일이 포함되어 여기

는 스크린 샷입니다. 단추 클릭 이벤트 처리기를 사용하여 FirstWinFormApp 프로젝트에서 양식 (First.cs)을 시작하려고합니다.

enter image description here

모든 것이 잘 작동해야한다. Form1의 MDI 컨테이너 안에 First.cs 폼을 시작할 수 있습니다.

여기 까다로운 부분이 있는데, MainWinForm의 Program.cs 대신 FirstWinFormApp의 Program.cs를 실행하고 싶습니다. 그 이유는 내 프로젝트 (어셈블리, 연결 등)에 대한 나의 요구 사항 때문입니다.

응용 프로그램을 시작하면 MainWinForm 프로젝트의 Program.cs가 트리거됩니다. 자식 응용 프로그램을 호출하면 Program.cs는 더 이상 호출되지 않습니다. MainWinForm 프로젝트의 Program.cs가 이미 호출 되었더라도 하위 응용 프로그램 (FirstWinFormApp)의 Program.cs를 호출 할 수 있습니까?

+0

당신이 무엇을 요구하고 있는지 분명하지 않습니다. – NineBerry

+0

나는 더 나은 이해를 위해 그것을 다시 쓰려고 노력했다. @NineBerry –

답변

3

MDI 컨테이너와 하위 창이 다른 실행 파일 (다른 프로젝트 및 모두)에 속한다고 가정합니다. 이것은 처음에는 권장하지 않지만 끝낼 수 있습니다. 기본적으로 Windows API를 망치고 Framework 관리 방식을 사용하지 않아야합니다.

SetParent API가 필요합니다. 상위 창이 MDI 컨테이너가 아니더라도 다른 창을 윈도우 내부에 넣을 수 있습니다. 하지만 부모 윈도우의 Handle 속성을 전달하는 방법이 필요하며 메서드가 불안정하거나 (양쪽 프로세스에서 액세스 할 수있는 포인터를 작성하는) 불필요하게 복잡합니다 (프로세스 간 통신이 필요합니다).

가장 쉬운 방법은 FindWindow를 사용하여 제목을 사용하여 아이의 메인 윈도우를 찾는 것입니다. 다른 프로그램이 MDI 창과 동일한 제목을 갖고 있으면이 작업은 실패합니다.

아래의 코드는 테스트되지 않은,하지만 당신은 당신의 아이 윈도우의 Program.cs의 내부에 그것을 필요 : 자녀 프로그램의 홈페이지()이이 것 당신의 경우

var hwnd = FindWindow(IntPtr.Zero, "My MDI Title"); 
SetParent(childWindow.Handle, hwnd); 

[DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 
private static extern IntPtr FindWindow(IntPtr className, string lpWindowName); 

과에 같을 것

[DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 
private static extern IntPtr FindWindow(IntPtr className, string lpWindowName); 

static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    var formObj = new First(); 

    var hwnd = FindWindow(IntPtr.Zero, "My MDI Title"); 
    SetParent(formObj.Handle, hwnd); 

    Application.Run(formObj); 
} 

MDI 형식의 제목도 "내 MDI 제목"으로 변경해야합니다. 아래의 테스트 응용 프로그램에서는 역순으로 수행하고 있습니다. - Form1에 메모장 창을 띄우고 있지만 원하는대로 할 수 있습니다.

Screenshot

+0

도움을 주셔서 감사합니다.당신의 SetParent 메서드 (SetParent (childWindow.Handle, hwnd))에 어려움을 겪고 있는데, childWindow에 무엇을 넣어야합니까? Form의 객체 인 –

+0

의 이름입니다. 편집 된 대답 – Sloth

+0

을 참조하십시오. Form1 프로젝트가 이미 자식 winform을 참조하고 있기 때문에 Form1을 참조 할 수 없기 때문에 순환 종속성이 발생합니다.이 코드를 호출하기 위해 자식 winform을 참조해야합니다 : 처음 x = new First(); x. MdiParent = this; x.Show(); –

관련 문제