Make your own free website on Tripod.com

Home
Home

--- Soumis par Dev Ashish---

Placer une image dans la fenêtre d'Access.

Note: Pour tester le code de cet article, vous devez avoir également le code pour AddressOf.

    En sous-classant la portion  MDIClient de la fenêtre d'Access, on peut capturer les messages WM_PAINT  que Windows transmet lors d'un repeinturage. En utilisant ces événements, on peut tracer une image dans la fenêtre d'Access.

CMDIWindow.cls modMDIClient.bas

Note: j'ai reçu du courrier d'un utilisateur dont ce code laissait vide une portion du formulaire après qu'on le libère d'une autre fenêtre qui le recouvrait partiellement. Si vous expérimentez le même comportement, vous est-il possible de me faire parvenir votre configuration et toute information pertinente permettant de débugger ce cas, via le lien Feedback.

    Créer un formulaire frmPutPicture et dans ses procédures événementielles OnOpen et OnUnload, appeler les sous-routines Hook et UnHook comme suit:

'********** Code Start **********
' Private variable
Private mclsMDIClientWnd As CMDIWindow

Private Sub Form_Open(Cancel As Integer)
On Error GoTo ErrHandler

    ' Instantiate the class
    Set mclsMDIClientWnd = New CMDIWindow
    
    ' Specify one image to automatically
    ' display in the MDIClient window when
    ' the form opens
    With mclsMDIClientWnd
        .DrawMode = 1
        .ImagePath = "D:\install\images\mordor.bmp"
        ' Start subclassing
        ' THIS ONLY NEEDS TO BE DONE ONCE
        ' IF YOU HAVE TO CALL HOOK AGAIN,
        ' CALL UNHOOK FIRST OTHERWISE YOU
        ' WILL LIKELY CRASH!!!
        .Hook
    End With
ExitHere:
    Exit Sub
ErrHandler:
    With Err
        MsgBox "Error: " & .Number & vbCrLf & .Description, _
            vbCritical + vbOKOnly, .Source
    End With
    Resume ExitHere
End Sub

Private Sub cmdChangeImage_Click()
    ' Change the DrawMode and image
    ' on the fly
    With mclsMDIClientWnd
        .DrawMode = 2
        .ImagePath = "D:\install\images\meditate.jpg"
    End With
End Sub

Private Sub Form_Close()
    ' Un-subclass and destroy the instance
    Call mclsMDIClientWnd.Unhook
    Set mclsMDIClientWnd = Nothing
End Sub
'********** Code End **********

Mettre ce code dans un nouveau module que l'on nomme modMDIClient (ce doit être précisément ce nom).

'********** Code Start **********
' module name MUST be "modMDIClient"
' This module is only needed if you are using
' Access 2000. Under Access 97, you
' will be using Michael Kaplan's and Ken Getz's
' AddrOf function. For more details,
' see http://www.mvps.org/accessfr/api/api0031.htm

' The class needs to set a refer to itself
Public pobjMDIClient As CMDIWindow

Public Function WndProc( _
            ByVal hWnd As Long, _
            ByVal Msg As Long, _
            ByVal wParam As Long, _
            ByVal lParam As Long) _
            As Long
    ' Whatever messages are received,
    ' just pass it on to the MDIClientWndProc
    ' message handler of the CMDIWindow
    ' instance currently held in pobjMDIClient
    '
    ' This does NOT account for multi-instancing
    ' and trying to multi-instance the class will
    ' likely result in a GPF.  But then again, you
    ' only have one MDIClient window to draw upon!
    WndProc = pobjMDIClient.MDIClientWndProc( _
                        hWnd, _
                        Msg, _
                        wParam, _
                        lParam)
End Function
'*********** Code End **********

 

Créer un nouveau module de classe, CMDIWindow, et y insérer le code qui suit:

'********** Code Start **********
'--------------------------------------------------------------
'Remerciements tous spéciaux à  Terry Kreft (terry.kreft@mps.co.uk)
'sans son aise, ce code n'aurait jamais fonctionné
'
'NOTE:  Ce code ne peut fonctionner sans Address Of de Ken Getz
'et Michael Kaplan.
'--------------------------------------------------------------
'
'*************************
'NE PAS PARCOURIR CE CODE 
'EN MODE DEBUG
'Utiliser de petits bitmaps pour accroître
'le temps de réponse.
'*************************
'

'Changer pour un fichier point-BMP existant
Private Const conPICPATH = "C:\win98\Setup.bmp"

'Utiliser une de constantes:  1, 2, 3, 4, 5
' où
'   1 = Effet mosaïque
'   2 = Centrer l'image
'   3 = Positionner dans le coin supérieur gauche
'   4 = Positionner dans le coin inférieur droit
'   5 = Étirer pour remplir la fenêtre
'
Private Const conDRAWMODE = 1

Private Type RECT
   left As Long
   top As Long
   right As Long
   bottom As Long
End Type

