2

Componentから派生したカスタムコントロールを作成しています。

このコントロールでは、何らかのイベントを作成するためにOSメッセージWM_DEVICEDCHANGEDを​​取得できる必要があります。

通常、アプリケーションフォームでWndProcを直接オーバーライドしますが、この機能が代わりにコントロールに直接配置されることが非常に重要です。

コントロールは常にフォームで使用されますが、コンポーネントから派生したコントロールでOSメッセージを受信することが重要です。そのため、フォームにコントロールをドロップするときに、フォームに手動で機能を追加する必要はありません。

NativeWindowやその他のソリューションについて言及している例をいくつか見ましたが、どのソリューションでも頭や尻尾を見つけることができなかったので、ここの誰かが私を助けてくれることを願っています。

ありがとう...

4

1 に答える 1

1

WM_DEVICECHANGED メッセージを受け取りたい

コンポーネントをドロップするフォームのウィンドウをサブクラス化するだけです。トップレベルのウィンドウはすべてそのメッセージを受け取ります。プロジェクトに新しいクラスを追加し、以下に示すコードを貼り付けます。建てる。ツールボックスの上部から新しいコンポーネントをフォームにドロップします。DeviceChange イベントのイベント ハンドラーを追加し、関心のあるデバイス変更通知の種類に関連するコードを追加します。そのコードを OnDeviceChange() メソッドに配置して、通知をさらに特化し、より具体的なイベントを発生させることもできます。ここから取るのはあなた次第です。

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;

public class DeviceChangeNotifier : Component {
    public delegate void DeviceChangeDelegate(Message msg);
    public event DeviceChangeDelegate DeviceChange;

    public DeviceChangeNotifier() {
        // Add initialization here
    }
    public DeviceChangeNotifier(IContainer container) : this() {
        // In case you need automatic disposal
        container.Add(this);
    }
    public DeviceChangeNotifier(ContainerControl parentControl) : this() {
        // In case you want to use it without the designer            
        this.ContainerControl = parentControl;
    }

    public ContainerControl ContainerControl {
        // References the parent form
        get { return this.parentControl; }
        set { 
            this.parentControl = value;
            this.parentControl.HandleCreated += parentControl_HandleCreated;
        }
    }

    private void parentControl_HandleCreated(object sender, EventArgs e) {
        // Subclass the form when its handle is created
        snooper = new MessageSnooper(this, parentControl.Handle);        
    }

    protected void OnDeviceChange(Message msg) {
        // Raise the DeviceChange message
        var handler = DeviceChange;
        if (handler != null) handler(msg);
    }

    public override ISite Site {
        // Runs at design time, ensures designer initializes ContainerControl 
        // so we'll have a reference to the parent form without it having to do any work
        set { 
            base.Site = value;
            if (value == null) return;
            IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (service == null) return;
            IComponent rootComponent = service.RootComponent;
            this.ContainerControl = rootComponent as ContainerControl;
        }
    }

    private ContainerControl parentControl;
    private MessageSnooper snooper;
    private const int WM_DESTROY = 0x0002;
    private const int WM_DEVICECHANGE = 0x0219;

    private class MessageSnooper : NativeWindow {
        // Subclasses the parent window
        public MessageSnooper(DeviceChangeNotifier owner, IntPtr handle) {
            this.owner = owner;
            this.AssignHandle(handle);
        }
        protected override void WndProc(ref Message m) {
            if (m.Msg == WM_DESTROY) this.ReleaseHandle();
            if (m.Msg == WM_DEVICECHANGE) owner.OnDeviceChange(m);
            base.WndProc(ref m);
        }
        private DeviceChangeNotifier owner;
    }
}
于 2013-03-24T00:44:34.310 に答える