@jetdv Hello, Sir, please, if possible, could you help me? I'm watching your tutorials' series of Build a Custom Command, and I'm trying to convert my scripts to a custom command. But, I'm always getting the same error;
"An error occured: Catastrophic failure (Excepetion from HRESULT: 0x8000FFFF {E_UNEXPECTED})"
This is the CCMainForm.cs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ScriptPortal.Vegas;
namespace CCTest
{
public partial class CCMainForm : UserControl
{
Vegas myVegas;
public CCMainForm(Vegas vegas)
{
myVegas = vegas;
InitializeComponent();
// Populate the ComboBox with the options "Frames", "Seconds", and "Minutes"
SelectUnitComboBox.Items.Add("Frames");
SelectUnitComboBox.Items.Add("Seconds");
SelectUnitComboBox.Items.Add("Minutes");
// Optionally, set a default selection
SelectUnitComboBox.SelectedIndex = 0; // "Frames" selected by default
// Set default value for numericUpDown1 to 42
numericUpDown1.Value = 42;
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
// Get the numeric up-down control that triggered the event
NumericUpDown inputBox = sender as NumericUpDown;
// Check if inputBox is not null
if (inputBox != null)
{
// Ensure the value is between 1 and 1000
int value = (int)inputBox.Value;
// You can now use this value for whatever logic you need
// For example: simple logic that uses the value
if (value >= 1 && value <= 1000)
{
// Value is valid, do something here if needed
// (e.g., pass it to another method or store it)
Console.WriteLine("Set value: " + value);
}
}
}
private void SelectUnitComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the selected unit from the ComboBox
string selectedUnit = SelectUnitComboBox.SelectedItem.ToString();
// Get the amount value from the numericUpDown control
int amount = (int)numericUpDown1.Value;
// Define the Timecode offset
Timecode offset;
// Apply the logic based on the selected unit
try
{
if (selectedUnit == "Frames")
{
offset = Timecode.FromFrames(amount);
}
else if (selectedUnit == "Seconds")
{
offset = Timecode.FromSeconds(amount);
}
else if (selectedUnit == "Minutes")
{
offset = Timecode.FromSeconds(amount * 60); // Convert minutes to seconds
}
else
{
throw new ArgumentException("Invalid time unit selected.");
}
// Do something with the calculated offset, e.g., store or display it
Console.WriteLine($"Offset calculated: {offset}");
}
catch (ArgumentException ex)
{
MessageBox.Show(ex.Message);
}
}
private void MoveLeftButton_Click(object sender, EventArgs e)
{
// Call MoveEventsLeft when "Move Left" button is clicked
MoveEventsLeft(myVegas);
}
void MoveEventsLeft(Vegas vegas)
{
// Retrieve the current value from numericUpDown1 (amount)
int amount = (int)numericUpDown1.Value;
// Retrieve the selected unit from SelectUnitComboBox
string selectedUnit = SelectUnitComboBox.SelectedItem.ToString();
// Determine the time offset based on the selected unit (Frames, Seconds, or Minutes)
Timecode offset;
if (selectedUnit == "Frames")
{
offset = Timecode.FromFrames(amount);
}
else if (selectedUnit == "Seconds")
{
offset = Timecode.FromSeconds(amount);
}
else if (selectedUnit == "Minutes")
{
offset = Timecode.FromSeconds(amount * 60); // Convert minutes to seconds
}
else
{
throw new ArgumentException("Invalid time unit specified.");
}
// Collect all selected events across all tracks
var allSelectedEvents = new List<TrackEvent>();
var processedEvents = new List<TrackEvent>(); // To track processed events
// Iterate over each track to gather selected events
foreach (Track track in vegas.Project.Tracks)
{
foreach (TrackEvent trackEvent in track.Events)
{
if (trackEvent.Selected)
{
allSelectedEvents.Add(trackEvent);
}
}
}
// Move all selected events left
foreach (TrackEvent trackEvent in allSelectedEvents)
{
try
{
if (processedEvents.Contains(trackEvent)) continue;
// Move the selected event left
trackEvent.Start -= offset;
FixUnquantizedFrames(trackEvent); // Fix unquantized frames
processedEvents.Add(trackEvent); // Mark as processed
// Handle grouped events
if (trackEvent.Group != null)
{
foreach (TrackEvent groupedEvent in trackEvent.Group)
{
if (processedEvents.Contains(groupedEvent)) continue; // Avoid moving grouped events twice
// Move grouped event left
groupedEvent.Start -= offset;
FixUnquantizedFrames(groupedEvent); // Fix unquantized frames
processedEvents.Add(groupedEvent); // Mark as processed
}
}
}
catch (System.Security.SecurityException ex)
{
MessageBox.Show("A security exception occurred: " + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show("An error occurred: " + ex.Message);
}
}
// Optionally move Volume Envelope Points left (if needed)
foreach (Track track in vegas.Project.Tracks)
{
MoveVolumeEnvelopePointsLeft(track, offset);
}
vegas.UpdateUI(); // Refresh UI to reflect changes immediately
}
// Method to move volume envelope points left (optional)
private void MoveVolumeEnvelopePointsLeft(Track track, Timecode offset)
{
foreach (Envelope envelope in track.Envelopes)
{
if (envelope.Type == EnvelopeType.Volume)
{
for (int i = 0; i < envelope.Points.Count; i++)
{
EnvelopePoint point = envelope.Points[i];
point.X = point.X - offset; // Move point left
}
}
}
}
// Method to fix unquantized frames for both video and audio events
private void FixUnquantizedFrames(TrackEvent evt)
{
if (evt == null) return;
double frameRate = myVegas.Project.Video.FrameRate;
double frameDurationMs = 1000.0 / frameRate; // Frame duration in milliseconds
// Adjust start time to nearest frame
double startMs = evt.Start.ToMilliseconds();
evt.Start = new Timecode(Math.Round(startMs / frameDurationMs) * frameDurationMs);
// Adjust length to nearest frame
double lengthMs = evt.Length.ToMilliseconds();
evt.Length = new Timecode(Math.Round(lengthMs / frameDurationMs) * frameDurationMs);
}
}
}
And this is the CCTest.cs;
using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Drawing;
using System.Runtime;
using System.Xml;
using System.Windows.Forms;
using ScriptPortal.Vegas;
namespace CCTest
{
public class CCTestDock : DockableControl
{
private CCTest.CCMainForm myform = null;
public CCTestDock() : base("CCTestInternal")
{
this.DisplayName = "CCTest";
}
public override DockWindowStyle DefaultDockWindowStyle
{
get { return DockWindowStyle.Docked; }
}
public override Size DefaultFloatingSize
{
get { return new Size(640, 480); }
}
protected override void OnLoad(EventArgs args)
{
myform = new CCTest.CCMainForm(myVegas);
myform.Dock = DockStyle.Fill;
this.Controls.Add(myform);
}
protected override void OnClosed(EventArgs args)
{
base.OnClosed(args);
}
}
}
public class CCTestCCM : ICustomCommandModule
{
public Vegas myVegas = null;
CustomCommand CCM = new CustomCommand(CommandCategory.View, "CCTest");
public void InitializeModule(Vegas vegas)
{
myVegas = vegas;
CCM.MenuItemName = "My Test Custom Command";
}
public ICollection GetCustomCommands()
{
CCM.MenuPopup += this.HandlePICmdMenuPopup;
CCM.Invoked += this.HandlePICmdInvoked;
CustomCommand[] cmds = new CustomCommand[] { CCM };
return cmds;
}
void HandlePICmdMenuPopup(Object sender, EventArgs args)
{
CCM.Checked = myVegas.FindDockView("CCTestInternal");
}
void HandlePICmdInvoked(Object sender, EventArgs args)
{
if (!myVegas.ActivateDockView("CCTestInternal"))
{
CCTest.CCTestDock CCMDock = new CCTest.CCTestDock();
CCMDock.AutoLoadCommand = CCM;
CCMDock.PersistDockWindowState = true;
myVegas.LoadDockView(CCMDock);
}
}
}
And this is the photo of the Form I'm creating to be like my original script;
The Move Right button is not ready yet. I'm trying to make the Move Left button works first. But Always getting that error.
In my original Script works fine. But, trying to adapt to a custom command, I'm getting this issue.
Please, Sir, where is my mistake?
