用Win32API写的一个幻灯片公映器(自动播放,没有交互),不知道为什么播放完一轮位图后不能够再次循环播放。具体框架如下

用Win32API写的一个幻灯片放映器(自动播放,没有交互),不知道为什么播放完一轮位图后不能够再次循环播放。具体框架如下
本帖最后由 VisualEleven 于 2015-04-28 13:28:06 编辑
我想要实现这样一个功能: 用Win32程序创建一个程序,它能够自动的显示一张位图,然后每隔几秒更换一张图片,像放幻灯片一样,放完最后一张图片后,自动循环回来开始放第一张图片

我的大致框架是这样的(部分重点代码):

先编写了一个位图类,用于存放位图数据

class Bitmap{                      //位图类,每一个对象对应一张位图
protected:
HBITMAP hBitmap; //位图句柄
int iWidth, iHeight;
void Free(); 
public:
Bitmap();
Bitmap(HINSTANCE hInst,HDC hdc,LPCSTR szFileName);    //从文件中读取位图
Bitmap(HINSTANCE hInst, HDC hdc, UINT uiResID);   //从资源中加载位图
~Bitmap();


BOOL Create(HINSTANCE hInst,HDC hdc, LPCSTR szFileName); //从文件中读取位图(位图不会被链接进EXE文件)
BOOL Create(HINSTANCE hInst, HDC hdc, UINT uiResID); //从资源中加载位图(位图会被链接进EXE文件)
BOOL Create(HDC hdc,COLORREF crColor);
void Draw(HWND hWnd,HDC hdc);
int GetWidth();
int GetHeight();
};   //我暂时没有用上位图的高度和宽度数据,我都是直接创建的具体大小的位图,同时创建符合其大小的窗口

Draw方法用于将位图绘制到屏幕上


然后定义了一个指针数组

const int g_iNumSlides = 9;      
Bitmap* g_pSlides[g_iNumSlides];    //指针数组,用于遍历位图对象
int g_iCurSlide;
//g_iCurSlide用于之后遍历该数组,作为动态下标

用new的方法指向每一张位图
//创建并加载幻灯片位图
HDC hdc = GetDC(hWnd);
g_pSlides[0] = new Bitmap(g_hInstance, hdc, IDB_SUN0);
g_pSlides[1] = new Bitmap(g_hInstance, hdc, IDB_SUN1);
g_pSlides[2] = new Bitmap(g_hInstance, hdc, IDB_SUN2);
g_pSlides[3] = new Bitmap(g_hInstance, hdc, IDB_SUN3);
g_pSlides[4] = new Bitmap(g_hInstance, hdc, IDB_SUN4);
g_pSlides[5] = new Bitmap(g_hInstance, hdc, IDB_SUN5);
g_pSlides[6] = new Bitmap(g_hInstance, hdc, IDB_SUN6);
g_pSlides[7] = new Bitmap(g_hInstance, hdc, IDB_SUN7);
g_pSlides[8] = new Bitmap(g_hInstance, hdc, IDB_SUN8);
ReleaseDC(hWnd, hdc);

//设置第一个幻灯片
g_iCurSlide = 0;

然后有两个特别的函数GamePaint和Gamecycle

void GamePaint(HWND hWnd,HDC hdc){   
//绘制当前幻灯片位图
g_pSlides[g_iCurSlide]->Draw(hWnd, hdc);

}

void Gamecycle(){
/*static int iDelay = 0;
//设置转到下一个幻灯片之前的3秒延迟
if (++iDelay > 3){
//恢复延迟计数器
iDelay = 0;
//移动到下一张幻灯片
*/
if (++g_iCurSlide == g_iNumSlides)
g_iCurSlide = 0;
//强制重新绘制,以便绘制下一个幻灯片
InvalidateRect(g_pGame->GetWindow(), NULL, FALSE);



}

GamePaint在WM_PAINT消息中
case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
//绘制游戏
GamePaint(hWnd, hdc);
EndPaint(hWnd, &ps);
return 0;

Gamecycle在主函数消息循环中,

while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//处理消息
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
//确保游戏引擎没有休眠
if (!GameEngine::GetEngine()->GetSleep()){
//检查滴答计数,查看是否过了一个游戏周期
iTickCount = GetTickCount();
if (iTickCount > iTickTrigger){
iTickTrigger = iTickCount + GameEngine::GetEngine()->GetFrameDelay();
Gamecycle();
}

并且Gamecycle用InvalidateRect发送WM_PAINT消息

然后程序运行的结果是显示了一轮图片,但是最后停在了最后一张就不在更新了

并且最后的时候我想要测试程序是否还在持续发送WM_PAINT消息的时候,就最大最小化,然后图片就不见了,变成了空白,也没有重绘,所以最后应该是没有在发送WM_PAINT消息了。。


就是不知道问题在哪。。调试也不知道怎么调试啊。。


简单的说就是  按理说能够持续发送WM_PAINT的并且重绘窗口,,但是不知道为什么遍历了一次位图数组就停下来了

有点长,,有大神能耐心看完吗。。我是用VS2013的,,如果有大神想要整个解决方案看看的,,可以回复我,加我

------解决思路----------------------
将你的程序分一下模块:播放管理、图像指针管理
播放部分不需要知道放到哪,只要处理图像指针给的图块就行了,指针管理部分就可以通过指针位置处理各种播放方式。
------解决思路----------------------

if (!GameEngine::GetEngine()->GetSleep()){

------解决思路----------------------
// if (iTickCount > iTickTrigger)
{
                        iTickTrigger = iTickCount + GameEngine::GetEngine()->GetFrameDelay();
                        Gamecycle();
                    }