2016年4月20日水曜日

TiddlyWiki5導入メモと隠しTiddlerの場所



メインはEvernoteなのですが、見た目が面白そうだったのでとりあえず導入しました。

TiddlyWikiはローカルで作成できるWikiです。リンクを貼るのも検索するのも可能で、かつPCに1ファイル作って管理するので、持ち運びにも便利です。
TiddlyWiki5はTiddlyWikiの中での最新版に当たるようです(前のTiddlyWikiはTiddlyWiki Classicと区別される)。

使い方は簡単で、始めは公式サイトの指示に従って(Firefoxユーザーは必要なアドオンをインストールしたうえで)htmlを落としてきます。これを適当な位置において開き、出てくるダイアログに対して許可を選択すると、タイトル編集画面が表示されるので、適当に決めます。もちろん後から変更可能。その後は、ネットで「TiddlyWiki5 日本語化」で検索して、日本語設定へ。


 TiddlyWikiの高度な設定は、あらかじめ用意されている特殊な記事で行うようです(例えばタイトルの変更は、実際にはSiteTitleという記事の本文を変更している)。

これらの特殊な記事は、記事タイトルが「$:/」で始まっており、一部のものを除いては少しわかりにくい位置に存在しています。

恐らくレイアウトを変更していなければ、wikiタイトルの下にある「表示中」「最近の更新」「ツール」「詳しく」というタブがあるので、そこから「詳しく」-「隠し」を選択すると一覧が出てきます。

2016年4月10日日曜日

Bluetoothの接続デバイスを取得する(c++)

※素人のメモ書きです、ご注意ください。

Bluetoothの信号を受け取ってみるのを目標に、今回はまず一覧取得まで作ってみた(コードはGistに投げました)。

こちらのページを参考に、C++で作成。変更したのはwcoutとendlをそれぞれstd::wcout,std::endlにして#include<iostream>を追加したくらい。


基本的には、
  1. radio側の情報取得用配列(para_radio)を用意し初期化
  2. radio側ではHANDLEを作成、BluetoothFindFirstRadioでPC側の持っているBTH機器の位置(?)を構造体に送る(findで成功失敗を確認)
  3. 成功した場合、BluetoothGetRadioInfoでPC側の機器情報を用意した配列(info)に送る
  4. 機器名出力、BluetoothFindNextRadioで次のBTH機器を確認、あれば3へ
  5. device側の情報取得用配列(para_dev)を用意し、情報取得のためのフラグ設定を行う
  6. BluetoothFindFirstDeviceで情報を取得する
  7. 機器名出力後、BluetoothFindNextDeviceで次の機器を確認、あれば6へ
(5に関して、設定毎でどのように結果が変わるのかが気になったので、書いたコードではループしています)

HANDLE型のradioは、FILEみたいな振る舞いをするものかと思ったけれど、device側ではHANDLE型は使われていない。radio側とdevice側で扱う関数は、似ているけれど部分で違うようです。

  
visual studioで、構造体名などで右クリックで定義が見られることを知ったので、ヘッダファイルの見方も慣れていきたいと思いつつ。


--

 構造体BLUETOOTH_DEVICE_SEARCH_PARAMSに関して、

定義では

    BOOL    fReturnAuthenticated;   //  IN  return authenticated devices
    BOOL    fReturnRemembered;      //  IN  return remembered devices
    BOOL    fReturnUnknown;         //  IN  return unknown devices
    BOOL    fReturnConnected;       //  IN  return connected devices

    BOOL    fIssueInquiry;          //  IN  issue a new inquiry
    UCHAR   cTimeoutMultiplier;     //  IN  timeout for the inquiry

    HANDLE  hRadio;                 //  IN  handle to radio to enumerate - NULL == all radios will be searched


