Designfrage C++ und WinAPI
-
Danke euch für die Infos, da ja viele Wege nach Rom führen freue ich mich natürlich über weitere Denkanstöße.
@Fallen Angle:
Ich habe mir mal deinen Quellcode angeschaut und blicke noch nicht ganz bei der Nachrichtenverarbeitung durch. Vielleicht könntest du, wenn es deine Zeit erlaubt, die einzelnen Methoden dazu mal kurz erläutern. Es ist zwar alles sehr schöner Code aber ohne Kommentare komme ich nicht ganz mit klar.Ich bin halt doch noch Anfänger und auch nicht Jemand der alles gleich auf Anhieb versteht. Ich muss halt viel lesen und probieren bis es klick macht.
G hibbes
-
Wir haben einen globalen Container (du kannst ihn natürlich auch statisch mit in die Klasse einpacken), der alle Instanzen der Fensterklasse hält.
Eine Fensterinstanz lässt sich eindeutig per Handle identifizieren.
Du hast 2 Funktionen zur Nachrichtenverwaltung. Einmal die statische und einmal die nicht-statsiche Nachrichtenprozedur:
static
LRESULT WINAPI MessageProcedure( HWND, UINT, LPARAM, WPARAM ),
LRESULT WINAPI MessageProcedure( UINT, LPARAM, WPARAM ).Die erstere dient für alle Fenster und geht den Container durch mit den erstellten Instanzen der Fensterklasse und vergleicht den 1. Parameter (Handle) mit den der einzelnen Fensterinstanzen. Stimmt eine überein können wir dessen Nachrichtenprozedur aufrufen (Nr. 2, oben) und sind in der Fensterinternen Nachrichtenprozedur.
Das war's an sich.
-
Danke, du hast mir sehr geholfen mit der Erklärung.
G hibbes
-
Hi ich bin noch ein recht frischer C++ programmierer und habe das Problem , dass ich wenn ich ein Programm geschrieben habe es immer kompilieren muss um es zu strarten .Kann mir jemand bitte sagen ob und wie es geht ,dass ich es als Programm speichere . Bei mir kommt immer MS-Dos hat ungültigen befehlfestgestellr.
Schon mal vielen dank.
-
Hallo,
bei mir gibt es ein Modul, das für das Dispatchen der Windowsmessages zu den jeweiigen Objekten verantwortlich ist.
Dieses Modul enthält einen statischen Container, der eine Liste aller Objekte speichert. Der Construktor der Basisklasse registriert alle erzeugten Objekte in diesem Container. Der Destruktor entfernt sie wieder.
Der Windowcallback klappert einfach die Liste ab und schickt dann die Nachricht an das gefundene Objekt:
extern "C" LONG FAR PASCAL _export WindowProc( HWND handle, UINT message, WPARAM wParam, LPARAM lParam ) { CALL_WIN *curWindow; LIST_CURSOR buff; LONG returnVal = true; curWindow = (CALL_WIN*)openWin.getFirst( &buff ); while( curWindow ) { if( curWindow->handle() == handle || curWindow->setHandle( handle )) { curWindow->callBackCount++; returnVal = curWindow->callBack( message, wParam, lParam ); curWindow->callBackCount--; if( curWindow->mayBeDeleted() && !curWindow->callBackCount && curWindow->getParent() ) ((BASIC_WIN*)curWindow->getParent())->handleChildClose( curWindow ); /*v*/ break; } curWindow = (CALL_WIN *)openWin.getNext( &buff ); } return returnVal; }Die Funktion setHandle liefert false zurück, wenn das Objekt schon sein Handle kennt. Andernfalls speichert es den neuen Handle und liefert true zurück. Das ist erforderlich, weil die ersten Message schon verschickt werden, bevor CreateWindow zurückkehrt ich als eine Chance habe, das Handle selbst zu speichern.
mfg Martin
-
Und wenn du mehrere Fenster gleichzeitig erstellst nimmst du einfach das Handle eines anderen Fensters an? Etwas unperformant. Die Nachricht wartet doch darauf das du PeekMessage/GetMessage aufrufst und bis dahin hast du das Handle doch?
Falls du die Nachrichtenverwaltung per Thread erledigst würde ich die Nachricht zwischenspeichern bzw. in einen temporären Container setzen, dann kannst du, falls das zutreffende Fenster noch nicht für eine Abfrage der Nachricht bereit ist, später noch die Nachricht bearbeiten.
-
Fallen Angel schrieb:
Und wenn du mehrere Fenster gleichzeitig erstellst nimmst du einfach das Handle eines anderen Fensters an? Etwas unperformant. Die Nachricht wartet doch darauf das du PeekMessage/GetMessage aufrufst und bis dahin hast du das Handle doch?
Falls du die Nachrichtenverwaltung per Thread erledigst würde ich die Nachricht zwischenspeichern bzw. in einen temporären Container setzen, dann kannst du, falls das zutreffende Fenster noch nicht für eine Abfrage der Nachricht bereit ist, später noch die Nachricht bearbeiten.Du hast recht. Threadsafe ist diese Lösung nicht. Sie stammt allerdings noch aus 16 Bit Zeiten, da gab es solche Probleme nicht,
Dein Lösungsansatz funktioniert nicht, weil CreateWindow auch Nachrichten verschickt, ohne die MainMessageLoop zu bemühen. Diese Nachrichten müssen auch sofort bearbeitet werden, weil von deren Ergebnis der Erfolg von CreateWindow abhängt. WM_INITDIALOG ist so ein Kandidat. Ich habe daher bis zu diesem Zeitpunkt keine andere Chance an das Handle zu kommen,
Wenn so eine Nachricht nicht verschickt wird und CreateWindow schon zurückgekehrt ist, dann hat mein Objekt eh schon das Handle. Dann stört auch ein weiterer Aufruf von CreateWindow nicht. Ich habe also immer nur maximal ein Objekt, das noch nicht sein Handle kennt.
mfg Martin
-
Tut mir leid aber ich bin kein stück schlauer als vorher...
ich dachte man kann das einfach als einen bestimmten Dateityp speichern.
Mitdiesen coden die ihr aufgelistet habt, muss man die einfach als erstes in die main() Funktion schreiben oder wie soll das funktionieren?
Wie gesagt ich bin gerade bei arrays und vektoren hab also von klassen und containern keinen blassen schimmer
(ich bringe mir C++ noch selbst bei)
-
DillBahadur schrieb:
Hi ich bin noch ein recht frischer C++ programmierer und habe das Problem , dass ich wenn ich ein Programm geschrieben habe es immer kompilieren muss um es zu strarten .Kann mir jemand bitte sagen ob und wie es geht ,dass ich es als Programm speichere . Bei mir kommt immer MS-Dos hat ungültigen befehlfestgestellr.
Schon mal vielen dank.Du solltest für dein Problem ein neues Posting aufmachen, entweder im Compiler und IDE oder im C++ Forum. Mit WinAPI hat deine Frage so erstmal nix zu tun. Vielleicht solltest du dein Buch auch nochmal ganz von vorne lesen, ich denke dir fehlt ein wenig das Grundverständnis.
Ein C++ Programm ist erst einmal nur eine Textdatei mir der Endung .cpp, der Compiler macht daraus ein fertig ausführbares Programm, wenn keine Fehler darin zu finden sind.
Es gibt also keinen anderen Weg aus einer C++ Textdatei ein ausführbares Programm zu machen, außer du lässt es kompilieren.
Eine C++ Entwicklungsumgebung speichert, kompiliert und startet das Programm automatisch mit einem Klick, was vielleicht für einen Anfänger den Anschein haben mag dass nicht extra kompiliert werden muss, das muss es aber immer.
G hibbes
-
Danke für die Hilfe.
In meinen Büchern steht leider nichts darüber...
Der Compiler macht aus der cpp-Datei eine exe-Datei und so dachte ich,dass ich die compilierte Ausgabe als exe-Datei speichern kann.
Aber MS-Dos findet irgendeinen fehler,auch wenn sich das programm compilieren muss.Natürlich fehlt mirdas Grundwissen.
Ich hab zwei Bücher und in denen Lese ich und bring mir das schreiben von programmen selber bei einen lehrer der mir sagt wie manches geht hab ich leider noch nich.
Aber trotzdem vielen dank an euch.
