Calling a DLL from Magic |
IntroductionThis technote is about the Windows 32 bits platforms (Windows 95, Windows 98, Windows millennium, Windows NT, Windows 2000, Windows XP, ...).
Magic Specific DLLsAs they are designed for Magic, they are several advantages
Note that Magic DLLs are loaded only once (and unloaded only at Magic shutdown) : this is good for performance if functions from this DLL have be to be often called, it also allows to keep in the DLL some context data. I wrote some tips about making a Magic Specific DLL with LCC-Win32 or Visual C++, and there is a project with Delphi on Craig Martin site. Once you have been able to make a Magic DLL, it's quite easy to maintain the MAGIC_BIND function and you don't have to maintain a .def file (only the MAGIC_BIND function has to be exported). You can call
For a DLL called DLLName, a function FunctionName or a procedure ProcedureName from this DLL, The syntax is
I provide a tool (in GET.DLL demo application, 'Utilities/DLL' menu) that use the MAGIC_BIND function in the same way than Magic to list available functions of a Magic DLL. Windows Standard DLLsYou could use the CALLDLL function, but this function is now obsolete, as the UDF function and the Call UDP operation can now handle standard DLLs. The syntax is the same than for Magic DLLs, except :
Each item of the type string comes from this list
Note that you can't call a function that needs as parameter a structure. As a result, a lot of functions can't be called from Magic, you need to make a Magic specific DLLs to handle this cases. In most cases, you want to use a Windows function. So, at first you need the Windows Win32 API documentation. You can download an old (but still useful) win32.hlp at LCC-Win32. Downloading an installing the compiler is also a good idea, you'll sometimes have to look in the header (.h files) to find the numeric value from a constant. For an up-to-date documentation, you can look online at MSDN. A sample : print a file via his associated programThe function we need is ShellExecute. How did I find the function ? I've found that usenet (comp.os.ms-windows.programmer.win32) is a very useful resource, I use Google Groups to search the archives. Try also MSDN and Google.
So look at Win32.hlp (or at ShellExecute.pdf), there is a "QuickInfo" button, it shows a menu with :
With this informations, we know that the function string is : '@Shell32.ShellExecuteA'. The case of the function name is important, the case of the DLL name isn't. Now we have to determine what are the parameters.
This function is called by using Call UDP '@Shell32.ShellExecuteA', parameters including the first (the type string) and the last (return value H, virtual of picture 10) are :
It's a function, so we could also set (init or update) H with
This function is also implemented in GET.DLL, so you could also use Call UDP 'get.print' 'c:\test.doc'. It illustrates the interest of using a Magic DLL : far less complexity from the Magic side. calldll.txt : export (Magic 8.30) of this sample. ActiveX DLLsVisual Basic can only generate such DLLs. It's a lot harder to call an ActiveX DLL, you need to use the mg_ocx stuff, and I can't help on this subject, this MagicDemo.zip complete sample (with a VB project) may help. Some utilization of mg_ocx are available on magicu-l shared folder
ANSI/OEMThere is an issue with Magic V7/V8 (OEM) and Windows (ANSI) : they don't use the same charset. So you need to convert before or after using a string. With GET.DLL you can use the ansi_to_oem, oem_to_ansi or load_convert procedure (that may rely on Windows API or Magic conversion table), the Windows functions are CharToOem and OemToChar. Using a Magic DLL from another tool ?This is possible, you just have to call the function like Magic. I've done it from C for my Magic cross reference printing shareware tool, where I'm able to call hotfudge bmp to jpg function. I've put the function I use in mgproc.dll (part of GET.DLL package). |