在Windows XP中以编程方式旋转显示器? (C ++ / Qt和WindowsAPI) [英] Rotating displays programmatically in Windows XP? (C++/Qt and WindowsAPI)

查看:181
本文介绍了在Windows XP中以编程方式旋转显示器? (C ++ / Qt和WindowsAPI)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,实质上,我们正在编写一个服务级应用程序,可以改变各种用户级设置的属性。我现在正在处理显示部分。



我们已经为我们的软件版本的Windows 7工作,几乎一切都与异常在Windows XP中旋转显示器(奇怪的是,DOES在Windows 7中工作)。 Microsoft提供的Windows API中的ChangeDisplaySettingsEX函数返回了错误显示模式(DISP_CHANGE_BADMODE)的返回码,因此我尝试应用该标志以允许不安全显示模式(因为我是反叛者,将尝试不安全的显示模式,注意:我们在这里处理一个坏的**)。应用该标志导致函数返回坏标志参数(DISP_CHANGE_BADFLAGS)。



进一步调查后,显然没有Windows XP本地的旋转显示的方式。然而,我们可以找到一种方法,但它是通过由英特尔(IEGD)提供的单独的驱动程序。对我来说,这意味着两件事:第一是没有办法,即使是非编程方式通过Windows,也没有办法使用Windows API调用。第二个是如果英特尔找到了一种方法来编程驱动程序来做它,必须有一些方法来做。



我会在下面放一些代码,对不起这是一种tl; dr。



...

  else if(key ==Rotation){
QString rotationsStr = value.toString();
QStringList rotationations = rotationsStr.split(,,QString :: SkipEmptyParts);

for(int i = 0; i WinMon tempMon = currentLayout.at(i);

DWORD dwTemp = tempMon.dm.dmPelsHeight;
if(rotations.size()> 1){
switch(rotations.at(i).toInt(& ok,10))
{
case 0: // Rotate 0 degrees

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
break;

case 1://旋转90度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_90;
break;

case 2://旋转180度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_180;
break;

case 3://旋转270度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_270;
break;

}
}

else
{
switch(rotations.at(0).toInt(& ok,10)) {

case 0:// Rotate 0 degrees

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
break;

case 1://旋转90度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_90;
break;

case 2://旋转180度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_180;
break;

case 3://旋转270度

tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
tempMon.dm.dmPelsWidth = dwTemp;
tempMon.dm.dmFields | = DM_PELSWIDTH | DM_PELSHEIGHT;
}
tempMon.dm.dmDisplayOrientation = DMDO_270;
break;
}
}

currentLayout.replace(i,tempMon);
}
}

我们应用以下设置:

  long returnCode; 

for(int i = 0; i< currentLayout.size(); i ++){
WinMon myMon = currentLayout.at(i);

returnCode = ChangeDisplaySettingsEx(myMon.name.utf16(),(DEVMODE *)&(myMon.dm),NULL,CDS_UPDATEREGISTRY | CDS_NORESET,NULL);
if(returnCode!= DISP_CHANGE_SUCCESSFUL)
{
qWarning()< 无法更改显示<<一世;
qWarning()<< 返回代码:< returnCode;

qWarning()<< ;
qWarning()<< DISP_CHANGE_SUCCESSFUL:< DISP_CHANGE_SUCCESSFUL;
qWarning()<< DISP_CHANGE_BADDUALVIEW:< DISP_CHANGE_BADDUALVIEW;
qWarning()<< DISP_CHANGE_BADFLAGS:< DISP_CHANGE_BADFLAGS;
qWarning()<< DISP_CHANGE_BADMODE:< DISP_CHANGE_BADMODE;
qWarning()<< DISP_CHANGE_BADPARAM:< DISP_CHANGE_BADPARAM;
qWarning()<< DISP_CHANGE_FAILED:< DISP_CHANGE_FAILED;
qWarning()<< DISP_CHANGE_NOTUPDATED:< DISP_CHANGE_NOTUPDATED;
qWarning()<< DISP_CHANGE_RESTART:< DISP_CHANGE_RESTART;
qWarning()<< ;
qWarning()<< 同样,您的返回值是:< returnCode;
return false;
}
}

ChangeDisplaySettingsEx(NULL,NULL,NULL,0,NULL);
return true;

因此底部的代码并不是特别优雅,尝试在我们清理它之前得到一个处理如何做。



所以,有没有人有任何想法如何旋转显示在这种方式为Windows XP ?

解决方案

XP中的整个显示和监视器功能并不像WDDM中那么清晰。虽然可以枚举显示器附加到监视器,但是您无法通过调用ChangeDisplaySettingsEx来更改监视器的模式。要更改显示模式,可以使用显示屏调用CDSE。 \\.\Display1或类似的东西。我在以前的生活中花了很多时间在XP上玩这些功能,我不认为你可以做他们想做的。



据我所知,屏幕旋转是XP下的显示驱动程序的实现细节,没有标准的方法来做这个从用户空间。有些Intel驱动程序列出了纵向模式,当你调用EnumDisplaySettings。通过将显示设置为这些模式之一,您最终将看到一个旋转的屏幕。



简而言之,没有标准的方法来为所有显卡供应商。



在Windows 7下,旋转和镜像是由操作系统提供的。 此链接应给你在Win7下如何工作的细节。对于XP我恐怕没有一个等同的东西。


So, essentially, we're writing a service-level application that can alter attributes of various user-level settings. I'm working on the display portion right now.

We've gotten it to work for the version of our software for Windows 7, and almost everything works with the exception of rotating the displays in Windows XP (which, curiously, DOES work in Windows 7). The "ChangeDisplaySettingsEX" function in the Windows API provided by Microsoft is returning the return code for a bad display mode (DISP_CHANGE_BADMODE), so I tried applying the flag to allow "unsafe" display modes (because I'm a rebel. Yeah I'll try unsafe display modes, watch out: we're dealing with a bad**s here). Applying that flag caused the function to return the bad flags parameter (DISP_CHANGE_BADFLAGS).

Upon further investigation, there is apparently no way native to Windows XP to rotate a display. We COULD, however, find a way to do it, but it was through a separate driver provided by Intel (IEGD). To me, this means two things: the first is that there isn't a way to do this even NON-programmatically through Windows, nor is there a way to do it using Windows API calls. The second is that if Intel found a way to program a driver to do it, there must be SOME way to do it.

I'll put some code below, sorry this is kind of tl;dr. The tl;dr version could simply be the title of the post, I suppose...

...

    else if( key == "Rotation" ) {
                QString rotationsStr = value.toString();
                QStringList rotations = rotationsStr.split(",", QString::SkipEmptyParts);

                for( int i = 0; i < currentLayout.size(); i++){
                    WinMon tempMon = currentLayout.at(i);

                    DWORD dwTemp = tempMon.dm.dmPelsHeight;
                    if(rotations.size() > 1) {
                        switch( rotations.at(i).toInt(&ok, 10) )
                        {
                        case 0:     // Rotate 0 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
                            break;

                        case 1:     // Rotate 90 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_90;
                            break;

                        case 2:     // Rotate 180 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_180;
                            break;

                        case 3:     // Rotate 270 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_270;
                            break;

                        }
                    }

                    else
                    {
                        switch( rotations.at(0).toInt(&ok, 10) ) {

                        case 0:     // Rotate 0 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
                            break;

                        case 1:     // Rotate 90 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_90;
                            break;

                        case 2:     // Rotate 180 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_180;
                            break;

                        case 3:     // Rotate 270 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_270;
                            break;
                        }
                    }

                    currentLayout.replace(i, tempMon);
                }
            }

We apply the settings below:

     long returnCode;

    for( int i=0; i < currentLayout.size(); i++ ){
        WinMon myMon = currentLayout.at(i);

        returnCode = ChangeDisplaySettingsEx(myMon.name.utf16(),(DEVMODE*)&(myMon.dm), NULL, CDS_UPDATEREGISTRY|CDS_NORESET, NULL);
        if( returnCode != DISP_CHANGE_SUCCESSFUL )
        {
            qWarning() << "Failed to change display " << i;
            qWarning() << "Return Code:  " << returnCode;

            qWarning() << " ";
            qWarning() << "DISP_CHANGE_SUCCESSFUL  : " << DISP_CHANGE_SUCCESSFUL;
            qWarning() << "DISP_CHANGE_BADDUALVIEW : " << DISP_CHANGE_BADDUALVIEW;
            qWarning() << "DISP_CHANGE_BADFLAGS    : " << DISP_CHANGE_BADFLAGS;
            qWarning() << "DISP_CHANGE_BADMODE     : " << DISP_CHANGE_BADMODE;
            qWarning() << "DISP_CHANGE_BADPARAM    : " << DISP_CHANGE_BADPARAM;
            qWarning() << "DISP_CHANGE_FAILED      : " << DISP_CHANGE_FAILED;
            qWarning() << "DISP_CHANGE_NOTUPDATED  : " << DISP_CHANGE_NOTUPDATED;
            qWarning() << "DISP_CHANGE_RESTART     : " << DISP_CHANGE_RESTART;
            qWarning() << " ";
            qWarning() << "Again, your return value was: " << returnCode;
            return false;
        }
    }

    ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
    return true;

So the code at the bottom in particular isn't written particularly elegantly, but that was because we were trying to get a handle on how to do it before we cleaned it up.

So, does anyone have any idea how to do rotate the displays in this manner for Windows XP?

解决方案

The whole Display and Monitor thing in XP isn't as clear cut as they are in WDDM. While you can enumerate monitors "attached" to a display, you can't change the mode of the monitor by calling ChangeDisplaySettingsEx. To change the display mode, you call CDSE with the display, e.g. "\\.\Display1" or something like that. I spent a good chunk of time playing with these functions on XP in a previous life and I don't think you can do what you want to do with them.

As far as I know, screen rotation is an implemention detail of the display driver under XP, and there is no standard way to do this from user space. Some Intel drivers list portrait modes when you call EnumDisplaySettings. By setting your display to one of these modes, you end up with a rotated screen.

In short, there is no standard way to do this for all graphics card vendors. But you maybe able to do the same thing their utility apps do to achieve the effect.

Under Windows 7, rotation and mirroring is provided by the OS. This link should give you the details of how things work under Win7. There isn't a equivalent things for XP I'm afraid.

这篇关于在Windows XP中以编程方式旋转显示器? (C ++ / Qt和WindowsAPI)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