C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.5692 の関連記事表示

<< 0 >>
■5692  OS上での文字列選択を感知したい
□投稿者/ まどか -(2007/07/20(Fri) 17:57:51)

    分類:[Windows 全般] 

    OSを使用中にあらゆるものをマウスで範囲選択することは日常的にありますよね。
    で、常駐アプリにて「範囲選択されたよ!」ってのを感知してその文字列を取得したいのだがというのがあります。

    実際の実装方法ではなく、実現方法の概要をお分かりの方教えてくださいませ。
    #「グローバルフック使うのじゃ」とか。
    #「範囲選択を含むウィンドウはこうやって求めるのじゃ」とか。
親記事 /過去ログ16より / 関連記事表示
削除チェック/

■5697  Re[1]: OS上での文字列選択を感知したい
□投稿者/ 中博俊 -(2007/07/20(Fri) 19:34:53)
>
    グローバルフックにそこまでのことをできるんかなー?
    でも選択肢はグローバルフックくらいしかないような。

    よくわかんない<じゃ書かなきゃいいのに(^^;
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5701  Re[1]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/20(Fri) 20:02:36)
    No5692 (まどか さん) に返信
    > 実際の実装方法ではなく、実現方法の概要をお分かりの方教えてくださいませ。

    ほぼ全てのアプリに対して範囲選択を取得するっていうのは無理 なのじゃ。
    自分で描いてる場合とか、できなそうですよね? なのじゃ。

    でも、コモンコントロール限定とかなら
    「グローバルフック使うのじゃ」で
    いけますねぇ なのじゃ。

    テキストボックスは範囲選択したときに
    固有なNotification投げますからそれを拾ってごにょれば なのじゃ。

    #回答の語尾を指定した質問って、ここではよくあるんですか?
    #わんくまってつらいなぁ
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5700  Re[1]: OS上での文字列選択を感知したい
□投稿者/ とっちゃん -(2007/07/20(Fri) 19:58:47)
>
    No5692 (まどか さん) に返信
    > OSを使用中にあらゆるものをマウスで範囲選択することは日常的にありますよね。
    > で、常駐アプリにて「範囲選択されたよ!」ってのを感知してその文字列を取得したいのだがというのがあります。
    >
    結論から言うと、かなり難しいです。

    Native のレベルでみると
    範囲選択の動作は

    WM_LBUTTONDOWN
    SetCapture の呼び出し
    終了

    WM_MOUSEMOVE
    選択範囲の更新(画面フィードバック)

    WM_LBUTTONUP
    ReleaseCapture の呼び出し
    範囲選択結果をどこかに格納
    終了

    という感じになります。

    ウィンドウによってはマウスムーブでスクロールすることもありますが。

    で、これとまったく同じ処理にドラッグドロップがあります。
    OLE の DoDragDrop を使う場合もあるでしょうけど、アプリ内でやってる場合もあります。
    ウィンドウ内だけで閉じているものもあれば、アプリ内で閉じているものもあります。

    もちろん、アプリ間であっても、OLEのDoDragDropを使わずに実現することも
    可能ですので、そういうことをしているソフトもあるかもしれません。


    なので、これだけの情報でそれが選択だったのか、ドラッグなのかは全くわからない
    と言えます。

    特定のアプリケーションのみ、あるいは、特定のウィンドウのみということであれば
    ある程度の精度は出せるとは思いますが、汎用的なものと言うのはたぶん不可能です。

    VisualStudioのテキストエディタで試してみるとわかりますが、
    選択されたところでマウスダウンした場合は、ドラッグ処理に、そうではない場合は選択処理になります。

    こういった条件で動作が変わるソフトもありますので、一概にどっちということは
    判断できないのではないかと。

    他にも、グラフィック系だと、回転とかもありますし、ソフトによっては変形というのもあります。


    それに、Vista になると権限の問題とかもからんでくるので、さらにややこしいことになります。

    結果からいえば、グローバルフックで動作をトレースすることはできたとしても
    それが具体的に何を行っているかは、特定のウィンドウ以外は判断することはできないと思います。
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5704  Re[2]: OS上での文字列選択を感知したい
□投稿者/ まどか -(2007/07/20(Fri) 22:37:49)
    みなさん、ありがとうございます。

    予想通りでした。(もしくは「なるほどね」と意外に簡単な答えと予想してました)
    この話を聞いたときに、
    難しいと思いますよ、
    実現に向けては条件を絞っていくことも必要ですよ
    と想像で答えていましたがやはりでしたか。

    話によるとそういうソフトがあるそうです。
    選択した文字列が電話番号と認識したら、自動で電話をかけるっていうしろもんらしいです。

    こんなんできるんかなぁ程度の話でしたので深刻ではないのが幸いです。
    なわけで、共通的見解が聞けてよかったです。

    > #回答の語尾を指定した質問って、ここではよくあるんですか?

    質問のレベルがわかってましたので仙人みたいな人が答えてくれるだろうと十分予想できました。(笑
記事No.5692 のレス / END /過去ログ16より / 関連記事表示
削除チェック/

■5705  Re[3]: OS上での文字列選択を感知したい
□投稿者/ 渋木宏明(ひどり) -(2007/07/21(Sat) 00:14:54)
>
    > 話によるとそういうソフトがあるそうです。

    バビロンもそーですね。

    昔、噂レベルで聞いた話では「DrawText をフックして…」というものもあるそうです。

記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5706  Re[4]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/21(Sat) 00:18:08)
    No5705 (渋木宏明(ひどり) さん) に返信
    > 昔、噂レベルで聞いた話では「DrawText をフックして…」というものもあるそうです。

    フックというかDLL置き換えでは?

    最近はDLL置き換えもできなくなりましたねぇ。
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5707  Re[5]: OS上での文字列選択を感知したい
□投稿者/ 渋木宏明(ひどり) -(2007/07/21(Sat) 00:28:46)
>
    > フックというかDLL置き換えでは?

    あー、この場合のフックは Windows フックではなくて API フックです。

    DLL インジェクションしてリモートスレッドを起動し、ターゲットプロセスの User32.dll などのインポートテーブルを書き換えるのです。
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5709  Re[6]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/21(Sat) 02:03:20)
    No5707 (渋木宏明(ひどり) さん) に返信
    >>フックというかDLL置き換えでは?
    > DLL インジェクションしてリモートスレッドを起動し、ターゲットプロセスの User32.dll などのインポートテーブルを書き換えるのです。

    インポートテーブル書き換えはAPI Hookでしたね。
    私の周りでは置き返えって呼んでた。
    置き換えだと偽DLL使う方法と間違えてよくないですね。
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5710  Re[4]: OS上での文字列選択を感知したい
□投稿者/ NyaRuRu -(2007/07/21(Sat) 04:51:55)
    No5705 (渋木宏明(ひどり) さん) に返信
    >>話によるとそういうソフトがあるそうです。
    >
    > バビロンもそーですね。

    一応その用途だと IAccessible を中核とした MSAA も,もしかしたら,使えるかもしれませんということで.
    私は全然知らないのでむしろ誰か代わりに調べてくれるなら,という感じですが.
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5712  Re[5]: OS上での文字列選択を感知したい
□投稿者/ 中博俊 -(2007/07/21(Sat) 10:03:38)
>
    >昔、噂レベルで聞いた話では「DrawText をフックして…」というものもあるそうです。

    GDI+や、WPFな世界では通用しないですね。
    複雑な世の中になったもんだ(^^
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5713  Re[5]: OS上での文字列選択を感知したい
□投稿者/ 渋木宏明(ひどり) -(2007/07/21(Sat) 10:32:58)
>
    > 一応その用途だと IAccessible を中核とした MSAA も,もしかしたら,使えるかもしれませんということで.

    実装していないアプリが山盛りあるので、適用範囲が限定されてしまうのが欠点ですね>アクセシビリティ
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5721  Re[6]: OS上での文字列選択を感知したい
□投稿者/ NyaRuRu -(2007/07/21(Sat) 15:05:43)
    No5713 (渋木宏明(ひどり) さん) に返信
    >>一応その用途だと IAccessible を中核とした MSAA も,もしかしたら,使えるかもしれませんということで.
    >
    > 実装していないアプリが山盛りあるので、適用範囲が限定されてしまうのが欠点ですね>アクセシビリティ

    まあ Common Control や Internet Explorer がサポートしていれば結構適用範囲は広いような気もしますけどね.
    あと試してませんが Explorer や Microsoft Office なんかも対応してそうな気がします.MSIME の候補文字列取得にも使えたような.
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5730  Re[7]: OS上での文字列選択を感知したい
□投稿者/ まどか -(2007/07/21(Sat) 21:48:32)
    > DLL インジェクションしてリモートスレッドを起動し、ターゲットプロセスの User32.dll などのインポートテーブルを書き換えるのです。

    むかしN88BASICではROM内からRAMのアドレスを呼び出す部分が組み込まれていましたねぇ。
    SyntaxErrorをフックしてエラー文字列をファイル名と解釈してフロッピーからロードして実行する、
    なんてCP/Mもどきに改造してたりしてたことを思い出しますです。

    おっしゃってる方法はまさに横取りですね。
    いかにも今の世の中ではセキュリティ等などで無理そうってな感じはします。
    まぁそういうやり方そのものも今後闇に消えてくんでしょうかね。

    WM_DRAGSELECTEDみたいなものを全ウィンドウにブロードキャストみたいに送ってくれれば一発解決なんだろうけどなぁ。
    #そういえばそういう仕組みって聞いたこと無い。。。

    なんか解決済みにしても解除されそうなんでしばらくこのままに。
    満足された段階で(ソースが出た!とか)解決済みにしてくださいまし>仙人の方々
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5733  Re[7]: OS上での文字列選択を感知したい
□投稿者/ NyaRuRu -(2007/07/22(Sun) 01:09:42)
    2007/07/22(Sun) 01:11:36 編集(投稿者)

    No5721 (NyaRuRu さん) に返信
    > まあ Common Control や Internet Explorer がサポートしていれば結構適用範囲は広いような気もしますけどね.
    > あと試してませんが Explorer や Microsoft Office なんかも対応してそうな気がします.MSIME の候補文字列取得にも使えたような.

    ちょっと時間がとれたので調べてみました.
    といっても全部やり出すと数日は調査が必要な規模だと分かったので,後はお仕事な人にお任せします.

    ================

    SetWinEventHook API で EVENT_OBJECT_TEXTSELECTIONCHANGED を取得すれば,ある程度のテキスト選択は検知できました.
    低レベルキーボードフックと同じで,SetWinEventHook は DLL にフックプロシージャを必要としないモードもあるので,利用自体は簡単でした.
    困ったのはここからで,フックプロシージャ内で AccessibleObjectFromEvent から IAccessible ポインタを取得し,IAccessible::get_accValue を使用すると,テキストボックス全体のテキストは得られるのですが,選択されている文字列そのものを得る方法はどうも見つかりませんでした.
    対象のウィンドウハンドルは取得できるのでメッセージベースの方法で何とかするか,DLL タイプのフックにして内部から API で取得するかは必要そうな印象を受けました.結局 MSAA の標準機能で何とかできるかどうかはよく分かりません.

    一方,.NET 3.0 に含まれる UI Automation を利用すると,マネージクライアントからアンマネージアプリケーションのテキスト選択を検知し,選択された文字列を取得することができるようです.
    もちろん全てのアプリケーションとはいかず,コモンコントロール V6 や,WPF アプリケーションなどに対象は制限されます.
    http://msdn2.microsoft.com/ja-jp/library/ms744822(VS.80).aspx

    ワードパッドの選択文字列をリアルタイムに取得するサンプルが Windows SDK に含まれています.
    UI Automation は Vista のみでなく XP や Windows Server 2003 もサポートされていルとのことですので,試してみて下さい.
    (RichEdit コントロールは,Windows Vista 以降に付属するバージョンが必要なようです)

    C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WPFSamples.zip
    Accessibility\FindText
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5738  Re[8]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/22(Sun) 07:19:00)
    No5733 (NyaRuRu さん) に返信
    > 困ったのはここからで,フックプロシージャ内で AccessibleObjectFromEvent から IAccessible ポインタを取得し,IAccessible::get_accValue を使用すると,テキストボックス全体のテキストは得られるのですが,選択されている文字列そのものを得る方法はどうも見つかりませんでした.
    > 対象のウィンドウハンドルは取得できるのでメッセージベースの方法で何とかするか,DLL タイプのフックにして内部から API で取得するかは必要そうな印象を受けました.結局 MSAA の標準機能で何とかできるかどうかはよく分かりません.

    http://msdn2.microsoft.com/en-us/library/ms696179.aspx
    には
    > Note to clients
    > Active Accessibility does not expose the text selection in edit and rich edit controls.

    と書かれているので
    選択文字はActive Accessiblityでは無理っぽいですね。
    選択範囲変更の通知は受け取れるのに、変な話ですが。

    EM_GETSELをSendMessageすればEdit ControlとRich Edit Controlで
    選択範囲の文字列が取れるようですので、これを使えということでしょう。きっと。

    ComboBoxは中身のEdit Controlの変更を取得できるようなので、
    MSAAのSetWinEventHookとWindowメッセージのEM_GETSELを組み合わせれば
    Edit、RichEdit、ComboBox
    の3つのコントロールで文字列選択を監視できるだろうということになりますね。
    試してませんが。

    List Box、List View、Tree Viewも処理したいなら
    get_accNameで選択項目の文字列を取れるようです。

    MSAAでは結構簡単にコモンコントロールは網羅できそうです。

    どこかのスレッドの話ではないですが、
    自分でエディタ描いた場合などではMSAAは全くダメですよね。

    DrawText監視はどんな感じになるんでしょう…?
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5739  Re[9]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/22(Sun) 08:02:05)
    No5738 (れい さん) に返信
    > DrawText監視はどんな感じになるんでしょう…?

    DrawTextそのもので選択範囲がわかるわけないので
    DrawTextを発生させたWindowを取得して
    その種類がEditやRichEditだったらEM_GETSELを飛ばすという処理になるんでしょうか?
    それとも描画する色から判断?

    無理・無駄が多いなぁ。

    DrawTextフックができれば
    これもMSAAと同じようにコモンコントロールに対応は簡単そうですが、
    あまりきれいじゃないですね。

    定期的にFocusのあるコントロールを探して、
    EditかRichEditだったなら、EM_GETSELを送るだけでもいい気がしてきました。
    これならコモンコントロール全部に簡単に対応できますし、
    COMも使わなくていいのでかなり簡単です。

    「定期的にFocusのあるコントロールを探して」の部分はグローバルフックなどで置き換えたら
    少し無駄が減るかもしれませんが、
    セキュリティの問題を楽に回避するならTIMERもいいかと。

    IEとOfficeで動けばかなりいけるとおもうんですが
    EM_GETSELは動かないでしょうから個別対応かと思います。

    他にいい方法ないでしょうか?
    今のとこでた案は以下の通り。

    1 メッセージフックでマウスイベント監視
    Dragとの区別がつらそう。
    権限の問題あり。
    2 DrawTextフックでごにょごにょ
    どうやってやるのか(私には)不明。
    権限の問題あり。
    3 MSAA+EM_GETSEL
    ComCtlはOK。
    IE、Officeは変更タイミングは確実に取得可能。選択文字は?
    COMをいじる必要あり(IAccessibleは.Netにあるのでかなり楽かな?)
    無駄は少ない。
    4 TIMER+EM_GETSEL
    ComCtlはOK。
    IE、Officeは?
    COMをいじる必要なし。
    無駄は多いが、ほとんどマネージで済みそう。
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5740  Re[10]: OS上での文字列選択を感知したい
□投稿者/ れい -(2007/07/22(Sun) 08:14:40)
    UI Automationを忘れてました

    5 UI AutomationのITextProvider::GetSelection(かな?)
    ComCtl、WPF
    IE、Officeは?(知らない。IEのAutomationはダメダメだと聞いてますがどうなんでしょう?)
記事No.5692 のレス /過去ログ16より / 関連記事表示
削除チェック/

■5931  Re[11]: OS上での文字列選択を感知したい
□投稿者/ まどか -(2007/07/26(Thu) 14:44:01)
    とりあえず、終了。
記事No.5692 のレス / END /過去ログ16より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -