• Welcome to Valhalla Legends Archive.
 

Owner drawn listbox

Started by DarkMinion, August 14, 2003, 02:13 PM

Previous topic - Next topic

DarkMinion

Every now and then, there seems to be a problem with my owner drawn listbox where all the icons will disappear completely, and when someone new joins the channel, it will not draw the icon.

It seems that when this happens the only thing that will be drawn are the text ladder ratings and the text usernames.

Any ideas as to what would cause this?

Thanks in advance.

Adron

Quote from: DarkMinion on August 14, 2003, 02:13 PM
Every now and then, there seems to be a problem with my owner drawn listbox where all the icons will disappear completely, and when someone new joins the channel, it will not draw the icon.

It seems that when this happens the only thing that will be drawn are the text ladder ratings and the text usernames.

Any ideas as to what would cause this?

Thanks in advance.

This is C++ ? Post some code? Have you checked all the return values / GetLastError from the functions you use to draw the icons?

DarkMinion

Yes, C++, and no, I haven't checked those, it would require waiting for the icons to disappear :P  And usually it only happens after a long time


         int iCount = SendMessage(GetDlgItem(hMain, IDC_CHANLIST), LB_GETCOUNT, 0, 0);
         if(iCount == 0)
            return TRUE;
         DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam;
         RECT rc = pdis->rcItem;
         rc.left = rc.left + 31;
         rc.right = rc.right - 49;
         char cr[128];
         HBRUSH hBrush;
         SetBkMode(pdis->hDC,TRANSPARENT);
         char sString[128];   
         HFONT hFont, hSmallFont;
         hBrush = CreateSolidBrush(BLACK);
         SetBkColor(pdis->hDC, BLACK);
         FillRect(pdis->hDC, &rc, hBrush);
         DeleteObject(hBrush);
         int iIcon, iLagIcon, iRating;
         SendMessage(pdis->hwndItem, LB_GETTEXT, pdis->itemID, (LPARAM)cr);
         sscanf(cr, "%i %i %s %i", &iIcon, &iLagIcon, sString, &iRating);
         char szRating[32];
         sprintf(szRating, "%i", iRating);
         if(!stricmp(sString, szUniqueName) || !stricmp(sString, szBotnetLogon))
            hFont = CreateFont(13, 6, 0, 0, 1000, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, "Verdana");
         else
            hFont = CreateFont(13, 6, 0, 0, 500, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, "Verdana");
         hSmallFont = CreateFont(12, 5, 0, 0, 500, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, "Arial");
         TEXTMETRIC tm;
         GetTextMetrics(pdis->hDC, &tm);
         HDC hIconDC = CreateCompatibleDC(pdis->hDC);
         HBITMAP hBM = CreateCompatibleBitmap(pdis->hDC, 28, 14);
         hBM = LoadBitmap(hDlgInst, MAKEINTRESOURCE(IDB_ICONS));
         SelectObject(hIconDC, hBM);

         if(pdis->itemAction & ODA_DRAWENTIRE){
            SelectObject(pdis->hDC, hFont);
            SetTextColor(pdis->hDC, LIGHTGRAY);
            TextOut(pdis->hDC, pdis->rcItem.left + 33, pdis->rcItem.top + 1, sString, strlen(sString));
            if(pdis->hwndItem != hBotnetList)
               BitBlt(pdis->hDC, pdis->rcItem.left + 1, pdis->rcItem.top + 1, 28, 14, hIconDC, 28 * IconList.Get(pdis->itemID), 0, SRCCOPY);
            else
               BitBlt(pdis->hDC, pdis->rcItem.left + 1, pdis->rcItem.top + 1, 28, 14, hIconDC, 28 * iIcon, 0, SRCCOPY);
            BitBlt(pdis->hDC, pdis->rcItem.left + 165, pdis->rcItem.top + 1, 28, 14, hIconDC, 28 * iLagIcon, 0, SRCCOPY);
            SetTextColor(pdis->hDC, YELLOW);
            SelectObject(pdis->hDC, hSmallFont);
            if(IconList.Get(pdis->itemID) > 7 && iRating > 0 && (iIcon == ICON_STAR_LADDER || iIcon == ICON_WAR2_0))
               TextOut(pdis->hDC, pdis->rcItem.left + 3, pdis->rcItem.top + 2, szRating, strlen(szRating));
         }
         DeleteObject(hIconDC);
         DeleteObject(hBM);
         DeleteObject(hFont);
         DeleteObject(hSmallFont);

