Сабклассинг
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Сабклассинг
Привет, коллеги.
Возникла необходимость сделать что-то типа ImageBrowse. У solid-ов на сайте скриншот болтается, а в примерах его нет.
Скачал пример - PaintArea, работает, битмапы добавляются. Но, вставляю энто безобразие в проект и прога начинает падать. В чем дело я понял - теряется адрес обработчика. А где, фиг его знает. В статьях нашел пример для сабклассинга, FlatDemo - те же яйца. Кто на эти грабли наступал, отзовитесь.
Возникла необходимость сделать что-то типа ImageBrowse. У solid-ов на сайте скриншот болтается, а в примерах его нет.
Скачал пример - PaintArea, работает, битмапы добавляются. Но, вставляю энто безобразие в проект и прога начинает падать. В чем дело я понял - теряется адрес обработчика. А где, фиг его знает. В статьях нашел пример для сабклассинга, FlatDemo - те же яйца. Кто на эти грабли наступал, отзовитесь.
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Увы, эт не то. Мне надо ListBox с картинками, а то, что может FreeImage в ImageEx по-моему круче. Его я и использую.
А что касаемо сабклассинга трабл в том, что отдаю в свой обработчик хэндл, например клиентской области окна, вывожу его в файл (для контроля), а когда начинает работать обработчик, то цифра уже не та. При попытке выдать ее в файл прога валится по вполне понятной причине.
А что касаемо сабклассинга трабл в том, что отдаю в свой обработчик хэндл, например клиентской области окна, вывожу его в файл (для контроля), а когда начинает работать обработчик, то цифра уже не та. При попытке выдать ее в файл прога валится по вполне понятной причине.
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Похоже знатоки API закончились ))))))))))))). А вопрос-то интересный. В отдельном prj с одним окном все сказочно, а когда всунешь все энто в аппликуху, то что-то не идет. Короче есть окно, в нем IMAGE с атр HVSCROLL. В него надо занести несколько BMP-шников, чтобы выбрать нужный. И вот, что получается. Если при сабклассинге в обработчик отдаем хэндл клиентской части окна, то скроллинг работает, но ничего не рисуется, если отдаем хэндл области, куда надо рисовать, то все наоборот - рисунок есть, а скроллинга нет. Ну и еще. Если это окно накрыть другим, то после закрытия того окна область прорисовки пропадает. Кого и когда нужно позвать, чтобы все это устаканить ?
- Дед Пахом
- Старичок
- Сообщения: 3289
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
- Контактная информация:
Re: Сабклассинг
Ну ведь нихрена же не понятно.
Сразу скажу, что обработчик сабклассинга должен быть глобальным.
Сразу скажу, что обработчик сабклассинга должен быть глобальным.
В него это в окно или в IMAGE?Короче есть окно, в нем IMAGE с атр HVSCROLL. В него надо занести несколько BMP-шников, чтобы выбрать нужный.
Чем объяснять, привёл бы код обработчика и предшествующий ему код подмены процедуры обработки.Если при сабклассинге в обработчик отдаем хэндл клиентской части окна, то скроллинг работает, но ничего не рисуется, если отдаем хэндл области, куда надо рисовать, то все наоборот - рисунок есть, а скроллинга нет.
С уважением, ДП
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Спасибо за ответ. В качестве базы взят пример из файлового архива PaintArea.
Окно:
PaintArea:Win WINDOW('Paint Area'),AT(,,221,224),FONT('MS Sans Serif',8,,),CENTER,SYSTEM,GRAY,DOUBLE
IMAGE('Blank_500x500.GIF'),AT(5,4,209,194),USE(?PaintArea:Image),HVSCROLL
END
Код:
OPEN(PaintArea:Win)
DISPLAY
PaintArea_hWnd = ?PaintArea:Image{PROP:Handle}
PaintArea_hDC = GetDC(PaintArea_hWnd)
IF PaintArea_hDC
! Создаем битовую карту изображения
PaintArea_hMemDC = CreateCompatibleDC(PaintArea_hDC)
IF PaintArea_hMemDC
PaintArea_hBitMap = CreateCompatibleBitmap(PaintArea_hDC, PaintArea_Width, PaintArea_Height)
IF PaintArea_hBitMap
PaintArea_hOldBitMap = SelectObject(PaintArea_hMemDC, PaintArea_hBitMap)
! Сабклассинг области просмотра
PaintArea_WndProc_Addr = SetWindowLong(PaintArea_hWnd, GWL_WNDPROC, ADDRESS(PaintArea_WndProc))
! Цикл работы с окном
ACCEPT
END
! Восстанавливаем предыдущую битовую карту
SelectObject(PaintArea_hMemDC, PaintArea_hOldBitMap)
END
! Удаляем контекст
DeleteDC(PaintArea_hMemDC)
END
ReleaseDC(PaintArea_hWnd, PaintArea_hDC)
END
CLOSE(PaintArea:Win)
Обработчик:
CBProc.PaintArea_WndProc PROCEDURE(HWND hWnd, UNSIGNED wMsg, WPARAM wParam, LPARAM lParam)
hDC HDC
hWndDC HDC
!PStruct LIKE(PAINTSTRUCT)
DrawRect LIKE(RECT) ! Координаты области для просмотра
PaintArea_HScrollPos SIGNED ! Текущая позиция (0-255) горизонтального скролбара
PaintArea_VScrollPos SIGNED ! Текущая позиция (0-255) вертикального скролбара
PosX LONG ! Координаты левого верхнего угла
PosY LONG ! отображаемой части картинки
RetValue LRESULT
CODE
CASE wMsg
OF WM_PAINT
PaintArea_HScrollPos = GetScrollPos(hWnd, SB_HORZ)
PaintArea_VScrollPos = GetScrollPos(hWnd, SB_VERT)
IF GetWindowRect(hWnd, DrawRect)
hWndDC = GetDC(hWnd)
IF hWndDC
! Координаты верхнего левого угла
IF PaintArea_Width > DrawRect.right - DrawRect.left
PosX = ((PaintArea_Width - (DrawRect.right - DrawRect.left)) / 256) * PaintArea_HScrollPos
ELSE
PosX = 0
END
IF PaintArea_Height > DrawRect.Bottom - DrawRect.top
PosY = ((PaintArea_Height - (DrawRect.Bottom - DrawRect.top)) / 256) * PaintArea_VScrollPos
ELSE
PosY = 0
END
!RetValue = CallWindowProc(PaintArea_WndProc_Addr, hWnd, wMsg, wParam, lParam)
BitBlt(hWndDC, 0, 0, DrawRect.right - DrawRect.left, DrawRect.Bottom - DrawRect.top, PaintArea_hMemDC, PosX, PosY, SRCCOPY)
ReleaseDC(hWnd, hWndDC)
END
END
RETURN FALSE
END
RETURN CallWindowProc(PaintArea_WndProc_Addr, hWnd, wMsg, wParam, lParam)
Все переменные и класс объявлены в области данных МОДУЛЯ.
Окно:
PaintArea:Win WINDOW('Paint Area'),AT(,,221,224),FONT('MS Sans Serif',8,,),CENTER,SYSTEM,GRAY,DOUBLE
IMAGE('Blank_500x500.GIF'),AT(5,4,209,194),USE(?PaintArea:Image),HVSCROLL
END
Код:
OPEN(PaintArea:Win)
DISPLAY
PaintArea_hWnd = ?PaintArea:Image{PROP:Handle}
PaintArea_hDC = GetDC(PaintArea_hWnd)
IF PaintArea_hDC
! Создаем битовую карту изображения
PaintArea_hMemDC = CreateCompatibleDC(PaintArea_hDC)
IF PaintArea_hMemDC
PaintArea_hBitMap = CreateCompatibleBitmap(PaintArea_hDC, PaintArea_Width, PaintArea_Height)
IF PaintArea_hBitMap
PaintArea_hOldBitMap = SelectObject(PaintArea_hMemDC, PaintArea_hBitMap)
! Сабклассинг области просмотра
PaintArea_WndProc_Addr = SetWindowLong(PaintArea_hWnd, GWL_WNDPROC, ADDRESS(PaintArea_WndProc))
! Цикл работы с окном
ACCEPT
END
! Восстанавливаем предыдущую битовую карту
SelectObject(PaintArea_hMemDC, PaintArea_hOldBitMap)
END
! Удаляем контекст
DeleteDC(PaintArea_hMemDC)
END
ReleaseDC(PaintArea_hWnd, PaintArea_hDC)
END
CLOSE(PaintArea:Win)
Обработчик:
CBProc.PaintArea_WndProc PROCEDURE(HWND hWnd, UNSIGNED wMsg, WPARAM wParam, LPARAM lParam)
hDC HDC
hWndDC HDC
!PStruct LIKE(PAINTSTRUCT)
DrawRect LIKE(RECT) ! Координаты области для просмотра
PaintArea_HScrollPos SIGNED ! Текущая позиция (0-255) горизонтального скролбара
PaintArea_VScrollPos SIGNED ! Текущая позиция (0-255) вертикального скролбара
PosX LONG ! Координаты левого верхнего угла
PosY LONG ! отображаемой части картинки
RetValue LRESULT
CODE
CASE wMsg
OF WM_PAINT
PaintArea_HScrollPos = GetScrollPos(hWnd, SB_HORZ)
PaintArea_VScrollPos = GetScrollPos(hWnd, SB_VERT)
IF GetWindowRect(hWnd, DrawRect)
hWndDC = GetDC(hWnd)
IF hWndDC
! Координаты верхнего левого угла
IF PaintArea_Width > DrawRect.right - DrawRect.left
PosX = ((PaintArea_Width - (DrawRect.right - DrawRect.left)) / 256) * PaintArea_HScrollPos
ELSE
PosX = 0
END
IF PaintArea_Height > DrawRect.Bottom - DrawRect.top
PosY = ((PaintArea_Height - (DrawRect.Bottom - DrawRect.top)) / 256) * PaintArea_VScrollPos
ELSE
PosY = 0
END
!RetValue = CallWindowProc(PaintArea_WndProc_Addr, hWnd, wMsg, wParam, lParam)
BitBlt(hWndDC, 0, 0, DrawRect.right - DrawRect.left, DrawRect.Bottom - DrawRect.top, PaintArea_hMemDC, PosX, PosY, SRCCOPY)
ReleaseDC(hWnd, hWndDC)
END
END
RETURN FALSE
END
RETURN CallWindowProc(PaintArea_WndProc_Addr, hWnd, wMsg, wParam, lParam)
Все переменные и класс объявлены в области данных МОДУЛЯ.
- Дед Пахом
- Старичок
- Сообщения: 3289
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
- Контактная информация:
Re: Сабклассинг
И что, если всё то же самое, но не в app, а в prj, то работает? Так не бывает.
С уважением, ДП
- StillZero
- Ветеран
- Сообщения: 458
- Зарегистрирован: 06 Июль 2005, 2:17
- Откуда: Хабаровск
- Поблагодарили: 1 раз
- Контактная информация:
Re: Сабклассинг
на коленке слобал, pure clarion code 

