I created a kind of class(or object) to create dialogs in memory, functions are not commented but there is an example that covers all. I plan to do a propertysheet class that uses the dialog class, if there is some interest i'll post it.
All API, not for beginners you'll need to know about window styles, dialog procedure, etc.. but makes the task of creating the memory template very easy.
The example dialog with 2 controls compiles in 5kb, you will need to disable XP themes support when creating the exe, don't know if this is normal.
You can run the following code directly(object + example)
Code: Select all
;Dialogs using memory templates
;Justin 09/2004
;dialogs.pbi
Interface IDialog
CreateTmpl(Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, font$, pointSize.w)
OpenModal(hwnd.l, dlgProc.l, param)
AddControl(class$, Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, id.w)
DestroyTmpl()
OpenModeless(hwnd.l, dlgProc.l, param)
get_Tmpl()
EndInterface
Structure DialogFunctionsVT
DLG_CreateTmpl.l
DLG_OpenModal.l
DLG_AddControl.l
DLG_DestroyTmpl.l
DLG_OpenModeless.l
DLG_get_Tmpl.l
EndStructure
Structure DialogOBJ
*VirtualTable.DialogFunctionsVT
;properties
tmpl.l ;memory template
tmplSize.l
cdit.w ;nr. dlg items
EndStructure
;- DECLARATION
Declare DLG_CreateTmpl(*THIS.DialogOBJ, Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, font$, pointSize.w)
Declare DLG_OpenModal(*THIS.DialogOBJ, hwnd.l, dlgProc.l, param)
Declare DLG_AddControl(*THIS.DialogOBJ, class$, Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, id.w)
Declare DLG_DestroyTmpl(*THIS.DialogOBJ)
Declare DLG_OpenModeless(*THIS.DialogOBJ, hwnd.l, dlgProc.l, param)
Declare DLG_get_Tmpl(*THIS.DialogOBJ)
Declare CDialog(*THIS.DialogOBJ, *Idlg.LONG)
;- CONSTRUCTOR
Global g_DialogFunctionsVT.DialogFunctionsVT
g_DialogFunctionsVT\DLG_CreateTmpl = @DLG_CreateTmpl()
g_DialogFunctionsVT\DLG_OpenModal = @DLG_OpenModal()
g_DialogFunctionsVT\DLG_AddControl = @DLG_AddControl()
g_DialogFunctionsVT\DLG_OpenModeless = @DLG_OpenModeless()
g_DialogFunctionsVT\DLG_DestroyTmpl = @DLG_DestroyTmpl()
g_DialogFunctionsVT\DLG_get_Tmpl = @DLG_get_Tmpl()
;dialogs.pb
Procedure CDialog(*THIS.DialogOBJ, *Idlg.LONG)
*THIS\VirtualTable = g_DialogFunctionsVT
If *Idlg : *Idlg\l = *THIS : EndIf
EndProcedure
Procedure DLG_get_Tmpl(*THIS.DialogOBJ) : ProcedureReturn *THIS\tmpl : EndProcedure
Procedure DLG_DestroyTmpl(*THIS.DialogOBJ)
If *THIS\tmpl : FreeMemory(*THIS\tmpl) : EndIf
EndProcedure
Procedure DLG_CreateTmpl(*THIS.DialogOBJ, Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, font$, pointSize.w)
*pwTemp.WORD
*THIS\tmplSize = SizeOf(DLGTEMPLATE) + (SizeOf(WORD)*2) ;menu, class arrays
*THIS\tmpl = AllocateMemory(*THIS\tmplSize)
*dtmp.DLGTEMPLATE = *THIS\tmpl
*dtmp\style = Style
*dtmp\dwExtendedStyle = dwExtendedStyle
*dtmp\cdit = 0
*dtmp\x = x
*dtmp\y = y
*dtmp\cx = w
*dtmp\cy = h
;title array
arrLen = 0
If title$=""
arrLen = SizeOf(WORD)
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
Else
wLen = MultiByteToWideChar_(#CP_ACP, 0, title$, -1, 0, 0)*2
arrLen + wLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
;set title
MultiByteToWideChar_(#CP_ACP, 0, title$, -1, *dtmp + *THIS\tmplSize - arrLen, wLen)
EndIf
;font array
If font$
arrLen = SizeOf(WORD) ;point size
wLen = MultiByteToWideChar_(#CP_ACP, 0, font$, -1, 0, 0)*2
arrLen + wLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
;set pointsize
*pwTemp = *dtmp + *THIS\tmplSize - arrLen : *pwTemp\w = pointSize
;set font name
MultiByteToWideChar_(#CP_ACP, 0, font$, -1, *pwTemp + SizeOf(WORD), wLen)
EndIf
*THIS\tmplSize + (*THIS\tmplSize % 4)
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
EndProcedure
Procedure DLG_OpenModal(*THIS.DialogOBJ, hwnd.l, dlgProc.l, param)
ProcedureReturn DialogBoxIndirectParam_(GetModuleHandle_(0), *THIS\tmpl, hwnd, dlgProc, param)
EndProcedure
Procedure DLG_OpenModeless(*THIS.DialogOBJ, hwnd.l, dlgProc.l, param)
ProcedureReturn CreateDialogIndirectParam_(GetModuleHandle_(0), *THIS\tmpl, hwnd, dlgProc, param)
EndProcedure
Procedure DLG_AddControl(*THIS.DialogOBJ, class$, Style.l, ExStyle.l, x.w, y.w, w.w, h.w, title$, id.w)
If class$="" Or *THIS\tmpl=0 : ProcedureReturn 0 : EndIf ;error
*THIS\tmplSize + SizeOf(DLGITEMTEMPLATE)
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
*dit.DLGITEMTEMPLATE = *THIS\tmpl + *THIS\tmplSize - SizeOf(DLGITEMTEMPLATE)
*dit\style = Style
*dit\dwExtendedStyle = ExStyle
*dit\x = x
*dit\y = y
*dit\cx = w
*dit\cy = h
*dit\id = id
itemLen = SizeOf(DLGITEMTEMPLATE)
;class array
arrLen = 0
wLen = MultiByteToWideChar_(#CP_ACP, 0, class$, -1, 0, 0)*2
arrLen + wLen
itemLen + arrLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
;set class
MultiByteToWideChar_(#CP_ACP, 0, class$, -1, *THIS\tmpl + *THIS\tmplSize - arrLen, wlen)
;title array
If title$
arrLen = 0
wLen = MultiByteToWideChar_(#CP_ACP, 0, title$, -1, 0, 0)*2
arrLen + wLen
itemLen + arrLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
;set title
MultiByteToWideChar_(#CP_ACP, 0, title$, -1, *THIS\tmpl + *THIS\tmplSize - arrLen, wlen)
Else
arrLen = SizeOf(WORD)
itemLen + arrLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
EndIf
;creation data array
arrLen = SizeOf(WORD)
itemLen + arrLen
*THIS\tmplSize + arrLen
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
*THIS\tmplSize + (itemLen % 4)
*THIS\tmpl = ReAllocateMemory(*THIS\tmpl, *THIS\tmplSize)
*THIS\cdit + 1
*dtmp.DLGTEMPLATE = *THIS\tmpl
*dtmp\cdit = *THIS\cdit
ProcedureReturn *THIS\cdit
EndProcedure
;dialogs_test.pb
;- TEST
Enumeration
#IDC_BT
#IDC_ED
EndEnumeration
Procedure DlgProc1(hwnd, msg, wParam, lParam)
Select msg
Case #WM_COMMAND
Select wparam>>16
Case #BN_CLICKED
Select wparam & $ffff
Case #IDC_BT
Debug "click"
EndSelect
EndSelect
ProcedureReturn 1
Case #WM_CLOSE
EndDialog_(hwnd, 1)
ProcedureReturn 1
Default : ProcedureReturn 0
EndSelect
EndProcedure
;create dialog
CDialog(@oDLG1.DialogOBJ, @pDLG1.IDialog)
pDLG1\CreateTmpl(#WS_SYSMENU|#DS_SETFONT, 0, 10, 10, 200, 200, "Modal Dialog", "Arial", 10)
pDLG1\AddControl("Button", #WS_VISIBLE|#WS_CHILD, 0, 2, 2, 80, 20, "Click Me", #IDC_BT)
pDLG1\AddControl("Edit", #WS_VISIBLE|#WS_CHILD, #WS_EX_CLIENTEDGE, 0, 40, 40, 20, "text", #IDC_ED)
;open
pDLG1\OpenModal(0, @DlgProc1(), 0)
;free memory template
pDLG1\DestroyTmpl()
End