001: /* dlg_untils.c */
002: /* Utilities for Dialogs */
003: 
004: // #include <string.h>

005: #include <memory.h>
006: #include <wchar.h>
007: 
008: #define DlgButton    0x0080
009: #define DlgEdit      0x0081
010: #define DlgStatic    0x0082
011: #define DlgListbox   0x0083
012: #define DlgScrollbar 0x0084
013: #define DlgCombobox  0x0085
014: 
015: typedef struct DynamicDialogTemplate {
016:   int bytes_accessable;
017:   int bytes_filled;
018:   int bytes_base;
019:   unsigned char *data;
020:   DLGTEMPLATE *dlg;
021: } DynDlgTemplate;
022: 
023: #define DynDlgTemplateNULL { 0 , 0, 0, NULL, NULL }
024: 
025: DynDlgTemplate DynDlgTemplateZero(void)
026: { DynDlgTemplate erg;
027:   erg.bytes_accessable = erg.bytes_filled = erg.bytes_base = 0;
028:   erg.data = NULL; erg.dlg = NULL;
029:   return erg;
030: }
031: 
032: void DynDlgTemplateFree(DynDlgTemplate *dt)
033: { if ((dt->bytes_accessable == 0) || (dt->data == NULL)) return;
034:   free(dt->data);
035:   *dt = DynDlgTemplateZero();
036: }
037: 
038: int DynDlgTemplateAlloc(DynDlgTemplate *dt, int dwords)
039: { int byte_count;
040:   unsigned long addr;
041:   byte_count = 4 * dwords + 3;
042:   if ((dt->data = malloc(byte_count)) == NULL) {
043:     *dt = DynDlgTemplateZero();
044:     return -1;
045:   }
046:   dt->bytes_base = 0; addr = (unsigned long) dt->data;
047:   while (addr & 3) { addr++; byte_count--; dt->bytes_base++; }
048:   dt->dlg = (void *) &(dt->data[dt->bytes_base]);
049:   dt->bytes_accessable = byte_count;
050:   dt->bytes_filled = 0;
051:   return 0;
052: }
053: 
054: int DynDlgTemplateExpand(DynDlgTemplate *dt, int dwords)
055: { int byte_count, neu_base;
056:   unsigned long addr;
057:   unsigned char *neu;
058:   if (dt->bytes_accessable >= 4 * dwords) return 0;
059:   byte_count = 4 * dwords + 3;
060:   if ((neu = malloc(byte_count)) == NULL) return -1;
061:   neu_base = 0; addr = (unsigned long) neu;
062:   while (addr & 3) { addr++; byte_count--; neu_base++; }
063:   if (dt->data != NULL) {
064:     if (dt->bytes_filled)
065:       memcpy(&(neu[neu_base]), &(dt->data[dt->bytes_base]), dt->bytes_filled);
066:     free(dt->data);
067:   }
068:   dt->data = neu;
069:   dt->bytes_base = neu_base;
070:   dt->dlg = (void *) &(dt->data[neu_base]);
071:   dt->bytes_accessable = byte_count;
072:   return 0;
073: }
074: 
075: int DynDlgSetHead(DynDlgTemplate *dt,
076:                   DWORD Style, DWORD ExtStyle, int x_0, int y_0, int x_w, int y_w,
077:                   wchar_t *MenuName, int Menu_ID,   /* -1 if none */
078:                   wchar_t *ClassName, int Class_ID, /* -1 if none */
079:                   wchar_t *Title,
080:                   wchar_t *Font, int FontPointsize, int FontWeight, int FontItalic)
081: /*  0 = ok

082:  * -1 = any error

083:  */
084: { int required_bytes, ct;
085:   DWORD style;
086:   struct DT {
087:     DWORD style;
088:     DWORD dwExtendedStyle;
089:     WORD  cDlgItms;
090:     short x;
091:     short y;
092:     short cx;
093:     short cy;
094:     wchar_t varies[3];
095:   } *neu;
096:   style = Style;
097:   required_bytes = sizeof(DLGTEMPLATE); if (required_bytes & 1) required_bytes++;
098:   if (MenuName != NULL) required_bytes += 2 * (wcslen(MenuName) + 1);
099:   else required_bytes += (Menu_ID == -1) ? 2 : 4;
100:   if (ClassName != NULL) required_bytes += 2 * (wcslen(ClassName) + 1);
101:   else required_bytes += (Class_ID == -1) ? 2 : 4;
102:   if (Title != NULL) required_bytes += 2 * (wcslen(Title) + 1);
103:   else required_bytes += 2;
104:   if (Font != NULL) {
105:     required_bytes += 2 * (wcslen(Font) + 4);
106:     style |= DS_SETFONT;
107:   }
108:   while (required_bytes & 3) required_bytes++;
109:   if (DynDlgTemplateExpand(dt, required_bytes >> 2)) return -1;
110:   neu = (struct DT *) dt->dlg;
111:   neu->style = style;
112:   neu->dwExtendedStyle = ExtStyle;
113:   neu->cDlgItms = 0;
114:   neu->x = x_0; neu->y = y_0; neu->cx = x_w; neu->cy = y_w;
115:   if (MenuName != NULL) { wcscpy(neu->varies, MenuName); ct = wcslen(MenuName) + 1;
116:   } else if (Menu_ID == -1) { neu->varies[0] = 0; ct = 1;
117:   } else { neu->varies[0] = 0xffff; neu->varies[1] = Menu_ID; ct = 2;
118:   }
119:   if (ClassName != NULL) { wcscpy(&(neu->varies[ct]), ClassName); ct += wcslen(ClassName) + 1;
120:   } else if (Class_ID == -1) { neu->varies[ct] = 0; ct++;
121:   } else { neu->varies[ct] = 0xffff; neu->varies[ct + 1] = Class_ID; ct += 2;
122:   }
123:   if (Title != NULL) { wcscpy(&(neu->varies[ct]), Title); ct += wcslen(Title) + 1;
124:   } else { neu->varies[ct] = 0; ct++;
125:   }
126:   if (Font != NULL) {
127:     neu->varies[ct] = FontPointsize; neu->varies[ct + 1] = FontWeight; neu->varies[ct + 2] = FontItalic;
128:     wcscpy(&(neu->varies[ct + 3]), Font);
129:     // ct += wcslen(Font) + 4;

130:   }
131:   // if (ct & 1) ct++;

132:   dt->bytes_filled = required_bytes;
133:   return 0;
134: }
135: 
136: int DynDlgAddItem(DynDlgTemplate *dt,
137:                   DWORD Style, DWORD ExtStyle, int x_0, int y_0, int x_w, int y_w, int ID,
138:                   wchar_t *ClassName, int Class_ID,
139:                   wchar_t *Title, int Title_ID,
140:                   int CreaDataType, void *CreaData, int CreaDataSize)
141: /*  0 = ok

142:  * -1 = any error

143:  */
144: { int required_bytes, ct;
145:   struct DI {
146:     DWORD style;
147:     DWORD dwExtendedStyle;
148:     short x;
149:     short y;
150:     short cx;
151:     short cy;
152:     WORD  id;
153:     wchar_t varies[3];
154:   } *neu;
155:   required_bytes = sizeof(DLGITEMTEMPLATE); if (required_bytes & 1) required_bytes++;
156:   required_bytes += (ClassName != NULL) ? 2 * (wcslen(ClassName) + 1) : 4;
157:   required_bytes += (Title != NULL) ? 2 * (wcslen(Title) + 1) : 4;
158:   required_bytes += 2; /* size */
159:   if (required_bytes & 1) required_bytes++;
160:   // while (required_bytes & 3) required_bytes++;

161:   switch (CreaDataType) {
162:     case 1: /* full array in pointer */
163:       required_bytes += *((unsigned char *)CreaData);
164:       while (required_bytes & 3) required_bytes++;
165:       break;
166:     case 2: /* Additional Data word aligned */
167:       required_bytes += CreaDataSize + 2;
168:       while (required_bytes & 3) required_bytes++;
169:       break;
170:     case 4: /* Additional Data dword aligned */
171:       required_bytes += CreaDataSize + 4;
172:       while (required_bytes & 3) required_bytes++;
173:       break;
174:     case 3: /* One short in CreaDataSize only, align by word */
175:       required_bytes += 4;
176:       break;
177:     case 5: /* One dword in CreaDataSize only, align by dword */
178:     case 6: /* Pass the pointer, align by dword */
179:       required_bytes += 8;
180:       break;
181:     default: /* 0, no Data */
182:     /* required_bytes += 4; */
183:       break;
184:   }
185:   while (required_bytes & 3) required_bytes++;
186:   if (DynDlgTemplateExpand(dt, (dt->bytes_filled + required_bytes) >> 2)) return -1;
187:   neu = (struct DI *) &(dt->data[dt->bytes_filled + dt->bytes_base]);
188:   neu->style = Style;
189:   neu->dwExtendedStyle = ExtStyle;
190:   neu->x = x_0; neu->y = y_0; neu->cx = x_w; neu->cy = y_w; neu->id = ID;
191:   if (ClassName != NULL) { wcscpy(&(neu->varies[0]), ClassName); ct = wcslen(ClassName) + 1;
192:   } else { neu->varies[0] = 0xffff; neu->varies[1] = Class_ID; ct = 2;
193:   }
194:   if (Title != NULL) { wcscpy(&(neu->varies[ct]), Title); ct += wcslen(Title) + 1;
195:   } else { neu->varies[ct] = 0; neu->varies[ct + 1] = Title_ID; ct += 2;
196:   }
197:   switch (CreaDataType) {
198:     case 1:
199:       neu->varies[ct] = *((unsigned char *)CreaData);
200:       break;
201:     case 2:
202:       neu->varies[ct] = CreaDataSize + 2;
203:       break;
204:     case 4:
205:       neu->varies[ct] = CreaDataSize + 4;
206:       break;
207:     case 3:
208:       neu->varies[ct] = 4;
209:       break;
210:     case 5: case 6:
211:       neu->varies[ct] = 8;
212:       break;
213:     default:
214:       neu->varies[ct] = 0;
215:   }
216:   ct++;
217:   // if ((ct + sizeof(DLGITEMTEMPLATE)/2) & 1) ct++;

218:   switch (CreaDataType) {
219:     case 1:
220:       memcpy(&(neu->varies[ct]), CreaData, *((unsigned char *)CreaData));
221:       break;
222:     case 2:
223:       neu->varies[ct] = CreaDataSize + 2;
224:       memcpy(&(neu->varies[ct + 1]), CreaData, CreaDataSize);
225:       break;
226:     case 4:
227:       neu->varies[ct] = CreaDataSize + 4;
228:       memcpy(&(neu->varies[ct + 2]), CreaData, CreaDataSize);
229:       break;
230:     case 3:
231:       neu->varies[ct] = 4;
232:       neu->varies[ct + 1] = CreaDataSize;
233:       break;
234:     case 5:
235:       neu->varies[ct] = 8;
236:       neu->varies[ct + 1] = 0;
237:       *((DWORD *) &(neu->varies[ct + 2])) = CreaDataSize;
238:       break;
239:     case 6:
240:       neu->varies[ct] = 8;
241:       neu->varies[ct + 1] = 0;
242:       *((void **) &(neu->varies[ct + 2])) = CreaData;
243:       break;
244:     default:
245:       /* neu->varies[ct] = 4;

246:       neu->varies[ct + 1] = 0; */
247:       break;
248:   }
249:   dt->dlg->cdit++;
250:   dt->bytes_filled += required_bytes;
251:   return 0;
252: }
253:   
254: