[C++/WinAPI] Ermitteln, ob Button gedrückt ist

mh1001

Lt. Commander
Registriert
Nov. 2003
Beiträge
2.039
Hallo,

ich bin gerade dabei, ein kleines Windows-Programm zu schreiben.
Nun habe ich folgendes Problem:
Über einen Timer soll alle x-Sekunden eine Funktion aufgerufen werden, die überprüft, ob das entsprechende Button gedrückt ist.
Eigendtlich sollte es laut der MSDN-Dokumentation folgendermaßen funktionieren:
Code:
if(SendMessage(GetDlgItem(hwnd, BUTTON_ID), BM_GETSTATE, 0, 0) == BST_PUSHED)
{
  ...
}
Doch leider liefert mir die SendMessage-Funktion nicht diesen Rückgabewert.
Auch mit BST_CHECKED klappt es nicht.

Das Button wird hierbei folgendermaßen erstellt:
Code:
HWND Button = CreateWindow("BUTTON", "Test", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON , 20, 20, 100, 20, hwnd, (HMENU)BUTTON_ID, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
Doch wie komme ich jetzt nur an den Status des Buttons?

MfG mh1001
 
Warum nutzt du nicht einfach den "OnClick-Event" des Buttons?

Ist das ein Button, welcher beim draufklicken unten bzw. oben bleibt? Wenn nein, dann wird dein Code warscheinlich nicht funktionieren, da der Zustand des Anklickens zu kurz ist...
 
Der onClick-Event ist in diesem Fall leider nicht anwendbar, da wie gesagt, dieser Wert nur in bestimmten Zeitintervallen benötigt wird und es sich dabei im Kontext dann nicht nur um einen, sondern gleich um eine ganze Reihe von Buttons dreht.

Das Button behält seinen Status auch nicht bei, sondern geht nach den Anklicken wieder in seinen Ursprungszustand zurück.
Jedoch geht es bewusst darum, dass der Anwender das Button mit der Maus mehrere Sekunden gedrückt hält und dieser Status dann bei jedem Timer-Event überprüft werden soll.

Das klingt zwar jetzt alles etwas seltsam, aber ich hoffe man versteht was ich meine. ;)

MfG mh1001
 
Ich meine da gibbet auch noch die Events ButtonUp und ButtonDown oder so ähnlich!

Du könntest einen Timer beim Down starten und beim Up beenden, dann hast du denke ich das, was du beschrieben hast einen Button, der so lange er gedrück wird zyklisch etwas macht, wenn ich das nun richtig verstanden habe :)
 
Da habe ich mich dann doch etwas schlecht ausgedrückt. ;)

Auf jeden Fall aber besten Dank für deine Bemühungen! :)

Noch einmal ganz von vorne:

Gegeben ist ein Timer, der in gewissen Abständen - beispielsweise alle 2 Sekunden - eine Funktion aufruft.
Nun habe ich mehrere Buttons - um genau zu sein acht - deren Status bei jedem Funktionsaufruf geprüft werden soll.
Dabei werden dann anhand des entsprechenden Status der Buttons bestimmte Werte berechnet, die dann im weiterem Programmablauf weiterverarbeitet werden und erst wieder beim nächsten Aufruf - sprich dem nächsten Timer-Event in diesem Fall - wieder überschreiben werden sollen.
Nun ist es in diesem Fall vollkommen uninteressant, wie die Button zwischen den Timer-Events stehen, entscheidend ist nur, wie sie beim Eintreten des Events stehen.
Und dazu erhoffe ich mir irgendeine Funktion, um den Status zu diesem Zeitpunkt zu ermitteln. ;)

MfG mh1001
 
Zuletzt bearbeitet:
Hallo mh1001,

probier es doch mal mit GetWindowLong und GWL_STYLE.

Allerdings halte ich diesen aktiven Ansatz mit Sendmessage für fehleranfällig. Wenn Du Dein Programm beendest und der Timer läuft noch und es hängt gerade in einem Sendmessage dann gibt das einen Absturz.

Ein mehr passiver Ansatz ist da fehlertoleranter. Sprich z.B. den Button überladen, auf WM_LBUTTONDOWN oder WM_SETFOCUS reagieren und den Zustand merken und im Timer dann den selber gemerkten Zustand abfragen.

Ein Sendmessage im Timer, da habe ich keine guten Erfahrungen.

MfG

Arnd
 
Ein weiteres Problem ist, dass die SendMessage-Aufrufe in einer Schleife passieren müssten und du nicht den Status aller Buttons atomar hast. Sprich, was passiert, wenn während die Schleife läuft ein Button seinen Status ändert? Wird zwar nicht so oft auftreten, aber der Seiteneffekt wäre so da. Arnds Variante sieht gut aus - sprich das Buttonobjekt in deiner Anwendung weiß schon, ob es gedrückt ist oder nicht. So hast du dann auch die Möglichkeit, die Stati der Buttons atomar zu erhalten.
 
Besten Dank euch beiden! :daumen:
Ich habe nun die jeweiligen Werte per WM_LBUTTONDOWN in ein Array geschrieben und lasse dieses bei jedem Timer-Event überprüfen, was auch ausgezeichnet funktioniert.

Da wir schon einmal beim Thema sind hätte ich gleich noch eine weitere Frage:
Und zwar benötige ich für mein derzeitiges Projekt einen "Audio Spektrum Analyser", um Daten von Mikrofon-, LineIn-Eingang und/oder WAV-Ausgang grafisch darzustellen und auszuwerten.
Leider kann ich im Internet absolut nichts sinvolles zu dieser Materie finden.

Deswegen meine Frage:
Hat irgendjemand einen Tipp/Ansatz (oder vielleicht sogar ein Tutorial), wie sich soetwas realisieren lässt?

MfG mh1001
 
Zum Spectrum Analyser:

Dazu musst du eine Frequenzanalyse des Eingangssignals durchführen. Wahrscheinlich mit der Fast Fourier Transformation. An derStelle wurde es mir bis jetzt aber immer viel zu mathematisch :) Da können dir hoffentlich andere Boardies weiterhelfen.



Vielleicht noch ein wenig zur Erklärung:
Das Eingangssignal beschreibt ja einfach nur eine Schwingung (stell dir vor, sie wird einfach konituierlich als Graph gezeichnet). An diesem "Geräusch" sind jetzt aber viele einzelne Schwingungen beteiligt. Vielleicht als Beispiel, stell Dir vor, zwei Sinus-Schwingungen verschiedener Frequenz überlagern sich und ihre Werte addieren sich einfach. Mittels Fourier-Analyse wäre es möglich, die Frequenzen dieser beiden beteiligten Schwingungen wieder zu isolieren.

Wenn du dann erstmal die Frequenzen der Einzelschwingungen hast, kannst du feststellen, ob sie in einen bestimmten Bereich des Specturm Analysers fallen und dort einen entsprechenden Ausschlag einzeichnen.
 
Zuletzt bearbeitet:
Nochmals vielen Dank. :)
Damit habe ich schon einmal reichlich an Lesematerial.
Dass das ganze so komplexe Formen annimmt hatte ich zwar nicht erwartet, aber ich hoffe, dass auch dies irgendwie machbar sein wird. ;)

MfG mh1001
 
Zurück
Oben