SacredTravis
SacredTravis

Reputation: 59

How to record while the window is not active?

I am making a recorder that records a specific window the user chooses. While I am recording, the program forces the window to be active all the time. It does not let me minimize it or even move it. It forced me to use alt + f4(that kills the active window) because I was not able to stop the recording. Is there a way to fix that?

Combobox code:

private void Handlebox_SelectedIndexChanged(object sender, EventArgs e)
{
    if (Handlebox.SelectedIndex == 0)
    {
        handle_name = Handlebox.Items[0].ToString();
    }
    else if (Handlebox.SelectedIndex == 1)
    {
        handle_name = Handlebox.Items[1].ToString();
    }
    else if (Handlebox.SelectedIndex == 2)
    {
        handle_name = Handlebox.Items[2].ToString();
    }
    else if (Handlebox.SelectedIndex == 3)
    {
        handle_name = Handlebox.Items[3].ToString();
    }
    else if (Handlebox.SelectedIndex == 4)
    {
        handle_name = Handlebox.Items[4].ToString();
    }
    else if (Handlebox.SelectedIndex == 5)
    {
        handle_name = Handlebox.Items[5].ToString();
    }
}

The way I add all the processes in the combobox:

foreach (Process process in processlist)
{
    if (!String.IsNullOrEmpty(process.MainWindowTitle))
    {
        Handlebox.Items.Add(process.ProcessName);
    }
}

The script that the whole recording takes place:

// Record video:
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

[DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hWnd);

private const int SW_RESTORE = 9;

[DllImport("user32.dll")]
private static extern IntPtr ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);

public Bitmap CaptureApplication(string procName)
{
    Process proc;

    // Cater for cases when the process can't be located.
    try
    {
        proc = Process.GetProcessesByName(procName)[0];
    }
    catch (IndexOutOfRangeException e)
    {
        return null;
    }

    // You need to focus on the application
    SetForegroundWindow(proc.MainWindowHandle);
    ShowWindow(proc.MainWindowHandle, SW_RESTORE);

    // Delay
    Thread.Sleep(1000);

    Rect rect = new Rect();
    IntPtr error = GetWindowRect(proc.MainWindowHandle, ref rect);

    // sometimes it gives error.
    while (error == (IntPtr)0)
    {
        error = GetWindowRect(proc.MainWindowHandle, ref rect);
    }

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    Graphics.FromImage(bmp).CopyFromScreen(rect.left,rect.top,0,0,new Size(width, height),CopyPixelOperation.SourceCopy);

    return bmp;
}

public void RecordVideo()
{
    // Keep track of time:
    watch.Start();

    // Save screenshot:
    string name = tempPath + "//screenshot-" + fileCount + ".png";
    CaptureApplication(handle_name).Save(name, ImageFormat.Png);
    inputImageSequence.Add(name);
    fileCount++;

    // Dispose of bitmap:
    CaptureApplication(handle_name).Dispose();
}

Upvotes: 1

Views: 121

Answers (1)

Andy Wynn
Andy Wynn

Reputation: 1273

Apologies for the brevity and style of this reply; I'm currently on mobile. Could you express your combobox event handler as:

private void Handlebox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (Handlebox.SelectedIndex == -1) return;
        handle_name = Handlebox.SelectedItem.ToString();
    }

I'm not sure what exactly you want this application to do eventually, but If all you want is to gracefully exit, I would look into registering an event handler that watches for a key combination, and stops and saves the recording when it is pressed. I can't easily type out how to do that, but some concerted googling should help you.

Upvotes: 1

Related Questions