2010-10-17 13 views
7

में स्क्रीन लॉक हो गया है मैं एक ऐप्लिकेशन है जो समय पर toaster messages के रूप में उपयोगकर्ता के लिए सूचना भेज देगा लिख ​​रहा हूँ।का पता लगा रहा है, तो स्क्रीनसेवर सक्रिय होता है और/या उपयोगकर्ता विंडोज

उपयोगकर्ता वहाँ नहीं है, तो वह अधिसूचना नहीं देख सकता। तो मैं क्या करना चाहता हूं यह जांचने में सक्षम है कि उपयोगकर्ता ने स्क्रीन लॉक कर दी है या यदि स्क्रीनसेवर सक्रिय हो जाता है।

कि जब तक उपयोगकर्ता नहीं देख सकते हैं यह देरी और दिखाया जाएगा जब उपयोगकर्ता में वापस लॉग करता है और उनके सत्र शुरू शुरू हो रहा है किसी भी अधिसूचना।

मैं विंडोज 7 पर स्वयं हूं, लेकिन मैं एक समाधान पसंद करूंगा जो विंडोज एक्सपी और ऊपर के लिए सार्वभौमिक रूप से काम करता है।

+0

आपने एक अमान्य लिंक –

+0

आह पोस्ट किया है, उन्होंने हॉटलिंकिंग अक्षम कर दी है। क्या यह काम करता है? http://images.google.com/imgres?imgurl=http://blog.fatbusinessman.com/blog-post-images/msn-pics-in-popups.png&imgrefurl=http://blog.fatbusinessman.com/ अभिलेखागार/2005/04/07/एमएसएन-दूत-7-समीक्षा/& USG = __ Ed4o5d78BK01ZJ3K6penXkWgsJc = & ज = 287 और w = 341 और SZ = 21 & hl = hi & 0 = और ज़ूम = 1 & tbnid = _fUzeg729w42dM शुरू: और tbnh = 157 और tbnw = 187 और पिछला =/छवियों% 3Fq% 3Dmsn% 2Bmessenger % 2Btoaster% 26hl% 3Den% 26biw% 3D1600% 26bih% 3D775% 26tbs% 3Disch: 1 और ITBS = 1 & IACT = आर सी और dur = 529 और Ei = jQS7TJnID9ug4QasnODRDQ और OEI = jQS7TJnID9ug4QasnODRDQ और ESQ = 1 & पेज = 1 & ndsp = 33 & वेद = 1T: 429, आर: 11, एस: 0 और tx = 146 और Ty = 89 – Pieter

उत्तर

22

जानने के लिए कि कार्य केंद्र वर्तमान में लॉक है कोई प्रलेखित तरीका नहीं है। हालांकि, जब यह अन/लॉक हो तो आपको अधिसूचना मिल सकती है। SystemEvents.SessionSwitch घटना सदस्यता लें, तो आप SessionSwitchReason.SessionLock हो और अनलॉक कर देंगे।

sceen सेवर भी परेशानी है। स्क्रीन सेवर चालू होने पर आपकी मुख्य विंडो WM_SYSCOMMAND संदेश प्राप्त होती है, SC_SCREENSAVE। यह जांचने के लिए कि क्या यह चल रहा है, आप SystemParametersInfo को पिनवोक कर सकते हैं। आपको this thread में मेरे उत्तर में इसके लिए नमूना कोड मिलेगा।

पता लगाने का कोई अच्छा तरीका नहीं है कि उपयोगकर्ता सो गया है या नहीं।

+3

+1 "यह पता लगाने का कोई अच्छा तरीका नहीं है कि उपयोगकर्ता सो गया है या नहीं।" :) – zeFree

1

कई कारण हैं कि उपयोगकर्ता आपकी सूचनाएं भी नहीं देख सकता है उदाहरण के लिए पूर्ण स्क्रीन वीडियो प्लेबैक या उपयोगकर्ता बस वहां नहीं है।

मेरा सुझाव है कि अधिसूचना प्रदर्शित की जा सकती है या नहीं, यह जांचने के बजाय कि उपयोगकर्ता वहां है या नहीं, आप कीबोर्ड और माउस की निगरानी करके ऐसा कर सकते हैं।

+0

यह काम कर सकता है, लेकिन केवल तब तक जब तक उपयोगकर्ता पूर्ण-स्क्रीन गेम नहीं चलाता है। – Pieter

+0

@Pieter आपको यह जांचने की आवश्यकता है कि स्क्रीन पूर्ण स्क्रीन में नहीं है विशेष मोड –

3

उपयोग SystemParametersInfo स्क्रीन सेवर चल रहा है कि क्या पता लगाने के लिए - CALLTYPE SPI_GETSCREENSAVERRUNNING है। यह Win2000 और ऊपर के लिए समर्थित है।

Wksta लॉक होने पर यह जांचने के लिए StackOverflow here पर @dan_g से कोड है।

8

मैंने हाल ही में previous blog post से यह कोड फिर से जांच लिया है ताकि यह सुनिश्चित किया जा सके कि यह विंडोज एक्सपी के संस्करणों पर 7, x86 और x64 पर काम करता है और इसे थोड़ा सा साफ करता है।

यहाँ नवीनतम minimalist कोड यदि वर्कस्टेशन लॉक किया गया है और अगर स्क्रीनसेवर दो आसान उपयोग करने के लिए स्थिर तरीकों में लिपटे चल रहा है की जाँच करता है वह यह है कि:

using System; 
using System.Runtime.InteropServices; 

namespace BrutalDev.Helpers 
{ 
    public static class NativeMethods 
    { 
    // Used to check if the screen saver is running 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool SystemParametersInfo(uint uAction, 
                uint uParam, 
                ref bool lpvParam, 
                int fWinIni); 

    // Used to check if the workstation is locked 
    [DllImport("user32", SetLastError = true)] 
    private static extern IntPtr OpenDesktop(string lpszDesktop, 
              uint dwFlags, 
              bool fInherit, 
              uint dwDesiredAccess); 

    [DllImport("user32", SetLastError = true)] 
    private static extern IntPtr OpenInputDesktop(uint dwFlags, 
                bool fInherit, 
                uint dwDesiredAccess); 

    [DllImport("user32", SetLastError = true)] 
    private static extern IntPtr CloseDesktop(IntPtr hDesktop); 

    [DllImport("user32", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool SwitchDesktop(IntPtr hDesktop); 

    // Check if the workstation has been locked. 
    public static bool IsWorkstationLocked() 
    { 
     const int DESKTOP_SWITCHDESKTOP = 256; 
     IntPtr hwnd = OpenInputDesktop(0, false, DESKTOP_SWITCHDESKTOP); 

     if (hwnd == IntPtr.Zero) 
     { 
     // Could not get the input desktop, might be locked already? 
     hwnd = OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP); 
     } 

     // Can we switch the desktop? 
     if (hwnd != IntPtr.Zero) 
     { 
     if (SwitchDesktop(hwnd)) 
     { 
      // Workstation is NOT LOCKED. 
      CloseDesktop(hwnd); 
     } 
     else 
     { 
      CloseDesktop(hwnd); 
      // Workstation is LOCKED. 
      return true; 
     } 
     } 

     return false; 
    } 

    // Check if the screensaver is busy running. 
    public static bool IsScreensaverRunning() 
    { 
     const int SPI_GETSCREENSAVERRUNNING = 114; 
     bool isRunning = false; 

     if (!SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, ref isRunning, 0)) 
     { 
     // Could not detect screen saver status... 
     return false; 
     } 

     if (isRunning) 
     { 
     // Screen saver is ON. 
     return true; 
     } 

     // Screen saver is OFF. 
     return false; 
    } 
    } 
} 

अद्यतन: कोड में सुझावों के आधार पर अद्यतन टिप्पणियाँ।

जब कार्य केंद्र तो लॉक किया गया है OpenInputDesktop विधि एक हैंडल के लिए एक संभाल वापसी नहीं करता है तो हम गिर वापसी कर सकते हैं OpenDesktop पर यकीन है कि यह स्विच करने के लिए कोशिश कर रहा द्वारा बंद है बनाने के लिए। यदि यह लॉक नहीं है तो OpenInputDesktop से आपके डिफ़ॉल्ट डेस्कटॉप को सक्रिय नहीं किया जाएगा, जो डेस्कटॉप आप देख रहे हैं उसके लिए एक वैध हैंडल लौटाएगा।

+2

जब तक मुझे कुछ याद नहीं आ रहा है, तो मैं इस ऐप में एक टाइमर पर चलने पर पागल हो जाऊंगा। बहुत यकीन है कि हमेशा लॉक नहीं होने पर डिफ़ॉल्ट डेस्कटॉप सक्रिय होने के लिए मजबूर होगा। मैंने कई डेस्कटॉप का उपयोग किया, और उन सभी में वास्तविक काम किया। मैं इसका उपयोग नहीं करता, लेकिन एमएस में डेस्कटॉपटॉप.एक्सई ऐप है जो आपको कई डेस्कटॉप बनाने और उनके बीच स्विच करने देता है, सुनिश्चित नहीं है कि बहुत से लोग इसका उपयोग करते हैं, यदि हां, तो यह कोड उत्पादन के लिए अच्छा नहीं है। मुझे लगता है कि वर्तमान इनपुट डेस्कटॉप प्राप्त करने का एक तरीका है, यह एक बेहतर जांच हो सकती है। – eselk

+1

इसके बजाय सक्रिय डेस्कटॉप नाम प्राप्त करने के लिए OpenInputDesktop और GetUserObjectInformation के लिए एमएसडीएन की जांच करें। – eselk

+0

@eselk: मान्य टिप्पणियों के लिए धन्यवाद। यदि आपके पास अलग-अलग नाम डेस्कटॉप हैं (बहुत दुर्लभ) तो आप सही हैं, यह आपको टाइमर लूप पर डिफ़ॉल्ट पर स्विच कर देगा। मैं इसके बजाय OpenInputDesktop का उपयोग करने के लिए आपके सुझाव का उपयोग करूंगा, इसलिए स्विच चुप है। GetUserObjectInformation उपयोगी नहीं होगा क्योंकि OpenInputDesktop का उपयोग करते समय मुझे डेस्कटॉप नाम की आवश्यकता नहीं है, बस हैंडल स्विच करने के लिए ठीक है। मुझे परीक्षण करने का मौका मिलने पर कोड में बुनियादी संपादन करेगा :) – BrutalDev

0
SystemEvents.SessionSwitch += new SessionSwitchEventHandler((sender, e) => 
     { 
      switch (e.Reason) 
      { 
       //If Reason is Lock, Turn off the monitor. 
       case SessionSwitchReason.SessionLock: 
        //SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_OFF); 
        MessageBox.Show("locked"); 
        break; 

       case SessionSwitchReason.SessionUnlock: 
        MessageBox.Show("unlocked"); 
        break; 
      } 
     }); 

जब सत्र लॉक किया गया और खुला है यह इंगित करेगा।

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