Closing A Notepad file opened with the shell command.

In one of my access programs I create a CSV file and then open it in Notepad using the shell command with a click of a button on my Access form.  I would also like the program to close the Notepad window when the user clicks another button if the file does not get closed manually.  Is there any easy way to close Notepad with VBA?  If yes, please include code..
Thx in advance...
LVL 1
kenadelglassAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DeverillCommented:
What action do you want to take if there are unsaved changes?

Access really has no direct control over notepad once it starts up.  The only thing I know is to have Windows identify the Notepad process and kill that but that would be ugly and involve Windows API calls and you would lose unsaved changes.  Hopefully someone else has an idea.
0
Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
Send keys is about it.  The Win API would be a better way to go as Deverill suggested.

  As an alternative, you might consider Word as it can be controlled via automation.

Jim.
0
kenadelglassAuthor Commented:
For the program I am writing, there will be no unsaved changes made to the Notepad csv file as changes.  I guess I can use SendKeys.  Does anyone know that name of the Win API that closes a program?  I may want to try it...
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

dapperryCommented:
Ummm, I have something similar, but not exactly what you want.  Heres some code that allows you to open a process, and then wait for it to finish before continuing.

'This module hosts the ExecCmd
'function, which allows you to
'execute a program, and then wait
'until the process is done, before
'returning to the calling procedure.
'
'*Note - This process works for
'Win95 and WinNT 4.0, except that
'it does not work for control
'panel applets in WinNT 4.0 (ie -
'control.exe xxxx.cpl

Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
    hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
    lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
         lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
         ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
         ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
         lpStartupInfo As STARTUPINFO, lpProcessInformation As _
         PROCESS_INFORMATION) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal _
    hObject As Long) As Long

Private Const NORMAL_PRIORITY_CLASS = &H20&
      Private Const INFINITE = -1&

Public Sub ExecCmd(cmdline$)
    Dim proc As PROCESS_INFORMATION
    Dim start As STARTUPINFO

    ' Initialize the STARTUPINFO structure:
    start.cb = Len(start)

    ' Start the shelled application:
    ret& = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
    NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)

    ' Wait for the shelled application to finish:
    ret& = WaitForSingleObject(proc.hProcess, INFINITE)
    ret& = CloseHandle(proc.hProcess)
End Sub

No I think if you have the info in PROCESS_INFORMATION you can then use another API function to kill the process.  However, I looked for it, but could not find it.  Maybe another expert will know.  Hope this points you in the right direction.

:) dapperry
0
Jeremy_DCommented:
Try this, it should work:

'---------------------------------------
Private Declare Function FindWindow Lib "user32" Alias _
                        "FindWindowA" (ByVal lpClassName As String, _
                                       ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias _
                        "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
                                        ByVal wParam As Integer, ByVal lParam As Long) As Long
Private Const WM_DESTROY = &H2


Public Function CloseNotepad() As Boolean
    Dim lHandle As Long, lResult As Long

    lHandle = FindWindow("Notepad", vbNullString)
    lResult = SendMessage(lHandle, WM_DESTROY, 0, 0)
    CloseNotepad = (lResult = 0)
End Function
'--------------------------------------

In stead of vbNullString in the FindWindow call you should use something like:

lHandle = FindWindow("Notepad", "YourFile.csv - Notepad")

The second string should be the title of the notepad window you want to close. NB: This depends on what language version you are using! In a Dutch version this would be "YourFile.csv - Kladblok" (Kladblok = Dutch for Notepad). If you don't specify the caption of the notepad window, I think it will close the first opened notepad window it encounters.
0
Jeremy_DCommented:
Darn, ever since this 'New Look' thingy my code doesn't fit in the windows anymore. Are we back to 640x480? Anyway, if you paste the code between the "'-------------------------------" lines into a module, the layout should be correct
0
kenadelglassAuthor Commented:
I actually answered my own question.  I found the solution in the Book Access 95 How-To by Litwin and Getz.  I just had to alter their code slightly.  I will give Jeremy D the credit as his is closest to what I used...

Thx
kenadelglass
0
Jeremy_DCommented:
Do I need to submit an answer or can you find the 'reward comment' option?
BTW, can you post the solution you found? Just interested.
0
dapperryCommented:
Yes, I'd like to see it too.  Jeremy D, your function works fine for closing notepad, but doesn't seem to work with other windows.  Does this just work with notepad?

:) dapperry
0
Jeremy_DCommented:
So, here's the answer ;-)

To use the FindWindow function for other windows, you'll have to know the ClassName of these windows. For Notepad this is simply "Notepad" (the first argument I used in the FindWindow function), for other windows this might be a less obvious name.
You can use a Visual Studio Tool (if you have them) like Spy++ to find the ClassName of a window. Personally I like the VBIDEUtils Visual Basic Add-In from Waty Thierry (you van download the shareware version from http://www.geocities.com/ResearchTriangle/6311/). I've seen more of this kind of utilities, both shareware and freeware, but you'll have to search for them yourself on the web, 'cause I don't remember any names.
To give you an idea of what these class-names can look like:
Windows Taskbar = "Shell_TrayWnd"
Command Button = "Button"
Taskbar Clock = "TrayClockWClass"
TextBox = "Edit" (I think)

If you have any more questions, submit them here before Friday 17:00 GMT, because I'll be on a course for 10 days after that (or ask another expert ;-)

Cheers,
Jeremy


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kenadelglassAuthor Commented:
The solution I found is probably the same solution as Jeremy's but I had to mess a bit with the calling function to get it to work the way I wanted...

Thx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.