Subversion Repositories SoapBoxCore

Rev

Rev 7 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 scott 1
//Copyright (c) 2007-2010, Adolfo Marinucci
7 scott 2
//All rights reserved.
3
 
4
//Redistribution and use in source and binary forms, with or without modification, 
5
//are permitted provided that the following conditions are met:
6
//
7
//* Redistributions of source code must retain the above copyright notice, 
8
//  this list of conditions and the following disclaimer.
9
//* Redistributions in binary form must reproduce the above copyright notice, 
10
//  this list of conditions and the following disclaimer in the documentation 
11
//  and/or other materials provided with the distribution.
12
//* Neither the name of Adolfo Marinucci nor the names of its contributors may 
13
//  be used to endorse or promote products derived from this software without 
14
//  specific prior written permission.
15
//
16
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
17
//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
18
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
19
//IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
20
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
21
//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
22
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
23
//OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
24
//EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25
 
26
using System;
27
using System.Collections.Generic;
28
using System.Text;
29
using System.Windows;
30
using System.Windows.Interop;
31
using System.Runtime.InteropServices;
32
using System.Diagnostics;
17 scott 33
using System.ComponentModel;
7 scott 34
 
35
namespace AvalonDock
36
{
37
    class WindowInteropWrapper : IDisposable
38
    {
17 scott 39
        public WindowInteropWrapper(Window window)
7 scott 40
        {
17 scott 41
            if (window == null)
42
                throw new ArgumentNullException("window");
43
 
44
            WrappedWindow = window;
45
            if (WrappedWindow.IsLoaded)
46
                AttachWindow();
47
            else
48
                window.Loaded += (s, e) => AttachWindow();
49
            window.Unloaded += (s, e) => DetachWindow();
7 scott 50
        }
51
 
17 scott 52
 
53
        public Window WrappedWindow { get; private set; }
54
 
55
        HwndSource _hwndSrc = null;
56
        HwndSourceHook _hwndSrcHook = null;
57
 
58
        void AttachWindow()
7 scott 59
        {
17 scott 60
            _hwndSrc = HwndSource.FromDependencyObject(WrappedWindow) as HwndSource;
61
            _hwndSrcHook = new HwndSourceHook(this.HookHandler);
62
            _hwndSrc.AddHook(_hwndSrcHook);            
63
        }
64
 
65
        void DetachWindow()
66
        {
67
            if (_hwndSrc != null)
7 scott 68
            {
17 scott 69
                _hwndSrc.RemoveHook(_hwndSrcHook);
70
                _hwndSrc = null;
71
                _hwndSrcHook = null;
7 scott 72
            }
73
        }
74
 
17 scott 75
        //DependencyObject _attachedObject;
76
 
77
        //public DependencyObject AttachedObject
78
        //{
79
        //    get {return _attachedObject;}
80
        //    set
81
        //    {
82
        //        if (_attachedObject != value)
83
        //        {
84
        //            if (_attachedObject != null)
85
        //            {
86
        //                _hwndSrc.RemoveHook(_hwndSrcHook);
87
        //                //_hwndSrc.Dispose();
88
        //                _hwndSrc = null;
89
        //                _hwndSrcHook = null;
90
        //            }
7 scott 91
 
17 scott 92
        //            _attachedObject = value;
93
 
94
        //            if (_attachedObject != null)
95
        //            {
96
        //                _hwndSrc = HwndSource.FromDependencyObject(value) as HwndSource;
97
        //                _hwndSrcHook = new HwndSourceHook(this.HookHandler);
98
        //                _hwndSrc.AddHook(_hwndSrcHook);
99
        //            }
100
        //        }
101
        //    }
102
        //}
103
 
7 scott 104
        #region interop funtions and consts
17 scott 105
        private const int WM_MOUSEACTIVATE = 0x0021, MA_NOACTIVATE = 0x0003;
7 scott 106
        const int WM_NCACTIVATE = 0x86;
107
        const int WM_ACTIVATEAPP = 0x1c;
108
        const int WM_ACTIVATE = 6;
109
        const int WM_WINDOWPOSCHANGING = 70;
110
        const int WM_WINDOWPOSCHANGED = 0x47;
111
        const int WM_MOVE = 0x0003;
112
        const int WM_SIZE = 0x0005;
113
        const int WM_NCMOUSEMOVE = 0xa0;
114
        const int WM_NCLBUTTONDOWN = 0xA1;
115
        const int WM_NCLBUTTONUP = 0xA2;
116
        const int WM_NCLBUTTONDBLCLK = 0xA3;
117
        const int WM_NCRBUTTONDOWN = 0xA4;
118
        const int WM_NCRBUTTONUP = 0xA5;
119
        const int HTCAPTION = 2;
120
        const int SC_MOVE = 0xF010;
121
        const int WM_SYSCOMMAND = 0x0112;
122
 
17 scott 123
 
124
        [DllImport("user32.dll")]
125
        private extern static IntPtr SetActiveWindow(IntPtr handle);
126
 
127
        private const int WA_INACTIVE = 0;
128
 
7 scott 129
 
130
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
131
        public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam);
132
 
133
        [DllImport("user32.dll")]
134
        public static extern bool LockWindowUpdate(IntPtr hWndLock);  
135
 
136
        #endregion
137
 
138
        private IntPtr HookHandler(
139
            IntPtr hwnd,
140
            int msg,
141
            IntPtr wParam,
142
            IntPtr lParam,
143
            ref bool handled
144
            )
145
        {
146
            handled = false;
147
 
148
            switch (msg)
149
            {
150
                case SC_MOVE:
151
                case WM_WINDOWPOSCHANGING:
17 scott 152
                    SafeFireEvent<EventArgs>(WindowPosChanging, EventArgs.Empty);
7 scott 153
                    break;
17 scott 154
                case WM_MOUSEACTIVATE:
155
                    {
156
                        CancelEventArgs args = new CancelEventArgs();
157
                        SafeFireEvent<CancelEventArgs>(WindowActivating, args);
158
                        if (args.Cancel)
159
                        {
160
                            Debug.WriteLine("Cancelled");
161
                            handled = true;
162
                            return (IntPtr)MA_NOACTIVATE;
163
                        }
164
                    }
165
                    break;
166
                case WM_ACTIVATE:
167
                    {
168
                        if (((int)wParam & 0xFFFF) != WA_INACTIVE)
169
                        {
170
                            CancelEventArgs args = new CancelEventArgs();
171
                            SafeFireEvent<CancelEventArgs>(WindowActivating, args);
172
                            if (args.Cancel)
173
                            {
174
                                if (lParam != IntPtr.Zero)
175
                                {
176
                                    SetActiveWindow(lParam);
177
                                }
178
                                Debug.WriteLine("Cancelled Activation");
179
                                handled = true;
180
                            }
181
                        }
182
                    }
183
                    break;
7 scott 184
            }
185
 
17 scott 186
            if (!handled)
187
            {
188
                FilterMessageEventArgs e = new FilterMessageEventArgs(
189
                    hwnd,
190
                    msg,
191
                    wParam,
192
                    lParam);
193
 
194
                SafeFireEvent<FilterMessageEventArgs>(FilterMessage, e);
195
 
196
                handled = e.Handled;
197
            }
198
 
7 scott 199
            return IntPtr.Zero;
200
        }
201
 
17 scott 202
        public event EventHandler<EventArgs> WindowPosChanging;
203
 
204
        public event EventHandler<CancelEventArgs> WindowActivating;
7 scott 205
 
17 scott 206
        public event EventHandler<FilterMessageEventArgs> FilterMessage;
7 scott 207
 
17 scott 208
        void SafeFireEvent<T>(EventHandler<T> eventToFireup, T e) where T : EventArgs
7 scott 209
        {
17 scott 210
            if (WrappedWindow != null &&
211
                PresentationSource.FromDependencyObject(WrappedWindow) != null)
7 scott 212
            {
213
                if (eventToFireup != null)
214
                    eventToFireup(this, e);
17 scott 215
            }
7 scott 216
        }
217
 
218
 
219
        #region IDisposable Members
220
 
221
        public void Dispose()
222
        {
17 scott 223
            DetachWindow();
7 scott 224
            GC.SuppressFinalize(this);
225
        }
226
 
227
        #endregion
228
    }
17 scott 229
 
230
 
231
    public class FilterMessageEventArgs : EventArgs
232
    {
233
        public FilterMessageEventArgs(
234
            IntPtr hwnd,
235
            int msg,
236
            IntPtr wParam,
237
            IntPtr lParam)
238
        {
239
            Hwnd = hwnd;
240
            WParam = wParam;
241
            LParam = lParam;
242
            Msg = msg;
243
        }
244
 
245
        public IntPtr Hwnd { get; private set; }
246
        public IntPtr WParam { get; private set; }
247
        public IntPtr LParam { get; private set; }
248
        public int Msg { get; private set; }
249
        public bool Handled { get; set; }
250
 
251
    }
7 scott 252
}