Sign in to follow this  

[Win32 C++] Obtain Dimensions of Taskbar Failing

This topic is 2571 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello

I am trying to use the win32 function SHAppBarMessage() to get the position/dimensions of the startbar/taskbar. This function returns true that the function worked when I use it BUT the RECT that I am meant to receive the dimensions into does not get updated.

I think it may have to do with the fact that I need to get the HWND to the taskbar, but first of all I am not sure that this is the reason the function is not working & second I have searched & searched & I cannot find a way to get a handle to the taskbar window?

What do you think is going wrong? And how do you think I can fix this?


Code to get the taskbar dimensions:

RECT barRect;
APPBARDATA barData;

barData.cbSize = sizeof(APPBARDATA);
barData.hWnd = hwnd;
barData.uCallbackMessage = 0;
barData.uEdge = 0;
barData.rc = barRect;
barData.lParam = (LPARAM) 0;

BOOL fResult = (BOOL) SHAppBarMessage( ABM_GETTASKBARPOS, &barData );

// See if the values are the bar data or even changed
cout << "Result from function call: " << fResult << endl;
cout << "rect.left: " << barRect.left << endl;
cout << "rect.right: " << barRect.right << endl;
cout << "rect.top: " << barRect.top << endl;
cout << "rect.bottom: " << barRect.bottom << endl << endl;




Full app

/*
Application:
*/


#include <iostream>
#include <windows.h>
#include <Shellapi.h>
#include <string>
#include <cstdlib>

using namespace std;

static HINSTANCE gInstance;


// Functions List //
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE gInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;


wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = gInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(DKGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "Custom Class";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

// if registration of main class fails
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}


hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"Custom Class",
"App Name",
WS_CAPTION|WS_MINIMIZEBOX|WS_VISIBLE|WS_OVERLAPPED|WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 500,
NULL, NULL, gInstance, NULL);

if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);


while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

switch(msg)
{
case WM_CREATE:
case WM_LBUTTONDOWN:
{
RECT barRect;
APPBARDATA barData;

barData.cbSize = sizeof(APPBARDATA);
barData.hWnd = hwnd;
barData.uCallbackMessage = 0;
barData.uEdge = 0;
barData.rc = barRect;
barData.lParam = (LPARAM) 0;

// See what are barRects default values
cout << "rect.left: " << barRect.left << endl;
cout << "rect.right: " << barRect.right << endl;
cout << "rect.top: " << barRect.top << endl;
cout << "rect.bottom: " << barRect.bottom << endl << endl;

BOOL fResult = (BOOL) SHAppBarMessage( ABM_GETTASKBARPOS, &barData );

// See if the values are the bar data or even changed
cout << "Result from function call: " << fResult << endl;
cout << "rect.left: " << barRect.left << endl;
cout << "rect.right: " << barRect.right << endl;
cout << "rect.top: " << barRect.top << endl;
cout << "rect.bottom: " << barRect.bottom << endl << endl;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}




Share this post


Link to post
Share on other sites
barData.rc = barRect;

barData.rc is not a pointer - you're assigning barRect to it, which is uninitialised

You then SHAppBarMessage which updates the contents of barData correctly, including the field barData.rc, but then you're expecting barRect to contain the coords. It's data is still uninitialised.

Share this post


Link to post
Share on other sites
Ah thanks :)

So stupid of me :P to not recognise that

I have another question to do with repositioning the windows start/taskbar.

From what I have read on msdn I believe the only thing I need to do to reposition the taskbar to, say, the right border of the screen is define a APPDATA struct with the necessary vars initialised then call SHAppBarMessage() with ABM_SETPOS (but doing ABM_QUERYPOS is first is more polite I know).

Is this a correct way to reposition the taskbar or is there more things to do? I ask because if you look at my code below it should reposition the taskbar to the right border of the screen but the taskbar stays where it is?

Can you suggest where I am going wrong?


RECT barRect;
APPBARDATA barData;
SetRect( &barRect, 1310, 10, 1350, 740 ); // My screen dimensions are 1360 by 768

/*
// 1st method to obtain handle to taskbar
HWND hDesktop = GetDesktopWindow();
HWND hShellTray = FindWindowEx( hDesktop, NULL, ("Shell_TrayWnd"), NULL );
HWND hReBar = FindWindowEx( hShellTray, NULL, ("ReBarWindow32"), NULL );
*/


// 2nd method
HWND hTaskbar = ::FindWindow( ("Shell_TrayWnd"), NULL );


barData.cbSize = sizeof(APPBARDATA);
barData.hWnd = hTaskbar;
barData.uCallbackMessage = 0;
barData.uEdge = ABE_RIGHT;
barData.rc = barRect;
barData.lParam = (LPARAM) FALSE;

// The right side of my desktop is empty so this should allow me to move my taskbar right?
BOOL fResult = (BOOL) SHAppBarMessage( ABM_QUERYPOS, &barData ); // Get system to verify & suggest position
fResult = (BOOL) SHAppBarMessage( ABM_SETPOS, &barData ); // Set position
fResult = (BOOL) SHAppBarMessage( ABM_WINDOWPOSCHANGED, &barData ); // Inform ??? that the taskbar pos has been changed

// Debugging
/* fResult = (BOOL) SHAppBarMessage( ABM_ACTIVATE, &barData );
// fResult = (BOOL) SHAppBarMessage( ABM_GETTASKBARPOS, &barData );

// See the bar data has moved logically which is never does
cout << "Result from function call: " << fResult << endl;
cout << "rect.left: " << barData.rc.left << endl;
cout << "rect.right: " << barData.rc.right << endl;
cout << "rect.top: " << barData.rc.top << endl;
cout << "rect.bottom: " << barData.rc.bottom << endl << endl; */


Share this post


Link to post
Share on other sites
http://us.generation-nt.com/answer/how-programmatically-move-windows-taskbar-help-37077862.html

This may not work in Vista or Windows 7 though. If it doesn't try running without UAC.

Share this post


Link to post
Share on other sites
Probably not helping, but be careful, Raymond Chen might want to put your app on his blog ;)

Also, HWND hTaskbar = ::FindWindow( ("Shell_TrayWnd"), NULL ); is just bound to break sooner or later once the shell is modified in a newer Windows version. Don't do that.



What reason does your app/game have to reposition MY task bar?

Share this post


Link to post
Share on other sites
Is Raymond Chen the guy who answers all the general windows questions on the msdn forum?

@taz0010 thanks for the link :) But as you said, (I think) it doesn't work in windows 7, also it appears that in windows vista the taskbar will move but then go back to where it was after a couple of seconds.

Surely the SHAppBarMessage() with ABM_SETPOS must work? The link attempts to do it another way(get a handle to the taskbar then SetWindowPos() it).

Anyway, I agree theres no reason at all for an app to move the taskbar (unless I create & register my own taskbar ;) ) but I came across the SHAppBarMessage() function & have been fidling around with all the messages.

Share this post


Link to post
Share on other sites
no suggestions on how to get SHAppBarMessage( ABM_SETPOS, .... ); to work?

I would really appreciate any advice (maybe using this message doesn't work in Windows 7, although I haven't found any documentation on msdn that suggests so).

Share this post


Link to post
Share on other sites

This topic is 2571 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this