标题:利用定时器循环播放图片
只看楼主
小赵q1
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:492
专家分:777
注 册:2011-8-26
结帖率:100%
已结贴  问题点数:100 回复次数:17 
利用定时器循环播放图片
写的程序里需要点击按钮启用定时器循环显示图片形成动画效果,找到的例子上是先使用  for  循环加载位图,获取设备上下文,创建兼容DC,创建定时器,加载位图到兼容DC,利用  for  循环显示图片,(这里的循环显示图片是放在创建窗口后面的,作用是显示窗口就有图片显示在上面),在WM_TIMER里面的步骤是加载位图到兼容DC,循环显示位图(这里的作用是循环显示图片,达到了动画效果);
在WM_PAINT 里面的步骤是加载位图到兼容DC,循环显示位图(这里的作用是保证位图不被重绘掉)。
我的问题是如果在点击按钮以后播放动画跟上面的步骤是一样的,可是我的创建兼容DC是在创建窗口后面的(mdc),别的位图显示也是在控件被单击后才显示的,先定义HDC xiaoDC,
然后xiaoDC=CreateCompatibleDC(NULL);
接着把位图加载到这个兼容DC里面,并显示,显示的目标 DC 是 mdc ,源 DC 是 xiaoDC ,在PAINT里面只用把 mdc 的内容显示在 hdc 上就可以了,
为什么播放动画的图片也这样显示就不可以呢?
我在CREATE消息里加载的那些图片,然后在点击控件事件后根据别的位图显示的方法定义了个 HDC xunhuanDC;然后 xunhuanDC=CreateCompatibleDC(NULL);
接着创建了个定时器,然后就是显示位图从 xunhuanDC 到 mdc 。如果在TIMER里面也要加载位图到兼容DC里面然后显示位图从兼容 DC 到 mdc 的话,是不是也要像在控件里面那样先定义一个HDC,然后xunhuanDC=CreateCompatibleDC(NULL);这样呢?
因为在PAINT里面有了显示 mdc 的内容到 hdc 上,是不是在这里就不用有像例子上的那样再显示一遍图片了呢?
想象的是这样的,结果试了好多次都不能把动画的图片显示在窗口上。希望有人能帮我分析下。
shiyan.rar (3.84 KB)


[ 本帖最后由 小赵q1 于 2012-9-7 22:30 编辑 ]
搜索更多相关主题的帖子: 上下文 
2012-09-05 22:24
stophin
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:227
专家分:618
注 册:2010-3-26
得分:10 
先mark一下下
2012-09-06 09:37
小赵q1
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:492
专家分:777
注 册:2011-8-26
得分:0 
回复 2楼 stophin
什么是mark呢?俺的英文不是一般的差

[ 本帖最后由 小赵q1 于 2012-9-6 13:23 编辑 ]
2012-09-06 13:20
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
得分:10 
工程能传上来吗
2012-09-07 08:53
小赵q1
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:492
专家分:777
注 册:2011-8-26
得分:0 
回复 4楼 寒风中的细雨
工程已经上传。谢谢
2012-09-07 22:30
stophin
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:227
专家分:618
注 册:2010-3-26
得分:10 
回复 3楼 小赵q1
mark就是标记一下以后好找的意思
我看了程序就不想改了--从没看到把宏名和全局变量名搞成一样的程序
不得不佩服,楼主竟然能编译通过!我找了好久一直是
ignored on left of 'int' when no variable is declared
syntax error : missing ';' before 'constant'
unexpected end of file found
错误,原来是zongfen搞的鬼
然后程序里,究竟用的是宏呢,还是全局变量呢,我不是楼主所以不知道,编译器更不知道
还希望楼主自己改一下
2012-09-08 08:52
小赵q1
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:492
专家分:777
注 册:2011-8-26
得分:0 
回复 6楼 stophin
你好,那个宏名是按钮的标记因为那个按钮是表示总数都所以定义zongfen了,没有注意到与下面的全局变量重名了,宏名那里定义成zongshu吧,点击按钮事件那里当然也要改一下,因为是根据程序需要临时写的一个例子程序在网吧编译器也打不开所以就没有调试,出现这样的错误确实是疏忽了。
楼上能帮我解决下遇到的问题吗?
2012-09-08 13:46
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
得分:60 
程序代码:
#include <windows.h>
#include <strsafe.h>
#include "resource.h"
#define BTN_START    (1)//启动按钮ID
#define BTN_END        (2)//
#define BUF_SIZE    (40)//文件名缓冲区大小
#define BMP_COUNT    (10)//位图的数量
#define ID_TIMER    (1)//定时器ID

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam,LPARAM lParam)
{
    static HBITMAP hBitMap[BMP_COUNT];//位图句柄
    static BITMAP bitMap[BMP_COUNT];//位图信息
    static int cxClient, cyClient, i;
    TCHAR szBmpName[BUF_SIZE] = {0};
    PAINTSTRUCT ps;
    HDC hdc, mdc;
    switch (msg)
    {
    case WM_CREATE:
        for (i = 0; i < BMP_COUNT; ++i)
        {//获取位图信息
            StringCchPrintf(szBmpName, _countof(szBmpName), TEXT("%d.bmp"),i);
            hBitMap[i] = (HBITMAP)LoadImage(NULL, szBmpName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
            GetObject(hBitMap[i], sizeof(BITMAP), &bitMap[i]);
        }
        CreateWindow(TEXT("button"),
                 TEXT("开始"),
                 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                 0, 0, 40, 20,
                 hwnd,
                 (HMENU) BTN_START,
                 ((LPCREATESTRUCT)lParam)->hInstance,
                 0);
        CreateWindow(TEXT("button"),
                TEXT("结束"),
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                0, 21, 40, 20,
                hwnd,
                (HMENU) BTN_END,
                ((LPCREATESTRUCT)lParam)->hInstance,
                0);
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case BTN_START:
            SetTimer(hwnd, ID_TIMER, 1000, NULL);
            break;
        case BTN_END:
            KillTimer(hwnd, ID_TIMER);
            break;
        }
    case WM_TIMER:
        hdc = GetDC(hwnd);
        mdc = CreateCompatibleDC(hdc);
        i %= BMP_COUNT;
        SelectObject(mdc, hBitMap[i]);
        BitBlt(hdc, (cxClient - bitMap[i].bmWidth) / 2,
            (cyClient - bitMap[i].bmHeight) / 2, bitMap[i].bmWidth,
            bitMap[i].bmHeight, mdc, 0, 0, SRCCOPY);
        DeleteDC(mdc);
        DeleteDC(hdc);
        ++i;
        break;

    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd,&ps);
        mdc = CreateCompatibleDC(hdc);
        i %= BMP_COUNT;
        SelectObject(mdc, hBitMap[i]);
        BitBlt(hdc, (cxClient - bitMap[i].bmWidth) / 2,
            (cyClient - bitMap[i].bmHeight) / 2, bitMap[i].bmWidth,
            bitMap[i].bmHeight, mdc, 0, 0, SRCCOPY);
        EndPaint(hwnd,&ps);
        DeleteDC(mdc);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int iCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;


    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  //主窗口客户区内的背景颜色,这里是黑色。
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);  //鼠标在客户区内的形状。
    wndclass.hIcon = LoadIcon(hInstance,(LPCTSTR)IDI_ICON1);  //窗口最小化的图标,这里的图标是金钟。
    wndclass.hInstance = hInstance;  //应用程序实力的句柄由WinMain函数传进来.
    wndclass.lpfnWndProc = WndProc;  //指明回调函数,要回调自己定义的那个函数,发生消息过程的那个函数。
    wndclass.lpszClassName = TEXT("chuangkou001"); //给自己设计的窗口类注册一个类名,后面创建窗口直接调用这个类名就能显示自己设置的特征。
    wndclass.lpszMenuName = NULL;  //系统菜单,如系统、帮助等左上角的下拉菜单,没有就用NULL代替。
    wndclass.style = CS_HREDRAW | CS_VREDRAW;  //类的样式,可以是任何组合。
    if(! RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("注册类失败"), TEXT("错误"),MB_OK);
        return -1;
    }

    //创建窗口
     hwnd = CreateWindow(TEXT("chuangkou001"),
                         TEXT("动画窗口"),
                         WS_OVERLAPPEDWINDOW,
                         10,0,711,800,
                         NULL,
                         NULL,
                         hInstance,
                         NULL);
    if(!hwnd)   //如果窗口创建失败,弹出提示窗口。
    {
      MessageBox(NULL, TEXT("创建窗口失败"), TEXT("错误"), MB_OK);
      return -1;
    }
    //显示并刷新窗口
    ShowWindow(hwnd,SW_SHOWNORMAL);
    UpdateWindow(hwnd);
    //消息循环。
    while(GetMessage(&msg, NULL, 0, 0) >0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
2012-09-09 01:50
寒风中的细雨
Rank: 17Rank: 17Rank: 17Rank: 17Rank: 17
等 级:贵宾
威 望:66
帖 子:1710
专家分:8645
注 册:2009-9-15
得分:0 
上传不了附件
程序代码:
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(中华人民共和国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
    "resource.h\0"
END
2 TEXTINCLUDE
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END
3 TEXTINCLUDE
BEGIN
    "\r\n"
    "\0"
END
#endif    // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_BITMAP1             BITMAP                  "0.bmp"
IDB_BITMAP2             BITMAP                  "1.bmp"
IDB_BITMAP3             BITMAP                  "2.bmp"
IDB_BITMAP4             BITMAP                  "3.bmp"
IDB_BITMAP5             BITMAP                  "4.bmp"
IDB_BITMAP6             BITMAP                  "5.bmp"
IDB_BITMAP7             BITMAP                  "6.bmp"
IDB_BITMAP8             BITMAP                  "7.bmp"
IDB_BITMAP9             BITMAP                  "8.bmp"
IDB_BITMAP10            BITMAP                  "9.bmp"
//IDB_BEIJING             BITMAP                  "bitmap11.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1               ICON                    "icon1.ico"
#endif    // 中文(中华人民共和国) resources
/////////////////////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

2012-09-09 01:54
小赵q1
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:492
专家分:777
注 册:2011-8-26
得分:0 
看了你的方法,原来需要点击控件显示动画,在点击控件的事件里只用放个定时器就可以了,加载图片可以放在创建窗口时的消息里,在TIME事件里循环显示图片达到动画的效果,在PAINT事件里循环显示图片达到被重绘后仍然显示不会在下一张图片显示之前还是空白的效果。
你是直接把图片加载到兼容DC了,然后把兼容DC的内容显示在hdc上了,我的那个例子是用的双缓存,两个兼容DC,那样的话我在点击控件事件里步骤如下:
    1.定义兼容DC变量;   HDC  xunhuanDC;
    2.创建兼容DC;        xunhuanDC=CreateCompatibleDC(NULL);
    3.放个定时器;       SetTimer(hwnd,1,500,NULL);
    3.循环把图片加载到兼容DC里;   SelectObject(xunhuanDC,DONGHUA[zhang]);
    4.显示兼容DC的内容到全局变量的兼容DC;  BitBlt(myhdc,235,347,Dong.bmWidth,DongbmHeight,xunhuanDC,0,0,SRCCOPY);
在TIME事件里把全局变量的兼容DC的内容显示在hdc上,BitBlt(hdc, 0, 0, Bmp.bmWidth, Bmp.bmHeight, myhdc, 0, 0, SRCCOPY);
在PAINT事件里那句保持不变:BitBlt(hdc, 0, 0, Bmp.bmWidth, Bmp.bmHeight, myhdc, 0, 0, SRCCOPY);
例子里的程序关于动画的就是这一部分了,这样是不是达不到显示动画的效果呢?不用双缓存的话楼上的确实是个好办法,
希望大家帮忙解答一下。
2012-09-09 13:50



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-380794-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.809820 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved