1 // This is a part of the Microsoft Foundation Classes C++ library.
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
5 // This source code is only intended as a supplement to the
6 // Microsoft Foundation Classes Reference and related
7 // electronic documentation provided with the library.
8 // See these sources for detailed information regarding the
9 // Microsoft Foundation Classes product.
11 // CWnd support for MFC Control containment (Feature Pack controls)
16 #include "afxctrlcontainer.h"
18 #include "afxtagmanager.h"
19 #include "afxbutton.h"
20 #include "afxcolorbutton.h"
21 #include "afxeditbrowsectrl.h"
22 #include "afxfontcombobox.h"
23 #include "afxlinkctrl.h"
24 #include "afxmaskededit.h"
25 #include "afxmenubutton.h"
26 #include "afxpropertygridctrl.h"
27 #include "afxshelllistctrl.h"
28 #include "afxshelltreectrl.h"
29 #include "afxvslistbox.h"
31 ////////////////////////////////////////////////////////////////////////////
33 static void DoRegisterWindowClass(LPCTSTR lpszClassName
, LPCTSTR lpszBaseClassName
)
35 ASSERT(lpszClassName
!= NULL
);
36 ASSERT(lpszBaseClassName
!= NULL
);
40 HINSTANCE hInst
= AfxGetInstanceHandle();
41 if (!AfxCtxGetClassInfo(hInst
, lpszBaseClassName
, &wnd
))
43 wnd
.style
= CS_DBLCLKS
;
44 wnd
.hInstance
= hInst
;
45 wnd
.lpfnWndProc
= ::DefWindowProc
;
48 wnd
.lpszClassName
= lpszClassName
;
49 AfxRegisterClass(&wnd
);
52 void AfxRegisterMFCCtrlClasses()
54 DoRegisterWindowClass(_T("MFCButton"), WC_BUTTON
);
55 DoRegisterWindowClass(_T("MFCColorButton"), WC_BUTTON
);
56 DoRegisterWindowClass(_T("MFCEditBrowse"), WC_EDIT
);
57 DoRegisterWindowClass(_T("MFCFontComboBox"), WC_COMBOBOX
);
58 DoRegisterWindowClass(_T("MFCLink"), WC_BUTTON
);
59 DoRegisterWindowClass(_T("MFCMaskedEdit"), WC_EDIT
);
60 DoRegisterWindowClass(_T("MFCMenuButton"), WC_BUTTON
);
61 DoRegisterWindowClass(_T("MFCPropertyGrid"), WC_STATIC
);
62 DoRegisterWindowClass(_T("MFCShellList"), WC_LISTVIEW
);
63 DoRegisterWindowClass(_T("MFCShellTree"), WC_TREEVIEW
);
64 DoRegisterWindowClass(_T("MFCVSListBox"), WC_STATIC
);
67 ////////////////////////////////////////////////////////////////////////////
68 // CMFCControlContainer
70 CMFCControlContainer::CMFCControlContainer(CWnd
* pWnd
) : m_pWnd(pWnd
)
74 CMFCControlContainer::~CMFCControlContainer()
76 FreeSubclassedControls();
80 BOOL
CMFCControlContainer::SubclassDlgControls()
82 if (m_pWnd
->GetSafeHwnd() != NULL
)
84 // Subclass Feature Pack controls:
85 CWnd
* pWndChild
= m_pWnd
->GetWindow(GW_CHILD
);
86 while (pWndChild
!= NULL
)
88 ASSERT_VALID(pWndChild
);
90 TCHAR lpszClassName
[MAX_CLASS_NAME
+ 1];
92 ::GetClassName(pWndChild
->GetSafeHwnd(), lpszClassName
, MAX_CLASS_NAME
);
93 CWnd
* pWndSubclassedCtrl
= CreateDlgControl(lpszClassName
);
95 if (pWndSubclassedCtrl
!= NULL
)
97 m_arSubclassedCtrls
.Add((CObject
*)pWndSubclassedCtrl
);
98 pWndSubclassedCtrl
->SubclassWindow(pWndChild
->GetSafeHwnd());
101 pWndChild
= pWndChild
->GetNextWindow();
110 void CMFCControlContainer::FreeSubclassedControls()
112 // Free subclassed controls:
113 for (int i
= 0; i
< m_arSubclassedCtrls
.GetCount(); i
++)
115 if (m_arSubclassedCtrls
[i
] != NULL
)
117 delete m_arSubclassedCtrls
[i
];
120 m_arSubclassedCtrls
.RemoveAll();
123 CWnd
* CMFCControlContainer::CreateDlgControl(LPCTSTR lpszClassName
)
125 ASSERT(m_pWnd
->GetSafeHwnd() != NULL
);
127 if (lpszClassName
!= NULL
)
129 CString strClass
= lpszClassName
;
130 CWnd
* pWndSubclassedCtrl
= NULL
;
132 if (strClass
== _T("MFCButton"))
134 pWndSubclassedCtrl
= new CMFCButton
;
136 else if (strClass
== _T("MFCColorButton"))
138 pWndSubclassedCtrl
= new CMFCColorButton
;
140 else if (strClass
== _T("MFCEditBrowse"))
142 pWndSubclassedCtrl
= new CMFCEditBrowseCtrl
;
144 else if (strClass
== _T("MFCFontComboBox"))
146 pWndSubclassedCtrl
= new CMFCFontComboBox
;
148 else if (strClass
== _T("MFCLink"))
150 pWndSubclassedCtrl
= new CMFCLinkCtrl
;
152 else if (strClass
== _T("MFCMaskedEdit"))
154 pWndSubclassedCtrl
= new CMFCMaskedEdit
;
156 else if (strClass
== _T("MFCMenuButton"))
158 pWndSubclassedCtrl
= new CMFCMenuButton
;
160 else if (strClass
== _T("MFCPropertyGrid"))
162 pWndSubclassedCtrl
= new CMFCPropertyGridCtrl
;
164 else if (strClass
== _T("MFCShellList"))
166 pWndSubclassedCtrl
= new CMFCShellListCtrl
;
168 else if (strClass
== _T("MFCShellTree"))
170 pWndSubclassedCtrl
= new CMFCShellTreeCtrl
;
172 else if (strClass
== _T("MFCVSListBox"))
174 pWndSubclassedCtrl
= new CVSListBox
;
177 return pWndSubclassedCtrl
;
183 BOOL
CMFCControlContainer::IsSubclassedFeaturePackControl(HWND hWndCtrl
)
185 if (hWndCtrl
== NULL
)
190 for (int i
= 0; i
< m_arSubclassedCtrls
.GetCount(); i
++)
192 CWnd
* pWnd
= (CWnd
*)m_arSubclassedCtrls
[i
];
193 if (pWnd
->GetSafeHwnd() == hWndCtrl
)
202 void CMFCControlContainer::PreUnsubclassControl(CWnd
* pControl
)
204 UNREFERENCED_PARAMETER(pControl
);
206 // CMFCShellListCtrl* pListCtrl = DYNAMIC_DOWNCAST(CMFCShellListCtrl, pControl);
207 // if (pListCtrl != NULL && pListCtrl->GetHeaderCtrl().GetSafeHwnd() != NULL)
209 // pListCtrl->GetHeaderCtrl().UnsubclassWindow();
213 BOOL
CMFCControlContainer::ReSubclassControl(HWND hWndCtrl
, WORD nIDC
, CWnd
& control
)
215 if (hWndCtrl
== NULL
)
221 for (int i
= 0; i
< m_arSubclassedCtrls
.GetCount(); i
++)
223 CWnd
* pWnd
= (CWnd
*)m_arSubclassedCtrls
[i
];
224 if (pWnd
->GetSafeHwnd() == hWndCtrl
)
233 CWnd
* pWnd
= DYNAMIC_DOWNCAST(CWnd
, m_arSubclassedCtrls
[nIndex
]);
235 if (pWnd
->GetSafeHwnd() != NULL
)
241 BYTE
* pbInitData
= NULL
;
242 GetControlData(nIDC
, dwSize
, pbInitData
);
244 // Free old subclassed control:
245 m_arSubclassedCtrls
[nIndex
] = NULL
;
248 PreUnsubclassControl(pWnd
);
249 VERIFY(pWnd
->UnsubclassWindow() == hWndCtrl
);
254 if (!control
.SubclassWindow(hWndCtrl
))
256 ASSERT(FALSE
); // possibly trying to subclass twice?
257 AfxThrowNotSupportedException();
263 control
.SendMessage(WM_MFC_INITCTRL
, (WPARAM
)dwSize
, (LPARAM
)pbInitData
);
273 void CMFCControlContainer::SetControlData(WORD nIDC
, DWORD dwSize
, BYTE
* pbData
)
275 CByteArray
* pArray
= new CByteArray
;
276 pArray
->SetSize(dwSize
);
278 BYTE
* pbBuffer
= pArray
->GetData();
279 if (memcpy_s(pbBuffer
, dwSize
, pbData
, dwSize
) != 0)
286 m_mapControlData
.SetAt(nIDC
, pArray
);
289 BOOL
CMFCControlContainer::GetControlData(WORD nIDC
, DWORD
& dwSize
, BYTE
*& pbData
)
291 CObject
* pData
= NULL
;
292 if (m_mapControlData
.Lookup(nIDC
, pData
) && pData
!= NULL
)
294 CByteArray
* pArray
= (CByteArray
*)pData
;
295 dwSize
= (DWORD
)pArray
->GetSize();
296 pbData
= pArray
->GetData();
303 void CMFCControlContainer::ClearControlData()
306 CObject
* pData
= NULL
;
307 POSITION pos
= m_mapControlData
.GetStartPosition();
310 m_mapControlData
.GetNextAssoc(pos
, nIDC
, pData
);
311 CByteArray
* pArray
= (CByteArray
*)pData
;
315 m_mapControlData
.RemoveAll();
318 ////////////////////////////////////////////////////////////////////////////
319 // Accessing dialog DLGINIT helpers
321 int __stdcall
CMFCControlContainer::UTF8ToString(LPCSTR lpSrc
, CString
& strDst
, int nLength
)
324 int count
= ::MultiByteToWideChar(CP_UTF8
, 0, lpSrc
, nLength
, NULL
, 0);
330 LPWSTR lpWide
= new WCHAR
[count
+ 1];
331 memset(lpWide
, 0, (count
+ 1) * sizeof(WCHAR
));
333 ::MultiByteToWideChar(CP_UTF8
, 0, lpSrc
, nLength
, lpWide
, count
);
338 count
= ::WideCharToMultiByte(::GetACP(), 0, lpWide
, -1, NULL
, 0, NULL
, 0);
342 lpDst
= new char[count
+ 1];
343 memset(lpDst
, 0, count
+ 1);
345 ::WideCharToMultiByte(::GetACP(), 0, lpWide
, -1, lpDst
, count
, NULL
, 0);
356 BOOL __stdcall
CMFCControlContainer::ReadBoolProp(CTagManager
& /*tagManager*/, LPCTSTR lpszTag
, BOOL
& bMember
)
364 // tagManager.ExcludeTag(lpszTag, str);
371 bMember
= (str
.CompareNoCase(PS_True
) == 0);