VC#中的多重继承 [英] Multi inheritance in VC#

查看:70
本文介绍了VC#中的多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


为了隐藏WebBrowser控件的图片,我不得不在程序中附加许多代码.我决定将所有这些代码重构为一个单独的类,作为一个库.问题在于这些代码被用作接口的已实现功能.而且我的主窗体类已经从Form类继承,并且编译器可以不允许多重继承.
有没有办法在不给正在使用图书馆的人增加负担的情况下做到这一点?

我的愿望代码:

文件: Form1.cs

Hi,
For hiding pictures of a WebBrowser control I had to append many codes in my program. I decided to refactor all of those code in a separate class as a library. The problem is that these codes are used as implemented functions of an interface. Also my main form class has been inherited from Form class and can the compiler does not permit multi inheritance.
Is there any way to do that without putting burden on a person who is using the library?

My desire codes:

File: Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using myCustomBrowser;


namespace CustomBrowser
{

    [ComVisible(true)]
    public partial class Form1 : Forml,WebOptionManager , myCustomBrowser.IOleClientSite
//The line above causes an error because of multi inheritance
    {
bool _bFirstTime = true;

        public Form1()
        {
            InitializeComponent();
            this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
            this.webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);
            this.webBrowser1.DocumentTitleChanged += new EventHandler(webBrowser1_DocumentTitleChanged);
        }

        void webBrowser1_DocumentTitleChanged(object sender, EventArgs e)
        {
            this.Text = "Custom Browser - " + this.webBrowser1.DocumentTitle;
        }

        void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
        }

        void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

            this.UrlTextBox.Text = e.Url.ToString();

            if ((webBrowserOptions & BrowserOptions.Images) != BrowserOptions.Images)
            {
                System.Diagnostics.Debug.WriteLine("Block images mode");
                HtmlElementCollection col = this.webBrowser1.Document.GetElementsByTagName("img");

                if ((col != null) && (col.Count > 0))
                {
                    System.Diagnostics.Debug.WriteLine("images");
                    this.BlockedLabel.Visible = true;
                }
            }
            else
            {
                this.BlockedLabel.Visible = false;
            }

            System.Diagnostics.Debug.WriteLine("Complete: " + e.Url);
            //this._options |= ~BrowserOptions.Images;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.webBrowser1.Navigate(this.UrlTextBox.Text);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Start();

        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            if (timer1.Enabled == false)
                return;

            timer1.Stop();

        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            if (_bFirstTime)
            {
                _bFirstTime = false;
                IOleObject obj = (IOleObject)this.webBrowser1.ActiveXInstance;
                obj.SetClientSite(this);
                this.webBrowser1.Navigate("http://google.com");
            }
        }

        private void BlockedLabel_MouseHover(object sender, EventArgs e)
        {
            this.BlockedLabel.BackColor = Color.Orange;
            this.BlockedLabel.ForeColor = Color.Black;
        }

        private void BlockedLabel_MouseLeave(object sender, EventArgs e)
        {
            this.BlockedLabel.BackColor = Color.PeachPuff;
            this.BlockedLabel.ForeColor = Color.SteelBlue;
        }

        private void BlockedLabel_Click(object sender, EventArgs e)
        {
            webBrowserOptions |= BrowserOptions.Images;

            IOleControl obj = (IOleControl)this.webBrowser1.ActiveXInstance;

            //notify browser of change
            obj.OnAmbientPropertyChange(-5512);

            this.webBrowser1.Navigate(this.webBrowser1.Url);

            while (this.webBrowser1.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }

            this.webBrowserOptions &= ~BrowserOptions.Images;
            obj.OnAmbientPropertyChange(-5512);
        }

        private void GoButton_Click(object sender, EventArgs e)
        {
            this.webBrowser1.Navigate(this.UrlTextBox.Text);
        }

        private void Form1_Deactivate(object sender, EventArgs e)
        {
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
        }
    }
}



文件: myCustomBrowser.cs



File: myCustomBrowser.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace myCustomBrowser
{
    public enum BrowserOptions : uint
    {
        /// <summary>
        /// No flags are set.
        /// </summary>
        None = 0,
        /// <summary>
        /// The browser will operate in offline mode. Equivalent to DLCTL_FORCEOFFLINE.
        /// </summary>
        AlwaysOffline = 0x10000000,
        /// <summary>
        /// The browser will play background sounds. Equivalent to DLCTL_BGSOUNDS.
        /// </summary>
        BackgroundSounds = 0x00000040,
        /// <summary>
        /// Specifies that the browser will not run Active-X controls. Use this setting
        /// to disable Flash movies. Equivalent to DLCTL_NO_RUNACTIVEXCTLS.
        /// </summary>
        DontRunActiveX = 0x00000200,
        /// <summary>
        ///  Specifies that the browser should fetch the content from the server. If the server''s
        ///  content is the same as the cache, the cache is used.Equivalent to DLCTL_RESYNCHRONIZE.
        /// </summary>
        IgnoreCache = 0x00002000,
        /// <summary>
        ///  The browser will force the request from the server, and ignore the proxy, even if the
        ///  proxy indicates the content is up to date.Equivalent to DLCTL_PRAGMA_NO_CACHE.
        /// </summary>
        IgnoreProxy = 0x00004000,
        /// <summary>
        ///  Specifies that the browser should download and display images. This is set by default.
        ///  Equivalent to DLCTL_DLIMAGES.
        /// </summary>
        Images = 0x00000010,
        /// <summary>
        ///  Disables downloading and installing of Active-X controls.Equivalent to DLCTL_NO_DLACTIVEXCTLS.
        /// </summary>
        NoActiveXDownload = 0x00000400,
        /// <summary>
        ///  Disables web behaviours.Equivalent to DLCTL_NO_BEHAVIORS.
        /// </summary>
        NoBehaviours = 0x00008000,
        /// <summary>
        ///  The browser suppresses any HTML charset specified.Equivalent to DLCTL_NO_METACHARSET.
        /// </summary>
        NoCharSets = 0x00010000,
        /// <summary>
        ///  Indicates the browser will ignore client pulls.Equivalent to DLCTL_NO_CLIENTPULL.
        /// </summary>
        NoClientPull = 0x20000000,
        /// <summary>
        ///  The browser will not download or display Java applets.Equivalent to DLCTL_NO_JAVA.
        /// </summary>
        NoJava = 0x00000100,
        /// <summary>
        ///  The browser will download framesets and parse them, but will not download the frames
        ///  contained inside those framesets.Equivalent to DLCTL_NO_FRAMEDOWNLOAD.
        /// </summary>
        NoFrameDownload = 0x00080000,
        /// <summary>
        ///  The browser will not execute any scripts.Equivalent to DLCTL_NO_SCRIPTS.
        /// </summary>
        NoScripts = 0x00000080,
        /// <summary>
        ///  If the browser cannot detect any internet connection, this causes it to default to
        ///  offline mode.Equivalent to DLCTL_OFFLINEIFNOTCONNECTED.
        /// </summary>
        OfflineIfNotConnected = 0x80000000,
        /// <summary>
        ///  Specifies that UTF8 should be used.Equivalent to DLCTL_URL_ENCODING_ENABLE_UTF8.
        /// </summary>
        UTF8 = 0x00040000,
        /// <summary>
        ///  The browser will download and display video media.Equivalent to DLCTL_VIDEOS.
        /// </summary>
        Videos = 0x00000020
    }


    #region COM Interfaces
    [StructLayout(LayoutKind.Sequential)]
    internal struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }




    [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct MSG
    {
        public IntPtr hwnd;
        public int message;
        public IntPtr wParam;
        public IntPtr lParam;
        public int time;
        public int pt_x;
        public int pt_y;
    }



    [ComVisible(true), Guid("0000011B-0000-0000-C000-000000000046"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleContainer
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] Object pbc,
            [In, MarshalAs(UnmanagedType.LPWStr)] String pszDisplayName, [Out,
            MarshalAs(UnmanagedType.LPArray)] int[] pchEaten, [Out,
            MarshalAs(UnmanagedType.LPArray)] Object[] ppmkOut);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int EnumObjects([In, MarshalAs(UnmanagedType.U4)] uint grfFlags, [Out,
            MarshalAs(UnmanagedType.LPArray)] Object[] ppenum);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int LockContainer([In, MarshalAs(UnmanagedType.Bool)] Boolean fLock);
    }

    [ComVisible(true), Guid("00000118-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleClientSite
    {
        [PreserveSig]
        int SaveObject();
        [PreserveSig]
        int GetMoniker([In, MarshalAs(UnmanagedType.U4)] int dwAssign, [In, MarshalAs(UnmanagedType.U4)] int dwWhichMoniker, [MarshalAs(UnmanagedType.Interface)] out object moniker);
        [PreserveSig]
        int GetContainer(out object container);
        [PreserveSig]
        int ShowObject();
        [PreserveSig]
        int OnShowWindow(int fShow);
        [PreserveSig]
        int RequestNewObjectLayout();
    }

    [ComVisible(true), ComImport(),
    Guid("00000112-0000-0000-C000-000000000046"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IOleObject
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int SetClientSite([In, MarshalAs(UnmanagedType.Interface)] IOleClientSite
            pClientSite);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetClientSite([Out, MarshalAs(UnmanagedType.Interface)] out IOleClientSite site);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int SetHostNames([In, MarshalAs(UnmanagedType.LPWStr)] String
            szContainerApp, [In, MarshalAs(UnmanagedType.LPWStr)] String
            szContainerObj);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Close([In, MarshalAs(UnmanagedType.U4)] uint dwSaveOption);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int SetMoniker([In, MarshalAs(UnmanagedType.U4)] uint dwWhichMoniker, [In,
            MarshalAs(UnmanagedType.Interface)] Object pmk);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetMoniker([In, MarshalAs(UnmanagedType.U4)] uint dwAssign, [In,
            MarshalAs(UnmanagedType.U4)] uint dwWhichMoniker, [Out, MarshalAs(UnmanagedType.Interface)] out Object moniker);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int InitFromData([In, MarshalAs(UnmanagedType.Interface)] Object
            pDataObject, [In, MarshalAs(UnmanagedType.Bool)] Boolean fCreation, [In,
            MarshalAs(UnmanagedType.U4)] uint dwReserved);
        int GetClipboardData([In, MarshalAs(UnmanagedType.U4)] uint dwReserved, out
			Object data);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int DoVerb([In, MarshalAs(UnmanagedType.I4)] int iVerb, [In] IntPtr lpmsg,
            [In, MarshalAs(UnmanagedType.Interface)] IOleClientSite pActiveSite, [In,
            MarshalAs(UnmanagedType.I4)] int lindex, [In] IntPtr hwndParent, [In] RECT
            lprcPosRect);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int EnumVerbs(out Object e); // IEnumOLEVERB
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int OleUpdate();
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int IsUpToDate();
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetUserClassID([In, Out] ref Guid pClsid);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetUserType([In, MarshalAs(UnmanagedType.U4)] uint dwFormOfType, [Out,
            MarshalAs(UnmanagedType.LPWStr)] out String userType);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int SetExtent([In, MarshalAs(UnmanagedType.U4)] uint dwDrawAspect, [In]
			Object pSizel); // tagSIZEL
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetExtent([In, MarshalAs(UnmanagedType.U4)] uint dwDrawAspect, [Out]
			Object pSizel); // tagSIZEL
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Advise([In, MarshalAs(UnmanagedType.Interface)] System.Runtime.InteropServices.ComTypes.IAdviseSink pAdvSink, out
			int cookie);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Unadvise([In, MarshalAs(UnmanagedType.U4)] int dwConnection);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int EnumAdvise(out Object e);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetMiscStatus([In, MarshalAs(UnmanagedType.U4)] uint dwAspect, out int
            misc);
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int SetColorScheme([In] Object pLogpal); // tagLOGPALETTE
    }


    [ComImport, Guid("B196B288-BAB4-101A-B69C-00AA00341D07"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleControl
    {
        [PreserveSig]
        int GetControlInfo([Out] object pCI);
        [PreserveSig]
        int OnMnemonic([In] ref MSG pMsg);
        [PreserveSig]
        int OnAmbientPropertyChange(int dispID);
        [PreserveSig]
        int FreezeEvents(int bFreeze);
    }

    #endregion COM Interfaces

    class WebOptionManager
    {
        BrowserOptions webBrowserOptions = BrowserOptions.DontRunActiveX | BrowserOptions.NoClientPull | BrowserOptions.NoJava | BrowserOptions.NoActiveXDownload;

        [DispId(-5512)]
        public virtual int IDispatch_Invoke_Handler()
        {
            System.Diagnostics.Debug.WriteLine("-5512");
            return (int)webBrowserOptions;
        }
        #region IOleClientSite Members

        public int SaveObject()
        {
            return 0;
        }

        public int GetMoniker(int dwAssign, int dwWhichMoniker, out object moniker)
        {
            moniker = this;
            return 0;
        }

        public int GetContainer(out object container)
        {
            container = this;
            return 0;
        }

        public int ShowObject()
        {
            return 0;
        }

        public int OnShowWindow(int fShow)
        {
            return 0;
        }

        public int RequestNewObjectLayout()
        {
            return 0;
        }

        #endregion
    }
}

推荐答案

我无意阅读所有这些代码.是的,您只能从一个基类继承.如果需要,接口是解决此问题的一种方法.如果您需要多重继承来执行您想做的事情,那么在C#的世界中,您需要重新考虑您的设计.

在我看来,您想要做的是创建一个从Web浏览器控件派生的自己的类,然后将THAT放入您的库中,以便任何使用您的库的人都使用从Web浏览器控件派生的控件,可以关闭图像.
I have no intention of reading all of this code. Yes, you can only inherit from one base class. Interfaces are a way around this, if need be. If you need multiple inheritance to do what you''re trying to do, then in the world of C#, you need to rethink your design.

It looks to me like what you want to do, is create your own class derived from the web browser control, and put THAT in your library, so that who-ever uses your library, uses a control derived from the web browser control, which has a mode to turn off images.


您可以从Form继承WebOptionManager,从WebOptionManager继承IOleClientSite,但这有点愚蠢.

如果是我,我会在您的Form中创建这两个对象,然后将它们用作成员变量.如果需要的话,您可以继承WebBrowser表单来创建一个对象...
You could inherit WebOptionManager from Form, and IOleClientSite from WebOptionManager, but that would be kinda stupid.

If it were me, I''d create those two objects inside your Form, and just use them as member variables. If need be, you could inherit WebBrowser form that other thing to create one object...


这篇关于VC#中的多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