2013-01-04 1 views
3

나는 WPF 프로젝트에서 다음 C# 코드가 있습니다WPF 창은 기본 소유자 창으로 모달, 그러나 아니다한다

private static void RunConfig(string owner) 
{ 
    long ownerHandle; 
    var settingsWindow = new SettingsWindow(); 
    if (long.TryParse(owner, out ownerHandle)) 
    { 
     WindowInteropHelper helper = new WindowInteropHelper(settingsWindow); 
     helper.Owner = new IntPtr(ownerHandle); 
    } 
    settingsWindow.ShowDialog(); 
} 

가 SettingsWindow가 제대로 (소유자 창으로 모달되지 않습니다 즉, 내가 할 수있는 SettingsWindow가 열려있는 동안 소유자 윈도우에 집중하고, 상호 작용하며, 심지어 닫을 수 있습니다). 내가 도대체 ​​뭘 잘못하고있는 겁니까?

컨텍스트의 경우이 코드는 화면 보호기 프로그램의 일부이며 소유자 창은 제어판 화면 보호기 선택 창 (명령 줄 매개 변수를 통해 소유자로 사용하기 위해 핸들을 전달 함)입니다. IF 문이 사실을 평가하고 핸들을 올바르게 파싱한다는 것을 알고 있습니다.

I는 user32.dll에서 SetWindowLongPtr 방법을 이용하여 시도 간단히 설명 here 사용 here에 도시되어있는 (따라서 SetWindowLong를 사용하지 않는, 64에 대해 컴파일). 이 방법은 WinForms에서 작동하지만 WPF에서는 여기서 작동하지 않습니다. Obi-Wan Kenobi, 내 유일한 희망이야.

+0

은'SettingsWindow' winforms 창입니까? 'SettingsWindow'도 WPF 인 경우'ShowDialog()'가 기본 WPF 폼에 대한 액세스를 차단해야하기 때문에 –

+0

아니요, SettingsWindow는 WPF 윈도우입니다. 내 프로그램에는 다른 창이 열리지 않고 '기본'창이 없습니다. 기본 창인 제어판 화면 보호기 선택 창은 settingsWindow의 소유자로 설정해야하는 창입니다. ShowDialog()는 내 프로그램의 UI 스레드를 차단하지만 문제는 아닙니다. settingsWindow가 필요합니다. 즉, settingsWindow가 닫힐 때까지 (즉, [모달 창] (http : //en.wikipedia.).org/wiki/Modal_window) – Jargon

+0

WindowInteropHelper를 사용하여 창 소유자를 설정할 때 소유자가 여전히 포커스를 받고 상호 작용할 수 있다고하더라도 창은 항상 소유자의 최상위에있게됩니다. 그래서 뭔가하고있는 것뿐입니다. – Jargon

답변

5

WindowInteropHelper을 사용하여 기본 창을 WPF 창 소유자로 설정하면 으로 작동하지만 전체 작업을 수행하지 않습니다. 이 방법으로 설정하면 기본 윈도우에 포커스가 있더라도 WPF 윈도우가 기본 윈도우 상단에 계속 표시됩니다. 그러나 그것이 유일한 효과입니다. WPF 윈도우는 네이티브 윈도우와의 상호 작용을 막지 않으며 WPF 윈도우를 닫거나 영향을받지 않고도 네이티브 윈도우를 닫을 수 있습니다. 원하는 동작의 나머지 부분을 얻기 위하여

, 우리는 WPF 윈도우가 종료되면 다시 활성화 다시 WPF 창에 ShowDialog를 호출하기 전에 기본 창을 사용하지 user32.dllEnableWindow 기능을 사용하고 있어야합니다.

수정 된 코드는 다음과 같다 :

private static void RunConfig(string owner) 
{ 
    long ownerHandle; 
    var settingsForm = new SettingsWindow(); 
    if (long.TryParse(owner, out ownerHandle)) 
    { 
     WindowInteropHelper helper = new WindowInteropHelper(settingsForm); 
     helper.Owner = new IntPtr(ownerHandle); 
     NativeMethods.EnableWindow(helper.Owner, false); 
     settingsForm.ShowDialog(); 
     NativeMethods.EnableWindow(helper.Owner, true); 
    } 
    else 
    { 
     settingsForm.ShowDialog(); 
    } 
} 

(주 :. 상기 코드는 일반적으로 정확하지만,이 코드가 실제로 사용되고있는 것이다 화면 보호기의 경우, 불완전에서 이 코드가 화면 보호기의 구성 창에 사용되는 경우 소유자 핸들에 전달 된 문자열은 소유자로 사용되는 제어판 창의 핸들이 아니라 오히려 컨트롤 패널 윈도우의 자식 컨트롤을 호출 할 수 있습니다.이 경우 추가 단계는 컨트롤의 부모 핸들을 얻는 것입니다. GetParent을 호출하거나 user32.dll을 호출하여이 작업을 수행 할 수 있습니다. n은 실제 핸들 우리는 소유자와 EnableWindow 통화에 사용하고 싶습니다.)

Microsoft에서 누구도 Owner 할당 및 ShowDialog 사용하는 경우이 때문에 제대로이 최대의 모든 설정, 어쩌면 WindowInteropHelper을 수정 고려해이 문제를 발견하면 모달 윈도우에 대한 적절한 완전한 동작.