Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  15:02[Войти] | [Зарегистрироваться]
Ответ на вопрос № 60256

14-03-2008 10:08
Добрый день жители Королевства
Пишу run-time компонент наследник от TCustomControl. В работе использовал материалы из статей и форума Королевства.
Всё было нормально пока не понадобилось при отрисовке компонента использовать только часть канвы.
Требуется нарисовать фигуру состоящую из разных примитивов с различными градиентными заливками, поэтому часть ClientRectanglе дложна быть прозрачной(должен быть виден Parent или нижележащий Control).
В коде переопределяется метод Paint. Реализацию взял из статьи статьи "Градиентная фантазия" http://delphikingdom.ru/asp/viewitem.asp?catalogid=1090
Насколько я понял ситуацию то еще до вызова моего метода TMyObj.Paint вызываются методы родительских компонентов TCustomcontrol, TWinControl, TControl которые закрашивают ВСЮ клиентскую область и только потом рисуется мой компонент.
Вопрос можно ли добится прозрачности на канве потомка от TCustomControl.
Наследование от TGraphicControl не устраивает нужен фокус.

procedure TMyObj.Paint;
var
  X, Y, W: Integer;
  BtnRect: TRect;
  ColArr: TColorArray;
begin
btnrect:=Clientrect;
InflateRect(btnrect,-30,-30);
W:=abs(btnRect.top-btnRect.bottom);
SetLength(ColArr,W + 1);
ComplexFillArray(Self.Color,fToColor,ColArr,w);
H_Gradient(Canvas,btnRect,ColArr);
if (fMode=mDesTime) and fCanMove then
  DrawAnchors(Canvas,ClientRect);
DoDrawText(Canvas,fvalue,fFont);
Finalize(ColArr);
end;



Заранее благодарен

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

19-03-2008 09:07
ОК. Вопрос закрыт.
невнимательное копирование не освобождает от ответственности.
Действительно все решается с помощью SetWindowRgn.
Огромное спасибо за помощь.

17-03-2008 10:31
Вопервых в Вашем фрагменте не SetWindowRgn а, SelectClipRgn.
В вторых - Paint не подходящее для этого место. Лучше посадить это на изменение размеров, родителя и ваших свойств, от которых зависят очертания фигуры

17-03-2008 01:49 | Сообщение от автора вопроса
to Антон Григорьев

В обработчик Paint


procedure TCustomObj.Paint;
var
  X, Y, W: Integer;
  BtnRect: TRect;
  ColArr: TColorArray;
  myrgn:hrgn;
begin
SetBkMode(Canvas.Handle,Transparent);
btnrect:=Clientrect;
InflateRect(btnrect,-30,-30);
MyRgn := CreateRectRgnIndirect(btnrect); //____Here
SelectClipRgn(Canvas.Handle,MyRgn);
W:=abs(btnRect.top-btnRect.bottom);
SetLength(ColArr,W + 1);
ComplexFillArray(Self.Color,fToColor,ColArr,w);
H_Gradient(Canvas,btnRect,ColArr);
SelectClipRgn(Canvas.Handle,0);
DeleteObject(MyRgn);
if (fMode=mDesTime) and fCanMove then
  DrawAnchors(Canvas,ClientRect);
DoDrawText(Canvas,fvalue,fFont);
Finalize(ColArr);
end;


16-03-2008 00:30
Как вы использовали SetWindowrRgn? Куда вставляли вызов?

