Click here to Skip to main content
15,886,026 members
Articles / Web Development / HTML

A Comprehensive CE Class Library to Replace ATL and MFC

Rate me:
Please Sign up or sign in to vote.
4.48/5 (14 votes)
4 Oct 2000CPOL 278.8K   998   70  
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
#include "StdAfx.h"
#include "CeWnd.h"
#include "CeMisc.h"

#ifdef _DEBUG
///////////////////////////////////////////////////////////////////////////////
//
// CeTrace - write a variable argument string to the debug output device
//
///////////////////////////////////////////////////////////////////////////////
void CeTrace(LPCTSTR lpszFormat, ...)
{
	va_list args;
	va_start(args, lpszFormat);

	TCHAR szBuffer[1024];
	wvsprintf(szBuffer, lpszFormat, args);
	::OutputDebugString(szBuffer);

	va_end(args);
}

///////////////////////////////////////////////////////////////////////////////
//
// CeAssert - checks the passed expression, breaks into the debugger if the 
//            boolean expression is false
//
///////////////////////////////////////////////////////////////////////////////
void CeAssert(BOOL bExp, LPCTSTR lpszExp)
{
	if (! bExp)
	{
		::CeTrace(_T("%s\n"), lpszExp);
		int nResp = ::MessageBox(NULL, lpszExp, _T("Debug Assert Failed!"), MB_OKCANCEL);
		if (nResp == IDCANCEL)
			DebugBreak();
	}
}


#endif

// called only the first time, binds the window to a pointer and
// sets the window proc
LRESULT CALLBACK CeWnd::StartWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	CeWnd* pWnd = (CeWnd*) ::GetWindowLong(hWnd, GWL_USERDATA);
	if (NULL != pWnd)
	{
		// we don't know ANYTHING about this window
		TRACE0("WARNING: Received starting message from UNKNOWN WINDOW\n");
		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
	}

//	TRACE(_T("pWnd = %x, hWnd = %x, uMsg = 0x%x, wParam = %x, lParam = %x\n"), pWnd, hWnd, uMsg, wParam, lParam);

	// Note: _FIRST_WM_MESSAGE must be WM_NCCREATE or WM_CREATE
	if (_FIRST_WM_MESSAGE == uMsg)
	{
		LPCREATESTRUCT lpCS = (LPCREATESTRUCT) lParam;
		pWnd = (CeWnd*) lpCS->lpCreateParams;
		CHW_ASSERT(ISVALIDPTR(pWnd, sizeof *pWnd));

		::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) WndProc);
		::SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWnd);
		pWnd->OnFirstMessage(hWnd);
		pWnd->m_hWnd = hWnd;

#ifdef STRICT
		return CallWindowProc(WndProc, hWnd, uMsg, wParam, lParam);
#else
		return CallWindowProc((FARPROC) WndProc, hWnd, uMsg, wParam, lParam);
#endif
	}
	else
	{
		// need to wait for the FIRST message to get the create params
		// to bind the window to this message
		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
}


///////////////////////////////////////////////////////////////////////////////
//
// WndProc -	window message ALL CeWnd messages are processed through, also
//				binds the window to the CREATESTRUCT passed in if the window
//				hasn't been bound yet
//
///////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK CeWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT lRet = 0;	// default
	CeWnd* pWnd = (CeWnd*) ::GetWindowLong(hWnd, GWL_USERDATA);
