UWSCのSlctBoxにアクセスキーをつける
UWSC公式掲示板で、キーボード入力とマウスクリックの両立に悩まれている方がいたので、この解決策を考えてみた。
結果、アクセスキーがつけられることに気付きました〜。
とりあえず、案の提示
こんなの書いてみました。
最初のSlctBoxが出たら、「i,t,o」と順番に押してみてください。
「いと」と入れるのと等価操作で、「イトーヨーカ堂」が選ばれます!
Hashtbl データ データ["最初"] = "あ(&a),い(&i),う(&u),え(&e),お(&o),か行(&k),さ行(&s),た行(&t),な行(&n),は行(&h),ま行(&m),や行(&y),ら行(&r),わ行(&w)" データ["か行(&k)"] = "か(&a),き(&i),く(&u),け(&e),こ(&o)" データ["さ行(&s)"] = "さ(&a),し(&i),す(&u),せ(&e),そ(&o)" データ["た行(&t)"] = "た(&a),ち(&i),つ(&u),て(&e),と(&o)" データ["な行(&n)"] = "な(&a),に(&i),ぬ(&u),ね(&e),の(&o)" データ["は行(&h)"] = "は(&a),ひ(&i),ふ(&u),へ(&e),ほ(&o)" データ["あ(&a)"] = "アイ会社(&i),青木工業(&o)" データ["い(&i)"] = "いタ行(&t),五十鈴(&s),イトーヨーカ堂(&1)" // 頻繁に使う選択肢は上位階層に特別なキーで登録しても データ["こ(&o)"] = "講談社(&u)" // 1つしか登録がなければ、SlctBoxを出さない実装も便利かもしれません データ["いタ行(&t)"] = "板橋印刷(&a),イトーヨーカ堂(&o)" // この調子で階層を増やし過ぎると、クリック派はかわいそう データ["アイ会社(&i)"] = "広島納品(&h),埼玉納品(&s)" // ここはアクセスキーをつけない方が良いかもしれません Const BACK = "戻る" Dim 答え="最初", 今回 While データ[答え, HASH_EXISTS] 今回 = 答え Eval("答え := SlctBox(SLCT_BTN OR SLCT_STR, 0,<#DBL>どれか選んでね<#DBL>,<#DBL>" + replace(データ[答え], "," , "<#DBL>,<#DBL>") + "<#DBL>,<#DBL>" + BACK + "<#DBL>)") If 答え = BACK Or 答え = -1 Then 答え = GetBackKey(データ, 今回) Wend // アクセスキーはどうやって切りましょうか、、、 // Eval魔法が使われているので、正規表現魔法を唱えましょう Dim regex = CreateOleObj("VBScript.RegExp") regex.Pattern = "\(&\w\)" // $をつけるべきかもしれません 答え = regex.Replace(答え, "") MsgBox(答え) Function GetBackKey(data[], key) // 連想配列の中身を順番に見て、選択肢を含むものを探します // 例えば、引数key="こ(&o)"の場合、「か行(&k)」を返します Dim i, m = Length(data) - 1 Result = -1 For i = 0 To m // こっちは正規表現の魔法は使わない方法で書きましょうか // 正規表現を使えば、Forの中身を減らせますね Dim l = Length(key) Dim val = data[i, HASH_VAL], vl = Length(val) Dim index = Pos(key, val) Ifb index > 1 Then // 前の文字はカンマで、後ろはカンマかないかですよね If Copy(val, index - 1, 1) = "," And (vl = l + index - 1 Or Copy(val, l + index, 1) = ",") Then Break ElseIf index = 1 Then // この場合は、後ろがカンマか、単体選択ですね If l = vl Or Copy(val, l + 1, 1) = "," Then Break EndIf Next If i <= m Then Result = data[i, HASH_KEY] Fend
どうでしょうか?
以下は、ここに至る思考です。
普通のWindowsアプリケーションなら、と考えてみる
当然、アクセスキーでしょう。
マウスクリックと等価にアプリケーションの操作ができます。
UWSCでアクセスキー
そういえば、PopupMenuはアクセスキーが出ますね。
Dim all[] = "日本", "{東京", "{世田谷", "千代田", "江戸川}", "名古屋", "大阪}", "アメリカ", "{ニューヨーク", "ロサンゼルス", "サンフランシスコ}" Dim sel = PopupMenu(all) Ifb sel >= 0 Then Msgbox(all[sel]) Else Msgbox("キャンセル") EndIf
これ、選択項目がアルファベットだとそれなりなアクセスキーですが、この場合は「Z」とか。
選びにくいです。
指定、できないかしらん?
と思って、試しに書いてみたところ、、、
Dim all[] = "日本(&j)", "{東京(&t)", "{世田谷(&s)", "千代田(&t)", "江戸川(&e)}", "名古屋(&n)", "大阪(&o)}", "アメリカ(&u)", "{ニューヨーク(&n)", "ロサンゼルス(&l)", "サンフランシスコ(&s)}" Dim sel = PopupMenu(all) Ifb sel >= 0 Then Msgbox(all[sel]) Else Msgbox("キャンセル") EndIf
期待動作した!
最初のPopupで「j」を押すと、「日本」の階層に入れます!
(「&」の次の文字がアクセスキーの指定です)
ではSlctBox
悩まれていた方は、「いと」と入れるとその候補が出る、というI/Fを考えられている。
ならばその入力をアクセスキーに振れば良いではありませんか!
Hashtbl データ データ["最初"] = "あ(&a),い(&i),う(&u),え(&e),お(&o),か行(&k),さ行(&s),た行(&t),な行(&n),は行(&h),ま行(&m),や行(&y),ら行(&r),わ行(&w)" データ["か行(&k)"] = "か(&a),き(&i),く(&u),け(&e),こ(&o)" データ["さ行(&s)"] = "さ(&a),し(&i),す(&u),せ(&e),そ(&o)" データ["た行(&t)"] = "た(&a),ち(&i),つ(&u),て(&e),と(&o)" データ["な行(&n)"] = "な(&a),に(&i),ぬ(&u),ね(&e),の(&o)" データ["は行(&h)"] = "は(&a),ひ(&i),ふ(&u),へ(&e),ほ(&o)" データ["あ(&a)"] = "アイ会社(&i),青木工業(&o)" データ["い(&i)"] = "いタ行(&t),五十鈴(&s),イトーヨーカ堂(&1)" データ["こ(&o)"] = "講談社(&u)" データ["いタ行(&t)"] = "板橋印刷(&a),イトーヨーカ堂(&o)" データ["アイ会社(&i)"] = "広島納品(&h),埼玉納品(&s)" Dim 答え="最初" While データ[答え, HASH_EXISTS] Eval("答え := SlctBox(SLCT_BTN OR SLCT_STR, 0,<#DBL>どれか選んでね<#DBL>,<#DBL>" + replace(データ[答え], "," , "<#DBL>,<#DBL>") + "<#DBL>)") Wend MsgBox(答え)
いや良いと思いませんか?
でも、アクセスキーの指定である「(&a)」とかがかっこ悪いですね。
なら、「答え」を書き変えましょう。
- 後ろ4文字を切る
- 「(」〜「)」を切る
とかも考えましたが、結局、面倒なので正規表現としました。
さらにおまけで、「戻る」を追加したのが、最初のものです。
UWSC、便利過ぎます。
アクセスキーも受け付けてくれるし(Windows標準とも言いますが)
VBScriptのオブジェクトも呼べてしまうし。
Powershellまで守備範囲とは。
また、この解決を考えることで、良い頭の体操をさせてもらいました。
ありがとうございました!