2013-03-12 4 views
5

Mi dica per favore, perché ottengo questo problemi:GetClipboardData (CF_UNICODETEXT);

  • se appunti contengono caratteri unicode (e.q. russo) ottengo solo la prima parola selezionata. Prima parola prima del carattere "spazio".

  • se gli appunti non contengono caratteri unicode (solo in inglese) Ottengo il primo carattere del testo selezionato.

selezionato testo:

CStringA getClipboard() 
{ 
    CStringA strData; 

    if (OpenClipboard(NULL)){ 

     HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT); 
     char *pchData = (char*)GlobalLock(hClipboardData); 
     strData = pchData; 
     GlobalUnlock(hClipboardData); 
     CloseClipboard(); 

    } 
    return strData; 
} 

Set testo:

bool setClipboard(CStringA textToclipboard) 
{ 
    bool success = true; 

    if (OpenClipboard(NULL)){ 

     EmptyClipboard(); 
     HGLOBAL hClipboardData; 
     size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR); 
     hClipboardData = GlobalAlloc(NULL, size); 
     TCHAR* pchData = (TCHAR*)GlobalLock(hClipboardData); 
     memcpy(pchData, LPCTSTR(textToclipboard.GetString()), size); 
     SetClipboardData(CF_UNICODETEXT, hClipboardData); 
     GlobalUnlock(hClipboardData); 
     CloseClipboard(); 
    } 

    return success; 

} 

ottiene semplicemente e il contenuto degli appunti set.

CStringA str = getClipboard(); 
setClipboard(str); 
+2

CStringA è una stringa ANSI - per UNICODE è necessario CStringW. –

+0

Non funziona. Ricevo i simboli B5: AB e strani "angoli" – user1537809

+0

Non è 'CF_UNICODETEXT' UTF-16, cioè la stringa di formato' W' standard, che significa per standard ascii, si otterrà solo un carattere. – Petesh

risposta

9

CF_UNICODETEXT usi UTF-16. Su Windows, gli elementi di dati wchar_t vengono utilizzati per UTF-16, ma il codice utilizza invece char. CStringA non è compatibile con UTF-16. Stai correggendo i dati in entrambe le funzioni, è per questo che non ottieni i risultati che ti aspetti.

Una soluzione è quella di utilizzare CStringW invece di CStringA:

CStringW getClipboard() 
{ 
    CStringW strData; 

    if (OpenClipboard(NULL)) 
    { 
     HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT); 
     if (hClipboardData) 
     { 
      WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData); 
      if (pchData) 
      { 
       strData = pchData; 
       GlobalUnlock(hClipboardData); 
      } 
     } 
     CloseClipboard(); 
    } 
    return strData; 
} 

bool setClipboard(CStringW textToclipboard) 
{ 
    bool success = true; 

    if (OpenClipboard(NULL)) 
    { 
     EmptyClipboard(); 
     size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR); 
     HGLOBAL hClipboardData = GlobalAlloc(NULL, size); 
     if (hClipboardData) 
     { 
      WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData); 
      if (pchData) 
      { 
       memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size); 
       GlobalUnlock(hClipboardData); 
       SetClipboardData(CF_UNICODETEXT, hClipboardData); 
      } 
     } 
     CloseClipboard(); 
    } 
    return success; 
} 

