/* * Helper functions for filling in DLG(ITEM)TEMPLATEs - * closely based on code provided Rector & Newcomer * in their book, Win32 programming. * * The only change here is to make it possible to * add any number of controls to the dialog without * having to worry about overrunning the chunk of * memory that we're writing all this info into. * */ #include #include #include #include "diatemp.h" #define DLGTEMPLATE_WORKING_SIZE 4096 LPDLGTEMPLATE getFinalDialog(DIA_TEMPLATE* dt) { LPDLGTEMPLATE ptr = dt->dtemplate; free(dt); return ptr; } LPWORD appendString (LPWORD ptr, LPCWSTR text) { LPWSTR str = (LPWSTR)ptr; wcscpy(str, text); ptr = (LPWORD)(str + wcslen(str) + 1); return ptr; } LPWORD setClassAtom(LPDLGITEMTEMPLATE item, WORD classatom) { LPWORD ptr = (LPWORD)&item[1]; *ptr++ = 0xffff; *ptr++ = classatom; return ptr; } LPWORD setClassName(LPDLGITEMTEMPLATE item, LPCWSTR classname) { LPWORD ptr = (LPWORD)&item[1]; ptr = appendString(ptr, classname); return ptr; } LPWORD setResourceID(LPWORD ptr, WORD id) { *ptr++ = 0xffff; *ptr++ = (WORD)id; return ptr; } 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 ) { LPDLGTEMPLATE dlg; LPWORD ptr; DIA_TEMPLATE* dtemp; if ( size == 0 ) { size = DLGTEMPLATE_WORKING_SIZE; } dlg = (LPDLGTEMPLATE)malloc(size); if (dlg == NULL) { return NULL; } dlg->x = x; dlg->y = y; dlg->cx = cx; dlg->cy = cy; dlg->cdit = 0; dlg->style = style; if (font == NULL) { dlg->style &= ~ DS_SETFONT; } else { dlg->style |= DS_SETFONT; } dlg->dwExtendedStyle = exstyle; ptr= (LPWORD)&dlg[1]; if (menu == NULL) { *ptr++ = 0; } else if (HIWORD(menu) == 0) { ptr = setResourceID(ptr, LOWORD(menu)); } else { ptr = appendString(ptr, menu); } if ( class == NULL ) { *ptr++ = 0; } else if ( HIWORD(class) == 0 ) { ptr = setResourceID(ptr, LOWORD(class)); } else { ptr = appendString(ptr, class); } ptr = appendString(ptr, (caption == NULL ? L"" : caption)); if ( font != NULL ) { *ptr++ = height; ptr = appendString(ptr, font); } dtemp = (DIA_TEMPLATE*)malloc(sizeof(DIA_TEMPLATE)); if ( dtemp == NULL ) return NULL; dtemp->dtemplate = dlg; dtemp->next_dia_item = (LPDLGITEMTEMPLATE)ptr; dtemp->bytes_left = (unsigned int)(((char*)dlg + size) - (char*)ptr); dtemp->bytes_alloced = size; return dtemp; } static DIA_TEMPLATE* check_if_enough_mem(DIA_TEMPLATE* dia, LPCWSTR text, LPCWSTR classname) { unsigned int sz = 0; sz += sizeof(DLGITEMTEMPLATE); if ( HIWORD(classname) == 0 ) { sz += sizeof(WORD); } else { sz += wcslen(classname) + 1; } if ( HIWORD(text) == 0 ) { sz += sizeof(WORD); } else { sz += wcslen(text) + 1; } if ( sz >= dia->bytes_left ) { unsigned int diff; dia->bytes_left = dia->bytes_left + dia->bytes_alloced; dia->bytes_alloced *= 2; /* Being defensive here.. */ diff = (unsigned int)((char*)dia->next_dia_item - (char*)dia->dtemplate); dia->dtemplate = (LPDLGTEMPLATE)realloc((void*)dia->dtemplate, dia->bytes_alloced); if ( dia->dtemplate == NULL ) return NULL; dia->next_dia_item = (LPDLGITEMTEMPLATE)((char*)dia->dtemplate + diff); return dia; } else { return dia; } } static LPWORD noParms (LPDLGITEMTEMPLATE item, LPWORD ptr) { *ptr++ = 0; if ( (((LPWORD)item) - ptr) & 0x1) *ptr++ = 0; return ptr; } DIA_TEMPLATE* addDiaControl ( DIA_TEMPLATE* dia , LPCWSTR text, short id , LPCWSTR classname, DWORD style , int x, int y, int cx, int cy , DWORD exstyle ) { LPWORD ptr; LPDLGITEMTEMPLATE item; dia = check_if_enough_mem(dia, text, classname); ptr = (LPWORD)&(dia->next_dia_item[1]); item = dia->next_dia_item; item->style = WS_CHILD | style; item->dwExtendedStyle = exstyle; item->x = x; item->y = y; item->cx = cx; item->cy = cy; item->id = (WORD)id; if ( HIWORD(classname) != 0 ) { ptr = setClassName(item, classname); } else { ptr = setResourceID(ptr, LOWORD(classname)); } if ( HIWORD(text) != 0 ) { ptr = appendString(ptr, text); } else { ptr = setResourceID(ptr, (short)(LOWORD(text))); } ptr = noParms(item, ptr); dia->bytes_left -= ((char*)ptr - ((char*)dia->next_dia_item)); dia->next_dia_item = (LPDLGITEMTEMPLATE)ptr; return dia; }