Private Type BITMAP
  bmType As Long
  bmWidth As Long
  bmHeight As Long
  bmWidthBytes As Long
  bmPlanes As Integer
  bmBitsPixel As Integer
  bmBits As Long
End Type



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 apiGetClientRect Lib "user32" _
  Alias "GetClientRect" _
  (ByVal hwnd As Long, lpRect As RECT) _
  As Long
    
Private Declare Function apiCreateCompatibleDC Lib "gdi32" _
  Alias "CreateCompatibleDC" _
  (ByVal hDC As Long) _
  As Long
    
Private Declare Function apiDeleteDC Lib "gdi32" _
  Alias "DeleteDC" _
  (ByVal hDC As Long) _
  As Long
    
Private Declare Function apiSelectObject Lib "gdi32" _
  Alias "SelectObject" _
  (ByVal hDC As Long, _
  ByVal hObject 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 apiGetClassName Lib "user32" _
  Alias "GetClassNameA" _
  (ByVal hwnd As Long, _
  ByVal lpClassname As String, _
  ByVal nMaxCount As Long) _
  As Long
    
Private Declare Function apiGetWindowText Lib "user32" _
  Alias "GetWindowTextA" _
  (ByVal hwnd As Long, _
  ByVal lpString As String, _
  ByVal aint As Long) _
  As Long
    
Private Declare Function apiBitBlt 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
  
Private Declare Function apiDeleteObject Lib "gdi32" _
  Alias "DeleteObject" _
  (ByVal hObject As Long) _
  As Long
  
Private Declare Function apiSetStretchBltMode Lib "gdi32" _
  Alias "SetStretchBltMode" _
  (ByVal hDC As Long, _
  ByVal nStretchMode 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 apiGetObjectBmp Lib "gdi32" _
  Alias "GetObjectA" _
  (ByVal hObject As Long, _
  ByVal nCount As Long, _
  lpObject As BITMAP) _
  As Long

Private Declare Function apiCallWindowProc Lib "user32" _
  Alias "CallWindowProcA" _
  (ByVal lpPrevWndFunc As Long, _
  ByVal hwnd As Long, _
  ByVal Msg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) _
  As Long
   
Private Declare Function apiSetWindowLong Lib "user32" _
  Alias "SetWindowLongA" _
  (ByVal hwnd As Long, _
  ByVal nIndex As Long, _
  ByVal wNewWord As Long) _
  As Long

Private Declare Function apiCreateSolidBrush Lib "gdi32" _
  Alias "CreateSolidBrush" _
  (ByVal crColor As Long) _
  As Long
    
Private Declare Function apiFillRect Lib "user32" _
  Alias "FillRect" _
  (ByVal hDC As Long, _
  lpRect As RECT, _
  ByVal hBrush As Long) _
  As Long

Private Declare Function apiGetSysColor Lib "user32" _
  Alias "GetSysColor" _
  (ByVal nIndex As Long) _
  As Long
    
Private Declare Function apiSendMessageLong Lib "user32" _
  Alias "SendMessageA" _
  (ByVal hwnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) _
  As Long
    
Private Const COLOR_APPWORKSPACE& = 12
Private Const WM_ERASEBKGND = &H14
Private Const WM_PAINT = &HF
Private Const STRETCH_HALFTONE& = 4
Private Const STRETCH_ORSCANS& = 2
Private Const IMAGE_BITMAP& = 0
Private Const LR_DEFAULTCOLOR& = &H0
Private Const LR_LOADFROMFILE& = &H10
Private Const LR_DEFAULTSIZE& = &H40
Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Const GW_OWNER = 4
Private Const SRCCOPY = &HCC0020
Private Const MAX_LEN = 255
Private lpPrevWndProc  As Long
Private Const GWL_WNDPROC  As Long = (-4)

Function fPaintMDI(ByVal hwnd As Long, _
            ByVal Msg As Long, _
            ByVal wParam As Long, _
            ByVal lParam As Long) As Long
Dim lngRet As Long
    
  On Error Resume Next
    
  Select Case Msg
    Case WM_PAINT:
      Call sPaintMDIClient
  End Select
  fPaintMDI = apiCallWindowProc( _
                 ByVal lpPrevWndProc, _
                 ByVal hwnd, _
                 ByVal Msg, _
                 ByVal wParam, _
                 ByVal lParam)
End Function

Sub sPaintMDIClient()
  Dim hWndMDI As Long
  Dim lngDC As Long
  Dim lngRet As Long
  Dim ShadowDC As Long
  Dim hObject As Object
  Dim lpObject As BITMAP
  Dim intI As Integer
  Dim intJ As Integer
  Dim lpRect As RECT
  Dim intWidth As Integer
  Dim intHeight As Integer
  Dim intTargetX As Integer
  Dim intTargetY As Integer
  
  hWndMDI = fGetMDIhWnd
    
  lngDC = apiGetDC(hWndMDI)
  lngRet = apiGetClientRect(hWndMDI, lpRect)
  With lpRect
    intWidth = Abs(.left - .right)
    intHeight = Abs(.top - .bottom)
  End With
  Set hObject = LoadPicture(conPICPATH)
  ShadowDC = apiCreateCompatibleDC(lngDC)
  lngRet = apiGetObjectBmp(hObject.handle, Len(lpObject), lpObject)
  lngRet = apiSelectObject(ShadowDC, hObject.handle)
  
  Select Case conDRAWMODE
    Case 1:     'Mosaïque
      For intI = 0 To intWidth Step lpObject.bmWidth
        For intJ = 0 To intHeight Step lpObject.bmHeight
          lngRet = apiBitBlt(lngDC, intI, intJ, _
                    lpObject.bmWidth, lpObject.bmHeight, _
                    ShadowDC, 0, 0, SRCCOPY)
        Next intJ
      Next intI
    Case 2:     'Centrer l'image
      With lpRect
        intTargetX = Abs(.right - .left) \ 2
        intTargetY = Abs(.bottom - .top) \ 2
      End With
      lngRet = apiBitBlt(lngDC, intTargetX, intTargetY, _
                lpObject.bmWidth, lpObject.bmHeight, _
                ShadowDC, 0, 0, SRCCOPY)
    Case 3:     'Coin supérieur gauche
      lngRet = apiBitBlt(lngDC, 0, 0, _
                lpObject.bmWidth, lpObject.bmHeight, _
                ShadowDC, 0, 0, SRCCOPY)
    Case 4:     'Coin inférieur droit
      With lpRect
        intTargetX = Abs(.right - lpObject.bmWidth)
        intTargetY = Abs(.bottom - lpObject.bmHeight)
        lngRet = apiBitBlt(lngDC, intTargetX, intTargetY, _
                  lpObject.bmWidth, lpObject.bmHeight, _
                  ShadowDC, 0, 0, SRCCOPY)
      End With
    Case 5:     'Étirer
      lngRet = apiSetStretchBltMode(lngDC, STRETCH_ORSCANS)
      lngRet = apiStretchBlt(lngDC, 0, 0, intWidth, intHeight, _
                    ShadowDC, 0, 0, lpObject.bmWidth, _
                    lpObject.bmHeight, SRCCOPY)
    Case Else:
      'Ne rien faire, constante non reconnue
  End Select
  'ménage général
  Set hObject = Nothing
  lngRet = apiDeleteDC(ShadowDC)
  lngRet = apiReleaseDC(hWndMDI, lngDC)
End Sub

Function fGetMDIhWnd() As Long
Dim hwnd As Long
  hwnd = apiGetWindow(hWndAccessApp, GW_CHILD)
  Do While Not hwnd = 0
    If fGetClassName(hwnd) = "MDIClient" Then
      fGetMDIhWnd = hwnd
      Exit Do
    End If
    hwnd = apiGetWindow(hwnd, GW_HWNDNEXT)
  Loop
End Function

Private Function fGetClassName(hwnd As Long)
  Dim strBuffer As String
  Dim lngRet As Long

  strBuffer = String$(32, 0)
  lngRet = apiGetClassName(hwnd, strBuffer, Len(strBuffer))
  If lngRet > 0 Then
    fGetClassName = left$(strBuffer, lngRet)
  End If
End Function

Private Function fGetCaption(hwnd As Long)
  Dim strBuffer As String
  Dim lngRet As Long

  strBuffer = String$(MAX_LEN, 0)
  lngRet = apiGetWindowText(hwnd, strBuffer, Len(strBuffer))
  If lngRet > 0 Then
    fGetCaption = left$(strBuffer, lngRet)
  End If
End Function

Sub sHook(hwnd As Long, strFunction As String)
  lpPrevWndProc = apiSetWindowLong(hwnd, _
                      GWL_WNDPROC, _
                      AddrOf(strFunction))
  'Obliger à repeindre
  Call apiSendMessageLong(hwnd, WM_PAINT, 0&, 0&)
End Sub

Sub sUnhook(hwnd As Long)
Dim lngTmp As Long
  On Error Resume Next
  lngTmp = apiSetWindowLong(hwnd, _
            GWL_WNDPROC, _
            lpPrevWndProc)
  Call sFillMDIClient(hwnd)
End Sub

Private Sub sFillMDIClient(ByVal hwnd As Long)
Dim lngDC As Long
Dim lpRect As RECT
Dim lngColor As Long
Dim hBrush As Long
Dim lngTmp As Long

  'Effacer l'arrière plan
  lngTmp = apiGetClientRect(hwnd, lpRect)
  lngDC = apiGetDC(hwnd)
  lngColor = apiGetSysColor(COLOR_APPWORKSPACE)
  hBrush = apiCreateSolidBrush(lngColor)
  lngTmp = apiFillRect(lngDC, lpRect, hBrush)
  lngTmp = apiDeleteDC(lngDC)
End Sub

'***************** Code End ***************