Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1260 lines
31 KiB

  1. /*
  2. * DATAUSER.CPP
  3. * Data Object User Chapter 6
  4. *
  5. * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  6. *
  7. * Kraig Brockschmidt, Software Design Engineer
  8. * Microsoft Systems Developer Relations
  9. *
  10. * Internet : kraigb@microsoft.com
  11. * Compuserve: >INTERNET:kraigb@microsoft.com
  12. */
  13. #define INIT_MY_GUIDS
  14. #include "datausr.h"
  15. #include "perror.h"
  16. #include <stdio.h>
  17. #ifdef WIN32
  18. #define APP_TITLE TEXT("32 Bit IDataObject User")
  19. #else
  20. #define APP_TITLE TEXT("16 Bit IDataObject User")
  21. #endif
  22. //These are for displaying clipboard formats textually.
  23. static TCHAR * rgszCF[13]={TEXT("Unknown"), TEXT("CF_TEXT")
  24. , TEXT("CF_BITMAP"), TEXT("CF_METAFILEPICT")
  25. , TEXT("CF_SYLK"), TEXT("CF_DIF"), TEXT("CF_TIFF")
  26. , TEXT("CF_OEMTEXT"), TEXT("CF_DIB")
  27. , TEXT("CF_PALETTE"), TEXT("CF_PENDATA")
  28. , TEXT("CF_RIFF"), TEXT("CF_WAVE")};
  29. static TCHAR szSuccess[] =TEXT("succeeded");
  30. static TCHAR szFailed[] =TEXT("failed");
  31. static TCHAR szExpected[] =TEXT("expected");
  32. static TCHAR szUnexpected[] =TEXT("unexpected!");
  33. TCHAR tcMessageBuf[4096]; // Misc use buffer for messages.
  34. int cKSizes[NUM_POINTS] = { 1, 2, 4, 6, 8,
  35. 10, 12, 16, 20, 24,
  36. 28, 32, 40, 48, 56 };
  37. /*
  38. * WinMain
  39. *
  40. * Purpose:
  41. * Main entry point of application.
  42. */
  43. int PASCAL WinMain(
  44. HINSTANCE hInst,
  45. HINSTANCE hInstPrev,
  46. LPSTR pszCmdLine,
  47. int nCmdShow)
  48. {
  49. MSG msg;
  50. PAPPVARS pAV;
  51. #ifndef WIN32
  52. int cMsg=96;
  53. while (!SetMessageQueue(cMsg) && (cMsg-=8));
  54. #endif
  55. pAV=new CAppVars(hInst, hInstPrev, nCmdShow);
  56. if (NULL==pAV)
  57. return -1;
  58. if (pAV->FInit())
  59. {
  60. while (GetMessage(&msg, NULL, 0,0 ))
  61. {
  62. TranslateMessage(&msg);
  63. DispatchMessage(&msg);
  64. }
  65. }
  66. delete pAV;
  67. return msg.wParam;
  68. }
  69. /*
  70. * DataUserWndProc
  71. *
  72. * Purpose:
  73. * Window class procedure. Standard callback.
  74. */
  75. LRESULT API_ENTRY DataUserWndProc(HWND hWnd, UINT iMsg
  76. , WPARAM wParam, LPARAM lParam)
  77. {
  78. HRESULT hr;
  79. PAPPVARS pAV;
  80. HMENU hMenu;
  81. FORMATETC fe;
  82. WORD wID;
  83. int i;
  84. pAV=(PAPPVARS)GetWindowLong(hWnd, DATAUSERWL_STRUCTURE);
  85. switch (iMsg)
  86. {
  87. case WM_NCCREATE:
  88. pAV=(PAPPVARS)((LPCREATESTRUCT)lParam)->lpCreateParams;
  89. SetWindowLong(hWnd, DATAUSERWL_STRUCTURE, (LONG)pAV);
  90. return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  91. case WM_DESTROY:
  92. PostQuitMessage(0);
  93. break;
  94. case WM_PAINT:
  95. pAV->Paint();
  96. break;
  97. case WM_COMMAND:
  98. SETDefFormatEtc(fe, 0, TYMED_HGLOBAL | TYMED_GDI| TYMED_MFPICT);
  99. hMenu=GetMenu(hWnd);
  100. wID=LOWORD(wParam);
  101. if(wID >= IDM_OBJECTSETDATA && wID <= IDM_OBJECTSETDATA+64)
  102. {
  103. // Blast all possible SetData menu items. Some don't exist.
  104. for(i=IDM_OBJECTSETDATA; i<=IDM_OBJECTSETDATA+64; i++)
  105. CheckMenuItem(hMenu,i, MF_UNCHECKED);
  106. CheckMenuItem(hMenu, wID, MF_CHECKED);
  107. pAV->m_SetData_SetSize(wID-IDM_OBJECTSETDATA);
  108. break;
  109. }
  110. switch (wID)
  111. {
  112. case IDM_USE16BITSERVER:
  113. if (pAV->m_f16Bit)
  114. break;
  115. pAV->m_f16Bit = TRUE;
  116. pAV->FReloadDataObjects(TRUE);
  117. break;
  118. case IDM_USE32BITSERVER:
  119. if (!pAV->m_f16Bit)
  120. break;
  121. pAV->m_f16Bit = FALSE;
  122. pAV->FReloadDataObjects(TRUE);
  123. break;
  124. case IDM_OBJECTQUERYGETDATA:
  125. if (NULL==pAV->m_pIDataObject)
  126. break;
  127. fe.tymed=TYMED_HGLOBAL | TYMED_GDI
  128. | TYMED_MFPICT;
  129. pAV->TryQueryGetData(&fe, CF_TEXT, TRUE, 0);
  130. pAV->TryQueryGetData(&fe, CF_BITMAP, TRUE, 1);
  131. #ifdef NOT_SIMPLE
  132. pAV->TryQueryGetData(&fe, CF_DIB, FALSE, 2);
  133. pAV->TryQueryGetData(&fe, CF_METAFILEPICT, TRUE, 3);
  134. pAV->TryQueryGetData(&fe, CF_WAVE, FALSE, 4);
  135. #endif /* NOT_SIMPLE */
  136. break;
  137. case IDM_OBJECTGETDATA_TEXT:
  138. case IDM_OBJECTGETDATA_BITMAP:
  139. #ifdef NOT_SIMPLE
  140. case IDM_OBJECTGETDATA_METAFILEPICT:
  141. #endif /* NOT_SIMPLE */
  142. if (pAV->m_GetData(wID) )
  143. {
  144. InvalidateRect(hWnd, NULL, TRUE);
  145. UpdateWindow(hWnd);
  146. }
  147. if(pAV->m_fDisplayTime)
  148. pAV->m_DisplayTimerResults();
  149. break;
  150. case IDM_OBJECTGETDATAHERE_TEXT:
  151. case IDM_OBJECTGETDATAHERE_NULLTEXT:
  152. case IDM_OBJECTGETDATAHERE_BITMAP:
  153. case IDM_OBJECTGETDATAHERE_NULLBITMAP:
  154. if (pAV->m_GetDataHere(wID) )
  155. {
  156. InvalidateRect(hWnd, NULL, TRUE);
  157. UpdateWindow(hWnd);
  158. }
  159. if(pAV->m_fDisplayTime)
  160. pAV->m_DisplayTimerResults();
  161. break;
  162. case IDM_OBJECTSETDATAPUNK_TEXT:
  163. case IDM_OBJECTSETDATAPUNK_BITMAP:
  164. pAV->m_SetData_WithPUnk(wID);
  165. break;
  166. case IDM_MEASUREMENT_1:
  167. case IDM_MEASUREMENT_50:
  168. case IDM_MEASUREMENT_300:
  169. case IDM_MEASUREMENT_OFF:
  170. case IDM_MEASUREMENT_ON:
  171. case IDM_MEASUREMENT_TEST:
  172. pAV->m_SetMeasurement(wID);
  173. break;
  174. case IDM_BATCH_GETDATA:
  175. pAV->m_MeasureAllSizes(IDM_OBJECTGETDATA_TEXT,
  176. TEXT("GetData w/HGLOBAL"),
  177. NULL);
  178. break;
  179. case IDM_BATCH_GETDATAHERE:
  180. pAV->m_MeasureAllSizes(IDM_OBJECTGETDATAHERE_TEXT,
  181. TEXT("GetDataHere w/HGLOBAL"),
  182. NULL);
  183. break;
  184. case IDM_BATCHTOFILE:
  185. pAV->m_BatchToFile();
  186. break;
  187. case IDM_OBJECTEXIT:
  188. PostMessage(hWnd, WM_CLOSE, 0, 0L);
  189. break;
  190. #ifdef NOT_SIMPLE
  191. case IDM_ADVISETEXT:
  192. case IDM_ADVISEBITMAP:
  193. case IDM_ADVISEMETAFILEPICT:
  194. if (NULL==pAV->m_pIDataObject)
  195. break;
  196. //Terminate the old connection
  197. if (0!=pAV->m_dwConn)
  198. {
  199. pAV->m_pIDataObject->DUnadvise(pAV
  200. ->m_dwConn);
  201. }
  202. CheckMenuItem(hMenu, pAV->m_cfAdvise
  203. +IDM_ADVISEMIN, MF_UNCHECKED);
  204. CheckMenuItem(hMenu, wID, MF_CHECKED);
  205. //New format is wID-IDM_ADVISEMIN
  206. pAV->m_cfAdvise=(UINT)(wID-IDM_ADVISEMIN);
  207. fe.cfFormat=pAV->m_cfAdvise;
  208. pAV->m_pIDataObject->DAdvise(&fe, ADVF_NODATA
  209. , pAV->m_pIAdviseSink, &pAV->m_dwConn);
  210. break;
  211. case IDM_ADVISEGETDATA:
  212. pAV->m_fGetData=!pAV->m_fGetData;
  213. CheckMenuItem(hMenu, wID, pAV->m_fGetData
  214. ? MF_CHECKED : MF_UNCHECKED);
  215. break;
  216. case IDM_ADVISEREPAINT:
  217. pAV->m_fRepaint=!pAV->m_fRepaint;
  218. CheckMenuItem(hMenu, wID, pAV->m_fRepaint
  219. ? MF_CHECKED : MF_UNCHECKED);
  220. break;
  221. #endif /* NOT_SIMPLE*/
  222. default:
  223. break;
  224. }
  225. break;
  226. default:
  227. return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  228. }
  229. return 0L;
  230. }
  231. /*
  232. * CAppVars::CAppVars
  233. * CAppVars::~CAppVars
  234. *
  235. * Constructor Parameters: (from WinMain)
  236. * hInst HINSTANCE of the application.
  237. * hInstPrev HINSTANCE of a previous instance.
  238. * nCmdShow UINT specifying how to show the app window.
  239. */
  240. CAppVars::CAppVars(HINSTANCE hInst, HINSTANCE hInstPrev
  241. , UINT nCmdShow)
  242. {
  243. m_hInst =hInst;
  244. m_hInstPrev =hInstPrev;
  245. m_nCmdShow =nCmdShow;
  246. m_hWnd =NULL;
  247. #ifdef NOT_SIMPLE
  248. m_fEXE =FALSE;
  249. m_pIAdviseSink =NULL;
  250. m_dwConn =0;
  251. m_cfAdvise =0;
  252. m_fGetData =FALSE;
  253. m_fRepaint =FALSE;
  254. m_pIDataSmall =NULL;
  255. m_pIDataMedium=NULL;
  256. m_pIDataLarge =NULL;
  257. #endif /* NOT_SIMPLE */
  258. m_pIDataObject=NULL;
  259. m_f16Bit=FALSE;
  260. m_cfFormat=0;
  261. m_stm.tymed=TYMED_NULL;
  262. m_stm.lpszFileName=NULL; //Initializes union to NULL
  263. m_stm.pUnkForRelease=NULL;
  264. m_HereAllocCount=0; // For debugging
  265. m_fInitialized=FALSE;
  266. return;
  267. }
  268. CAppVars::~CAppVars(void)
  269. {
  270. //This releases the data object interfaces and advises
  271. FReloadDataObjects(FALSE);
  272. ReleaseStgMedium(&m_stm);
  273. #ifdef NOT_SIMPLE
  274. if (NULL!=m_pIAdviseSink)
  275. m_pIAdviseSink->Release();
  276. #endif /* NOT_SIMPLE */
  277. if (IsWindow(m_hWnd))
  278. DestroyWindow(m_hWnd);
  279. if (m_fInitialized)
  280. CoUninitialize();
  281. return;
  282. }
  283. /*
  284. * CAppVars::FInit
  285. *
  286. * Purpose:
  287. * Initializes an CAppVars object by registering window classes,
  288. * creating the main window, and doing anything else prone to
  289. * failure such as calling CoInitialize. If this function fails
  290. * the caller should insure that the destructor is called.
  291. *
  292. * Parameters:
  293. * None
  294. *
  295. * Return Value:
  296. * BOOL TRUE if successful, FALSE otherwise.
  297. */
  298. BOOL CAppVars::FInit(void)
  299. {
  300. WNDCLASS wc;
  301. DWORD dwVer;
  302. BOOL fRet;
  303. dwVer=CoBuildVersion();
  304. if (rmm!=HIWORD(dwVer))
  305. return FALSE;
  306. if (FAILED(CoInitialize(NULL)))
  307. return FALSE;
  308. m_fInitialized=TRUE;
  309. //Register our window classes.
  310. if (!m_hInstPrev)
  311. {
  312. wc.style = CS_HREDRAW | CS_VREDRAW;
  313. wc.lpfnWndProc = DataUserWndProc;
  314. wc.cbClsExtra = 0;
  315. wc.cbWndExtra = CBWNDEXTRA;
  316. wc.hInstance = m_hInst;
  317. wc.hIcon = LoadIcon(m_hInst, TEXT("Icon"));
  318. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  319. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  320. wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
  321. wc.lpszClassName = TEXT("DATAUSER");
  322. if (!RegisterClass(&wc))
  323. return FALSE;
  324. }
  325. //Create the main window.
  326. m_hWnd=CreateWindow(TEXT("DATAUSER"),
  327. APP_TITLE,
  328. WS_OVERLAPPEDWINDOW,
  329. 35, 35, 350, 250,
  330. NULL, NULL,
  331. m_hInst, this);
  332. if (NULL==m_hWnd)
  333. return FALSE;
  334. ShowWindow(m_hWnd, m_nCmdShow);
  335. UpdateWindow(m_hWnd);
  336. m_iDataSizeIndex=1;
  337. CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTSETDATA+1, MF_CHECKED);
  338. for(int i=0; i<64; i++)
  339. m_hgHereBuffers[i] = NULL;
  340. m_cIterations = 1;
  341. CheckMenuItem(GetMenu(m_hWnd), IDM_MEASUREMENT_1, MF_CHECKED);
  342. m_fDisplayTime = FALSE;
  343. CheckMenuItem(GetMenu(m_hWnd), IDM_MEASUREMENT_OFF, MF_CHECKED);
  344. #ifdef NOT_SIMPLE
  345. m_pIAdviseSink=new CImpIAdviseSink(this);
  346. if (NULL==m_pIAdviseSink)
  347. return FALSE;
  348. m_pIAdviseSink->AddRef();
  349. CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTUSEDLL, MF_CHECKED);
  350. CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTDATASIZESMALL
  351. , MF_CHECKED);
  352. #endif /* NOT_SIMPLE */
  353. //Load the initial objects
  354. fRet=FReloadDataObjects(TRUE);
  355. #ifdef NOT_SIMPLE
  356. m_pIDataObject=m_pIDataSmall;
  357. #endif /* NOT_SIMPLE */
  358. m_swTimer.m_ClassInit();
  359. return fRet;
  360. }
  361. /*
  362. * CAppVars::FReloadDataObjects
  363. *
  364. * Purpose:
  365. * Releases the old data objects we're holding on to and reloads
  366. * the new ones from either EXE or DLL depending on m_fEXE.
  367. *
  368. * Parameters:
  369. * fReload BOOL indicating if we are to recreate everything
  370. * or just release the old ones (so we can use this
  371. * from the destructor).
  372. *
  373. * Return Value:
  374. * BOOL TRUE if there are usable objects in us now.
  375. */
  376. BOOL CAppVars::FReloadDataObjects(BOOL fReload)
  377. {
  378. HCURSOR hCur, hCurT;
  379. //Clean out any data we're holding
  380. m_cfFormat=0;
  381. ReleaseStgMedium(&m_stm);
  382. //Turn off whatever data connection we have
  383. #ifdef NOT_SIMPLE
  384. if (NULL!=m_pIDataObject && 0!=m_dwConn)
  385. m_pIDataObject->DUnadvise(m_dwConn);
  386. if (NULL!=m_pIDataLarge)
  387. m_pIDataLarge->Release();
  388. if (NULL!=m_pIDataMedium)
  389. m_pIDataMedium->Release();
  390. if (NULL!=m_pIDataSmall)
  391. m_pIDataSmall->Release();
  392. #else /* IS SIMPLE */
  393. if (NULL != m_pIDataObject)
  394. m_pIDataObject->Release();
  395. #endif /* NOT_SIMPLE */
  396. m_pIDataObject=NULL;
  397. CoFreeUnusedLibraries();
  398. //Exit if we just wanted to free.
  399. if (!fReload)
  400. return FALSE;
  401. hCur=LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
  402. hCurT=SetCursor(hCur);
  403. ShowCursor(TRUE);
  404. #ifdef NOT_SIMPLE
  405. HRESULT hr1, hr2, hr3;
  406. DWORD dwClsCtx;
  407. dwClsCtx=(m_fEXE) ? CLSCTX_LOCAL_SERVER : CLSCTX_INPROC_SERVER;
  408. hr1=CoCreateInstance(CLSID_DataObjectSmall, NULL, dwClsCtx
  409. , IID_IDataObject, (PPVOID)&m_pIDataSmall);
  410. hr2=CoCreateInstance(CLSID_DataObjectMedium, NULL, dwClsCtx
  411. , IID_IDataObject, (PPVOID)&m_pIDataMedium);
  412. hr3=CoCreateInstance(CLSID_DataObjectLarge, NULL, dwClsCtx
  413. , IID_IDataObject, (PPVOID)&m_pIDataLarge);
  414. #else /* IS SIMPLE */
  415. HRESULT hr;
  416. if(m_f16Bit)
  417. {
  418. hr = CoCreateInstance(CLSID_DataObjectTest16,
  419. NULL,
  420. CLSCTX_LOCAL_SERVER,
  421. IID_IDataObject,
  422. (PPVOID)&m_pIDataObject);
  423. }else
  424. {
  425. hr = CoCreateInstance(CLSID_DataObjectTest32,
  426. NULL,
  427. CLSCTX_LOCAL_SERVER,
  428. IID_IDataObject,
  429. (PPVOID)&m_pIDataObject);
  430. }
  431. #endif /* NOT_SIMPLE */
  432. ShowCursor(FALSE);
  433. SetCursor(hCurT);
  434. //If anything fails, recurse to clean up...
  435. #ifdef NOT_SIMPLE
  436. if (FAILED(hr1) || FAILED(hr2) || FAILED(hr3))
  437. #else /* IS SIMPLE */
  438. if (FAILED(hr))
  439. #endif /* NOT_SIMPLE */
  440. {
  441. perror_OKBox(0, TEXT("CoCreateInstance Failed: "), hr);
  442. return FReloadDataObjects(FALSE);
  443. }
  444. HMENU hMenu = GetMenu(m_hWnd);
  445. UINT uTempD, uTempE;
  446. if(m_f16Bit)
  447. {
  448. CheckMenuItem(hMenu, IDM_USE16BITSERVER, MF_CHECKED);
  449. CheckMenuItem(hMenu, IDM_USE32BITSERVER, MF_UNCHECKED);
  450. }
  451. else
  452. {
  453. CheckMenuItem(hMenu, IDM_USE16BITSERVER, MF_UNCHECKED);
  454. CheckMenuItem(hMenu, IDM_USE32BITSERVER, MF_CHECKED);
  455. }
  456. hMenu=GetMenu(m_hWnd);
  457. for(int i=IDM_OBJECTSETDATA; i<=IDM_OBJECTSETDATA+64; i++)
  458. {
  459. CheckMenuItem(hMenu, i, MF_UNCHECKED);
  460. }
  461. m_iDataSizeIndex = 1;
  462. CheckMenuItem(hMenu,
  463. IDM_OBJECTSETDATA + m_iDataSizeIndex,
  464. MF_CHECKED);
  465. //Reset the state of the menus for Small, no advise, no options.
  466. #ifdef NOT_SIMPLE
  467. CheckMenuItem(hMenu, IDM_OBJECTDATASIZESMALL, MF_CHECKED);
  468. CheckMenuItem(hMenu, IDM_OBJECTDATASIZEMEDIUM, MF_UNCHECKED);
  469. CheckMenuItem(hMenu, IDM_OBJECTDATASIZELARGE, MF_UNCHECKED);
  470. m_pIDataObject=m_pIDataSmall;
  471. CheckMenuItem(hMenu, m_cfAdvise+IDM_ADVISEMIN, MF_UNCHECKED);
  472. uTempE=m_fEXE ? MF_CHECKED : MF_UNCHECKED;
  473. uTempD=!m_fEXE ? MF_CHECKED : MF_UNCHECKED;
  474. CheckMenuItem(hMenu, IDM_OBJECTUSEDLL, uTempD);
  475. CheckMenuItem(hMenu, IDM_OBJECTUSEEXE, uTempE);
  476. CheckMenuItem(hMenu, IDM_ADVISEGETDATA, MF_UNCHECKED);
  477. CheckMenuItem(hMenu, IDM_ADVISEREPAINT, MF_UNCHECKED);
  478. m_fGetData=FALSE;
  479. m_fRepaint=FALSE;
  480. //Cannot request data using async advises, so disable these.
  481. uTempE=m_fEXE ? MF_DISABLED | MF_GRAYED : MF_ENABLED;
  482. EnableMenuItem(hMenu, IDM_ADVISEGETDATA, uTempE);
  483. EnableMenuItem(hMenu, IDM_ADVISEREPAINT, uTempE);
  484. #endif /* NOT_SIMPLE */
  485. return TRUE;
  486. }
  487. /*
  488. * CAppVars::TryQueryGetData
  489. *
  490. * Purpose:
  491. * Centralized function call and output code for displaying results
  492. * of various IDataObject::QueryGetData calls.
  493. *
  494. * Parameters:
  495. * pFE LPFORMATETC to test.
  496. * cf UINT specific clipboard format to stuff in pFE
  497. * before calling. If zero, use whatever is
  498. * already in pFE.
  499. * fExpect BOOL indicating expected results
  500. * y UINT line on which to print results.
  501. *
  502. * Return Value:
  503. * None
  504. */
  505. void CAppVars::TryQueryGetData(LPFORMATETC pFE, UINT cf
  506. , BOOL fExpect, UINT y)
  507. {
  508. TCHAR szTemp[80];
  509. LPTSTR psz1;
  510. LPTSTR psz2;
  511. UINT cch;
  512. HRESULT hr;
  513. HDC hDC;
  514. if (0!=cf)
  515. pFE->cfFormat=cf;
  516. hr=m_pIDataObject->QueryGetData(pFE);
  517. psz1=(NOERROR==hr) ? szSuccess : szFailed;
  518. psz2=((NOERROR==hr)==fExpect) ? szExpected : szUnexpected;
  519. hDC=GetDC(m_hWnd);
  520. SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  521. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  522. if (CF_WAVE < cf || 0==cf)
  523. {
  524. cch=wsprintf(szTemp, TEXT("QueryGetData on %d %s (%s).")
  525. , cf, psz1, psz2);
  526. }
  527. else
  528. {
  529. cch=wsprintf(szTemp, TEXT("QueryGetData on %s %s (%s).")
  530. , (LPTSTR)rgszCF[cf], psz1, psz2);
  531. }
  532. //Don't overwrite other painted display.
  533. SetBkMode(hDC, TRANSPARENT);
  534. TextOut(hDC, 0, 16*y, szTemp, cch);
  535. ReleaseDC(m_hWnd, hDC);
  536. return;
  537. }
  538. int
  539. CAppVars::m_GetData(WORD wID)
  540. {
  541. FORMATETC fe;
  542. HRESULT hr;
  543. if (NULL == m_pIDataObject)
  544. return(0); // Don't redraw.
  545. //Clean up whatever we currently have.
  546. m_cfFormat = 0;
  547. ReleaseStgMedium(&m_stm);
  548. switch (wID)
  549. {
  550. case IDM_OBJECTGETDATA_TEXT:
  551. SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL);
  552. break;
  553. #ifdef NOT_SIMPLE
  554. case IDM_OBJECTGETDATA_BITMAP:
  555. SETDefFormatEtc(fe, CF_BITMAP, TYMED_GDI);
  556. break;
  557. case IDM_OBJECTGETDATA_METAFILEPICT:
  558. SETDefFormatEtc(fe, CF_METAFILEPICT, TYMED_MFPICT);
  559. break;
  560. #endif /* NOT_SIMPLE */
  561. default:
  562. MessageBox(0,
  563. TEXT("Type is Unsupported in the Client"),
  564. TEXT("GetData"),
  565. MB_OK);
  566. return(0);
  567. }
  568. m_swTimer.m_Start();
  569. HRESULT didfail = NOERROR;
  570. for(int i=0; i<m_cIterations; i++)
  571. {
  572. hr = m_pIDataObject->GetData(&fe, &m_stm);
  573. if (SUCCEEDED(hr))
  574. {
  575. // If we are just whacking off for the benchmark.
  576. // Then release all but the last one we recieve.
  577. if(i < m_cIterations-1)
  578. ReleaseStgMedium(&m_stm);
  579. }
  580. else
  581. didfail = hr;
  582. }
  583. m_swTimer.m_Stop();
  584. if (SUCCEEDED(didfail))
  585. m_cfFormat=fe.cfFormat;
  586. else
  587. {
  588. perror_OKBox(0,
  589. TEXT("GetData Failed"),
  590. didfail);
  591. }
  592. return(1); // Do redraw even if it failed (draw blank).
  593. }
  594. int
  595. CAppVars::m_GetDataHere(WORD wID)
  596. {
  597. FORMATETC fe;
  598. HRESULT hr;
  599. if(NULL == m_pIDataObject)
  600. return(0); // Don't redraw
  601. m_cfFormat = 0;
  602. // Don't Release the STGMedium. We recycle them!
  603. switch(wID)
  604. {
  605. case IDM_OBJECTGETDATAHERE_TEXT:
  606. SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL);
  607. break;
  608. case IDM_OBJECTGETDATAHERE_NULLTEXT:
  609. SETDefFormatEtc(fe, CF_TEXT, TYMED_NULL);
  610. break;
  611. /* Other cases go here.... */
  612. default:
  613. MessageBox(0,
  614. TEXT("Type is Unsupported in the Client"),
  615. TEXT("GetDataHere"),
  616. MB_OK);
  617. return(0);
  618. }
  619. HGLOBAL* phg = &m_hgHereBuffers[m_iDataSizeIndex];
  620. if(NULL == *phg)
  621. {
  622. ++m_HereAllocCount;
  623. *phg = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE,
  624. DATASIZE_FROM_INDEX(m_iDataSizeIndex) );
  625. if(NULL == *phg)
  626. {
  627. MessageBox(0,
  628. TEXT("GlobalAlloc Return NULL"),
  629. TEXT("Failure"),
  630. MB_OK);
  631. PostQuitMessage(0);
  632. return(0); // Don't redraw
  633. }
  634. }
  635. m_stm.hGlobal=*phg;
  636. m_stm.tymed=TYMED_HGLOBAL;
  637. m_stm.pUnkForRelease=NULL;
  638. // The TYMED_NULL case tests code in olethk where it is written:
  639. // "If tymed == TYMED_NULL then GetDataHere should behave like GetData."
  640. // I can't find this in any manual (OLE2 or Ole). I wanted to see what
  641. // good that code was. (there is also bug #15974) Aug 8th 1995 BChapman.
  642. if (IDM_OBJECTGETDATAHERE_NULLTEXT == wID)
  643. {
  644. m_stm.hGlobal=NULL;
  645. m_stm.tymed=TYMED_NULL;
  646. }
  647. // The other side "knows" the size of the data.
  648. // (It is told via. SetData)
  649. HRESULT didfail = NOERROR;
  650. m_swTimer.m_Start();
  651. for(int i=0; i<m_cIterations; i++)
  652. {
  653. hr = m_pIDataObject->GetDataHere(&fe, &m_stm);
  654. if (FAILED(hr))
  655. didfail = hr;
  656. // We don't ReleaseSTGMedium because this
  657. // is GetDataHere !
  658. }
  659. m_swTimer.m_Stop();
  660. if (SUCCEEDED(didfail))
  661. m_cfFormat=fe.cfFormat;
  662. else
  663. {
  664. perror_OKBox(0,
  665. TEXT("GetDataHere Failed"),
  666. didfail);
  667. }
  668. return(1); // redraw (if FAILED(hr) then draw blank)
  669. }
  670. int
  671. CAppVars::m_SetData_SetSize(long iSizeIndex)
  672. {
  673. FORMATETC fe;
  674. HRESULT hr;
  675. if (NULL == m_pIDataObject)
  676. return 0;
  677. SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL);
  678. m_iDataSizeIndex = iSizeIndex;
  679. HGLOBAL hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(ULONG) );
  680. if(NULL == hMem)
  681. {
  682. MessageBox(0,
  683. TEXT("GlobalAlloc Return NULL"),
  684. TEXT("Failure"),
  685. MB_OK);
  686. PostQuitMessage(0);
  687. return 0;
  688. }
  689. long* pl=(long*)GlobalLock(hMem); // Lock
  690. *((long*)pl) = DATASIZE_FROM_INDEX(m_iDataSizeIndex);
  691. GlobalUnlock(hMem); // Unlock
  692. m_stm.hGlobal=hMem;
  693. m_stm.tymed=TYMED_HGLOBAL;
  694. m_stm.pUnkForRelease=NULL;
  695. hr = m_pIDataObject->SetData(&fe, &m_stm, FALSE); // Keep Ownership.
  696. if (FAILED(hr))
  697. {
  698. perror_OKBox(0,
  699. TEXT("SetData Failed"),
  700. hr);
  701. return 0;
  702. }
  703. return 1;;
  704. // release the hMem HGLOBAL perhaps ???
  705. }
  706. int
  707. CAppVars::m_SetData_WithPUnk(WORD wID)
  708. {
  709. FORMATETC fe;
  710. HRESULT hr;
  711. if(NULL == m_pIDataObject)
  712. return 0;
  713. switch(wID)
  714. {
  715. case IDM_OBJECTSETDATAPUNK_TEXT:
  716. SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL);
  717. break;
  718. /* Other cases go here.... */
  719. default:
  720. MessageBox(0,
  721. TEXT("Type is Unsupported in the Client"),
  722. TEXT("SetData"),
  723. MB_OK);
  724. return(0);
  725. }
  726. HGLOBAL hMem=GlobalAlloc( GMEM_SHARE | GMEM_MOVEABLE, sizeof(ULONG) );
  727. if(NULL == hMem)
  728. {
  729. MessageBox(0,
  730. TEXT("GlobalAlloc Return NULL"),
  731. TEXT("Failure"),
  732. MB_OK);
  733. PostQuitMessage(0);
  734. return 0;
  735. }
  736. long* pl=(long*)GlobalLock(hMem); // Lock
  737. *((long*)pl) = 0xffffffff; // Use
  738. GlobalUnlock(hMem); // Unlock
  739. m_stm.hGlobal=hMem;
  740. m_stm.tymed=TYMED_HGLOBAL;
  741. hr = GetStgMedpUnkForRelease(&m_stm.pUnkForRelease);
  742. if(NOERROR != hr)
  743. {
  744. perror_OKBox(0, TEXT("Can't get pUnk For Release"), hr);
  745. }
  746. hr = m_pIDataObject->SetData(&fe, &m_stm, TRUE); // Pass Ownership.
  747. // We passed ownership so SetData took the HGLOBAL from us.
  748. if (FAILED(hr))
  749. {
  750. perror_OKBox(0,
  751. TEXT("SetData Failed"),
  752. hr);
  753. return 0;
  754. }
  755. return 1;
  756. }
  757. #define NUM_RUNS 5
  758. void
  759. CAppVars::m_BatchToFile()
  760. {
  761. dataset_t dsGetDataText;
  762. dataset_t dsGetDataHereText;
  763. pm_ClearDataset(&dsGetDataText);
  764. pm_ClearDataset(&dsGetDataHereText);
  765. int iRun;
  766. for(iRun=0; iRun < NUM_RUNS; iRun++)
  767. {
  768. m_MeasureAllSizes(IDM_OBJECTGETDATA_TEXT,
  769. NULL,
  770. &dsGetDataText);
  771. m_MeasureAllSizes(IDM_OBJECTGETDATAHERE_TEXT,
  772. NULL,
  773. &dsGetDataHereText);
  774. }
  775. FILE *fp;
  776. int i;
  777. if(NULL == (fp = fopen(FILENAME, "w")))
  778. {
  779. MessageBox(0, TEXT("Cannot Open Output File"),
  780. TEXT(FILENAME),
  781. MB_OK | MB_ICONSTOP);
  782. return;
  783. }
  784. fprintf(fp, " GetData w/ HGLOBAL GetDataHere w/ HGLOBAL\n");
  785. fprintf(fp, " Size Best Worst Average Best Worst Average\n");
  786. for (i=0; i<NUM_POINTS; i++)
  787. {
  788. fprintf(fp, "%5d\t", cKSizes[i]);
  789. #define PR_TIME(fp, v) (fprintf(fp, "%3lu.%03lu\t", (v)/1000, (v)%1000))
  790. PR_TIME(fp, dsGetDataText.cBest[i]);
  791. PR_TIME(fp, dsGetDataText.cWorst[i]);
  792. PR_TIME(fp, dsGetDataText.cTotal[i]/NUM_RUNS);
  793. PR_TIME(fp, dsGetDataHereText.cBest[i]);
  794. PR_TIME(fp, dsGetDataHereText.cWorst[i]);
  795. PR_TIME(fp, dsGetDataHereText.cTotal[i]/NUM_RUNS);
  796. fprintf(fp, "\n");
  797. }
  798. fclose(fp);
  799. MessageBox(0, TEXT("Output Written to file.dat!"),
  800. TEXT("Done"), MB_OK);
  801. }
  802. void
  803. CAppVars::pm_ClearDataset(dataset_t *ds)
  804. {
  805. int i;
  806. for(i=0; i<NUM_POINTS; i++)
  807. {
  808. ds->cTotal[i] = 0;
  809. ds->cBest[i] = 0xFFFFFFFF;
  810. ds->cWorst[i] = 0;
  811. }
  812. }
  813. void
  814. CAppVars::m_MeasureAllSizes(
  815. WORD wID,
  816. LPTSTR tstrTitle,
  817. dataset_t *ds)
  818. {
  819. int i;
  820. ULONG cUSecs[NUM_POINTS];
  821. // Save some state.
  822. ULONG iOldDataSizeIndex = m_iDataSizeIndex;
  823. for (i=0; i<NUM_POINTS; i++)
  824. {
  825. m_SetData_SetSize(cKSizes[i]);
  826. switch(wID)
  827. {
  828. case IDM_OBJECTGETDATA_TEXT:
  829. case IDM_OBJECTGETDATA_BITMAP:
  830. m_GetData(wID);
  831. break;
  832. case IDM_OBJECTGETDATAHERE_TEXT:
  833. case IDM_OBJECTGETDATAHERE_BITMAP:
  834. m_GetDataHere(wID);
  835. break;
  836. }
  837. m_swTimer.m_Read(&cUSecs[i]);
  838. cUSecs[i] /= m_cIterations;
  839. }
  840. // Restore save state.
  841. m_iDataSizeIndex = iOldDataSizeIndex;
  842. m_SetData_SetSize(m_iDataSizeIndex);
  843. // If the caller provided memory then return the data in it.
  844. if(NULL != ds)
  845. {
  846. for (i=0; i<NUM_POINTS; i++)
  847. {
  848. ds->cData[i] = cUSecs[i];
  849. ds->cTotal[i] += cUSecs[i];
  850. if(ds->cBest[i] > cUSecs[i])
  851. ds->cBest[i] = cUSecs[i];
  852. if( ds->cWorst[i] < cUSecs[i])
  853. ds->cWorst[i] = cUSecs[i];
  854. }
  855. }
  856. // If the caller passed a NULL Title then no message box.
  857. if(NULL == tstrTitle)
  858. return;
  859. // Render Results.
  860. LPTSTR tstr = &tcMessageBuf[0];
  861. for (i=0; i<NUM_POINTS; i++)
  862. {
  863. wsprintf(tstr, TEXT("%dK: %lu.%03lu%c"),
  864. cKSizes[i], cUSecs[i]/1000, cUSecs[i]%1000,
  865. (i%4==3)? TEXT('\n'):TEXT('\t') );
  866. tstr += lstrlen(tstr);
  867. }
  868. MessageBox(0, tcMessageBuf, tstrTitle, MB_OK);
  869. }
  870. void
  871. CAppVars::m_SetMeasurement(WORD wID)
  872. {
  873. HMENU hMenu=GetMenu(m_hWnd);
  874. switch (wID)
  875. {
  876. case IDM_MEASUREMENT_ON:
  877. m_fDisplayTime = TRUE;
  878. CheckMenuItem(hMenu, IDM_MEASUREMENT_ON, MF_CHECKED);
  879. CheckMenuItem(hMenu, IDM_MEASUREMENT_OFF, MF_UNCHECKED);
  880. break;
  881. case IDM_MEASUREMENT_OFF:
  882. m_fDisplayTime = FALSE;
  883. CheckMenuItem(hMenu, IDM_MEASUREMENT_ON, MF_UNCHECKED);
  884. CheckMenuItem(hMenu, IDM_MEASUREMENT_OFF, MF_CHECKED);
  885. break;
  886. case IDM_MEASUREMENT_1:
  887. m_cIterations = 1;
  888. goto set_menu;
  889. case IDM_MEASUREMENT_50:
  890. m_cIterations = 50;
  891. goto set_menu;
  892. case IDM_MEASUREMENT_300:
  893. m_cIterations = 300;
  894. goto set_menu;
  895. set_menu:
  896. CheckMenuItem(hMenu, IDM_MEASUREMENT_1, MF_UNCHECKED);
  897. CheckMenuItem(hMenu, IDM_MEASUREMENT_50, MF_UNCHECKED);
  898. CheckMenuItem(hMenu, IDM_MEASUREMENT_300, MF_UNCHECKED);
  899. CheckMenuItem(hMenu, wID, MF_CHECKED);
  900. break;
  901. case IDM_MEASUREMENT_TEST:
  902. m_swTimer.m_Start();
  903. m_swTimer.m_Sleep(777);
  904. m_swTimer.m_Stop();
  905. m_DisplayTimerResults();
  906. break;
  907. }
  908. }
  909. void
  910. CAppVars::m_DisplayTimerResults()
  911. {
  912. ULONG usecs;
  913. m_swTimer.m_Read(&usecs);
  914. usecs /= m_cIterations;
  915. wprintf_OKBox(0, TEXT("MilliSeconds"),
  916. TEXT("%lu.%03lu"),
  917. usecs/1000, usecs%1000);
  918. }
  919. /*
  920. * CAppVars::Paint
  921. *
  922. * Purpose:
  923. * Handles WM_PAINT for the main window by drawing whatever
  924. * data we have sitting in the STGMEDIUM at this time.
  925. *
  926. * Parameters:
  927. * None
  928. *
  929. * Return Value:
  930. * None
  931. */
  932. void CAppVars::Paint(void)
  933. {
  934. PAINTSTRUCT ps;
  935. HDC hDC;
  936. #ifdef NOT_SIMPLE
  937. HDC hMemDC;
  938. LPMETAFILEPICT pMF;
  939. #endif /* NOT_SIMPLE */
  940. LPTSTR psz;
  941. RECT rc;
  942. FORMATETC fe;
  943. GetClientRect(m_hWnd, &rc);
  944. hDC=BeginPaint(m_hWnd, &ps);
  945. //May need to retrieve the data with EXE objects
  946. #ifdef NOT_SIMPLE
  947. if (m_fEXE)
  948. {
  949. if (TYMED_NULL==m_stm.tymed && 0!=m_cfFormat)
  950. {
  951. SETDefFormatEtc(fe, m_cfFormat, TYMED_HGLOBAL
  952. | TYMED_MFPICT | TYMED_GDI);
  953. if (NULL!=m_pIDataObject)
  954. m_pIDataObject->GetData(&fe, &m_stm);
  955. }
  956. }
  957. #endif /* NOT_SIMPLE */
  958. switch (m_cfFormat)
  959. {
  960. case CF_TEXT:
  961. psz=(LPTSTR)GlobalLock(m_stm.hGlobal);
  962. if (NULL==psz)
  963. break;
  964. SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  965. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  966. pm_DrawText(hDC, psz, &rc, DT_LEFT | DT_WORDBREAK);
  967. GlobalUnlock(m_stm.hGlobal);
  968. break;
  969. #ifdef NOT_SIMPLE
  970. case CF_BITMAP:
  971. hMemDC=CreateCompatibleDC(hDC);
  972. if (NULL!=SelectObject(hMemDC, (HGDIOBJ)m_stm.hGlobal))
  973. {
  974. BitBlt(hDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top
  975. , hMemDC, 0, 0, SRCCOPY);
  976. }
  977. DeleteDC(hMemDC);
  978. break;
  979. case CF_METAFILEPICT:
  980. pMF=(LPMETAFILEPICT)GlobalLock(m_stm.hGlobal);
  981. if (NULL==pMF)
  982. break;
  983. SetMapMode(hDC, pMF->mm);
  984. SetWindowOrgEx(hDC, 0, 0, NULL);
  985. SetWindowExtEx(hDC, pMF->xExt, pMF->yExt, NULL);
  986. SetViewportExtEx(hDC, rc.right-rc.left
  987. , rc.bottom-rc.top, NULL);
  988. PlayMetaFile(hDC, pMF->hMF);
  989. GlobalUnlock(m_stm.hGlobal);
  990. break;
  991. #else /* IS SIMPLE */
  992. case CF_BITMAP:
  993. case CF_METAFILEPICT:
  994. DebugBreak();
  995. break;
  996. #endif /* NOT_SIMPLE */
  997. default:
  998. break;
  999. }
  1000. EndPaint(m_hWnd, &ps);
  1001. return;
  1002. }
  1003. void
  1004. CAppVars::pm_DrawText(
  1005. HDC hDC,
  1006. LPTSTR psz,
  1007. RECT* prc,
  1008. UINT flags)
  1009. {
  1010. SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  1011. SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  1012. // If we are WIN32 and the server is 16 bits this must be ASCII.
  1013. #ifdef WIN32
  1014. if(m_f16Bit)
  1015. DrawTextA(hDC, (char*)psz, -1, prc, flags);
  1016. else
  1017. #endif
  1018. DrawText(hDC, psz, -1, prc, flags);
  1019. }
  1020.