MessageCodes umwandeln



  • lade sie in einen speicher und durchsuch sie, bau die datei einfach zb wie folgt auf:
    das DateiFormat, vorschlag:
    Byte:
    FF FF = Word 0xFFFF als trennzeichen
    xx xx = Word Als länge der Char, bzw länge der MessageCodes Beschreibung
    xx xx = Message Codes als HEX
    xx xx xx ... = Bezeichnung der MessageCodes in ASCII;

    dann lädst du die gesammte datei in den speicher und dursuchst den buffer!!



  • Warum so kompliziert? Man kann doch auch einfach ein Array benutzen. Der Lookup ist deutlich einfacher.



  • nimm ein switch/case!



  • buntehaare schrieb:

    lade sie in einen speicher und durchsuch sie

    das geht wegen der performance nicht, denn wenn man zB das Fenster so an den Bildschirmrand schiebt, dass es nur noch teilweise sichtbar ist und wieder richtung mitte zieht kommen schon mal 50 WM_PAINTs und andere nachrichten pro sekunde.
    es sollte ziemlich unmöglich sein, eine Liste mit mehreren tausend einträgen 50 mal pro sekunde durchzugehen und die codes dabei umzurechnen(da dürfte einmal komplette durchsuchen und umrechnen max. 5-10ms dauern!) [jenachdem wieviele einträge es genau sind, die sprünge machen es ziemlich schlecht zählbar^^].

    bitsch schrieb:

    nimm ein switch/case!

    das wäre mit der Performance zwar nahezu perfekt aber ich kann unmöglich alles abtippen 😞

    O.o schrieb:

    Warum so kompliziert? Man kann doch auch einfach ein Array benutzen. Der Lookup ist deutlich einfacher

    Das Problem eines Arrays ist, dass die werte durchgehend besetzt sein müssen:

    z.B. machen die nachrichtencodes in den dezimalwerten sprünge:

    Liste schrieb:

    84=WM_USERCHANGED
    85=WM_NOTIFYFORMAT
    123=WM_CONTEXTMENU

    und das geht öfter so... in einem standard-array kann ich aber nicht einfach lücken lassen 😞

    ich denke es wäre am einfachsten eine std::map zu verwenden, oder gibt es bessere Alternativen?

    lg,
    andi01.



  • Hier ein Beispiel wie man es einfach machen kann ohne das man den Wert der Nachricht im Code als Zahl schreiben muss.

    #define WORDCASE(w) case w: return _T(#w)

    static const TCHAR *printable_servicecontrol(DWORD dwControl)
    {
    	switch (dwControl)
    	{
    	  WORDCASE(SERVICE_CONTROL_STOP);
    	  WORDCASE(SERVICE_CONTROL_PAUSE);
    	  WORDCASE(SERVICE_CONTROL_CONTINUE);
    	  WORDCASE(SERVICE_CONTROL_INTERROGATE);
    	  WORDCASE(SERVICE_CONTROL_SHUTDOWN);
    	  WORDCASE(SERVICE_CONTROL_PARAMCHANGE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDADD);
    	  WORDCASE(SERVICE_CONTROL_NETBINDREMOVE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDENABLE);
    	  WORDCASE(SERVICE_CONTROL_NETBINDDISABLE);
    
    	  default: return _T("SERVICE_CONTROL_???");
    	}
    }
    


  • hm also zB 0x0007 ist nach meiner liste als WM_SETFOCUS definiert, deine Funktion sagt aber SERVICE_CONTROL_NETBINDADD 😕

    also es sollen eigentlich die codes für die Windows-Nachrichten in Text "umgewandelt" werden.

    zb. 0x0007->WM_SETFOCUS
    0x0008->WM_KILLFOCUS
    ...

    aber gibt es da auch so eine Funktion? das würde mir nämlich sehr viel Arbeit ersparen 😃
    ganau sowas bräuchte ich für diese codes, das wäre perfekt 🙂

    edit: link zu Liste: http://wiki.winehq.org/List_Of_Windows_Messages

    also mein aktueller Ansatz ist die Liste in eine txt-datei zu kopieren (das geht ja schnell), zu beginn des Programms einmalig in eine globale map einzulesen (bei der der dezimalwert der key-wert ist) und zur laufzeit unter den dezimalwerten mit fast perfekter performance die Nachrichten umzuwandeln...

    oder kann man das noch geschickter oder besser lösen?

    lg,
    andi01.



  • oh mann das war ein BEISPIEL wie du es machen könntest für deine Nachrichten



  • Du kannst die HTML-Seite vom Wine-Wiki in OpenOffice Writer einladen und die Spalte kopieren dann hast du schonmal alle Nachrichten extrahiert. Dann musst du nur noch ein kleines Programm schreiben jeden String in dieses WORDCASE-Makro kapselt und du bist fast fertig.



  • also ich hätte es jetzt spontan mit einer map gelöst (nachdem ich die nachrichten extrahiert hatte) (siehe edit letzter post).

    am wichtigsten ist eigentlich die performance weil sehr schnell sehr viele nachrichten ankommen^^

    lg,
    andi01.



  • Das ist kein Problem!



  • naja ich mache mich mal dran die nachrichten mit den codes in eine textdatei zu extrahieren.

    bg,
    andi01.



  • so ich habe jetzt die Datei soweit, dass vorne der dezimalwert steht, dann kommt ein tabspace und dann die Nachricht mit einer Zeile pro Nachricht.

    meine datei sieht momentan so aus (upload) : http://www.dateiupload.com/files/Ql96mjhwqH.txt

    auch die einlesemethode habe ich schon fertig.

    auch die performance ist sehr gut (unter 1s!).

    ich werde sie später mal in meine dll reinprogrammieren und schaun ob alles funktioniert.

    übrigens so sieht die (vorläufige) methode zum einlesen aus:

    #include<map>
    
    map<UINT, string> Nachrichten;//globale map
    
    bool ist_zahl(char zeichen)//nur ziffern
    {
    	int i=static_cast<int>(zeichen);
    	if(i>47&&i<58)//zwischen 0 und 9
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    void nachrichten_einlesen()
    {
    	MessageBox(0, TEXT("beginne einlesen der Nachrichtenliste..."), TEXT("INFO:"), MB_OK);
    	ifstream is("nachrichten.txt");
    
    	//einlesenund direkt verarbeiten:
    	is.seekg(0L, ios::beg);
    
    	char zeile[1024];
    	UINT code;
    	string nachricht;
    	string code_alt;
    
    	if(is.is_open())
    	{
    	while(!is.eof())
    	{
    		is.getline(zeile, 1024);//zeile einlesen;
    
    		//zeile filtern:
    
    		//UINT-Wert filtern:
    		//zeilenformat: 7=WM_SETFOCUS
    		int a;
    		for(a=0;ist_zahl(zeile[a])==true&&a<strlen(zeile);a++)
    		{
    			code_alt+=zeile[a];
    		}
    		a++;//tabspace überspringen
    
    		//Nachricht filtern:
    		for(int b=a;b<strlen(zeile);b++)
    		{
    			nachricht+=zeile[b];
    		}
    
    		//nachrichten konvertieren:
    		code=atoi(code_alt.c_str());
    
    		//nachrichten hinzufügen:
    		Nachrichten[code]=nachricht;
    
    		//aufräumen:
    		nachricht.clear();
    		code_alt.clear();
    	}
    	}
    
    	is.close();
    	MessageBox(0, TEXT("Einlesen beendet."), TEXT("INFO:"), MB_OK);
    }
    

    lg,
    andi01.



  • so ich habe jetzt alles implementiert und es funktioniert perfekt 🙂
    auch die Performance ist gar kein Problem.

    aber es tauchen immer wieder 3 codes in meinem log auf die offenbar in der liste fehlen:

    176
    201
    187

    weiß jemand für welche Messages die stehen?

    lg,
    andi01.



  • Was wird den geloggt?

    LRESULT CALLBACK neueWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    

    Nur der Teil "message" oder gehst du ins Detail und untersuchst auch "lParam" bei WM_NOTIFY und "wParam" bei WM_COMMAND?



  • natürlich gehe ich ins detail, die funktion ist in meinem code um einiges komplizierter als ich sie hier gepostet habe.

    ich habe den Code nur auf das Wesentliche reduziert um keine 100 Zeilen für etwas posten zu müssen was ich auch in 5 erklären kann 😉 . (nämlich die tastsache, dass für die Messages zu diesem zeitpunkt nur die codes wie 0x0007 ankamen, ziel des codeschnippsels war es den grund dafür anschaulich zu machen^^)

    natürlich logge ich auch wparam, lparam, die jeweiligen HIWORDs und LOWORDs, ob die message ans child oder parent ging, uhrzeit, datum,die aktuelle cursorposition als die nachricht reinkam,...

    ich versuche nämlich gerade bestimmte message-abfolgen zu loggen, zB was passiert wenn man einen button klickt oder eine checkbox "checkt", welche messages werden gesandt mit welchen parametern usw.

    dabei fehlern mir nur noch obige 3 codes dann habe ich das schonmal komplett, dann muss ich mich nur noch drum kümmern welche messages im zusammenhang mit einem bestimmten ereignis (zB button anklicken) stehen (zB anhand der exakten zeit).

    lg,
    andi01.



  • ich glaube du gehst ein bisschen zu tief ins detail das hört sich ja schon fast kriminell an. 🤡



  • die logs sind auch kriminell groß... viel zu groß, nach 1 minute loggen braucht editor schon 10 sec zum öffnen der datei 😃

    ich glaube ich werde mich mal auf die wesentlichen messaged beschränken und zB so sachen wie WM_PAINT oder so rausstreichen weil die mich bei Buttonklicks eher nicht interessieren.

    Welche sind denn zB wichtig wenn ich einen Button drücke? auf jedenfall schonmal WM_NCHITTEST und WM_COMMAND, muss ich auf andere auch noch achten?
    ich stehe noch ziemlich am Anfang mit meinen Kenntnissen bei welchen ereignissen welche messages geschickt werden und will mir das ganze über das log mal genauer anschaun^^

    edit: und ganz wichtig, auf welche parameter muss ich genau achten? zB wparam HIWORD oder Lparam LOWORD? ich logge nämlich erstmal alles und das wird sehr schnell sehr viel...

    lg,
    andi01.



  • andi01 schrieb:

    edit: und ganz wichtig, auf welche parameter muss ich genau achten? zB wparam HIWORD oder Lparam LOWORD? ich logge nämlich erstmal alles und das wird sehr schnell sehr viel...

    Ich hab mich zwar schon länger mit der WinApi direkt beschäftigt, aber wenn mich nicht alles täuscht, hängt das immer von der jeweiligen Nachricht ab. Was das dann im einzelnen bedeutet ist alles fein säuberlich im MSDN dokumentiert 😃



  • andi01 schrieb:

    natürlich gehe ich ins detail, die funktion ist in meinem code um einiges komplizierter als ich sie hier gepostet habe.

    ich habe den Code nur auf das Wesentliche reduziert um keine 100 Zeilen für etwas posten zu müssen was ich auch in 5 erklären kann 😉 . (nämlich die tastsache, dass für die Messages zu diesem zeitpunkt nur die codes wie 0x0007 ankamen, ziel des codeschnippsels war es den grund dafür anschaulich zu machen^^)

    Aha!? 🙂

    "winuser.h" z.B. EM_GETSEL = 176
    Guggst du weiter findest du alles.



  • oh mir fällt gerade noch ein anderes Problem meines Programmes auf...

    Die Messages kommen ja als hex-werte rein, oder?
    das problem ist nämlich, dass in meiner textdatei die dec-werte stehen^^

    kann ich im programm die im Parameter message (typ UINT) ankommenden hex-werte in meinem programm irgendwie so umrechnen, dass die Performance erhalten bleibt?
    (denn der einzige Weg der mir auf die Schnelle einfällt wäre über stringstreams, aber die sind viel zu langsam 😞 )

    gibt es eine Möglichkeit mit guter Performance?

    denn ich kenne nur diesen langsamen Weg:

    string hex_wert;
    string dec_wert;
    stringstream sstr;
    sstr<<hex_wert;
    sstr>>dec>>dec_wert;
    

    aber das ist zu langsam 😞

    lg,
    andi01.


Anmelden zum Antworten