COLORS1 代码分析

来源:互联网 发布:维克兰特号航母知乎 编辑:程序博客网 时间:2024/06/04 19:08

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

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


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

static HWND ScrollBarHwnd[3],LabelHwnd[3],ValueHwnd[3],RectHwnd;//10个子窗口控件static int color[3];//记录3个滚动条的thumb的posstatic 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);}




0 0
原创粉丝点击