Problèmes avec les API graphiques de windows

Résolu
Signaler
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018
-
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018
-
Bonjour !
J'ai trouvé des morceaux de code sur différents sites touchant au API graphique présents dans windows, mais je ne sais pourquoi je n'arrive pas a en faire marcher un seul ..

Que se soit SetPixel ou bitblt par exemple, j'obtient a chaque fois la meme erreur.
Voici les déclarations des deux API :

Declare Function BitBlt Lib "gdi32" Alias "BitBlt" ( _
                 ByVal hDestDC As Long, _
                 ByVal x As Long, _
                 ByVal y As Long, _
                 ByVal nWidth As Long, _
                 ByVal nHeight As Long, _
                 ByVal hSrcDC As Long, _
                 ByVal xSrc As Long, _
                 ByVal ySrc As Long, _
                 ByVal dwRop As Long)As Long

Declare Function SetPixel Lib "gdi32" (byval hDC as long, ByVal X as long, ByVal Y as long, ByVal color as long) As Long.

Travaillant sur VB 2005, voici des exemples de code que j'ai testé, sans succès :

setpixel(form1.handle, 50,50, color)  (color étant défini par la fonction RGB auparavant dans mon programme), le but étant ici de faire aparaitre un pixel de la couleur voulue au point de coordonnées 50/50 sur ma form.

bitblt(form1.handle, 50,50,picSource.width, picSource.height, picSource.handle, 0,0, SRCCOPY)
SRCCOPY étant une constante de l'API = &HCC0020 , le but ici étant de copier l'image d'une picturebox vers une autre simplement.

Cependant, dans chacun des cas, une erreur survient :

PInvokeStackImbalance a été détecté
Message: Un appel à la fonction PInvoke 'WindowsApplication1!WindowsApplication1.Form1::SetPixel' a déséquilibré la pile. Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature cible non managée. Vérifiez que la convention d'appel et les paramètres de la signature PInvoke correspondent à la signature non managée cible.

Quelqu'un maniant bien ces APIs en VB 2005 pourrait-il me dépanner? car je ne trouve vraiment rien sur MSDN qui me sorte de ce mauvais pas :s

8 réponses

Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

Je pense avoir trouvé :

une API de windows est la suivante :

Private Declare Function GetDC Lib "user32" ( _
ByVal hwnd As Integer) As Integer

Ainsi, pour SetPixel, en faisant :
SetPixel(GetDC(Me.Handle), x, y, color)

au lieu de :
SetPixel(Me.Handle, x, y, color)

Nous obtenons enfin un résultat concluant ! A vérifier maintenant si c'est aussi le cas pour BitBlt, mais cela ne devrait poser aucun problème, GetDC fournissant le hDC inexistant en .NET :)
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

Je viens cependant de m'apercevoir d'une chose : GetDc étant assez long d'exécution il est préférable de mettre le hDC du controle voulu dans une variable puis d'utiliser celle-ci, comme suit :

Dim hdc As Int32 = GetDC(Me.Handle)

puis

SetPixel(hdc, x, y, color)

En effet, en 1 seconde, le code du message précédent ne trace que 2400 points, alors que celui que je viens de donner en trace près de 73000 !
Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
71
le probleme est que tu ne libère pas ton DC, et que, par conséquent, tu risque de provoquer un crash rapidement...

ReleaseDc


SetPixelV ira plus vite encore....

Renfield
Admin CodeS-SourceS- MVP Visual Basic
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

Private Declare Function ReleaseDC Lib "user32" ( _
ByVal hwnd As Integer, _
ByVal hdc As Integer) As Integer

ça peut servir ;)
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

De plus, après vérification, la seule différence entre SetPixel et SetPixelV est la valeur de retour (long pour la couleur dans un cas, boolean dans l'autre).

Donc meme avec SetPixelV, le problème de libération du hDC se serait posé ^ ^.

De plus, MSDN nous dit que SetPixelV est censé être plus rapide que SetPixel, mais après plusieurs test l'écart de rapidité apparait comme négligeable. (moins de 200 point d'écart, quelques soit la durée d'exécution du code).

Je pense donc que les API SetPixel, GetDc et ReleaseDc suffisent ^ ^
Messages postés
7741
Date d'inscription
mercredi 1 septembre 2004
Statut
Membre
Dernière intervention
24 septembre 2014
41
Si tu travaille en VB2005, il te faut modifier toutes les déclarations des fonctions de l'api.

En effet, à moins que ce soit explicitement mentionner, les codes que tu trouvera ne sont par pour la plateforme .Net. Sous .Net certains types de variables ont changés. C'est le cas notamment des Long. Sur une structure Win32 (API windows, VB6, ...) un long fait 32 bits soit 4 octets. Sur une plateforme Win64 ou sur la plateforme .Net, un long fait 64 bits soit 8 octets.

Dans toutes les déclarations, il faut donc que tu remplace tous les long par leur équivalent 32bits sous .Net soit au choix Integer ou Int32

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

hum ta solution corrigé bien l'erreur, mais cependant je n'arrive pas a afficher les pixel et les image normalement obtenues a l'écran :s

La form sur laquelle je suis sensé dessiner reste vierge ..
Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
71
en VB6, je t'aurais dit de faire un Refresh, et de vérifier ton AutoRedraw...

form1.handle => c'est le hWnd
il faut passer un hDc aux API

Renfield
Admin CodeS-SourceS- MVP Visual Basic