//	TRACE(_T("pWnd = %x, hWnd = %x, uMsg = 0x%x, wParam = %x, lParam = %x\n"), pWnd, hWnd, uMsg, wParam, lParam);

	if (NULL == pWnd)
	{
		// we don't know ANYTHING about this window
		TRACE0("WARNING: Received window message from UNKNOWN WINDOW\n");
		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	else
	{
		CHW_ASSERT(ISVALIDPTR(pWnd, sizeof *pWnd));
		//CHW_ASSERT(pWnd->m_hWnd == hWnd);
	}

	// keep message for default call
	pWnd->m_cemsg.hwnd = hWnd;
	pWnd->m_cemsg.uMsg = uMsg;
	pWnd->m_cemsg.wParam = wParam;
	pWnd->m_cemsg.lParam = lParam;

	bool bHandled = false;		// not handled by default

	// encapsulate external calls in exception handlers, CE doesn't do a 
	// good job of showing exception conditions in the UI
	__try
	{
		// what to return as a result of handling message
		lRet = pWnd->ProcessMessage(uMsg, wParam, lParam, bHandled);

		if (! bHandled)
			lRet = pWnd->Default();

		if (_LAST_WM_MESSAGE == uMsg)
		{
			// we received the LAST message we're going to to get
			// unsubclass the window
			if (NULL != pWnd->m_lpfnOldWndProc)
			{
				// restore the window to the old window proc
				::SetWindowLong(pWnd->m_hWnd, GWL_WNDPROC, (LONG) pWnd->m_lpfnOldWndProc);
			}
			else
			{
				// the window was our class but we're going away, so just set to default
				// so the messages get processed anyway
				::SetWindowLong(pWnd->m_hWnd, GWL_WNDPROC, (LONG) ::DefWindowProc);
			}

			// clear out window handle
			HWND hWnd = pWnd->m_hWnd;
			pWnd->m_hWnd = NULL;

			// allow derived classes to clean up after window is destroyed
			pWnd->OnFinalMessage(hWnd);
		}
	}
    __except (EXCEPTION_EXECUTE_HANDLER)
	{
		TCHAR szErr[256];
		wsprintf(szErr, _T("Window message (0x%04x) termainated abnormally by an exception"), uMsg);
		::MessageBox(NULL, szErr, _T("Fatal"), MB_OK | MB_ICONSTOP);
	}

	return lRet;
}


BOOL CeWnd::Subclass(UINT nID, HWND hWndParent)
{
	return Subclass( ::GetDlgItem(hWndParent, nID) );
}

BOOL CeWnd::Subclass(HWND hWnd)
{
	CHW_ASSERT(m_hWnd == NULL);
	if (NULL != m_hWnd)
		return FALSE;

	m_lpfnOldWndProc = (WNDPROC) ::GetWindowLong(hWnd, GWL_WNDPROC);

	::SetWindowLong(hWnd, GWL_USERDATA, (LONG) this);
	::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) WndProc);

	return Attach(hWnd);
}

HWND CeWnd::Unsubclass()
{
	SetWindowLong(GWL_USERDATA, 0);

	if (NULL != m_lpfnOldWndProc)
	{
		// restore the window to the old window proc
		::SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG) m_lpfnOldWndProc);
	}
	else
	{
		// the window was our class but we're going away, so just set to default
		// so the messages get processed anyway
		::SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG) ::DefWindowProc);
	}

	return Detach();
}


