Results 1 to 9 of 9

Thread: Problem With Threading on MouseEnter Event.

  1. #1
    dHeather is offline VB.NET Forum Newbie
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2012
    Posts
    26
    Reputation
    14

    Question Problem With Threading on MouseEnter Event.

    Hello,


    Can somebody tell me where I'm going wrong please?

    I have a routine (below) that when a user hovers over a button a thumb is created in a picture box of the target file. The problem I have is that a lot of the target files are large and creating the thumb can take a while (up to a second). What I am trying to do is to add threading so I can interupt the MouseEnter event if the use clicks. I can't get it working though. Can anyone tell me where I'm going wrong please?

    Thank you very much

    My code is Below:

    [XCODE]
    Imports System.IO
    Imports System.Drawing
    Imports System.Threading '<----------

    Public
    Class Form1
    Dim FileString, FolderString AsString
    Dim myFiles AsNew List(Of IO.FileInfo)
    Dim myButtons AsNew List(Of Button)
    Dim t AsNew Thread(AddressOf Image_Buttons_MouseEnter) '<----------

    Private
    Sub Image_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button14.Click, Button15.Click, Button16.Click, Button17.Click, Button18.Click, Button19.Click, Button20.Click, Button21.Click, Button22.Click, Button23.Click, Button24.Click, Button25.Click, Button26.Click, Button27.Click, Button28.Click, Button29.Click, Button30.Click, Button31.Click
    t.Abort() '<---------
    Dim CurrentBtn As Button = sender
    Dim FileName AsString = myFiles(CurrentBtn.Text - 1).ToString
    Try
    Process.Start("D:\" & FolderString & myFiles(CurrentBtn.Text - 1).ToString)
    Catch ex As Exception
    EndTry
    EndSub

    Private
    Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load
    For i AsInteger = 6 To 31
    myButtons.Add(
    Me.Controls("Button" & i))
    Next i
    Me.Label23.Parent = Me.Label22
    Me.Label23.BackColor = Color.Transparent
    Me.PictureBox1.Visible = True
    Me.PictureBox1.Image = My.Resources.New_logo_4__small_
    FolderString =
    "acouStac Info\acouStac Photos\"
    EndSub

    PrivateSub Image_Buttons_MouseEnter(ByVal sender AsObject, ByVal e As System.EventArgs) Handles Button6.MouseEnter, Button7.MouseEnter, Button8.MouseEnter, Button9.MouseEnter, Button10.MouseEnter, Button11.MouseEnter, Button12.MouseEnter, Button13.MouseEnter, Button14.MouseEnter, Button15.MouseEnter, Button16.MouseEnter, Button17.MouseEnter, Button18.MouseEnter, Button19.MouseEnter, Button20.MouseEnter, Button21.MouseEnter, Button22.MouseEnter, Button23.MouseEnter, Button24.MouseEnter, Button25.MouseEnter, Button26.MouseEnter, Button27.MouseEnter, Button28.MouseEnter, Button29.MouseEnter, Button30.MouseEnter, Button31.MouseEnter
    t.Start() '<----------
    Dim CurrentBtn As Button = sender
    Dim FileName AsString = myFiles(CurrentBtn.Text - 1).ToString
    Dim TempImg As Bitmap = System.Drawing.Image.FromFile("D:\" & FolderString & FileName)
    Dim ImgWidth AsSingle = TempImg.Width
    Dim ImgHeight AsSingle = TempImg.Height
    Dim newWidth AsInteger
    Dim newHeight AsInteger
    If TempImg.Width > TempImg.Height Then
    newWidth = 300
    newHeight = (newWidth / TempImg.Width) * TempImg.Height
    Else
    newHeight = 300
    newWidth = (newHeight / TempImg.Height) * TempImg.Width
    EndIf
    Dim resized As Bitmap = New Bitmap(newWidth, newHeight)
    Dim g As Graphics = Graphics.FromImage(resized)
    g.DrawImage(TempImg,
    New Rectangle(0, 0, resized.Width, resized.Height), 0, 0, TempImg.Width, TempImg.Height, GraphicsUnit.Pixel)
    Me.PictureBox1.Image = resized
    g.Dispose()
    EndSub

    Private
    Sub Image_Buttons_MouseLeave(ByVal sender AsObject, ByVal e As System.EventArgs) Handles Button6.MouseLeave, Button7.MouseLeave, Button8.MouseLeave, Button9.MouseLeave, Button10.MouseLeave, Button11.MouseLeave, Button12.MouseLeave, Button13.MouseLeave, Button14.MouseLeave, Button15.MouseLeave, Button16.MouseLeave, Button17.MouseLeave, Button18.MouseLeave, Button19.MouseLeave, Button20.MouseLeave, Button21.MouseLeave, Button22.MouseLeave, Button23.MouseLeave, Button24.MouseLeave, Button25.MouseLeave, Button26.MouseLeave, Button27.MouseLeave, Button28.MouseLeave, Button29.MouseLeave, Button30.MouseLeave, Button31.MouseLeave
    t.Abort() '<---------
    Me.PictureBox1.Image = My.Resources.New_logo_4__small_
    EndSub
    PrivateSub ListView1_MouseDoubleClick(ByVal sender AsObject, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDoubleClick
    Try
    Process.Start("D:\" & FolderString & Me.ListView1.SelectedItems(0).Text)
    Me.Button5.Focus()
    Catch ex As Exception
    EndTry
    EndSub

    End
    Class
    [/XCODE]
    Last edited by dHeather; 07-04-2012 at 1:04 PM.

  2. #2
    Dunfiddlin's Avatar
    Dunfiddlin is offline VB.NET Forum Master
    .NET Framework
    .NET 4.0
    Join Date
    Jun 2012
    Posts
    253
    Reputation
    31
    You do realise that just about everything you want here is pretty much automatic if you use an ImageList control?

  3. #3
    dHeather is offline VB.NET Forum Newbie
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2012
    Posts
    26
    Reputation
    14
    Hello,

    Thanks for the quick response.

    I started with an Image List but the resolution of the created preview (300x300) was very poor even on a 32 Bit Colour Depth so I swapped over to a picture box which displays perfectly.

    If I can sort out how to interupt the MouseEnter event it should work fine, hence my query.

  4. #4
    dHeather is offline VB.NET Forum Newbie
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2012
    Posts
    26
    Reputation
    14
    A quick update,

    I thought that it might be the fact that I was trying to handle a thread during an event so I have moved the creation of the thumb into its' own sub, but still no luck.

    I'm obviously missing something fundimental, but I just can't see what.

    Any ideas anyone?

    Thanks

  5. #5
    Dunfiddlin's Avatar
    Dunfiddlin is offline VB.NET Forum Master
    .NET Framework
    .NET 4.0
    Join Date
    Jun 2012
    Posts
    253
    Reputation
    31
    Threads are simply not designed for this kind of task. They are designed to take infinitely repeating tasks out of the main program flow. They should be started once, usually in the form load, paused when necessary and aborted only when the task is no longer required. The subroutines they refer to should essentially be self contained. You can't stop the thread, feed it new values, and then start it again, at least not without a complete re-initialisation. You certainly can't tie it to an event!

    Threading really can't help! What you really need to do is separate the creation of the thumbnail and the display so that when the mouse events occur the thumbnail (if 300 x 300 can really be described as a thumbnail) is already waiting and appears more or less instantaneously. In other words, if the existing ImageList control isn't of good enough quality for you, you really need to create your own version of it! At the very least you need to strip down the thumbnail creation routine (there appear to be at least two variables added that never get used!) and find a way to avoid the file read.

  6. #6
    dHeather is offline VB.NET Forum Newbie
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2012
    Posts
    26
    Reputation
    14
    Thanks for that. It's been driving me nuts. I'll be pleased not to have to read another site about threading. I was tying myself up in knots.

    If I create a set of 300 x 300 images and add them to Resources, then just update the PictureBox on the MouseEnter event is this a sensible solution? There are about 60 pictures. Or is this bad practice?

    (Thanks also for pointing out the redundant variables. I hadn't noticed them, they must have been hanging around from old code.)

  7. #7
    JohnH's Avatar
    JohnH is offline VB.NET Forum Moderator
    .NET Framework
    .NET 4.0
    Join Date
    Dec 2005
    Location
    Norway
    Posts
    14,176
    Reputation
    2368
    If this is a static set of images that the app provides you should definitely create the thumbnails at design time also.

    As for a dynamic set of images and thumbnails, you don't need to create the same thumbnail each time you MouseEnter a button, do you? Once should suffice. To further speed things up you can start to create the thumbnails on a secondary thread from the form Load event. Store all the thumbnails in a Dictionary, for button MouseEnter you can check in dictionary if thumbnail is available, and if it not choose to either show a 'loading' image/message or spend that 'second' to create that thumbnail in UI thread.

  8. #8
    dHeather is offline VB.NET Forum Newbie
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2012
    Posts
    26
    Reputation
    14
    Thanks for the great advice. My images are static so I will add them to Resources.

    I will have a go at the dictionary idea too, not for the final program, just so I can get my head around threading.

    Thanks again for all you help.

  9. #9
    Dunfiddlin's Avatar
    Dunfiddlin is offline VB.NET Forum Master
    .NET Framework
    .NET 4.0
    Join Date
    Jun 2012
    Posts
    253
    Reputation
    31
    Hmm. Bad practice is as bad practice does for me. If it works with no obvious potential exceptions and you understand why and how it works then that's good enough for personal projects! However, if you're going to use mouse events as triggers just make sure that the target is big enough and avoid butting everything up together so that there is a clear distinction between in and out. Remember that the code in the event will be executed in full so you need to take some account of what happens if a user crosses a lot of targets in a short time. If you're sticking to a button for every picture with a single event covering them all you might want to think about using a different and more definite trigger.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Harvest time tracking