Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: о ListBox  (Прочитано 20579 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« : 05-02-2014 09:38 » 

Исходные данные:   visual c++ 6      +     MFC
                                 ListBox  - требуется изменить стандартный цвет полосы,кот.отмечает выбранную строчку,
                                 с синего на другой (светло                серый,например).

Могу изменить цвет текста, а также фон, вот так:
Код: (C++)
DDX_Control(pDX, IDC_LISTkuku, cl_kuku);

        CListBox        cl_kuku;

HBRUSH CTestDMPbuttonDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
        HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
       
        int id = pWnd->GetDlgCtrlID();

    if(id == IDC_LISTkuku)
        {
           pDC->SetTextColor(RGB(255,0,0));
           pDC->SetBkColor(RGB(192,192,192));
    }

        return hbr;
}
Пока в инете не нашла внятно-понятного ответа на свой вопрос.
Если поможете, то   Улыбаюсь
« Последнее редактирование: 12-02-2014 11:58 от Джон » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 05-02-2014 10:55 » 

OnCtlColor не поможет, тк он отвечает за отображение всего элемента на форме, а тебе нужно "ковыряться" внутри контрола.
Поэтому делай свой класс - наследник CListBox, и переписывай его DrawItem. Для примера смотри MSDN
http://msdn.microsoft.com/en-us/library/kc9hahtd.aspx

Обрати внимание на блок:

if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
      (lpDrawItemStruct->itemState & ODS_SELECTED))

Это как раз то, что тебе нужно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #2 : 11-02-2014 13:21 » 

Джон, почти неделю мучилась с этой задачкой, про которую и написано таки немало.
Но, результата нет.
Теперь по порядку:
1. visual c++ 6  & MFC
2. кидаю ListBox на диалоге с LBS_OWNERDRAWVARIABLE без сортировки
3. Создаю свой класс CMyListBox : public CListBox...
         в нём  DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) - содержимое из MSDN
4. объявляю в диалоге CMyListBox m_list;

5.Пытаюсь записать информацию   m_list.AddString("11"); - при Debug вылетает на ASSERT ?
                                                                                                  без Debug список чист
Только   не надо на меня сильно ругаться - я что-то мб простое не понимаю или упустила Не понял
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 11-02-2014 13:43 » 

ann_nef, ну... код покажи. Особенно в части DrawItem.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 11-02-2014 19:51 » 

ann_nef, всё в порядке. У тебя скорей всего типичная ошибка человека не желающего разбираться в матчасти. Просто стиль LBS_OWNERDRAWVARIABLE требует наличия в наследуемом классе ещё парочки виртуальных ф-ций.

Поэтому, в дереве классов правой кнопочкой по классу твоего ListBox -> добавить виртуальную ф-цию -> добавляешь MeasureItem и CompareItem и... наслаждаешься цветами. Ага


зы Почитай вот тут, даже на русском Ага http://www.firststeps.ru/mfc/steps/help/r.php?947

* TestListBox.zip (16.97 Кб - загружено 925 раз.)
« Последнее редактирование: 11-02-2014 19:54 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #5 : 12-02-2014 08:05 » 

Джон,что-то не получается наслаждаться цветами…
Добавила виртуальные ф-ции CompareItem и MeasureItem. Цвет меняется, но есть проблемы c m_list.Add

Джон, как перевести на русский : «Вызванный рамкой, когда список владельцем создан со стилем отрисовки владельцем.»
« Последнее редактирование: 12-02-2014 09:49 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 12-02-2014 08:42 » 

Подозреваю, что это был машинный перевод. Это означает, что в случае, когда класс списка (например CMyListBox) является наследником базового класса (CListBox) и у него установлен стиль LBS_OWNERDRAWVARIABLE, то эти ф-ции должны быть переопределены в дочернем классе.

А мой пример у тебя работает?

зы Я ща на работе, а тут у меня нет шестой студии (эт я дома на одном старом компе её откапал), поэтому с проверкой будет сложновато.

зы зы Ща глянул "Первые шаги". И должен извиниться. Забудь про них. Когда-то это был неплохой ресурс для начинающих, а теперь получается машинный перевод MSDN на корявый русский. Сорри. Жаль

зы зы зы http://msdn.microsoft.com/en-us/library/bk2h3c6w%28v=vs.71%29.aspx и не только для CLIstBox
« Последнее редактирование: 12-02-2014 09:31 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #7 : 12-02-2014 10:58 » 

Что-то стало получаться, когда добавила MeasureItem и убрала Has strings у ListBox.
CompareItem в моём случае вроде бы не нужна, тк не использую сортировку.

Джон, но, мб с ходу ответишь, почему так получается?
Код: (C++)
...
CMyListBox m_list;
....
// Вот кусочек программы из обработки  клика на кнопку
CString str[]={"1","2","3","4","5"};
for(int i=0;i<2;i++)
{              
    m_list.AddString((LPCTSTR)str[i]); // причина в этом
    m_list.AddString("kuku");
    m_list.AddString("bubu");
}
На месте 1 и 4 кракозябры(см. картинку во вложении), а с kuku bubu - всё хорошо.

Буду разбираться как CString в LPCTSTR перегнать.

* List.JPG (12.85 Кб - загружено 959 раз.)
« Последнее редактирование: 12-02-2014 12:42 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 12-02-2014 11:52 » 

CompareItem в моём случае вроде бы не нужна, тк не использую сортировку.

Дело не в этом, а в том, что базовый класс вызывает эту ф-ю хочешь ты того или нет. Поэтому переопределить её придётся. Можешь оставить как она создана мастером и ничего в ней не меняй.

Сравни стили ListBox в моём проекте. Собственно в MSDN примере в коментах написано с какими стилями он его создал.

Джон, но, мб с ходу ответишь, почему так получается?

Да легко. Ага

Только давай для начала ты мне ПОДРОБНО, те буквально каждую букаффку, объяснишь вот эту строчку:
Код: (C++)
CString str[]={"1","2","3","4","5"};

1. что ты хотела сделать?
2. что ты на самом деле сделала?
3. почему ты так сделала?
4. (риторический) КТО?
« Последнее редактирование: 12-02-2014 11:56 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #9 : 12-02-2014 12:57 » 

CompareItem в своём классе прописала, так что он есть.

Я пытала сымитировать(наше любимое слово), что я буду
  1.читаю информацию из бинарного файла
  2.преобразовывать в текстовый вид(CString str)
  3.записываю в ListBox так  m_list.AddStrring(str);

1 и 2 - это в основной программе делается, используется стандартный ListBox.

Сейчас поменяла CString на LPCSTR и получились нормальные строчки.
Но! буду разбираться теперь как от CString перейти на LPCSTR.

Джон на все вопросы ответила? риторически  - я во всём виновата. Краснею
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 12-02-2014 15:43 » 

Улыбаюсь

Ага. Ляп  втихую исправила. "Пабысраму". И радуется.

Дело в том, что в строчке:

Код: (C++)
CString str[]={"1","2","3","4","5"};

ты определяешь МАССИВ объектов ТИПА CString. А не одну строчку. В конечном итоге, ты передаёшь УКАЗАТЕЛЬ на этот массив в ф-ю AddString, приводя его к типу LPCTSTR:

Код: (C++)
m_list.AddString((LPCTSTR)str);

Получается, что некая область памяти, куда указывает этот указатель, начинает интерпретироваться как строка символов, до первого встречного нуля. Поэтому ты и видела кракозябры.

Ладно
Код: (C++)
str[i]
тебя спасло. Ага Надеюсь ошибка заключалась в "торопыжности", а не в непонимании материи. Риторический вопрос был на тему: кто тебя надоумил так делать?

Ок, к CString и LPCSTR.

CString это в 6-ой студии, объект библиотеки MFC. LPCSTR - простой дефайн указателя (LP - long pointer) стандартного типа данны C++, а именно - char. Буква С - стоит для const. Ну и поскольку массив char-ов - это какая-никакая строка, поэтому и STR. "Не далее, не более" (с)

