Solved

Moving other application's windows

Posted on 2003-11-05
6
318 Views
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
    Next
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!)?
0
Comment
Question by:TWCMIL
[X]
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
6 Comments
 
LVL 17

Expert Comment

by:zzzzzooc
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.
0
 
LVL 1

Accepted Solution

by:
lmckenzie earned 300 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
0
 
LVL 9

Expert Comment

by:Dang123
ID: 9694615
TWCMIL,
    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.

Dang123


0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:TWCMIL
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.
0
 
LVL 17

Assisted Solution

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


Form1:

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)
        DoEvents
    Loop
End Function
0
 
LVL 1

Author Comment

by:TWCMIL
ID: 9699709
The combo of the 2 worked beautifully.

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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
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…

688 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