とあったが、実際にどうなるのか気になったのでfReturnUnknownとfReturnConnectedのみ確認しました(他はすべてTRUE)。
windows側のBluetooth設定で「BSHSBE21(ペアリング済)」「iphone(ペアリング可能」「不明なデバイス」の3つが表示されている状態での実行結果です。

 

fReturnUnknownはTRUEにすると「名前の取得に失敗していても表示」、fReturnConnectedは「ペアリング済のみ表示」になるようです。



Cortanaをコマンドラインから呼び出す

※素人のメモ書きですのでご注意願います。

--
(2016/10/27追記)
どのタイミングからか不明ですが、build 14393時点でCortanaの呼び出しショートカットが「WINキー+SHIFT+c」に変更になってました。コードのみ修正しました。


--

win10搭載のCortanaに関して、「コルタナさん」と口で言うのは格好良くない気がしたので別の方法で呼び出すことにした。

最初はwin10の資料を探せばCortanaを呼び出すAPIくらいすぐ出るだろうと踏んだが、英語資料が読めず断念。

ブラウザから呼び出せるschemeがあるということは公式サイト内の「コルタナを起動する」リンクから見つけられたが、入力後すぐに音声待ち状態にはならなかったので不採用。
(ちなみにschemeは ms-cortana://)

色々調べた結果、「WINキー+c」「WINキー+SHIFT+c」 のショートカットでCortanaが呼び出せることが分かったのでキー入力を送るプログラムを書くことにした。


--

まず思いついたのは、VBScriptの利用。メモ帳で書いて拡張子を「.vbs」にすれば完成するので手軽。詳しくはないけれど、SendKeysの使い方も入力キーを書いてやるだけだったので。

set obj =CreateObject("WScript.shell")
obj.SendKeys "^{ESC}"


winキーの指定方法がMSDNになかったけれど、「WINキーはCtrl+ESCで代用可能」とあったのでこのように書いた。しかし、これではうまくいかない。どうやら「Ctrl+ESC」の組み合わせは「WINキー」ではなく「スタートメニューを表示する」だけの組み合わせのようだった。
結局SendKeysでWINキーの指定方法が見つけられなかったので、この方法は諦めた。

--

次にSendInput(参考:MSDN)を使用する案が出てきたので、ほとんど書いたことがないC++で挑戦。普段はC言語かつemacsでコード書いてcygwin+gccなので、Visual Studioの使い方から分からないという事態に。

「プロジェクトを新規作成」から「Visual C++ - Win32コンソールアプリケーション」で作成。コードはこちらを参考にさせてもらいつつ作成。





(おそらく初歩的なミスなのだろうが、includeの順をwindows.h,stdafx.hにしていたせいで「No target architecture」が出て大変だった)

LPINPUT構造体に関してまともに情報を見つけられなかったのが悔しい。こういうのは定義を見にいけば良いのだろうか。

見た範囲だと
  • type - キーボード入力ならINPUT_KEYBOARD,マウス入力ならINPUT_MOUSEになる
  • ki - (おそらく)Keyboard Inputの略,マウス入力を作るならmiになるっぽい
  • wVK - WORD型(16bits?)でのキーコード指定、0~255までで指定できる(参考)
  • wScan - 不明
  • dwFlags - 0だとキーを押すイベント、KEYEVENTF_KEYUPだと指定キーを放すイベント
  • time - 不明
となりそう。


 SendInput自体は、
  • SendInput(回数,キーイベントの配列(LPINPUT),配列の大きさ)
なので分かりやすい。

とりあえず、
  1. lpkeyの値を変更してWINキー押下の情報を作る
  2. SendInputでWINキー押下するという情報を送る
  3. lpkeyの値を変更してCキー押下の情報を作る
  4. SendInputでC押下するという情報を送る
  5. lpkeyのdwFlagsのみ変更してCキー開放の情報を作る
  6. SendInputでC開放の情報を送る
  7. lpkeyの残りをWINキー用に書き換えてWINキー開放の情報を作る
  8.  SendInputで投げる
という手順で「WINキー+c」が完成。

後はこれをVisual Studioの上部にある「ローカルWindowsデバッガー」を押して走らせて、問題が無ければ、横の「Debug」を「Release」に変えて、もう一度「ローカルWindowsデバッガー」を押すとexeを作ってくれる。
作成場所は出力ウィンドウの「出力元」を見ればパスが出ているが、多分「ソリューションエクスプローラー」を右クリックして「エクスプローラでフォルダを開く」を選んだ方が早いと思う。

完成のexeを実行して問題が無ければ、後はコマンドプロンプトのパスが通るところに置くなり、aliasでパスを指定しておけば、コマンドラインからCortanaを呼び出せるようになる。

とりあえずcygwinのconfig.iniにcortanaというコマンド名でaliasを書いている。設定はしたが全く実用性はなさそう。


--

(C++の方法で出来たので試してはいないけれど、SendInputがどこかのdllで設定されているならrundll32.exeでコマンドプロンプトから直接実行できるのではという方法もあった。
仕組みが全く分からない上に情報がぼんやりしすぎてて博打感が怖い)



--
追記: Cortanaの音声受付に成功して、結果が返ってからアクティブがCygwinに返ってこないのが気になっている。気が向いたら直す。