Pergunta

i'm not being succefull on drawing my own listbox, heres the code:

LRESULT CALLBACK ListBoxProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        switch (msg)
        {
               case WM_DRAWITEM:
                    LPDRAWITEMSTRUCT Item;
                    Item = (LPDRAWITEMSTRUCT)lParam;

                if (Item->itemState == ODS_SELECTED)
                {
                    FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(0));
                    SetTextColor(Item->hDC, 0x0000FF);
                }
                else
                {
                    SetBkColor(Item->hDC, 0);
                    FillRect(Item->hDC, &Item->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
                    SetTextColor(Item->hDC, 0xFFFFFF);
                }
                LPSTR lpBuff;
                SendMessageA(Item->hwndItem , LB_GETTEXT, Item->itemID, (LPARAM)lpBuff);
                TextOutA(Item->hDC, Item->rcItem.left, Item->rcItem.top, (lpBuff), strlen(lpBuff)-1);
                if (Item->itemState & ODS_FOCUS)
                {
                   DrawFocusRect(Item->hDC, &Item->rcItem);
                }
                return true;
                break;
           case WM_MEASUREITEM:
                break;
           default:
                   DefWindowProcA(hwnd, msg, wParam, lParam);
    }
    return 0;
}

I create the ListBox like this:

lbLogs = CreateWindowExA(0, "LISTBOX", "", WS_VISIBLE + WS_CHILD + WS_BORDER + LBS_HASSTRINGS + LBS_NOINTEGRALHEIGHT + WS_TABSTOP, 15, 115, 515, 180, hwnd, (HMENU)1005, hInstance, NULL);
         //-----------------------------
         SetWindowLong(lbLogs, GWL_WNDPROC, (LONG)&ListBoxProcedure);

Could someone explain to me whats wrong in it? I'm trying to make a listbox that has black bg and red text and when an item gets selected it's text transforms to white.But the listbox just don't add nothing.

Foi útil?

Solução

You are creating a listbox, then installing your own WNDPROC to process messages sent to the listbox. However, an owner-draw listbox sends WM_MEASUREITEM and WM_DRAWITEM messages to its owner, so you need to handle those messages in the parent window's WNDPROC, not the listbox WNDPROC.

Also, even if subclassing was the correct approach (which it is not in this case), your subclass WNDPROC should pass unprocessed messages to the original listbox WNDPROC, not DefWindowProc(). Bypassing the original listbox WNDPROC will most likely cause trouble.

Outras dicas

You are not specifying any LBS_OWNERDRAW... window style when creating the ListBox. Those messages are also sent to the ListBox's parent window, not the ListBox itself, so you need to catch them in WindowProcedure() instead of ListBoxProcedure(). That is why you are not getting any WM_MEASUREITEM or WM_DRAWITEM messages.

You have to implement the WM_MEASUREITEM message, not discard it like you currently are.

You need to use the | operator instead of the + operator when combining bit-based flags together, like window styles.

You are not using the LB_GETTEXT message or DefWindowProc() function correctly.

Try this instead:

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

const TCHAR szClassName[] = TEXT("JMBSoftwares");

HWND hMainWnd, btnClose, btnMinimize, txtFileName, btnLoad, btnGo, lbLogs;

WINAPI _tWinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR lpszArgument,
                    int nFunsterStil)
{
    WNDCLASSEX wincl = {0};
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = CreateSolidBrush(0);

    if (!RegisterClassEx (&wincl))
        return 0;

    hMainWnd = CreateWindowEx (
           0,
           szClassName,
           TEXT("JMB Encryptor - V1.0"),
           WS_VISIBLE | WS_DLGFRAME,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    if (!hMainWnd)
        return 0;

    SetWindowLong(hMainWnd, GWL_STYLE, GetWindowLong(hMainWnd, GWL_STYLE) & ~(WS_BORDER | WS_DLGFRAME));
    ShowWindow (hMainWnd, nFunsterStil);

    MSG messages;
    while (GetMessage (&messages, NULL, 0, 0) > 0)
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    return 0;
}

void DrawMyText(HDC hDC, COLORREF Color, DWORD Size, DWORD X, DWORD Y, LPTSTR FontName, LPTSTR Text, BOOL SolidBG)
{
    HFONT hFont = CreateFont(Size, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, FontName);
    if (!hFont) return;

    HFONT hOldFont = (HFONT) SelectObject(hDC, hFont);

    int iOldBkMode;
    if (!SolidBG)
        iOldBkMode = SetBkMode(hDC, TRANSPARENT);
    else
    {
        SetBkColor(hDC, RGB(0, 0, 0));
        iOldBkMode = SetBkMode(hDC, OPAQUE);
    }

    COLORREF clrOldColor = SetTextColor(hDC, Color);
    TextOut(hDC, X, Y, Text, lstrlen(Text));
    SetTextColor(hDC, clrOldColor);
    SetBkMode(hDC, iOldBkMode);

    SelectObject(hDC, hOldFont);
    DeleteObject(hFont);
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage (0);
            break;

        case WM_CREATE:
        {
             HINSTANCE hInstance = GetModuleHandle(NULL);
             btnClose = CreateWindowEx(0, TEXT("STATIC"), TEXT("X"), WS_VISIBLE | WS_CHILD | SS_NOTIFY, 530, 1, 10, 15, hwnd, (HMENU)1001, hInstance, NULL);
             btnMinimize = CreateWindowEx(0, TEXT("STATIC"), TEXT("_"), WS_VISIBLE | WS_CHILD | SS_NOTIFY, 515, -3, 10, 18, hwnd, (HMENU)1002, hInstance, NULL);
             txtFileName = CreateWindowEx(0, TEXT("EDIT"), TEXT(""), WS_VISIBLE | WS_CHILD, 75, 40, 280, 15, hwnd, NULL, hInstance, NULL);
             btnLoad = CreateWindowEx(0, TEXT("STATIC"), TEXT("Load a file"), WS_VISIBLE | WS_CHILD | WS_BORDER | SS_NOTIFY | SS_CENTER, 380, 38, 150, 20, hwnd, (HMENU)1003, hInstance, NULL);
             btnGo = CreateWindowEx(0, TEXT("STATIC"), TEXT("Protect my file!"), WS_VISIBLE | WS_CHILD | WS_BORDER | SS_NOTIFY | SS_CENTER, 380, 70, 150, 20, hwnd, (HMENU)1004, hInstance, NULL);
             lbLogs = CreateWindowEx(0, TEXT("LISTBOX"), TEXT(""), WS_VISIBLE | WS_CHILD | WS_BORDER | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_OWNERDRAWVARIABLE | LBS_NOTIFY | WS_TABSTOP, 15, 115, 515, 180, hwnd, (HMENU)1005, hInstance, NULL);
             break;
        }

        case WM_COMMAND:
        {
             switch (wParam)
             {
                    case 1004: //Protect my File!
                    {
                         SendMessage(lbLogs, LB_ADDSTRING, 0, (LPARAM)TEXT("TEST"));
                         break;
                    }
             }
             break;
        }

        case WM_PAINT:
        {
             PAINTSTRUCT ps;
             HDC hDC = BeginPaint(hwnd, &ps);
             HPEN hPen = CreatePen(PS_SOLID, 3, 0x0000FF);
             HPEN hOldPen = (HPEN) SelectObject(hDC, hPen);
             HBRUSH hOldBrush = (HBRUSH) SelectObject(hDC, GetStockObject(NULL_BRUSH));
             Rectangle(hDC, 1, 1, 544, 374);
             DrawMyText(hDC, RGB(0xFF, 0xFF, 0xFF), 15, 1, 3, TEXT("Arial Black"), TEXT("JMB Encryption V1.1"), FALSE);
             MoveToEx(hDC, 1, 20, NULL);
             LineTo(hDC, 544, 20);
             MoveToEx(hDC, 1, 354, NULL);
             LineTo(hDC, 544, 354);
             DrawMyText(hDC, RGB(0xFF, 0xFF, 0xFF), 15, 1, 357, TEXT("Arial Black"), TEXT("Written by João Marcelo Brito - BETA Version"), FALSE);
             DrawMyText(hDC, RGB(0xFF, 0xFF, 0xFF), 12, 10, 42, TEXT("Arial Black"), TEXT("File Name:"), FALSE);
             DrawMyText(hDC, RGB(0xFF, 0xFF, 0xFF), 15, 10, 70, TEXT("Arial Black"), TEXT("You can also use Drag and Drop"), FALSE);
             MoveToEx(hDC, 75, 56, NULL);
             LineTo(hDC, 360, 56);
             Rectangle(hDC, 10, 110, 534, 300);
             DrawMyText(hDC, RGB(0xFF, 0xFF, 0xFF), 12, 25, 105, TEXT("Arial Black"), TEXT("Logs "), TRUE);
             SelectObject(hDC, hOldPen);
             SelectObject(hDC, hOldBrush);
             DeleteObject(hPen);
             EndPaint(hwnd, &ps);
             break;
        }

        case WM_CTLCOLORSTATIC:
        {
             SetBkMode((HDC)wParam, TRANSPARENT);
             SetTextColor((HDC)wParam, 0x0000FF);
             return (LRESULT)GetStockObject(NULL_BRUSH);
        }

        case WM_CTLCOLOREDIT:
        {
             SetBkColor((HDC)wParam, 0);
             SetTextColor((HDC)wParam, 0x0000FF);
             break;
        }

        case WM_DRAWITEM:
        {
            LPDRAWITEMSTRUCT Item = (LPDRAWITEMSTRUCT)lParam;
            if (Item->CtlID == 1005)
            {
                if (Item->itemID != -1)
                {
                    if (Item->itemState == ODS_SELECTED)
                    {
                        FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(0));
                        SetTextColor(Item->hDC, 0x0000FF);
                    }
                    else
                    {
                        SetBkColor(Item->hDC, 0);
                        FillRect(Item->hDC, &Item->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
                        SetTextColor(Item->hDC, 0xFFFFFF);
                    }

                    int len = SendMessage(Item->hwndItem , LB_GETTEXTLEN, Item->itemID, 0);
                    if (len > 0)
                    {
                        LPTSTR lpBuff = new TCHAR[len+1];
                        len = SendMessage(Item->hwndItem , LB_GETTEXT, Item->itemID, (LPARAM)lpBuff);
                        if (len > 0)
                            TextOut(Item->hDC, Item->rcItem.left, Item->rcItem.top, lpBuff, len);
                        delete[] lpBuff;
                    }
                }

                if (Item->itemState & ODS_FOCUS)
                {
                    DrawFocusRect(Item->hDC, &Item->rcItem);
                }

                return TRUE;
            }
            break;
        }

        case WM_MEASUREITEM:
        {
            MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT*) lParam;
            if (mis->CtlID == 1005)
            {
                mis->itemHeight = 15; // your desired item height, in pixels
                return TRUE;
            }
            break;
        }

        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top