0

我没有成功绘制自己的列表框,代码如下:

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;
}

我像这样创建 ListBox:

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);

有人可以向我解释其中有什么问题吗?我正在尝试制作一个具有黑色背景和红色文本的列表框,当一个项目被选中时,它的文本将转换为白色。但列表框不添加任何内容。

4

2 回答 2

5

您正在创建一个列表框,然后安装您自己的 WNDPROC 来处理发送到列表框的消息。但是,自绘列表框会向其所有者发送 WM_MEASUREITEM 和 WM_DRAWITEM 消息,因此您需要在父窗口的 WNDPROC,而不是列表框 WNDPROC 中处理这些消息。

此外,即使子类化是正确的方法(在这种情况下不是这样),您的子类 WNDPROC 也应该将未处理的消息传递给原始列表框 WNDPROC,而不是 DefWindowProc()。绕过原始列表框 WNDPROC 很可能会导致麻烦。

于 2012-08-08T19:19:43.203 回答
3

LBS_OWNERDRAW...创建 ListBox 时,您没有指定任何窗口样式。这些消息也会发送到 ListBox 的父窗口,而不是 ListBox 本身,因此您需要在WindowProcedure()而不是ListBoxProcedure(). 这就是为什么您没有收到任何WM_MEASUREITEM消息WM_DRAWITEM的原因。

您必须执行该WM_MEASUREITEM消息,而不是像现在这样丢弃它。

在将基于位的标志组合在一起时,您需要使用|运算符而不是运算符,例如窗口样式。+

您没有正确使用LB_GETTEXT消息或DefWindowProc()功能。

试试这个:

#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;
}
于 2012-08-08T18:58:33.857 回答