Member Avatar for david56connor

Hi, I have a piece of code which loops through checked checkboxes to do something with each of them. After each turn in the loop I want to pause before it continues to the next checkbox until the user enters a piece of text into the text box.

I have tried something like this but haven't had any sucess, I'm still quite new to VB.Net so please bare with me!

Private keypressed as Boolean = False

    Private Sub txtCurrentCaptcha_keyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtCurrentCaptcha.KeyDown
        If e.KeyCode = Keys.Enter Then
            keypressed = True
        End If
    End Sub

    Private Sub joinChar()
        If lstRaidsForming.SelectedIndex >= 0 Then  ' Check for a selected item
            Dim raidItem As String = lstRaidsForming.SelectedItem.ToString
            Dim raidName As String = w.iB(raidItem, "name=", " id=")
            Dim raidID As String = w.iB(raidItem, "id=", " ")
            zraidID = raidID

            If lstChars.CheckedItems.Count > 0 Then  ' Check for checked checkboxes
                For i As Integer = 0 To lstChars.CheckedItems.Count - 1 ' Loop through the checked checkboxes
                    keypressed = False ' Reset keypressed before entering while loop again
                    While keypressed = False ' Whilst the enter key isn't pressed do ...
                        Dim characterItem As ListViewItem = lstChars.CheckedItems(i) ' get the item at index i
                        Dim characterID As String
                        Dim charName As String

                        characterID = characterItem.SubItems(1).Text
                        charName = characterItem.SubItems(0).Text
                        zcharID = characterID
                        Dim getImg As String = getCaptchaImage(characterID, raidID)
                    End While
                Next
            Else
                MsgBox("Error: No characters selected.")
                Exit Sub
            End If
        Else
            MsgBox("Error: Must select a raid")
            Exit Sub
        End If



    End Sub

But I realise my problem and that is that I am now stuck in a neverending while loop, I've tried a few other ways but still can't find a solution to this!

Any help would be greatly appreciated.

David.

Add Application.DoEvents() inside the while-loop to yield processing time for processing user events.

HTH

Member Avatar for david56connor

Hi Teme64, thanks for your reply. I looked at the Application.DoEvents() method on MSDN and I understand how it works in their application, but I'm not sure how I could implement it into mine so that after the image in the picturebox loads it must wait until the user has entered the text for that image?

Thanks, David.

You're right. I didn't quite get what you're up to (still not sure :) ).

Still I would put:

Threading.Thread.Sleep(100) ' Wait 0,1 sec.
Application.DoEvents()

a short delay and yield CPU time inside the for loop.

I don't quite understand how do you determine that the user has entered the correct answer? I would add that validation right after the while loop (user pressed enter). Could you explain more?

Member Avatar for david56connor

My program is fairly simple, however my programming skills aren't great!

I'll give you a quick run through of what the purpose of the program is if you don't mind taking a little time to understand it.

1. User logs in to the site
2. Select some characters on the character list
3. Find current raids forming
4. Start joining selected characters to the raid

What I need is for the program to wait after the image is loaded to allow the user to enter the captcha and wait for the user to hit enter to submit the text and join the character to the selected raid. Then continue to the next character on the list.

[img]http://img98.imageshack.us/img98/5770/41642650.jpg[/img]

Not sure of how to work the images on this forum so I attached it as well if it doesn't load above.

Thanks for your help.
David.

Excellent!

Lets open the logic (I dropped login etc. unrelated to captcha):
1) user selects a new Character, no -> continue app
2) yes -> Captcha - is solved? , no -> continue app (or re-captcha i.e. go to 2)
3) yes -> join a raid
4) go to 1)

Instead of joining raid selection and Captcha solving, keep them as separate, sequential phases. And with a clear separation of user tasks (select, solve etc.) you're app is in a well-known state all the time. When you have these well-known states, you can "guide" the user by enabling/disabling controls which can only be used in that particular state. This gives also a better user experience (and reduces logical errors).

So, I'll show this as a pseudo-code. You have all the bits and pieces here and there, you just need to rearrange them. First, you'll need a main sub which contains the four app states mentioned above. This is not the whole applications Main procedure, but the "main" proc for this state (you could put these "main" procs in separate classes or modules too).

Sub Main1()

  While True
    characterID = selectNewCharacter()
    If characterID IsNot Valid Then
      Exit Sub ' No more character selections, exit and go back to Main
    End If

    If Not solveCaptcha() Then
      Exit Sub ' User did not solve the captcha or didn't want to, exit and go back to Main
    End If

    raidID = selectNewRaid() ' User selects a raid
    joinRaid(characterID, raidID) ' Join the selected character to the raid
  End While

End Sub ' After this app's Main calls Main2 which does the next thing in the game

I used Main1 and Main2 but I suggest using a better naming.

Lets open up solveCaptcha() function:

Private bCheckFlag As Boolean ' Global flag

Function solveCaptcha() As Boolean
  ' Show a captcha image, wait for the text and test for the match

  Dim captchaText As String

  bCheckFlag = False ' Init
  txtCurrentCaptcha.Text = "" ' Init
  getCaptchaImage(picCaptcha.Image, captchaText) ' ByRef Image and String

  Do Until True
    Application.DoEvents() ' Wait and yield CPU
 
    If bCheckFlag Then
      ' Case insensitive check
      If captchaText.ToUpper() = txtCurrentCaptcha.Text.ToUpper() Then
        Return True ' Solved
      End If
    ' Load a new captcha if you want
    ' Or prompt user if continue. If user doesn't want to continue: Return False
    getCaptchaImage(picCaptcha.Image, captchaText)
    txtCurrentCaptcha.Text = ""
    bCheckFlag = False      
    End If
  Loop

  Return False

End Function

Private Sub txtCurrentCaptcha_keyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtCurrentCaptcha.KeyDown

  If e.KeyCode = Keys.Enter Then
    bCheckFlag = True ' Enter pressed, ready to check
  End If

End Sub

This was a bit ad hoc coding but I hope you get the idea. The main point is planning and creating application structure (state transitions) when you have a large application in your hands.

HTH

Member Avatar for david56connor

I understand what your saying that my program needs to be structured better, but at this stage it would take me a very long time to rewrite what I have already done which is around 800 lines at the moment.

I am also not able to validate the captcha text that the user enters as it is using the captcha provided by Google, which when verified is destroyed, this program is for my use only so user experience doesn't necessarily have to be the best although it would be nice!

I think if I was to start again at this program I'd be better reading up on the fundamentals of the entire programming language rather than pulling pieces of code from here and there as I go along!

I noticed that a lot of people have moved from VB to C++, what would be your thoughts on C++ as opposed to VB.Net? I'm currently studying an ICT course and looking for placement at the moment and I see a lot more jobs that involve C++ rather than VB.Net so I'm quite unsure which line of programming languages to follow.

Thanks again for your help, I don't know that your code will suit my needs but I'll try come up with an alternate solution :)

David.

at this stage it would take me a very long time to rewrite what I have already done which is around 800 lines at the moment.

Sorry, I didn't mean to scare you :'( It could be possible to solve the problem with the original code. I just didn't grasp the idea in the first place (actually still don't, to be honest :) ) That's way I tried to get the bigger picture of your app.

I'd be better reading up on the fundamentals of the entire programming language

There has been traditionally two ways to design the programs: from the bottom up and from top to down. First approach starts by building a pieces of code i.e. procedures, classes, libraries as building blocks for the app. The latter one, which I used, takes the program as a problem which is divided to smaller sub-problems until each sub-problem can be written as a code that solves it. Application designing itself is a language independent process.

a lot of people have moved from VB to C++, what would be your thoughts on C++ as opposed to VB.Net?

If VB.NET is your first programming language, it's a good choice. It's more important to learn (good) programming practices and techniques than the syntax of a one programming language itself. I've moved from VB.NET to C# and it was pretty painless to do. C++ is a powerful tool but when you need error-free code in a short time, I would go for VB.NET or C#. Besides both can be used as a "code behind" coding for the websites, never seen C++ to be used for that.

HTH

Member Avatar for david56connor

I suppose I never really went into the full details of the program I'm trying to make, I play a game which doesn't interest me to play without "cheating" so I learn to do new things with programming by trying automate them in a program.

On the game I play there are 'raids' which spawn at random times during the day, and in the past people were killing these in a matter of seconds due to automation so they implemented the ReCaptcha system. A raid takes 20 characters minimum to launch which entails filling out 20 captchas... a bit of a pain in the ass if you ask me.

Many thanks for your contribution and support, I'll mark this thread as being solved! :)

David.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.