context: using System;
  using System.Text;
  using System.Collections;
  using System.Runtime.InteropServices;
  using System.Runtime.InteropServices.ComTypes;
  using System.Text.RegularExpressions;
  
  namespace IfacesEnumsStructsClasses
  {
      /// <summary>
      /// Windows API constants and functions
      /// </summary>
      public sealed class WinApis
      {
          public const uint MAX_PATH = 512;
          public const uint STGM_READ = 0x00000000;
          public const uint SHDVID_SSLSTATUS = 33;
          public const int GWL_WNDPROC = -4;
          public const uint KEYEVENTF_EXTENDEDKEY = 0x01;
          public const uint KEYEVENTF_KEYUP = 0x02;
  
          public const short
              //defined inWTypes.h
              // 0 == FALSE, -1 == TRUE
              //typedef short VARIANT_BOOL;
              VAR_TRUE = -1,
              VAR_FALSE = 0;
  
          #region Methods - GetWindowName - GetWindowClass
  
          public static int HiWord(int number)
          {
              if ((number & 0x80000000) == 0x80000000)
                  return (number >> 16);
              else
                  return (number >> 16) & 0xffff;
          }
  
          public static int LoWord(int number)
          {
              return number & 0xffff;
          }
  
          public static int GET_X_LPARAM(int lp)
          {
              return ((int)(short)(lp & 0xffff));
          }
  
          public static int GET_Y_LPARAM(int lp)
          {
              if ((lp & 0x80000000) == 0x80000000)
                  return ((int)(short)(lp >> 16));
              else
                  return ((int)(short)(lp >> 16) & 0xffff);
          }
  
          public static int MakeLong(int LoWord, int HiWord)
          {
              return (HiWord << 16) | (LoWord & 0xffff);
          }
  
          public static IntPtr MakeLParam(int LoWord, int HiWord)
          {
              return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
          }
  
          public static string GetWindowName(IntPtr Hwnd)
          {
              if (Hwnd == IntPtr.Zero)
                  return string.Empty;
              // This function gets the name of a window from its handle
              StringBuilder Title = new StringBuilder((int)WinApis.MAX_PATH);
              WinApis.GetWindowText(Hwnd, Title, (int)WinApis.MAX_PATH);
  
              return Title.ToString().Trim();
          }
  
          public static string GetWindowClass(IntPtr Hwnd)
          {
              if (Hwnd == IntPtr.Zero)
                  return string.Empty;
              // This function gets the name of a window class from a window handle
              StringBuilder Title = new StringBuilder((int)WinApis.MAX_PATH);
              WinApis.RealGetWindowClass(Hwnd, Title, (int)WinApis.MAX_PATH);
  
              return Title.ToString().Trim();
          }
  
          public static FILETIME DateTimeToFiletime(DateTime time)
          {
              FILETIME ft;
              long hFT1 = time.ToFileTimeUtc();
              ft.dwLowDateTime = (uint)(hFT1 & 0xFFFFFFFF);
              ft.dwHighDateTime = (uint)(hFT1 >> 32);
              return ft;
          }
  
          public static DateTime FiletimeToDateTime(FILETIME fileTime)
          {
              if ((fileTime.dwHighDateTime == Int32.MaxValue) ||
                  (fileTime.dwHighDateTime == 0 && fileTime.dwLowDateTime == 0))
              {
                  // Not going to fit in the DateTime.  In the WinInet APIs, this is
                  // what happens when there is no FILETIME attached to the cache entry.
                  // We're going to use DateTime.MinValue as a marker for this case.
                  return DateTime.MaxValue;
              }
              //long hFT2 = (((long)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
              //return DateTime.FromFileTimeUtc(hFT2);
  
              SYSTEMTIME syst = new SYSTEMTIME();
              SYSTEMTIME systLocal = new SYSTEMTIME();
              if (0 == FileTimeToSystemTime(ref fileTime, ref syst))
              {
                  throw new ApplicationException("Error calling FileTimeToSystemTime: " + Marshal.GetLastWin32Error().ToString());
              }
              if (0 == SystemTimeToTzSpecificLocalTime(IntPtr.Zero, ref syst, out systLocal))
              {
                  throw new ApplicationException("Error calling SystemTimeToTzSpecificLocalTime: " + Marshal.GetLastWin32Error().ToString());
              }
              return new DateTime(systLocal.Year, systLocal.Month, systLocal.Day, systLocal.Hour, systLocal.Minute, systLocal.Second);
          }
  
          public static string ToStringFromFileTime(FILETIME ft)
          {
              DateTime dt = FiletimeToDateTime(ft);
              if (dt == DateTime.MinValue)
              {
                  return string.Empty;
              }
  
              return dt.ToString();
          }
  
          /// <summary>
          /// UrlCache functionality is taken from:
          /// Scott McMaster (smcmaste@hotmail.com)
          /// CodeProject article
          /// 
          /// There were some issues with preparing URLs
          /// for RegExp to work properly. This is
          /// demonstrated in AllForms.SetupCookieCachePattern method
          /// 
          /// urlPattern:
          /// . Dump the entire contents of the cache.
          /// Cookie: Lists all cookies on the system.
          /// Visited: Lists all of the history items.
          /// Cookie:.*\.example\.com Lists cookies from the example.com domain.
          /// http://www.example.com/example.html$: Lists the specific named file if present
          /// \.example\.com: Lists any and all entries from *.example.com.
          /// \.example\.com.*\.gif$: Lists the .gif files from *.example.com.
          /// \.js$: Lists the .js files in the cache.
          /// </summary>
          /// <param name="urlPattern"></param>
          /// <returns></returns>
          public static ArrayList FindUrlCacheEntries(string urlPattern)
          {
              ArrayList results = new ArrayList();
  
              IntPtr buffer = IntPtr.Zero;
              UInt32 structSize;
  
              //This call will fail but returns the size required in structSize
              //to allocate necessary buffer
              IntPtr hEnum = FindFirstUrlCacheEntry(null, buffer, out structSize);
              try
              {
                  if (hEnum == IntPtr.Zero)
                  {
                      int lastError = Marshal.GetLastWin32Error();
                      if (lastError == Hresults.ERROR_INSUFFICIENT_BUFFER)
                      {
                          //Allocate buffer
                          buffer = Marshal.AllocHGlobal((int)structSize);
                          //Call again, this time it should succeed
                          hEnum = FindFirstUrlCacheEntry(urlPattern, buffer, out structSize);
                      }
                      else if (lastError == Hresults.ERROR_NO_MORE_ITEMS)
                      {
                          return results;
                      }
                  }
  
                  INTERNET_CACHE_ENTRY_INFO result = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(buffer, typeof(INTERNET_CACHE_ENTRY_INFO));
                  try
                  {
                      if (Regex.IsMatch(result.lpszSourceUrlName, urlPattern, RegexOptions.IgnoreCase))
                      {
                          results.Add(result);
                      }
                  }
                  catch (ArgumentException ae)
                  {
                      throw new ApplicationException("Invalid regular expression, details=" + ae.Message);
                  }
  
                  if (buffer != IntPtr.Zero)
                  {
                      try { Marshal.FreeHGlobal(buffer); }
                      catch { }
                      buffer = IntPtr.Zero;
                      structSize = 0;
                  }
  
                  //Loop through all entries, attempt to find matches
                  while (true)
                  {
                      long nextResult = FindNextUrlCacheEntry(hEnum, buffer, out structSize);
                      if (nextResult != 1) //TRUE
                      {
                          int lastError = Marshal.GetLastWin32Error();
                          if (lastError == Hresults.ERROR_INSUFFICIENT_BUFFER)
                          {
                              buffer = Marshal.AllocHGlobal((int)structSize);
                              nextResult = FindNextUrlCacheEntry(hEnum, buffer, out structSize);
                          }
                          else if (lastError == Hresults.ERROR_NO_MORE_ITEMS)
                          {
                              break;
                          }
                      }
  
                      result = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(buffer, typeof(INTERNET_CACHE_ENTRY_INFO));
                      if (Regex.IsMatch(result.lpszSourceUrlName, urlPattern, RegexOptions.IgnoreCase))
                      {
                          results.Add(result);
                      }
  
                      if (buffer != IntPtr.Zero)
                      {
                          try { Marshal.FreeHGlobal(buffer); }
                          catch { }
                          buffer = IntPtr.Zero;
                          structSize = 0;
                      }
                  }
              }
              finally
              {
                  if (hEnum != IntPtr.Zero)
                  {
                      FindCloseUrlCache(hEnum);
                  }
                  if (buffer != IntPtr.Zero)
                  {
                      try { Marshal.FreeHGlobal(buffer); }
                      catch { }
                  }
              }
  
              return results;
          }
  
          /// <summary>
          /// Attempts to delete a cookie or cache entry
          /// </summary>
          /// <param name="url">INTERNET_CACHE_ENTRY_INFO.lpszSourceUrlName</param>
          public static void DeleteFromUrlCache(string url)
          {
              long apiResult = DeleteUrlCacheEntry(url);
              if (apiResult != 0)
              {
                  return;
              }
  
              int lastError = Marshal.GetLastWin32Error();
              if (lastError == Hresults.ERROR_ACCESS_DENIED)
              {
                  throw new ApplicationException("Access denied: " + url);
              }
              else
              {
                  throw new ApplicationException("Insufficient buffer: " + url);
              }
          }
  
          #endregion
  
          [DllImport("user32.dll")]
          public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
             UIntPtr dwExtraInfo);
  
          [DllImport("shell32.dll", CharSet = CharSet.Auto)]
          public static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex);
  
          [DllImport("user32.dll")]
          public static extern bool DestroyIcon(IntPtr hIcon);
  
          [DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
          public static extern int CallWindowProc(
              IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
  
          [DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
          public static extern IntPtr SetWindowLong(
              IntPtr hWnd, int nIndex, IntPtr newProc);
  
          [DllImport("ole32.dll", SetLastError = true,
          ExactSpelling = true, CharSet = CharSet.Auto)]
          public static extern int RevokeObjectParam(
              [In, MarshalAs(UnmanagedType.LPWStr)] string pszKey);
  
          //[DllImport("urlmon.dll", SetLastError = true)]
          //public static extern int RegisterBindStatusCallback(
          //    [MarshalAs(UnmanagedType.Interface)] IBindCtx pBc,
          //    [MarshalAs(UnmanagedType.Interface)] DownloadManagerImpl.IBindStatusCallback pBSCb,
          //    [Out, MarshalAs(UnmanagedType.Interface)] out IBindStatusCallback ppBSCBPrev,
          //    [In, MarshalAs(UnmanagedType.U4)] UInt32 dwReserved); 
  
          //[DllImport("user32.dll", SetLastError = true)]
          //public static extern int GetClipboardFormatName(uint format, [Out] StringBuilder
          //   lpszFormatName, int cchMaxCount);
  
          [DllImport("user32.dll", SetLastError = true)]
          public static extern IntPtr GetWindowDC(IntPtr hWnd);
  
          //MSDN
          //This function should no longer be used. Use the CoTaskMemFree and CoTaskMemAlloc functions in its place.
          [DllImport("shell32.dll", SetLastError = true)]
          public static extern int SHGetMalloc(out IMalloc ppMalloc);
  
          [DllImport("gdi32.dll", SetLastError = true)]
          public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth,
             int nHeight);
  
          [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
          public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
  
          [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
          public static extern bool DeleteDC(IntPtr hdc);
  
          [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
          public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
  
          [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
          public static extern bool DeleteObject(IntPtr hObject);
  
          [DllImport("gdi32.dll", SetLastError = true)]
          public static extern bool SetStretchBltMode(IntPtr hdc, StretchMode iStretchMode);
  
          [DllImport("gdi32.dll", SetLastError = true)]
          public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
              int nWidth, int nHeight,
              IntPtr hObjSource, int nXSrc, int nYSrc,
              TernaryRasterOperations dwRop);
  
          [DllImport("gdi32.dll", SetLastError = true)]
          public static extern bool StretchBlt(IntPtr hdcDest, int nXDest, int nYDest,
              int nWidthDest, int nHeightDest,
              IntPtr hdcSrc, int nXSrc, int nYSrc, int nWidthSrc, int nHeightSrc,
              TernaryRasterOperations dwRop);
  
          [DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
          public static extern int CreateBindCtx(
              [MarshalAs(UnmanagedType.U4)] uint dwReserved,
              [Out, MarshalAs(UnmanagedType.Interface)] out IBindCtx ppbc);
  
          [DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
          public static extern int CreateAsyncBindCtx(
              [MarshalAs(UnmanagedType.U4)] uint dwReserved,
              [MarshalAs(UnmanagedType.Interface)] IBindStatusCallback pbsc,
              [MarshalAs(UnmanagedType.Interface)] IEnumFORMATETC penumfmtetc,
              [Out, MarshalAs(UnmanagedType.Interface)] out IBindCtx ppbc);
  
          [DllImport("urlmon.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
          public static extern int CreateURLMoniker(
              [MarshalAs(UnmanagedType.Interface)] IMoniker pmkContext,
              [MarshalAs(UnmanagedType.LPWStr)] string szURL,
              [Out, MarshalAs(UnmanagedType.Interface)] out IMoniker ppmk);
  
          public const uint URL_MK_LEGACY = 0;
          public const uint URL_MK_UNIFORM = 1;
          public const uint URL_MK_NO_CANONICALIZE = 2;
          [DllImport("urlmon.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
          public static extern int CreateURLMonikerEx(
              [MarshalAs(UnmanagedType.Interface)] IMoniker pmkContext,
              [MarshalAs(UnmanagedType.LPWStr)] string szURL,
              [Out, MarshalAs(UnmanagedType.Interface)] out IMoniker ppmk,
              uint URL_MK_XXX); //Flags, one of 
  
          [DllImport("user32.dll", CharSet = CharSet.Auto)]
          public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg,
              IntPtr wParam, IntPtr lParam);
  
          [DllImport("user32.dll", CharSet = CharSet.Auto)]
          public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg,
              IntPtr wParam, ref StringBuilder lParam);
  
          [DllImport("user32.dll", CharSet = CharSet.Auto)]
          public static extern void SendMessage(HandleRef hWnd, uint msg,
              IntPtr wParam, ref tagRECT lParam);
  
          [DllImport("user32.dll", CharSet = CharSet.Auto)]
          public static extern IntPtr SendMessage(HandleRef hWnd, uint msg,
              IntPtr wParam, ref tagPOINT lParam);
  
  
gt:         [DllImport("ole32.dll", CharSet = CharSet.Auto)]