n° 185
Maggio/Giugno 2013
Maggio 21, 2013, 11:03:54 am *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  

* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: Convertire/estrarre dati da una Api?  (Letto 2480 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
SoldatoSemplice
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 21


Mostra profilo
« inserita:: Giugno 03, 2010, 05:38:10 pm »

Ciao a tutti, mi trovo qui per porre alla comunità una domanda a cui non trovo risposta, e sperando in un aiuto.

Stò cominciando a studiare la programmazione con le API di Windows, e la mia domanda non riguarda una API in particolare ma è un pò più generica, vorrei sapere: dato che di solito le API sono una structure che immagazina variabili di formati molto diversi tra di loro, ma l'API stessa viene trattata a sua volta come una variabile lei stessa.

Detto questo la domanda è: esiste una funzione che in qualche modo mi permetta di accedere ad uno solo dei parametri della API dichiarata? Ad esempio usando questa API: WM_DEVICECHANGE, per accedere solo al wParam che è uno dei parametri, come faccio? In questo caso particolare tale parametro non è altro che un numero esadecimale, ma come lo estraggo?

Inoltre, la seconda domanda: come vedete molti dei parametri o variabili usati dalle API sono formati mai visti: HWND, UINT, WPARAM, LPARAM....  come faccio a convertirli in un comune formato interpretabile dal Visual Basic tipo Int o Double? Ho l'impressione che questi ultimi formati siano a loro volta precedentemente definiti da altri API e siano anche questi ultimi delle struct, e quindi la domanda si ripete medesima: Dove scopro quale struct definisce il mio tipo wParam e come faccio a "derubricare" tale struct usando una sola delle sue variabili?

Inoltre se una API restituisce un puntatore ad una struttura, per accedere ai dati di tale struttura devo trattare il puntatore come un comune riferimento e accedo ai miei dati con:

Codice:
dati_desiderati=*puntatore_restituito

Giusto?

Chiedo scusa per il terzo grado e anche se non sono riuscito ad esprimermi correttamente, qualora fosse necessario proverò a chiarire meglio, ma spero vivamente in un aiuto.

Grazie mille

Saluti

Leo
Registrato
VBeXtreme
Sr. Member
****

Karma: +17/-98
Scollegato Scollegato

Messaggi: 662



Mostra profilo
« Risposta #1 inserita:: Giugno 03, 2010, 09:03:18 pm »

Citazione di: SoldatoSemplice
Stò cominciando a studiare la programmazione con le API di Windows, e la mia domanda non riguarda una API in particolare ma è un pò più generica, vorrei sapere: dato che di solito le API sono una structure che immagazina variabili di formati molto diversi tra di loro, ma l'API stessa viene trattata a sua volta come una variabile lei stessa.

Le api sono funzioni del sistema operativo! quindi ad esempio l'api GetPixel sarà una funzione della libreria gdi32.

Citazione di: SoldatoSemplice
Detto questo la domanda è: esiste una funzione che in qualche modo mi permetta di accedere ad uno solo dei parametri della API dichiarata? Ad esempio usando questa API: WM_DEVICECHANGE, per accedere solo al wParam che è uno dei parametri, come faccio? In questo caso particolare tale parametro non è altro che un numero esadecimale, ma come lo estraggo?

Luso della windows procedure in vb6 sarà l'apice dello studio delle api e non l'inizio!Quindi ti consiglio di iniziare da qualcosa di piu semplice

Citazione di: SoldatoSemplice
Inoltre, la seconda domanda: come vedete molti dei parametri o variabili usati dalle API sono formati mai visti: HWND, UINT, WPARAM, LPARAM....  come faccio a convertirli in un comune formato interpretabile dal Visual Basic tipo Int o Double? Ho l'impressione che questi ultimi formati siano a loro volta precedentemente definiti da altri API e siano anche questi ultimi delle struct, e quindi la domanda si ripete medesima: Dove scopro quale struct definisce il mio tipo wParam e come faccio a "derubricare" tale struct usando una sola delle sue variabili?

Dato che sei agli inizi ti conviene usare l'utilissimo ApiTextViewer che è nella cartella:visualstudio6/visualstudio6tool/
Li trovi già tutte le dichiarazioni delle funzioni api,le strutture e le costanti.
HWND e compagnia bella sono tipi definiti in c/c++ per farti comprendere:

LINGUAGGIO C:

typedef int HWND;

in questo modo tutte le variabili dichiarate HWND sono delle variabili int,quindi puoi semplicemente mettere long come tipo di parametro.
La traduzione delle api dal c a vb è una cosa complessa quindi continuo a consigliarti di usare ApiTextViewer!
 
Citazione di: SoldatoSemplice
Inoltre se una API restituisce un puntatore ad una struttura, per accedere ai dati di tale struttura devo trattare il puntatore come un comune riferimento e accedo ai miei dati con:

In vb non si possono usare i puntatori,anche se ho scritto un articolo per usarli nella sezionetips  sarebbe buona norma non usarli!
Le api non restituiscono mai un puntatore ma sempre un codice di successo o meno o un valore long,ma invece gli verrà passato la struttura per riferimento e i dati saranno salvati li:

Codice:

Public Type POINTAPI
        x As Long
        y As Long
End Type

Public Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) As Long

...
...
...

dim cp as POINTAPI

GetCursorPos cp

msgbox "mouse pos x=" & cp.x & " y=" & cp.y 



Per ulteriori chiarimenti sono qui
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
SoldatoSemplice
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 21


Mostra profilo
« Risposta #2 inserita:: Giugno 03, 2010, 10:17:44 pm »

Allora innanzi tutto ti ringrazio per la risposta,  Ghigno vediamo se riesco a risponderti a tutto....

Capito le API sono funzioni.

Sò anche bene che programmare correttamente usando API è un punto di arrivo e non pretendo una conoscenza dettagliata, ma il mio scopo è conoscere le API quel tanto che basta per prendere il controllo della porta USB.

Per raggiungere lo scopo stò studiando questo testo, la parte elettronica, lo sviluppo del descrittore, e del device USB non mi dovrebbe creare problemi, le mie difficoltà cominciano nel momento in cui dovrò evocare le API necessarie a trovare il dispositivo sul sistema e ad aprire un handle per comunicarci, in pratica una parte generosa del mio progetto passa necessariamente attraverso le suddette API.

Consiglio sull'ApiTextViewer accettato, utile, non lo conoscevo, ma considerando che continuo ad usare Visual Basic, trascurando il caso di handle of the window (hwnd) che è un intero, ad esempio il tipo wparam che è nativamente definito in C, come lo potrei usare nel Visual Basic? Esiste una apposita funzione?

Ora mi studio il codice di esempio che mi hai postato ma credo di averlo capito.

Grazie di nuovo e ciao.

Leo
Registrato
VBeXtreme
Sr. Member
****

Karma: +17/-98
Scollegato Scollegato

Messaggi: 662



Mostra profilo
« Risposta #3 inserita:: Giugno 04, 2010, 12:07:43 pm »

Il discorso è lungo e complesso!
Fino a che non impari a usare le api(e oltre) EVITA DI CONVERTIRE LE API DA C A VB! Per poterle convertire devi conoscere il c,il vb e le loro differenze.

! ! ! Tutte le api,costanti,strutture,le trovi dichiarate nell'ApiTextViewer ! ! !

Cerca di partire dal semplice,inizia con imparare:

SetPixel
GetPixel

Questo è un ottimo sito(+programma) per imparare le api

Come primo esperimento è assai difficile intercettare il messaggio Device_Change che viene generato dal sistema operativi quando avviene una modifica hardware!
In vb6 la windows procedure è eseguita dietro le quinte,per potervi accedere bisogna subclassarla e dire a windows di inviare i messaggi di sistema a tale funzione.

Prova a creare un nuovo progetto,aggiungi un modulo1 e metti questo
Codice:
Option Explicit

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Const WM_DEVICECHANGE As Long = &H219
Private Const GWL_WNDPROC = (-4)
Private Const WM_CLOSE = &H10

Private FrmHwnd As Long
Private PreviusProc As Long

Public Sub StartSubClassing(ByVal hwndFrm As Long)
    FrmHwnd = hwndFrm
    PreviusProc = SetWindowLong(hwndFrm, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub StopSubClassing()
    SetWindowLong FrmHwnd, GWL_WNDPROC, PreviusProc
End Sub

Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim er As Long, ck As Long
   
    'processo il messaggio
   
    If uMsg = WM_DEVICECHANGE Then
        Debug.Print "wParam  " & wParam
   
        Select Case wParam
            Case &H8000&
                Debug.Print "New device"
     
            Case &H8004&
                Debug.Print "Removed device"
        End Select
    End If
   
    'passa il comando a windows
    WindowProc = CallWindowProc(PreviusProc, hw, uMsg, wParam, lParam)
End Function


Mentre nel form1 metti questo:

Codice:
Option Explicit

Private Sub Form_Load()
    StartSubClassing Form1.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
    StopSubClassing
End Sub

In questo modo nella finestra Immediate dell'ide di vb6 verrà visualizzato quando viene inserito o disinserito un hardware,e tutti i messaggi Device_Change.


NON BUTTARTI ! ! ! nel scrivere del codice a casaccio ! ! ! ma cerca di imparare cosa sono le api e come si utilizzano ! ! ! se cerchi in rete troverai tantissime cose! ! !
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
lucy
Newbie
*

Karma: +0/-5
Scollegato Scollegato

Messaggi: 2


Mostra profilo E-mail
« Risposta #4 inserita:: Giugno 04, 2010, 12:23:23 pm »

Ciao. Scusatemi se vi chiedo aiuto qui, ma non so usare il pc e non so come trovare qualcuno che possa venirmi incontro. Ho necessità urgente di trovare una password di una gmail. Se esiste una persona tra voi in grado di potermi dare una mano sarò felice di ricompensarla!!
Potete contattarmi alla mia mail solodisperata@gmail.com
GRAZIE FIN D'ORA!!!!!
Registrato
SoldatoSemplice
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 21


Mostra profilo
« Risposta #5 inserita:: Giugno 04, 2010, 01:09:46 pm »

In pratica se ho capito bene il subclassing mi permette di intercettare l'evento WM_DEVICECHANGE e di inviarlo all'handle della finestra per gestirlo, il programma che mi hai dato mi è quasi tutto chiaro, la parte che ancora non riesco a comprendere, è quale sia lo scopo della funzione setwindow long, ora provo a studiarla, ma eventualmente mi aiuteresti ancora? Grazie

Il discorso è lungo e complesso!
Fino a che non impari a usare le api(e oltre) EVITA DI CONVERTIRE LE API DA C A VB! Per poterle convertire devi conoscere il c,il vb e le loro differenze.

! ! ! Tutte le api,costanti,strutture,le trovi dichiarate nell'ApiTextViewer ! ! !

Cerca di partire dal semplice,inizia con imparare:

SetPixel
GetPixel

Questo è un ottimo sito(+programma) per imparare le api

Come primo esperimento è assai difficile intercettare il messaggio Device_Change che viene generato dal sistema operativi quando avviene una modifica hardware!
In vb6 la windows procedure è eseguita dietro le quinte,per potervi accedere bisogna subclassarla e dire a windows di inviare i messaggi di sistema a tale funzione.

Prova a creare un nuovo progetto,aggiungi un modulo1 e metti questo
Codice:
Option Explicit

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Const WM_DEVICECHANGE As Long = &H219
Private Const GWL_WNDPROC = (-4)
Private Const WM_CLOSE = &H10

Private FrmHwnd As Long
Private PreviusProc As Long

Public Sub StartSubClassing(ByVal hwndFrm As Long)
    FrmHwnd = hwndFrm
    PreviusProc = SetWindowLong(hwndFrm, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub StopSubClassing()
    SetWindowLong FrmHwnd, GWL_WNDPROC, PreviusProc
End Sub

Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim er As Long, ck As Long
   
    'processo il messaggio
   
    If uMsg = WM_DEVICECHANGE Then
        Debug.Print "wParam  " & wParam
   
        Select Case wParam
            Case &H8000&
                Debug.Print "New device"
     
            Case &H8004&
                Debug.Print "Removed device"
        End Select
    End If
   
    'passa il comando a windows
    WindowProc = CallWindowProc(PreviusProc, hw, uMsg, wParam, lParam)
End Function


Mentre nel form1 metti questo:

Codice:
Option Explicit

Private Sub Form_Load()
    StartSubClassing Form1.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
    StopSubClassing
End Sub

In questo modo nella finestra Immediate dell'ide di vb6 verrà visualizzato quando viene inserito o disinserito un hardware,e tutti i messaggi Device_Change.


NON BUTTARTI ! ! ! nel scrivere del codice a casaccio ! ! ! ma cerca di imparare cosa sono le api e come si utilizzano ! ! ! se cerchi in rete troverai tantissime cose! ! !
Registrato
VBeXtreme
Sr. Member
****

Karma: +17/-98
Scollegato Scollegato

Messaggi: 662



Mostra profilo
« Risposta #6 inserita:: Giugno 04, 2010, 03:49:35 pm »

Come ti ho già ripetuto NON BUTTARTI A PROVARE COSE A CASACCIO ma fatti una ricerca in internet!

Citazione di: SoldatoSemplice
In pratica se ho capito bene il subclassing mi permette di intercettare l'evento WM_DEVICECHANGE e di inviarlo all'handle della finestra per gestirlo, il programma che mi hai dato mi è quasi tutto chiaro, la parte che ancora non riesco a comprendere, è quale sia lo scopo della funzione setwindow long, ora provo a studiarla, ma eventualmente mi aiuteresti ancora? Grazie

IN PRATICA NON HAI CAPITO NIENTE!

Ti mostro cosa avviene dietro alle quinte quando crei un programma:

PseudoCodice:

Function WinMain()
    CreateForm()
    CreateWindowsProcedure()
    Do
        GetMessage()
        TranslateMessage()
        DispacthMessage()
    loop
End Function

Function WindowsProcedure()
    If Hwnd=FrmHwnd   
         If uMsg=WM_Click then
             Form1_ClicK
         elseif ....
         ....
         end if
    else if....
    ....
end function

Ecco quando crei un form1 dietro a tale form hai una sottospecie di quel codice,Quando ad esempio intercetti l'evonto Form_Load() Quell'evento viene richiamato di nascosto dalla windows procedure che ha creato segretamente vb6!
Ora se noi vogliamo estrarre tale windows procedure per fare in modo di interaggire con essa dobbiamo subclassarla e quindi con SetWindowsLong diciamo a windows di inviare il messaggio alla nuova windowsprocedure e però dobbiamo ricordarci di reimpostare la vecchia prima di uscire.


Quindi dal momento che usiamo noi la windowsprocedure dobbiamo intercettare i messaggi e trattarli a dovere,con l'istruzione:

WindowProc = CallWindowProc(PreviusProc, hw, uMsg, wParam, lParam)

Non facciamo altro che reinviare i messaggi alla vecchia windowsprocedure in modo che vengano processati.
Se noi leviamo tale riga vedrai che la form non risponde piu ai comandi!
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
SoldatoSemplice
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 21


Mostra profilo
« Risposta #7 inserita:: Giugno 04, 2010, 04:41:53 pm »

Non ho assolutamente provato cose a casaccio, infatti non ho ancora steso nemmeno una riga di codice, ne su Viual Basic ne tantomeno sul dispositivo USB, sono ancora nella fase di studio.

Ho fatto una ricerca ed ho trovato  questo documento.

Anche se la spiegazione è un pò astrusa il principio di funzionamento da come l'ho capito io è questo:

Parto dal presupposto di avere un programma in VB che sta funzionando regolarmente, e ad un certo punto io voglio verificare se si verifica l'evento device_change, allora quello che faccio è di dichiarare la funzione SetWindowLong, a quest'ultima funzione passo l'handle di una seconda e nuova windows procedure che avrà il compito di intercettarmi il messaggio WM_DEVICECHANGE, a SetWindowsLong dico che questa seconda nuova windows procedure ha il compito di estrarre informazioni da un processo di background di Windows e lo fa leggendo il flag GWL_WNDPROC.

Questa seconda windows procedure restituisce il messaggio "dispositivo inserito" oppure "dispositivo rimosso" ed infine restituisco il controllo al programma di VB con la CallWindowsProc, con la quale passo anche allo stesso programma di VB l'uMsg che gli dice se si è verificato il devicechange.

In questo modo posso proseguire nel mio programma VB avendo l'informazione DEVICE_CHANGE.

Magari è un pò contorto, ma il concetto è corretto?

Grazie.

Registrato
VBeXtreme
Sr. Member
****

Karma: +17/-98
Scollegato Scollegato

Messaggi: 662



Mostra profilo
« Risposta #8 inserita:: Giugno 04, 2010, 05:13:44 pm »

Il sito va benino,non hai capito una cosuccia:

con SetwindowsLong dici quale funzione deve svolgere da windowsprocedure e quindi andrà richiamata prima e dopo l'uso

Pseudocode

Avvio subclassing:
VecchiaWindowsProc=Setwindowlong(...)

TerminoSubclassing:
setWindowlong(vecchiawindowsproc)

la callwindowsproc non fa altro che passare il messaggio alla funzione standard della windows procedure,potresti evitarla di mettere,ma dovresti gestire manualmente tutti i messaggi,dato che per gestire tutti i messaggi vb6 crea una funzione nascosta noi gli passiamo il messaggio.

PseudoCode

Funzione Nascosta StandardWindowsProc(...)
   if umsg...
   ...
   ...
end function


Funzione MiaWindowsProc(...)
    If umsg ...
        ...
    else
        StandardWindowsProc(...)
    end if
end function

Bisogna usare quindi la callwindowsproc perchè tale funzione è nascosta!
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
SimoneVB
Sr. Member
****

Karma: +3/-0
Scollegato Scollegato

Messaggi: 775


simonevb@live.it
Mostra profilo
« Risposta #9 inserita:: Agosto 12, 2010, 03:45:57 am »

Alla faccia!!!
Eh bravo Tato: vedo che ci dai alla grande col subclassing!
... e traspare un bel po' di professionalità dalle tue parole.
Well Done!

P.S: Se ti va rispondi alla discussione "Progetto Comune, Adesioni". Ricordi? Koala!
Registrato

--------------------------------------------------
Incredibilmente esistono ancora persone che
proteggono i propri PC con password=pippo.
VBeXtreme
Sr. Member
****

Karma: +17/-98
Scollegato Scollegato

Messaggi: 662



Mostra profilo
« Risposta #10 inserita:: Agosto 12, 2010, 08:48:20 am »

mica solo col subclassing  Ghigno

Mi sono buttato sul c/c++/c# ,dato che il vb.net mi ha fatto abbandonare tale linguaggio.
Si che ricrdo koala,ma dovresti farti vedere un pò piu spesso sul forum,magari creiamo qualcosa.
So che sei impagnato già tanto impagnato come un pò tutti d'altronde,ma il forum è un pò morto c'è bisogno di utenti vivi,e di proposte!
Io un'ora qua e la riesco a recuperarla per iniziare un nuovo progetto cosa ne dici?niente di troppo serio,un progettino Open Source che possa tornarci utile nella vita di tutti noi programmatori.
Unico scopo divertirci!
Se accetti forse un'ora potrebbe dedicarcela anche hyde,amd è scomparso nel nulla!
Ma la riapertura dell'ioteam riaccenderebbe buona parte del forum.
Da solo no...no....
Registrato

Ragionare non è nient’altro che calcolare
"Thomas Hobbes"
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2011 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



Links to Page