COLORS1 代码分析

COLORS1这个应用程序的功能是利用3个滚动条控件来调控颜色。

我把这个程序分成3大部分:(1)基础功能的实现(2)滚动条控件与静态窗口的美化(3)实现Tab键转移焦点功能


先来看基础功能的实现,首先从创建控件开始吧:

static HWND ScrollBarHwnd[3],LabelHwnd[3],ValueHwnd[3],RectHwnd;//10个子窗口控件
static int color[3];//记录3个滚动条的thumb的pos
static TCHAR *szLabel[3]={TEXT("RED"),TEXT("GREEN"),TEXT("BLUE")};//3个Label窗口的文本
if(uimsg==WM_CREATE)
{
	HINSTANCE hInstance=((LPCREATESTRUCT)lparam)->hInstance;
	RectHwnd=CreateWindow(TEXT("static"),NULL,WS_CHILD | WS_VISIBLE | SS_WHITERECT,0,0,0,0,hwnd,(HMENU)9,hInstance,NULL);
	for(int i=0;i<3;i++)
	{
		ScrollBarHwnd[i]=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_VERT,0,0,0,0,hwnd,(HMENU)i,hInstance,NULL);
		SetScrollRange(ScrollBarHwnd[i],SB_CTL,0,255,false);
		color[i]=0;
		SetScrollPos(ScrollBarHwnd[i],SB_CTL,color[i],false);

		LabelHwnd[i]=CreateWindow(TEXT("static"),szLabel[i],WS_CHILD | WS_VISIBLE | SS_CENTER,0,0,0,0,hwnd,(HMENU)(i+3),hInstance,NULL);
		ValueHwnd[i]=CreateWindow(TEXT("static"),TEXT("0"),WS_CHILD | WS_VISIBLE | SS_CENTER,0,0,0,0,hwnd,(HMENU)(i+6),hInstance,NULL);
	}
	return 0;
}
else if(uimsg==WM_SIZE)
{
	int cxClient=LOWORD(lparam);
	int cyClient=HIWORD(lparam);
	int cyChar=HIWORD(GetDialogBaseUnits());
	MoveWindow(RectHwnd,0,0,cxClient/2,cyClient,true);
	for(int i=0;i<3;i++)
	{
		MoveWindow(ScrollBarHwnd[i],(2*i+1)*cxClient/14,2*cyChar,cxClient/14,cyClient-4*cyChar,true);
		MoveWindow(LabelHwnd[i],(4*i+1)*cxClient/28,cyChar/2,cxClient/7,cyChar,true);
		MoveWindow(ValueHwnd[i],(4*i+1)*cxClient/28,cyClient-3*cyChar/2,cxClient/7,cyChar,true);
	}
	return 0;
}


接着实现右边显示3种RGB融合之后的颜色:

else if(uimsg==WM_VSCROLL)
	{
		int id=GetWindowLong((HWND)lparam,GWL_ID);//确定是哪一个滚动条发送的消息
		if(LOWORD(wparam)==SB_LINEDOWN)
			color[id]++;
		else if(LOWORD(wparam)==SB_LINEUP)
			color[id]--;
		else if(LOWORD(wparam)==SB_PAGEDOWN)
			color[id]+=16;
		else if(LOWORD(wparam)==SB_PAGEUP)
			color[id]-=16;
		else if(LOWORD(wparam)==SB_THUMBPOSITION || LOWORD(wparam)==SB_THUMBTRACK)
			color[id]=HIWORD(wparam);
		color[id]=min(255,max(0,color[id]));
		SetScrollPos(ScrollBarHwnd[id],SB_CTL,color[id],true);//处理滚动条的位置,使它正常运行

		TCHAR szbuf[100];
		wsprintf(szbuf,TEXT("%d"),color[id]);
		SetWindowText(ValueHwnd[id],szbuf);//修改ValueHwnd的内容

		DeleteObject((HBRUSH)SetClassLong(hwnd,GCL_HBRBACKGROUND,(LONG)CreateSolidBrush(RGB(color[0],color[1],color[2]))));//更换主窗口的背景画刷
		InvalidateRect(hwnd,&rcColor,true);//无效化显示区域,使颜色变化显示出来
		return 0;
	}

上面的代码就能实现了我们程序的基本功能,接下来就要美化静态子窗口的文字:

static RECT rcColor;//记录右边显示区域的大小
static HBRUSH hbrush[3],hbrushstatic;//对应美化静态窗口的3种颜色
static COLORREF colorPrim[3]={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255)};
else if(uimsg==WM_CTLCOLORSCROLLBAR)//lparam参数是控件窗口的句柄,wparam参数是控件窗口的hdc(所有WM_CTLCOLOR???这样的消息基本都是这样子)
{
	int id=GetWindowLong((HWND)lparam,GWL_ID);
	return (LRESULT)hbrush[id];
}
else if(uimsg==WM_CTLCOLORSTATIC)
{
	int id=GetWindowLong((HWND)lparam,GWL_ID);
	if(id>=3 && id<=8)
	{
		SetTextColor((HDC)wparam,colorPrim[id%3]);
		SetBkColor((HDC)wparam,GetSysColor(COLOR_BTNHIGHLIGHT));
		return (LRESULT)hbrushstatic;
	}
}

最后我们就要处理Tab的功能转移焦点:

首先在父窗口加如下代码:

else if (uimsg==WM_KEYDOWN)
	{
		return 0;
	}
并在这个消息里面设置断点,调试,我们可以发现当我们用鼠标拖动thumb的时候,滚动条也做出了相应的变化,但是我们再按键盘的时候程序依然会停在断点处,可以得出滚动条控件与button控件不一样,不会因为点击而得到焦点,我们按tab的时候应该把焦点传到滚动条控件去的,顺便可以增加按VK_UP这些键功能,不但如此,如果我们只是简单的在父窗口转移焦点,第一次转移还可以,但是第二次转移的时候tab这个keydown消息就传去子窗口控件中去了,我们有必要处理到控件的过程函数才行。


在创建完每个滚动条之后,把它的过程函数改变为我们自己弄的,并且保存之前的过程函数用于DefWindowProc同样的功能

OldScrollBarProc[i]=(WNDPROC)SetWindowLong(ScrollBarHwnd[i],GWL_WNDPROC,(LONG)ScrollBarProc);

在自己的滚动条过程函数里面处理自己感兴趣的消息:

LRESULT CALLBACK ScrollBarProc(HWND hwnd,UINT uimsg,WPARAM wparam,LPARAM lparam)
{
	int id=GetWindowLong(hwnd,GWL_ID);
	if(uimsg==WM_KEYDOWN)//处理Tab键的转移焦点
	{
		if(wparam==VK_TAB)
		{
			id=(id+1)%3;
			SetFocus(GetDlgItem(GetParent(hwnd),id));
		}
		else if(wparam==VK_UP)
			SendMessage(GetParent(hwnd),WM_VSCROLL,SB_LINEUP,(LPARAM)hwnd);
		else if(wparam==VK_DOWN)
			SendMessage(GetParent(hwnd),WM_VSCROLL,SB_LINEDOWN,(LPARAM)hwnd);
		return 0;
	}
	else if(uimsg==WM_SETFOCUS)
	{
		idFocus=id;
		return 0;
	}
	return CallWindowProc(OldScrollBarProc[id],hwnd,uimsg,wparam,lparam);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值