Creating your own Drag and Drop apps in VB6

Level:
Level2

Overview

 

As a Windows user, you have undoubtedly used drag and drop techniques to copy or move files from one folder to another, to delete a file by dragging it to the recycle bin, and to perform actions in various application programs. The drag-and-drop features in Visual Basic allow you to incorporate this functionality in the programs you develop.

 

The action of holding a mouse button down and moving a control is called dragging, and the action of releasing the button is called dropping.

 

Basically, a control can work as a source or as a destination of a drag-and-drop operation. Visual Basic supports two drag-and-drop modes, automatic or manual. In automatic mode, you just have to set a property at design time or at run time and let Visual Basic do everything. Conversely, in manual mode you have to respond to a number of events that occur while dragging is in progress, but in return you get better control over the process.

To incorporate drag and drop functionality in your VB programs, you use a handful of properties, events, and methods.

Properties

The two properties involved are DragMode, which specifies whether Automatic or Manual dragging will be used, and DragIcon, which specifies what icon is displayed when the control is dragged.

 

Events

The two events involved are DragDrop, which occurs when a control is dropped onto the object, and DragOver, which occurs when a control is dragged over the object.

 

Method

The Drag method starts or stops manual dragging.

 

All controls except menus, timers, lines, and shapes support the DragMode and DragIcon properties and the Drag method. Forms recognize the DragDrop and DragOver events, but they don't support the DragMode and DragIcon properties or the Drag method.

 

 

Sample Program

 

The sample program presented in this topic is a child's game where the objective is to match a picture to its corresponding word.

 

When the program runs, a splash screen is briefly displayed:

 

 

 

The main screen then displays, presenting the user with 10 pictures in a column on the left, and 10 words in a column on the right. Empty slots appear next to each word. The user's task is to drag the picture on the left to the slot next to the matching word on the right.

 

 

Screen shot of play in progress – the player has dragged some of the pictures on the left to the appropriate spot on the right:

 

 


When done, the player clicks "Check Score", and the program evaluates the results. A red "X" is placed next to wrong answers; a green check is placed next to correct answers. The yellow label near the top right of the screen appears indicating the percent correct and the number of tries so far.

 


The players clicks the "Reset" button, which causes the wrong items to be returned back to their respective slots on the left (and causes the Reset button to disappear).

 


The player corrects his mistakes and clicks "Check Score" once more. (This time all answers are correct. At this point, the user would either start a new game or exit.)

 

 

 

Designing the Sample Program

 

Icons Used

 

The pictures used for word-matching comes from an icon set called "Kid Icons", obtained from the site www.iconfactory.com. A subset of the icon set, shown below, is included in the download.

 

 

The program uses a handful of other icons from custom icon sets. These are included in the download as well.

 

 

 

Project Structure

 

As indicated by the screen-shot below, the project consists of two forms (a splash screen "frmSplash" and the main game form "frmWordGame") and one .BAS module ("modCommon").

 

 

 

Contents of modCommon.bas

 

The modCommon module contains the CenterForm Sub, which is a generic routine to center a form on the screen:

 

Option Explicit

 

'------------------------------------------------------------------------

Public Sub CenterForm(pobjForm As Form)

'------------------------------------------------------------------------

 

With pobjForm

.Top = (Screen.Height - .Height) / 2

.Left = (Screen.Width - .Width) / 2

End With

 

End Sub

 

 

Splash Screen (frmSplash) Design

 

The design-time version of the splash screen is shown below. To build the app, place the controls on the form as shown and set the properties as indicated by the callouts. Note: The backcolor of the form (&H00D8E9EC&) is what I refer to as "XP Beige", and can be a nice alternative to the default gray color for forms.

 

 

Splash Screen (frmSplash) Code

The Splash Screen form contains code for two events, as discussed below.

 

The Form_Load Event

The Form_Load event calls the CenterForm Sub, which centers the form on the screen.

 

Private Sub Form_Load()

CenterForm Me

End Sub

 

The tmrSplash_Timer Event

This event will fire after the two-second Interval (set at design-time) has elapsed. The main form ("frmWordGame") will be displayed, and the splash screen will unload itself.

 

Private Sub tmrSplash_Timer()

frmWordGame.Show

Unload Me

End Sub

 

 

Main Screen (frmWordGame) Design

 

The main screen of the application, as it looks at design-time, is shown below:

 

 

With the aid of screen-shots with callouts, the names and property settings for each control on the form, as well as for the form itself, will be shown in parts.

 

The properties for the form itself as well as the items at the top of the form are shown in the callouts below. Recall that setting the Font property for a form makes that font the default for any control placed on the form – so all controls that display text will have a font of Tahoma, Size 12 unless explicitly changed via that control's Font property.

 

 

The properties for the various control arrays used in the main part of the form are shown in the callouts below:

 

 

The properties for the command buttons and other controls used on the right-hand side of the main part of the form are shown in the callouts below:

 

The cluster of images at the bottom of the form comprise the "image repository" for this application. The Visible property for all of these images is set to False at design-time and are used as needed by the application during run-time. All of the images except for the three shown with the callouts below form the "image bank" of 25 images for the game, 10 of which are selected at random at the start of a new game.

 

The three "non image bank" images are:

 

 

The 25 "image bank" images are shown circled below.

 

 

This is an Image control array named imgSourcePic, indexed 0 to 24. The BorderStyle property for all is set to 1 – Fixed Single, and the Visible property for all is set to False. The Tag property for each image has been set to a word that describes the image. It is the content of the Tag property that will be used when presenting the word list to the user during game play.

 

The table below shows what picture has been assigned to which element of the control array along with the content of the Tag property.

 

Index

Tag

Picture

0

airplane

Airplane.ico

1

balloons

Balloons.ico

2

baseball glove

Baseball Glove.ico

3

pencil

Big Pencil.ico

4

bone

Dog Bone.ico

5

dog

Doggie.ico

6

fire plug

Fire Plug.ico

7

fish

Fishy.ico

8

ice cream cone

Ice Cream.ico

9

ladybug

Lady Bug.ico

10

moon

Moon.ico

11

computer

My Computer.ico

12

house

My House.ico

13

paddle ball

Paddle Ball.ico

14

popsicle

Popsicle.ico

15

present

Present.ico

16

heart

Red Heart.ico

17

robot

Robot.ico

18

castle

Sandcastle.ico

19

submarine

Submarine.ico

20

sun

Sun.ico

21

traffic light

Traffic Light.ico

22

tree

Tree.ico

23

spaceship

UFO.ico

24

star

Yellow Star.ico

 

Main Screen (frmWordGame) Code

 

The General Declarations Section

 

One form-level variable is declared for number of tries.

 

Private mintNumTries As Integer

 

The Form_Load Event

The Form_Load event calls the CenterForm Sub, which centers the form on the screen. This is followed by a call to the NewGameInit Sub.

 

'------------------------------------------------------------------------

Private Sub Form_Load()

'------------------------------------------------------------------------

CenterForm Me

NewGameInit

 

End Sub

 

The NewGameInit Sub

 

The purpose of this Sub is to set up a new game. Ten images are selected at random from the "image bank" of 25 images and are loaded into the column of images on the left. The Tag properties of the ten selected images are then "mixed up" and used as the word list on the right. See the comments in the code for more detail.

 

'------------------------------------------------------------------------

Private Sub NewGameInit()

'------------------------------------------------------------------------

 

Dim blnNumberExists As Boolean

Dim intRandomNumber As Integer

Dim aintPicIndex(0 To 9) As Integer

Dim aintWordIndex(0 To 9) As Integer

Dim intX As Integer

Dim intY As Integer

'Reseed the VB's random number generator

Randomize

'Set the 10 pictures that will be used in this game ...

For intX = 0 To 9

' Get a random number between 0 and 24, make sure it is not

' one we already have ...

Do

