我正在开发一个所有者绘制的列表框控件,我设法创建并填充而没有错误。
这是我的问题: 当我滚动它时,列表框及其父窗口在滚动几秒后变得无法响应。(使用PgDown)
请注意:
其中有很多项目(超过4k)
邮件仍在处理中,我可以在控制台上监控它们,然后发送和接收邮件。 唯一的区别是,不再发送WM_DRAWITEM ...
列表框的项目通过LB_ADDSTRING
我尝试了什么:
- >列表填写后程序崩溃
- >没有效果
代码段:
窗口过程
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HBRUSH Brush;
HBRUSH BLANK_BRUSH;
HBRUSH BLUE_BRUSH;
Brush = CreateSolidBrush(RGB(163, 255, 249));
BLANK_BRUSH = CreateSolidBrush(RGB(255,255, 255));
BLUE_BRUSH = CreateSolidBrush(RGB(0,0, 255));
int tabs[13]={140,256,261,287,318,353,422,460,500,530,550,570,610};
switch(msg)
{
HDC hdc ;
PAINTSTRUCT ps ;
PMEASUREITEMSTRUCT pmis;
LPDRAWITEMSTRUCT Item;
RECT rect ;
rect.top=-50;
rect.bottom=0;
RECT rect2 ;
rect.top=10;
case WM_MEASUREITEM:
pmis = (PMEASUREITEMSTRUCT) lParam;
pmis->itemHeight = 17;
return TRUE;
break;
case WM_DRAWITEM:
Item = (LPDRAWITEMSTRUCT)lParam;
if (Item->itemState & ODS_FOCUS)
{
SetTextColor(Item->hDC, RGB(255,255,255));
SetBkColor(Item->hDC, RGB(0, 0, 255));
FillRect(Item->hDC, &Item->rcItem, (HBRUSH)BLUE_BRUSH);
}
else
{
SetTextColor(Item->hDC, RGB(0,0,0));
SetBkColor(Item->hDC, RGB(255, 255, 255));
FillRect(Item->hDC, &Item->rcItem, (HBRUSH)BLANK_BRUSH);
}
int len = SendMessage(Item->hwndItem , LB_GETTEXTLEN, (WPARAM)Item->itemID, 0);
if (len > 0)
{
LPCTSTR lpBuff = malloc((len+1)*sizeof(TCHAR));
len = SendMessage(Item->hwndItem , LB_GETTEXT, (WPARAM)Item->itemID, (LPARAM)lpBuff);
if (len > 0) {
TabbedTextOut(Item->hDC,Item->rcItem.left, Item->rcItem.top,(LPARAM)lpBuff,len,13,&tabs,140);
}
}
return TRUE;
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect(hwnd, &rect);
SetBkColor(hdc, RGB(230,50,2));
SetBkMode(hdc,TRANSPARENT);
FillRect(hdc,&ps.rcPaint,Brush);
DrawText(hdc, TEXT("Liste des messages décodés: "), -1, &rect, DT_CENTER );
DrawText(hdc, TEXT("Numéro d'engin (4xxxy): "), -1, &rect, DT_LEFT );
EndPaint (hwnd, &ps);
return 0 ;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_ERASEBKGND:
return TRUE;
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
消息循环
BOOL bRet;
while (1)
{
bRet = GetMessage(&Msg, NULL, 0, 0);
if (bRet > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
else if (bRet == 0){
break;
}
else
{
printf("error\n");
return -1;
}
}
return Msg.wParam;
创建窗口
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"List of messages",WS_OVERLAPPEDWINDOW,0, 0, 1500, 1000,NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
if(hwnd == NULL)
{
return 0;
}
hwnd2 = CreateWindowEx(0,"LISTBOX" ,"Data",WS_CHILD |WS_HSCROLL |WS_VSCROLL |WS_BORDER|WS_THICKFRAME | LBS_USETABSTOPS | LBS_OWNERDRAWFIXED | LBS_NOTIFY | LBS_HASSTRINGS,15,70,1450,450,hwnd,(HMENU) NULL,hInstance,NULL);
看起来某个地方有一个计时器,如果键盘触摸时间过长,它会以某种方式混乱......
有人之前遇到过这样的问题,或者可以帮我理解发生了什么事吗?
答案 0 :(得分:3)
您的代码中存在重大的GDI资源泄漏。
在WndProc
功能的顶部,您正在创建三个画笔,而您永远不会删除它们。每次窗口处理消息时都会创建这些画笔。
您只应在实际需要它们进行绘画时创建画笔,并在完成它们时调用DeleteObject
释放它们。