我正在尝试获取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。
答案 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库担心这一点,因为系统会在解析时将正确的路径添加到路径中。
希望有所帮助。