Novah
Novah

Reputation: 90

Qt 5.5 MSVC 2013. Trouble getting the Windows System Tray geometry

I am trying to get the Windows System Tray geometry:

    RECT rect;//Rect System Tray
    HWND taskBar = FindWindow(L"Shell_traywnd", NULL);//Error
    if(taskBar && GetWindowRect(taskBar, &rect))//Error
    //...

But the compiler MSVC 2013 64 bit extradite errors:

Window.obj:-1: error: LNK2019: a reference to the unresolved external symbol __imp_GetWindowRect in the function "private: class QRect __cdecl Window::availableGeometry(bool const &)" (?availableGeometry@Window@@AEAA?AVQRect@@AEB_N@Z)
Window.obj:-1: error: LNK2019: a reference to the unresolved external symbol __imp_FindWindowW in the function "private: class QRect __cdecl Window::availableGeometry(bool const &)" (?availableGeometry@Window@@AEAA?AVQRect@@AEB_N@Z)

If I use MinGw 32 bit, compiler does not extradite errors. Please tell me what is the problem. Thanks in advance. I use Qt 5,5 on Windows 8.1.

Upvotes: 0

Views: 385

Answers (1)

phyatt
phyatt

Reputation: 19112

Basically, MingW doesn't have the symbols loaded for those libraries.

MSVC might have them already... but even MSVC doesn't include all the libraries at times, especially uncommon ones. But you can get around it by explicitly loading the libraries yourself. I've done this a number of times using QLibrary and the MSDN documentation.

You need to copy the header file information for the functions you are using, and load the symbol and typecast it as the function you are using. I'll post a code sample shortly.

So for the first one: GetWindowRect, you can find it under:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx

BOOL WINAPI GetWindowRect(
  _In_  HWND   hWnd,
  _Out_ LPRECT lpRect
);

Note that on the bottom of the page it mentions which header file it is in an which dll/lib it is a part of. Also note which versions of windows it will apply for. You can query the version of windows and switch how you behave for specific versions of windows in some cases.

To add this with an explicit declaration, here is a nice little wrapper class:

winlibs.h

#ifndef WINLIBS_H
#define WINLIBS_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <QLibrary>

typedef HWND (WINAPI * GetShellWindow_Ptr)(void);
typedef BOOL (WINAPI * GetWindowRect_Ptr)(
    /*_In_*/  HWND   hWnd,
    /*_Out_*/ LPRECT lpRect
);

class WinLibs
{
public:
     WinLibs();
     static GetShellWindow_Ptr GetShellWindow;
     static GetWindowRect_Ptr GetWindowRect;
     static void cleanUp();
     static QLibrary * myLib;
};

#endif // WINLIBS_H

winlibs.cpp

#include "winlibs.h"
#include <QDebug>

GetShellWindow_Ptr WinLibs::GetShellWindow = 0;
GetWindowRect_Ptr WinLibs::GetWindowRect = 0;

QLibrary * WinLibs::myLib = 0;

bool WinLibs::hasInitialized = false;

WinLibs::WinLibs()
{
     if(hasInitialized)
          return;

     myLib = new QLibrary("User32.dll");
     GetShellWindow = (GetShellWindow_Ptr) myLib->resolve("GetShellWindow");
     GetWindowRect = (GetWindowRect_Ptr) myLib->resolve("GetWindowRect");
     if(GetShellWindow == 0 || GetWindowRect == 0)
          qCritical() << "Failed to load User32.dll properly!";

     hasInitialized = true;
}

void WinLibs::cleanUp()
{
     hasInitialized = false;
     myLib->unload();
     delete myLib;
     myLib = 0;
}

example usage:

WinLibs w;
if(w.GetShellWindow)
{
    // use w.GetShellWindow here
}

if(w.GetWindowRect)
{
    // use w.GetWindowRect here

    RECT rect;//Rect System Tray
    HWND taskBar = FindWindow(L"Shell_traywnd", NULL);
    if(taskBar && w.GetWindowRect(taskBar, &rect))
    {
        // .. more code
    }
}

Be sure to handle errors and return values properly from Windows functions when trying to debug them, too. And note that you will get errors if you are building a 64 bit program and you try to access a 32 bit dll and vice versa. Usually you don't have to worry about this for windows libraries because the system will add the correct one to the path when they are getting resolved.

Hope that helps.

Upvotes: 1

Related Questions