May 08, 2024, 02:44:34 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


HowTo: Read Emergence, Aurora and Creative .dlg files

Started by Ionic Wind Support Team, August 08, 2008, 11:35:19 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ionic Wind Support Team

Over the years a few users have asked for the format of the .dlg files used by Emergence, Creative and Aurora.  Usually I would point them to the C++ code I use to create and load the files.

However, I recently needed a way to read these files using Emergence code, for the Linux version.  So I am posting this here for any IDE writers that want to import and save to the .dlg format.  And as a learning tool for others that are just curious about it.



/* UDT's needed */

TYPE DlgHeader
UINT Magic
INT rcleft
INT rctop
INT rcright
INT rcbottom
STRING strCaption
STRING strVariable
STRING strClassname
INT bTitleBar
INT bHorizScroll
INT bVertScroll
INT bSystemMenu
INT bMaximizeBox
INT bMinimizeBox
INT nID: 'next control ID
INT nButtonCount
INT nCheckCount
INT nRadioCount
INT nEditCount
INT nListCount
INT nComboCount
INT nControlCount
ENDTYPE

TYPE DlgControl
int nType
int bGroup
int bDisabled
int bVisible
int bSysButton
int rcleft
int rctop
int rcright
int rcbottom
uint dwStyle
uint dwExStyle
string strCaption
int nID
string strClassName
ENDTYPE

