Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5463337
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类: C/C++

2007-09-29 11:44:12

 

Introduction

I was searching for a technique to colorize the scroll bars of the windows of my application, to make the appearance of the UI a bit more attractive, especially for the UI that I developed in VC++. As you know, to get anything done in MFC, you need to do a lot of work. But, you can find mountains of resources on the Internet to help you do whatever you want. That's what I did to bring this article very close to a beginner VC++ developer's level. I will show you how to get a scroll bar attached statically to the application's main window and, more interestingly, how to colorize it.

Background (Technical Details)

According to the MSDN definition, the scroll bars let a user choose the direction and the distance to scroll through information in a related window. The scroll bars are of two types: horizontal and vertical respectively. At this moment, let me introduce the components of the scoll bar. If you take a standard vertical scroll bar, there are:

  • The top arrow button
  • The bottom arrow button
  • The scroll box (also called the scroll thumb)
  • The scroll area where the thumb floats

To be precise, this article shows you how to colorize the last item of the scroll bar—the scroll area.

Using the Code

You will attach your scroll bars to the main window frame of an SDI application and then see how to colorize them. The rest of the article will be in a tutorial style so you could learn the concepts clearly, and then, given a clue, you could also colorize the scroll bars of the child windows of an MDI app.

Step 1

Develop an MFC application of type Single Document Interface. Name the project as you want and accept all the default selections from the rest of the appwizard and click Finish. After getting the skeleton code from the appwizard, you will add some variables of type CScrollBar in your frame class. This you can do manually, as shown below.

class CMainFrame : public CFrameWnd
{
   private:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   CScrollBar myHScroll;
   CScrollBar myVScroll;
   CScrollBar myCutebox;
   CBrush m_brColor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   ...
   ...
};

Step 2

Create the scrollbars as usual after your frame is created in an OnCreate() handler of the frame window class:

int CMainFrame::OnCreate(...)
{
// code edited by the wizards by default ......
   ......
   ......
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   CRect rect(0,0,0,0);
   myHScroll.Create(WS_VISIBLE|WS_CHILD|SBS_HORZ, rect, this,
                    AFX_IDW_HSCROLL_FIRST);
   myVScroll.Create(WS_VISIBLE|WS_CHILD|SBS_VERT, rect, this,
                    AFX_IDW_HSCROLL_FIRST+1);
   myCutebox.Create(WS_VISIBLE|WS_CHILD|SBS_SIZEBOX, rect, this,-1);
   m_brColor.CreateSolidBrush(RGB(255,0,0));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   return 0;
}

As you can see in the preceding chunk of code, you also have to create a scroll bar box. This box is nothing but a little window that sets where the horizontal and vertical scroll bars meet each other.

Step 3

You also have to write code to resize the scroll bars as and when you resize your window. This is done in the overriden virtual function RecalcLayout(..), as shown below.

void CMainFrame::RecalcLayout(BOOL bNotify)
{
// must call the base class version before working with any child.
   CFrameWnd::RecalcLayout();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   CColorizedScrollsView* pView =
      (CColorizedScrollsView*)GetActiveView();
   if (pView)
   {
    CRect rect;
    pView->GetWindowRect(&rect);
    ScreenToClient(&rect);
    int cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
    int cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
    rect.right -= cxVScroll;
    rect.bottom -= cyHScroll;
    pView->MoveWindow(rect)
    rect.left = rect.right;
    rect.right += cxVScroll;
    myVScroll.MoveWindow(rect);
    rect.left = 0;
    rect.right -= cxVScroll;
    rect.top = rect.bottom;
    rect.bottom += cyHScroll;
    myHScroll.MoveWindow(rect);
    rect.left = rect.right;
    rect.right +=cxVScroll;
    myCuteBox.MoveWindow(rect);
   }// if
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
}

Step 4

Finally, put the color into the scroll area. Because this can only be done by handling the WM_CTLCOLOR window message, a color notification is sent by every child window to its parent container window. Here it is.

HBRUSH CMainFrame::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
   HBRUSH hbr = CFrameWnd::OnCtlColor(pDC, pWnd, nCtlColor);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   if(nCtlColor==CTLCOLOR_SCROLLBAR)
      return m_brColor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
   return hbr;
}

Step 5

Don't forget to # include the header files in the frame CPP file that is in the MainFrm.cpp; for example,

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
#include "ColorizedScrollsDoc.h"
#include "ColorizedScrollsView.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>

That'sall. Compile and execute the code to get the colorized scroll bars displayed in your app's window.

Notes

  1. In this article, I have not discussed how the scroll bars work to scroll the contents. This is a kind of Doc/View topic. Basically, to the scroll bars in action, you must handle WM_HSCROLL and WM_VSCROLL messages. It is left to you as an exercise.
  2. I promised above that I will give a clue about using this article with MDI applications. As you know MDI, contains the child frame windows within a main frame. So, the scroll bars would appear in the child frames instead of the main frame. You just have to remember that whatever you did above in Main Frame class, instead you will do the same in the Child Frame class. In addition, you have to remember two things. One is that the Appwizard doesn't automatically write the OnCreate(..) handler in the Child Frame class; you have to do it yourself. The second is that when you run the app, the scroll bars will not be seen anywhere. To get them to show, you have to maximize the child window. Or, you have to handle WM_SHOWWINDOW message by saying:

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
    ShowWindow(SW_SHOWMAXIMIZED);
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
    
  3. I have provided the source code that can be either opened/compiled/executed by the MS VC++ 6.0 editor or by the MS VisualStudio.NET editor, as I have provided seperate .dsp files and the .dsw file for the former and .sln file for the latter.
  4. If you are VC++ 6.0 developer, you have to write the WM_CTLCOLOR message handler, its prototype, and an entry in the message map all by yourself because the Class Wizard doesn't list this message. Do like this, you just copy the same from the sample code above into your frame class' header and implementation files respectively.

That's to say finished. Have a nice programming experience....
Please don't forget to rate this article....

About the Author
Habeeballah is a full-time employee working with Visual C++.Net to provide Systems, Network & Computer-Telephony solutions at a leading software development company of Sana'a, the capital city of The Republic of Yemen. He started programming with Visual C++ 5.0 back in 1998, and have loved it since then and forever. A good slogan : "There is no substitute for Hard Work".

Downloads

  • - Demo project executables both on VC++ 6.0 and VC++.Net runtimes
  • - Source Code editable with both VC++6.0 and VC++.Net IDEs
  • 阅读(1252) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~