///////////////////////////////////////////////////////////////////////////////
//
// ProcessMessage - 
//
///////////////////////////////////////////////////////////////////////////////
LRESULT CeMsgWnd::ProcessMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
{
	LRESULT lRet = 0;		// default WndProc result
	POINT pt;
	bHandled = false;		// we didn't handle it, but gave the oppertunity

	switch (uMsg)
	{
#ifndef _WIN32_WCE
	case WM_QUERYENDSESSION: lRet = OnQueryEndSession((UINT) wParam, (UINT) lParam, bHandled );
		break;
	case WM_ENDSESSION: OnEndSession((BOOL) wParam, (UINT) lParam, bHandled );
		break;
#endif
	case WM_CHAR: OnChar((UINT) wParam, LOWORD(lParam), HIWORD(lParam), bHandled);
		break;
	case WM_CLOSE:
		TRACE0("OnClose\n");
		OnClose(bHandled);
		break;
	case WM_COMMAND:
		TRACE0("OnCommand\n");
		lRet = OnCommand(wParam, lParam, bHandled);
		break;
	case WM_CREATE: OnCreate( (LPCREATESTRUCT) lParam, bHandled );
		break;
	case WM_DESTROY: OnDestroy( bHandled );
		break;
	case WM_ENABLE:	OnEnable( (BOOL) wParam, bHandled );
		break;
	case WM_ERASEBKGND: lRet = OnEraseBkgnd( (HDC) wParam, bHandled);
		break;
	case WM_KEYDOWN: OnKeyDown((UINT) wParam, LOWORD(lParam), HIWORD(lParam), bHandled);
		break;
	case WM_KEYUP: OnKeyUp((UINT) wParam, LOWORD(lParam), HIWORD(lParam), bHandled);
		break;
	case WM_LBUTTONDBLCLK: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam);
		OnLButtonDblClk( wParam, pt, bHandled );
		break;
	case WM_LBUTTONDOWN: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam);
		OnLButtonDown( wParam, pt, bHandled );
		break;
	case WM_LBUTTONUP: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam);
		OnLButtonUp( wParam, pt, bHandled );
		break;
	case WM_MOUSEMOVE: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam);
		OnMouseMove( wParam, pt, bHandled ); 
		break;
	case WM_MOVE: OnMove( LOWORD(lParam), HIWORD(lParam), bHandled ); 
		break;
	case WM_NOTIFY:
		lRet = OnNotify((int) wParam, (LPNMHDR) lParam, bHandled);
		break;
	case WM_PAINT: OnPaint( bHandled );
		break;
#ifndef _WIN32_WCE
	case WM_SETCURSOR: lRet = OnSetCursor((HWND) wParam, LOWORD(lParam), HIWORD(lParam), bHandled );
		break;
#endif
	case WM_SHOWWINDOW: OnShowWindow( (BOOL) wParam, (int) lParam, bHandled );
		break;
	case WM_SIZE: OnSize( wParam, LOWORD(lParam), HIWORD(lParam), bHandled );
		break;
	case WM_TIMER: OnTimer( wParam, bHandled );
		break;
	case WM_SETTINGCHANGE:	OnSettingChange( wParam, (LPCTSTR)lParam, bHandled );
		break;

	default: lRet = OnMessage( uMsg, wParam, lParam, bHandled );
		break;
	}

	return lRet;
}


///////////////////////////////////////////////////////////////////////////////
//
// RegisterClass - Registers a window class for later use in a CeWnd derived
//				   class
//
///////////////////////////////////////////////////////////////////////////////
bool CeWnd::RegisterClass(LPCTSTR lpszClassName, UINT style, int cbClsExtra,
					 int cbWndExtra, HICON hIcon, HCURSOR hCursor, HBRUSH hbrBackground,
					 LPCTSTR lpszMenuName, HINSTANCE hInst)
{
	WNDCLASS wc;

	if (hInst == NULL)
		hInst = CeGetAppInstance();

	wc.lpszClassName = lpszClassName;
	wc.lpfnWndProc = StartWndProc;	// default proc for first message

	wc.style = style;
	wc.cbClsExtra = cbClsExtra;
	wc.cbWndExtra = cbWndExtra;
	wc.hInstance = hInst;
	wc.hIcon = hIcon;
	wc.hCursor = hCursor;
	wc.hbrBackground = hbrBackground;

	if (NULL == hbrBackground)
		wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

	wc.lpszMenuName = lpszMenuName;

#ifdef _WIN32_WCE
	wc.hCursor = NULL;
	wc.lpszMenuName = NULL;
#endif

	ATOM a;
	a = ::RegisterClass(&wc);
	return (0 != a);
}


