GetMessage oder PeekMessage ?
-
moin meisters ...
Ein Dialog mit Fortschrittsanzeige und Abbrechen-Button.
Ich möchte keinen Thread verwenden.
In einer Schleife wird was gemacht, und in dieser möchte ich immer mal prüfen
ob der Button gedrückt wurde.Es darf kein Thread sein, weil ich den Code auch für PalmOS (keine Threads
möglich ) verwenden möchte, etwas geändert natürlich, aber im Ablauf und
Design soll beides identisch sein.Was wird in einem solchen Fall genommen, GetMessage oder PeekMessage ?
Besten Dank im Voraus
mfg
RB
-
GetMessage kehrt immer nur dann erst zurück, wenn tatsächlich eine Message eingetroffen ist (z.B. Buttonclick). Liegen keine Messages vor, so "schläft" das Programm.
PeekMessage dagegen, kehrt sofort zurück, auch wenn keine Message vorliegt. In diesem Fall kann das Programm andere Aktivitäten machen.Ein Beispiel (Windows, MFC):
MSG message; if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&message); ::DispatchMessage(&message); }
Auf API übertragen, sollte das ähnlich aussehen.
EDIT: Sorry, das sind APIs
-
Danke für die schnelle Antwort
mfg
RB
-
irgendwie habe ich da aber doch ein Problem
// soll Abbrechen realisieren bool IsCanceled(UINT idBtnCancel) { bool canceled = false; MSG msg; if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { TranslateMessage(&msg); if( msg.message == WM_COMMAND && LOWORD(msg.wParam) == idBtnCancel ) canceled = true; else DispatchMessage(&msg); } return canceled; } // DIALOG(!)-Proc ... case WM_COMMAND: if( LOWORD(wParam) == IDC_BTN_START ) { for(long l=0; l<100000 && !IsCanceled(IDC_BTN_STOP); l++) SendMessage(hProgress, PBM_SETPOS, l, 0); return TRUE; }
Also die for-Schleife soll abgebrochen werden können. Ich kann aber auf der
"Abbrechen"-Schaltfläche rumklicken wie ich willes passiert nichts.
Hat jemand sowas schon mal gemacht und kann mir noch nen Tip geben ?
Liegts daran, daß ein Dialog verwendet wurde ? (Ich muß aber einen Dialog verwenden !)mfg
RB
-
WM_COMMAND kommt gar nicht in der Message Loop an.
-
ok stimmt.
Aber WM_LBUTTONDOWN, nur das nützt mir nix, weil ich nicht weiß von welchem
Button( wenn überhaupt ) und über die Koordinaten ... keine Lösung.Ich versuche nun schon ne ganze weile, nur mit dem Debugger is auch nicht das Wahre.
WM_COMMAND wird wohl erst duch DispatchMessage generiert ?
Also werden denn nur die Nachrichten des Buttons an den Dialog dort empfangen.
Also für PalmOS würde es so aussehen,
static bool DialogCanceled( ControlPtr ctlP, unsigned short ctlId ) { EventType event; // Ereigniszeiger bool canceled = false; // Rückgabe // Liegen Ereignisse an ? if( EvtSysEventAvail( false ) || EvtEventAvail ( ) ) { // hole Ereignis EvtGetEvent( &event, 0 ); // Ereiginstyp und Id prüfen if( event.eType == ctlSelectEvent && event.data.ctlSelect.controlID == ctlId ) // Abbrechen wurde gedrückt canceled = true; if( !SysHandleEvent( &event ) ) // alle anderen Ereignisse verarbeiten lassen CtlHandleEvent( ctlP, &event ); } return canceled; }
nur halt für Windows ...
wenn nicht lasse ich mir was anderes einfallen, würde mir aber nicht recht sein
mfg
RB
-
johu
bool IsCanceled(UINT idBtnCancel, HWND hDlg) { bool canceled = false; MSG msg; if( PeekMessage(&msg, hDlg, 0, 0, PM_REMOVE) ) { TranslateMessage(&msg); if( msg.hwnd == GetDlgItem(hDlg, idBtnCancel) ) { if( msg.message == WM_LBUTTONUP ) { canceled = true; } DispatchMessage(&msg); } } return canceled; }
so wirds was
nur ebend sollten die anderen Controls deaktiviert werden, weil sie eh nicht reagieren ...
mfg
RB
-
EnableWindow - aber warum verarbeitest du nicht alle Nachrichten und setzt bei dieser Message in deiner normalen Fenster-Prozedur einfach eine globale Variable
-
moin meister ...
der entgültige Code sieht jetzt so erst mal aus.
bool IsCanceled(UINT idBtnCancel, HWND hDlg) { bool canceled = false; static bool bDown = false; RECT rc; MSG msg; if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { TranslateMessage(&msg); if( msg.hwnd == GetDlgItem(hDlg, idBtnCancel) ) // wurde Taste der Mous über der Schaltfläche gedrückt ? if( msg.message == WM_LBUTTONDOWN ) // ja: Merker setzen bDown = true; // wird die Taste der Mous über der Schaltfläche gelöst und wurde sie vorher gedrückt ? if( msg.message == WM_LBUTTONUP && bDown) { // ja: // Koordinaten konvertieren ScreenToClient(msg.hwnd, &msg.pt); // Bereich des Clients holen GetClientRect(msg.hwnd, &rc); // Mouse wurde über Client losgelassen if( PtInRect(&rc, msg.pt) ) // Aktion soll abgebrochen werden canceled = true; // Merker zurücksetzen, weil static bDown = false; } DispatchMessage(&msg); } return canceled; }
weiter oben hatte ich mal den Code gezeigt für PalmOS.
Ich möchte gern Programme für PalmOS und WinCE schreiben, wobei bei der Programmierung selbst eigentlich keine großen Unterschiede mehr anfallen sollen.Wenn ich diese Funktionalität nur für Win bräuchte würde ich mir diese Umständliche Lösung nicht aufhalsen.
Nur PalmOS verarbeitet Nachrichten nicht ganz so wie Windows. Es gibt auch keine Threads, hier gäbe es für Win eine einfache Lösung.
Unter PalmOS kann man daher eine "Endlosschleife" nicht abbrechen, oder man verwendet eine Funktion in der Schleife wie weiter oben in einem Beitrag
aufgezeigt ist.Jetz der Compatible Code für Win und Palm
for(int i=0; i<MAX && !IsDialogCanceled(...); i++)
machewas()wobei machewas in ANSI-C oder so gepinselt ist und eh "platformunabhänig" ist.
So werde ich die Geister von J2ME die ich rief wieder los !!!
Wenn wer schon mal mit J2ME (JAVA für Handys) gearbeitet hat, wird feststellen,
das Java mit sehr viel Glück platformunabhängig sein kann aber niemals Geräteunabhängig sein wirdZumindest häufen sich die Stellenangebote:
"Suche J2ME-Programmierer der Siemens-Spiele auf Nokia portiert"Seit wann wird platformunabhängige Software auf andere (Fremdfirmen)Platformen portiert ? Da stimmt doch was nicht !!!
Auch Tool wie AppForge ( VB für Palm/WinCE ) bewegen sich auf dem schmalen Grad
des kleinsten gemeinsamen Nenners und sind keine Alternative.Die obige Problematik mit der Schleife ist nicht zu lösen, da Appforge viel zu träge ist. Die Schleife soll aber abgebrochen werden wen Cancel gedrückt wird und nicht 3 Minuten Später ...
mfg
RB