WindowMessage wird unbeabsichtigt ausgelöst
-
Hm, ja. Das habe ich mal geändert. Das Problem besteht weiterhin.
Das Entfernen der break-Anweisung hat nichts gebracht.
-
Fried schrieb:
Das Entfernen der break-Anweisung hat nichts gebracht.
Du sollst auch nichts entfernen. In deinem Program fehlt etwas!
Vielleicht schaust du dir das Kapitel über switch nochmal an.
-
Hier meine ersten Auffälligkeiten:
Zwischen den case-Zweigen WM_COMMAND und WM_USER fehlt vielleicht ein break ?
Zwischen den case-Zweigen IDC_BTDISCNCT und IDC_BTSEND fehlt vielleicht ein break ?
Meine persönliche Empfehlung: Schließe jeden case-Zweig mit einem break-Befehl ab, auch dann wenn der Zweig vorzeitig durch return verlassen wird. Nur so kannst Du Dir einen unbewußten Automatismus beim Programmieren "trainieren" und solche sehr gemeine Stolperfallen vermeiden.
Die Nachricht (den "Rundruf")
SendMessage( HWND_BROADCAST, WM_USER, NULL, NULL );an ALLE Prozesse zu senden ist wohl ein wenig oversized
es soll ja NUR Dein eigener Thread in Deinem eigenen Prozess benachrichtigt werden, oder nicht?Martin
-
Okay, die Nachrichtenschleife des Dialoges sieht jetzt wie folgt aus:
switch(message) { case WM_INITDIALOG: { // Dialogicon setzen SendMessage(hDlg,WM_SETICON,TRUE,(LONG) LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1))); return TRUE; } case WM_CLOSE: { EndDialog(hDlg,0); return TRUE; } case WM_COMMAND: { switch(LOWORD(wParam)) { case IDEXIT: { ClosePort(); EndDialog(hDlg,0); return TRUE; } case IDC_BTCNCT: // "Verbinden"-Knopf { InitDCB(&sDCB); if(!OpenPort(2, &sDCB)) MessageBox(hDlg, "Verbindung konnte nicht hergestellt werden!", "Fehler!", MB_ICONERROR | MB_OK); else MessageBox(hDlg, "Verbindung auf COM2 hergestellt!", "Nachricht", MB_ICONWARNING | MB_OK); return TRUE; } case IDC_BTDISCNCT: // "Trennen"-Knopf { if(!ClosePort()) MessageBox(hDlg, "Verbindung konnte nicht getrennt werden!", "Fehler!", MB_ICONERROR | MB_OK); else MessageBox(hDlg, "Verbindung getrennt!", "Nachricht", MB_ICONWARNING | MB_OK); return TRUE; } case IDC_BTSEND: // "Senden"-Knopf { hEdit = GetDlgItem(hDlg, IDC_EDIT1); cTxtLen = GetWindowTextLength(hEdit); lpszMem = (LPSTR) VirtualAlloc((LPVOID) NULL, (DWORD) (cTxtLen + 1), MEM_COMMIT, PAGE_READWRITE); GetWindowText(hEdit, lpszMem, cTxtLen + 1); if (lpszMem != NULL) { SendDlgItemMessage(hDlg, IDC_LIST1, LB_ADDSTRING, 0, (DWORD) ((LPSTR) lpszMem)); SetWindowText(hEdit, (LPSTR) NULL); WritePort(lpszMem); }; return TRUE; } default: break; } } case WM_USER: { SendDlgItemMessage(hDlg, IDC_LIST2, LB_ADDSTRING, 0, (DWORD) &Recv_Buffer[0]); return TRUE; } default: break; }Die einzelnen Case-Statements werden mit return TRUE abgeschlossen, da die Nachricht ja bearbeitet wurde (Zumindest habe ich das so verstanden.).
Das ein Rundruf problematisch ist, habe ich mir auch schon gedacht. Das Einzige, was da helfen könnte, wäre ein Zugriff auf das Handle des Dialoges. CreateThread mault aber rum, wenn ich der Funktion ReadPort dieses Handle als Parameter übergebe. Bleibt nur globaler Zugriff.
Gibt's eine bessere Möglichkeit?
-
Entweder via RegisterWindowMessage () sich eine "eigene" Botschaft besorgen oder dafür sorgen, dass CreateThread () nicht mehr "herummault".
Schliesslich kannst Du nicht ahnen, was ein WM_USER bei anderen Anwendungen alles auslöst.
-
Ich habe jetzt die switch-case-Geschichte in Ordnung gebracht.
Daran hat's allerdings nicht gelegen.Es wird jedes Mal, wenn ich einen Button oder ein Feld klicke die Nachricht WM_USER geschickt.
Wie kann ich das abstellen?
-
Fried schrieb:
Ich habe jetzt die switch-case-Geschichte in Ordnung gebracht.
Daran hat's allerdings nicht gelegen.Au weia

Fried schrieb:
Wie kann ich das abstellen?
Indem du am Ende deines case-Blocks für WM_COMMAND ein break einfügst!
-
Die Lösung des Problems liegt im korrekten Ansprechen des Handles für die Listbox. Wenn die global verfügbar ist, kann ich das Ganze ohne WindowMessage durchspielen. Die restlichen Komponenten des Dialogs, die offensichtlich störend wirken, werden somit umgangen.
Danke alle, die mitgeholfen haben.
-
Fried schrieb:
Ja, das habe ich schon gemacht. Der Fall WM_USER müßte jetzt eigentlich separat behandelt werden, wird er aber nicht.
Du hast es nicht verstanden!Lass bitte den Broadcast bleiben. Warum sollen andere Prozesse Deine WM_USER Nachricht bekommen? Was ist wenn die unter WM_USER was ganz anderes verstehen...
-
Aye, aye! Broadcast abgestellt und stattdessen LB_ADDSTRING direkt an das Handle der Box geschickt.
SendMessage erwartet ja als ersten Parameter ein HWND. Das gebe ich ihm jetzt als HWND der Listbox mit. Damit gibt's keine WM_USER an die anderen Boxes.
Vorrangig ist, dass es läuft. Es ist auch kein Freizeit-Projekt, ich steh' unter Termindruck.

-
Fried schrieb:
Aye, aye! Broadcast abgestellt und stattdessen LB_ADDSTRING direkt an das Handle der Box geschickt.
SendMessage erwartet ja als ersten Parameter ein HWND. Das gebe ich ihm jetzt als HWND der Listbox mit. Damit gibt's keine WM_USER an die anderen Boxes.
Vorrangig ist, dass es läuft. Es ist auch kein Freizeit-Projekt, ich steh' unter Termindruck.

Und übergibst Du auch den lParam richtig? Ansonsten WM_USER senden und dabei Das Handle Deines Hauptfensters verwenden, dass eben auch die WM_USER Nachricht behandelt.
-
Die GUI funktioniert jetzt so, wie sie soll.
Der Aufruf für die Listbox sieht nun so aus:
SendMessage( hWnd, LB_ADDSTRING, 0, (LPARAM)(LPSTR)Recv_Buffer );