Plug-In Style Guide (How to Create a Plug-In) Changed in Version 2024.2

www.CAD6.com

Plug-ins based on the CAD6interface will always work inside the user interface that the serving application offers. As a result, the user assumes that plug-ins will look and work similar to the serving application. This will help them to easily get into each new plug-in, however powerful it is.

 

In order to provide a consistent user interface, plug-ins should follow some design rules that are assembled in this Plug-In Style Guide. Even though each plug-in has its freedom to react in any manner, a good plug-in should try to integrate smoothly into the complete system. This starts with the naming of the plug-in and its commands, continues with the design of command icons and ends with the design of dialog windows.

 

 

Plug-In Naming

Plug-in files have to have special file names: the plug-in's file name has to end with an underscore _ (Unicode 95), followed by the extension .DLL . Command extension plug-in file names should always start with the three-character identification of the plug-in's creator. You will receive your private three-character identification at the time you contact Malz++Kassner in order to receive your unique owner identifier (see Getting Your Private Owner ID).

 

When using language DLLs that contain all language dependent data, like all plug-ins supplied by Malz++Kassner do, name the language DLL similar to the plug-in's file, but without the final underscore. The same applies to help files (which are also language-dependent). If your plug-in is named FSBPLG1_.DLL, the language-dependent library is to be named FSBPLG1.DLL, the help file FSBPLG1.CHM.

 

Resulting from the fact that you have to use a three-character identification at the beginning and an underscore at the end of the file name, you should use the characters in between to identify the plug-in. A good idea would be to use simple shortcuts like DIM (for dimensioning), TXT (for text), TRM (for trimming), or DRW (for drawing) to identify the type of commands the plug-in offers, plus one digit to allow several plug-ins for a similar purpose. Just make sure that you do not use any file name twice!

 

 

Version Numbers

When displaying a plug-in's version number (usually after the user selected the plug-in's "About..." command), it is best to use version number of the serving application for which it was designed, such as "Release 2024.1". This will help the user identify compatible versions.

 

 

Command Structure

A plug-in supplies a number of commands that can by called by the serving application. After being loaded into the application's memory, the plug-in will be asked what commands it does offer. It may return a list of up to 20 commands that will be placed in a submenu of the plug-in menu item or up to 200 commands that will be placed in the plug-in's own menu. If no (sub)menu is required (as only one command is available), the plug-in does supply an empty list.

 

The (sub)menu may contain separators to increase the legibility of the (sub)menu. Use them! A good value is to have a separator every four commands in average. The last command of the (sub)menu should always be "About...", displaying a message box stating the plug-in's name, its version and copyright messages.

 

In order to allow a good naming, each command may has two different names: a "short" name displayed in the menu (up to about 30 characters long) and a "long" description that is displayed in the status line while the command is executed (up to about 80 characters long). Use the opportunity to make the long command name more precise! If a command results in a dialog window to be opened immediately after the command's selection, append ellipses points to the command's name (please do always use three single points instead of the horizontal ellipse Ansi 133 / Unicode 8230, which will cause problems on some displays).

 

 

Command Icons Changed in Version 2012.0

All plug-ins and filters can supply a command icon to their commands at plug-in initialization time. This icon will be used in the same way the serving application's icons are used.

 

A command icon has a size of 80 by 80 pixels, a menu icon has a size of 48 by 48 pixels. Both must be defined with 32 bit RGBA colors. Use MKI_BitmapLoadImage to load PNG files with alpha channel as icon templates. The content of a command's or menu's icon is not restricted, but try to create icons that fit into the serving application's icon design style! If a plug-in supplies more than one icon, they should be placed within a single, large bitmap to reduce the plug-in's resource size.

 

 

Dialog Windows Changed in Version 2024.0

In order to give the user the impression that the serving application and the plug-ins are forming an integrated whole, it is important that the dialog windows in the plug-ins provide the same "look and feel" as those in the serving application. For example, all dialog windows should use the font "MS Shell Dlg 8pt".

 

Supporting Help (F1 Key)

