By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,057 Members | 1,401 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,057 IT Pros & Developers. It's quick & easy.

Working with clipboard

P: 16
I posted a few weeks ago about an encryption program I was writing. I now have it working almost as a translator program. I want to use system wide hotkeys to be able to copy, run through the scrambler, and paste over wherever the text was, while also continue to add to the log kept in the home form. I am using mclhotkey for the systemwide hotkeys, but I am not familiar with the clipboard in VB6.

This is the code I have to encode whatever input is entered.
Expand|Select|Wrap|Line Numbers
  1. sl = Len(uinput.Text)
  2. For x = 1 To sl
  3. word2$(x) = Mid$(uinput, x, 1)
  4. Next x
  5. M = 0
  6. Log.Text = Log.Text & "Me: " + uinput.Text + " ("
  7. Do Until W = sl
  8. W = W + 1
  9. For x = 1 To 95
  10. If alpha$(x) = word2$(W) Then R = x
  11. Next x
  12. Log.Text = Log.Text & code$(R)
  13. Loop
  14. Log.Text = Log.Text & "#)" + vbCrLf
  15. uinput = ""
uinput is the userinput textbox, the alpha$ array is ascii 32-127, the code$ array is ascii 32-127 randomly ordered in order to scramble the letters. As far as I can see, I would simply replace uinput with the clipboard text, and add in to save the scrambled text to the clipboard and repaste is where it was originally from. I THINK I have the concept of what to do but I'm not sure if I am correct and I'm not sure how to implement it =X.

Hopefully I provided enough info for you all to know what I'm talking about, help please!

Fr0g
Nov 29 '06 #1
Share this Question
Share on Google+
14 Replies


Expert 5K+
P: 8,434
sl = Len(uinput.Text)
Try this, for starters.
Expand|Select|Wrap|Line Numbers
  1. If Not Clipboard.GetFormat(vbCFText) Then
  2.   Exit Sub
  3. End If
  4. sl = Clipboard.GetText(vbCFText)
Nov 29 '06 #2

P: 16
I dont understand, what is it supposed to be doing then?



Try this, for starters.
Expand|Select|Wrap|Line Numbers
  1. If Not Clipboard.GetFormat(vbCFText) Then
  2.   Exit Sub
  3. End If
  4. sl = Clipboard.GetText(vbCFText)
Nov 30 '06 #3

Expert 5K+
P: 8,434
I dont understand, what is it supposed to be doing then?
It's checking that there is actually text on the clipboard. If there is, it retrieves that text into variable sl.
Nov 30 '06 #4

P: 16
ooh okay. sl is = sentence length..it takes the length of the sentence so it knows how long to loop when converting. I suppose instead of sl i would make it uinput (userinput). So that way it is taking the clipboard text and replacing the textbox input in my program. Now the only problem is I'm not familiar with the clipboard in VB6 and all the tutorials online are unclear. I want one hotkey to copy, scramble, and paste. The way you had it written they would have to copy and then run it, but I want to be able to do it all in ONE keystroke. Would I do it like this?


Expand|Select|Wrap|Line Numbers
  1. uinput = clipboard.gettext
  2. sl = Len(uinput.Text)
  3. For x = 1 To sl
  4. word2$(x) = Mid$(uinput, x, 1)
  5. Next x
  6. M = 0
  7. Log.Text = Log.Text & "Me: " + uinput.Text + " ("
  8. Do Until W = sl
  9. W = W + 1
  10. For x = 1 To 95
  11. If alpha$(x) = word2$(W) Then R = x
  12. Next x
  13. Log.Text = Log.Text & code$(R)
  14. Loop
  15. Log.Text = Log.Text & "#)" + vbCrLf
  16. uinput = ""
  17.  
I got as far as that if I'm even correct there. I dont know how I would get the scrambled code back onto the clipboard and paste into where it got the text from. Thanks for your help so far!
Fr0g
Dec 1 '06 #5

Expert 5K+
P: 8,434
ooh okay. sl is = sentence length..it takes the length of the sentence so it knows how long to loop when converting. I suppose instead of sl i would make it uinput (userinput). So that way it is taking the clipboard text and replacing the textbox input in my program.
Yeah, sorry. I hit the wrong variable.

Now the only problem is I'm not familiar with the clipboard in VB6 and all the tutorials online are unclear. I want one hotkey to copy, scramble, and paste. The way you had it written they would have to copy and then run it, but I want to be able to do it all in ONE keystroke. Would I do it like this?
Oh, so you want your application to drive the copy, as well? Hm... that's likely to be much more involved.

You might get around it by using SendKeys to send a Ctrl-C, but that relies on the application expecting that key.

I think the reason you're having trouble with tutorials is that they would all be working from the assumption that you want your application to interact with the clipboard to store or retrieve data - not drive other applications doing so.

You see, the clipboard is a "scratch pad" area where applications can place data for their own later use, or to be shared by other applications. It is not (as far as I'm aware) designed to jump in and take their data.

I got as far as that if I'm even correct there. I dont know how I would get the scrambled code back onto the clipboard and paste into where it got the text from.
Getting it back onto the clipboard is the easy part. Just use Clipboard.SetText. Pasting it back to the other application is once again in the realm of "back-seat driving" the application. I don't think the clipboard can "push" the data anywhere.

As with the copy, you might be able to use SendKeys to tell the application to do a paste operation.

Alternatively, maybe there are windows messages you can send to initiate a copy or paste operation. You might try researching that angle. (Behind the scenes, everything happens by Windows sending messages around, but it can get quite involved, and I don't have much experience in that area.)

By the way, I'd suggest you get into the habit of indenting your code - it's usually much easier to read. Example...
Expand|Select|Wrap|Line Numbers
  1. uinput = clipboard.gettext
  2. sl = Len(uinput.Text)
  3. For x = 1 To sl
  4.   word2$(x) = Mid$(uinput, x, 1)
  5. Next x
  6. M = 0
  7. Log.Text = Log.Text & "Me: " + uinput.Text + " ("
  8. Do Until W = sl
  9.   W = W + 1
  10.   For x = 1 To 95
  11.     If alpha$(x) = word2$(W) Then R = x
  12.   Next x
  13.   Log.Text = Log.Text & code$(R)
  14. Loop
  15. Log.Text = Log.Text & "#)" + vbCrLf
  16. uinput = ""
Dec 1 '06 #6

P: 16
I'm not familiar with the sendkeys command but I've been toying around with it without success. I'm thinking once I have that down I will be pretty much finished. Nearly every program in Windows recognizes the Ctrl-C and Ctrl-V commands so hopefully I will soon be finished. All I will have to do once I figure out how to copy the text to the clipboard is
Expand|Select|Wrap|Line Numbers
  1. uinput = clipboard.gettext
and then have it run the scrambling subprogram and do a
Expand|Select|Wrap|Line Numbers
  1. clipboard.settext = scrambled$
Is that correct?

If you could specify exactly how I would use the sendkeys in this case it would be greatly appreciated!

Fr0g
Dec 1 '06 #7

Expert 5K+
P: 8,434
...Nearly every program in Windows recognizes the Ctrl-C and Ctrl-V commands so hopefully I will soon be finished. All I will have to do once I figure out how to copy the text to the clipboard is
Expand|Select|Wrap|Line Numbers
  1. uinput = clipboard.gettext
and then have it run the scrambling subprogram and do a
Expand|Select|Wrap|Line Numbers
  1. clipboard.settext = scrambled$
Is that correct?
That sounds right.
If you could specify exactly how I would use the sendkeys in this case it would be greatly appreciated!
You would have to have some hot-key to activate your application. To be honest, I have found the hotkeys very unreliable under Windows XP, but we'll assume for the omment that it works. If you create a shortcut to your EXE, in the shortcut properties you can set a shortcut key (which I believe was referred to as a hotkey in earlier Windows versions). In theory, if you place that shortcut somewhere under your Start menu, pressing that key should invoke the shortcut.

When your program starts up, you may want to check which is the active application if you want - though I don't recall the details at present, I believe there is an API call you can use.

Then I'd suggest somethiing like this procedure
  • Clear the clipboard (Clipboard.Clear)
  • Issue your copy keypress
    Expand|Select|Wrap|Line Numbers
    1. SendKeys "^C", True
  • Check for text on the clipboard
  • Scramble/unscramble the text
  • Issue the paste keypress
    Expand|Select|Wrap|Line Numbers
    1. SendKeys "^V", True
Note, after your program starts, you might need to issue an Alt-Tab to switch back to the previously active application. This will probably take some fiddling about to get right.
Dec 3 '06 #8

P: 16
I got it! I figured it out not 10 minutes before you posted. This is what I did.

Expand|Select|Wrap|Line Numbers
  1. sl = Len(uinput.Text)
  2. For x = 1 To sl
  3. word2$(x) = Mid$(uinput, x, 1)
  4. Next x
  5. M = 0
  6. Log.Text = Log.Text & "Me: " + uinput.Text + " ("
  7. Do Until W = sl
  8. W = W + 1
  9. For x = 1 To 95
  10. If alpha$(x) = word2$(W) Then R = x
  11. Next x
  12. Log.Text = Log.Text & code$(R)
  13. opaste = opaste & code$(R)
  14. Loop
  15. Clipboard.SetText opaste
  16. Log.Text = Log.Text & "M)" + vbCrLf
  17. SendKeys "(^v)"
  18. uinput.Text = ""
For some reason, the ^c sendkey was not working, so I tried the
Expand|Select|Wrap|Line Numbers
  1. screen.activecontrol.seltext
which I had tried before but didn't work for some reason.
Essentially this does exactly what I want, it doesn't bring my program into focus at all, it just keeps a log of everything as you are encoding/decoding.

I have ONE more question for you though. In my code, when I set my array for code$(x), I have to do it one by one, because I cannot loop in a random order to set it.
For example, I set my alpha$ array like this:
Expand|Select|Wrap|Line Numbers
  1. For x = 1 To 95
  2. alpha$(x) = Chr(x + 31)
  3. Next x
but for my code$ array I have to set it like:
Expand|Select|Wrap|Line Numbers
  1. code$(1) = Chr(67)
  2. code$(2) = Chr(50)
  3. code$(3) = Chr(69)
all the way to code$(95)

Is there any way that I can assign this array through a loop? Maybe with the RND function, but I'm not sure how I would do it without repeating numbers.
Dec 3 '06 #9

Expert 5K+
P: 8,434
I got it! I figured it out not 10 minutes before you posted.
Rats! Beaten to the punch.

:) Seriously, that's great! Like probably most people here, I find it much more satisfying to help someone figure out their own answer than to hand out ready-made solutions. It's a bit like that old saying...
Give a man a fish, and you feed him for a day.
Teach him to fish, and he'll never bother you again.

Okay, that's a slightly corrupted version but hopefully you get the idea.

This is what I did.
...
For some reason, the ^c sendkey was not working, so I tried the
Expand|Select|Wrap|Line Numbers
  1. screen.activecontrol.seltext
which I had tried before but didn't work for some reason.
Hm, I wasn't familiar with it. I'll have to check it out. Actually, I think the only things I've touched in the Screen object are the TwipsPerPixel values and MousePointer. There you go, I've picked up a useful tip today.

That's one of the great things about this kind of forum - the transfer of information is never entirely one-way.

I have ONE more question for you though. In my code, when I set my array for code$(x), I have to do it one by one, because I cannot loop in a random order to set it.
For example, I set my alpha$ array like this:
Expand|Select|Wrap|Line Numbers
  1. For x = 1 To 95
  2. alpha$(x) = Chr(x + 31)
  3. Next x
but for my code$ array I have to set it like:
Expand|Select|Wrap|Line Numbers
  1. code$(1) = Chr(67)
  2. code$(2) = Chr(50)
  3. code$(3) = Chr(69)
all the way to code$(95)
Is there any way that I can assign this array through a loop? Maybe with the RND function, but I'm not sure how I would do it without repeating numbers.
Well, let's see. You certainly could use a loop, but to avoid repeating numbers you would need a nested loop to check the ones already allocated. For example...
Expand|Select|Wrap|Line Numbers
  1. Randomize
  2. For x = 1 to 95
  3.   Do While code$(x) = ""
  4.     code$(x) = Chr(Rnd*26 + 31) ' I don’t know the right constraints here.
  5.     For y = 1 To (x - 1)
  6.       ' If this value is already used, blank it out. This will
  7.       ' cause us to loop until we hit a new value.
  8.       If code$(y) = code$(x) Then
  9.         code$(y) = ""
  10.         Exit For
  11.       End If
  12.     Next
  13.   Loop
  14. Next
Actually, I think that as written this will produce an infinite loop (:(), because there are 95 entries to be produced, and only 26 (or maybe 27) possible values produced by my use of Rnd. You will need to play with the line that assigns the value, as I don’t recall what characters you are generating.

Also, did you actually intend to generate the array randomly each time? Or is it a random array you have worked out once, which then needs to be the same each time you run the program? (Note, you can actually reproduce the same sequence of pseudo-random numbers by using the same “seed” in the Randomize statement. For example Randomize 1.
Dec 3 '06 #10

P: 16
Also, did you actually intend to generate the array randomly each time? Or is it a random array you have worked out once, which then needs to be the same each time you run the program? (Note, you can actually reproduce the same sequence of pseudo-random numbers by using the same “seed” in the Randomize statement. For example Randomize 1.
Yes, I want it to be the same sequence each time, otherwise a program on another computer could not decode it. Essentially I have 10 different code$ arrays with an identifier halfway through the sentence to signal the decoder which array to use. I'll have to play around with the Randomize statement to see if i acn figure something out, seeing as this problem greatly increases the size of my program. I basically have an extra 950 lines lying around, also making it difficult to navigate around in the code. Also, for some reason my
Expand|Select|Wrap|Line Numbers
  1. clipboard.settext screen.activecontrol.seltext
is no longer working =(. So basically I can make it work in my program, and thats it. The screen.activecontrol.seltext works, but no longer on the active window, only if the active window is my program! Mclhotkey is a great tool I found though, if you haven't used it before it's excellent. So, my major problem still lies in the faultiness of the sendkeys command...
Expand|Select|Wrap|Line Numbers
  1. SendKeys "^V"
works just fine, but
Expand|Select|Wrap|Line Numbers
  1. SendKeys "^C"
does not.
Dec 4 '06 #11

Expert 5K+
P: 8,434
Yes, I want it to be the same sequence each time, otherwise a program on another computer could not decode it. Essentially I have 10 different code$ arrays with an identifier halfway through the sentence to signal the decoder which array to use. I'll have to play around with the Randomize statement to see if i acn figure something out, seeing as this problem greatly increases the size of my program. I basically have an extra 950 lines lying around, also making it difficult to navigate around in the code.
Well, at the very least I would move this code to another sub. If the array is local in scope (not available outside this routine) then just pass the array to the Sub. Something like
Expand|Select|Wrap|Line Numbers
  1. FillThisWithGarbage code$()
will certainly clutter up your code a lot less. I may have the syntax wrong, here. But you can pass an array as a parameter.

One thing you might try is using the trigger character (the one you said is in the middle of the sentence) as the seed for the randomiser.

Also, for some reason my
Expand|Select|Wrap|Line Numbers
  1. clipboard.settext screen.activecontrol.seltext
is no longer working =(. So basically I can make it work in my program, and thats it. The screen.activecontrol.seltext works, but no longer on the active window, only if the active window is my program! Mclhotkey is a great tool I found though, if you haven't used it before it's excellent. So, my major problem still lies in the faultiness of the sendkeys command...
Expand|Select|Wrap|Line Numbers
  1. SendKeys "^V"
works just fine, but
Expand|Select|Wrap|Line Numbers
  1. SendKeys "^C"
does not.
Um... now that I think about it, sending Ctl-C isn't going to work (assuming it can at all) unless the user has already selected the text. Perhaps you could send Ctrl-A first to "select all"? If I get a chance, I'll have a look at the hotkey product.

Are you sure that the window you're interested in is the active window? This is where it can get tricky - starting up your program can take the focus away from the one you want active. You might be able to use AppActivate to put it back there, or perhaps send an Alt-Tab.

I don't know about the seltext thing - never used it, sorry.
Dec 4 '06 #12

P: 16
Alright, I now have the program running fine. You simply hightlight what text you want converted and hit win-z and it replaces that text with the encoded text. You highlight what text you want decoded and you get a message box with the decoded text, all while keeping this inside the log in the main program. I also have it to minimize to the tray. I didn't figure out how to set the code$ array in a more organized fashion yet, but I suppose I'm content with a working program. One more problem that I have, is if you select (or input into the input box) a set of different paragraphs, it does not decode it as a seperate paragraph, it simply repeats the last letter that it had in its memory for however many times "enter" was pressed to form the new column. I tried setting a variable for vbcrlf but that doesnt work. Any idea on how I would do this? Thanks so much for your help, if you want to see what I have stable so far I'll host it up for you!
Dec 7 '06 #13

Expert 5K+
P: 8,434
If you post your latest code we can check it out. However, the problem with vbCrLf may just be due to your not allowing for the fact that it's two characters. They are carriage return (CR), which is Chr(13), and line feed (LF) which is Chr(10).

You could try scanning for VbCr then skipping it and the subsequent character (which will be VbLf). (Or rather, copying them across intact).
Dec 7 '06 #14

P: 2
The sendkeys "^c" fixed my problem as well.

I got myself a search engine. I just added the
feature to recall URL's and email addresses.

When a match is found on a line and the next
line contains a URL or Email address
I wanted to put it into the clipboard.

I was manually doing Ctrl/C then a paste
to the browser or the email I was sending.

Thanks again
Jan 30 '07 #15

Post your reply

Sign in to post your reply or Sign up for a free account.