Click here to Skip to main content
15,896,557 members
Articles / Programming Languages / C++

Writing Win32 Apps with C++: V2 - part 1

Rate me:
Please Sign up or sign in to vote.
4.70/5 (34 votes)
20 Jun 2005CPOL14 min read 108K   1.2K   73  
An independent framework to handle Win32 objects inside C++ classes.
//////////////////////////////////////////////
//	winhelpers.hpp
//		some Win32 shortcuts
#pragma once
#include "dependency.h"
#include "handles.hpp"
#include "coords.hpp"
#include "loop.hpp"
#include "win.hpp"
#pragma message("including " __FILE__)

namespace GE_{ namespace winx {


	inline HWND CreateWnd(LPCTSTR text, DWORD ExStyle, 
		DWORD style, const winx::rect& rc, HWND hParent, UINT nID, LPVOID lpParam, HINSTANCE hInst=0)
	{
		if(!hInst) hInst = GetModuleHandle(0);
		return ::CreateWindowEx(ExStyle,app::wndcls::pane(),text,style,
			rc.left, rc.top, rc.width(), rc.height(), (hParent)? hParent: app::msgloop::global()->get_hwnd(), (HMENU)(LPARAM)nID, hInst, lpParam);
	}

	inline bool MoveWindow(HWND h, LPCRECT lprc, bool bRepaint)
	{	return 0!=::MoveWindow(h,lprc->left,lprc->top,lprc->right-lprc->left,lprc->bottom-lprc->top,bRepaint); }

	inline void ScreenToClient(HWND hWnd, LPRECT lpRect)
	{	::ScreenToClient(hWnd, (LPPOINT)lpRect); ::ScreenToClient(hWnd, ((LPPOINT)lpRect)+1); }

	inline void ClientToScreen(HWND hWnd, LPRECT lpRect)
	{	::ClientToScreen(hWnd, (LPPOINT)lpRect); ::ClientToScreen(hWnd, ((LPPOINT)lpRect)+1); }

	inline LONG ModifyStyle(HWND h, LONG add, LONG remove)
	{
		LONG s = GetWindowLong(h,GWL_STYLE);
		s &= ~remove; s |= add;
		SetWindowLong(h, GWL_STYLE, s);
		return s;
	}

	inline LONG ModifyExStyle(HWND h, LONG add, LONG remove)
	{
		LONG s = GetWindowLong(h,GWL_EXSTYLE);
		s &= ~remove; s |= add;
		SetWindowLong(h, GWL_EXSTYLE, s);
		return s;
	}

	inline void CenterPopup(HWND hPopup)
	{
		HWND hParent = GetParent(hPopup);
		winx::rect rc; GetWindowRect(hParent, rc);
		winx::rect rcp; GetWindowRect(hPopup, rcp);
		winx::size delta = (rc.size()-rcp.size())/2;
		rcp += rc.topleft() - rcp.topleft() + delta;
		MoveWindow(hPopup, rcp, true);
	}
	
	namespace draw {

		inline bool SetWindowOrgEx(HDC hdc, const winx::point& pt, LPPOINT lpp)
		{	return 0!=::SetWindowOrgEx(hdc,pt.x,pt.y,lpp); }
		
		inline bool SetViewportOrgEx(HDC hdc, const winx::point& pt, LPPOINT lpp)
		{	return 0!=::SetViewportOrgEx(hdc,pt.x,pt.y,lpp); }

		inline bool SetWindowExtEx(HDC hdc, const winx::size& sz, LPSIZE lps)
		{	return 0!=::SetWindowExtEx(hdc,sz.cx,sz.cy,lps); }

		inline bool SetViewportExtEx(HDC hdc, const winx::size& sz, LPSIZE lps)
		{	return 0!=::SetViewportExtEx(hdc,sz.cx,sz.cy,lps); }

		inline void rectangle(HDC hdc, LPCRECT  lprc)
		{ ::Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); }

		inline bool BitBlt(HDC hdcDest, const winx::rect& rcdest, HDC hdcSrc, const POINT& srcplc, DWORD rop)
		{
			return 0!=::BitBlt(hdcDest,rcdest.left,rcdest.top,rcdest.width(),rcdest.height(),
				hdcSrc, srcplc.x, srcplc.y, rop);
		}

		inline void Draw3dRect(HDC hdc, LPCRECT lprc, COLORREF topleftcolor, COLORREF bottomrightcolor)
		{
			winx::HSPEN topleftpen(CreatePen(PS_SOLID, 1, topleftcolor));
			winx::HSPEN bottomrightpen(CreatePen(PS_SOLID, 1, bottomrightcolor));
			winx::DC_Save dc(hdc);
			dc.selectobject(topleftpen);
			MoveToEx(dc,lprc->left, lprc->bottom-1,NULL);
			LineTo(dc, lprc->left, lprc->top); LineTo(dc, lprc->right-1, lprc->top);
			dc.selectobject(bottomrightpen);
			LineTo(dc, lprc->right-1, lprc->bottom-1); LineTo(dc, lprc->left, lprc->bottom-1);
		}

	}

	//get a window rectangle in term of its parent client coord
	inline void GetChildRect(HWND h, LPRECT lprc)
	{
		GetWindowRect(h,lprc);
		HWND hp = GetParent(h);
		::ScreenToClient(hp,(LPPOINT)lprc);
		::ScreenToClient(hp,((LPPOINT)lprc)+1);
	}

#pragma pack(push)
#pragma pack(1)
	union Color
	{
		COLORREF c;
		struct
		{
			BYTE r;
			BYTE g;
			BYTE b;
			BYTE a;
		};
		BYTE x[4];
		enum colorcomponent { cr, cg, cb, ca, cfirst=0, clast=3 };
	};
#pragma pack(pop)

	namespace color {

		//weighted colo sum
		inline COLORREF mix(COLORREF c1, int w1, COLORREF c2, int w2)
		{
			int w = w1+w2; if(!w) w=1;
			Color& cl1= *(Color*)&c1;
			Color& cl2= *(Color*)&c2;

			int r=((int)cl1.r*w1+(int)cl2.r*w2)/w;
			int g=((int)cl1.g*w1+(int)cl2.g*w2)/w;
			int b=((int)cl1.b*w1+(int)cl2.b*w2)/w;
			operators::set_min(r,0); operators::set_max(r,255);
			operators::set_min(g,0); operators::set_max(g,255);
			operators::set_min(b,0); operators::set_max(b,255);
			return RGB(r,g,b);
		}

		//force the saturation:
		// m = RGB(128,128,128) and n = 1 are neutral
		// over 128 enhance the difference from gray, lss than 128 makes color more gray
		inline COLORREF glow(COLORREF c, COLORREF m, int gain=1)
		{
			Color&C = *(Color*)&c; Color& M= *(Color*)&m;
			int i; Color R;
			i = 128+((int)C.r-128)*(128+gain*((int)M.r-128))/128; operators::set_range(i,0,255); R.r = (BYTE)i;
			i = 128+((int)C.g-128)*(128+gain*((int)M.g-128))/128; operators::set_range(i,0,255); R.g = (BYTE)i;
			i = 128+((int)C.b-128)*(128+gain*((int)M.b-128))/128; operators::set_range(i,0,255); R.b = (BYTE)i;
			return R.c;
		}

		//convet c in a color inside a shade between min nd max
		inline COLORREF monocrome(COLORREF c, COLORREF min=RGB(0,0,0), COLORREF max=RGB(255,255,255))
		{	
			Color& C=*(Color*)&c ; Color& Min=*(Color*)&min; Color& Max=*(Color*)&max;
			int i = (4*C.g+2*C.r+C.b) / 7; operators::set_max(i, 255);
			Color R; 
			R.r = (BYTE)(Min.r + (Max.r-Min.r)*i/255);
			R.g = (BYTE)(Min.g + (Max.g-Min.g)*i/255);
			R.b = (BYTE)(Min.b + (Max.b-Min.b)*i/255);
			return R.c;
		}

	}

	namespace plugins
	{
		class selfcentredpopup_wnd:
			public winx::win
		{
		public:
			selfcentredpopup_wnd()
			{
			}
			virtual ~selfcentredpopup_wnd()
			{
			}

		protected:
			virtual bool on_message(winx::winmsg& M)
			{
				if(M.hWnd == *this && M.uMsg == WM_CREATE)
					CenterPopup(*this);
				return winx::win::on_message(M);
			}
		};
	};

}}

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
Architect
Italy Italy
Born and living in Milan (Italy), I'm an engineer in electronics actually working in the ICT department of an important oil/gas & energy company as responsible for planning and engineering of ICT infrastructures.
Interested in programming since the '70s, today I still define architectures for the ICT, deploying dedicated specific client application for engineering purposes, working with C++, MFC, STL, and recently also C# and D.

Comments and Discussions