[VC++ .NET] WinProc / WndProc Messages abfangen

the incredible Leitman

Erfahrenes Mitglied
Hallo Leute... ich habe vor, mich mit dem Abfangen von Windows Messages zu beschäftigen (benötige das um bestimmte Tasten zu sperren und eine TabPage immer offen zu halten)

Habe bereits stundenlang gegoogelt und überall im Web alles mögliche darüber gelesen...
Nun bin ich auf folgendes Problem gestoßen:

Es gibst sowohl die Funktion WinProc, als aud WndProc?
Was ist da der Unterschied? Nach meiner Recherche bin ich ziemlich verwirrt, habe für beide dieser Methoden ungefähr dieselbe Implementierung gefunden... in der MSDN ist jedoch nur zu WndProc etwas zu finden
(http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.wndproc.aspx)
:confused:

Hoffe, dass mich da nun jemand WIRKLICH aufklären kann

Was ich bist jetzt probiert habe:

In den Datein
CommCtrl.h
und WinUser.h
(aus dem SV SDK) findet man die Deklarationen der einzelnen Message Keys

Ich habe eine Standart WindowsForm erstellt (in MS VS2005) und folgende Funktion implementiert:
C++:
protected:
virtual void WndProc ( Message %m ) override
{
	const System::Int32 WM_KEYDOWN = 0x0100;

	switch ( m.Msg )
	{
		case WM_KEYDOWN: 
			MessageBox::Show(" left Mouse pressed! ");
			break;
		default:
			break;
	}
}
Kann ich problemlos kompilieren, jedoch beim ausführen erscheint immer die Fehlermeldung: "Win32Exception: Error creating window handle"

Was mache ich falsch? Muss ich noch extra etwas includen / einbinden?

Wenn ich "windows.h" include, erhalte ich beim kompilieren bereits 2 Fehler in der Zeile in der WM_KEYDOWN deklariert wird:
"error C2143: syntax error : missing ';' before 'constant' "
"error C2106: '=' : left operand must be l-value"

In dem Fall, dass ich die Deklaration weglasse, kann ich zwar vollständig kompiliere, jedoch erscheint beim Ausführen wieder der Fehler "Error creating window handle"

Oder muss ich überhaupt etwas anderes verwenden?

etwa in der Art:
C++:
LRESULT CALLBACK Window::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
        case WM_SYSCOMMAND:
            switch (wParam)    {
                case SC_SCREENSAVE:
                case SC_MONITORPOWER:
                return 0;
            }
            break;
        case WM_KEYDOWN:
            // Fenster schließen
            if (wParam==VK_ESCAPE) _exit = true; // Ausnahme !
            break;       
        case WM_CLOSE:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

Hoffe, jemand von euch kann mich erleuchten,
Vielen Dank für eure Zeit

mfG
der Leitman
 
ahhhh... *lichtaufgeh*

Ich hab lediglich vergessen, die Message weiter zu leiten :suspekt:

C++:
System::Windows::Forms::Form::WndProc( m );
Jetzt gehts zumindest einmal :D

naja... ein bisschen laggy aber es geht *freu*
 
OK, weiter gehts...

Hab nun (einfach zum, Spaß *lol*) einfach alle Messages ausgegeben...

Es läuft ähnlich dieser Reihenfolge ab wenn ich auf eine TabPage drücke:
WM_PARENTNOTIFY
WM_MOUSEACTIVATE
WM_NOTIFY :confused: aber 3 Mal

