Qt 5.5 MSVC 2013.无法获取Windows系统托盘几何体

时间:2015-07-24 16:32:56

标签: c++ qt

我正在尝试获取Windows系统托盘几何体:

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

但编译器MSVC 2013 64位引渡错误:

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)

如果我使用MinGw 32位,编译器不会引渡错误。 请告诉我是什么问题。提前致谢。 我在Windows 8.1上使用Qt 5,5。

1 个答案:

答案 0 :(得分:1)

基本上,MingW没有为这些库加载符号。

MSVC可能已经拥有它们......但即使MSVC有时也不包括所有库,尤其是不常见的库。但是你可以通过自己明确加载库来解决它。我已使用QLibrary和MSDN文档多次完成此操作。

您需要复制正在使用的函数的头文件信息,并加载符号并将其类型转换为您正在使用的函数。 我很快就会发布一个代码示例。

因此,对于第一个:GetWindowRect,您可以在以下位置找到它:

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

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

请注意,在页面底部,它提到了哪个头文件位于哪个dll / lib中。另请注意它将适用于哪种版本的Windows。在某些情况下,您可以查询窗口版本并切换特定版本Windows的行为方式。

要使用显式声明添加它,这是一个不错的小包装类:

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;
}

示例用法:

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
    }
}

在尝试调试时,请务必正确处理错误并从Windows函数返回值。请注意,如果要构建64位程序并尝试访问32位dll,则会出现错误,反之亦然。通常,您不必为Windows库担心这一点,因为系统会在解析时将正确的路径添加到路径中。

希望有所帮助。