WM_SETTEXT sendet nur ein Zeichen?



  • Was sagen denn die Rückgabewerte?



  • Also, das erste Sendmessage (WM_GETTEXTLENGHT) gibt die Anzahl der Zeichen des Edit-Controls zurück. Dass der Rückgabewert stimmt hab ich schon überprüft.

    Das zweite Sendmessage (WM_GETTEXT) gibt den selben Wert zurück (die Anzahl der bezogenen Zeichen), auch das ist korrekt.

    Das dritte Sendmessage (WM_SETTEXT) gibt 1 zurück, also "Erfolg".

    Von daher müsste ja alles passen, oder? Leider klappt es aus einem mir nicht ersichtlichen Grund trotzdem nicht.



  • Und du verwendest nun korrekterweise auch SendMessageW()?



  • Jawohl, hab alle SendMessages durch SendMessageW ersetzt, genau das Gleiche Verhalten, genau die gleichen Return-Werte.

    In "buff" steht der Text auch korrekt, wenn ich mir den mittels:

    for(int i = 0; i < length; i++)
    	std::cout << static_cast<char>(buff[i]);
    

    ausgeben lasse erhalte ich in der Konsole auch genau den richtigen Text des ersten Edit-Controls. Das funktioniert also.

    Nur das WM_SETTEXT klappt irgendwie nicht, bzw. schickt es nur den ersten Buchstaben.



  • happystudent schrieb:

    Jawohl, hab alle SendMessages durch SendMessageW ersetzt, genau das Gleiche Verhalten, genau die gleichen Return-Werte.

    In "buff" steht der Text auch korrekt, wenn ich mir den mittels:

    for(int i = 0; i < length; i++)
    	std::cout << static_cast<char>(buff[i]);
    

    ausgeben lasse erhalte ich in der Konsole auch genau den richtigen Text des ersten Edit-Controls. Das funktioniert also.

    Funktioniert und zeigt, das die UNICODE Kenntnisse gegen NULL gehen 😉

    Wenn buff ein wchar_t ist, sollte man evtl. wcout verwenden und sich den
    Umstand mit der for()-Schleife und dem Index sparen ...

    Es wäre zudem auch gesünder bei SendMessage() nicht length + 1 zu verwenden, sondern nur length.



  • merano schrieb:

    Funktioniert und zeigt, das die UNICODE Kenntnisse gegen NULL gehen 😉

    Nun, das kann ich nicht abstreiten 😃

    merano schrieb:

    Wenn buff ein wchar_t ist, sollte man evtl. wcout verwenden und sich den
    Umstand mit der for()-Schleife und dem Index sparen ...

    Ja, also das Problem ist ja nicht das cout, das war nur als Beispiel mit dem ich sichergehen konnte dass kein Schrott in dem buff array steht. Worum es eigentlich geht ist ja das WM_SETTEXT. Wenn ich das Ganze so mache funktioniert es:

    // Textlänge holen
    int length = SendMessageW(hWnd1, WM_GETTEXTLENGTH, 0, 0);
    
    // Zwei Buffer Arrays anlegen
    wchar_t* buff1 = new wchar_t[length + 1];
    char* buff2 = new char[length + 1];
    
    // Text in den ersten Buffer holen
    SendMessageW(hWnd1, WM_GETTEXT, textLength + 1, reinterpret_cast<LPARAM>(buff1));
    
    // Dann in den zweiten Buffer umkonvertieren
    for(int i = 0; i <= length; i++)
    	buff2[i] = static_cast<char>(buff1[i]);
    
    // Versenden (klappt so)
    SendMessageW(hWnd2, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(buff2));
    
    // Aufräumen
    delete[] buff1;
    delete[] buff2;
    

    Das find ich aber nicht besonders schön und performance technisch ist es bestimmt auch nicht optimal dass ich dann nochmal extra über das Ganze Array iterieren muss.

    Wie löse ich das geschickter?



  • happystudent schrieb:

    Ja, also das Problem ist ja nicht das cout, das war nur als Beispiel mit dem ich sichergehen konnte dass kein Schrott in dem buff array steht. Worum es eigentlich geht ist ja das WM_SETTEXT. Wenn ich das Ganze so mache funktioniert es:

    // Textlänge holen
    int length = SendMessageW(hWnd1, WM_GETTEXTLENGTH, 0, 0);
    
    // Zwei Buffer Arrays anlegen
    wchar_t* buff1 = new wchar_t[length + 1];
    char* buff2 = new char[length + 1];
    
    // Text in den ersten Buffer holen
    SendMessageW(hWnd1, WM_GETTEXT, textLength + 1, reinterpret_cast<LPARAM>(buff1));
    
    // Dann in den zweiten Buffer umkonvertieren
    for(int i = 0; i <= length; i++)
    	buff2[i] = static_cast<char>(buff1[i]);
    
    // Versenden (klappt so)
    SendMessageW(hWnd2, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(buff2));
    
    // Aufräumen
    delete[] buff1;
    delete[] buff2;
    

    Das find ich aber nicht besonders schön und performance technisch ist es bestimmt auch nicht optimal dass ich dann nochmal extra über das Ganze Array iterieren muss.

    Wie löse ich das geschickter?

    Indem Du den ganzen Ramsch mit dem W und dem kopieren weglässt 🙄

    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd, hWnd1, hWnd2;
    
       hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    	  CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    
       if(!hWnd)
    	return FALSE;
    
       hWnd1 = CreateWindow(TEXT("EDIT"), TEXT("eins"), WS_CHILD | WS_VISIBLE,
    	  20, 20, 200, 40, hWnd, (HMENU)1, hInstance, NULL);
    
       hWnd2 = CreateWindow(TEXT("EDIT"), TEXT("zwei"), WS_CHILD | WS_VISIBLE,
    	  20, 60, 200, 40, hWnd, (HMENU)2, hInstance, NULL);
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
        // Textlänge holen 
    	int length = SendMessage(hWnd1, WM_GETTEXTLENGTH, 0, 0); 
    
    	// Buffer anlegen 
    	wchar_t* buff1 = new wchar_t[length + 1]; 
    	// char* buff2 = new char[length + 1]; 
    
    	// Text in den ersten Buffer holen 
    	SendMessage(hWnd1, WM_GETTEXT, length+1, reinterpret_cast<LPARAM>(buff1)); 
    
    	// Versenden (klappt so) 
    	SendMessage(hWnd2, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(buff1)); 
    
    	// Aufräumen 
    	delete[] buff1; 
    
       return TRUE;
    }
    

    Bei mir steht dann zwei mal eins untereinander auf dem Bildschirm.



  • merano schrieb:

    Indem Du den ganzen Ramsch mit dem W und dem kopieren weglässt 🙄

    [...]
      
    	// Buffer anlegen 
    	wchar_t* buff1 = new wchar_t[length + 1]; 
    	// char* buff2 = new char[length + 1]; 
    
    [...]
    

    Warum dann nicht:

    TCHAR* buff1 = new TCHAR[length + 1];
    

    wie in Zeile 13 auch:
    hWnd1 = CreateWindow(TEXT("EDIT"), TEXT("eins") ...
    ?


  • Mod

    Klar geht das und ist meines Erachtens auch besser.



  • merano schrieb:

    Indem Du den ganzen Ramsch mit dem W und dem kopieren weglässt 🙄

    Also jetzt doch ohne W?

    merano schrieb:

    Bei mir steht dann zwei mal eins untereinander auf dem Bildschirm.

    Das ist ja das komische, bei mir klappt das mit diesem Code nicht (ist ja genau der gleiche wie aus meinem Anfangspost). Kann das vielleicht an dem Textfeld der externen Applikation liegen? Oder einfach an der Tatsache dass es eine externe Applikation ist?

    Momentan klappt es halt leider nur mit dem Kopier-Schritt. 😞

    Belli schrieb:

    Warum dann nicht:

    Hab ich gleich ausprobiert, bringt leider auch nicht das gewünschte Ergebnis.



  • Belli schrieb:

    Warum dann nicht:

    TCHAR* buff1 = new TCHAR[length + 1];
    

    Ist natürlich der saubere Weg, wollte hier aber keine neue Baustelle aufmachen.

    Was ist genau eine "externen Applikation".

    Du willst eine Fenster-Message an einen anderen Prozess senden ?

    Die Doku sagt dazu:

    Message sending is subject to UIPI. The thread of a process can send messages only to message queues of threads in processes of lesser or equal integrity level.

    Wenn allerdings ein Zeichen ankommt sollte das ja erfüllt sein, oder ?



  • merano schrieb:

    Was ist genau eine "externen Applikation".

    Eine Anwendung die mir nicht zugänglich ist, wie zum Beispiel Notepad.

    merano schrieb:

    Wenn allerdings ein Zeichen ankommt sollte das ja erfüllt sein, oder ?

    Ja schon. Das Senden an sich funktioniert ja auch einwandfrei wenn ich den zu sendenden Text davor per Schleife in normale chars umwandel.





  • asbestos schrieb:

    ➡ GetWindowText function http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520(v=vs.85).aspx

    Sicher? In der MS Doku steht: However, GetWindowText cannot retrieve the text of a control in another application.

    Werds aber trotzdem mal ausprobieren, Danke.



  • habe das in MASM zb. mal so gemacht - mit erfolg:

    include \masm32\include\masm32rt.inc
    
    .data?
    value dd ?
    buffer1 db 1024 dup (?)
    
    .data
    hbtn dd 123456 ; = handle of ctrl
    
    .code
    
    start:
    
    invoke GetWindowText,hbtn,addr buffer1,lengthof buffer1  ; hbtn = handle of ctrl
    mov value, eax
    invoke GetWindowText,hbtn,addr buffer1,value+1
    print addr buffer1,13,10
    
    inkey
    exit
    
    end start
    

Anmelden zum Antworten