我正在使用Qt Framework和MS RDP组件编写应用程序。我需要的是对远程计算机的桌面图像进行后期处理,然后再在屏幕上进行显示。
因此,主要问题是:有什么方法可以从MsRdpClientNotSafeForScripting实例中获取远程桌面图片位图?换句话说,我需要直接访问包含远程计算机的桌面图像数据的内存。
我正在使用ActiveQt与RDP组件一起使用。我试图从AxWidget
获取OLE对象并将其绘制在HBITMAP
(OnMakeScreenShotSlot()
中的代码)上。但是,首先,获取屏幕位图的方法是错误的,而且,此方法毕竟会产生错误的结果:(附加的代码)当我们按下“屏幕截图”按钮时,将出现文件“ screen.bmp”,其中包含文字为“我还活着!”的白色矩形位于中心(但不是远程计算机桌面的图像)。 “我还活着!”是IMsRdpClient实例的ConnectedStatusText
属性的值。
附带代码。工作环境:Windows 8,MSVC 2012,Qt 4.8.5,x86。
Main.cpp:
#include <QApplication>
#include "containerwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ContainerWidget *w = new ContainerWidget();
w->show();
return a.exec();
}
containerwidget.h:
#ifndef CONTAINERWIDGET_H
#define CONTAINERWIDGET_H
#include <QWidget>
#include <QAxWidget>
#include <QAxObject>
#include <QPushButton>
class ContainerWidget : public QWidget
{
Q_OBJECT
QAxWidget *m_rdpWidget;
QPushButton *m_screenshotButton;
void initRdpWidget();
public:
ContainerWidget(QWidget *parent = 0);
~ContainerWidget();
public slots:
void OnMakeScreenshotSlot();
};
#endif // CONTAINERWIDGET_H
containerwidget.cpp:
#include "containerwidget.h"
#include <QBoxLayout>
#include <QDebug>
#include <QUuid>
#include <comdef.h>
ContainerWidget::ContainerWidget(QWidget *parent) :
QWidget(parent)
{
initRdpWidget();
m_screenshotButton = new QPushButton("Make screenshot", this);
connect(m_screenshotButton, SIGNAL(clicked()), this, SLOT(OnMakeScreenshotSlot()));
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(m_rdpWidget);
mainLayout->addWidget(m_screenshotButton);
}
ContainerWidget::~ContainerWidget()
{
if (m_rdpWidget) {
m_rdpWidget->dynamicCall("Disconnect()");
}
}
void ContainerWidget::initRdpWidget()
{
m_rdpWidget = new QAxWidget();
m_rdpWidget->setControl("{7cacbd7b-0d99-468f-ac33-22e495c0afe5}");
m_rdpWidget->dynamicCall("SetDesktopWidth(int)", 800);
m_rdpWidget->dynamicCall("SetDesktopHeight(int)", 600);
m_rdpWidget->dynamicCall("SetServer(QString)", "ip");
m_rdpWidget->dynamicCall("SetUserName(QString)", "user");
m_rdpWidget->dynamicCall("SetConnectedStatusText(QString)", "I'm alive!");
QAxObject *advancedSettings2 = m_rdpWidget->querySubObject("AdvancedSettings2");
if (advancedSettings2) {
advancedSettings2->dynamicCall("SetClearTextPassword(QString)", "password");
advancedSettings2->dynamicCall("SetAuthenticationLevel(int)", 2);
}
m_rdpWidget->dynamicCall("Connect()");
m_rdpWidget->setFixedSize(800, 600);
m_rdpWidget->setVisible(true);
}
void ContainerWidget::OnMakeScreenshotSlot()
{
if (m_rdpWidget != NULL) {
IOleObject *oleObj = NULL;
m_rdpWidget->queryInterface((QUuid)IID_IOleObject, (void **)&oleObj);
if (oleObj == NULL) {
qDebug() << "bad ole obj.";
return;
}
IViewObject2 *iviewObj2 = NULL;
HRESULT hres = oleObj->QueryInterface(IID_IViewObject2, (void **)&iviewObj2);
if (SUCCEEDED(hres)) {
SIZE picSize;
hres = iviewObj2->GetExtent(DVASPECT_CONTENT, -1, NULL, &picSize);
if (SUCCEEDED(hres)) {
HDC dc = GetDC(0);
SIZE adjustedSize;
adjustedSize.cx = MulDiv(picSize.cx, GetDeviceCaps(dc, LOGPIXELSX), 2540);
adjustedSize.cy = MulDiv(picSize.cy, GetDeviceCaps(dc, LOGPIXELSY), 2540);
ReleaseDC(0, dc);
RECT r;
SetRect(&r, 0, 0, adjustedSize.cx, adjustedSize.cy);
HDC tmpDC = GetDC(0);
HDC memDC = CreateCompatibleDC(tmpDC);
HBITMAP hBmp = CreateCompatibleBitmap(memDC, adjustedSize.cx, adjustedSize.cy);
HBITMAP oldBmp = (HBITMAP)SelectObject(memDC, hBmp);
OleDraw(oleObj, DVASPECT_CONTENT, memDC, &r);
QPixmap p = QPixmap::fromWinHBITMAP(hBmp);
p.save(QString("screen.bmp"));
SelectObject(memDC, oldBmp);
DeleteDC(memDC);
ReleaseDC(0, tmpDC);
} else {
qDebug() << "bad picSize.";
}
} else {
qDebug() << "bad iviewobj2.";
}
}
}
最佳答案
好吧,似乎没有办法从MsTsc组件获取原始图像字节。
关于c++ - 有什么方法可以从MS RDP组件(AxMSTSCLib)获取桌面图片位图吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21779054/