» home
» bugs
» git
 

LiteStep Module Coding Tutorial

Introduction

This tutorial serves as an introduction to LiteStep module coding. It however does not teach you how to program. If you really want to make a LiteStep module but you can’t program in any (compatible) language, I suggest you go to the cprogramming.com tutorial.

This tutorial uses C++, the language most commonly used for modules, as LiteStep is written in C++ as well. We suggest building using MinGW (using Code::Blocks) or Visual Studio (6, 7.1 or 8 work best).

You can however develop modules in any programming language, as long as it supports building Windows DLLs with exports. Some languages like Delphi require header conversion files. Java requires the use of an interpreter. Hopefully you can convert the examples here to your language of choice. If you do, feel free to send us your converted module template.

Before you start coding

You probably already have ideas for your module, but do check if some other module already does what you want. If you find one that is similar but doesn't do exactly what you want, you could update that module rather than writing a new one from scratch. If there is no suitable module or if the module is in a language you can’t code in (or if the code is simply a mess!), you'll have to start from scratch.

Before you start coding, you need to either download the SDK or compile a fresh version of LiteStep. There's a guide for compiling LiteStep and a guide to get the SDK and LiteStep core code from CVS (here). Either way you get the required lsapi library and header files - lsapi.lib and lsapi.h, respectively.

Making a basic module

We’ll start with the bare essentials: your module's entry points. The two functions to make a module work with LiteStep are initModuleEx and quitModule. LiteStep uses a C-compatible module interface so you need to define them in your header file as follows:

extern "C"
{
int __cdecl initModuleEx(HWND hParent, HINSTANCE hInstance, const char *path);
void __cdecl quitModule(HINSTANCE hInstance);
}

You also need to export these functions using a .def file:

EXPORTS
  initModuleEx
  quitModule

You could also use Visual Studio style exports, but those aren't compatible with MinGW.

LiteStep calls initModuleEx when it loads the module. You should return 0 if initialization succeeds or a nonzero value otherwise. This is where you create windows, register messages and initialize your module's main instance if you have one.

LiteStep calls quitModule when it unloads the module. This is where you should destroy your module's window, unregister messages and delete your module's instance.

This is all you need to know to make a very basic module.

Bang commands

To add bang commands to your module you’ll need to use an LSAPI function: AddBangCommand. To use this function and anything else from the LSAPI, include lsapi.h. AddBangCommand registers a bang command so the user or other modules can call this. The callback function given to AddBangCommand has to look like BangCommandProc. When the bang is executed your callback is run. Example code:

void __cdecl BangHello(HWND hWnd, LPCSTR pszArgs)
{
    MessageBox(hWnd, "Hello World!", "New LiteStep Module", MB_OK);
}
 
int __cdecl initModuleEx(HWND hParent, HINSTANCE hInstance, const char *path)
{
    AddBangCommand("!Hello", BangHello);
 
    return 0;
}

The registered bang also has to be unregistered. Therefore RemoveBangCommand should be called from inside quitModule.

If you need multiple bang commands to use 1 function use AddBangCommandEx with it’s BangCommandProcEx.'

Any arguments passed along with the bang should be parsed with GetToken, LCTokenize or CommandTokenize.

A very basic module with only the Module functions and a bang command can be found here. If you are relatively new to coding ignore any lines with TRACE in it.

Evars

Another way to communicate with modules is through the use of evars. Typically a user configures his modules by putting settings in his .rc files. A module can get these settings by using the GetRC* functions. There is one for each data type, or if there isn’t use the Line version to get an unparsed version. These configuration lines are essentially evars too.

If you need to make information your module has available to the user evars are the way to do it. LSSetVariable allows the module to give any $evar$ any string value. Note that modules won’t be aware of that change so for example changing $labelX$ to another value will NOT move the label to another location.

Completing the module

Even though the basic module can do most things, it has a few obligations it has to fulfill in order to be called complete. LiteStep and it’s modules communicate with messages similar to Window Message’s (WM_*’s). In order to receive them you need to register for them first by sending the core a LM_REGISTERMESSAGE by using Window’s SendMessage(). You can then receive those messages by using a Message Loop. Your module should at least register for and properly handle the LM_GETREVID and LM_REFRESH messages. Naturally this window can also be used to process any WM_*’s should you need them.

Additional info for LM_REFRESH: Your module should reload any settings that might have changed overtime when it receives this message. This means reloading any rc settings, resetting any exported evars and redrawing anything on screen. Typically this means destroying and recreating your modules main class instance. Thus functions like getting RC lines should be in the class’s constructor.

Additional notes

All LiteStep functions and messages can be found in The LiteStep Reference. The complete SDK with the hello example and more advanced examples can be found here. You might also want to take a look at the module debugging guide.

While developing your module, in particular if you use Visual Studio, it is very helpful to run Debug builds of both LiteStep and your module. It often time helps finding subtle bugs, and stepping through your code in a debugger makes fixing issues much easier. You need to recompile LiteStep to get a Debug build.

If you require any help please contact us in IRC Freenode #LiteStep / #LSDev or on the LSDev Mailing List.

 
lsdev/tutorials/module_coding.txt · Last modified: 2009/01/31 20:00 by jugg
 
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki