PDA

View Full Version : Word Window Focus



james4189
09-06-2015, 10:32 PM
I have a document that contains a Rich Text Content Control. I show a form when it is clicked with:

Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If ContentControl.Title = "MaxPointsA" Then
frmMaxPoints.Show
frmMaxPoints.txtboxMaxPoints.SetFocus
End If
End Sub

When the user clicks the cancel button on the form, it hides it with:


' this extra sub for hiding was just so I could place all of my testing code in one place
' while I was trying to get it to work.
Private Sub HideForm()
frmMaxPoints.Hide
End Sub

Private Sub btnCancel_Click()
Call HideForm
End Sub

What I want is to be able to have the form hidden & be able to immediately click the content control again & have it reshow the form (strictly for oops I made a mistake & need to change it moments). As it stands I have to click out of the content control, somewhere else on the document, and then click the content control to get it to appear.

I search a lot for an answer and have tried what little I found with no luck.
I've tried these, suggestions I found, after hiding the form:


' This Did nothing
Word.Application.Activate

' This Moved the cursor, but the word window did not have focus so I still had to click twice.
' Once to set focus to the word app and again to click the content control.
Selection.MoveDown

' This allowed the word app to regain focus after the form was hidden,
' but I still had to click out of the content control & back in.
' setting ShowModal to false



These two together made it work, but only when I click the cancel button & just hide the form.


' setting ShowModal to false
Selection.MoveDown

If the user clicks accept it runs

Private Sub btnAccept_Click()
SetPointScales txtboxMaxPoints

Call HideForm
End Sub

SetPointScales loops through a table (about 40 rows) and places a number in the first cell & a date in the second.

Clicking accept the cursor does move out of the content control, but the word app does not regain focus after the form hides so I still have to click the content control twice. Once for word to regain focus & again to click the content control.

Any ideas what I'm doing wrong?

gmayor
09-07-2015, 12:06 AM
The main problem is the line

frmMaxPoints.txtboxMaxPoints.SetFocuswhich keeps the focus in the userform until it is unloaded (which with your code it never is). If you remove that line and change the cancel code to
Private Sub btnCancel_Click()
Dim oRng As Range
Dim oCC As ContentControl
For Each oCC In ActiveDocument.Range.ContentControls
If Selection.InRange(oCC.Range) Then
Set oRng = oCC.Range
oRng.End = oRng.End + 1
oRng.Collapse 0
Exit For
End If
Next oCC
Me.Hide
oRng.Select
Exit Sub
End Sub


It works as I believe you intended.

gmaxey
09-07-2015, 04:58 AM
Where it is located, your SetFocus line is pointless. In a modal userform, code execution is halted in a procedure at the .Show command and doesn't resume until the form is hidden or unloaded. To see this for yourself, but a msgbox line between your .Show and set focus lines.

So, move the set focus line before the .Show.


Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
If ContentControl.Title = "MaxPointsA" Then
frmMaxPoints.txtboxMaxPoints.SetFocus
frmMaxPoints.Show
End If
End Sub

I think Graham and I both assume you realize that since your trigger is the CC on enter event, that in order to redisplay th form as you described, you will have to exit the CC. His code and mine collapse the selection to a point just after the CC.

You might as well deal with the "X" click while you are at it.





Private Sub btnCancel_Click()
Dim oRng As Range
'Eliminates loop but assumes the CC MaxPointsA is a single unit titled CC.
Set oRng = ActiveDocument.SelectContentControlsByTitle("MaxPointsA").Item(1).Range
oRng.End = oRng.End + 1
oRng.Collapse wdCollapseEnd
oRng.Select
Hide
lbl_Exit:
Exit Sub
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Cancel = True
btnCancel_Click
End If
lbl_Exit:
Exit Sub
End Sub

james4189
09-07-2015, 01:07 PM
Thank you both for your help. I still had another problem, but after pointing out my mistake calling .SetFocus in the wrong place


frmMaxPoints.Show
frmMaxPoints.txtboxMaxPoints.SetFocus

I was able to figure it out and get it working. Thanks for your help!

It does leave me with two questions though if you don't mind answering.
In my accept button I was running this:


Private Sub btnAccept_Click()
If Not IsNumeric(txtboxMaxPoints.Value) Then
MsgBox "You must enter a valid number.", vbCritical
GoTo ErrorHandling
End If

If txtboxMaxPoints.Value < 0 Then
MsgBox "Maximum Points must be greater than 0.", vbCritical
GoTo ErrorHandling
End If

SetPointScales txtboxMaxPoints
Call HideForm

ErrorHandling:
ClearMaxPointsTxtBox
Exit Sub

End Sub

ClearMaxPointsTxtBox (sets focus back to the textbox) was running after the form was hidden which was apparently another reason word did not have focus.
I copied that idea of handling error checking off of some site I read somewhere. From what I had read I , apparently misunderstood and, thought that the ErrorHandling: section of code only ran if called with GoTo ErrorHandling. Otherwise I thought it was just skipped over. I'm guessing now that this is not the way it works and I probably should have had my own Exit Sub before the ErrorHandling: section?

Also in gmaxey's code, what does this do?


lbl_Exit:
Exit Sub


I see no call for anything like GoTo lbl_Exit. I'm guessing this also has something to do with my misunderstanding of the GoTo ErrorHandling. But if that code always gets run (his Exit Sub), what is the point in calling Exit Sub, when its the last line of code in the sub and its going to exit anyhow...or do Exit Sub & End Sub do different things (other than the fact that you can call Exit Sub anywhere in a sub)?

gmaxey
09-07-2015, 02:48 PM
James,

First ...
lbl_Exit:
Exit Sub
End Sub

Is just my coding style and in practically every procedure I write. Pointless here really, but if you were handling actual errors correctly then you might have code like this:

lbl_Exit:
Exit Sub
Err_Handler:
ClearMaxPointsTxtBox
Resume lbl_Exit
End Sub

I am not a fan of after the fact validation. If I were you, I would disable the btnAccept command button until txtPointsMaxValue was numeric and greater than 0. Use the keypress evaluate and allow only numeric entries, use the change event to validate value > 0.

james4189
09-07-2015, 03:14 PM
I get it now, your lbl_Exit is there to stop the other areas of code under it from running. We just didn't have any in that first example of code.
I didn't even think about validating it as they type like you suggested. Good idea.

Thanks very much for the help!

gmaxey
09-07-2015, 06:32 PM
James,

You weren't really handling an error in your code. The fact that text isn't numeric or a value less than 1 is not an error. You could have named your GoTo label practically anything e.g., GoTo TheMiddleOfNextWeek

For more see: http://gregmaxey.mvps.org/word_tip_pages/error_handling_101.html