intRandomNumber = GetRandomNumber(0, 24)

blnNumberExists = False

intY = 0

Do Until intY >= intX Or blnNumberExists

If intRandomNumber = aintPicIndex(intY) Then

blnNumberExists = True

Else

intY = intY + 1

End If

Loop

Loop While blnNumberExists

' Store the new random number in the aintPicIndex array, so we

' can check for the next go-round ...

aintPicIndex(intX) = intRandomNumber

' Load the picture from the source image array to the

' current set for this game ...

imgPicToMatch(intX).Picture = imgSourcePic(intRandomNumber).Picture

imgPicToMatch(intX).Tag = imgSourcePic(intRandomNumber).Tag

' set the image's drag icon to match its picture

imgPicToMatch(intX).DragIcon = imgPicToMatch(intX).Picture

' allow automatic dragging

imgMatchingPic(intX).DragMode = vbAutomatic

Next intX

 

' Using the Tag property of the 10 images to be used in this game, "mix 'em up" and

' set the "word" label that appears to the right of the second column of images.

For intX = 0 To 9

Do

intRandomNumber = GetRandomNumber(0, 9)

blnNumberExists = False

intY = 0

Do Until intY >= intX Or blnNumberExists

If intRandomNumber = aintWordIndex(intY) Then

blnNumberExists = True

Else

intY = intY + 1

End If

Loop

Loop While blnNumberExists

aintWordIndex(intX) = intRandomNumber

lblWord(intX).Caption = imgPicToMatch(intRandomNumber).Tag

Next intX

 

' No need to see the "scoring box" or Reset button at this time ...

lblScoreMessage.Visible = False

lblReset.Visible = False

cmdReset.Visible = False

End Sub

 

The GetRandomNumber Function

 

This function, used by the NewGameInit Sub, returns a random integer that falls within the range of the two arguments passed.

 

'------------------------------------------------------------------------

Private Function GetRandomNumber(pintLowerBound As Integer, _

pintUpperBound As Integer) _

As Integer

'------------------------------------------------------------------------

' This function will return a random integer that falls with the range

' of the two arguments passed.

GetRandomNumber = Int((pintUpperBound - pintLowerBound + 1) * Rnd + pintLowerBound)

 

End Function

 

 

The imgMatchingPic_DragDrop Event

 

This code is triggered when the user drops an image from the left-hand column to a slot in the right-hand column. See the comments in the code for more detail.

 

'------------------------------------------------------------------------

Private Sub imgMatchingPic_DragDrop(Index As Integer, _

Source As Control, _

X As Single, _

Y As Single)

'------------------------------------------------------------------------

 

' This event occurs when the user has dragged an image from the

' left-hand column of images (the "imgPicToMatch" control array) and

' has released the mouse to drop the image into an empty slot in the

' right-hand column (the "imgMatchingPic" control array).

' The image being dragged from the imgPicToMatch control array is

' passed as the "Source" argument to this event.

 

' (This event will also occur if the user has dropped an image into

' a slot on the right, but changes their mind and drags it from that

' slot on the right to a different slot on the right.)

 

' If the user attempts to drop the image into a slot that already

' has a picture in it, do nothing and exit the sub ...

If imgMatchingPic(Index).Picture <> LoadPicture() Then Exit Sub

' Populate the Picture and Tag properties of the "target" image

' with those of the "Source" image ...

imgMatchingPic(Index).Picture = Source.Picture

imgMatchingPic(Index).Tag = Source.Tag

' Set the DragIcon of the target image to be its Picture (in case

' the user wants to drag the picture back out because they changed

' their mind) ...

imgMatchingPic(Index).DragIcon = imgMatchingPic(Index).Picture

' Clear the Picture and DragIcon from the "Source" image ...

Source.Picture = LoadPicture()

Source.DragIcon = LoadPicture()

 

End Sub

 

The imgPicToMatch_DragOver Event

 

This event occurs when a user is dragging an image over a slot in the left-hand column. See the comments in the code for more detail.

 

'------------------------------------------------------------------------

Private Sub imgPicToMatch_DragOver(Index As Integer, _

Source As Control, _

X As Single, _

Y As Single, _

State As Integer)

'------------------------------------------------------------------------

 

' This event occurs when a user is dragging an image over an element

' in the left-hand column (the imgPicToMatch control array). If the

' image is "legal" for the slot being "hovered over", then the mouse

' icon will be the image that goes in that slot; otherwise, the mouse

' icon will be the "No" symbol.

' This can occur in the following situations:

' (1) The user is initally dragging an image from the left-hand side

' but hovers over another image or empty slot in the left-hand column

' prior to either dropping it either into an empty slot on the right

' or back in its original slot on the left.

' (2) After the user has dropped the image into a slot on the right, but

' then changes their mind and decides to drag it back to its original

' slot on the left.

 

If State = 1 Then

' leaving (moving out of the control)

Source.DragIcon = Source.Picture

Else

If imgPicToMatch(Index).Tag = Source.Tag Then

Source.DragIcon = Source.Picture

Else

Source.DragIcon = imgNo.Picture

End If

End If

 

End Sub

 

The imgPicToMatch_DragDrop Event

 

This event occurs when a user attempts to drop an image into a slot in the left-hand column. See the comments in the code for more detail.

 

'------------------------------------------------------------------------

Private Sub imgPicToMatch_DragDrop(Index As Integer, _

Source As Control, _

X As Single, _

Y As Single)

'------------------------------------------------------------------------

 

' This event occurs when the user attempts to drop an image into a

' slot of the left-hand column (the imgPicToMatch control array).

' This will typically occur after the user moved an image to a slot on

' the right, but then decides to move it back to its original slot on

' the left.

' However, this event will also occur if the user attempts to move an

' image from one slot on the left to another slot on the left (but the

' "If" tests in the code will not allow the drop to take place).

 

' If the user attempts to drop the image into a slot that already

' has a picture in it, do nothing and exit the sub ...

If imgPicToMatch(Index).Picture <> LoadPicture() Then Exit Sub

' Make sure that this is the original slot for the image being dropped ...

If imgPicToMatch(Index).Tag = Source.Tag Then

' Populate the Picture and DragIcon properties of the "target" image

' with those of the "Source" image ...

imgPicToMatch(Index).Picture = Source.Picture

imgPicToMatch(Index).DragIcon = Source.Picture

' Clear the Picture and DragIcon from the "Source" image ...

Source.Picture = LoadPicture()

Source.DragIcon = LoadPicture()

End If

 

End Sub

 

The cmdCheckScore_Click Event

 

This code executes when the user clicks the "Check Score" button, typically after moving all of the images from the left-hand column to the appropriate slots in the right-hand column. The Tags of the images are checked against the corresponding verbiage in the word label and are "marked" accordingly. If the user scored less than 100%, they are given the opportunity to "reset" the wrong answers and try again.

 

'------------------------------------------------------------------------

Private Sub cmdCheckScore_Click()

'------------------------------------------------------------------------

 

Dim intX As Integer

Dim intNumCorrect As Integer

Dim intPercentCorrect As Integer

Dim strCongrats As String

Dim strTries As String

' Loop thru the imgMatchingPic control array and "mark" the answer

' as correct or wrong ...

For intX = 0 To 9

If imgMatchingPic(intX) = LoadPicture() Then

' If the picture was left blank, then mark it wrong (place

' the "red X" next to the image) ...

imgMark(intX).Picture = imgWrong.Picture

ElseIf imgMatchingPic(intX).Tag = lblWord(intX).Caption Then

' If the Tag of the image that was dropped into the slot

' matches the caption of the corresponding element of the

' lblWord Label control array, then mark it correct (place

' the green checkmark next to the image) and increment the

' counter for the number of correct answers.

imgMark(intX).Picture = imgCorrect.Picture

intNumCorrect = intNumCorrect + 1

Else

