static bool IsInFormulaEditMode() { // I assume LPenHelper is available under Excel 2007+ if (ExcelDnaUtil.ExcelVersion >= 12.0) { // check edit state directly var fmlaInfo = new XlCall.FmlaInfo(); // If Excel is shutting down, CallPenHelper will throw an InvalidOperationException. var result = CallPenHelper(XlCall.xlGetFmlaInfo, ref fmlaInfo); if (result == 0) { // Succeeded return(fmlaInfo.wPointMode != XlCall.xlModeReady); } } // Otherwise try Focus windows check, else menu check. IntPtr focusedWindow = GetFocus(); if (focusedWindow == IntPtr.Zero) { // Excel (this thread) does not have the keyboard focus. Use the Menu check instead. bool menuEnabled = IsFileOpenMenuEnabled(); // Debug.Print("Menus Enabled: " + menuEnabled); return(!menuEnabled); } string className = GetWindowClassName(focusedWindow); // Debug.Print("Focused window class: " + className); return(className == "EXCEL<" || className == "EXCEL6"); }
// The call to LPenHelper will cause an AccessViolation after Excel starts shutting down. // .NET40: If this library is recompiled to target .NET 4+, we need to add an attribute to indicate that this exception // (which might indicate corrupted state) should be handled in our code. // For now, we target .NET 2.0, and even when running under .NET 4.0 we'll see the exception and be able to handle is. // See: http://msdn.microsoft.com/en-us/magazine/dd419661.aspx // (Also for CheckExcelApiAvailable()) // [HandleProcessCorruptedStateExceptions] static int CallPenHelper(int wCode, ref XlCall.FmlaInfo fmlaInfo) { try { // (If Excel is shutting down, we see an Access Violation here, reading at 0x00000018.) return(XlCall.LPenHelper(XlCall.xlGetFmlaInfo, ref fmlaInfo)); } catch (AccessViolationException ave) { throw new InvalidOperationException("LPenHelper call failed. Excel is shutting down.", ave); } }
static bool IsInFormulaEditMode() { // check edit state directly var fmlaInfo = new XlCall.FmlaInfo(); // If Excel is shutting down, CallPenHelper will throw an InvalidOperationException. var result = CallPenHelper(XlCall.xlGetFmlaInfo, ref fmlaInfo); if (result == 0) { // Succeeded return(fmlaInfo.wPointMode != XlCall.xlModeReady); } else { // Log and return true (the safer option) ??? // Error for now, but maybe Warn is safe too. Logger.Registration.Error("IsInFormulaEditMode - PenHelper failed, result " + result); return(true); } }
internal static int LPenHelper(int wCode, ref XlCall.FmlaInfo fmlaInfo) { return(_integrationHost.LPenHelper(wCode, ref fmlaInfo)); }
static int CallPenHelper(int wCode, ref XlCall.FmlaInfo fmlaInfo) { return(ExcelIntegration.LPenHelper(XlCall.xlGetFmlaInfo, ref fmlaInfo)); }
public int LPenHelper(int wCode, ref XlCall.FmlaInfo fmlaInfo) => XlAddIn.LPenHelper(wCode, ref fmlaInfo);