Forum: PC-Programmierung BEGIN_MESSAGE_MAP in Visual C++


von brechbunkt (Gast)


Lesenswert?

Hallo,

ich verwende das Code-Beispiel „ffconst_2003“ von Microsoft. Dort wird 
ein Fenster erzeugt und durch Klicken und Ziehen der Mouse können dann 
Funktionen für DirectX angesteuert werden. Den Hauptteil des Codes kann 
man auch hier sehen:
http://www.getcodesamples.com/src/AF47D42D/8B839A3B

Die Nachrichten der Mouse werden dort durch WM_MOUSEMOVE, 
WM_LBUTTONDOWN und WM_LBUTTONUP im callback abgehandelt.

Nun würde ich gerne weitere Nachrichten hinzufügen. Laut Internet 
sollten diese innerhalb von BEGIN_MESSAGE_MAP(theClass,baseClass) und 
END_MESSAGE_MAP() definiert werden. Allerdings ist der erste Parameter 
in BEGIN_MESSAGE_MAP eine Klasse und wie man im Beispiel sehen kann, 
gibt es in diesem keine Klassen. Außerdem frage ich mich, wie/wo die 
bisherigen (bereits verwendeten) Nachrichten definiert wurden. Eine 
Suche nach BEGIN_MESSAGE_MAP über das gesamte Projekt gab keine 
Treffer.

Kann mir jemand sagen wie ich hier vorgehen sollte? Gibt es wohl noch 
andere Wege neue Nachrichtentypen zu verwenden, ohne BEGIN_MESSAGE_MAP 
zu nutzen?

von Klaus W. (mfgkw)


Lesenswert?

Ich habe vor vielen Jahren auch versucht,  MFC halbwegs zu verstehen und 
bin aber zu blöd dafür.  Seither nehme ich Qt.

Abgesehen davon gibt es für Windowsprogrammierung sicher besser passende 
Foren als dieses.

von oggy (Gast)


Lesenswert?

du vermischt hier WinAPI und MFC

von Hans-Georg L. (h-g-l)


Lesenswert?

Wenn du die WinApi direkt, wie bei deinem Beispielcode verwendest musst 
du für jede weitere Nachricht in deiner Nachrichtenschleife 
(MainDlgProc) ein neues case einfügen.

BEGIN_MESSAGE_MAP  ist ein Preprocessor Macro aus der sogenannten 
"MessageCrackerApi" der MFC.

Du kannst dir sehr vereinfacht vorstellen:

#define BEGIN_MESSAGE_MAP switch(msg) {

und

#define END_MESSAGE_MAP  };

von brechbunkt (Gast)


Lesenswert?

Hans-Georg Lehnard schrieb:
> ...musst du für jede weitere Nachricht in deiner Nachrichtenschleife 
(MainDlgProc) ein neues case einfügen...

So habe ich es bereits schon versucht. Ich habe testweise mal versucht 
die Taste "a" abzufangen, aber der case-fall wird nie "eingesprungen". 
Auch ein Breakpoint zeigt, dass er diese Nachricht ignoriert.

1
switch( msg )
2
    {
3
        case WM_KEYDOWN:
4
            if (wParam == 0x41)
5
            {
6
                MessageBox( hDlg, _T("a wurde gedrückt"), _T("Taste"), MB_OK );
7
            }
8
            else
9
            {
10
                MessageBox( hDlg, _T("Fail"), _T("Taste"), MB_OK );
11
            }
12
            break;
13
14
    // .......

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und wo kommt "msg" her?

von brechbunkt (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Und wo kommt "msg" her?
1
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
2
{
3
    InitCommonControls();
4
    // Display the main dialog box.
5
    DialogBox( hInst, MAKEINTRESOURCE( IDD_FORCE_FEEDBACK ), NULL, MainDlgProc );
6
    return 0;
7
}
1
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
2
{
3
    switch( msg )
4
    {
5
    // ....

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Aha.

a) Warum tust Du Dir das an?

Das ist Masochismus. Purer, reiner Masochismus.

b) Hast Du mal einen Breakpoint auf das switch-Statement selbst gesetzt, 
so daß Du Dir ansehen kannst, was da als "msg" durchkommt?

c) Literaturempfehlung:
Charles Petzoldt, "Programming Windows".
Das gibt/gab es in verschiedenen Iterationen, angefangen hat das mit der 
16-Bit-Windows-API (und die willst Du Dir wirklich nicht antun), achte 
also darauf, eine 32-Bit-Version zu bekommen, aber eine, in der es um C 
bzw. C++, aber NICHT um das .Net-Geraffel geht.
Das gibt/gab es auch auf Deutsch; ISBN 3860631888 wäre beispielsweise 
ein Kandidat.

von brechbunkt (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> a) Warum tust Du Dir das an?

Meinen bisherigen Code hatte ich in Qt geschrieben. Wäre mir natürlich 
auch hier lieber. Qt unterstützt zwar auch Joystik-Eingaben und DirectX, 
jedoch keine mit Force-Feedback-Unterstützung. Das ganze ist so ziemlich 
fast fertig. Muss nur noch diese blöden Nachrichten ans laufen bringen.


Rufus Τ. Firefly schrieb:
> b) Hast Du mal einen Breakpoint auf das switch-Statement selbst gesetzt,
> so daß Du Dir ansehen kannst, was da als "msg" durchkommt?

Auf jedem Fall werden die hier behandelt:
WM_KEYDOWN, WM_INITDIALOG, WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, 
WM_PAINT, WM_ACTIVATE, WM_COMMAND und WM_DESTROY


Rufus Τ. Firefly schrieb:
> c) Literaturempfehlung:

Ich werde mich mal umschauen. Habe nur das blöde Gefühl, dass dort das 
gleiche Steht wie das, das schon im Netz gefunden habe. An sich sollte 
es wohl tatsächlich genügen (in diesem Fall) nur einen neuen Case-Fall 
ein zu fügen.

von fbi (Gast)


Lesenswert?

Das geht nicht, da es sich bei Dir um eine "DialogProc" Funktion 
handelt. Die bekommt einfach die WM_KEYDOWN nicht (die geht an das 
Control, das den Keyboardfocus hat). Du könntest ein Subclassing aud die 
DialogBox Klasse machen und eine eigene WndProc benutzen, statt dem 
DialogBox gleich ein normales Window benutzen oder in der WM_INITDIALOG 
mittels RegisterHotKey Deine Taste registrieren und dann WM_HOTKEY 
behandeln.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.