' The Tag of the image that was dropped into the slot does

' NOT match the caption of the corresponding element of the

' lblWord Label control array, so mark it wrong (place

' the "red X" next to the image) ...

imgMark(intX).Picture = imgWrong.Picture

End If

' Disable automatic dragging for the moment by setting the DragMode

' to Manual ...

imgMatchingPic(intX).DragMode = vbManual

Next

' Increment the number of tries for this game ...

mintNumTries = mintNumTries + 1

' Calculate the percent correct ...

intPercentCorrect = (intNumCorrect / 10) * 100

' Formulate a message indicating how many answers are correct and in how

' many tries ...

If mintNumTries = 1 Then

strTries = "try"

If intPercentCorrect = 100 Then

strCongrats = "Congratulations! "

End If

Else

strTries = "tries"

End If

Beep

lblScoreMessage.Visible = True

lblScoreMessage.Caption = strCongrats & "You scored " & _

intPercentCorrect & "% in " & mintNumTries & _

" " & strTries & "."

' If the user did not get a perfect score, make the Reset button visible

' so they can go back and correct the answers they got wrong ...

If intPercentCorrect < 100 Then

lblReset.Visible = True

cmdReset.Visible = True

cmdReset.Default = True

Else

lblReset.Visible = False

cmdReset.Visible = False

End If

End Sub

 

The cmdReset_Click Event

 

This code executes when the user clicks the "Reset" button, which they can only do after they have checked their score and received less than 100%. This Sub moves all "wrong answer" images back to their original slots on the left.

 

'------------------------------------------------------------------------

Private Sub cmdReset_Click()

'------------------------------------------------------------------------

 

Dim intX As Integer

Dim intY As Integer

' Loop thru the imgMatchingPic control array ...

For intX = 0 To 9

' If the user got the answer wrong ...

If imgMatchingPic(intX).Tag <> lblWord(intX).Caption Then

' If they left the image blank, then just clear the "red X" mark ...

If imgMatchingPic(intX).Picture = LoadPicture() Then

imgMark(intX).Picture = LoadPicture()

Else

' Otherwise, move the picture back to its original slot on the

' left and clear it from the wrong slot on the right ...

For intY = 0 To 9

If imgPicToMatch(intY).Tag = imgMatchingPic(intX).Tag Then

imgPicToMatch(intY).Picture = imgMatchingPic(intX).Picture

imgPicToMatch(intY).DragIcon = imgPicToMatch(intY).Picture

imgMatchingPic(intX).Picture = LoadPicture()

imgMark(intX).Picture = LoadPicture()

Exit For

End If

Next

End If

' Set the DragMode for this slot back to Automatic ...

imgMatchingPic(intX).DragMode = vbAutomatic

End If

Next

' Remove the Reset button from the screen at this time ...

lblReset.Visible = False

cmdReset.Visible = False

End Sub

 

The cmdNewGame_Click Event

 

This code executes when the user clicks the "New Game" button. It clears the "marks" as well as the images in the right-hand column and calls the NewGameInit Sub to prepare a new game.

 

'------------------------------------------------------------------------

Private Sub cmdNewGame_Click()

'------------------------------------------------------------------------

 

Dim intX As Integer

' Clear the "marks" as well as the images in the right-hand column ...

For intX = 0 To 9

imgMark(intX).Picture = LoadPicture()

imgMatchingPic(intX).Picture = LoadPicture()

Next intX

' Reset number of tries counter ...

mintNumTries = 0

' Prepare for a new game ...

Call NewGameInit

' Make the "Check Score" button the default button ...

cmdCheckScore.Default = True

cmdCheckScore.SetFocus

End Sub

 

The cmdExit_Click Event

 

This code executes when the user clicks the "Exit" button. It issues the Unload statement, which triggers the Form_Unload event.

 

'------------------------------------------------------------------------

Private Sub cmdExit_Click()

'------------------------------------------------------------------------

Unload Me

End Sub

 

The Form_Unload Event

 