- Вложения
-
- example.zip
- (70.58 КБ) 296 скачиваний
по аэродрому...
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Бывает, особенно когда во что-то не втыкаешься. (это я про себя).Дед Пахом писал(а):И что, если всё то же самое, но не в app, а в prj, то работает? Так не бывает.
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Озадачил, однако, но с API разобраться все равно надо.StillZero писал(а):на коленке слобал, pure clarion code
- StillZero
- Ветеран
- Сообщения: 458
- Зарегистрирован: 06 Июль 2005, 2:17
- Откуда: Хабаровск
- Поблагодарили: 1 раз
- Контактная информация:
Re: Сабклассинг
я честно смысла задачи не понимаю... че делать?...хз 
Приведенный код похоже просто скроллирует картинку.
Из практики, обработки одного только WM_PAINT маловато будет, потому и при закрытии окна другим приложением нихрена не происходит, что то вроде WM_ERASEBACKGROUND и InvalidateRect надо смотреть или повторить код копирования из базовой картинки на экран.

Приведенный код похоже просто скроллирует картинку.
Из практики, обработки одного только WM_PAINT маловато будет, потому и при закрытии окна другим приложением нихрена не происходит, что то вроде WM_ERASEBACKGROUND и InvalidateRect надо смотреть или повторить код копирования из базовой картинки на экран.
по аэродрому...
-
- Старожил
- Сообщения: 280
- Зарегистрирован: 11 Февраль 2009, 8:41
- Откуда: г. Анапа
- Поблагодарили: 3 раза
Re: Сабклассинг
Да, тут копать глубже надо.StillZero писал(а):я честно смысла задачи не понимаю... че делать?...хз
Приведенный код похоже просто скроллирует картинку.
Из практики, обработки одного только WM_PAINT маловато будет, потому и при закрытии окна другим приложением нихрена не происходит, что то вроде WM_ERASEBACKGROUND и InvalidateRect надо смотреть или повторить код копирования из базовой картинки на экран.
За пример большое спасибо, этого хватит выше крыши. Прилепил к нему SysTree - сказка. Жаль только, что Клаша не дружит с PNG, приходится извращаться.