我在ce上用两个for循环transparentblt加载位图32*32的一块区域但是效率及其低下,画面上是一条一条刷新,于是我想到在缓存dc上先整合出图片在一次性贴上去,但不知如何下笔,由于是手机上网,希望大家能给贴个代码,谢谢了

解决方案 »

  1.   

    双缓冲吧?建一个内存DC,先通过原来的方法绘制到内存DC中,然后1次将内存DC的内容拷贝到窗口DC。http://www.vckbase.com/document/viewdoc/?id=1612
      

  2.   

    transparentblt就是双缓存了,缓存dc加载位图,但不是拷贝位图,就像游戏地图一样需要整合出一个地图,这放在pc上没什么问题,在ce上不行
      

  3.   

    transparentblt和双缓冲不是一码事啊,你不是在循环中调用的么,这样就是对窗口DC的操作做了很多次。
    双缓冲是把重复性的操作先做到内存DC中,然后只对窗口DC进行一次操作。
      

  4.   

    是,我的缓存dc用于加载位图了,我不知道该如何做
    [code=c/c++]
    hdc = BeginPaint(hWnd, &ps);
    HDC menDC=CreateCompatibleDC(hdc);
    HBITMAP bit=LoadBitmap((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),
    MAKEINTRESOURCE(IDB_BITMAP1));
    SelectObject(menDC,bit);
    DeleteObject(bit);
    for (int i=0;i<15;i++)
    {
    for (int j=0;j<15;j++)
    { TransparentBlt(hdc,i*32,j*32,32,32,menDC,0,0,32,32,RGB(255,255,255));
    }
    }
    DeleteDC(menDC);
    EndPaint(hWnd, &ps);
    [c/c++]
      

  5.   

    [code=C/C++] hdc = BeginPaint(hWnd, &ps);
    HDC menDC=CreateCompatibleDC(hdc);
    HBITMAP bit=LoadBitmap((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),
    MAKEINTRESOURCE(IDB_BITMAP1));
    HBITMAP hOldBmp = (HBITMAP)SelectObject(menDC,bit);
    DeleteObject(hOldBmp); CRect rc = ps.rcPaint;
    HDC memoryDC = CreateCompatibleDC(hdc);
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&memoryDC, rc.Width(), rc.Height());
    SelectObject(memoryDC, bmp); for (int i=0;i<15;i++)
    {
    for (int j=0;j<15;j++) 
    { TransparentBlt(memoryDC,i*32,j*32,32,32,menDC,0,0,32,32,RGB(255,255,255));
    }
    }
    BitBlt(hdc, rc.left, rc.right, rc.Width(), rc.Height(), memoryDC, 0, 0, SRCCOPY); DeleteDC(memoryDC);
    DeleteDC(menDC);
    EndPaint(hWnd, &ps);
    大致是这个样子吧,你看看我上面写的那个网址,肯定可以理解的
      

  6.   

    你这两次for循环每次贴的东西有什么变化么
    如果没有可以在初始化的时候贴到一个内存位图上啊
    这篇文章中材质的处理用的就是内存位图
    有兴趣可以看看
    http://blog.csdn.net/xianglitian/article/details/6590687
      

  7.   

    代码大致是这样的
    55)))
    {
    ShowErr(hwnd,TEXT("transparentblt err %d"),GetLastError());
    goto err;
    }
    }
    }
    if(!BitBlt(hdc,0,0,480,480,paintDC,0,0,SRCCOPY))
    {
    ShowErr(hwnd,TEXT("bitblt err %d"),GetLastError());
    goto err;
    }
    err:
    if(bmppaint){DeleteObject(bmppaint);}
    if (bmprc){DeleteObject(bmprc);}
    if (paintDC){ReleaseDC(hwnd,paintDC);DeleteDC(paintDC);}
    if (memDC){ReleaseDC(hwnd,memDC);DeleteDC(memDC);}
    }
    [c/c++]
      

  8.   

    代码大致是这样的
    55)))
    {
    ShowErr(hwnd,TEXT("transparentblt err %d"),GetLastError());
    goto err;
    }
    }
    }
    if(!BitBlt(hdc,0,0,480,480,paintDC,0,0,SRCCOPY))
    {
    ShowErr(hwnd,TEXT("bitblt err %d"),GetLastError());
    goto err;
    }
    err:
    if(bmppaint){DeleteObject(bmppaint);}
    if (bmprc){DeleteObject(bmprc);}
    if (paintDC){ReleaseDC(hwnd,paintDC);DeleteDC(paintDC);}
    if (memDC){ReleaseDC(hwnd,memDC);DeleteDC(memDC);}
    }
    [c/c  ]
      

  9.   

    代码大致是这样的
    55))) { ShowErr(hwnd,TEXT("transparentblt err %d"),GetLastError()); goto err; } } } if(!BitBlt(hdc,0,0,480,480,paintDC,0,0,SRCCOPY)) { ShowErr(hwnd,TEXT("bitblt err %d"),GetLastError()); goto err; }err: if(bmppaint){DeleteObject(bmppaint);} if (bmprc){DeleteObject(bmprc);} if (paintDC){ReleaseDC(hwnd,paintDC);DeleteDC(paintDC);} if (memDC){ReleaseDC(hwnd,memDC);DeleteDC(memDC);}}[c/c  ]
      

  10.   

    本帖最后由 xianglitian 于 2011-07-09 20:39:23 编辑
      

  11.   

    你的代码我看了
    代码本身从功能上说没有什么问题
    是应用双缓冲实现绘制
    不过如果这段代码也用在WM_PAINT消息中那其实无助于提高效率
    我按着你的思路给你写了一个demo
    你看看会不会有帮助
    // wsaasyncselect.cpp : 定义应用程序的入口点。
    //#include <Windows.h>
    #include <tchar.h>
    #include "resource.h"#pragma comment(lib, "Msimg32.lib")// 全局变量:
    HINSTANCE hInst;
    HBITMAP bmppaint;
    // 此代码模块中包含的函数的前向声明:
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);     // TODO: 在此放置代码。
        MSG msg;    // 初始化全局字符串
        MyRegisterClass(hInstance);    // 执行应用程序初始化:
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }    // 主消息循环:
        while (GetMessage(&msg, NULL, 0, 0))
        {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
        }    return (int) msg.wParam;
    }ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;    wcex.cbSize = sizeof(WNDCLASSEX);    wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = NULL;
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = _T("WinMain");
        wcex.hIconSm = NULL;    return RegisterClassEx(&wcex);
    }BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
       hInst = hInstance; // 将实例句柄存储在全局变量中   hWnd = CreateWindow(_T("WinMain"), _T("Demo"), WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)
       {
          return FALSE;
       }   //预先拼接内存位图
       HDC hdc = GetDC(hWnd);
       HDC memDC = CreateCompatibleDC(hdc);
       HBITMAP bmprc = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP_DEMO));
       HDC paintDC = CreateCompatibleDC(hdc);   bmppaint = CreateCompatibleBitmap(hdc, 480, 480);
       SelectObject(memDC, bmprc);
       SelectObject(paintDC, bmppaint);   for(int i=0; i<15; i++)
       {
       for(int j=0; j<15; j++)
       {
       TransparentBlt(paintDC, 32*i, 32*j, 32, 32, memDC, 0, 0, 32, 32, RGB(255, 255, 255));
       }
       }
       ReleaseDC(hWnd, hdc);
       DeleteDC(memDC);
       DeleteDC(paintDC);   ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);   return TRUE;
    }LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_PAINT:
    {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    HDC memDC = CreateCompatibleDC(hdc);
    SelectObject(memDC, bmppaint);
    BitBlt(hdc, 0, 0, 480, 480, memDC, 0, 0, SRCCOPY); DeleteDC(memDC);
    EndPaint(hWnd, &ps);
    }
    break;
        case WM_DESTROY:
    PostQuitMessage(0);
    break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
      

  12.   

    向老大实际我上面的代码无任何效果,并且无任何出错信息,倒不是说效率问题了,但是直接缓存dc绘制到hdc可以
      

  13.   

    今天测试了下向老大的代码,发现只出现了半屏,于是把代码给了老大,老大说可能设备力有未逮,于是尝试了invalidate一次后发现代码都可行了