2008-12-13 17 views
10

मैं कुछ समय के लिए Rainlendar का उपयोग कर रहा हूं और मैंने देखा कि खिड़की को "डेस्कटॉप पर" रखने का विकल्प है। यह नीचे की तरह है सबसे खिड़की (शीर्ष के खिलाफ के रूप में)।विंडो "डेस्कटॉप पर"

मैं इसे WPF ऐप पर कैसे कर सकता हूं?

धन्यवाद

उत्तर

14

मेरा जवाब Win32 एपीआई के मामले में, WPF के लिए विशिष्ट नहीं है (और शायद पी की आवश्यकता होती है/सी # से आह्वान):

Rainlendar दो विकल्प हैं:

  • " डेस्कटॉप पर ", यह एक्सप्लोरर डेस्कटॉप विंडो (" प्रोग्राम मैनेजर ") का बच्चा बन जाता है। आप इसे SetParent एपीआई के साथ प्राप्त कर सकते हैं।
  • "नीचे पर" आप जो वर्णन करते हैं - इसकी खिड़कियां ज़ेड-ऑर्डर के नीचे रहती हैं, बस डेस्कटॉप के सामने। उन्हें शुरू करने के लिए उन्हें वहां रखना आसान है (SetWindowPos देखें) - चाल क्लिक करने पर उन्हें सामने आने से रोकना है। मैं WM_WINDOWPOSCHANGING संदेश को संभालने का सुझाव दूंगा।
+0

धन्यवाद ह्यूग, मैं हिस्सा काम कर रहे "तल पर", SetParant साथ अब कोशिश करने के लिए जा रहा है। मूल रूप से "डेस्कटॉप पर" दाएं को कम किए बिना "नीचे" है? –

+0

मुझे यकीन नहीं है कि आप "बिना न्यूनतम किए" के साथ क्या प्राप्त कर रहे हैं, लेकिन यदि आप खिड़की के पेड़ की जांच करने के लिए एमएस जासूस ++ का उपयोग करते हैं (रेनलेडर चलने के साथ) तो आप उम्मीद करेंगे कि मेरा क्या मतलब है। –

7

यह है कि मैं क्या "तल पर" का इस्तेमाल किया तो खिड़की हमेशा है:

using System; 
    using System.Runtime.InteropServices; 
    using System.Windows; 
    using System.Windows.Interop; 

...

[DllImport("user32.dll")] 
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, 
    int Y, int cx, int cy, uint uFlags); 

const UInt32 SWP_NOSIZE = 0x0001; 
const UInt32 SWP_NOMOVE = 0x0002; 
const UInt32 SWP_NOACTIVATE = 0x0010; 

static readonly IntPtr HWND_BOTTOM = new IntPtr(1); 

public static void SetBottom(Window window) 
{ 
    IntPtr hWnd = new WindowInteropHelper(window).Handle; 
    SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 
} 
+0

यह विंडोज 10 –

3

OnDesktop संस्करण का उपयोग कर इम:

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

public static void SetOnDesktop(Window window) 
{ 
    IntPtr hWnd = new WindowInteropHelper(window).Handle;   
    IntPtr hWndProgMan = FindWindow("Progman", "Program Manager"); 
    SetParent(hWnd, hWndProgMan); 
} 

मुझे प्रोग्राम प्रबंधक विंडो खोजने में कुछ परेशानी हो रही थी, लेकिन किममो, सी Rainlendar से reator मुझे कोड के लिए एक लिंक दिया:

http://www.ipi.fi/~rainy/legacy.html

किसी की जरूरत है और अधिक विस्तार सिर्फ समारोह SetWindowZPos के लिए पुस्तकालय/rainwindow.cpp में लग रहे हो।

6

चेतावनी स्वीकृत उत्तर से पता चलता है कि आप डेस्कटॉप के बच्चे को बनाने के लिए SetParent को कॉल करते हैं। यदि आप ऐसा करते हैं, तो आप Win32 विंडो मैनेजर को डेस्कटॉप की इनपुट कतार को अपने बच्चे की विंडो में सिंक्रनाइज़ करने का कारण बनते हैं, यह खराब चीज - Raymond Chen explains why. असल में, यदि आपकी विंडो लटकती है या ब्लॉक करती है (संदेशबॉक्स के साथ कहें) तो आप लॉक करेंगे अपने डेस्कटॉप को ऊपर उठाओ।