///////////////////////////////////////////////////////////////////////////////
//
// RegisterWndSuperclass - 
//
///////////////////////////////////////////////////////////////////////////////
LPCTSTR CeWnd::CreateGenericWndClass(HINSTANCE hInst)
{
	static bool bRegistered = false;

	if (! bRegistered)
	{
		WNDCLASS wc;

		if (hInst == NULL)
			hInst = CeGetAppInstance();

		wc.style = 0 ;
		wc.lpfnWndProc = (WNDPROC) StartWndProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = hInst;
		wc.hIcon = NULL;
		wc.hCursor = NULL;
		wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
		wc.lpszMenuName = NULL;
		wc.lpszClassName = WC_CEGENERICWNDCLASS;

		::RegisterClass(&wc);

		bRegistered = true;
	}

	return WC_CEGENERICWNDCLASS;
}


///////////////////////////////////////////////////////////////////////////////
//
// RegisterWndSuperclass - 
//
///////////////////////////////////////////////////////////////////////////////
BOOL CeWnd::RegisterWndSuperclass(LPCTSTR lpszClass, WNDPROC& lpfnWndProc, HINSTANCE hInst)
{
	// allocate a buffer big enough for the class name + 7 double byte characters
	LPTSTR lpszWndClass = (LPTSTR)_alloca((lstrlen(lpszClass) + 14) * sizeof(TCHAR));
	lpfnWndProc = NULL;

	if (hInst == NULL)
		hInst = CeGetAppInstance();

	// either a global class or preregistered
	WNDCLASS wc;
	if (::GetClassInfo(NULL, lpszClass, &wc))
	{
		wsprintf(lpszWndClass, _T("CeWnd:%s"), lpszClass);

		// setup the old 
		lpfnWndProc = wc.lpfnWndProc;

		// Check if it's already registered as a CeWnd class
		WNDCLASS wc1;
		if (wc.lpfnWndProc != CeWnd::WndProc || 0 == GetClassInfo(NULL, lpszWndClass, &wc1))
		{
			// register the class as a superclass
			wc.lpszClassName = lpszWndClass;
			wc.lpfnWndProc = StartWndProc;
			wc.hInstance = hInst;
			wc.style &= ~CS_GLOBALCLASS;	// we don't register global classes

			return ::RegisterClass(&wc);
		}
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
//
// Default - Calls either the default window procedure or the
//           subclassed window procedure for the active message
//
///////////////////////////////////////////////////////////////////////////////
LRESULT CeMsgWnd::Default()
{
	if (m_lpfnOldWndProc)
	{
#ifdef STRICT
		return CallWindowProc((WNDPROC) m_lpfnOldWndProc, m_cemsg.hwnd,
			m_cemsg.uMsg, m_cemsg.wParam, m_cemsg.lParam);
#else
		return CallWindowProc((FARPROC) m_lpfnOldWndProc, m_cemsg.hwnd,
			m_cemsg.uMsg, m_cemsg.wParam, m_cemsg.lParam);
#endif
	}
	else
		return DefWindowProc(m_cemsg.hwnd, m_cemsg.uMsg, m_cemsg.wParam, m_cemsg.lParam);
}


///////////////////////////////////////////////////////////////////////////////
//
// IsCeWndProc - Checks to see if the class being passed in is already been
//               subclassed by us.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CeWnd::IsCeWndProc(LPCTSTR lpstrWndClass, HINSTANCE hInst)
{
	WNDCLASS wc;
	if (hInst == NULL)
		hInst = CeGetAppInstance();
	
	return (::GetClassInfo(hInst, lpstrWndClass, &wc) && wc.lpfnWndProc == CeWnd::WndProc);
}


///////////////////////////////////////////////////////////////////////////////
//
// Create - Create a child window
//
///////////////////////////////////////////////////////////////////////////////
BOOL CeWnd::Create(LPCTSTR lpstrWndClass, HWND hWndParent,
				   const RECT& rcPos, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
				   UINT nID, HINSTANCE hInst)
{
	LPCTSTR lpszClass;

	if (hInst == NULL)
		hInst = CeGetAppInstance();

	// we have a valid window class find out if it is subclassed to our window proc
	// otherwise subclass and replace the window class window proc
	if (NULL != lpstrWndClass && 0 != lstrlen(lpstrWndClass))
	{
		if (! IsCeWndProc(lpstrWndClass, hInst))
		{
			RegisterWndSuperclass(lpstrWndClass, m_lpfnOldWndProc, hInst);
			lpszClass = (LPTSTR)_alloca((lstrlen(lpstrWndClass) + 14) * sizeof(TCHAR));
			wsprintf((LPTSTR) lpszClass, _T("CeWnd:%s"), lpstrWndClass);
		}
	}

	if (NULL == lpstrWndClass || 0 == lstrlen(lpstrWndClass))
		lpszClass = CreateGenericWndClass(hInst);

	HWND hWnd = ::CreateWindowEx(dwExStyle, lpszClass, szWindowName,
		dwStyle, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
		rcPos.bottom - rcPos.top, hWndParent, (HMENU)nID,
		hInst, this);

	return (NULL != hWnd && hWnd == m_hWnd);
}

///////////////////////////////////////////////////////////////////////////////
//
// Create - Create a popup window
//
///////////////////////////////////////////////////////////////////////////////
BOOL CeWnd::Create(LPCTSTR lpstrWndClass, HWND hWndParent,
				   LPCRECT lpRect, LPCTSTR szWindowName,	DWORD dwStyle, DWORD dwExStyle,
				   HMENU hMenu, HINSTANCE hInst)
{
	static RECT rcDefault = {CW_USEDEFAULT, CW_USEDEFAULT, 0, 0};

	if (lpRect == NULL)
		lpRect = &rcDefault;

	return Create(lpstrWndClass,
		hWndParent,
		lpRect->left,
		lpRect->top,
		lpRect->right - lpRect->left,
		lpRect->bottom - lpRect->top,
		szWindowName,
		dwStyle,
		dwExStyle,
		hMenu,
		hInst);
}

BOOL CeWnd::Create(LPCTSTR lpstrWndClass, HWND hWndParent,
				   int x, int y, int cx, int cy, LPCTSTR szWindowName,	DWORD dwStyle, DWORD dwExStyle,
				   HMENU hMenu, HINSTANCE hInst)
{
	if (hInst == NULL)
		hInst = CeGetAppInstance();

	LPCTSTR lpszClass;

	// we have a valid window class find out if it is sibclassed to our window proc
	// otherwise subclass and replace the window class window proc
	if (NULL != lpstrWndClass && 0 != lstrlen(lpstrWndClass))
	{
		if (! IsCeWndProc(lpstrWndClass, hInst))
		{
			RegisterWndSuperclass(lpstrWndClass, m_lpfnOldWndProc, hInst);
			lpszClass = (LPTSTR)_alloca((lstrlen(lpstrWndClass) + 14) * sizeof(TCHAR));
			wsprintf((LPTSTR) lpszClass, _T("CeWnd:%s"), lpstrWndClass);
		}
	}

	if (NULL == lpstrWndClass || 0 == lstrlen(lpstrWndClass))
		lpszClass = CreateGenericWndClass(hInst);

	HWND hWnd = ::CreateWindowEx(dwExStyle, lpszClass, szWindowName,
		dwStyle, x, y, cx, cy, hWndParent, hMenu, hInst, this);

	return (NULL != hWnd && hWnd == m_hWnd);
}


/* static */
BOOL CeBaseWnd::ModifyStyle(HWND hWnd, DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
	ASSERT(hWnd != NULL);

	DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE);
	DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
	if (dwStyle == dwNewStyle)
		return FALSE;

	::SetWindowLong(hWnd, GWL_STYLE, dwNewStyle);
	if (nFlags != 0)
	{
		::SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
			SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | nFlags);
	}

	return TRUE;
}

BOOL CeBaseWnd::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
	return ModifyStyle(m_hWnd, dwRemove, dwAdd, nFlags);
}


#ifdef _WIN32_WCE
BOOL CeBaseWnd::GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
{ 
	SCROLLINFO si;
	memset( &si, 0, sizeof(SCROLLINFO) );
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask  = SIF_RANGE;

	if(! GetScrollInfo( nBar, &si))
		return (FALSE);

	*lpMinPos = si.nMin;
	*lpMaxPos = si.nMax;

	return TRUE; 
}

int CeBaseWnd::GetScrollPos(int nBar) const
{ 
	BOOL       bIsOK = FALSE;
	SCROLLINFO si;

	memset(&si, 0, sizeof(SCROLLINFO));
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask  = SIF_POS;

	if(!GetScrollInfo(nBar, &si))
		return 0;

	return si.nPos; 
}
#endif // _WIN32_WCE

BOOL CeBaseWnd::ShowScrollBar(int nBar, BOOL bShow)
{
// WinCE: this workaround doesn't work with x86em
#if defined(_WIN32_WCE_EMULATION)
	return TRUE;
#else // _WIN32_WCE_EMULATION
	DWORD dwStyle = GetStyle();
	if(bShow)
		dwStyle |= ((nBar == SB_HORZ) ? WS_HSCROLL : WS_VSCROLL);
	else
		dwStyle &= ~((nBar == SB_HORZ) ? WS_HSCROLL : WS_VSCROLL);
	return (SetWindowLong(GWL_STYLE, dwStyle) != 0);
#endif // _WIN32_WCE_EMULATION
	return TRUE;
}


