Miscellaneous
Exontrol.COM Software - Miscellaneous
VB.1:
The article ACC2000, How to convert Twips to Pixels, explains what you have to do. Anyway, here's the Twips2Pixels function that converts X and Y twips coordinates to pixels coordinates.
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90

' Converts twips corrdinates to pixels coordinates
Private Sub Twips2Pixels(X As Long, Y As Long)
    Dim hDC As Long
    hDC = GetDC(0)
    X = X / 1440 * GetDeviceCaps(hDC, LOGPIXELSX)
    Y = Y / 1440 * GetDeviceCaps(hDC, LOGPIXELSY)
    ReleaseDC 0, hDC
End Sub
VB.2:
If you feel that a window is flickering while you are updating a control, you can use the showWindow function described bellow. The function hides the window, but do not reflect the changes ( in the container window ) until you show again the window. The function uses the SetWindowPos API function. There is a LockWindow API function, but it locks only a single window at a time.
' We need SetWindowPos API
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_FRAMECHANGED = &H20
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOREDRAW = &H8
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOZORDER = &H4
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_HIDEWINDOW = &H80

Private Sub showWindow(ByVal h As Long, ByVal bShow As Boolean)
    If (Not bShow) Then
        SetWindowPos h, 0, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_HIDEWINDOW Or SWP_NOREDRAW
    Else
        SetWindowPos h, 0, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_SHOWWINDOW Or SWP_FRAMECHANGED
    End If
End Sub

Sample:
showWindow List1.hwnd, False
With List1
    .BeginUpdate
    With .Items
        .Add "Item 1"
        .Add "Item 2"
        .............
        .Add "Item n"
    End With
    .EndUpdate
End With
showWindow List1.hwnd, True
VB.3:
Using a layered window can significantly improve performance and visual effects for a window that has a complex shape, animates its shape, or wishes to use alpha blending effects:
Private Declare Function SetLayeredWindowAttributes Lib "user32.dll" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Boolean  
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long  
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long  
Const LWA_ALPHA = 2  
Const GWL_EXSTYLE = (-20)  
Const WS_EX_LAYERED = &H80000  

Private Sub Form_Load()  
    SetWindowLong hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) Or WS_EX_LAYERED  
    SetLayeredWindowAttributes hwnd, 0, 128, LWA_ALPHA  
End Sub 
VB.4:
The following sample runs un Windows NT, 2000 or XP. The sample prints each process and its modules:
Option Explicit
Private Declare Function EnumProcesses Lib "psapi" (lpIdProcess As Any, ByVal cb As Long, cbNeeded As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_READ = 16

Private Sub Form_Load()
    EnumP
End Sub

Private Function onEnumM(ByVal strModule As String, ByVal asProcess As Boolean) As Boolean
    onEnumM = True
    If (Not asProcess) Then
        strModule = "    " & strModule
    End If
    Debug.Print strModule
End Function


Private Function EnumP() As Boolean

    Dim idProcess() As Long
    Dim cb As Long, I As Long

    cb = 16
    Do
        ReDim idProcess(0 To cb - 1) As Long
        If EnumProcesses(idProcess(0), cb * 4, I) = 0 Then Exit Function
        If I < cb * 4 Then
            ReDim idProcess(0 To (I / 4) - 1) As Long
            EnumProcesses idProcess(0), cb * 4, I
            Exit Do
        End If
        cb = cb * 2
    Loop
    
    Dim bResult As Boolean
    bResult = True
    For I = LBound(idProcess) To UBound(idProcess)
        Dim h As Long
        h = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, idProcess(I))
        If (h <> 0) Then
            bResult = EnumM(h)
            CloseHandle h
            If (Not bResult) Then Exit For
        End If
    Next
    EnumP = bResult
End Function

Private Function EnumM(ByVal hProcess As Long) As Boolean

    Dim hModule() As Long
    Dim cb As Long, I As Long
    
    ' If the cb is grather than 1 the procedure gets all modules of the process
    cb = 2
    Do
        ReDim hModule(0 To cb - 1) As Long
        If EnumProcessModules(hProcess, hModule(0), cb * 4, I) = 0 Then
            EnumM = True
            Exit Function
        End If
        If (cb = 1) Then Exit Do
        If I < cb * 4 Then
            ReDim hModule(0 To (I / 4) - 1) As Long
            EnumProcessModules hProcess, hModule(0), cb * 4, I
            Exit Do
        End If
        cb = cb * 2
    Loop
    
    For I = LBound(hModule) To UBound(hModule)
        Dim s As String
        s = String(1024, " ")
        s = Mid(s, 1, GetModuleFileNameExA(hProcess, hModule(I), s, 1024))
        If (Not onEnumM(s, I = LBound(hModule))) Then
            EnumM = False
            Exit Function
        End If
    Next
    EnumM = True
End Function
VB.5:
The following sample displays the "My Computer" view:
Private Sub Form_Load()
    Dim b As Object
    Set b = Controls.Add("Shell.Explorer", "Browser", Me)
    b.Object.Navigate2 "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
    b.Visible = True
End Sub
VB.6:
The following sample loads a HTML string into a WebBrowser control:
Private Sub loadHTML(ByVal sHTML As String)
    With WebBrowser1
        .Navigate "about:blank"
        DoEvents
        .Document.write sHTML
    End With
End Sub
C++.1:
Here's MFC based tool, that's easy and free. All that you need to do is to run the "lines.exe" file and to drag files/folders to the right-side list box control. If you drag a folder the control enumerates all files recursively. Change the extension masks to count only the files that you are interested into. Click here to download the VC project.
C++.2:
The following function loads the RT_VERSION data and looks for the file version:
STDMETHODIMP get_Version(BSTR *pVal)
{
	if ( pVal )
	{
		*pVal = NULL;
		if ( HRSRC hVersion = FindResource( _Module.GetResourceInstance(), MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION ) )
			if ( HGLOBAL hGlobal = LoadResource( _Module.GetResourceInstance(), hVersion ) )
			{
				WORD* pVersionInfo = (WORD*)LockResource( hGlobal );
				DWORD* p = (DWORD*)pVersionInfo;
				// Looks for the Value signature: 0xFEEF04BD
				for ( int i = 0; i < (*pVersionInfo) / 2; i++, p++ )
					if ( *p  == 0xFEEF04BD )
					{
						// Jumps the signature and the structure version fields.
						p += 2;
						DWORD dwMS = *p++, dwLS = *p;
						TCHAR szVersion[1024] = _T("");
						wsprintf( szVersion, "%i.%i.%i.%i", HIWORD( dwMS ), LOWORD(dwMS), HIWORD( dwLS ), LOWORD( dwLS ) );
						*pVal = A2BSTR( szVersion );
						break;
					}
				UnlockResource( hGlobal );
				FreeResource( hGlobal );
			}
		return S_OK;
	}
	return E_POINTER;
}
C++.3:
The following function fills a rectangle using a transparent color : 
void FillRectTransparent( HDC hDC, RECT rtClient, COLORREF rgbColor )
{
	if ( HDC hDCMem = CreateCompatibleDC( hDC ) )
	{
		long cx = rtClient.right - rtClient.left, cy = rtClient.bottom - rtClient.top;
		RECT rtMemClient = rtClient; OffsetRect( &rtMemClient, -rtClient.left, -rtClient.top );
		if ( HBITMAP hBitmap = CreateCompatibleBitmap( hDC, cx, cy ) )
		{
			CGDIBrush brush( rgbColor );
			HBITMAP hOldBitmap = (HBITMAP)::SelectObject( hDCMem, hBitmap );
			FillRect( hDCMem, &rtMemClient, brush.m_hBrush );
			BitBlt( hDC, rtClient.left, rtClient.top, cx, cy, hDCMem, 0, 0, SRCAND );
			::SelectObject( hDCMem, hOldBitmap );
			DeleteObject( hBitmap );
		}
		DeleteDC( hDCMem );
	}
}
C++.4:
The following sample uses the IShellLink interface to create a shortcut file: 
TCHAR* szShortCut = _T("c:\winnt\\calc.exe");
string strLinkFile = _T("c:\\temp\\calc.lnk");
CComPtr<IShellLink> spShellLink;
CoInitialize( NULL );
if ( SUCCEEDED( CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&spShellLink ) ) )
{
	spShellLink->SetPath( szShortCut );
	if ( CComQIPtr<IPersistFile> spFile(spShellLink) )
	{
		USES_CONVERSION;
		spFile->Save( T2OLE(strLinkFile.c_str()), TRUE );
	}
}
CoUninitialize();
C++.5:
The following samples show how to let user moves the dialog by clicking anywhere in the dialog:
void CXdDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, NULL );
	
	CDialog::OnLButtonDown(nFlags, point);
}

void CXdDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	PostMessage( WM_SYSCOMMAND, SC_MOVE , NULL );
	
	CDialog::OnLButtonDown(nFlags, point);
}
C++.6:
You can handle the WM_ERASEBKGND or WM_CTLCOLORDLG message:
...
MESSAGE_HANDLER(WM_CTLCOLORDLG, OnCtlColorDlg)
...

 LRESULT OnCtlColorDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
 {
  return (LRESULT)GetSysColorBrush( COLOR_WINDOW );
 }

...
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd)
...

 LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
 {
  HDC hDC = (HDC)wParam;
  RECT rtClient = {0}; GetClipBox( hDC, &rtClient );
  FillRect( hDC, &rtClient, GetSysColorBrush( COLOR_WINDOW )) ;
  return TRUE;
 }
C++.7:
The VariantChangeType API function  converts a VARIANT from one type to another. The following sample uses CComVariant class to convert a VARIANT to a string: 
static string V2S( VARIANT* pv, LPCTSTR szDefault = _T("") )
{
	if ( pv )
	{
		if ( pv->vt == VT_ERROR )
			return szDefault;

		CComVariant vt;
		if ( SUCCEEDED( vt.ChangeType( VT_BSTR, pv ) ) )
		{
			USES_CONVERSION;
			return OLE2T(V_BSTR( &vt ));
		}
	}
	return szDefault;
}
C++.8:
To find out the interfaces that a COM object implements, you have to query the object for all registered interfaces. The windows registry holds all known interfaces in the HKCR\Interfaces registry key. The QI::MsgBox( yourCOMObject ) displays a list of interfaces implemented by the passed object  :
#include <atlbase.h>
#include <string>
#include <sstream>
class QI : protected CRegKey,
#ifdef _UNICODE
	public std::wstringstream
#else
	public std::stringstream
