如何提高效率 我在ce上用两个for循环transparentblt加载位图32*32的一块区域但是效率及其低下,画面上是一条一条刷新,于是我想到在缓存dc上先整合出图片在一次性贴上去,但不知如何下笔,由于是手机上网,希望大家能给贴个代码,谢谢了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 双缓冲吧?建一个内存DC,先通过原来的方法绘制到内存DC中,然后1次将内存DC的内容拷贝到窗口DC。http://www.vckbase.com/document/viewdoc/?id=1612 transparentblt就是双缓存了,缓存dc加载位图,但不是拷贝位图,就像游戏地图一样需要整合出一个地图,这放在pc上没什么问题,在ce上不行 transparentblt和双缓冲不是一码事啊,你不是在循环中调用的么,这样就是对窗口DC的操作做了很多次。双缓冲是把重复性的操作先做到内存DC中,然后只对窗口DC进行一次操作。 是,我的缓存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++] [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);大致是这个样子吧,你看看我上面写的那个网址,肯定可以理解的 你这两次for循环每次贴的东西有什么变化么如果没有可以在初始化的时候贴到一个内存位图上啊这篇文章中材质的处理用的就是内存位图有兴趣可以看看http://blog.csdn.net/xianglitian/article/details/6590687 代码大致是这样的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++] 代码大致是这样的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 ] 代码大致是这样的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 ] 本帖最后由 xianglitian 于 2011-07-09 20:39:23 编辑 你的代码我看了代码本身从功能上说没有什么问题是应用双缓冲实现绘制不过如果这段代码也用在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;} 向老大实际我上面的代码无任何效果,并且无任何出错信息,倒不是说效率问题了,但是直接缓存dc绘制到hdc可以 今天测试了下向老大的代码,发现只出现了半屏,于是把代码给了老大,老大说可能设备力有未逮,于是尝试了invalidate一次后发现代码都可行了 MFC下的CSocket接收数据的问题。 [activex]新手问题之——如何Debug CTreeCtrl失去焦点时,当前选中的ITEM显示为灰色背景,象windows资源管理器一样,如何实现? 大家帮我看看这问题,发言有分! 重金求CDDB SDK和相关文档。 用SDK开发程序与WEB服务器通讯,该怎么做呢???请大家帮忙!!!急!!! 数据库中的Currency类型字段 很简单的问题,怎样将测试的数据在视图全部显示出来?寻求方法,紧急求助!!! Dll注入问题 谁有windows 98 编程实用大全 程序源代码? 自会按钮 小问题 如何对被遮盖的窗口截图
双缓冲是把重复性的操作先做到内存DC中,然后只对窗口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++]
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);
大致是这个样子吧,你看看我上面写的那个网址,肯定可以理解的
如果没有可以在初始化的时候贴到一个内存位图上啊
这篇文章中材质的处理用的就是内存位图
有兴趣可以看看
http://blog.csdn.net/xianglitian/article/details/6590687
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++]
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 ]
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 ]
代码本身从功能上说没有什么问题
是应用双缓冲实现绘制
不过如果这段代码也用在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;
}