Ownerdrawn Bug bei Listboxes?
-
Hi, ich hab meine Listbox in ownerdrawn gemacht. Durch Zufall ist mir aufgefallen, dass wenn man die Lisrbox zu oft scrollt plötzlich alles kurz flackert und dann die ganzen anderen Controls verschwinden, bis man mitm Mauszeiger wieder raufgeht. Jedoch werden diese erst wieder beim Programm neustart wieder richtig angezeigt.
Wenn ich die Listbox dann normal (nicht ownerdrawn) lasse, kann ich so oft scrollen wie ich will. Ist das ein Bug? Ich stell hier mal den Code rein://Hier ein Teil, wo die Listboxcontrol erstellt wird
//
...
hControl = CreateWindowEx(WS_EX_CLIENTEDGE,
"listbox",
"",
WS_VISIBLE | WS_CHILD | LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_VSCROLL,
10,
48,
200,
200,
hwnd,
(HMENU) BITMAP_LISTBOX,
hInstance,
NULL
);
...
//
//Hier die Callbackfunktion
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;switch(message)
{
case WM_COMMAND:
switch(HIWORD(wParam))
{
case BN_CLICKED:
{
switch(LOWORD(wParam))
{
case BUTTON_ADD_ITEM:
SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) "Bitmap-Listbox Eintrag");
break;
case BUTTON_ADD_SEP:
SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) "SEPARATOR");
break;
}
}
break;
}
break;
case WM_MOUSEMOVE:
MouseX = LOWORD(lParam);
MouseY = HIWORD(wParam);
break;case WM_MEASUREITEM:
if(lpmis->CtlID == BITMAP_LISTBOX)
lpmis->itemHeight = 36;
break;case WM_DRAWITEM:
OnDrawItem(lpdis, lParam);
break;case WM_CLOSE:
DestroyWindow(hwnd);
break;case WM_DESTROY:
PostQuitMessage(0);
break;default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}//Funktion OnDrawItem()
VOID OnDrawItem(LPDRAWITEMSTRUCT lpdis, LPARAM lParam)
{
HDC hdc = CreateCompatibleDC(lpdis->hDC);if(lpdis->CtlID == BITMAP_LISTBOX && SendMessage(hControl,LB_GETCOUNT, 0, 0)>0)
{
COLORREF BGColor;
char buf[64];SendMessage(hControl,LB_GETTEXT,lpdis->itemID,(long)buf);
std::string sCompare = buf;
std::string sSep = "SEPARATOR";if(lpdis->itemState & ODS_SELECTED)
{
if(sCompare != sSep)
BGColor = RGB(49, 106, 197);
else
BGColor = RGB(255, 255, 255);
}
else
BGColor = RGB(255, 255, 255);HBRUSH BGBrush = CreateSolidBrush(BGColor);
SelectObject(lpdis->hDC, GetStockObject(DEFAULT_GUI_FONT));
SetBkColor(lpdis->hDC, BGColor);
FillRect(lpdis->hDC, &lpdis->rcItem, BGBrush);
if(sCompare != sSep)
TextOut(lpdis->hDC, lpdis->rcItem.left+36, lpdis->rcItem.top+12, buf, strlen(buf));
DeleteObject(BGBrush);if(sCompare != sSep)
{
hBitmap = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDB_BITMAP), IMAGE_BITMAP, 32, 32, LR_SHARED);
SelectObject(hdc, hBitmap);
StretchBlt(lpdis->hDC, lpdis->rcItem.left+2, lpdis->rcItem.top+2, 32, 32, hdc, 0, 0, 32, 32, SRCCOPY);
}
else
{
MoveToEx(lpdis->hDC, lpdis->rcItem.left+2, lpdis->rcItem.top+18, NULL);
LineTo(lpdis->hDC, lpdis->rcItem.right-2, lpdis->rcItem.top+18);
}
}
}freue mich auf eure antworten.
mfg CriticalTIE
-
kann bitte jemand da die C++ Code tags hinzufügen und dann diesen beitrag löschen?
srymfg CriticalTIE
-
Hallo
Du solltes nicht jedes mal die GDI-Objekte erzeugen:
... HBRUSH BGBrush = CreateSolidBrush(BGColor); ... hBitmap = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDB_BITMAP), IMAGE_BITMAP, 32, 32, LR_SHARED); ...Ein mal beim Erzeugen des Fensters alles erstellen, und bei WM_DESTROY löschen.
Ich glaub mit LoadImage überlastest du den Rechner.Meine Homepage http://members.inode.at/anton.zechner/az/index.html