·天新网首页·加入收藏·设为首页
首页|笔记本|手机|数码相机|摄像机|MP3/MP4|主板|内存|显示器|办公|打印机|下载|开发|汽车|学院|业界
硬件|台式机|数码|数字家庭|投影仪|GPS/CPU|显卡|硬盘|服务器|网络|一体机|驱动|源码|游戏|考试|报价
您现在的位置:天新网 > 软件开发 > 开发语言 > VC开发
Windows 界面设计:拉帘按钮设计
http://dev.21tx.com 2005年05月06日 放飞技术网

大家一定都用过Oicq,是不是觉得里面的拉帘按钮很炫,就是当我们点击好友,陌生人或黑名单时所需的内容就会自动出现在主窗口中,其中按钮有一种被拉起或拉下的感觉。现在我就叫大家作这种特效。

第一:创建

启动Visual C++ =〉New Project => MFC AppWizard(exe) 假定AppName为Oicq

在Step 1中选SDI,在Step 4中不选tool bar,status bar,printing选项,因为用不着。其余各步均按默认选项,创建了一个标准的SDI模板。

第二:设计初始大小和窗口风格

在CMainFrame::PreCreateWindow(CREATESTRUCT& cs)函数中加如下语句

cs.style=WS_OVERLAPPEDWINDOW;//标准窗口类型
cs.lpszName=_T("QQ");        //标题
cs.hMenu=NULL;               //取消菜单
cs.cx=100;                   //初始宽100pixels
cs.cy=700;                   //初始长700pixels

真么样,有点样子了吧,这只是刚开始,好戏还在后头,慢慢来。

第三:添加按钮

在COicqView中加入三个Button变量

CButton myButton1;
CButton myButton2;
CButton myButton3;

在COicqView中添加消息函数OnCreate(LPCREATESTRUCT lpCreateStruct),添加方法不在详述,利用ClassWizard。以后的消息函数均由ClassWizard添加。在OnCreate中加入下列语句

myButton1.Create(_T("好友"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
CRect(0,0,100,20),this,IDC_BUTTON_GOODFRIEND);
//创建好友按钮
myButton2.Create(_T("陌生人"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
CRect(0,20,100,40),this,IDC_BUTTON_STRANGER);
//创建陌生人按钮
myButton3.Create(_T("黑名单"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
CRect(0,40,100,60),this,IDC_BUTTON_BLACKLIST);
//创建黑名单按钮

记住在Resource.h中定义
#define IDC_BUTTON_GOODFRIEND 150
#define IDC_BUTTON_STRANGER 151
#define IDC_BUTTON_BLACKLIST 152

下面加入按钮消息映射,在COicqView中加入三个函数GoodFriend(),Stranger(),BlackList(),分别处理单击三个按钮的消息。
afx_msg void GoodFriend();
afx_msg void BlackList();
afx_msg void Stranger();

在OicqView.cpp中加映射
ON_BN_CLICKED(IDC_BUTTON_GOODFRIEND, GoodFriend)
ON_BN_CLICKED(IDC_BUTTON_STRANGER, Stranger)
ON_BN_CLICKED(IDC_BUTTON_BLACKLIST, BlackList)
注意添加位置,在BEGIN_MESSAGE_MAP(COicqView, CView)和END_MESSAGE_MAP()之间。

第四:准备移动

这一步是关键的一步,它为以后的工作打好基础,在我看来这是非常重要的,要想清楚以后的需要。
1.添加相关宏定义到OicqView.h
#define UP 1        //定义按钮状态
#define DOWN 2
2.添加状态变量
int GoodFriendState;
int BlackListState;
int StrangerState;
3.添加三个CRect变量来表示三个按钮的位置
CRect Button1_Rect;
CRect Button2_Rect;
CRect Button3_Rect;
4.添加一个CSize的变量来表示客户区大小
SIZE OldClientSize;
5.初始化各变量在OnCreate函数中
OldClientSize.cx=100;
OldClientSize.cy=669;
GoodFriendState=UP;
StrangerState=UP;
BlackListState=UP;
6.在COicqView中添加函数GetPosition()来获得各个按钮的当前位置
void COicqView::GetPosition()
{
this->myButton1.GetWindowRect(&Button1_Rect);//获得窗口坐标
ScreenToClient(&Button1_Rect);               //转化Client坐标
this->myButton2.GetWindowRect(&Button2_Rect);
ScreenToClient(&Button2_Rect);
this->myButton3.GetWindowRect(&Button3_Rect);
ScreenToClient(&Button3_Rect);

}
7.在OnCreate()中添加GetPosition()

第五:移动

这里只介绍GoodFriend函数的算法,Stranger函数和BlackList函数类似,详见代码下载

void COicqView::GoodFriend()
{
    int i;
    switch(StrangerState)
    {
    case UP:
        switch(BlackListState)
        {       
        case UP:
            for(i=Button3_Rect.top;i<=OldClientSize.cy-Button3_Rect.Height();i++)
            {
                myButton3.MoveWindow(Button3_Rect.left,i,Button3_Rect.Width(),Button3_Rect.Height(),1);
                ValidateRect(CRect(Button3_Rect.left,i-1,Button3_Rect.right,i));
                myButton2.MoveWindow(Button2_Rect.left,i-Button2_Rect.Height(),
                    Button2_Rect.Width(),Button2_Rect.Height(),1);
                ValidateRect(CRect(Button3_Rect.left,i-Button2_Rect.Height()-1,Button3_Rect.right,i));
             }
            this->GetPosition();
            StrangerState=DOWN;
            BlackListState=DOWN;
            break;
            case DOWN:
            for(i=Button2_Rect.top;i<=Button3_Rect.top-Button2_Rect.Height();i++)
            {
                myButton2.MoveWindow(Button2_Rect.left,i,Button2_Rect.Width(),Button2_Rect.Height());
                ValidateRect(CRect(Button2_Rect.left,i-1,Button2_Rect.right,i));
            }
            this->GetPosition();
            StrangerState=DOWN;
            break;
        }
        case DOWN:
            break;
    }

}

两个关键函数
BOOL MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE );
BOOL ValidateRect( LPCRECT lpRect );
只要在准备移动部分都看懂了,这是一段不难懂的代码。关键是在MoveWindow后,要用ValidateRect使移动后的空白区域变为有效区。

第六:OnSize函数

运行后不难发现当改变窗口大小时按钮却大小不变,解决方法,添加OnSize消息函数用ClassWizard,在OnSize中加如下代码即时更新按钮大小。

void COicqView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);
    if(cx!=OldClientSize.cx)
    {
        myButton1.MoveWindow(Button1_Rect.left,Button1_Rect.top,cx,Button1_Rect.Height());
        myButton2.MoveWindow(Button2_Rect.left,Button2_Rect.top,cx,Button2_Rect.Height());
        myButton3.MoveWindow(Button3_Rect.left,Button3_Rect.top,cx,Button3_Rect.Height());
    }
    this->GetPosition();
    if(cy!=OldClientSize.cy)
    {
        if(DOWN==BlackListState)
        {
            myButton3.MoveWindow(Button3_Rect.left,cy-Button3_Rect.Height(),Button3_Rect.Width(),Button3_Rect.Height());
        }
        if(DOWN==StrangerState)
        {
            myButton2.MoveWindow(Button2_Rect.left,cy-Button3_Rect.Height()-    Button2_Rect.Height(),Button2_Rect.Width(),Button2_Rect.Height());
        }
    }
    OldClientSize.cx=cx;
    OldClientSize.cy=cy;
    this->GetPosition();
}
 
现在万事OK了,不难吧!

上一篇: 为什么要学Win32及Win32程序框架
下一篇: 多进程编程的相关知识总结(二)

Google
 
热点文章
关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net