Newsgroup: it.comp.lang.visual-basic
Titolo: implementare il drag/drop sull'icona

Ciao a tutti.
Vorrei implementare una funzione che, trascinando un file sull'icona del mio
programma, mi apra il programma con il contenuto di quel file.
Per intendersi, tipo quando io trascino un file di testo sull'icona del
Notepad, e apre il Notepad con quel file caricato, o quando trascino l'icona
di una bitmap sull'icona di AcdSee, e mi si apre AcdSee visualizzando quella
bitmap.
Qualsiasi suggerimento sarà gradito. Grazie e a presto.
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 Qualsiasi suggerimento sarà gradito. Grazie e a presto.
Lo fa già windows da solo di avviare il tuo programma e passargli il nome di 
quel che hai trascinato sopra al collegamento al tuo programma o all'exe 
stesso.
A te non resta altro che leggere la variabile Command$ (vedi help) per 
scoprire cosa è stato trascinato sopra l'icona!
Ciao,
    Diego 

 scoprire cosa č stato trascinato sopra l'icona!
Fatto. Funziona perfettamente. Grazie mille.
Ora perň mi sono alluzzato, e vorrei saperne di piů. Ad esempio: e se
volessi passare piů argomenti della linea di comando, che so due o tre flags
diversi (tipo "Dir C:\Windows /w /p /on")? Cosa contiene in questo caso la
variabile Command$?
Grazie ancora.


 variabile Command$?
quel dollaro dà l'idea che continui a restituire una stringa, da scandire
per vederne il contenuto. f1:
Funzione Command
Restituisce la parte degli argomenti della riga di comando utilizzata per
avviare Microsoft Visual Basic o un programma eseguibile sviluppato con
Visual Basic.
Sintassi
Command
Osservazioni
Quando Visual Basic viene avviato dalla riga di comando, qualsiasi parte
della riga di comandi successiva a /cmd viene passata al programma come
argomento della riga di comandi. Nell'esempio seguente,
argomentirigadicomando rappresenta gli argomenti restituiti dalla funzione
Command.
VB /cmd argomentirigadicomando
Per le applicazioni sviluppate con Visual Basic e compilate in un file exe,
Command restituisce tutti gli argomenti visualizzati dopo il nome
dell'applicazione nella riga di comando. Ad esempio:
MyApp argomentirigadicomando
Per informazioni su come modificare gli argomenti della riga di comando
utilizzando l'interfaccia utente dell'applicazione, cercare la voce
"argomenti della riga di comando" nella Guida in linea.

 variabile Command$?
Beh.. prova e vedrai subito, no?
..trovo che si impara molto con questa tecnica..
Ciao,
    Diego 

 ha
scritto:

si, l'ho letto, ma trovo che sia più interessante il codice d'esempio, che
risponde anche alla domanda sugli argomenti multipli. Volevo solo una
conferma che gli argomenti vanno trattati come nel caso del Dir(), cioè
separati da spazi e sottoposti a Split in lettura.
Il problema è stato un altro: il nome del file restituito - quello
trascinato sull'icona - era in 8+3, mentre a me serviva il nome lungo,
perchè ho diversi file con nomi simili (e poi è bruttissimo da mostrare
all'utente), e non sapevo se dipendeva da un'impostazione di Command.
Dopo ripetute prove ho realizzato che non dipende dalla funzione Command, ma
da Windows (98) stesso. Ho risolto con la API FindFirstFile: cerco il file
restituito da Command, e dopo vado a leggere il nome del file trovato, ma mi
chiedevo se c'era un sistema migliore.
Esiste un modo per convertire direttamente un path 8+3 in un path lungo?


 Esiste un modo per convertire direttamente un path 8+3 in un path lungo?
ne dubito, dall'acquario fai il brodetto, ma difficilmente il reciproco. in
quel caso poi, in 10 anni non ho mai capito se c'e' una regola fissa di
conversione da lungo a corto. sul gruppo vb ms, si discuteva con una persona
che ha portato esempi di nomi corti che credevo impossibili.
ciao, a.

 ne dubito, dall'acquario fai il brodetto, ma difficilmente il reciproco. in
C'è qualche controindicazione alle api GetShortPathName e GetLongPathName ?

> C'è qualche controindicazione alle api GetShortPathName e GetLongPathName
?
mi erano sfuggite, oggi le provo.


 C'è qualche controindicazione alle api GetShortPathName e GetLongPathName
?
bella domanda :)
nell'altro caso, la persona doveva filtrare su un certo carattere, e non
c'era saltato fuori.
ciao, a.

 mi erano sfuggite, oggi le provo.
...ehm, ma la GetLongPathName dove si trova?


 ...ehm, ma la GetLongPathName dove si trova?
*GetShortPathName*
DA MSDN:
DWORD GetShortPathName(
  LPCTSTR lpszLongPath,  // null-terminated path string
  LPTSTR lpszShortPath,  // short form buffer
  DWORD cchBuffer        // size of short form buffer
);
Requirements
  Windows NT/2000/XP: Included in Windows NT 3.5 and later.
  Windows 95/98/Me: Included in Windows 95 and later.
  Library: Use Kernel32.lib.
Quindi:
Declare Function GetShortPathName Lib "kernel32" Alias _
   "GetShortPathNameA" (ByVal lpszLongPath As String, _
   ByVal lpszShortPath As String, ByVal cchBuffer As Long) _
   As Long
E c'è per ogni versione di Windows a 32 bit
*GetLongPathName*
DA MSDN:
DWORD GetLongPathName(
  LPCTSTR lpszShortPath, // file name
  LPTSTR lpszLongPath,   // path buffer
  DWORD cchBuffer        // size of path buffer
);
Requirements
  Windows NT/2000/XP: Included in Windows 2000 and later.
  Windows 95/98/Me: Included in Windows 98 and later.
  Library: Use Kernel32.lib.
Quindi:
Declare Function GetLongPathName Lib "kernel32" Alias _
   "GetLongPathNameA" (ByVal lpszShortPath As String, _
   ByVal lpszLongPath As String, ByVal cchBuffer As Long) _
   As Long
E c'è solo per Windows2000 e successivi (quindi anche XP e 2003) e
Windows98 e successivi (quindi anche ME)

 Windows98 e successivi (quindi anche ME)
(io uso VB6 e Win98se. Perchč non c'č nel Visualizzatore API, e AllAPI.net
non ne fa menzione?)
Hai anche un esempio di codice che la usa? Io la provo subito, comunque.


 Hai anche un esempio di codice che la usa? Io la provo subito, comunque.
Fatto. Funziona. Ecco il codice finale:
Option Explicit
Private Declare Function GetLongPathName Lib "kernel32" Alias
"GetLongPathNameA" _
    (ByVal lpszShortPath As String, ByVal lpszLongPath As String, _
    ByVal cchBuffer As Long) As Long
Private Sub Form_Load()
    Dim shortname As String, longname As String, ret As Long
    shortname = Command$() ' becca il file che è stato trascinato sull'icona
    If Not shortname = vbNullString Then
        longname = Space(255)
        ret = GetLongPathName(shortname, longname, 255)
        longname = Trim$(longname)
        txtPath.Text = longname
    End If
End Sub
Grazie mille.


         ret = GetLongPathName(shortname, longname, 255)
Occhio che di solito i nomi dei file sono lunghi al massimo MAX_PATH
caratteri, e tale costante vale 260 e non 255. Lo so che è una
puntigliosità, ma spesso sono arrivato al limite di tale dimensione (e
anche superato... se qualcuno ha usato gnu-arch sa di cosa parlo...)
Si può inoltre usare una funzionalità carina delle due funzioni
GetShortPathName e GetLongPathName: ti ritorna il numero di caratteri
necessari per il buffer destinato a contenere il nome del file/cartella
in uscita. Ergo ecco qui già bell'e pronte due belle funzioncine:
Private Declare Function GetShortPathName Lib "kernel32" Alias _
   "GetShortPathNameA" (ByVal lpszLongPath As String, _
   ByVal lpszShortPath As String, ByVal cchBuffer As Long) _
   As Long
Private Declare Function GetLongPathName Lib "kernel32" Alias _
   "GetLongPathNameA" (ByVal lpszShortPath As String, _
   ByVal lpszLongPath As String, ByVal cchBuffer As Long) _
   As Long
Function ToShort(ByVal Lungo As String) As String
   Dim s As String, n As Long
   ToShort = ""
   n = GetShortPathName(Lungo, vbNullString, 0&)
   If n > 0& Then
      s = String$(n + 1&, vbNullChar)
      GetShortPathName Lungo, s, n + 1&
      n = InStr(1, s, vbNullChar)
      Select Case n
         Case 0&
            ToShort = s
         Case Is > 1&
            ToShort = Left$(s, n - 1&)
      End Select
   End If
End Function
Function ToLong(ByVal Corto As String) As String
   Dim s As String, n As Long
   ToLong = ""
   n = GetLongPathName(Corto, vbNullString, 0&)
   If n > 0& Then
      s = String$(n + 1&, vbNullChar)
      GetLongPathName Corto, s, n + 1&
      n = InStr(1, s, vbNullChar)
      Select Case n
         Case 0&
            ToLong = s
         Case Is > 1&
            ToLong = Left$(s, n - 1&)
      End Select
   End If
End Function
Sub Test()
   Dim LungoOriginale As String
   Dim Corto As String
   Dim LungoFinale As String
   LungoOriginale = "C:\Programmi\Microsoft Visual Studio"
   Corto = ToShort(LungoOriginale)
   'NOTA: a questo punto per me Corto vale "C:\PROGRA~1\MICROS~2"
   LungoFinale = ToLong(Corto)
End Sub

 End Sub
Ottimo, me lo grabbo.
