|
APIs: Dessiner une image sur un formulaire Access |
Author(s) Dev Ashish |
![](../images/spacer.gif) |
Dessiner une image sur un formulaire Access.
Cette question est souvent demandée dans les groupes de discussions
d'Access: un développeur désire dessiner une image sur un formulaire en
utilisant les fonctions API. Malheureusement, pratiquement tout le code
graphique qui fonctionne en VB ne produit pas l'effet escompté en Access:
- les formulaires Access ne sont pas conçus pour cela, <g> et
- ils sont déjà fortement sous classés.
Pour prouver ce point, voici un exemple qui fonctionne et ne fonctionne pas.
En essayant de dessiner sur un formulaire Access, le problème est de
repérer le bon hWnd et le bon hDC.
La propriété hWnd fournie est actuellement celle liée au sélecteur
d'enregistrement ( RecordSelector ). La portion client du formulaire est
une fenêtre différente dont il faut trouver le hWnd pour y dessiner avec
succès. Mais ce n'est pas tout! Pour maintenir l'image sur le
formulaire, il faut le retracer chaque fois que la fenêtre reçoit le message
WM_PAINT depuis Windows. Cela implique qu'on utilise une technique pour
sous classer la fenêtre, mais c'est une technique qui
- n'est pas supportée ni recommandée sous Access 97 (VBA5); (
Voir
AddressOf) et
- même si elle est supportée sous Access 2000 (VBA6), elle
n'est toujours pas recommandée.
Si vous lancez sDrawImageOnForm depuis un bouton sur un
formulaire, vous noterez que l'image n'est pas retracée si vous envoyez le
formulaire en background ou si vous le recouvrez par une autre fenêtre.
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function apiGetClassName Lib "user32" _
Alias "GetClassNameA" _
(ByVal hWnd As Long, _
ByVal lpClassname As String, _
ByVal nMaxCount As Long) _
As Long
Private Declare Function apiGetWindow Lib "user32" _
Alias "GetWindow" _
(ByVal hWnd As Long, _
ByVal wCmd As Long) _
As Long
Private Declare Function apiStretchBlt Lib "gdi32" _
Alias "StretchBlt" _
(ByVal hDC 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 nSrcWidth As Long, _
ByVal nSrcHeight As Long, _
ByVal dwRop As Long) _
As Long
Private Declare Function apiGetDC Lib "user32" _
Alias "GetDC" _
(ByVal hWnd As Long) _
As Long
Private Declare Function apiReleaseDC Lib "user32" _
Alias "ReleaseDC" _
(ByVal hWnd As Long, _
ByVal hDC As Long) _
As Long
Private Declare Function apiGetWindowRect Lib "user32" _
Alias "GetWindowRect" _
(ByVal hWnd As Long, _
lpRect As RECT) _
As Long
Private Declare Function apiSetStretchBltMode Lib "gdi32" _
Alias "SetStretchBltMode" _
(ByVal hDC As Long, _
ByVal nStretchMode As Long) _
As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
Private Const MAX_LEN = 255
Private Const ACC_FORM_CLIENT_CLASS = "OFormSub"
Private Const ACC_FORM_CLIENT_CHILD_CLASS = "OFEDT"
Private Const SRCCOPY = &HCC0020
Private Const STRETCH_HALFTONE& = 4
Private Const STRETCH_ORSCANS& = 2
Sub sDrawImageOnForm(frm As Form)
Dim hWnd As Long, hWndSrc As Long
Dim hDCSrc As Long
Dim hDCDest As Long
Dim lpRectSrc As RECT
Dim lpRectDest As RECT
hWnd = fGetClientHandle(frm)
If hWnd = 0 Then Exit Sub
hWndSrc = hWndAccessApp
hDCSrc = apiGetDC(hWndSrc)
hDCDest = apiGetDC(hWnd)
Call apiGetWindowRect(hWndSrc, lpRectSrc)
Call apiGetWindowRect(hWnd, lpRectDest)
Call apiSetStretchBltMode(hDCDest, STRETCH_ORSCANS)
With lpRectDest
Call apiStretchBlt(hDCDest, 0, 0, .Right - .Left, .Bottom - .Top, _
hDCSrc, 0, 0, lpRectSrc.Right - lpRectSrc.Left, _
lpRectSrc.Bottom - lpRectSrc.Top, SRCCOPY)
End With
Call apiReleaseDC(hWnd, hDCDest)
Call apiReleaseDC(hWndSrc, hDCSrc)
End Sub
Function fGetClientHandle(frm As Form) As Long
Dim hWnd As Long
hWnd = apiGetWindow(frm.hWnd, GW_CHILD)
Do While hWnd
If fGetClassName(hWnd) = ACC_FORM_CLIENT_CLASS Then
If fGetClassName(apiGetWindow( _
hWnd, GW_CHILD)) = _
ACC_FORM_CLIENT_CHILD_CLASS Then
fGetClientHandle = hWnd
Exit Do
End If
End If
hWnd = apiGetWindow(hWnd, GW_HWNDNEXT)
Loop
End Function
Private Function fGetClassName(hWnd As Long)
Dim strBuffer As String
Dim lngCount As Long
strBuffer = String$(MAX_LEN - 1, 0)
lngCount = apiGetClassName(hWnd, strBuffer, MAX_LEN)
If lngCount > 0 Then
fGetClassName = Left$(strBuffer, lngCount)
End If
End Function
Pour une situation qui peut s'accommoder d'un hDC, on peut également se référer à
ImageClass de
Stephen Lebans
|