duvc-ctl 2.0.0
USB Video Class Camera Control Library
Loading...
Searching...
No Matches
device_monitor.cpp
Go to the documentation of this file.
1
6#ifdef _WIN32
7
8// clang-format off
9#include <windows.h>
10#include <dbt.h>
11// clang-format on
12#include <dshow.h>
14#include <duvc-ctl/detail/com_helpers.h>
16
17namespace duvc {
18
19// Global state for device monitoring (declared in device.h)
21extern HWND g_notification_window;
22extern HDEVNOTIFY g_device_notify;
23
34 LPARAM lParam) {
36 DUVC_LOG_DEBUG("Received device change notification");
37
40
41 if (hdr && hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
43 reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam);
44
46 std::wstring device_path = dev_iface->dbcc_name;
47
48 DUVC_LOG_INFO(std::string("Device ") +
49 (device_added ? "added: " : "removed: ") +
50 std::string(device_path.begin(), device_path.end()));
51
52 // Call user callback
53 try {
55 } catch (const std::exception &e) {
56 DUVC_LOG_ERROR("Exception in device change callback: " +
57 std::string(e.what()));
58 } catch (...) {
59 DUVC_LOG_ERROR("Unknown exception in device change callback");
60 }
61 }
62 }
63 }
64
66}
67
73 WNDCLASSW wc = {};
74 wc.lpfnWndProc = device_notification_wndproc;
75 wc.hInstance = GetModuleHandle(nullptr);
76 wc.lpszClassName = L"DuvcDeviceNotificationWindow";
77
79 if (result == 0) {
80 DWORD error = GetLastError();
81 if (error != ERROR_CLASS_ALREADY_EXISTS) {
82 DUVC_LOG_ERROR("Failed to register window class: " +
83 std::to_string(error));
84 return false;
85 }
86 }
87
88 return true;
89}
90
97 return nullptr;
98 }
99
100 HWND hwnd = CreateWindowW(L"DuvcDeviceNotificationWindow", // Class name
101 L"duvc-ctl Device Monitor", // Window title
102 0, // Style
103 0, 0, 0, 0, // Position and size (hidden)
104 HWND_MESSAGE, // Message-only window
105 nullptr, // Menu
106 GetModuleHandle(nullptr), // Instance
107 nullptr // Creation parameter
108 );
109
110 if (!hwnd) {
111 DUVC_LOG_ERROR("Failed to create notification window: " +
112 std::to_string(GetLastError()));
113 }
114
115 return hwnd;
116}
117
124 // Register for video input device interface notifications
126 notification_filter.dbcc_size = sizeof(notification_filter);
129
132
133 if (!handle) {
134 DUVC_LOG_ERROR("Failed to register device notifications: " +
135 std::to_string(GetLastError()));
136 } else {
137 DUVC_LOG_INFO("Successfully registered for device notifications");
138 }
139
140 return handle;
141}
142
144 // Don't register multiple times
146 DUVC_LOG_WARNING("Device change callback already registered");
147 return;
148 }
149
150 g_device_callback = callback;
151
152 // Create invisible window for receiving notifications
155 g_device_callback = nullptr;
156 return;
157 }
158
159 // Register for device interface notifications
161 if (!g_device_notify) {
162 DestroyWindow(g_notification_window);
163 g_notification_window = nullptr;
164 g_device_callback = nullptr;
165 return;
166 }
167
168 DUVC_LOG_INFO("Device change monitoring started");
169}
170
172 if (g_device_notify) {
173 UnregisterDeviceNotification(g_device_notify);
174 g_device_notify = nullptr;
175 DUVC_LOG_DEBUG("Unregistered device notifications");
176 }
177
179 DestroyWindow(g_notification_window);
180 g_notification_window = nullptr;
181 DUVC_LOG_DEBUG("Destroyed notification window");
182 }
183
184 g_device_callback = nullptr;
185 DUVC_LOG_INFO("Device change monitoring stopped");
186}
187
188} // namespace duvc
189
190#endif // _WIN32
#define DUVC_LOG_ERROR(msg)
Definition api.h:1077
#define DUVC_LOG_WARNING(msg)
Definition api.h:1076
#define DUVC_LOG_INFO(msg)
Definition api.h:1075
#define DUVC_LOG_DEBUG(msg)
Definition api.h:1074
Result type that can contain either a value or an error.
Definition result.h:75
EXTERN_C const CLSID CLSID_VideoInputDeviceCategory
Definition device.cpp:18
Device enumeration and management functions.
Structured logging interface for duvc-ctl.
Definition core.h:13
static DeviceChangeCallback g_device_callback
Definition core.cpp:147
void unregister_device_change_callback()
Unregister device change callback.
Definition core.cpp:537
static HWND create_notification_window()
Create invisible window for receiving device notifications.
static HDEVNOTIFY g_device_notify
Definition core.cpp:149
void register_device_change_callback(DeviceChangeCallback callback)
Register callback for device hotplug events.
Definition core.cpp:511
std::function< void(bool device_added, const std::wstring &device_path)> DeviceChangeCallback
Device change callback function type.
Definition core.h:34
static LRESULT CALLBACK device_notification_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Window procedure for handling device change notifications.
static HDEVNOTIFY register_device_notifications(HWND hwnd)
Register for device interface notifications.
static HWND g_notification_window
Definition core.cpp:148
static bool register_notification_window_class()
Register window class for device notifications.