GUI/GadgetWindow.cs
author moel.mich
Sat, 02 Oct 2010 18:15:46 +0000
changeset 206 1fa8eddc24a7
parent 183 3096735e99b2
child 208 08635c9dac04
permissions -rw-r--r--
Replaced HttpUtility.UrlEncode with Uri.EscapeDataString and deleted the reference to the System.Web assembly. The System.Web assembly seems to be missing on some .NET 4.0 installations (and the overhead of using it is a bit large, just for the UrlEncode method).
moel@202
     1
/*
moel@176
     2
  
moel@176
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@176
     4
moel@176
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@176
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@176
     7
  the License. You may obtain a copy of the License at
moel@176
     8
 
moel@176
     9
  http://www.mozilla.org/MPL/
moel@176
    10
moel@176
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@176
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@176
    13
  for the specific language governing rights and limitations under the License.
moel@176
    14
moel@176
    15
  The Original Code is the Open Hardware Monitor code.
moel@176
    16
moel@176
    17
  The Initial Developer of the Original Code is 
moel@176
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@176
    19
  Portions created by the Initial Developer are Copyright (C) 2010
moel@176
    20
  the Initial Developer. All Rights Reserved.
moel@176
    21
moel@176
    22
  Contributor(s):
moel@176
    23
moel@176
    24
  Alternatively, the contents of this file may be used under the terms of
moel@176
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@176
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@176
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@176
    28
  of those above. If you wish to allow use of your version of this file only
moel@176
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@176
    30
  use your version of this file under the terms of the MPL, indicate your
moel@176
    31
  decision by deleting the provisions above and replace them with the notice
moel@176
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@176
    33
  the provisions above, a recipient may use your version of this file under
moel@176
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@176
    35
 
moel@176
    36
*/
moel@176
    37
moel@176
    38
using System;
moel@176
    39
using System.Drawing;
moel@176
    40
using System.Reflection;
moel@176
    41
using System.Runtime.InteropServices;
moel@176
    42
using System.Windows.Forms;
moel@176
    43
moel@176
    44