Nichts von TabPage change oder dergleichen :(

Habe nun aber nun doch die Messages für TabControls gefunden... beginnen alle mit TCS_ oder TCN_ oder dergleichen
Jetzt gibts da TCN_SELCHANGE, TCN_SELCHANGING und TCN_FOCUSCHANGE, die (denke ich mal) für das wechseln der TabPages zuständig sind...
leider steht dort als HEX Code TCN_FIRST - 3 :confused: was bedeutet das?

Nun wollte ich einfach die Datei CommCtrl.h einbinden, dann habe ich ja die ganzen definitionen bereits zur Verfügung... aber dann kommen beim kompilieren Fehler aus dieser Datei...
z.B: CALLBACK undeclared Identifier
aber ich traue mich nicht daran etwas zu ändern, weil es ja doch eine Standart Komponente ist oder?

Kann mir bitte jemand helfen?
 
Zuletzt bearbeitet:
-3 bedeutet, dass Du von dem Wert TCN_FIRST 3 abziehen musst.
Welches Headerfile hast den am Wickel?
// Edit: Sehs grad. *g*
Hab keine Ahnung warum das meckert. Definier die Codes die Du brauchst, halt in deinem Control statisch.
 
Zuletzt bearbeitet:
-3 bedeutet, dass Du von dem Wert TCN_FIRST 3 abziehen musst.
Das dachte ich mir schon, aber wie erfahre ich den Wert von TCN_FIRST?
Im CommCtrl.h Header File steht neben TCN_FIRST im Bereich "WM_NOTIFY codes (NMHDR.code values)" (0U - 550U) und ein Hinweis see prsht.h
Was bedeutet das? :confused:
Welches Headerfile hast den am Wickel?
Naja, eigentlich musste ich ja kein file includen, dann funktioniert die Methode,
aber dann ich muss die einzelnen Messagekeys zuerst selber definieren
C++:
//also z.B. für die linke Maustaste:
const System::Int32 WM_LBUTTONDOWN = 0x0201;
Da die aber bereits alle in den Datein CommCtrl.h" und "WinUser.h" vorhanden sind, dachte ich mir, ich könnte die einfach verwenden indem ich die beiden Headerfiles einbinde...
Aber dann erhalte ich Fehlermeldungen, das z.B HRESULT nicht definiert ist...

//EDIT:
Sehs grad. *g*
Hab keine Ahnung warum das meckert. Definier die Codes die Du brauchst, halt in deinem Control statisch
Ja, das hatte ich eigentlich vor, aber ich wußte nicht, wie ich TCN_FIRST - 3 definieren soll -.-
Aber das hat sich erledigt, habs doch zusammengebracht, die ganzen Keys zu includen ^^

//EDIT:
Ok, ich habs... tztztz... also so eine Deppenaktion -.-

Habe nun
C++:
#include <windows.h>
#include <CommCtrl.h>
#include <WinUser.h>
inkludiert, jetzt kommt kein Fehler mehr *freu*

Gut, momentan prüfe ich die Messages folgendermaßen:
C++:
protected:
	virtual void WndProc ( Message %m ) override
	{
		System::Diagnostics::Debug::WriteLine("wParam: " + m.WParam);
		System::Diagnostics::Debug::WriteLine("lParam: " + m.LParam);
		System::Diagnostics::Debug::WriteLine("Msg: " + m.Msg);
		System::Diagnostics::Debug::WriteLine("Result: " + m.Result);
		System::Diagnostics::Debug::WriteLine("HWnd: " + m.HWnd);

		switch ( Convert::ToInt32(m.Msg) )
		{
			case WM_LBUTTONDOWN: 
				System::Diagnostics::Debug::WriteLine("*##EVENT##* Left MousePressed! ");
				break;
			case TCN_SELCHANGE: 
				System::Diagnostics::Debug::WriteLine("*##EVENT##* Selchange! ");
				break;
			case TCN_SELCHANGING: 
				System::Diagnostics::Debug::WriteLine("*##EVENT##* Selchanging! ");
				break;
			case TCN_FOCUSCHANGE: 
				System::Diagnostics::Debug::WriteLine("*##EVENT##* Focuschange! ");
				break;
		}
		System::Windows::Forms::Form::WndProc( m );
	}
Wenn ich mit der Maus innerhalb der Form klicke, erscheint die Meldung "##EVENT##* Left MousePressed! " wie erwartet,
aber wenn ich andere TabPages auswähle, kommt nichts -.-
In diesem Fall erhalte ich nicht einmal die Meldung, dass die linke Maustaste gedrückt wurde :confused:

Was mache ich falsch? Muss ich andere MessageKeys verwenden? Wie kann ich herausfinden, was wirklich für die Änderung der TabPage zuständig ist?
 
Zuletzt bearbeitet:
Was mache ich falsch? Muss ich andere MessageKeys verwenden? Wie kann ich herausfinden, was wirklich für die Änderung der TabPage zuständig ist?
Es gibt auf TheCodeProject TabControls die ihre Reiter komplett selber zeichnen
und solche die das Tabverhalten erweitern. Such Dir eines raus,
womit Du am einfachsten an die Rectangles der einzenen TabReiter herran kommst.
Kannst Dir auch eines raussuchen, was die TabReiter sogar selber zeichnet und verwaltet.
(Rectangles der Reiter werden irgend wo gespeichert).
Wenn dann der entsprechende Reiter angeklickt wurde, ignorierst in der WndProc alle weiteren Messages
die einen Tabwechsel auslösen. Das währe ein möglicher Weg.
 
Zuletzt bearbeitet:
Was Reiter sind? :D
Das sind die kleinen Nippel, die auf dem TabControl drauf klemmen.
Mit ner Beschriftung drauf und so. Das kann man überigens auch drauf klicken ond so... :D
haha... :p
Die heißen "Items" falls dus nicht gewußt hast ^^ *klugshice*
in C++ zumindest

Grund für diese Annahme: Ich kann die Größe dieser "Nippel" *lol* mittels ItemSize setzten
^^
 
Zuletzt bearbeitet:
OK, Zwischenstand....

Also, ich habe jetzt schon ziemlich viel Zeit auf Codeproject verbracht, alles mögliche über TabControl und Pages Erweiterungen und Ergänzungen gefunden, da war aber nie das dabei, was ich gebraucht hab... vl suche ich falsch? :confused:

Habe nun beinahe ALLE Möglichen Messages abgefangen und ausgegeben die irgendwas mit TabControls zu tun haben, aber scheinbar wird da nichts aufgerufen -.-

Nun habe ich mir das folgendermaßen überlegt... wenn ich halt über diese WindowsProcs nicht weiterkomme, versuche ichs einfach über events nochmal... habe mir das ca. so gedacht:
C++:
// Pseudocode:
Event Pagechanging // also bevor die TabPage gewechselt wird
{
    for all TabControl
    {
        // Überprüfe ob meine deklarierte TabPage 
        // nach dem Wechsel mind. 1 mal selected ist
        if (wenn ja) ==> PageChange
        else  ==> tu nichts
    }
}
So wäre eigentlich meine logische Überlegung, aber ich weiß nicht genau, wie ich das programmiertechnisch umsetzten soll :confused:

Es gibt zwar eine Deselect und SelectTab Methode im .NET Framework 2.0, aber ich hänge daran, über die Events zu erfahren, welche TabPage die Aktion gerufen hat und auf welche TabPage gewechselt wird....
Kann aber auch sein, das ich schon so tief in diesem Problem feststecke, dass ich irgendwas übersehen habe -.-

Hoffe, da kann mich jemand aufklären,
danke für eure Zeit

mfG
Leitman
 

Neue Beiträge

Zurück