如何用Electron获取其他应用程序的位置和大小?

问题描述 投票:0回答:1

Loom一样,我想获取其他应用程序的窗口位置和窗口大小以显示录制区域。 我只能使用此代码获取窗口的大小。

const constraints = {...}
const stream = await navigator.mediaDevices.getUserMedia(constraints)
const {height, width} = stream.getVideoTracks()[0].getSettings()

但我不知道如何获取桌面上特定窗口的位置...

使用 BrowserWindow.getAllWindows() 和 webContents.getAllWebContents() ,似乎我可以获取仅由电子创建的窗口的位置和大小。 如何从其他应用程序的窗口获取它们?

javascript reactjs electron
1个回答
0
投票

现在可能有点晚了,但可以开发两种解决方案 第一个可以通过 chil 过程来完成,这将花费更少的时间 另一种方法是干扰电子源代码并重新编译并使用它,但这将是一个耗时的过程。

子进程示例。

        import { promisify } from 'util';
        import { exec } from 'child_process';
        const execAsync = promisify(exec);
        
        
        interface WindowValues {
          X?: number;
          Y?: number;
          WIDTH?: number;
          HEIGHT?: number;
          [key: string]: number | undefined;
        }
    
    
    async function getWindowInfo(windowId: string): Promise<{ x: number, y: number, width: number, height: number } | null> {
        const numericId = extractWindowId(windowId);
    
        let command = '';
      
        switch (process.platform) {
          case 'win32':
            command = `
    $code = @'
    using System;
    using System.Runtime.InteropServices;
    public class Win32 {
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
    }
    }
    '@
    Add-Type -TypeDefinition $code -Language CSharp
    $hwnd = [IntPtr]${numericId}
    $rect = New-Object Win32+RECT
    $result = [Win32]::GetWindowRect($hwnd, [ref]$rect)
    if ($result) {
    $width = $rect.Right - $rect.Left
    $height = $rect.Bottom - $rect.Top
    "$($rect.Left),$($rect.Top),$width,$height"
    } else {
    "Window not found"
    }
    `.trim();
            break;
          case 'darwin':
            command = `osascript -e 'tell application "System Events" to set windowList to every window of (every process whose unix id is ${numericId})\nif windowList is not {} then\nset targetWindow to item 1 of windowList\nset {x, y} to position of targetWindow\nset {width, height} to size of targetWindow\nx & "," & y & "," & width & "," & height\nelse\n"Window not found"\nend if'`;
            break;
          case 'linux':
            command = `if xdotool getwindowgeometry --shell ${numericId} > /dev/null 2>&1; then xdotool getwindowgeometry --shell ${numericId}; else echo "Window not found"; fi`;
            break;
          default:
            throw new Error('Unsupported platform');
        }
      
        try {
          const { stdout, stderr } = await execAsync(command, { shell: process.platform === 'win32' ? 'powershell' : '/bin/bash' });
          //console.log('Command output:', stdout);
          if (stderr) console.error('Command error:', stderr);
      
          if (stdout.includes("Window not found")) {
            console.log('Window not found');
            return null;
          }
      
          const lines = stdout.trim().split('\n');
          //console.log('Output lines:', lines);
      
          let x, y, width, height;
      
          if (process.platform === 'linux') {
            const values = lines.reduce<WindowValues>((acc, line) => {
              const [key, value] = line.split('=');
              acc[key] = parseInt(value, 10);
              return acc;
            }, {});
            
            x = values.X;
            y = values.Y;
            width = values.WIDTH;
            height = values.HEIGHT;
          } else {
            const lastLine = lines[lines.length - 1];
            [x, y, width, height] = lastLine.split(',').map(Number);
          }
      
          if (typeof x !== 'number' || typeof y !== 'number' || 
              typeof width !== 'number' || typeof height !== 'number') {
            console.error('Invalid window info:', { x, y, width, height });
            return null;
          }
      
          return { x, y, width, height };
        } catch (error) {
          console.error('Error getting window info:', error);
          return null;
        }
      }

  function extractWindowId(id: string): number {
    
    const match = id.match(/^window:(\d+):/);
    return match ? parseInt(match[1].trim(), 10) : parseInt(id.trim(), 10);
  }

export default DiscoverySources;

//用过它

bounds = 等待 getWindowInfo(source.id);

© www.soinside.com 2019 - 2024. All rights reserved.