Changing the "Working Area" of a screen.

I am trying to develop an application that will act a bit like a second taskbar, in that it will resize the working area of a screen so that maximised applications do not cover over it, or simply get hidden behind it. Examples of applications that use this would be things such as Desktop Sidebar or JetToolbar. I am trying to develop the application in Visual Basic 2005 Express Edition (using the .NET Framework 2.0). I have found how to get the current working area, but despite extensive searching I have not found a way to change it. Is this possible in Visual Basic

Answer this question

Changing the "Working Area" of a screen.

  • Paul Raj

    Oi, my brain just isn't with me today... VB.NET code you say... try the code midway down this page.

  • Rania

    Thank you very much for your tip, but I was referring to the working area of the screen, not my form. The working area of the screen is the are not taken up by the taskbar etc., and seems to dictate the size of maximised programs. Some applications seem able to change it though, so that windows does not try and use the parts of the screen that they display in when a program is maximised. Also, allow me to clarify: when I said "or simply get hidden behind it" in my original question, I was stating that I did not want this to happen, on reading it again it seems ambiguos to me.
  • Darren Tao

    Well done, Brendan. I haven't tested it yet, but It seems to match all the C# etc. code I've seen, well done, and thanks.
  • ChupaChupa

    I'll guess that that has the right code, although I can't say that I can see it, on account of not having either A: an account there or B: a credit card to buy an account with
  • keithster

    Let me paste the post in question:

    Imports System
    Imports System.Drawing
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports System.Data
    Imports System.Runtime.InteropServices

    Public Class Form1
    Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

    Public Sub New()
    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
    If Not (components Is Nothing) Then
    components.Dispose()
    End If
    End If
    MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    Me.Button1 = New System.Windows.Forms.Button()
    Me.SuspendLayout()
    '
    'Button1
    '
    Me.Button1.Location = New System.Drawing.Point(72, 80)
    Me.Button1.Name = "Button1"
    Me.Button1.Size = New System.Drawing.Size(80, 40)
    Me.Button1.TabIndex = 0
    Me.Button1.Text = "Close"
    '
    'Form1
    '
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.ClientSize = New System.Drawing.Size(292, 266)
    Me.Controls.Add(Me.Button1)
    Me.Name = "Form1"
    Me.Text = "Form1"
    Me.ResumeLayout(False)

    End Sub

    #End Region

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    RegisterBar()
    End Sub

    Structure RECT
    Public left As Integer
    Public top As Integer
    Public right As Integer
    Public bottom As Integer
    End Structure 'RECT


    Structure APPBARDATA
    Public cbSize As Integer
    Public hWnd As IntPtr
    Public uCallbackMessage As Integer
    Public uEdge As Integer
    Public rc As RECT
    Public lParam As IntPtr
    End Structure 'APPBARDATA
    Enum ABMsg

    ABM_NEW = 0
    ABM_REMOVE = 1
    ABM_QUERYPOS = 2
    ABM_SETPOS = 3
    ABM_GETSTATE = 4
    ABM_GETTASKBARPOS = 5
    ABM_ACTIVATE = 6
    ABM_GETAUTOHIDEBAR = 7
    ABM_SETAUTOHIDEBAR = 8
    ABM_WINDOWPOSCHANGED = 9
    ABM_SETSTATE=10

    End Enum
    Enum ABNotify

    ABN_STATECHANGE = 0
    ABN_POSCHANGED
    ABN_FULLSCREENAPP
    ABN_WINDOWARRANGE

    End Enum
    Enum ABEdge

    ABE_LEFT = 0
    ABE_TOP
    ABE_RIGHT
    ABE_BOTTOM
    End Enum

    Private fBarRegistered As Boolean = False

    Public Declare Function SHAppBarMessage Lib "shell32.dll" Alias "SHAppBarMessage" (ByVal dwMessage As Integer, ByRef pData As APPBARDATA) As System.UInt32
    Public Declare Function GetSystemMetrics Lib "User32.dll" Alias "GetSystemMetrics" (ByVal index As Integer) As Integer
    Public Declare Function MoveWindow Lib "User32.dll" Alias "MoveWindow" (ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal repaint As Boolean) As Boolean
    Private Declare Auto Function RegisterWindowMessage Lib "User32.dll" (ByVal msg As String) As Integer
    Private uCallBack As Integer

    Private Sub RegisterBar()
    Dim abd As New APPBARDATA()
    abd.cbSize = Marshal.SizeOf(abd)
    abd.hWnd = Me.Handle
    If Not fBarRegistered Then
    uCallBack = RegisterWindowMessage("AppBarMessage")
    abd.uCallbackMessage = uCallBack

    Dim ret As System.UInt32 = SHAppBarMessage(CInt(ABMsg.ABM_NEW), abd) 'ToDo: Unsigned Integers not supported
    fBarRegistered = True

    ABSetPos()

    Else
    SHAppBarMessage(CInt(ABMsg.ABM_REMOVE), abd)
    fBarRegistered = False
    End If
    End Sub 'RegisterBar


    Private Sub ABSetPos()
    Dim abd As New APPBARDATA()
    abd.cbSize = Marshal.SizeOf(abd)
    abd.hWnd = Me.Handle
    abd.uEdge = CInt(ABEdge.ABE_TOP)

    If abd.uEdge = CInt(ABEdge.ABE_LEFT) Or abd.uEdge = CInt(ABEdge.ABE_RIGHT) Then
    abd.rc.top = 0
    abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height
    If abd.uEdge = CInt(ABEdge.ABE_LEFT) Then
    abd.rc.left = 0
    abd.rc.right = Size.Width
    Else
    abd.rc.right = SystemInformation.PrimaryMonitorSize.Width
    abd.rc.left = abd.rc.right - Size.Width
    End If

    Else
    abd.rc.left = 0
    abd.rc.right = SystemInformation.PrimaryMonitorSize.Width
    If abd.uEdge = CInt(ABEdge.ABE_TOP) Then
    abd.rc.top = 0
    abd.rc.bottom = Size.Height
    Else
    abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height
    abd.rc.top = abd.rc.bottom - Size.Height
    End If
    End If

    ' Query the system for an approved size and position.
    SHAppBarMessage(CInt(ABMsg.ABM_QUERYPOS), abd)

    ' Adjust the rectangle, depending on the edge to which the
    ' appbar is anchored.
    Select Case abd.uEdge
    Case CInt(ABEdge.ABE_LEFT)
    abd.rc.right = abd.rc.left + Size.Width
    Case CInt(ABEdge.ABE_RIGHT)
    abd.rc.left = abd.rc.right - Size.Width
    Case CInt(ABEdge.ABE_TOP)
    abd.rc.bottom = abd.rc.top + Size.Height
    Case CInt(ABEdge.ABE_BOTTOM)
    abd.rc.top = abd.rc.bottom - Size.Height
    End Select

    ' Pass the final bounding rectangle to the system.
    SHAppBarMessage(CInt(ABMsg.ABM_SETPOS), abd)

    ' Move and size the appbar so that it conforms to the
    ' bounding rectangle passed to the system.
    MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, True)
    End Sub 'ABSetPos


    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If m.Msg = uCallBack Then
    Select Case m.WParam.ToInt32()
    Case CInt(ABNotify.ABN_POSCHANGED)
    ABSetPos()
    End Select
    End If

    MyBase.WndProc(m)
    End Sub 'WndProc


    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
    Get
    Dim cp As CreateParams = MyBase.CreateParams
    cp.Style = cp.Style And Not &HC00000 ' WS_CAPTION
    cp.Style = cp.Style And Not &H800000 ' WS_BORDER
    cp.ExStyle = &H80 Or &H8 ' WS_EX_TOOLWINDOW | WS_EX_TOPMOST
    Return cp
    End Get
    End Property

    Private Sub End_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    RegisterBar()
    End
    End Sub
    End Class



  • ashish1482

    Your form’s WorkingArea property is directly related to the form’s Size property, the primary difference being the Working area is the Size minus the form borders, title bars and what not.

    If you increase your form’s Size (or just it’s Length or Width), the WorkingArea will increase as well.



  • landre3567

    Thanks again for the help, and this looks to hit the nail on the head, although it is only in C++ and C# which I have never tried using before, and so I am now looking again for help, but am probably nearer as I now know I should be registering as an appbar instead of tring to resize the workingarea.
  • dwebb

    Oopsie. I had suspected that... but didn’t persue it...

    When it comes to doing this sort of thing for the entire screen... instead of changing the working area directly, I believe that you would register your window/app as an appbar. Try this tutorial for information on that.



  • Changing the "Working Area" of a screen.