На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Изображение в ListBox
    Сунул картинку в лисбокс. Однако возникла проблема. Фон надписей в листбоксе затирает картинку, но если поизменять размеры окна, этот фон убирается. Пробовал UpdateWindow по таймеру и SetBkMode для надписей в листбоксе - бесполезно. Подскажите что надо исправить. Теряюсь в догадках. Вот код:

    ExpandedWrap disabled
      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;
      Цитата 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.

      только так :yes:
        А если вместо рисования через WM_PAINT нарисовать фон через WM_ERASEBKGND ??
          ElcnU, добавил это свойство к листбоксу. Однако взамешательстве насчет WM_DRAWITEM (я не знаю что именно там прорисовать - цвет или кисть, потому как никогда не прорисовывал самостоятельно элементы).

          Jenya, это как через WM_ERASEBKGND? Все-таки разные посылаемые сообщения. Ну-ка пример в студию...
            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
              Я на Делфи, а не с Визуал Си. А на другом регистрироваться надо чтобы скачать пример.
                Следует уточнить, я имел ввиду использование WM_ERASEBKGND , если картинку использовать в виде фона ListBox. А для картинки в каждом элементе следует использовать OWNERDRAW, как тебе и сказали.
                  Так, а если и то и то сразу использовать. То есть самостоятельную отрисовку строк и отрисовку фоновой картинки. Строки окрашиваю цветом черезстрочно (немного научился):
                  ExpandedWrap disabled
                    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;


                  Нужно проместить на фон лисбокса битмап. Его загружаю при инициализации диалога:
                  ExpandedWrap disabled
                            lBoxBitmap := LoadImage(hInstance, MAKEINTRESOURCE('Logo'), IMAGE_BITMAP, 0, 0, 0);


                  Ну и остался такой код, ранее использованный в WM_DRAWITEM:
                  ExpandedWrap disabled
                            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 растр подставить в контекст? Что-то не получается. Попробовал подставить, но овнедравные строки перекрывают картинку. Как совместить-то и то и то?
                    Неужели никто из программистов тутошних не знает? В аттаче пример текущей реализации. Как нужно рисовать то в WM_ERASEBKGND? Я пытался в такой же контекст копировать картинку - вообще ничего не было, да и ерундень была с фоном тулбара на диалоге из-за этого. Хотя бы на C/С++ дайте код, я уж переделаю как нужно. Или вообще сабклассинг тут нужен?
                    Текущий код рисует битмап через WM_DRAWITEM - соответственно в каждом пункте списка из-за чего при перемещении по элементам битмап в списке кучу раз на себя накладывается. FillRect пытался добавить, но затираются строчки в списке.
                    Сообщение отредактировано: Maksim V. -

                    Прикреплённый файлПрикреплённый файлlistbox_ownerdraw_winapi.rar (40.07 Кбайт, скачиваний: 120)
                      Имелось ввиду WM_ERASEBKGND в оконной процедуре ListBox, то есть сабклассить - надо.
                      Определяешь клиентскую область и заливаешь кистью с нужным цветом.
                      Сообщение отредактировано: Jenya -
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0331 ]   [ 16 queries used ]   [ Generated: 26.04.24, 21:07 GMT ]