Hack Forums
[.NET] Basic Windows Shell - Printable Version

+- Hack Forums (https://hackforums.net)
+-- Forum: Tech (https://hackforums.net/forumdisplay.php?fid=444)
+--- Forum: Coding (https://hackforums.net/forumdisplay.php?fid=151)
+---- Forum: Software Development (https://hackforums.net/forumdisplay.php?fid=118)
+---- Thread: [.NET] Basic Windows Shell (/showthread.php?tid=4512734)



Basic Windows Shell - Blixuk - Oct 29, 2014

So I hacked this together using a few different things. It works, but not beautifully at all. I thought I would share it and see if anyone could clean it up and improve on the whole thing.

This is a basic Windows Shell.
It can display all open windows and allow you select and open them as well as allowing you to minimizes them and bring them back.
This also removes the current window shell and makes a new shell location at the top of the screen. This also allows for windows to full screen without over lapping your shell.

You will need two classes that I will add here one for the Windows API and another for the Functions.

Functions.
Code
Imports System.Windows.Forms
Imports System.Diagnostics
Imports System.Collections

Public Class Functions

    Structure WindowData
      Public hwnd As IntPtr
      Public title As String
    End Structure

#Region "Private variables"
    Private Shared m_rcOldDesktopRect As WinAPI.RECT
    Private Shared m_hTaskBar As IntPtr
#End Region

    'Resizes the Desktop area to our shells' requirements
    Public Shared Sub MakeNewDesktopArea()
      ' Save current Working Area size
      m_rcOldDesktopRect.left = SystemInformation.WorkingArea.Left
      m_rcOldDesktopRect.top = SystemInformation.WorkingArea.Top
      m_rcOldDesktopRect.right = SystemInformation.WorkingArea.Right
      m_rcOldDesktopRect.bottom = SystemInformation.WorkingArea.Bottom

      'Make a new Workspace
      Dim rc As WinAPI.RECT
      rc.left = SystemInformation.VirtualScreen.Left
      'We reserve the 24 pixels on top for our taskbar
      rc.top = SystemInformation.VirtualScreen.Top + 25
      rc.right = SystemInformation.VirtualScreen.Right
      rc.bottom = SystemInformation.VirtualScreen.Bottom
      WinAPI.SystemParametersInfo(CInt(WinAPI.SPI.SPI_SETWORKAREA), 0, rc, 0)
    End Sub

    'Restores the Desktop area
    Public Shared Sub RestoreDesktopArea()
      WinAPI.SystemParametersInfo(CInt(WinAPI.SPI.SPI_SETWORKAREA), 0, m_rcOldDesktopRect, 0)
    End Sub

    'Hides the Windows Taskbar
    Public Shared Sub HideTaskBar()
      ' Get the Handle to the Windows Taskbar
      m_hTaskBar = WinAPI.FindWindow("Shell_TrayWnd", Nothing)
      ' Hide the Taskbar
      If CInt(m_hTaskBar) <> 0 Then
      WinAPI.ShowWindow(m_hTaskBar, CInt(WinAPI.WindowShowStyle.Hide))
      End If
    End Sub

    'Show the Windows Taskbar
    Public Shared Sub ShowTaskBar()
      If CInt(m_hTaskBar) <> 0 Then
      WinAPI.ShowWindow(m_hTaskBar, CInt(WinAPI.WindowShowStyle.Show))
      End If
    End Sub

    'Gets a list of Active Tasks
    Public Shared Function GetActiveTasks() As ArrayList
      Dim ar As New ArrayList()
      Dim child As IntPtr = IntPtr.Zero

      Dim process__1 As Process() = Process.GetProcesses()
      For Each p As Process In process__1
      Dim w As WindowData
      If p.MainWindowHandle <> IntPtr.Zero AndAlso p.MainWindowTitle.Length > 0 Then
            w.hwnd = p.MainWindowHandle
            w.title = p.MainWindowTitle
            ar.Add(w)
      End If
      Next
      Return ar
      ar.Clear()
    End Function

End Class

WinAPI.
Code
Imports System.Text
Imports System.Runtime.InteropServices

Public Class WinAPI

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

    Public Structure PointAPI
      Public x As Integer
      Public y As Integer
    End Structure

    Public Structure WindowPlacement
      Public Length As Integer
      Public Flags As Integer
      Public showCmd As Integer
      Public MinPosition As PointAPI
      Public MaxPosition As PointAPI
      Public NormalPosition As RECT
    End Structure

    'ShowWindow
    Public Enum WindowShowStyle As Integer
      Hide = 0
      ShowNormal = 1
      ShowMinimized = 2
      ShowMaximized = 3
      Maximize = 3
      ShowNormalNoActivate = 4
      Show = 5
      Minimize = 6
      ShowMinNoActivate = 7
      ShowNoActivate = 8
      Restore = 9
      ShowDefault = 10
      ForceMinimized = 11
    End Enum

    Public Const HSHELL_WINDOWCREATED As Integer = 1
    Public Const HSHELL_WINDOWDESTROYED As Integer = 2
    Public Const HSHELL_WINDOWACTIVATED As Integer = 4

    'SystemParametersInfo
    Public Enum SPI As Integer
      SPI_SETWORKAREA = &H2F
      SPI_GETWORKAREA = &H30
    End Enum

    Private Declare Function GetWindowPlacement Lib "user32" (ByVal hwnd As Integer, ByRef lpwndpl As WindowPlacement) As Integer

    <DllImport("user32.dll", SetLastError:=True)> _
    Public Shared Function SystemParametersInfo(ByVal uiAction As UInteger, ByVal uiParam As UInteger, ByRef pvParam As RECT, ByVal fWinIni As UInteger) As Boolean
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function ShowWindow(ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As Boolean
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, _
   ByVal uFlags As UInteger) As Boolean
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Public Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Public Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Public Shared Sub SwitchToThisWindow(ByVal hWnd As IntPtr, ByVal fAltTab As Boolean)
    End Sub

    <DllImport("user32.dll")> _
    Public Shared Function SetTaskmanWindow(ByVal hWnd As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function RegisterShellHookWindow(ByVal hWnd As IntPtr) As Integer
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function RegisterWindowMessage(ByVal lpString As String) As Integer
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function DeregisterShellHookWindow(ByVal hWnd As IntPtr) As Boolean
    End Function

End Class

I'm not going to go in detail about them.
Ok, so here's how to use them to create our Shell.

You need 2 Forms One is just a Launcher and isn't required but helps for testing.
The second is the shell itself.

The Launcher is really simple. You don't need anything on this at all so make it really small. Just make sure you can use the exit button. Open this form up and add a Form Load and a Form Closing event.

In the form closing event we will add 2 lines of code. These function calls will allow us to reset everything back to how it was when we close the shell.
Code
Functions.RestoreDesktopArea()
Functions.ShowTaskBar()

In the form load event we will add this code. Just 4 lines to start us off. We have to function calls, one to hide the current task bar and another to create our new desktop working area. After this we need to display our shell.
Code
Application.EnableVisualStyles()

Functions.HideTaskBar()
Functions.MakeNewDesktopArea()

BasicShell.Show()

Once we have all that done on to making the Shell.
Create a new form and call it whatever you like. There is a few things you will need to do to set this form up. In the form properties make these changes.
FormBoarderStyle = None
Size = 600, 25
ShowInTaskbar = False

You will also need to add some controls to this form.
A Button call it whatever you like this will act as our start button.
A ComboBox this is going to be a our tab/window control. Call this 'windowList'
You will also need to ListBox's call one liveList and the other updateList. Make sure both of them are not visible on the form.
Visible = False.
You can add a label if you like, you can use to display the current time.
Last add a Timer control and Enable it.

Ok now for the code.

Imports. We need to make a few Imports first.
Code
Imports BasicShell.Functions
Imports System.Runtime.InteropServices
Imports System.Text

In the form load event you will need to add this line of code.
What this does is set's our form position and makes sure we are in set location for the shell.
This all so extends our shell across the screen as well as setting the hight. to the 25px we set on the form.
Code
WinAPI.SetWindowPos(Me.Handle, 0, 0, 0, SystemInformation.VirtualScreen.Width, 25, &H40)

Create an event for windowList SelectedIndexChanged, then add this code to the event.
What we are doing here is allowing the user to be able to select a window and display it.
Code
Dim windowName As String = windowList.Text
Dim handle As IntPtr = WinAPI.FindWindow(Nothing, windowName)
WinAPI.ShowWindow(handle, 1)
WinAPI.SetForegroundWindow(handle)

Now create an event for our timer Tick, then add this code here.
What this code does is updates the items in our windowList by checking if they are still open or if they have closed. By using the 2 listbox's we can avoid a constant update of the list. This way is will check before adding new items or removing old ones.
Code
timeLbl.Text = TimeOfDay
Dim ar As ArrayList = GetActiveTasks()
updateList.Items.Clear()
liveList.Items.Clear()
      For i As Integer = 0 To ar.Count - 1
      Dim w As WindowData = DirectCast(ar(i), WindowData)
      liveList.Items.Add(w.title)
      If windowList.Items.Contains(w.title) Then

      Else
            windowList.Items.Add(w.title)
      End If
      Next

      For Each item In windowList.Items
      updateList.Items.Add(item)
      Next

      For Each item In updateList.Items
      If Not liveList.Items.Contains(item) Then
            windowList.Items.Remove(item)
      End If
      Next

That's basically it. If you can improve on it let me know. It's really messy and poorly coded.
It could do with removing the timer and using threading. It could also use a better method for handling the the window update. Like I said this was hacked together.


* - nuk - Oct 29, 2014

Just curious... by "hacked together"; what you're really saying is Copy&Pasted?


* - Blixuk - Oct 29, 2014

No not at all. Yeah I read up some different stuff here and there. I converted a small tutorial I found from C# to VB. The tutorial only covered some of the concept and used a different method to display the windowList. I copied the WinAPI and also added some stuff. When I say hacked together I mean like taking one thing and changing it and adding stuff to get it to work how I want. There isn't anything really covered on this in VB. But I didn't just C&P something and post it here claiming I made it all. Like I said I'm sharing because maybe someone can use it and improve on it.


* - $lick - Oct 29, 2014

(Oct 29, 2014 06:57 AM)nuk Wrote:  Just curious... by "hacked together"; what you're really saying is Copy&Pasted?

I can't find anything from google that's a direct copy/paste...


* - nuk - Oct 29, 2014

Okay that sweet then.... I was just wondering if that's what you meant is all ;) I shall check this out good sir and give a proper review :) Sorry if it seemed like I was accusing you of C/P ;)


* - Blixuk - Oct 29, 2014

It's perfectly fine. I know there is a lot of C&P on here. Thanks for taking the time to read it. I can add source or images if need be.