C# Winform WPF DeskBand 窗体嵌入任务栏,在任务栏显示文字

C# Winform WPF DeskBand 窗体嵌入任务栏,在任务栏显示文字,第1张

概述更新日期:2020年4月23日,更新内容:更新ComImport、DeskBand,解决电脑重启以及explorer.exe重启后,勾选状态没有保存的问题 最近写了个小程序,用于将固态硬盘的写入量等信

    更新日期:2020年4月23日,更新内容:更新Comimport、DeskBand,解决电脑重启以及explorer.exe重启后,勾选状态没有保存的问题

 

    最近写了个小程序,用于将固态硬盘的写入量等信息显示在任务栏,最开始使用windows API也可以实现,但是当任务栏托盘增加的时候,会被遮盖,最终采用了DeskBand来实现,填了很多坑。

    参考的GitHub地址:https://github.com/dsafa/CSDeskBand

    DeskBand相关代码如下:

colorREF:

// This code snippet was used by SharpShell.//using System.Drawing; System.Runtime.InteropServices;namespace MydiskInfo.Interop{    [StructLayout(LayoutKind.Sequential)]    public struct colorREF    {        public colorREF(color color)        {            DWord = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);        }        uint DWord;         color color        {            get            {                return color.FromArgb(                    (int)(0x000000FFU & DWord),(0x0000FF00U & DWord) >> 8,1)">0x00FF0000U & DWord) >> );            }        }    }}
VIEw Code

DESKBANDINFO:

 System; MydiskInfo.Interop{    /// <summary>    /// Receives information about a band object. This structure is used with the deprecated IDeskBand::GetBandInfo method.    </summary>    [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]     DESKBANDINFO    {        <summary>         Set of flags that determine which members of this structure are being requested.         </summary>        <remarks>         This will be a combination of the following values:             DBIM_MINSIZE    ptMinSize is being requested.             DBIM_MAXSIZE    ptMaxSize is being requested.             DBIM_INTEGRAL   ptIntegral is being requested.             DBIM_ACTUAL     ptActual is being requested.             DBIM_Title      wszTitle is being requested.             DBIM_MODEFLAGS  DWModeFlags is being requested.             DBIM_BKcolor    crBkgnd is being requested.        </remarks>         DBIM DWMask;         Point structure that receives the minimum size of the band object.          The minimum wIDth is placed in the x member and the minimum height          is placed in the y member.         </summary>         POINT ptMinSize;         Point structure that receives the maximum size of the band object.          The maximum height is placed in the y member and the x member is ignored.          If there is no limit for the maximum height,(LONG)-1 should be used.          POINT ptMaxSize;         Point structure that receives the sizing step value of the band object.          The vertical step value is placed in the y member,and the x member is ignored.          The step value determines in what increments the band will be resized.          This member is ignored if DWModeFlags does not contain DBIMF_VARIABLEHEIGHT.          POINT ptIntegral;         Point structure that receives the IDeal size of the band object.          The IDeal wIDth is placed in the x member and the IDeal height is placed in the y member.          The band container will attempt to use these values,but the band is not guaranteed to be this size.         POINT ptActual;         The Title of the band.        </summary>        [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 255)]         String wszTitle;         A value that receives a set of flags that define the mode of operation for the band object.          This must be one or a combination of the following values.             DBIMF_norMAL             The band is normal in all respects. The other mode flags modify this flag.             DBIMF_VARIABLEHEIGHT             The height of the band object can be changed. The ptIntegral member defines the              step value by which the band object can be resized.              DBIMF_DEBOSSED             The band object is displayed with a sunken appearance.             DBIMF_BKcolor             The band will be displayed with the background color specifIEd in crBkgnd.         DBIMF DWModeFlags;         The background color of the band.         This member is ignored if DWModeFlags does not contain the DBIMF_BKcolor flag.          colorREF crBkgnd;         The vIEw mode of the band object. This is one of the following values.        </summary>        [Flags]        enum DBIF        {            <summary>             Band object is displayed in a horizontal band.            </summary>            DBIF_viewmode_norMAL = 0x0000 Band object is displayed in a vertical band.            </summary>            DBIF_viewmode_VERTICAL = 0x0001 Band object is displayed in a floating band.            </summary>            DBIF_viewmode_floatING = 0x0002 Band object is displayed in a transparent band.            </summary>            DBIF_viewmode_transparent = 0x0004        }         The set of flags that determine which members of this structure are being requested by the caller. One or more of the following values:         DBIM        {             ptMinSize is requested.            </summary>            DBIM_MINSIZE =  ptMaxSize is requested.            </summary>            DBIM_MAXSIZE =  ptIntegral is requested.            </summary>            DBIM_INTEGRAL =  ptActual is requested.            </summary>            DBIM_ACTUAL = 0x0008 wszTitle is requested.            </summary>            DBIM_Title = 0x0010 DWModeFlags is requested.            </summary>            DBIM_MODEFLAGS = 0x0020 crBkgnd is requested.            </summary>            DBIM_BKcolor = 0x0040 A value that receives a set of flags that specify the mode of operation for the band object. One or more of the following values:        enum DBIMF :         {             The band uses default propertIEs. The other mode flags modify this flag.            </summary>            DBIMF_norMAL =  windows XP and later: The band object is of a fixed sized and position. With this flag,a sizing grip is not displayed on the band object.            </summary>            DBIMF_FIXED =  DBIMF_FIXEDBMP             windows XP and later: The band object uses a fixed bitmap (.bmp) file as its background. Note that backgrounds are not supported in all cases,so the bitmap may not be seen even when this flag is set.            </summary>            DBIMF_FIXEDBMP =  The height of the band object can be changed. The ptIntegral member defines the step value by which the band object can be resized.            </summary>            DBIMF_VARIABLEHEIGHT =  windows XP and later: The band object cannot be removed from the band container.            </summary>            DBIMF_UNDELETEABLE =  The band object is displayed with a sunken appearance.            </summary>            DBIMF_DEBOSSED =  The band is displayed with the background color specifIEd in crBkgnd.            </summary>            DBIMF_BKcolor =  windows XP and later: If the full band object cannot be displayed (that is,the band object is smaller than ptActual,a chevron is shown to indicate that there are more options available. These options are displayed when the chevron is clicked.            </summary>            DBIMF_USECHEVRON = 0x0080 windows XP and later: The band object is displayed in a new row in the band container.            </summary>            DBIMF_BREAK = 0x0100 windows XP and later: The band object is the first object in the band container.            </summary>            DBIMF_ADDTOFRONT = 0x0200 windows XP and later: The band object is displayed in the top row of the band container.            </summary>            DBIMF_topAliGN = 0x0400 windows Vista and later: No sizing grip is ever displayed to allow the user to move or resize the band object.            </summary>            DBIMF_NOgripPER = 0x0800 windows Vista and later: A sizing grip that allows the user to move or resize the band object is always shown,even if that band object is the only one in the container.            </summary>            DBIMF_ALWAYSgripPER = 0x1000 windows Vista and later: The band object should not display margins.            </summary>            DBIMF_NOmarginS = 0x2000        }    }}
VIEw Code

POINT:

// The POINT structure defines the x- and y- coordinates of a point.     POINT    {         The x-coordinate of the point.        int X;         The y-coordinate of the point.         Y;    }}
VIEw Code

RECT:

 RECT    {        public RECT(int left,int top,1)">int right,1)"> bottom)        {            this.left = left;            this.top = top;            this.right = right;            this.bottom = bottom;        }         left,top,right,bottom;         WIDth()        {            return right - left;        }         Height()        {            return bottom - top;        }        voID Offset(int x,1)"> y)        {            left += x;            right += x;            top += y;            bottom += y;        }        voID Set( bottom;        }        bool IsEmpty()        {            return WIDth() == 0 && Height() == 0;        }    }}
VIEw Code

Attributes:

 MydiskInfo{     The display name of the extension and the description for the HelpText(displayed in status bar when menu command selected).        [AttributeUsage(AttributeTargets.Class)]    class DeskBandInfoAttribute : System.Attribute    {        private string _displayname;         _helpText;         displayname        {            get {  _displayname; }        }         HelpText        {             _helpText; }        }         DeskBandInfoAttribute() { }        public DeskBandInfoAttribute(string displayname,1)"> helpText)        {            _displayname = displayname;            _helpText = helpText;        }    }}
VIEw Code

WinError:

 System.Collections.Generic; System.linq; System.Text; System.Threading.Tasks; MydiskInfo.Interop{    static  WinError    {        const int S_OK = ;        int S_FALSE = int E_FAIL = -2147467259int E_INVALIDARG = -2147024809int E_OUTOFMEMORY = -2147024882int E_UNEXPECTED = unchecked((int)0x8000FFFF);        int E_NOTIMPL = 0x80004001int E_NOINTERFACE = 0x80004002int STRSAFE_E_INSUFFICIENT_BUFFER = -2147024774;        uint SEVERITY_SUCCESS = uint SEVERITY_ERROR = 1;         Create an HRESulT value from component pIEces.        <param name="sev">The severity to be used</param>        <param name="fac">The facility to be used<param name="code">The error number<returns>A HRESulT constructed from the above 3 values</returns>        int MAKE_HRESulT(uint sev,1)">uint fac,1)"> code)        {            return (int)((sev << 31) | (fac << 16) | code);        }    }}
VIEw Code

Comimport:

 System.Runtime.InteropServices; System.Security; System.windows.Interop; ProvIDes a simple way to support communication between an object and its site in the container.        [Comimport]    [InterfaceType(ComInterfaceType.InterfaceIsIUnkNown)]    [GuID("FC4801A3-2BA9-11CF-A229-00AA003D7352")]    interface IObjectWithSite    {         Enables a container to pass an object a pointer to the interface for its site.        <param name="pUnkSite">A pointer to the IUnkNown interface pointer of the site managing this object.         If NulL,the object should call Release on any existing site at which point the object no longer kNows its site.</param>        [PreserveSig]        int SetSite([MarshalAs(UnmanagedType.IUnkNown)] object pUnkSite);         RetrIEves the latest site passed using SetSite.        <param name="riID">The IID of the interface pointer that should be returned in ppvSite.<param name="ppvSite">Address of pointer variable that receives the interface pointer requested in riID.int GetSite(ref GuID riID,[MarshalAs(UnmanagedType.IUnkNown)] out IntPtr ppvSite);    }     Exposes a method that is used to communicate focus changes for a user input object contained in the Shell.    F1DB8392-7331-11D0-8C99-00A0C92DBFE8 IinputObjectSite    {         Informs the browser that the focus has changed.        <param name="punkObj">The address of the IUnkNown interface of the object gaining or losing the focus.<param name="fSetFocus">Indicates if the object has gained or lost the focus. If this value is nonzero,the object has gained the focus.         If this value is zero,the object has lost the focus.Returns S_OK if the method was successful,or a COM-defined error code otherwise.</returns>        [PreserveSig]        Int32 OnFocusChangeIS([MarshalAs(UnmanagedType.IUnkNown)] Object punkObj,Int32 fSetFocus);    }     The IoleWindow interface provIDes methods that allow an application to obtain the handle to the varIoUs windows that participate in in-place activation,and also to enter and exit context-sensitive help mode.    00000114-0000-0000-C000-000000000046 IoleWindow    {         RetrIEves a handle to one of the windows participating in in-place activation (frame,document,parent,or in-place object window).        <param name="phwnd">A pointer to a variable that receives the window handle.This method returns S_OK on success.int Getwindow( IntPtr phwnd);         Determines whether context-sensitive help mode should be entered during an in-place activation session.        <param name="fEnterMode">TRUE if help mode should be entered; FALSE if it should be exited.This method returns S_OK if the help mode was entered or exited successfully,depending on the value passed in fEnterMode.int ContextSensitiveHelp( fEnterMode);    }    [Comimport]    [InterfaceType(ComInterfaceType.InterfaceIsIUnkNown)]    [GuID(012DD920-7B26-11D0-8CA9-00A0C92DBFE8 IDockingWindow : IoleWindow    {        #region IoleWindow        [PreserveSig]        new  IntPtr phwnd);        [PreserveSig]         fEnterMode);        #endregion         Instructs the docking window object to show or hIDe itself.        <param name="fShow">TRUE if the docking window object should show its window.         FALSE if the docking window object should hIDe its window and return its border space by calling SetborderSpaceDW with zero values.If this method succeeds,it returns S_OK. Otherwise,it returns an HRESulT error code.int ShowDW([In]  fShow);         NotifIEs the docking window object that it is about to be removed from the frame.         The docking window object should save any persistent information at this time.        <param name="DWReserved">Reserved. This parameter should always be zero. CloseDW([In] UInt32 DWReserved);         NotifIEs the docking window object that the frame's border space has changed.        <param name="prcborder">Pointer to a RECT structure that contains the frame's available border space.<param name="punkToolbarSite">Pointer to the site's IUnkNown interface. The docking window object should call the queryInterface method for this interface,requesting IID_IDockingwindowsite.         The docking window object then uses that interface to negotiate its border space. It is the docking window object's responsibility to release this interface when it is no longer needed.<param name="fReserved">int ResizeborderDW(RECT prcborder,[In,MarshalAs(UnmanagedType.IUnkNown)] IntPtr punkToolbarSite,1)"> fReserved);    }     Gets information about a band object.    EB0FE172-1A3A-11D0-89B3-00A0C90A90AC IDeskBand : IDockingWindow    {        #endregion        #region IDockingWindow fShow);        [PreserveSig]         CloseDW([In] UInt32 DWReserved);        [PreserveSig]         fReserved);         Gets state information for a band object.        <param name="DWBandID">The IDentifIEr of the band,assigned by the container. The band object can retain this value if it is required.<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 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.int GetBandInfo(UInt32 DWBandID,DESKBANDINFO.DBIF DWviewmode,1)">ref DESKBANDINFO pdbi);    }     Exposes methods to enable and query translucency effects in a deskband object.    79D16DE4-ABEE-4021-8D9D-9169B261D657 IDeskBand2 : IDeskBand    {        #region IDeskBand DESKBANDINFO pdbi);         Indicates the deskband's ability to be displayed as translucent.        <param name="pfCanRenderComposited">When this method returns,contains a BOol indicating ability.int CanRenderComposited(out  pfCanRenderComposited);         Sets the composition state.        <param name="fCompositionEnabled">TRUE to enable the composition state; otherwise,FALSE.int SetCompositionState( fCompositionEnabled);         Gets the composition state.        <param name="pfCompositionEnabled">int GetCompositionState( pfCompositionEnabled);    }     Enables the saving and loading of objects that use a simple serial stream for their storage needs.    00000109-0000-0000-C000-000000000046 IPersistStream : IPersist    {        #region IPersist OverrIDes         RetrIEves the class IDentifIEr (CLSID) of the object.        <param name="pClassID">A pointer to the location that receives the CLSID on return.         The CLSID is a globally unique IDentifIEr (GUID) that uniquely represents an object class that defines the code that can manipulate the object's data.<returns>         If the method succeeds,the return value is S_OK. Otherwise,it is E_FAIL.        int GetClassID( GuID pClassID);         Determines whether this instance is dirty.        <returns></returns> IsDirty();         Initializes an object from the stream where it was saved prevIoUsly.        <param name="pStm">An IStream pointer to the stream from which the object should be loaded.This method can return the following values. S_OK,E_OUTOFMEMORY,E_FAIL.int Load([In,MarshalAs(UnmanagedType.Interface)]  pStm);         Saves an object to the specifIEd stream.        An IStream pointer to the stream into which the object should be saved.<param name="fClearDirty">Indicates whether to clear the dirty flag after the save is complete. If TRUE,the flag should be cleared. If FALSE,the flag should be left unchanged.int Save([In,MarshalAs(UnmanagedType.Interface)] IntPtr pStm,1)"> fClearDirty);         RetrIEves the size of the stream needed to save the object.        <param name="pcbSize">The size in bytes of the stream needed to save this object,in bytes.This method returns S_OK to indicate that the size was retrIEved successfully.int GetSizeMax(ulong pcbSize);    }     ProvIDes the CLSID of an object that can be stored persistently in the system.      Allows the object to specify which object handler to use in the clIEnt process,as it is used in the default implementation of marshaling.    0000010c-0000-0000-c000-000000000046 IPersist    {        A pointer to the location that receives the CLSID on return.         If the method succeeds,it is E_FAIL. GuID pClassID);    }     Exposes methods that change UI activation and process accelerators for a user input object contained in the Shell.    68284faa-6a48-11d0-8c78-00c04fd918b4)]    [SuppressUnmanagedCodeSecurity]     IinputObject    {         UI-activates or deactivates the object.        <param name="fActivate">Indicates if the object is being activated or deactivated. If this value is nonzero,the object is being activated. If this value is zero,the object is being deactivated.<param name="msg">A pointer to an MSG structure that contains the message that caused the activation change. This value may be NulL.int UIActivateIO(bool fActivate,1)"> MSG msg);         Determines if one of the object's windows has the keyboard focus.        Returns S_OK if one of the object's windows has the keyboard focus,or S_FALSE otherwise. HasFocusIO();         Enables the object to process keyboard accelerators.        The address of an MSG structure that contains the keyboard message that is being translated.Returns S_OK if the accelerator was translated,1)">int TranslateAcceleratorIO( MSG msg);    }}
VIEw Code

DeskBand,这里和GitHub上的程序不同的是,DeskBand直接继承的ElementHost类,GitHub上的好像是多例的,我想要的是单例的,所以修改了一下。这里粘的代码是WPF的,如果你想实现Winform的,就让DeskBand继承UserControl,DeskBand代码如下:

 copyright(c) 2017 Patrick Becker// Visit the Project page for more information.// https://github.com/patbec/TaskbarSampleExtension Microsoft.Win32; System.ComponentModel; System.windows.Forms; MydiskInfo.Interop; System.windows.Forms.Integration; Utils; System.Threading; Basic class for a DeskBand object    </summary>    <example>     [ComVisible(true)]     [GuID("00000000-0000-0000-0000-000000000000")]     [DeskBandInfo("BeispIEl Erweiterung","DIEse ist eine BeispIEl Erweiterung für dIE Taskleiste.")]     public class SampleExtension : DeskBand     { /*...*/ }    </example>     DeskBand : ElementHost,IObjectWithSite,IDeskBand2,IPersistStream,IinputObject    {        [Dllimport(user32.dll",SetLastError = trueextern  SetParent(IntPtr hWndChild,IntPtr hWndNewParent);        );        protected IinputObjectSite DeskBandSite;         DeskBand()        {            InitializeComponent();        }        voID InitializeComponent()        {            this.name = DeskBand;        }        #region PropertIEs         Title of the band object,displayed by default on the left or top of the object.        </summary>        [browsable()]        [DefaultValue(""public String Title { get; set; }         Minimum size of the band object. Default value of -1 sets no minimum constraint.        )]        [DefaultValue(typeof(Size),-1,-1public Size MinSize {  Maximum size of the band object. Default value of -1 sets no maximum constraint.        public Size MaxSize {  Minimum vertical size of the band object. Default value of -1 sets no maximum constraint. (Used when the taskbar is aligned vertically.)        public Size MinSizeVertical {  Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint.        public Size IntegralSize { ; }        #region IObjectWithSite         SetSite([In,MarshalAs(UnmanagedType.IUnkNown)] Object pUnkSite)        {            tryif (DeskBandSite != null) Marshal.ReleaseComObject(DeskBandSite);                if (pUnkSite != )                {                    var oleWindow = (IoleWindow)pUnkSite;                    IntPtr pHandle = IntPtr.Zero;                    oleWindow.Getwindow( pHandle);                    SetParent(this.Handle,pHandle);                    DeskBandSite = (IinputObjectSite)pUnkSite;                    LogUtil.Log(SetSite S_OK);                     WinError.S_OK;                }                else                {                    LogUtil.Log(SetSite E_FAIL WinError.E_FAIL;                }            }            catch (Exception ex)            {                LogUtil.Error(ex,1)">SetSite error);                 WinError.E_FAIL;            }        }         IntPtr ppvSite)        {            var pUnkNown = Marshal.GetIUnkNownForObject(DeskBandSite);                    var result = Marshal.queryInterface(pUnkNown,1)">ref riID,1)"> ppvSite);                    Marshal.Release(pUnkNown);                    LogUtil.Log(GetSite " + result);                     result;                }                GetSite E_FAIL);                    ppvSite = IntPtr.Zero;                    GetSite error);                Thread.Sleep(200);                ppvSite = IntPtr.Zero;                #region IDeskBand2        virtual  pfCanRenderComposited)        {            pfCanRenderComposited = ;             S_OK;        }         fCompositionEnabled)        {            fCompositionEnabled =  pfCompositionEnabled)        {            pfCompositionEnabled = falseint GetBandInfo(uint DWBandID,1)"> DESKBANDINFO pdbi)        {            if (pdbi.DWMask.HasFlag(DESKBANDINFO.DBIM.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(DESKBANDINFO.DBIF.DBIF_viewmode_floatING) || DWviewmode.HasFlag(DESKBANDINFO.DBIF.DBIF_viewmode_VERTICAL))                {                    pdbi.ptMinSize.Y = .MinSizeVertical.WIDth;                    pdbi.ptMinSize.X = .MinSizeVertical.Height;                }                                {                    pdbi.ptMinSize.X = .MinSize.WIDth;                    pdbi.ptMinSize.Y = .MinSize.Height;                }            }             (pdbi.DWMask.HasFlag(DESKBANDINFO.DBIM.DBIM_MAXSIZE))            {                 DWviewmode.HasFlag(DESKBANDINFO.DBIF.DBIF_viewmode_VERTICAL))                {                    pdbi.ptMaxSize.Y = .MaxSize.WIDth;                    pdbi.ptMaxSize.X = .MaxSize.Height;                }                                {                    pdbi.ptMaxSize.X = .MaxSize.WIDth;                    pdbi.ptMaxSize.Y = .MaxSize.Height;                }            }             (pdbi.DWMask.HasFlag(DESKBANDINFO.DBIM.DBIM_INTEGRAL))            {                 DWviewmode.HasFlag(DESKBANDINFO.DBIF.DBIF_viewmode_VERTICAL))                {                    pdbi.ptIntegral.Y = .IntegralSize.WIDth;                    pdbi.ptIntegral.X = .IntegralSize.Height;                }                                {                    pdbi.ptIntegral.X = .IntegralSize.WIDth;                    pdbi.ptIntegral.Y = .IntegralSize.Height;                }            }             (pdbi.DWMask.HasFlag(DESKBANDINFO.DBIM.DBIM_ACTUAL))            {                 DWviewmode.HasFlag(DESKBANDINFO.DBIF.DBIF_viewmode_VERTICAL))                {                    pdbi.ptActual.Y = .Size.WIDth;                    pdbi.ptActual.X = .Size.Height;                }                                {                    pdbi.ptActual.X = .Size.WIDth;                    pdbi.ptActual.Y = .Size.Height;                }            }             (pdbi.DWMask.HasFlag(DESKBANDINFO.DBIM.DBIM_Title))            {                pdbi.wszTitle = .Title;            }            pdbi.DWModeFlags = DESKBANDINFO.DBIMF.DBIMF_ALWAYSgripPER | DESKBANDINFO.DBIMF.DBIMF_norMAL | DESKBANDINFO.DBIMF.DBIMF_VARIABLEHEIGHT;            pdbi.DWMask = pdbi.DWMask | DESKBANDINFO.DBIM.DBIM_BKcolor | DESKBANDINFO.DBIM.DBIM_Title;  Testen             IntPtr phwnd)        {            phwnd = Handle;             fEnterMode)        {             fShow)        {             (fShow)                Show();                            HIDe();             ClearResources()        {        }        int CloseDW([In]  DWReserved)        {            ClearResources();            dispose();             fReserved)        {             E_NOTIMPL;        }        #region Implementation of IPersistStream        int IPersistStream.GetClassID( GuID pClassID)        {              Log key events.              Return the server class ID.            pClassID = .GetType().GUID;              Return success.             WinError.S_OK;        }         IPersistStream.IsDirty()        {              Todo: return S_OK to indicate the object has changed              since the last time is was saved to a stream.              Until we need explorer bar persistence,we're not dirty.             WinError.S_FALSE;        }        int IPersistStream.Load( pStm)        {              Not implemented: Explorer provIDed Persistence.            int IPersistStream.Save(IntPtr pStm,1)"> fClearDirty)        {            int IPersistStream.GetSizeMax( pcbSize)        {              Not implemented: Explorer provIDed Persistence.            pcbSize = int IPersist.GetClassID(  The class ID is just a unique IDentifIEr for the class,meaning              that we can use the class GUID as it will be provIDed for              all SharpShell servers.            pClassID = #region Implementation of IinputObject         If this method succeeds,it returns an HRESulT error code.        int IinputObject.UIActivateIO( MSG msg)        {              We're done.             WinError.S_OK;        }         Returns S_OK if one of the object's windows has the keyboard focus,or S_FALSE otherwise.         IinputObject.HasFocusIO()        {             Returns S_OK if the accelerator was translated,1)">int IinputObject.TranslateAcceleratorIO( MSG msg)        {            #region Register / Unregister        [ComregisterFunctionAttribute]         Register(Type t)        {            string guID = t.GUID.ToString(B);            DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[])            t.GetCustomAttributes(typeof(DeskBandInfoAttribute),1)">);             Register only the extension if the attribute DeskBandInfo is used.            if (deskBandInfo.Length == )            {                RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\ guID);                RegistryKey rkCat = rkClass.CreateSubKey(Implemented CategorIEs);                string _displayname = t.name;                string _helpText = t.name;                if (deskBandInfo[0].displayname != )                {                    _displayname = deskBandInfo[].displayname;                }                0].HelpText != )                {                    _helpText = deskBandInfo[].HelpText;                }                rkClass.SetValue(MenuTextHelpText Taskbar                rkCat.CreateSubKey({00021492-0000-0000-C000-000000000046});                Console.Writeline(String.Format({0} {1} {2}successfully registered.));            }                        {                Console.Writeline(guID +  has no attributes);            }        }        [ComUnregisterFunctionAttribute]         Unregister(Type t)        {            )            {                 t.name;                ].displayname;                }                Registry.ClassesRoot.CreateSubKey(CLSID).DeleteSubKeyTree(guID);                Console.Writeline(String.Format(successfully removed.);            }        }        #endregion    }}
VIEw Code

diskInfo,该类继承DeskBand,用于实现业务和界面,代码如下:

 DataStruct; System.Threading.Tasks; System.windows; System.windows.Controls; System.windows.Data; System.windows.documents; System.windows.input; System.windows.Media; System.windows.Media.Imaging; System.windows.Navigation; System.windows.Shapes; WCFServer; 固态硬盘信息显示控件    </summary>    partial  diskInfoCtrl : UserControl    {        #region 字段        private Thread _thread = private IClIEntServer _clIEnt = new ClIEntServer();        double _wIDth = 140double _height = 30int _interval = 60 * 1000; 刷新间隔        private diskModel _diskInfo = private diskInfoviewmodel _model =  diskInfoviewmodel();        #region 构造函数         diskInfoCtrl()        {            InitializeComponent();            尺寸            this.WIDth = _wIDth;            this.Height = _height;            this.DataContext = _model;            ShowdiskInfo();            _thread = new Thread(new ThreadStart(() =>while ()                {                    Thread.Sleep(_interval);                    ShowdiskInfo();                }            }));            _thread.Start();        }        #region 显示硬盘信息         显示硬盘信息         ShowdiskInfo()        {            BackWork.Run(() =>            {                _diskInfo = _clIEnt.GetdiskInfo();            },() =>            {                _model.Info = string.Format({0}G {1}G {2}PE { });        }        #region 释放资源         ClearResources()        {            if (_thread != )            {                _thread.Abort();                _thread = ;            }        }            }    #region diskInfoviewmodel     diskInfoviewmodel : INotifyPropertyChanged    {        event PropertyChangedEventHandler PropertyChanged;         _Info;         Info        {             _Info; }                        {                _Info = value;                OnPropertyChanged(InfovoID OnPropertyChanged( name)        {            if (PropertyChanged != )            {                PropertyChanged(this,1)"> PropertyChangedEventArgs(name));            }        }    }    }
VIEw Code

实现业务界面的WPF用户控件:

XAML:

<UserControl x:Class="MydiskInfo.diskInfoCtrl"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"              xmlns:d="http://schemas.microsoft.com/Expression/blend/2008"              mc:Ignorable="d"              d:DesignHeight="30" d:DesignWIDth="120" >    GrID>        TextBlock Text="{Binding Info}" FontFamily="微软雅黑" FontSize="12" Foreground="White" TextAlignment="Center" HorizontalAlignment VerticalAlignment="Center"></TextBlock</>UserControl>    
VIEw Code

后台代码:

 _height;            _diskInfo = _clIEnt.GetdiskInfo();            _model.Info =  _model;            _thread = )                {                    Thread.Sleep(_interval);                    BackWork.Run(() =>                    {                        _diskInfo = _clIEnt.GetdiskInfo();                    },1)">                    {                        _model.Info =  { });                }            }));            _thread.Start();        }        }
VIEw Code

    类库是需要签名的:

其它代码就不粘了,上面粘的代码,去掉业务代码,写个测试的界面,也可以跑起来,程序写好后,怎么安装呢,我写了个Install.bat代码如下:

@echo off"%~dp0gacutil.exe" /if "%~dp0MydiskInfo.dll""%~dp0RegAsm.exe" "%~dp0MydiskInfo.dll"reg import "%~dp0register.reg""%~dp0ServiceInstallUtil\InstallUtil.exe" "%~dp0MydiskInfoService.exe"sc config MydiskInfoService start= autosc config MydiskInfoService type= interact type= ownnet start MydiskInfoServicetaskkill /f /im explorer.exe start explorer.exe Pause
VIEw Code

我是Win10系统,由于GitHub上的,安装之后DeskBand并没有显示在windows工具栏菜单中,可能是注册表写的位置不对,我写了个register.reg,代码如下:

windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}]@="diskInfo""MenuText"="diskInfo""HelpText"="Show diskInfo"[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented CategorIEs][HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented CategorIEs\{00021492-0000-0000-C000-000000000046}][HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented CategorIEs\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}][HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\InprocServer32]@="mscoree.dll""ThreadingModel"="Both""Class"="MydiskInfo.diskInfo""Assembly"="MydiskInfo,Version=1.0.0.0,Culture=neutral,PublicKeyToken=bec8b29cd4c20aff""RuntimeVersion"="v4.0.30319"[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\InprocServer32.0.0.0]"Class"="MydiskInfo.diskInfo""Assembly"="MydiskInfo,PublicKeyToken=bec8b29cd4c20aff""RuntimeVersion"="v4.0.30319"[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\ProgID]@="MydiskInfo.diskInfo"
VIEw Code

最终效果图:

    存在的问题:Win10系统下正常,Win7 *** 作系统下,背景无法透明,如果DeskBand修改为继承Form并且设置TransparenceKey属性为Backcolor,依然无法实现透明,最后放弃了。

    由于DeskBand没有权限读取固态硬盘信息,我写了个windows服务来读取信息,windows服务的安全性设置为“这是完全可信的应用程序”,使用WCF实现进程间管道通信来把数据传给DeskBand显示。

    windows服务注册为开机启动,但是DeskBand不是开机启动,需要自己勾选能才显示出来,DeskBand的自动启动我没有实现,网上资料多是C++的,用勾子实现 (该问题已解决,参见:https://blog.csdn.net/q886yes/article/details/86531307)

完整代码如下:

MyDiskInfo_WPF版_固态硬盘写入量信息嵌入任务栏工具栏

 

总结

以上是内存溢出为你收集整理的C# Winform WPF DeskBand 窗体嵌入任务栏,在任务栏显示文字全部内容,希望文章能够帮你解决C# Winform WPF DeskBand 窗体嵌入任务栏,在任务栏显示文字所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1212643.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存