occmgr.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  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.
  10. #include "stdafx.h"
  11. #ifdef MACOCX
  12. #define DBINITCONSTANTS
  13. #endif
  14. #include "occimpl.h"
  15. #include "ocdb.h"
  16. #ifdef AFX_OCC_SEG
  17. #pragma code_seg(AFX_OCC_SEG)
  18. #endif
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. #define new DEBUG_NEW
  24. #ifndef _AFX_NO_OCC_SUPPORT
  25. /////////////////////////////////////////////////////////////////////////////
  26. // AfxEnableControlContainer - wire up control container functions
  27. PROCESS_LOCAL(COccManager, _afxOccManager)
  28. void AFX_CDECL AfxEnableControlContainer(COccManager* pOccManager)
  29. {
  30. if (pOccManager == NULL)
  31. afxOccManager = _afxOccManager.GetData();
  32. else
  33. afxOccManager = pOccManager;
  34. }
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Helper functions for cracking dialog templates
  37. static inline BOOL IsDialogEx(const DLGTEMPLATE* pTemplate)
  38. {
  39. return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
  40. }
  41. static inline WORD& DlgTemplateItemCount(DLGTEMPLATE* pTemplate)
  42. {
  43. if (IsDialogEx(pTemplate))
  44. return reinterpret_cast<DLGTEMPLATEEX*>(pTemplate)->cDlgItems;
  45. else
  46. return pTemplate->cdit;
  47. }
  48. static inline const WORD& DlgTemplateItemCount(const DLGTEMPLATE* pTemplate)
  49. {
  50. if (IsDialogEx(pTemplate))
  51. return reinterpret_cast<const DLGTEMPLATEEX*>(pTemplate)->cDlgItems;
  52. else
  53. return pTemplate->cdit;
  54. }
  55. AFX_STATIC DLGITEMTEMPLATE* AFXAPI _AfxFindFirstDlgItem(const DLGTEMPLATE* pTemplate)
  56. {
  57. DWORD dwStyle = pTemplate->style;
  58. BOOL bDialogEx = IsDialogEx(pTemplate);
  59. WORD* pw;
  60. if (bDialogEx)
  61. {
  62. pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1);
  63. dwStyle = ((DLGTEMPLATEEX*)pTemplate)->style;
  64. }
  65. else
  66. {
  67. pw = (WORD*)(pTemplate + 1);
  68. }
  69. if (*pw == (WORD)-1) // Skip menu name ordinal or string
  70. pw += 2; // WORDs
  71. else
  72. while (*pw++);
  73. if (*pw == (WORD)-1) // Skip class name ordinal or string
  74. pw += 2; // WORDs
  75. else
  76. while (*pw++);
  77. while (*pw++); // Skip caption string
  78. if (dwStyle & DS_SETFONT)
  79. {
  80. pw += bDialogEx ? 3 : 1; // Skip font size, weight, (italic, charset)
  81. while (*pw++); // Skip font name
  82. }
  83. // Dword-align and return
  84. return (DLGITEMTEMPLATE*)(((DWORD)pw + 3) & ~3);
  85. }
  86. AFX_STATIC DLGITEMTEMPLATE* AFXAPI _AfxFindNextDlgItem(DLGITEMTEMPLATE* pItem, BOOL bDialogEx)
  87. {
  88. WORD* pw;
  89. if (bDialogEx)
  90. pw = (WORD*)((DLGITEMTEMPLATEEX*)pItem + 1);
  91. else
  92. pw = (WORD*)(pItem + 1);
  93. if (*pw == (WORD)-1) // Skip class name ordinal or string
  94. pw += 2; // WORDs
  95. else
  96. while (*pw++);
  97. if (*pw == (WORD)-1) // Skip text ordinal or string
  98. pw += 2; // WORDs
  99. else
  100. while (*pw++);
  101. WORD cbExtra = *pw++; // Skip extra data
  102. // Dword-align and return
  103. return (DLGITEMTEMPLATE*)(((DWORD)pw + cbExtra + 3) & ~3);
  104. }
  105. /////////////////////////////////////////////////////////////////////////////
  106. // COccManager
  107. BOOL COccManager::OnEvent(CCmdTarget* pCmdTarget, UINT idCtrl,
  108. AFX_EVENT* pEvent, AFX_CMDHANDLERINFO* pHandlerInfo)
  109. {
  110. return pCmdTarget->OnEvent(idCtrl, pEvent, pHandlerInfo);
  111. }
  112. COleControlContainer* COccManager::CreateContainer(CWnd* pWnd)
  113. {
  114. // advanced control container apps may want to override
  115. return new COleControlContainer(pWnd);
  116. }
  117. COleControlSite* COccManager::CreateSite(COleControlContainer* pCtrlCont)
  118. {
  119. // advanced control container apps may want to override
  120. return new COleControlSite(pCtrlCont);
  121. }
  122. const DLGTEMPLATE* COccManager::PreCreateDialog(_AFX_OCC_DIALOG_INFO* pDlgInfo,
  123. const DLGTEMPLATE* pOrigTemplate)
  124. {
  125. ASSERT(pDlgInfo != NULL);
  126. pDlgInfo->m_ppOleDlgItems =
  127. (DLGITEMTEMPLATE**)malloc(sizeof(DLGITEMTEMPLATE*) *
  128. (DlgTemplateItemCount(pOrigTemplate) + 1));
  129. if (pDlgInfo->m_ppOleDlgItems == NULL)
  130. return NULL;
  131. DLGTEMPLATE* pNewTemplate = SplitDialogTemplate(pOrigTemplate,
  132. pDlgInfo->m_ppOleDlgItems);
  133. pDlgInfo->m_pNewTemplate = pNewTemplate;
  134. return (pNewTemplate != NULL) ? pNewTemplate : pOrigTemplate;
  135. }
  136. void COccManager::PostCreateDialog(_AFX_OCC_DIALOG_INFO* pDlgInfo)
  137. {
  138. if (pDlgInfo->m_pNewTemplate != NULL)
  139. GlobalFree(pDlgInfo->m_pNewTemplate);
  140. if (pDlgInfo->m_ppOleDlgItems != NULL)
  141. free(pDlgInfo->m_ppOleDlgItems);
  142. }
  143. DLGTEMPLATE* COccManager::SplitDialogTemplate(const DLGTEMPLATE* pTemplate,
  144. DLGITEMTEMPLATE** ppOleDlgItems)
  145. {
  146. DLGITEMTEMPLATE* pFirstItem = _AfxFindFirstDlgItem(pTemplate);
  147. ULONG cbHeader = (BYTE*)pFirstItem - (BYTE*)pTemplate;
  148. ULONG cbNewTemplate = cbHeader;
  149. BOOL bDialogEx = IsDialogEx(pTemplate);
  150. int iItem;
  151. int nItems = (int)DlgTemplateItemCount(pTemplate);
  152. DLGITEMTEMPLATE* pItem = pFirstItem;
  153. DLGITEMTEMPLATE* pNextItem = pItem;
  154. #ifndef OLE2ANSI
  155. LPWSTR pszClassName;
  156. #else
  157. LPSTR pszClassName;
  158. #endif
  159. BOOL bHasOleControls = FALSE;
  160. // Make first pass through the dialog template. On this pass, we're
  161. // interested in determining:
  162. // 1. Does this template contain any OLE controls?
  163. // 2. If so, how large a buffer is needed for a template containing
  164. // only the non-OLE controls?
  165. for (iItem = 0; iItem < nItems; iItem++)
  166. {
  167. pNextItem = _AfxFindNextDlgItem(pItem, bDialogEx);
  168. pszClassName = bDialogEx ?
  169. #ifndef OLE2ANSI
  170. (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  171. (LPWSTR)(pItem + 1);
  172. #else
  173. (LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  174. (LPSTR)(pItem + 1);
  175. #endif
  176. #ifndef OLE2ANSI
  177. if (pszClassName[0] == L'{')
  178. #else
  179. if (pszClassName[0] == '{')
  180. #endif
  181. {
  182. // Item is an OLE control.
  183. bHasOleControls = TRUE;
  184. }
  185. else
  186. {
  187. // Item is not an OLE control: make room for it in new template.
  188. cbNewTemplate += (BYTE*)pNextItem - (BYTE*)pItem;
  189. }
  190. pItem = pNextItem;
  191. }
  192. // No OLE controls were found, so there's no reason to go any further.
  193. if (!bHasOleControls)
  194. {
  195. ppOleDlgItems[0] = (DLGITEMTEMPLATE*)(-1);
  196. return NULL;
  197. }
  198. // Copy entire header into new template.
  199. BYTE* pNew = (BYTE*)GlobalAlloc(GMEM_FIXED, cbNewTemplate);
  200. DLGTEMPLATE* pNewTemplate = (DLGTEMPLATE*)pNew;
  201. memcpy(pNew, pTemplate, cbHeader);
  202. pNew += cbHeader;
  203. // Initialize item count in new header to zero.
  204. DlgTemplateItemCount(pNewTemplate) = 0;
  205. pItem = pFirstItem;
  206. pNextItem = pItem;
  207. // Second pass through the dialog template. On this pass, we want to:
  208. // 1. Copy all the non-OLE controls into the new template.
  209. // 2. Build an array of item templates for the OLE controls.
  210. for (iItem = 0; iItem < nItems; iItem++)
  211. {
  212. pNextItem = _AfxFindNextDlgItem(pItem, bDialogEx);
  213. pszClassName = bDialogEx ?
  214. #ifndef OLE2ANSI
  215. (LPWSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  216. (LPWSTR)(pItem + 1);
  217. if (pszClassName[0] == L'{')
  218. #else
  219. (LPSTR)(((DLGITEMTEMPLATEEX*)pItem) + 1) :
  220. (LPSTR)(pItem + 1);
  221. if (pszClassName[0] == '{')
  222. #endif
  223. {
  224. // Item is OLE control: add it to the array.
  225. ppOleDlgItems[iItem] = pItem;
  226. }
  227. else
  228. {
  229. // Item is not an OLE control: copy it to the new template.
  230. ULONG cbItem = (BYTE*)pNextItem - (BYTE*)pItem;
  231. ASSERT(cbItem >= (size_t)(bDialogEx ?
  232. sizeof(DLGITEMTEMPLATEEX) :
  233. sizeof(DLGITEMTEMPLATE)));
  234. memcpy(pNew, pItem, cbItem);
  235. pNew += cbItem;
  236. // Incrememt item count in new header.
  237. ++DlgTemplateItemCount(pNewTemplate);
  238. // Put placeholder in OLE item array.
  239. ppOleDlgItems[iItem] = NULL;
  240. }
  241. pItem = pNextItem;
  242. }
  243. ppOleDlgItems[nItems] = (DLGITEMTEMPLATE*)(-1);
  244. return pNewTemplate;
  245. }
  246. BOOL COccManager::CreateDlgControls(CWnd* pWndParent, LPCTSTR lpszResourceName,
  247. _AFX_OCC_DIALOG_INFO* pOccDlgInfo)
  248. {
  249. // find resource handle
  250. void* lpResource = NULL;
  251. HGLOBAL hResource = NULL;
  252. if (lpszResourceName != NULL)
  253. {
  254. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_DLGINIT);
  255. HRSRC hDlgInit = ::FindResource(hInst, lpszResourceName, RT_DLGINIT);
  256. if (hDlgInit != NULL)
  257. {
  258. // load it
  259. hResource = LoadResource(hInst, hDlgInit);
  260. if (hResource == NULL)
  261. {
  262. TRACE0("DLGINIT resource was found, but could not be loaded.\n");
  263. return FALSE;
  264. }
  265. // lock it
  266. lpResource = LockResource(hResource);
  267. ASSERT(lpResource != NULL);
  268. }
  269. #ifdef _DEBUG
  270. else
  271. {
  272. // If we didn't find a DLGINIT resource, check whether we were
  273. // expecting to find one
  274. DLGITEMTEMPLATE** ppOleDlgItems = pOccDlgInfo->m_ppOleDlgItems;
  275. ASSERT(ppOleDlgItems != NULL);
  276. while (*ppOleDlgItems != (DLGITEMTEMPLATE*)-1)
  277. {
  278. if (*ppOleDlgItems != NULL)
  279. {
  280. TRACE0("Dialog has OLE controls, but no matching DLGINIT resource.\n");
  281. break;
  282. }
  283. ++ppOleDlgItems;
  284. }
  285. }
  286. #endif
  287. }
  288. // execute it
  289. BOOL bResult = TRUE;
  290. if (lpResource != NULL)
  291. bResult = CreateDlgControls(pWndParent, lpResource, pOccDlgInfo);
  292. // cleanup
  293. if (lpResource != NULL && hResource != NULL)
  294. {
  295. UnlockResource(hResource);
  296. FreeResource(hResource);
  297. }
  298. return bResult;
  299. }
  300. BOOL COccManager::CreateDlgControls(CWnd* pWndParent, void* lpResource,
  301. _AFX_OCC_DIALOG_INFO* pOccDlgInfo)
  302. {
  303. // if there are no OLE controls in this dialog, then there's nothing to do
  304. if (pOccDlgInfo->m_pNewTemplate == NULL)
  305. return TRUE;
  306. ASSERT(pWndParent != NULL);
  307. HWND hwParent = pWndParent->GetSafeHwnd();
  308. BOOL bDialogEx = IsDialogEx(pOccDlgInfo->m_pNewTemplate);
  309. BOOL bSuccess = TRUE;
  310. if (lpResource != NULL)
  311. {
  312. ASSERT(pOccDlgInfo != NULL);
  313. ASSERT(pOccDlgInfo->m_ppOleDlgItems != NULL);
  314. DLGITEMTEMPLATE** ppOleDlgItems = pOccDlgInfo->m_ppOleDlgItems;
  315. UNALIGNED WORD* lpnRes = (WORD*)lpResource;
  316. int iItem = 0;
  317. HWND hwAfter = HWND_TOP;
  318. while (bSuccess && *lpnRes != 0)
  319. {
  320. WORD nIDC = *lpnRes++;
  321. WORD nMsg = *lpnRes++;
  322. DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;
  323. #define WIN16_LB_ADDSTRING 0x0401
  324. #define WIN16_CB_ADDSTRING 0x0403
  325. ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
  326. nMsg == WIN16_LB_ADDSTRING || nMsg == WIN16_CB_ADDSTRING ||
  327. nMsg == WM_OCC_LOADFROMSTREAM ||
  328. nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  329. nMsg == WM_OCC_LOADFROMSTORAGE ||
  330. nMsg == WM_OCC_LOADFROMSTORAGE_EX ||
  331. nMsg == WM_OCC_INITNEW);
  332. if (nMsg == WM_OCC_LOADFROMSTREAM ||
  333. nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  334. nMsg == WM_OCC_LOADFROMSTORAGE ||
  335. nMsg == WM_OCC_LOADFROMSTORAGE_EX ||
  336. nMsg == WM_OCC_INITNEW)
  337. {
  338. // Locate the DLGITEMTEMPLATE for the new control, and the control
  339. // that should precede it in z-order.
  340. DLGITEMTEMPLATE* pDlgItem;
  341. while (((pDlgItem = ppOleDlgItems[iItem++]) == NULL) &&
  342. (pDlgItem != (DLGITEMTEMPLATE*)(-1)))
  343. {
  344. if (hwAfter == HWND_TOP)
  345. hwAfter = GetWindow(hwParent, GW_CHILD);
  346. else
  347. hwAfter = GetWindow(hwAfter, GW_HWNDNEXT);
  348. ASSERT(hwAfter != NULL); // enough non-OLE controls?
  349. }
  350. ASSERT(pDlgItem != NULL); // enough dialog item templates?
  351. HWND hwNew = NULL;
  352. if (pDlgItem != (DLGITEMTEMPLATE*)(-1))
  353. {
  354. #ifdef _DEBUG
  355. WORD id = bDialogEx ?
  356. (WORD)((DLGITEMTEMPLATEEX*)pDlgItem)->id :
  357. pDlgItem->id;
  358. ASSERT(id == nIDC); // make sure control IDs match!
  359. #endif
  360. // Create the OLE control now.
  361. hwNew = CreateDlgControl(pWndParent, hwAfter, bDialogEx,
  362. pDlgItem, nMsg, (BYTE*)lpnRes, dwLen);
  363. }
  364. if (hwNew != NULL)
  365. {
  366. if (bDialogEx)
  367. SetWindowContextHelpId(hwNew,
  368. ((DLGITEMTEMPLATEEX*)pDlgItem)->helpID);
  369. if (GetParent(hwNew) == hwParent)
  370. hwAfter = hwNew;
  371. }
  372. else
  373. bSuccess = FALSE;
  374. }
  375. // skip past data
  376. lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
  377. }
  378. }
  379. if (bSuccess)
  380. {
  381. // unfreeze events now that all controls are loaded
  382. if (pWndParent->m_pCtrlCont != NULL)
  383. pWndParent->m_pCtrlCont->FreezeAllEvents(FALSE);
  384. BindControls(pWndParent);
  385. }
  386. return bSuccess;
  387. }
  388. void COccManager::BindControls(CWnd* pWndParent)
  389. {
  390. HWND hWnd;
  391. COleControlSite* pSite;
  392. if (pWndParent->m_pCtrlCont != NULL)
  393. {
  394. // Now initialize bound controls
  395. POSITION pos = pWndParent->m_pCtrlCont->m_siteMap.GetStartPosition();
  396. while (pos != NULL)
  397. {
  398. pWndParent->m_pCtrlCont->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  399. // For each cursor bound property initialize pClientSite ptr and bind to DSC
  400. CDataBoundProperty* pBinding = pSite->m_pBindings;
  401. if(pBinding)
  402. {
  403. while(pBinding)
  404. {
  405. pBinding->SetClientSite(pSite);
  406. if (pBinding->m_ctlid != 0)
  407. {
  408. CWnd* pWnd = pWndParent->GetDlgItem(pBinding->m_ctlid);
  409. ASSERT(pWnd);
  410. ASSERT(pWnd->m_pCtrlSite);
  411. pBinding->SetDSCSite(pWnd->m_pCtrlSite);
  412. }
  413. pBinding = pSite->m_pBindings->GetNext();
  414. }
  415. }
  416. // Bind default bound property
  417. if (pSite->m_ctlidRowSource != NULL)
  418. {
  419. CWnd* pWnd = pWndParent->GetDlgItem(pSite->m_ctlidRowSource);
  420. ASSERT(pWnd); // gotta be a legitimate control id
  421. ASSERT(pWnd->m_pCtrlSite); // and it has to be an OLE Control
  422. pWnd->m_pCtrlSite->EnableDSC();
  423. ASSERT(pWnd->m_pCtrlSite->m_pDataSourceControl); // and a Data Source Control
  424. pSite->m_pDSCSite = pWnd->m_pCtrlSite;
  425. pWnd->m_pCtrlSite->m_pDataSourceControl->BindProp(pSite);
  426. }
  427. }
  428. // Finally, set up bindings on all DataSource controls
  429. pos = pWndParent->m_pCtrlCont->m_siteMap.GetStartPosition();
  430. while (pos != NULL)
  431. {
  432. pWndParent->m_pCtrlCont->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  433. if (pSite->m_pDataSourceControl)
  434. pSite->m_pDataSourceControl->BindColumns();
  435. }
  436. }
  437. }
  438. HWND COccManager::CreateDlgControl(CWnd* pWndParent, HWND hwAfter,
  439. BOOL bDialogEx, LPDLGITEMTEMPLATE pItem, WORD nMsg, BYTE* lpData, DWORD cb)
  440. {
  441. #ifndef OLE2ANSI
  442. LPWSTR pszClass = (LPWSTR)(pItem + 1);
  443. #else
  444. LPSTR pszClass = (LPSTR)(pItem + 1);
  445. #endif
  446. DLGITEMTEMPLATE dlgItemTmp;
  447. if (bDialogEx)
  448. {
  449. // We have an extended dialog template: copy relevant parts into an
  450. // ordinary dialog template, because their layouts are different
  451. DLGITEMTEMPLATEEX* pItemEx = (DLGITEMTEMPLATEEX*)pItem;
  452. dlgItemTmp.style = pItemEx->style;
  453. dlgItemTmp.dwExtendedStyle = pItemEx->exStyle;
  454. dlgItemTmp.x = pItemEx->x;
  455. dlgItemTmp.y = pItemEx->y;
  456. dlgItemTmp.cx = pItemEx->cx;
  457. dlgItemTmp.cy = pItemEx->cy;
  458. dlgItemTmp.id = (WORD)pItemEx->id;
  459. pItem = &dlgItemTmp;
  460. #ifndef OLE2ANSI
  461. pszClass = (LPWSTR)(pItemEx + 1);
  462. #else
  463. pszClass = (LPSTR)(pItemEx + 1);
  464. #endif
  465. }
  466. CRect rect(pItem->x, pItem->y, pItem->x + pItem->cx, pItem->y + pItem->cy);
  467. ::MapDialogRect(pWndParent->m_hWnd, &rect);
  468. BSTR bstrLicKey = NULL;
  469. // extract license key data, if any
  470. if (cb >= sizeof(ULONG))
  471. {
  472. ULONG cchLicKey = *(UNALIGNED ULONG*)lpData;
  473. lpData += sizeof(ULONG);
  474. cb -= sizeof(ULONG);
  475. if (cchLicKey > 0)
  476. {
  477. bstrLicKey = SysAllocStringLen((LPCOLESTR)lpData, cchLicKey);
  478. lpData += cchLicKey * sizeof(WCHAR);
  479. cb -= cchLicKey * sizeof(WCHAR);
  480. }
  481. }
  482. // If WM_OCC_INITNEW, we should have exhausted all of the data by now.
  483. ASSERT((nMsg != WM_OCC_INITNEW) || (cb == 0));
  484. CDataBoundProperty* pBindings = NULL;
  485. CString strDataField;
  486. WORD ctlidRowSource = 0;
  487. DISPID defdispid = 0;
  488. UINT dwType = 0;
  489. if (nMsg == WM_OCC_LOADFROMSTREAM_EX ||
  490. nMsg == WM_OCC_LOADFROMSTORAGE_EX)
  491. {
  492. // Read the size of the section
  493. ULONG cbOffset = *(UNALIGNED ULONG*)lpData;
  494. ULONG cbBindInfo = cbOffset - sizeof(DWORD);
  495. lpData += sizeof(DWORD);
  496. ULONG dwFlags = *(UNALIGNED ULONG*)lpData;
  497. cbBindInfo -= sizeof(DWORD);
  498. lpData += sizeof(DWORD);
  499. ASSERT(dwFlags == 1);
  500. // ULONG cbBinding = *(UNALIGNED ULONG*)lpData;
  501. cbBindInfo -= sizeof(DWORD);
  502. lpData += sizeof(DWORD);
  503. while (cbBindInfo > 0)
  504. {
  505. DISPID dispid;
  506. UWORD ctlid;
  507. dispid = *(UNALIGNED DISPID *)lpData;
  508. lpData += sizeof(DISPID);
  509. cbBindInfo -= sizeof(DISPID);
  510. ctlid = *(UNALIGNED WORD *)lpData;
  511. lpData += sizeof(WORD);
  512. cbBindInfo -= sizeof(WORD);
  513. if(dispid == DISPID_DATASOURCE)
  514. {
  515. defdispid = *(UNALIGNED ULONG*)lpData;
  516. cbBindInfo -= sizeof(DISPID);
  517. lpData += sizeof(DISPID);
  518. dwType = *(UNALIGNED ULONG*)lpData;
  519. cbBindInfo -= sizeof(DWORD);
  520. lpData += sizeof(DWORD);
  521. ASSERT(*(UNALIGNED DISPID *)lpData == DISPID_DATAFIELD);
  522. lpData += sizeof(DISPID);
  523. cbBindInfo -= sizeof(DISPID);
  524. // Skip the string length
  525. lpData += sizeof(DWORD);
  526. cbBindInfo -= sizeof(DWORD);
  527. strDataField = (char *)lpData;
  528. lpData += strDataField.GetLength()+1;
  529. cbBindInfo -= strDataField.GetLength()+1;
  530. ctlidRowSource = ctlid;
  531. } else
  532. pBindings = new CDataBoundProperty(pBindings, dispid, ctlid);
  533. }
  534. cb -= cbOffset;
  535. // From now on act as a regular type
  536. nMsg -= (WM_OCC_LOADFROMSTREAM_EX - WM_OCC_LOADFROMSTREAM);
  537. }
  538. GUID clsid;
  539. HRESULT hr;
  540. #ifndef OLE2ANSI
  541. if (pszClass[0] == L'{')
  542. #else
  543. if (pszClass[0] == '{')
  544. #endif
  545. hr = CLSIDFromString(pszClass, &clsid);
  546. else
  547. hr = CLSIDFromProgID(pszClass, &clsid);
  548. #ifdef _DEBUG
  549. if (FAILED(hr))
  550. {
  551. #ifndef OLE2ANSI
  552. TRACE1("Unable to convert \"%ls\" to a class ID.\n", pszClass);
  553. #else
  554. TRACE1("Unable to convert \"%s\" to a class ID.\n", pszClass);
  555. #endif
  556. TRACE1(">>> Result code: 0x%08lx\n", hr);
  557. if (pszClass[0] != L'{')
  558. TRACE0(">>> Is the control properly registered?\n");
  559. }
  560. #endif
  561. CMemFile memFile(lpData, cb);
  562. CMemFile* pMemFile = (nMsg == WM_OCC_INITNEW) ? NULL : &memFile;
  563. COleControlSite* pSite = NULL;
  564. if (SUCCEEDED(hr) &&
  565. pWndParent->InitControlContainer() &&
  566. pWndParent->m_pCtrlCont->CreateControl(NULL, clsid, NULL, pItem->style,
  567. rect, pItem->id, pMemFile, (nMsg == WM_OCC_LOADFROMSTORAGE),
  568. bstrLicKey, &pSite))
  569. {
  570. ASSERT(pSite != NULL);
  571. // freeze events until all controls are loaded
  572. pSite->FreezeEvents(TRUE);
  573. // set ZOrder only!
  574. SetWindowPos(pSite->m_hWnd, hwAfter, 0, 0, 0, 0,
  575. SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  576. pSite->m_pBindings = pBindings;
  577. pSite->m_strDataField = strDataField;
  578. pSite->m_ctlidRowSource = ctlidRowSource;
  579. pSite->m_defdispid = defdispid;
  580. pSite->m_dwType = dwType;
  581. }
  582. if (bstrLicKey != NULL)
  583. SysFreeString(bstrLicKey);
  584. return (pSite != NULL) ? pSite->m_hWnd : NULL;
  585. }
  586. /////////////////////////////////////////////////////////////////////////////
  587. // CDataExchange::PrepareOleCtrl
  588. CWnd* CDataExchange::PrepareOleCtrl(int nIDC)
  589. {
  590. ASSERT(nIDC != 0);
  591. ASSERT(nIDC != -1); // not allowed
  592. CWnd* pWndCtrl = m_pDlgWnd->GetDlgItem(nIDC);
  593. if ((pWndCtrl == NULL) || (pWndCtrl->m_hWnd == NULL))
  594. {
  595. TRACE1("Error: no data exchange control with ID 0x%04X\n", nIDC);
  596. ASSERT(FALSE);
  597. AfxThrowNotSupportedException();
  598. }
  599. m_hWndLastControl = pWndCtrl->m_hWnd;
  600. m_bEditLastControl = FALSE; // not an edit item by default
  601. return pWndCtrl;
  602. }
  603. #endif //!_AFX_NO_OCC_SUPPORT