JvExVCL



What is it?

JvExVCL is an extension to VCL that makes it easier to port VCL components to CLX. The classes in JvExVCL map VCL messages to CLX compatible virtual or dynamic methods. The big advantage is that you can write controls for CLX and VCL without IFDEF'ing the code (too much).
 

How to use it?

Just add the required JvExXXXX unit (where XXXX is the VCL unit or the VisualCLX unit without the leading "Q") to the uses clause of your control. For example use JvExStdCtrls instead of StdCtrls or QStdCtrls. Change the base class of the control to derive from TJvExXXXX (for example, derive from TJvExCustomControl instead of TCustomControl). Now you must replace any message handler with the corresponding virtual and dynamic method. By calling inherited in the first derived class the original message handler is executed (if nothing else is specified in the following tables).
 

Table of message to method mapping for TControl/TGraphicControl derived VCL classes.
message   corresponding virtual/dynamic method
CM_VISIBLECHANGED procedure VisibleChanged;
CM_ENABLEDCHANGED procedure EnabledChanged;
CM_FONTCHANGED procedure FontChanged;
CM_COLORCHANGED procedure ColorChanged;
CM_PARENTFONTCHANGED procedure ParentFontChanged;
CM_PARENTCOLORCHANGED procedure ParentColorChanged;
CM_PARENTSHOWHINTCHANGED procedure ParentShowHintChanged;
CM_TEXTCHANGED procedure TextChanged;
CM_HINTSHOW function HintShow(var HintInfo: THintInfo): Boolean;
CM_HITTEST function HitTest(X, Y: Integer): Boolean;
CM_MOUSEENTER procedure MouseEnter(AControl: TControl);
CM_MOUSELEAVE procedure MouseLeave(AControl: TControl);
CM_DIALOGCHAR function WantKey(Key: Integer; Shift: TShiftState;
  const KeyText: WideString): Boolean;
CM_FOCUSCHANGED procedure FocusChanged(AControl: TWinControl);

Extensions

 

Table of message to method mapping for TWinControl/TCustomControl derived VCL classes.

The mappings above for TControl/TGraphicControl applies to these classes as well.

message   corresponding virtual/dynamic method
CM_CURSORCHANGED procedure CursorChanged;
CM_SHOWINGCHANGED procedure ShowingChanged;
CM_SHOWHINTCHANGED procedure ShowHintChanged;
CM_CONTROLLISTCHANGE procedure ControlsListChanging(Control: TControl; Inserting: Boolean);
procedure ControlsListChanged(Control: TControl; Inserting: Boolean);
(ControlsListChanging is called before the actual change, ControlListChanged is called after the change)
CM_CONTROLCHANGE procedure ControlsListChanging(Control: TControl; Inserting: Boolean);
procedure ControlsListChanged(Control: TControl; Inserting: Boolean);
(ControlsListChanging is called before the actual change, ControlListChanged is called after the change)
WM_ERASEBKGND function DoEraseBackground(Canvas: TCanvas; Param: Integer): Boolean;
(DoEraseBackground is protected by SaveDC/RestoreDC, Param is the LParam from the message)
WM_GETDLGCODE procedure GetDlgCode(var Code: TDlgCodes);
 
TDlgCode = (
  dcWantAllKeys, dcWantArrows, dcWantChars, dcButton,
  dcHasSetSel, dcWantTab,
  dcNative { if dcNative is in the set the native functions are used and DoGetDlgCode is ignored }
);
TDlgCodes = set of TDlgCode;
WM_SETFOCUS procedure FocusSet(FocusedWnd: HWND);
WM_KILLFOCUS procedure FocusKilled(FocusedWnd: HWND);
WM_SIZE procedure BoundsChanged;
(original WM_SIZE is called before BoundsChanged)

Extensions

 

Table of message blocking for TCustomEdit/TCustomMemo derived VCL classes.
message   blocked if
WM_PASTE not (caPaste in ClipboardCommand)
WM_COPY not (caCopy in ClipboardCommand)
WM_CUT not (caCut in ClipboardCommand)
WM_UNDO not (caUndo in ClipboardCommand)
WM_CLEAR not (caClear in ClipboardCommand)

Extensions

 

How does it work?

The JvExVCL changes the route a message takes. It overrides the WndProc of the control and redirects some message to virtual or dynamic methods of the control. These methods can be overriden by user code. In order to allow the user-control to invoke the inherited behaviour all virtual and dynamic (message) methods call the inherited WndProc. This means that a simple "inherited" in the overriden method invokes the original message handler.

 

Example:
 
SendMessage(MyCtrl.Handle, CM_VISIBLECHANGED, 0, 0);
TMyCtrl.WndProc()
TMyCtrl.VisibleChanged() // overriden method
inherited VisibleChanged;
TJvExControl.VisibleChanged()
TControl.WndProc(CM_VISIBLECHANGED)
TControl.CMVisibleChanged()

 

How to extend the JvExVCL (developer)?

JvExVCL uses macros that are preprocessed by the Delphi Preprocessor (JVCL 3 contains a precompiled dpp32.exe). These macros allow easier modification because you only need to change one file and all classes derived from it will use the new features. This also means that you should not modify the generated JvExVCL units directly since they will be overwritten the next time the preprocessor is used.

The JvExVCL sources (un-preprocessed files) are in $(JVCL)\devtools\JvExVCL\src