Resolved Is the task bar visible or not ?

Gloops

Well-known member
Joined
Jun 30, 2022
Messages
104
Programming Experience
10+
Context
In an application that shows the state of the cursor (regarding mainly the caps lock) to the user of a laptop, a previous version was planed with two places allocated on the screen to avoid staying under the mouse cursor, then the click through notion reduced the necessity to move the form.
Then appeared the notion of changing FormBorderStyle to hide the title bar.
The new version is able to be displayed in the status bar of an application.
A further concern remains: the application that has the focus can be displayed full screen, meaning that the Windows task bar is not displayed. The coordinates to display the state of the keyboard must be adjusted accordingly.

Hello everybody,
I want to display the state of the keyboard on the status bar of the active application. For this, I have to take into account whether the application is displayed full screen, in which case the status bar of the application is down the screen, otherwise it is above the task bar.

My first idea to get this information, is to pick a point down the screen, and then ask what program opened the window at that point.

My reasoning is that if my point is on the task bar, the associated program is explorer. Then, I shall probably have to take care of the case of an explorer window displayed full screen.

So, I want to know what program opened the window three pixels above the middle of the down side of the screen.

To position my form, I have a function that contains:
part of the function that positions the form:
                int dpix = (int)graphics.DpiX / 96;
                int dpiy = (int)graphics.DpiY / 96;

So, I am tempted to make an infringement to the rule of "one responsibility, one function", and to optimize a little the code by avoiding to declare these values again.
Maybe, I should put them at the module level.

C#:
        private void PositionsForm()
        {
            using (Graphics graphics = this.CreateGraphics())
            {
                int dpix = (int)graphics.DpiX / 96;
                int dpiy = (int)graphics.DpiY / 96;

                // Here, the instructions that position the form
            
                pt = new Point
                    (
                        Screen.PrimaryScreen.Bounds.Width * dpix / 2,
                        Screen.PrimaryScreen.Bounds.Height * dpiy - 3
                    );
            }
        }

One thing done. Of course the point is declared at the module level.

On my screen dimensioned 1920x1080, my point is at x=960, y=1077. Somewhere behind the shortcuts to the applications.

In the timer_Tick I have this:
Trying to get the associated module with the window under the point:
            PositionsForm();
            IntPtr hWnd = WindowFromPoint(pt);
            uint ret = GetWindowModuleFileName(hWnd, sbfileName, 2000);
            string strApp = sbfileName.ToString();
            Debug.Print(String.Format("The application down the screen is {0}", strApp));

sbfileName is a StringBuilder declared at the module level.

And ... It displays an empty string, which to code properly I should have detected by ret=0.

So, did I choose a bad point, or is my reasoning false?
One precision: hWnd is not null.

Just an out-of-topic aparte: in PositionsForm I can get hdc=graphics.GetHdc;
 
Last edited:
Solution
Got it !
I placed my point more to the left, x=10, and instead of GetWindowModuleFileName I use GetWindowText.

If the title of the window under the point is the title of the Start button, then the task bar is displayed, I position my form down PrimaryScreen.WorkingArea, else the task bar is not visible, I position my form down PrimaryScreen.Bounds.

And by the way I corrected the objection concerning declaring the point in PositionsForm, as the point is needed for a correct positioning of the form. A good part of the code I quoted is transferred to PositionsForm, and the lines I mentioned concerning the positioning of the form are rejected at the end of PositionsForm, after the exploitation of the point.

Two...

Gloops

Well-known member
Joined
Jun 30, 2022
Messages
104
Programming Experience
10+
Got it !
I placed my point more to the left, x=10, and instead of GetWindowModuleFileName I use GetWindowText.

If the title of the window under the point is the title of the Start button, then the task bar is displayed, I position my form down PrimaryScreen.WorkingArea, else the task bar is not visible, I position my form down PrimaryScreen.Bounds.

And by the way I corrected the objection concerning declaring the point in PositionsForm, as the point is needed for a correct positioning of the form. A good part of the code I quoted is transferred to PositionsForm, and the lines I mentioned concerning the positioning of the form are rejected at the end of PositionsForm, after the exploitation of the point.

Two improvements appear possible of this (I think I forgot a third one):
  • support an external screen
  • support an international deployment: getting the local title for the Start button
So, for my immediate needs it is OK, the first point I mentioned could be useful in a few months, and the international deployment can be interesting for a complete treatment of the question, in case somebody interested reads this.
 
Solution

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,469
Location
Chesapeake, VA
Programming Experience
10+
Why even try to figure out if the taskbar is visible or not? Wouldn't it be simpler to call GetForeGroundWindow() to find out which window the user is currently using. With that window handle, call GetWindowRect() on that window handle to find out that window's bounds. Now that you know that window's bounds, you place your status UI within those bounds. If that window happens to be full screen and overlapping the taskbar, you are placed at the correct position. If that window in maximized not overlapping the taskbar, or any other size in between, you are still the correct size.

Also assuming that the taskbar is at the bottom of the screen is an assumption you can only make on Windows 11. With Win95 through Windows 10, the taskbar can be placed left, right, top, or bottom. Additionally, the taskbar can be at the bottom or top and be some number of rows tall.
 

Gloops

Well-known member
Joined
Jun 30, 2022
Messages
104
Programming Experience
10+
Hello,
Well, I am still on Windows 10. I guessed that Microsoft was able to do worse for Windows 11, so I am not even disappointed.
You are right about the task bar that can be displayed on other edges of the screen. But I just made a test with the task bar on the right. Firefox in full screen hides the task bar on the right. Its status bar stays at the same place, and the Caps indicator is on it. But the Scroll indicator is not visible, it is hidden by the Windows task bar —thus, only if Firefox is not displayed full screen (supposing it is the active application). Curiously, I do not have that problem with the task bar on the left.
Seeing the dimensions of the active application has the interest to be simple. That being said, I was careful about another application displayed on the front, while Firefox is displayed full screen in the back.
I am going to see with the user whether she prefers following the active application, or having the Caps indicator at a stable position. She sometimes has difficulties to even know what application is active, although I took care to affect different colors to the title bars, so the experience of support leads me to think that the most stable is the best. Aesthetically, it is more beautiful on a status bar of an application. For the ease of use, it is not certain. I have got to think about that Scroll indicator that can be hidden by the task bar on the right. Putting the application a little more to the left is a simple solution, but knowing that a clock will be positioned on the left, this hides not far from the half of the Firefox status bar, where the URL of a hovered link is displayed. Repositioning the clock when the indicators are off can solution this, at the price of something sophisticated, and perhaps it is better to avoid being too sophisticated.

EDIT: in fact the labels were too far from each other. I have brought them closer and integrated the clock, I can leave a margin on the right for the task bar, and I have more than three quarters of the status bar free. I shall add a key to hide the application, for when you hover a link with a long URL.
 
Last edited:
Top Bottom