2011-06-23 4 views
2

IOleCommandTarget.Exec()を呼び出せるように、パネルコントロールハンドルからIOleCommandTarget参照を取得しようとしています。私NativeMethods.csでNativeWindowでWM_GETOBJECTを処理してIOleCommandTargetを返します。

NativeMethods.IOleCommandTarget target = null; 
if (GetObjectFromHandle<NativeMethods.IOleCommandTarget>(panel.Handle, out target)) 
{ 
    Guid guidCmdGroup = commandID.Guid; 
    handled = (target.Exec(ref guidCmdGroup, commandID.ID, 0, null, 0) == NativeMethods.S_OK); 
} 

private static bool GetObjectFromHandle<T>(IntPtr hwnd, out T value) 
{ 
    Guid guid = typeof(T).GUID; 
    object obj = null; 
    var hr = NativeMethods.AccessibleObjectFromWindow(hwnd, 0, ref guid, ref obj); 
    if (hr == NativeMethods.S_OK) 
    { 
     value = (T)obj; 
     return true; 
    } 
    value = default(T); 
    return false; 
} 

[ComImport] 
[ComVisible(true)] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("B722BCCB-4E68-101B-A2BC-00AA00404770")] 
public interface IOleCommandTarget 
{ 
    [return: MarshalAs(UnmanagedType.I4)] 
    [PreserveSig] 
    int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In, Out] NativeMethods.OLECMD prgCmds, [In, Out] IntPtr pCmdText); 
    [return: MarshalAs(UnmanagedType.I4)] 
    [PreserveSig] 
    int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn, int pvaOut); 
} 

[DllImport("oleacc.dll")] 
public static extern int AccessibleObjectFromWindow(
     IntPtr hwnd, 
     uint id, 
     ref Guid iid, 
     [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject); 

のIOleCommandTargetの参照を返すことができるように、私は、NativeWindowのとのIOleCommandTargetを実装CommandTargetWindowクラスを作成し、私はWM_GETOBJECTメッセージを傍受するためにWndProcメソッドをオーバーライドしていますAccessibleObjectFromWindowは()送信する:

public sealed class CommandTargetWindow : NativeWindow, 
    NativeMethods.IOleCommandTarget, 
    IDisposable 
{ 
    private IWin32Window _parent; 

    public CommandTargetWindow(IWin32Window parent) 
    { 
     _parent = parent; 
     base.AssignHandle(parent.Handle); 
    } 

    [PermissionSetAttribute(SecurityAction.Demand, Unrestricted = true)] 
    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     if (m.Msg == NativeMethods.WM_GETOBJECT) 
     { 
      //How do I pass back an IOleCommandTarget through the message? 
     } 
     base.WndProc(ref m); 
    } 
} 

の質問はどのように行う、上記のコメントのように、ですメッセージを通じてIOleCommandTargetを渡しますか?

我々は(代わりのIOleCommandTargetの)インタフェースたIRawElementProviderSimpleを実装し、定義された静的メソッドAutomationInteropProvider.ReturnRawElementProviderを(使用して、オートメーション目的で使用する他の場所で似た何かを):

[PermissionSetAttribute(SecurityAction.Demand, Unrestricted = true)] 
protected override void WndProc(ref System.Windows.Forms.Message m) 
{ 
    if ((m.Msg == NativeMethods.WM_GETOBJECT) && (m.LParam.ToInt32() == AutomationInteropProvider.RootObjectId)) 
    { 
     m.Result = AutomationInteropProvider.ReturnRawElementProvider(
      Handle, m.WParam, m.LParam, (IRawElementProviderSimple)this); 

     return; 
    } 
    base.WndProc(ref m); 
} 

任意のアイデア?それは私が私のWndProcで今

[DllImport("oleacc.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
public static extern IntPtr LresultFromObject(ref Guid refiid, IntPtr wParam, IntPtr pAcc); 

として、私はNativeMethods.csに定義されているCOMメソッドLresultFromObjectを使用する必要が判明

答えて

2

、私はm.ResultでのIOleCommandTargetハンドルを返すためにLresultFromObjectを呼び出します。

[PermissionSetAttribute(SecurityAction.Demand, Unrestricted = true)] 
protected override void WndProc(ref System.Windows.Forms.Message m) 
{ 
    if (m.Msg == (int)NativeMethods.WindowMessage.GETOBJECT) 
    { 
     if (m.LParam.ToInt32() == AutomationInteropProvider.RootObjectId) 
     { 
      m.Result = AutomationInteropProvider.ReturnRawElementProvider(
       Handle, m.WParam, m.LParam, (IRawElementProviderSimple)this); 

      return; 
     } 
     else if (m.LParam == (IntPtr)NativeMethods.OBJID_NATIVEOM) 
     { 
      IntPtr handle = Marshal.GetComInterfaceForObject(this, typeof(NativeMethods.IOleCommandTarget)); 
      Guid unknownGuid = typeof(NativeMethods.IUnknown).GUID; 
      m.Result = NativeMethods.LresultFromObject(ref unknownGuid, m.WParam, handle); 
      return; 
     } 
    } 
    base.WndProc(ref m); 
} 
関連する問題