Any dialog box should provide its own help topic using hotspots. If the user presses the F1 key inside a plug-in's dialog box, this help topic should be displayed. In order to get notice of the user pressing the F1 key, the following code segment should be placed in each dialog window's main message dispatching code:

 

INT_PTR CALLBACK

DialogProc( HWND f_hDlg, UINT f_unMessage, WPARAM f_wParam, LPARAM f_lParam )

{

  switch( f_unMessage )

  {

 

    ...

 

    case WM_HELP:

      MKI_DialogHelpTopic( g_hGlobalWnd, ... );

      return( 1 );

 

    default:

      return( MKI_DialogHandleDefaultMessages( f_hDlg, f_unMessage, f_wParam, f_lParam ) );

  }

  return( 0 );

}

 

Only if this code is placed is all dialog windows (whether they have their own help topic or not), help will work in all dialog windows, including those of the serving application called through the programming interface.

 

Standard Modal Dialogs

For a uniform look of all dialog windows, all relevant dialog controls shall be sub-classed by means of MKI_SUBCLASS_LIST. Use code similar to the following to subclass all controls in your dialog window's main message dispatching code:

 

INT_PTR CALLBACK

DialogProc( HWND f_hDlg, UINT f_unMessage, WPARAM f_wParam, LPARAM f_lParam )

{

  static MKI_SUBCLASS_LIST s_cSubclassList;

 

  switch( f_unMessage )

  {

    case WM_INITDIALOG:

 

      ...

 

      s_cSubClassList.Init();

      // Subclass any individual controls here, if required.

      s_cSubClassList.AddDialogControls( f_hDlg );

      break;

  }

  return( 0 );

}

 

If you wish to change the visibility and state of sub-classed controls, use the appropriate functions MKI_DialogControlShow(), MKI_DialogControlHide(), MKI_DialogControlEnable(), and MKI_DialogControlDisable(). Using the general Windows commands EnableWindow() or ShowWindow() may result in incomplete visual updating since they do not force a redraw!

 

Property Sheet Dialogs

If you use property sheet windows, please use MKI_DialogInitPropertySheet() or MKI_SUBCLASS_LIST::AddPropertySheetControls() to subclass the parent property sheet's controls in addition to all property page controls.

 

Non-Modal Dialogs

If the plug-in creates popup windows (i.e. permanently visible windows, aka non-modal windows), it must include some code into those windows' callback procedure to avoid interference with popup windows handled by the serving application:

 

INT_PTR CALLBACK 

DialogProc( HWND f_hDlg, UINT f_unMessage, WPARAM f_wParam, LPARAM f_lParam )

{

  switch( f_unMessage )

  {

    case WM_CREATE:

    case WM_INITDIALOG:

      MKI_DialogPopupRegister( f_hDlg );

      // Further initialization here, if required.

      break;

 

    case WM_ACTIVATE:

      // React on the WM_ACTIVATE message here, if required.

      MKI_DialogPopupActivate( f_hDlg, f_wParam, f_lParam );

      break;

 

    case WM_SIZE:

      // React on the WM_SIZE message here, if required.

      MKI_DialogPopupMove( f_hDlg );

      break;

 

    case WM_MOVE:

      // React on the WM_MOVE message here, if required.

      MKI_DialogPopupMove( f_hDlg );

      break;

 

    case WM_SETCURSOR:

      // React on the WM_SETCURSOR message here, if required.

      MKI_DialogPopupSetCursor( f_hDlg, f_wParam, f_lParam );

      return( DefWindowProc( f_hDlg, f_unMessage, f_wParam, f_lParam ) );

 

    case WM_DESTROY:

      MKI_DialogPopupUnregister( f_hDlg );

      // Further uninitialization here, if required.

      break;

 

    ...

 

  }

  return( 0 );

}

 

 

Help Files Changed in Version 2021.0

All documentation, especially help files, should be supplied in CHM format (compiled HTML help). You can use the Microsoft HTML Help Workshop to create such help files, or use third-party tools such as "Help & Manual" or "RoboHelp". When creating such files, please use the standard Layout and Color Scheme to provide a consistent look over all help files.

 

CAD6interface 2024.2 - Copyright 2024 Malz++Kassner® GmbH