How to determine coordinates of boxes in a wmf form that is placed within a picture box placed on a form using the mouse pointer in vb6

Setup is this - I have a vb6 application where I place a picture box on a form, place a wmf file in the picture box, then expand the picture box to completely cover the form.  The wmf file  is a form containing several boxes.  I need to be able to determine the x y coordinates for each of the boxes in the wmf form.  After determining the coordinates for a particular box, I would write the coordinates to a text file from within the program.  I would repeat this process for each box in the wmf form identifying each wmf boxs by number, starting point of the box, and length.

This application would be used to set the wmf box coordinates for boxes in many wmf forms that are processed by  another application, where the operator is able to select a particular wmf form from a group of forms, populate the form by placing information only in the wmf boxes , then  print the form.

For the purpose of this request, I just need help in determining the coordinates for a particular wmf form and possibly determining the length of each box (begin x y and end x y) I will be using a fixed length font in the program that uses the information from this program so the text box length would translate directly to the number of characters in the box.

Can I do this directly or do I need to create a program text box, and move the text box over each of the boxes in the wmf form? I

If this is necessary, I would need some pointers how to move the text box over each of the pre printed boxes in the particular wmf form, chen click the mouse pointer to determine the x y coordinates.


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Chris Raisin(Retired Analyst/Programmer)Commented:
Looking into it...stand by
Chris Raisin(Retired Analyst/Programmer)Commented:
Do you mean a Windows Metafile (graphix) such as the one showing below?
Chris Raisin(Retired Analyst/Programmer)Commented:
If you arfter coordinates of a particular part of an image (such as a box drawn on the image) if would involve checking each pixel and I think that is in the "too hard" basket for VB6.
If on the other hand you are not talking about an image file but rather a "form" which is captured as an image and then placed in the picture box. the cordinates could be ascertained provided you know the coordinates in the original form before it was captured.
Please clarify.
Newly released Acronis True Image 2019

In announcing the release of the 15th Anniversary Edition of Acronis True Image 2019, the company revealed that its artificial intelligence-based anti-ransomware technology – stopped more than 200,000 ransomware attacks on 150,000 customers last year.

morrisboAuthor Commented:

I have attached a jpeg file which is a snapshot of the screen showing the picture box containing the wmf file image.  As you can see, it is just a group of lines and boxes.  

