Solved

API call from Access 97

Posted on 1998-04-20
6
390 Views
Last Modified: 2008-02-01
Please Help!

I am trying to upgrade my Access 2.0 (16-bit) application to Access 97 (32-bit). My problem is with calls
to the Windows API from Access 97.  Basically what I am trying to do is: (1) open an "Explorer type window"
to display the file tree (This seems to work fine with the "GetOpenFileName" function), (2) send some default
paths with the "xFilter$" variable, (3) Select the file in the Explore type window and capture the File and path
to the xfilename$ variable, (4) send the Title$ variable "Select File" to the Explorer type window titlebar.  The problem seems to be with the "lstrcpy" function.  I have included some of my code to maybe help with the
solution.  This code seems to work fine when used in the Access 2.0 16 bit version. (with obvious changes
to the dll file names).  I would really appreciate anyone's help on this!


**MY Code *******************************************************************
Option Compare Database   'Use database order for string comparisons
Option Explicit

Type tagOPENFILENAME
     lStructSize As Long
     hWndOwner As Long
     hInstance As Long
     lpstrFilter As String
     lpstrCustomFilter As String
     nMaxCustFilter As Long
     nFilterIndex As Long
     lpstrFile As String
     nMaxFile As Long
     lpstrFileTitle As String
     nMaxFileTitle As Long
     lpstrInitialDir As String
     lpstrTitle As String
     flags As Long
     nFileOffset As Integer
     nFileExtension As Integer
     lpstrDefExt As String
     lCustData As Long
     lpfnHook As Long
     lpTemplateName As String
End Type

Public Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (OPENFILENAME As tagOPENFILENAME) As Long

Public Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameA" (OPENFILENAME As tagOPENFILENAME) As Long

Public Declare Function lstrcpy& Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpsSring2 As String)

Dim OPENFILENAME As tagOPENFILENAME


Function OpenCommDlg(F As Form) As String
 
  Dim xFilter$, xfilename$, FileTitle$, DefExt$
  Dim Title$, szCurDir$, APIResults%
 
  On Error GoTo Err_OpenCommDlg
   
    F.Visible = 0

    '*Define the filter string and allocate space in the "c" string
xFilter = "All (*.*)" & vbNullChar & "*.*" & vbNullChar
     xFilter = xFilter & "Text (*.txt)" & vbNullChar & "*.TXT" & vbNullChar
     xFilter$ = xFilter & "Access (*.mdb)" & vbNullChar & "*.MDB" & vbNullChar

    '* Allocate string space for the returned strings.
    xfilename$ = vbNullChar & Space$(255) & vbNullChar
    FileTitle$ = Space$(255) & vbNullChar

    '* Give the dialog a caption title.
    Title$ = "Select File" & vbNullChar

    '* If the user does not specify an extension, append TXT.
    DefExt$ = "TXT" & vbNullChar

    '* Set up the default directory
    szCurDir$ = CurDir$ & vbNullChar

    '* Set up the data structure before you call the GetOpenFileName

    OPENFILENAME.lStructSize = Len(OPENFILENAME)
    OPENFILENAME.hWndOwner = F.hwnd
    OPENFILENAME.lpstrFilter = lstrcpy(xFilter$, xFilter$)
    OPENFILENAME.nFilterIndex = 1
    OPENFILENAME.lpstrFile = lstrcpy(xfilename$, xfilename$)
    OPENFILENAME.nMaxFile = Len(xfilename$)
    OPENFILENAME.lpstrFileTitle = lstrcpy(FileTitle$, FileTitle$)
    OPENFILENAME.nMaxFileTitle = Len(FileTitle$)
    OPENFILENAME.lpstrTitle = lstrcpy(Title$, Title$)
    OPENFILENAME.lpstrDefExt = lstrcpy(DefExt$, DefExt$)
    OPENFILENAME.hInstance = 0
    OPENFILENAME.lpstrCustomFilter = 0
    OPENFILENAME.nMaxCustFilter = 0
    OPENFILENAME.lpstrInitialDir = lstrcpy(szCurDir$, szCurDir$)
    OPENFILENAME.nFileOffset = 0
    OPENFILENAME.nFileExtension = 0
    OPENFILENAME.lCustData = 0
    OPENFILENAME.lpfnHook = 0
    OPENFILENAME.lpTemplateName = 0

    '* This will pass the desired data structure to the Windows API,
    '* which will in turn use it to display the Open Dialog form.
Retry:

    APIResults% = GetOpenFileName(OPENFILENAME)
    If Len(RTrim$(xfilename$)) <= 1 Then GoTo Retry
    If APIResults% <> 0 Then
        OpenCommDlg = RTrim$(xfilename$)
    End If
    F.Visible = -1

Exit_OpenCommDlg:
    On Error GoTo 0
    Exit Function

Err_OpenCommDlg:
    MsgBox Err & " " & Error$, , "Open Common Dialog"
    Resume Exit_OpenCommDlg

End Function
0
Comment
Question by:fairfax
  • 4
  • 2
6 Comments
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
Two things I notice:

First, you are copying from xFilter$ to xFilter$
OPENFILENAME.lpstrFilter = lstrcpy(xFilter$, xFilter$)

Second (a less important but you should change it anyway), you have declared APIResults as in integer (%) it should be a long (%)

0
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
Sorry, that last sentense should read:
Second (a less important but you should change it anyway), you have declared APIResults as in integer (%) it should be a long (&)
0
 

Author Comment

by:fairfax
Comment Utility
Thanks for your suggestions clifABB, but either I am too dense or I am overlooking something.  Anyway, I made the following code changes.
*************
Dim yFilter$, xTitle$

OPENFILENAME.lpstrFilter = lstrcpy(yFilter$, xFilter$)
OPENFILENAME.lpstrTitle = lstrcpy(xTitle$, Title$)

'Changed all APIResults variables from APIResults% to APIResults&

Based on the variables I'am trying to pass to the File Tree Window, I would expect the following results: Titlebar would read "Select File"   - instead, it reads 0.
                  in the ' Files of type' combo box, I expect to see - "All (*.*)"
                                                                                                 "*.*"  
                                                                                     "Text (*.txt)"
                                                                                             "*.TXT"  
again the value I actually see is 0.

Hope you have a couple of more suggestions I can try. Thanks!
         xFilter$ = xFilter & "Access (*.mdb)" & vbNullChar & "*.MDB" & vbNullChar
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 6

Accepted Solution

by:
clifABB earned 100 total points
Comment Utility
I'm sorry, I was completely wrong when I had you change lstrcpy from
lstrcpy(xFilter$, xFilter$)
to
lstrcpy(yFilter$, xFilter$)

I didn't completely realize what you were doing until I ran your code myself.  Basically what lstrcpy(xFilter$, xFilter$) doesn is return the pointer to the string.

With this knowledge, I can solve your problem.

In your structure (tagOPENFILENAME) change all occurances of string to long
example:
lpstrFileTitle As String -> lpstrFileTitle As Long

You are passing pointers to the strings, not the strings themselves.

This will work, I ran your code on my machine with these changes (including changing yFilter back to xFilter).

Now, I'm curious.  Why are you using the API to open the file dialog rather than the common dialog control?
0
 

Author Comment

by:fairfax
Comment Utility
ClifABB, thanks for the extra input - I tried your suggestion with reference to xFilter and it worked great!  However I wasn't as successful when passing the other variables filename$, Title$, Filetitle$ and DefExt$).  Also from time to time the application has problems opening the File tree window.  -- I appreciate you sticking with me on this one.  I don't want to nickle-dime you on this but I would really appreciate your followup.  This is my first question to "Experts-Exchange" (what a great service!) so I'am not sure how to award these points at this time.  I want to make sure you get credit since you have been so helpful.  So I'am just going to give you the 100 points and look for any additional info you can give.  Thank again!
0
 
LVL 6

Expert Comment

by:clifABB
Comment Utility
I don't mind.  As long as the questions refer to this initial question, then it's fair.  On the other hand, if the questions start drifting too far, then you should post a separate question.

First off, to your other variables (filename$ etc), they should all look similar:
OPENFILENAME.lpstrFile = lstrcpy(xfilename$, xfilename$)

And, in the structure tagOPENFILENAME, all declares that are strings should be declared as long.

Now, as to the question of my last comment, just curious why you aren't using the commondialog control that comes with Access?

Excuse me if I underestimate you but here's how to use it:

Place the commondialog control on your main form (preferably one that won't be closed when you use it).  Do this by selecting the menu option 'Insert/Activex Controls...'
Select Microsoft Common Dialog Control and click ok.

Now, using your code from above (with changes):

Function OpenCommDlg(F As Form) As String
   
  Dim xFilter$, xfilename$, FileTitle$, DefExt$
  Dim Title$, szCurDir$, APIResults%
   
  On Error GoTo Err_OpenCommDlg
     
    F.Visible = 0

    '*Define the filter string and allocate space in the "c" string
  xFilter = "All (*.*)|*.*|Text (*.txt)|*.TXT|Access (*.mdb)|*.MDB"

    '* Give the dialog a caption title.
    Title$ = "Select File"

    '* If the user does not specify an extension, append TXT.
    DefExt$ = "TXT"

    ActiveXCtl1.Filter = Filter$
    ActiveXCtl1.FilterIndex = 1
    ActiveXCtl1.Filename = filename$
    ActiveXCtl1.DialogTitle = Title$
    ActiveXCtl1.DefExt = DefExt$
    ActiveXCtl1.InitDir = CurDir$

Retry:
    ActiveXCtl1.ShowOpen
    If ActiveXCtl1.Filename = "" Then GoTo Retry
    OpenCommDlg = ActiveXCtl1.Filename
    F.Visible = -1

Exit_OpenCommDlg:
    On Error GoTo 0
    Exit Function

Err_OpenCommDlg:
    MsgBox Err & " " & Error$, , "Open Common Dialog"
    Resume Exit_OpenCommDlg

End Function

This is much easier than using the API calls.  What do ya think?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now