+0

पर काम नहीं करता है। "डेस्कटॉप" जो मैं संदर्भित करता हूं वह GetDesktopWindow() द्वारा लौटाई गई रूट विंडो नहीं है। 2. भले ही आप SetParent (myWindow, GetDesktopWindow()) को कॉल करें, इससे कोई समस्या नहीं आएगी - यह आपकी विंडो को "शीर्ष स्तर" विंडो बना देगा, अगर यह पहले से नहीं था। मुझे लगता है कि आपको फिर से रेमंड चेन लेख पढ़ना चाहिए। –

+0

ह्यूग, क्या आपने वास्तव में यह कोशिश की - इसे पुन: उत्पन्न करना आसान है। 1. माता-पिता के रूप में "प्रोग्राम प्रबंधक" के साथ सेटपैरेंट को कॉल करें। 2. अपने बच्चे की खिड़की को लटकाएं (नींद करें, जो कुछ भी हो) 3. ध्यान दें कि डेस्कटॉप अब लटका हुआ है, आप इसके साथ बातचीत नहीं कर सकते (शॉर्टकट इत्यादि)। –

+0

ठीक है अगर आप प्रोगोगन के बच्चे को लटकाते हैं तो आप प्रोगोगन को लटकाते हैं, लेकिन एक संदेशबॉक्स दिखाकर यह नहीं करता है, और यह वही है जो आप वैसे भी ठीक कर सकते हैं (प्रक्रिया को मार दें)। आपने इस आलेख को लिंक करके इस मुद्दे को भ्रमित कर दिया है जो कुछ अलग वर्णन करता है (रूट विंडो को अक्षम करके पूरी मशीन को लटकाना)। –

3

मैं ऐसा करने की कोशिश कर रहा था ... मैंने बहुत सारे विचारों का उपयोग किया है, लेकिन मैं इसे करने में सक्षम था और झटके को रोकने में सक्षम था।

मैं WndProc ओवरराइड करने में कामयाब रहे, एक setwindowpos से पहले इस्तेमाल पृष्ठभूमि में यह डाल करने के लिए, और एक अन्य फोकस हो रहा से इसे रोकने के लिए ...

const UInt32 SWP_NOSIZE = 0x0001; 
    const UInt32 SWP_NOMOVE = 0x0002; 
    const UInt32 SWP_NOACTIVATE = 0x0010; 
    const UInt32 SWP_NOZORDER = 0x0004; 
    const int WM_ACTIVATEAPP = 0x001C; 
    const int WM_ACTIVATE = 0x0006; 
    const int WM_SETFOCUS = 0x0007; 
    static readonly IntPtr HWND_BOTTOM = new IntPtr(1); 
    const int WM_WINDOWPOSCHANGING = 0x0046; 

    [DllImport("user32.dll")] 
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, 
     int Y, int cx, int cy, uint uFlags); 
    [DllImport("user32.dll")] 
    static extern IntPtr DeferWindowPos(IntPtr hWinPosInfo, IntPtr hWnd, 
     IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); 
    [DllImport("user32.dll")] 
    static extern IntPtr BeginDeferWindowPos(int nNumWindows); 
    [DllImport("user32.dll")] 
    static extern bool EndDeferWindowPos(IntPtr hWinPosInfo); 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     IntPtr hWnd = new WindowInteropHelper(this).Handle; 
     SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 

     IntPtr windowHandle = (new WindowInteropHelper(this)).Handle; 
     HwndSource src = HwndSource.FromHwnd(windowHandle); 
     src.AddHook(new HwndSourceHook(WndProc)); 
    } 

    private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_SETFOCUS) 
     { 
      IntPtr hWnd = new WindowInteropHelper(this).Handle; 
      SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 
      handled = true; 
     } 
     return IntPtr.Zero; 
    } 

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     IntPtr windowHandle = (new WindowInteropHelper(this)).Handle; 
     HwndSource src = HwndSource.FromHwnd(windowHandle); 
     src.RemoveHook(new HwndSourceHook(this.WndProc)); 
    } 
