[英]MSDN (Owner Drawn) Listbox control freeze after scrolling
I'm working on an Owner-Drawn Listbox Control that i managed to create and populate without errors. 我正在使用一个所有者绘制的列表框控件,该控件可以成功创建和填充,并且没有错误。
Here's my problem : When i scroll it, the listbox and its parent window becomes unresponsive after scrolling for a few seconds.(with PgDown) 这是我的问题: 滚动几秒钟后,列表框及其父窗口变得无响应。(使用PgDown)
Note that : 注意 :
There's a lot of items in it (more than 4k) 里面有很多物品(超过4k)
The messages are still being processed, i can monitor them on the console and they are being sent and received. 消息仍在处理中,我可以在控制台上监视它们,并且它们正在被发送和接收。 Only difference is, WM_DRAWITEM is no longer sent...
唯一的不同是,不再发送WM_DRAWITEM ...
The items of the listbox are added via LB_ADDSTRING 列表框的项目是通过LB_ADDSTRING添加的
What i tried : 我试过的
-> Program crashes after the list is filled ->列表填充后程序崩溃
-> No effets ->没有效果
Code snippets : 代码段:
Window Procedure 窗口程序
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; }
Message Loop 讯息循环
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;
Window creation 窗口创建
WNDCLASSEX wc; 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);
It looks like there's a timer somewhere, and if a keyboard touch stays too long down, it somehow messes everything up... 看起来好像在某个地方有一个计时器,如果键盘触摸的时间太长,就会以某种方式弄乱一切……
Has someone encountered a problem like this before or could help me understand what is going on ? 有人以前遇到过这样的问题吗,或者可以帮助我了解发生了什么?
You have a significant GDI resource leak in your code. 您的代码中有大量的GDI资源泄漏。
At the top of your WndProc
function you're creating three brushes, and you never delete them. 在
WndProc
函数的顶部,您正在创建三个笔刷,并且永远不会删除它们。 These brushes are created every time your window processes a message. 每次窗口处理消息时都会创建这些画笔。
You should only create the brushes when you actually need them for painting, and call DeleteObject
to release them when you're done with them. 您只应在实际需要绘画时才创建画笔,并在完成使用后调用
DeleteObject
释放它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.