WPF

2009-05-29 7 views
10

में विंडो स्टेट चेंजिंग ईवेंट मुझे कम से कम WPF एप्लिकेशन को संभालने की आवश्यकता है, इससे पहले कि यह पहले से मौजूद न हो। मुझे विंडो ऑब्जेक्ट स्टेट चेंज पर मिला, लेकिन जब यह विंडो ऑब्जेक्ट पहले से ही कम से कम राज्य में है, तो यह आग लगती है, तो यह बहुत देर हो चुकी है।WPF

तो, मुझे "स्टेट चेंजिंग" ईवेंट को संभालने के लिए कुछ चाहिए, जबकि विंडो ऑब्जेक्ट अभी भी पिछली स्थिति में है।

क्या ऐसी घटना बनाना संभव है?

उत्तर

11

स्पाइ ++ का उपयोग करके कम से कम विंडो पर कॉल किए गए विंडोज संदेशों को मिला। जिसे पहले कहा जाता है वह WM_WINDOWPOSCHANGING है। मुझे नहीं पता था कि खिड़की -32000 पर खिड़की चल रही है, -32000 स्थान बिंदु जब विधवा को कम करता है, और वे WM_WINDOWPOSCHANGING में पैरा थे। हालांकि, मैंने परीक्षण किया है केवल Vista पर है। यहां इस्तेमाल किया http://blogs.msdn.com/oldnewthing/archive/2004/10/28/249044.aspx

कोड Nir द्वारा पोस्ट किया गया here

यहाँ

नमूना कोड है

XAML:

<Window x:Class="WindowStateTest2.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 

     <RowDefinition Height="*"></RowDefinition> 
    </Grid.RowDefinitions> 
     <Button Click="btnClear_Click" Grid.Row="0" x:Name="btnClear">Clear</Button>    

     <TextBox Name="txt" VerticalScrollBarVisibility="Visible" Grid.Row="2"></TextBox> 
</Grid> 
</Window> 

सी #

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Windows.Interop; 
using System.Runtime.InteropServices; 

namespace WindowStateTest2 
{ 
/// <summary> 
/// Interaction logic for Window1.xaml 
/// </summary> 
public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     this.StateChanged += new EventHandler(Window1_StateChanged); 
     this.SourceInitialized += new EventHandler(Window1_SourceInitialized); 

    } 

    #region Event handlers 

    void btnClear_Click(object sender, RoutedEventArgs e) 
    { 
     this.txt.Text = string.Empty; 
    } 
    void Window1_SourceInitialized(object sender, EventArgs e) 
    { 
     AttachWndProc(); 
    } 

    void Window1_StateChanged(object sender, EventArgs e) 
    { 
     if (this.WindowState == WindowState.Minimized) 
      Console.WriteLine("SC: " + this.WindowState); 
    } 

    #endregion 

    #region Const 

    private int SYSCOMMAND = 0x0112; 
    private int SC_MINIMIZE = 0xf020; 
    private int WINDOWPOSCHANGING = 0x0046; 

    #endregion 

    private void AttachWndProc() 
    { 
     HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
     source.AddHook(new HwndSourceHook(WndProc)); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct WINDOWPOSPARAMS 
    { 
     public IntPtr hwnd; 
     public IntPtr hwndInsertAfter; 
     public int x; 
     public int y; 
     public int cx; 
     public int cy; 
     public int flags; 
    } 


    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WINDOWPOSCHANGING)    
     { 
      WINDOWPOSPARAMS param = (WINDOWPOSPARAMS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOSPARAMS)); 
      if (param.x == -32000 && param.y == -32000) 
      { 
       Output(""); 

            // EVENT WOULD BE RAISED HERE 

       Output("State before minimize:"); 
       Output(string.Format("CurrentState: {0}", this.WindowState)); 
       Output(string.Format("Location {0} {1}: ", this.Top, this.Left)); 
       Output(""); 
      } 
     } 

     // process minimize button 
     if (msg == SYSCOMMAND && SC_MINIMIZE == wParam.ToInt32()) 
     { 
      Output("Minimize clicked");    
     } 

     handled = false; 
     return IntPtr.Zero; 
    } 

    public void Output(object output) 
    { 
     this.txt.Text += output.ToString(); 
     this.txt.Text += Environment.NewLine;   
    }  

} 
} 
0

मुझे नहीं लगता कि आप इसे सीधे करने में सक्षम होंगे।

खिड़की पर एक न्यूनतम कॉल विंडो स्थानों पर कम से कम बटन नहीं हो सकता है, उदाहरण के लिए विंडो क्रोम पर छोटा बटन (जैसे टास्कबार पर राइट क्लिक करना, या विंडोज टास्क मैनेजर से), और AFAIK, कोई रास्ता नहीं है विंडो क्रोम से निकाले गए बटन ईवेंट को सीधे संभाल लें (अगर कोई जानता है कि यह कैसे करें, तो कृपया मुझे बताएं!)।

अच्छी खबर यह है कि आप इसे नकली बना सकते हैं, लेकिन यह मामूली नहीं है, इसलिए आपको यह तय करना होगा कि यह इसके लायक है या नहीं। सबसे पहले, आपको मानक विंडो क्रोम को अपने आप से बदलना होगा। आप यह पता लगा सकते हैं कि here कैसे करें।

दूसरा, आपको अपने स्वयं के "अधिकतम/न्यूनतम/बंद करें" बटन बनाना होगा और घटनाओं को उचित व्यवहारों में तार बनाना होगा। चूंकि यह आपका यूआई है, इसलिए आप चुनने के दौरान बटन ईवेंट को सुन और रद्द कर सकते हैं।

ध्यान रखें कि आप अभी भी टास्कबार/विंडोज टास्क मैनेजर के माध्यम से उपयोगकर्ताओं को कम करने से रोकने या रोकने में सक्षम नहीं होंगे, इसलिए यह वही नहीं हो सकता है जो आप खोज रहे हैं।

+0

उत्तर के लिए धन्यवाद। मेरे पास पहले से ही विंडो पर कस्टम क्रोम है, और मैंने बटन मेनू पर सिस्टम मेनू से विंडोज संदेशों को पकड़ लिया है: टाइटल बार में, टास्क बार पर सिस्टम मेनू, Alt + Space पर सिस्टम मेनू। लेकिन मैं अभी भी टॉगल डेस्कटॉप (विन + डी) और सभी को न्यूनतम (विन + एम) के लिए एप्लिकेशन में ईवेंट कैप्चर नहीं कर सकता ... –

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

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