Checkboxen, Focus, Zwischenablage und die Enter-Taste



  • "Using the Clipboard" in der MSDN

    Schau Dir da mal die Beispiele "Copying Information to the Clipboard" und "Pasting Information from the Clipboard" an...



  • Wenn ich das richtig verstehe geht es in diesem beispiel darum ausgewählten Text
    in das Clipboard zu schreiben, ich habe aber den Text doch bereits, der wird ja
    nicht vom Benutzer bestimmt. Das Beispiel ist ziemlich komplex, dadurch mal sehen
    ob ich trotzdem durchsteige.



  • Wenn der User den Text nicht bestimmt, warum willst Du dann das Clipboard vergewaltigen?

    Also, wenn mir ein Programm einfach so mirnix dirnix meine Zwischenablage überschreiben würde, würde es im selben Atemzug von der Platte verbannt werden, das kann ich Dir sagen...

    Es gibt eigentlich keinen Grund für ein Programm, ohne Befehl des Users die Zwischenablage anzufassen...

    Was willst Du tun?



  • Das Programm ist für mich, auschließlich, und damit ich weniger tippen muss,
    soll es mir den Wert automatisch in die zwischenablage schreiben, allerdings
    nur wenn die Checkbox makiert ist. Das funktioniert ja nur das schreiben in
    das Clipboard nicht.
    Und um ehrlich zu sein ich verstehe das Beispiel kein bischen, habe damit eben
    etwas experimentiert, aber ich verstehe nichtmal wie durch das kopieren in
    lpstrCopy auf einmal der Wert auch in hglbCopy stehen kann.



  • GlobalLock gibt dir doch einen Pointer auf das erste Byte des angegebenen Speicherbereichs an.
    hglbCopy, lpstrCopy zeigen also auf ein und denselben Speicher 😉

    Von der Vorgehensweise her musst du dir eben zu erst mit GlobalAlloc globalen Speicher besorgen, sodass dein String hineinpasst, dann lockst du ihn mit GlobalLock und kopierst deinen String hinein (z.B. lstrcpy). Anschließend mit GlobalUnlock die Sperre wieder aufheben und den Pointer an SetClipboardData übergeben



  • // Hier wird Speicher Global reserviert, hglbCopy ist der HANDLE auf den Speicherbereich
    hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (cch + 1) * sizeof(TCHAR)); 
    
    // Dann gelockt... lptstrCopy zeigt nun auf das erste Byte des Speicherblocks
    lptstrCopy = GlobalLock(hglbCopy); 
    
    // und mit dem Inhalt des Editfeldes beschrieben (&pbox->atchLabel[ich1] ist der Inhalt des Edit-Feldes, bzw. ein Zeiger auf das erste Byte des Inhaltes)
    memcpy(lptstrCopy, &pbox->atchLabel[ich1], cch * sizeof(TCHAR)); 
    
    // abschließend mit '\0' terminiert
    lptstrCopy[cch] = (TCHAR) 0;    // null character 
    
    // ...und wieder unlocked...
    GlobalUnlock(hglbCopy);
    

    Probier doch mal &pbox->atchLabel[ich1] durch einen Zeiger auf Deinen Text-String zu ersetzen...





  • Ich bekomme folgenden Fehler (habe es eben nochmals versucht):

    156 E:\Sources\CPP\Calc\main.cpp
    invalid conversion from `void*' to `TCHAR*'
    

    Meine Variante:

    void CopyToClipboard (int value, HWND hwnd) {
     LPTSTR  lptstrCopy; 
     HGLOBAL hglbCopy; 
     char item[64];
     snprintf (item,64, "%d",value);
    
     if (!OpenClipboard (hwnd))
     	return;
     EmptyClipboard ();
    
     hglbCopy = GlobalAlloc(GMEM_MOVEABLE, strlen (item) * sizeof (char) + 1);
     if (!hglbCopy) {
     	CloseClipboard ();
     	return;
     }
     lptstrCopy = GlobalLock(hglbCopy); 
     memcpy(lptstrCopy, item,strlen (item) * sizeof(char)); 
     lptstrCopy[strlen (item)] = 0;
     GlobalUnlock(hglbCopy); 
    
     SetClipboardData(CF_TEXT, hglbCopy); 
    
     CloseClipboard ();
    
     return;
    }
    

    Sind derzeit leider noch keine Kommentare drin, dürft aber auch so gehen 🙂



  • Habe jetzt die Funktion aus dem Beitrag aus dem Konsolenforum verwendet, mit dieser
    geht es 🙂

    Jetzt fehlt nur noch die Enter-Taste 😞



  • Da mir hier keiner mehr helfen konnte bin ich ins Usenet und habe nach Hilfe
    gefragt und nachdem ich den Tipp bekam, das Ereignis in der message loop vor
    dem Dispatch abzufangen und zu überprüfen, fiel mir auf, dass es nicht an
    der Enter-Taste liegt, sondern die Eingabe nicht ausgelesen wird. Und vllt.
    stimmt mit der Ausgabe auch etwas nicht.

    ich erlaube mir einfach mal das posting aus dem usenet zu coden 🤡

    Und nochmal ich, ich habe gerade festgestellt, dass das
    drücken der Enter-Taste erkannt wird, zuerst dachte ich
    der Wert wird dann wohl falsch in das Editfeld geschrieben
    bzw. überhaupt nicht. Allerdings hat sich eben herausgestellt,
    dass es nicht daran liegt, sondern am Auslesen des Eingabefeldes
    (ebenfalls ein Edit-Feld). Der gleiche Code funktioniert über
    den Mausklick fehlerfrei, erzeugt jedoch über die Enter-Taste
    als Eingabe immer eine "0" und in der Ausgabe erscheint nichts.
    
    Der mausklick:
       case WM_COMMAND:
    
          switch (LOWORD(wParam))
          {
            case ID_BUTTON:
            {
              UINT zahl = GetDlgItemInt(hwnd,ID_INPUT,NULL,FALSE);
              UINT erg  = vielfaches(zahl);
              SetDlgItemInt(hwnd,ID_OUTPUT,erg,FALSE); // Ausgabefeld
    
              if (IsDlgButtonChecked(hwnd, ID_CHECKBOX) == BST_CHECKED)
                         CopyToClipboard (erg, hwnd); // Zwischenablage
    
              SetDlgItemText(hwnd,ID_INPUT,""); // Eingabefeld leeren
           SetFocus(GetDlgItem(hwnd, ID_INPUT)); // Focus für Eingabefeld
              return (0);
            }
          }
          break;
    
    Enter drücken in WndProc:
       case WM_KEYDOWN:
           switch (wParam)
           {
             case VK_RETURN:
             {
                UINT zahl = GetDlgItemInt(hwnd,ID_INPUT,NULL,FALSE);
                UINT erg  = vielfaches(zahl);
                SetDlgItemInt(hwnd,ID_OUTPUT,erg,FALSE); // Ausgabefeld
    
                if (IsDlgButtonChecked(hwnd, ID_CHECKBOX) == BST_CHECKED)
                         CopyToClipboard (erg, hwnd); // Zwischenablage
    
                SetDlgItemText(hwnd,ID_INPUT,""); // Eingabefeld leeren
                SetFocus(GetDlgItem(hwnd,ID_INPUT)); //Focus für Eingabefeld
                return (0);
             }
          }
          break;
    
    Enter drücken in der MessageLoop abgefangen:
       while (GetMessage (&msg, NULL, 0, 0))
       {
          TranslateMessage (&msg);
          if (!pressedReturn (&msg)) // Enter gedrückt ?
              DispatchMessage (&msg);
       }
    
    bool pressedReturn (MSG *msg) {
      // Taste gedrückt ?
      if (msg->message == WM_KEYDOWN) {
        // Enter gedrückt ?
        if (msg->wParam == VK_RETURN) {
          UINT zahl = GetDlgItemInt(msg->hwnd,ID_INPUT,NULL,FALSE);
              UINT erg  = vielfaches(zahl);
    
              SetDlgItemInt(msg->hwnd,ID_OUTPUT,erg,FALSE); // Ausgabefeld
    
              if (IsDlgButtonChecked(msg->hwnd, ID_CHECKBOX) == BST_CHECKED)
                     CopyToClipboard (erg, msg->hwnd); // Zwischenablage
    
              SetDlgItemText(msg->hwnd,ID_INPUT,""); // zurücksetzen
           SetFocus(GetDlgItem(msg->hwnd,ID_INPUT)); //Focus Eingabefeld
    
              return true;
            }
         }
         return false;
    }
    
    Ich versteh das nicht
    

    Jetzt die alles entscheidende Frage: Warum 😕

    Ich versteh das absolut nicht 😞



  • Kannst du nochmal genau sagen was du willst? (so einfach wie möglich)



  • Er will den Druck auf die Enter-Taste abfangen, auch wenn das Edit den Fokus besitzt. Mit Subclassing sollte sich das eigentlich auf jeden Fall machen lassen, aber eigentlich müsste das doch auch einfacher gehen 😕



  • müsste schon auch anders gehen. IsDialogMessage kann es ja auch.



  • Damit hatte er in meiner Test-Anwendung nur auf Tabs reagiert, indem er zum nächsten Element gesprungen ist. Enter hat aber nicht den DEFPUSHBUTTON ausgelöst...



  • Genau ich will, dass das drücken von Enter abgefangen wird, was ja jetzt auch
    klappt, allerdings stimmt irgendetwas mit dem wParam nicht, denn darin steht
    nur Datenmüll, sonst könnte es ja in einen UINT (zahl) eingelesen werden, das
    wird es aber nicht. Wenn ich mit snprintf zahl in eine Zeichenkette
    umwandle und ausgebe wird es als 0 ausgegeben, es ist jedoch keine 0, sonst
    würde auch durch das berechnen als Ergebnis eine 0 rauskommen und nicht nichts.

    Mal was anderes, ich will euch hiermit nicht dumm anmachen oder so, aber das hat
    mich doch etwas erstaunt. Ich habe irgendwie langsam das Gefühl, dass es keinen
    Menschen gibt, der sich wirklich mit der Winapi auskennt, ihr könnt mir nicht
    weiterhelfen (bis jetzt), die in #c++.de im qnet, die im usenet. Das gibt mir
    irgendwie zu denken. Ist das wirklich so oder täusche ich mich da ?



  • Ich hatte dein Post von vorhin wohl zu sehr überflogen, also Enter abfangen klapp, nur die Zahl wird falsch ausgelesen, oder?! Das ist wohl nur der Fall, wenn du Enter in der Edit-Box drückst, oder?
    Das liegt dann daran, dass du in pressedReturn für GetDlgItemInt, SetDlgItemInt, IsDlgButtonChecked, ... msg->hwnd verwendest. Dort hast du aber direkt das Handle der Edit-Box - du benötigst aber für diese Aufrufe das Handle des Parents -> GetParent(msg->hwnd)

    SirLant schrieb:

    Mal was anderes, ich will euch hiermit nicht dumm anmachen oder so, aber das hat
    mich doch etwas erstaunt. Ich habe irgendwie langsam das Gefühl, dass es keinen
    Menschen gibt, der sich wirklich mit der Winapi auskennt, ihr könnt mir nicht
    weiterhelfen (bis jetzt), die in #c++.de im qnet, die im usenet. Das gibt mir
    irgendwie zu denken. Ist das wirklich so oder täusche ich mich da ?

    Bei mir hast du da völlig Recht, auch wenn hier wohl einige nicht den Eindruck haben 🤡
    So richtig Anwendungen hab ich eigentlich noch gar nie mit WinAPI oder auch anderen Klassenbibliotheken programmiert (ich programmiere eigentlich fast nur in PHP) - die gewissen "Grundlagen-Kenntnisse" habe ich durch dieses Forum, und durch Petzold und Richters erlangt 😉 Meine praktische Erfahrungen in diesem Bereich sind daher nahezu NULL 🕶



  • flenders schrieb:

    Bei mir hast du da völlig Recht, auch wenn hier wohl einige nicht den Eindruck haben 🤡
    So richtig Anwendungen hab ich eigentlich noch gar nie mit WinAPI oder auch anderen Klassenbibliotheken programmiert (ich programmiere eigentlich fast nur in PHP) - die gewissen "Grundlagen-Kenntnisse" habe ich durch dieses Forum, und durch Petzold und Richters erlangt 😉 Meine praktische Erfahrungen in diesem Bereich sind daher nahezu NULL 🕶

    LOL!

    Also dafür, muß ich Dir mal sagen, lieferst Du hier einen fantastischen Job ab, flenders!



  • Hepi schrieb:

    Also dafür, muß ich Dir mal sagen, lieferst Du hier einen fantastischen Job ab, flenders!

    Danke, sowas freut einen doch 🙂

    Aber manchmal würde ich mir wünschen, doch etwas mehr praktische Erfahrung in der Umsetzung zu haben, sodass man auch mal etwas sinnvolles damit anfangen kann - gerade im Bereich der Strukturierung etwas größerer Projekte. Kann mir da evtl. jemand etwas gutes empfehlen?

    Aber das sollten wir wenn dann wohl an anderer Stelle weiterdiskutieren - gehört hier ja nicht so wirklich hin 🙄 🤡



  • Flenders du bist der beste 👍 🙂
    Jetzt funktioniert es Danke und auch allen anderen die mir so fleißig geholfen haben ein
    ganz großes Dankeschön 🙂


Anmelden zum Antworten