2008-10-19

SIPの切り替え その2

昨日から悩んでいたSIP切り替え後に表示が崩れる問題を調べている途中、MSDNのSipSetInfo()のページで こんな説明を見つけました。
To prevent undesirable information from being passed to SipSetInfo, clear the SIPINFO structure beforehand.
The following code example shows how to clear the structure.
 
memset(pSipInfo, 0, sizeof(SIPINFO))
 
"undesirable information"というのが引っかかったので、空のSIPINFOをSipSetInfo()に渡してSipSetCurrentIM()の前後で実行してみたのですが何も変わりませんでした。
 
ところが、ふとSIPINFOの定義を見てみると おなじみのcbSizeメンバがあるじゃないですか。 cbSizeをセットしてやると SIPを切り替えても表示が崩れなくなりました。
 
たまたま動いているだけかもしれませんが、昨日のSIP切り替え部分はこんな感じになりました。
static VOID ChgSip()
{
    DWORD   dwData  = 0L;
    SIPINFO sipInfo = {0};

    if (SUCCEEDED(RegistryGetDWORD(SN_DISPLAYROTATION_ROOT, SN_DISPLAYROTATION_PATH, SN_DISPLAYROTATION_VALUE, &dwData))) {
        ZeroMemory(&sipInfo, sizeof(SIPINFO));
        sipInfo.cbSize = sizeof(SIPINFO);
        SipSetInfo(&sipInfo);
        if (0L == dwData) {
            SipSetCurrentIM(&g_clsidPortrait);
        } else {
            SipSetCurrentIM(&g_clsidLandscape);
        }
    }
}

「cbSizeがあったらセットする」というのは常識なのかもしれませんが、せっかくサンプル書くならそこまで書いておいて欲しいですよね。
 
という訳で、一応動いているプログラムを公開しておきます。
 
ChgSIP.exeを適当なフォルダにコピーして起動するとSIPの選択画面が出るので、縦画面・横画面それぞれのSIPを選択してください。
 
あとは画面の向きが切り替わったときに自動的にプログラムが起動してSIPを切り替えます。
 
やっている事は既存ツールの組み合わせで実現できる上に、PQzIIなら普通に備わっている機能なので あくまで参考程度という事で...。
 

8 件のコメント:

CDS さんのコメント...

ChgSIPちょと試してみましたが、非常駐なのは良いですね。
SIPを切り替えるという単機能のみが目的の場合なら、ここはPQzIIに対するメリットじゃないでしょうか。
# ただ一時的とはいえ状態遷移時にはプロセスが立ち上がるのでしょうから、JoeTune常用している身としてはJoeTuneプラグインやservice的な実装の方がより嬉しかったりしますが。

よりPQzIIと差別化を図るなら、アドエス(03も?)限定になりますが、HKEY_CURRENT_USER\Software\Sharp\PhoneStatus\Status22 bit16でのスライドオープン/クローズ遷移も取り込むのというのはどうでしょうか? これもHookKeyHookなんかで可能ですけど。

ネタとしてよりマニアックな設定を許すなら画面のスライド連動回転を切ってる場合向けに、画面向きXスライドの計4状態間の各状態間遷移全8パターンで独立設定可能(SIP切替不要なパターン用にプルダウンメニューに"切替なし"とか追加で)とかでは。ここまでくればJTLPChgEXEC + JTHookKeyHook + MortScript + ChangeSIPとかでやるより単体アプリの方が扱いがかなりスマートです...って
もはやどういうシチュエーションだと便利なのかは微妙ですねぇ(笑)。

kazuaki さんのコメント...

CDSさん こんばんは。
コメントありがとうございます。

そうですね。
Windows Mobileにとって貴重なプロセス数を消費しないというのは重要な事だと思います。
(WM6.1になってDLLの扱いも劇的に改善されているみたいですしね)
JoeTuneは気になっているので何か1つくらいは作ってみたいです。

横方向でキーボード尚且つスライド時というのは盲点でした。
確かに横方向でもキーボードが出てない時は小さいSIPが欲しいですね。

さすがに8方向は...使ってて悩みそうですね(笑

CDS さんのコメント...

お返事どうもです。
JoeTuneのネタ(というか、まぁぶっちゃけJoeTune以外の手段でもいんですが(笑))ですが、RfLedRestrictorを/trafficで常用させていただいてる身としては、これのプロセスが浮くようなら非常に嬉しかったり(^^;;

kazuaki さんのコメント...

CDSさん おはようございます。
コメントありがとうございます。

JoeTuneですが、ちょっとだけ使ってみました。
配置が楽になるというだけを取ってもサービスで作るよりも便利ですね。

RfLedRestrictorが適しているのかを含めてもう少し勉強してみます。

CDS さんのコメント...

RfLedRestrictorのJTプラグイン化ひとまずは可能性の検討を考えていただけるようで有難う御座います。

常駐物というと要望としてはUse10Keyもあるのですが、なんといっても、JoeTuneで他プロセスのサブクラス化って出来るの??(ウィンドウの生成は出来るみたいですが)って所があったので、比較すると実装が素直そうなRfLedRestrictorの方が実現性が高いんじゃないかと思ってこちらにしてみました。

kazuakiさんは色々面白い実装をチャレンジされているので、JoeTuneで面白いアイディアが浮かぶようなら、RfLedRestrictorにこだわらなくても、kazuakiさんの作りたいものを作られてください。

kazuaki さんのコメント...

CDSさん こんばんは。

プラグインの練習をしていたつもりが、JoeTuneとは全く関係のない部分で頭を抱えています(笑

サブクラス化についてはまだ試していませんが問題無いと思います。

でも、Windows Mobile 7になるとこんな無法な事はできなくなるのでしょうね。
少しばかりアバウトな方がいろいろと楽しめるのかもしれません。

CDS さんのコメント...

全プロセスが同一仮想メモリ空間上にマップされているのが他プロセスウィンドウのサブクラス化が可能な理由と推測されてるので、これができるのは32bitアドレス空間前提で考えるなら、32MBx32slot程度に制限されているからこそとも云えるので、2GBx32000プロセスと引き替えならやむなしといった感もありますね...。
でもあいかわらずWM7は逃げ水のように遠ざかっていってるので、相対的にJoeTuneに期待せざるをえないんですが、JoeTuneにしても、同時にロードしてるプラグインが増えれば、dllがメモリ空間を圧迫して、device.exeのドライバロード失敗とかいつもの問題が起きてくるワケですが...。

kazuaki さんのコメント...

CDSさん おはようございます。

それでもWM6.1からはDLLにるメモリの圧迫は大幅に改善しているらしいです。
噂ではWM6.5ではUIが改善されるとか言われているので、そのくらいで止まってくれた方がいろいろ遊べて面白いのかもしれませんね。