2012-02-17 9 views
5

में एरो स्नैप संदेश को संभालना मेरे सी # .NET 4 एप्लिकेशन में, मैं WndProc का उपयोग कुछ संदेशों को संसाधित करने के लिए करता हूं जो अधिकतर स्क्रीन से एप्लिकेशन को आकार बदलने के साथ काम करते हैं।WndProc

अभी मैं सिर्फ SC_MAXIMIZE और WM_NCLBUTTONDBLCLK से निपटने हूँ निर्धारित करने के लिए करता है, तो खिड़की करने के लिए या एक अधिकतम राज्य (मैं जानता हूँ कि मैं SC_MAXIMIZE संभाल करने WndProc जरूरत नहीं है, लेकिन Form_Resize एक के लिए आग नहीं मालूम था से आकार दिया जा रहा है WM_NCLBUTTONDBLCLK संदेश जब मैं एप्लिकेशन के शीर्षक पट्टी पर डबल-क्लिक करता हूं।

अब मैंने देखा है कि अगर मैं स्क्रीन को स्क्रीन के शीर्ष पर विंडो को अधिकतम करने के लिए स्नैप करता हूं, तो ऊपर दिए गए संदेशों में से कोई भी पोस्ट नहीं किया जाता है इसलिए कुछ तर्क लागू नहीं होते हैं जब खिड़की को एरो स्नैप के माध्यम से अधिकतम किया जाता है। मैं केवल संदेश को संभालना चाहता हूं अगर खिड़की को दाएं या बाएं की बजाय स्क्रीन के शीर्ष पर स्नैप किया गया हो, या यदि खिड़की को अधिकतम पी से अपरिवर्तित किया गया है osition।

मुझे एरो स्नैप से संबंधित किसी भी विंडो संदेश नहीं मिल सका। क्या किसी को उन संदेशों के लिए किसी भी संदर्भ के बारे में पता है?

+0

मैंने यह भी सोचा है ... हालांकि, मैं इसे कभी भी समझने में सक्षम नहीं हूं। – aboveyou00

उत्तर

7

मुझे लगता है कि यहां कोई विशेष संदेश नहीं हैं; एरो शायद सादा Win32 एपीआई - ShowWindow(SW_MAXIMIZE) और इसी तरह का उपयोग कर रहा है।

SC_ संदेश के साथ uderstand जाएगा बात यह है कि उन लोगों के लिए एक मेनू से अनुरोध खिड़की पूछ आकार बदलने के लिए/बहाल/आदि ही हैं, लेकिन लगता है कि विंडोज़ का आकार बदलने के लिए केवल तंत्र नहीं मानता। शायद यह हो रहा है कि जब एक विंडो SC_MAXIMIZE हो जाती है, तो DefWndProc इसे ShowWindow (SW_MAXIMIZE) पर कॉल करके लागू करता है।

WM_SIZE संदेश सुनने के लिए आपका सबसे अच्छा सबसे अच्छा तरीका है, जो विंडो प्राप्त करता है, चाहे आकार परिवर्तन किस प्रकार ट्रिगर किया गया हो: सिस्टम मेनू, एपीआई, या अन्य माध्यम। विशेष रूप से, एलपीएआर आपको बताएगा कि खिड़की को अधिकतम किया गया था (SIZE_MAXIMIZED) या पुनर्स्थापित (SIZE_RESTORED)।

+3

यह सही है। एयरो स्नैप के परिणामस्वरूप कोई विशेष सूचनाएं नहीं भेजी गई हैं। यह मानक 'WM_MOVING'/'WM_MOVE' और' WM_SIZING'/'WM_SIZE' संदेशों का उपयोग करता है। यदि आप 'DefWindowProc' को कॉल किए बिना इन्हें संसाधित करते हैं, तो एरो स्नैप आपकी विंडो के लिए काम नहीं करेगा। हां, आप 'WM_SIZE' के लिए सुन सकते हैं, लेकिन संभवतः आप ['WM_WINDOWPOSCHANGED'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632652.aspx) का उपयोग करके सामान्य रूप से बेहतर तरीके से बंद हो सकते हैं। । यह एक "नया" फ़ंक्शन है, जिसमें गलती हुई है, विंडोज 3.1। :-) [प्रासंगिक पढ़ने] (http://blogs.msdn.com/b/oldnewthing/archive/2008/01/15/7113860.aspx)। –

+1

पोस्चेंज के साथ पकड़ यह है कि आप इसे * किसी भी * चाल/आकार में परिवर्तन के लिए प्राप्त करते हैं, जिसमें "स्नैप" से पहले खिड़की को स्थानांतरित किया जा रहा है, इसलिए आपको अधिक फ़िल्टरिंग करने की आवश्यकता है। और मुझे नहीं पता कि क्या आप इसके पैरामीटर से अधिकतम 'स्नैप' निर्धारित कर सकते हैं - कोई स्पष्ट नहीं है "खिड़की को अधिकतम किया गया है" सूचक। WM_SIZE के साथ, lParam की जांच करें और आप कर चुके हैं! – BrendanMcK

+0

हां, आपको कुछ फ़िल्टरिंग करने की आवश्यकता है। यह मूल रूप से अपरिहार्य है, आपको यह सुनिश्चित करने के लिए 'WM_SIZE' फ़िल्टर करना होगा कि आप केवल एरो स्नैप द्वारा शुरू की गई आकार बदलने वाली घटनाओं से निपटें। मुद्दा यह है कि आपका सभी हैंडलिंग कोड एक ही स्थान पर है। मुझे वास्तव में आपके 'WM_WINDOWPOSCHANGED' संदेश हैंडलर के अंदर' स्विच 'कथन और' WM_MOVE', 'WM_SIZE',' को संभालने वाली आपकी विंडो प्रक्रिया के अंदर 'स्विच' कथन के बीच का अंतर दिखाई नहीं देता है।मुझे लगता है कि महान शक्ति के साथ बड़ी ज़िम्मेदारी आती है; कोई भी काम करेगा। –

2

WM_SIZE संदेश के बजाय अधिकतम WM_WINDOWPOSCHANGING संदेश को संभालने के लिए कोड यहां दिया गया है। एसओ पर 20 या उससे अधिक प्रश्नों के लिए धन्यवाद कि मुझे इसे एक साथ रखने और इसे काम करने के लिए सभी बिट्स खोजने के लिए पढ़ना पड़ा। यह विभिन्न संकल्पों का उपयोग कर कई मॉनीटरों के साथ होने वाली समस्याओं को संबोधित करता है।

//register the hook 
public static void WindowInitialized(Window window) 
{ 
    IntPtr handle = (new WindowInteropHelper(window)).Handle; 
    var hwndSource = HwndSource.FromHwnd(handle); 
    if (hwndSource != null) 
    { 
     hwndSource.AddHook(WindowProc); 
    } 
} 

//the important bit 
private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    switch (msg) 
    { 
     case 0x0046: //WINDOWPOSCHANGING 
      var winPos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); 
      var monitorInfo = new MONITORINFO(); 
      IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MonitorDefaultToNearest); 
      GetMonitorInfo(monitorContainingApplication, monitorInfo); 
      RECT rcWorkArea = monitorInfo.rcWork; 
      //check for a framechange - but ignore initial draw. x,y is top left of current monitor so must be a maximise 
      if (((winPos.flags & SWP_FRAMECHANGED) == SWP_FRAMECHANGED) && (winPos.flags & SWP_NOSIZE) != SWP_NOSIZE && winPos.x == rcWorkArea.left && winPos.y == rcWorkArea.top) 
      { 
       //set max size to the size of the *current* monitor 
       var width = Math.Abs(rcWorkArea.right - rcWorkArea.left); 
       var height = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); 
       winPos.cx = width; 
       winPos.cy = height; 
       Marshal.StructureToPtr(winPos, lParam, true); 
       handled = true; 
      }      
      break; 
    } 
    return (IntPtr)0; 
} 


//all the helpers for dealing with this COM crap 
[DllImport("user32")] 
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); 

[DllImport("user32")] 
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); 

private const int MonitorDefaultToNearest = 0x00000002; 

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

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public class MONITORINFO 
{ 
    public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); 
    public RECT rcMonitor; 
    public RECT rcWork; 
    public int dwFlags; 
} 

[StructLayout(LayoutKind.Sequential, Pack = 0)] 
public struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 
+0

आपकी टिप्पणी के लिए पूरी तरह से उपरोक्त "इस COM बकवास से निपटने के लिए सभी सहायक" ... –

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