Se avete bisogno di attaccare con CStringA, allora:

  1. uso CF_TEXT invece di CF_UNICODETEXT e lasciare che le conversioni maniglia appunti tra Ansi e Unicode per voi:

    CStringA getClipboard() 
    { 
        CStringA strData; 
    
        if (OpenClipboard(NULL)) 
        { 
         HANDLE hClipboardData = GetClipboardData(CF_TEXT); 
         if (hClipboardData) 
         { 
          CHAR *pchData = (CHAR*) GlobalLock(hClipboardData); 
          if (pchData) 
          { 
           strData = pchData; 
           GlobalUnlock(hClipboardData); 
          } 
         } 
         CloseClipboard(); 
        } 
        return strData; 
    } 
    
    bool setClipboard(CStringA textToclipboard) 
    { 
        bool success = true; 
    
        if (OpenClipboard(NULL)) 
        { 
         EmptyClipboard(); 
         size_t size = (textToclipboard.GetLength()+1) * sizeof(CHAR); 
         HGLOBAL hClipboardData = GlobalAlloc(NULL, size); 
         if (hClipboardData) 
         { 
          CHAR* pchData = (CHAR*) GlobalLock(hClipboardData); 
          if (pchData) 
          { 
           memcpy(pchData, (CHAR*) textToclipboard.GetString(), size); 
           GlobalUnlock(hClipboardData); 
           SetClipboardData(CF_TEXT, hClipboardData); 
          } 
         } 
         CloseClipboard(); 
        } 
        return success; 
    } 
    
  2. convertire da/UTF-16 manualmente quando utilizza CF_UNICODETEXT:

    CStringA getClipboard() 
    { 
        CStringW strData; 
    
        if (OpenClipboard(NULL)) 
        { 
         HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT); 
         if (hClipboardData) 
         { 
          WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData); 
          if (pchData) 
          { 
           strData = pchData; 
           GlobalUnlock(hClipboardData); 
          } 
         } 
         CloseClipboard(); 
        } 
    
        return CStringA((WCHAR*)strData.GetString()); 
    } 
    
    bool setClipboard(CStringA strData) 
    { 
        CStringW textToclipboard((CHAR*)strData.GetString()); 
        bool success = true; 
    
        if (OpenClipboard(NULL)) 
        { 
         EmptyClipboard(); 
         size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR); 
         HGLOBAL hClipboardData = GlobalAlloc(NULL, size); 
         if (hClipboardData) 
         { 
          WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData); 
          if (pchData) 
          { 
           memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size); 
           GlobalUnlock(hClipboardData); 
           SetClipboardData(CF_UNICODETEXT, hClipboardData); 
          } 
         } 
         CloseClipboard(); 
        } 
        return success; 
    } 
    

Un'altra soluzione consiste nell'utilizzare CString anziché sia ​​CStringA o CStringW, e quindi utilizzare CF_TEXT o CF_UNICODETEXT seconda che TCHAR è Ansi o Unicode:

#ifdef UNICODE 
#define CF_TEXT_T CF_UNICODETEXT 
#else 
#define CF_TEXT_T CF_TEXT 
#endif 

CString getClipboard() 
{ 
    CString strData; 

    if (OpenClipboard(NULL)) 
    { 
     HANDLE hClipboardData = GetClipboardData(CF_TEXT_T); 
     if (hClipboardData) 
     { 
      TCHAR *pchData = (TCHAR*) GlobalLock(hClipboardData); 
      if (pchData) 
      { 
       strData = pchData; 
       GlobalUnlock(hClipboardData); 
      } 
     } 
     CloseClipboard(); 
    } 
    return strData; 
} 

bool setClipboard(CString textToclipboard) 
{ 
    bool success = true; 

    if (OpenClipboard(NULL)) 
    { 
     EmptyClipboard(); 
     size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR); 
     HGLOBAL hClipboardData = GlobalAlloc(NULL, size); 
     if (hClipboardData) 
     { 
      TCHAR* pchData = (TCHAR*) GlobalLock(hClipboardData); 
      if (pchData) 
      { 
       memcpy(pchData, (TCHAR*) textToclipboard.GetString(), size); 
       GlobalUnlock(hClipboardData); 
       SetClipboardData(CF_TEXT_T, hClipboardData); 
      } 
     } 
     CloseClipboard(); 
    } 
    return success; 
} 
+0

Wow! Grazie mille. Cambio CStringA in CStringW e char * in WCHAR * e funziona perfettamente! Con l'inglese tutte le lingue! Grazie! – user1537809

+0

Beh, grazie, grazie –

5

Entrambi sono Unicode ...

Ma in Unicode, più che un byte rappresenta un carattere. Ad esempio, forse 2 byte sono usati per un personaggio. Pertanto:

Quando è russa, la stringa è come

              '\0' 
                  ---- 
0x04 0x3F 0x04 0x40 0x04 0x38 0x04 0x32 0x04 0x35 0x04 0x42 0x00 0x20 
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ 
    п   р   и  в   е   т  space 

Si legge fino a quando lo spazio.

Quando è inglese, la stringa è come

'\0' 
---- 
0x00 0x48 0x00 0x65 0x00 0x6C 0x00 0x6C 0x00 0x6F 0x00 0x20 
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ 
    H   e   l  l   o  space 

Si legge nulla. (Se avete letto prima, è a causa di ordine di byte di stoccaggio, LE o BE)

Nota: Forse non sono la precisione nella scelta di parole (Unicode, UTF, ...)

+0

Grazie mille. Ma per favore spiegami come posso usarlo. – user1537809

+0

Forse la terminologia è errata (non so o non mi interessa) ma la spiegazione è ottima. Punti extra per i diagrammi. :-) – enhzflep

+0

Ok, provo a cambiare questa riga: strData = pchData; Ho bisogno di un'altra conversione? – user1537809