2012-05-03 15 views
6

क्या यह निर्धारित करने का कोई तरीका है कि किसी भी डेस्कटॉप के कनेक्टेड मॉनीटर में एक खुली WPF विंडो वर्तमान में दिखाई दे रही है या नहीं? दृश्यमान से मेरा मतलब है कि खिड़की की सीमा आयताकार किसी भी मॉनीटर के डेस्कटॉप आयताकार के साथ छेड़छाड़ करता है।यह निर्धारित करें कि किसी भी मॉनीटर पर एक खुली WPF विंडो दिखाई दे रही है

मुझे यह निर्धारित करने के लिए इस कार्यक्षमता की आवश्यकता है कि एक विंडो को पुनर्स्थापित करने की आवश्यकता है क्योंकि मॉनीटर कॉन्फ़िगरेशन (कार्यक्षेत्रों की सीमाएं, मॉनीटर गिनती) मेरे एप्लिकेशन के पुनरारंभ (जो विंडो की स्थिति बचाती है) के बीच बदल जाती है।

मैं नीचे दिए गए कोड के साथ आए हैं और यह काम करने लगता है, लेकिन यह कई समस्याएं हैं:

  1. मैं खिड़कियों रूपों को संदर्भित करने की जरूरत है।
  2. मुझे डेस्कटॉप की डीपीआई सेटिंग्स की आवश्यकता है और विंडोज़ को वास्तविक पिक्सल को WPF आभासी पिक्सेल में बदलना है।
  3. मुझे एक अचूक दृश्य उदाहरण की आवश्यकता है जो पहले से ही रूपांतरण करने के लिए प्रस्तुत किया गया है।

क्या आप ऐसे समाधान के बारे में जानते हैं जो उपरोक्त तीन या सभी मुद्दों से छुटकारा पाता है? (प्रारंभ) Desktop वर्ग के

using System.Collections.Generic; 
using System.Linq; 
using System.Windows; 
using System.Windows.Forms; 
using System.Windows.Media; 

internal static class Desktop 
{ 
    private static Size dpiFactor = new Size(1.0, 1.0); 
    private static bool isInitialized; 

    public static IEnumerable<Rect> WorkingAreas 
    { 
     get 
     { 
      return 
       Screen.AllScreens.Select(
        screen => 
        new Rect(
         screen.WorkingArea.Left * dpiFactor.Width, 
         screen.WorkingArea.Top * dpiFactor.Height, 
         screen.WorkingArea.Width * dpiFactor.Width, 
         screen.WorkingArea.Height * dpiFactor.Height)); 
     } 
    } 

    public static void TryInitialize(Visual visual) 
    { 
     if (isInitialized) 
     { 
      return; 
     } 

     var ps = PresentationSource.FromVisual(visual); 
     if (ps == null) 
     { 
      return; 
     } 

     var ct = ps.CompositionTarget; 
     if (ct == null) 
     { 
      return; 
     } 

     var m = ct.TransformToDevice; 
     dpiFactor = new Size(m.M11, m.M22); 
     isInitialized = true; 
    } 
} 

उपयोग:

private bool IsLocationValid(Rect windowRectangle) 
    { 
     foreach (var workingArea in Desktop.WorkingAreas) 
     { 
      var intersection = Rect.Intersect(windowRectangle, workingArea); 
      var minVisible = new Size(10.0, 10.0); 
      if (intersection.Width >= minVisible.Width && 
       intersection.Height >= minVisible.Height) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 

अद्यतन

आभासी स्क्रीन (SystemParameters.VirtualScreen*) का उपयोग करना, क्योंकि जब "डेस्कटॉप एकाधिक मॉनिटर का उपयोग कर काम नहीं करता है "एक साधारण आयताकार नहीं है। यह बहुभुज हो सकता है। वहाँ आभासी स्क्रीन क्योंकि

  1. जुड़ा स्क्रीन आप प्रत्येक स्क्रीन की स्थिति को कॉन्फ़िगर कर सकते हैं विभिन्न प्रस्तावों
  2. हो सकता है में ब्लाइंड स्पॉट किया जाएगा।
+0

http: // stackoverflow।कॉम/प्रश्न/2465646/कैसे-करें-i-know-what-monitor-a-wpf-window-is- – Flot2011

+0

में हालांकि, उस लिंक का प्रश्न बहुत समान है, यह मेरे प्रश्न का उत्तर नहीं देता है। मैंने पहले से ही एक समाधान का प्रस्ताव दिया है और मैं उल्लेख किए गए तीन मुद्दों से छुटकारा पाने का तरीका ढूंढना चाहता हूं। – bitbonk

+0

फिर डब्ल्यूपीएफ और मानक सी # पुस्तकालय आपकी मदद नहीं कर सकते हैं। आप PInvoke आज़मा सकते हैं, लेकिन यह शायद अधिक गंदा है। इस प्रश्न को इसके बारे में और जानने के लिए देखें: http://stackoverflow.com/questions/1927540/how-to-get-the-size-of-the-current-screen-in-wpf – AkselK

उत्तर

7

कोड जो हम कुछ उपयोग करने के लिए उपयोग करते हैं SystemParameters, विशेष रूप से SystemParameter.VirtualScreenLeft, शीर्ष, चौड़ाई और ऊंचाई में।

अगर हमें पता लगता खिड़की इस तरह सीमा से बाहर है हम तो एक बचाया स्थान और आकार है:

bool outOfBounds = 
    (location.X <= SystemParameters.VirtualScreenLeft - size.Width) || 
    (location.Y <= SystemParameters.VirtualScreenTop - size.Height) || 
    (SystemParameters.VirtualScreenLeft + 
     SystemParameters.VirtualScreenWidth <= location.X) || 
    (SystemParameters.VirtualScreenTop + 
     SystemParameters.VirtualScreenHeight <= location.Y); 
+2

वर्चुअल स्क्रीन का उपयोग करना काम नहीं करता है क्योंकि एकाधिक मॉनीटर का उपयोग करते समय "डेस्कटॉप" एक साधारण आयत नहीं है। वर्चुअल स्क्रीन में अंधेरे धब्बे होंगे क्योंकि ए) कनेक्टेड स्क्रीन में विभिन्न संकल्प हो सकते हैं और बी) आप प्रत्येक स्क्रीन की स्थिति को कॉन्फ़िगर कर सकते हैं। – bitbonk