namespace OpenHardwareMonitor.GUI {
moel@183
    45
moel@176
    46
  public class GadgetWindow : NativeWindow {
moel@176
    47
moel@176
    48
    private bool visible = false;
moel@183
    49
    private bool lockPositionAndSize = false;
moel@176
    50
    private bool alwaysOnTop = false;
moel@176
    51
    private byte opacity = 255;
moel@176
    52
    private Point location = new Point(100, 100);
moel@176
    53
    private Size size = new Size(130, 84);
moel@176
    54
    private ContextMenu contextMenu = null;
moel@176
    55
    private MethodInfo commandDispatch;
moel@176
    56
moel@176
    57
    public GadgetWindow() {
moel@176
    58
      Type commandType = 
moel@176
    59
        typeof(Form).Assembly.GetType("System.Windows.Forms.Command");
moel@176
    60
      commandDispatch = commandType.GetMethod("DispatchID", 
moel@176
    61
        BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, 
moel@176
    62
        null, new Type[]{ typeof(int) }, null);
moel@176
    63
moel@176
    64
      this.CreateHandle(CreateParams);
moel@176
    65
moel@176
    66
      // move window to the bottom
moel@176
    67
      MoveToBottom(Handle);
moel@176
    68
moel@176
    69
      // prevent window from fading to a glass sheet when peek is invoked
moel@176
    70
      try {
moel@176
    71
        bool value = true;
moel@202
    72
        NativeMethods.DwmSetWindowAttribute(Handle,
moel@176
    73
          WindowAttribute.DWMWA_EXCLUDED_FROM_PEEK, ref value,
moel@176
    74
          Marshal.SizeOf(value));
moel@176
    75
      } catch (DllNotFoundException) { } catch (EntryPointNotFoundException) { }
moel@176
    76
    }
moel@176
    77
moel@176
    78
    private void ShowDesktopChanged(bool showDesktop) {
moel@176
    79
      if (showDesktop) {
moel@176
    80
        MoveToTopMost(Handle);
moel@176
    81
      } else {
moel@176
    82
        MoveToBottom(Handle);
moel@176
    83
      }
moel@176
    84
    }
moel@176
    85
moel@176
    86
    private void MoveToBottom(IntPtr handle) {
moel@176
    87
      NativeMethods.SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0,
moel@176
    88
        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
moel@176
    89
    }
moel@176
    90
moel@176
    91
    private void MoveToTopMost(IntPtr handle) {
moel@176
    92
      NativeMethods.SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0,
moel@176
    93
        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
moel@176
    94
    }
moel@176
    95
moel@176
    96
    private void ShowContextMenu(Point position) {
moel@176
    97
      NativeMethods.TrackPopupMenuEx(contextMenu.Handle, 
moel@176
    98
        TPM_RIGHTBUTTON | TPM_VERTICAL, position.X,
moel@176
    99
        position.Y, Handle, IntPtr.Zero);
moel@176
   100
    }
moel@176
   101
moel@176
   102
    protected virtual CreateParams CreateParams {
moel@176
   103
      get {
moel@183
   104
        CreateParams cp = new CreateParams();        
moel@183
   105
        cp.Width = 4096;
moel@183
   106
        cp.Height = 4096;
moel@176
   107
        cp.X = location.X;
moel@176
   108
        cp.Y = location.Y;
moel@176
   109
        cp.ExStyle = WS_EX_LAYERED | WS_EX_TOOLWINDOW;
moel@176
   110
        return cp;
moel@176
   111
      }
moel@176
   112
    }
moel@176
   113
moel@176
   114
    protected override void WndProc(ref Message message) {
moel@176
   115
      switch (message.Msg) {
moel@183
   116
        case WM_COMMAND: {
moel@183
   117
            // need to dispatch the message for the context menu
moel@183
   118
            if (message.LParam == IntPtr.Zero)
moel@183
   119
              commandDispatch.Invoke(null, new object[] { 
moel@183
   120
              message.WParam.ToInt32() & 0xFFFF });
moel@183
   121
          } break;
moel@183
   122
        case WM_NCHITTEST: {
moel@183
   123
            message.Result = (IntPtr)HitResult.Caption;
moel@183
   124
            if (HitTest != null) {
moel@183
   125
              Point p = new Point(
moel@183
   126
                (int)((uint)message.LParam & 0xFFFF) - location.X,
moel@183
   127
                (int)(((uint)message.LParam >> 16) & 0xFFFF) - location.Y);
moel@183
   128
              HitTestEventArgs e = new HitTestEventArgs(p, HitResult.Caption);
moel@183
   129
              HitTest(this, e);
moel@183
   130
              message.Result = (IntPtr)e.HitResult;
moel@183
   131
            }
moel@183
   132
          } break;
moel@183
   133
        case WM_NCLBUTTONDBLCLK: {
moel@183
   134
            message.Result = IntPtr.Zero;
moel@183
   135
          } break;
moel@183
   136
        case WM_NCRBUTTONDOWN: {
moel@183
   137
            message.Result = IntPtr.Zero;
moel@183
   138
          } break;
moel@183
   139
        case WM_NCRBUTTONUP: {
moel@183
   140
            if (contextMenu != null)
moel@183
   141
              ShowContextMenu(new Point(
moel@183
   142
                (int)((uint)message.LParam & 0xFFFF),
moel@183
   143
                (int)(((uint)message.LParam >> 16) & 0xFFFF)));
moel@183
   144
            message.Result = IntPtr.Zero;
moel@183
   145
          } break;
moel@183
   146
        case WM_WINDOWPOSCHANGING: {
moel@183
   147
            WindowPos wp = (WindowPos)Marshal.PtrToStructure(
moel@183
   148
              message.LParam, typeof(WindowPos));
moel@183
   149
            
moel@183
   150
            if (!lockPositionAndSize) {
moel@183
   151
              // prevent the window from leaving the screen
moel@183
   152
              if ((wp.flags & SWP_NOMOVE) == 0) {
moel@183
   153
                Rectangle rect = Screen.GetWorkingArea(new Point(wp.x, wp.y));
moel@183
   154
                const int margin = 16;
moel@183
   155
                wp.x = Math.Max(wp.x, rect.Left - wp.cx + margin);
moel@183
   156
                wp.x = Math.Min(wp.x, rect.Right - margin);
moel@183
   157
                wp.y = Math.Max(wp.y, rect.Top - wp.cy + margin);
moel@183
   158
                wp.y = Math.Min(wp.y, rect.Bottom - margin);
moel@183
   159
              }
moel@176
   160
moel@183
   161
              // update location and fire event
moel@183
   162
              if ((wp.flags & SWP_NOMOVE) == 0) {
moel@183
   163
                if (location.X != wp.x || location.Y != wp.y) {
moel@183
   164
                  location = new Point(wp.x, wp.y);
moel@183
   165
                  if (LocationChanged != null)
moel@183
   166
                    LocationChanged(this, EventArgs.Empty);
moel@183
   167
                }
moel@183
   168
              }
moel@176
   169
moel@183
   170
              // update size and fire event
moel@183
   171
              if ((wp.flags & SWP_NOSIZE) == 0) {
moel@183
   172
                if (size.Width != wp.cx || size.Height != wp.cy) {
moel@183
   173
                  size = new Size(wp.cx, wp.cy);
moel@183
   174
                  if (SizeChanged != null)
moel@183
   175
                    SizeChanged(this, EventArgs.Empty);
moel@183
   176
                }
moel@183
   177
              } 
moel@176
   178
moel@183
   179
              // update the size of the layered window
moel@183
   180
              if ((wp.flags & SWP_NOSIZE) == 0) {
moel@183
   181
                NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero,
moel@183
   182
                  IntPtr.Zero, ref size, IntPtr.Zero, IntPtr.Zero, 0,
moel@183
   183
                  IntPtr.Zero, 0);                
moel@183
   184
              }
moel@183
   185
moel@183
   186
              // update the position of the layered window
moel@183
   187
              if ((wp.flags & SWP_NOMOVE) == 0) {
moel@183
   188
                NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 
moel@183
   189
                  location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | 
moel@183
   190
                  SWP_NOZORDER | SWP_NOSENDCHANGING);
moel@183
   191
              }
moel@176
   192
            }
moel@183
   193
            
moel@183
   194
            // do not forward any move or size messages
moel@183
   195
            wp.flags |= SWP_NOSIZE | SWP_NOMOVE;            
moel@183
   196
            Marshal.StructureToPtr(wp, message.LParam, false);                      
moel@183
   197
            message.Result = IntPtr.Zero;
moel@183
   198
          } break;
moel@183
   199
        default: {
moel@183
   200
            base.WndProc(ref message);
moel@183
   201
          } break;
moel@176
   202
      }      
moel@176
   203
    }
