SetLastError()
and then typically return a value indicating an error has occured. In most cases this error indicator is 0, -1, FALSE
or NULL
, depending on the function and type it returns.As usual, if a function fails, any output parameters are undefined and you cannot rely on their value.
Also note that for a category of caller's programmatic errors (e.g. typically using invalid value in a function parameter or invalid combination of multiple parameters; or when calling any function without having the particular mCtrl module initialized), mCtrl uses very pragmatic approach: they are only checked if it is reasdonably easy to do so. Some more checks can be enabled if you use DEBUG build of mCtrl (see Debug Level).
MCTRL.DLL
supports Unicode and strings held internally in the library are encoded in Unicode.
However on interfave level, MCTRL.DLL
supports both Unicode and ANSI strings as well. If a function, message of a control or a structure uses string, there are usually two variants of the entity: one for Unicode and one for the ANSI string. When calling a function or sending a message, ANSI strings in paramaters and structure members are converted to Unicode on input and Unicode to ANSI on output.
Identifiers of the Unicode variant then have the "W" suffix and ANSI have "A" suffix, in the same way as Win32API does. The public headers also provide preprocessor macros without the suffix, as an alias for the one of the two depending whether UNICODE
is defined or not.
This means you may use MCTRL.DLL
easily in Unicode-enabled application as well in ANSI applications.
TCHAR
, but MCTRL.DLL
is then always built with preoprocessor macros UNICODE
and _UNICODE
defined. The TCHAR
is used mainly as a courtesy for people who might want to port MCTRL.DLL
to non-unicode environments (e.g. Windows 95/98). The non-unicode builds are not tested, and they are not supported.
I.e. you can call the same MCTRL.DLL
concurrently from multiple threads.
However remeber that access to data visible externally through MCTRL.DLL
interface is not synchronized: If you have such data (e.g. instance of document, see mc_DOC created with mcDoc_Create()), and then want to manipulate with the data concurrently from multiple threads, MCTRL.DLL
does not synchronize for you: It's your application developer's responsibility to do so in order to avoid race conditions.
Also note that some mCtrl modules may include yet another limitations. Any such limitations are described in documentation of such the particular modules. (The MC_WC_HTML control is a prominent example of such limitation.)
Before you may use any functionality of the module you have to initialize it and after you stop using it you should terminate it to free any resources the module uses.
For controls, the initialization routine typically registers the control's window class with RegisterClass()
, and the termination function unregisters it with UnregisterClass()
.
Note that for performance reasons mCtrl functions do not test whether the module is properly initialized, so the function can fail in any means if the module is not initialized, or can work if the function does not currently rely on the initialziation. But note that in the latter case there is no guaranty the behavior does not change in future versions of mCtrl.
The initialization funtion can be always called multiple times (even concurrently for multiple threads). Each module has its own initialization counter, incremented in the initialization function and decremented in the termination function. The module is really uninitialized only after the counter drops back down to zero.
MCTRL.DLL
from you dynamic library, you may not call the initialization and termination functions in context of DllMain()
. Its severly limited what can be done safely in the DllMain
context. Even if it would be safe for some modules currently there is no guaranty that future version of mCtrl won't use anything problematic in this regard.