DarkStep SDK 1.0 ~~~~~~~~~~~~~~~~ Table of Contents ----------------- Part 1 - Introduction Part 2 - API Part 1 - Introduction This is the first version of the DarkStep SDK. I would advice all module coders to read this document completely before embarking on the task of writing a DarkStep module as this document outlines a few conventions that you will have to follow when coding a native DarkStep module in order to be compliant with planned future additions to the way DarkStep works and is configured. I will try to provide an explanation of all API function calls at the end of this document. First, unlike in LiteStep, the configuration options are divided into two categories under DarkStep - user specific info and theme specific info. It is left to each module author how they want to divide up the module settings into these categories but I do ask you to give some thought as to how you do the division as this will affect how much control either the user or the theme creator has over specific settings once dynamic theme switching comes into play. The user specific settings go in a separate section for the module in the DarkStep Step.Rc. So for a module called foo, you'd have the settings in a section named [Foo]. The theme specific settings go in a separate RC file by the same name as the module (so in this case Foo.Rc) and there will be a line in the [Themes] section of the Step.Rc which points to the location of this file. ex: [Themes] Foo=C:\DarkStep\Themes\mytheme\foo.rc Please ensure that you adhere to the above naming conventions for your theme specific Rc file, the [Themes] section entry key and the RC file name as it is essential that conformity be maintained for planned future additions such as a module installer and a theme switcher :-) In your config reading section, please check the [Themes] section to see whether there is an entry with your module's name and if there is, use the file pointed to by that entry to get your settings for the theme specific portion of the configuration. If there is no entry in the [Themes] section, point to the DarkStep Step.Rc as the place to get the theme specific info and see whether any of the theme specific stuff is defined in the section for your module. This way, a user's preferences can be overridden by a themer when switching themes but the user always has the option of commenting out the line for a specific module in the [Themes] section and restoring their own settings. If you don't find anything in the Step.Rc either, you can fall back on the default settings. In reality, the whole operation isn't as complicated as it sounds due to the way you can use the DarkStep API but here I guess a more concrete example would be preferable. So feel free to take a look at how this whole idea is implemented in some of the DarkStep modules I have already released :-) DarkStep is written with the idea of being single byte, multibyte or Unicode compatible. This means that I had to stick with certain MS standards and use the macro's defined for string functions. You can do things the same way or just write it straight. Up to you ... That dispenses with the standard requirements unless you are doing a module which works with themes in some way. In that case, note that all themes will be installed in a subdirectory named "themes" under the DarkStep directory and each theme will have a directory of it's own. That really concludes all the requirements Part 2 - API * LPTSTR Tokenize(LPCTSTR string, LPTSTR buf, LPTSTR delims) This function takes the string given in "string" and returns the first substring that is separated by the character/s specified in "delims" in the buffer "buf". The function also returns the rest of the string after the delimiter. This way you can recursively call the Tokenize function with the value returned from the function till the string returned by Tokenize is of length zero. If a delimiter cannot be found in "string", the whole string is returned in "buf" and the function returns a zero length string. Delimiters inside quotes (single or double) are ignored. * LPTSTR ExpandVars(LPCTSTR value) This function takes "value" and checks the string to see whether there are any $ characters in the string. If there is a $, the function searches till it finds another $ and then takes the substring between the two $ signs and checks it against the [Environment] section to see whether there is a key which matches it. If a matching key is found, the value for the key is substituted for the substring and the $ signs, if no value is found a warning message is displayed. The function returns the expanded string or the original string if no expansion took place. * LPTSTR RCReadValue(LPCTSTR inifile, LPCTSTR section, LPCSTR keyword, LPLONG ptr=NULL) This function reads the file named in "inifile" and checks it to see whether it has a section that matches the value given in "section". If there is such a section, it checks the section to see whether there is a key matching "keyword" and if there is such a key, the value for that key is returned by the function. The parameter "ptr" defaults to NULL if not specified and in that case has no effect but if you do pass a pointer to a LONG variable as the value for "ptr" (the LONG variable has to be initialized to 0 the first time), then "ptr" gets the file pointer value for the line just read from "inifile" and the next time you call the RCReadValue function, it will position the file pointer at the point pointed to by "ptr" instead of scanning for the value given by "section" and look for a key matching "keyword". This way, you can read multiple lines with the same key. * int RCReadInt(LPCTSTR inifile, LPCTSTR section, LPCSTR keyword, int def) This is a wrapped version of RCReadValue to return an integer value. If the key specified by "keyword" doesn't exist, the value defined by "def" is returned. * BOOL RCReadBool(LPCTSTR inifile, LPCTSTR section, LPCSTR keyword) This is a wrapped version of RCReadValue to return a boolean value. If the key specified by "keyword" doesn't exist, FALSE is returned otherwise if the value for the key is on or 1, TRUE is returned and if the value is off or 0, FALSE is returned. * LPTSTR RCReadString(LPCTSTR inifile, LPCTSTR section, LPCSTR keyword, LPTSTR def) This is a wrapped version of RCReadValue to return a string. If the key specified by "keyword" doesn't exist, the value defined by "def" is returned. * COLORREF RCReadColor(LPCTSTR inifile, LPCTSTR section, LPCSTR keyword, COLORREF def) This is a wrapped version of RCReadValue to return an RGB color value. If the key specified by "keyword" doesn't exist, the value defined by "def" is returned. * int DSMessage(HWND hWnd, int mode, LPCTSTR title, LPCTSTR msg, DWORD code) This function displays different types of message boxes depending on the value of "mode" which is actually an enumerated type of the form: static enum msgMode { warnok, warnyes, stopok, askyesno } mMode; warnok - Displays a warning (with exclamation mark icon) and an OK button warnyes - Displays a warning (with exclamation mark icon) and YES/NO buttons stopok - Displays a critical error (with stop icon) and an OK button askyesno - Displays a query (with question mark icon) and YES/NO buttons The "hWnd" value gives the parent window for the message dialog and it can be 0 or NULL while "title" contains the title for the message box and "msg" the actual message. If "mode" is of type stopok, the function takes the value of "code" (which will be the return value from a GetLastError() function call) and formats it to come up with a more human understandable error message which will be appended to the message given in "msg". * BOOL AddBang(LPCTSTR command, void *f) This function is used to add a new !bang command to the internal list of DarkStep !bang commands. If the !bang command named by "command" already exists, the function pointer value for the command is changed to "f" but if it doesn't, a new !bang command is added to the internal list. * BOOL DelBang(LPCTSTR command) This function removes the !bang command named "command" from the internal list if such a command exists. * HWND GetShellWindow() This function returns the windows handle for the main DarkStep window. * LPTSTR GetShellSet(int type) This function returns several DarkStep settings depending on the value of "type". "type" could be any one of the following defined in dsapi.h: #define DM_RCPATH 9230 - The full path to the Step.Rc file as it doesn't necessarily have to be in the same directory as the DarkStep.Exe #define DM_DSPATH 9231 - The full path to the DarkStep directory #define DM_IMGPATH 9232 - The full path to the image directory * HBITMAP GetImage(LPTSTR imgPath) This function returns a handle to a bitmap pointed to by "imgPath". If "imgPath" has a value of ".none" a NULL pointer is returned. You can specify an external path to a bitmap in "imgPath" or a ".extract=" command that will extract a picture from a DLL or EXE. * void GetImageSize(HBITMAP hBitmap, int *x, int *y) This function returns the width and height of the bitmap pointed to by "hBitmap" in "x" and "y". * HICON GetIcon(LPCSTR icon) This function is similar to GetImage() but returns a handle to an icon instead of a bitmap. The parameter "icon" could be a direct path to an icon file or a ".extract=" line which points to where the icon is to be extracted from. * void TransDraw(HDC dc, int X, int Y, int wd, int ht, HDC mDC, int sx, int sy, COLORREF cl) This function draws an image with the color given by COLORREF set as transparent. The parameters "dc", "X", "Y", "wd", "ht" provide the destination device context, destination x coordinate, destination y coordinate, destination width and destination height while "mDC", "sx" and "sy" provide the source DC, source x coordinate and source y coordinate. * HBITMAP IcoToBmp(HICON hIcon) This function converts to icon pointed to by "hIcon" into a bitmap and returns a handle to it. * HRGN BmpToRgn(HBITMAP hBmp, COLORREF cTrans, COLORREF cTol, int x, int y) This function converts the bitmap pointed to by "hBmp" into a region and returns a handle to the region. The other parameters "cTrans", "cTol", "x" and "y" provide the transparency color, the color tolerance for the transparent pixels, x-offset value for the bitmap and the y-offset value for the bitmap. * HINSTANCE CmdExec(HWND caller, LPCTSTR cmd, LPCTSTR param, LPCTSTR dir) This function takes a command (or a string of commands separated by ^) specified by "cmd" and then depending on whether it is a !bang command (the command has a "!" as the first character) or not, executes it in two different ways. If the command is a !bang command, the function calls BangExec() to execute it, otherwise it passes the parameters to a SHELLEXECUTEINFO structure to execute it. Of the other parameters, "caller" identifies the window which is calling this function while "param" and "dir" specify the parameters and the directory from which to run the application if this was a single command instead of a whole set of commands separated by ^. If this was a set of commands separated by ^, then "param" and "dir" would be NULL and CmdExec would first Tokenize "cmd" to break it up into individual commands and parameters and then the !bang commands would be executed via BangExec while normal executables would take the executable's location as the working directory and would be executed from there. * BOOL BangExec(HWND caller, LPCTSTR command, LPCTSTR args) This function executes the !bang command specified by "command" with the parameters given in "arg" (if there are any). "caller" specifies the window from which this function was called. * BOOL RCWriteValue(LPTSTR inifile, LPTSTR section, LPTSTR keyword, LPCTSTR value) Not yet fully working. Do not use as yet. DarkStep SDK documentation formatted by demigod for Fahim Farook. contact: demigod@darkstep.com last updated: 12/2/99 1:56PM