2016/08/23

KEYEVENTF_EXTENDEDKEY

zeKeyのメイン機能 キーコード送信にはSendInputを使っています
SendInputには KEYBDINPUT構造体に値をセットして渡すのですが dwFlagsには常にKEYEVENTF_EXTENDEDKEY(拡張キーフラグ)を付けていました

正しくは右Shiftやフルキーボードでいう矢印やDelの列のキー等に付くものなのですが 余計につけても動くという情報も見ましたし 実際動いていました

しかしVisual StudioのエディタでCtrl+ホイール(コードの拡大縮小)をしたところ不具合が出ました(その後のテストでShiftもおかしいと判明)

左Ctrlに拡張キーフラグがセットされているとKeyDownは認識されてコードの拡大縮小はできますが KeyUpは無視するようで通常のスクロールにはならず拡大縮小が継続されてしまいました(当然ですが右Ctrlなら拡張キーなので想定通りの動作になります)

セットするべきキーとセットしないキーは実際実験すればすぐわかるのですが Key列挙体には見た事もない実験のできないキーがたくさんあって困ってしまいます
仮想キーコードが決まれば拡張フラグも決まると思うのですがなんとかならないものか

現状 面倒なので左Alt Ctrl Shiftだけ付けないようにしていますw

2016/08/22

xamlでエキスパンダーのヘッダーにツールチップ表示

拙作のスキン画面にあるエキスパンダー
<Expander Header="スキンフォルダ(_D)">
のヘッダーにツールチップを付けようとしたところ

<Expander Header="スキンフォルダ(_D)" ToolTip="なんたら">
では内部全体に付いてしまいました(当たり前)

<Expander>
  <Expander.Header>
    <TextBlock Text="スキンフォルダ(_D)" ToolTip="なんたら"/>
  </Expander.Header>
</Expander>
にしたらツールチップは思った通りにヘッダーに付きました(当たり前)
しかし スキンフォルダ(_D)と表示されてアクセスキー機能が働かなくなりました
アクセスキー(アクセラレータキー)とは
メニューバーの[ファイル(F)]とかのFの部分
通常はAlt+Fで選択されます 条件によってはAlt無しでも動きます
ちなみに[コピー(C) Ctrl+C]のCtrl+Cの部分はショートカットキーです
実際には何を使ってるのかをライブビジュアルツリー(VS2015の新機能 便利ですね)で見てみたところAccessTextとなっていました
ほとんどの場合AccessTextに自動でラップされるようで表に出てきませんが こういう場合は明示的に書く必要があります

で結局
<Expander>
  <Expander.Header>
    <AccessText Text="スキンフォルダ(_D)" ToolTip="なんたら"/>
  </Expander.Header>
</Expander>
にすればよいということです
テンプレート書く羽目になるかと思っていたので 簡単に解決してよかったです

2016/08/07

かな入力モード ConversionMode

以下の情報は私の環境での結果です 違う環境ではどうなっているか分かりません
Windows7 MS-IME 日本語109キーキーボード

ローマ字入力かな入力の切り替えは
          <z:LRButton.LeftTypeKeys>
            <z:TypeKeys TypeKey="LeftAlt">
              <z:TypeKeys TypeKey="OemCopy" />
            </z:TypeKeys>
          </z:LRButton.LeftTypeKeys>
で注意喚起のダイアログが出た上で トグル動作でした
この場合 入力モードは正常に取得できました

IMEオンの時かなキー
<z:LRButton TypeKey="OemCopy">
だけを押すと一時的に変えるモードなのかよくわかりませんが 何かキーを押すまで入力モードが反映されませでした

かなモードでの英数入力は 英数キー(Capsキー)ですが
<z:LRButton TypeKey="OemAttn">
でトグル動作でした
<z:LRButton TypeKey="Capital"/>
はCapsのトグル動作でした

KeyState.ConversionModeに実際値が入っています IMEオフの時は {x:Null} です

引用 (AutoHotkey)(IMEの制御をする 編) - もらかなです。
状態一覧表
0 = かな入力 半角英数
3 = かな入力 半角カナ
8 = かな入力 全角英数
9 = かな入力 全角ひらがな
11 = かな入力 全角カタカナ
16 = ローマ字入力 半角英数
19 = ローマ字入力 半角カタカナ
24 = ローマ字入力 全角英数
25 = ローマ字入力 全角ひらがな
27 = ローマ字入力 全角カタカナ

zeKeyセキュリティ対策

今のところzeKeyでは

外部アセンブリ禁止

Blend機能は惜しい気もしますが そこまで必要性は感じないし ほかのDLL読み込んでまで必要な機能が思いつかない
DLL自作出来るような人はもっといいのを作ってください

namespaceはスキン用以外読み込ませない

C#は逆コンパイルも簡単らしいので(よく知りませんが)クラス名やメンバ名がわかってもいいように namespaceを分けてxmlns:zを決め打ちすることで安全性が上がるはず
System等が欲しいなと思う時もあるんですが あまりにも広範囲すぎて危なそうなので禁止します

スキンからのアクセスをそのフォルダ以下に制限

Image等のSourceを内部で強制変換します

HyperlinkExクリックで確認ダイアログ

当然ですね

をセキュリティ対策としたいと思います

セキュリティガバガバはさすがにイヤですが ユーザーの自由度がなくなってしまっては意味が無いのでこのあたりが落し所かなと思います
もちろん大穴が見つかったら修正するつもりですが どうしようもない場合公開中止もあるかもしれません

セキュリティ対策をユーザーの責任でキャンセルを許すかどうかですが
スキン設定ファイルにユーザー固有値を含めた上で暗号化して保存する等で 十分安全を担保して実現可能だと思います がそこまで必要か悩み中です


悪意のあるスキンを使ってしまった というのは
例えば ランチャーソフト向けに(ランチャーソフトとは無関係の悪意がある人が)便利設定と偽って設定ファイルとPC破壊バッチファイルをセットで公開し それを使ってしまったのと大差ないというのは言いすぎでしょうか?
それとも ブラウザのバグを突いてHPを開いただけでPCがクラッシュするような状況に近いのでしょうか?
前者はさすがに使ったユーザーの責任 後者はソフト側にも責任(法的には損害賠償などは無理でしょうが)があるような感じがしますが スキンファイルの扱いは前者寄りだと思うのですがどうでしょう?

無責任な言い方かもしれませんが 十二分に注意喚起して それ以上はユーザー責任で使ってもらうしかないかなと思います

2016/08/06

簡単! Path作成

xamlで標準で使えるデータとしてPathがあります
ベクターデータなので画像よりサイズが小さいですし 拡大しても荒れません
作成チュートリアルとしてEnterキーを作ってみます

Blend for Visual Studio 2015

Visual Studio Community 2015をインストールすると一緒に付いてくる Blend for Visual Studio 2015で作成します

コルタナさんで検索しBlendを起動して 新規WPFプロジェクトを作ります

Canvas


アセット-コントロール-パネルからCanvasをドラッグ&ドロップします

Canvasを右クリックしてレイアウト-すべてリセット

Rectangle

アセット-図形-RectangleをCanvasにドラッグ&ドロップ

Rectangleを選択してプロパティウィンドウから RadiusX,Yをマウスホイールで5に変更して角を丸めます

Rectangleをコピー&ペーストで4つ作ります

Rectangleをサイズ調整し↑のように重ねます

結合

重ねたRectangleをCtrlクリックで両方選択して 右クリック-結合-合算でPathにします

もうひとつ↑のように合算します

最後のRectangleを↑のように配置して今度は減算します
位置がずれるとガタガタになるのでマウスホイールで拡大したり RectangleのFillを無しにしたりしてしっかり合わせてください
減算の時は抜きたい方(左下のRectangle)を先に選択し 抜かれる方(右上のPath)を後に選択します

ペンツール

ペンツールを選択するとPathのコントロールポイントが見えるようになります
ドローソフトに慣れている方はベジェ曲線等で自由に描いてみてください

合算で出来てしまった不要なポイントをクリックして削除します

xaml

デザインからXAMLに切り替えます(↑はXamlStylerでFormat XAMLをした後です)

以上で終了です スキンにコピペして使ってみましょう
 <Path Width="92"
            Height="127"
            Data="M5.5,0.5 L86.5,0.5 C89.26,0.5 91.5,2.74 91.5,5.5 L91.5,32.5 91.5,121.5
            C91.5,124.26 89.26,126.5 86.5,126.5 L21.5,126.5 C18.74,126.5 16.5,124.26   
            16.5,121.5 L16.5,64.5 C16.5,61.74 14.26,59.5 11.5,59.5 L5.5,59.5 C2.74,59.5  
            0.5,57.26 0.5,54.5 L0.5,5.5 C0.5,2.74 2.74,0.5 5.5,0.5 z"
            Fill="#FFF4F4F5"
            Stretch="Fill"
            Stroke="Black" />
数値に微妙な誤差が出ていてちょっと気持ち悪いので 小数点第3位を四捨五入してすっきりさせました

絵心があればイラスト等も描けるのですが 私は無いのでこれで精一杯ですw

レインボーアニメーション

一発ネタっぽいですがww

某天国.xaml より(わかりやすいように背景のみにしています)
元ネタ Rainbow color Animation by GradientStops[index].offset : Color « Windows Presentation Foundation « VB.Net Tutorial
<Rectangle Margin="15,50,15,15">
  <Rectangle.Fill>
    <LinearGradientBrush x:Name="brush">
      <LinearGradientBrush.GradientStops>
        <GradientStop Color="Red"/>
        <GradientStop Color="Orange"/>
        <GradientStop Color="Yellow"/>
        <GradientStop Color="Green"/>
        <GradientStop Color="Blue"/>
        <GradientStop Color="Indigo"/>
        <GradientStop Color="Violet"/>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Rectangle.Fill>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard SpeedRatio="3" TargetName="brush">
          <DoubleAnimation Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[0].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:1"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[1].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:2"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[2].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:3"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[3].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:4"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[4].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:5"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[5].Offset"
                            To="1"/>
          <DoubleAnimation BeginTime="0:0:6"
                            Duration="0:0:7"
                            RepeatBehavior="Forever"
                            Storyboard.TargetProperty="GradientStops[6].Offset"
                            To="1"/>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>
コピペコードですが スキンロード時に タイミングをずらしながら7色の基準位置を変更するアニメーションを開始して 虹スクロールするようになっています
そのため最初は単色なのと 左右両端で色が変わる時に ちょっと期待(画像を無限スクロールするようなイメージ)と違う動作になっていますが まあそんなに目立たないでしょう
単独で使う場合は何か他の方法がいいかもしれませんが 思いついていませんw

EventTrigger と Storyboard は非常に強力なので何かいいアイデアを思いついたら どんどん活用したいですね

zeKeyのTypeKeyで指定する値とキーボードの対応表

ぶっちゃけた話 .NETのSystem.Windows.Input.Key をそのまま使っています
ここここをみればいいんですが とても見やすいとは思えないのでまとめました

日本語109キーボードでの対応表


画像クリックで元画像
グレーのキーは文字そのままで通ります(xamlでは大文字小文字の区別はしないようです)
半角/全角キーとひらがな/カタカナキーは 特殊な挙動をしますので実際にキーコードを追ってください(とはいえzeKeyで完全に再現するのは無理です)
IMEのOnOffはKanjiModeで良いです

ややこしい記号キー部分

意味とキーが合っているものは意味のある名前 合ってないものは番号にしました
詳しくは↓の表を見てください

xamlで通るSystem.Windows.Input.Key値

複数の定義があるKey値やKeyConverterで変換されるものも含む
日本語キーボードになさそうなものは除外
Key値説明
Cancel, BREAKBreak キー Ctrl+Pause
Back, BACKSPACE, BKSP, BSBackspace キー
TabTAB キー
ClearClear キー NumLock中にテンキーの5キー
Return, EnterEnter キー
PausePause キー
Capital, CapsLockCapsLock キー
KanaModeIMEかなモード キー
KanjiModeIME漢字モード キー Alt+半角/全角
Escape, ESCEsc キー
ImeConvert変換 キー
ImeNonConvert無変換 キー
SpaceSpace キー
Prior, PageUp, PGUPPageUp キー
Next, PageDown, PGDNPageDown キー
EndEnd キー
HomeHome キー
Left← キー
Up↑ キー
Right→ キー
Down↓ キー
Snapshot, PrintScreen, PRTSCPrintScreen キー
Insert, INSInsert キー
Delete, DELDelete キー
D00 キー(テンキーでは無い方) 数字のみの0は不可
D99 キー(テンキーでは無い方) 数字のみの9は不可
AA キー
ZZ キー
LWin, WINDOWS, WIN, LEFTWINDOWS左Windows キー
RWin, RIGHTWINDOWS右Windows キー
Apps, APPLICATIONアプリケーション キー
NumPad0テンキーの0 キー
|
NumPad9テンキーの9 キー
Multiplyテンキーの* キー
Addテンキーの+ キー
Subtractテンキーの- キー
Decimalテンキーの. キー
Divideテンキーの/ キー
F1F1 キー
|
F12F12 キー
NumLockNumLock キー
ScrollScrollLock キー
LeftShift, SHIFT左Shift キー
RightShift右Shift キー
LeftCtrl, CONTROL, CTRL左Ctrl キー
RightCtrl右Ctrl キー
LeftAlt, ALT左Alt キー
RightAlt右Alt キー
BrowserBackブラウザーの戻る キー
BrowserForwardブラウザーの進む キー
BrowserRefreshブラウザーの更新 キー
BrowserStopブラウザーの中止 キー
BrowserSearchブラウザーの検索 キー
BrowserFavoritesブラウザーのお気に入り キー
BrowserHomeブラウザーのホーム キー
VolumeMute音量ミュート キー
VolumeDown音量ダウン キー
VolumeUp音量アップ キー
MediaNextTrackメディアの次のトラック キー
MediaPreviousTrackメディアの前のトラック キー
MediaStopメディアの停止 キー
MediaPlayPauseメディアの再生/一時停止 キー
SelectMediaメディアの選択 キー
LaunchMailメールを起動 キー
LaunchApplication1アプリケーション1の起動 キー
LaunchApplication2アプリケーション2の起動 キー
Oem1, OemSemicolon, SEMICOLON:* キー (注意)
OemPlus;+ キー
OemComma, COMMA,< キー
OemMinus, MINUS-= キー
OemPeriod, PERIOD.> キー
Oem2, OemQuestion/? キー
Oem3, OemTilde@` キー (注意)
Oem4, OemOpenBrackets[{ キー
Oem5, OemPipe¥| キー
Oem6, OemCloseBrackets]} キー
Oem7, OemQuotes, QUOTES^~ キー (注意)
Oem102, OemBackslash, BACKSLASH¥_ キー

以下IME関連?
私も良くわからないのでキーコードを表示しながらキーボードを打ってみてください
FinalModeThe IME Final mode key.
ImeAcceptThe IME Accept key.
ImeModeChangeThe IME Mode change request.
OemAttn, DbeAlphanumericThe OEM_ATTN key.
OemFinish, DbeKatakana, FINISHThe OEM_FINISH key.
OemCopy, DbeHiraganaThe OEM_COPY key.
OemAuto, DbeSbcsCharThe OEM_AUTO key.
OemEnlw, DbeDbcsCharThe OEM_ENLW key.
OemBackTab, DbeRomanThe OEM_BACKTAB key.
Attn, DbeNoRomanThe ATTN key.