ToolBar .
In [Configuration] / [Source Editor], you may set the ToolBar On.
You can customize the ToolBar by Double-Cliking on it. You can also, move the ToolBar Button by [Alt] / [Drag].
[Alt] / [Drag] may also be used to insert/remove Separators: Just move a Button half way of its size.
~~~~~~~
Loaders ...
Be aware that, because of some bugs in older Win32 Versions, your Resources should not exceed 0FFFF size. So, avoid loading big sound files or big BitMaps in Resources. Let them reside in files. The fitting equivalent functions do exist.
BitMap Loader
To allow BitMaps now, I have just written a little Loader instead of an Editor. I am unsure that, in this particular case (as there are so many good Editors available for free), that it would be of no interest to write another Editor for RosAsm.
RCDATA Loader
RC data are undefined resources. You can store what you want under this general purpose type. To retrieve RC Data resources, do:
GetRcDataPtr:
api 'KERNEL32.FindResourceA' D§hInstance eax &RT_RCDATA
api 'KERNEL32.LoadResource' D§hInstance eax
api 'KERNEL32.LockResource' eax
mov esi eax
ret
mov eax 1 ; ID number
call GetRcDataPtr ; >>> esi = Pointer to Data
Wave Loader
Like it says. To play a Resource Wave:
api 'WINMM.PlaySound' ID D§hInstance &SND_ASYNC__&SND_RESOURCE
Again, take care of size. I cannot implement an alert MessageBox because the limit size may vary depending on the Memory state and on the various Win32 releases. Resources are not a good place to store full Wave Files. You have the disk for this. See the File version of PlaySound in mmedia.hlp and MCI functions for files larger than 100 Kb.
Since V.2.004c, this Resources Size limitation has been removed, it remains nevertheless better to keep huge Resources on Disk.
Avi Loader
Avi in resources can only be silent ones (without sound). For the ones with sounds, see in Ron Thomas demo (AviDemo).
To play a Resource Avi, see ACM_OPEN / ACM_PLAY in Win32.hlp. Other files functions (with sounds are in WinMM.hlp).
Cursors Loader
As it says. To load a custom cursor from resources:
api 'User32.LoadCursorA' D§hInstance ID | mov D§CustomCursorHandle eax
To assign a Cursor to some Window at run time:
api 'User32.SetClassLongA' D§MyWindowHandle &GCL_HCURSOR D§CustomCursorHandle
Icons Loader
RosAsm manages two features for icons: the main Icon_Editor and an Icons loader for other Icons. Both work on the same resources Type. Main Icon ID is 1. The first 'other icon' ID is 2. The main Icon Editor is able to retrieve the fitting icon inside multi-icons files. The loader deals only with mono-icons file but they can be of any icon type.
~~~~~~~
Accelerators ....
I choose to not implement any Accelerators Editor for following reasons:
We have two ways for managing Accelerators. Accelerators stored in Resources:
call 'USER32.LoadAccelerators' D§hInstance ID
mov D§AccelHandle eax
and Accelerators stored in Data:
[ACCELERATORS:
U§ &FVIRTKEY__&FNOINVERT &VK_F1 M00_Help
&FVIRTKEY__&FCONTROL__&FNOINVERT 'F' M00_Find
&FVIRTKEY__&FCONTROL__&FNOINVERT+FLAGLAST &VK_8 DRAWLINE]
[ACCELNUMBER 3 FLAGLAST 080]
call 'USER32.CreateAcceleratorTableA' ACCELERATORS ACCELNUMBER
mov D§AccelHandle eax
__________________________________________________________________
; In both cases, the main message loop looks like this:
__________________________________________________________________
jmp L1>
L0: call 'User32.TranslateAccelerator' D§hwnd D§AccelHandle Firstmsg
call 'User32.TranslateMessage' Firstmsg
call 'User32.DispatchMessageA' Firstmsg
L1: call 'User32.GetMessageA' FirstMsg 0 0 0
cmp eax 0 | ja L0<
call 'USER32.DestroyAcceleratorTable' D§AccelHandle ; <<<<<<<<<<
call 'Kernel32.ExitProcess' D§FWparam
The only difference between these two ways is that, when storing Accelerators in Resources, upper '<<<<<<<<' line is not required whereas it is, with Data Accelerators. This is not a great inconvenience..
On the other hand, having Accelerators table(s) in Resources have several disadvantages. The first one is bound to the way RosAsm holds the source and the resources: There is no way to store any ID Equate in Resources. So, having an Editor for Accelerators would require we enter the IDs by number (like all other Editors). This can be an added pain, compared to simple Data storage (which allow Equates, as usual). For example, if you add an item at the beginning of a menu, all the following Menu IDs are changed. We just Click on [Store IDs to ClipBoard] and paste our new Equates set. But, if these IDs are reused in Accelerators (which is usually the case), we would have to change all the bounded Accelerators IDs by hand.
A solution would be to implement an Equates parser between Source and Resources jobs. This would be possible but I consider this as much too much work for a such an easy problem.
A last point is that Data Accelerators are a bit easier to modify at run time, for example to provide a user customizable list than one stored in Resources.
~~~~~~~
Strings in Resources ..
Strings in Resources are rarely used because they are at least double the size (Unicode storage + Resources tree headers + dummy Strings, when required) and because they are slower to access. So, you should never consider Resources as a good place where to store your Applications Strings. Usual Memory is the preferred place for this.
In RosAsm, the whole size of Resources Strings is limited to 0FFFF.
To load a String:
call 'USER32.LoadStringA' D§hInstance ID StringBufferAddress D§StringBufferLength
Resources Strings are well designed for storing small Strings that you wish to access randomly, using the Strings IDs as an access index, as, for example, with ToolTips Strings. Here is a clever example from a Test Department's Tutorial.
;==============================================================================
; WM_NOTIFY (value=4Eh) message, here used to show the toolbar tip !
; With a WM_NOTIFY message Windows gives you pointer to a NMHDR structure.
;------------------------------------------------------------------------------
WP1_uMsg_04E:
cmp eax 04E ;check if WM_NOTIFY message recieved
jne WP1_uMsg_0A0 ;if not goto label
;------------------------------------------------------------------------------
; The NMHDR structure contains information about a notification message.
; The TOOLTIPTEXT structure identifies a tool for which text is to be displayed
; and receives the text for the tool.
; We must fill it with the CORRECT values ...
; The POINTER to this structure is specified as lParam member of WM_NOTIFY.
; This POINTER is given to us with the WM_NOTIFY message by Windows.
;------------------------------------------------------------------------------
; - NMHDR structure -
; hwndFrom = D$WP1_lParam+0 ;handle to control sending message
; idFrom = D$WP1_lParam+4 ;identifier of control sending message
; code = D$WP1_lParam+8 ;notification code
; - TOOLTIPTEXT structure -
; hdr = placeholder for NMHDR ;required for all WM_NOTIFY messages
; lpszText = D$WP1_lParam+12 ;Pointer string or resource ID
; szText[80]= D$WP1_lParam+16 ;buffer for text, alternate to lpszText
; hinst = D$WP1_lParam+20 ;handle instance, 0 if lpszText=pointer
; uFlags = D$WP1_lParam+24 ;Flag indicates how to interpret idFrom
;------------------------------------------------------------------------------
mov ebx D$WP1_lParam ;pointer to struc, given by windows !
mov eax D$ebx+8 ;move code ( NMHDR structure ) into eax
cmp eax 0FFFFFDF8 ;check if code TTN_NEEDTEXT received
jne TB_customize_0 ;if not goto label
mov eax D$ebx+4 ;move idFrom ( NMHDR structure ) to eax
cmp eax 0C0 ;is it toolbar button ID=0C1h
jb WP1_return
cmp eax 0CD ;last identifier in TBBUTTON structure
ja WP1_return
mov D$ebx+12 eax ;store resource ID of tooltiptext
mov eax D$hInstance
mov D$ebx+20 eax ;store module instance
As you can see, the 3 last instructions are enough to return the information expected in response to the WM_NOTIFY message. TD has ranged his ToolBar Buttons IDs from 0C0 to 0CD. Then, he saved in Resources the respective ToolTips Strings with the same ID numbers so that there is no computation at all to perform the attributions.
Strings Editor usage
Enter your Strings in the Strings Edit Box. Begin each String with the decimal #Number of each String ID:
#1 First string.
#2 Second string with
one CR/FL inside
#3 Third string with...
... 2 CR/LF inside.
The First entered Chararacter of a new String *MUST* be '#', immediately followed by the decimal number, with one single space before the String data. If you hit 2 Spaces between the number and your first 'non-Space' data, your String begins by one Space.
CR/LF and Tabs are allowed.
ID numbers are from 0 to 0FFFF and are to be given in Decimal notation only.
IDs Internals
It might seem surprising that a zeroed ID would be impossible, but, for strings, it is. In Resources, the true user_IDs are split this way: (User_ID shr 4) + 1. These 'main IDs' are the ones stored in the Resources tree. The relative Resources pointers point to groups of 16 unicodes Strings written in Pascal convention one after another (Len, String, len, String,...). The 4 Bit lower part of the user_IDs are not stored at all. The loading functions simply read as many records as wished to access the target String inside a group.
When entering Strings IDs that are *not* aligned on 16 bit boundaries, or that are not conforming to the numeric order, the Editor fills the missing records with dummy Strings. When reloading a Strings table, the Editor shows you these added Strings paddings.
Inserting Strings
Because of this complicated organization, the Editor is featured for helping you at inserting Strings inside long tables. You can add any String with any ID, anywhere you like. If the IDs you enter are not in numeric order, the Editor will rearrange the Strings for you. If two Strings have the same ID, the Editor will increase the following IDs, only as far as required, saving you the pain of rewriting all the downward IDs and checking these damned boundaries. This simplifies a lot the problems you would encounter when inserting new Strings. Example:
You have entered a table like this:
#1 One
#2 Three
#3 Four
#16 Sixteen
#17 Eighteen
Now, you add, at the bottom, two Strings to be inserted:
#1 One
#2 Three
#3 Four
#16 Sixteen
#17 Eighteen
#1 Two <<<<
#16 Seventeen <<<<
If you hit [OK] and, again, [Resources] / [Strings], you will see:
#0
#1 One
#2 Two <<<<
#3 Three
#4 Four
#16 Sixteen
#17 Seventeen <<<<
#18 Eighteen
~~~~~~~
Menu Editor ....
Enter your menu names (what user sees in your application's menu) in the main window. One per line. Use '&' sign to design desired shortcuts as usual.
Blank lines are Menu Separators. Never enter any blank line if you do not expressly want a Separator between two items. No blank line as first or last line!
Use [tab]s to define your menu levels organization. In this new version, you no longer have to set the flags for Popup / Item / LastItem / LastPopup. The editor does it better than us, ... after analysis of tabs.
Use [tab] too, to separate menu item name from menu Items hotkeys. example: '&Paste[tab]Ctrl+V'. This will prevent the 'keys' to be part of the equate name you will be given back, for use in your message loop.
'ID_Menu' value is used to stand all the IDs numbers of a menu. Instead of writing, for as many items [M00_New 1001 M00_Open 1002 ....], you simply write one '1000' in this edit box and the editor does the job: When over, click on 'Equates > Clipboard', go to your source and paste (Ctrl/V) to get all the menu equates at once. Do this each time you modify your menu and avoid modifying the names once done, as you would have to modify your source evocations too... For namings, do not use signs that would conflict with RosAsm symbols writing convention (math signs, reserved signs).
Example of flags, as set by the Editor after 'tabs' analysis:
> File [* PopUp]
> &New [* Item]
> &Open [* Item]
> &Close [* Item]
> ; true separator
> E&xit [* LastItem]
> &Help [* LastPopUp] ; last popup of level 1
> &About [* Item]
> ; true separator
> Topics [* LastPopUp] ; last popup of 'Help level' (level 2)
> &Editor Help [* Item]
> &Criptor Help [* LastItem] ; closes the list
To edit the 'Grayed' flag, double-click on each menu item in order to make the CheckBox active. Menus data have several other flags to allow 'dead hot keys', 'checked Items' 'Radio items'. They are not yet implemented. (We usually prefer to set them at run time by Api calls anyway... more consistent).
~~~~~~~
Icon Editor ...
It can upload icons from PEs and .ico files and rewrite them to PE file or save them in a new icon file. Choosing the 'Keep' option defines the actual icon as the one to use and save with actual edited application (if any). I have restrained .ico saving to only new files because in this first write version, we do not have 16/16 icon. So it's better not to overwrite pre-existing icon files that could previously contain many icons (this is most often the case).
For icon edition:
Left click on a color box > Color selection for drawing
Left click on edit box > Drawing
Right click on edit box > Clearing
For Color selection:
Right click on color box > Color edition
Left click on rainbow > Temporary select the color
Left click on color box > Fixes new chosen color
Right click anywhere > Restore previous color and exit rainbow
Colors selection is not so sophisticated as the 'common' one but, instead, it does what we need (what the common one does NOT do): changing this ONE color we have chosen to. The 'rainbow' is a simple red/blue square table and the slider rules the amount of green.
Do not forget that when you modify an existing PE icon, Win doesn't update opened directories: In this case, you have to 'refresh' to see the results.
>>>>>>>>>>> Main ID_Icon is 1 <<<<<<<<<<<<
~~~~~~~
Wizards ..
The Wizards Concept
A Wizard is a Visual Designer Interface that creates a Source Template to be pasted into a client Source.
RosAsm Wizards are independent PE files, to be located in the [RosAsmFiles] Folder, aside the Equates Files, the Interactive Visual Tutorials, and friends. For now, only one Wizard is available, and is still under development, the Form Wizard.
You can run the Wizards either by the [Wizard] Menu Item, for fresh new creations, or you can re-edit an existing Wizard Template, by Right-Clicking upon the associated 'Tag' Comment in the source code.
The Wizards Templates
When leaving the Wizard, the edited Template is pasted inside your Source, at the actual position of the Cursor. A Template always begins by, for example:
; Tag Wizard Form 'FileName'
... and ends with:
; Tag End
You should never remove, or even modify, these Comments and the in-between Sources, if you wish to keep the re-edition possibility. Modifying something inside the Template Source will be erased by a re-edition.
Because of this difficulty, you should always paste your Wizards Templates at the end of your Source, in a dedicated TITLE, in order to make sure that you will never accidentally modify them. The Source Editor has actually no security implemented to save you from such accidents.
The actual Form Wizards
This first Wizard is still under development and is actually used to study, define and finalize the exchange mechanisms between the Source Editor and the Wizards. It is fully effective, but will probably be improved and extended.
The purpose of this Form Wizard is to visually edit the windows interface of a Program, a bit similar to what the Resources Editor does, but in a more powerful and flexible manner as, in this case, the creations are not based on Dialogs, but on the 'CreateWindow' Function.
The Form Wizards Files
The Window Wizard File (*.wwf) format is used to store all information about a form.
See the Wizard source code for additional information on the file format (TITLE Help).
Wizard Global Introduction
Drawing
All drawing actions can be done with the mouse.
Once you have drawn a control, you can move it by a simple drag-and-drop.
A right-click on one of the controls will display a context menu which provides quick access to Edit menu options.
Properties
The properties window allows you to modify all the styles available for a given control.
(Window Tab for window styles, WindowEx Tab for extended window styles and Control Tab for control specific styles)
The A-Z Tab contains additional information:
The Name of the control as it will appear in RosAsm Source
The Caption of the control
The client coordinates of the control.
Code writing
You can output the code corresponding to your form in several ways. (All these options are available in the Output menu)
Display it in a pop-up window.
Write it to a file.
Paste it into RosAsm.
Menu
File
New : Create a new form
Open : Open a new *.wwf file
Save : Save the current form
Save As : Save the current form with new name
Edit
Bring To Front : Bring the control to the top of the Z-Order.
Send To Back : Send the control to the bottom of the Z-Order.
Delete : Delete the current selected control(s).
Lock Controls : Lock control position.
Output
Display
The whole code : Display in a pop-up window the code corresponding to the current form.
Current control code : Display in a pop-up window the code corresponding to the current selected control (the one with yellow squares).
Write in file : Write in a file the code corresponding to the current form.
Paste in RosAsm and quit : Paste into RosAsm the code corresponding to the current form, save it in a file and close the wizard.
Requirements
The wizard uses a file so as to store all the window and control styles.
The file rwslist.dat is a raw list of all available styles with only basic information. You can get more information about this file in the Wizard source (TITLE Help).
~~~~~~~
Memory Templates Dialog ....
The Memory Templates are the ones you save in the ClipBoard, paste in your Source as Data, and execute with:
call 'USER32.DialogBoxIndirectParam', ...
They are more flexible than the ones saved directly by the Dialog Editor into Resources, and they do not have any of limitations that I have chosen to set, for simplicity, security and portability means.
If you wish to modify some behavior or some appearance of your Dialog, at run time, memory templates are a good choice. Just one example:
Depending on user action, you want to stand your dialog up screen or down screen. Maybe (I really do not know...), there is some api or some message you could send to your dialog to get what you mean. But, -if this *does* exist-, it will take you one hour, one day, one ... (!!!!) to find what, where, how in damned Win32.hlp. With such a template in memory:
[MyDialogTemplate: B$
D$ 090C400C2 0 ; style / extended style
U$ 03 ; control-number
MDTX: 0000 ; X pos
MDTY: 0000 ; Y pos
00DC 00C8 ; width hight
0 ; no menu
0 ; class 0 > default
'New Dialog' 0 ; title
08 'Helv' 0 ; Font'
...]
You can do:
move W$MDTY W$WishedPosition
... and it's done. (in this example, of course, DS_CENTER is off).
You can find such an example of modification in RosAsm Source at 'SetFindReplaceBox:' / 'SetSimpleSearchBox:' where the same Dialog data are used for both options with different sizes and Controls number.
You will notice that each control is a separate [data set]. This is because templates Controls must be dWords aligned: Don't remove the brackets. You can modify the data as you wish, like any other data set, but, of course with respect to according Win32 dialog data rules.
Your are responsible, too, for setting the names you wish for each template component. A Dialog Template, fresh out from ClipBoard, could look like this:
[Dialog: D$ 090C408C2 0 ; Style
U$ 03 0 0 0DC 0C8 ; Dim
0 ; Menu (not yet)
0 ; Class(not yet)
'Example Dialog' 0 ; Title
08 'Helv' 0] ; Font
[Control0: D$ 050040309 0 ; Style
U$ 02D 03C 064 018 ; Dim
07A ; ID
0FFFF 080 ; Class
'My Radio Button' 0 ; Title
0] ; No creation data
[Control1: D$ 050040001 0 ; Style
U$ 023 082 08D 018 ; Dim
07B ; ID
'msctls_trackbar32' 0 ; Class
'' 0 ; Title
0] ; No creation data
[Control2: D$ 050000000 0 ; Style
U$ 0A3 0B0 038 018 ; Dim
07C ; ID
0FFFF 080 ; Class
'OK' 0 ; Title
0] ; No creation data
Of course you might have to change the default namings for more meaningful ones, in order to avoid namings conflicts between several dialogs. Usually, having each control named by labels ('Control0:', ...) is of no use for you: It is just required by RosAsm syntax for data declarations.
You can edit all the records (and even add some entire controls 'by hand' if you want), and reload the dialog template in the editor... with respect to strict organization rules.
The routine for recovering the template from ClipBoard is not as flexible as you might wish >>> You must take care of the line organization (if, for example, one record is missing, the editor will abort; if you set ID record and Class record on the same line, if one record data is wrong, the editor will NOT correct the data, and results will be unpredictable, including a system hang inside USER32.DLL because of a zero division (I have seen this: The code of USER32 for Dialogs showing is not very secure -Your Dialog Data are supposed to be good-).
Before doing [Control][C] from your source, you have to carefully select your data from first '[' to last ']'.
One common error, when we add or delete by hand one control in a source template, is to forget adjustment of the n (Number of controls) record. This is the first member of 'Dialog Dim' line. If the number is wrong, the editor will correct it (Exception, it is set by the editor, anyway).
>>> U$ 03 0 0 0DC 0C8 ; Dim (n = 3, in upper example second line)
^^
As a general rule, you should avoid going back and forth between source template and dialog editor because it resets all your namings to default. I will make it more flexible and intelligent in the future. Often times, you just want to modify one or two value(s) inside Template. So, reload, modify, read the new data in the editor Edit Control, abort and write by hand the new value(s) inside your source Data. Simple and safe. If, after modifications of your data template, Win32 is unable to run your Dialog, do not hope that the Dialog Editor will be able to reload it... It is much more stupid than Win32 is.
For all common dialogs that do not need run time modifications, you should prefer the usual saving in Resources.
~~~~~~~
Resources Templates ...
The RosAsm Dialog Editor may output the Dialog Templates directly into the PE Resources Section. This method is simple and secure. It is well designed for all usual dialogs. You run them with:
call 'USER32.DialogBoxParam' , ...
Secure Styles
Dialog Managing of all Styles and Features, available for the various OS versions is a very complicated thing. Even for the simpler styles definitions the various Flags may conflict. Sometimes, one Style can be activated, only if another Style is also activated. Sometimes, two Styles cannot be selected together.
Other Dialogs Editors do not take care of this, they offer all of the available Styles and leave the choices responsibility to the user.
The RosAsm Dialog Editor takes care of these problems, with two Bits Tables for each Control Styles List:
The 'MustHaveBitTable'. When you select a Style requiring another Style the must have Bits are ORed.
The 'ExcludeBitTable'. Does the opposite: When you select a Style that conflicts with another enabled Style, the conflicting Style is removed.
These two features, -which are, in fact much more complicated than what I describe here...-, may save you from a lot of work and problems, especially of Documentation searches.
Limitations
Also, the purpose of the Dialog Editor is not to enable you with all of the various possible Styles and choices available under all OS versions. Just the opposite: It enables you with the more insured and simpler styles, that you may be sure to run under all OSes without any conflict problems. Of course, this choice results in some limitations.
But overcoming these limitations is not a problem. You have several ways for this. Of course, Memory_Templates, are the evident way for a complete freedom to define anything you want, but this way is also a bit more difficult to maintain, more painful to develop and more risky to use.
Another way for overcoming the Dialog Editor limitations is, simply, to do whatever customization you like, in the Dialog Procedure, with the &WM_INITDIALOG case. Example, as you may have noticed, the Extended Styles definition is not implemented in the Dialog Editor.
Now, let us suppose you want the Dialog to be a Tool-Window. You simply have to say:
.If D@Message = &WM_INITDIALOG
call 'USER32.SetWindowLongA' D@adressee, &GWL_EXSTYLE, &WS_EX_TOOLWINDOW
~~~~~~~
Using the Dialog Editor ....
Add / Insert a control
The same menu option ('Add') is used either to either INSERT or to ADD a new control:
If any control data line is selected, the new control is added at the end of template.
If no line is selected in main editor list, the new control is added at the end of template too.
But: If a blank line (separator) is selected, the new control is inserted at this given place.
You cannot do anything with a Control until you define its ID.
An 'ID' -IDentifier-, is a number used to indentify each Control. If two Controls in a same Dialog have the same ID, only the first one will be accessed.
>>> ID Zero does not exist. <<<
Moving/Sizing the controls
Three features are available for modifying the sizes and the positions of the Controls in a DialogBox:
Edit Controls in the Editor Window: Just enter the Values you want.
Up and Down Controls: Definition of the Controls Positions and Dimensions.
Direct Mouse actions: The Left Mouse Button enables you with usual Drag and Drop. Right Mouse Button enables you with Size Drag.
The Mouse actions on the Control, directly inside the Edited Dialog are for quick and dirty drawing. Just take care of not moving a Control under another one. All Controls, in a Dialog have a Z order (the order the OS draws the various Windows). The Dialog Editor does not modify this Z order in order to avoid moving a control under another one, and it may become invisible. If this happens, recover a visible position with the other editing features. In a Dialog Template, the Z order is the one of the Controls creations (simply, Top-Down, in the List View).
Mouse actions cannot be applied to a New created Control until you define its ID.
If you use the Direct Mouse actions, ''fine tuning'' of dimension and position may be achieved faster with Up and Down Controls and Edit Controls .
Selecting a Control by Left or Right Click produces a move of the Dialog Editor to the corresponding Coordinates Edition.
Dialog Class record
See the example in Iczelion Tutorial / 10MainDialog / Dialog1.exe for the relations between the name you set in the dialog editor and how to use it in the class record of WindowClassStructure designed for api registerClass.
Menus in Dialogs
Menus and Dialogs are two separate resources Types. When the Dialog Editor offers you the possibility of editing a new menu, this is just 'friendly'... As it is possible to use one menu for several purposes, I didn't set any option in the Dialog Editor to erase a Dialog Menu. Instead, go in 'Resources / Menu / Delete a Menu'. There is a security there to prevent accidental erasing of a menu used by a Dialog, that will adjust the Dialog Data if you confirm erasing.
Dialog saving
The RosAsm Dialog Editor may output the results either directly into the Resources (Resources Templates) or onto the ClipBoard, to be pasted as 'Memory Templates'. Resources dialogs functions have their 'twin' Functions:
call 'USER32.DialogBoxParam' , ... ; for Resources_Templates.
call 'USER32.DialogBoxIndirectParam', ... ; for Memory_Templates.
For all common dialogs that do not need run time modifications, you should prefer the usual savings in resources.
Controls Equates
For driving your Dialog, you have to manage your ID's equates inside your source: You DO have to do it. Unlike the Menu Editor, the Dialog Editor cannot set these equates for you, for several reasons:
You are allowed to give the same ID number to several controls (for example several '2' - to be used as 'Cancel' Case with the same branching as default &ID_CANCEL -). IDs are not guaranteed unique.
You can give the same 'title' name to different controls and, in any case, there is no way for the editor to save equates names in resources.
Several dialog boxes may use the same set of IDs... And so on.
~~~~~~~