运行到一段时间,就卡的不得了。
位图已经提前载入
HDC backImage=CreateCompatibleDC(NULL);
HDC heroImage=CreateCompatibleDC(NULL);
BITMAP backbm;
BITMAP herobm;
HBITMAP heroBitmap;
HBITMAP backBitmap;backBitmap=(HBITMAP)LoadImage(NULL,"pic\\hero1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
SelectObject(backImage,backBitmap);
GetObject(backBitmap,sizeof(backbm),&backbm);heroBitmap=(HBITMAP)LoadImage(NULL,"pic\\hero.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
SelectObject(heroImage,heroBitmap);
GetObject(heroBitmap,sizeof(herobm),&herobm);主循环是这样的:
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!GetMessage(&msg,NULL,0,0))
{
return msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Mytimer();
MyGetMessage();
MyFrame();
          }Mytimer()函数如下
int Mytimer()
{
HANDLE hTimer=NULL;
LARGE_INTEGER liDueTime;
liDueTime.QuadPart=-100000;
hTimer=CreateWaitableTimer(NULL,TRUE,"timer");
SetWaitableTimer(hTimer,&liDueTime,0,NULL,NULL,0);
if(WaitForSingleObject(hTimer,INFINITE)==WAIT_OBJECT_0)
{
return 1;
CloseHandle(hTimer);
}else
{
return 0;
}
CloseHandle(hTimer);
}刷新页面函数是Myframe()
void MyFrame()
{
HDC hdc;
hdc=GetDC(hWnd);
RECT rect;
RECT rectback={0,0,MAXWIDTH,MAXHEIGHT};
if(lpDDSBack->GetDC(&hdc)==DD_OK)
{
GetWindowRect(hWnd,&rect);
rect.left+=GSM_CXBORDER;
rect.top+=GSM_CAPTION+GSM_CYBORDER+GSM_CYMENU;
rect.right-=GSM_CXBORDER;
rect.bottom-=GSM_CYBORDER;
FillRect(hdc,&rectback,(HBRUSH)GetStockObject(BLACK_BRUSH)); BitBlt(hdc,0,0,backbm.bmWidth,backbm.bmHeight,backImage,0,0,SRCCOPY);
BitBlt(hdc,x,y,herobm.bmWidth,herobm.bmHeight,heroImage,0,0,SRCCOPY);
lpDDSBack->ReleaseDC(hdc);
}
lpDDSPrimary->Blt(&rect,lpDDSBack,&rectback,DDBLT_WAIT,NULL);
ReleaseDC(hWnd,hdc);
DeleteDC(hdc);
}

解决方案 »

  1.   

    会不会多次载入位图?
    lpDDSPrimary->Blt(&rect,lpDDSBack,&rectback,DDBLT_WAIT,NULL);
    ReleaseDC(hWnd,hdc);
    DeleteDC(hdc);
    最后一句DeleteDC(hdc);不用了,get对应ReleaseDC,create才对应delete
      

  2.   

    if(WaitForSingleObject(hTimer,INFINITE)==WAIT_OBJECT_0)
    {
    return 1;
    CloseHandle(hTimer);
    }
    这段代码,有意思,你都return 了,如何close?
      

  3.   

    CreateWaitableTimer了多个,却从没有CloseHandle
      

  4.   

    用任务管理器看看,是否GDI资源、内存或者句柄有没有特别的增多!有可能是其它原因
      

  5.   

    完整的代码是这样的,timer那个就不贴了。
    没有多少东西,小弟第一次接触win32编程,很多地方都模模糊糊的,有什么见笑的地方请大大们谅解#include "stdafx.h"
    #include "resource.h"
    #include "timer.h"
    /*宏定义*/#define GSM_CAPTION GetSystemMetrics(SM_CYCAPTION)
    #define GSM_CXBORDER GetSystemMetrics(SM_CXFIXEDFRAME)
    #define GSM_CYBORDER GetSystemMetrics(SM_CYFIXEDFRAME)
    #define GSM_CYMENU GetSystemMetrics(SM_CYMENU)
    #define MAXWIDTH 800
    #define MAXHEIGHT 600/*函数及变量初始化*/HWND hWnd;
    HDC backImage=CreateCompatibleDC(NULL);
    HDC heroImage=CreateCompatibleDC(NULL);
    BITMAP backbm;
    BITMAP herobm;
    HBITMAP heroBitmap;
    HBITMAP backBitmap;
    LPDIRECTDRAW lpDD=NULL;
    LPDIRECTDRAWSURFACE lpDDSPrimary=NULL;
    LPDIRECTDRAWSURFACE lpDDSBack=NULL;
    LPDIRECTDRAWCLIPPER lpDDClipper=NULL;BOOL InitDDraw(void);
    void MyFrame();
    void MyGetMessage();
    ATOM MyRegisterClass(HINSTANCE);
    BOOL InitWindow(HINSTANCE,int);
    LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
    static int x=375;
    static int y=275;
    static int npcx=400;
    static int npcy=200;
    static int step=10;
    static int flag=1;
    /*主窗口显示*/
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    /* 预先载入位图*/ backBitmap=(HBITMAP)LoadImage(NULL,"pic\\hero1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    SelectObject(backImage,backBitmap);
    GetObject(backBitmap,sizeof(backbm),&backbm); heroBitmap=(HBITMAP)LoadImage(NULL,"pic\\hero.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    SelectObject(heroImage,heroBitmap);
    GetObject(heroBitmap,sizeof(herobm),&herobm); MSG msg;
    MyRegisterClass(hInstance);
    if(!InitWindow(hInstance,nCmdShow))
    {
    return FALSE;
    }
    if(!InitDDraw())
    {
    MessageBox(hWnd,"初始化DirectDraw出错","Error",MB_OK);
    DestroyWindow(hWnd);
    return FALSE;
    }
    while(1)
    {
    if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
    {
    if(!GetMessage(&msg,NULL,0,0))
    {
    return msg.wParam;
    }
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    MyGetMessage();
    MyFrame();
    }
    ReleaseDC(hWnd,heroImage);
    ReleaseDC(hWnd,backImage);
    return msg.wParam;
    } /*注册窗口类*/ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    WNDCLASS wc; wc.style=CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc=(WNDPROC)WinProc;
    wc.cbClsExtra=0;
    wc.cbWndExtra=0;
    wc.hInstance=hInstance;
    wc.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName=LPCSTR(IDR_MENU1);
    wc.lpszClassName="test"; return RegisterClass(&wc);
    }/*初始化窗口*/BOOL InitWindow(HINSTANCE hInstance,int nCmdShow)
    { hWnd=CreateWindowEx(0,
    "test",
    "test",
    WS_OVERLAPPEDWINDOW,
    0,
    0,
    800,
    600,
    NULL,
    NULL,
    hInstance,
    NULL); if(!hWnd) 
    {
    return FALSE;
    }
    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;}/*窗口消息处理*/LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    switch(message)
    {
    case WM_DESTROY:
    {
    PostQuitMessage(0);
    break;
    }
    default:
    {
    return DefWindowProc(hWnd,message,wParam,lParam);
    }
    }
    return 0;
    }/*初始化DirectDraw*/BOOL InitDDraw()
    {
    DDSURFACEDESC ddsd;
    if(DirectDrawCreate(NULL,&lpDD,NULL)!=DD_OK)
    {
    return FALSE;
    }
    if(lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL)!=DD_OK)
    {
    return FALSE;
    }
    if(lpDD->SetDisplayMode(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),32)!=DD_OK) /*设置显示模式*/
    {
    return FALSE;
    } /*做前页*/
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS;
    ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;

    if(lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL)!=DD_OK)
    {
    lpDDSPrimary->Release();
    lpDD=NULL;
    return FALSE;
    }
    /*做后页*/
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
    ddsd.dwWidth=800;
    ddsd.dwHeight=600;
    ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; if(lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL)!=DD_OK)
    {
    lpDDSBack->Release();
    lpDD=NULL;
    return FALSE;
    }
    /*设置剪切板*/
    if(lpDD->CreateClipper(NULL,&lpDDClipper,NULL)!=DD_OK)
    {
    lpDDClipper->Release();
    lpDD=NULL;
    return FALSE;
    }
    if(lpDDClipper->SetHWnd(0,hWnd)!=DD_OK)
    {
    lpDDClipper->Release();
    lpDD=NULL;
    return FALSE;
    }
    if(lpDDSPrimary->SetClipper(lpDDClipper)!=DD_OK)
    {
    lpDDClipper->Release();
    lpDD=NULL;
    return FALSE;
    }
    return TRUE;
    }/*主循环*/
    void MyFrame()
    {
    HDC hdc;
    hdc=GetDC(hWnd);
    RECT rect;
    RECT rectback={0,0,MAXWIDTH,MAXHEIGHT};
    if(lpDDSBack->GetDC(&hdc)==DD_OK)
    {
    GetWindowRect(hWnd,&rect);
    rect.left+=GSM_CXBORDER;
    rect.top+=GSM_CAPTION+GSM_CYBORDER+GSM_CYMENU;
    rect.right-=GSM_CXBORDER;
    rect.bottom-=GSM_CYBORDER;
    FillRect(hdc,&rectback,(HBRUSH)GetStockObject(BLACK_BRUSH)); BitBlt(hdc,0,0,backbm.bmWidth,backbm.bmHeight,backImage,0,0,SRCCOPY);
    BitBlt(hdc,x,y,herobm.bmWidth,herobm.bmHeight,heroImage,0,0,SRCCOPY);
    lpDDSBack->ReleaseDC(hdc);
    }
    lpDDSPrimary->Blt(&rect,lpDDSBack,&rectback,DDBLT_WAIT,NULL);
    ReleaseDC(hWnd,hdc);
    }/*消息处理*/
    void MyGetMessage()
    { if(GetAsyncKeyState(VK_UP))
    {
    if(y<=0)
    {
    }else
    {
    y-=step;
    }
    }
    if(GetAsyncKeyState(VK_DOWN))
    {
    if(y>480)
    {
    }else
    {
    y+=step;
    }
    }
    if(GetAsyncKeyState(VK_LEFT))
    {
    if(x<0)
    {
    }else
    {
    x-=step;
    }
    }
    if(GetAsyncKeyState(VK_RIGHT))
    {
    if(x>740)
    {
    }else
    {
    x+=step;
    }
    }
    }
      

  6.   

    用GDI不会出现这样的问题,是不是我循环部分做的不好。有没有一个比较好用的定时器。我不会用线程。
      

  7.   

    lpDDSBack->ReleaseDC(hdc);
    }
    lpDDSPrimary->Blt(&rect,lpDDSBack,&rectback,DDBLT_WAIT,NULL);
    ReleaseDC(hWnd,hdc);
    对同一个dc释放2次?而且,不是同一个窗口释放的?这段代码应该有问题!
      

  8.   

    嗯,我再试试看,windows编程真麻烦啊。我看MFC就头大。
      

  9.   

    ReleaseDC(hWnd,hdc);
    我把这个去了,还是不行,刚开始挺流畅,后面就越来越慢。。
    是不是别的地方还有问题。
    我觉得自己有点笨到家了。。
      

  10.   

    while(1)
    {
    if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
    {
    if(!GetMessage(&msg,NULL,0,0))
    {
    return msg.wParam;
    }
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    Mytimer();
    MyGetMessage();
    MyFrame();
    }
    这3个函数在WM_QUIT前一直在执行不要这么写吧。。
      

  11.   

    改了一下好多了。
    BOOL bActive;然后再windows的消息处理哪里加上
    case WM_ACTIVATEAPP:
    bActive = wParam;
    break;然后在改成if(bActive)
    {
    Mytimer();
    MyGetMessage();
    MyFrame();
    }现在情况好了很多了。至少运行一段时间不卡了。谢谢SullenSun,谢谢其他大大的不吝赐教。小弟受益匪浅。
      

  12.   

    MyFrame()里面的hdc=GetDC(hWnd);也是画蛇添足。