所有者绘制的窗口
OwnerDrawn Window
我并没有成功地绘制自己的列表框,这是代码:
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;
}
我像这样创建列表框:
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);
有人可以向我解释其中有什么问题吗?我正在尝试制作一个包含黑色 bg 和红色文本的列表框,当一个项目被选中时,它的文本会转换为白色。但是列表框不会添加任何内容。
您正在创建一个列表框,然后安装自己的 WNDPROC 来处理发送到列表框的消息。 但是,所有者绘制列表框向其所有者发送WM_MEASUREITEM和WM_DRAWITEM消息,因此您需要在父窗口的 WNDPROC 中处理这些消息,而不是列表框 WNDPROC。
此外,即使子类化是正确的方法(在这种情况下不是),您的子类 WNDPROC 也应该将未处理的消息传递给原始列表框 WNDPROC,而不是 DefWindowProc()。 绕过原始列表框 WNDPROC 很可能会造成麻烦。
创建列表框时未指定任何LBS_OWNERDRAW...
窗口样式。 这些消息也会发送到列表框的父窗口,而不是列表框本身,因此您需要在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;
}
相关文章:
- QuadTree只在窗口的右上角绘制
- SFML 文本未绘制在窗口上
- GDI 绘制到外部窗口 (C++)
- 使用标准窗口与wxWidgets一起绘制?
- 如何在SDL2窗口上使用Cairo绘制一条白色直线
- 为什么在GLFW窗口中没有用这个代码在我的屏幕上绘制立方体
- 如何在 direct2d 中使用随其窗口重新缩放的效果绘制图像
- 如何使用WinAPI每帧只重新绘制一次子窗口
- 使用 Win32 将 GDI 绘制大小缩放为窗口大小
- 如何在窗口外绘制图形(OpenGL GLFW)
- SFML参考窗口在绝对位置绘制
- 在窗口大小上绘制的OpenGL消失
- 在 c++ 生成器中检测绘制线的窗口坐标的最佳方法
- 如何在调用函数时将对象绘制到 sfml 窗口上
- 如何将成员从类绘制到窗口 c++ 上
- 如何在子小部件而不是父窗口小部件上绘制一条线
- OpenGL-如何绘制完整的窗口矩形
- 如何调用OnEraseBkgnd()在另一个函数中重新绘制窗口?(MFC)
- WTL 如何在同一窗口中使用 2 个自定义绘制的 CListViewCtr
- 如何在win32中在不覆盖标题栏的情况下围绕窗口绘制矩形