0

@ HrejWaltz के जवाब के साथ संलग्न संपत्ति संस्करण:

अद्यतन (12/28/2016)

public class WindowSinker 
{ 
    #region Properties 

    const UInt32 SWP_NOSIZE = 0x0001; 
    const UInt32 SWP_NOMOVE = 0x0002; 
    const UInt32 SWP_NOACTIVATE = 0x0010; 
    const UInt32 SWP_NOZORDER = 0x0004; 
    const int WM_ACTIVATEAPP = 0x001C; 
    const int WM_ACTIVATE = 0x0006; 
    const int WM_SETFOCUS = 0x0007; 
    const int WM_WINDOWPOSCHANGING = 0x0046; 

    static readonly IntPtr HWND_BOTTOM = new IntPtr(1); 

    Window Window = null; 

    #endregion 

    #region WindowSinker 

    public WindowSinker(Window Window) 
    { 
     this.Window = Window; 
    } 

    #endregion 

    #region Methods 

    [DllImport("user32.dll")] 
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); 

    [DllImport("user32.dll")] 
    static extern IntPtr DeferWindowPos(IntPtr hWinPosInfo, IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); 

    [DllImport("user32.dll")] 
    static extern IntPtr BeginDeferWindowPos(int nNumWindows); 

    [DllImport("user32.dll")] 
    static extern bool EndDeferWindowPos(IntPtr hWinPosInfo); 

    void OnClosing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     var Handle = (new WindowInteropHelper(Window)).Handle; 

     var Source = HwndSource.FromHwnd(Handle); 
     Source.RemoveHook(new HwndSourceHook(WndProc)); 
    } 

    void OnLoaded(object sender, RoutedEventArgs e) 
    { 
     var Hwnd = new WindowInteropHelper(Window).Handle; 
     SetWindowPos(Hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 

     var Handle = (new WindowInteropHelper(Window)).Handle; 

     var Source = HwndSource.FromHwnd(Handle); 
     Source.AddHook(new HwndSourceHook(WndProc)); 
    } 

    IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_SETFOCUS) 
     { 
      hWnd = new WindowInteropHelper(Window).Handle; 
      SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 
      handled = true; 
     } 
     return IntPtr.Zero; 
    } 

    public void Sink() 
    { 
     Window.Loaded += OnLoaded; 
     Window.Closing += OnClosing; 
    } 

    public void Unsink() 
    { 
     Window.Loaded -= OnLoaded; 
     Window.Closing -= OnClosing; 
    } 

    #endregion 
} 

public static class WindowExtensions 
{ 
    #region Always On Bottom 

    public static readonly DependencyProperty SinkerProperty = DependencyProperty.RegisterAttached("Sinker", typeof(WindowSinker), typeof(WindowExtensions), new UIPropertyMetadata(null)); 
    public static WindowSinker GetSinker(DependencyObject obj) 
    { 
     return (WindowSinker)obj.GetValue(SinkerProperty); 
    } 
    public static void SetSinker(DependencyObject obj, WindowSinker value) 
    { 
     obj.SetValue(SinkerProperty, value); 
    } 

    public static readonly DependencyProperty AlwaysOnBottomProperty = DependencyProperty.RegisterAttached("AlwaysOnBottom", typeof(bool), typeof(WindowExtensions), new UIPropertyMetadata(false, OnAlwaysOnBottomChanged)); 
    public static bool GetAlwaysOnBottom(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(AlwaysOnBottomProperty); 
    } 
    public static void SetAlwaysOnBottom(DependencyObject obj, bool value) 
    { 
     obj.SetValue(AlwaysOnBottomProperty, value); 
    } 
    static void OnAlwaysOnBottomChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var Window = sender as Window; 
     if (Window != null) 
     { 
      if ((bool)e.NewValue) 
      { 
       var Sinker = new WindowSinker(Window); 
       Sinker.Sink(); 
       SetSinker(Window, Sinker); 
      } 
      else 
      { 
       var Sinker = GetSinker(Window); 
       Sinker.Unsink(); 
       SetSinker(Window, null); 
      } 
     } 
    } 

    #endregion 
} 
संबंधित मुद्दे