Valhalla Legends Archive

Programming => Battle.net Bot Development => Topic started by: Stealth on February 23, 2004, 06:32 PM

Title: Synchronous file downloading
Post by: Stealth on February 23, 2004, 06:32 PM
I would like StealthBot to download a news file (simple, one-line .txt file containing formatted data). This is fairly easily accomplished using INet, or the URLDownloadToFile() API call. However, I need the file to be downloaded without interfering with the functionality of the bot at all or it won't meet my standards.

The current method, a standard INet control, hangs the rest of the bot's operations while it downloads. This isn't acceptable. I also attempted to create a class module to handle the task using URLDownloadToFile() -- the same problem occurs. URLDownloadToFile() within the class hangs the program until finished. Is it possible to download the file synchronously, perhaps by multithreading it? If necessary, I can port the class module's code to a standard module so that it can be used with the AddressOf operator.

Additionally, I will post the code to either the static-reference subroutine or the class module if necessary.
Title: Re:Synchronous file downloading
Post by: K on February 23, 2004, 06:50 PM
The easiest way to trick VB into multithreading is to do something like:


// to download file:
Form1_Load() // or whenever
{
  tmrDownload.Enabled = True
}

// Timer Proc
tmrDownload_Tick()
{
  URLDownloadToFile(/ * ..... */ )
  MessageBox(0, "File Download Complete", "", MB_OK)
  DoThingsWithDownloadedFile()
  tmrDownload.Enabled = False
 
}


Alternatively, I believe the INET control does have the ability to do asynchronous downloading.  I'm not sure how, though.
Title: Re:Synchronous file downloading
Post by: Stealth on February 23, 2004, 07:17 PM
The timer idea worked beautifully. Thank you. :)
Title: Re:Synchronous file downloading
Post by: UserLoser. on February 23, 2004, 07:21 PM
Could just set up a socket, connect, and request the file to the news, then just dump all the recieved text to a file
Title: Re:Synchronous file downloading
Post by: Stealth on February 23, 2004, 07:36 PM
I ended up writing a module that uses SetTimer and KillTimer to create a short-lived timer thread within which URLDownloadToFile() can do its thing peacefully and without interfering. It works and it's low-overhead, so it seems to be all good. =)
Title: Re:Synchronous file downloading
Post by: o.OV on February 24, 2004, 12:58 AM
mm..
You already have a working solution but..
I'll add to the thread anyways.

One alternate method involves using UserControls.
I suck with my object oriented programming but..
here is an example project.



'FORM1

Option Explicit

Public fromFile As String, toFile As String

Private Sub Form_Load()
   'specify the url to download from
   fromFile = "http://forum.valhallalegends.com/bbsImages/vl_logo_new.jpg"
   'specify where to output the file to
   toFile = App.Path & "\Temp.jpg"
   'start the download
   Load Form2
End Sub

Private Sub Form_Unload(Cancel As Integer)
   'abort download
   Unload Form2
End Sub




'FORM2

'nothing here _
don't forget to add the UserControl to form2 using ToolBox




'USERCONTROL1

Option Explicit

Private Type SHFILEOPSTRUCT
   hWnd As Long
   wFunc As Long
   pFrom As String
   pTo As String
   fFlags As Integer
   fAnyOperationsAborted As Long
   hNameMappings As Long
   lpszProgressTitle As Long
End Type

Dim Operation As SHFILEOPSTRUCT

Private Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)
   If AsyncProp.PropertyName = 69 Then
       With Operation
           .wFunc = 1
           .pFrom = AsyncProp.Value
           .pTo = Form1.toFile
           .fFlags = &H100
       End With
       SHFileOperation Operation
       MsgBox Form1.toFile
       Unload Form2
   End If
End Sub

Private Sub UserControl_Initialize()
   UserControl.AsyncRead Form1.fromFile, vbAsyncTypeFile, 69
End Sub

Title: Re:Synchronous file downloading
Post by: Adron on February 24, 2004, 03:56 PM
I don't see why using SetTimer and KillTimer is supposed to help. Don't they call in the context of the original thread, blocking that?

Also, as far as I can remember, the Inet transfer control operates just fine asynchronously, with events for when you receive some data.
Title: Re:Synchronous file downloading
Post by: Stealth on February 24, 2004, 04:39 PM
Quote from: Adron on February 24, 2004, 03:56 PM
I don't see why using SetTimer and KillTimer is supposed to help. Don't they call in the context of the original thread, blocking that?

Also, as far as I can remember, the Inet transfer control operates just fine asynchronously, with events for when you receive some data.

You may be correct about the threading -- my testing of whether or not it actually stalled the rest of the operations wasn't very scientific.

In any event, I rewrote it as follows:

'Form_Load()
INet.Execute "http://www.cold-chaos.net/stealth/getver.php", "GET"


Private Sub INet_StateChanged(ByVal State As Integer)
   If (State = icResponseCompleted) Then
       Call HandleNews(INet.GetChunk(1024, icString))
   End If
End Sub