moel@176
   204
moel@176
   205
    private BlendFunction CreateBlendFunction() {
moel@176
   206
      BlendFunction blend = new BlendFunction();
moel@176
   207
      blend.BlendOp = AC_SRC_OVER;
moel@176
   208
      blend.BlendFlags = 0;
moel@176
   209
      blend.SourceConstantAlpha = opacity;
moel@176
   210
      blend.AlphaFormat = AC_SRC_ALPHA;
moel@176
   211
      return blend;
moel@176
   212
    }
moel@176
   213
moel@176
   214
    public void Update(Bitmap bitmap) {
moel@176
   215
      IntPtr screen = NativeMethods.GetDC(IntPtr.Zero);
moel@176
   216
      IntPtr memory = NativeMethods.CreateCompatibleDC(screen);
moel@176
   217
      IntPtr newHBitmap = IntPtr.Zero;
moel@176
   218
      IntPtr oldHBitmap = IntPtr.Zero;
moel@176
   219
moel@176
   220
      try {
moel@176
   221
        newHBitmap = bitmap.GetHbitmap(Color.Black);
moel@176
   222
        oldHBitmap = NativeMethods.SelectObject(memory, newHBitmap);
moel@176
   223
moel@176
   224
        Point pointSource = Point.Empty;
moel@183
   225
        BlendFunction blend = CreateBlendFunction();
moel@176
   226
moel@183
   227
        NativeMethods.UpdateLayeredWindow(Handle, screen, IntPtr.Zero,
moel@176
   228
          ref size, memory, ref pointSource, 0, ref blend, ULW_ALPHA);
moel@183
   229
moel@183
   230
        // make sure the window is at the right location
moel@183
   231
        NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 
moel@183
   232
          location.X, location.Y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | 
moel@183
   233
          SWP_NOZORDER | SWP_NOSENDCHANGING);
moel@183
   234
moel@183
   235
      } finally {        
moel@176
   236
        if (newHBitmap != IntPtr.Zero) {
moel@176
   237
          NativeMethods.SelectObject(memory, oldHBitmap);
moel@176
   238
          NativeMethods.DeleteObject(newHBitmap);
moel@176
   239
        }
moel@176
   240
        NativeMethods.DeleteDC(memory);
moel@183
   241
        NativeMethods.ReleaseDC(IntPtr.Zero, screen);
moel@176
   242
      }
