1 /*
2 * Helper functions for filling in DLG(ITEM)TEMPLATEs -
3 * closely based on code provided Rector & Newcomer
4 * in their book, Win32 programming.
5 *
6 * The only change here is to make it possible to
7 * add any number of controls to the dialog without
8 * having to worry about overrunning the chunk of
9 * memory that we're writing all this info into.
10 *
11 */
12
13 #define UNICODE
14 #include <windows.h>
15 #include <wchar.h>
16 #include <stdlib.h>
17 #include "diatemp.h"
18
19 #define DLGTEMPLATE_WORKING_SIZE 4096
20
getFinalDialog(DIA_TEMPLATE * dt)21 LPDLGTEMPLATE getFinalDialog(DIA_TEMPLATE* dt)
22 {
23 LPDLGTEMPLATE ptr = dt->dtemplate;
24 free(dt);
25 return ptr;
26 }
27
28 LPWORD
appendString(LPWORD ptr,LPCWSTR text)29 appendString (LPWORD ptr, LPCWSTR text)
30 {
31 LPWSTR str = (LPWSTR)ptr;
32 wcscpy(str, text);
33 ptr = (LPWORD)(str + wcslen(str) + 1);
34 return ptr;
35 }
36
37 LPWORD
setClassAtom(LPDLGITEMTEMPLATE item,WORD classatom)38 setClassAtom(LPDLGITEMTEMPLATE item, WORD classatom)
39 {
40 LPWORD ptr = (LPWORD)&item[1];
41 *ptr++ = 0xffff;
42 *ptr++ = classatom;
43 return ptr;
44 }
45
46 LPWORD
setClassName(LPDLGITEMTEMPLATE item,LPCWSTR classname)47 setClassName(LPDLGITEMTEMPLATE item, LPCWSTR classname)
48 {
49 LPWORD ptr = (LPWORD)&item[1];
50 ptr = appendString(ptr, classname);
51 return ptr;
52 }
53
54 LPWORD
setResourceID(LPWORD ptr,WORD id)55 setResourceID(LPWORD ptr, WORD id)
56 {
57 *ptr++ = 0xffff;
58 *ptr++ = (WORD)id;
59 return ptr;
60 }
61
62 DIA_TEMPLATE*
mkDiaTemplate(UINT size,int x,int y,int cx,int cy,DWORD style,DWORD exstyle,LPCWSTR menu,LPCWSTR class,LPCWSTR caption,LPCWSTR font,int height)63 mkDiaTemplate
64 ( UINT size, int x, int y, int cx, int cy
65 , DWORD style, DWORD exstyle
66 , LPCWSTR menu, LPCWSTR class
67 , LPCWSTR caption, LPCWSTR font
68 , int height
69 )
70 {
71 LPDLGTEMPLATE dlg;
72 LPWORD ptr;
73 DIA_TEMPLATE* dtemp;
74
75 if ( size == 0 ) {
76 size = DLGTEMPLATE_WORKING_SIZE;
77 }
78 dlg = (LPDLGTEMPLATE)malloc(size);
79 if (dlg == NULL) {
80 return NULL;
81 }
82
83 dlg->x = x;
84 dlg->y = y;
85 dlg->cx = cx;
86 dlg->cy = cy;
87
88 dlg->cdit = 0;
89
90 dlg->style = style;
91 if (font == NULL) {
92 dlg->style &= ~ DS_SETFONT;
93 } else {
94 dlg->style |= DS_SETFONT;
95 }
96 dlg->dwExtendedStyle = exstyle;
97
98 ptr= (LPWORD)&dlg[1];
99 if (menu == NULL) {
100 *ptr++ = 0;
101 } else if (HIWORD(menu) == 0) {
102 ptr = setResourceID(ptr, LOWORD(menu));
103 } else {
104 ptr = appendString(ptr, menu);
105 }
106
107 if ( class == NULL ) {
108 *ptr++ = 0;
109 } else if ( HIWORD(class) == 0 ) {
110 ptr = setResourceID(ptr, LOWORD(class));
111 } else {
112 ptr = appendString(ptr, class);
113 }
114
115 ptr = appendString(ptr, (caption == NULL ? L"" : caption));
116
117 if ( font != NULL ) {
118 *ptr++ = height;
119 ptr = appendString(ptr, font);
120 }
121
122 dtemp = (DIA_TEMPLATE*)malloc(sizeof(DIA_TEMPLATE));
123 if ( dtemp == NULL )
124 return NULL;
125
126 dtemp->dtemplate = dlg;
127 dtemp->next_dia_item = (LPDLGITEMTEMPLATE)ptr;
128 dtemp->bytes_left = (unsigned int)(((char*)dlg + size) - (char*)ptr);
129 dtemp->bytes_alloced = size;
130
131 return dtemp;
132 }
133
134 static
135 DIA_TEMPLATE*
check_if_enough_mem(DIA_TEMPLATE * dia,LPCWSTR text,LPCWSTR classname)136 check_if_enough_mem(DIA_TEMPLATE* dia, LPCWSTR text, LPCWSTR classname)
137 {
138 unsigned int sz = 0;
139
140 sz += sizeof(DLGITEMTEMPLATE);
141
142 if ( HIWORD(classname) == 0 ) {
143 sz += sizeof(WORD);
144 } else {
145 sz += wcslen(classname) + 1;
146 }
147 if ( HIWORD(text) == 0 ) {
148 sz += sizeof(WORD);
149 } else {
150 sz += wcslen(text) + 1;
151 }
152
153 if ( sz >= dia->bytes_left ) {
154 unsigned int diff;
155 dia->bytes_left = dia->bytes_left + dia->bytes_alloced;
156 dia->bytes_alloced *= 2;
157 /* Being defensive here.. */
158 diff = (unsigned int)((char*)dia->next_dia_item - (char*)dia->dtemplate);
159 dia->dtemplate = (LPDLGTEMPLATE)realloc((void*)dia->dtemplate, dia->bytes_alloced);
160 if ( dia->dtemplate == NULL )
161 return NULL;
162 dia->next_dia_item = (LPDLGITEMTEMPLATE)((char*)dia->dtemplate + diff);
163 return dia;
164 } else {
165 return dia;
166 }
167 }
168
169 static
noParms(LPDLGITEMTEMPLATE item,LPWORD ptr)170 LPWORD noParms (LPDLGITEMTEMPLATE item, LPWORD ptr)
171 {
172 *ptr++ = 0;
173 if ( (((LPWORD)item) - ptr) & 0x1)
174 *ptr++ = 0;
175
176 return ptr;
177 }
178
179 DIA_TEMPLATE*
addDiaControl(DIA_TEMPLATE * dia,LPCWSTR text,short id,LPCWSTR classname,DWORD style,int x,int y,int cx,int cy,DWORD exstyle)180 addDiaControl
181 ( DIA_TEMPLATE* dia
182 , LPCWSTR text, short id
183 , LPCWSTR classname, DWORD style
184 , int x, int y, int cx, int cy
185 , DWORD exstyle
186 )
187 {
188 LPWORD ptr;
189 LPDLGITEMTEMPLATE item;
190
191 dia = check_if_enough_mem(dia, text, classname);
192
193 ptr = (LPWORD)&(dia->next_dia_item[1]);
194
195 item = dia->next_dia_item;
196
197 item->style = WS_CHILD | style;
198 item->dwExtendedStyle = exstyle;
199 item->x = x;
200 item->y = y;
201 item->cx = cx;
202 item->cy = cy;
203 item->id = (WORD)id;
204
205 if ( HIWORD(classname) != 0 ) {
206 ptr = setClassName(item, classname);
207 } else {
208 ptr = setResourceID(ptr, LOWORD(classname));
209 }
210
211 if ( HIWORD(text) != 0 ) {
212 ptr = appendString(ptr, text);
213 } else {
214 ptr = setResourceID(ptr, (short)(LOWORD(text)));
215 }
216
217 ptr = noParms(item, ptr);
218
219 dia->bytes_left -= ((char*)ptr - ((char*)dia->next_dia_item));
220 dia->next_dia_item = (LPDLGITEMTEMPLATE)ptr;
221
222 return dia;
223 }
224
225