What I would like to accomplish is to quickly determine the starting x & y coordinates and the ending x & y coordinates of each box, and then write this information to a text file identifying the box # (I will generate this number) along with the coordinates.  I tried to use the mouse down and mouse up events in the picture box control, but only got 0 for each (x & y for both beginning and ending coordinates.
Also, I will need to write some text to each box (maybe just an "X" when I capture the information, so that I can keep up with which boxes have been processed.

Also, I will need to add a vertical scroll bar since the whole image will not fit in the picture box, using its actual size.

Any assistance in adding the scroll bar is also appreciated.

I have about 40 - 50 wmf forms that I must capture this information.

The information captured will be used in another program to create text boxes placed over the pre printed boxes in order to populate each form with variable information. That program has already been written and tested.  The project we are discussing is necessary since the forms have been upgraded to a later version.  I am just attempting to reduce the work of determining the location of the various boxes on each of the forms.  Manually, this would be a long process.  Just trying to automate the procedure of ascertaining this information.

I tried to attach the actual wmf form but it was not accepted as a valid format.  Also, tried to zip up the file but this was not accepted also.



Chris Raisin(Retired Analyst/Programmer)Commented:
A challenge!
Stand by....
Chris Raisin(Retired Analyst/Programmer)Commented:
I just succeeded indoing everything you are after (including scroll bars), then a bad click and I lost it all! But I am re-writing and will get back to you ASAP......Looks good!
Chris Raisin(Retired Analyst/Programmer)Commented:
OK...I haven't yet quite perfected the "scrolling" bit. But the code appears below for what I do have.
I will contact the moderator and obtain instructions on how to upload the entire project to make things easier for you.
The scrolling bit can be handled by the control "MBScroller" but I have to master it's setup first. That control is not presently on the forms so scrolling is not in place yet and the whole form is not currently displaying. I upload these jsut for your testing.
Basically what you do is load the required image into the program by clicking on the "LoadGraphic" button, move the red "XY" locator by holding down the left mouse button and moving it into place as per diagram 1 (for "Top/Left" co-ordinate, then type in the field name in the appropriate text box, ensure that "TopLeft" option button is selected, then click the "record" button to record the cords into the text file "XYWriter.txt" stored in the working directory (the applications directory).
Repeat the process for the bottom/right co-ordinate.

Note that an adjustment should be doen before you start recording the cordinates. Place the red "XY" Locator at the very top left of your work area, note the co-ordiantes showing and copy those co-ordinates into the "Adjust" fiels" (The Coordinates field should then display "0:0" (which is taken as the start of the form.
The alignment for bottom-right is a little different. See the ligning up for the "Agency" field as showing in the third graphic.
I hope you get the idea.

Is this the sort of thing you are after?

I may not have the scrolling bit fixed until late next week, since I am heading off on a 2000KM drive in about 6 hours to visit my Mother for Easter. It is along way to drive and I won't be driving back until the Friday after Easter. I hope you can wait that long.

Option Explicit
Dim MX1, MY1 As Integer

Private Sub cmdLoadGraphic_Click()
  On Error GoTo leave
  Picture1.Picture = LoadPicture(Me.CommonDialog1.FileName)
End Sub

Private Sub cmdRecord_Click()
  Dim nFile As Integer
  Dim StrText As String
  nFile = FreeFile
  Me.txtBoxId.Text = UCase$(Me.txtBoxId.Text)
  StrText = Me.txtBoxId.Text + ":" + IIf(Me.OptTopLeft, "TL", "BR") + "= " + Adjust("Left") + ":" + Adjust("Top")
  Open App.Path + "\XYWriter.txt" For Append As #nFile
  If Me.OptTopLeft.Value = True Then
    Me.OptBottomRight.Value = True
    Me.OptTopLeft.Value = True
    Me.txtBoxId.Text = ""
  End If
  Print #nFile, StrText
  Close #nFile
  Me.txtRecord.Text = StrText
End Sub

Private Sub cmdStop_Click()
  Shell "notepad.exe " + App.Path + "\XYWriter.txt", vbMaximizedFocus
  Unload Me
End Sub
Private Sub OptBottomRight_Click()
  Me.OptTopLeft.Value = False
End Sub

Private Sub OptTopLeft_Click()
  Me.OptBottomRight.Value = False
End Sub

Private Sub txtAdjLeft_Change()
   Me.txtCoOrds.Text = Adjust("Left") + ":" + Adjust("Top")
End Sub

Private Sub txtAdjTop_Change()
   Me.txtCoOrds.Text = Adjust("Left") + ":" + Adjust("Top")
End Sub

Private Sub txtBoxId_Click()
  txtBoxId.Text = ""
End Sub
Private Sub txtBoxId_change()
  Me.cmdRecord.Enabled = Len(Trim(txtBoxId.Text)) > 0
End Sub
Private Sub txtBoxId_lostfocus()
  txtBoxId.Text = Format(txtBoxId.Text, ">")
  txtBoxId.SelStart = Len(txtBoxId)
End Sub
Private Sub form_load()
  Dim cFile As String
  cFile = GetSetting(App.EXEName, "Setup", "Picture", "")
  Me.xy.Left = GetSetting(App.EXEName, "Setup", "xyLeft", 720)
  Me.xy.Top = GetSetting(App.EXEName, "Setup", "xyTop", 7320)
  Me.txtAdjLeft.Text = GetSetting(App.EXEName, "Setup", "AdjLeft", "")
  Me.txtAdjTop.Text = GetSetting(App.EXEName, "Setup", "AdjTop", "")
  Me.txtRecord.Text = GetSetting(App.EXEName, "Setup", "Record", "")
  If Len(cFile) > 0 Then
    Picture1.Picture = LoadPicture(cFile)
    Me.CommonDialog1.FileName = cFile
  End If
End Sub
Private Sub Form_unload(cancel As Integer)
  SaveSetting App.EXEName, "Setup", "Picture", Me.CommonDialog1.FileName
  SaveSetting App.EXEName, "Setup", "AdjLeft", Me.txtAdjLeft.Text
  SaveSetting App.EXEName, "Setup", "AdjTop", Me.txtAdjTop.Text
  SaveSetting App.EXEName, "Setup", "xyLeft", Me.xy.Left
  SaveSetting App.EXEName, "Setup", "xyTop", Me.xy.Top
  SaveSetting App.EXEName, "Setup", "Record", Me.txtRecord.Text
End Sub
Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single)
 xy.Move X - MX1, Y - MY1
 Me.txtCoOrds.Text = Adjust("Left") + ":" + Adjust("Top")
End Sub
Private Function Adjust(cType As String) As String
Select Case LCase(cType)
  Case "left"
    Adjust = CStr(xy.Left - Val(Me.txtAdjLeft.Text))
  Case "top"
    Adjust = CStr(xy.Top - Val(Me.txtAdjTop.Text))
End Select
End Function

Private Sub Picture1_DragDrop(Source As Control, X As Single, Y As Single)
 xy.Move Picture1.Left + X - MX1, Picture1.Top + Y - MY1
 Me.txtCoOrds.Text = Adjust("Left") + ":" + Adjust("Top")
End Sub

Private Sub xy_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
 If Button = vbLeftButton Then
  MX1 = X
  MY1 = Y
 End If
End Sub

Open in new window

morrisboAuthor Commented:

Thanks a bunch.

This is really helpful.

I can tell you have spent some "serious" time on this and I really do appreciate your help.

It would be great if you are able to send the project.  I could basically just use your program to accomplish the task. I can wait on the scroll bars feature.

I could furnish an external email but I am guessing that would be against the Expert Exchange rules.

Hope you enjoy your trip for Easter.  Was wondering in what country you would be located.  

In the USA distance is normally given in miles versus KM.

Chris Raisin(Retired Analyst/Programmer)Commented:
I live in Melbourne Australia.
I am still waiting for the method of uploading the files to you. Please stand by.
Chris Raisin(Retired Analyst/Programmer)Commented:
OK...the moderator must be on Easter leave, so after a lot of searching I found out how to upload the complete project.
You need to click on the following link and after logging in you can get the files:
 Will work on the scrolling part when I return from Qoeensland. By the way 2000 Km equals 1242 Miles (that's just one way, then after three days I have to drive back!)
We live in  a big country!  :-)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
morrisboAuthor Commented:

Got the file downloaded.

Thanks for your help.  I really appreciate it.

Will give it a try this weekend.  We are off from work tomorrow for the Easter Weekend.

Have a good trip.

I live in Waxahachie, Tx., a small town one county south of Dallas, Texas.

morrisboAuthor Commented:
Great work.  
morrisboAuthor Commented:

I have been able to run the exe in the file that I downloaded.  You did a great job.

I really wasn't expecting you to take this problem as far as you did but am grateful for your effort.

I did not see the Source Code, didn't know if this was just an oversight or what you intended.

Just a few suggestions to make it exactly what is needed. With the source code, I could make the changes that I have outlined below. I could put it together with the code snippets that you furnished earlier.

In the Picture box control properties -
AutoSize = True - this will show the form in its actual size - wilth the scroll bar that would make it easy to position the red box exactly where it needs to be in order to capture the coordinates.
BackColor &H00FFFFFF& (white) would help also.

Just back ground information - all of the various forms that I would be capturing the information are designed for 6 lines per inch, and 80 columns (characters) per line or 10 characters per inch.
The forms are all letter size.

For the program using the coordinate information - Using the Courier New font which is a fixed length font. , by knowing the distance in inches from beginning to end of each text box, I know how many characters will fit in the box, so I can set the maximum characters property for each text box.

Here is the format of the text file that the other program currently uses to determine how to position (move) the various text boxes in the text box array that is created for entering information on the form.
The program that is used to populate the various forms, reads a text file with the file number corresponding to the form selected by the operator.  For example, the file for the form 001XXA11.WMF
that I provided earlier would be 001XXA11.TXT. There is a record in the text file for each field.  By first counting the number of records in the file, I am able to create the text box array on the form from one initial text box placed on the form at design time, then using the move command I position each text box over the underlying wmf form.  Actually, the program uses an ocx from the "Component One" tool box suite, .

The first number is the field number, second is field length, third is column (x coordinate in inches), fourth is the line # (y coordinate in inches).

example of the first few records in one of the text files for the corresponding form #.
The first item designated 1 is 10 positions long, beginning in column 69 on line 4.

Don't know how much trouble it would be to create this file.  In the program that you have written
the first click (upper left) would give the line number and beginning column # for the particular text box, then the second click would give the difference in beginning and ending position of the text box.
Looks like the values now are maybe in twips.

This may be too much trouble for you to do this extra work.
Having the source code, I could make the changes to create the file exactly as the subsequent program is currently expecting the data.

One other thing that I think would make it a little easier would be to reduce the size of the red box, maybe around 1/6 inches in heigth. Also 1/6 inches in width.

With the above items and the scroll bars, this will make the project to crreate the data for the new versions of the Acord forms much, much easier, saving several hours of programming time.

Just let me know if any of the above information needs further clarification.

Hope you are having a good trip on your visit.  I looked at a map of Australia.  That is a long trip.

Thanks, Morris
morrisboAuthor Commented:

Just wanted to bring you up to date on my project while you were on your trip.  Hope it was a pleasant trip for you.

I took the basic concept we have been working with, with a few changes.

Basically, I added a vertical scroll bar using the basic MC tool to a form to the right of a picture box where the acord wmf form is placed, with max scroll property of 5000, min 0.  This allowed the form to scroll just enough so that we can see the whole wmf picture.

I used the mouse up event to record the beginning position of each box on the wmf form using the left mouse button, then also used the mouse up event and the right mouse button to mark the end of the end of the field.

Then I converted twips to inches and computed the line and column info in inches, and also calculated the field length (difference in ending position and beginning position of mouse).  I also printed a "B" followed by the field number just to the right of the "B" and printed an "E" to signify the end of the field.

Also added a routine to enable a "restart" at any point to correct misplaced information previously placed on the form. Used the picture.cls then repopulated data prior to restart field information placed in the restart text box.

When form population is complete, the Close button then writes out a record for each item previously stored in an array as data was being marked. I used the Acord WMF file name with ext .txt vice .wmf.

I am including code snippets if you are interested.

I have tested the program using actual acord wmf forms and it seems to work ok.  

I took the text file created in this special program and placed it in the program using the data generated here.  It works ok.  

I am attaching an word document containing a few images as well as code snippets.

Thanks for your help.  Just wanted to let you know my progress, so that you wouldn't spend time in my earlier suggestions.

Thanks again for your assistance with this project.


'Command button on start up form (Form1.frm)
Private Sub cmdStart_Click()
   Load Form2
   Dim FileName As String
   FileName = "002XXA11.WMF"
   Dim PictureFileName As String
   PictureFileName = App.Path & "\" & FileName
   Form2.lblFileName = FileName
   Form2.Picture1.Picture = LoadPicture(PictureFileName)
   Form2.Show vbModal
End Sub

'Declarations for Form2.frm
Option Explicit
Dim Itm As Long
Dim Lne As Long
Dim Cl1 As Long
Dim Cl2 As Long
Dim Ln As Long
Dim TwipsLne As Long
Dim Itms() As String
Dim YTwipsButton1() As Long
Dim XTwipsButton1() As Long

Dim YTwipsButton2() As Long
Dim XTwipsButton2() As Long

Dim LastButton As String

Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
  Dim x1 As Long
  Dim y1 As Long
  Dim Item As String
If Button = 1 Then
    If LastButton = "1" Then
       Exit Sub
   End If
End If

If Button = 2 Then
   If LastButton <> "1" Then
      Exit Sub
   End If
End If

x1 = x
y1 = y
Me.Picture1.CurrentX = x1
Me.Picture1.CurrentY = y1

If Button = 1 Then
   LastButton = "1"
   Lne = y1 \ 240
   TwipsLne = Lne * 240
   Me.Picture1.CurrentY = TwipsLne
   Cl1 = x1 \ 144
   Me.Picture1.CurrentX = Cl1 * 144
   Me.Picture1.Print "B" & Trim(Str(Itm + 1))
End If

If Button = 2 Then
  LastButton = "2"
  Cl2 = x1 \ 144
  Ln = Cl2 - Cl1
  If Ln < 1 Then Ln = 1
  Me.Picture1.CurrentY = TwipsLne
  Me.Picture1.CurrentX = Cl2 * 144
  Me.Picture1.Print "E"
  Itm = Itm + 1
  ReDim Preserve YTwipsButton2(Itm)
  YTwipsButton2(Itm) = Lne * 240
  ReDim Preserve YTwipsButton1(Itm)
  YTwipsButton1(Itm) = Lne * 240
  ReDim Preserve XTwipsButton2(Itm)
  XTwipsButton2(Itm) = Cl2 * 144
  ReDim Preserve XTwipsButton1(Itm)
  XTwipsButton1(Itm) = Cl1 * 144
  ReDim Preserve Itms(Itm)
  Dim PCl1 As Long
  PCl1 = Cl1 - 3
  If PCl1 = 0 Then PCl1 = 1
  Dim PLne As Long
  PLne = Lne + 1
  Item = Itm & "," & Ln & "," & PCl1 & "," & PLne
  Itms(Itm) = Item
End If

End Sub

'command button on Form2

Private Sub cmdClose_Click()
Dim x As Long
Dim Response As Integer
Dim FileName As String
Dim FName As String
FName = Me.lblFileName
Dim p As Long
p = InStr(FName, ".")
Mid(FName, p + 1, 3) = "txt"
FileName = App.Path & "\" & FName
Response = MsgBox("Write out file", vbYesNo)
If Response = vbYes Then
   Open FileName For Output As #1
   For x = 1 To Itm
      Print #1, Itms(x)
   Next x
   Close #1
   Printer.FontSize = 12
   For x = 1 To Itm
     Printer.Print Itms(x)
   Next x
End If
Unload Me
End Sub
'Restart command button on Form2 to restart at a previous item

Private Sub cmdRestart_Click()
   If Me.txtRestart = "" Then
      MsgBox "Must enter restart item #"
      Exit Sub
   End If
   Dim x As Long
   For x = 1 To Val(Me.txtRestart.Text)
      Me.Picture1.CurrentY = YTwipsButton1(x)
      Me.Picture1.CurrentX = XTwipsButton1(x)
      Me.Picture1.Print "B" & Trim(Str(x))

      Me.Picture1.CurrentY = YTwipsButton2(x)
      Me.Picture1.CurrentX = XTwipsButton2(x)
      Me.Picture1.Print "E"
   Next x
   ReDim Preserve Itms(x)
   ReDim Preserve YTwipsButton1(x)
   ReDim Preserve XTwipsButton1(x)
   ReDim Preserve YTwipsButton2(x)
   ReDim Preserve XTwipsButton2(x)
   Itm = x - 1
   LastButton = "2"
End Sub

Open in new window

Chris Raisin(Retired Analyst/Programmer)Commented:
Looks great.
Glad to see your nice enhancements.
Happy coding!
Chris Raisin(Retired Analyst/Programmer)Commented:
Did you want any further help wiith this question or is everything working fine now?
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.