Solved

visual basic 6 macro, the clipboard & third-party software add-on

Posted on 2012-12-26
8
554 Views
Last Modified: 2013-01-04
Hi all,

I'm having an issue with a macro I wrote to get an ID from a third-party product.  I need the ID from the third-party screen (form) to figure out which record I'm on, because there is no data layer in the SDK.  Basically, I created a DLL that adds an option to the product's menu.  When the user clicks the new option on the menu, the program moves the cursor (using Alt-G) to the first field on the form, then "presses" Ctrl-C.  This works great if it is isolated--I can use ctrl-v to paste the contents of the ID field after it runs.  However, as soon as I add anything else to it, like MsgBox Clipboard.GetText, for example, it doesn't work.  Since my whole reason to do the "macro" exercise is to capture the info in the clipboard, I really need to fix this.  Code follows, but please read my last comment, below.

The code is here in a sub of a Functions.bas module:
    Clipboard.Clear
    ' Alt-G:
    Call keybd_event(vbKeyMenu, 0, 0, 0)
    Call keybd_event(vbKeyG, 0, 0, 0)
    Call keybd_event(vbKeyG, 0, KEYEVENTF_KEYUP, 0)
    Call keybd_event(vbKeyMenu, 0, KEYEVENTF_KEYUP, 0)
    Call keybd_event(vbKeyControl, 0, 0, 0)
    ' Ctrl-C:
    Call keybd_event(vbKeyC, 0, 0, 0)
    Call keybd_event(vbKeyC, 0, KEYEVENTF_KEYUP, 0)
    Call keybd_event(vbKeyControl, 0, KEYEVENTF_KEYUP, 0)

And in the Globals:
Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

And in the declarations of the Functions module:
Declare Function apiFindWindow Lib "user32" Alias "FindWindowA" _
   (ByVal lpclassname As Any, ByVal lpCaption As Any) As Long

Final Comment:
I noticed that when it works (if it runs by itself without any code after it), my cursor is where it should be -- in the ID field -- and the whole field is selected.  When I run it with my "msgbox" command (or any command) after it, the focus is not on the ID field.    I'm not sure if this matters but I figured I'd include it in case it helps.

Thanks,
jr
0
Comment
Question by:jruhe
  • 5
  • 3
8 Comments
 
LVL 45

Expert Comment

by:aikimark
ID: 38725644
You could assign the value in the clipboard object to a variable, rather than including it in the msgbox statement directly.

If the variable assignment removes the item from the clipboard, you can add it back to the clipboard.

Question: Have you considered SendMessage() API or SendKeys, rather than keybd_event() API?
0
 
LVL 4

Author Comment

by:jruhe
ID: 38733009
Thanks for your response a1kimark :)

Yes--I actually only used MsgBox to show the problem--indeed I do need it in a variable and have attempted to do something like MyVar = Clipboard.GetText, but it doesn't work--it's like, if there's any code at all after the keyboard events, the keyboard events don't work.  It may be some kind of quirk with the products' API, but it's undocumented.

Do you have more info on SendMessage() or SendKeys?  I tried SendKeys but it didn't appear to work at all (and ugh--I didn't save the code I used!).  That said, I've never used anything like this, so if you've got a good example of either, I'd like to see it.  

Thanks,
Joy
0
 
LVL 45

Accepted Solution

by:
aikimark earned 500 total points
ID: 38733501
create a small project with two textbox controls, a timer control, and two command buttons.

text1.text will be the title of the dialog window
text2.text will be the text you want to send to that dialog window
Set the interval for the timer control to 2000 (2 seconds), and set the enabled property = False
Command1_Click() enables the timer control
Command2_Click() disables the timer control
The timer1_Timer() routine does the following:
Private Sub timer1_Timer()
  On Error Resume Next
  AppActivate Text1.text
  If Err = 0 Then
    SendKeys Text2.Text
  Else
    Err.Cls
  End If
End Sub

Open in new window

0
 
LVL 4

Author Comment

by:jruhe
ID: 38735158
I considered this (or something akin -- note I don't have access to the interface itself so I can't populate a textbox and it looks like I can't use SendKeys if that's what it does).   It was just supposed to populate the clipboard contents on a form that I don't have access to, and then run some code based on that.  However, your suggestion gave me an idea:  perhaps I can create a form whose "visible" property is set to False, and add the timer to it.  The menu command (which I do have access to) could fire the form, then fire the Keyboard Event commands to collect the data then do the rest of the program based on the contents.

I will try that this week. . .  thank you.  meantime, if you know of a timer object that you don't need an interface for, I'd be obliged.

One thing I should "say out loud" before I close. . .  It feels like the clipboard contents are falling out of scope if other commands are added.  It's fine encapsulated (without any commands after the Clipboard GetText command--kind of like it's dabbling within the main program's form and the clipboard (to the user) is still in scope--Ctrl-V will yield the data it copied).  However, once other commands are added, it's almost like the scope of the whole program event stays within my program (as evidenced by the fact that, in the former scenario (no commands after GetText), the cursor ends up in the field that it copied (and all data is selected in that field).  In the latter scenario (commands after GetText--even those that don't mess with the interface--like if a very random MyVar = "abc" was the only command after it copies the clipboard), the cursor ends up off the screen entirely--no field has focus.

I'll try your suggestion this week and truly appreciate your help so far and any thoughts you may have on the above.

jr
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 45

Expert Comment

by:aikimark
ID: 38735522
why can't you use Sendkeys?

There is a Sleep() API that you can use in place of a timer.  Be sure to include a DoEvents statement in the loop so that your code can respond to user-directed stop (looping) action.
0
 
LVL 4

Author Comment

by:jruhe
ID: 38745717
I was thinking I couldn't use SendKeys because I thought it was an object method--I thought you had to specify the form to use it, but I was incorrect.

I just tested it and ran into the issue that the forms run from within the third-party program/API have to be modal.  When I try to run the Timer form modelessly, the API throws an error.  So I can't use AppActivate().  I'm batting a thousand here, aren't I?  :-)

Checking the sleep() api now. . .  will update when I've got enough info to make it interesting!

jr
0
 
LVL 4

Author Comment

by:jruhe
ID: 38745915
Woot Woot!  It worked with a combination of your Timer Control and having the API menu call use an EXE (which will end up containing the rest of the logic). . .  

THANK YOU--you're great!

jr
0
 
LVL 4

Author Closing Comment

by:jruhe
ID: 38745918
Timely, concise--what I needed.  Thank you
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

706 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

12 Experts available now in Live!

Get 1:1 Help Now