Adron


HBITMAP hBM = CreateCompatibleBitmap(pdis->hDC, 28, 14);
        hBM = LoadBitmap(hDlgInst, MAKEINTRESOURCE(IDB_ICONS));


You leak resources here.

You should still add code to check for errors and display them. Actually, if you build this with pdb's and run it, you could just break in with devstudio or windbg at whatever time you have the icon problem and check all return codes to find out what the problem is. My guess is that you are running out of resources.

DarkMinion

Ok....I'm not familiar with how that is leaking recources.  Should I only load it once?

DarkMinion

Ah I see...

HBITMAP hBM = CreateCompatibleBitmap(pdis->hDC, 28, 14);

This is completely unnecessary for one...

And the bitmap should be loaded only once at program start, and destroyed when the program ends.

Thanks for your help.

UserLoser

#6
I have somewhat the same problem, on my computer I don't see any icons, but I know it works because I sent it out two about three other people, and when they ran the program, they said they saw icons in the listbox.  Anyone have any ideas why it might not work on my computer, but other people's computers?

http://darknet.darktech.org/ods.zip is the program if anyone wants to see and tell me if they see icons in the listbox.

Soul Taker

Quote from: UserLoser on September 06, 2003, 10:12 AM
I have somewhat the same problem, on my computer I don't see any icons, but I know it works because I sent it out two about three other people, and when they ran the program, they said they saw icons in the listbox.  Anyone have any ideas why it might not work on my computer, but other people's computers?

http://darknet.darktech.org/ods.zip is the program if anyone wants to see and tell me if they see icons in the listbox.
Code would be nice.

Camel


UserLoser

   Case WM_DRAWITEM
       ' When a draw item message is received, copy the
       ' accompanying Draw Item Structure to local storage.
       Call CopyMemory(DIS, ByVal lParam, Len(DIS))
       Select Case DIS.CtlType
           Case ODT_LISTBOX
               ' Drawing the ListBox.
               With DIS
                   ' Get the text, indicated by DrawItemStruct.iItemID,
                   ' from the listbox.
                   sString = Space$(128)
                   lRet = SendMessage(.hwndItem, LB_GETTEXT, .itemID, ByVal sString)
                   sString = Left$(sString, lRet)
                   ' Create a logical font based on the font specified
                   ' in the listbox.
                   hDC = CreateCompatibleDC(.hDC)
                   lFont = CreateFont(0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, sString)
                   ' Select the font into the new device context.
                   ' Compute the width and height of a string of text (font name).
                   ' Set the height of the listbox item accordingly.
                   Call SelectObject(.hDC, lFont)
                   Call GetTextExtentPoint32(.hDC, sString, Len(sString), tSize)
                   Call SendMessage(.hwndItem, LB_SETITEMHEIGHT, .itemID, ByVal tSize.cy)
                   ' Set the color of the text of the list item
                   ' based on whether the item is selected or not.
                   If .itemState And ODS_SELECTED Then
                       Call SetBkColor(.hDC, GetSysColor(COLOR_HIGHLIGHT))
                       Call SetTextColor(.hDC, GetSysColor(COLOR_HIGHLIGHTTEXT))
                   Else
                       Call SetBkColor(.hDC, GetSysColor(COLOR_WINDOW))
                       Call SetTextColor(.hDC, GetSysColor(COLOR_WINDOWTEXT))
                   End If
               End With
               ' Draw the text in the listbox.
               With DIS.rcItem
                   Call ImageList_Draw(frmBot.imgList.hImageList, 1, DIS.hDC, .Left, .Top, 0)
                   Call TextOut(DIS.hDC, .Left + 30, .Top, sString, Len(sString))
               End With
               Call DeleteObject(lFont)
               Call DeleteDC(hDC)