首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 有关SetTimer的问题!
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:00:46 楼主
    从网上找了一个Splash类,我修改了部分代码,让启动的时候画面慢慢的显示,而不是一下子把图片显示出来,建的是一个MFC工程CGD,添加了该类,并且在CGD.CPP中调用它:pCsw->ShowSplash();在Splash类中有OnPaint函数,我是这么写的:
    void CSplashWnd::OnPaint()
    {
    CPaintDC dc(this);
    if(FirstTime)
    {
    Bmp.LoadBitmap(160);
    CRect rc(0,0,0,0);
    //pic.Render(&dc, rc);
    pDC.CreateCompatibleDC (&dc);
    pDC.SelectObject (&Bmp);

    rBlendProps.BlendOp = AC_SRC_OVER;
    rBlendProps.BlendFlags = 0;
    rBlendProps.AlphaFormat = 0;

    BITMAP bmInfo;
    ::GetObject( Bmp.m_hObject, sizeof(BITMAP), &bmInfo );
    nWidth = bmInfo.bmWidth;
    nHeigh = bmInfo.bmHeight;
    int i = 0;
    /////while循环实现慢慢显示位图
    while(i  <= 255)
    {
    rBlendProps.SourceConstantAlpha = i;
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );
    i += 5;
    Sleep(20);
    }
    FirstTime = false;
    }
    else
    {
    ////////正常显示位图,不再需要慢慢显示
     AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth,nHeigh,rBlendProps );
    }
    }
    位图能够慢慢显示出,但是不能够刷新,即窗口被别的窗口覆盖一下后就看不到位图了,OnPaint在初始化调用一次后就没调用了,我也不知道怎么会这样。所以我想用一个SetTimer使其隔一段时间就刷新一下:强制调用OnPaint(),并且添加了消息映射ON_WM_TIMER(),重载了OnTimer:
    void CSplashWnd::OnTimer( UINT nIDEvent )
    {
    OnPaint();
    }
    可是仿佛定时器没有工作一样,OnTimer从来没有被调用。这是怎么回事呢?
    另外,SetTimer函数只要在初始化的任意一个函数里面调用一下是不是就可以开始记时工作了?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:02:181楼 得分:0
    顶呀,期盼大家回答和赐教啊!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:15:442楼 得分:0
    怎么没人回答呀……
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:24:503楼 得分:0
    你的settimer是否已添加,如果有settimer,哪么应该是添加的位置不对
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • kingmax54212008
    • 等级:
    发表于:2008-05-08 11:27:314楼 得分:0
    settimer是否Enable.再细看一下,其成员方法的用法。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:30:165楼 得分:0
    while(i   <= 255) 

    rBlendProps.SourceConstantAlpha = i; 
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps ); 
    i += 5; 
    Sleep(20); 
    //一直也退出,你的程序挂起


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:32:466楼 得分:0
    有SetTimer啊,
    int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
    // Center the window.
    CenterWindow();
    SetTimer(1,100,NULL);
    return 0;
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:33:417楼 得分:0
    什么意思呀?“一直也退出,你的程序挂起”
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:34:158楼 得分:0
    如何查看SetTimer是否enable?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:34:449楼 得分:0
    把你设置定时器的代码发上来啊。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:36:2710楼 得分:0
    刚刚发了,在6楼,我跟踪了一下,OnCreate函数先于OnPaint函数调用的,所以应该没什么问题吧?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:37:5811楼 得分:0
    哎,我拼命的按F5刷新该页面,希望得到大家的回答呀……急……
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:40:5312楼 得分:0
    从网上下的源程序中OnPaint函数是这么写的:
    void CSplashWnd::OnPaint()
    {
    if(fileIsValid)/////bool fileIsValid:用来判断位图文件是否存在及正确
    {
    CPaintDC dc(this);
    CRect rc(0,0,0,0);;
    pic.Render(&dc, rc);
    }
    }
    这样就不能实现慢慢显示,所以我改了里面的代码。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:48:5813楼 得分:0
    应该强制刷新,
    void CSplashWnd::OnTimer( UINT nIDEvent ) 

    OnPaint(); 
    Invalidate( 
    BOOL bErase = TRUE ); 

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    发表于:2008-05-08 11:58:2014楼 得分:0
    把while(i  <= 255)
    改成while(i  < 255)

    不需要定时。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    发表于:2008-05-08 12:00:1315楼 得分:0
    更正一下,应该用do-while循环
    do{
    } while(i  < 255);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 12:07:0216楼 得分:0
    为什么不需要定时呢?要是不定时那OnPaint只调用一次就结束了呀,我没发现它再次被调用。我想定时的目的就是要强制的去调用OnPaint函数啊、
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 12:09:4617楼 得分:0
    我的OnTimer都不能被调用了,那再往里面写什么也都没用了不是吗?
    如果OnTimer被调用的话我会试试你的强制刷新,看看能不能解决问题。谢谢了!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 12:18:2118楼 得分:0
    怎么又没人了呀,都吃饭去了?呵呵~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 12:44:0919楼 得分:0
    慢慢显示出来是个啥概念?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:01:2720楼 得分:0
    AnimateWindow(GetSafeHwnd(),1000,AW_ACTIVATE ¦AW_CENTER); 能实现不
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:10:5521楼 得分:0
    楼上能给一个范例么,不会用这个函数啊……
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:20:4822楼 得分:0
    SetTimer(1,100,OnTimer); 
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    发表于:2008-05-08 13:21:3423楼 得分:0
    while(i  <= 255)

    rBlendProps.SourceConstantAlpha = i; 
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps ); 
    i += 5; 
    Sleep(20); 

    这个循环不就是慢慢显示出来吗,为什么还要定时?
    当需要刷新的时候就不需要慢慢显示了吧?
    刷新的时候没有显示应该是因为rBlendProps.SourceConstantAlpha的值是260,所以我才建议你改成do...while(i <255)的形式。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:22:4024楼 得分:0
    最后一个变量为NULL不就默认调用OnTimer吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:28:0725楼 得分:0
    to cnzdgs:
    可能是我没说明白,因为程序运行后在初始化中的确调用了onpaint函数,也得到了慢慢显示出来(淡入的效果)的效果,但是后来就没发现有调用onpaint了,所以一旦被别的窗口覆盖一下,这个画面就没了,所以我想自己定时去调用onpaint函数。当然,如果你有方法能够让onpaint调用也可以,那就不需要定时器了。
    我也按你的改了一下,但是还是不行。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:43:3126楼 得分:0
    有两点要说得了:
    1。你保证你的timer可以正常运行.比如添加messagebox什么的,开测试了!
    2.你把onpaint中的动作放在ontimer中执行好了.在程序启动起来后,kill调这个timer了,呵呵! 
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:47:5527楼 得分:0
    强人!我也看了一下,发现OnTimer就从来没有被调用。难道是我settimer写错了?我在另一个类中也是这么写的啊,就没有出错。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 14:09:0828楼 得分:0
    顶呀,没人知道吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 14:18:0029楼 得分:0
    你的OnPaint函数里面的循环导致界面消息被阻塞。

    在OnTimer中逐渐改变透明度然后刷新,OnPaint中只要根据这个透明度来绘制就可以,而不是在OnPaint中循环计算,更不要OnPaint中Sleep。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 14:41:2730楼 得分:0
    to Mackz:
    哦,我试试看!谢谢!不过ontimer始终没有被调用呀,这是怎么回事呢?是因为你说的:“你的OnPaint函数里面的循环导致界面消息被阻塞。”吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 15:03:0631楼 得分:0

    void CSplashWnd::OnPaint() 
    {
    //去掉while那段
    //用一个成员或全局变量来控制你要画的图形的位置m_nDrawPos
    rBlendProps.SourceConstantAlpha = m_nDrawPos; 
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );  
    }

    void CSplashWnd::OnTimer( UINT nIDEvent ) 

    m_nDrawPos+=5;
    //去掉OnPaint(),改用
    Invalidate();
    UpdateWindow();
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    发表于:2008-05-08 15:14:5832楼 得分:0
    else 

    ////////正常显示位图,不再需要慢慢显示 
     AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth,nHeigh,rBlendProps ); 

    这个函数用到的各个参数都是在哪里定义的?你可以在这行代码上设置一个断点,查看一下各个参数的值是否正确,如果执行不到这个断点,则说明你响应消息的代码有问题,可能是执行了死循环或者处理时间过长。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 15:16:0433楼 得分:0
    to Mackz and weisite:
    你们提出的方案我试过了,还是不行,ontimer函数根本就没有被调用。而且onpaint还是调用了一次就没有了。onpaint中的if、else已经换为了一下的代码:
    if(FirstTime)
    {
    rBlendProps.SourceConstantAlpha = SourceConstantAlpha;
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );
    if(SourceConstantAlpha > 250)
    {
    FirstTime = false;
    }
    }
    else
    {
    rBlendProps.SourceConstantAlpha = SourceConstantAlpha;
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 15:21:3834楼 得分:0
    回复cnzdgs:
    各参数定义的地方:
    dc:在onpaint中,通过CPaintDC dc(this);
    nWidth, nHeigh ,pDC,rBlendProps 都定义为成员变量,只有pDC每次在onpaint中重新赋值,其他三个均在oncreate函数中初始化。贴上代码:
    int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
    // Center the window.
    CenterWindow();
    SourceConstantAlpha = 0;
    Bmp.LoadBitmap(160);
    CRect rc(0,0,0,0);
    //pic.Render(&dc, rc);
    rBlendProps.BlendOp = AC_SRC_OVER;
    rBlendProps.BlendFlags = 0;
    rBlendProps.AlphaFormat = 0;

    BITMAP bmInfo;
    ::GetObject( Bmp.m_hObject, sizeof(BITMAP), &bmInfo );
    nWidth = bmInfo.bmWidth;
    nHeigh = bmInfo.bmHeight;
    SetTimer(1,10,NULL);
    return 0;
    }
    void CSplashWnd::OnPaint()
    {
    CPaintDC dc(this);
    pDC.CreateCompatibleDC (&dc);
    pDC.SelectObject (&Bmp);
    if(fileIsValid)
    {
    rBlendProps.SourceConstantAlpha = SourceConstantAlpha;
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );
    if(SourceConstantAlpha > 250)
    {
    fileIsValid = false;
    }
    }
    else
    {
    rBlendProps.SourceConstantAlpha = SourceConstantAlpha;
    AlphaBlend( dc.m_hDC, 0, 0, nWidth, nHeigh, pDC.m_hDC, 0, 0, nWidth, nHeigh, rBlendProps );
    }
    }
    void CSplashWnd::OnTimer( UINT nIDEvent )
    {
    if(SourceConstantAlpha  < 255)
    {
    SourceConstantAlpha += 5;
    }
    Invalidate(); 
    UpdateWindow();
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 15:24:5835楼 得分:0
    是这样吧,呵呵!
    void CSplashWnd::OnTimer( UINT nIDEvent ) 

    OnPaint(); 
      CWnd::OnTimer(nIDEvent);

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天