Device Notification - präziser darstellen anhand lParam und wParam
-
Hallo Forum,
bin zur Zeit an einer DLL am erweitern, die ich von einer externen Quelle bekommen hab.
Ich soll mich mit dieser DLL bei Windows anmelden und mich für Device Notifications registrieren (Klappt schon), um dann Änderungen am USB-Port als Nachricht mir ausgeben zu lassen (klappt eher semibefriedigend).
Ich habe dazu folgenden Code von MSDN gefunden und benutze den vollständigen code.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363432%28v=vs.85%29.aspxBeim starten meines Projekts kommt in einem kleinen Fenster:
"Registered for USB device notification..." (das schonmal gut)Wenn ich nun meine Platine (AT90USB1287) (die angesteckt ist) abstecke , erhalte ich eine Nachricht
"Message 1: DBT_DEVNODES_CHANGED".Wenn ich die Platine nun wieder anstecke kommen folgende Nachrichten:
"Message 2: DBT_DEVNODES_CHANGED
Message 3: DBT_DEVNODES_CHANGED
Message 4: DBT_DEVNODES_CHANGED
Message 5: DBT_DEVNODES_CHANGED
Message 6: DBT_DEVNODES_CHANGED
Message 7: DBT_DEVNODES_CHANGED
Message 8: DBT_DEVNODES_CHANGED
Message 9: DBT_DEVNODES_CHANGED
Message 10: DBT_DEVNODES_CHANGED"
alle auf einmal...benutzte wird die Funktion dafür:
INT_PTR WINAPI WinProcCallback( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) // Routine Description: // Simple Windows callback for handling messages. // This is where all the work is done because the example // is using a window to process messages. This logic would be handled // differently if registering a service instead of a window. // Parameters: // hWnd - the window handle being registered for events. // message - the message being interpreted. // wParam and lParam - extended information provided to this // callback by the message sender. // For more information regarding these parameters and return value, // see the documentation for WNDCLASSEX and CreateWindowEx. { LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; static HWND hEditWnd; static ULONGLONG msgCount = 0; switch (message) { case WM_CREATE: // // This is the actual registration., In this example, registration // should happen only once, at application startup when the window // is created. // // If you were using a service, you would put this in your main code // path as part of your service initialization. // if (!DoRegisterDeviceInterfaceToHwnd( WceusbshGUID, hWnd, &hDeviceNotify)) { // Terminate on failure. ErrorHandler(TEXT("DoRegisterDeviceInterfaceToHwnd")); ExitProcess(1); } // // Make the child window for output. // hEditWnd = CreateWindow(TEXT("EDIT"),// predefined class NULL, // no window title WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, // set size in WM_SIZE message hWnd, // parent window (HMENU)1, // edit control ID (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); // pointer not needed if (hEditWnd == NULL) { // Terminate on failure. ErrorHandler(TEXT("CreateWindow: Edit Control")); ExitProcess(1); } // Add text to the window. SendMessage(hEditWnd, WM_SETTEXT, 0, (LPARAM)TEXT("Registered for USB device notification...\n")); break; case WM_SETFOCUS: SetFocus(hEditWnd); break; case WM_SIZE: // Make the edit control the size of the window's client area. MoveWindow(hEditWnd, 0, 0, // starting x- and y-coordinates LOWORD(lParam), // width of client area HIWORD(lParam), // height of client area TRUE); // repaint window break; case WM_DEVICECHANGE: { // // This is the actual message from the interface via Windows messaging. // This code includes some additional decoding for this particular device type // and some common validation checks. // // Note that not all devices utilize these optional parameters in the same // way. Refer to the extended information for your particular device type // specified by your GUID. // PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; TCHAR strBuff[256]; // Output some messages to the window. switch (wParam) { //wParam = 0x8004 //lParam = case DBT_DEVICEARRIVAL: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); break; //wParam = 0x8004 //lParam = case DBT_DEVICEREMOVECOMPLETE: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); break; //wParam = 0x0007 //lParam = Set to zero. case DBT_DEVNODES_CHANGED: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); break; default: //wParam = msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), msgCount, wParam); break; } OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); } break; case WM_CLOSE: if (!UnregisterDeviceNotification(hDeviceNotify)) { ErrorHandler(TEXT("UnregisterDeviceNotification")); } DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); break; } return lRet; }
jetzt würde ich aber gerne wissen was der Unterschied aller Nachrichten ist und somit was mir lparam und wParam sagen wollen.
Dazu würde ich mir gerne diese beiden ausgeben lassen aber ich weiss nicht wo im Code und ich weiss nicht wie.
Oder gibt es auch noch eine Möglichkeit mir alle Informationen über die Veränderung am USB-Port mitteilen zu lassen also ob dieses abgesteckt wurde oder einfahc nur nicht mehr verfügbar ist im Moment weil es anderweitig benutzt. Irgendwie halt aussagekräftigere Info als die oben.
Kurze Info zum Schluss: Bin Anfänger auf dem Gebiet also je ausführlicher oder je eindeutiger desto besser für mich :).
Wäre um Hilfe sehr sehr dankbar!!!
Gruß
Markus
-
Was genau willst Du erreichen? Für mich sieht es eben so aus, als abonnierst Du Ereignisse für Veränderungen von WCE Devices. Hast Du sowas, oder sind es wieder HIDs? Wenn letzteres, dann in etwa so:
DEV_BROADCAST_DEVICEINTERFACE itf = {}; itf.dbcc_size = sizeof(itf); itf.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; HidD_GetHidGuid(&itf.dbcc_classguid); RegisterDeviceNotification(hWnd, &itf, DEVICE_NOTIFY_WINDOW_HANDLE);
Wenn das in die falsche Richtung geht, dann -v bitte.
-
Ich arbeit nur mit HID Interfaces.
Allgemein möchte ich erstmal herausfinden was hinter diesen Nachrichten "Message 1: DBT_DEVNODES_CHANGED" genauer steht. Also was sich genau geändert hat.
Weil aussagekräftig finde ich das jetzt nicht.Und ich würde gerne wissen wieso ich nicht ein anderes Ereignis auch bekomme wie z.b. "DBT_DEVICEARRIVAL" weil es wird ja auch wieder meine Platine angesteckt.
-
pargus schrieb:
Allgemein möchte ich erstmal herausfinden was hinter diesen Nachrichten "Message 1: DBT_DEVNODES_CHANGED" genauer steht. Also was sich genau geändert hat.
Weil aussagekräftig finde ich das jetzt nicht.Tja, so ist das eben, wenn es der Treiber versäumt, IoRegisterDeviceInterface aufzurufen (wie z.B. usbser.sys). Das ist aber kein Problem, wenn Du Dir das "Vorher" gemerkt hast. Und bei HIDs kommen ja auch noch andere Notifications.
pargus schrieb:
Und ich würde gerne wissen wieso ich nicht ein anderes Ereignis auch bekomme wie z.b. "DBT_DEVICEARRIVAL" weil es wird ja auch wieder meine Platine angesteckt.
Bei HIDs kommt definitiv DBT_DEVICEARRIVAL, wenn sie angestöpselt werden. Hast Du denn jetzt wenigstens den Aufruf von RegisterDeviceNotification korrigiert, oder hast Du das noch immer falsch in Deinen Quellen stehen?
-
Mox schrieb:
Tja, so ist das eben, wenn es der Treiber versäumt, IoRegisterDeviceInterface aufzurufen (wie z.B. usbser.sys). Das ist aber kein Problem, wenn Du Dir das "Vorher" gemerkt hast.
Wie meinst du das mit vorher gemerkt hast?
Mox schrieb:
Und bei HIDs kommen ja auch noch andere Notifications.
Bist jetzt kommen bei mir keine anderen Notifications ausser eben "Message x: DBT_DEVNODES_CHANGED"
Mox schrieb:
Bei HIDs kommt definitiv DBT_DEVICEARRIVAL, wenn sie angestöpselt werden.
Glaub ich gerne aber bei mir leider nicht
Mox schrieb:
Hast Du denn jetzt wenigstens den Aufruf von RegisterDeviceNotification korrigiert, oder hast Du das noch immer falsch in Deinen Quellen stehen?
Habe ihn wie folgt geändert also das was du gepostet hast und dabei enstehen 2 Fehler und 7 Warnings. (kopier ich zum schluss rein)
Also mein Teil des codes in Kommentar und deinen Vorschlag reinkopiert.BOOL DoRegisterDeviceInterfaceToHwnd( IN GUID InterfaceClassGuid, IN HWND hWnd, OUT HDEVNOTIFY *hDeviceNotify ) // Routine Description: // Registers an HWND for notification of changes in the device interfaces // for the specified interface class GUID. // Parameters: // InterfaceClassGuid - The interface class GUID for the device // interfaces. // hWnd - Window handle to receive notifications. // hDeviceNotify - Receives the device notification handle. On failure, // this value is NULL. // Return Value: // If the function succeeds, the return value is TRUE. // If the function fails, the return value is FALSE. // Note: // RegisterDeviceNotification also allows a service handle be used, // so a similar wrapper function to this one supporting that scenario // could be made from this template. { DEV_BROADCAST_DEVICEINTERFACE itf = {}; itf.dbcc_size = sizeof(itf); itf.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; HidD_GetHidGuid(&itf.dbcc_classguid); RegisterDeviceNotification(hWnd, &itf, DEVICE_NOTIFY_WINDOW_HANDLE); /* DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid = InterfaceClassGuid; *hDeviceNotify = RegisterDeviceNotification( hWnd, // events recipient &NotificationFilter, // type of device DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle ); */ if (NULL == *hDeviceNotify) { ErrorHandler(TEXT("RegisterDeviceNotification")); return FALSE; } return TRUE; }
Falls du möchtest kopier ich hier mal den ganzen Quelltext rein.
Hier nun die Fehlermeldungen:
warning C4305: 'Initialisierung': Verkürzung von 'int' in 'unsigned char'
warning C4305: 'Initialisierung': Verkürzung von '__int64' in 'unsigned char'
error C2059: Syntaxfehler: '}'
warning C4013: 'HidD_GetHidGuid' undefiniert; Annahme: extern mit Rückgabetyp int
warning C4133: 'Funktion': Inkompatible Typen - von 'PTSTR' zu 'LPCWSTR'
warning C4133: 'Funktion': Inkompatible Typen - von 'PWSTR' zu 'LPCSTR'
warning C4133: 'Funktion': Inkompatible Typen - von 'PWSTR' zu 'LPCSTR'
========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========
-
pargus schrieb:
Wie meinst du das mit vorher gemerkt hast?
Du erstellst eine Liste mit allen Geräten. Wenn sich was geändert hat, erstellst Du eine neue Liste und vergleichst sie mit der alten Liste. Die Liste erstellst Du mit den Funktionen des Setup-APIs, aber das habe ich ja nun auch schon X mal erzählt.
pargus schrieb:
Hier nun die Fehlermeldungen:
warning C4305: 'Initialisierung': Verkürzung von 'int' in 'unsigned char'
warning C4305: 'Initialisierung': Verkürzung von '__int64' in 'unsigned char'
error C2059: Syntaxfehler: '}'
warning C4013: 'HidD_GetHidGuid' undefiniert; Annahme: extern mit Rückgabetyp int
warning C4133: 'Funktion': Inkompatible Typen - von 'PTSTR' zu 'LPCWSTR'
warning C4133: 'Funktion': Inkompatible Typen - von 'PWSTR' zu 'LPCSTR'
warning C4133: 'Funktion': Inkompatible Typen - von 'PWSTR' zu 'LPCSTR'
========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========Ich sehe hier leider nicht, auf welche Zeilen sich das bezieht. Allerdings spricht dieses hier eine deutliche Sprache: "warning C4013: 'HidD_GetHidGuid' undefiniert; Annahme: extern mit Rückgabetyp int"
Du willst mit HIDs arbeiten und inkludierst nicht einmal die nötigen Header? Weißt Du wenigstens ansatzweise was Du da machst?
Davon ab: Denkst Du auch nach bei Programmieren? Oder beschränkst Du Dich auf Copy&Paste? Oder was denkst Du bewirkt diese Abfrage, wenn Du zuvor die Rückgabe von RegisterDeviceNotification ignorierst?
pargus schrieb:
if (NULL == *hDeviceNotify)
-
Naja sagen wirs so mich interessiert das Thema programmieren schon und das is meine Bachelorarbeit und ich habe am Anfang nicht gemerkt, dass das so komplex ist darum bewege ich mich hier in dem Forum weil ich dringend Hilfe brauche.
Also Ich weiß nicht viel was ich da tue aber ich setze mir Puzzleteil für puzzleteil mit jeder Hilfe irgendwie zusammen.Nein ein bisschen versteh ich "c" schon aber halt bei weitem zu wenig, um diese Windows-Programmierung komplett zu verstehen. Darum frage ich euch da ich ja teilweise schon sachen hinbekomm (hab ja den MSDN code auch abgeändert das die drei Fehler nicht mehr auftauchen und ich immerhin Nachrichten bekomme) aber Hilfe brauch ich trotzdem dringend. Sorry falls du dir jetzt denkst wie dumm kann man sein, aber hilft mir auch nicht weiter :(.
Dachte das bei deinem Vorschlag das schon 1:1 übernehmbar ist. Sorry da hab ich nicht nachgedacht aber den Fehler hab ich schon bemerkt mit der If-Anweisung aber wenn es hat auch nen sinn warum ich kein Edit meines Posts gemacht habe.
Wäre also trotzdem nett wenn du mir helfen würdest.
Mox schrieb:
Allerdings spricht dieses hier eine deutliche Sprache: "warning C4013: 'HidD_GetHidGuid' undefiniert; Annahme: extern mit Rückgabetyp int"
Ich dachte Warnungen kann man vorerst getrost ignorieren und sind nicht so schlimm wie Fehler. Is das Falsch?
Mox schrieb:
Du willst mit HIDs arbeiten und inkludierst nicht einmal die nötigen Header?
Welche Header meinst du genau? vielleicht hab ich die ja schon inkludiert.
Dein Vorschlag war folgender:
DEV_BROADCAST_DEVICEINTERFACE itf = {}; //hier kommt der Fehler itf.dbcc_size = sizeof(itf); itf.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; HidD_GetHidGuid(&itf.dbcc_classguid); RegisterDeviceNotification(hWnd, &itf, DEVICE_NOTIFY_WINDOW_HANDLE);
Dabei kommt der Fehler:
Fehler 4 error C2059: Syntaxfehler: '}' 71 1 Hid_dll_mauer-Test
(Zeile 71, Spalte1)Allgemein hab ich zur Zeit folgende Aufgabe:
-Ich hab eine AT90USB1287 Platine hier.
- Ich soll das Projekt meines Professors erweitern. Dies gibt bis jetzt Angaben in einem eigenen Windwos fenster über die angeschlossenen HID-Devices aus bzw Deren Pfad wo diese abgespeichert sind.Device \\?\hid#vid_16c0&pid_1001&mi_01#7&37a49a66&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} can be opened for R/W VID: 16c0, PID 1001, Revision: 0, Interface-Nr: 1
- zu diesem Projekt soll ich eben eine Fehlerbehandlung einbauen (diese MSDN geschichte) dass ich Nachrichten bekomme, wenn ein Gerät bei laufendem Betrieb an oder abgesteckt wird.
- Und das dritte ist das ich das Projekt Babygrid http://www.codeguru.com/cpp/controls/controls/gridcontrol/article.php/c5277/Win32-Grid-Control-with-Low-Overhead-BABYGRID.htm mit diesem Projekt einbinden soll.
Babygrid erstellt eine Tabelle die man bearbeiten kann.
In diese Tabelle sollen später die VID,PID, REV, Interface-Nr., Gerätename, "gerät aktiv", "Gerät wurde entfernt", "Gerät blockiert" usw eingetragen werden.
Also informationen für den Programmierer.
Der Benutzer soll dann nur noch anhand des Indizes der Tabelle ein paar ausgewählte(!) Informationen aus der Tabelle abfragen können aber bekommt nicht die komplette Tabelle geliefert (die ist vorerst erstmal für den Programmierer (mich)).Darum würd ich jetzt erstmal die Fehlerbehandlung in sein Projekt übertragen.
[Allgemein hat er mir früher nur die DLL.c Datei geschickt mit der ich arbeite soll. Nun hat er ein komplettes Projekt darausgemacht und seine DLL.c in das Projekt eingebunden und teilweise in Headers ausgelagert. Dabei arbeite ich noch in der DLL.c die er mir damals geschickt hat (is diesselbe wie im Projekt nur halt ohne Header auslagerung und ohne Windows zeugs). Bei meinen test mit der früheren DLL.c hab ich die Fehlerbehandlung schon halbwegs hinbekommen, dass ich mich registrieren kann in Windows und meldungen folgender art bekomme:
"Message x: DBT_DEVNODES_CHANGED", aber mehr Infos bekomme ich noch nicht. Jetzt würde ich zumindest schonmal gerne die zwei Projekte vereinen damit die Nachrichten auch in dem Fenster erscheinen. Also Zuerst die HID-Geräte auflistung und dann das ich mich für die Device notifications registriert hab und auf Veränderungen warte. Quasi folgendesInitial windows created. Device \\?\hid#vid_045e&pid_00b0&mi_01&col02#7&3adb5499&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} can be opened for R/W VID: 45e, PID b0, Revision: 272, Interface-Nr: 1 Device \\?\hid#vid_058f&pid_6364&mi_01#7&918e966&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} can be opened for R/W VID: 58f, PID 6364, Revision: 256, Interface-Nr: 1 Device \\?\hid#vid_16c0&pid_1001&mi_00#7&25aeb47&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} can be opened for R/W VID: 16c0, PID 1001, Revision: 0, Interface-Nr: 0 Device \\?\hid#vid_16c0&pid_1001&mi_01#7&37a49a66&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} can be opened for R/W VID: 16c0, PID 1001, Revision: 0, Interface-Nr: 1 Found a total of 7 HID interfaces Error code 0 at index 7 Registered for USB device notification... //beim warten auf Veränderung Message x: DBT_DEVNODES_CHANGED //bei an oder Abstecken des Devices Message x: DBT_DEVNODES_CHANGED ....
]
Ich hoffe mir hilft trotzdem noch jemand und falls Fragen da sind versuche ich diese so ausführlich wie möglich zu beantworten.
Ich bin über Hilfe jeglicher Art Dankbar.
Bei Problembeseitigung warum ich nur "DBT_DEVNODES_CHANGED"'s bekomme oder seis worauf ich achten muss die zwei Projekte zu vereinen. Weil da ja doch einiges Schief gehen kann.Und @Mox ich hab dir doch auch nichts getan aber du attackierst mich direkt obwohl ich einfach nur fragen habe. (Kann ja sein, dass das alles dumm rüberkommt hilft mir aber auch nicht weiter
) und ich war dir über deine Hilfe bis jetzt sehr dankbar!
Gruß Markus
-
Hallo nochmal
@Mox habe dein Vorschlag eingebaut und Fehler beseitigt. Also bekomme schonmal verschiedene Ausgaben. Danke für den Tipp!Habe nun folgende bibliothek "#include "hidsdi.h"" eingebunden.
Nun bekomme ich auch keine Linker Fehler und ich bekomme interessante Ausgaben:
Message 1: DBT_DEVNODES_CHANGED //Beim abstecken eines bereits angeschlossenen HID-Device
Message 2: DBT_DEVICEREMOVECOMPLETE
Message 3: DBT_DEVICEREMOVECOMPLETEMessage 4: DBT_DEVNODES_CHANGED //Beim wieder anstecken
Message 5: DBT_DEVNODES_CHANGED
Message 6: DBT_DEVNODES_CHANGED
Message 7: DBT_DEVNODES_CHANGED
Message 8: DBT_DEVNODES_CHANGED
Message 9: DBT_DEVNODES_CHANGED
Message 10: DBT_DEVNODES_CHANGED
Message 11: DBT_DEVICEARRIVAL
Message 12: DBT_DEVNODES_CHANGED
Message 13: DBT_DEVICEARRIVAL
Message 14: DBT_DEVNODES_CHANGEDDas ist schonmal gut!
Aber mein Problem ist, will ich nun das geöffnete Fenster mit dem x rechts oben schließen, bekomm ich einen Windows(??)-fehler:UnregisterDeviceNotification failed with error 1784: Der angegebene Benutzerpuffer ist für den angeforderten Vorgang nicht zulässig.
Wo schau ich denn jetzt am besten nach dem Fehler für den Puffer?
-
pargus schrieb:
Das ist schonmal gut!
Na siehste.
pargus schrieb:
Aber mein Problem ist, will ich nun das geöffnete Fenster mit dem x rechts oben schließen, bekomm ich einen Windows(??)-fehler:
UnregisterDeviceNotification failed with error 1784: Der angegebene Benutzerpuffer ist für den angeforderten Vorgang nicht zulässig.
Wo schau ich denn jetzt am besten nach dem Fehler für den Puffer?
Wie ich vorhin schon sagte, Du musst Dir den Rückgabewert von RegisterDeviceNotification merken. Also:
h = RegisterDeviceNotification(..); . . . UnregisterDeviceNotification(h);
-
case WM_CLOSE: if (!UnregisterDeviceNotification(RegisterDeviceNotification)) { ErrorHandler(TEXT("UnregisterDeviceNotification")); } DestroyWindow(hWnd); break;
Hab ich ja gemacht kommt aber immer noch der Fehler beim Schließen des Fensters
(Aber siehste so dumm bin ich auch net
;))
Haste irgendwelche Ideen?
oder auch zu oben?
-
Habe weiter geforscht und denke dass ich zumindest weiß wo der Fehler entsteht:
void ErrorHandler( LPTSTR lpszFunction ) // Routine Description: // Support routine. // Retrieve the system error message for the last-error code // and pop a modal alert box with usable info. // Parameters: // lpszFunction - String containing the function name where // the error occurred plus any other relevant data you'd // like to appear in the output. // Return Value: // None // Note: // This routine is independent of the other windowing routines // in this application and can be used in a regular console // application without modification. { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); // Display the error message and exit the process. lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, g_pszAppName, MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); }
irgendwie gibt er diesen Fehler aus. Ich denke (vllt stimmts auch nciht) dass in einen der drei folgenden Funktionen etwas nicht stimmt:
-lpszFunction,
-dw = GetLastError() und
-lpMsgBufIch update ich sobald ich was neues hab. Bitte zu jedem Post wenn ihr Anmerkungen habt einfach reinschreiben
-
pargus schrieb:
if (!UnregisterDeviceNotification(RegisterDeviceNotification))
Hilfe! Du sollst hier keinen Funktionszeiger übergeben, sondern den Rückgabewert des vorherigen Aufrufs von RegisterDeviceNotification. Das, was Du da geschrieben hast, ist genau so ein Nonsens wie dieses hier:
free(malloc));
Ich hoffe, es brennt Dir jetzt ebenso in den Augen wie mir.
-
Mox schrieb:
free(malloc));
Ich hoffe, es brennt Dir jetzt ebenso in den Augen wie mir.
ok leuchtet mir jetzt auch ein.
Hab das jetzt mit nem HANDLE h; und h = RegisterDeviceNotification(..); und UnregisterDeviceNotification(h) wieder wegbekommen.
Wie gesagt kenn mich mit den Bedeutungen von den Windows Funktionen auch nicht gut aus. (Wusste also nicht das RegisterDeviceNotification ein Funktionszeiger ist.)
Darum bitte ich euch ja um Hilfe.
Hast du auch noch vorschläge wie ich eventuell genauere Details über folgende Nachrichten bekommen kann (oder ist das nciht möglich?):
Registered for USB device notification... Message 1: DBT_DEVNODES_CHANGED Message 2: DBT_DEVICEREMOVECOMPLETE Message 3: DBT_DEVICEREMOVECOMPLETE Message 4: DBT_DEVNODES_CHANGED Message 5: DBT_DEVNODES_CHANGED Message 6: DBT_DEVNODES_CHANGED Message 7: DBT_DEVNODES_CHANGED Message 8: DBT_DEVNODES_CHANGED Message 9: DBT_DEVNODES_CHANGED Message 10: DBT_DEVNODES_CHANGED Message 11: DBT_DEVICEARRIVAL Message 12: DBT_DEVNODES_CHANGED Message 13: DBT_DEVICEARRIVAL Message 14: DBT_DEVNODES_CHANGED
-
pargus schrieb:
Hast du auch noch vorschläge wie ich eventuell genauere Details über folgende Nachrichten bekommen kann (oder ist das nciht möglich?):
Die Details findest Du unter Device Management Events. Konzentriere Dich aber auf DBT_DEVICEARRIVAL und DBT_DEVICEREMOVECOMPLETE, das sind für Deine Anwendung die einzig interessanten Notifications. Den Rest darfst Du zunächst ruhigen Gewissens ignorieren.
-
pargus schrieb:
Wie gesagt kenn mich mit den Bedeutungen von den Windows Funktionen auch nicht gut aus. (Wusste also nicht das RegisterDeviceNotification ein Funktionszeiger ist.)
Was hast Du denn gedacht was das sonst ist? Ein Funktions-Aufruf kann es ja schließlich nicht sein, denn dafür hätte sich ja wohl mindestens noch eine Klammer öffnen müssen. Das passiert aber nicht, der Name der Funktion steht einfach nur da.
Und das hat mit Windows nichts zu tun, Das sind C-Grundlagen.
-
Hallo nochmal
ich bin noch bei dem selben Thema mit dem USB Port und den Notficiations aber schon bissal weiter.
da ich ja folgende Ausgabe kriege:
Nachrichten beim Abstecken
Message: DBT_DEVNODES_CHANGED Message: DBT_DEVICEREMOVECOMPLETE Message: DBT_DEVICEREMOVECOMPLETE Message: DBT_DEVNODES_CHANGED
Nachrichten beim ANstecken
Message: DBT_DEVNODES_CHANGED Message: DBT_DEVNODES_CHANGED Message: DBT_DEVNODES_CHANGED Message: DBT_DEVNODES_CHANGED Message: DBT_DEVNODES_CHANGED Message: DBT_DEVNODES_CHANGED Message: DBT_DEVICEARRIVAL Message: DBT_DEVNODES_CHANGED Message: DBT_DEVICEARRIVAL Message: DBT_DEVNODES_CHANGED
Dies kommt wenn ich meine Platine an oder abstecke, darum habe ich mit meinem Prof ausgemacht , wir kümmern uns nur um das erste "arrival" und das erste "removal" notification.
Mein Problem ist nur wie kann ich das in dem unten stehenden code anbauen, dass er mir die erste Nachricht von Removal ausspuckt und die nächste drei ignoriert, aber trotzdem bei einem erneuten abstecken eines anderen GErätes wieder eine removal nachricht ausgibt und wieder die restlichen ignoriert.
Code:
// // WinProcCallback // INT_PTR WINAPI WinProcCallback( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) // Routine Description: // Simple Windows callback for handling messages. // This is where all the work is done because the example // is using a window to process messages. This logic would be handled // differently if registering a service instead of a window. // Parameters: // hWnd - the window handle being registered for events. // message - the message being interpreted. // wParam and lParam - extended information provided to this // callback by the message sender. // For more information regarding these parameters and return value, // see the documentation for WNDCLASSEX and CreateWindowEx. { LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; static HWND hEditWnd; static ULONGLONG msgCount = 0; switch (message) { case WM_CREATE: // // This is the actual registration., In this example, registration // should happen only once, at application startup when the window // is created. // // If you were using a service, you would put this in your main code // path as part of your service initialization. // if ( ! DoRegisterDeviceInterfaceToHwnd( WceusbshGUID, hWnd, &hDeviceNotify) ) { // Terminate on failure. ErrorHandler(TEXT("DoRegisterDeviceInterfaceToHwnd")); ExitProcess(1); } // // Make the child window for output. // hEditWnd = CreateWindow(TEXT("EDIT"),// predefined class NULL, // no window title WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, // set size in WM_SIZE message hWnd, // parent window (HMENU)1, // edit control ID (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), NULL); // pointer not needed if ( hEditWnd == NULL ) { // Terminate on failure. ErrorHandler(TEXT("CreateWindow: Edit Control")); ExitProcess(1); } // Add text to the window. SendMessage(hEditWnd, WM_SETTEXT, 0, (LPARAM)TEXT("Registered for USB device notification...\n")); break; case WM_SETFOCUS: SetFocus(hEditWnd); break; case WM_SIZE: // Make the edit control the size of the window's client area. MoveWindow(hEditWnd, 0, 0, // starting x- and y-coordinates LOWORD(lParam), // width of client area HIWORD(lParam), // height of client area TRUE); // repaint window break; case WM_DEVICECHANGE: { // // This is the actual message from the interface via Windows messaging. // This code includes some additional decoding for this particular device type // and some common validation checks. // // Note that not all devices utilize these optional parameters in the same // way. Refer to the extended information for your particular device type // specified by your GUID. // PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; TCHAR strBuff[256]; // Output some messages to the window. switch (wParam) { case DBT_DEVICEARRIVAL: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); break; case DBT_DEVICEREMOVECOMPLETE: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); break; case DBT_DEVNODES_CHANGED: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); break; default: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), msgCount, wParam); break; } OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); } break; case WM_CLOSE: if ( ! UnregisterDeviceNotification(hDeviceNotify) ) { ErrorHandler(TEXT("UnregisterDeviceNotification")); } DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); break; } return lRet; }
Mittlerweile schauen meine Cases wie folgt aus
case WM_DEVICECHANGE: { // declaration of the structures for later usage // new structur for the output of every table item, to allocate memory for the structure and fill it with the function "hid_devchange" HID_INFO_INTERN *hid_info3 = (HID_INFO_INTERN*)malloc(sizeof(HID_INFO_INTERN)); int i = 0; //HID_INFO_INTERN *hid_info2; // for test below //HID_INFO_PUBLIC hid_public2; // // This is the actual message from the interface via Windows messaging. // This code includes some additional decoding for this particular device type // and some common validation checks. // // Note that not all devices utilize these optional parameters in the same // way. Refer to the extended information for your particular device type // specified by your GUID. // PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; TCHAR strBuff[256]; // Output some messages to the window. switch (wParam) { // wParam = 0x8004 // lParam = A pointer to a structure identifying the device inserted. // The structure consists of an event-independent header, followed by // event-dependent members that describe the device. To use this structure, // treat the structure as a DEV_BROADCAST_HDR structure, then check its dbch_devicetype // member to determine the device type. case DBT_DEVICEARRIVAL: { msgCount++; // Output message of Arrival-Notification logprintf(L"Message: DBT_DEVICEARRIVAL\n"); // deallocate the allocated memory free(hid_info3); } break; // wParam = 0x8004 // lParam = A pointer to a structure identifying the device removed. // The structure consists of an event-independent header, // followed by event-dependent members that describe the device. // To use this structure, treat the structure as a DEV_BROADCAST_HDR structure, // then check its dbch_devicetype member to determine the device type. case DBT_DEVICEREMOVECOMPLETE: msgCount++; logprintf(L"Message: DBT_DEVICEREMOVECOMPLETE\r\n"); // deallocate the allocated memory free(hid_info3); break; // wParam = 0x0007 // lParam = Set to zero. case DBT_DEVNODES_CHANGED: //F12 msgCount++; //hid_devchange(hid_info3, i); logprintf(L"Message: DBT_DEVNODES_CHANGED\n"); // deallocate the allocated memory free(hid_info3); break; default: msgCount++; loggprintf(L"WM_DEVICECHANGE message received, value %d unhandled.\n", wParam); break; } } break;
Falls einer ne Idee hat wie ich nur in einmal in den Case reingehe und danach für dieses eine Abstecken nicht mehr (also die drei anderen "Removals" ignoriere) wäre ich sehr dankbar weil ich grad aufm Schlauch stehe.
Danke Markus
-
pargus schrieb:
Falls einer ne Idee hat wie ich nur in einmal in den Case reingehe und danach für dieses eine Abstecken nicht mehr (also die drei anderen "Removals" ignoriere) wäre ich sehr dankbar weil ich grad aufm Schlauch stehe.
Welche drei anderen Removals? Du bekommst doch insgesamt nur zwei gesendet, ich zitiere:
pargus schrieb:
Message: DBT_DEVNODES_CHANGED
Message: DBT_DEVICEREMOVECOMPLETE
Message: DBT_DEVICEREMOVECOMPLETE
Message: DBT_DEVNODES_CHANGEDAnsonsten sollst Du gefälligst beide Removals bearbeiten. Oder woher weißt Du, welche der beiden Nachrichten für Dich interessant ist? Bislang schaust Du nicht nach, ob es überhaupt ein Removal für Dein Gerät ist. Du schaust Dir die Informationen gleich gar nicht an.
Du wartest doch auf Ereignisse, die Device-Interfaces betreffen. Schau nach, ob Du per LPARAM Strukturen des Typs DBT_DEVTYP_DEVICEINTERFACE übermittelt bekommst. Dann schaust Du, ob es Dein Gerät betrifft. Und wenn Du dieses Gerät nicht oder nicht mehr geöffnet hast, machst Du eben auch nichts.
Nur auf das erste Removal zu reagieren, geht definitiv in die Büx. Aber schön, dass Du zumindest mit Deinem Prof einig bist. Man, man...