inline static const WORD& DlgTemplateItemCount(const DLGTEMPLATE* pTemplate) { if (IsDialogEx(pTemplate)) return reinterpret_cast<const DLGTEMPLATEEX*>(pTemplate)->cDlgItems; else return pTemplate->cdit; }
static DLGITEMTEMPLATE* FindFirstDlgItem(const DLGTEMPLATE* pTemplate) { BOOL bDialogEx = IsDialogEx(pTemplate); WORD* pw; DWORD dwStyle; if (bDialogEx) { pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1); dwStyle = ((DLGTEMPLATEEX*)pTemplate)->style; } else { pw = (WORD*)(pTemplate + 1); dwStyle = pTemplate->style; } // Check for presence of menu and skip it if there is one // 0x0000 means there is no menu // 0xFFFF means there is a menu ID following // Everything else means that this is a NULL terminated Unicode string // which identifies the menu resource if (*pw == 0xFFFF) pw += 2; // Has menu ID, so skip 2 words else while (*pw++); // Either No menu, or string, skip past terminating NULL // Check for presence of class name string // 0x0000 means "Use system dialog class name" // 0xFFFF means there is a window class (atom) specified // Everything else means that this is a NULL terminated Unicode string // which identifies the menu resource if (*pw == 0xFFFF) pw += 2; // Has class atom, so skip 2 words else while (*pw++); // Either No class, or string, skip past terminating NULL // Skip caption string while (*pw++); // If we have DS_SETFONT, there is extra font information which we must now skip if (dwStyle & DS_SETFONT) { // If it is a regular DLGTEMPLATE there is only a short for the point size // and a string specifying the font (typefacename). If this is a DLGTEMPLATEEX // then there is also the font weight, and bItalic which must be skipped if (bDialogEx) pw += 3; // Skip font size, weight, (italic, charset) else pw += 1; // Skip font size while (*pw++); // Skip typeface name } // Dword-align and return return (DLGITEMTEMPLATE*)(lpwAlign(pw)); }
BOOL CDialogTemplate::SetFont(LPCTSTR lpFaceName, WORD nFontSize) { ASSERT(m_hTemplate != NULL); if (m_dwTemplateSize == 0) return FALSE; DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)GlobalLock(m_hTemplate); BOOL bDialogEx = IsDialogEx(pTemplate); BOOL bHasFont = ::HasFont(pTemplate); int cbFontAttr = FontAttrSize(bDialogEx); if (bDialogEx) ((DLGTEMPLATEEX*)pTemplate)->style |= DS_SETFONT; else pTemplate->style |= DS_SETFONT; #ifdef _UNICODE int cbNew = cbFontAttr + ((lstrlen(lpFaceName) + 1) * sizeof(TCHAR)); BYTE* pbNew = (BYTE*)lpFaceName; #else WCHAR wszFaceName [LF_FACESIZE]; int cbNew = cbFontAttr + 2 * MultiByteToWideChar(CP_ACP, 0, lpFaceName, -1, wszFaceName, LF_FACESIZE); BYTE* pbNew = (BYTE*)wszFaceName; #endif BYTE* pb = GetFontSizeField(pTemplate); int cbOld = bHasFont ? cbFontAttr + 2 * (wcslen((WCHAR*)(pb + cbFontAttr)) + 1) : 0; BYTE* pOldControls = (BYTE*)(((DWORD)pb + cbOld + 3) & ~3); BYTE* pNewControls = (BYTE*)(((DWORD)pb + cbNew + 3) & ~3); BYTE nCtrl = bDialogEx ? (BYTE)((DLGTEMPLATEEX*)pTemplate)->cDlgItems : (BYTE)pTemplate->cdit; if (cbNew != cbOld && nCtrl > 0) memmove(pNewControls, pOldControls, (size_t)(m_dwTemplateSize - (pOldControls - (BYTE*)pTemplate))); *(WORD*)pb = nFontSize; memmove(pb + cbFontAttr, pbNew, cbNew - cbFontAttr); m_dwTemplateSize += (pNewControls - pOldControls); GlobalUnlock(m_hTemplate); m_bSystemFont = FALSE; return TRUE; }
void TDialogRes::GetRect(TRect& rect) const { if (!IsDialogEx()) { DLGTEMPLATE* dlgTemplate = GetTemplate(); rect.left = dlgTemplate->x; rect.right = dlgTemplate->x + dlgTemplate->cx; rect.top = dlgTemplate->y; rect.bottom= dlgTemplate->y + dlgTemplate->cy; } else { DLGTEMPLATEEX* dlgTemplate = GetTemplateEx(); rect.left = dlgTemplate->x; rect.right = dlgTemplate->x + dlgTemplate->cx; rect.top = dlgTemplate->y; rect.bottom= dlgTemplate->y + dlgTemplate->cy; } }
void CDialogTemplate::GetSizeInDialogUnits(SIZE* pSize) const { ASSERT(m_hTemplate != NULL); DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)GlobalLock(m_hTemplate); if (IsDialogEx(pTemplate)) { pSize->cx = ((DLGTEMPLATEEX*)pTemplate)->cx; pSize->cy = ((DLGTEMPLATEEX*)pTemplate)->cy; } else { pSize->cx = pTemplate->cx; pSize->cy = pTemplate->cy; } GlobalUnlock(m_hTemplate); }
UINT AFX_CDECL CDialogTemplate::GetTemplateSize(const DLGTEMPLATE* pTemplate) { BOOL bDialogEx = IsDialogEx(pTemplate); BYTE* pb = GetFontSizeField(pTemplate); if (::HasFont(pTemplate)) { // Skip font size and name pb += FontAttrSize(bDialogEx); // Skip font size, weight, (italic, charset) pb += 2 * (wcslen((WCHAR*)pb) + 1); } WORD nCtrl = bDialogEx ? (WORD)((DLGTEMPLATEEX*)pTemplate)->cDlgItems : (WORD)pTemplate->cdit; while (nCtrl > 0) { pb = (BYTE*)(((DWORD_PTR)pb + 3) & ~DWORD_PTR(3)); // DWORD align pb += (bDialogEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE)); if (*(WORD*)pb == (WORD)-1) // Skip class name string or ordinal pb += 2 * sizeof(WORD); else pb = (BYTE*)_SkipString((WCHAR*)pb); if (*(WORD*)pb == (WORD)-1) // Skip text string or ordinal pb += 2 * sizeof(WORD); else pb = (BYTE*)_SkipString((WCHAR*)pb); WORD cbExtra = *(WORD*)pb; // Skip extra data if (cbExtra != 0 && !bDialogEx) cbExtra -= 2; pb += sizeof(WORD) + cbExtra; --nCtrl; } //IA64: Max dialog template size of 4GB should be fine return UINT(pb - (BYTE*)pTemplate); }
int TDialogRes::GetText(LPTSTR buffer, int size, TDlgResText which) const { LPCWSTR p, pMenu, pClass, pCaption; if (!IsDialogEx()) { DLGTEMPLATE* dlgTemplate = GetTemplate(); p = (LPCWSTR)(dlgTemplate+1); pMenu = p; pClass = pMenu + ((*pMenu == 0xffff) ? 2 : lstrlenW(pMenu)+1); pCaption = pClass + ((*pClass == 0xffff) ? 2 : lstrlenW(pClass)+1); } //else{ Y.B. Finish ?????????????????????????????????????????????????????? // DLGTEMPLATEEX* dlgTemplateEx = GetTemplateEx(); // !BB Get info about DLGEX! //} switch (which) { case drtMenuName: p = pMenu; break; case drtClassName: p = pClass; break; case drtCaption: p = pCaption; break; default: return 0; }; # if defined(UNICODE) int req_size = (*p == 0xffff) ? 2 : lstrlen(p) + 1; if (!buffer || size < req_size) return req_size; if((*p == 0xffff)){ memcpy(buffer, p, 2); return 2; } lstrcpy(buffer, p); return lstrlen(buffer); # else return WideCharToMultiByte(CP_ACP, 0, p, (*p == 0xffff) ? 2 : lstrlenW(p), buffer, size, 0, 0); # endif }
BOOL FDialog::IsSysFont() { DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)GlobalLock(m_hTemplate); BOOL hasFont = ::HasFont(pTemplate); GlobalUnlock(m_hTemplate); if (!hasFont) return FALSE; BOOL retval=FALSE; BYTE* pb = GetFontSizeField(pTemplate); pb += FontAttrSize(IsDialogEx(pTemplate)); #if defined(_UNICODE) || (defined(OLE2ANSI) && !defined(_MAC)) if (lstrcmp(pb,"MS Sans Serif")==0 || lstrcmp(pb,"Helv")==0) retval=TRUE; #else // Convert Unicode font name to MBCS if (wcscmp((WCHAR *)pb,L"MS Sans Serif")==0 || wcscmp((WCHAR *)pb,L"Helv")==0) retval=TRUE; #endif return retval; }
static DLGITEMTEMPLATE* FindFirstDlgItem(const DLGTEMPLATE* pTemplate) { DWORD dwStyle = pTemplate->style; BOOL bDialogEx = IsDialogEx(pTemplate); WORD* pw; if (bDialogEx) { pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1); dwStyle = ((DLGTEMPLATEEX*)pTemplate)->style; } else { pw = (WORD*)(pTemplate + 1); } if (*pw == (WORD)-1) // Skip menu name ordinal or string pw += 2; // WORDs else while (*pw++); if (*pw == (WORD)-1) // Skip class name ordinal or string pw += 2; // WORDs else while (*pw++); while (*pw++); // Skip caption string if (dwStyle & DS_SETFONT) { pw += bDialogEx ? 3 : 1; // Skip font size, weight, (italic, charset) while (*pw++); // Skip font name } // Dword-align and return return (DLGITEMTEMPLATE*)(((DWORD)pw + 3) & ~3); }
static BYTE* GetFontSizeField(const DLGTEMPLATE* pTemplate) { BOOL bDialogEx = IsDialogEx(pTemplate); WORD* pw; if (bDialogEx) pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1); else pw = (WORD*)(pTemplate + 1); if (*pw == (WORD)-1) // Skip menu name string or ordinal pw += 2; // WORDs else while(*pw++); if (*pw == (WORD)-1) // Skip class name string or ordinal pw += 2; // WORDs else while(*pw++); while (*pw++); // Skip caption string return (BYTE*)pw; }
BOOL AFX_CDECL CDialogTemplate::GetFont(const DLGTEMPLATE* pTemplate, CString& strFace, WORD& nFontSize) { ASSERT(pTemplate != NULL); if (!::HasFont(pTemplate)) return FALSE; BYTE* pb = GetFontSizeField(pTemplate); nFontSize = *(WORD*)pb; pb += FontAttrSize(IsDialogEx(pTemplate)); #if defined(_UNICODE) // Copy font name strFace = (LPCTSTR)pb; #else // Convert Unicode font name to MBCS WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pb, -1, strFace.GetBufferSetLength(LF_FACESIZE), LF_FACESIZE, NULL, NULL); strFace.ReleaseBuffer(); #endif return TRUE; }
DLGTEMPLATE* COccManager::SplitDialogTemplate(const DLGTEMPLATE* pTemplate, DLGITEMTEMPLATE** ppOleDlgItems) { DLGITEMTEMPLATE* pFirstItem = FindFirstDlgItem(pTemplate); ULONG cbHeader = (BYTE*)pFirstItem - (BYTE*)pTemplate; ULONG cbNewTemplate = cbHeader; BOOL bDialogEx = IsDialogEx(pTemplate); int iItem; int nItems = (int)DlgTemplateItemCount(pTemplate); DLGITEMTEMPLATE* pItem = pFirstItem; DLGITEMTEMPLATE* pNextItem = pItem; LPWSTR pszClassName; BOOL bHasOleControls = FALSE; // Make first pass through the dialog template. On this pass, we're // interested in determining: // 1. Does this template contain any OLE controls? // 2. If so, how large a buffer is needed for a template containing // only the non-OLE controls? for (iItem = 0; iItem < nItems; iItem++) { pNextItem = FindNextDlgItem(pItem, bDialogEx); pszClassName = bDialogEx ? (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) : (LPWSTR)(pItem + 1); if (pszClassName[0] == L'{') { // Item is an OLE control. bHasOleControls = TRUE; } else { // Item is not an OLE control: make room for it in new template. cbNewTemplate += (BYTE*)pNextItem - (BYTE*)pItem; } pItem = pNextItem; } // No OLE controls were found, so there's no reason to go any further. if (!bHasOleControls) { ppOleDlgItems[0] = (DLGITEMTEMPLATE*)(-1); return NULL; } // Copy entire header into new template. BYTE* pNew = (BYTE*)GlobalAlloc(GMEM_FIXED, cbNewTemplate); DLGTEMPLATE* pNewTemplate = (DLGTEMPLATE*)pNew; memcpy(pNew, pTemplate, cbHeader); pNew += cbHeader; // Initialize item count in new header to zero. DlgTemplateItemCount(pNewTemplate) = 0; pItem = pFirstItem; pNextItem = pItem; // Second pass through the dialog template. On this pass, we want to: // 1. Copy all the non-OLE controls into the new template. // 2. Build an array of item templates for the OLE controls. for (iItem = 0; iItem < nItems; iItem++) { pNextItem = FindNextDlgItem(pItem, bDialogEx); pszClassName = bDialogEx ? (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) : (LPWSTR)(pItem + 1); if (pszClassName[0] == L'{') { // Item is OLE control: add it to the array. ppOleDlgItems[iItem] = pItem; } else { // Item is not an OLE control: copy it to the new template. ULONG cbItem = (BYTE*)pNextItem - (BYTE*)pItem; ASSERT(cbItem >= (size_t)(bDialogEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE))); memcpy(pNew, pItem, cbItem); pNew += cbItem; // Incrememt item count in new header. ++DlgTemplateItemCount(pNewTemplate); // Put placeholder in OLE item array. ppOleDlgItems[iItem] = NULL; } pItem = pNextItem; } ppOleDlgItems[nItems] = (DLGITEMTEMPLATE*)(-1); return pNewTemplate; }
inline static BOOL HasFont(const DLGTEMPLATE* pTemplate) { return (DS_SETFONT & (IsDialogEx(pTemplate) ? ((DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style)); }
BOOL CDialogTemplate::SetFont(LPCTSTR lpFaceName, WORD nFontSize) { ASSERT(m_hTemplate != NULL); if (m_dwTemplateSize == 0) return FALSE; DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)GlobalLock(m_hTemplate); BOOL bDialogEx = IsDialogEx(pTemplate); BOOL bHasFont = ::HasFont(pTemplate); int cbFontAttr = FontAttrSize(bDialogEx); if (bDialogEx) ((DLGTEMPLATEEX*)pTemplate)->style |= DS_SETFONT; else pTemplate->style |= DS_SETFONT; int nFaceNameLen = lstrlen(lpFaceName); if( nFaceNameLen >= LF_FACESIZE ) { // Name too long return FALSE; } #ifdef _UNICODE int cbNew = cbFontAttr + ((nFaceNameLen + 1) * sizeof(TCHAR)); BYTE* pbNew = (BYTE*)lpFaceName; #else WCHAR wszFaceName [LF_FACESIZE]; int cbNew = cbFontAttr + 2 * MultiByteToWideChar(CP_ACP, 0, lpFaceName, -1, wszFaceName, LF_FACESIZE); BYTE* pbNew = (BYTE*)wszFaceName; #endif if (cbNew < cbFontAttr) { return FALSE; } BYTE* pb = GetFontSizeField(pTemplate); int cbOld = (int)(bHasFont ? cbFontAttr + 2 * (wcslen((WCHAR*)(pb + cbFontAttr)) + 1) : 0); BYTE* pOldControls = (BYTE*)(((DWORD_PTR)pb + cbOld + 3) & ~DWORD_PTR(3)); BYTE* pNewControls = (BYTE*)(((DWORD_PTR)pb + cbNew + 3) & ~DWORD_PTR(3)); WORD nCtrl = bDialogEx ? (WORD)((DLGTEMPLATEEX*)pTemplate)->cDlgItems : (WORD)pTemplate->cdit; if (cbNew != cbOld && nCtrl > 0) { size_t nBuffLeftSize=(size_t)(m_dwTemplateSize - (pOldControls - (BYTE*)pTemplate)); if (nBuffLeftSize > m_dwTemplateSize) { return FALSE; } Checked::memmove_s(pNewControls,nBuffLeftSize, pOldControls, nBuffLeftSize); } *(WORD*)pb = nFontSize; Checked::memmove_s(pb + cbFontAttr, cbNew - cbFontAttr, pbNew, cbNew - cbFontAttr); //IA64: Max dialog template size of 4GB should be fine m_dwTemplateSize += ULONG(pNewControls - pOldControls); GlobalUnlock(m_hTemplate); m_bSystemFont = FALSE; return TRUE; }
BOOL COccManager::CreateDlgControls(CWnd* pWndParent, void* lpResource, _AFX_OCC_DIALOG_INFO* pOccDlgInfo) { // if there are no OLE controls in this dialog, then there's nothing to do if (pOccDlgInfo->m_pNewTemplate == NULL) return TRUE; ASSERT(pWndParent != NULL); HWND hwParent = pWndParent->GetSafeHwnd(); BOOL bDialogEx = IsDialogEx(pOccDlgInfo->m_pNewTemplate); BOOL bSuccess = TRUE; if (lpResource != NULL) { ASSERT(pOccDlgInfo != NULL); ASSERT(pOccDlgInfo->m_ppOleDlgItems != NULL); DLGITEMTEMPLATE** ppOleDlgItems = pOccDlgInfo->m_ppOleDlgItems; UNALIGNED WORD* lpnRes = (WORD*)lpResource; int iItem = 0; HWND hwAfter = HWND_TOP; while (bSuccess && *lpnRes != 0) { #ifndef _MAC WORD nIDC = *lpnRes++; WORD nMsg = *lpnRes++; DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++; #else // Unfortunately we can't count on these values being // word-aligned (and dwLen is word-swapped besides), so // we have to pull them out a byte at a time to avoid // address errors on 68000s. WORD nIDC; WORD nMsg; DWORD dwLen; memcpy(&nIDC, lpnRes++, sizeof(WORD)); memcpy(&nMsg, lpnRes++, sizeof(WORD)); memcpy((WORD*)&dwLen + 1, lpnRes++, sizeof(WORD)); memcpy(&dwLen, lpnRes++, sizeof(WORD)); #endif #define WIN16_LB_ADDSTRING 0x0401 #define WIN16_CB_ADDSTRING 0x0403 ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == WIN16_LB_ADDSTRING || nMsg == WIN16_CB_ADDSTRING || nMsg == WM_OCC_LOADFROMSTREAM || nMsg == WM_OCC_LOADFROMSTREAM_EX || nMsg == WM_OCC_LOADFROMSTORAGE || nMsg == WM_OCC_LOADFROMSTORAGE_EX || nMsg == WM_OCC_INITNEW); if (nMsg == WM_OCC_LOADFROMSTREAM || nMsg == WM_OCC_LOADFROMSTREAM_EX || nMsg == WM_OCC_LOADFROMSTORAGE || nMsg == WM_OCC_LOADFROMSTORAGE_EX || nMsg == WM_OCC_INITNEW) { // Locate the DLGITEMTEMPLATE for the new control, and the control // that should precede it in z-order. DLGITEMTEMPLATE* pDlgItem; while (((pDlgItem = ppOleDlgItems[iItem++]) == NULL) && (pDlgItem != (DLGITEMTEMPLATE*)(-1))) { if (hwAfter == HWND_TOP) hwAfter = GetWindow(hwParent, GW_CHILD); else hwAfter = GetWindow(hwAfter, GW_HWNDNEXT); ASSERT(hwAfter != NULL); // enough non-OLE controls? } ASSERT(pDlgItem != NULL); // enough dialog item templates? HWND hwNew = NULL; if (pDlgItem != (DLGITEMTEMPLATE*)(-1)) { #ifdef _DEBUG WORD id = bDialogEx ? (WORD)((DLGITEMTEMPLATEEX*)pDlgItem)->id : pDlgItem->id; ASSERT(id == nIDC); // make sure control IDs match! #endif // Create the OLE control now. hwNew = CreateDlgControl(pWndParent, hwAfter, bDialogEx, pDlgItem, nMsg, (BYTE*)lpnRes, dwLen); } if (hwNew != NULL) { if (GetParent(hwNew) == hwParent) hwAfter = hwNew; } else bSuccess = FALSE; } // skip past data lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen); } } if (bSuccess) BindControls(pWndParent); return bSuccess; }
DLGTEMPLATE* TDialogRes::GetTemplate() const { PRECONDITION(!IsDialogEx()); return OldResource->operator DLGTEMPLATE*(); }
DLGTEMPLATEEX* TDialogRes::GetTemplateEx() const { PRECONDITION(IsDialogEx()); return NewResource->operator DLGTEMPLATEEX*(); }