3

カスタム作業ウィンドウ ( _CustomTaskPane MSDN ) を作成し、そのDockPositionをフローティングに設定するときに、表示されるウィンドウのTopプロパティとLeftプロパティを指定したいと思います。Office COM API はこれを行う直接的な可能性を提供しないため、CommandBar の対応するプロパティの値を変更することをお勧めします。

var application = (_Application)_nativeTaskPane.Application;
application.CommandBars["Task Pane Title"].Top = top;
application.CommandBars["Task Pane Title"].Left = left;

上記のコードでは、

1) _nativeTaskPane は _CustomTaskPane を実装する私のインスタンスです (実際には Microsoft.Office.Core.CustomTaskPane です)

2) _Application は Microsoft.Office.Interop.Excel._Application です。

もちろん、 Visible = trueを設定してからやっています。より確実にするために、作業ウィンドウのVisibleStateChangeにサブスクライブしました。ただし、HRESULT E_FAILED で COMException が発生しています。

問題は、デバッグ時にこれらのプロパティ (Top & Left) を読み取ることができることですが、それらを設定すると例外がスローされます。

問題がインターネットで少なくとも数回発生したようです。

1) http://www.add-in-express.com/forum/read.php?FID=1&TID=5595

2) [http://aritrasaha.wordpress.com/2009/05/19/programatically-position-office-2007-floating-custom-task-pane/]

3) [http://www.visualstudiodev.com/visual-studio-tools-for-office/need-location-of-custom-task-pane-45822.shtml]

回避策は、Windows API を使用することです。しかし、CommandBar アプローチを使用することの何が問題なのか、誰か説明できますか? たぶん、このトップ/レフトセッターが例外なく機能するように「再構成」することができます。

4

4 に答える 4

1

これは私のプログラムで使用するソリューションです:

    /// <summary>
    /// Set a custom panes position in the undocked state.
    /// </summary>
    /// <param name="customTaskPane">The custom task pane.</param>
    /// <param name="x">The new X position.</param>
    /// <param name="y">The new Y position.</param>
    private void SetCustomPanePositionWhenFloating(CustomTaskPane customTaskPane, int x, int y)
    {
        var oldDockPosition = customTaskPane.DockPosition;
        var oldVisibleState = customTaskPane.Visible;

        customTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
        customTaskPane.Visible = true; //The task pane must be visible to set its position

        var window = FindWindowW("MsoCommandBar", customTaskPane.Title); //MLHIDE
        if (window == null) return;

        WinApi.MoveWindow(window, x, y, customTaskPane.Width, customTaskPane.Height, true);

        customTaskPane.Visible = oldVisibleState;
        customTaskPane.DockPosition = oldDockPosition;
    }

    [DllImport("user32.dll", EntryPoint = "FindWindowW")]
    public static extern System.IntPtr FindWindowW([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpClassName, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpWindowName);

    [DllImport("user32.dll", EntryPoint = "MoveWindow")]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
    public static extern bool MoveWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool bRepaint);



    /// <summary>
    /// Set a custom panes size in the undocked state.
    /// </summary>
    /// <param name="customTaskPane">The custom task pane.</param>
    /// <param name="width">The new width.</param>
    /// <param name="height">The new height.</param>
    private void SetCustomPaneSizeWhenFloating(CustomTaskPane customTaskPane, int width, int height)
    {
        var oldDockPosition = customTaskPane.DockPosition;

        customTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
        customTaskPane.Width = width;
        customTaskPane.Height = height;

        customTaskPane.DockPosition = oldDockPosition;
    }

気軽に使ってください... :-)

よろしく、ヨルグ

于 2013-09-06T08:31:24.090 に答える
1

それは動作するはずであり、このエラーに関する MVP Cindy Meister による興味深いコメントがここにあります (彼女はこのフォーラムの質問に答える前に動作することをテストしました) - http://social.msdn.microsoft.com/Forums/vstudio/en-US/ 2df0e430-4d93-416e-89a0-56f8ad5dc988/フローティング カスタム タスク ペインの位置の設定?prof=必須

その中で彼女は、間違った変数を使用してアプリケーション オブジェクトを取得すると、次のようなエラーが発生すると述べています。

Globals.MyAddIn.Application -> this will ultimately cause an exception   
Globals.ThisAddin.Application -> this will ultimately work

両方が同じ Application オブジェクトを返すと仮定します。

それが奇妙だと思うなら、あなたは良い仲間です。

Application オブジェクトへのアクセスに使用される変数の名前が違いを生む理由を尋ねる質問にコメントを追加しました。確かに、同じ Application オブジェクトが使用されています。

私はそれが他のいくつかの内部によって課せられた恐ろしい内部のリフレクションのような制限だと思います. しかし、罪のない開発者は、この非常に奇妙なシナリオから保護されていません。

于 2013-06-26T03:48:31.417 に答える
0

カスタム ペインを設定するfloatingと、定義上、その上部/左側のプロパティを変更できないと思います。正確に何を達成したいですか?ペインを特定の位置に配置しますか? はいの場合は、visibleプロパティを trueに設定する前に実行してください

于 2011-08-04T11:09:08.997 に答える