Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using Win32 API - hwnd problems?

Status
Not open for further replies.

kjv1611

New member
Jul 9, 2003
10,758
US
I have an Access 2003 database that I have used the built-in VBA SendKeys function, as well as an API MySendKeys replacement programmed by Dev Ashish for sending keystrokes to an external application for filling in a form on the application. The application I am sending the data to is Creative Media Source Player. The Access database sends the file name, "artist name", title, genre, and maybe one other piece of info that I can't remember at the moment.

At first, it worked 100% fine with just using the SendKeys function. Then we upgraded the computer from a Single core (500mhz) processor computer to a Dell with dual core Pentium D processor. All of a sudden, I had all kinds of problems with the SendKeys function not working correctly. So, I found Dev Ashish's MySendKeys API call after doing some research into using API calls. After some tweaking of how I used it, it worked flawlessly.

Then, I ran some Windows updates and possible Office udpates on the machine. Since that time, the MySendKeys has been having some of the same problems as SendKeys. It would fill in one field correctly, and no other fields; or either put the title in the file name; or do something along those lines.

So, I thought I'd do some more searching, to see if there were another solution. I read about an API call, "SendMessage". It sounded like it could solve my problems, but I wasn't sure how to use it in VBA. So, I kept searching. Then I found the site, which seems to be a good resource for API calls in VB/VBA.

Here is my problem: I tried one of their samples, to see how this works, and I'm getting an error that I've not the slighest of where to go with it. I searched the help file, and tried searching the web, but just didn't find what I think is a real answer.

All of the code works, except for one line, and it breaks, b/c of one reference to a handle property. My immediate guess is that a listbox doesn't have a handle. But, I'll post it here, so that anyone else can look at it, and possibly give me some advice/direction on it:

The code from the example:
Code:
'This project needs a ListBox, named List1 and a TextBox, named Text1
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const LB_FINDSTRING = &H18F
Private Sub Form_Load()
    'KPD-Team 1998
    'URL: [URL unfurl="true"]http://www.allapi.net/[/URL]
    'E-Mail: KPDTeam@Allapi.net
    'Add some items to the listbox
    With List1
        .AddItem "Computer"
        .AddItem "Screen"
        .AddItem "Modem"
        .AddItem "Printer"
        .AddItem "Scanner"
        .AddItem "Sound Blaster"
        .AddItem "Keyboard"
        .AddItem "CD-Rom"
        .AddItem "Mouse"
    End With
End Sub
Private Sub Text1_Change()
    'Retrieve the item's listindex
    [highlight]List1.ListIndex = SendMessage(List1.[b]hwnd[/b], LB_FINDSTRING, -1, _
         ByVal CStr(Text1.Text))[/highlight]
End Sub

The error message:
Compile error:

Method or data member not found
 
Also, the VBA helpfile shows this about the hwnd property:
Hwnd Property
See AlsoApplies ToExampleSpecificsYou can use the hWnd property to determine the handle (a unique Long Integer value) assigned by Microsoft Windows to the current window. Read/write Long.

expression.Hwnd
expression Required. An expression that returns one of the objects in the Applies To list.

Remarks
This property is available only by using a macro or Visual Basic.

You can use this property in Visual Basic when making calls to Windows application programming interface (API) functions or other external routines that require the hWnd property as an argument. Many Windows functions require the hWnd property value of the current window as one of the arguments.

Caution Because the value of this property can change while a program is running, don't store the hWnd property value in a public variable.

Example
The following example uses the hWnd property with the Windows API IsZoomed function to determine if a window is maximized.

' Enter on single line in Declarations section of Module window.
Declare Function IsZoomed Lib "user32" (ByVal hWnd As Long) As Long

Sub Form_Activate()
Dim intWindowHandle As Long
intWindowHandle = Screen.ActiveForm.hWnd
If Not IsZoomed(intWindowHandle) Then
DoCmd.Maximize
End If
End Sub

So, is it possible that a listbox just cannot have a handle (but rather the form would have the handle), and therefore the sample code is just flawed? That is my guess, but I didn't want to just jump to conclusions without asking others' advice.
 
AddItem is not the usual thing in a VBA listbox, so where are you using this code? Listboxes do not have a Hwnd property, as far as I know. Someone may come up with an idea if you post the SendKey stuff that is not working.
 