moel@176
   243
    }
moel@176
   244
moel@176
   245
    public byte Opacity {
moel@176
   246
      get {
moel@176
   247
        return opacity;
moel@176
   248
      }
moel@176
   249
      set {
moel@176
   250
        if (opacity != value) {
moel@176
   251
          opacity = value;
moel@176
   252
          BlendFunction blend = CreateBlendFunction();
moel@176
   253
          NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero, IntPtr.Zero,
moel@176
   254
            IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, ref blend, ULW_ALPHA);
moel@176
   255
        }
moel@176
   256
      }
moel@176
   257
    }
moel@176
   258
moel@176
   259
    public bool Visible {
moel@176
   260
      get {
moel@176
   261
        return visible;
moel@176
   262
      }
moel@176
   263
      set {
moel@176
   264
        if (visible != value) {
moel@176
   265
          visible = value;
moel@176
   266
          NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 0, 0, 0, 0,
moel@176
   267
            SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER |
moel@176
   268
            (value ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
moel@180
   269
          if (value) {
moel@180
   270
            if (!alwaysOnTop)
moel@180
   271
              ShowDesktop.Instance.ShowDesktopChanged += ShowDesktopChanged;
moel@180
   272
          } else {
moel@180
   273
            if (!alwaysOnTop)
moel@180
   274
              ShowDesktop.Instance.ShowDesktopChanged -= ShowDesktopChanged;
moel@180
   275
          }
moel@176
   276
        }
moel@176
   277
      }
moel@176
   278
    }
moel@176
   279
moel@183
   280
    // if locked, the window can not be moved or resized
moel@183
   281
    public bool LockPositionAndSize {
moel@176
   282
      get {
moel@183
   283
        return lockPositionAndSize;
moel@176
   284
      }
moel@176
   285
      set {
moel@183
   286
        lockPositionAndSize = value;
moel@176
   287
      }
moel@176
   288
    }
moel@176
   289
moel@176
   290
    public bool AlwaysOnTop {
moel@176
   291
      get {
moel@176
   292
        return alwaysOnTop;
moel@176
   293
      }
moel@176
   294
      set {
moel@176
   295
        if (value != alwaysOnTop) {
moel@176
   296
          alwaysOnTop = value;
moel@176
   297
          if (alwaysOnTop) {
moel@180
   298
            if (visible)
moel@180
   299
              ShowDesktop.Instance.ShowDesktopChanged -= ShowDesktopChanged;
moel@176
   300
            MoveToTopMost(Handle);            
moel@176
   301
          } else {
moel@176
   302
            MoveToBottom(Handle);
moel@180
   303
            if (visible)
moel@180
   304
              ShowDesktop.Instance.ShowDesktopChanged += ShowDesktopChanged;
moel@176
   305
          }
moel@176
   306
        }
moel@176
   307
      }
moel@176
   308
    }
moel@176
   309
moel@176
   310
    public Size Size {
moel@176
   311
      get {
moel@176
   312
        return size; 
moel@176
   313
      }
moel@176
   314
      set {
moel@176
   315
        if (size != value) {
moel@176
   316
          size = value;
moel@183
   317
          NativeMethods.UpdateLayeredWindow(Handle, IntPtr.Zero, IntPtr.Zero,
moel@183
   318
            ref size, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, 0);                    
moel@183
   319
          if (SizeChanged != null)
moel@183
   320
            SizeChanged(this, EventArgs.Empty);
moel@176
   321
        }
moel@176
   322
      }
moel@176
   323
    }
moel@176
   324
moel@183
   325
    public event EventHandler SizeChanged;
moel@183
   326
moel@176
   327
    public Point Location {
moel@176
   328
      get {
moel@176
   329
        return location;
moel@176
   330
      }
moel@176
   331
      set {
moel@183
   332
        if (location != value) {
moel@183
   333
          location = value;
moel@183
   334
          NativeMethods.SetWindowPos(Handle, IntPtr.Zero, 
moel@183
   335
            location.X, location.Y, 0, 0, 
moel@183
   336
            SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING);          
moel@183
   337
          if (LocationChanged != null)
moel@183
   338
            LocationChanged(this, EventArgs.Empty);
moel@183
   339
        }
moel@176
   340
      }
moel@176
   341
    }
moel@176
   342
moel@176
   343
    public event EventHandler LocationChanged;
moel@176
   344
moel@176
   345
    public ContextMenu ContextMenu {
moel@176
   346
      get {
moel@176
   347
        return contextMenu;
moel@176
   348
      }
moel@176
   349
      set {
moel@176
   350
        this.contextMenu = value;
moel@176
   351
      }
moel@176
   352
    }
moel@176
   353
moel@183
   354
    public event HitTestEventHandler HitTest;
moel@183
   355
moel@176
   356
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
moel@176
   357
    private struct BlendFunction {
moel@176
   358
      public byte BlendOp;
moel@176
   359
      public byte BlendFlags;
moel@176
   360
      public byte SourceConstantAlpha;
moel@176
   361
      public byte AlphaFormat;
moel@176
   362
    }
moel@176
   363
moel@176
   364
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
moel@176
   365
    private struct WindowPos {
moel@176
   366
      public IntPtr hwnd;
moel@176
   367
      public IntPtr hwndInsertAfter;
moel@176
   368
      public int x;
moel@176
   369
      public int y;
moel@176
   370
      public int cx;
moel@176
   371
      public int cy;
moel@176
   372
      public uint flags;
moel@176
   373
    }
moel@176
   374
moel@176
   375
    public static readonly IntPtr HWND_BOTTOM = (IntPtr)1;
moel@176
   376
    public static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);
moel@176
   377
moel@176
   378
    public const int WS_EX_LAYERED = 0x00080000;
moel@176
   379
    public const int WS_EX_TOOLWINDOW = 0x00000080;
moel@176
   380
moel@176
   381
    public const uint SWP_NOSIZE = 0x0001;
moel@176
   382
    public const uint SWP_NOMOVE = 0x0002;
moel@176
   383
    public const uint SWP_NOACTIVATE = 0x0010;
moel@176
   384
    public const uint SWP_HIDEWINDOW = 0x0080;
moel@176
   385
    public const uint SWP_SHOWWINDOW = 0x0040;
moel@176
   386
    public const uint SWP_NOZORDER = 0x0004;
moel@176
   387
    public const uint SWP_NOSENDCHANGING = 0x0400;
moel@176
   388
moel@176
   389
    public const int ULW_COLORKEY = 0x00000001;
moel@176
   390
    public const int ULW_ALPHA = 0x00000002;
moel@176
   391
    public const int ULW_OPAQUE = 0x00000004;
moel@176
   392
moel@176
   393
    public const byte AC_SRC_OVER = 0x00;
moel@176
   394
    public const byte AC_SRC_ALPHA = 0x01;
moel@176
   395
moel@176
   396
    public const int WM_NCHITTEST = 0x0084;
moel@176
   397
    public const int WM_NCLBUTTONDBLCLK = 0x00A3;
moel@176
   398
    public const int WM_NCLBUTTONDOWN = 0x00A1;
moel@176
   399
    public const int WM_NCLBUTTONUP = 0x00A2;
moel@176
   400
    public const int WM_NCRBUTTONDOWN = 0x00A4;
moel@176
   401
    public const int WM_NCRBUTTONUP = 0x00A5;
moel@176
   402
    public const int WM_WINDOWPOSCHANGING = 0x0046;
moel@176
   403
    public const int WM_COMMAND = 0x0111;
moel@176
   404
moel@176
   405
    public const int TPM_RIGHTBUTTON = 0x0002;
moel@176
   406
    public const int TPM_VERTICAL = 0x0040;
moel@176
   407
moel@176
   408
    private enum WindowAttribute : int {
moel@176
   409
      DWMWA_NCRENDERING_ENABLED = 1,
moel@176
   410
      DWMWA_NCRENDERING_POLICY,
moel@176
   411
      DWMWA_TRANSITIONS_FORCEDISABLED,
moel@176
   412
      DWMWA_ALLOW_NCPAINT,
moel@176
   413
      DWMWA_CAPTION_BUTTON_BOUNDS,
moel@176
   414
      DWMWA_NONCLIENT_RTL_LAYOUT,
moel@176
   415
      DWMWA_FORCE_ICONIC_REPRESENTATION,
moel@176
   416
      DWMWA_FLIP3D_POLICY,
moel@176
   417
      DWMWA_EXTENDED_FRAME_BOUNDS,
moel@176
   418
      DWMWA_HAS_ICONIC_BITMAP,
moel@176
   419
      DWMWA_DISALLOW_PEEK,
moel@176
   420
      DWMWA_EXCLUDED_FROM_PEEK,
moel@176
   421
      DWMWA_LAST
moel@176
   422
    }
