Newsgroup: it.comp.lang.c++
Titolo: creare collegamenti

ciao,
  devo creare, dal mio programma, un collegamento nel menu avvio della
machina su cui girerà, ho iniziato a dare un'occhiata all'help e ho scoperto
che devo usare l'interfaccia IShellLink, quindi un oggetto COM che non so
bene utilizzare (...e mi fà un po' paura...)
volevo chiedervi se c'è un'altro metodo più semplice per creare questo
shortcut da programma oppure se devo buttarmi sulla IShellLink.
sull'help ho trovato questo esempio a riguardo, e mi sono sorte un po' di
domande......
// CreateLink - uses the shell's IShellLink and IPersistFile interfaces
//   to create and store a shortcut to the specified object.
// Returns the result of calling the member functions of the interfaces.
// lpszPathObj - address of a buffer containing the path of the object
// lpszPathLink - address of a buffer containing the path where the
//   shell link is to be stored
// lpszDesc - address of a buffer containing the description of the
//   shell link
HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc)
{     
   HRESULT hres; 
    IShellLink* psl;
     // Get a pointer to the IShellLink interface. 
    hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl); 
    if (SUCCEEDED(hres)) {
             IPersistFile* ppf;  
            // Set the path to the shortcut target, and add the description.
             psl->lpVtbl->SetPath(psl, lpszPathObj); 
            psl->lpVtbl->SetDescription(psl, lpszDesc);  
           // Query IShellLink for the IPersistFile interface for saving the shortcut in persistent storage. 
           hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf);
           if (SUCCEEDED(hres)) { 
                    WORD wsz[MAX_PATH];              
                    // Ensure that the string is ANSI. 
                    MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, 
                     wsz, MAX_PATH);  
                    // Save the link by calling IPersistFile::Save. 
 
                hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
                    ppf->lpVtbl->Release(ppf);
         }
        psl->lpVtbl->Release(psl);
     }
     return hres;
}
domande:
--- il primo parametro è descritto come: lpszPathObj - address of a buffer
containing the path of the object
ma di che oggetto si sta parlando? forse è la parte di windows che si occupa
di fare i collegamenti? e io dove trovo il suo indirizzo?
--- perchè quando richiama un metodo di IShellLink lo fà in questo modo:
psl->lpVtbl->SetPath()
psl è un punt alla IShellLink, SetPath() è un metodo di IShellLink, ma
lpVtbl cos'è?
--- perchè la IShellLink.QueryInterface ha tre parametri? dall'help ne
dovrebbe avere soltanto due!
anche la IPersistFile.Save() e la IPersistFile.Release() hanno un parametro
in più rispetto a quello che c'è scritto sull'help.
grazie anticipate,
c ya!
/\/\etal Dave.
<<<<< 
DucaCr...@iol.it
 >>>>>>>>
--
Posted from [195.99.97.2]
via Mailgate.ORG Server - 
http://www.mailgate.org

in più rispetto a quello che c'è scritto sull'help.
Infatti (anche le altre se é per questo).  Hai notato che il parametro
in piú é sempre il primo, ed é lo stesso oggetto attraverso il cui
lpVtbl viene fatta la chiamata...?  É quello che il C++ normalmente
passa in modo implicito, e che all'interno del metodo stesso puoi
poi usare con la parola-chiave "this".
Ancora una volta, per usare il COM a livello C bisogna in pratica
"esplicitare" i meccanismi soggiacenti al modello-oggetto del C++,
che in C++ stesso sono impliciti e "nascosti" al programmatore.
Alex

Risposte:
1) lpszPathObj rappresenta il percorso completo dell'oggetto (file,
cartella, ecc.) a cui vuoi che il tuo link faccia riferimento. Ad esempio,
se stai creando un collegamento ad un file che si chiama "Documento.doc" e
che si trova nella cartella "c:\cartella\sottocartella", lpszPathObj sarŕ 
"c:\\cartella\\sottocartella\\Documento.doc".
2) Questo esempio č stato scritto per essere compilato con un compilatore
C, che non gestisce la Virtual Table. Tu, di sicuro, compili in C++, quindi
puoi tranquillamente scrivere psl->SetPath(...).
3) Anche questo ha a che fare con il fatto che l'esempio č stato scritto
per un compilatore C e vale per tutti gli oggetti (se controlli, anche
SetPath č documentata con un solo parametro). Se dai un'occhiata a qualche
file header in cui vengono dichiarati oggetti, noterai che all'inizio
dell'elenco dei 
parametri c'č una macro THIS_ (il simbolo THIS_ č definito in objbase.h
intorno alla linea 200, salvo aggiunte); se compili in C, la macro THIS_
viene definita cosě: '#define THIS_   INTERFACE FAR* This,' cioč un vero e
proprio parametro; se compili in C++ viene invece definita cosě: '#define
THIS_', perciň al momento dell'espansione della macro, il simbolo THIS_
viene sostituito con un bel niente. Se scrivi un programma per un
compilatore C, questo parametro in piů non č altro che un puntatore
all'oggetto 
che stai usando (cioč a se stesso). Infatti la chiamata a SetPath č:
'psl->lpVtbl->SetPath(psl, lpszPathObj);'.
Se scrivi per C++, non devi usare questo primo parametro; quindi, in
definitiva scriverai:
'psl->SetPath(lpszPathObj);'.
Per evitarti la ricerca in objbase.h, ecco la parte di codice che ci
interessa:
  .
  .
#if defined(__cplusplus) && !defined(CINTERFACE)
  .
  .
#define THIS_
  .
  .
#else
  .
  .
#define THIS_                   INTERFACE FAR* This,
  .
  .
Stefano.

che in C++ stesso sono impliciti e "nascosti" al programmatore.
ok, io il COM devo usarlo.... ma devo per forza usarlo a livello C oppure
posso anche stare al livello C++?
cioè: è possibile utilizzare oggetti COM da un programma C++?


cioè: è possibile utilizzare oggetti COM da un programma C++?
Certo, anzi e' molto piu` comodo che da un programma C.  In VC++
5 e successivi, in particolare, l'istruzione #import lo rende facilissimo.
Alex

cioč: č possibile utilizzare oggetti COM da un programma C++?
Certo, anzi, il C++ e' il linguaggio migliore (anche se, usato da solo,
richiede una conoscenza MOLTO buona del COM, che richiede un GROSSO
sforzo).
Davide Marcato.
----------------------------------------------------
| -- Freelance International Consultant
| -- Win32/MFC/COM Development & Training
| -- Technical Writer & Speaker
----------------------------------------------------
| -- Email: 
mar...@programmers.net
| -- Web: 
http://www.DavideMarcato.com
----------------------------------------------------

devi linkare e' invece la .LIB...!).
e infatti mi era parso strano che quel file avesse estensione .dll
comunque adesso sono riuscito a compilare e linkare il tutto, e funziona.
c'è una cosa che mi lascia perplesso: la funzione
IShellLink::SetDescription() fa questo:
"Sets the description for a shell link object. The description can be any
application-defined string. "
ma non ho capito che cosa sia quasta descrizione, andando a cercare nelle
proprietà del link creato dalla mia applicazione non la ho mica trovata
questa stringa!
c ya!
/\/\etal Dave.
<<<< 
DucaCr...@iol.it
 >>>>>
PS (grazie a tutti per i preziosi aiuti che mi state dando!)