#endif
{
protected:
	virtual tstring Query( IUnknown* pUnk )
	{
		if ( pUnk != NULL && ( ERROR_SUCCESS == Open( HKEY_CLASSES_ROOT, _T("Interface") ) ) )
		{
			TCHAR szKeyName[1024] = _T("");
			for ( int i = 0; ERROR_SUCCESS == RegEnumKey( m_hKey, i, szKeyName, 1024 ); i++ )
			{
				USES_CONVERSION;
				CLSID clsID = CLSID_NULL;
				if ( SUCCEEDED( CLSIDFromString( T2OLE(szKeyName), &clsID ) ) )
				{
					CComPtr<IUnknown> spObject = NULL;
					if ( SUCCEEDED( pUnk->QueryInterface( clsID, (void**)&spObject ) ) )
					{
						TCHAR szValue[1024] = _T(""); LONG ncbValue = 1024;
						if ( ERROR_SUCCESS == RegQueryValue( m_hKey, szKeyName, szValue, &ncbValue ) )
							*this << tstring(szValue) + _T("\r\n");
					}
				}
			}
			Close();
		}
		return str();
	}

public:
	static void MsgBox( IUnknown* pUnk )
	{
		QI objQI;
		MessageBox( NULL, objQI.Query( pUnk ).c_str(), _T("The object implements:"), MB_ICONINFORMATION );
	}
};
C++.9:
A picture object implements this interface along with IPicture to provide access to the picture's properties through Automation. The following function loads a picture for a file:
BOOL LoadPicture( LPCTSTR szFileName, IPictureDisp** ppPictureDisp )
{
	BOOL bResult = FALSE;
	if ( szFileName )
	{
		OFSTRUCT of;
		HANDLE hFile = NULL;;
#ifdef _UNICODE
		USES_CONVERSION;
		if ( (hFile = (HANDLE)OpenFile( W2A(szFileName), &of, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR )
#else
		if ( (hFile = (HANDLE)OpenFile( szFileName, &of, OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR )
#endif
		{
			*ppPictureDisp = NULL;
			DWORD dwHighWord = NULL, dwSizeLow = GetFileSize( hFile, &dwHighWord );
			DWORD dwFileSize = dwSizeLow;
			HRESULT hResult = NULL;
			if ( HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize) )
				if ( void* pvData = GlobalLock( hGlobal ) )
				{
					DWORD dwReadBytes = NULL;
					BOOL bRead = ReadFile( hFile, pvData, dwFileSize, &dwReadBytes, NULL );
					GlobalUnlock( hGlobal );
					if ( bRead )
					{
						CComPtr spStream;
						_ASSERTE( dwFileSize == dwReadBytes );
						if ( SUCCEEDED( CreateStreamOnHGlobal( hGlobal, TRUE, &spStream) ) )
							if ( SUCCEEDED( hResult = OleLoadPicture( spStream, 0, FALSE, IID_IPictureDisp, (void**)ppPictureDisp ) ) )
								bResult = TRUE;
					}
				}
			CloseHandle( hFile );
		}
	}
	return bResult;
}
C++.10:
A picture object implements this interface along with IPicture to provide access to the picture's properties through Automation. The following function loads a picture for a application's resource:
ULONG CreateStream(const char *ResourceType, const char *ResourceName, IStream **ppStream)
{
	BOOL bResult = FALSE;
	DWORD dwSize = NULL;
#ifdef _ATL
	HMODULE hInstance = _Module.GetModuleInstance();
#else
	HMODULE hInstance = AfxGetResourceHandle();
#endif 
	if ( HRSRC hResource = FindResource( hInstance, ResourceName, ResourceType ) )
		if (HGLOBAL hGlobal = LoadResource( hInstance, hResource ))
		{
			if ( HGLOBAL hGlobalStream = GlobalAlloc(GMEM_MOVEABLE, dwSize = SizeofResource( hInstance, hResource ) ) )
			{
				memcpy( GlobalLock( hGlobalStream ), LockResource( hGlobal ), dwSize );
				GlobalUnlock( hGlobalStream );
				if ( SUCCEEDED( CreateStreamOnHGlobal( hGlobalStream, TRUE, ppStream ) ) )
					bResult = TRUE;
			}
			FreeResource( hResource );
		}
	return bResult ? dwSize : 0;
}

IStream* pStream = NULL;
if ( CreateStream( "JPG", MAKEINTRESOURCE( IDR_EXONTROL ), &pStream ) )
{
	IPictureDisp* pPictureDisp = NULL;
	if ( SUCCEEDED( OleLoadPicture( pStream, NULL, FALSE, IID_IPictureDisp, (LPVOID*)&pPictureDisp ) ) )
	{
		.........................
		pPictureDisp->Release();
	}
	pStream->Release();
}
C++.11:
The DrawPicture method takes a IPictureDisp pointer, and paints the picture to give device context :
void DrawPicture( IPictureDisp* pPictureDisp, HDC hDC, RECT rDraw )
{
	if ( CComQIPtr<spPicture>( pPictureDisp ) )
	{
		SIZEL src = {0,0}, srcExtent = { NULL, NULL };
		spPicture->get_Width( (OLE_XSIZE_HIMETRIC*)&srcExtent.cx ) ; spPicture->get_Height( (OLE_YSIZE_HIMETRIC*)&srcExtent.cy );
		SIZEL extent = srcExtent;
		AtlHiMetricToPixel( &srcExtent, &extent );
		spPicture->Render( hDC, rDraw.left, rDraw.top, RectWidth(&rDraw), RectHeight(&rDraw), src.cx , srcExtent.cy - src.cy, srcExtent.cx, -srcExtent.cy, NULL );
	}
}
C++.12:
The following two functions helps you to draw a bitmap using a transparent color.
void BitBltTransparent( HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, COLORREF colorTransaparent)
{
	if (HDC hdcMask = ::CreateCompatibleDC(hdcDest))
	{
		HBITMAP hBitmap = CreateBitmap( nWidth, nHeight, 1, 1, NULL );
		HBITMAP hdcMaskBitmap = (HBITMAP)::SelectObject( hdcMask, hBitmap );
		::SetBkColor( hdcSrc, colorTransaparent );
		::BitBlt( hdcMask, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
		::SetBkColor( hdcSrc, NULL );
		::SetTextColor( hdcSrc, RGB(255,255,255) );
		::BitBlt( hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcMask, 0,0, SRCAND );
		::SetBkColor( hdcDest, RGB(255,255,255) );
		::SetTextColor( hdcDest, NULL );
		::BitBlt( hdcDest, nXDest, nYDest, nWidth, nHeight, hdcMask, 0,0, SRCAND );
		::BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCPAINT);
		::SelectObject( hdcMask, hdcMaskBitmap );
		DeleteDC( hdcMask );
		DeleteObject( hBitmap );
	}
};

void BitBltTransparent( HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc, COLORREF colorTransaparent )
{
	if ( hBitmap )
	{
		HDC hDCBitmap = CreateCompatibleDC( hdcDest );
		HBITMAP hOldBitmap = (HBITMAP)::SelectObject( hDCBitmap, hBitmap );
		HDC hdcCopy = CreateCompatibleDC( hdcDest );
		HBITMAP hBitmapCopy = CreateCompatibleBitmap( hdcDest, nWidth, nHeight );
		HBITMAP hBitmapCopy2 = (HBITMAP)::SelectObject( hdcCopy, hBitmapCopy );
		::BitBlt( hdcCopy, 0, 0, nWidth, nHeight, hDCBitmap, nXSrc, nYSrc, SRCCOPY );
		BitBltTransparent( hdcDest, nXDest, nYDest, nWidth, nHeight, hdcCopy, 0, 0, colorTransaparent );
		::SelectObject( hdcCopy, hBitmapCopy2 );
		::SelectObject( hDCBitmap, hOldBitmap );
		::DeleteObject( hBitmapCopy );
		::DeleteDC( hdcCopy );
		::DeleteDC( hDCBitmap );
	}
}
C++.13:
Here's the definition for CAxWnd window that implements a light but powerful container that hosts a control using IClassFactory or IClassFactory2 interfaces.
class CAxWnd :  public IDispatch,
		public IOleClientSite,
		public IOleInPlaceSite,
		public IOleInPlaceFrame,
		public CWindowImpl

{
public:
	typedef void (CALLBACK *ONEVENT)( LPARAM lParam, DISPID event, DISPPARAMS* pParameters );

	class CAxEvents : public IDispatch
	{
	public:

		CAxEvents(CAxWnd* pWnd) : m_pWnd( pWnd )
		{
			m_dwRef = 0; // reset the counter
		};
		virtual ~CAxEvents()
		{
		};

		// IUnknown
		STDMETHOD(QueryInterface)( REFIID riid, void* *ppvObject);
		STDMETHOD_(ULONG, AddRef)( void );
		STDMETHOD_(ULONG, Release)( void );

		// IDispacth
		STDMETHOD(GetTypeInfoCount)( UINT * pctinfo);
		STDMETHOD(GetTypeInfo)( UINT iTInfo, LCID lcid, ITypeInfo* *ppTInfo);
		STDMETHOD(GetIDsOfNames)( REFIID riid, LPOLESTR  *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId );
		STDMETHOD(Invoke)( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS  *pDispParams, VARIANT  *pVarResult, EXCEPINFO  *pExcepInfo, UINT  *puArgErr);

	protected:
		// Attributes
		CAxWnd* m_pWnd;
		ULONG m_dwRef;
	};

protected:
	CAxWnd( ONEVENT onEvent = NULL, LPARAM lParam = NULL );
	virtual ~CAxWnd();

public:
	DECLARE_WND_CLASS( _T("AxWnd") ) 

	BEGIN_MSG_MAP(CAxWnd)
		MESSAGE_HANDLER(WM_CREATE, onCreate)
		MESSAGE_HANDLER(WM_DESTROY, onDestroy)
		MESSAGE_HANDLER(WM_SIZE, onSize)
	END_MSG_MAP()

//IUnknown
    STDMETHOD(QueryInterface)( REFIID riid, void* *ppvObject );
    STDMETHOD_(ULONG,AddRef)(void);
	STDMETHOD_(ULONG,Release)(void);

// IDispatch
    STDMETHOD(GetTypeInfoCount)(  UINT * pctinfo);
    STDMETHOD(GetTypeInfo)(  UINT iTInfo,  LCID lcid,  ITypeInfo* *ppTInfo);
    STDMETHOD(GetIDsOfNames)(  REFIID riid, LPOLESTR  *rgszNames,  UINT cNames,  LCID lcid, DISPID *rgDispId);
    STDMETHOD(Invoke)( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS  *pDispParams, VARIANT  *pVarResult, EXCEPINFO  *pExcepInfo, UINT  *puArgErr);

//IOleClientSite
    STDMETHOD(SaveObject)( void );
    STDMETHOD(GetMoniker)( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker  * *ppmk);
	STDMETHOD(GetContainer)( IOleContainer** ppContainer);
	STDMETHOD(ShowObject)( void );
    STDMETHOD(OnShowWindow)( BOOL fShow);
    STDMETHOD(RequestNewObjectLayout)( void );

//IOleInPlaceSite
    STDMETHOD(CanInPlaceActivate)(void);
    STDMETHOD(OnInPlaceActivate)(void);
    STDMETHOD(OnUIActivate)(void);
    STDMETHOD(GetWindowContext)( IOleInPlaceFrame* *ppFrame, IOleInPlaceUIWindow* *ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo);
    STDMETHOD(Scroll)(  SIZE scrollExtant);
    STDMETHOD(OnUIDeactivate)(  BOOL fUndoable);
    STDMETHOD(OnInPlaceDeactivate)(void);
    STDMETHOD(DiscardUndoState)(void);
    STDMETHOD(DeactivateAndUndo)(void );
    STDMETHOD(OnPosRectChange)(  LPCRECT lprcPosRect );

//IOleInPlaceUIWindow
    STDMETHOD(GetBorder)( LPRECT lprectBorder);
    STDMETHOD(RequestBorderSpace)( LPCBORDERWIDTHS pborderwidths);
    STDMETHOD(SetBorderSpace)( LPCBORDERWIDTHS pborderwidths);
    STDMETHOD(SetActiveObject)( IOleInPlaceActiveObject* pActiveObject, LPCOLESTR pszObjName);

//IOleInPlaceFrame
    STDMETHOD(InsertMenus)( HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
    STDMETHOD(SetMenu)( HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject);
    STDMETHOD(RemoveMenus)( HMENU hmenuShared);
    STDMETHOD(SetStatusText)( LPCOLESTR pszStatusText);
    STDMETHOD(EnableModeless)( BOOL fEnable);
    STDMETHOD(TranslateAccelerator)( LPMSG lpmsg, WORD wID);

//IOleWindow
    STDMETHOD(GetWindow)(  HWND* phwnd);
    STDMETHOD(ContextSensitiveHelp)(  BOOL fEnterMode);


public:
	// Operations
	static HRESULT AxCreateControl( HWND hWndParent, RECT rtPos, BSTR strProgID, BSTR strLicense = NULL, LPARAM lParam = NULL, ONEVENT onEvent = NULL, CAxWnd** ppAxWnd = NULL );
	virtual IDispatch* GetControl();

	// Attributes
	GUID				m_iidEvent;
	ONEVENT				m_onEvent;
	LPARAM				m_lParam;
protected:

	// Message handlers
	virtual void show();
	virtual void hide();
	virtual LRESULT onCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	virtual LRESULT onDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	virtual LRESULT onSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	virtual void OnFinalMessage(HWND /*hWnd*/);
	virtual void term();
	virtual void initEvents();
	virtual void termEvents();
	virtual HRESULT init( BSTR strProgID, BSTR strLicense );
	static GUID	iidEvents( IOleObject* pOleObject );

	// Attributes
	CComBSTR			m_strProgID;
	CComBSTR			m_strLicense;
	CComPtr				m_spControl;
	CComPtr 			m_spOleObject;
	int				m_dwRef;
	BOOL				m_bVisible;
	unsigned long			m_dwObjectStatus;
	RECT				m_rcPos;
	CAxEvents*			m_pAxEvents;
	DWORD				m_dwCookie;
	static	int			m_nInstances;

};
C++.14:
The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect function. The following function forces WM_PAINT message to be processed:
void WaitToValidate( HWND hWnd )
{
	MSG msg = {0};
	while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
	{
		if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
			return;
		DispatchMessage(&msg);
	}
}
C++.15:
You can use the following function to check your pointer:
BOOL IsValidAddress(const void* lp, UINT nBytes, BOOL bReadWrite)
{
	return (lp != NULL && !::IsBadReadPtr(lp, nBytes) &&
		(!bReadWrite || !::IsBadWritePtr((LPVOID)lp, nBytes)));
}
C++.16:
The CoCreateInstance creates a single uninitialized object of the class associated with a specified CLSID. The following sample takes the control's identifier and creates an object instance. The sample doesn't use CoCreateInstance method. 
#include "stdafx.h"
#include <windows.h>
#include <atlbase.h>

typedef HRESULT (CALLBACK *DLLGETCLASSOBJECT)(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
// Function name	: MyCreateInstance
// Description	    : Creates an object based on its identifier.
// Return type		: HRESULT 
// Argument         : LPCTSTR szObjectID
// Argument         : IUnknown** ppObject
HRESULT MyCreateInstance( LPCTSTR szObjectID, IUnknown** ppObject )
{
	HRESULT hResult = E_POINTER;
	if ( ppObject )
	{
		*ppObject = NULL;
		USES_CONVERSION;
		CLSID clsid = CLSID_NULL;
		if ( SUCCEEDED( hResult = CLSIDFromProgID( T2OLE( szObjectID ), &clsid ) ) )
		{
			BSTR strObjectCLSID = NULL;
			if ( SUCCEEDED( StringFromCLSID( clsid, &strObjectCLSID ) ) )
			{
				TCHAR szModule[1024] = _T("");
				TCHAR szInprocServer[1024] = _T("");
				wsprintf( szInprocServer, _T("CLSID\\%s\\InprocServer32"), OLE2T( strObjectCLSID ) );
				CRegKey key;
				if ( ERROR_SUCCESS == key.Open( HKEY_CLASSES_ROOT, szInprocServer , KEY_READ ) )
				{
					DWORD dwCount = 1024;
					if ( ERROR_SUCCESS == key.QueryValue( szModule, _T(""), &dwCount ) )
					{
						if ( HMODULE h = LoadLibrary( szModule ) )
						{
							if ( DLLGETCLASSOBJECT s = (DLLGETCLASSOBJECT)GetProcAddress( h, "DllGetClassObject" ) )
							{
								CComPtr<IClassFactory> spFactory;
								if ( SUCCEEDED( hResult = (s)( clsid, IID_IClassFactory, (LPVOID*) &spFactory ) ) )
									hResult = spFactory->CreateInstance( NULL, IID_IUnknown, (LPVOID*)ppObject );
							}
							FreeLibrary( h );
						}
					}
				}
				CoTaskMemFree( strObjectCLSID );
			}
		}
	}
	return hResult;
}

int main(int argc, char* argv[])
{
	CoInitialize( NULL );
	CComPtr<IUnknown> spObject;
	HRESULT hResult = MyCreateInstance( _T("Exontrol.Grid"), &spObject );
	CoUninitialize();
	return 0;
}
C++.17:
The Clipboard2Variant method copies the content of the clipboard to a Variant. 
// Function name	: Clipboard2Variant
// Description	    : Retrieves the content of Clipboard to the pvtValue
// Return type		: HRESULT 
// Argument         : VARIANT* pvtValue
HRESULT Clipboard2Variant( VARIANT* pvtValue )
{
	CComPtr<IDataObject> spDataObject;
	HRESULT hResult = E_POINTER;
	if ( pvtValue )
	{
		USES_CONVERSION;
		VariantClear( pvtValue );
		if ( SUCCEEDED( hResult = OleGetClipboard( &spDataObject ) ) )
		{
			// We are looking for Text
			FORMATETC fetcText				= { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
			FORMATETC fetcObjectDescriptor	= { cfObjectDescriptor, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
			FORMATETC fetcEmbeddedObject	= { cfEmbeddedObject, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE };
			FORMATETC fetcEmbedSource		= { cfEmbedSource, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE };
			STGMEDIUM stgText;

			if ( !IsClipboardFormatAvailable( fetcObjectDescriptor.cfFormat ) )
				if ( SUCCEEDED( hResult = spDataObject->GetData( &fetcText, &stgText ) ) )
				{
					pvtValue->vt = VT_BSTR;
					pvtValue->bstrVal = ::SysAllocString( T2OLE( (LPTSTR)GlobalLock( stgText.hGlobal ) ) );
					GlobalUnlock( stgText.hGlobal );
					ReleaseStgMedium( &stgText );
					return hResult;
				};
			
			// We are looking for Object Descriptor
			STGMEDIUM stgObjectDescriptor;
			if ( SUCCEEDED( hResult = spDataObject->GetData( &fetcObjectDescriptor, &stgObjectDescriptor ) ) )
			{
				HGLOBAL hGlobalObjectDescriptor = stgObjectDescriptor.hGlobal;
				if ( OBJECTDESCRIPTOR* pObjectDescriptor = (OBJECTDESCRIPTOR*)GlobalLock( hGlobalObjectDescriptor ) )
				{
					BSTR bstrProgID = NULL;
					if ( SUCCEEDED( hResult = ProgIDFromCLSID( pObjectDescriptor->clsid, &bstrProgID ) ) )
					{
						OLEObjectHeader oleObjectHeader;
						 oleObjectHeader.strObjectClass = OLE2T(bstrProgID);
						 oleObjectHeader.strObjectName = W2T((unsigned short*)((BYTE*)pObjectDescriptor + pObjectDescriptor->dwFullUserTypeName ));
						
						 // We are looking for Object Storage;
						 // There are two possibilties: Embed Source or Embedded Object.
						 
						STGMEDIUM stgEmbed;
						if ( SUCCEEDED( hResult = spDataObject->GetData( &fetcEmbeddedObject, &stgEmbed ) ) || SUCCEEDED( hResult = spDataObject->GetData( &fetcEmbedSource, &stgEmbed ) ) )
						{
							if ( LPMEMORYOLESTREAM pMemoryStream = CreateMemoryOleStream( NULL, NULL ) )
							{
								oleObjectHeader.WriteToOLEStream( pMemoryStream );
								OleConvertIStorageToOLESTREAM( stgEmbed.pstg, pMemoryStream );

								SAFEARRAYBOUND safeArray = { GlobalSize( pMemoryStream->hGlobal ), 0 };
								pvtValue->vt = VT_ARRAY | VT_UI1;
								pvtValue->parray = SafeArrayCreate( VT_UI1, 1, &safeArray );
								void* pArrayData = NULL;
								if ( SUCCEEDED( hResult = SafeArrayAccessData( pvtValue->parray, &pArrayData ) ) )
								{
									CopyMemory( pArrayData, GlobalLock( pMemoryStream->hGlobal ), safeArray.cElements );
									GlobalUnlock( pMemoryStream->hGlobal );
									SafeArrayUnaccessData( pvtValue->parray );
								}
								DeleteMemoryOleStream( pMemoryStream );
							}
							ReleaseStgMedium( &stgEmbed );
						}
						CoTaskMemFree( bstrProgID );
					};
				};
				GlobalUnlock( hGlobalObjectDescriptor );
				ReleaseStgMedium( &stgObjectDescriptor );
			};
		};
	}
	return hResult;
}
C++.18:
The Round function performs round to even, which is different from round to larger. The return value is the number closest to the value of expression, with the appropriate number of decimal places. If expression is exactly halfway between two possible rounded values, the function returns the possible rounded value whose rightmost digit is an even number. (In a round to larger function, a number that is halfway between two possible rounded values is always rounded to the larger number.). Round to even is a statistically more accurate rounding algorithm than round to larger. A possible implementation for Round function can be found here:
long Round( double d )
{
	double f = floor( d ), c = ceil(d), df = d - f, cd = c - d;
	if ( df > cd )
		return (long)c;
	if ( df < cd )
		return (long)f;
	return (long)((long)f % 2 ? c : f);
}
C++.19:
The "\" VB operator divides two numbers and returns an integer result. Before division is performed, numeric expressions are rounded to Byte, Integer, or Long subtype expressions. A possible implementation for "\" Integer Division Operator could be:
long( Round(d) / Round( n ) )
C++.20:
The LoadImage API function loads an icon, cursor, animated cursor, or bitmap. The LoadIcon API function loads the specified icon resource from the executable (.exe) file associated with an application instance. Both functions load icons with less than 16 colors. In order to load your icon file using more colors you have to use the LoadPicture function. The following code adds your icon to an image list using all colors in the icon:
CComPtr<IPictureDisp> spPictureDisp;
if ( LoadPicture( pszExeFileName, &spPictureDisp ) )
	if ( CComQIPtr<IPicture> spPicture(spPictureDisp) )
	{
		OLE_HANDLE hIcon = NULL;
		if ( SUCCEEDED( spPicture->get_Handle( &hIcon ) ) )
			ImageList_AddIcon( hImageList, (HICON)hIcon );
	}
C++.21:
Prototype the function with a complete argument list and then specify actual parameters when declaring the pointer, as follows:
  • type (*ptr)(parameter_list);

If the function you want to call is member of a class ( non static member ), you have to specify the prototype like:

  • type (class::*ptr)(parameter_list);

The following sample declares two classes A and B, and a pointer to a function that's not static:

class A
{

protected:
	void a1()
	{
		// do something
	}

	void a2()
	{
		// do something
	}
};

class B : public A
{
public:

	typedef void (A::*callback_a)();

	virtual void callA( callback_a a = A::a1 )
	{
		(this->*a)();
	}
};
If you would try to call in the function callA something like a(), or (*a)(), the compiler gives "error C2064: term does not evaluate to a function", that's why you have to call explicit the this pointer like: (this->*a)().
C++.22:
The Windows system provides an API called IntersectRect. The IntersectRect function calculates the intersection of two source rectangles and places the coordinates of the intersection rectangle into the destination rectangle. If the source rectangles do not intersect, an empty rectangle (in which all coordinates are set to zero) is placed into the destination rectangle. The single problem with this API seems to be when one of the source rectangles is empty. An empty rectangle is when the width or height of the rectangle is 0. For instance, if you have a rectangle like (0,0,10,10) , and you want the intersection with (5,5,5,5) rectangle, the IntersectRect API gives (0,0,0,0), instead (5,5,5,5) that's actually not what we are looking for so the following function just gives you the correct intersection:
// Function name	: IntersectRectFix
// Description	    : The IntersectRect function calculates the intersection of two source rectangles and places the coordinates of the intersection rectangle into the destination rectangle.
// Return type		: RECT 
// Argument         : RECT* prtA
// Argument         : RECT* prtB
BOOL IntersectRectFix( RECT* prtResult, RECT* prtA, RECT* prtB )
{
	RECT rtEmpty = {0}, rtResult = rtEmpty;
	rtResult.left = min(max(prtA->left, prtB->left),prtB->right);
	rtResult.right = max(min(prtA->right, prtB->right),prtB->left);
	rtResult.top = min(max(prtA->top, prtB->top),prtB->bottom);
	rtResult.bottom = max(min(prtA->bottom, prtB->bottom),prtB->top);
	*prtResult = rtEmpty;
	RECT* p = prtA;
	for ( long i = 0; i < 2; i++, p = prtB )
		if ( !( ( ( rtResult.left >= p->left ) && ( rtResult.right <= p->right ) ) && ( ( rtResult.top >= p->top ) && ( rtResult.bottom <= p->bottom ) ) ) )
			return FALSE;
	*prtResult = rtResult;
	return TRUE;
}
C++.23:
The following function gets the EMF format (CF_ENHMETAFILE) from the clipboard and saves it to a picture file ( EMF file ). You can use a graphic viewer to view EMF files, like MS Paint, MS Office Picture Manager, and so on. Also, you can drag and drop the file from the Windows Explorer to Microsoft Word, or OLE compliant applications.
BOOL saveEMFtoFile( LPCTSTR szFileName )
{
	BOOL bResult = FALSE;
	if ( ::OpenClipboard( NULL ) )
	{
		CComPtr<IPicture> spPicture;
		PICTDESC pictDesc = {0};
		pictDesc.cbSizeofstruct = sizeof(pictDesc);
		pictDesc.emf.hemf = (HENHMETAFILE)::GetClipboardData( CF_ENHMETAFILE );
		pictDesc.picType = PICTYPE_ENHMETAFILE;
		if ( SUCCEEDED( OleCreatePictureIndirect( &pictDesc, IID_IPicture, FALSE, (LPVOID*)&spPicture ) ) )
		{
			HGLOBAL hGlobal = NULL;
			CComPtr<IStream> spStream;
			if ( SUCCEEDED( CreateStreamOnHGlobal( hGlobal = GlobalAlloc( GPTR, 0 ), TRUE, &spStream ) ) )
			{
				long dwSize = NULL;
				if ( SUCCEEDED( spPicture->SaveAsFile( spStream, TRUE, &dwSize ) ) )
				{
					USES_CONVERSION;
					HANDLE hFile = CreateFile( szFileName, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL );
					if ( hFile != INVALID_HANDLE_VALUE )
					{
						LARGE_INTEGER l = {NULL};
						spStream->Seek(l, STREAM_SEEK_SET, NULL);
						long dwWritten = NULL;
						while ( dwWritten < dwSize )
						{
							unsigned long dwRead = NULL;
							BYTE b[10240] = {0};
							spStream->Read( &b, 10240, &dwRead );
							DWORD dwBWritten = NULL;
							WriteFile( hFile, b, dwRead, &dwBWritten, NULL );
							dwWritten += dwBWritten;
						}
						CloseHandle( hFile );
						bResult = TRUE;
					}
				}
			}
		}
		CloseClipboard();
	}
	return bResult;
}
C++.24:
The following function saves an EMF file as a BMP file. The szEMFFile indicates the file name of the EMF file to be read, while the szBMPFile is the file name of the BMP file to be created. The nWidth and nHeight parameters indicates the size of the BMP to be created. If -1 is used, the BMP size will be getting from the bounding rectangle of the EMF header:
BOOL EMF2BMP( LPCTSTR szEMFFile, LPCTSTR szBMPFile, long nWidth = -1, long nHeight = -1 )
{
	BOOL bResult = FALSE;
	if ( HENHMETAFILE hEMFFile = GetEnhMetaFile( szEMFFile ) )
	{
		if ( ( nWidth < 0 ) || ( nHeight < 0 ) )
		{
			ENHMETAHEADER emfHeader = {0};
			emfHeader.nSize = sizeof(ENHMETAHEADER);
			if ( GetEnhMetaFileHeader( hEMFFile, emfHeader.nSize, &emfHeader ) )
			{
				if ( nWidth < 0 )
					nWidth = emfHeader.rclBounds.right - emfHeader.rclBounds.left;
				if ( nHeight < 0 )
					nHeight = emfHeader.rclBounds.bottom - emfHeader.rclBounds.top;
			}
		}

		BOOL bDelete = FALSE;
		RECT rtDraw = {0,0,nWidth,nHeight};
		HDC hDCS = ::GetDC( NULL );
		HDC hDCDraw = ::CreateCompatibleDC( hDCS );
		HBITMAP hBitmap = ::CreateCompatibleBitmap( hDCS, nWidth, nHeight ), hOldBitmap = (HBITMAP)SelectObject( hDCDraw, hBitmap );
		PlayEnhMetaFile( hDCDraw, hEMFFile, &rtDraw );
		{
			CComPtr<IPicture> spPicture;
			PICTDESC pictDesc = {0};
			pictDesc.cbSizeofstruct = sizeof(pictDesc);
			pictDesc.bmp.hbitmap = hBitmap;
			pictDesc.picType = PICTYPE_BITMAP;
			if ( SUCCEEDED( OleCreatePictureIndirect( &pictDesc, IID_IPicture, FALSE, (LPVOID*)&spPicture ) ) )
			{
				HGLOBAL hGlobal = NULL;
				CComPtr<IStream> spStream;
				if ( SUCCEEDED( CreateStreamOnHGlobal( hGlobal = GlobalAlloc( GPTR, 0 ), TRUE, &spStream ) ) )
				{
					long dwSize = NULL;
					if ( SUCCEEDED( spPicture->SaveAsFile( spStream, TRUE, &dwSize ) ) )
					{
						USES_CONVERSION;
						HANDLE hFile = CreateFile( szBMPFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL );
						if ( hFile != INVALID_HANDLE_VALUE )
						{
							LARGE_INTEGER l = {NULL};
							spStream->Seek(l, STREAM_SEEK_SET, NULL);
							long dwWritten = NULL;
							while ( dwWritten < dwSize )
							{
								unsigned long dwRead = NULL;
								BYTE b[10240] = {0};
								spStream->Read( &b, 10240, &dwRead );
								DWORD dwBWritten = NULL;
								WriteFile( hFile, b, dwRead, &dwBWritten, NULL );
								dwWritten += dwBWritten;
							}
							CloseHandle( hFile );
							bResult = TRUE;
						}
					}
				}
			}
		}
		::SelectObject( hDCDraw, hOldBitmap );
		::DeleteObject( hBitmap );
		::DeleteDC( hDCDraw );
		::ReleaseDC( NULL, hDCS );
		::DeleteEnhMetaFile( hEMFFile );
	}
	return bResult;
}
C++.24:
The VariantChangeType API function  converts a VARIANT from one type to another. The following sample uses CComVariant class to convert a VARIANT to a string: 
static string V2D( double vtDate, LPCTSTR szDefault = _T("") )
{
	return V2S( &CComVariant( vtDate, VT_DATE ), szDefault );
}
where the V2S can be found here.