2017-09-02 12 views
0

IDeskBand2を実装する将来のプロジェクト用のサンプルテンプレートを作成しました。IDeskBand2実装がクラッシュする

gacutiます。regasm作品への登録は、それはまた、ツールバーに表示されます。表示/実行したい場合、エクスプローラがクラッシュします。

私はMircosoftとpinvokeのドキュメントを使用して作成しました。

media-control-deskbandと私のプロジェクトを比較し、いくつかのことを試しました(私のプロジェクトのCOMInteropファイル、コード比較など) しかし、原因を見つけることができません。

これは私の実装です。

IDeskBand2インターフェース:使用中の

/// <summary> 
/// Gets information about a band object. 
/// </summary> 
[ComImport] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")] 
public interface IDeskBand : IDockingWindow 
{ 
    /// <summary> 
    /// Gets state information for a band object. 
    /// </summary> 
    /// <param name="dwBandID">The identifier of the band, assigned by the container. The band object can retain this value if it is required.</param> 
    /// <param name="dwViewMode">The view mode of the band object. One of the following values: DBIF_VIEWMODE_NORMAL, DBIF_VIEWMODE_VERTICAL, DBIF_VIEWMODE_FLOATING, DBIF_VIEWMODE_TRANSPARENT.</param> 
    /// <param name="pdbi">Pointer to a DESKBANDINFO structure that receives the band information for the object. The dwMask member of this structure indicates the specific information that is being requested.</param> 
    /// <returns></returns> 
    [PreserveSig] 
    int GetBandInfo(UInt32 dwBandID, DeskBandInfoViewMode dwViewMode, ref DESKBANDINFO pdbi); 
} 


/// <summary> 
/// Exposes methods to enable and query translucency effects in a deskband object. 
/// </summary> 
[ComImport] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("79D16DE4-ABEE-4021-8D9D-9169B261D657")] 
public interface IDeskBand2 : IDeskBand 
{ 
    /// <summary> 
    /// Indicates the deskband's ability to be displayed as translucent. 
    /// </summary> 
    /// <param name="pfCanRenderComposited">When this method returns, contains a BOOL indicating ability.</param> 
    /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns> 
    [PreserveSig] 
    int CanRenderComposited(out bool pfCanRenderComposited); 

    /// <summary> 
    /// Gets the composition state. 
    /// </summary> 
    /// <param name="pfCompositionEnabled">When this method returns, contains a BOOL that indicates state.</param> 
    /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns> 
    [PreserveSig] 
    int GetCompositionState(out bool pfCompositionEnabled); 

    /// <summary> 
    /// Sets the composition state. 
    /// </summary> 
    /// <param name="fCompositionEnabled">TRUE to enable the composition state; otherwise, FALSE.</param> 
    /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns> 
    [PreserveSig] 
    int SetCompositionState(bool fCompositionEnabled); 
} 

IDeskBand2:(GetBandInfo機能がテストされ、正常に動作します。)

/// <summary> 
/// Basic class for a DeskBand object 
/// </summary> 
/// <example> 
/// [Guid("00000000-0000-0000-0000-000000000000")] 
/// [DeskBandInfo("Beispiel Erweiterung", "Diese ist eine Beispiel Erweiterung für die Taskleiste.")] 
/// public class SampleExtension : DeskBand 
/// { /*...*/ } 
/// </example> 
public class DeskBand : UserControl, IDeskBand2 
{ 
    #region Constants 

    private const int S_OK = 0; 
    private const int E_NOTIMPL = unchecked((int)0x80004001); 

    #endregion 

    #region Properties 

    /// <summary> 
    /// Title of the band object, displayed by default on the left or top of the object. 
    /// </summary> 
    [Browsable(true)] 
    [DefaultValue("")] 
    public String Title { get; set; } 

    /// <summary> 
    /// Minimum size of the band object. Default value of -1 sets no minimum constraint. 
    /// </summary> 
    [Browsable(true)] 
    [DefaultValue(typeof(Size), "-1,-1")] 
    public Size MinSize { get; set; } 

    /// <summary> 
    /// Maximum size of the band object. Default value of -1 sets no maximum constraint. 
    /// </summary> 
    [Browsable(true)] 
    [DefaultValue(typeof(Size), "-1,-1")] 
    public Size MaxSize { get; set; } 

    /// <summary> 
    /// Minimum vertical size of the band object. Default value of -1 sets no maximum constraint. (Used when the taskbar is aligned horinzortal.) 
    /// </summary> 
    [Browsable(true)] 
    [DefaultValue(typeof(Size), "-1,-1")] 
    public Size MinSizeVertical { get; set; } 

    /// <summary> 
    /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint. 
    /// </summary> 
    [Browsable(true)] 
    [DefaultValue(typeof(Size), "-1,-1")] 
    public Size IntegralSize { get; set; } 

    #endregion 

    #region IDeskBand2 

