Creating The Plugin Format

In order for pluins to work, they need to have some type of pre-defined format/function(s) which can be called by the application for which they are intended. Since we have already defined these functions when we wrote note_plug.dll, we need to incorporate those functions into a sample DLL and create a skeleton framework for others to use.

Tools Used

[~] Dev-C++ - Used to compile the plugin DLLs.
[~] Plugin1.zip - All the files for the plugin Dev-C++ project.

A Sample DLL Plugin

The below code is well commented, so even if you have not been reading the tutorial, you should be able to figure out how to create your own plugin with no problem. Because of this I will make only a few points before closing, simply to stress their importance:

1. Each plugin must contain a pluginit and plugproc function. The primary purpose of pluginit is to create a menu option, while the primary purpose of plugproc is to process the WM_COMMAND messages passed to it. These functions may perform any other calculations as needed, provided that they do not violate any of the following rules.

2. Each pluginit function is passed the following arguments:

HMENU menu: A menu handle to notepad-ex's primary menu.
HMENU submenu: A menu handle to the 'Plugins' popup menu.
HWND handle: A handle to notepad-ex's main window.
int msgno: The menu ID value to be used for the plugin's menu option.

If a plugin requires more than one menu option, it must increment msgno by one for each additional menu option created. In either case, pluginit must return the final msgno value to the calling function, and idno must be set equal to the msgno value originally passed to pluginit; this is to ensure that no two plugins use the same ID value for their menu option(s). See below for an example.

3. Each plugproc function is passed the following arguments:

int Msg: The ID number sent as the lParam argument with the WM_COMMAND message.
HWND hwnd: A handle to notepad-ex's main window.

The pluginit function should have set idno equal to the msgno value, and subsequently, to the value of the ID number of the plugin's first menu option. If the plugin has multiple options, idno+1 will be the ID of the second menu option created, idno+2 will be the third, and so on (see below for an example). Plugproc may return a 0 to indicate that it other plugins as well as notepad's original code may continue to process the WM_COMMAND message, or it may return a 1 indicating that no other code should process the message.

Note that each plugin is passed every WM_COMMAND message, so you can also modify any pre-existing functionality in notepad as well. Additionally, while it is suggested that you add your menu option(s) to the 'Plugins' popup menu, you may add them to any popup menu, or create your own if you wish.


************************Plugin Code********************************

/*Standard notepad plugin DLL.*/
#include "dll.h"
#include
<windows.h>
#include <stdio.h>
#include <stdlib.h>

int idno;

//Pluginit is called first and creates the menu options
DLLIMPORT int pluginit(HMENU menu,HMENU submenu,HWND handle,int msgno)
{
//idno must equal msgno passed to pluginit and is used in theplugproc function
idno = msgno;
//Add the menu option to the 'Plugins' popup menu. Use the msgno
//integer supplied from note_plug.dll as the menu ID for the first
//menu option.
AppendMenu(submenu, MF_STRING, msgno, "&Hello...");
//If more than one option is created, msgno must be incremented by one for
//each additional menu option.
msgno++;
AppendMenu(submenu, MF_STRING, msgno, "&Goodbye...");
msgno++;
AppendMenu(submenu,MF_STRING,msgno,"&Surprise");
//Apply menu settings
SetMenu(handle,menu);
//Return the final msgno value to note_plug.dll so it knows how many
//menu IDs were used.
return msgno;
}

//Plugproc is passed the ID values each time notepad recieves a WM_COMMAND message.
//Note that ALL WM_COMMAND messages are passed to each plugin's plugproc function,
//allowing each plugin to also intercept and modify any existing WM_COMMAND messages.
DLLIMPORT int plugproc(int Msg,HWND hwnd)
{
//If this ID number is the first menu option...
if(Msg == idno)
{
MessageBox(NULL,"Hello World!","Hello...",MB_OK);
return 1;
}
//If this ID number is the second menu option...
if(Msg == idno+1)
{
MessageBox(NULL,"This program will now close.","Goodbye...",MB_OK);
ExitProcess(0);
return 1;
}
//If this ID number is the third menu option...
if(Msg == idno+2)
{
if(MessageBox(NULL,"Are you surprised?","Surprise",MB_YESNO) == IDYES){
MessageBox(NULL,"Good for you!","Yes",MB_OK);
} else {
MessageBox(NULL,"Too bad!","Oh well",MB_OK);
}
return 1;
}
//Return 1 if you do not want notepad to furthur process the WM_COMMAND message (be careful!).
//Return 0 if you do want notepad to process the WM_COMMAND message.
return 0;
}

************************End Plugin Code****************************

Conclusion

The source code for the above sample plugin, a skeleton plugin, and an XOR encryption plugin are all available in the Notepad-EX download. We have finally come to the end of this tutorial, and hopefully you now know enough to add plugins to any window program you wish. Feel free to experiment with the plugins and Win32 APIs to see how you can modify and customize them to your liking.

Copyright ©2006 craigheffner.com