15-03-2008 13:42 | Сообщение от автора вопроса
SetWindowRgn было испробовано в первую очередь. Результат 0(Null).
У меня остается стойкое подозрение что отрисовкой BackGrounda занимается предок TWinContorl-a.
Появилась идея наследовать от TControl (для наследования обработки мыши и Handle, для графики прикрутить наследника от TGraphicControl в качестве переменной.
Совет с копированием обязательно попробую, мож подойдет.
Спасибо.

15-03-2008 02:20
Единственный паривльный вариант - это SetWindowRgn, как сказал bems. WS_EX_TRANSPARENT - тяжёлое наследие старых версий Windows, обращаться с ним сложно. Запоминание того, что находится снизу - работа тяжёлая, само по себе это не прокатит, потому что то, что снизу, само по себе не нарисуется, система старается не тратить время на рисование того, что потом не будет видно. Поэтому приходится прибегать к относительно затратным способам типа предложенного F.I.N., чтобы нарисовать то, что нужно. Это оправдано только тогда, когда фон нужен для дальнейшей обработки - например, для создания полупрозрачного изображения. Но у вас такой задачи, кажется, не просматривается, вам фон не нужен, а нужно только, чтобы компонент не занимал всю прямоугольную область - для таких задач SetWindowRgn идеальное решение.

14-03-2008 14:47
Я иногда пользуюсь вот такой процедуркой. Писал не я. Выдернул с какого-то компонента...помнится там тоже было выдернуто :) и по-моему их RX. Косяков в работе не обнаружено.

procedure CopyParentImage(Control: TControl; Dest: TCanvas);
var
  I, Count, X, Y, SaveIndex: Integer;
  DC: HDC;
  R, SelfR, CtlR: TRect;
begin
  if (Control = nil) or (Control.Parent = nil) then Exit;
  Count := Control.Parent.ControlCount;
  DC := Dest.Handle;
{$IFDEF WIN32}
  with Control.Parent do
  ControlState := ControlState + [csPaintCopy];
  try
{$ENDIF}
    with Control do
    begin
      SelfR := Bounds(Left, Top, Width, Height);
      X := -Left; Y := -Top;
    end;
    SaveIndex := SaveDC(DC);
    try
      SetViewportOrgEx(DC, X, Y, nil);
      IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth, Control.Parent.ClientHeight);
      with TParentControl(Control.Parent) do
      begin
        Perform(WM_ERASEBKGND, DC, 0);
        PaintWindow(DC);
      end;
    finally
      RestoreDC(DC, SaveIndex);
    end;
    for I := 0 to Count - 1 do
    begin
      if Control.Parent.Controls[I] = Control then
      Break
      else
      if (Control.Parent.Controls[I] <> nil) and (Control.Parent.Controls[I] is TGraphicControl) then
      begin
        with TGraphicControl(Control.Parent.Controls[I]) do
        begin
          CtlR := Bounds(Left, Top, Width, Height);
          if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then
          begin
{$IFDEF WIN32}
            ControlState := ControlState + [csPaintCopy];
{$ENDIF}
            SaveIndex := SaveDC(DC);
            try
              SetViewportOrgEx(DC, Left + X, Top + Y, nil);
              IntersectClipRect(DC, 0, 0, Width, Height);
              Perform(WM_PAINT, DC, 0);
            finally
              RestoreDC(DC, SaveIndex);
{$IFDEF WIN32}
              ControlState := ControlState - [csPaintCopy];
{$ENDIF}
            end;
          end;
        end;
      end;
    end;
{$IFDEF WIN32}
  finally
    with Control.Parent do
    ControlState := ControlState - [csPaintCopy];
  end;
{$ENDIF}
end;


Процедура копирует на указанный канвас (Canvas) "все что сзади" указанного контрола (Control).

14-03-2008 13:45
И третий вариант - задать контролу нестандартный регион с помощью SetWindowRgn

14-03-2008 11:17
Ну тут пару вариантов есть...
Первый.
Компонент делается прозрачным с помощью WM_EX_TRANSPARENT следующим образом

procedure TSomeComponent.CreateParams(var Params:TCreateParams);
begin
  inherited;
  Params.ExStyle:=Params.ExStyle or WS_EX_TRANSPARENT;
end;



Правда после этого есть одна проблемка. Будет рябить немного. Ну тут можно немного помухлевать с FDoubleBuffered и областями отрисовки...

Второй.
Запоминаете то, что находится под вашим компонентом, и при приходе WM_ERASEBKGND отрисовываете те области, где нету градиента. С FDoubleBuffered тоже придется помухлевать

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Зимой — белый, летом — серый. Кто?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования