variable locale qui change de valeur
Publié : sam. 22/juil./2006 11:22
dans ma fonction pour passer une image en RTF je n'ai pas l'ensemble de mes variables locales qui changent de valeur mais juste une. donc c'est pas un décalage de la pile. ce bug ne se produit que pour les bitmaps en mémoire.
Code : Tout sélectionner
Procedure.s ImageToEditor(Image.l)
Protected Editor.s, hDC.l, bih.BitmapInfoHeader
Protected *HeaderBits.Bytes, *ImageBits.Bytes, c.l, i.l
Protected *Editor.Characters, *HexBuffer.Characters = @"0123456789abcdef"
;initialisation des données
bih\biSize = SizeOf(BitmapInfoHeader)
*HeaderBits = bih
;récupère un dc valide
hDC = GetDC_(#Null)
;si on récupère pas les infos du Bitmap on libère le DC
If hDC And Not GetDIBits_(hDC, ImageID(Image), 0, 0, #Null, *HeaderBits, #DIB_RGB_COLORS)
ReleaseDC_(#Null, hDC)
hDC = #Null
;sinon on alloue la mémoire nécessaire
Else
*ImageBits = AllocateMemory(bih\biSizeImage)
EndIf
;serait-ce un bug ? le bloc ci-dessous change la valeur de *ImageBits
t = *ImageBits
;si la mémoire n'a pas été allouée on s'arrête là
If Not *ImageBits
ReleaseDC_(#Null, hDC)
hDC = #Null
;sinon on rempli la zone de mémoire avec les données de l'image
ElseIf Not GetDIBits_(hDC, ImageID(Image), 0, bih\biHeight, *ImageBits, *HeaderBits, #DIB_RGB_COLORS)
;mais en cas d'échec il faut libèrer la mémoire
FreeMemory(*ImageBits)
*ImageBits = #Null
EndIf
;on rétablie la valeur d'origine
*ImageBits = t
;si tout est oké y reste plus qu'à créer le RTF
If *ImageBits
;le plus rapide c'est de directement créer la chaine et de travailler avec un pointeur
Editor = "{\rtf1 {\pict\dibitmap " + Space((SizeOf(BitmapInfoHeader) + bih\biSizeImage) * 2) + " }}"
*Editor = @Editor
;pour le pointeur faut pas oublier qu'on démarre pas au début de la chaine
c = Len("{\rtf1 {\pict\dibitmap ")
i = 0
While i < SizeOf(BitmapInfoHeader)
;un octet se représente avec deux chiffres hexa (de $00 à $FF)
*Editor\c[c+0] = *HexBuffer\c[ HiNibble(*HeaderBits\b[i]) ]
*Editor\c[c+1] = *HexBuffer\c[ LoNibble(*HeaderBits\b[i]) ]
i + 1
c + 2
Wend
i = 0
While i < bih\biSizeImage
*Editor\c[c+0] = *HexBuffer\c[ HiNibble(*ImageBits\b[i]) ]
*Editor\c[c+1] = *HexBuffer\c[ LoNibble(*ImageBits\b[i]) ]
i + 1
c + 2
Wend
ReleaseDC_(#Null, hDC)
EndIf
;retourne le résultat dans une chaine de caracteres
;heureusement que la limitation n'existe plus parce que ca grimpe vite
ProcedureReturn Editor
EndProcedure
;charge une magnifique image créée par moi meme
If LoadImage(1, "dri.bmp") And CopyImage(1, 0)
;image 0 -> 100% en mémoire
:image 1 -> DIB Section
s.s = ImageToEditor(0)
EndIf
;crée un magnifique RTF (il est magnifique grace à l'image =)
If s And CreateFile(0, "dri.rtf")
WriteString(0, s)
CloseFile(0)
;chez moi sur ma vieille config avec cette petite (mais magnifique) image
;l'affichage du "fini" est instantanée avec le debugger
;vive les pointeurs pour ces performances :D
Debug "fini"
EndIf