FileMakerでWindows 10のタブレットモードを少し快適に使いたい・・・プラグイン作ってみた

# ファイルメーカーでタッチスクリーンキーボード入力を少し便利にしてみた・・・Windows 10 Tablet PCの話

### FileMakerではWindows10のタブレットモードで何故か入力制御がサポートされない？

iOS向けFileMaker Goでは、入力の補助としてタッチキーボードタイプが選べて、数値のみ入力の場合など結構快適に入力できる。
![tsk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/efd06619-8fcc-3335-abc1-29c1cba9fa98.png)

（※一部語弊があったので下方に追記）

しかし、Windows 10のタブレットモードではその動作はサポートされていないっぽくて・・・デスクトップモードであれば、IMEの制御は期待通りの動きをする。macOS版と同じ挙動だ。一方タブレットモードにするとIMEは無視され、タッチスクリーンキーボードを出したら日本語入力モードに固定されている。

なので、タブレットを使用した場合・・・

1. 入力対象を選択
2. キーボードを出す
3. 英語モードに変える
4. 数値モードに切り替える
5. 入力する

と入力開始までに３ステップ以上が必要になる。数値モードに切り替えて、数値入力を開始して、ふと日本語モード全角入力だったときは途方も無い苛立ちを覚えるw また、タッチスクリーンキーボードを出したままにしていたら問題ないのかもしれないが、表示エリアが狭くなるので一旦閉じて、別の項目を入力しようとすると同じ操作の繰り返しが必要だ・・・どうしてこうなった？

それを、入力テキストボックスに入った時、必要なモードでタッチスクリーンキーボードを出す事ができたら若干シアワセになれるかも？という魂胆だったりする。

もう一つは一時期大量に量産された安価なWindowsタブレット端末。これ有効活用できないか？持ち出してユーザーさんに出先で入力作業を行ってもらおうと考えた時、タッチスクリーンキーボードの動作がアレだと非難囂々間違いないw それを若干でも緩和できれば・・・

---
### Windows 10のタブレットモードって

タブレットモードの使用を積極推進していないのはClaris社の方針なのか？もしや、Windows版のFileMaker Goを準備しているのか？

どうやら.NETなWPFアプリなら簡単にプロパティ設定だけで解決できるらしいが、Formアプリや旧Win32アプリなどでは同様のジレンマが存在するらしい。さては、WFPなストアアプリの普及を企むMSの魂胆に、Clarisもガッツリ乗っかっている形なのか？確かにデスクトップモードなら、macOS版と挙動も同じで矛盾もない。積極的タブレットモードのサポートは、ノーマルFileMaker Proを廃止して、Advanced版だけに絞った事からも、現実的に望み薄かも。

ただ期待して止まないのは、FileMaker Go・・・iOS版のみの現状だが、これをAndroid版、Windowsタブレットモード版としてリリースしたら結構な勢いで普及するんじゃなかろうか。ただAppleの子会社的にその辺は大人の事情も絡んでそうで難しいのかな。

---
### プラグインなら解決できそうだ

タッチスクリーンキーボードは、TabTip.exeが担っているらしい。

```
C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe
```
何でもコイツは、[SetInputScope](https://docs.microsoft.com/en-us/windows/win32/api/inputscope/ne-inputscope-inputscope)を使用したら、その影響を受けるらしい。

幸いプラグインSDKは入手できるし、別口で[SetInputScope](https://docs.microsoft.com/en-us/windows/win32/api/inputscope/ne-inputscope-inputscope)にも触れたことがある。これは試しに作ってみようか。

プラグインの初期化時にライブラリをロード

```c++
hoge = LoadLibrary(TEXT("msctf.dll"));
```

終了時に解放を忘れずに。

```c++
FreeLibrary(hoge);
```

後は呼び出される度に

```c++
InputScope ahe = (InputScope)dat.GetAsNumber().AsLong();
HRESULT ret = 0;

if (setInputScope)
{
  ret = setInputScope(GetFocus(), ahe);
  if( ret == 0 )
  {
    ShellExecute(NULL, L"open", L"C:¥¥Program Files¥¥Common Files¥¥microsoft shared¥¥ink¥¥TabTip.exe", NULL, NULL, SW_SHOW);
  }
}
```
TabTip.exeのプロセスが既に稼働している場合の対策もしなくっちゃいけないっぽい。ググって適当なTipsからコピペw

---
### ついでに[GetSystemMetrics](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics)もラップしてみた。


[GetSystemMetrics](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics)を使って、SM_TABLETPC(86)を引数にすると、タブレットかどうかが判るらしい。（いわゆるタッチスクリーンあり？）それ以外にも色々調査した値を取得できるのでリンク先のドキュメントから引数を調べてね。

---
### 現在タブレットモードになっているかどうかを知りたい

デスクトップPCやノートPCで"あえて"タブレットモードで運用する事はないと思いますが、"あえて"切り替えている場合など、現在のモードが知りたいと思った時、GetSystemMetrics(SM_CONVERTIBLESLATEMODE)で調べるとか情報はありますがイマイチピンとこない。

GetSystemMetrics(SM_TABLETPC)では無い場合、つまりタブレットとしてデザインされていないPCでタブレットモードになっている状態を調べるとかどうやったら良いものか・・・もちろんタブレットPCでデスクトップモードになっている場合の状態も調べたい。

いろいろ調べていると、

```
HKEY_CURRENT_USER¥Software¥Microsoft¥Windows¥CurrentVersion¥ImmersiveShell¥TabletMode
```

のDWORDが0でデスクトップモード、1でタブレットモードということがわかった。

そんなに頻繁に呼ぶ物でもなし、タイミング的にシビアなものでも無さそうなのでレジストリ読み込みで判定して値を返す関数を加えてみた。

```
GetTabletMode( 0 ) // 1 = TabletMode ; 0 = DesktopMode ; -1 = Error
```

戻り値
- 1 = タブレットモード 
- 0 = デスクトップモード 
- -1 = レジストリ読み込みエラーの何か

となる。

---
### 現在ダークモードになっているかどうかを知りたい

```
GetDarkMode( 0 ) // 1 = DarkMode ; 0 = LightMode ; -1 = Error（未設定？）
```

戻り値
- 1 = ダークモード 
- 0 = ライトモード 
- -1 = レジストリ読み込みエラーの何か。未設定の場合も-1なのでライトモードとみなしてよい？



---
### タブレットじゃ無いけどソフトウェアキーボード入力させたい

osk.exe（オンスクリーンキーボード）を呼んだら出てくるけどコレじゃないんだ、タブレットモードの時のヤツのがイイんだ！！という場合、レジストリエディタで・・・

```
HKEY_LOCAL_MACHINE¥SOFTWARE¥Microsoft¥TabletTip¥1.7¥
```
を開いて、DWORD値のEnableDesktopModeAutoInvokeを新規入力して値に1を書き込む。

そうするとデスクトップモードでも、TabTip.exeによるタッチスクリーンキーボードが出てくるようになる。

---
### プラグインを使ってみる。

プラグインはWindows専用で、32bitと64bitの２種類、適宜必要な方をインストールする。

FileMakerでスクリプトを作成。
![tk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/6e3c44f4-be7a-40dc-6aa4-d2704ce13066.png)

トリガの設定は、こんな感じ。
![trigger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/43857ddd-7b90-14d3-e782-017a6fb87354.png)

スクリプト引数に設定する数値は、こんな感じ。

```
IS_HIRAGANA = 44 // 日本語入力
IS_KATAKANA_HALFWIDTH = 45 // 全角カナ
IS_KATAKANA_FULLWIDTH = 46 // 半角カナ

IS_DEFAULT = 0 // 日本語になっちゃう？

IS_URL = 1  // 英語モード入力.comとか出てくる。
IS_FILE_FULLFILEPATH = 2 // 英語モード良い感じ
IS_NUMBER = 29 // 半角数字入力モード
IS_TELEPHONE_FULLTELEPHONENUMBER = 32 //半角数字モード（電話番号）
```

すると、必要な項目に入力カーソルが来たらこんな風にタッチスクリーンキーボードによる入力ができるようになる。
![FMWTouchKeyboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/3e58fb64-bb3a-b492-eb91-acf06c3f333d.png)
まさにカーソルがテキストボックスに入ったら半角数字入力モードでタッチスクリーンキーボードが出てきた図だ。Windows10のデスクトップモードでもごらんの通り。

ついでに、GetSystemMetricsは、こんな感じ。
![gsm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/6dd06fd1-facf-37df-56e7-0db125a788ed.png)


---
### ダウンロード

[こちら](https://www.dropbox.com/s/nm8jtd5z7id0rmy/FMWTouchKeyboard.zip?dl=0)

- 英語アルファベットモードだけ、前回のタッチスクリーンキーボード日本語モード／英語モードに引っ張られてるみたい？いや常に日本語モードになっているみたい？
    * スクリプト引数0（IS_DEFAULT）がダメみたい。
    * 1（IS_URL）とか、2（IS_FILE_FULLFILEPATH）とかにしたら、取り敢えず英語モード（半角モード）になっているっぽい。
- 電話番号入力モードと数値入力モードの違いがわからん。
- Windows 7 でもなんかソフトウェアキーボードが出てきたw
- Windows 8、8.1で動作するかは知らない。（MS的にも無かったことにしたいらしい.uso）
- そういえば、FileMaker Serverで運用する場合、プラグインをオブジェクトフィールドに埋め込んでおいて、クライアント起動時に自動配信する仕組みを見かけたけど、32bitと64bit版の判別ってどうやっているのだろう・・・そう考えると4Dのプラグイン配信構造のが洗練されてていいな。
- テストはWindows 10 32bit/64bit、FileMaker Pro 18 Advancedにてのみ実施。17や19で動くかどうかは不明。
- プラグインの作成についての作法はよくわかっていないので、プラグインIDとかで問題がでるかも。SDKについてくるサンプルをコソコソ改修したもので・・・
- レジストリ読み取りで、タブレットモード判定追加
- 　　　　　〃　　　　　ダークモード判定追加
- 遅ればせながら、FileMaker Pro 19をインストールして試してみた。どうやら問題無さそうだ・・・

---
### 使用について
ご自由にどうぞ。本格運用に耐えられるかわかりません。問題があってもサポートできません。自己責任のうえご利用ください。

とりあえず、自分の求める動作・・・数値入力の場合は数字半角モードでタッチスクリーンキーボードを表示させる・・・は解決して、自前の環境ではウマく行ったので満足:)

---
### 謝辞

miyako氏の[4Dプラグイン](https://github.com/miyako/4d-plugin-input-scope)を参考にさせて頂きました。

---

そして、ここまで書いて気づく・・・
[リファレンス](https://fmhelp.filemaker.com/help/18/fmp/ja/FMP_Help/reference.html#wwconnect_header) > [スクリプトステップリファレンス](https://fmhelp.filemaker.com/help/18/fmp/ja/FMP_Help/script-steps-reference.html#wwconnect_header) > [その他のスクリプトステップ](https://fmhelp.filemaker.com/help/18/fmp/ja/FMP_Help/miscellaneous-script-steps.html#wwconnect_header) > [タッチキーボードの有効化](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help/enable-touch-keyboard.html)

まさかWindows10のタブレットモードではデフォルトでOFFなのか？そんな殺生な・・・見なかった事にしようかしら。

ONにして試してみると、入力が必要そうな時、常に日本語入力モードで出てくる・・・タッチキーボードタイプの制御は受け付けてくれないっぽい・・・何も考えずにTabTip.exeを叩いたときと同じじゃんorz

というか、[SetInputScope](https://docs.microsoft.com/en-us/windows/win32/api/inputscope/ne-inputscope-inputscope) を呼び出すことはさほど難しくない・・・いやむしろ気づかない訳がない。ではなぜWindows版のFileMakerでは実装されていないのか？サクッと実装しちゃえば良さそうなものだが・・・