Setting focus back to Excel from advanced excel task pane

Add-in Express™ Support Service
That's what is more important than anything else

Setting focus back to Excel from advanced excel task pane
 
Mark K


Guest


Hi,

I have data on an advanced excel task pane that the user interacts with. After certain actions I want to set the focus back to the excel sheet so that he can then use the data I have inserted. I have tried ExcelApp.ActiveCell.Select() but it doesn't do anything.

I have also found the ADXKeyFilter event as a possible, but not prefered, solution where the task pane keeps the focus but passes the key presses through to Excel. Unfortunately I cannot find any reference for how this works.

My preferred solution by far is to just give the focus back to Excel.

Any help greatly appreciated.

Cheers

mark
Posted 12 Jun, 2008 22:51:54 Top
Eugene Astafiev


Guest


Hello Mark,

You should find handle of the main window and set focus to it.
Posted 13 Jun, 2008 10:50:10 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Mark,

And the code for doing this follows below:

        private void SetFocusToExcel()
        {
            IntPtr h = APIUtils.GetXLMainWindowHandle(APIUtils.GetDesktopWindow());
            APIUtils.SetFocus(h);
        }

        public class APIUtils
        {
            public static IntPtr GetXLMainWindowHandle(IntPtr DesktopHandle)
            {
                return FindMainWindowInProcess(DesktopHandle, String.Empty, "XLMAIN");
            }

            internal static IntPtr FindMainWindowInProcess(IntPtr HWNDParent, string WindowName, string WindowClass)
            {
                IntPtr FoundWindow = IntPtr.Zero;

                string FindClass = String.Empty;
                string FindName = String.Empty;
                uint WindowProcessID;

                IntPtr tempWindow = GetWindow(HWNDParent, GW_CHILD);
                while ((int)tempWindow > 0)
                {
                    FindName = GetWindowText(tempWindow);
                    FindClass = GetClassName(tempWindow);

                    bool CompareClass = ((FindClass.IndexOf(WindowClass) >= 0) || (WindowClass == String.Empty));
                    bool CompareCaption = ((FindName.IndexOf(WindowName) >= 0) || (WindowName == String.Empty));

                    if (CompareClass && CompareCaption)
                    {
                        GetWindowThreadProcessId(tempWindow, out WindowProcessID);
                        if (GetCurrentProcessId() == WindowProcessID)
                        {
                            FoundWindow = tempWindow;
                            if (IsWindowVisible(FoundWindow))
                            {
                                break;
                            }
                        }
                    }
                    tempWindow = GetWindow(tempWindow, GW_HWNDNEXT);
                }
                return FoundWindow;
            }

            [DllImport("user32.dll")]
            public static extern IntPtr SetFocus(IntPtr hWnd);

            [DllImport("user32.dll")]
            public static extern IntPtr GetDesktopWindow();

            [DllImport("User32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr GetWindow(IntPtr hwnd, int uCmd);

            [DllImport("user32.dll")]
            public static extern int GetWindowText(IntPtr hwnd,
                [In][Out]StringBuilder lpClassName, int nMaxCount);

            [DllImport("user32.dll")]
            public static extern int GetClassName(IntPtr hwnd,
                [In][Out]StringBuilder lpClassName, int nMaxCount);

            [DllImport("user32.dll")]
            public static extern bool IsWindowVisible(IntPtr hWnd);

            [DllImport("user32.dll", SetLastError = true)]
            public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

            [DllImport("kernel32.dll")]
            public static extern uint GetCurrentProcessId();

            public static string GetWindowText(IntPtr handle)
            {
                System.Text.StringBuilder lpBuffer = new System.Text.StringBuilder(255);
                if (GetWindowText(handle, lpBuffer, 255) > 0)
                {
                    return lpBuffer.ToString();
                }
                else
                    return "";
            }

            public static string GetClassName(IntPtr handle)
            {
                System.Text.StringBuilder className = new System.Text.StringBuilder(255);
                if (GetClassName(handle, className, 255) > 0)
                {
                    return className.ToString();
                }
                else
                    return "";
            }

            public const int GW_CHILD = 5;
            public const int GW_HWNDNEXT = 2;

        }


HTH,


Andrei Smolin
Add-in Express Team Leader
Posted 13 Jun, 2008 11:28:21 Top
Mark K


Guest


Hi Andrei,

Unfortunately I use Delphi so I couldn't use the code you supplied but I figured it out from your suggestion.

Thanks heaps

Mark
Posted 13 Jun, 2008 19:25:23 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hi Mark,

Just terribly sorry. I completely missed the forum id of your message.


Andrei Smolin
Add-in Express Team Leader
Posted 14 Jun, 2008 11:03:34 Top
Fedor Shihantsov


Guest


Here is a Delphi equivalent:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Excel2000, adxxlFormsManager, StdCtrls;

type

  TadxExcelTaskPane1 = class(TadxExcelTaskPane)
    Edit1: TEdit;
    Label1: TLabel;
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
  end;

{NOTE: The adxExcelTaskPane1 variable is intended for the exclusive use
       by the TadxExcelTaskPanesCollectionItem Designer.
       NEVER use this variable for other purposes.}
var
  adxExcelTaskPane1 : TadxExcelTaskPane1;

  function FindMainWindowInProcess(HWNDParent: HWND; WindowName: string; WindowClass: string): HWND;
  function GetWindowCaption(HandleWindow: HWND): string;
  function GetWindowClassName(HandleWindow: HWND): string;

implementation

uses adxWSbcls;

{$R *.DFM}

procedure TadxExcelTaskPane1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  H: HWND;
begin
  if (Key = 13) then begin
    H := FindMainWindowInProcess(GetDesktopWindow(), '', 'XLMAIN');
    Windows.SetFocus(H);
  end;
end;

function FindMainWindowInProcess(HWNDParent: HWND; WindowName: string; WindowClass: string): HWND;
var
  FoundWindow: HWND;
  FindClass: string;
  FindName: string;
  WindowProcessID: cardinal;
  tempWindow: HWND;
  CompareClass: boolean;
  CompareCaption: boolean;
begin
  FoundWindow := 0;
  tempWindow := GetWindow(HWNDParent, GW_CHILD);
  while (tempWindow > 0) do begin
    FindName:= GetWindowCaption(tempWindow);
    FindClass:= GetWindowClassName(tempWindow);

    CompareCaption := (pos(WindowName, FindName) > 0) or (WindowName = '');
    CompareClass := (pos(WindowClass, FindClass) > 0) or (WindowClass = '');

    if (CompareClass and CompareCaption) then begin
      GetWindowThreadProcessId(tempWindow, @WindowProcessID);
      if (GetCurrentProcessId() = WindowProcessID) then begin
        FoundWindow := tempWindow;
        if (IsWindowVisible(FoundWindow)) then begin
          break;
        end;
      end;
    end;
    tempWindow := GetWindow(tempWindow, GW_HWNDNEXT);
  end;
  result := FoundWindow;
end;

function GetWindowCaption(HandleWindow: HWND): string;
var
  lpBuffer : array [0..256-1] of Char;
begin
  Result:= '';
  if GetWindowText(HandleWindow, @lpBuffer, 256) > 0 then
    Result:= StrPas(lpBuffer);
end;

function GetWindowClassName(HandleWindow: HWND): string;
var
  lpBuffer : array [0..256-1] of Char;
begin
  Result:= '';
  if GetClassName(HandleWindow, @lpBuffer, 256) > 0 then
    Result:= StrPas(lpBuffer);
end;

initialization
  RegisterClass(TPersistentClass(TadxExcelTaskPane1));

finalization
end.
Posted 18 Jul, 2011 06:41:49 Top