Files
cbh/ElaWidgetTools/ElaDxgiManager.cpp
2025-09-19 22:40:52 +08:00

294 lines
6.8 KiB
C++

#include "ElaDxgiManager.h"
#ifdef Q_OS_WIN
#include <d3d11.h>
#include <dxgi1_6.h>
#include <windows.h>
#include <QApplication>
#include <QDebug>
#include <QPainter>
#include <QPainterPath>
#include <QThread>
#include <QUrl>
#include "ElaDxgi.h"
#include "ElaDxgiManagerPrivate.h"
Q_SINGLETON_CREATE_CPP(ElaDxgiManager);
ElaDxgiManager::ElaDxgiManager(QObject* parent)
: QObject{parent}, d_ptr(new ElaDxgiManagerPrivate())
{
Q_D(ElaDxgiManager);
d->q_ptr = this;
d->_dxgiThread = new QThread(this);
d->_dxgi = new ElaDxgi();
setGrabArea(0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));
bool ret = d->_dxgi->initialize(0, 0);
if (!ret)
{
for (int i = 1; i < d->_dxgi->getDxDeviceList().count(); i++)
{
bool ret = d->_dxgi->initialize(i, 0);
if (ret)
{
break;
}
}
}
if (!ret)
{
d->_dxgi->initialize(0, 0);
qCritical() << "No available screenshot devices";
}
d->_dxgi->moveToThread(d->_dxgiThread);
d->_dxgiThread->start();
connect(d, &ElaDxgiManagerPrivate::grabScreen, d->_dxgi, &ElaDxgi::onGrabScreen);
connect(d->_dxgi, &ElaDxgi::grabScreenOver, this, &ElaDxgiManager::grabImageUpdate);
}
ElaDxgiManager::~ElaDxgiManager()
{
Q_D(ElaDxgiManager);
if (d->_dxgi)
{
d->_dxgi->setIsGrabActive(false);
}
if (d->_dxgiThread->isRunning())
{
d->_dxgiThread->quit();
d->_dxgiThread->wait();
}
delete d->_dxgi;
}
QStringList ElaDxgiManager::getDxDeviceList() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getDxDeviceList();
}
QStringList ElaDxgiManager::getOutputDeviceList() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getOutputDeviceList();
}
QImage ElaDxgiManager::grabScreenToImage() const
{
Q_D(const ElaDxgiManager);
if (!d->_dxgi->getIsInitSuccess())
{
return QImage();
}
return d->_dxgi->getGrabImage();
}
void ElaDxgiManager::startGrabScreen()
{
Q_D(ElaDxgiManager);
d->_isAllowedGrabScreen = true;
if (!d->_dxgi->getIsGrabActive())
{
d->_dxgi->setIsGrabActive(true);
Q_EMIT d->grabScreen();
}
}
void ElaDxgiManager::stopGrabScreen()
{
Q_D(ElaDxgiManager);
d->_isAllowedGrabScreen = false;
d->_dxgi->setIsGrabActive(false);
}
bool ElaDxgiManager::getIsGrabScreen() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getIsGrabActive();
}
bool ElaDxgiManager::setDxDeviceID(int dxID)
{
Q_D(ElaDxgiManager);
if (dxID < 0 || d->_dxgi->getDxDeviceList().count() <= dxID)
{
return false;
}
d->_dxgi->setIsGrabActive(false);
while (!d->_dxgi->getIsGrabStoped())
{
//等待任务结束
QApplication::processEvents();
}
if (d->_dxgi->initialize(dxID, d->_dxgi->getOutputDeviceID()))
{
if (d->_isAllowedGrabScreen)
{
d->_dxgi->setIsGrabActive(true);
Q_EMIT d->grabScreen();
}
return true;
}
return false;
}
int ElaDxgiManager::getDxDeviceID() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getDxDeviceID();
}
bool ElaDxgiManager::setOutputDeviceID(int deviceID)
{
Q_D(ElaDxgiManager);
if (deviceID < 0 || d->_dxgi->getOutputDeviceList().count() <= deviceID)
{
return false;
}
d->_dxgi->setIsGrabActive(false);
while (!d->_dxgi->getIsGrabStoped())
{
//等待任务结束
QApplication::processEvents();
}
if (d->_dxgi->initialize(d->_dxgi->getDxDeviceID(), deviceID))
{
if (d->_isAllowedGrabScreen)
{
d->_dxgi->setIsGrabActive(true);
Q_EMIT d->grabScreen();
}
return true;
}
return false;
}
int ElaDxgiManager::getOutputDeviceID() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getOutputDeviceID();
}
void ElaDxgiManager::setGrabArea(int width, int height)
{
Q_D(ElaDxgiManager);
int maxWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int maxHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (width <= 0 || width > maxWidth)
{
width = maxWidth;
}
if (height <= 0 || height > maxHeight)
{
height = maxHeight;
}
d->_dxgi->setIsGrabCenter(true);
d->_dxgi->setGrabArea(QRect(0, 0, width, height));
}
void ElaDxgiManager::setGrabArea(int x, int y, int width, int height)
{
Q_D(ElaDxgiManager);
int maxWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int maxHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (width <= 0 || width > maxWidth)
{
width = maxWidth;
}
if (height <= 0 || height > maxHeight)
{
height = maxHeight;
}
d->_dxgi->setIsGrabCenter(false);
d->_dxgi->setGrabArea(QRect(x, y, width, height));
}
QRect ElaDxgiManager::getGrabArea() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getGrabArea();
}
void ElaDxgiManager::setGrabFrameRate(int frameRateValue)
{
Q_D(ElaDxgiManager);
if (frameRateValue > 0)
{
d->_dxgi->setGrabFrameRate(frameRateValue);
}
}
int ElaDxgiManager::getGrabFrameRate() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getGrabFrameRate();
}
void ElaDxgiManager::setTimeoutMsValue(int timeoutValue)
{
Q_D(ElaDxgiManager);
if (timeoutValue > 0)
{
d->_dxgi->setTimeoutMsValue(timeoutValue);
}
}
int ElaDxgiManager::getTimeoutMsValue() const
{
Q_D(const ElaDxgiManager);
return d->_dxgi->getTimeoutMsValue();
}
Q_PROPERTY_CREATE_Q_CPP(ElaDxgiScreen, int, BorderRadius)
ElaDxgiScreen::ElaDxgiScreen(QWidget* parent)
: QWidget(parent), d_ptr(new ElaDxgiScreenPrivate())
{
Q_D(ElaDxgiScreen);
d->q_ptr = this;
d->_pBorderRadius = 5;
d->_dxgiManager = ElaDxgiManager::getInstance();
setFixedSize(700, 500);
connect(d->_dxgiManager, &ElaDxgiManager::grabImageUpdate, this, [=](QImage img) {
if (isVisible())
{
d->_img = std::move(img);
update();
}
});
}
ElaDxgiScreen::~ElaDxgiScreen()
{
}
void ElaDxgiScreen::paintEvent(QPaintEvent* event)
{
Q_D(ElaDxgiScreen);
if (d->_dxgiManager->getIsGrabScreen())
{
QPainter painter(this);
painter.save();
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
QPainterPath path;
path.addRoundedRect(rect(), d->_pBorderRadius, d->_pBorderRadius);
painter.drawImage(rect(), d->_img);
painter.restore();
}
}
void ElaDxgiScreen::setIsSyncGrabSize(bool isSyncGrabSize)
{
Q_D(ElaDxgiScreen);
if (isSyncGrabSize)
{
setFixedSize(d->_dxgiManager->getGrabArea().size());
}
}
bool ElaDxgiScreen::getIsSyncGrabSize() const
{
Q_D(const ElaDxgiScreen);
return d->_isSyncGrabSize;
}
#endif