| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > Картинка в CListCtrl из буфера обмена |
| Автор: jackevsen 2.2.2009, 23:35 | ||
MFC приложение.Задача следующая: В буфере обмена есть картинка и эту картинку нужно поместить в CListCtrl.Делаю так:
CPaintDC dc(this); - здесь this это окно HGDIOBJ pOldBitmap = newdc.SelectObject(icon); - здесь icon это (HBITMAP)GetClipboardData(uFormat); где uFormat это CF_BITMAP Ситуация следующая...картинка в буфере обмена есть точно.Если раскомментировать вот эту строчку : //dc.BitBlt(20,20,50,50,&newdc,0,0,SRCCOPY); то картинка нарисуется на форме.Когда я пытаюсь запихнуть ее в CListCtrl, то у меня появляется только черный квадратик. Я уже перепробовал разные способы, в том числе создавать CBitmap и запихивать в него icon через FromHandle() и Attach().Ничего не получается...все тот же черный квадратик. В чем здесь может быть дело?Или я вообще двигаюсь не в том направлении.....? |
| Автор: Earnest 3.2.2009, 11:30 |
| 1) Если icon - это bitmap (кстати, зачем себе и любям мозги пудритьтакими именами?), то почему ты не помещаешь ее в imageList непосредственно - т.е. просто Add (icon, RGB(...)), зачем это делать через CDC? 2) Убедись, что картинка по размеру соответствует размеру картинки в image-list и что цвет маски выбран разумный 3) Не вижу, как ты эту картинку присваиваешь итему |
| Автор: jackevsen 3.2.2009, 20:30 | ||||
| icon - это HBITMAP, и если сделать так cImageList.Add(icon,RGB(0,0,0)); то на меня наругаются и скажут ,что не могут переконвертить HBITMAP в CBitmap *. Делал так:
В этом случае даже черного квадратика не появляется. Делал так:
В этом случае появляется черный квадратик. CDC я задействовал из-за того, что: Я пока не очень хорошо разбираюсь в подобных механизмах и в интернете находил код где всегда использовалось CDC.И потом, ради эксперимента я хотел что бы картинка из буфера обмена у меня рисовалась на форме.Эксперимент удался, картинка рисуется, и я подумал раз уж в CDC эта картинка есть, то её можно вытащить и в imageList.Отсюда и строка cImageList.Add(newdc.GetCurrentBitmap(),RGB(0,0,0)); но в этом случае у меня появляется только черный квадратик.Потом я начал искать пути решения проблемы и пробовал тот код, который написал чуть выше в этом посте.Все равно ничего не получается.... |
| Автор: Earnest 4.2.2009, 08:32 |
| Код, где используешь bmp.Attach - правильный, использовать контекст - нафиг не нужно. Обрати внимание также на остальные пункты моего поста. Имена лучше выбирать такие, чтобы они подсказывали, а не путали. Есть тип HICON и есть тип HBITMAP. Если ты битмап обозвал icon, то иконка у тебя будет называться bitmap? Правильные имена очень важны: компилятору-то все равно, а вот коллеги-программисты и побить за такое могут. Я бы точно не удержалась. |
| Автор: jackevsen 4.2.2009, 22:23 |
И не сомневаюсь.... В первой же строчке ответа на мою тему: "Ты почему не используешь 9-ю поправку к приложению №276/34 от 7.05.2007, а вместо этого присваиваешь переменным имена по своему разумению.Ты что, не уважаешь комитет по стандартизации?" В свое оправдание могу сказать, что на работе работаю с языком в котором не важен тип переменой, с каким она объявляется...так как тип этой переменной в функции еще 10 раз поменяться может.А конкретно про имя icon... то это наверное потому, что в свойствах CListCtrl есть свойство View и в нем есть значение Icon....возможно поэтому я эту переменную так назвал А так, конечно, про имена переменных полностью согласен. Теперь по теме.... Что-то у меня не получается.... А что будет, если размер картинки не соответствует размеру картинки в image-list? Будет видна только часть картинки или она вообще видна не будет? Такой момент интересный...Когда я все эти манипуляции делаю в OnPaint окна в котором расположен CListCtrl, то у меня в итемах вместо картинки появляются черные квадратики, а если в другой функции , то даже этих квадратиков нету... Хотя, с другой стороны для эксперимента писал такую строчку: ListImage->SetBkImage(icon,1,bmpInfo.bmHeight,bmpInfo.bmWidth); и та картинка, которая в буфере обмена,появляется в CListCtrl на заднем плане....Это еще раз доказывает что картинка есть и её можно отобразить....А в итеме никак появляться не хочет.... |
| Автор: jackevsen 5.2.2009, 22:57 |
| Я идиот....Нет, я хуже...А еще программистом называюсь....Можно перефразировать один диалог из одной известной передачи: - Ты что там делал? - Я программировал. - Лошара ты, а не программировал! Когда я добавлял картинку к итему то создавал переменную CImageList прямо в функции отслеживающей изменения в буфере обмена, добавлял его в итем.Кстати, делал это так: ListImage->SetImageList(&cImageList,LVSIL_NORMAL); , а при выходе из функции CImageList разрушался, следуя правилам видимости переменных....Поэтому картинки видно не было. Как только я объявил глобальную переменную CImageList cImageList; картинка сразу стала видна в лист контроле. Правда теперь другая проблема...Когда я копирую следующую картинку в буфер обмена, то в лист контроле у меня дублируется первая скопированная картинка.... Блин, как же все сложно....теперь нужно решать эту проблему.... |
| Автор: Earnest 6.2.2009, 08:15 |
| Так ты ее не итему добавляешь, а просто устанавливаешь ImageList. Посмотри структуру, которая передается в InsertItem, там есть переменная для номера картинки + еще маску нужно добавить, что ты картинку устанавливаешь. Причем сначала нужно установить контролу ImageList, а потом уже итемы создавать (или картинки им устанавливать). ImageList конечно, должен жить пока жив список. Поэтому удобнее всего интегрировать его в свой класс-наследник лист-контрола. Создание и присоединение ImageList удобно делать на PreCreateWindow (если контрол динамически создается) или PreSubclassWindow (если ты его в ресурсах на диалог ставишь). Или и там и там, чтобы контрол получился универсальный. Там же можно создавать колонки. |
| Автор: jackevsen 8.2.2009, 17:36 | ||
Сам в своем коде запутался...Итему я добавлял картинку так ListImage.InsertItem(ListImage.GetItemCount(),shText,0); Ну да ладно...с этим я уже разобрался. Переделал добавление на структуру, по твоему совету. Как всегда, одна проблема решена, появляется другая.А именно: Я, когда создаю СImageList то делаю размер картинок 100 Х 100.И когда я копирую в буфер картинку большего размера, то эта картинка при добавлении в СImageList разбивается на несколько картинок одинакового размера, а если я копирую в буфер картинку меньшего размера, то эта картинка вообще не добавляется в СImageList.Поэтом возникла необходимость масштабировать картинку до нужного размера перед добавления её в СImageList. Делаю так:
Но у меня появляется черный квадрат....Я вообще правильно делаю масштабирование? |
| Автор: Earnest 9.2.2009, 09:29 |
Насчет правильно или нет, сразу сказать не могу; но ты можешь сам проверить: вывде битмап на окно, как ты раньше делал с исходным и посмотри. Попробуй заменить CPaintDC на CWindowDC или CClientDC или просто GetDC(this) (только не забудь тогда сделать ReleaseDC). |
| Автор: jackevsen 11.2.2009, 19:52 | ||
| Ура!!! Заработало!!! Оказалось, я всего лишь не написал одну строчку, и из-за этой строчки картинки видно не было....Вот эта строчка: imageDC.SelectObject(oldImageBmp); Тем более, что я видел в других примерах что так нужно делать, но не придал этому такого уж критического значения. Теперь у меня картинки из буфера обмена красиво попадают в CListCtrl и выглядит это так же как Thumbnails в окне Виндовс. Вот, окончательный вариант, может кому-то пригодится....
Earnest, спасибо за отзывчивость и помощь. Ох, как подумаю, сколько еще всего нужно сделать....Следующий шаг это горячие клавиши....Ну,ладно, пойду работать.... |