Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Keep Notepad on top

Status
Not open for further replies.

ZOR

Technical User
Jan 30, 2002
2,963
GB
I am shelling to use notepad. It gets text put on it from the application, however if a user clicks away from Notepad, Notepad hides under the application. Any way of making it take command until its closed? Thanks
 
Basically you need to use the 'SetWindowPos' API call to set Notepad's window z-order to 'TOPMOST.'

The shell() function only provides you with the 'HInstance' of the application, so you have to convert the HInstance to a valid HWnd before you use the SetWindowPos API. Here's how:
Code:
'********************
'    GETWINDOW CONSTANTS
'********************
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GWW_HINSTANCE = (-6)

'********************
'     SETWINDOWPOS CONSTANTS
'********************
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOMOVE = &H2                   
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOZORDER = &H4
Public Const SWP_FRAMECHANGED = &H20
Public Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_NOCOPYBITS = &H100
Public Const SWP_NOOWNERZORDER = &H200
Public Const SWP_NOREDRAW = &H8
Public Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Public Const SWP_SHOWWINDOW = &H40
Public Const SWP_HIDEWINDOW = &H80

Public Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" _
  (ByVal hWnd As Long, lpdwprocessid As Long) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
  (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public 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

'@--------------------------------------------------------@

Sub NoteIt()
  Dim hInstance As Long
  Dim hWnd As Long
  Dim lngErr As Long
  
  hInstance = shell("NotePad.exe ""C:\Boot.ini""", vbNormalFocus)
  hWnd = GetWinHandle(hInstance)
  
  lngErr = _
   SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE) 
 
End Sub

@---------------------------------------------------------@

Function ProcIDFromWnd(ByVal hWnd As Long) As Long
  Dim idProc As Long
  
  ' Get PID for this HWnd
  GetWindowThreadProcessId hWnd, idProc
  
  ' Return PID
  ProcIDFromWnd = idProc
End Function

@---------------------------------------------------------@
      
Function GetWinHandle(hInstance As Long) As Long
  Dim tempHwnd As Long
  
  ' Grab the first window handle that Windows finds:
  tempHwnd = FindWindow(vbNullString, vbNullString)
  
  ' Loop until you find a match or there are no more window handles:
  Do Until tempHwnd = 0
     ' Check if no parent for this window
     If GetParent(tempHwnd) = 0 Then
        ' Check for PID match
        If hInstance = ProcIDFromWnd(tempHwnd) Then
           ' Return found handle
           GetWinHandle = tempHwnd
           ' Exit search loop
           Exit Do
        End If
     End If
  
     ' Get the next window handle
     tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
  Loop
End Function
VBSlammer
redinvader3walking.gif
 
I don't think that will be enough for what he needs. It sounds like he's using sendkeys (or something similer) so even if notepad is on top of all other apps it can still loose focus even if it's only to the taskbar. I'm sure there's away to stop that from happening too but I can't think of it off the top of my head.
 
Many thanks VBSlammer for taking so much time to put an answer together, and thanks misery347 for the comments. I was using sendkeys to set fonts etc. I was running some code which populated the notepad page. Problems were Notepad dissapearing from view causing multiple instances of Notepad being generated to fulfil the requirements. So there is still a possibilty with VBSlammers excellent code it may still vanish?. Any comments from VBSlammer on this please, thanks again
 
Your best bet would be to write your data to a file before opening notepad and then just open the newly created file in the same call you make to 'shell' since SendKeys can't guarantee where it is sending your keystrokes.

If you're relying on mulitple calls to SendKeys to write data to an open instance of notepad, you will definitely run into problems because you can't predict what users are going to do while your code is running. If you can't write the info to file first, you're limited to 255 characters per SendKeys call.

If you're getting multiple instances of notepad you have more problems than just the focus issue. However, once you figure out how to properly shell notepad (single instance), you can still use SetWindowPos more than once if necessary to force topmost z-order because you have access to the HWnd of its window.

VBSlammer
redinvader3walking.gif
 
Thanks VBSlammer,points taken. I will do what you suggest and put the data in a temp file. Its a shame I cannot find an easy way to make my application sleep off screen while Notepad is shown. Although maybe I could minimize my app or run a batch file to do something. Anyway thanks for your help. Regards
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top