Тень рисунка с помощью быстрой функции

Программирование на Visual Basic for Applications
Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Тень рисунка с помощью быстрой функции

Сообщение Avtopic » 14.11.2006 (Вт) 13:25

Здравствуйте!

Сделал тень рисунка с помощью GetPixel, SetPixel, но никак не удается сделать с помощью BitBlt.
Поднаправьте чуть-чуть, если можно, как это можно сделать с помощью BitBlt, или дугой быстрой функцией.
Спасибо!
Вложения
Shadow.rar
(18.69 Кб) Скачиваний: 52

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.11.2006 (Вт) 13:55

Avtopic, если уж у тебя в коде стоит претенциозная проверка на версию Excel при определении hwnd, то почему же ты вызываешь метод Show у формы всегда с параметром? :) В Excel 97 параметра в этом методе нет, и код просто не скомпилируется и не запустится вообще.

Получение маски рисунка через BitBlt можно взять здесь.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 14.11.2006 (Вт) 14:05

Этот файл пол часа тому назад вообще не существовал, сделал для форума пример, добавил кнопку для удобства и сразу же поставил Show 0, вообще, hwnd формы в этом примере тоже не нужно. Можно было взять GetWindowDC(0) для этого примера.

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 14.11.2006 (Вт) 17:49

Все сделал. Спасибо за ветку GSerg. Наконец, понял, где собака зарыта.

Pavel55
Обычный пользователь
Обычный пользователь
 
Сообщения: 90
Зарегистрирован: 27.10.2006 (Пт) 20:11

Сообщение Pavel55 » 14.11.2006 (Вт) 18:43

Нам расскажи )

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 14.11.2006 (Вт) 20:19

Расскажу :) . Потому что файл содержит много мусора, очищу и прикреплю позже.
последний аргумент BitBlt, dwRop в зависимости от флага, совершает
комбинации OR AND XOR NOT операторов над пикселали при копировании.
OR AND XOR NOT это двоичная арифметика т.е. 0 и 1. 0 это белый, а 1 это черный.
Трудность для меня заключалось в том, как различить остальные
цвета, как задать всем кроме белого значение 1, чтобы возможно
было различить, какие пиксели представляют рисунок и какие фон.
Т.н. маска рисунка.
так вот:
Когда происходит BitBlt цветного изображения в черно-белое, BitBlt
устанавливает в 1 все пиксели, совпадающие с цветом фона исходного
изображения. Остальные пиксели устанавливаются в 0.
Таким образом, нужно взять черно-белый Bitmap, и скопировать
изображение туда, получим маску, а потом двоичная арифметика над
нулями и единицами этой маски и основного рисунка.

>>>
Вложения
Shadow new.rar
(22.77 Кб) Скачиваний: 59
Shadow new.rar
(22.77 Кб) Скачиваний: 58

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 15.11.2006 (Ср) 18:33

Ой, два раза добавилось. Один лишний. :roll:

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.11.2006 (Сб) 16:18

Посмотрите, пожалуйста, участок кода. Что там неправильно, что
вызывает сбой Windows-овского меню. Правда, не с первого раза.

Это процедура вызывается из MsgProc (сабклассинга).
Пока в процедуре происходило перерисовка рисунка с помощью
GetPixel, SetPixel, сбой не происходил. Как вставил перерисовку с
помощью BitBlt и пришлось создавать новые контексты устройства
пошли сбои.
Может что-то не уничтожаю в конце процедуры или наоборот не восстанавливаю?
Код: Выделить всё
Private Sub DrawPicture(hdc As Long, rcAreaPicture As RECT, Picture As StdPicture, clPicShadow As Boolean)

Dim hDcSource As Long, hSourceOld As Long
Dim hDcColor As Long, hColorOld As Long, hColorBuff As Long
Dim hMaskDC As Long, hMaskOld As Long, hMaskBuff As Long
Dim PicSize As POINTAPI, Pt As POINTAPI, rec As RECT

If Picture Is Nothing Then Exit Sub

hDcSource = CreateCompatibleDC(hdc)
hSourceOld = SelectObject(hDcSource, Picture.Handle)

hColorBuff = CreateCompatibleBitmap(hdc, PicSize.X, PicSize.Y)
hDcColor = CreateCompatibleDC(hdc)
hColorOld = SelectObject(hDcColor, hColorBuff)


hMaskBuff = CreateBitmap(PicSize.X, PicSize.Y, 1, 1, ByVal 0&)
hMaskDC = CreateCompatibleDC(hdc)
hMaskOld = SelectObject(hMaskDC, hMaskBuff)

'.... BitBlt операции

Call SelectObject(hDcSource, hSourceOld)
DeleteObject SelectObject(hDcColor, hColorOld)
DeleteObject SelectObject(hMaskDC, hMaskOld)
Call DeleteDC(hDcSource)
Call DeleteDC(hColorOld)
Call DeleteDC(hMaskDC)
DeleteObject hColorBuff
DeleteObject hMaskBuff
End Sub

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 18.11.2006 (Сб) 16:36

Ты дважды удаляешь hColorBuff и hMaskBuff.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.11.2006 (Сб) 17:01

понимаю. было так:
Код: Выделить всё

Call SelectObject(hDcSource, hSourceOld)
Call SelectObject(hDcColor, hColorOld)
Call SelectObject(hMaskDC, hMaskOld)
Call DeleteDC(hDcSource)
Call DeleteDC(hColorOld)
Call DeleteDC(hMaskDC)
DeleteObject hColorBuff
DeleteObject hMaskBuff
в агонии сделал так:
Код: Выделить всё

Call SelectObject(hDcSource, hSourceOld)
DeleteObject SelectObject(hDcColor, hColorOld)
DeleteObject SelectObject(hMaskDC, hMaskOld)
Call DeleteDC(hDcSource)
Call DeleteDC(hColorOld)
Call DeleteDC(hMaskDC)
DeleteObject hColorBuff
DeleteObject hMaskBuff
Результат одинаковый Т.е. сбивается и в том и в этом случае.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 18.11.2006 (Сб) 17:09

Что значит "сбой"?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.11.2006 (Сб) 17:24

GSerg писал(а):Что значит "сбой"?
Все меню Windows показываются, как будто кто-то питается их перекрасить.
вариант 1: меню в окнах Windows или в IE, показываются на черном фоне с чернимы элементами.
вариант 2: меню в окнах Windows или в IE, при правом клике не показываются, пока курсор не выберет элемент меню.
Все это восстанавливается только после перезагрузки Windows

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.11.2006 (Сб) 19:23

в вышеуказанном коде
a = SelectObject(hDcSource, hSourceOld)
b = SelectObject(hDcColor, hColorOld)
c = SelectObject(hMaskDC, hMaskOld)
d = DeleteDC(hDcSource)
e = DeleteDC(hColorOld)
f = DeleteDC(hMaskDC)
g = DeleteObject(hColorBuff)
k = DeleteObject(hMaskBuff)

Все возвращают 1, "e" возвращает 0.
вроде не должно бить так?!


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 46

    TopList