|
|
/*
* DATAUSER.CPP * Data Object User Chapter 6 * * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved * * Kraig Brockschmidt, Software Design Engineer * Microsoft Systems Developer Relations * * Internet : kraigb@microsoft.com * Compuserve: >INTERNET:kraigb@microsoft.com */
#define INIT_MY_GUIDS
#include "datausr.h"
#include "perror.h"
#include <stdio.h>
#ifdef WIN32
#define APP_TITLE TEXT("32 Bit IDataObject User")
#else
#define APP_TITLE TEXT("16 Bit IDataObject User")
#endif
//These are for displaying clipboard formats textually.
static TCHAR * rgszCF[13]={TEXT("Unknown"), TEXT("CF_TEXT") , TEXT("CF_BITMAP"), TEXT("CF_METAFILEPICT") , TEXT("CF_SYLK"), TEXT("CF_DIF"), TEXT("CF_TIFF") , TEXT("CF_OEMTEXT"), TEXT("CF_DIB") , TEXT("CF_PALETTE"), TEXT("CF_PENDATA") , TEXT("CF_RIFF"), TEXT("CF_WAVE")};
static TCHAR szSuccess[] =TEXT("succeeded"); static TCHAR szFailed[] =TEXT("failed"); static TCHAR szExpected[] =TEXT("expected"); static TCHAR szUnexpected[] =TEXT("unexpected!");
TCHAR tcMessageBuf[4096]; // Misc use buffer for messages.
int cKSizes[NUM_POINTS] = { 1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32, 40, 48, 56 };
/*
* WinMain * * Purpose: * Main entry point of application. */
int PASCAL WinMain( HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR pszCmdLine, int nCmdShow) { MSG msg; PAPPVARS pAV;
#ifndef WIN32
int cMsg=96;
while (!SetMessageQueue(cMsg) && (cMsg-=8)); #endif
pAV=new CAppVars(hInst, hInstPrev, nCmdShow);
if (NULL==pAV) return -1;
if (pAV->FInit()) { while (GetMessage(&msg, NULL, 0,0 )) { TranslateMessage(&msg); DispatchMessage(&msg); } }
delete pAV; return msg.wParam; }
/*
* DataUserWndProc * * Purpose: * Window class procedure. Standard callback. */
LRESULT API_ENTRY DataUserWndProc(HWND hWnd, UINT iMsg , WPARAM wParam, LPARAM lParam) { HRESULT hr; PAPPVARS pAV; HMENU hMenu; FORMATETC fe; WORD wID; int i;
pAV=(PAPPVARS)GetWindowLong(hWnd, DATAUSERWL_STRUCTURE);
switch (iMsg) { case WM_NCCREATE: pAV=(PAPPVARS)((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowLong(hWnd, DATAUSERWL_STRUCTURE, (LONG)pAV); return (DefWindowProc(hWnd, iMsg, wParam, lParam));
case WM_DESTROY: PostQuitMessage(0); break;
case WM_PAINT: pAV->Paint(); break;
case WM_COMMAND: SETDefFormatEtc(fe, 0, TYMED_HGLOBAL | TYMED_GDI| TYMED_MFPICT);
hMenu=GetMenu(hWnd); wID=LOWORD(wParam);
if(wID >= IDM_OBJECTSETDATA && wID <= IDM_OBJECTSETDATA+64) { // Blast all possible SetData menu items. Some don't exist.
for(i=IDM_OBJECTSETDATA; i<=IDM_OBJECTSETDATA+64; i++) CheckMenuItem(hMenu,i, MF_UNCHECKED); CheckMenuItem(hMenu, wID, MF_CHECKED);
pAV->m_SetData_SetSize(wID-IDM_OBJECTSETDATA); break; }
switch (wID) { case IDM_USE16BITSERVER: if (pAV->m_f16Bit) break; pAV->m_f16Bit = TRUE; pAV->FReloadDataObjects(TRUE); break;
case IDM_USE32BITSERVER: if (!pAV->m_f16Bit) break; pAV->m_f16Bit = FALSE; pAV->FReloadDataObjects(TRUE); break;
case IDM_OBJECTQUERYGETDATA: if (NULL==pAV->m_pIDataObject) break;
fe.tymed=TYMED_HGLOBAL | TYMED_GDI | TYMED_MFPICT;
pAV->TryQueryGetData(&fe, CF_TEXT, TRUE, 0); pAV->TryQueryGetData(&fe, CF_BITMAP, TRUE, 1); #ifdef NOT_SIMPLE
pAV->TryQueryGetData(&fe, CF_DIB, FALSE, 2); pAV->TryQueryGetData(&fe, CF_METAFILEPICT, TRUE, 3); pAV->TryQueryGetData(&fe, CF_WAVE, FALSE, 4); #endif /* NOT_SIMPLE */
break;
case IDM_OBJECTGETDATA_TEXT: case IDM_OBJECTGETDATA_BITMAP: #ifdef NOT_SIMPLE
case IDM_OBJECTGETDATA_METAFILEPICT: #endif /* NOT_SIMPLE */
if (pAV->m_GetData(wID) ) { InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); }
if(pAV->m_fDisplayTime) pAV->m_DisplayTimerResults(); break;
case IDM_OBJECTGETDATAHERE_TEXT: case IDM_OBJECTGETDATAHERE_NULLTEXT: case IDM_OBJECTGETDATAHERE_BITMAP: case IDM_OBJECTGETDATAHERE_NULLBITMAP: if (pAV->m_GetDataHere(wID) ) { InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); }
if(pAV->m_fDisplayTime) pAV->m_DisplayTimerResults(); break;
case IDM_OBJECTSETDATAPUNK_TEXT: case IDM_OBJECTSETDATAPUNK_BITMAP: pAV->m_SetData_WithPUnk(wID); break;
case IDM_MEASUREMENT_1: case IDM_MEASUREMENT_50: case IDM_MEASUREMENT_300: case IDM_MEASUREMENT_OFF: case IDM_MEASUREMENT_ON: case IDM_MEASUREMENT_TEST: pAV->m_SetMeasurement(wID); break;
case IDM_BATCH_GETDATA: pAV->m_MeasureAllSizes(IDM_OBJECTGETDATA_TEXT, TEXT("GetData w/HGLOBAL"), NULL); break;
case IDM_BATCH_GETDATAHERE: pAV->m_MeasureAllSizes(IDM_OBJECTGETDATAHERE_TEXT, TEXT("GetDataHere w/HGLOBAL"), NULL); break;
case IDM_BATCHTOFILE: pAV->m_BatchToFile(); break;
case IDM_OBJECTEXIT: PostMessage(hWnd, WM_CLOSE, 0, 0L); break;
#ifdef NOT_SIMPLE
case IDM_ADVISETEXT: case IDM_ADVISEBITMAP: case IDM_ADVISEMETAFILEPICT: if (NULL==pAV->m_pIDataObject) break;
//Terminate the old connection
if (0!=pAV->m_dwConn) { pAV->m_pIDataObject->DUnadvise(pAV ->m_dwConn); }
CheckMenuItem(hMenu, pAV->m_cfAdvise +IDM_ADVISEMIN, MF_UNCHECKED); CheckMenuItem(hMenu, wID, MF_CHECKED);
//New format is wID-IDM_ADVISEMIN
pAV->m_cfAdvise=(UINT)(wID-IDM_ADVISEMIN); fe.cfFormat=pAV->m_cfAdvise; pAV->m_pIDataObject->DAdvise(&fe, ADVF_NODATA , pAV->m_pIAdviseSink, &pAV->m_dwConn);
break;
case IDM_ADVISEGETDATA: pAV->m_fGetData=!pAV->m_fGetData; CheckMenuItem(hMenu, wID, pAV->m_fGetData ? MF_CHECKED : MF_UNCHECKED); break;
case IDM_ADVISEREPAINT: pAV->m_fRepaint=!pAV->m_fRepaint; CheckMenuItem(hMenu, wID, pAV->m_fRepaint ? MF_CHECKED : MF_UNCHECKED); break; #endif /* NOT_SIMPLE*/
default: break; } break;
default: return (DefWindowProc(hWnd, iMsg, wParam, lParam)); }
return 0L; }
/*
* CAppVars::CAppVars * CAppVars::~CAppVars * * Constructor Parameters: (from WinMain) * hInst HINSTANCE of the application. * hInstPrev HINSTANCE of a previous instance. * nCmdShow UINT specifying how to show the app window. */
CAppVars::CAppVars(HINSTANCE hInst, HINSTANCE hInstPrev , UINT nCmdShow) { m_hInst =hInst; m_hInstPrev =hInstPrev; m_nCmdShow =nCmdShow;
m_hWnd =NULL; #ifdef NOT_SIMPLE
m_fEXE =FALSE;
m_pIAdviseSink =NULL; m_dwConn =0; m_cfAdvise =0; m_fGetData =FALSE; m_fRepaint =FALSE;
m_pIDataSmall =NULL; m_pIDataMedium=NULL; m_pIDataLarge =NULL; #endif /* NOT_SIMPLE */
m_pIDataObject=NULL; m_f16Bit=FALSE; m_cfFormat=0; m_stm.tymed=TYMED_NULL; m_stm.lpszFileName=NULL; //Initializes union to NULL
m_stm.pUnkForRelease=NULL;
m_HereAllocCount=0; // For debugging
m_fInitialized=FALSE; return; }
CAppVars::~CAppVars(void) { //This releases the data object interfaces and advises
FReloadDataObjects(FALSE);
ReleaseStgMedium(&m_stm);
#ifdef NOT_SIMPLE
if (NULL!=m_pIAdviseSink) m_pIAdviseSink->Release(); #endif /* NOT_SIMPLE */
if (IsWindow(m_hWnd)) DestroyWindow(m_hWnd);
if (m_fInitialized) CoUninitialize();
return; }
/*
* CAppVars::FInit * * Purpose: * Initializes an CAppVars object by registering window classes, * creating the main window, and doing anything else prone to * failure such as calling CoInitialize. If this function fails * the caller should insure that the destructor is called. * * Parameters: * None * * Return Value: * BOOL TRUE if successful, FALSE otherwise. */
BOOL CAppVars::FInit(void) { WNDCLASS wc; DWORD dwVer; BOOL fRet;
dwVer=CoBuildVersion();
if (rmm!=HIWORD(dwVer)) return FALSE;
if (FAILED(CoInitialize(NULL))) return FALSE;
m_fInitialized=TRUE;
//Register our window classes.
if (!m_hInstPrev) { wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = DataUserWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = CBWNDEXTRA; wc.hInstance = m_hInst; wc.hIcon = LoadIcon(m_hInst, TEXT("Icon")); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = TEXT("DATAUSER");
if (!RegisterClass(&wc)) return FALSE; }
//Create the main window.
m_hWnd=CreateWindow(TEXT("DATAUSER"), APP_TITLE, WS_OVERLAPPEDWINDOW, 35, 35, 350, 250, NULL, NULL, m_hInst, this);
if (NULL==m_hWnd) return FALSE;
ShowWindow(m_hWnd, m_nCmdShow); UpdateWindow(m_hWnd);
m_iDataSizeIndex=1; CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTSETDATA+1, MF_CHECKED); for(int i=0; i<64; i++) m_hgHereBuffers[i] = NULL;
m_cIterations = 1; CheckMenuItem(GetMenu(m_hWnd), IDM_MEASUREMENT_1, MF_CHECKED);
m_fDisplayTime = FALSE; CheckMenuItem(GetMenu(m_hWnd), IDM_MEASUREMENT_OFF, MF_CHECKED);
#ifdef NOT_SIMPLE
m_pIAdviseSink=new CImpIAdviseSink(this);
if (NULL==m_pIAdviseSink) return FALSE;
m_pIAdviseSink->AddRef();
CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTUSEDLL, MF_CHECKED); CheckMenuItem(GetMenu(m_hWnd), IDM_OBJECTDATASIZESMALL , MF_CHECKED); #endif /* NOT_SIMPLE */
//Load the initial objects
fRet=FReloadDataObjects(TRUE); #ifdef NOT_SIMPLE
m_pIDataObject=m_pIDataSmall; #endif /* NOT_SIMPLE */
m_swTimer.m_ClassInit();
return fRet; }
/*
* CAppVars::FReloadDataObjects * * Purpose: * Releases the old data objects we're holding on to and reloads * the new ones from either EXE or DLL depending on m_fEXE. * * Parameters: * fReload BOOL indicating if we are to recreate everything * or just release the old ones (so we can use this * from the destructor). * * Return Value: * BOOL TRUE if there are usable objects in us now. */
BOOL CAppVars::FReloadDataObjects(BOOL fReload) { HCURSOR hCur, hCurT;
//Clean out any data we're holding
m_cfFormat=0; ReleaseStgMedium(&m_stm);
//Turn off whatever data connection we have
#ifdef NOT_SIMPLE
if (NULL!=m_pIDataObject && 0!=m_dwConn) m_pIDataObject->DUnadvise(m_dwConn);
if (NULL!=m_pIDataLarge) m_pIDataLarge->Release();
if (NULL!=m_pIDataMedium) m_pIDataMedium->Release();
if (NULL!=m_pIDataSmall) m_pIDataSmall->Release(); #else /* IS SIMPLE */
if (NULL != m_pIDataObject) m_pIDataObject->Release(); #endif /* NOT_SIMPLE */
m_pIDataObject=NULL; CoFreeUnusedLibraries();
//Exit if we just wanted to free.
if (!fReload) return FALSE;
hCur=LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)); hCurT=SetCursor(hCur); ShowCursor(TRUE);
#ifdef NOT_SIMPLE
HRESULT hr1, hr2, hr3; DWORD dwClsCtx;
dwClsCtx=(m_fEXE) ? CLSCTX_LOCAL_SERVER : CLSCTX_INPROC_SERVER;
hr1=CoCreateInstance(CLSID_DataObjectSmall, NULL, dwClsCtx , IID_IDataObject, (PPVOID)&m_pIDataSmall);
hr2=CoCreateInstance(CLSID_DataObjectMedium, NULL, dwClsCtx , IID_IDataObject, (PPVOID)&m_pIDataMedium);
hr3=CoCreateInstance(CLSID_DataObjectLarge, NULL, dwClsCtx , IID_IDataObject, (PPVOID)&m_pIDataLarge); #else /* IS SIMPLE */
HRESULT hr;
if(m_f16Bit) { hr = CoCreateInstance(CLSID_DataObjectTest16, NULL, CLSCTX_LOCAL_SERVER, IID_IDataObject, (PPVOID)&m_pIDataObject); }else { hr = CoCreateInstance(CLSID_DataObjectTest32, NULL, CLSCTX_LOCAL_SERVER, IID_IDataObject, (PPVOID)&m_pIDataObject); }
#endif /* NOT_SIMPLE */
ShowCursor(FALSE); SetCursor(hCurT);
//If anything fails, recurse to clean up...
#ifdef NOT_SIMPLE
if (FAILED(hr1) || FAILED(hr2) || FAILED(hr3)) #else /* IS SIMPLE */
if (FAILED(hr)) #endif /* NOT_SIMPLE */
{ perror_OKBox(0, TEXT("CoCreateInstance Failed: "), hr); return FReloadDataObjects(FALSE); }
HMENU hMenu = GetMenu(m_hWnd); UINT uTempD, uTempE;
if(m_f16Bit) { CheckMenuItem(hMenu, IDM_USE16BITSERVER, MF_CHECKED); CheckMenuItem(hMenu, IDM_USE32BITSERVER, MF_UNCHECKED); } else { CheckMenuItem(hMenu, IDM_USE16BITSERVER, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_USE32BITSERVER, MF_CHECKED); }
hMenu=GetMenu(m_hWnd); for(int i=IDM_OBJECTSETDATA; i<=IDM_OBJECTSETDATA+64; i++) { CheckMenuItem(hMenu, i, MF_UNCHECKED); } m_iDataSizeIndex = 1; CheckMenuItem(hMenu, IDM_OBJECTSETDATA + m_iDataSizeIndex, MF_CHECKED);
//Reset the state of the menus for Small, no advise, no options.
#ifdef NOT_SIMPLE
CheckMenuItem(hMenu, IDM_OBJECTDATASIZESMALL, MF_CHECKED); CheckMenuItem(hMenu, IDM_OBJECTDATASIZEMEDIUM, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_OBJECTDATASIZELARGE, MF_UNCHECKED);
m_pIDataObject=m_pIDataSmall; CheckMenuItem(hMenu, m_cfAdvise+IDM_ADVISEMIN, MF_UNCHECKED);
uTempE=m_fEXE ? MF_CHECKED : MF_UNCHECKED; uTempD=!m_fEXE ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(hMenu, IDM_OBJECTUSEDLL, uTempD); CheckMenuItem(hMenu, IDM_OBJECTUSEEXE, uTempE);
CheckMenuItem(hMenu, IDM_ADVISEGETDATA, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ADVISEREPAINT, MF_UNCHECKED);
m_fGetData=FALSE; m_fRepaint=FALSE;
//Cannot request data using async advises, so disable these.
uTempE=m_fEXE ? MF_DISABLED | MF_GRAYED : MF_ENABLED; EnableMenuItem(hMenu, IDM_ADVISEGETDATA, uTempE); EnableMenuItem(hMenu, IDM_ADVISEREPAINT, uTempE); #endif /* NOT_SIMPLE */
return TRUE; }
/*
* CAppVars::TryQueryGetData * * Purpose: * Centralized function call and output code for displaying results * of various IDataObject::QueryGetData calls. * * Parameters: * pFE LPFORMATETC to test. * cf UINT specific clipboard format to stuff in pFE * before calling. If zero, use whatever is * already in pFE. * fExpect BOOL indicating expected results * y UINT line on which to print results. * * Return Value: * None */
void CAppVars::TryQueryGetData(LPFORMATETC pFE, UINT cf , BOOL fExpect, UINT y) { TCHAR szTemp[80]; LPTSTR psz1; LPTSTR psz2; UINT cch; HRESULT hr; HDC hDC;
if (0!=cf) pFE->cfFormat=cf;
hr=m_pIDataObject->QueryGetData(pFE); psz1=(NOERROR==hr) ? szSuccess : szFailed; psz2=((NOERROR==hr)==fExpect) ? szExpected : szUnexpected;
hDC=GetDC(m_hWnd); SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
if (CF_WAVE < cf || 0==cf) { cch=wsprintf(szTemp, TEXT("QueryGetData on %d %s (%s).") , cf, psz1, psz2); } else { cch=wsprintf(szTemp, TEXT("QueryGetData on %s %s (%s).") , (LPTSTR)rgszCF[cf], psz1, psz2); }
//Don't overwrite other painted display.
SetBkMode(hDC, TRANSPARENT); TextOut(hDC, 0, 16*y, szTemp, cch);
ReleaseDC(m_hWnd, hDC);
return; }
int CAppVars::m_GetData(WORD wID) { FORMATETC fe; HRESULT hr;
if (NULL == m_pIDataObject) return(0); // Don't redraw.
//Clean up whatever we currently have.
m_cfFormat = 0; ReleaseStgMedium(&m_stm);
switch (wID) { case IDM_OBJECTGETDATA_TEXT: SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL); break;
#ifdef NOT_SIMPLE
case IDM_OBJECTGETDATA_BITMAP: SETDefFormatEtc(fe, CF_BITMAP, TYMED_GDI); break;
case IDM_OBJECTGETDATA_METAFILEPICT: SETDefFormatEtc(fe, CF_METAFILEPICT, TYMED_MFPICT); break; #endif /* NOT_SIMPLE */
default: MessageBox(0, TEXT("Type is Unsupported in the Client"), TEXT("GetData"), MB_OK); return(0); }
m_swTimer.m_Start(); HRESULT didfail = NOERROR;
for(int i=0; i<m_cIterations; i++) { hr = m_pIDataObject->GetData(&fe, &m_stm); if (SUCCEEDED(hr)) { // If we are just whacking off for the benchmark.
// Then release all but the last one we recieve.
if(i < m_cIterations-1) ReleaseStgMedium(&m_stm); } else didfail = hr; } m_swTimer.m_Stop();
if (SUCCEEDED(didfail)) m_cfFormat=fe.cfFormat; else { perror_OKBox(0, TEXT("GetData Failed"), didfail); }
return(1); // Do redraw even if it failed (draw blank).
}
int CAppVars::m_GetDataHere(WORD wID) { FORMATETC fe; HRESULT hr;
if(NULL == m_pIDataObject) return(0); // Don't redraw
m_cfFormat = 0;
// Don't Release the STGMedium. We recycle them!
switch(wID) { case IDM_OBJECTGETDATAHERE_TEXT: SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL); break;
case IDM_OBJECTGETDATAHERE_NULLTEXT: SETDefFormatEtc(fe, CF_TEXT, TYMED_NULL); break;
/* Other cases go here.... */
default: MessageBox(0, TEXT("Type is Unsupported in the Client"), TEXT("GetDataHere"), MB_OK); return(0); }
HGLOBAL* phg = &m_hgHereBuffers[m_iDataSizeIndex]; if(NULL == *phg) { ++m_HereAllocCount; *phg = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, DATASIZE_FROM_INDEX(m_iDataSizeIndex) ); if(NULL == *phg) { MessageBox(0, TEXT("GlobalAlloc Return NULL"), TEXT("Failure"), MB_OK); PostQuitMessage(0); return(0); // Don't redraw
} }
m_stm.hGlobal=*phg; m_stm.tymed=TYMED_HGLOBAL; m_stm.pUnkForRelease=NULL;
// The TYMED_NULL case tests code in olethk where it is written:
// "If tymed == TYMED_NULL then GetDataHere should behave like GetData."
// I can't find this in any manual (OLE2 or Ole). I wanted to see what
// good that code was. (there is also bug #15974) Aug 8th 1995 BChapman.
if (IDM_OBJECTGETDATAHERE_NULLTEXT == wID) { m_stm.hGlobal=NULL; m_stm.tymed=TYMED_NULL; }
// The other side "knows" the size of the data.
// (It is told via. SetData)
HRESULT didfail = NOERROR; m_swTimer.m_Start(); for(int i=0; i<m_cIterations; i++) { hr = m_pIDataObject->GetDataHere(&fe, &m_stm); if (FAILED(hr)) didfail = hr; // We don't ReleaseSTGMedium because this
// is GetDataHere !
} m_swTimer.m_Stop();
if (SUCCEEDED(didfail)) m_cfFormat=fe.cfFormat; else { perror_OKBox(0, TEXT("GetDataHere Failed"), didfail); } return(1); // redraw (if FAILED(hr) then draw blank)
}
int CAppVars::m_SetData_SetSize(long iSizeIndex) { FORMATETC fe; HRESULT hr;
if (NULL == m_pIDataObject) return 0;
SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL);
m_iDataSizeIndex = iSizeIndex;
HGLOBAL hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(ULONG) ); if(NULL == hMem) { MessageBox(0, TEXT("GlobalAlloc Return NULL"), TEXT("Failure"), MB_OK); PostQuitMessage(0); return 0; }
long* pl=(long*)GlobalLock(hMem); // Lock
*((long*)pl) = DATASIZE_FROM_INDEX(m_iDataSizeIndex); GlobalUnlock(hMem); // Unlock
m_stm.hGlobal=hMem; m_stm.tymed=TYMED_HGLOBAL; m_stm.pUnkForRelease=NULL;
hr = m_pIDataObject->SetData(&fe, &m_stm, FALSE); // Keep Ownership.
if (FAILED(hr)) { perror_OKBox(0, TEXT("SetData Failed"), hr); return 0; } return 1;; // release the hMem HGLOBAL perhaps ???
}
int CAppVars::m_SetData_WithPUnk(WORD wID) { FORMATETC fe; HRESULT hr;
if(NULL == m_pIDataObject) return 0;
switch(wID) { case IDM_OBJECTSETDATAPUNK_TEXT: SETDefFormatEtc(fe, CF_TEXT, TYMED_HGLOBAL); break;
/* Other cases go here.... */
default: MessageBox(0, TEXT("Type is Unsupported in the Client"), TEXT("SetData"), MB_OK); return(0); }
HGLOBAL hMem=GlobalAlloc( GMEM_SHARE | GMEM_MOVEABLE, sizeof(ULONG) ); if(NULL == hMem) { MessageBox(0, TEXT("GlobalAlloc Return NULL"), TEXT("Failure"), MB_OK); PostQuitMessage(0); return 0; }
long* pl=(long*)GlobalLock(hMem); // Lock
*((long*)pl) = 0xffffffff; // Use
GlobalUnlock(hMem); // Unlock
m_stm.hGlobal=hMem; m_stm.tymed=TYMED_HGLOBAL; hr = GetStgMedpUnkForRelease(&m_stm.pUnkForRelease); if(NOERROR != hr) { perror_OKBox(0, TEXT("Can't get pUnk For Release"), hr); }
hr = m_pIDataObject->SetData(&fe, &m_stm, TRUE); // Pass Ownership.
// We passed ownership so SetData took the HGLOBAL from us.
if (FAILED(hr)) { perror_OKBox(0, TEXT("SetData Failed"), hr); return 0; } return 1; }
#define NUM_RUNS 5
void CAppVars::m_BatchToFile() { dataset_t dsGetDataText; dataset_t dsGetDataHereText;
pm_ClearDataset(&dsGetDataText); pm_ClearDataset(&dsGetDataHereText);
int iRun; for(iRun=0; iRun < NUM_RUNS; iRun++) { m_MeasureAllSizes(IDM_OBJECTGETDATA_TEXT, NULL, &dsGetDataText); m_MeasureAllSizes(IDM_OBJECTGETDATAHERE_TEXT, NULL, &dsGetDataHereText); }
FILE *fp; int i; if(NULL == (fp = fopen(FILENAME, "w"))) { MessageBox(0, TEXT("Cannot Open Output File"), TEXT(FILENAME), MB_OK | MB_ICONSTOP); return; }
fprintf(fp, " GetData w/ HGLOBAL GetDataHere w/ HGLOBAL\n"); fprintf(fp, " Size Best Worst Average Best Worst Average\n"); for (i=0; i<NUM_POINTS; i++) { fprintf(fp, "%5d\t", cKSizes[i]); #define PR_TIME(fp, v) (fprintf(fp, "%3lu.%03lu\t", (v)/1000, (v)%1000))
PR_TIME(fp, dsGetDataText.cBest[i]); PR_TIME(fp, dsGetDataText.cWorst[i]); PR_TIME(fp, dsGetDataText.cTotal[i]/NUM_RUNS); PR_TIME(fp, dsGetDataHereText.cBest[i]); PR_TIME(fp, dsGetDataHereText.cWorst[i]); PR_TIME(fp, dsGetDataHereText.cTotal[i]/NUM_RUNS); fprintf(fp, "\n"); } fclose(fp);
MessageBox(0, TEXT("Output Written to file.dat!"), TEXT("Done"), MB_OK); }
void CAppVars::pm_ClearDataset(dataset_t *ds) { int i; for(i=0; i<NUM_POINTS; i++) { ds->cTotal[i] = 0; ds->cBest[i] = 0xFFFFFFFF; ds->cWorst[i] = 0; } }
void CAppVars::m_MeasureAllSizes( WORD wID, LPTSTR tstrTitle, dataset_t *ds) { int i; ULONG cUSecs[NUM_POINTS];
// Save some state.
ULONG iOldDataSizeIndex = m_iDataSizeIndex;
for (i=0; i<NUM_POINTS; i++) { m_SetData_SetSize(cKSizes[i]);
switch(wID) { case IDM_OBJECTGETDATA_TEXT: case IDM_OBJECTGETDATA_BITMAP: m_GetData(wID); break;
case IDM_OBJECTGETDATAHERE_TEXT: case IDM_OBJECTGETDATAHERE_BITMAP: m_GetDataHere(wID); break; } m_swTimer.m_Read(&cUSecs[i]); cUSecs[i] /= m_cIterations; }
// Restore save state.
m_iDataSizeIndex = iOldDataSizeIndex; m_SetData_SetSize(m_iDataSizeIndex);
// If the caller provided memory then return the data in it.
if(NULL != ds) { for (i=0; i<NUM_POINTS; i++) { ds->cData[i] = cUSecs[i]; ds->cTotal[i] += cUSecs[i];
if(ds->cBest[i] > cUSecs[i]) ds->cBest[i] = cUSecs[i]; if( ds->cWorst[i] < cUSecs[i]) ds->cWorst[i] = cUSecs[i]; } }
// If the caller passed a NULL Title then no message box.
if(NULL == tstrTitle) return;
// Render Results.
LPTSTR tstr = &tcMessageBuf[0]; for (i=0; i<NUM_POINTS; i++) { wsprintf(tstr, TEXT("%dK: %lu.%03lu%c"), cKSizes[i], cUSecs[i]/1000, cUSecs[i]%1000, (i%4==3)? TEXT('\n'):TEXT('\t') ); tstr += lstrlen(tstr); } MessageBox(0, tcMessageBuf, tstrTitle, MB_OK); }
void CAppVars::m_SetMeasurement(WORD wID) { HMENU hMenu=GetMenu(m_hWnd); switch (wID) { case IDM_MEASUREMENT_ON: m_fDisplayTime = TRUE; CheckMenuItem(hMenu, IDM_MEASUREMENT_ON, MF_CHECKED); CheckMenuItem(hMenu, IDM_MEASUREMENT_OFF, MF_UNCHECKED); break;
case IDM_MEASUREMENT_OFF: m_fDisplayTime = FALSE; CheckMenuItem(hMenu, IDM_MEASUREMENT_ON, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_MEASUREMENT_OFF, MF_CHECKED); break;
case IDM_MEASUREMENT_1: m_cIterations = 1; goto set_menu; case IDM_MEASUREMENT_50: m_cIterations = 50; goto set_menu; case IDM_MEASUREMENT_300: m_cIterations = 300; goto set_menu; set_menu: CheckMenuItem(hMenu, IDM_MEASUREMENT_1, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_MEASUREMENT_50, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_MEASUREMENT_300, MF_UNCHECKED); CheckMenuItem(hMenu, wID, MF_CHECKED); break;
case IDM_MEASUREMENT_TEST: m_swTimer.m_Start(); m_swTimer.m_Sleep(777); m_swTimer.m_Stop(); m_DisplayTimerResults(); break; } }
void CAppVars::m_DisplayTimerResults() { ULONG usecs; m_swTimer.m_Read(&usecs); usecs /= m_cIterations; wprintf_OKBox(0, TEXT("MilliSeconds"), TEXT("%lu.%03lu"), usecs/1000, usecs%1000); }
/*
* CAppVars::Paint * * Purpose: * Handles WM_PAINT for the main window by drawing whatever * data we have sitting in the STGMEDIUM at this time. * * Parameters: * None * * Return Value: * None */
void CAppVars::Paint(void) { PAINTSTRUCT ps; HDC hDC; #ifdef NOT_SIMPLE
HDC hMemDC; LPMETAFILEPICT pMF; #endif /* NOT_SIMPLE */
LPTSTR psz; RECT rc; FORMATETC fe;
GetClientRect(m_hWnd, &rc);
hDC=BeginPaint(m_hWnd, &ps);
//May need to retrieve the data with EXE objects
#ifdef NOT_SIMPLE
if (m_fEXE) { if (TYMED_NULL==m_stm.tymed && 0!=m_cfFormat) { SETDefFormatEtc(fe, m_cfFormat, TYMED_HGLOBAL | TYMED_MFPICT | TYMED_GDI);
if (NULL!=m_pIDataObject) m_pIDataObject->GetData(&fe, &m_stm); } } #endif /* NOT_SIMPLE */
switch (m_cfFormat) { case CF_TEXT: psz=(LPTSTR)GlobalLock(m_stm.hGlobal);
if (NULL==psz) break;
SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
pm_DrawText(hDC, psz, &rc, DT_LEFT | DT_WORDBREAK);
GlobalUnlock(m_stm.hGlobal); break;
#ifdef NOT_SIMPLE
case CF_BITMAP: hMemDC=CreateCompatibleDC(hDC);
if (NULL!=SelectObject(hMemDC, (HGDIOBJ)m_stm.hGlobal)) { BitBlt(hDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top , hMemDC, 0, 0, SRCCOPY); }
DeleteDC(hMemDC); break;
case CF_METAFILEPICT: pMF=(LPMETAFILEPICT)GlobalLock(m_stm.hGlobal);
if (NULL==pMF) break;
SetMapMode(hDC, pMF->mm); SetWindowOrgEx(hDC, 0, 0, NULL); SetWindowExtEx(hDC, pMF->xExt, pMF->yExt, NULL);
SetViewportExtEx(hDC, rc.right-rc.left , rc.bottom-rc.top, NULL);
PlayMetaFile(hDC, pMF->hMF); GlobalUnlock(m_stm.hGlobal); break;
#else /* IS SIMPLE */
case CF_BITMAP: case CF_METAFILEPICT: DebugBreak(); break;
#endif /* NOT_SIMPLE */
default: break; }
EndPaint(m_hWnd, &ps); return; }
void CAppVars::pm_DrawText( HDC hDC, LPTSTR psz, RECT* prc, UINT flags) { SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
// If we are WIN32 and the server is 16 bits this must be ASCII.
#ifdef WIN32
if(m_f16Bit) DrawTextA(hDC, (char*)psz, -1, prc, flags); else #endif
DrawText(hDC, psz, -1, prc, flags); }
|