Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.139.97.157] |
|
Сообщ.
#1
,
|
|
|
Сунул картинку в лисбокс. Однако возникла проблема. Фон надписей в листбоксе затирает картинку, но если поизменять размеры окна, этот фон убирается. Пробовал UpdateWindow по таймеру и SetBkMode для надписей в листбоксе - бесполезно. Подскажите что надо исправить. Теряюсь в догадках. Вот код:
var hBMP : hBitmap; function DlgProc(hWin: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): bool; stdcall; var ps: TPaintStruct; dc: HDC; hMemDC: HDC; rect: TRect; begin Result := False; case uMsg of WM_INITDIALOG : begin hBMP := LoadBitmap(hInstance, 'IMAGE'); SendMessage(GetDlgItem(hWin, 113), LB_ADDSTRING, 0, Integer(PChar('Ñòðîêà'))); SendMessage(GetDlgItem(hWin, 113), LB_ADDSTRING, 0, Integer(PChar('Ñòðîêà'))); end; WM_PAINT: begin dc := BeginPaint(getdlgitem(hWin, 113), ps); hMemDC := CreateCompatibleDC(dc); SelectObject(hMemDC, hBMP); GetClientRect(getdlgitem(hWin, 113), rect); BitBlt(dc, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY); DeleteDC(hMemDC); EndPaint(getdlgitem(hWin, 113), ps); InvalidateRect(getdlgitem(hWin, 113), 0, False); UpdateWindow(hwin); end; WM_DESTROY, WM_CLOSE: begin DeleteObject(hBMP); PostQuitMessage(0); end; end; end; |
Сообщ.
#2
,
|
|
|
Цитата msdn The WM_DRAWITEM message is sent to the parent window of an owner-drawn button, combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed. + Цитата LBS_OWNERDRAWFIXED The owner of the list box is responsible for drawing its contents; the items in the list box are the same height. только так |
Сообщ.
#3
,
|
|
|
А если вместо рисования через WM_PAINT нарисовать фон через WM_ERASEBKGND ??
|
Сообщ.
#4
,
|
|
|
ElcnU, добавил это свойство к листбоксу. Однако взамешательстве насчет WM_DRAWITEM (я не знаю что именно там прорисовать - цвет или кисть, потому как никогда не прорисовывал самостоятельно элементы).
Jenya, это как через WM_ERASEBKGND? Все-таки разные посылаемые сообщения. Ну-ка пример в студию... |
Сообщ.
#5
,
|
|
|
http://www.vbaccelerator.com/home/vb/Code/Controls/Combo_and_List_Boxes/Owner_Draw_Combo_and_List_Box/article.asp
С VB, надеюсь, проблем нет? Если все же есть, тогда тебе сюда: http://www.codeproject.com/KB/combobox/MFC_OwnerDraw_Listbox.aspx |
Сообщ.
#6
,
|
|
|
Я на Делфи, а не с Визуал Си. А на другом регистрироваться надо чтобы скачать пример.
|
Сообщ.
#7
,
|
|
|
Следует уточнить, я имел ввиду использование WM_ERASEBKGND , если картинку использовать в виде фона ListBox. А для картинки в каждом элементе следует использовать OWNERDRAW, как тебе и сказали.
|
Сообщ.
#8
,
|
|
|
Так, а если и то и то сразу использовать. То есть самостоятельную отрисовку строк и отрисовку фоновой картинки. Строки окрашиваю цветом черезстрочно (немного научился):
var ListWnd : THandle; ListDC : hDC; RectBox : TRect; TextBox : Array [0..$400] of Char; BrushNew : hBrush; BrushOld : hBrush; lBoxBitmap : HBITMAP; MemoryDC : hDC; BitmapInfo : TBitmapInfo; Rect : TRect; ////////////////////////////// WM_DRAWITEM : case wParam of ID_PLAYLIST_LISTBOX : begin ListWnd := PDRAWITEMSTRUCT(lParam).hwndItem; RectBox := PDRAWITEMSTRUCT(lParam).rcItem; ListDC := PDRAWITEMSTRUCT(lParam).hDC; if Integer(PDRAWITEMSTRUCT(lParam).ItemID) > -1 then begin if (PDRAWITEMSTRUCT(lParam).itemState and ODS_SELECTED) <> 0 then begin FillRect(ListDC, RectBox, GetSysColorBrush(COLOR_HIGHLIGHT)); SetBkMode(ListDC, GetSysColor(COLOR_HIGHLIGHT)); SetTextColor(ListDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); end else begin FillRect(ListDC, RectBox, GetSysColorBrush(COLOR_WINDOW)); SetBkColor(ListDC, GetSysColor(COLOR_WINDOW)); SetTextColor(ListDC, GetSysColor(COLOR_WINDOWTEXT)); if (PDRAWITEMSTRUCT(lParam).itemID mod 2) <> 0 then begin BrushNew := CreateSolidBrush(RGB(245, 245, 245)); BrushOld := SelectObject(ListDC, BrushNew); FillRect(ListDC, RectBox, BrushNew); SetBkColor(ListDC, RGB(245, 245, 245)); SelectObject(ListDC, BrushOld); DeleteObject(BrushNew); end; end; RectBox.Left := RectBox.Left + 5; RectBox.Right := RectBox.Right - 5; SendMessage(ListWnd, LB_GETTEXT, PDRAWITEMSTRUCT(lParam).ItemID, LongInt(@TextBox[0])); DrawText(ListDC, @TextBox[0], -1, RectBox, DT_SINGLELINE or DT_VCENTER); end; end; end; Нужно проместить на фон лисбокса битмап. Его загружаю при инициализации диалога: lBoxBitmap := LoadImage(hInstance, MAKEINTRESOURCE('Logo'), IMAGE_BITMAP, 0, 0, 0); Ну и остался такой код, ранее использованный в WM_DRAWITEM: GetClientRect(GetDlgItem(hWndPls, ID_PLAYLIST_LISTBOX), Rect); MemoryDC := CreateCompatibleDC(ListDC); SelectObject(MemoryDC, lBoxBitmap); GetObject(lBoxBitmap, SizeOf(TBitmapInfo), @BitmapInfo); BitBlt(ListDC, ((Rect.Right - Rect.Left) - BitmapInfo.bmiHeader.biWidth) - 7, ((Rect.Bottom - Rect.Top) - BitmapInfo.bmiHeader.biHeight) - 7, BitmapInfo.bmiHeader.biWidth, BitmapInfo.bmiHeader.biHeight, MemoryDC, 0, 0, SRCAND); SelectObject(MemoryDC, ListDC); DeleteObject(MemoryDC); DeleteDC(MemoryDC); Понятно что отрисовка растра происходит для кадого пункта в списке. Поэтому при скроллинге контрола или перемещении строк эта картинка накладывается на предыдущие в строках и получается смесь. Самое легко е что можно придумать в такой ситуации - обновлять окно. Но это не устраивает. Как в WM_ERASEBKGND растр подставить в контекст? Что-то не получается. Попробовал подставить, но овнедравные строки перекрывают картинку. Как совместить-то и то и то? |
Сообщ.
#9
,
|
|
|
Неужели никто из программистов тутошних не знает? В аттаче пример текущей реализации. Как нужно рисовать то в WM_ERASEBKGND? Я пытался в такой же контекст копировать картинку - вообще ничего не было, да и ерундень была с фоном тулбара на диалоге из-за этого. Хотя бы на C/С++ дайте код, я уж переделаю как нужно. Или вообще сабклассинг тут нужен?
Текущий код рисует битмап через WM_DRAWITEM - соответственно в каждом пункте списка из-за чего при перемещении по элементам битмап в списке кучу раз на себя накладывается. FillRect пытался добавить, но затираются строчки в списке. Прикреплённый файлlistbox_ownerdraw_winapi.rar (40.07 Кбайт, скачиваний: 120) |
Сообщ.
#10
,
|
|
|
Имелось ввиду WM_ERASEBKGND в оконной процедуре ListBox, то есть сабклассить - надо.
Определяешь клиентскую область и заливаешь кистью с нужным цветом. |