Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Api in VB.net?
Forum - C# / VB.NET - Api in VB.net?

Avatar
Carlo (Member)
Expert


Messaggi: 445
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 15:17
Lunedì, 26/02/2018
Programmo da un po' in VB.net, e con i controlli standard non ho problemi, però sono anche curioso di esplorare altre possibilità.

Per esempio tracciare una linea sul form è semplice:

Codice sorgente - presumibilmente VB.NET

  1. Dim G As Graphics = Me.CreateGraphics
  2. Dim pen As New Pen(Color.Black)
  3. G.DrawLine(pen, 0, 0, 300, 300)



oppure:
Codice sorgente - presumibilmente C#

  1. Using pen As New Pen(Color.Blue), formGraphics As Graphics = Me.CreateGraphics()
  2.         formGraphics.DrawLine(pen,300, 300, 0, 0)
  3. End Using


e non solo....

Con le API come si farebbe?

Sono riuscito ad usare l'API gdi32, ma non riesco a gestire il colore

In un modulo ho dichiarato l'API usando gli Integer, per la compatibilità con VB.net:

Codice sorgente - presumibilmente VB.NET

  1. Public Structure POINTAPI
  2.         Friend X As Integer
  3.         Friend Y As Integer
  4. End Structure
  5.  
  6.  
  7. Public Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByRef lpPoint As POINTAPI) As Integer
  8.  
  9. Public Declare Function LineTo Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer) As Integer



e nel form ho scritto:

Codice sorgente - presumibilmente VB.NET

  1. Dim grp As Graphics = Me.CreateGraphics
  2. Dim hdc As IntPtr = grp.GetHdc ' trovo l'hdc del form
  3. Dim point As POINTAPI ' usato su MoveTo, restituisce l'ultima coordinata
  4.  
  5. MoveToEx(hdc, 0, 0, point) ' sposto le coordinate dove devo iniziare a tracciare la riga
  6. LineTo(hdc, 300, 300) ' disegno la riga da MoveToEx a LineTo


La riga tracciata è sempre e solo nera anche se imposto un colore nella proprietà ForeColor del form

Ho anche provato l'API:
Codice sorgente - presumibilmente VB.NET

  1. ' nel modulo
  2. Public Declare Function SetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal crColor As Integer) As Integer
  3. ' nel form
  4. SetPixel(hdc, 100, 100, &HFF00FF) ' scrive un pixel viola



Il pixel viene visualizzato nel colore voluto.

Ultima modifica effettuata da Carlo il 26/02/2018 alle 15:55


In programmazione tutto è permesso
PM Quote
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1894
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 15:54
Lunedì, 26/02/2018
Ciao Carlo, quello che ti consiglio e di usare le api per altre cose.

Non è un rimprovero o un invito a non usarle sia chiaro, puoi anche utilizzare le api per la grafica.
Ma ne vale la pena quando il .net gestisce già tutto il modo ordinato?

Sicuramente questo sito fà al tuo caso.

http://www.pinvoke.net/

Qui trovi tutte le api con esempi da utilizzare in vb.net o C#.
troverai anche http://www.pinvoke.net/default.aspx/gdi32.LineTo

L'unico problema che avrai ad usare le winapi, è quello di dover cmq rimanere legato a windows.
mentre le gdi del .net sono compatibili con le gdi+ del mono è quindi cross-platform.

Anche perché le le gdi del net sono molto ampie e si possono fare veramente tantissime cose.
Sfruttando la potenzialità del Lockbit triplicando la velocità di renderizzazione di un'immagine.
o ad esempio il doppio buffer.

Altre esempio ancora l'unsafe + lockbit in unmanaged mode.

come un esempio trovato sulla rete

Esempio C# con codice non gestito e puntatori
Codice sorgente - presumibilmente VB.NET

  1. public unsafe Image ThresholdUA(float thresh)
  2. {
  3.     Bitmap b = new Bitmap(_image);//note this has several overloads, including a path to an image
  4.  
  5.     BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);
  6.  
  7.     byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);
  8.  
  9.     /*This time we convert the IntPtr to a ptr*/
  10.     byte* scan0 = (byte*)bData.Scan0.ToPointer();
  11.  
  12.     for (int i = 0; i < bData.Height; ++i)
  13.     {
  14.         for (int j = 0; j < bData.Width; ++j)
  15.         {
  16.             byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
  17.  
  18.             //data is a pointer to the first byte of the 3-byte color data
  19.         }
  20.     }
  21.  
  22.     b.UnlockBits(bData);
  23.  
  24.     return b;
  25. }




Algorithm    Total Time (ms)    % Difference N=10
unsafe    194    0
IntPtr    262    35%
GetPixel    238,299 (~4 min.)    122,734%    ( GDI )

quindi a te la scelta :k:

Tornando un'attimo al tuo topic, non vedo da nessuna parte che al metodo LineTo
precedentemente hai impostato un colore.
Di default è nero. ma non puoi basarti sul ForeColor del form.
Il ForeColor del form è relativo al colore di una label che gli andrà collocata sopra.

Se non sbaglio dovresti impostare prima il colore della penna

Codice sorgente - presumibilmente VB.NET

  1. <DllImport("gdi32.dll")> _
  2. Private Shared Function CreatePen(fnPenStyle As PenStyle, nWidth As Integer, crColor As UInteger) As IntPtr
  3. End Function



Ultima modifica effettuata da Thejuster il 26/02/2018 alle 16:06


PM Quote
Avatar
Carlo (Member)
Expert


Messaggi: 445
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 16:24
Lunedì, 26/02/2018
Non devo fare niente, sto solo studiando.

Il codice che mi hai consigliato di vedere, mi ha fatto capire che devo comunicare all'hdc in uso quale "penna" usare.
Purtroppo per me non sono ancora in grado di convertire il C nella giusta sintassi del VB.net, mi puoi aiutare?

Il codice in C# che hai postato è molto interessante, l'ho messo da parte per un futuro approfondimento.

grazie.

Ultima modifica effettuata da Carlo il 26/02/2018 alle 16:56


In programmazione tutto è permesso
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5714
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 16:31
Lunedì, 26/02/2018
Testo quotato

Postato originariamente da Carlo:

l'API gdi32



gdi32 è una dll non una api

Anch'io sono poco propenso ad usare Api con vb.net.
Vb6 era un'altra storia perché molto limitato e tanto si risolveva con le Api.
Vb.net e c# non ne hanno bisogno se non in casi particolari.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
Carlo (Member)
Expert


Messaggi: 445
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 16:48
Lunedì, 26/02/2018
'Se non sbaglio dovresti impostare prima il colore della penna'

Si ho settato il colore della penna con:

Dim pen As New Pen(Color.Blue)

ed ora anche con la tua funzione, ma siccome non sortiva nessun effetto non l'havevo inserita nel codice.

Il problema è che la penna che deve essere usata da gdi32 deve appartenere allo stesso hdc, come credo di aver capito dal codice C nelle righe da me boldate:

{

    IntPtr pTarget = maskg.GetHdc();
    IntPtr pDC = CreateCompatibleDC(pTarget);
    IntPtr pOrig = SelectObject(pDC, hbitmap);

    Color penColor = Color.Blue;
    int penWidth = 20;

    IntPtr pen = CreatePen(PenStyle.PS_SOLID | PenStyle.PS_GEOMETRIC | PenStyle.PS_ENDCAP_ROUND, penWidth, (uint)ColorTranslator.ToWin32(penColor));

    // select the pen into the device context
    IntPtr oldpen = SelectObject(pDC, pen);

    MoveToEx(pDC, start.X, start.Y, IntPtr.Zero);
    LineTo(pDC, end.X, end.Y);

    // select the old pen back
    DeleteObject(SelectObject(pDC, oldpen));
    SelectObject(pDC, pOrig);
    maskg.ReleaseHdc();

}

Ultima modifica effettuata da Carlo il 26/02/2018 alle 17:12


In programmazione tutto è permesso
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5714
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 17:41
Lunedì, 26/02/2018
Ogni oggetto GDI che vuoi usare deve essere impostato nell'hdc che stai renderizzando, altrimenti usa quello attuale.

Questo fatto è indipendente da vb.net, vb6 o altro linguaggio ma è il funzionamento standard di tutte le API GDI.

Documentazione di base da studiare

https://msdn.microsoft.com/it-it/library/windows/desktop/dd ...

Ultima modifica effettuata da nessuno il 26/02/2018 alle 17:46


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
Carlo (Member)
Expert


Messaggi: 445
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 12:19
Martedì, 27/02/2018
Ho trovato su:
https://www.slideshare.net/DavidRossGoben/restoring-raster- ...

David Ross ha scritto un' intera Classe in VB.net per gestire completamente la GDI32.
Fa quello che cercavo io e molto di più.
Certo per un uso "normale" di VB.net è inutile, ma per studiare e per chi è curioso è una lettura interessante.

Ho anche messo in pratica la Classe di David Ross e funziona egregiamente.
il PDF si scarica su:
https://vdocuments.site/download/restoring-raster-graphics- ...

Ci risentiremo quando cercherò di usare l'unsafe + lockbit in unmanaged mode.


In programmazione tutto è permesso
PM Quote