OVH Cloud OVH Cloud

Récupérer l'image d'un control

9 réponses
Avatar
Laurent
Bonjour,
Voila mon problème, j'ai un container control VB.Net dans lequel j'ai des
UserControls, eux mêmes composés de différents éléments (label, textbox...).
Je voudrais récupérer une image bitmap de chaque control.
En regardant sur le net, j'ai trouvé 2 solutions :
- par le OnPaintMethod.Invoke forçant le control à se redessiner - ne marche
pas avec tous les controls (exemple : Label, textbox...),
- par l'API Bitbilt... ne marche pas avec les contrôles cachés.
Si quelqu'un a une idée, merci beaucoup.
Laurent

9 réponses

Avatar
Zoury
Salut Laurent ! :O)

- par l'API Bitbilt... ne marche pas avec les contrôles cachés.



Tu veux obtenir l'image d'un contrôle et de ses sous-contrôles même si ces
derniers sont invisibles ?
À mon avis tu n'auras pas d'autre choix que de les rendre visible durant
l'opération... Au quel cas l'API BitBlt serait la méthode à employer.

Voici un exemple qui pourrait t'intéressé :
'***
Option Explicit On

Imports System.Runtime.InteropServices

Public Class Form1
Inherits System.Windows.Forms.Form

<DllImport("gdi32.dll")> _
Public Shared Function BitBlt( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Int32, _
ByVal nYDest As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Int32, _
ByVal nYSrc As Int32, _
ByVal dwRop As Int32) As Boolean
End Function

Private Shared ReadOnly SRCCOPY As Int32 = &HCC0020


#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Button3 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.TextBox1 = New System.Windows.Forms.TextBox
Me.TextBox2 = New System.Windows.Forms.TextBox
Me.Button2 = New System.Windows.Forms.Button
Me.Label2 = New System.Windows.Forms.Label
Me.Button3 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(144, 80)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(104, 24)
Me.Button1.TabIndex = 0
Me.Button1.Text = "&Visible/Invisible"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(24, 112)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(112, 24)
Me.Label1.TabIndex = 1
Me.Label1.Text = "Label1"
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(24, 144)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size(96, 20)
Me.TextBox1.TabIndex = 2
Me.TextBox1.Text = "TextBox1"
'
'TextBox2
'
Me.TextBox2.Location = New System.Drawing.Point(24, 168)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.TabIndex = 3
Me.TextBox2.Text = "TextBox2"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(144, 112)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(104, 23)
Me.Button2.TabIndex = 4
Me.Button2.Text = "BMP Visible"
'
'Label2
'
Me.Label2.Location = New System.Drawing.Point(24, 80)
Me.Label2.Name = "Label2"
Me.Label2.TabIndex = 5
Me.Label2.Text = "Label2"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(144, 144)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(104, 23)
Me.Button3.TabIndex = 6
Me.Button3.Text = "BMP Tous"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.Button3)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.TextBox2)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
TextBox2.Visible = Not TextBox2.Visible
Label2.Visible = Not Label2.Visible
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click

SaveControlBitmap(Me, "c:mybitmap_visibleonly.bmp", False)
Process.Start("c:mybitmap_visibleonly.bmp")

End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button3.Click

SaveControlBitmap(Me, "c:mybitmap_all.bmp", True)
Process.Start("c:mybitmap_all.bmp")

End Sub

Private Function SaveControlBitmap(ByVal ctl As Control, ByVal FilePath
As String, ByVal ShowAll As Boolean)

Dim al As ArrayList

' vérifie s'il faut afficher tous les contrôles
If (ShowAll) Then
' on rend visible les contrôles invisibles
' et conserve leur reference pour plus tard
al = New ArrayList
For Each c As Control In Me.Controls
If (Not c.Visible) Then
c.Visible = True
al.Add(c)
End If
Next
' permet au formulaire de se redessinner
' et donc d'afficher tous les contrôles
Me.Refresh()
End If

' créer le bitmap du contrôle et le sauvegarde sur le disque
Dim bmp As Bitmap = CreateBitmapFromControl(ctl)
bmp.Save(FilePath)

' vérifie s'il fallait afficher tous les contrôles
If (ShowAll) Then
' rend les contrôles invisibles à nouveau
For Each o As Object In al
DirectCast(o, Control).Visible = False
Next
End If

End Function

Private Function CreateBitmapFromControl(ByVal ctl As Control) As Bitmap

Dim gCtl As Graphics = ctl.CreateGraphics()
Dim bmp As Bitmap = New Bitmap(ctl.ClientRectangle.Width,
ctl.ClientRectangle.Height, gCtl)
Dim gMem As Graphics = Graphics.FromImage(bmp)
Dim hCtlHDC As IntPtr = gCtl.GetHdc()
Dim hMemHDC As IntPtr = gMem.GetHdc()

BitBlt(hMemHDC, 0, 0, ctl.ClientRectangle.Width,
ctl.ClientRectangle.Height, hCtlHDC, 0, 0, SRCCOPY)

gCtl.ReleaseHdc(hCtlHDC)
gMem.ReleaseHdc(hMemHDC)

Return bmp

End Function

End Class
'***

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Laurent
Bonjour Zoury,
Mon containercontrol a une taille largement superieure a la fenetre
affichable a l'ecran (navigation par ascenseurs) et mon probleme concerne
surtout des controles bien visibles mais non affiches sur l'ecran (hors
champs de l'ecran).
C'est pour cela que j'avais privilegie la methode par le
OnPaintMethod.Invoke, le probleme est que cela ne marche pas avec tous les
controles (ex : textbox, label...)
Laurent
Avatar
Zoury
Salut Laurent ! :O)

Mon containercontrol a une taille largement superieure a la fenetre
affichable a l'ecran (navigation par ascenseurs) et mon probleme concerne
surtout des controles bien visibles mais non affiches sur l'ecran (hors
champs de l'ecran).



Aaaaah ! Invisibles dans ce contexte là !


Et bien dans ce cas, les exemples ne pleuvent pas sur le net.. :O/
Une façon de procéder, serait de faire défiler les scrollbars de ton
contrôle et prendre des copies de l'image affichée entre chaque défilement..
Les seuls petits problèmes que je peux voir avec cette méthode, c'est qu'on
peut voir les scrollbars bouger pendant l'opération.

Avec un ContainerControl, bouger le scroll d'un page signifie que l'image
passe directement au "carré" suivant ce qui nous permet de redessiner
l'image "facilement".
Notez que le concept peut s'appliquer d'autre type de conteneur, mais le
code pourrait nécessité des modifications selon le contrôle :
'***
Option Explicit On

Imports System.ComponentModel
Imports System.Runtime.InteropServices

Public Class Form1
Inherits System.Windows.Forms.Form

Private Const SRCCOPY As Int32 = &HCC0020
Private Const WM_HSCROLL As Int32 = &H114
Private Const WM_VSCROLL As Int32 = &H115

Private Const SB_PAGEDOWN As Int32 = 3
Private Const SB_THUMBPOSITION As Int32 = 4
Private Const SB_TOP As Int32 = 6

<DllImport("gdi32.dll")> _
Public Shared Function BitBlt( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Int32, _
ByVal nYDest As Int32, _
ByVal nWidth As Int32, _
ByVal nHeight As Int32, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Int32, _
ByVal nYSrc As Int32, _
ByVal dwRop As Int32) As Boolean
End Function

<DllImport("user32", SetLastError:=True)> _
Private Shared Function GetScrollInfo( _
ByVal hwnd As IntPtr, _
ByVal fnBar As ScrollBarTypes, _
ByRef lpsi As SCROLLINFO) As Int32
End Function

<DllImport("user32")> _
Private Shared Function SetScrollInfo( _
ByVal hwnd As IntPtr, _
ByVal fnBar As ScrollBarTypes, _
ByRef lpsi As SCROLLINFO, _
ByVal fRedraw As Boolean) As Int32
End Function

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32) As Int32
End Function

<StructLayout(LayoutKind.Sequential)> _
Public Structure SCROLLINFO
Public Size As Int32
Public Mask As ScrollInfoFlags
Public Min As Int32
Public Max As Int32
Public Page As Int32
Public Pos As Int32
Public TrackPos As Int32
End Structure

<Flags()> _
Public Enum ScrollInfoFlags
Range = &H1
Page = &H2
Position = &H4
DisableNoScroll = &H8
TrackPos = &H10
All = Range Or Page Or Position Or TrackPos
End Enum

Public Enum ScrollBarTypes
Horizontal = 0
Vertical = 1
Control = 2
Both = 3
End Enum

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents ContainerControl1 As ContainerControl
Friend WithEvents Panel1 As System.Windows.Forms.Panel
Friend WithEvents Button5 As System.Windows.Forms.Button
Friend WithEvents Button4 As System.Windows.Forms.Button
Friend WithEvents Button3 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.ContainerControl1 = New System.Windows.Forms.ContainerControl
Me.Panel1 = New System.Windows.Forms.Panel
Me.Button5 = New System.Windows.Forms.Button
Me.Button4 = New System.Windows.Forms.Button
Me.Button3 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.ContainerControl1.SuspendLayout()
Me.Panel1.SuspendLayout()
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(8, 8)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'ContainerControl1
'
Me.ContainerControl1.AutoScroll = True
Me.ContainerControl1.BackColor System.Drawing.Color.FromArgb(CType(255, Byte), CType(192, Byte), CType(192,
Byte))
Me.ContainerControl1.Controls.Add(Me.Panel1)
Me.ContainerControl1.Location = New System.Drawing.Point(96, 16)
Me.ContainerControl1.Name = "ContainerControl1"
Me.ContainerControl1.Size = New System.Drawing.Size(216, 216)
Me.ContainerControl1.TabIndex = 1
Me.ContainerControl1.Text = "ContainerControl1"
'
'Panel1
'
Me.Panel1.Controls.Add(Me.Button5)
Me.Panel1.Controls.Add(Me.Button4)
Me.Panel1.Controls.Add(Me.Button3)
Me.Panel1.Controls.Add(Me.Button2)
Me.Panel1.Location = New System.Drawing.Point(0, 0)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(400, 400)
Me.Panel1.TabIndex = 0
'
'Button5
'
Me.Button5.Location = New System.Drawing.Point(208, 208)
Me.Button5.Name = "Button5"
Me.Button5.Size = New System.Drawing.Size(184, 184)
Me.Button5.TabIndex = 7
Me.Button5.Text = "Button5"
'
'Button4
'
Me.Button4.Location = New System.Drawing.Point(8, 208)
Me.Button4.Name = "Button4"
Me.Button4.Size = New System.Drawing.Size(184, 184)
Me.Button4.TabIndex = 6
Me.Button4.Text = "Button4"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(208, 8)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(184, 184)
Me.Button3.TabIndex = 5
Me.Button3.Text = "Button3"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(8, 8)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(184, 184)
Me.Button2.TabIndex = 4
Me.Button2.Text = "Button2"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(704, 558)
Me.Controls.Add(Me.ContainerControl1)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ContainerControl1.ResumeLayout(False)
Me.Panel1.ResumeLayout(False)
Me.ResumeLayout(False)

End Sub

#End Region

Private Function CreateBitmapFromScrollableControl(ByVal ctl As
ScrollableControl) As Bitmap

' obtient les informations sur les scrollbars du conteneur
Dim siHS As SCROLLINFO = GetScrollInfo(ctl.Handle,
ScrollBarTypes.Horizontal)
Dim siVS As SCROLLINFO = GetScrollInfo(ctl.Handle,
ScrollBarTypes.Vertical)

' prépare le bitmap source
Dim gCtl As Graphics = ctl.CreateGraphics()
Dim bmp As Bitmap = New Bitmap(siHS.Max, siVS.Max, gCtl)
Dim gMem As Graphics = Graphics.FromImage(bmp)
Dim hCtlHDC As IntPtr = gCtl.GetHdc()
Dim hMemHDC As IntPtr = gMem.GetHdc()

' calcule le nombre de page on a à boucler
Dim nUBoundX As Int32 = Math.Floor(siHS.Max siHS.Page)
Dim nUBoundY As Int32 = Math.Floor(siVS.Max siVS.Page)
' calcule la largeur (width) en pixel ayant en surplus après la
dernière page complète
Dim nHReste As Int32 = siHS.Max Mod siHS.Page
Dim nVReste As Int32 = siVS.Max Mod siVS.Page
' cacule la position où sera copié l'image sur le bitmap source
après la dernière page complète
Dim nLastXPosDest As Int32 = siHS.Max - nHReste
Dim nLastYPosDest As Int32 = siVS.Max - nVReste
' calcule la largeur devant être copié après la dernière page
complète
Dim nLastWidthX As Int32 = siHS.Page - nHReste
Dim nLastWidthY As Int32 = siHS.Page - nHReste

' on positionne les scrolls barres au début du contrôle
SendMessage(ctl.Handle, WM_HSCROLL, SB_TOP, 0)
SendMessage(ctl.Handle, WM_VSCROLL, SB_TOP, 0)
Application.DoEvents()

' fait défiler la scrollbar verticale
For y As Int32 = 0 To nUBoundX
' fait défiler la scrollbar horizontale
For x As Int32 = 0 To nUBoundY

' on prend le carré présentement affiché dans le contrôle
' et le copie à l'endroit approprié sur le bitmap
BitBlt(hMemHDC, _
IIf(x < nUBoundX, siHS.Page * x, nLastXPosDest), _
IIf(y < nUBoundY, siHS.Page * y, nLastYPosDest), _
IIf(x < nUBoundX, siHS.Page, nHReste), _
IIf(y < nUBoundY, siVS.Page, nVReste), _
hCtlHDC, _
IIf(x < nUBoundX, 0, nLastWidthX), _
IIf(y < nUBoundY, 0, nLastWidthY), _
SRCCOPY)

' avance la scrollbar horizontale d'un page
SendMessage(ctl.Handle, WM_HSCROLL, SB_PAGEDOWN, 0)
Application.DoEvents()

Next
' remet la scrollbar horizontale au début et
' avance la scrollbar verticale d'une page
SendMessage(ctl.Handle, WM_HSCROLL, SB_TOP, 0)
SendMessage(ctl.Handle, WM_VSCROLL, SB_PAGEDOWN, 0)
Application.DoEvents()
Next

' Remet les barres à leur emplacement initiale
SetScrollInfo(ctl.Handle, ScrollBarTypes.Horizontal, siHS, True)
SendMessage(ctl.Handle, WM_HSCROLL, SB_THUMBPOSITION, 0)
SetScrollInfo(ctl.Handle, ScrollBarTypes.Vertical, siVS, True)
SendMessage(ctl.Handle, WM_VSCROLL, SB_THUMBPOSITION, 0)

' libère les DCs
gCtl.ReleaseHdc(hCtlHDC)
gMem.ReleaseHdc(hMemHDC)

Return bmp

End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click


CreateBitmapFromScrollableControl(ContainerControl1).Save("c:image.bmp")
Process.Start("c:image.bmp")

End Sub

Private Function GetScrollInfo(ByVal hWnd As IntPtr, ByVal sbt As
ScrollBarTypes) As SCROLLINFO

Dim si As SCROLLINFO
si.Size = Marshal.SizeOf(si)
si.Mask = ScrollInfoFlags.All
If (GetScrollInfo(hWnd, sbt, si) = 0) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If

Return si

End Function

End Class
'***

En espèrant que te ça te mette sur une piste.

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Zoury
Il à noter que l'image résultante n'est pas encore parfaite... j'vais tenter
de réparer ces défauts dans les prochains jours.

--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Laurent
Merci beaucoup, je vais cherche de mon coté.
Laurent
Avatar
Zoury
hmm.. J'avais interchangé des valeurs X et Y et/ou HS ou Vs à quelques
endroits....

voilà qui devrait être beaucoup mieux :
'***
Private Function CreateBitmapFromScrollableControl(ByVal ctl As Control)
As Bitmap

' obtient les informations sur les scrollbars du conteneur
Dim siHS As SCROLLINFO = GetScrollInfo(ctl.Handle,
ScrollBarTypes.Horizontal)
Dim siVS As SCROLLINFO = GetScrollInfo(ctl.Handle,
ScrollBarTypes.Vertical)

' prépare le bitmap source
Dim gCtl As Graphics = ctl.CreateGraphics()
Dim bmp As Bitmap = New Bitmap(siHS.Max, siVS.Max, gCtl)
Dim gMem As Graphics = Graphics.FromImage(bmp)
Dim hCtlHDC As IntPtr = gCtl.GetHdc()
Dim hMemHDC As IntPtr = gMem.GetHdc()

' calcule le nombre de page on a à boucler
Dim nUBoundX As Int32 = Math.Floor(siHS.Max siHS.Page)
Dim nUBoundY As Int32 = Math.Floor(siVS.Max siVS.Page)
' calcule la largeur (width) en pixel ayant en surplus après la
dernière page complète
Dim nHReste As Int32 = siHS.Max Mod siHS.Page
Dim nVReste As Int32 = siVS.Max Mod siVS.Page
' cacule la position où sera copié l'image sur le bitmap source
après la dernière page complète
Dim nLastXPosDest As Int32 = siHS.Max - nHReste
Dim nLastYPosDest As Int32 = siVS.Max - nVReste
' calcule la largeur devant être copié après la dernière page
complète
Dim nLastWidthX As Int32 = siHS.Page - nHReste
Dim nLastWidthY As Int32 = siVS.Page - nVReste

' on positionne les scrolls barres au début du contrôle
SendMessage(ctl.Handle, WM_HSCROLL, SB_TOP, 0)
SendMessage(ctl.Handle, WM_VSCROLL, SB_TOP, 0)
Application.DoEvents()

' fait défiler la scrollbar verticale
For y As Int32 = 0 To nUBoundY
' fait défiler la scrollbar horizontale
For x As Int32 = 0 To nUBoundX

' on prend le carré présentement affiché dans le contrôle
' et le copie à l'endroit approprié sur le bitmap
BitBlt(hMemHDC, _
IIf(x < nUBoundX, siHS.Page * x, nLastXPosDest), _
IIf(y < nUBoundY, siVS.Page * y, nLastYPosDest), _
IIf(x < nUBoundX, siHS.Page, nHReste), _
IIf(y < nUBoundY, siVS.Page, nVReste), _
hCtlHDC, _
IIf(x < nUBoundX, 0, nLastWidthX), _
IIf(y < nUBoundY, 0, nLastWidthY), _
SRCCOPY)

' avance la scrollbar horizontale d'un page
SendMessage(ctl.Handle, WM_HSCROLL, SB_PAGEDOWN, 0)
Application.DoEvents()

Next
' remet la scrollbar horizontale au début et
' avance la scrollbar verticale d'une page
SendMessage(ctl.Handle, WM_HSCROLL, SB_TOP, 0)
SendMessage(ctl.Handle, WM_VSCROLL, SB_PAGEDOWN, 0)
Application.DoEvents()
Next

' Remet les barres à leur emplacement initiale
SetScrollInfo(ctl.Handle, ScrollBarTypes.Horizontal, siHS, True)
SendMessage(ctl.Handle, WM_HSCROLL, SB_THUMBPOSITION, 0)
SetScrollInfo(ctl.Handle, ScrollBarTypes.Vertical, siVS, True)
SendMessage(ctl.Handle, WM_VSCROLL, SB_THUMBPOSITION, 0)

' libère les DCs
gCtl.ReleaseHdc(hCtlHDC)
gMem.ReleaseHdc(hMemHDC)

Return bmp

End Function
'***

--
Cordialement
Yanick
MVP pour Visual Basic
"Laurent" a écrit dans le message de
news:
Merci beaucoup, je vais cherche de mon coté.
Laurent


Avatar
Laurent
Bonjour Zouri,

Je suis en train de tester le code que tu m'as fait parvenir, je suis bloqué
sur la partie suivante :

Private Function GetScrollInfo(ByVal hWnd As IntPtr, ByVal sbt As
ScrollBarTypes) As SCROLLINFO

Dim si As SCROLLINFO
si.Size = Marshal.SizeOf(si)
si.Mask = ScrollInfoFlags.All
If (GetScrollInfo(hWnd, sbt, si) = 0) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If

Return si

Il me bloque en déclanchant un erreur dont le code est le suivant :

Une exception non gérée du type 'System.ComponentModel.Win32Exception' s'est
produite dans WindowsApplication2.exe

Informations supplémentaires : Opération réussie

Voila, si tu as une idée...
Laurent
Avatar
Laurent
Désolé Zouri,
C'est moi qui avait fait une petite erreur lors de la recopie du code !!! Il
marche effectivement bien, mais j'ai peur que cela ne puisse pas me servir
car je ne peux pas bouger la partie affichée de mon containercontrol.
Laurent
Avatar
Zoury
Salut Laurent ! :O)

If (GetScrollInfo(hWnd, sbt, si) = 0) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If



Une exception non gérée du type 'System.ComponentModel.Win32Exception'


s'est
produite dans WindowsApplication2.exe

Informations supplémentaires : Opération réussie

Voila, si tu as une idée...




hmm.... selon la MSDN, GetScrollInfo() renvoit les valeurs suivantes :
---
Return Value
If the function retrieved any values, the return value is nonzero.
If the function does not retrieve any values, the return value is zero.
To get extended error information, call GetLastError.
---

As-tu pris la même déclaration de GetScrollInfo() que moi ?

--
Cordialement
Yanick
MVP pour Visual Basic