ThomasAJ said:
I have a Bound Object Frame in a form into which I drop a JPG image which
then is stored in the table. All works OK.
Because Access stores images very inefficiently I want to NOT store the
image but save the object name and its location in the table and of course
display the image on forms. How do I achieve this?
Tom, unfortunately Access does not expose this functionality. Most
developers will pop open the standard Windows File Dialog window and allow
the user to select the desired file. Drag and Drop is great in theory but
very complex to implement in Access. Since A2K, there has been a bug which
can cause problems for inline subclassing code. It is generally recommended
to place all such code within an external DLL. Unless you are distributing
MDE I would really suggest the use of external DLL to hold the subclassing
code.
Felix posted the necessary code to implement Drag and Drop several years
ago. I've pasted it below my SIG.
--
HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
here is an earlier reply from Felix of MS on this very subject.
From: Felix Lima (felixl[MS]@online.microsoft.com)
Subject: RE: Get FileName from Drag and Drop
Newsgroups: microsoft.public.access.formscoding
View this article only
Date: 2002-02-21 09:33:57 PST
Hi Justin,
In order to do this effectively in Access, you will need to use
subclassing
and API calls. Subclassing in Access is not really recommended and may
cause significant problems. Q278379 explains some problems with
subclassing:
"Because of problems with subclassing
windows after loading the Microsoft Office Visual Basic Editor,
Microsoft
highly
recommends that you use Microsoft Visual Basic or Microsoft Visual C++
to
create
an ActiveX DLL, and that you then reference the DLL from your Microsoft
Access
application."
Basically, In order to successfully get this to work, you need to
subclass
the window and then call the DragAcceptFiles() API. When the user drops
files from explorer, the window is sent the WM_DROPFILES message. This
can
be accomplished in Access by first creating a VB dll and then calling
the
dll from Access.
I was able to create a VB 6 dll which can be referenced in Access to
successfully get the file path from windows explorer to a textbox on an
access form. (It is a modification of a post by Stoil Marinov in
comp.lang.basic.visual 19/11/1999):
Here are the steps I took:
a) Create a VB6 dll with a module (basDragDrop) and a class
(clsDragDrop)
b) Add the following code to the basDragDrop module:
Option Compare Text
Option Explicit
Public CDrag As CDragDrop
Public lpPrevWndProc As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_DROPFILES = &H233
Public Const GetNumOfFiles = &HFFFF
Public Declare Function CallWindowProc 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
Public Declare Function SetWindowLong Lib "user32" Alias _
"SetWindowLongA" (ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Sub DragAcceptFiles Lib "shell32.dll" _
(ByVal hWnd As Long, _
ByVal fAccept As Long)
Public Declare Sub DragFinish Lib "shell32.dll" _
(ByVal hDrop As Long)
Public Declare Function DragQueryFile Lib "shell32.dll" _
Alias "DragQueryFileA" (ByVal hDrop As Long, _
ByVal lFile As Long, _
ByVal lpFileName As String, _
ByVal cbLen As Long) As Long
Public Function WindowProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal
wp
As Long, ByVal lp As Long) As Long
If Msg = WM_DROPFILES Then
'Files have been dropped
CDrag.AcceptDroppedFiles wp
Else
WindowProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wp, lp)
End If
End Function
c) Add the following code CDragDrop:
Option Compare Text
Option Explicit
Private frm As Object
Private txt As Object
Public Property Set Form(frmIn As Object)
Set frm = frmIn
End Property
Public Property Set textbox(txtin As Object)
Set txt = txtin
End Property
Public Sub SubClassHookForm()
Call DragAcceptFiles(frm.hWnd, 1)
lpPrevWndProc = SetWindowLong(frm.hWnd, GWL_WNDPROC, _
AddressOf WindowProc)
Set CDrag = Me
End Sub
Public Sub SubClassUnHookForm()
Call SetWindowLong(frm.hWnd, GWL_WNDPROC, lpPrevWndProc)
Call DragAcceptFiles(frm.hWnd, 0)
End Sub
Sub AcceptDroppedFiles(hDrop As Long)
Dim lNumOfFiles As Long
Dim lReturn As Long
Dim sFilename As String
Dim lm As Long
'Get the number of dropped files
lNumOfFiles = DragQueryFile(hDrop, GetNumOfFiles, 0&, 0)
For lm = 0 To lNumOfFiles
'Allocate buffer for the name of the file
sFilename = String$(257, Chr$(0))
'Get the name of the file
lReturn = DragQueryFile(hDrop, lm, sFilename, Len(sFilename))
'Add the file name to the list
If lReturn > 0 Then
txt.Text = txt.Text & Left$(sFilename, lReturn) & vbCrLf
End If
Next lm
'Tell Windows to free the memory allocated to store the dropped files
DragFinish hDrop
End Sub
c) Compile the dll in VB
d) Add the following to a form in Access that has a textbox called
Text1
and a reference to the compiled dll above:
Option Compare Database
Option Explicit
Dim CDrag As New CDragDrop
Private Sub Form_Load()
'Subclass the form
Set CDrag.TextBox = Me.Text1
Set CDrag.Form = Me
CDrag.SubClassHookForm
End Sub
Private Sub Form_Unload(Cancel As Integer)
'UnSubclass the form
CDrag.SubClassUnHookForm
Set CDrag.Form = Nothing
Set CDrag.TextBox = Nothing
Set CDrag = Nothing
End Sub
HTH
Félix Lima
Microsoft Online Support Engineer
This posting is provided "AS IS" with no warranties, and confers no
rights.
Get Secure! -
www.microsoft.com/security