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
|
|
Eugene Astafiev
Guest
|
Hello Mark,
You should find handle of the main window and set focus to it. |
|
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 |
|
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 |
|
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 |
|
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.
|
|