Solved Qt's strange behavior with windows api functions
-
I created a simple project in which i used 2 windows api functions namely GetDesktopWindow() and MonitorFromWindow().
My project ( with output ):
Both the functions need User32.dll, User32.lib and windows.h header file in order to work ( as is mentioned in the Requirements section of the 2 functions check out the links ). But i was able to use the 2 functions without including the User32.dll and User32.lib files ( by just including windows.h header file only ).
And if i try to include everything ( User32.dll, User32.lib and windows.h header file ) it still work only until i don't hit any key in the editor. If i hit any key and try to run the project it throws the following error :
here is how i include dll and lib files in the pro file:
I wanna know why i get those errors and how fix them ?
thanks
-
Hi, don't think it matters if you hit any key or not in the editor, perhaps it's because you've forgotten to click "Run qmake"? (should be done every time you edit your .pro file)
User32.dll you don't need to include in your build, it's only required once your program is started.
If you are using the MinGW compiler you don't need to add any LIBS += .. statements in your .pro file to get MonitorFromWindow() and GetDesktopWindow() to work. So in that case it suffices to #include "windows.h".
However, if you are using a Microsoft compiler you will need to add that LIBS += ... statement, otherwise you will not be able to build your program. Shortest possible LIBS statement (which I normally use):
LIBS += -luser32
-
@hskoglund how to "Run qmake" ? and how to include User32.dll when my app is started ? kindly note i am a beginner in qt.
And Yes i am using MinGW compiler here have a look :
so if i am using MinGW compiler than i don't have to include any lib or dil files in my .pro just the windows.h header file for those 2 functions. But if i use another 2 windows api functions also, which are GetNumberOfPhysicalMonitorsFromHMONITOR and GetPhysicalMonitorsFromHMONITOR ( for which need to include PhysicalMonitorEnumerationAPI.h header file, dxva2.dll and dxva2.lib but as u said i just include the header file only ) with the ones i am already using ( making total of 4 win api functions ). Then i get the following error :
here is my updated project ( after included another 2 windows api functions ) :
but if i include the required library for GetNumberOfPhysicalMonitorsFromHMONITOR and GetPhysicalMonitorsFromHMONITOR ( dxva2.lib and dxva2.dll ) in the .pro file
i get the previous error which is this :so what should i do when i need all the 4 win api functions ?? and why those 2 functions ( GetNumberOfPhysicalMonitorsFromHMONITOR and GetPhysicalMonitorsFromHMONITOR ) need to include dxva2.dll and dxva2.lib files when i am using MinGW compiler in order to work ?
as far including library goes i didn't included it manually i just used the "Add Library" option in the Qt to add the library so its the Qt that included library in that confusing way.
I know those are lot of questions to ask but that problem is killing me since weeks please help :( you are my only hope :'( btw thanks.
-
Hi, "Run qmake" you'll find in the Build menu (3rd choice) in Qt Creator.
Abour the 2 functions you mention GetNumberOfPhysicalMonitors...., they are newer (10 years old instead of 20 years old) so they are not yet so popular, that's probably why you have to do a
LIBS += -ldxva2
even though you using the MinGW compiler.About those DLLs user32.dll and dxva2.dll, you shouldn't worry about them, they are very difficult to get rid of without a hammer, I mean they are hardwired into Windows. So if they are missing most likely Windows is fubar anyway.
Finally, I you really want to learn Qt, why no try some Qt functions instead of Microsoft's monitor API? That way, once you learned the Qt functions, you can use them not only on Windows, but also on a Raspberry Pi, an iPhone or Samsung phone or a big IBM computer.
I'll give you a small test program to test with, that prints out more or less the same information as in your example above, but by not #including "windows.h"., so it should work equally well on Linux, MacOS and Windows, this is main.cpp:#include <QApplication> #include <QDesktopWidget> #include <QDebug> int main(int argc, char *argv[]) { QApplication a(argc, argv); auto rect2String = [](QRect r){ return QString("(%1,%2,%3,%4)").arg(r.left()).arg(r.top()).arg(r.right()).arg(r.bottom()); }; // get desktop widget QDesktopWidget* dw = QApplication::desktop(); QRect rDW = dw->geometry(); QRect rFW = dw->normalGeometry(); bool bVirtualDesktop = dw->isVirtualDesktop(); int nScreenCount = dw->screenCount(); qDebug() << "Desktop widget geometry: " << rect2String(rDW); qDebug() << "Desktop frame geometry: " << rect2String(rFW); qDebug() << ""; qDebug() << "virtualDesktop: " << (bVirtualDesktop ? "yes" : "no"); qDebug() << "screenCount: " << nScreenCount; for (int nScreen = 0; (nScreen < nScreenCount); ++nScreen) { qDebug() << ""; qDebug() << "Screen #" << nScreen << ":"; qDebug() << "primaryScreen:" << (nScreen == dw->primaryScreen() ? "yes" : "no"); QRect rScreen = dw->screenGeometry(nScreen); QRect rAvailable = dw->availableGeometry(nScreen); qDebug() << "screen geometry:" << rect2String(rScreen); qDebug() << "available geometry:" << rect2String(rAvailable); } return a.exec(); }
Because it uses the QDesktopWidget class, it needs a QApplication instead of QCoreApplication. Also you need to change your .pro file so that it includes widgets, change from:
QT += core
to
QT += core widgets
don't forget to run qmake! :-)
-
@hskoglund Is there any functions in qt with which i can get and set the system brightness ( that is actually what i am trying to do ) ?? and do i have to copy the dxva2.lib file in my project directory or does qt bring it on its own ( when you write "LIBS +=-ldxva2" in .pro file ) ?
btw thanks alot brother you are awesome :D -
@Ahti No sorry changing the system brightness is not possible using Qt's API on Windows. In that case you'll need to dig deeper into Microsoft's functions.
About that dxva2.lib file, it's not a part of Qt. It's the responsibility of the compiler, in your case MinGW, to place that file on your computer, usually in C:\Program Files (x86)\Microsoft SDK.. or \Windows Kit... or similar place and then set up a path to it so your LIBS... statement works. So you shouldn't have to copy it anywhere.