This code displays a prompt to confirm that the user really wants to quit, and if so, proceeds with the unload, which will cause the program to end.

 

'------------------------------------------------------------------------

Private Sub Form_Unload(Cancel As Integer)

'------------------------------------------------------------------------

Dim inUserResponse As Integer

 

inUserResponse = MsgBox("Are you sure you want to exit?", _

vbYesNo + vbQuestion + vbDefaultButton1, _

"Young Challenger Word Game")

If inUserResponse = vbNo Then

Cancel = 1

End If

 

End Sub

 

Download the VB project code for the example above here.

If you enjoyed this post, subscribe for updates (it's free)

Nice Tutorial

I especially like the way you designed the game. It is very practical and I am sure that small children would find it both challenging and rewarding; in fact, I have a six year old granddaughter that will be playing this before long. Thank you for sharing your code with everyone. I am thinking of increasing the size of the icons a bit to make the designs easier to recognize.

yange challenger word game

hi
i am teacher in iran
i want this program for my classroom in my school
this program very naice
i want one sorce of this program
plz send for mi

kasra is your student in vb6
thans

Great Post.....

Simply marvelous!!! Your article provides a fresh new insight to this topic which was yet undiscovered. I must say your research skills are sharp and your narration is interesting. Splendid work!!
http://bestpanicattackcure.com

Centering form

Why don't you use the StartupPosition property of the spash screen to center it on the screen?? The CenterForm Sub duplicates its behaviour!

But...

I agree, but it gives me an idea on how to center child of MDI forms which are generally do let me change the Startup Position property.

drag drop

how to drag and drop from the toolbox to the picturebox, and to enlarge and shrink the size. For your information, I am currently developing software tools(like ratinal rose or smartdraw)but just basic.tQ

hey i have vb 8 express

hey i have vb 8 express edition i cant seem to find the dragmode etc. properties plzz email me

vb 2010 drag label across form

how can i drag a label and its text within the label across a form? I don't want a specific drop. I just want to be able to drag labels across
the form in various locations on the form. I can't seem to find any solution for this. Please email me if you can help. Thanks.

Use MouseMove event

You can use the MouseMove event instead of Drag&Drop

If your label is called lbl, try:

Dim mxMse As Single, myMse As Single ' In declarations section
 
Private Sub lbl_MouseDown(B As Integer, S as Integer, X as Single, Y as Single)
    If B = vbLeftButton Then mxMse = X: myMse = Y
End Sub
Private Sub lbl_MouseMove(B As Integer, S as Integer, X as Single, Y as Single)
    If B = vbLeftButton Then _
        lbl.Move lbl.Left + X - mxMse, lbl.Top + Y - myMse
End Sub

Much luck

LabelMove

That worked perfectly. Sometimes it's nice to not have to figure out the solution (and be a bit mentally lazy). I knew it had to do with keeping track of the X & Y coordinates but I figured you could just change the top and left from instant to instant with X & Y instead of adding and subtracting their values.

If it's not working for you be sure you put the variables in the declaration space and be sure you either change your label's name to match the code or do what I did change lbe to Label1 (the default name for a label of course) in the code you copy & paste from the post.

references

what references need to be added to make this work. I'm getting many compile errors.

Thanks

Very useful

COOL...高手...

COOL...高手...

on dragdrop

hello
youre tutorials are really great, i just want to ask about something.

im trying to kill my brains by building this sudoku game in vb6 and i cant shake anything from my head. im just a beginner but im willing. which part of the sample code randomizes the pictures? and im still working on dragdrop functions. its quite hard ~_~

Excellent...... Nice

Excellent...... Nice Tutorial for the self learners

Excellent tutorial

Thank you for generously sharing this code! More power to you!

Thanks, this page helped me

Thanks, this page helped me figure out how to make my final project for programming! :)

hahaha..so long ah...got

hahaha..so long ah...got summary not...hahahaha

Thanks

Thanks, the tutorial is so clear and easy. It's usefull for my application. Thanks again.