/*
Copyright (C) 2012-2013 Anton Lobov <zhuravlik> <ahmad200512[at]yandex.ru>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA
*/
package zhuravlik.automation.util.win32;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Ole32;
import com.sun.jna.platform.win32.Ole32Util;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinUser.POINT;
import com.sun.jna.platform.win32.jnacom.ComObject;
import com.sun.jna.platform.win32.jnacom.IUnknown;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import java.awt.Point;
import java.awt.Rectangle;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import zhuravlik.automation.jna.IUIAutomation;
import zhuravlik.automation.jna.IUIAutomationElement;
import zhuravlik.automation.util.AutomationObject;
public class UIAObject extends AutomationObject {
IUIAutomationElement uiaelement;
private static UIAObject uiaObjectFromPointerByReference(PointerByReference p) throws Exception {
IUIAutomation au = getRootOleObject();
//Dispatch el = new Dispatch();
//el.m_pDispatch = (int)Memory.nativeValue(p.getValue());
IUnknown iu2 = ComObject.wrapNativeInterface(p.getValue(), IUnknown.class);
IUIAutomationElement elt = iu2.queryInterface(IUIAutomationElement.class);
return new UIAObject(elt);
}
public static UIAObject getRootElement() throws Exception {
IUIAutomation au = getRootOleObject();
PointerByReference p = new PointerByReference();
au.GetRootElement(p);
return uiaObjectFromPointerByReference(p);
}
public static UIAObject getFocusedElement() throws Exception {
IUIAutomation au = getRootOleObject();
PointerByReference p = new PointerByReference();
au.GetFocusedElement(p);
return uiaObjectFromPointerByReference(p);
}
public static UIAObject getFromHandle(WinDef.HWND hwnd) throws Exception {
IUIAutomation au = getRootOleObject();
PointerByReference p = new PointerByReference();
au.ElementFromHandle(hwnd, p);
return uiaObjectFromPointerByReference(p);
}
private UIAObject(IUIAutomationElement elt) {
uiaelement = elt;
}
public static IUIAutomation getRootOleObject() throws Exception {
final Ole32 ole32 = Ole32.INSTANCE;
PointerByReference ptr2 = new PointerByReference();
ole32.CoInitializeEx(Pointer.NULL, 2);
WinNT.HRESULT h = ole32.CoCreateInstance(Ole32Util.getGUIDFromString("{ff48dba4-60ef-4201-aa87-54103eef594e}")
, Pointer.NULL, 1, Ole32Util.getGUIDFromString("{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}"),
ptr2);
if (h.intValue() == 0) {
IUnknown iu = ComObject.wrapNativeInterface(ptr2.getValue(), IUnknown.class);
IUIAutomation au = iu.queryInterface(IUIAutomation.class);
return au;
}
else
throw new Exception("COM error getting UIA for element: " + h);
}
@Override
public List<AutomationObject> getChildItems() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public AutomationObject getParent() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Rectangle getRectangle() {
return getBoundingRectangle();
}
@Override
public void mouseDown(Point p) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void mouseUp(Point p) {
throw new UnsupportedOperationException("Not supported yet.");
}
public String getName() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentName(ppr);
return ppr.getValue().getString(0, true);
}
public String getAutomationId() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentAutomationId(ppr);
return ppr.getValue().getString(0, true);
}
public String getFrameworkId() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentAutomationId(ppr);
return ppr.getValue().getString(0, true);
}
public String getLocalizedControlType() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentLocalizedControlType(ppr);
return ppr.getValue().getString(0, true);
}
public String getAcceleratorKey() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentAcceleratorKey(ppr);
return ppr.getValue().getString(0, true);
}
public String getAccessKey() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentAccessKey(ppr);
return ppr.getValue().getString(0, true);
}
public String getClassName() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentClassName(ppr);
return ppr.getValue().getString(0, true);
}
public String getHelpText() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentHelpText(ppr);
return ppr.getValue().getString(0, true);
}
public String getItemType() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentItemType(ppr);
return ppr.getValue().getString(0, true);
}
public String getItemStatus() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentItemStatus(ppr);
return ppr.getValue().getString(0, true);
}
public String getAriaRole() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentAriaRole(ppr);
return ppr.getValue().getString(0, true);
}
public String getAriaProperties() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentAriaProperties(ppr);
return ppr.getValue().getString(0, true);
}
public String getProviderDescription() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentProviderDescription(ppr);
return ppr.getValue().getString(0, true);
}
public Rectangle getBoundingRectangle() {
RECT r = new RECT();
WinNT.HRESULT nm = uiaelement.Get_CurrentBoundingRectangle(r);
return new Rectangle(r.left, r.top, r.right - r.left, r.bottom - r.bottom);
}
public int getProcessId() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentProcessId(ppr);
return ppr.getValue();
}
public int getCultureId() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentCulture(ppr);
return ppr.getValue();
}
public ControlType getControlType() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentControlType(ppr);
int cid = ppr.getValue();
return ControlType.fromId(cid);
}
public OrientationType getOrientation() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentControlType(ppr);
int cid = ppr.getValue();
return OrientationType.fromOrdinal(cid);
}
public boolean isHasKeyboardFocus() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentHasKeyboardFocus(ppr);
return ppr.getValue() != 0;
}
public boolean isKeyboardFocusable() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentIsKeyboardFocusable(ppr);
return ppr.getValue() != 0;
}
public boolean isEnabled() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentIsEnabled(ppr);
return ppr.getValue() != 0;
}
public boolean isControlElement() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.get_CurrentIsControlElement(ppr);
return ppr.getValue() != 0;
}
public boolean isContentElement() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentIsContentElement(ppr);
return ppr.getValue() != 0;
}
public boolean isPassword() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentIsPassword(ppr);
return ppr.getValue() != 0;
}
public boolean isOffscreen() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentIsOffscreen(ppr);
return ppr.getValue() != 0;
}
public boolean isRequiredForForm() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentIsRequiredForForm(ppr);
return ppr.getValue() != 0;
}
public boolean isDataValidForForm() {
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentIsDataValidForForm(ppr);
return ppr.getValue() != 0;
}
public WinDef.HWND getNativeWindowHandle() {
PointerByReference ppr = new PointerByReference();
WinNT.HRESULT nm = uiaelement.Get_CurrentNativeWindowHandle(ppr);
return new WinDef.HWND(ppr.getValue());
}
public Point getClickablePoint() {
POINT p = new POINT();
IntByReference ppr = new IntByReference();
WinNT.HRESULT nm = uiaelement.getClickablePoint(p, ppr);
if (ppr.getValue() != 0)
return new Point(p.x, p.y);
else
return null;
}
public void setFocus() {
uiaelement.setFocus();
}
/*public class Placeholder0<T> {
}*/
public class Placeholder<T> {
T p;
}
public <T> T getPattern(Class<T> clazz) throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
String className = clazz.getSimpleName();
String patternName = className.replace("Pattern", "");
ControlPattern patternKind = ControlPattern.valueOf(patternName);
// some reflection magic to not enumerate all cases manually
Class c = Class.forName("zhuravlik.automation.jna.patterns.raw.IUIAutomation" + patternName + "Pattern");
IUnknown ptrn = getPatternRaw(patternKind);
IUnknown qq = ptrn.queryInterface(c);
Object qqq = c.cast(qq);
return clazz.getConstructor(c).newInstance(qqq);
}
private IUnknown getPatternRaw(ControlPattern patternKind) {
PointerByReference pp = new PointerByReference();
uiaelement.getCurrentPattern(patternKind.getValue(), pp);
return ComObject.wrapNativeInterface(pp.getValue(), IUnknown.class);
}
/*public UIAObject FindFirst(TreeScope scope, ISearchCondition condition) {
}
public UIAObject[] FindAll(TreeScope scope, ISearchCondition condition) {
}*/
}