6

Qt4 で c++ を使用してスクリーン キャプチャ アプリケーションを作成しています。デュアル スクリーンでチューニングするときに問題が発生します。2 番目の画面で画像を取得できません。私は ac# アプリケーションを試してみました。これはすべてのデスクトップを 1 つのイメージで取得し、そこから各画面のデスクトップ イメージを抽出できました。ここにc#コードがあります

    using System;
using System.Drawing;
using System.Runtime.InteropServices;

public class TestGrab
{
  [STAThread]
  static void Main(string[] args)
  {
    IntPtr hDC = WindowsNative.GetDC(WindowsNative.GetDesktopWindow());
    IntPtr hBitmap = WindowsNative.GetCurrentObject(hDC,
    WindowsNative.OBJ_BITMAP);
    System.Drawing.Bitmap imageDesktop = System.Drawing.Image.FromHbitmap(
    hBitmap);
    imageDesktop.Save(@"c:\zzzzdesktop.png");
  }
}

public class WindowsNative
{
  [DllImport("user32.dll")]
  public static extern IntPtr GetDesktopWindow();

  [DllImport("user32.dll")]
  public static extern IntPtr GetDC(IntPtr ptr);

  public const int OBJ_BITMAP = 7;
  [DllImport("gdi32.dll")]
  public static extern IntPtr GetCurrentObject(IntPtr hdc, uint
  uiObjectType);
}

Qt コードは小さく、デスクトップへのネイティブ ウィンドウ ハンドルが Qt desktop0>winId() と異なるかどうかもテストしましたが、それらは同じです

QPixmap CaptureWinDesktop()
{
    WId desktop=GetDesktopWindow();
    WId desktop2=QApplication::desktop()->winId();
    if(desktop!=desktop2)
    {
        qDebug("sunt fdiferite WId");
    }
     QPixmap entireDesktop= QPixmap::grabWindow(desktop);
     return entireDesktop;
}

これが Qt のバグなのか機能なのかはわかりません。同じウィンドウ ハンドルを使用すると、実際にはデスクトップが 2 つの画面からリレー構成されているときに、最初のデスクトップのみが再試行されます。1 つのアイデアは、ネイティブの Windows 呼び出しを使用して一時ファイルに画像を保存し、そこから QPixmap をロードすることですが、MFC を使用せずに C++ のファイルに HBITMAP を保存するのは簡単ではありません。結論: Qt のバグは何だと思いますか? それを回避する方法(MFCなし)

4

4 に答える 4

4

QDesktopWidget::screenCount()(Qt 4.6)で画面を数えてから、すべての画面を移動して実行できますQPixmap::grabWindow(...)

「2画面構成のデスクトップ」について。2 つの画面が仮想 (すべての画面が 1 つの画面として扱われる) かどうかによって異なります。

@Frerich Raabe:同様のコードを使用して画面グラブを実行しているため、Windows 7で動作します。

于 2010-10-19T08:55:41.383 に答える
3

最近、同じ問題に気づきました。

最終的に、スクリーンショットを撮るために Qt をやめることにしました。Qt が壊れるもう 1 つの状況は、Windows Vista または Windows 7 の Aero テーマを使用している場合です。このテーマは明らかにすべてのデータをバックグラウンド バッファーにレンダリングするため、Qt によって撮影されたすべてのスクリーンショットはすべて黒です。

Qt を使用する代わりに、http://www.apriorit.com/our-experience/articles/9-sd-articles/193-multi-monitor-screenshotで説明されているように、ScreenShooter クラスを使用することをお勧めします。

于 2010-10-19T08:29:57.780 に答える
2

仮想デスクトップでは、このQPixmap::grabWindowメソッドはプライマリ スクリーンのサイズのスクリーンショットを返すようです。完全な仮想デスクトップのサイズを渡すと、両方のモニターのスクリーンショットが返されます。

  QDesktopWidget *desktop = QApplication::desktop();
  QPixmap screenshot = QPixmap::grabWindow(desktop->winId(), 0, 0, desktop->width(), desktop->height());

Unix / Mac ボックスでこの動作をまだテストしていませんが、Windows 7 で動作します。

于 2012-05-16T01:46:23.333 に答える
0

Windows でのマルチモニター設定では、モニターは通常、仮想デスクトップに結合されます。XP SP0 (2001 年 10 月 25 日) から Win8 SP0 (2012 年 10 月 26 日) までのすべての Windows バージョンで何が起こるか完全にはわからないので、「通常」と言います。ただし、仮想デスクトップとして、これscreen(x)は常に同じウィジェットを返すことを意味します。私が見たところ、これは唯一無二の QDesktopWidget そのものです。ただし、screenGeometry(x)列挙されたモニターごとに異なる値を返します。

screenGeometry(x)結果を QPixmap::grabWindow; のパラメーターとして使用することで、2 番目の画面を取得できます。すなわち:

QDesktopWidget* desktop = QApplication::desktop();
WId wid = desktop->winId();
QRect geo = desktop->screenGeometry(indexOfTheMonitorYouWant);
QPixmap cap = QPixmap::grabWindow(wid, geo.left(), geo.top(), geo.width(), geo.height());

これは現在うまく機能しており、ビルドを QA チームに引き渡そうとしています。

于 2012-10-26T19:27:00.653 に答える