Since the KOL library is designed for a very wide range of tasks, it is almost impossible to satisfy all requirements using the same code, while keeping its size small. The way out is to allow the programmer to choose the code variants that he needs in his specific task. This is what the conditional compilation symbols are for.
To change the set of symbols or options that control conditional compilation, open the project properties dialog (Project | Options) and on the Directories / Conditionals tab correct the Conditional defines line by listing the required symbols separated by semicolons. An alternative is to add {$ DEFINE option} declarations to the project file (DPR) for each option you want to use for the entire project. They say it works - I have not tested it.
In MCK projects, the symbol KOL_MCK must always be present here, which "hides" the VCL code of the project from the Delphi compiler at the time of compilation. Some options may not apply to KOL, but to third-party modules. For example, some component packages for KOL are dual, that is, they can work with VCL and KOL. In this case, a conditional compilation symbol is often required to include a version of the code adapted for KOL (usually this symbol is the string 'KOL' - without quotes, but you still need to read the component description before using it in practice).
The list of options that can control sections of the code of the KOL library itself is located near the beginning of the KOL.pas file, with a brief description of the purpose of each symbol. Here I will try to give a detailed overview of these symbols, but it is almost impossible to describe everything without going into details. Therefore, further in the text, these symbols are mentioned more specifically in the context of each specialized function or object to which these symbols can be applied.
In most cases, adding one of the following characters to the project options list will result in some form of increment in the application code. In the opposite cases, I record this separately.
PAS_VERSION symbol (disable assembly code). Including this option in a project will significantly increase the size of the code, and make it somewhat slower. But there is a chance that the application will be more resilient. Basically, this symbol is intended for testing purposes and for identifying "bugs" in the assembler version. The Pascal code is largely self-documenting, and is actually kept in KOL, including as a commentary to the assembler version.
However, using the PAS_VERSION symbol is not a panacea. In the history of the development of the library, it often happened that the error lurked precisely in the Pascal version of the "guilty" procedure, while the assembler version was more correct.
The PARANOIA symbol is intended, on the other hand, to deepen the optimization of the assembler code - when using older Delphi compilers, version 5 and below. (Of course, this symbol only works if the project uses the assembler version of the library code). In these versions, the compiler used double-byte versions of some machine instructions, regardless of the fact that there is a single-byte version for them, which is no different in functionality. Beginning with Delphi 6, Borland has removed this compiler flaw and is no er needed.
The SMALLEST_CODE symbol is designed to turn off everything you can do without by default. The form in this case will look very Spartan, since this also disables support for processing WM_CTLCOLORXXXX messages, which are responsible for coloring visual elements according to the developer's preferences, and the system fonts are used by default. (In this case, the color is provided by the system itself, its palette is not rich, but if functionality interests you more, then why not give the artist's functions to the system). Some checks are disabled in the code (for example: in the Int2Hex function it is no longer checked that the second parameter is> 15).
In fact, quite a lot of code fragments, mostly small ones, are disabled, and the savings in the code as a whole are very small. But it does take place, so I decided that the symbol should be.
The SMALLEST_CODE_PARENTFONT symbol, when using the above SMALLEST_CODE, nevertheless ensures that child visual objects inherit the font from their parents at the time of creation. If you install a different font for the parent than the system default for windows, then at least you don't have to repeat this operation for all its children. Thus, this option partially overrides the previous one, but only in this particular application to font inheritance.
The SMALLER_CODE symbol does almost the same thing as SMALLEST_CODE, but to a lesser extent, affecting the appearance and behavior of controls as little as possible.
The SPEED_FASTER symbol, included by default, increases the performance of some of the functions and algorithms used, at the expense of additional code. For example, the SortArray function is used to sort lists and strings, which increases the speed compared to using the more versatile SortData function by about 5-10% (in assembler version). To compare Ansi strings, the preliminary construction of an ordered set of Ansi-symbols is used, with the refusal of the subsequent call of API functions, after which the speed of comparison operations of the AnsiStrCompare and AnsiStrCompareNoCase functions increases several times. At the same time, this reduces the sorting of the list of strings StrList by several times (AnsiSort method). If improved performance is not required for these operations, this option can be disabled by adding the conditional compilation symbol SPEED_NORMAL.
The TLIST_FAST symbol changes the internal representation of lists. In the Delphi VCL, lists are actually arrays. When developing KOL, this approach was also initially taken as a basis, since provides high performance for small lists, and does not require a lot of code. With the TLIST_FAST option, the algorithms for working with lists and their internal representation are changed in such a way as to provide greater speed when inserting and deleting elements at arbitrary positions in the list. Namely, the elements are no longer stored as a solid array, but as a list of blocks with a maximum of 256 elements per block. This approach can, if used incorrectly, not only fail to increase performance, but, conversely, reduce it. For example, the operation of random access to the elements of the list at arbitrary indices can be relatively slow compared to the standard approach. To provide an opportunity for individual lists to keep the usual algorithm of operation, the list has the propertyUseBlockswhich can be installed in FALSEfor these lists. In addition, adding the DFLT_TLIST_NOUSE_BLOCKS option allows you to disable the TLIST_FAST option for default lists, and then assignUseBlocks TRUE for a select set of lists only.
The USE_NAMES symbol was added at the request of numerous programmers who are used to the fact that in the VCL every component has a Name property. Including this code adds this property to all objects starting with TObj. This makes it possible to search for components by name using the form's FindObj method. This option can also be useful for step-by-step debugging in order to make it easier to navigate in the context of code execution when stopping at an arbitrary point. MCK automatically generates the assignment of the component name to the visual and non-visual objects of the form, "hidden" in the parentheses of the conditional compilation {$ IFDEF USE_NAMES}. So, in the case of MCK projects, no additional effort is required to naming the components: it is enough to include this option in the project.
The USE_CONSTRUCTORS symbol was originally intended to use Delphi constructors for initial object initialization instead of using NewXXXXX's own constructing functions. Since there are no requirements from users to maintain this mechanism, support for the correctness of the code generated if this option is enabled is not guaranteed. In short: it is better not to use this option.
The USE_CUSTOMEXTENSIONS symbol is intended for those programmers who want to include their own additions in the KOL library, namely in the KOL.pas module itself, and precisely in the code of the TControl object. Position the cursor over this symbol, and press Ctrl + F in order to find all uses of this symbol in the KOL.pas module. You will find that it is used three times. 1) To add arbitrary code from the CUSTOM_TCONTROL_EXTENSION.inc file to the TControl object definition, 2) add some declarations to the interface section from the CUSTOM_KOL_EXTENSION.inc file, and 3) place some code into the implementation section from the CUSTOM_CODE_EXTENSION file. inc. You can prepare these files yourself and place them in the project folder. This method is good for extending the functionality of KOL without making changes to the code of the library itself, or at the stage of testing additions,
UNICODE_CTRLS symbol is intended for converting visual objects of TControl into windows that work directly in Unicode encoding. This work has been completed almost completely (although some problems are periodically found, but they are eliminated). It is enough to include this option in the project, and the application will almost completely support UNICODE encodings. All calls to API functions are redirected to UNICODE versions of these functions (with the ending W). Controls like TREEVIEW and LISTVIEW start working with UNICODE versions of window messages. Etc.
The USE_MHTOOLTIP symbol allows you to include in the library (and use in the project) tooltips implemented by Dmitry Zharov aka Gandalf. At a minimum, you will need to download the appropriate package and “install” it before adding this option to the project. After that, by assigning the Hint and ShowHint properties to regulate the use of tooltips on controls.
The USE_OnIdle symbol includes a call to the ProcessIdle procedure in the message loops, which, if there is any downtime, calls the OnIdle handler that you assigned (by the RegisterIdleHandler procedure).
The ENUM_DYN_HANDLERS_AFTER_RUN symbol quite dramatically changes the behavior of the message manager at the end of an application. By default, as soon as the AppletTerminated variable is true, dynamically attached message handlers are no longer invoked from that point on. This is done mainly in order to prevent unnecessary code activity at the time of the application termination. In some cases, for example, the activation of timers that are still not turned off, or some other handlers that respond to changes in the states of window elements (and at the moment of termination of the work, the state of windows begins to actively change, otherwise it cannot be), they could try to address objects that do not exist, or try to get handles of already destroyed windows. All this led to some glitches. To avoid such failures,
If you want your event handlers to continue working until all processes are complete, then add this option to the project, and make sure that your event handlers behave correctly when the application is closed. By the way, enabling this option does not just increase the code, but even slightly reduces it (checking the value of the AppletTerminated variable is disabled).
There are a number of conditional compilation symbols to control the appearance and behavior of buttons, regular (button) and "drawn" (bitbtn).
The BUTTON_DBLCLICK_AS_CLICK symbol for all buttons (buttons) of the application changes the functionality in such a way that the event of a double click with the mouse (left key) is no longer recognized as a double click, but in reality leads to two clicks on the button.
The ALL_BUTTONS_RESPOND_TO_ENTER symbol provides all kinds of buttons (button and bitbtn) with the ability to respond to the Enter key. The fact is that by default in Windows, buttons respond only to pressing the "space" key, and this is not my invention, this is how the window message handlers of the operating system work. In order for the buttons to be pressed with the Enter key, it is required to add some insignificant code. As KOL strives for leaner application code, this functionality has been made optional. If you want to get it in your application, add this option to your project.
The ESC_CLOSE_DIALOGS character adds a response to the Escape key for all dialog forms, ensuring that they are closed.
The CLICK_DEFAULT_CANCEL_BTN_DIRECTLY symbol changes the functionality of the default buttons (DefaultBtn property) and cancel buttons (CancelBtn property), namely, pressing these buttons from the keyboard becomes "non-visual". By default, when this symbol is not included in the project options, pressing the corresponding buttons on the keyboard results in visual clicks of buttons on the form, and switching the focus to these buttons on the form.
The DEFAULT_CANCEL_BTN_EXCLUSIVE symbol prevents the same button from assigning the CancelBtn and DefaultBtn properties at the same time. Adds some code that, when set to a property, checks for an alternative and disables the opposite property.
The NO_DEFAULT_BUTTON_BOLD character disables the special visual appearance of the default button (DefaultBtn), in which it is surrounded by a wider shadow than other buttons on the form. Disabling the special design does not increase, but even slightly reduces the code by a couple of machine instructions.
The KEY_PREVIEW symbol provides filtering of button press messages in a form handler for which the KeyPreview property is set (that is, you must both enable this option and set the KeyPreview property for the form to true so that the form can always be the first to process the keys intended for its visual objects ).
The OpenSaveDialog_Extended symbol significantly expands the functionality of the standard file open and save dialogs (TOpenSaveDialog). This option allows you to use its OSHook and OSTemplate options in the dialog properties, and specify the template name (Template property), for example, to add your own control elements (buttons, checkboxes, labels, etc.) to the dialog window. In addition, using the NoPlaceBar property, it becomes possible to turn off the "standard placements panel" on the left in the dialogs of the new standard. (This may be needed, for example, to speed up the process of opening a dialog, for some reason this panel may slow it down noticeably). If this symbol is not added to the project option, all these options are unavailable (and the placement panel is always present in this case), but the code is somewhat shorter.
The AUTO_CONTEXT_HELP symbol provides an automatic response to the WM_CONTEXTMENU message. If the target visual object (TControl) has a nonzero value of the HelpContext property, the application's help system is called for it, passing this context to it. Of course, you must take care of the formation of the help system in the form of a file with the HLP or CHM extension.
The NOT_FIX_CURINDEX symbol is for backward compatibility with older KOL projects. In the initial versions of KOL, there was a bug related to visual objects oriented to work with elements (listbox, combobox). This error led to a shift in the value of the CurIndex property in the process of programmatically assigning values to the overlying items (Items), since the assignment is performed by deleting the item and inserting a new value into its position. In the absence of this option in the project properties, this error is now eliminated automatically, but with some increase in the code. In case this error is irrelevant for your application working with visual lists, or if it is fixed in the application itself, you can add this symbol.
The NOT_FIX_MODAL symbol returns the situation to the time when KOL applications “did not know how” to activate when clicking on any of their windows at the moment when the modal window is active. By default, KOL applications now respond correctly, activating as expected. But this requires a little extra code. If you do not need this behavior correction for some reason, you can cancel it with this option.
The NEW_MODAL symbol is an alternative implementation of the modality proposed by Alexander Pravdin. The implementation of this version of the modality is a little more code-based, and even then mainly because it is not translated into assembler. And it provides more modality organization service for applications. For example, it becomes possible to use the ShowModalParented method, which allows you to show a model form only in relation to a specific form, without affecting other active forms of the application.
The USE_SETMODALRESULT symbol somewhat speeds up the application when the form is assigned a new value to the ModalResult property. By default, the value of this property will be analyzed only when processing the next message from the message queue, but the regularity of messages to the window is not guaranteed until nothing happens to it (for example, the mouse does not move and is outside the window, no keys are pressed, no redrawing) required). And the dialog, if its property is assigned a new ModalResult value programmatically, possibly after the completion of any internal operations, may "learn" that it is time to close, with some delay (sometimes a great delay). In the usual case, when the ModalResult change occurs as a response to a key press by the user, there can be no problems, since the button will still have to be pressed out, redrawing will occur, a number of window messages will appear in the queue, and the dialog will react immediately and close quickly. If your situation differs from usual, then use this option: it will provide, in addition to changing the property value, also forced activation of the message reading cycle by sending an empty WM_NULL message to the queue.
The USE_MENU_CURCTL symbol allows you to analyze in the event handler that responds to the triggering of the context menu items, which visual object was the "initiator" of the context menu. In fact, the initiator, of course, is usually the user. It is he who presses the right mouse button on any visual element of the form, and enabling this option only ensures that a pointer to the object corresponding to this visual element is entered into the property of the called CurCtl pop-up menu.
The NEW_MENU_ACCELL symbol includes alternate code for working with accelerator keys corresponding to menu items without using the system accelerator table. This is one of the few cases where the presence of an option gives a shorter code than its absence. (Probably, one should even enter the opposite symbol OLD_MENU_ACCELL, and make this version of the code the main one).
The USE_DROPDOWNCOUNT symbol allows you to change the number of dropdown items displayed in the combo box (by the DropDownCount property). If this option is absent in the project, the number of drop-down elements is entirely determined by the operating system. When this option is present, the default value is set to 8 items, and the DropDownCount property becomes available for editing, which allows you to change this value for each combo box separately.
The NOT_UNLOAD_RICHEDITLIB symbol excludes from the KOL module the part of the finalization code that is responsible for unloading the richedXXXX library, if one was loaded. In fact, even if rich edit controls are used in the project, there is no special need to unload this library, and this is done solely for pro forma. The operating system, after the application terminates, will correctly disable all dynamic DLLs in use. The only possible purpose of using this option in a project is to save some code size.
The NOT_USE_RICHEDIT symbol excludes all references to richedit from the KOL module altogether. You can use this option only if your project does not really use rich edit controls. The savings when using this symbol is about 60 bytes of code.
The RICHEDIT_XPBORDER symbol adds code to make the border of a rich edit visual appear correctly when using XP themes. With the addition of support for themes in KOL with the GRAPHCTL_XPSTYLES symbol, this symbol is automatically included together with GRAPHCTL_XPSTYLES, which provides a change of themes and more adequate rendering of visual elements (as well as their transparency) in accordance with the themes of XP / Vista / Windows7.
The USE_PROP symbol includes the old version of the code responsible for binding the window to its object. Initially, to provide such binding, API functions GetProp and SetProp were used, which create a named "property" for the window with the identifier 'SELF_'. Later it was decided that for this in most cases it is more convenient and economical to use the GWL_USERDATA field (which is obtained and set by the API functions Get / SetWindowLong). Use this option if, for some reason, you need to use the GWL_USERDATA field, as well as if you use previously written components that call GetProp to get the object associated with the window.
The PROVIDE_EXITCODE symbol provides the application exit code set in the WM_QUIT message. If this option is present, to terminate the application with the required exit code, simply executePostQuitMessage (exit_code)... If the option is missing, the exit code will always be 0.
The INITIALFORMSIZE_FIXMENU symbol provides an initial form size equal to the form design time set for the MCK project, regardless of whether the form has a main menu bar. In fact, this option ensures that the overall size of the form is saved before the main menu object of the form is created, and the form is restored to this size immediately after the menu is installed on the form. If this is not done, the system keeps the client part of the window unchanged, and for this it increases the total window size.
The USE_GRAPHCTLS symbol should be used if your project contains graphics visual objects that do not have their own windows. Prior to version 2.40, it was possible to use graphic controls without any additional character, but this option was introduced, since non-window controls are not used too often, and completely disabling the code associated with their support saves more than a hundred bytes in the final application.
The GRAPHCTL_XPSTYLES symbol allows both graphical (non-windowed) visuals and a number of window controls to look almost like XP - Vista - Seven themes when using XP themes. This requires a decent amount of code by KOL standards (visual_xp_styles.inc module), and therefore this option should be used only if you really care about the external side of the interface as much as functionality. See also the next option.
The GRAPHCTL_HOTTRACK symbol aggravates the previous option, allowing graphic visuals not only to statically look "inscribed" in the current XP theme, but also to support the visual effects associated with mouse hovering (as you know, visuals caught under the mouse cursor are slightly "highlighted" slightly changing its appearance). This option includes some more code to achieve the desired effect.
The ICON_DIFF_WH symbol provides support for TIcon objects for the Width and Height properties, allowing you to work with non-square thumbnail images (simply "icons"). Initially, KOL only had support for square icons. The functionality to support rectangular icons requires some additional code and is not required as often, which is why it was added as an option.
The NEW_GRADIENT symbol includes an alternative fill for the gradient bar suggested by Alexander Karpinsky aka homm. It is faster and smaller in code. Elliptical and rhombic fill is not supported with this option.
The NEW_ALIGN symbol enables a new (faster) way to align visuals. Currently, this option is enabled by default, and the OLD_ALIGN symbol should be used to include the old code (in the future, it will probably have to be dropped in order to simplify support).
The FILE_EXISTS_EX symbol affects the code of the FileExists function, checking for the existence of the file more carefully. The normal shortcode just takes the file attributes (GetFileAttributes) and checks that the result is received and the attribute is not a directory. In fact, DOS is not dead, and some of the file names in the system have remained reserved for the I / O devices of this prehistoric operating system, for example, PRN. *, CON. *. You can never create such files, neither programmatically nor from explorer. Moreover, these files always "exist", and the GetFileAttributes API function will return attributes that the FileExists function deems acceptable. This option exists just to use an alternative, slightly larger code that searches for the requested file on disk, and as a result, the correct answer was received to the request for the existence of the file, regardless of its phantom. If your application is not going to work with completely arbitrary files (for example, it always receives file names only as a result of executing open and save dialogs, that is, from "trusted" sources), then you will not need this option.
The NOT_USE_AUTOFREE4CONTROLS symbol, added in version 2.40, returns the previous behavior when child controls were destroyed in a separate loop in the parent control's destructor. Starting with version 2.40, this functionality is assigned to the general Add2AutoFree method, which uses the code that is always present in the KOL application. Usually, the old visual release mechanism is unnecessary (and will probably be removed from your code).
The ENDSESSION_HALT symbol adds code that immediately terminates the process in response to the WM_ENDSESSION message. Moreover, the completion occurs in this case in a rather dangerous way: through a call to Halt. This means that the application will be terminated rather abnormally, without having time to save its states and unsaved data, without performing all the other actions required by the protocol. Conclusion: this option is not recommended for use.
The PSEUDO_THREADS symbol turns all command threads (NewThreadXXX) into pseudo-threads. Basically, such a transformation can be used for debugging purposes - to increase determinism and make it easier to find errors in a multithreaded application. Another potential use of pseudo-threads is greater programmatic control over the execution priority of threads, but you must implement this functionality yourself.
The WAIT_SLEEP symbol, when present with the PSEUDO_THREADS symbol, adds 10 milliseconds of wait to the loop of its own version of the WaitForMultipleObjects function, in this case replacing the standard API function. The purpose of this addition is to reduce the processor utilization indicator displayed in the task manager (without this symbol, the dispatcher shows 100% processor utilization during the entire waiting cycle, since the cycle is spinning continuously).
And finally, about a number of options for debugging purposes. These options can help you both find problems in your own application and find bugs in the KOL library itself.
The FILESTREAM_POSITION symbol makes a copy of the current position in the fData.fPosition field of the file stream object (TStream), although this is not necessary. In fact, when accessing the Position property, the application obtains reliable information about the position in the stream in a different way; duplicating this value in the fPosition field should be equated with a debugging tool for step-by-step debugging. Thus, it becomes possible to find out what the read or write position in the stream is using the variable inspectors (without this option, it is simply impossible to find out this position when stopping at an arbitrary point until some function of the stream working with the position is called, yes and it is rather difficult to do there).
The DEBUG_GDIOBJECTS symbol includes code that counts GDI resources (fonts, brushes, pencils). If at the end of the work there are unreleased objects of these types, or after a call to a procedure that should not leave trash after itself, the balance has changed, then you should immediately start the source of the leak.
The CHK_BITBLT symbol includes code that analyzes the results of BitBlt operations (in the TBitmap.Draw method), and in case of an error, informs the user about it. I recommend using it only at the debugging stage, especially in cases where you have already noticed any artifacts during drawing.
The DEBUG_ENDSESSION symbol is used in conjunction with the ENDSESSION_HALT option to log all window messages after WM_ENDSESSION to the es_debug.txt file in the application folder. Or, this option can be used independently, just provide your own code that sets the EndSession_Initiated variable to true (and it is not at all necessary that this happens in response to the WM_ENDSESSION message).
The DEBUG_CREATEWINDOW symbol can help you debug window creation problems. If present, the Session.log file records information about requests to create windows.
The CRASH_DEBUG symbol is very useful for finding problems with pointer memory misreplorations. Fills the memory occupied by the object when it is freed with hexadecimal DD bytes. If after freeing the object the application will still try to access this memory, then the problem will be detected very quickly, since the object's data is forcibly corrupted after its "death".
DEBUG_OBJKIND symbol adds to objects TControl field fObjKind type PChar... When creating a control, this pointer receives one of the strings that specifies the kind of control (and, possibly, its construction method, for example,'TControl: BitBtn'). This feature can be useful for step-by-step debugging to understand what type of control is processing the message at the moment.
special conditional compilation symbols EXTERNAL_KOLDEFS and EXTERNAL_DEFINES
Since the total number of conditional compilation symbols can easily exceed the size limit, after which the Delphi compiler refuses to accept the remaining symbols, special conditional compilation symbols EXTERNAL_KOLDEFS and EXTERNAL_DEFINES have been introduced into KOL. If present, the PROJECT_KOL_DEFS.INC and EXTERNAL_DEFINES.INC files are included at the beginning of KOL.pas, respectively. You provide them, and you place your conditional compilation symbols in it as a set of preprocessor statements {$ DEFINE symbol}. Thus, the limitation on the number of conditional compilation symbols is removed, and it becomes more convenient to manage them than by editing project properties. Do not forget that after changing the composition of symbols, it is better to rebuild the project using the Build command (not Compile).
F_P must be used for FreePascal compatibility. It should be added to the list of defined project symbols when compiled by this compiler.
Other options will be described throughout this text in the context of the various KOL components, if required.