Jerry -
Looks like you have a solution to your problem already. I just thought I'd describe an alternative approach, maybe for the benefit of others. If you don't want to create a custom document tab, you can implement customized user interaction in zero document state using the Application menu.
The solution is based on setting the variables STARTMODE 0 and STARTUP 3.
AutoCAD will launch in zero document mode and the RIBBON component will be pre-initialized, which gives you access to the ComponentManager, which holds the ApplicationMenu.
Create a managed dll that gets loaded at AutoCAD startup, load control value 2.
//Global var for ZeroDocState
ApplicationMenuItem acApMenuItem = null;
public void Initialize()
{
if (ComponentManager.ApplicationMenu != null)
ComponentManager.ApplicationMenu.Opening += new EventHandler<EventArgs>(ApplicationMenu_Opening);
}
public void Terminate()
{
// Remove the application menu Opening event handler
if (acApMenuItem != null)
ComponentManager.ApplicationMenu.Opening -= new EventHandler<EventArgs>(ApplicationMenu_Opening);
}
void ApplicationMenu_Opening(object sender, EventArgs e)
{
// Check to see if the custom menu item was added previously
if (acApMenuItem == null)
{
// Get the application menu component
ApplicationMenu acApMenu = ComponentManager.ApplicationMenu;
// Create a new application menu item
acApMenuItem = new ApplicationMenuItem();
acApMenuItem.Text = "ZeroDoc Cmd";
acApMenuItem.LargeImage = getBitmap("CustomCmd.png");
acApMenuItem.ShowImage = true;
acApMenuItem.CommandHandler = new MyCommandHandler();
// Append the new menu item
acApMenu.MenuContent.Items.Add(acApMenuItem);
}
}
BitmapImage getBitmap(string fileName)
{
BitmapImage bmp = new BitmapImage();
//BitmapImage.UriSource must be in a BeginInit/ EndInit block.
bmp.BeginInit();
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
bmp.UriSource = new Uri(path + @"\Support\" + fileName);
bmp.EndInit();
return bmp;
}


Image from an old OEM application, but same applies to vanilla AutoCAD.
In the command handler you'd call your custom code:
public class MyCommandHandler : System.Windows.Input.ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
ModalForm modal = new ModalForm();
Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(modal);
}
}
With this approach you could even create a modeless form in the Initialize() function, a standard Palette using the AutoCAD.Windows.PaletteSet.
ModelessForm mf = new ModelessForm();
mf.testPalette();
public void testPalette()
{
try
{
if (ps == null)
{
ps = new Autodesk.AutoCAD.Windows.PaletteSet("Test Palette Set");
ps.Style = PaletteSetStyles.ShowAutoHideButton | PaletteSetStyles.ShowCloseButton;
ps.Opacity = 90;
ps.MinimumSize = new System.Drawing.Size(300, 300);
System.Windows.Forms.UserControl myCtrl = new ModelessForm();
ps.Add("test", myCtrl);
ps.Visible = false;
ps.Visible = true;
}
}
catch
{
}
}
Of course, the same limitations to custom,native command access as well as DWG related API functions, apply as in the provided custom document solution you already got from Norman Yuan.
Cheers,
Paavo Rantanen, Tech Soft 3D