Problèmes avec les API graphiques de windows

Résolu
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018 - 27 mai 2007 à 18:12
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018 - 28 mai 2007 à 12:32
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

cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018
28 mai 2007 à 11:04
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 :)
3
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018
28 mai 2007 à 11:18
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 !
3
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 71
28 mai 2007 à 12:21
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
3
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018
28 mai 2007 à 12:23
Private Declare Function ReleaseDC Lib "user32" ( _
ByVal hwnd As Integer, _
ByVal hdc As Integer) As Integer

ça peut servir ;)
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018
28 mai 2007 à 12:32
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 ^ ^
3
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
27 mai 2007 à 18:58
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 #
0
cs_Kite37 Messages postés 242 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 17 janvier 2018
27 mai 2007 à 19:28
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 ..
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 71
28 mai 2007 à 09:09
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
0
Rejoignez-nous