/*
void wce_ScrollChildren(HWND hWnd, int cx, int cy)
{
	// WinCE does not perform any scrolling if the window is
	// not visible.  This leaves child windows unscrolled.
	// To account for this oversight, the child windows are moved
	// directly instead.
	HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
	if (hWndChild != NULL)
	{
		for (; hWndChild != NULL;
			hWndChild = ::wce_GetNextWindow(hWndChild, GW_HWNDNEXT))
		{
			RECT rect;
			::GetWindowRect(hWndChild, &rect);
			::ScreenToClient(hWnd,(POINT*)&rect.left);
			::SetWindowPos(hWndChild, NULL,	rect.left-cx, rect.top-cy,
				0, 0, SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER);
		}
	}
}

*/

///////////////////////////////////////////////////////////////////////////////
//
// Create - Center the window from the parent
//
///////////////////////////////////////////////////////////////////////////////
BOOL CeBaseWnd::CenterWindow(HWND hWndCenter)
{
	ASSERT(::IsWindow(m_hWnd));

	// determine owner window to center against
	DWORD dwStyle = GetStyle();
	if (hWndCenter == NULL)
	{
		if(dwStyle & WS_CHILD)
			hWndCenter = ::GetParent(m_hWnd);
		else
		{
			// we'll center within the visible space of the
			// window when we're on a P/PC with only a portion
			// of the window showing (SIP displayed)
#ifdef _WCE_PPC_
			hWndCenter = ::GetWindow(m_hWnd, GW_OWNER);
#else
			hWndCenter = ::GetWindow(m_hWnd, GW_OWNER);
#endif
		}
	}

	// get coordinates of the window relative to its parent
	RECT rcDlg;
	::GetWindowRect(m_hWnd, &rcDlg);
	RECT rcArea;
	RECT rcCenter;
	HWND hWndParent;
	if(!(dwStyle & WS_CHILD))
	{
		// don't center against invisible or minimized windows
		if(hWndCenter != NULL)
		{
			DWORD dwStyle = ::GetWindowLong(hWndCenter, GWL_STYLE);
#ifndef _WIN32_WCE
			if (!(dwStyle & WS_VISIBLE) || (dwStyle & WS_MINIMIZE))
#else
			if (!(dwStyle & WS_VISIBLE))
#endif
				hWndCenter = NULL;
		}

		// center within screen coordinates
		::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
		if(hWndCenter == NULL)
			rcCenter = rcArea;
		else
			::GetWindowRect(hWndCenter, &rcCenter);
	}
	else
	{
		// center within parent client coordinates
		hWndParent = ::GetParent(m_hWnd);
		ASSERT(::IsWindow(hWndParent));

		::GetClientRect(hWndParent, &rcArea);
		ASSERT(::IsWindow(hWndCenter));
		::GetClientRect(hWndCenter, &rcCenter);
		::MapWindowPoints(hWndCenter, hWndParent, (POINT*)&rcCenter, 2);
	}

	int DlgWidth = rcDlg.right - rcDlg.left;
	int DlgHeight = rcDlg.bottom - rcDlg.top;

	// find dialog's upper left based on rcCenter
	int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2;
	int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;

	// if the dialog is outside the screen, move it inside
	if(xLeft < rcArea.left)
		xLeft = rcArea.left;
	else if(xLeft + DlgWidth > rcArea.right)
		xLeft = rcArea.right - DlgWidth;

	if(yTop < rcArea.top)
		yTop = rcArea.top;
	else if(yTop + DlgHeight > rcArea.bottom)
		yTop = rcArea.bottom - DlgHeight;

	// map screen coordinates to child coordinates
	return ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1,
		SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}



