[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now


Moving other application's windows

Posted on 2003-11-05
Medium Priority
Last Modified: 2010-05-01
I have an application that's a Shell App bar that runs at the top of the screen.

We have a poorly written app that we use for our customer database... problem is, this application slowly moves upwards in increments at screen resolutions of 1024x768 or higher for some reason. Eventually, it works its way underneath my app bar.

So, I want my app bar to "bump" windows down X pixels if they take over (or under technically) its space. I'll probably fire it when a user moves their mouse over my App Bar or even clicks it; I think I'd need to scan for all open windows, and if their window hwnd is within the top X pixels, bump them down Y pixels...

Here's the abstract code of what I'm trying to do:

Sub MoveWindowsAtTheTop()
    For Each Window that's not maximized
        If The Top Position of the Window is within X pixels of the top of the screen Then
            Move this window down Y pixels
        End If
End Sub

I'm no API expert and I can't get past Enumerating Unmaximized, open windows. I would think I would need to use EnumWindows ; IsWindowVisible() ; GetWindowText ; GetWindowRect ; ClientToScreen ; ScreenToClient ; MoveWindow ; SetWindowPos.

Can anyone convert this to real, working VB6 code (NOT using .NET!)?
Question by:TWCMIL
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 17

Expert Comment

ID: 9694066
When you create an AppBar, the desktop "space" is reserved so nothing can get in the way. You need to set the window position (SetWindowPos) of your AppBar window to z-order top so nothing is able to go above the window.

>> this application slowly moves upwards in increments at screen resolutions of 1024x768 or higher for some reason

I suggest you resolve that issue instead of looking for a solution such as what you asked for. If you'd still like an example of enumerating through all maximized windows, I can come up with something.

Accepted Solution

lmckenzie earned 1200 total points
ID: 9694157
I'm no API expert by any means either but I tried this and it seems to work on my system.  Assuming you have a list of window handles, pass each one to the MoveUnderlappedWindow function.  If the top of the window is less than the limit you set, it will be moved by the amount you specify in lngOffset.  If it's only the DB app's window that causes problems, use the FindWindow api call to get it's handle rather than enumerating all of them.  You could also use the GetWindowRect on your own appiication's window to get it's bottom position and use that instead of the top of screen offset

Option Explicit

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function IsZoomed Lib "user32" (ByVal hwnd As Long) As Long

Private Function MoveUnderlappedWindow(lngHandle as long)

Dim lngHandle As Long
Dim AppRect As RECT
Dim lngTop As Long
Dim lngHeight As Long
Dim lngLeft As Long
Dim lngWidth As Long
Dim lngResult As Long
Dim lngOffset As Long
Dim lngUpperLimit as long

lngUpperLimit = 'Whatever position you want to keep windows below
lngOffset = 10 'Choose how far below you want to move them

    If CBool(IsZoomed(lngHandle)) = vbFalse Then 'Window not maximized
        lngResult = GetWindowRect(lngHandle, AppRect) 'Get the window's position
        lngHeight = AppRect.Bottom - AppRect.Top
        lngWidth = AppRect.Right - AppRect.Left
        lngLeft = AppRect.Left
        lngTop = AppRect.Top
            If AppRect.Top < lngUpperLimit Then 'Is it underlapped?
                lngTop = lngUpperLimit + lngOffset
                lngResult = MoveWindow(lngHandle, lngLeft, lngTop, lngWidth, lngHeight, True)
            End If
    End If
End Function

Expert Comment

ID: 9694615
    If the database app is so "poorly written", you would probably be better off rewriting it in VB.  If the app is encountering such severe problems, how trustworthy is the data being manipulated by it? VB is very string at communicating with databases.

    Just a thought.


Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 9697911
Well I've tried this:

I like the philosophy that zzzzzooc has... fix my app instead of messing with others, but from my expiriments, it's not possible to prevent every window from moving above a point on the screen. I did add the SetWindowPos() code but the problem is the application would be under the App Bar, not over it. For some reason the DB application thinks it can go under the App Bar. Quite frankly I can manually drag anything under it... it's just that this DB app strangely moves up all by itself.

I'd love to get rid of this DB application, but it's not feasible... we paid $120K+ for it, and it's a GUI front-end of our AS400, and re-training 700+ employees is just not going to happen.

I think I'll stick with the original request... lmckenzie is on track, but since my Windows API knowledge is pretty much non-existent, I just need the code to get a list of window handles so I can pass it to the function lmckenzie posted above to close & award points.
LVL 17

Assisted Solution

zzzzzooc earned 800 total points
ID: 9699336
Something such as the below should work. Just put it together quickly so it might need tweaking.


Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Private Const GW_HWNDNEXT = 2
Private Sub Form_Load()
    Dim ColWindows As New Collection, iLoop As Integer
    Call ListWindows(ColWindows)
    For iLoop = 1 To ColWindows.Count
        Debug.Print ColWindows.Item(iLoop) 'This is the window handle
    Next iLoop
    Set ColWindows = Nothing
End Sub
Private Function ListWindows(ByRef ColWindows As Collection)
    Dim lHandle As Long
    lHandle = FindWindow(vbNullString, vbNullString)
    Do Until lHandle = 0
        ColWindows.Add lHandle
        lHandle = GetWindow(lHandle, GW_HWNDNEXT)
End Function

Author Comment

ID: 9699709
The combo of the 2 worked beautifully.

Thanks for all the help... points given for code writers!

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question