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




Posts: 85
Joined: 2007-05-29
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


Add-in Express team


Posts: 8540
Joined: 2007-07-25
Hello Mark,

You should find handle of the main window and set focus to it.
.NET, Extended MAPI, Windows Phone & RT
Posted 13 Jun, 2008 10:50:10 Top
Andrei Smolin


Add-in Express team


Posts: 9620
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,

Regards from Belarus (GMT+2),

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




Posts: 85
Joined: 2007-05-29
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: 9620
Joined: 2006-05-11
Hi Mark,

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

Regards from Belarus (GMT+2),

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


Add-in Express team


Posts: 1188
Joined: 2005-01-11
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