//////////////////////////////////////////////
// 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);
}
};
};
}}