    public virtual int CanRenderComposited(out bool pfCanRenderComposited) 
    { 
     pfCanRenderComposited = true; 
     return S_OK; 
    } 

    public int GetCompositionState(out bool pfCompositionEnabled) 
    { 
     pfCompositionEnabled = false; 
     return S_OK; 
    } 

    public int SetCompositionState(bool fCompositionEnabled) 
    { 
     fCompositionEnabled = true; 
     return S_OK; 
    } 

    public int GetBandInfo(uint dwBandID, DeskBandInfoViewMode dwViewMode, ref DESKBANDINFO pdbi) 
    { 
     if (pdbi.dwMask.HasFlag(DeskBandInfoMasks.DBIM_MINSIZE)) 
     { 
      // Support for a vertical taskbar 
      // Most examples have no support for a vertical taskbar. Who in hell uses their taskbar vertically? Me! Very practical on a 21:9 monitor. 
      if (dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_VERTICAL)) 
      { 
       pdbi.ptMinSize.Y = this.MinSizeVertical.Width; 
       pdbi.ptMinSize.X = this.MinSizeVertical.Height; 
      } 
      else 
      { 
       pdbi.ptMinSize.X = this.MinSize.Width; 
       pdbi.ptMinSize.Y = this.MinSize.Height; 
      } 
     } 
     if (pdbi.dwMask.HasFlag(DeskBandInfoMasks.DBIM_MAXSIZE)) 
     { 
      if (dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_VERTICAL)) 
      { 
       pdbi.ptMaxSize.Y = this.MaxSize.Width; 
       pdbi.ptMaxSize.X = this.MaxSize.Height; 
      } 
      else 
      { 
       pdbi.ptMaxSize.X = this.MaxSize.Width; 
       pdbi.ptMaxSize.Y = this.MaxSize.Height; 
      } 
     } 
     if (pdbi.dwMask.HasFlag(DeskBandInfoMasks.DBIM_INTEGRAL)) 
     { 
      if (dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_VERTICAL)) 
      { 
       pdbi.ptIntegral.Y = this.IntegralSize.Width; 
       pdbi.ptIntegral.X = this.IntegralSize.Height; 
      } 
      else 
      { 
       pdbi.ptIntegral.X = this.IntegralSize.Width; 
       pdbi.ptIntegral.Y = this.IntegralSize.Height; 
      } 
     } 

     if (pdbi.dwMask.HasFlag(DeskBandInfoMasks.DBIM_ACTUAL)) 
     { 
      if (dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DeskBandInfoViewMode.DBIF_VIEWMODE_VERTICAL)) 
      { 
       pdbi.ptActual.Y = this.Size.Width; 
       pdbi.ptActual.X = this.Size.Height; 
      } 
      else 
      { 
       pdbi.ptActual.X = this.Size.Width; 
       pdbi.ptActual.Y = this.Size.Height; 
      } 
     } 

     if (pdbi.dwMask.HasFlag(DeskBandInfoMasks.DBIM_TITLE)) 
     { 
      pdbi.wszTitle = this.Title; 
     } 

     pdbi.dwModeFlags = DeskBandInfoModeFlag.DBIMF_ALWAYSGRIPPER | DeskBandInfoModeFlag.DBIMF_NORMAL | DeskBandInfoModeFlag.DBIMF_VARIABLEHEIGHT; 
     pdbi.dwMask = pdbi.dwMask | DeskBandInfoMasks.DBIM_BKCOLOR | DeskBandInfoMasks.DBIM_TITLE; // Testen 

     return S_OK; 
    } 

    public int CloseDW([In] uint dwReserved) 
    { 
     Dispose(true); 
     return S_OK; 
    } 

    public int ResizeBorderDW(IntPtr prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] object punkToolbarSite, bool fReserved) 
    { 
     return E_NOTIMPL; 
    } 

    public int ShowDW([In] bool fShow) 
    { 
     if (fShow) 
      Show(); 
     else 
      Hide(); 

     return S_OK; 
    } 

    public int GetWindow(out IntPtr phwnd) 
    { 
     phwnd = Handle; 
     return S_OK; 
    } 

    public int ContextSensitiveHelp(bool fEnterMode) 
    { 
     return S_OK; 
    } 

    #endregion 

    #region COM 

    [ComRegisterFunctionAttribute] 
    public static void Register(Type t) 
    { 
     string guid = t.GUID.ToString("B"); 

     RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid); 
     RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories"); 

     DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[]) 
      t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false); 

     string _displayName = t.Name; 
     string _helpText = t.Name; 

     if (deskBandInfo.Length == 1) 
     { 
      if (deskBandInfo[0].DisplayName != null) 
      { 
       _displayName = deskBandInfo[0].DisplayName; 
      } 

      if (deskBandInfo[0].HelpText != null) 
      { 
       _helpText = deskBandInfo[0].HelpText; 
      } 
     } 

     rkClass.SetValue(null, _displayName); 
     rkClass.SetValue("MenuText", _displayName); 
     rkClass.SetValue("HelpText", _helpText); 

     // TaskBar 
     rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}"); 
    } 

    [ComUnregisterFunctionAttribute] 
    public static void Unregister(Type t) 
    { 
     string guid = t.GUID.ToString("B"); 

     DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[]) 
      t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false); 

     Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid); 
    } 

    #endregion 

    public DeskBand() 
    { 
     InitializeComponent(); 
    } 

    private void InitializeComponent() 
    { 
     this.Name = "DeskBand"; 
    } 
} 
} 

