Creating AddIns
One of the most powerful features of RadASM is its ability to use AddIns. An AddIn is simply put a DLL that is loaded when RadASM starts that can be used to perform tasks that are not available to the IDE. In some cases an AddIn will be installed to alter the way an existing feature of RadASM works and in some cases it will add a completely new function to the IDE. Creating your own AddIns requires a knowledge of how to make a DLL, for the purposes of this tutorial that will be assumed.
RadASM recognizes 2 exports from an AddIn DLL :
InstallDll: This function is called when RadASM loads the DLL, it allows the DLL to perform the necessary setup for your program and to tell RadASM what aspects of the program the DLL will monitor.
DllProc: This function is called depending on what functions are monitored. The DLL can perform tasks based on values passed to it.
InstallDll hWin, fOpt
hWin is a handle to the RadASM main window, you will send messages to this window in order to extract the information you need for your AddIn, fOpt is the DWORD parameter that was specified in the RadASM.ini entry for your AddIn.
During the installation process you would most likely want to get the pointers to the various structures in RadASM. These structures are filled by RadASM with key information that your DLL will need to modify RadASM. The pointers to the structures are obtained by sending the following messages to RadASM.
ADDINHANDLES
Contains a list of handles used in RadASM
Send the message AIM_GETHANDLES to hWin to obtain a pointer to this structure
ADDINPROCS
Contains a list of pointers to procedures used in RadASM
Send the message AIM_GETPROCS to hWin to obtain a pointer to this structure
ADDINDATA
Contains a list of useful data variables used in RadASM
Send the message AIM_GETDATA to hWin to obtain a pointer to this structure
In addition to getting the pointers to the structures you can get a unique ID for your application to use for inserting a menu item or toolbar button, use the AIM_GETMENUID message to obtain an ID.
On return from this procedure your DLL places the information it would like to monitor in eax using the RAM_ flags. To use more than one flag simply OR the values. The available flags are detailed in the \radasm\masm\inc\radasm.inc include file. Whichever flags you return to RadASM, when an event occurs that triggers that flag RadASM will call your DllProc with information concerning the event.
DllProc hWin, uMsg, wParam , lParam
The DllProc is called each time RadASM needs to pass information to the DLL based on the RAM_ flags that were specified when the DLL was installed. This is the only permanent interface that is supplied to RadASM so your AddIn must use this procedure as a jumping point to everything it does. The DllProc procedure should be treated as if it is a DialogProc, returning FALSE if it does not process a message or wishes RadASM to continue with default processing once it's done. Generally this procedure can be viewed as a standard Dialog procedure in that it's only function is to take action based on messages it receives from RadASM. The messages and their constants are found in the \radasm\masm\inc\radasm.inc include file, all messages passed to your AddIn have the prefix AIM_. The following is an example of a DllProc message proc.
DllProc PROC hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD cmp uMsg, AIM_COMMAND jnz @F mov eax, wParam cmp MyAddInID, eax jnz _end mov eax,lpHandles mov eax,[eax].ADDINHANDLES.hWnd invoke DialogBoxParam,hInstance,200,eax,addr DialogProc,NULL ; The message has been processed mov eax,TRUE ret @@: cmp uMsg, AIM_INITMENUPOPUP jnz _end ; Enable the menu item mov eax, lpData mov eax, [eax].ADDINDATA.fProject xor eax, 1 or eax, MF_BYCOMMAND invoke EnableMenuItem, hSubMenu, MyAddInID, eax _end: xor eax, eax ret DllProc ENDP
The ADDINPROCS structure gives your AddIn direct access to some key procedures in RadASM, you may want to perform certain functions like opening a file or a search, this ADDINPROCS allow you to do these tasks using RadASM's built in functionality. Two functions that are used frequently are lpTextOut and lpClearOut, they send text to the output window and clear that window respectively.
Example of calling a Procedure :
mov edi,lpProcs
push Param2
push Param1
call [edi].ADDINPROCS.lpProc
In some cases the procedure will require that prerequisite data be set up before it is called. Read the remarks beside the structure elements, they detail the parameters and prerequisites. The most common prerequisite is lpFileName, if this is required you must first set ADDINDATA.lpFile to the appropriate filename before calling the procedure.
How to make your addin 'Addin Manager compatible'.
AIM_CLOSE
Your addin must respond to AIM_CLOSE by cleaning
up what has been added to RadASM such as:
- Deleting menu items.
- Deleting toolbar buttons.
- Undo subclassing of RadASM windows.
GetOptions proc
This proc returns a pointer to two or more ADDINOPT
structures. The last structure must be all zeros.
There is a AND and a OR value to support check groups.
There can be max 16 check boxes.
Example (masm): ADDINOPT struct lpStr dd ? ;Pointer to CheckBox text nAnd dd ? ;Option AND value nOr dd ? ;Option OR value ADDINOPT ends .data szText1 db 'Option#1',0 szText2 db 'Option#2',0 AddinOpt ADDINOPT <offset szText1,1,1> ADDINOPT <offset szText2,2,2> ADDINOPT <0,0,0> .code ;This proc must be exported GetOptions proc mov eax,offset AddinOpt ret GetOptions endp
TIP: The FlipCase AddIn demonstrates almost all of the features of an AddIn and makes an excellent tutorial. You can download source code for many AddIns at KetilO's website