-
Feb 21st, 2012, 10:51 AM
#1
Thread Starter
Member
Need help getting form window to top and active
I'm self-taught in VB macros in Word and Excel, and I dabble a bit in VB6 (Classic, not NET). I'm not at all up on APIs, relying on slurping from the internet.
I have a one-form program that works fine. I use it at church to pull up songs. I can type in the name or the first line of a song, and it searches a folder and pulls up the song as Word doc. At that point, the form is resized to about height of a Title bar and about 2" wide.
After opening the Word doc, I can use Me.SetFocus and Me.Text1.SetFocus to bring the form back on top and deactivate the Word window. This does two things: it allows me to close the Word doc by simply typing a 0, and it keeps me from accidentally typing in the doc.
But if the mouse gets clicked and the Word doc gets the focus, I'm kinda dead! I can get the form window on top of the Word window, but I can't make the form or VB the active application. I've got a timer in the form that keeps checking to see if there's an active Word doc object (just in case the doc gets accidentally closed); if not, it restores the form to full size. I'm trying to get it so if there is a doc object, then ensure VB and the form are on top and active.
Any help with this?
Ed
-
Feb 21st, 2012, 01:04 PM
#2
Re: Need help getting form window to top and active
Here is some old code I used to use back in VB5 should do the trick
You will need to add this code to a module in your project or create a new module for it.
Code:
Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Const HWND_TOP = 0
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
Public Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
Public Sub StayOnTop(the As Form)
Dim setwinontop
setwinontop = SetWindowPos(the.hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
End Sub
The in your form code you will need something like
-
Feb 21st, 2012, 01:09 PM
#3
Re: Need help getting form window to top and active
You may want to add a check box or menu item to toggle the functionality. Here is a simple example, just copy the API declarations to the top of your form, then copy the subroutine towards bottom of your form. No Timers needed
Code:
' API declaration
Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
' the subroutine
Private Sub MakeTopMost(bSet As Boolean)
Const SWP_NOSIZE As Long = &H1
Const SWP_NOMOVE As Long = &H2
Const HWND_TOPMOST As Long = -1
Const HWND_NOTOPMOST As Long = -2
If bSet Then
SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
Else
SetWindowPos Me.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End If
End Sub
In your form_load, simply call MakeTopMost True
Edited: Beat to the punch I see
-
Feb 21st, 2012, 02:20 PM
#4
Thread Starter
Member
Re: Need help getting form window to top and active
Thanks for the replies. But I've done this. And a bunch more - ActiveWindow, SetFocus etc. (Sorry - I'm on another computer right now and I don't have the code with me. Actually, though, I've deleted all the codes that didn't work.)
I can get the VB form window to be on top, but I can't get it to be the active application with Word in the background. I thought I saw an AppActivate in my searching, but it wouldn't compile in my form module, Maybe that's dot-net??
But anything I do from within the form module when Word is the active app just makes the form's notifier on the bottom flash until I click on it, and Word stays as the active application, although it's stacked behind the form.
Ed
-
Feb 21st, 2012, 02:40 PM
#5
Re: Need help getting form window to top and active
Have you tried simply adding a in a timer? Or
Code:
AppActivate (Me.Caption)
Either should pull your app to the front and give it focus at any time.
-
Feb 21st, 2012, 03:33 PM
#6
Thread Starter
Member
Re: Need help getting form window to top and active
Originally Posted by DataMiser
Have you tried simply adding a in a timer? Or
Code:
AppActivate (Me.Caption)
Either should pull your app to the front and give it focus at any time.
Yah, I tried both. The SetFocus just makes the app notification on bottom flash. The AppActivate wouldn't compile.
I'll get the code later when I get back to the other computer and I'll post what I have. Like I said, I've deleted a lot of stuff that just didn't work.
Oh - this is with Word 2000 and XPSP3.
Ed
-
Feb 21st, 2012, 05:43 PM
#7
Re: Need help getting form window to top and active
Originally Posted by Ed_from_AZ
Yah, I tried both. The SetFocus just makes the app notification on bottom flash. The AppActivate wouldn't compile.
I'll get the code later when I get back to the other computer and I'll post what I have. Like I said, I've deleted a lot of stuff that just didn't work.
Oh - this is with Word 2000 and XPSP3.
Ed
I am confused. Where did you put this code? In a word doc or in a VB app?
-
Feb 21st, 2012, 02:42 PM
#8
Re: Need help getting form window to top and active
You'll probably need to show us some code
-
Feb 21st, 2012, 04:12 PM
#9
Re: Need help getting form window to top and active
I tried both methods here and both methods worked just fine in XPSP3. No matter what application I had running in fact I had to stop the program before I could type this message because it would grab focus away every second.
-
Feb 21st, 2012, 04:50 PM
#10
Re: Need help getting form window to top and active
Ed
A shot in the dark here (as an alternative in the
event the other suggestions don't pan out) ..
.. is there some way to bring the Word doc "into"
your VB6 app .. ie, place it in some sort of control?
I'm thinking out loud here ..
- maybe in a RichTextbox control?
- something else?
My thinking is that if it is all "contained" on your Form,
your "inadvertant" issues would evaporate.
Unfortunately, I just don't know enough about Word docs
and VB6 forms to be of any real help. Hopefully, others
will have more ideas.
Spoo
-
Feb 21st, 2012, 06:30 PM
#11
Thread Starter
Member
Re: Need help getting form window to top and active
Spoo: I didn't mess with a Rich Text box because I didn't want to import the doc or cause any changes to the formatting, etc; I just wanted to open the doc. (It was all fine as long as it was just me using this and I could work around all my bad code! But now I gotta share and the other person isn't as into it all as I am.)
DataMiser: All code is in a VB form; nothing is in a Word doc. I just mentioned my Word and Windows versions in case something there made a difference in what was happening.
Ed
-
Feb 21st, 2012, 10:24 PM
#12
Re: Need help getting form window to top and active
Ed
Fair enough.
It belatedly occurred to me that the "something" else
might be a WebBrowser control.
Maybe something like this will suffice ...
Code:
Dim myFile As String
myFile = "c:\myWord.doc"
With WebBrowser1
.Top = 100
.Left = 100
.Height = 5000
.Width = 12000
.Visible = True
.Navigate2 myFile
End With
I just tried it and it works, except for the File Download
dialogue box that comes up.
I clicked Open and it seems fine. But, I don't work enough
with the WebBrowser control to know how to prevent this
message or how to automatically deal with it.
Maybe someone else does.
Anyway.. perhaps this is a usable alternative.
EDIT
I should also add that it "doesn't work" if the file is already
open.
You get the same dialogue box, but after clicking Open,
"nothing" seems to happen... ie, the WebBrowser control
does not get populated.
So, some additional code will be needed to see if the file
is open somewhere else on the desktop.
Spoo
Last edited by Spoo; Feb 21st, 2012 at 10:40 PM.
-
Feb 22nd, 2012, 08:59 AM
#13
Thread Starter
Member
Re: Need help getting form window to top and active
Okay - finally, here's some chunks of my code. (I tried posting this last night, but my phone wouldn't cooperate!) The whole purpose of this app is to let me type in a word or phrase from a song and open the Word doc for that song. All the song docs are in one folder. Because they are songs, they have certain font and style settings that I didn't want to risk affecting by opening them in anything other than Word. There should never be more than one doc open at a time, and there are no other apps running other than VB and Word. Also, I only have the learning edition, so this is not a compiled exe - but it still works, except for my one problem.
On Load, the form reads through a doc and populates drop-down boxes. There's also a test field that lets me type in words and phrases. Using these, I'm able to specify a certain Word doc I want opened. I can then key in a number from 1 to 8 or Shift+1 to 8 and open that doc; when the doc opens, the form shrinks and moves to the upper left. If I type a zero, the doc closes and the form resets.
That's why I'm trying so hard to keep the VB form and app on top and active. If the mouse gets clicked and the Word doc becomes the active app (even if the VB form is the top-most window), if I type the 0 the doc doesn't close. A CTRL+W to close then brings up the dialog about "Do you want to save changes?", and it's just something I don't need.
I've included the declarations, the Text1_KeyPress sub that opens a doc, and the timer routine where I'm trying to stick the code to put the VB app on top and active. But anything I try just makes the VB taskbar button flash until I click it.
vb Code:
Private m_clsCombo1 As clsControlCombo
Private m_clsCombo2 As clsControlCombo
Private m_clsCombo3 As clsControlCombo
Private m_clsCombo4 As clsControlCombo
Private m_clsCombo5 As clsControlCombo
Private m_clsCombo6 As clsControlCombo
Private Declare Function GetActiveWindow Lib _
"user32" () As Integer
Private Declare Function SetActiveWindow Lib _
"user32" (ByVal HWnd As Long) As Integer
Private Declare Function GetForegroundWindow Lib _
"user32" () As Long
Private Declare Function SetForegroundWindow Lib _
"user32" (ByVal HWnd As Long) As Integer
Private Declare Function SetWindowPos Lib _
"user32" (ByVal HWnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare Function FindWindow Lib _
"user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetClassName Lib _
"user32" Alias "GetClassNameA" _
(ByVal HWnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Dim appWd As Word.Application
Dim doc As Word.Document
Dim rng As Word.Range
Dim aryTlb() As String
Dim cntTlb As Integer
Dim aryFT() As String
Dim aryFL() As String
Dim aryFC() As String
Dim aryST() As String
Dim arySL() As String
Dim arySC() As String
Dim arySongs(100) As String
Dim cntSongs As Integer
Dim x As Integer
Dim bolChgMe As Boolean
Dim bolNoSong As Boolean
Dim bolTwoMon As Boolean
Dim bolSongCls As Boolean
Dim bolFirstLet As Boolean
Dim XX
Dim frmTop As Long
Dim frmLeft As Long
Dim ScreenArea 'As RECT
Dim MyHwnd
''
Private m_clsCombo1 As clsControlCombo
Private m_clsCombo2 As clsControlCombo
Private m_clsCombo3 As clsControlCombo
Private m_clsCombo4 As clsControlCombo
Private m_clsCombo5 As clsControlCombo
Private m_clsCombo6 As clsControlCombo
Private Declare Function GetActiveWindow Lib _
"user32" () As Integer
Private Declare Function SetActiveWindow Lib _
"user32" (ByVal HWnd As Long) As Integer
Private Declare Function GetForegroundWindow Lib _
"user32" () As Long
Private Declare Function SetForegroundWindow Lib _
"user32" (ByVal HWnd As Long) As Integer
Private Declare Function SetWindowPos Lib _
"user32" (ByVal HWnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare Function FindWindow Lib _
"user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetClassName Lib _
"user32" Alias "GetClassNameA" _
(ByVal HWnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Dim appWd As Word.Application
Dim doc As Word.Document
Dim rng As Word.Range
Dim aryTlb() As String
Dim cntTlb As Integer
Dim aryFT() As String
Dim aryFL() As String
Dim aryFC() As String
Dim aryST() As String
Dim arySL() As String
Dim arySC() As String
Dim arySongs(100) As String
Dim cntSongs As Integer
Dim x As Integer
Dim bolChgMe As Boolean
Dim bolNoSong As Boolean
Dim bolTwoMon As Boolean
Dim bolSongCls As Boolean
Dim bolFirstLet As Boolean
Dim XX
Dim frmTop As Long
Dim frmLeft As Long
Dim ScreenArea 'As RECT
Dim MyHwnd
'
'************
'
Private Sub Text1_KeyPress(KeyAscii As Integer)
XX = KeyAscii
Dim idx
Dim strList As String
Dim strFile As String
If KeyAscii = 48 Then ' Typed zero, close top Word doc
'Stop
If appWd.Documents.Count > 0 Then
appWd.Documents(1).Close
bolSongCls = True
GoTo SongClosed
End If
End If
If KeyAscii < 33 Then Exit Sub
If KeyAscii > 95 Then Exit Sub
If KeyAscii > 64 And KeyAscii < 91 Then Exit Sub
If Me.Text1.Text = "" Then bolNoSong = True
If InStr(1, Me.Text1.Text, "=") > 0 Then bolNoSong = True
Select Case XX
Case 33 'SHIFT+1 = Fast Title
If bolNoSong = True Then GoTo NoSong
idx = Me.Label7.Tag
strFile = aryFT(idx + 1, 2)
Case 64 'SHIFT+2 = Fast Line
If bolNoSong = True Then GoTo NoSong
idx = Me.Label9.Tag
strFile = aryFL(idx + 1, 2)
Case 35 'SHIFT+3 = Fast Chorus
If bolNoSong = True Then GoTo NoSong
idx = Me.Label8.Tag
strFile = aryFC(idx + 1, 2)
Case 36 'SHIFT+4 = Slow Title
If bolNoSong = True Then GoTo NoSong
idx = Me.Label10.Tag
strFile = aryST(idx + 1, 2)
Case 37 'SHIFT+5 = Slow Line
If bolNoSong = True Then GoTo NoSong
idx = Me.Label12.Tag
strFile = arySL(idx + 1, 2)
Case 94 'SHIFT+6 = Slow Chorus
If bolNoSong = True Then GoTo NoSong
idx = Me.Label11.Tag
strFile = arySC(idx + 1, 2)
Case 49 '1 = Fast List #1
strFile = aryFT(Me.Combo7.ListIndex + 1, 2)
Case 50 '2 = Fast List #2
strFile = aryFT(Me.Combo8.ListIndex + 1, 2)
Case 51 '3 = Fast List #3
strFile = aryFT(Me.Combo9.ListIndex + 1, 2)
Case 52 '4 = Offering
strFile = aryFT(Me.Combo10.ListIndex + 1, 2)
Case 53 '5 = Slow List #1
strFile = aryST(Me.Combo11.ListIndex + 1, 2)
Case 54 '6 = Slow List #2
strFile = aryST(Me.Combo12.ListIndex + 1, 2)
Case 55 '7 = Slow List #3
strFile = aryST(Me.Combo13.ListIndex + 1, 2)
Case 56 '8 = Slow List #4
strFile = aryST(Me.Combo14.ListIndex + 1, 2)
End Select
SongClosed:
KeyAscii = 0
Me.Text1.Text = ""
'Stop
'If Word app is gone, reset app object
Err.Clear
On Error Resume Next
Dim tstAppName As String
tstAppName = appWd.Name
On Error GoTo 0
If tstAppName = "" Then
Set appWd = New Word.Application
End If
tstAppName = ""
If bolSongCls = True Then
bolSongCls = False
If bolTwoMon = True Then
SearchMe.SetFocus
SearchMe.Text1.SetFocus
End If
GoTo NoSong
End If
'Stop
If strFile <> "" Then
cntSongs = cntSongs + 1
arySongs(cntSongs) = strFile
strFile = Chr(34) & strFile & Chr(34)
Set doc = appWd.Documents.Open(FileName:=strFile, Visible:=True)
'doc.AttachedTemplate = Chr(34) & "C:\Documents and Settings\Ed\My Documents\FindSongs\SongsTempl.dot" & Chr(34)
appWd.ActiveWindow.WindowState = wdWindowStateMaximize
appWd.ActiveWindow.View = wdPrintView
'''appWd.ActiveWindow.View.Zoom.Percentage = 92
'''appWd.ActiveWindow.View.Zoom.Percentage = 130
doc.ActiveWindow.ActivePane _
.Zooms(wdPrintView).PageFit = wdPageFitFullPage
bolFirstLet = True
Else
'MsgBox "No file"
End If
If bolTwoMon = False Then
'Set form to go back
frmTop = SearchMe.Top
frmLeft = SearchMe.Left
SearchMe.Top = 3
SearchMe.Left = 3
SearchMe.Height = 1
SearchMe.Width = 5000
SearchMe.Caption = "Close song by typing 0 (zero)."
End If
Timer1.Enabled = True
Timer1.Interval = 600
If strFile <> "" Then
On Error Resume Next
appWd.Visible = True
AppActivate appWd.Caption
appWd.Windows(1).Activate
On Error GoTo 0
appWd.Windows(1).View.TableGridlines = False
appWd.Windows(1).DisplayRulers = False
appWd.Windows(1).View.ShowAll = False
doc.ShowGrammaticalErrors = False
doc.ShowSpellingErrors = False
appWd.Windows(1).SmallScroll Down:=3
'If bolTwoMon = True Then
SearchMe.SetFocus
SearchMe.Text1.SetFocus
'End If
End If
NoSong:
bolNoSong = False
End Sub
Private Sub Timer1_Timer()
Dim tstDocName As String
' Check to see if a Word doc exists
On Error Resume Next
Set doc = appWd.Documents(1)
tstDocName = doc.Name
'If no Word doc, restore form
If Err.Number <> 0 Then
Timer1.Enabled = False
Set doc = Nothing
'Bring app to front
appWd.Visible = False
SearchMe.Top = frmTop
SearchMe.Left = frmLeft
SearchMe.Height = 12075
SearchMe.Width = 10980
SearchMe.Caption = "Search Song List"
'''SearchMe.Visible = True
SearchMe.SetFocus
SearchMe.Text1.SetFocus
Else
'If a Word doc exists, ensure form has focus
Call SetWindowPos(MyHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE)
Call SetActiveWindow(MyHwnd)
'SearchMe.SetFocus
'AppActivate ("FindMySong")
If bolTwoMon = False Then _
doc.Windows(1).Activate
End If
On Error GoTo 0
End Sub
-
Feb 22nd, 2012, 09:27 AM
#14
Re: Need help getting form window to top and active
Code:
'AppActivate ("FindMySong")
Try
Code:
AppActivate(Me.Caption)
Could this be your problem that makes it flash?
Code:
If bolTwoMon = False Then _
doc.Windows(1).Activate
End If
-
Feb 23rd, 2012, 08:46 AM
#15
Thread Starter
Member
Re: Need help getting form window to top and active
Originally Posted by DataMiser
Could this be your problem that makes it flash?
Code:
If bolTwoMon = False Then _
doc.Windows(1).Activate
End If
Commented this out
Originally Posted by DataMiser
Code:
'AppActivate ("FindMySong")
Try
Code:
AppActivate(Me.Caption)
No joy! The task bar and the form title bar just flash.
Looks like it's time to see about a second form with a full-screen WebBrowser control.
Ed
-
Feb 22nd, 2012, 10:24 AM
#16
Thread Starter
Member
Re: Need help getting form window to top and active
Thank you very much!! I'll have to wait until later to try those, and I'll let you know what happens.
So I had the AppActivate syntax wrong, eh?? Knew it would be something simple!
And all the bolTwoMon stuff should have been commented out. I'll have to fix that. (Originally, this was just me on my laptop, and I had thought to try an external monitor so I could leave the form open on one and pull up songs on the other. Now we do have two monitors, but they're clones showing the same thing.)
Ed
-
Feb 22nd, 2012, 01:05 PM
#17
Re: Need help getting form window to top and active
Ed
Glad you and DataMiser have worked things out.
So, now that your "deck" is sufficiently cleared, you
might be in a better position to try the alternative
I mentioned.
Regarding your concern ..
Because they are songs, they have certain font and
style settings that I didn't want to risk affecting by
opening them in anything other than Word.
.. I'll mention in passing that the WebBrowser control
- preserves all font and style settings
- preserves all highlighted text (colors)
- preserves all graphics
- automatically includes scroll bars
Basically, it looks and feels just like Word itself.
Spoo
-
Feb 22nd, 2012, 02:06 PM
#18
Thread Starter
Member
Re: Need help getting form window to top and active
Thank you, Spoo. Obviously, I've never delved that far into this. The WebBrowser control might be a good alternative, especially if it loads faster! :8>)
Ed
-
Feb 23rd, 2012, 09:25 AM
#19
Re: Need help getting form window to top and active
Ed
In that case, you might want to take a look at this thread
http://www.vbforums.com/showthread.php?t=673141
Guess which thread was "another thread" ..
Spoo
-
Feb 23rd, 2012, 10:41 AM
#20
Thread Starter
Member
Re: Need help getting form window to top and active
Yah - saw that thread as I was scoping out the WebBrowser control.
I'm sure I will have some questions to add to it!!
Won't have a chance until this weekend, though.
Ed
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|