///////////////////////////////////////////////////////////////////////////////
//
// Window message virtual functions
//
///////////////////////////////////////////////////////////////////////////////

// Other timely virtual functions for override
void CeMsgWnd::OnFirstMessage(HWND /*hWnd*/)
	{}
void CeMsgWnd::OnFinalMessage(HWND /*hWnd*/)
	{}

void CeMsgWnd::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags, bool& bHandled )
	{}
void CeMsgWnd::OnClose( bool& bHandled )
	{}
int CeMsgWnd::OnCreate( LPCREATESTRUCT lpCS, bool& bHandled )
	{ return 1; }
void CeMsgWnd::OnDestroy( bool& bHandled )
	{}
void CeMsgWnd::OnEnable( BOOL bEnable, bool& bHandled )
	{}
BOOL CeMsgWnd::OnEraseBkgnd( HDC hDC, bool& bHandled )
	{ return FALSE; }
void CeMsgWnd::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags, bool& bHandled )
	{}
void CeMsgWnd::OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags, bool& bHandled )
	{}
void CeMsgWnd::OnLButtonDblClk( UINT nFlags, POINT point, bool& bHandled )
	{}
void CeMsgWnd::OnLButtonDown( UINT nFlags, POINT point, bool& bHandled )
	{}
void CeMsgWnd::OnLButtonUp( UINT nFlags, POINT point, bool& bHandled )
	{}
void CeMsgWnd::OnMouseMove( UINT nFlags, POINT point, bool& bHandled )
	{}
void CeMsgWnd::OnMove( int x, int y, bool& bHandled )
	{}
void CeMsgWnd::OnPaint( bool& bHandled )
	{}
void CeMsgWnd::OnShowWindow( BOOL bShow, UINT nStatus, bool& bHandled )
	{}
void CeMsgWnd::OnSize( UINT nType, int cx, int cy, bool& bHandled )
	{}
void CeMsgWnd::OnTimer( UINT nTimer, bool& bHandled )
	{}
void CeMsgWnd::OnSettingChange( WORD wFlags, LPCTSTR lpszSection, bool& bHandled )
	{}

LRESULT CeMsgWnd::OnNotify(int nCtrlId, LPNMHDR pNMH, bool& bHandled)
	{return TRUE;}
BOOL CeMsgWnd::OnCommand( WPARAM wParam, LPARAM lParam, bool& bHandled )
	{return TRUE;}

#ifndef _WIN32_WCE
BOOL CeMsgWnd::OnQueryEndSession( UINT nSource, BOOL fLogOff, bool& bHandled )
	{return FALSE;}
void CeMsgWnd::OnEndSession( BOOL fEndSession, UINT fLogoff, bool& bHandled )
	{}
BOOL CeMsgWnd::OnSetCursor( HWND hWnd, UINT nHitTest, UINT message, bool& bHandled )
	{return FALSE;}
#endif

LRESULT CeMsgWnd::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
	{ return 0; }

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions