Oppure

Loading
26/02/18 14:17
Carlo
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:

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


oppure:
Using pen As New Pen(Color.Blue), formGraphics As Graphics = Me.CreateGraphics()
        formGraphics.DrawLine(pen,300, 300, 0, 0)
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:

Public Structure POINTAPI
        Friend X As Integer
        Friend Y As Integer
End Structure

 
Public Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByRef lpPoint As POINTAPI) As Integer

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:

Dim grp As Graphics = Me.CreateGraphics
Dim hdc As IntPtr = grp.GetHdc ' trovo l'hdc del form 
Dim point As POINTAPI ' usato su MoveTo, restituisce l'ultima coordinata

MoveToEx(hdc, 0, 0, point) ' sposto le coordinate dove devo iniziare a tracciare la riga
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:
' nel modulo
Public Declare Function SetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal crColor As Integer) As Integer
' nel form
SetPixel(hdc, 100, 100, &HFF00FF) ' scrive un pixel viola


Il pixel viene visualizzato nel colore voluto.
Ultima modifica effettuata da Carlo 26/02/18 14:55
in programmazione tutto è permesso
26/02/18 14:54
Thejuster
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.

pinvoke.net/

Qui trovi tutte le api con esempi da utilizzare in vb.net o C#.
troverai anche pinvoke.net/default.aspx/…

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

public unsafe Image ThresholdUA(float thresh)
{
    Bitmap b = new Bitmap(_image);//note this has several overloads, including a path to an image

    BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

    byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);

    /*This time we convert the IntPtr to a ptr*/
    byte* scan0 = (byte*)bData.Scan0.ToPointer();

    for (int i = 0; i < bData.Height; ++i)
    {
        for (int j = 0; j < bData.Width; ++j)
        {
            byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;

            //data is a pointer to the first byte of the 3-byte color data
        }
    }

    b.UnlockBits(bData);

    return b;
}




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


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


Ultima modifica effettuata da Thejuster 26/02/18 15:06
mire.forumfree.it/ - Mire Engine
C# UI Designer
26/02/18 15:24
Carlo
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 26/02/18 15:56
in programmazione tutto è permesso
26/02/18 15:31
nessuno
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à.
26/02/18 15:48
Carlo
'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 26/02/18 16:12
in programmazione tutto è permesso
26/02/18 16:41
nessuno
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

msdn.microsoft.com/it-it/library/windows/desktop/…(v=vs.85).aspx
Ultima modifica effettuata da nessuno 26/02/18 16: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à.
27/02/18 11:19
Carlo
Ho trovato su:
slideshare.net/DavidRossGoben/…

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:
vdocuments.site/download/…

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