Qt 5.5 MSVC 2013.获取Windows系统托盘几何图形时遇到麻烦

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

本文关键字:几何图形 遇到 麻烦 系统 MSVC 2013 获取 Windows Qt      更新时间:2023-10-16

我正在尝试获得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

基本上,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的版本并切换特定版本的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库,通常你不必担心这个问题,因为当它们被解析时,系统会将正确的库添加到路径中。

希望有帮助。