0

इस कोड को जांच करता है कि एक खिड़की शीर्ष कोने छोड़ दिया आभासी स्क्रीन बॉक्स के अंदर (आयत है जिसमें सभी उपलब्ध स्क्रीन शामिल हैं)। यह मल्टीमोनिटर सेट अप का भी ख्याल रखता है जहां निर्देशांक नकारात्मक हो सकते हैं, उदाहरण के लिए दाएं या नीचे प्राथमिक मॉनिटर।

bool valid_position = 
SystemParameters.VirtualScreenLeft <= saved_location.X && 
(SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth) >= saved_location.X && 
SystemParameters.VirtualScreenTop <= saved_location.Y && 
(SystemParameters.VirtualScreenTop + SystemParameters.VirtualScreenHeight) >= saved_location.Y; 
+2

वर्चुअल स्क्रीन का उपयोग करना काम नहीं करता है क्योंकि एकाधिक मॉनीटर का उपयोग करते समय "डेस्कटॉप" एक साधारण आयत नहीं है। वर्चुअल स्क्रीन में अंधेरे धब्बे होंगे क्योंकि ए) कनेक्टेड स्क्रीन में विभिन्न संकल्प हो सकते हैं और बी) आप प्रत्येक स्क्रीन की स्थिति को कॉन्फ़िगर कर सकते हैं। – bitbonk

0

मैं इस कोड का उपयोग स्टार्टअप पर अपने डब्ल्यूपीएफ प्रोजेक्ट में फिसल गया; यह vb.net में लिखा है:

If My.Settings.RememberWindowPositionAndSize Then 
    If My.Settings.winMainWinState > 2 Then My.Settings.winMainWinState = WindowState.Normal 
    If My.Settings.winMainWinState = WindowState.Minimized Then My.Settings.winMainWinState = WindowState.Normal 
    Me.WindowState = My.Settings.winMainWinState 
    If My.Settings.winMainWinState = WindowState.Normal Then 
     Dim winBounds As New System.Drawing.Rectangle(CInt(My.Settings.winMainPosX), CInt(My.Settings.winMainPosY), 
                 CInt(My.Settings.winMainSizeB), CInt(My.Settings.winMainSizeH)) 
     For Each scr As System.Windows.Forms.Screen In System.Windows.Forms.Screen.AllScreens 
      If winBounds.IntersectsWith(scr.Bounds) Then 
       Me.Width = My.Settings.winMainSizeB 
       Me.Height = My.Settings.winMainSizeH 
       Me.Top = My.Settings.winMainPosY 
       Me.Left = My.Settings.winMainPosX 
       Exit For 
      End If 
     Next 
    End If 
End If 

और यहाँ एक ही (परिवर्तित) सी # में कोड है

if (My.Settings.RememberWindowPositionAndSize) { 
    if (My.Settings.winMainWinState > 2) 
     My.Settings.winMainWinState = WindowState.Normal; 
    if (My.Settings.winMainWinState == WindowState.Minimized) 
     My.Settings.winMainWinState = WindowState.Normal; 
    this.WindowState = My.Settings.winMainWinState; 

    if (My.Settings.winMainWinState == WindowState.Normal) { 
     System.Drawing.Rectangle winBounds = new System.Drawing.Rectangle(Convert.ToInt32(My.Settings.winMainPosX), Convert.ToInt32(My.Settings.winMainPosY), Convert.ToInt32(My.Settings.winMainSizeB), Convert.ToInt32(My.Settings.winMainSizeH)); 

     foreach (System.Windows.Forms.Screen scr in System.Windows.Forms.Screen.AllScreens) { 
      if (winBounds.IntersectsWith(scr.Bounds)) { 
       this.Width = My.Settings.winMainSizeB; 
       this.Height = My.Settings.winMainSizeH; 
       this.Top = My.Settings.winMainPosY; 
       this.Left = My.Settings.winMainPosX; 
       break; 
      } 
     } 
    } 
} 
संबंधित मुद्दे

 संबंधित मुद्दे