デザイナーコードなしの実際の拡張子:

namespace TaskbarSampleExt 
{ 
    [Guid("2D53D9CC-0288-4511-A387-B330044C63EA")] 
    [DeskBandInfo("Beispiel Erweiterung", "Diese ist eine Beispiel Erweiterung für die Taskleiste.")] 
    public partial class SampleExtension : DeskBand 
    { 

     public SampleExtension() 
     { 
      this.MinSize = new Size(90, 40); 
      this.MinSizeVertical = new Size(90, 40); 
      this.Title = "Beispiel Erweiterung"; 

      InitializeComponent(); 
     } 

    } 
} 

ありがとうございました

Brocken files

+0

インターフェイス宣言が誤っている、CLRは、COMインターフェイスに関するgimpyであることIUnknownまたはIDispatch以外のインターフェイスを継承します。 CLRがインターフェイスを実装する方法は、C++コンパイラでは実行できない方法と互換性がありません。インターフェイスで指定された順序でクラスを実装することを要求なしでバインディングする方がずっと柔軟です。正しい順序でメソッドが必要なCOMクライアントに柔軟性がない場合は、回避策として基本インターフェイスから継承されたメソッドを含める必要があります。ちょうど退屈なコピー&ペースト。または、インタフェースを平坦化するだけです。 –

+0

答えをいただきありがとうございます。私はSimon Mourierの第2の例のようにインターフェースを変更しました。 _(IDeskBand2ではIOleWindow、IDockingWindowなどのインターフェイスが追加されました)_ これで、クラッシュせずに拡張機能を開始できますが、フォームはタスクバーに表示されません。 Visual Studio(2017)で拡張機能をデバッグすることはできますか、またはExplorerからエラーメッセージを読み取ることはできますか? – patbec

+0

問題が見つかりました。さらに、インターフェイスIObjectWithSiteをベースクラスに含める必要があります。 あなたの説明をありがとう:私はトピックCOMに自分自身を読んで続けます。 – patbec

答えて

1

あなたは正しくペースト/元のコードをコピーしませんでした。 .NETで

あなたは派生インタフェースを宣言IDeskBandからIDeskBand2を言って、あなたベースのインターフェイスのすべてのメソッドを再宣言しなければなりません(と再帰的に、あなただけのコースのIUnknownのを省略することができます)。このよう

は(あなたが派生したい場合は、.NETに表示されます):このような

public interface IDeskBand2 : IDeskBand 
{ 
    // IOleWindow 
    new int GetWindow(out IntPtr phwnd); 
    new int ContextSensitiveHelp(bool fEnterMode); 

    // IDockingWindow 
    new int ShowDW(bool bShow); 
    new int CloseDW(UInt32 dwReserved); 
    new int ResizeBorderDW(RECT rcBorder, IntPtr punkToolbarSite, bool fReserved); 

    // IDeskBand 
    new int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi); 

    // IDeskBand2 
    int CanRenderComposited(out bool pfCanRenderComposited); 
    .... 
} 

または単に:

public interface IDeskBand2 
{ 
    // IOleWindow 
    int GetWindow(out IntPtr phwnd); 
    int ContextSensitiveHelp(bool fEnterMode); 

    // IDockingWindow 
    int ShowDW(bool bShow); 
    int CloseDW(UInt32 dwReserved); 
    int ResizeBorderDW(RECT rcBorder, IntPtr punkToolbarSite, bool fReserved); 

    // IDeskBand 
    int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi); 

    // IDeskBand2 
    int CanRenderComposited(out bool pfCanRenderComposited); 
    .... 
} 
+0

答えをありがとう、私はインターフェイスを変更しました。 クラッシュせずに拡張機能を起動できますが、フォームはタスクバーに表示されません。 IDeskBand2のみを基本クラスに実装するだけで十分ですか? **クラスDeskBand:UserControl、IDeskBand2 ** 拡張機能をデバッグすることはできますか、またはExplorerからエラーを読み取ることはできますか? – patbec

+0

これは別の質問です。しかし、公式の医者は、 "バンド[...]はWindows 7でサポートされていません"と述べています。https://msdn.microsoft.com/en-us/library/windows/desktop/bb762064.aspx –

+0

Windows 10では問題なく動作します。これまでのところ、私はDeskBandsの本当の選択肢を見つけませんでした。 – patbec

関連する問題