/* simple test program to read the .dlg file and print out the details*/
OpenConsole
string filename
memory pDlg
pointer pControls,pData
int offset
string yesno[2]:yesno = "no","yes"
DlgHeader dh
filename = FileRequest( "Choose a .dlg file",null,1,"Dialog Files (*.dlg)|*.dlg||")
if len(filename)
pDlg = OpenDialogFile(filename)
if pDlg <> NULL
offset = ReadDialogHeader(pDlg,dh)
if offset <> -1
print "Dialog Header"
print "-------------"
print "Dialog Caption: ",dh.strCaption
print "Variable Name: ",dh.strVariable
if dh.Magic = 0xFFCF
print "Class Name: ",dh.strClassname
endif
print "Dimensions: ",dh.rcLeft,dh.rcTop,dh.rcRight,dh.rcBottom
print "Show title bar: ",yesno[dh.bTitleBar]
print "Horiz. scroll bar: ",yesno[dh.bHorizScroll]
print "Vert. scroll bar: ",yesno[dh.bVertScroll]
print "System menu: ",yesno[dh.bSystemMenu]
print "Min. box: ",yesno[dh.bMinimizeBox]
print "Max. box: ",yesno[dh.bMaximizeBox]
print "Number of controls: ",dh.nControlCount
if dh.nControlCount
pControls = ReadControlRecords(pDlg,offset,dh.nControlCount)
if pControls
print
print "Dialog Control records"
print "----------------------"
for pData = each pControls as DlgControl
print "Control Type: ",ExtractControlType(#pData)
print "Dimensions: ",#pData.rcLeft,#pData.rcTop,#pData.rcRight,#pData.rcBottom
print "Style: ",hex$(#pData.dwStyle)
print "ExStyle: ",hex$(#pData.dwExStyle)
print "Caption: ",#pData.strCaption
print "ControlID: ",#pData.nID
if #pData.nType = 0x89
'for a custom control created with CONTROLEX
print "Control Class: ",#pData.strClassname
endif
print
next
ListRemoveAll(pControls,true)
endif
endif

else
Print "Error: invalid file"
endif
freemem pDlg
endif
endif
print "Press any key to close"
do:until inkey$ <> ""
end



/* routines to read the Emergence (and Aurora) .dlg files */

sub OpenDialogFile(string path),memory
BFILE f
int length
memory pReturn
pReturn = NULL
if OpenFile(f,path,"R") = 0
length = len(f)
AllocMem pReturn,length,1
__read f,pReturn,length
CloseFile f
endif
return pReturn
endsub

sub ReadDialogHeader(pointer pMem,DlgHeader dh),int
/* The header is not a fixed size, so each element has to be read individually.
The two strings are saved to length, preceeded by a byte indicating the size of the strings,
chaning the locations of the remaining elements in the file

Returns the offset in memory for the start of control records, or -1 to indicate an error
*/
int size,c
pointer pTemp:pTemp = pMem
'the magic number indicates it is a valid .dlg file
'and is changed when the format of the file changes
'so the reading routine can adapt.
'0xFFCE is the current Emergence format and 0xFFCF is the current Aurora format
'0xFFCD is an older format, still used by Creative BASIC

dh.Magic = #<UINT>pTemp:pTemp += 4
print hex$(dh.Magic)
if (dh.Magic <> 0xFFCF) AND  (dh.Magic <> 0xFFCE) AND (dh.Magic <> 0xFFCD)
'error condition here, not a valid .dlg file
return -1
endif
dh.rcleft = #<INT>pTemp:pTemp += 4
dh.rctop = #<INT>pTemp:pTemp += 4
dh.rcright = #<INT>pTemp:pTemp += 4
dh.rcbottom = #<INT>pTemp:pTemp += 4
'ok, now the tough part.  The strings aren't NULL terminated
'so we will need to read their length, loop to read the bytes
'and terminate it ourselves
size = #<char>pTemp:pTemp += 1
for c = 0 to size-1
dh.strCaption[c] = #<char>pTemp
pTemp+=1
next c
dh.strCaption[c] = 0
size = #<char>pTemp:pTemp += 1
for c = 0 to size-1
dh.strVariable[c] = #<char>pTemp
pTemp+=1
next c
dh.strVariable[c] = 0
if dh.Magic = 0xFFCF
'Aurora dialog files contain the class name
size = #<char>pTemp:pTemp += 1
for c = 0 to size-1
dh.strClassname[c] = #<char>pTemp
pTemp+=1
next c
dh.strClassname[c] = 0
else
dh.strClassName = ""
endif
dh.bTitleBar = #<INT>pTemp:pTemp += 4
dh.bHorizScroll = #<INT>pTemp:pTemp += 4
dh.bVertScroll = #<INT>pTemp:pTemp += 4
dh.bSystemMenu = #<INT>pTemp:pTemp += 4
dh.bMaximizeBox = #<INT>pTemp:pTemp += 4
dh.bMinimizeBox = #<INT>pTemp:pTemp += 4
dh.nID = #<INT>pTemp:pTemp += 4: 'next control ID
dh.nButtonCount = #<INT>pTemp:pTemp += 4
dh.nCheckCount = #<INT>pTemp:pTemp += 4
dh.nRadioCount = #<INT>pTemp:pTemp += 4
dh.nEditCount = #<INT>pTemp:pTemp += 4
dh.nListCount = #<INT>pTemp:pTemp += 4
dh.nComboCount = #<INT>pTemp:pTemp += 4
dh.nControlCount = #<INT>pTemp:pTemp += 4
return pTemp - pMem
endsub

sub ReadControlRecords(pointer pMem,int offset,int count),pointer
'reads the control records, storing them in a linked list
'strings are stored in the same manner as the header
'
'Uses the offset and control count returned by ReadDialogHeader
'Returns a linked list of DialogControl UDT's
pointer pTemp:pTemp = pMem
pointer pList,pData:pList = ListCreate()
int size,c,x,nTemp
uint magic
DlgControl dc
magic = #<UINT>pTemp
pTemp += offset
for x = 0 to count-1
dc.nType = #<int>pTemp:pTemp += 4
dc.bGroup = #<int>pTemp:pTemp += 4
dc.bDisabled = #<int>pTemp:pTemp += 4
nTemp =  #<int>pTemp:pTemp += 4
dc.bVisible = nTemp & 0xFFFF
dc.bSysButton =  (nTemp >> 16) & 0xFFFF
dc.rcleft = #<int>pTemp:pTemp += 4
dc.rctop = #<int>pTemp:pTemp += 4
dc.rcright = #<int>pTemp:pTemp += 4
dc.rcbottom = #<int>pTemp:pTemp += 4
dc.dwStyle = #<uint>pTemp:pTemp += 4
dc.dwExStyle = #<uint>pTemp:pTemp += 4
size = #<char>pTemp:pTemp += 1
for c = 0 to size-1
dc.strCaption[c] = #<char>pTemp
pTemp+=1
next c
dc.strCaption[c] = 0
dc.nID = #<int>pTemp - 2024:pTemp += 4
if (Magic = 0xFFCE) OR (Magic = 0xFFCF)
size = #<char>pTemp:pTemp += 1
for c = 0 to size-1
dc.strClassName [c] = #<char>pTemp
pTemp+=1
next c
dc.strClassName[c] = 0
endif
pData = ListAdd(pList,new(DlgControl,1))
#<DlgControl>pData = dc
next x
return pList
endsub

sub ExtractControlType(DlgControl dc),string
string ret
'The nType parameter of DlgControl is the windows control class ID
'which is a holdover from windows 16 bit days and still used
'in resource files for dialog templates.
'
'In Windows a pushbutton, radiobutton, checkbox and group box
'are all a 'button' so will share the 0x80 ID, the style bits
'determine what kind of control it is.
'
'The way the style bits are compared is also important as they
'haven't change since the early Windows days. Some bits are shared
'so if you compare them in the wrong order you'll get an invalid result.
select dc.nType
case 0x80 /*button*/
if dc.bSysButton
ret = "@SYSBUTTON"
else
ret = "@BUTTON"
endif
if (dc.dwStyle & 0x09) = 0x09
ret = "@RADIOBUTTON"
else
if (dc.dwStyle & 0x03) = 0x03
ret = "@CHECKBOX"
endif
endif
if dc.bGroup
ret = "@GROUPBOX"
endif
case 0x81
ret = "@EDIT"
case 0x82
ret = "@STATIC"
case 0x83
ret = "@LISTBOX"
case 0x84
ret = "@SCROLLBAR"
case 0x85
ret = "@COMBOBOX"
case 0x86
ret = "@RICHEDIT"
case 0x87
ret = "@LISTVIEW"
case 0x88
ret = "@TREEVIEW"
case 0x89
ret = "CUSTOM"
case 0x90
ret = "TAB CONTROL" : 'Aurora only
default
ret = "UNKNOWN"
endselect
return ret
endsub


I'll also attach it to the message for easy download.

Later,
Paul.
Ionic Wind Support Team

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

peterpuk

Peter