Вместо LPCSTR  ты можешь написать: const char *

Совершенно очевидно, что перейти от CString (объекта) к LPCSTR  (указателю) будет довольно затруднительно.

Поэтому сначала надо разобраться что же такое "бинарный файл" и "текстовый вид". По сути абсолютно ВСЕ данные в файлах являются бинарными. Даже текстовые. Открой какой-нить текстовый файл в HEX-редакторе. И ты не увидишь ни одной буквы кроме A..F (как "цифр" шестнадцатиричных чисел). Остальное всё цифры. Решающий момент, это как мы будем интерпретировать эти данные. Например, из файла прочитано число 0x3F. Что это? 63 яблока в корзине? или это счёт 3:15 некой игры? или это код символа вопроса? Да это может быть всё что угодно. Поэтому ты и только ты определяешь, что означает эта "бинарная" информация.

В каком виде ты читаешь её из файла? Как массив байтов? Но массив байтов конечной длинны и есть уже по сути строка. Если коды соответствуют символам, то ты можешь смело передавать указатель на такой массив хоть в ф-ю AddString, хоть в конструктор объекта CString если тебе больше нравиться работать с ним.

byte* pByte = ...
m_list.AddString((LPCTSTR)pByte);
auto st = CString(pByte);
m_list.AddString(st);








Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #11 : 13-02-2014 06:18 » 

Так,как говорит наш президент, отделим мух от котлет.
1.
Сначала о том кусочке тестовой программы,кот. так раскритиковал.
Хотела как-то проверить свой класс CMyListBox.
Для этого надо что-то было записать в строки.
Первое что пришло в голову написать:
CString str;
for(int i=0;i<10;i++)
{
    str.Format("%d %d%d%d%d",i,i,i,i,i);
   m_list.AddString(str);
}
Получила кракозябры,удивилась,тк при стандартном ListBox работает без вопросов!
 Стала судорожно что-то менять, поэтому появился вариант CString str[]={""1", ..},который так тебе не понравился.
А ситуация мной пока не решена:      
      у меня  нормальная вменяемая инфа в стандартном ListBox,но без изменения цвета выбора 
      либо кракозябра вместо инфы в моём MyListBox,но с изменением цвета.
 Что делать? И кто виноват? - знаю ответ только на второй вопрос.
                                                           




Добавлено через 18 минут и 28 секунд:
2. Почему я использую CString и что такое бинарники в моём представлении(спасибо за подробный рассказ о них)
Файлы, с которыми я работаю, передаются мне из QNX, записаны они,к примеру
      справочник некий по структуре
struct SPR1
{   
      unsigned short    Kod1,
     char     Name[30], AbrS [11];
      unsigned char   s[2],n [2], gsp, num_ka, kol_s, num_p;
      S _INFO        s _info;
    GSP       gsp[2];
                 S_M_INFO        s_m_info;
     ……………………и тд и тп
   crc_t   crc;
};
или файл -основная информация
struct P_RECORD{
        time_t time_event;
        unsigned short type_event,len_rec;
        union unid{
                   REZULT                 rezult_reg_user;
                   time_t          time_of_cp;
                  unsigned char         regim_upr,
                  EVENT_1                event_1;
……..
         EVENT_50      event_50;      
   }unid;
};

Читаю байты и потом разбираю, ищу в справочниках доп.инфу , формирую строку CStringи пишу в ListBox
« Последнее редактирование: 13-02-2014 06:37 от ann_nef » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 13-02-2014 08:27 » 

Цитата: ann_nef
Первое что пришло в голову написать:
CString str;
for(int i=0;i<10;i++)
{
    str.Format("%d %d%d%d%d",i,i,i,i,i);
   m_list.AddString(str);
}
Получила кракозябры,удивилась,тк при стандартном ListBox работает без вопросов!
 Стала судорожно что-то менять, поэтому появился вариант CString str[]={""1", ..},который так тебе не понравился.
Ну это штука фундаментальная: отличать значение от указателя.

Контрол значения строки не содержит. Он содержит указатель на значение, которое ты сама создаёшь в другой части программы. Что ты делаешь в цикле? Переписываешь одну и ту же область памяти разными значениями. При перезаписи внутри CString, когда не хватает размера внутреннего буфера, происходит замена буфера на новый - большего размера. Но указатели-то, ранее записанные в контрол, никто не менял: они ссылаются на старые участки памяти уже удалённых буферов. Отсюда каша.

Когда ты делаешь массив строк, Джон уже объяснил, что происходит.

Раз такая неразбериха, я бы посоветовал сначала как следует потренироваться на обычных C-строках (char *, он же LPSTR) и указателях, прежде, чем браться за использование классов CString из MFC или string из STL. Т.е. это принципиальный момент. Без него хоть сколько-нибудь сложных программ на C++ писать не получится - будут бесконечные баги и косяки.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #13 : 13-02-2014 09:10 » 

Dimka, я согласна со всем, что пишешь. Да-да

Но, почему это работает в стандартном ListBox ?

И мб, если всё-таки находимся "Учимся программировать>Начинающим", то гуру покажут ,как эту ситуацию разрешить. Здесь была моя ладья...    
Как бы заполнили ListBox?
for(int i=0;i<10;i++)
{
 "i=0 0000"  записать в m_list??
  
}
Буду очень вам признательна

Я задержалась так долго на создании своего ListBox,  а мне всего-то нужно было, чтобы у одного неактивного из двух LIstBox полоса выделения становилась серенькой, а у активного она была стандартно синей.
« Последнее редактирование: 13-02-2014 10:25 от ann_nef » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 13-02-2014 10:34 » 

ann_nef, посмотрел MSDN по этому поводу. Внутреннее хранилище в стандартном ListBox есть. Причём вызовом метода InitStorage его можно настраивать под количество элементов и под размер элементов. Что в нём хранится - сами ли строки, или указатели, не знаю. Но это можно проверить. Структура DRAWITEMSTRUCT меня удивила. Элемент itemData имеет тип DWORD - 4 байта, число. Но рассматривается как-то самое значение, которое было получено в AddString. Любопытно, как это работает на 64-х битах, но это лирика, к 6-й студии отношения не имеющая. Поскольку AddString принимает указатель, "то же самое значение" должно быть в точности тем самым указателем. Это несложно проверить.

Добавь в класс вспомогательную переменную типа char *.
Код: (C++)
LPSTR m_CheckPtr;

Непосредственно перед AddString сделай приведение к типу const char *.
Код: (C++)
str.Format(...
m_CheckPtr = (LPCSTR)str;
m_list.AddString(...

В методе отрисовки тоже получи указатель правильного типа и сверь с тем, который сохранился до этого:
Код: (C++)
LPSTR s = (LPCSTR)lpDrawItemStruct->itemData;
ASSERT(s == m_CheckPtr);
...

Добавь в контрол только 1 строчку и запусти. Если свалится по assert, значит внутри происходят преобразования и копирования. Тогда косяки нужно искать в другом месте. Если нет, значит указатели совпадают, и значит структуру данных (строчку) для каждого пункта нужно хранить вручную, а сам контрол содержит только массив указателей.

Что там происходит в точности в этом твоём случае, я не знаю. Поэтому предлагаю либо проверить и узнать в точности, либо ждать, что Джон "придёт и всё исправит". 6-й студии у меня нет, чтобы посмотреть самому.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 13-02-2014 13:08 » 

Как бы заполнили ListBox?
for(int i=0;i<10;i++)
{
 "i=0 0000"  записать в m_list??
  
}
Буду очень вам признательна


Насчёт "0 пробел 0000" не понял логики. Как будет выглядеть, например, седьмой элемент?
А если надо выровнять до 5 нулей, типа 00001 00002 00003 ... то

Код: (C++)
        for (int i = 0; i<10; i++)
        {
                CString stBuf;
                stBuf.Format(_T("i=%05d"), i);
                m_myListBox.AddString(stBuf);
        }

Добавлено через 8 минут и 31 секунду:
Я задержалась так долго на создании своего ListBox,  а мне всего-то нужно было, чтобы у одного неактивного из двух LIstBox полоса выделения становилась серенькой, а у активного она была стандартно синей.

И чего бы сразу с этого не начать? Нууу взяла бы не ListBox, а ListCtrl, у него есть стиль LVS_SHOWSELALWAYS, который делает именно то, что тебе надо - фокус синий, без фокуса -> серый.
« Последнее редактирование: 13-02-2014 13:16 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #16 : 13-02-2014 13:24 » 

Джон, Dimka, проект прицепляю,чтобы все мои изыскания были видны.
Докопалась до того, что если
 1.   стандартная ListBox и m_listMFC.AddString(CString str), то первым делом выполняется
      _AFX_INLINE CString::operator LPCTSTR() const
      {return m_pchData;}
 2. при моей - нет
 3. если использовать
    char *p;
    p = new char[30];
    int i=99;
    spintf(p,"i=%d",i);
    m_list.AddString(p);
    появиться строчка в MuListBox   i=99
    4.НО,если делать в цикле, то появится n-раз n-яя строка
       Это почему так?
    5.То, что хотела, получила только многократным выполнением программки,где
       содержится п.3 без цикла

Честно говоря рез-т п.4 мне не понятен.

Помогите разобраться, п-ста



Добавлено через 6 минут и 16 секунд:
Джон писали одновременно.
Твоё         for (int i = 0; i<10; i++)
        {
                CString stBuf;
                stBuf.Format(_T("i=%05d"), i);
                m_myListBox.AddString(stBuf);
        }
будет изображаться кракозяброй.
С этим практически разобралась, если перейти на char* или в своём классу прописать то, что написала в п.1 своего предыдущего сообщения.
Посмоти,п-ста, что написала. Мб там не всё глупость.

* ColorListBox.zip (29.58 Кб - загружено 887 раз.)
« Последнее редактирование: 13-02-2014 13:31 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 13-02-2014 13:51 » 

У меня на работе, только 2012/13 студии. Поэтому в 6-ой смогу посмотреть только дома.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 13-02-2014 14:46 » 

Цитата: ann_nef
НО,если делать в цикле, то появится n-раз n-яя строка
       Это почему так?
Ну явный признак, что список содержит n указателей на одну и ту же - последнюю - строку, которая получилась на последней итерации цикла. Т.е. тут тебе повезло, что буфер внутри строки не пересоздавался, и поэтому нет мусора.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #19 : 13-02-2014 15:10 » 

А ну всё понятно. Я даже как-то не обратил на это внимание.

Твоё
        for (int i = 0; i<10; i++)
        {
                CString stBuf;
                stBuf.Format(_T("i=%05d"), i);
                m_myListBox.AddString(stBuf);
        }
будет изображаться кракозяброй.

И это естественно. По той же причине. CString stBuf; создаётся на стеке и в конце итерации перестаёт существовать. Поэтому сохранённые указатели указывают на какой-то мусор в памяти. Для этого объекты надо сохранить в каком-нить контейнере. Самое простое:

добавить диалогу мембер
private:
   CStringArray m_staBuf;

и в OnInitDialog()

   CString str;
   for(int i=0;i<20;i++)
   {
      str.Format(L"i=%d %d%d%d%d",i,i,i,i,i);
      m_staBuf.Add(str);
      m_listMFC.AddString(str);
   }

   for (int i = 0; i<20; i++)
   {
       str.Format(L"i=%d %d%d%d%d", i, i, i, i, i);
       m_staBuf.Add(str);
       m_list.AddString(str);
   }

В прицепе я доработал твой проект в 2013 студии, но я думаю ты сможешь открыть его и в 6-ой. Если нет, то просто скопируй .h,.cpp.rc файлы в твой проект.

В качестве бонуса, доработал листбокс (выбросил тела виртуальных ф-ций, ты же сама сказала что сортировать не надо) и диалог, оба списка теперь объекты "твоего" класса с нужной функциональностью - активный/не активный.

зы Совсем забыл. Удали L перед " в 6ой студии. Просто 2013-я работает теперь только с юникодом.

* ColorListBox2.zip (30.46 Кб - загружено 902 раз.)
« Последнее редактирование: 13-02-2014 15:17 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #20 : 14-02-2014 05:36 » 

Из Сухановской песни :"Спасибо, спасибо тому строил..."
Джон, спасибо!!!
Конечно, всё получилось. Настроение стало отличное.
Dimka -тоже спасибо.

Добавлено через 4 дня, 3 часа, 40 минут и 39 секунд:
Рано радовалась...
Не получается прочитать из MyListBox, например 3 строку :

CString str;
m_list.GetText(3,str); Не понял
« Последнее редактирование: 18-02-2014 09:16 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #21 : 18-02-2014 14:35 » 

Час от часу не легче. Улыбаюсь
А ведь начали с простого цвета фона... Что ты ещё собираешься с ним делать?
"Огласите весь список пжалуста." (с)

Ладно, продолжаем учить матчасть. Итак, MSDN несёт разумное, доброе... короче MSDN несёт:

1. GetText есть ничто иное как отправка сообщения LB_GETTEXT для получения текста конкретного элемента.
2. НО у нас установлен стиль LBS_OWNERDRAWVARIABLE и выключен стиль LBS_HASSTRINGS
Вот что говорит MSDN для такой комбинации

Цитата: MSDN

LBS_HASSTRINGS

Specifies that a list box contains items consisting of strings. The list box maintains the memory and addresses for the strings so 1. that the application can use the LB_GETTEXT message to retrieve the text for a particular item. By default,  2. all list boxes except owner-drawn list boxes have this style. You can create an owner-drawn list box either with or without this style.

3. For owner-drawn list boxes without this style, the LB_GETTEXT message retrieves the value associated with an item (the item data).

Итак:

1. Для того, чтобы мы могли пользоваться ф-ей GetText, у ListBox ДОЛЖЕН быть установлен стиль LBS_HASSTRINGS
2. Этот стиль установлен по умолчанию у всех типов ListBox ЗА ИСКЛЮЧЕНИЕМ созданных с установленным стилем LBS_OWNERDRAW
3. Если этот стиль не установлен, GetTеxt возвращает значение itemData.

В силу 3, можно использовать для получения текста запись в ListBox след. образом:

Создавать строковые объекты в куче (*p = new CString) и сохранять указатель в поле itemData:
m_list.SetItemData(i, (DWORD)p);

тогда через GetItemData или (в силу п.3) GetText получив указатель, мы приведём его к типу указателя на CString и получим наш текст. Только надо не забыть освободить память после окончания работы со списком, или же перед его след. новой инициаллизацией.

Можно сделать по-другому (учитывая пп 1 и 2). Чтобы получать текст, как ты хочешь, необходимо установить стиль LBS_HASSTRINGS, в этом случае, необходимо будет доработать ф-ю DrawItem, тк мы уже не можем в ней получать текст через указатель itemData.
Код: (C++)
...
        LPCTSTR lpszText = (LPCTSTR)lpDrawItemStruct->itemData;
        ASSERT(lpszText != NULL); // в этому случае указатель lpszText будет нулевым
...

Те эти строчки необходимо будет выбросить, а для рисования использовать текст полученный через вызов GetText

вместо:
Код: (C++)
        // Draw the text.
        dc.DrawText( lpszText, (int)_tcslen(lpszText),
                &lpDrawItemStruct->rcItem, DT_LEFT | DT_SINGLELINE | DT_VCENTER);

отрисовываем текст так:
Код: (C++)
        CString st;
        GetText(lpDrawItemStruct->itemID, st);
        // Draw the text.
        dc.DrawText(st, st.GetLength(),
                &lpDrawItemStruct->rcItem, DT_LEFT | DT_SINGLELINE | DT_VCENTER);

Я думаю, второй вариант тебе больше подходит.

зы СОВСЕМ ЗАБЫЛ!!!  Включенный стиль LBS_HASSTRINGS означает, что ListBox сам заботится о содержимом - выделяет и управляет памятью, те тебе больше нет необходимости дополнительно сохранять текс в контейнере и m_staBuf.Add(str); в циклах как и сам контейнер можно выбросить.
« Последнее редактирование: 18-02-2014 14:44 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #22 : 19-02-2014 05:10 » 

Это получилось, но...без отладчика

При DEBUG ошибка:
Debag Assertion Failed!
Program: .....
File: strcore.cpp
Line: 519

Пытаюсь разобраться, что не так Жаль

Хотя сделала вариант, чтобы не надо было читат, те не использую GetText,остановилась на предыдущем варианте.
« Последнее редактирование: 19-02-2014 12:27 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #23 : 19-02-2014 10:35 » 

Выложи актуальный код, что-то ты упустила.

ps или лучше так, сравни с этим, он работает и в DEBUG

* ColorListBox3.zip (13.95 Кб - загружено 871 раз.)
« Последнее редактирование: 19-02-2014 11:24 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #24 : 19-02-2014 12:32 » 

Джон на тестовой задаче всё получилось, а в рабочей муть с дебагером.
Программа рабочая большая...
Сейчас посмотрю твою программу.
Проблему не решила, а обошла.
« Последнее редактирование: 19-02-2014 12:34 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 19-02-2014 23:37 » 

1. В каком именно месте в программе падает?
2. Что стоит в:

File: strcore.cpp
Line: 519

У меня просто сейчас исходников MFC 4.2 под рукой нет, но там должно быть всё ясно написано.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #26 : 21-02-2014 07:14 » 

Джон, хотя и обошла проблему, но почему-то никак не могу успокоиться.
Поэтому возвращаюсь к ней.
На твой вопрос:"Что ты ещё собираешься с ним делать? "
Писать в него и читать из него - с этим вроде бы разобрались.

Ещё временами хочу делать то видимым, то не видимым.

Так вот, после заполнения MyListBox информацией, я пытаюсь сделать его на время невидимым:
this->GetDlgItem(ID_LIST1))->ShowWindow(SW_HIDE)

и получаю
LPTSTR CString::GetBufferSetLength(int nNewLength)
{
   ASSERT(nNewLength >= 0); Вылетает на этой строке!!!!….
}


Содержимое стека:

CString::GetBufferSetLength(int -1) line 519 + 25 bytes
CListBox::GetText(int -1, CString & {""}) line 153 + 21 bytes
CMyListBox::DrawItem(tagDRAWITEMSTRUCT * 0x0012e9e0) line 89

Line 89 в CMyListBox::DrawItem:
dc.DrawText(st, st.GetLength(),
                      &lpDrawItemStruct->rcItem,
                       DT_LEFT | DT_SINGLELINE | DT_VCENTER);



Добавлено через 3 минуты и 13 секунд:
Да, в тестовой программке всё работает. То есть, пишет, читает, делает невидимыми и видимыми оба ListBox, попеременно и одновременно  А черт его знает...
« Последнее редактирование: 21-02-2014 07:18 от ann_nef » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #27 : 21-02-2014 13:53 » new

Хм... По теории, если контрол невидим, то для него не должно никаких DrawItem вызываться. Эт раз. Вылетает в момент "выключения" или "включения"? А если это (вкл/выкл) не делать, всё нормально работает?

2. Отследи вызовы DrawItem , чтобы установить с каким именно элементом проблема и что у него за текст в этот момент. Для этого добавь перед dc.DrawText ... след. код:

TRACE2("item=%d text=%s\r\n", lpDrawItemStruct->itemID, st);

3. Проверь ещё раз внимательно, в чём разница между тестовым и твоим проектами. Особое внимание удели стилям ListBox, его инициаллизации  и текстам.
« Последнее редактирование: 21-02-2014 13:55 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines