Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / UIAutomation / UIAutomationClient / MS / Internal / Automation / Misc.cs / 1 / Misc.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Miscellaneous helper routines // // History: // 06/04/2003 : BrendanM Ported to WCP // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using Microsoft.Win32.SafeHandles; using MS.Win32; using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Provider; namespace MS.Internal.Automation { // Helper class that contains methods/utilities that don't really belong anywhere else, // or don't justify a class of their own. internal static class Misc { // Static class, so no ctor //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods #region Element Comparisons // compare two arrays internal static bool Compare(int[] a1, int[] a2) { CheckNonNull(a1, a2); int l = a1.Length; if (l != a2.Length) return false; for (int i = 0; i < l; i++) { if (a1[i] != a2[i]) { return false; } } return true; } // compare two AutomationElements internal static bool Compare(AutomationElement el1, AutomationElement el2) { CheckNonNull(el1, el2); return Compare(el1.GetRuntimeId(), el2.GetRuntimeId()); } #endregion Element Comparisons #region Array combination // Concantenate arrays from a collection of arrays internal static Array CombineArrays(IEnumerable arrays, Type t) { int totalLength = 0; foreach (Array a in arrays) { totalLength += a.Length; } Array combined = Array.CreateInstance(t, totalLength); int pos = 0; foreach (Array a in arrays) { int l = a.Length; Array.Copy(a, 0, combined, pos, l); pos += l; } return combined; } // return an array with duplicate elements removed. Has side-effect of sorting array; // therefore elements must be sortable (IComparable) internal static Array RemoveDuplicates(Array a, Type t) { if (a.Length == 0) return a; Array.Sort(a); // Remove duplicate elements by selective copy-to-self... int dest = 0; for (int src = 1; src < a.Length; src++) { if (!a.GetValue(src).Equals(a.GetValue(dest))) { dest++; a.SetValue(a.GetValue(src), dest); } } // dest was the index of the last item, now use it as the length by adding one. int newLength = dest + 1; if (newLength == a.Length) { // No duplicates found - just return as-is return a; } else { // Return shorter array Array a2 = Array.CreateInstance(t, newLength); Array.Copy(a, 0, a2, 0, newLength); return a2; } } #endregion Array combination #region Interface & Property Wrapping // Wrap pattern interface on client side, before handing to client - ie. create a client-side pattern wrapper internal static object WrapInterfaceOnClientSide(AutomationElement el, SafePatternHandle hPattern, AutomationPattern pattern) { if (hPattern.IsInvalid) return null; AutomationPatternInfo pi; if (!Schema.GetPatternInfo(pattern, out pi)) { throw new ArgumentException(SR.Get(SRID.UnsupportedPattern)); } if (pi.ClientSideWrapper == null) { Debug.Assert(false, "missing client-side pattern wrapper"); return null; } else { // false -> not cached. (Cached goes via AutomationElement.GetCachedPattern, not here) return pi.ClientSideWrapper(el, hPattern, false); } } #endregion Interface & Property Wrapping #region Param validation & Error related // Check that specified argument is non-null, if so, throw exception internal static void ValidateArgumentNonNull(object obj, string argName) { if (obj == null) { throw new ArgumentNullException(argName); } } // Throw an argument Exception with a generic error internal static void ThrowInvalidArgument(string argName) { throw new ArgumentException(SR.Get(SRID.GenericInvalidArgument, argName)); } // Check that specified condition is true; if not, throw exception internal static void ValidateArgument(bool cond, string reason) { if (!cond) { throw new ArgumentException(SR.Get(reason)); } } // Check that specified condition is true; if not, throw exception internal static void ValidateArgumentInRange(bool cond, string argName) { if (!cond) { throw new ArgumentOutOfRangeException(argName); } } // Called by the patterns before accessing .Cache internal static void ValidateCached(bool cached) { if (!cached) { throw new InvalidOperationException(SR.Get(SRID.CacheRequestNeedCache)); } } // Called by the patterns before accessing .Current internal static void ValidateCurrent(SafePatternHandle hPattern) { if (hPattern.IsInvalid) { throw new InvalidOperationException(SR.Get(SRID.CacheRequestNeedLiveForProperties)); } } // Call IsCriticalException w/in a catch-all-exception handler to allow critical exceptions // to be thrown (this is copied from exception handling code in WinForms but feel free to // add new critical exceptions). Usage: // try // { // Somecode(); // } // catch (Exception e) // { // if (Misc.IsCriticalException(e)) // throw; // // ignore non-critical errors from external code // } internal static bool IsCriticalException( Exception e ) { return e is NullReferenceException || e is StackOverflowException || e is OutOfMemoryException || e is System.Threading.ThreadAbortException; } internal static bool IsWindowsFormsControl(string className) { return className.IndexOf("windowsforms", StringComparison.OrdinalIgnoreCase) > -1; } internal static void ThrowWin32ExceptionsIfError(int errorCode) { switch (errorCode) { case 0: // 0 ERROR_SUCCESS The operation completed successfully. // The error code indicates that there is no error, so do not throw an exception. break; case 6: // 6 ERROR_INVALID_HANDLE The handle is invalid. case 1400: // 1400 ERROR_INVALID_WINDOW_HANDLE Invalid window handle. case 1401: // 1401 ERROR_INVALID_MENU_HANDLE Invalid menu handle. case 1402: // 1402 ERROR_INVALID_CURSOR_HANDLE Invalid cursor handle. case 1403: // 1403 ERROR_INVALID_ACCEL_HANDLE Invalid accelerator table handle. case 1404: // 1404 ERROR_INVALID_HOOK_HANDLE Invalid hook handle. case 1405: // 1405 ERROR_INVALID_DWP_HANDLE Invalid handle to a multiple-window position structure. case 1406: // 1406 ERROR_TLW_WITH_WSCHILD Cannot create a top-level child window. case 1407: // 1407 ERROR_CANNOT_FIND_WND_CLASS Cannot find window class. case 1408: // 1408 ERROR_WINDOW_OF_OTHER_THREAD Invalid window; it belongs to other thread. throw new ElementNotAvailableException(); // We're getting this in AMD64 when calling RealGetWindowClass; adding this code // to allow the DRTs to pass while we continue investigation. case 87: // 87 ERROR_INVALID_PARAMETER throw new ElementNotAvailableException(); case 8: // 8 ERROR_NOT_ENOUGH_MEMORY Not enough storage is available to process this command. case 14: // 14 ERROR_OUTOFMEMORY Not enough storage is available to complete this operation. throw new OutOfMemoryException(); case 998: // 998 ERROR_NOACCESS Invalid access to memory location. throw new InvalidOperationException(); default: // Not sure how to map the reset of the error codes so throw generic Win32Exception. throw new Win32Exception(errorCode); } } #endregion Param validation & Error related #region Misc internal static IntPtr CreateRectRgn(int left, int top, int right, int bottom) { IntPtr result = SafeNativeMethods.CreateRectRgn(left, top, right, bottom); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == IntPtr.Zero) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool CloseHandle(IntPtr handle) { bool result = UnsafeNativeMethods.CloseHandle(handle); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool DeleteObject(IntPtr hrgn) { bool result = UnsafeNativeMethods.DeleteObject(hrgn); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetClientRect(NativeMethods.HWND hwnd, out NativeMethods.RECT rc) { bool result = SafeNativeMethods.GetClientRect(hwnd, out rc); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetGUIThreadInfo(int idThread, ref SafeNativeMethods.GUITHREADINFO guiThreadInfo) { guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo); bool result = SafeNativeMethods.GetGUIThreadInfo(0, ref guiThreadInfo); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { // If the focused thread is on another [secure] desktop, GetGUIThreadInfo // will fail with ERROR_ACCESS_DENIED - don't throw an exception for that case, // instead treat as a failure. Callers will treat this as though no window has // focus. if (lastWin32Error == 5 /*ERROR_ACCESS_DENIED*/) return false; ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetMenuBarInfo(NativeMethods.HWND hwnd, int idObject, uint item, ref UnsafeNativeMethods.MENUBARINFO mbi) { bool result = UnsafeNativeMethods.GetMenuBarInfo(hwnd, idObject, item, ref mbi); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetModuleFileNameEx(MS.Internal.Automation.SafeProcessHandle hProcess, IntPtr hModule, StringBuilder buffer, int length) { int result = SafeNativeMethods.GetModuleFileNameEx(hProcess, hModule, buffer, length); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetMessage(ref UnsafeNativeMethods.MSG msg, NativeMethods.HWND hwnd, int nMsgFilterMin, int nMsgFilterMax) { int result = UnsafeNativeMethods.GetMessage(ref msg, hwnd, nMsgFilterMin, nMsgFilterMax); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == -1) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static NativeMethods.HWND GetWindow(NativeMethods.HWND hwnd, int uCmd) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); NativeMethods.HWND result = SafeNativeMethods.GetWindow(hwnd, uCmd); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == NativeMethods.HWND.NULL) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetWindowLong(NativeMethods.HWND hWnd, int nIndex) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); int result = SafeNativeMethods.GetWindowLong(hWnd, nIndex); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetWindowPlacement(NativeMethods.HWND hwnd, ref UnsafeNativeMethods.WINDOWPLACEMENT wp) { bool result = UnsafeNativeMethods.GetWindowPlacement(hwnd, ref wp); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetWindowRect(NativeMethods.HWND hwnd, out NativeMethods.RECT rc) { bool result = SafeNativeMethods.GetWindowRect(hwnd, out rc); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static short GlobalAddAtom(string lpString) { short result = SafeNativeMethods.GlobalAddAtom(lpString); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static short GlobalDeleteAtom(short atom) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); short result = SafeNativeMethods.GlobalDeleteAtom(atom); ThrowWin32ExceptionsIfError(Marshal.GetLastWin32Error()); return result; } [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)] internal static int TryMsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask, ref int lastWin32Error) { int terminationEvent; if (handle == null) { terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(0, null, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } else { RuntimeHelpers.PrepareConstrainedRegions(); bool fRelease = false; try { handle.DangerousAddRef(ref fRelease); IntPtr[] handles = { handle.DangerousGetHandle() }; terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(1, handles, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } finally { if (fRelease) { handle.DangerousRelease(); } } } return terminationEvent; } internal static int MsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask) { int lastWin32Error = 0; int terminationEvent = TryMsgWaitForMultipleObjects(handle, waitAll, milliseconds, wakeMask, ref lastWin32Error); if (terminationEvent == UnsafeNativeMethods.WAIT_FAILED) { ThrowWin32ExceptionsIfError(lastWin32Error); } return terminationEvent; } internal static IntPtr OpenProcess(int dwDesiredAccess, bool fInherit, int dwProcessId, NativeMethods.HWND hwnd) { IntPtr processHandle = UnsafeNativeMethods.OpenProcess(dwDesiredAccess, fInherit, dwProcessId); int lastWin32Error = Marshal.GetLastWin32Error(); // If we fail due to permission issues, if we're on vista, try the hooking technique // to access the process instead. if (processHandle == IntPtr.Zero && lastWin32Error == 5/*ERROR_ACCESS_DENIED*/ && System.Environment.OSVersion.Version.Major >= 6) { try { processHandle = UnsafeNativeMethods.GetProcessHandleFromHwnd(hwnd.h); lastWin32Error = Marshal.GetLastWin32Error(); } catch(EntryPointNotFoundException) { // Ignore; until OLEACC propogates into Vista builds, the entry point may not be present. } } if (processHandle == IntPtr.Zero) { ThrowWin32ExceptionsIfError(lastWin32Error); } return processHandle; } internal static bool PostMessage(NativeMethods.HWND hWnd, int nMsg, IntPtr wParam, IntPtr lParam) { bool result = UnsafeNativeMethods.PostMessage(hWnd, nMsg, wParam, lParam); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool RegisterHotKey(NativeMethods.HWND hWnd, int id, int fsModifiers, int vk) { bool result = UnsafeNativeMethods.RegisterHotKey(hWnd, id, fsModifiers, vk); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int SendInput(int nInputs, ref UnsafeNativeMethods.INPUT mi, int cbSize) { int result = UnsafeNativeMethods.SendInput(nInputs, ref mi, cbSize); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, IntPtr lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, ref UnsafeNativeMethods.MINMAXINFO lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, ref lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, StringBuilder lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static bool SetWindowPlacement(NativeMethods.HWND hwnd, ref UnsafeNativeMethods.WINDOWPLACEMENT wp) { bool result = UnsafeNativeMethods.SetWindowPlacement(hwnd, ref wp); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool SetWindowPos(NativeMethods.HWND hWnd, NativeMethods.HWND hWndInsertAfter, int x, int y, int cx, int cy, int flags) { bool result = UnsafeNativeMethods.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, flags); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool UnregisterHotKey(NativeMethods.HWND hWnd, int id) { bool result = UnsafeNativeMethods.UnregisterHotKey(hWnd, id); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } // this strips the mnemonic prefix for short cuts as well as leading spaces // If we find && leave one & there. internal static string StripMnemonic(string s) { // If there are no spaces or & then it's ok just return it if (string.IsNullOrEmpty(s) || s.IndexOfAny(new char[2] { ' ', '&' }) < 0) { return s; } char[] ach = s.ToCharArray(); bool amper = false; bool leadingSpace = false; int dest = 0; for (int source = 0; source < ach.Length; source++) { // get rid of leading spaces if (ach[source] == ' ' && leadingSpace == false) { continue; } else { leadingSpace = true; } // get rid of & if (ach[source] == '&' && amper == false) { amper = true; } else { ach[dest++] = ach[source]; } } return new string(ach, 0, dest); } #endregion Misc #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- #region Private Methods // Helper used by the various comparison functions above private static void CheckNonNull(object el1, object el2) { if (el1 == null) throw new ArgumentNullException("el1"); if (el2 == null) throw new ArgumentNullException("el2"); } //This function throws corresponding exception depending on the last error. private static void EvaluateSendMessageTimeoutError(int error) { // SendMessageTimeout Function // If the function fails or times out, the return value is zero. To get extended error information, // call GetLastError. If GetLastError returns zero, then the function timed out. // NOTE: The GetLastError after a SendMessageTimeout my also be an ERROR_TIMEOUT depending on the // message. // 1460 This operation returned because the timeout period expired. ERROR_TIMEOUT if (error == 0 || error == 1460) { throw new TimeoutException(); } else { ThrowWin32ExceptionsIfError(error); } } #endregion Private Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Miscellaneous helper routines // // History: // 06/04/2003 : BrendanM Ported to WCP // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using Microsoft.Win32.SafeHandles; using MS.Win32; using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Provider; namespace MS.Internal.Automation { // Helper class that contains methods/utilities that don't really belong anywhere else, // or don't justify a class of their own. internal static class Misc { // Static class, so no ctor //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods #region Element Comparisons // compare two arrays internal static bool Compare(int[] a1, int[] a2) { CheckNonNull(a1, a2); int l = a1.Length; if (l != a2.Length) return false; for (int i = 0; i < l; i++) { if (a1[i] != a2[i]) { return false; } } return true; } // compare two AutomationElements internal static bool Compare(AutomationElement el1, AutomationElement el2) { CheckNonNull(el1, el2); return Compare(el1.GetRuntimeId(), el2.GetRuntimeId()); } #endregion Element Comparisons #region Array combination // Concantenate arrays from a collection of arrays internal static Array CombineArrays(IEnumerable arrays, Type t) { int totalLength = 0; foreach (Array a in arrays) { totalLength += a.Length; } Array combined = Array.CreateInstance(t, totalLength); int pos = 0; foreach (Array a in arrays) { int l = a.Length; Array.Copy(a, 0, combined, pos, l); pos += l; } return combined; } // return an array with duplicate elements removed. Has side-effect of sorting array; // therefore elements must be sortable (IComparable) internal static Array RemoveDuplicates(Array a, Type t) { if (a.Length == 0) return a; Array.Sort(a); // Remove duplicate elements by selective copy-to-self... int dest = 0; for (int src = 1; src < a.Length; src++) { if (!a.GetValue(src).Equals(a.GetValue(dest))) { dest++; a.SetValue(a.GetValue(src), dest); } } // dest was the index of the last item, now use it as the length by adding one. int newLength = dest + 1; if (newLength == a.Length) { // No duplicates found - just return as-is return a; } else { // Return shorter array Array a2 = Array.CreateInstance(t, newLength); Array.Copy(a, 0, a2, 0, newLength); return a2; } } #endregion Array combination #region Interface & Property Wrapping // Wrap pattern interface on client side, before handing to client - ie. create a client-side pattern wrapper internal static object WrapInterfaceOnClientSide(AutomationElement el, SafePatternHandle hPattern, AutomationPattern pattern) { if (hPattern.IsInvalid) return null; AutomationPatternInfo pi; if (!Schema.GetPatternInfo(pattern, out pi)) { throw new ArgumentException(SR.Get(SRID.UnsupportedPattern)); } if (pi.ClientSideWrapper == null) { Debug.Assert(false, "missing client-side pattern wrapper"); return null; } else { // false -> not cached. (Cached goes via AutomationElement.GetCachedPattern, not here) return pi.ClientSideWrapper(el, hPattern, false); } } #endregion Interface & Property Wrapping #region Param validation & Error related // Check that specified argument is non-null, if so, throw exception internal static void ValidateArgumentNonNull(object obj, string argName) { if (obj == null) { throw new ArgumentNullException(argName); } } // Throw an argument Exception with a generic error internal static void ThrowInvalidArgument(string argName) { throw new ArgumentException(SR.Get(SRID.GenericInvalidArgument, argName)); } // Check that specified condition is true; if not, throw exception internal static void ValidateArgument(bool cond, string reason) { if (!cond) { throw new ArgumentException(SR.Get(reason)); } } // Check that specified condition is true; if not, throw exception internal static void ValidateArgumentInRange(bool cond, string argName) { if (!cond) { throw new ArgumentOutOfRangeException(argName); } } // Called by the patterns before accessing .Cache internal static void ValidateCached(bool cached) { if (!cached) { throw new InvalidOperationException(SR.Get(SRID.CacheRequestNeedCache)); } } // Called by the patterns before accessing .Current internal static void ValidateCurrent(SafePatternHandle hPattern) { if (hPattern.IsInvalid) { throw new InvalidOperationException(SR.Get(SRID.CacheRequestNeedLiveForProperties)); } } // Call IsCriticalException w/in a catch-all-exception handler to allow critical exceptions // to be thrown (this is copied from exception handling code in WinForms but feel free to // add new critical exceptions). Usage: // try // { // Somecode(); // } // catch (Exception e) // { // if (Misc.IsCriticalException(e)) // throw; // // ignore non-critical errors from external code // } internal static bool IsCriticalException( Exception e ) { return e is NullReferenceException || e is StackOverflowException || e is OutOfMemoryException || e is System.Threading.ThreadAbortException; } internal static bool IsWindowsFormsControl(string className) { return className.IndexOf("windowsforms", StringComparison.OrdinalIgnoreCase) > -1; } internal static void ThrowWin32ExceptionsIfError(int errorCode) { switch (errorCode) { case 0: // 0 ERROR_SUCCESS The operation completed successfully. // The error code indicates that there is no error, so do not throw an exception. break; case 6: // 6 ERROR_INVALID_HANDLE The handle is invalid. case 1400: // 1400 ERROR_INVALID_WINDOW_HANDLE Invalid window handle. case 1401: // 1401 ERROR_INVALID_MENU_HANDLE Invalid menu handle. case 1402: // 1402 ERROR_INVALID_CURSOR_HANDLE Invalid cursor handle. case 1403: // 1403 ERROR_INVALID_ACCEL_HANDLE Invalid accelerator table handle. case 1404: // 1404 ERROR_INVALID_HOOK_HANDLE Invalid hook handle. case 1405: // 1405 ERROR_INVALID_DWP_HANDLE Invalid handle to a multiple-window position structure. case 1406: // 1406 ERROR_TLW_WITH_WSCHILD Cannot create a top-level child window. case 1407: // 1407 ERROR_CANNOT_FIND_WND_CLASS Cannot find window class. case 1408: // 1408 ERROR_WINDOW_OF_OTHER_THREAD Invalid window; it belongs to other thread. throw new ElementNotAvailableException(); // We're getting this in AMD64 when calling RealGetWindowClass; adding this code // to allow the DRTs to pass while we continue investigation. case 87: // 87 ERROR_INVALID_PARAMETER throw new ElementNotAvailableException(); case 8: // 8 ERROR_NOT_ENOUGH_MEMORY Not enough storage is available to process this command. case 14: // 14 ERROR_OUTOFMEMORY Not enough storage is available to complete this operation. throw new OutOfMemoryException(); case 998: // 998 ERROR_NOACCESS Invalid access to memory location. throw new InvalidOperationException(); default: // Not sure how to map the reset of the error codes so throw generic Win32Exception. throw new Win32Exception(errorCode); } } #endregion Param validation & Error related #region Misc internal static IntPtr CreateRectRgn(int left, int top, int right, int bottom) { IntPtr result = SafeNativeMethods.CreateRectRgn(left, top, right, bottom); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == IntPtr.Zero) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool CloseHandle(IntPtr handle) { bool result = UnsafeNativeMethods.CloseHandle(handle); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool DeleteObject(IntPtr hrgn) { bool result = UnsafeNativeMethods.DeleteObject(hrgn); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetClientRect(NativeMethods.HWND hwnd, out NativeMethods.RECT rc) { bool result = SafeNativeMethods.GetClientRect(hwnd, out rc); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetGUIThreadInfo(int idThread, ref SafeNativeMethods.GUITHREADINFO guiThreadInfo) { guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo); bool result = SafeNativeMethods.GetGUIThreadInfo(0, ref guiThreadInfo); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { // If the focused thread is on another [secure] desktop, GetGUIThreadInfo // will fail with ERROR_ACCESS_DENIED - don't throw an exception for that case, // instead treat as a failure. Callers will treat this as though no window has // focus. if (lastWin32Error == 5 /*ERROR_ACCESS_DENIED*/) return false; ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetMenuBarInfo(NativeMethods.HWND hwnd, int idObject, uint item, ref UnsafeNativeMethods.MENUBARINFO mbi) { bool result = UnsafeNativeMethods.GetMenuBarInfo(hwnd, idObject, item, ref mbi); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetModuleFileNameEx(MS.Internal.Automation.SafeProcessHandle hProcess, IntPtr hModule, StringBuilder buffer, int length) { int result = SafeNativeMethods.GetModuleFileNameEx(hProcess, hModule, buffer, length); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetMessage(ref UnsafeNativeMethods.MSG msg, NativeMethods.HWND hwnd, int nMsgFilterMin, int nMsgFilterMax) { int result = UnsafeNativeMethods.GetMessage(ref msg, hwnd, nMsgFilterMin, nMsgFilterMax); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == -1) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static NativeMethods.HWND GetWindow(NativeMethods.HWND hwnd, int uCmd) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); NativeMethods.HWND result = SafeNativeMethods.GetWindow(hwnd, uCmd); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == NativeMethods.HWND.NULL) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int GetWindowLong(NativeMethods.HWND hWnd, int nIndex) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); int result = SafeNativeMethods.GetWindowLong(hWnd, nIndex); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetWindowPlacement(NativeMethods.HWND hwnd, ref UnsafeNativeMethods.WINDOWPLACEMENT wp) { bool result = UnsafeNativeMethods.GetWindowPlacement(hwnd, ref wp); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool GetWindowRect(NativeMethods.HWND hwnd, out NativeMethods.RECT rc) { bool result = SafeNativeMethods.GetWindowRect(hwnd, out rc); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static short GlobalAddAtom(string lpString) { short result = SafeNativeMethods.GlobalAddAtom(lpString); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static short GlobalDeleteAtom(short atom) { // The failure case of this API may also be a valid return. GetLastError() is need to determine a true failure state. // Clear the last error code to make sure we have a good starting condition to determine error state. UnsafeNativeMethods.SetLastError(0); short result = SafeNativeMethods.GlobalDeleteAtom(atom); ThrowWin32ExceptionsIfError(Marshal.GetLastWin32Error()); return result; } [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)] internal static int TryMsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask, ref int lastWin32Error) { int terminationEvent; if (handle == null) { terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(0, null, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } else { RuntimeHelpers.PrepareConstrainedRegions(); bool fRelease = false; try { handle.DangerousAddRef(ref fRelease); IntPtr[] handles = { handle.DangerousGetHandle() }; terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(1, handles, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } finally { if (fRelease) { handle.DangerousRelease(); } } } return terminationEvent; } internal static int MsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask) { int lastWin32Error = 0; int terminationEvent = TryMsgWaitForMultipleObjects(handle, waitAll, milliseconds, wakeMask, ref lastWin32Error); if (terminationEvent == UnsafeNativeMethods.WAIT_FAILED) { ThrowWin32ExceptionsIfError(lastWin32Error); } return terminationEvent; } internal static IntPtr OpenProcess(int dwDesiredAccess, bool fInherit, int dwProcessId, NativeMethods.HWND hwnd) { IntPtr processHandle = UnsafeNativeMethods.OpenProcess(dwDesiredAccess, fInherit, dwProcessId); int lastWin32Error = Marshal.GetLastWin32Error(); // If we fail due to permission issues, if we're on vista, try the hooking technique // to access the process instead. if (processHandle == IntPtr.Zero && lastWin32Error == 5/*ERROR_ACCESS_DENIED*/ && System.Environment.OSVersion.Version.Major >= 6) { try { processHandle = UnsafeNativeMethods.GetProcessHandleFromHwnd(hwnd.h); lastWin32Error = Marshal.GetLastWin32Error(); } catch(EntryPointNotFoundException) { // Ignore; until OLEACC propogates into Vista builds, the entry point may not be present. } } if (processHandle == IntPtr.Zero) { ThrowWin32ExceptionsIfError(lastWin32Error); } return processHandle; } internal static bool PostMessage(NativeMethods.HWND hWnd, int nMsg, IntPtr wParam, IntPtr lParam) { bool result = UnsafeNativeMethods.PostMessage(hWnd, nMsg, wParam, lParam); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool RegisterHotKey(NativeMethods.HWND hWnd, int id, int fsModifiers, int vk) { bool result = UnsafeNativeMethods.RegisterHotKey(hWnd, id, fsModifiers, vk); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static int SendInput(int nInputs, ref UnsafeNativeMethods.INPUT mi, int cbSize) { int result = UnsafeNativeMethods.SendInput(nInputs, ref mi, cbSize); int lastWin32Error = Marshal.GetLastWin32Error(); if (result == 0) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, IntPtr lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, ref UnsafeNativeMethods.MINMAXINFO lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, ref lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static IntPtr SendMessageTimeout(NativeMethods.HWND hwnd, int Msg, IntPtr wParam, StringBuilder lParam) { // Use a timeout of 10 seconds. // Don't use the SMTO_ABORTIFHUNG flag - windows if often too quick to think that an app is hung - eg only a couple of // seconds or less - many apps recover from this. IntPtr lresult; IntPtr smtoRetVal = UnsafeNativeMethods.SendMessageTimeout(hwnd, Msg, wParam, lParam, 0, 10000, out lresult); int lastWin32Error = Marshal.GetLastWin32Error(); if (smtoRetVal == IntPtr.Zero) { EvaluateSendMessageTimeoutError(lastWin32Error); } return lresult; } internal static bool SetWindowPlacement(NativeMethods.HWND hwnd, ref UnsafeNativeMethods.WINDOWPLACEMENT wp) { bool result = UnsafeNativeMethods.SetWindowPlacement(hwnd, ref wp); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool SetWindowPos(NativeMethods.HWND hWnd, NativeMethods.HWND hWndInsertAfter, int x, int y, int cx, int cy, int flags) { bool result = UnsafeNativeMethods.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, flags); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } internal static bool UnregisterHotKey(NativeMethods.HWND hWnd, int id) { bool result = UnsafeNativeMethods.UnregisterHotKey(hWnd, id); int lastWin32Error = Marshal.GetLastWin32Error(); if (!result) { ThrowWin32ExceptionsIfError(lastWin32Error); } return result; } // this strips the mnemonic prefix for short cuts as well as leading spaces // If we find && leave one & there. internal static string StripMnemonic(string s) { // If there are no spaces or & then it's ok just return it if (string.IsNullOrEmpty(s) || s.IndexOfAny(new char[2] { ' ', '&' }) < 0) { return s; } char[] ach = s.ToCharArray(); bool amper = false; bool leadingSpace = false; int dest = 0; for (int source = 0; source < ach.Length; source++) { // get rid of leading spaces if (ach[source] == ' ' && leadingSpace == false) { continue; } else { leadingSpace = true; } // get rid of & if (ach[source] == '&' && amper == false) { amper = true; } else { ach[dest++] = ach[source]; } } return new string(ach, 0, dest); } #endregion Misc #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- #region Private Methods // Helper used by the various comparison functions above private static void CheckNonNull(object el1, object el2) { if (el1 == null) throw new ArgumentNullException("el1"); if (el2 == null) throw new ArgumentNullException("el2"); } //This function throws corresponding exception depending on the last error. private static void EvaluateSendMessageTimeoutError(int error) { // SendMessageTimeout Function // If the function fails or times out, the return value is zero. To get extended error information, // call GetLastError. If GetLastError returns zero, then the function timed out. // NOTE: The GetLastError after a SendMessageTimeout my also be an ERROR_TIMEOUT depending on the // message. // 1460 This operation returned because the timeout period expired. ERROR_TIMEOUT if (error == 0 || error == 1460) { throw new TimeoutException(); } else { ThrowWin32ExceptionsIfError(error); } } #endregion Private Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- pingexception.cs
- TextPointerBase.cs
- FormsAuthenticationEventArgs.cs
- ArraySubsetEnumerator.cs
- TextureBrush.cs
- DataGridViewImageColumn.cs
- ConfigXmlReader.cs
- ScriptModule.cs
- UniqueConstraint.cs
- GroupBox.cs
- ToolStripPanelCell.cs
- base64Transforms.cs
- Int32CAMarshaler.cs
- TextEditorCopyPaste.cs
- Missing.cs
- ResourceDefaultValueAttribute.cs
- ObservableCollection.cs
- SQLUtility.cs
- ApplicationSettingsBase.cs
- Html32TextWriter.cs
- ColorContext.cs
- ValidationPropertyAttribute.cs
- DataServiceStreamProviderWrapper.cs
- AsymmetricKeyExchangeDeformatter.cs
- login.cs
- ArraySegment.cs
- __Error.cs
- Tuple.cs
- TabletDeviceInfo.cs
- XmlSchemaIdentityConstraint.cs
- Int32RectConverter.cs
- infer.cs
- Parser.cs
- MessageQueuePermissionEntryCollection.cs
- ObjectNotFoundException.cs
- SqlCaseSimplifier.cs
- ResolveMatchesCD1.cs
- EdmScalarPropertyAttribute.cs
- ConstructorNeedsTagAttribute.cs
- Point4DValueSerializer.cs
- HtmlWindow.cs
- IriParsingElement.cs
- DateTimeFormat.cs
- HttpInputStream.cs
- SerializerProvider.cs
- HostingEnvironment.cs
- ThreadInterruptedException.cs
- SystemTcpStatistics.cs
- CodeTypeMember.cs
- RoutedUICommand.cs
- ADRoleFactory.cs
- EntityKeyElement.cs
- InitializationEventAttribute.cs
- NavigationEventArgs.cs
- NGCSerializer.cs
- AssemblyResolver.cs
- PrimitiveSchema.cs
- XmlDataImplementation.cs
- HostExecutionContextManager.cs
- RuntimeResourceSet.cs
- CheckBox.cs
- Registry.cs
- _CommandStream.cs
- FtpCachePolicyElement.cs
- RegisteredHiddenField.cs
- ConnectionConsumerAttribute.cs
- HttpResponseHeader.cs
- RemoteCryptoSignHashRequest.cs
- ValidatorCompatibilityHelper.cs
- DescendantOverDescendantQuery.cs
- SystemKeyConverter.cs
- CreateSequence.cs
- ComboBox.cs
- FieldToken.cs
- CodeParameterDeclarationExpression.cs
- CalculatedColumn.cs
- SignatureDescription.cs
- GiveFeedbackEventArgs.cs
- PageWrapper.cs
- ClassHandlersStore.cs
- QueuePropertyVariants.cs
- ApplicationContext.cs
- AsyncOperation.cs
- SoapFault.cs
- EditorPart.cs
- HexParser.cs
- Misc.cs
- IRCollection.cs
- SimpleWebHandlerParser.cs
- ConfigurationElementProperty.cs
- LateBoundChannelParameterCollection.cs
- KeyPressEvent.cs
- SpoolingTaskBase.cs
- SingleTagSectionHandler.cs
- MsmqIntegrationSecurityMode.cs
- sapiproxy.cs
- ScaleTransform.cs
- ZipIOModeEnforcingStream.cs
- TextRangeBase.cs
- TreeBuilderXamlTranslator.cs