moel@176
   423
moel@176
   424
    private static class NativeMethods {
moel@176
   425
      private const string USER = "user32.dll";
moel@176
   426
      private const string GDI = "gdi32.dll";
moel@176
   427
      public const string DWMAPI = "dwmapi.dll";
moel@176
   428
moel@176
   429
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   430
      [return: MarshalAs(UnmanagedType.Bool)]
moel@183
   431
      public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,
moel@183
   432
        IntPtr pptDst, ref Size psize, IntPtr hdcSrc, IntPtr pprSrc,
moel@183
   433
        int crKey, IntPtr pblend, int dwFlags);
moel@183
   434
moel@183
   435
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@183
   436
      [return: MarshalAs(UnmanagedType.Bool)]
moel@176
   437
      public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, 
moel@183
   438
        IntPtr pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, 
moel@176
   439
        int crKey, ref BlendFunction pblend, int dwFlags);
moel@176
   440
moel@176
   441
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   442
      [return: MarshalAs(UnmanagedType.Bool)]
moel@176
   443
      public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,
moel@176
   444
        IntPtr pptDst, IntPtr psize, IntPtr hdcSrc, IntPtr pprSrc,
moel@176
   445
        int crKey, ref BlendFunction pblend, int dwFlags);  
moel@176
   446
moel@176
   447
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   448
      public static extern IntPtr GetDC(IntPtr hWnd);
moel@176
   449
moel@176
   450
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   451
      public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
moel@176
   452
moel@176
   453
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   454
      public static extern bool SetWindowPos(IntPtr hWnd,
moel@176
   455
        IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
moel@176
   456
moel@176
   457
      [DllImport(USER, CallingConvention = CallingConvention.Winapi)]
moel@176
   458
      public static extern bool TrackPopupMenuEx(IntPtr hMenu, uint uFlags, 
moel@176
   459
        int x, int y, IntPtr hWnd, IntPtr tpmParams);
moel@176
   460
moel@176
   461
      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
moel@176
   462
      public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
moel@176
   463
moel@176
   464
      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
moel@176
   465
      [return: MarshalAs(UnmanagedType.Bool)]
moel@176
   466
      public static extern bool DeleteDC(IntPtr hdc);
moel@176
   467
      
moel@176
   468
      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
moel@176
   469
      public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
moel@176
   470
moel@176
   471
      [DllImport(GDI, CallingConvention = CallingConvention.Winapi)]
moel@176
   472
      [return: MarshalAs(UnmanagedType.Bool)]
moel@176
   473
      public static extern bool DeleteObject(IntPtr hObject);
moel@176
   474
moel@176
   475
      [DllImport(DWMAPI, CallingConvention = CallingConvention.Winapi)]
moel@176
   476
      public static extern int DwmSetWindowAttribute(IntPtr hwnd,
moel@176
   477
        WindowAttribute dwAttribute, ref bool pvAttribute, int cbAttribute);
moel@176
   478
    }    
moel@176
   479
  }
moel@183
   480
moel@183
   481
  public enum HitResult {
moel@183
   482
    Transparent = -1,
moel@183
   483
    Nowhere = 0,
moel@183
   484
    Client = 1,
moel@183
   485
    Caption = 2,
moel@183
   486
    Left = 10,
moel@183
   487
    Right = 11,
moel@183
   488
    Top = 12,
moel@183
   489
    TopLeft = 13,
moel@183
   490
    TopRight = 14,
moel@183
   491
    Bottom = 15,
moel@183
   492
    BottomLeft = 16,
moel@183
   493
    BottomRight = 17,
moel@183
   494
    Border = 18
moel@183
   495
  }
moel@183
   496
moel@183
   497
  public delegate void HitTestEventHandler(object sender, HitTestEventArgs e);
moel@183
   498
moel@183
   499
  public class HitTestEventArgs : EventArgs {
moel@183
   500
    public HitTestEventArgs(Point location, HitResult hitResult) {
moel@183
   501
      Location = location;
moel@183
   502
      HitResult = hitResult;
moel@183
   503
    }
moel@183
   504
    public Point Location { get; private set; }
moel@183
   505
    public HitResult HitResult { get; set; }
moel@183
   506
  }
moel@176
   507
}