-
Notifications
You must be signed in to change notification settings - Fork 74
RadASM Custom Controls
Custom controls are dynamic link library files that add additional functionality to RadASM and to programs that make use of them. They can add new types of UI interaction that speeds up development for developers and potentially adds an ease of use quality to programs, for users that use them.
Custom controls can be added to RadASM in two ways: by using the menu Option->Custom Controls and browsing for the the appropriate dll file that hosts the controls

or by manual editing the RadASM.ini file and adding the dll file reference to the CustCtrl section. Optionally the number of controls hosted in the dll file can be specified by manually editing the CustCtrl entry and appending a comma and the count of the number of controls. Below is an example of a CustCtrl entry:
[CustCtrl]
1=RACad.dll,1
2=RAEdit.dll,1
3=RAHexEd.dll,1
4=RAGrid.dll,1
5=SprSht.dll,1
6=WBDll.dll,1
7=RAFile.dll,1
8=RACodeComplete.dll,2
9=hl.dll,1
10=RAGraph.dll,1
11=RAVideo.dll,1
The maximum number of custom controls was 32 and was raised to 64 with v2.2.2.3 of RadASM. A number of custom controls are already included with RadASM packages and these controls are stored in the same folder as RadASM.exe by default.
A custom control is a standard win32 dynamic link library file. The RadASM custom control dll requires at least two functions exported for it to be usable with RadASM (after it has been added to the CustCtrl section via manual entry or via menu option). These two functions are:
GetDefGetDefEx
The prototypes for both functions are as follows:
GetDef PROTO :DWORD ; nInx
GetDefEx PROTO :DWORD ; nInx
If you are developing the custom control using assembly (and using RadASM) you will also need to specify in the definition file the required functions for exporting, for example:
LIBRARY MyControl
EXPORTS GetDef
GetDefEx
Additionally the dll will require the DllEntry function, and in this you should make a call to a function to register your controls class. Here is an example of the DllEntry function:
DllEntry PROC PUBLIC hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
.IF reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
Invoke InstallControl, hInst, TRUE
.ELSEIF reason == DLL_PROCESS_DETACH
.ENDIF
mov eax,TRUE
ret
DllEntry ENDP
The above example shows a call to an InstallControl function. It might look something like this example:
InstallControl PROC PUBLIC hInst:HINSTANCE, fGlobal:DWORD
LOCAL wc:WNDCLASSEX
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_PARENTDC or CS_DBLCLKS
.if fGlobal
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_PARENTDC or CS_DBLCLKS or CS_GLOBALCLASS
.endif
mov wc.lpfnWndProc, offset MyControlMainProc
mov eax, NULL
mov wc.cbClsExtra, eax
mov wc.hbrBackground, eax
mov wc.lpszMenuName, eax
mov wc.hIcon, eax
mov wc.hIconSm, eax
mov wc.cbWndExtra, 4
mov eax, hInst
mov wc.hInstance, eax
mov hInstance, eax
mov wc.lpszClassName, offset szMyControlClassName
Invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
Invoke RegisterClassEx, Addr wc
ret
InstallControl ENDP
Whatever the name of the function, the function used to register your control should include code to store the class information for your control in a WNDCLASSEX structure. The WNDCLASSEX structure is then used in a call to the RegisterClassEx function. The lpfnWndProc field of the WNDCLASSEX has to point to the controls main window procedure, which is where the main controls functionality is handled along with any required windows events (WM_ messages) and painting of the control.
Once your control's class is registered then the control can be created by referencing the classname in calls to CreateWindow/CreateWindowEx or via a dialog creating its child controls from resources that reference the control's classname.
The GetDef function was used by earlier versions of RadASM v1.2.0.5 until RadASM v2.1.0.4 when the GetDefEx function was introduced to extend the functionality. GetDef remains to provide backward compatible support for older custom controls.
GetDef has one DWORD parameter, which is nInx, an index to the control hosted in the dll to fetch information for. GetDef must return in eax a valid pointer to a CCDEF structure for the specified index (nInx parameter) or 0 otherwise.
GetDefEx has one DWORD parameter, which is nInx, an index to the control hosted in the dll to fetch information for. GetDefEx must return in eax a valid pointer to a CCDEFEX structure for the specified index (nInx parameter) or 0 otherwise.
Typically the GetDef and GetDefEx functions will look like the following example (for 1 hosted control)
GetDef PROC nInx:DWORD
mov eax, nInx
.IF !eax
Invoke LoadBitmap, hInstance, IDB_BMP ; Load the toolbox bitmap
mov ccdef.hbmp, eax ; Save handle of bitmap to ccdef struct
lea eax, ccdef ; Return pointer to inited ccdef struct
.ELSE
xor eax, eax
.ENDIF
ret
GetDef ENDP
GetDefEx PROC public nInx:DWORD
mov eax, nInx
.IF !eax
Invoke LoadBitmap, hInstance, IDB_BMP ; Load the toolbox bitmap
mov ccdefex.hbmp, eax ; Save handle of bitmap to ccdefex struct
lea eax, ccdefex ; Return pointer to inited ccdefex struct
.ELSE
xor eax, eax
.ENDIF
ret
GetDefEx ENDP
The CCDEF and CCDEFEX structures store information relating to each control hosted in the dll file. The CCDEF structure is used with the GetDef function and the CCDEFEX structure is used with the GetDefEx function. Both structures share mostly the same fields with a few exceptions - which are detailed below.
For a dll file that host multiple controls, additional CCDEF and CCDEFEX definitions will be required. For best practice the requirement should be for every control hosted, a pair of CCDEF and CCDEFEX definitions is required.
;Used by RadASM 1.2.0.5
CCDEF STRUCT
ID DD ? ; Controls uniqe ID
lptooltip DD ? ; Pointer to tooltip text
hbmp DD ? ; Handle of bitmap
lpcaption DD ? ; Pointer to default caption text
lpname DD ? ; Pointer to default id-name text
lpclass DD ? ; Pointer to class text
style DD ? ; Default style
exstyle DD ? ; Default ex-style
flist1 DD ? ; Property listbox 1
flist2 DD ? ; Property listbox 2
disable DD ? ; Disable controls child windows. 0=No, 1=Use method 1, 2=Use method 2
CCDEF ENDS
;Used by RadASM 2.1.0.4+
CCDEFEX STRUCT
ID DD ? ; Controls uniqe ID
lptooltip DD ? ; Pointer to tooltip text
hbmp DD ? ; Handle of bitmap
lpcaption DD ? ; Pointer to default caption text
lpname DD ? ; Pointer to default id-name text
lpclass DD ? ; Pointer to class text
style DD ? ; Default style
exstyle DD ? ; Default ex-style
flist1 DD ? ; Property listbox 1
flist2 DD ? ; Property listbox 2
flist3 DD ? ; Property listbox 3
flist4 DD ? ; Property listbox 4
lpproperty DD ? ; Pointer to properties text to add
lpmethod DD ? ; Pointer to property methods
CCDEFEX ENDS
Each field of the structures as pointed to by a defined .DATA variable should be filled in to help define how the control will work and respond. As example of a control using both structures could be like this:
.CONST
MYCTRLID EQU 70000
.DATA
szTip DB 'My New Control',0
szCap DB 'Some Text to display',0
szName DB 'IDC_MYCONTROL',0
szClass DB 'MyControlClass',0
; NILTWHCBCMMEVCSDAAMWMTLCSTFMCNAW SFSTFSGIUSOSMHTxxIIBPOTTAWAATWDD
ccdef CCDEF <MYCTRLID,offset szTip,0,offset szCap,offset szName,offset szClass,STYLE,EXSTYLE, 11111110000110000000000101000000b, 00010000000000011000000000000000b,0>
ccdefex CCDEFEX <MYCTRLID,offset szTip,0,offset szCap,offset szName,offset szClass,STYLE,EXSTYLE, 11111110000110000000000101000000b, 00010000000000011000000000000000b,0,0,offset szProperty,offset Methods>
Additional explanation and coverage of each field used in the CCDEF and CCDEFEX structures may help with understanding their purpose - using the example above.
ID (CCDEF/CCDEFEX) - This is a unique identifier for the custom control. Custom controls should use an value above 65535. In the example we are using a constant MYCTRLID with the value of 70000 to store in the CCDEF and CCDEFEX structures using the ccdef and ccdefex variables.
lptooltip (CCDEF/CCDEFEX) - A pointer to a string containing the tooltip to be displayed when the user hovers over the custom control's image button on the toolbox.
hbmp (CCDEF/CCDEFEX) - A handle to a bitmap used for the custom controls image button on the toolbox. Typically the bitmap is stored and compiled as a BITMAP resource in the custom control, and a call to LoadBitmap (Invoke LoadBitmap,hInstance,IDB_BMP) is used inside the GetDef and GetDefEx functions to obtain the handle and store it in the hbmp field before GetDef and GetDefEx return the pointer to the CCDEF / CCDEFEX variable.
lpcaption (CCDEF/CCDEFEX) - A pointer to a string containing the text associated with the control. This text is shown as the Caption property in the properties list of the control when editing the dialog that uses this custom control. Controls will use this text in different ways: as a title, as some text to display etc.
lpname (CCDEF/CCDEFEX) - A pointer to a string containing the constant text name used to associate the controls id with. Not to be confused with the ID field above, the controls id is used in the resource file. The text representing this id can be used in code to interact with the control. This text is shown as the (Name) property in the properties list of the control when editing the dialog that uses this custom control. The text is appended with a numeric for each new control of that type added to a dialog (IDC_MYCONTROL1 etc). Using the menu option Tools->Export IDs Equ this will be exported to a constant equate (IDC_MYCONTROL1 EQU 1001 for example)
lpclass (CCDEF/CCDEFEX) - A pointer to a string containing the class to use when creating the control. The class must be registered before the control can be used by the RadASM IDE or by any program that creates the control either by a call to CreateWindow/CreateWindowEx or by reference to the class in a dialog when it loads its child resources.
style (CCDEF/CCDEFEX) - The default windows style flags used when creating the control, typically these will include WS_VISIBLE and WS_CHILD at least. Any custom flags you have defined with your control can also be included here. Windows reserves the lower 16bit word of dwStyle for use by the user. See Windows Styles for more details.
exstyle (CCDEF/CCDEFEX) - The default windows extended style flags used when creating the control. Typically this will be 0 unless you have a specific requirement. See Extended Windows Styles for more details.
flist1 (CCDEF/CCDEFEX) - A DWORD size bitmask that indicates which properties are shown in the properties list of the control when editing the dialog that uses this custom control. Note: Only some of the properties are general and can be used by the custom control. These properties are marked with *
Bit Property Use
31 (Name) *
30 (ID) *
29 Left *
28 Top *
27 Width *
26 Height *
25 Caption *
24 Border *
23 SysMenu -
22 MaxButton -
21 MinButton -
20 Enabled *
19 Visible *
18 Clipping *
17 ScrollBar *
16 Default -
15 Auto -
14 Alignment -
13 Mnemonic -
12 WordWrap -
11 MultiLine -
10 Type -
09 Locked -
08 Child *
07 SizeBorder -
06 TabStop *
05 Font -
04 Menu -
03 Class -
02 Notify -
01 AutoScroll -
00 WantCr -
flist2 (CCDEF/CCDEFEX) - A second DWORD size bitmask that indicates which properties are shown in the properties list of the control when editing the dialog that uses this custom control. Note: Only some of the properties are general and can be used by the custom control. These properties are marked with *
Bit Property Use
31 Sort -
30 Flat -
29 (StartID) -
28 TabIndex *
27 Format -
26 SizeGrip -
25 Group *
24 Icon -
23 UseTabs -
22 StartupPos -
21 Orientation -
20 SetBuddy -
19 MultiSelect -
18 HideSel -
17 TopMost -
16 xExStyle *
15 xStyle *
14 IntegralHgt -
13 Image -
12 Buttons -
11 PopUp -
10 OwnerDraw -
09 Transp -
08 Timer -
07 AutoPlay -
06 WeekNum -
05 AviClip -
04 AutoSize -
03 ToolTip -
02 Wrap -
01 Divider -
00 DragDrop -
disable (CCDEF only) - Disable controls child windows. 0=No, 1=Use method 1, 2=Use method 2
flist3 (CCDEFEX only) - A third DWORD size bitmask that indicates which custom properties are shown in the properties list of the control when editing the dialog that uses this custom control. Custom properties are defined with the use of the lpproperty and lpmethod fields. See below for details.
flist4 (CCDEFEX only) - A fourth DWORD size bitmask that indicates which custom properties are shown in the properties list of the control when editing the dialog that uses this custom control. Custom properties are defined with the use of the lpproperty and lpmethod fields. See below for details.
lpproperty (CCDEFEX only) - A pointer to a string containing a comma seperated list of custom properties to add to the control which will be shown in the properties list when editing the dialog that uses this control. An example of which is:
szProperty DB 'TextFontType,TextFontSize,Hand,TextAlign',0
lpmethod (CCDEFEX only) - A pointer to an array containing information relating to each comma seperated property as defined in the lpproperty field. The pointer to the array is defined in the CCDEFEX structure using an offset (for example Offset Methods where Methods is the start of the array and the variable defined in the .DATA section). Each array entry contains two DWORD values. The first DWORD value indicates the type of property: A true/false, or a multiple selection property. The second DWORD value is a pointer to another structure - the structure it points to depends on the type of property (defined in the first DWORD value), either an array of true/false entries or an array pointing to multiple options.
The supported property types are defined as:
.CONST
PROP_STYLETRUEFALSE EQU 1 ; TRUE/FALSE style
PROP_EXSTYLETRUEFALSE EQU 2 ; TRUE/FALSE extended style
PROP_STYLEMULTI EQU 3 ; Mulitple selection
PROP_STYLETRUEFALSE_DESC EQU 4 ; TRUE/FALSE style with custom property description (added in v2.2.2.3)
PROP_EXSTYLETRUEFALSE_DESC EQU 5 ; TRUE/FALSE extended style with custom property description (added in v2.2.2.3)
PROP_STYLEMULTI_DESC EQU 6 ; Mulitple selection with custom property description (added in v2.2.2.3
PROP_STYLETRUEFALSE example:
.CONST
HAND_POINTER EQU 80h
.DATA
szProperty db "Hand pointer",0
PropertyHand dd -1 xor HAND_POINTER,0
dd -1 xor HAND_POINTER,HAND_POINTER
Methods dd PROP_STYLETRUEFALSE,offset PropertyHand
PROP_STYLETRUEFALSE_DESC example:
.CONST
HAND_POINTER EQU 80h
.DATA
szProperty db "Hand Pointer",0
PropertyHand dd -1 xor HAND_POINTER,0
dd -1 xor HAND_POINTER,HAND_POINTER
db "Specifies if the mouse changes to a hand pointer.",0
Methods dd PROP_STYLETRUEFALSE_DESC,offset PropertyHand
PROP_STYLEMULTI example:
.CONST
ALIGN_LEFT EQU 128 ; left aligned text
ALIGN_RIGHT EQU 256 ; right aligned text
ALIGN_CENTER EQU 512 ; center aligned text
.DATA
szProperty DB 'TextAlign',0
PropertyTextAlign db 'Left,Right,Center',0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_LEFT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_RIGHT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_CENTER
dd -1,0
Methods dd PROP_STYLEMULTI,offset PropertyTextAlign
PROP_STYLEMULTI_DESC example:
.CONST
ALIGN_LEFT EQU 128 ; left aligned text
ALIGN_RIGHT EQU 256 ; right aligned text
ALIGN_CENTER EQU 512 ; center aligned text
.DATA
szProperty DB 'TextAlign',0
PropertyTextAlign db 'Left,Right,Center',0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_LEFT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_RIGHT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_CENTER
dd -1,0
db "Specifies the alignment of text displayed in the control",0
Methods dd PROP_STYLEMULTI_DESC,offset PropertyTextAlign
A PROP_STYLEMULTI and PROP_STYLETRUEFALSE combined example:
.CONST
HAND_POINTER EQU 80h
ALIGN_LEFT EQU 128 ; left aligned text
ALIGN_RIGHT EQU 256 ; right aligned text
ALIGN_CENTER EQU 512 ; center aligned text
.DATA
szProperty DB 'TextAlign,Hand Pointer',0
PropertyTextAlign db 'Left,Right,Center',0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_LEFT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_RIGHT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_CENTER
dd -1,0
PropertyHand dd -1 xor HAND_POINTER,0
dd -1 xor HAND_POINTER,HAND_POINTER
Methods dd PROP_STYLEMULTI_DESC,offset PropertyTextAlign
dd PROP_STYLETRUEFALSE_DESC,offset PropertyHand
A PROP_STYLEMULTI_DESC and PROP_STYLETRUEFALSE_DESC combined example:
.CONST
HAND_POINTER EQU 80h
ALIGN_LEFT EQU 128 ; left aligned text
ALIGN_RIGHT EQU 256 ; right aligned text
ALIGN_CENTER EQU 512 ; center aligned text
.DATA
szProperty DB 'TextAlign,Hand Pointer',0
PropertyTextAlign db 'Left,Right,Center',0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_LEFT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_RIGHT
dd -1,0
dd -1 xor (ALIGN_LEFT or ALIGN_RIGHT or ALIGN_CENTER),ALIGN_CENTER
dd -1,0
db "Specifies the alignment of text displayed in the control",0
PropertyHand dd -1 xor HAND_POINTER,0
dd -1 xor HAND_POINTER,HAND_POINTER
db "Specifies if the mouse changes to a hand pointer.",0
Methods dd PROP_STYLEMULTI_DESC,offset PropertyTextAlign
dd PROP_STYLETRUEFALSE_DESC,offset PropertyHand