2009-03-17 8 views
3

私のC#.Netアプリケーションでは、現在フォーカスされているウィンドウで現在選択されているテキストを取得できるようにしようとしています。 (これは、単語やサファリなどのウィンドウで開いているウィンドウでもかまいません)。C#では、現在フォーカスされているウィンドウの選択されたテキストコンテンツを一貫して取得できる方法はありますか?

現在フォーカスが設定されているコントロールのハンドルを取得できます。 (user32.dllとkernel32.dllに対するいくつかのinterop呼び出しを使用します)。

しかし、私は一貫して選択したテキストを返すことができませんでした。

私はSENDMESSAGEとGET_TEXTを使用しようとしました。しかし、これはいくつかのアプリケーション(ワードパッドのような単純なアプリケーションでは機能し、firefoxやwordなどのより複雑なアプリケーションでは機能しません)では機能するようです。

私はSENDMESSAGEとWM_COPYを使ってみました。しかし、もう一度これはいくつかのコントロールでのみ機能するようです。 (私は、WM_COPYは、手動でCTRL-Cを押すのと全く同じ動作を引き起こすと思いますが、そうではありません)。

私はSENDMESSAGEとWM_KEYUP + WM_KEYDOWNを使用して、手動でコピーコマンドを刺激しようとしました。これは常にうまくいくわけではありません。 (おそらく、ユーザーがアプリケーションを起動するために実際に押したホットキーと重複している可能性があります)。

現在選択されているテキストを一貫して取得できるアイデアはありますか? (任意のアプリケーションで)。

答えて

1

私はそれが可能であるとは思わない、現在フォーカスが選択されたテキストを含むことはできません。 (テキストはまったく含まれていないかもしれません)。あるいは、現在の選択は、アイコンまたは画像であってもよい。

おそらくユーザーが選択したテキストをクリップボードにコピーする必要があるかもしれません。

+0

私の場合は、いつもテキストが選択されていると見なすことができます。 – vicsz

1

質問に間違いがありましたが、Ctrl + cを押しても問題ありませんか?ウィンドウが常に最優先で、コピーするテキストが選択されていることがわかっていれば?一度クリップボードにコピー

SendKeys.SendWait("^c"); 

it's not trickyプログラム的にコンテンツを取得するには(あなたも、それが実際にその時点でのテキストですチェックできます)。

+0

私はSENDMESSAGE KEYUP/KEYDOWNと一緒にこれを試しました。それは必ずしもうまくいくわけではありません。私はそれがキーの重複だと思う。 (つまり、ユーザーがプログラムを起動するためにCtrl + Shift-P、Ctrl + cを押してCtrl + Shift + Pキーを押してctrlcを理解できないなど) – vicsz

0

クリップボードモニタを作成するのは良い選択だと思います。私はKlipper(KDEクリップボードモジュール)を見ることをお勧めします。クリップボードリストで選択したすべてのものをコピーします。コンテンツはファイル、フォルダ、またはテキストです。

詳細はhereです。

0

ええと...あなたは簡単だと思いますか?どうして?

SendKeys.SendWait( "^ c")の最良の代替手段です。私はこの1つだったが見つかりました:

http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=46203

しかし、それは唯一のメモ帳のようないくつかのアプリケーションのために動作します。 Webブラウザの場合、クラッシュするだけです。

誰でも良いものはありますか?

0

他の方法では機能しないコントロールでGetWindowText() APIを試してください。

2

私はワードパッド/メモ帳とUIオートメーションをサポートするもののテキストを取得できました。

下記のコードは、場合によっては動作する場合があります。 Reflectorを使って、TextBoxBase.SelectedTextプロパティのウィンドウがテキストボックスに対してどのようにそれを行うかを見てみましょう。

public static string SelectedText 
{ 
    get 
    { 
     AutomationElement focusedElement = AutomationElement.FocusedElement; 

     object currentPattern = null; 

     if (focusedElement.TryGetCurrentPattern(TextPattern.Pattern, out currentPattern)) 
     { 
      TextPattern textPattern = (TextPattern)currentPattern; 
      TextPatternRange[] textPatternRanges = textPattern.GetSelection(); 
      if (textPatternRanges.Length > 0) 
      { 
       string textSelection = textPatternRanges[0].GetText(-1); 
       return textSelection; 
      } 
     } 
     return string.Empty; 
    } 
    set 
    { 
     AutomationElement focusedElement = AutomationElement.FocusedElement; 
     IntPtr windowHandle = new IntPtr(focusedElement.Current.NativeWindowHandle); 
     NativeMethods.SendMessage(windowHandle, NativeMethods.EM_REPLACESEL, true, value); 
    } 
} 
+0

良いアイデア、私のマシン(勝利7)..で動作しません.Net 3.5 WPFのアプリケーション..返されるwindowHandleは常にゼロです。 – vicsz

4

私はこれをいくつかの組み合わせで動作させました。したがって:

  1. 現在放されている修飾子がすべて解放されるのを待ちます。
  2. Keyboard.SimulateKeyStrokeはクリスSchmickのであるのに対し、そうKeyboard.Modifiersは、System.Windows.Input.Keyboardである私は、WPFを使用しています(この答えTrigger OS to copy (ctrl+c or Ctrl-x) programmaticallyを使用して)

     bool stillHeld = true; 
         int timeSlept = 0; 
    
         do 
         { 
          // wait until our hotkey is released 
          if ((Keyboard.Modifiers & ModifierKeys.Control) > 0 || 
           (Keyboard.Modifiers & ModifierKeys.Alt) > 0 || 
           (Keyboard.Modifiers & ModifierKeys.Shift) > 0) 
          { 
           timeSlept += 50; 
           System.Threading.Thread.Sleep(timeSlept); 
          } 
          else 
          { 
           stillHeld = false; 
          } 
         } while (stillHeld && timeSlept < 1000); 
    
         Keyboard.SimulateKeyStroke('c', ctrl: true); 
    

をコントロール+ Cを送信回答。

注意してください、timeSleptは私の最大時間であり、メイリー・ウェイを続ける前にキーを離れるのを待つ時間です。

関連する問題