2 Home
Claire edited this page 2 years ago

Code Notebook

Introduction

We have an ASUS Zenbook UX31A in our collection. It's a pretty sweet little machine - my model has a third-gen i5 and 16GB RAM, and it's surprisingly speedy for its age. After a clean Windows 10 install, Windows Update finds and installs the official ASUS Smart Gesture drivers and software.

Like way, way too many OEMs, ASUS's software is pretty pointless. It offers little customization and provides no way to configure multi-finger clicks on the touchpad. I did some poking around and discovered that I could not only access the generic Elantech control panel, but I could edit the registry for the software to display every setting available in the software.

The downside of this solution is that the software re-disables all the additional settings every time you run it. Fortunately, this is easy to work around with some PowerShell.

As an aside, you may want to install the generic Elantech drivers alongside the ASUS Smart Gesture drivers. I found them on Station Drivers. This site is kind of slow on the download speed, but it seems to be legitimate and has every version of the Elantech software available. You'll need to force Windows to use the downloaded drivers via Update Driver > Have Disk.

New versions of Windows seem to forcefully revert to the ASUS drivers, so if you've updated and you're back on ASUS's configuration, you'll want to force the touchpad to use the Elantech driver. I've also discovered that you need the ASUS SmartGesture drivers installed before the Elantech driver will work reliably.

The Script

There's probably an easier way to accomplish this, but what I came up with does work reliably. What you need to do is get the existing data in the registry for the touchpad's software, loop through every DWORD property set to zero, change the value to one, and then launch the touchpad settings software.

First, we need to point to the right registry location and pull out the properties of the registry key using Get-ItemProperty:

# set path to registry key
$reg = "HKCU:\Software\Elantech\SmartPadDisplay"

# get properties of key
$regprops = Get-ItemProperty -Path $reg -Name *

Now, what this returns is not immediately useable data for our purposes. This returns a single PS object containing a 'NoteProperty' for each property in the registry. It looks something like this:

Name               MemberType       Definition
----               ----------       ----------
Button_Display     NoteProperty     int Button_Display=1

It's easy to dump this into a variable thanks to Get-Member. The Definition property of each member of our object contains some super useful information - both the name and value of each property of our registry key. It looks something like int Button_Display=1. Every property of the Elan registry key we're using is an integer, so I filtered out the result of Get-Member to use only NoteProperty members that are integers.

# get members of properties
# this is because $props is a single row with columns for each property
# we'll filter out non-integer properties and any methods, since we only care about the int values
$members = $regprops | gm | ?{$_.MemberType -eq "NoteProperty" -and $_.Definition -like "int*"}

If you look at the results of Get-Member, the definition property of each member is formatted with the member type, name, and value:

Name               MemberType       Definition
----               ----------       ----------
Button_Display     NoteProperty     int Button_Display=1

The easiest way to get rid of the extraneous information is to just use the Replace method to strip both the int and space from the definition. This line will also replace each item in $members with just the definition of each item.

# the definition property of each $member contains the current reg value and the property name
# clean up $member.definition string
$members = $members.Definition.Replace("int ","")

This will leave us with a format of Name=Value, which is easy to manipulate with the Split method. We need to loop through the list of members and create a new array of custom PSObjects with two properties - name and value, pulled from the definition.

# loop through members and create a new object array of property and value
$props = @()
foreach ($m in $members)
{
    $msplit = $m.Split("=")
    $mprop = $msplit[0]
    $mval = $msplit[1]

    $obj = New-Object -TypeName PSObject
    Add-Member -InputObject $obj -MemberType NoteProperty -Name "Property" -Value $mprop
    Add-Member -InputObject $obj -MemberType NoteProperty -Name "Value" -Value ([int]$mval)

    $props += $obj
}

Now that we have all of the registry properties we care about, we need to set every property with a zero value to one.

# $props now has an array of registry key properties and their corresponding values
# for every value of 0, change it to a 1 in the registry
foreach ($p in $props)
{
    if ($p.Value -eq 0)
    {
        New-ItemProperty -Path $reg -Name $p.Property -Value "1" -PropertyType DWORD -Force | Out-Null
    }
}

The registry is now set up for the Elan software to display every setting available, so we can launch the control panel.

# Run the control panel
Invoke-Item "C:\Program Files\Elantech\ETDAniConf.exe"

It is interminably annoying that so many OEMs insist on using their own control panels and disabling various features of touchpads. There are only a handful of touchpad manufacturers - Elan, Alps, and Synaptics. All three have reasonably useful generic control panels, so there's no real reason to mess with these touchpads as much as OEMs tend to do. In ASUS's case, their "Smart Gesture" application offers no ability to change the settings of multitouch gestures and clicks, which means two-finger click doesn't open context menus and three-finger click doesn't emulate middle click (which is super useful for opening links in new tabs in your browser of choice).