2017-07-04 12 views
0

DLPソフトウェアの非常に特殊な要件のために、私はOpenFileDialogsを検出し、選択したファイルをキャプチャした後にファイル選択アクションをキャンセルしようとしています。OpenFileDialogを検出する

どうすればよいですか?

マウスとキーボードにグローバルフックを付けました。 OpenFileDialogウィンドウでファイルを選択するためにユーザーが実行できるすべての操作を検出します。

今までできなかったことは、ウィンドウがhwndによってOpenFileDialogであるかどうかを検出することでした。

なぜこのようにしていますか?

私は高度なプログラマーであり、最初はウィンドウフックで試してみましたが、成功しませんでした。私はeasyhookとdeviare2を試しました。 COM(IFileDialog)コンポーネント呼び出しにグローバルフックを配置する簡単な方法はないようです。

hwndがデフォルトのWindows OpenFileDialogウィンドウであるかどうかを検出する方法はありますか? 部分的な解決策として

public bool IsOpenFileDialog(IntPtr hwnd) 
{ 
    return ? 
} 
+1

十分なことを願っています

public bool IsOpenFileDialog(IntPtr hwnd) { return IsDialogClassName(hwnd) && !IsSaveCaption(hwnd); } 

は確か? –

+1

クラス名 'GetClassName'をチェックしてコントロールなどを列挙できますが、完全にはわかりません。敵が同じクラス名、コントロール、幅、高さなどのウィンドウを作成している可能性があります。 –

+0

こんにちは@DavidHeffernan、Just Windows、XP、7,8,10、そして一般的なサーバーバージョン。 –

答えて

4

(敵対者が、このようなダイアログを模倣することができます)、私は窓場合標準のダイアログをチェックすることをお勧めし、それがあれば、それはキャプションに「保存」を持っていません(あなたはここにもより良いctriteriumを置くことができる):

まず、のはclassをチェックしてみましょう:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx

using System.Runtime.InteropServices; 

... 

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    private static extern int GetClassName(IntPtr hWnd, 
    StringBuilder lpClassName, 
    int nMaxCount); 

    private static String WndClassName(IntPtr handle) { 
    int length = 1024; 

    StringBuilder sb = new StringBuilder(length); 

    GetClassName(handle, sb, length); 

    return sb.ToString(); 
    } 

    public static bool IsDialogClassName(IntPtr handle) { 
    // Standard windows dialogs like OpenFileDialog, SaveFileDialog have #32770 class name 
    return "#32770".Equals(WndClassName(handle)); 
    } 

はしかし、それはあまりにも広いクリテリウムだ:Save File DialogOpen File Dialogの両方がそれを渡します。ウィンドウのキャプションを確認してみましょう:

最後に
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] 
    private static extern int GetWindowTextLength(IntPtr hWnd); 

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern int GetWindowText(IntPtr hWnd, 
    StringBuilder text, 
    int length); 

    private static String WindowText(IntPtr handle) { 
    int length = GetWindowTextLength(handle); 

    StringBuilder sb = new StringBuilder(length + 1); 

    GetWindowText(handle, sb, length + 1); 

    return sb.ToString(); 
    } 

    public static bool IsSaveCaption(IntPtr handle) { 
    //TODO: put a better check for dialog's caption here 
    return WindowText(handle).IndexOf("Save", StringComparison.OrdinalIgnoreCase) >= 0; 
    } 

:あなたには、いくつかの他の基準を望むかもしれないが、私は、これら2つは、どのオペレーティング・システムは、このようなあなたの仕事をするだろう

+0

ありがとう@ドミトリー!私は解決策を提供するためにこのサンプルに従います。ダイアログボックスの子コントロールクラスをチェックするようなフィルタをいくつか追加します。トップナビゲーションバーのような相対的な配置かもしれません。

関連する問題