关于位图背景重画多次会消失的问题,也许你没注意到

bonogyb 2010-12-04 09:04:33
代码如下,大家经常用,可是遇到过这样的问题吗?
以下代码正常,运行没问题,这个时候你拖动窗口若干次,把窗口一部分拖到屏幕外,也许是20,30,40,50次...然后窗口的背景重画的那一块在某一次之后一定会重画不出,不知道为啥,请大大们瞅瞅

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);


hdcSrc = CreateCompatibleDC(hdc) ; //源
SelectObject(hdcSrc, hBitmap);
StretchBlt(hdc,0, 0, 200, 200, hdcSrc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY) ;
//ReleaseDC (hWnd, hdcDes);
DeleteDC (hdcSrc) ;
EndPaint (hWnd, &ps) ;
break;
...全文
79 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
bonogyb 2010-12-04
  • 打赏
  • 举报
回复
ok,解决了,我把hBitmap和bitmap定义为局部变量,果断解决了,我试验了300多次,果然没出现问题..
谢谢Eleven大哥
Eleven 2010-12-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bonogyb 的回复:]
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
这两句拿到WM_CREATE消息中去处理,这样背景就不显示了...
[/Quote]
把你的hBitmap和bitmap定义到外面去定义为全局的或者定义为static局部变量
bonogyb 2010-12-04
  • 打赏
  • 举报
回复
我把整个主窗口回调函数贴出来吧,大大们帮帮忙吧

#include <windows.h>
#include "resource.h"


LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);


BOOL CALLBACK DlgWindowProc(HWND hWndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);


int WINAPI WinMain(HINSTANCE hInstance, // 输入参数:当前程序的实例句柄
HINSTANCE hPrevInstance, // 任选输入参数:以前程序的实例句柄
LPSTR lpCmdLine, // 任选输入参数:命令行
int nShowCmd // 输入参数:当前窗口的显示方式
)
{
static TCHAR szAppName[] = TEXT("Modal Dialog");

HWND hWnd; // 窗口句柄
MSG msg; // 窗口消息结构体
HACCEL hAccTable; // 加速器表资源句柄



WNDCLASS wndcls; // 窗口类别信息结构体

wndcls.style = CS_HREDRAW | CS_VREDRAW; // 窗口样式
wndcls.lpfnWndProc = WndProc; // 窗口过程函数指针
wndcls.cbClsExtra = 0; // 窗口类别附加数据
wndcls.cbWndExtra = 0; // 窗口类别附加数据
wndcls.hInstance = hInstance; // 拥有窗口类别的窗口实例句柄
wndcls.hIcon = LoadIcon(hInstance, NULL); // 最小窗口图标
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口内使用的光标
wndcls.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); // 用来着色窗口的背景刷子
wndcls.lpszMenuName = NULL; // 指向菜单资源名的指针
wndcls.lpszClassName= szAppName; // 指向窗口类名的指针

if (!RegisterClass(&wndcls)) // 窗口注册登记函数在系统中注册当前的窗口类别
{
MessageBox(NULL, TEXT("This program requires Windows version!"),
szAppName, MB_ICONERROR); // 显示消息框的函数

return 0;
}


hWnd = CreateWindow(szAppName, // 注册窗口结构(类型)的名字
TEXT("Hello CT11 Window"), // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, // x 位置
CW_USEDEFAULT, // y 位置
CW_USEDEFAULT, // x 大小
CW_USEDEFAULT, // y 大小
NULL, // 父窗体样式
NULL, // 窗口菜单栏句柄
hInstance, // 程序实例句柄
NULL // 创建窗口的附加参数
);
ShowWindow(hWnd, nShowCmd); // 在屏幕上显示当前窗口
UpdateWindow(hWnd); // 指示当前窗口自我更新(发送WM_PAINT)消息
// 重画窗口——使窗口恢复成以前的那个样
while (GetMessage(&msg, NULL, 0, 0)) // 从消息队列中取得消息
{
if (TranslateAccelerator(hWnd, hAccTable, &msg) == 0) // 处理快捷键函数
{
TranslateMessage(&msg); // 转译某些键盘消息
DispatchMessage(&msg); // 将消息发送给窗口消息处理程序(窗口过程回调函数)
}
}

return (int)msg.wParam;
}

//////////////////////////////////////////////////////////////////////////
// 主窗口回调函数
//
LRESULT CALLBACK WndProc(HWND hWnd, // 窗口句柄
UINT uMsg, // 传入的消息
WPARAM wParam, // 该消息的其他附加信息,其含义与具体的消息有关
LPARAM lParam // 该消息的其他附加信息,其含义与具体的消息有关
)
{
static HINSTANCE hInstance;
RECT rct;
HDC hdc;
HDC hdcSrc;
BITMAP bitmap;
HBITMAP hBitmap;
PAINTSTRUCT ps;

switch(uMsg)
{
case WM_CREATE:
break;

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);


hdcSrc = CreateCompatibleDC(hdc) ; //源
SelectObject(hdcSrc, hBitmap);
StretchBlt(hdc,0, 0, 400, 400, hdcSrc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY) ;
DeleteDC (hdcSrc) ;
EndPaint (hWnd, &ps) ;
break;



case WM_DESTROY:
PostQuitMessage(0); // 在消息队列中插入一个“退出程序”的消息
break;

default:
return DefWindowProc(hWnd, uMsg, wParam, lParam); // 执行默认的窗口过程回调函数
}

return 0;
}

bonogyb 2010-12-04
  • 打赏
  • 举报
回复
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
这两句拿到WM_CREATE消息中去处理,这样背景就不显示了...

Eleven 2010-12-04
  • 打赏
  • 举报
回复
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
这两句拿到WM_CREATE消息中去处理。
另外你在DeleteDC()删除内存DC之前,先还原的bitmap

HBITMAP hOld = (HBITMAP)SelectObject(hdcSrc, hBitmap);
...
SelectObject(hdcSrc, hOld);
DeleteDC (hdcSrc) ;
Eleven 2010-12-04
  • 打赏
  • 举报
回复
hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
这两句拿到WM_CREATE消息中去处理。
另外你在DeleteDC()删除内存DC之前,先还原的bitmap

HBITMAP hOld = (HBITMAP)SelectObject(hdcSrc, hBitmap);
...
SelectObject(hdcSrc, hOld);
DeleteDC (hdcSrc) ;
bonogyb 2010-12-04
  • 打赏
  • 举报
回复
2楼这位大哥你说的应该是和我写的代码差不多,就是
HDC hdc = BeginPaint(hWnd, &ps);
HDC hdcSrc = CreateCompatibleDC(hdc) ; //源
hBitmap = LoadBitmap(...);
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
SelectObject(hdcSrc, hBitmap);
StretchBlt(hdc,0, 0, 200, 200,
hdcSrc, 0, 0, bitmap.bmWidth,bitmap.bmHeight,SRCCOPY) ;
这样吧,效果是一样的,窗口中的背景冲刷过一定次数之后仍然会出现某一块变白的情况
bonogyb 2010-12-04
  • 打赏
  • 举报
回复
GDI资源释放是什么意思啊
cranium 2010-12-04
  • 打赏
  • 举报
回复
虽然没有遇到楼主的这种情形。

不过你写的这段代码似乎跟常见的代码有些不同,我也不能确定你这种写法是否正确。

试试下面的方法:
你创建一个hdc兼容的内存位图,将此位图选入hdcSrc,然后将hBitmap会知道hdcSrc上,再做些其他的绘制,最后StretchBlt到hdc看看 。
Eleven 2010-12-04
  • 打赏
  • 举报
回复
GDI资源没有释放?

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