Well, the AddItem deal did work 100% correctly in the sample code - I created a form, and tested it out. The only line that didn't run was the the one with the handle reference.

As far as the SendKeys that is not working correctly, I don't have the code in front of me, but it goes something like this:

Code:
Private Sub cmdSaveFile_Click()
  Dim strPreacher as String
  'Code to swap the name around from [Last,First to First Last] format - works 100% fine. strPreacher stores the new value.

  AppActivate "Save File Info" 'Or something like that - the title is the only part I can't remember ver betim
  'The "Save File Info" is the userform that pops up from Creative Media Source Player asking for the artist name, title, file name, genre.

  'The code for MySendKeys can be found here:
     [URL unfurl="true"]http://www.mvps.org/access/api/api0046.htm[/URL]

  MySendKeys txtFileName
  MySendKeys {TAB 4}
  MySendKeys txtTitle
  MySendKeys {TAB 1}
  MySendKeys strPreacher
  MySendKeys {TAB 1}
  MySendKeys "Gospel"
  
End Sub

There may be some other code in there, but that is the general gist of it. I have tried adding the AppActivate into other locations to make sure it has the focus the entire time, but that didn't work. I've tried setting the WAIT parameter to True with the AppActivate, but that made it worse. I also tried changing the WAIT parameters for each SendKey location, but that also did not help.

If anyone has any suggestions there, I'll be glad to listen.

Thanks.
 
Also, as an additional thought. I cannot remember for sure if I tried using the fSendKeys Function to call the mySendKeys procedure in the code or not. I do not think that is how I currently have it setup, so I may be bypassing some benefit there. When I get a chance - hopefully within the next couple of days - I'll give it a shot changing the code to see if that possibly corrects the problems for now at least.

 
I think the most important question is "where are you using this code?" If the AddItem code is working perfectly, it suggests VB, not VBA. In VBA, it is usually easiest to use SendKeys with Shell.
 
It's being used in VBA.

I tested the sample code in VBA, and the SendKeys method is being run in VBA (from within an Access database).

For using SendKeys with Shell, how would you suggest changing my current method?

Instead of AppActivate "Window Name", use this:
Code:
Dim retVal
RetVal = Shell("C:\Program Files\Creative\MediaSource.exe", 1)

SendKeys txtFileName
SendKeys {TAB 4}
''etc. etc.

???
 
And, the SendKeys example in the help file shows this:
Code:
Dim ReturnValue, I
ReturnValue = Shell("CALC.EXE", 1)    ' Run Calculator.
AppActivate ReturnValue     ' Activate the Calculator.
For I = 1 To 100    ' Set up counting loop.
    SendKeys I & "{+}", True    ' Send keystrokes to Calculator
Next I    ' to add each value of I.
SendKeys "=", True    ' Get grand total.
SendKeys "%{F4}", True    ' Send ALT+F4 to close Calculator.

So, why would using the actual application name work better than the active window of that application - or would it at all..

 
I am missing your point. Do you find the multiple lines of code and API calls simpler than Shell?

I am still baffled that AddItems worked in VBA. What version of Access is that?
 
When I was talking about whether or not to use Shell, I was speaking of using the Shell command versus just calling the Window title directly with AppActivate - not directly related with the API calls.

So, regarding the Shell question, I'm talking about using AppActivate without Shell - only one line, versus 2 or 3 lines total when using the Shell function, which I guess I could still use in one line. I just wasn't sure whether using:
AppActivate "WindowName"
would be just as well as something like:
AppActivate Shell("C:\Program Files\Creative\MediaSource.exe", 1)

And as for the AddItems working in VBA. I am using Access 2003. The only error I ran into initially was that the listbox row source had to set to value list rather than the default table/query. Otherwise, I've had no problems.


The whole reason for looking into this again is that since some sort of Windows or Office update, this problem seems to have been showing itself. I've no idea why it would be having problems, since it didn't before, but apparently some other process is running and grabbing the attention away from my current app, or doing some other strange thing. Not sure what is causing it, really.

Using the API call from Dev Ashish, all I had to do was create a code module, copy his code into the module, and refer to it instead of the standard SendKeys. It did work better, but now it is also having problems. So, no extra code, as it works identically (as far as what I type to call it).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top