📄 atlhostex.h
字号:
case WM_MEASUREITEM:
if(wParam) // not from a menu
hWndChild = GetDlgItem(((LPMEASUREITEMSTRUCT)lParam)->CtlID);
break;
case WM_COMPAREITEM:
if(wParam) // not from a menu
hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
break;
case WM_DELETEITEM:
if(wParam) // not from a menu
hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
break;
case WM_VKEYTOITEM:
case WM_CHARTOITEM:
case WM_HSCROLL:
case WM_VSCROLL:
hWndChild = (HWND)lParam;
break;
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
hWndChild = (HWND)lParam;
break;
default:
break;
}
if(hWndChild == NULL)
{
bHandled = FALSE;
return 1;
}
ATLASSERT(::IsWindow(hWndChild));
return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
}
STDMETHOD(QueryService)( REFGUID rsid, REFIID riid, void** ppvObj)
{
HRESULT hr = E_NOINTERFACE;
// Try for service on this object
// No services currently
// If that failed try to find the service on the outer object
if (FAILED(hr) && m_spServices)
hr = m_spServices->QueryService(rsid, riid, ppvObj);
return hr;
}
};
/////////////////////////////////////////////////////////////////////////////
// Helper functions for cracking dialog templates
#define _ATL_RT_DLGINIT MAKEINTRESOURCE(240)
class _DialogSplitHelper
{
public:
// Constants used in DLGINIT resources for OLE control containers
// NOTE: These are NOT real Windows messages they are simply tags
// used in the control resource and are never used as 'messages'
enum
{
WM_OCC_LOADFROMSTREAM = 0x0376,
WM_OCC_LOADFROMSTORAGE = 0x0377,
WM_OCC_INITNEW = 0x0378,
WM_OCC_LOADFROMSTREAM_EX = 0x037A,
WM_OCC_LOADFROMSTORAGE_EX = 0x037B,
DISPID_DATASOURCE = 0x80010001,
DISPID_DATAFIELD = 0x80010002,
};
//local struct used for implementation
#pragma pack(push, 1)
struct DLGINITSTRUCT
{
WORD nIDC;
WORD message;
DWORD dwSize;
};
struct DLGTEMPLATEEX
{
WORD dlgVer;
WORD signature;
DWORD helpID;
DWORD exStyle;
DWORD style;
WORD cDlgItems;
short x;
short y;
short cx;
short cy;
// Everything else in this structure is variable length,
// and therefore must be determined dynamically
// sz_Or_Ord menu; // name or ordinal of a menu resource
// sz_Or_Ord windowClass; // name or ordinal of a window class
// WCHAR title[titleLen]; // title string of the dialog box
// short pointsize; // only if DS_SETFONT is set
// short weight; // only if DS_SETFONT is set
// short bItalic; // only if DS_SETFONT is set
// WCHAR font[fontLen]; // typeface name, if DS_SETFONT is set
};
struct DLGITEMTEMPLATEEX
{
DWORD helpID;
DWORD exStyle;
DWORD style;
short x;
short y;
short cx;
short cy;
DWORD id;
// Everything else in this structure is variable length,
// and therefore must be determined dynamically
// sz_Or_Ord windowClass; // name or ordinal of a window class
// sz_Or_Ord title; // title string or ordinal of a resource
// WORD extraCount; // bytes following creation data
};
#pragma pack(pop)
static BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
{
return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
}
inline static WORD& DlgTemplateItemCount(DLGTEMPLATE* pTemplate)
{
if (IsDialogEx(pTemplate))
return reinterpret_cast<DLGTEMPLATEEX*>(pTemplate)->cDlgItems;
else
return pTemplate->cdit;
}
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*)(((DWORD)pw + 3) & ~3);
}
// Given the current dialog item and whether this is an extended dialog
// return a pointer to the next DLGITEMTEMPLATE*
static DLGITEMTEMPLATE* FindNextDlgItem(DLGITEMTEMPLATE* pItem, BOOL bDialogEx)
{
WORD* pw;
// First skip fixed size header information, size of which depends
// if this is a DLGITEMTEMPLATE or DLGITEMTEMPLATEEX
if (bDialogEx)
pw = (WORD*)((DLGITEMTEMPLATEEX*)pItem + 1);
else
pw = (WORD*)(pItem + 1);
if (*pw == 0xFFFF) // Skip class name ordinal or string
pw += 2; // (WORDs)
else
while (*pw++);
if (*pw == 0xFFFF) // Skip title ordinal or string
pw += 2; // (WORDs)
else
while (*pw++);
WORD cbExtra = *pw++; // Skip extra data
// Dword-align and return
return (DLGITEMTEMPLATE*)(((DWORD)pw + cbExtra + 3) & ~3);
}
// Find the initialization data (Stream) for the control specified by the ID
// If found, return the pointer into the data and the length of the data
static DWORD FindCreateData(DWORD dwID, BYTE* pInitData, BYTE** pData)
{
while (pInitData)
{
// Read the DLGINIT header
WORD nIDC = *((UNALIGNED WORD*)pInitData);
pInitData += sizeof(WORD);
WORD nMsg = *((UNALIGNED WORD*)pInitData);
pInitData += sizeof(WORD);
DWORD dwLen = *((UNALIGNED DWORD*)pInitData);
pInitData += sizeof(DWORD);
// If the header is for the control specified get the other info
if (nIDC == dwID)
{
DWORD cchLicKey = *((UNALIGNED DWORD*)pInitData);
pInitData += sizeof(DWORD);
dwLen -= sizeof(DWORD);
if (cchLicKey > 0)
{
CComBSTR bstrLicKey;
bstrLicKey.m_str = SysAllocStringLen((LPCOLESTR)pInitData, cchLicKey);
pInitData += cchLicKey * sizeof(OLECHAR);
dwLen -= cchLicKey * sizeof(OLECHAR);
}
// Extended (DATABINDING) stream format is not supported,
// we reject databinding info but preserve other information
if (nMsg == WM_OCC_LOADFROMSTREAM_EX ||
nMsg == WM_OCC_LOADFROMSTORAGE_EX)
{
// Read the size of the section
ULONG cbOffset = *(UNALIGNED ULONG*)pInitData;
// and simply skip past it
*pData = pInitData + cbOffset;
dwLen = dwLen - cbOffset;
return dwLen;
}
if (nMsg == WM_OCC_LOADFROMSTREAM)
*pData = pInitData;
return dwLen;
}
// It's not the right control, skip past data
pInitData += dwLen;
}
return 0;
}
// Convert MSDEV (MFC) style DLGTEMPLATE with controls to regular DLGTEMPLATE
// Changing all ActiveX Controls to use ATL AxWin hosting code
static DLGTEMPLATE* SplitDialogTemplate(DLGTEMPLATE* pTemplate, BYTE* pInitData)
{
USES_CONVERSION;
LPCWSTR lpstrAxWndClassNameW = T2CW(CAxWindow::GetWndClassName());
// Calculate the size of the DLGTEMPLATE for allocating the new one
DLGITEMTEMPLATE* pFirstItem = FindFirstDlgItem(pTemplate);
ULONG cbHeader = (BYTE*)pFirstItem - (BYTE*)pTemplate;
ULONG cbNewTemplate = cbHeader;
BOOL bDialogEx = IsDialogEx(pTemplate);
int iItem;
int nItems = (int)DlgTemplateItemCount(pTemplate);
#ifndef OLE2ANSI
LPWSTR pszClassName;
#else
LPSTR pszClassName;
#endif
BOOL bHasOleControls = FALSE;
// Make first pass through the dialog template. On this pass, we're
// interested in determining:
// 1. Does this template contain any ActiveX Controls?
// 2. If so, how large a buffer is needed for a template containing
// only the non-OLE controls?
DLGITEMTEMPLATE* pItem = pFirstItem;
DLGITEMTEMPLATE* pNextItem = pItem;
for (iItem = 0; iItem < nItems; iItem++)
{
pNextItem = FindNextDlgItem(pItem, bDialogEx);
pszClassName = bDialogEx ?
#ifndef OLE2ANSI
(LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
(LPWSTR)(pItem + 1);
#else
(LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
(LPSTR)(pItem + 1);
#endif
// Check if the class name begins with a '{'
// If it does, that means it is an ActiveX Control in MSDEV (MFC) format
#ifndef OLE2ANSI
if (pszClassName[0] == L'{')
#else
if (pszClassName[0] == '{')
#endif
{
// Item is an ActiveX control.
bHasOleControls = TRUE;
cbNewTemplate += (bDialogEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE));
// Length of className including NULL terminator
cbNewTemplate += (lstrlenW(lpstrAxWndClassNameW) + 1) * sizeof(WCHAR);
// Add length for the title CLSID in the form "{00000010-0000-0010-8000-00AA006D2EA4}"
// plus room for terminating NULL and an extra WORD for cbExtra
cbNewTemplate += 80;
// Get the Control ID
DWORD wID = bDialogEx ? ((DLGITEMTEMPLATEEX*)pItem)->id : pItem->id;
BYTE* pData;
cbNewTemplate += FindCreateData(wID, pInitData, &pData);
// Align to next DWORD
cbNewTemplate = ((cbNewTemplate + 3) & ~3);
}
else
{
// Item is not an ActiveX 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)
return pTemplate;
// 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 ?
#ifndef OLE2ANSI
(LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
(LPWSTR)(pItem + 1);
if (pszClassName[0] == L'{')
#else
(LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
(LPSTR)(pItem + 1);
if (pszClassName[0] == '{')
#endif
{
// Item is OLE control: add it to template as custom control
// Copy the dialog item template
DWORD nSizeElement = bDialogEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE);
memcpy(pNew, pItem, nSizeElement);
pNew += nSizeElement;
// Copy ClassName
DWORD nClassName = (lstrlenW(lpstrAxWndClassNameW) + 1) * sizeof(WCHAR);
memcpy(pNew, lpstrAxWndClassNameW, nClassName);
pNew += nClassName;
// Title (CLSID)
memcpy(pNew, pszClassName, 78);
pNew += 78; // sizeof(L"{00000010-0000-0010-8000-00AA006D2EA4}") - A CLSID
DWORD wID = bDialogEx ? ((DLGITEMTEMPLATEEX*)pItem)->id : pItem->id;
BYTE* pData;
nSizeElement = FindCreateData(wID, pInitData, &pData);
// cbExtra
*((WORD*)pNew) = (WORD) nSizeElement;
pNew += sizeof(WORD);
memcpy(pNew, pData, nSizeElement);
pNew += nSizeElement;
//Align to DWORD
pNew += (((~((DWORD)pNew)) + 1) & 3);
// Incrememt item count in new header.
++DlgTemplateItemCount(pNewTemplate);
}
else
{
// Item is not an OLE control: copy it to the new template.
ULONG cbItem = (BYTE*)pNextItem - (BYTE*)pItem;
ATLASSERT(cbItem >= (size_t)(bDialogEx ?
sizeof(DLGITEMTEMPLATEEX) :
sizeof(DLGITEMTEMPLATE)));
memcpy(pNew, pItem, cbItem);
pNew += cbItem;
// I
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -