Tôi đang cố gắng viết thư viện lớp có thể bắt các thông báo của cửa sổ thông báo cho tôi nếu thiết bị đã được đính kèm hoặc bị xóa. Thông thường, trong một cửa sổ ứng dụng hình thức tôi sẽ chỉ ghi đè lên phương pháp WndProc nhưng không có phương pháp WndProc trong trường hợp này. Có cách nào khác để tôi có thể nhận được tin nhắn không?Cách nhận thông báo thiết bị Plug & Play không có dạng cửa sổ
Trả lời
Bạn sẽ cần một cửa sổ, không có cách nào xung quanh điều đó. Đây là triển khai mẫu. Triển khai trình xử lý sự kiện cho DeviceChangeNotifier.DeviceNotify sự kiện để nhận thông báo. Gọi phương thức DeviceChangeNotifier.Start() khi bắt đầu chương trình của bạn. Gọi DeviceChangeNotifier.Stop() ở cuối chương trình của bạn. Lưu ý rằng sự kiện DeviceNotify được nâng lên trên một chuỗi nền, hãy nhớ khóa khi cần thiết để giữ cho chuỗi của bạn an toàn.
using System;
using System.Windows.Forms;
using System.Threading;
class DeviceChangeNotifier : Form {
public delegate void DeviceNotifyDelegate(Message msg);
public static event DeviceNotifyDelegate DeviceNotify;
private static DeviceChangeNotifier mInstance;
public static void Start() {
Thread t = new Thread(runForm);
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
}
public static void Stop() {
if (mInstance == null) throw new InvalidOperationException("Notifier not started");
DeviceNotify = null;
mInstance.Invoke(new MethodInvoker(mInstance.endForm));
}
private static void runForm() {
Application.Run(new DeviceChangeNotifier());
}
private void endForm() {
this.Close();
}
protected override void SetVisibleCore(bool value) {
// Prevent window getting visible
if (mInstance == null) CreateHandle();
mInstance = this;
value = false;
base.SetVisibleCore(value);
}
protected override void WndProc(ref Message m) {
// Trap WM_DEVICECHANGE
if (m.Msg == 0x219) {
DeviceNotifyDelegate handler = DeviceNotify;
if (handler != null) handler(m);
}
base.WndProc(ref m);
}
}
Tôi có một lớp giao tiếp USB hoạt động thực hiện thông báo thay đổi thiết bị theo cách hơi khác nếu có ai quan tâm. Nó khá nhỏ gọn (w / o các ý kiến) và không dựa trên các công cụ Threading
hoặc OnSourceInitialized
và HwndHandler
trong ứng dụng khách. Ngoài ra, bạn không cần Form
hoặc Cửa sổ như đã đề cập. Bất kỳ loại nào bạn có thể ghi đè WndProc()
có thể được sử dụng. Tôi sử dụng Control
.
Mẫu chỉ chứa mã cần thiết để thông báo và không có gì khác. Mã mẫu là C++/CLI và mặc dù tôi không đăng ký thực hành đặt mã thực thi trong các tệp tiêu đề, vì lợi ích của ngắn gọn, tôi làm như vậy ở đây.
#pragma once
#include <Windows.h> // Declares required datatypes.
#include <Dbt.h> // Required for WM_DEVICECHANGE messages.
#include <initguid.h> // Required for DEFINE_GUID definition (see below).
namespace USBComms
{
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Windows;
using namespace System::Windows::Forms;
// This function is required for receieving WM_DEVICECHANGE messages.
// Note: name is remapped "RegisterDeviceNotificationUM"
[DllImport("user32.dll" , CharSet = CharSet::Unicode, EntryPoint="RegisterDeviceNotification")]
extern "C" HDEVNOTIFY WINAPI RegisterDeviceNotificationUM(
HANDLE hRecipient,
LPVOID NotificationFilter,
DWORD Flags);
// Generic guid for usb devices (see e.g. http://msdn.microsoft.com/en-us/library/windows/hardware/ff545972%28v=vs.85%29.aspx).
// Note: GUIDs are device and OS specific and may require modification. Using the wrong guid will cause notification to fail.
// You may have to tinker with your device to find the appropriate GUID. "hid.dll" has a function `HidD_GetHidGuid' that returns
// "the device interfaceGUID for HIDClass devices" (see http://msdn.microsoft.com/en-us/library/windows/hardware/ff538924%28v=vs.85%29.aspx).
// However, testing revealed it does not always return a useful value. The GUID_DEVINTERFACE_USB_DEVICE value, defined as
// {A5DCBF10-6530-11D2-901F-00C04FB951ED}, has worked with cell phones, thumb drives, etc. For more info, see e.g.
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx.
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
/// <summary>
/// Declare a delegate for the notification event handler.
/// </summary>
/// <param name="sender">The object where the event handler is attached.</param>
/// <param name="e">The event data.</param>
public delegate void NotificationEventHandler(Object^ sender, EventArgs^ e);
/// <summary>
/// Class that generetaes USB Device Change notification events.
/// </summary>
/// <remarks>
/// A Form is not necessary. Any type wherein you can override WndProc() can be used.
/// </remarks>
public ref class EventNotifier : public Control
{
private:
/// <summary>
/// Raises the NotificationEvent.
/// </summary>
/// <param name="e">The event data.</param>
void RaiseNotificationEvent(EventArgs^ e) {
NotificationEvent(this, e);
}
protected:
/// <summary>
/// Overrides the base class WndProc method.
/// </summary>
/// <param name="message">The Windows Message to process. </param>
/// <remarks>
/// This method receives Windows Messages (WM_xxxxxxxxxx) and
/// raises our NotificationEvent as appropriate. Here you should
/// add any message filtering (e.g. for the WM_DEVICECHANGE) and
/// preprocessing before raising the event (or not).
/// </remarks>
virtual void WndProc(Message% message) override {
if(message.Msg == WM_DEVICECHANGE)
{
RaiseNotificationEvent(EventArgs::Empty);
}
__super::WndProc(message);
}
public:
/// <summary>
/// Creates a new instance of the EventNotifier class.
/// </summary>
EventNotifier(void) {
RequestNotifications(this->Handle); // Register ourselves as the Windows Message processor.
}
/// <summary>
/// Registers an object, identified by the handle, for
/// Windows WM_DEVICECHANGE messages.
/// </summary>
/// <param name="handle">The object's handle.</param>
bool RequestNotifications(IntPtr handle) {
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_reserved = 0;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
return RegisterDeviceNotificationUM((HANDLE)handle, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE) != NULL;
}
/// <summary>
/// Defines the notification event.
/// </summary>
virtual event NotificationEventHandler^ NotificationEvent;
};
}
Sau đó, trong 'nhận' (các đối tượng mà đặt mua và tiêu thụ NotificationEvent
của chúng tôi), tất cả các bạn phải làm là:
void Receiver::SomeFunction(void)
{
USBComms::EventNotifier usb = gcnew USBComms::EventNotifier();
usb->NotificationEvent += gcnew USBComms::NotificationEventHandler(this, &Receiver::USBEvent);
}
void Receiver::USBEvent(Object^ sender, EventArgs^ e)
{
// Handle the event notification as appropriate.
}
Form là hậu duệ của Control và control kết thúc tốt đẹp một instance window win32. Phương pháp không dựa trên cửa sổ duy nhất mà tôi đã tìm thấy là sử dụng ManagementEventWatcher. Nhưng điều này dường như có những vấn đề riêng của nó. – Felix
Trong các dự án Windows CE/Windows Mobile/SmartDevice, tiêu chuẩn Form
không cung cấp ghi đè lên phương pháp WndProc
, nhưng điều này có thể được thực hiện bằng cách tạo lớp dựa trên Microsoft.WindowsCE.Forms.MessageWindow
, tạo một hàm tạo có dạng, giữ biểu mẫu đó trong biến cục bộ để một phương thức trên biểu mẫu đó có thể được gọi bất cứ khi nào tin nhắn được phát hiện. Đây là một mẫu thu nhỏ để minh họa. Hy vọng điều này là hữu ích cho một ai đó trong thế giới CE/Windows Mobile.
public class MsgWindow : Microsoft.WindowsCE.Forms.MessageWindow {
public const int WM_SER = 0x500;
public const int WM_SER_SCANDONE = WM_SER + 0;
frmMain msgform { get; set; }
public MsgWindow(frmMain msgform) {
this.msgform = msgform;
}
protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message m) {
switch (m.Msg) {
case WM_SER_SCANDONE:
this.msgform.RespondToMessage(WM_SER_SCANDONE);
break;
default:
break;
}
base.WndProc(ref m);
}
}
public partial class frmMain : Form {
public frmMain() {
InitializeComponent();
}
public void RespondToMessage(int nMsg) {
try {
switch (nMsg) {
case MsgWindow.WM_SER_SCANDONE:
// do something here based on the message
break;
default:
break;
}
} catch (Exception ex) {
MessageBox.Show(string.Format("{0} - {1}", ex.Message, ex.ToString()), "RespondToMessage() Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
// throw;
}
}
}
- 1. cách nhận mã thông báo thiết bị?
- 2. nhận tên cửa sổ thông báo
- 3. Có thể viết thiết bị dựa trên cửa sổ không?
- 4. Nhận mã thông báo thiết bị cho thông báo đẩy sau khi ứng dụng bị xóa
- 5. Đại lý không đồng bộ và thông báo cửa sổ
- 6. Cách mở cửa sổ từ thiết bị đầu cuối mac
- 7. Có thể nhận mã thông báo thiết bị ngay cả khi Thông báo đẩy không được bật không?
- 8. Dịch vụ của Google Play: Cách xử lý các thiết bị không có Google Play?
- 9. Mã thông báo đẩy thiết bị?
- 10. Mã thông báo thiết bị có độc đáo như ID thiết bị không?
- 11. Cách tạo cửa sổ WPF không cửa sổ có thể kéo được mà không nhận được InvalidOperationException
- 12. WndProc: Cách nhận thông báo cửa sổ khi biểu mẫu được thu nhỏ
- 13. Thông báo Ngoại lệ với thông báo 'không được nhận dạng' trong WCF
- 14. lập trình nhận dạng thiết bị iphone
- 15. Cách nhận thông báo khi cửa sổ lấy nét trong WPF?
- 16. Cửa sổ chính có thể được thông báo khi cửa sổ con đóng không? (trên một miền khác)
- 17. Mạo danh nhận dạng xác nhận quyền sở hữu đối với cửa sổ nhận dạng
- 18. Kiểm tra xem cửa sổ có bị mất tiêu điểm
- 19. Mã thông báo thiết bị iPhone - NSData hoặc NSString
- 20. Đóng cửa sổ (Xcodes "Thông báo cài đặt") không có loại yếu tố đóng
- 21. Thông báo đẩy iOS - cách xử lý ID thiết bị?
- 22. có thể nhận số nhận dạng duy nhất từ thiết bị di động không?
- 23. Đăng ký thông báo đẩy và mã thông báo thiết bị của Apple Nhận thông tin làm rõ?
- 24. Cách nhận thông báo khi thông báo được thông báo
- 25. Vô hiệu hóa thông báo Gnome 3/cửa sổ bật lên/thông báo tích hợp
- 26. Cách thêm hệ thống "móc cửa sổ" để được thông báo về cửa sổ đang được tạo/kích hoạt?
- 27. Cách nhận cửa sổ có nền mờ trong suốt
- 28. Mã thông báo thiết bị APN có duy nhất cho từng ứng dụng riêng lẻ không?
- 29. Cách nhận tên thiết bị thân thiện từ DEV_BROADCAST_DEVICEINTERFACE và ID thiết bị thiết bị
- 30. Eclipse không nhận dạng được thiết bị Nexus One
+1 Ví dụ tuyệt vời và nobugz là đúng, bạn cần một cửa sổ. – SwDevMan81
+1. Ví dụ hay. –
Tôi thấy bạn sử dụng .Invoke. Điều này có hiệu quả nếu đại biểu không có trong giao diện người dùng không? –