mIRC is the most popular Internet Relay Chat (IRC) client for Windows - www.mirc.com
Based on the mIRC documentation I've put together a simple skeleton to create your own DLLs to interface back and forth with mIRC. It is very simple, but as with anything it's still important to know the specifics (not just to ensure that you're doing things right, but so you know exactly what can and can't be done), so if you do use this code I'd encourage you to take some time to look in the mIRC helpfile for "SendMessage", "/dll" and "DLL Support".
To call a function in your DLL from a mIRC script ...
First, export a function with the associated parameters that mIRC expects, eg.
FUNCTION MyMircFunction ALIAS "MyMircFunction" (BYVAL hWndMirc AS DWORD, BYVAL hActiveMircWnd AS DWORD, szData AS ASCIIZ, szParams AS ASCIIZ, BYVAL quiet AS DWORD, BYVAL nopause AS DWORD) EXPORT AS DWORD
You can then return 0, 1, 2 or 3 as the function result depending on which action you want mIRC to take. You might for example want to fill the szData variable with a mIRC command like "//echo -a Hello from the DLL", and return 2 as the function result which tells mIRC to execute the commands in the szData field.
Now to call it simply add this line to your mIRC script (or type it in the mIRC command line textbox):
/dll c:\irc\mymirc.dll MyMircFunction null
Alternatively you may want to simply return a string to MIRC to allow the mIRC script to process the result. In that case, return 3 instead of 2 from your function, and with the mIRC script looking something like this:
/var %dllresult = $dll(c:\mirc\mymirc.dll,MyMircFunction,$null)
//echo -a The result from the DLL is: %dllresult
To call mIRC from your DLL at any time ...
The above example is fine for when your script calls your DLL function - ie. your DLL reacts to the script, but sometimes your DLL might want to 'push' commands to mIRC as opposed to mIRC asking for them ... for example if it was monitoring an RSS news feed and wanted to get mIRC to tell people as soon as news breaks.
To do this we need to create a memory mapped file of size at least 1024 bytes which by default is named "mIRC" but that can be changed (see 'SendMessage' in the helpfile), and you may need to if it's already in use by another mIRC DLL. Using that memory mapped file we can fill its buffer with whatever commands we like (each cmd separated by a "|", eg. "//echo -a Hello | //echo -a Hi again")
Then we invoke SendMessage WM_USER+200 to get mIRC to execute the buffer.
The SendCommandsToMIRC command in the source code encompasses that.
If you have no need for that functionality you can remove the file mapping code.
To forcibly unload your DLL from mIRC ... (useful when having to recompile!)
/dll -u c:\irc\mymirc.dll
mIRC DLL Skeleton
Based on the mIRC documentation I've put together a simple skeleton to create your own DLLs to interface back and forth with mIRC. It is very simple, but as with anything it's still important to know the specifics (not just to ensure that you're doing things right, but so you know exactly what can and can't be done), so if you do use this code I'd encourage you to take some time to look in the mIRC helpfile for "SendMessage", "/dll" and "DLL Support".
To call a function in your DLL from a mIRC script ...
First, export a function with the associated parameters that mIRC expects, eg.
FUNCTION MyMircFunction ALIAS "MyMircFunction" (BYVAL hWndMirc AS DWORD, BYVAL hActiveMircWnd AS DWORD, szData AS ASCIIZ, szParams AS ASCIIZ, BYVAL quiet AS DWORD, BYVAL nopause AS DWORD) EXPORT AS DWORD
You can then return 0, 1, 2 or 3 as the function result depending on which action you want mIRC to take. You might for example want to fill the szData variable with a mIRC command like "//echo -a Hello from the DLL", and return 2 as the function result which tells mIRC to execute the commands in the szData field.
Now to call it simply add this line to your mIRC script (or type it in the mIRC command line textbox):
/dll c:\irc\mymirc.dll MyMircFunction null
Alternatively you may want to simply return a string to MIRC to allow the mIRC script to process the result. In that case, return 3 instead of 2 from your function, and with the mIRC script looking something like this:
/var %dllresult = $dll(c:\mirc\mymirc.dll,MyMircFunction,$null)
//echo -a The result from the DLL is: %dllresult
To call mIRC from your DLL at any time ...
The above example is fine for when your script calls your DLL function - ie. your DLL reacts to the script, but sometimes your DLL might want to 'push' commands to mIRC as opposed to mIRC asking for them ... for example if it was monitoring an RSS news feed and wanted to get mIRC to tell people as soon as news breaks.
To do this we need to create a memory mapped file of size at least 1024 bytes which by default is named "mIRC" but that can be changed (see 'SendMessage' in the helpfile), and you may need to if it's already in use by another mIRC DLL. Using that memory mapped file we can fill its buffer with whatever commands we like (each cmd separated by a "|", eg. "//echo -a Hello | //echo -a Hi again")
Then we invoke SendMessage WM_USER+200 to get mIRC to execute the buffer.
The SendCommandsToMIRC command in the source code encompasses that.
If you have no need for that functionality you can remove the file mapping code.
To forcibly unload your DLL from mIRC ... (useful when having to recompile!)
/dll -u c:\irc\mymirc.dll
mIRC DLL Skeleton
Code:
#COMPILE DLL "c:\irc\mymirc.dll" #INCLUDE "Win32API.inc" TYPE MircLoadDLL mVersion AS DWORD mHwnd AS DWORD mKeep AS DWORD END TYPE GLOBAL ghInstance AS DWORD, gmircHwnd AS DWORD, ghFileView AS DWORD FUNCTION MyMircFunction ALIAS "MyMircFunction" (BYVAL hWndMirc AS DWORD, BYVAL hActiveMircWnd AS DWORD, szData AS ASCIIZ, _ szParams AS ASCIIZ, BYVAL quiet AS DWORD, BYVAL nopause AS DWORD) EXPORT AS DWORD '// Use ONE of the following return options, comment out or remove the rest ... '0 = mIRC should /halt processing, so no more scripts or anything FUNCTION = 0 EXIT FUNCTION '1 = mIRC should simply continue processing, so if theres any more scripts theyll still run FUNCTION = 1 EXIT FUNCTION '2 = The DLL has filled the szData variable with a command which it wants mIRC to perform, and has filled parms with the parameters to use, if any, when performing the command. szData = "//echo -a Hello from the mIRC DLL (1st command) | /echo -a Hello again from the mIRC DLL (2nd command)" FUNCTION = 2 '3 = the DLL has filled the data variable with the result that $dll() as an identifier should return. szData = "Hello from the mIRC DLL" FUNCTION = 3 'and a sample mIRC script to call it: ' /var %dllresult = $dll(c:\mirc\mircdll.dll,MyMircFunction,$null) ' //echo -a The result from the DLL is: %dllresult END FUNCTION '// If you ever need to 'push' commands to mIRC (rather than mIRC asking for it) you can use this, which uses a memory-mapped file SUB SendCommandsToMIRC(sCmds AS STRING) POKE$ ghFileview, sCmds & CHR$(0) SendMessage(BYVAL gmircHwnd, BYVAL %WM_USER + 200, BYVAL 1, BYVAL 0) '// See 'SendMessage' in the mIRC helpfile END SUB SUB LoadDll ALIAS "LoadDll" (mLoadDLL AS MircLoadDLL) EXPORT '// Called by mIRC as soon as it's loaded (but obviously LIBMAIN is activated first) mLoadDLL.mKeep = 1 '1 = keep loaded, otherwise the dll will be unloaded immediately after the function call gmircHwnd = mLoadDLL.mhWnd SendCommandsToMIRC("//echo -a Hello from the mIRC DLL (1st command) | /echo -a Hello again from the mIRC DLL (2nd command)") '// Note: The first cmd needs to start with '//' double slash or the other cmds will be treated as the one string rather than seperate cmds END SUB FUNCTION UnloadDll ALIAS "UnloadDll" (BYVAL dwReason AS DWORD) EXPORT AS DWORD '// Called my mIRC when attempting to unload the DLL 'dwReason: 0=unloaded with /dll -u 1=hasnt been used for 10 mins (return 0 to force the DLL to stay loaded) 2=mirc exitting IF dwReason = 1 THEN FUNCTION = 0 'stay loaded ELSE FUNCTION = 1 END IF END FUNCTION FUNCTION LIBMAIN (BYVAL hInstance AS LONG, _ BYVAL fwdReason AS LONG, _ BYVAL lpvReserved AS LONG) AS LONG SELECT CASE fwdReason CASE %DLL_PROCESS_ATTACH LOCAL hFileMap AS DWORD ghInstance = hInstance hFileMap = CreateFileMapping(%INVALID_HANDLE_VALUE, BYVAL 0, %PAGE_READWRITE, BYVAL 0, BYVAL 4096, "mIRC") ghFileView = MapViewOfFile(hFileMap, %FILE_MAP_ALL_ACCESS, 0, 0, 0) MSGBOX "mIRC DLL Loaded!" FUNCTION = 1 'success! CASE %DLL_PROCESS_DETACH CALL UnmapViewOfFile(ghFileView) MSGBOX "mIRC DLL Unloaded" CASE ELSE FUNCTION = 1 'success! END SELECT END FUNCTION