Newsgroup: it.comp.lang.c
Titolo: clipboard in windows...

Qualcuno sa come prelevare le immagini dalla clipboard di windows???
Grazie
				Ale

Qualcuno sa come prelevare le immagini dalla clipboard di windows???
Certo.  OpenClipboard(0) rende il tuo task "padrone" della
clipboard (se qualcun altro la sta tenendo aperta, il task
andra' in coda di attesa sinche' non si libera).  Poi, una
IsClipboardDataAvailable (o piu` di una) ti permette di
verificare se sono disponibili dati nel formato che desideri;
torna TRUE o FALSE, e prende come unico argomento
il codice del tipo-dati che desideri, ad esempio CF_DIB
se cerchi una device-independent bitmap, o CF_BITMAP
se cerchi una HBITMAP (handle-to-bitmap), o CF_TIFF
per una Tagged-Image File-Format (Tiff, appunto), ecc
ecc.  Se trovi un tipo di dati che ti va bene ed e' presente
nella clipboard, GetClipboardData, con unico argomento
quello stesso codice CF_QUALCOSA, ti tornera' la
appropriata handle (torna 0 in caso di problemi, al che
puoi chiamare GetLastError per sapere quali sono stati
i problemi stessi, come per piu` o meno tutte le API).
Copia immediatamente i dati, che restano di proprieta`
della clipboard e NON sono tuoi "a lungo termine" (in
particolare, ***NON*** free-are quella handle, e neppure
lasciarla lockata indefinitamente!!!).  Infine, ricordati di
chiamare CloseClipboard!
La clipboard puo` anche fare alcune conversioni di
dati, per esempio fra CF_BITMAP e CF_DIB in
entrambi i sensi, per cui puo` anche esserti piu`
comodo evitare la IsClipboardFormatAvailable e
provare semplicemente la GetClipboardData se
desideri un unico formato, rinunciando se ti torna
NULL.
C'e anche un approccio alternativo alla clipboard
basato su COM (o come una volta si diceva "OLE"),
ma questo delle API nude e crude, nei casi semplici,
puo` essere piu` che sufficiente.
Alex

 Ale







la uso, ma nopn mi fa accedere ai dati.
Per esempio se il leggo il contenuto in un vettore di caratteri, appena
accedo al primo carattere mi da una access violation: la memoria non
poteva essere read.
Come posso fare?
		Grazie
			Ale

Come posso fare?
Postaci un esempio-giocattolo che mostri esattamente
quello che stai facendo -- una decina di righe dovrebbero
bastare, controlli d'errore compresi -- e potremo forse
esserti piu' utili (sul gruppo, please, NON in mail).
Alex

Allora, quello che tento di fare e' piu' o meno questo:
HANDLE flusso;
unsigned char *caratteri;
OpenClipboard (NULL); il null puo' essere anche una finestra
flusso = Get Clipboarddata(CF_BITMAP);
if flusso != NULL 
	caratteri = Globallock (flusso);
 
Qui ognitentativo di accedere a caratteri mi da acces violation.
Perche'?
Grazie
			Ale

...
    [snip]
Ecco un programmino-giocattolo che legge testo dalla
clipboard e lo mostra su console.  Facci sapere se
risolve il tuo problema, oppure quali problemi restano!
#include <stdio.h>
#include <windows.h>
char* error(const char* msg, int mustClose)
{
    int rc = GetLastError();
    printf("Error %s: %d\n", msg, rc);
    if(mustClose)
        CloseClipboard();
    return 0;
}
char* read_clip()
{
    HANDLE hRes;
    void *pvRes;
    char *pcRes;
    char *pcCop;
    if(!OpenClipboard(0))
        return error("opening clipboard",0);
    hRes = GetClipboardData(CF_TEXT);
    if(!hRes)
        return error("reading clipboard",1);
    pvRes = GlobalLock(hRes);
    if(!pvRes)
        return error("locking handle", 1);
    pcRes = (char*) pvRes;
    pcCop = _strdup(pcRes);
    if(!GlobalUnlock(hRes)) {
        free(pcCop);
        return error("unlocking handle", 1);
    }
    if(!CloseClipboard()) {
        free(pcCop);
        return error("closing clipboard", 0);
    }
    return pcCop;
}
void free_clip(char* p)
{
    free(p);
}
int main()
{
    char* pr = read_clip();
    if(pr) {
        printf("Text on clipboard: (%s)\n", pr);
        free_clip(pr);
    } else {
        printf("No text on clipboard\n");
    }
    return 0;
}
Alex

Perche'?
Perche' la handle che ottieni, per CF_BITMAP, non e' la
handle di un oggetto di memoria.  Dalla doc in linea...:
Value                    Meaning 
CF_BITMAP         A handle to a bitmap (HBITMAP)
e una HBITMAP non e' (necessariamente) una HANDLE
ritornata da GlobalAlloc.  Quindi, non puoi accedervi con
GlobalLock, bensi` devi usare le funzioni specifiche per le
HBITMAP, tutte orientate a inserirle in vari modi in un
device context (DC).  In particolare se per qualche ragione
ti serve che il device context sia in memoria, ad esempio
per potervi fare il SelectObject della bitmap, dovrai crearne
uno compatibile con un DC "vero", usando, naturalmente,
la CreateCompatibleDC.  O forse quello che intendi fare
si compie meglio con GetDIBits.
Alex