Oppure

Loading
21/04/11 17:54
Dyango
ciao ragazzi mentre riguardavo vecchi progetti in vb6 ho trovato una funzione con le stesse funzionalità del DoeEvents ma piu veloce, cosi per provare se davvero funzionasse ho tradotto il codice in vb.net:
Private Structure POINTAPI
        Dim x As Integer
        Dim y As Integer
    End Structure

    Private Structure MSG
        Dim hwnd As Integer         ' hwnd  della finestra di destinazione del messaggio
        Dim message As Integer   'numero che identifica il tipo di messaggio
        Dim wParam As Integer     'parametro del messaggio (tipo e valore cambiano in funzione del tipo di messaggio inviato)
        Dim lParam As Integer      'altro parametro del messaggio che varia sempre in funzione del messaggio
        Dim time As Integer          'l'ora in cui è stato inviato il messaggio
        Dim pt As POINTAPI      'posizione del cursore al momento dell'invio del messaggio
    End Structure
    Private Declare Function TranslateMessage Lib "user32" (ByRef lpMsg As MSG) As Integer
    '============================================
    'La funzione DispatchMessage richiama la corretta procedura che deve elaborare il messaggio in base al valore del campo hwnd della struttura MSG
    'N.B.: l'omissione di questa funzione porterebbe alla mancata elaborazione dei messaggi e, quindi, al probabile blocco del sistema.
    Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (ByRef lpMsg As MSG) As Integer
    '============================================
    Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (ByRef lpMsg As MSG, ByVal hwnd As Integer, ByVal wMsgFilterMin As Integer, ByVal wMsgFilterMax As Integer, ByVal wRemoveMsg As Integer) As Integer
    Private Const PM_REMOVE As Integer = &H1 'indica alla funzione PeekMessage di rimuovere il messaggio in coda

    Private Const lMaxCounter As Integer = 100000
    '===================================================================================================
    Public Sub MyDoEvents() 'funzione alternativa alla funzione di VB "DoEvents"
        Dim CurrMsg As MSG

        'Questo loop recupera (e cancella) tutti i messaggi dalla coda e li invia alla finestra di destinazione

        Do While PeekMessage(CurrMsg, 0, 0, 0, PM_REMOVE) <> 0
            TranslateMessage(CurrMsg)
            DispatchMessage(CurrMsg)
        Loop

    End Sub

quando vado per provarlo mi esce il seguente errore alla riga: TranslateMessage(CurrMsg)
errore: System.AccessViolationException
Message= Tentativo di lettura o scrittura della memoria protetta. Spesso questa condizione indica che altre parti della memoria sono danneggiate.

P.S: Codice corretto e funzionante
Ultima modifica effettuata da Dyango 22/04/11 11:56
aaa
21/04/11 18:43
HeDo
quando uno non sa nulla di nulla succede questo...
aaa
21/04/11 19:04
Dyango
Postato originariamente da HeDo:

quando uno non sa nulla di nulla succede questo...

sono qui apposta per imparare:k: se hai voglia mi diresti il problema di questo codice?
aaa
21/04/11 19:32
ampeg
le variabili Long del VB corrispondono ad Integer nel VB.NET

quindi tutte la variabili tipo Long in .Net devono essere Integer per usarle con le API

l'errore è dovuto al fatto che essendo sballato lo spazio destinato alle variabili, il programma cerca di scrivere in zone di memoria già allocate
aaa
21/04/11 19:51
Dyango
Postato originariamente da ampeg:

le variabili Long del VB corrispondono ad Integer nel VB.NET

quindi tutte la variabili tipo Long in .Net devono essere Integer per usarle con le API

l'errore è dovuto al fatto che essendo sballato lo spazio destinato alle variabili, il programma cerca di scrivere in zone di memoria già allocate

gia che stupido mi sono dimenticato di questo piccolo particolare ammetto le mie colpe... merito di essere fustigato:hail:
grazie per aver corretto la mia svista ampeg:k:

p.s: corretto con gli integer però ora non entra piu nel ciclo do while della sub MyDoEvents come mai?
Ultima modifica effettuata da Dyango 21/04/11 20:10
aaa
22/04/11 6:28
ampeg
non avevo provato il codice, e ci sono delle piccole modifiche da fare

1. la costante PM_REMOVE meglio dichiararla come Integer
Private Const PM_REMOVE AS Integer = &H1

2. tutti i riferimenti alla struttura MSG passata nelle dichiarazioni API vanno passate per riferimento e non per valore poiché devono ricevere i valori dalle API
... (ByRef lpMsg As MSG....

così dovrebbe funzionare


edit
comunque ho fatto una prova al volo e non mi sembra ci sia molta differenza con Application.DoEvents del .NET
Ultima modifica effettuata da ampeg 22/04/11 6:33
aaa
22/04/11 11:54
Dyango
Postato originariamente da HeDo:

Postato originariamente da ampeg:
comunque ho fatto una prova al volo e non mi sembra ci sia molta differenza con Application.DoEvents del .NET


ma perchè glie lo dici? è divertente reimplementare la ruota!

cosi da avere un riscontro in più oltre al mio, comunque ecco i miei risultati:

- PROVA 1 - Semplice ciclo for da 1 a 1.000.000
doevents: 00:00:02.1192798
mydoevents: 00:00:00.3614555

- PROVA 2 - Semplice ciclo for da 1 a 15.000.000
doevents: 00:00:27.7811519
mydoevents: 00:00:03.7047812

- PROVA 3 - ciclo for da 1 a 150.000 + visualizzazione dell indice in una textbox
doevents: 00:01:59.1523503
mydoevents: 00:01:50.4645110

- PROVA 4 - ciclo for da 1 a 300.000 + visualizzazione dell indice in una textbox
doevents: 00:04:47.4224763
mydoevents: 00:03:47.7001901

da queste prove si evince che qualche vantaggio in termini di tempo lo da (in certi casi anche molto evidenti) bisognerebbe provare con qualche algoritmo più complicato e vedere gli effetti
aaa
22/04/11 14:21
HeDo
Postato originariamente da Dyango:

bla bla bla



tutto questo è inutile, NON HA SENSO TESTARE LE PERFORMANCES DEL DOEVENTS

in quanto è un escamotage di un linguaggio single thread come vb6 per mantenere la gui operativa...

in .NET esistono costrutti molto più intelligienti e CORRETTI dal punto di vista concettuale per fare questa cosa
aaa