Конференция "Компоненты" » Требуется компонент - подобие TEdit [D7, WinXP]
 
  • R1ka (29.04.08 20:23) [0]
    Требуется компонент - подобие TEdit, но с градиентным фоном, вопросы такие:
    какой класс наследовать ? (Tedit, TCustomEdit, TWinControl)
    какие методы перекрывать ?
    в каком методе производить отрисовку градиента и на какой поверхности?
    как быть со стандартным св-вом Color?
    то что понадобятся три новых свойства уже понял и реализовал, вообще буду благодарен любой информации в рамках этой темы.
  • DVM © (29.04.08 22:59) [1]

    > какой класс наследовать ?

    TWinControl круто будет слишком, проще Tedit.


    > какие методы перекрывать ?


    > в каком методе производить отрисовку градиента и на какой
    > поверхности?

    Написать свой обработчик для WM_ERASEBKGND. Возможно, что и для WM_PAINT тоже понадобится.


    > как быть со стандартным св-вом Color?

    Никак. Использовать цвет или не использовать.
  • {RASkov} © (29.04.08 23:17) [2]
    > > как быть со стандартным св-вом Color?
    >
    > Никак. Использовать цвет или не использовать.

    Можно его использовать для одного из градиентного цвета...
    Съэкономим 4 байта...

     TGradEdit = class(TCustomEdit)
     private
       FSecondColor: TColor;
       procedure SetSecondColor(const Value: TColor);
       function GetFirstColor: TColor;
       procedure SetFirstColor(const Value: TColor);
     published
       property FirstColor: TColor read GetFirstColor write SetFirstColor;
       property SecondColor: TColor read FSecondColor write SetSecondColor;
     end;
    .....
    function TGradEdit.GetFirstColor: TColor;
    begin
     Result:=Color;
    end;

    procedure TGradEdit.SetFirstColor(const Value: TColor);
    begin
     if Color<>Value then Color := Value;
    ....
    end;

    procedure TGradEdit.SetSecondColor(const Value: TColor);
    begin
     if FSecondColor <> Value then FSecondColor := Value;
    ....
    end;

  • Игорь Шевченко © (30.04.08 11:19) [3]
    замучаешься Edit переписывать, ищи готовое решение. Я вполне серьезно
  • R1ka © (30.04.08 12:52) [4]
    мне для моей проги не только един нужен, писать все-равно придется
  • R1ka © (30.04.08 20:57) [5]
    Все сделал как сказали:
    Создал буфер для градиента, при создании заполняю его.
    Перекрыл WM_ERASEBKGND и WM_PAINT, в них заменил заполнение цветом на заполнение моим рисунком, все собирается и ставится. Но фона почему-то нету О_О


    // Заполнение буфера-битмапа градиентом
    procedure TMRAEdit.FillBuffer;
    var
     i: integer;
     Deltas: Array [0 .. 2] of real;
    begin
     Deltas[0] := (GetRValue(FBgColorEnd) - GetRValue(FBgColorStart)) / FBGBuffer.Height;
     Deltas[1] := (GetGValue(FBgColorEnd) - GetGValue(FBgColorStart)) / FBGBuffer.Height;
     Deltas[2] := (GetBValue(FBgColorEnd) - GetBValue(FBgColorStart)) / FBGBuffer.Height;

     for i := 0 to FBGBuffer.Height - 1 do
     begin
       FBGBuffer.Canvas.MoveTo(0, i);
       FBGBuffer.Canvas.Pen.Color := RGB(
         Round(GetRValue(FBgColorStart) + I * Deltas[0]),
         Round(GetGValue(FBgColorStart) + I * Deltas[1]),
         Round(GetBValue(FBgColorStart) + I * Deltas[2]));
       FBGBuffer.Canvas.LineTo(FBGBuffer.Width, i);
     end;
    end;

    procedure TMRAEdit.WMEraseBkgnd(var Message: TWmEraseBkgnd);
    begin
     with ThemeServices do
     if ThemesEnabled and Assigned(Parent) and (csParentBackground in FControlStyle) then
       begin
         { Get the parent to draw its background into the control's background. }
         DrawParentBackground(Handle, Message.DC, nil, False);
       end
       else
       begin
         { Only erase background if we're not doublebuffering or painting to memory. }

         if not FDoubleBuffered or
            (TMessage(Message).wParam = TMessage(Message).lParam) then
           //Тут было заполнение пустым цветом
           BitBlt(Message.DC, 0, 0, ClientRect.Right, ClientRect.Bottom, FBGBuffer.Canvas.Handle, 0, 0, SRCCOPY);
       end;

     Message.Result := 1;
    end;

    procedure TMRAEdit.WMPaint(var Message: TWMPaint);
    var
     DC, MemDC: HDC;
     MemBitmap, OldBitmap: HBITMAP;
     PS: TPaintStruct;
    begin
     if not FDoubleBuffered or (Message.DC <> 0) then
     begin
       if not (csCustomPaint in ControlState) and (ControlCount = 0) then
         inherited
       else
         PaintHandler(Message);
     end
     else
     begin
       DC := GetDC(0);
       MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
       ReleaseDC(0, DC);
       MemDC := CreateCompatibleDC(0);
       OldBitmap := SelectObject(MemDC, MemBitmap);
       try
         DC := BeginPaint(Handle, PS);
         Perform(WM_ERASEBKGND, MemDC, MemDC);
         Message.DC := MemDC;
         WMPaint(Message);
         Message.DC := 0;
         // Тут подменил источник копирования на свой буфер
         BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, FBGBuffer.Canvas.Handle, 0, 0, SRCCOPY);
         EndPaint(Handle, PS);
       finally
         SelectObject(MemDC, OldBitmap);
         DeleteDC(MemDC);
         DeleteObject(MemBitmap);
       end;
     end;
    end;

  • DVM © (30.04.08 22:05) [6]
    Зачем такие выкрутасы в TMRAEdit.WMPaint явно скопированные из TWinControl ?
  • Игорь Шевченко © (30.04.08 22:23) [7]

    > Но фона почему-то нету О_О


    И не будет. WM_Paint надо переписывать не вызывая стандартный.
  • DVM © (30.04.08 22:36) [8]

    > R1ka ©

    Глюкавенько, но работает (в image1 jpeg загружен):


    unit Unit1;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, jpeg, ExtCtrls, ComCtrls, StdCtrls;

    type

     TEdit = class(StdCtrls.TEdit)
     private
       FBitmap: TBitmap;
     protected
       procedure WndProc(var Message: TMessage); override;
       procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
     public
       property Bitmap: TBitmap read FBitmap write FBitmap;
     end;

     TForm1 = class(TForm)
       Image1: TImage;
       Edit1: TEdit;
       procedure FormCreate(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    uses CommCtrl;

    procedure TEdit.WndProc(var Message: TMessage);
    begin
     if Message.Msg = WM_ERASEBKGND then
     begin
       Message.Result := 1
     end else
     begin
       case Message.Msg of
         WM_KEYDOWN:
           InvalidateRect(Handle, nil, False);
       end;
       inherited
     end
    end;

    procedure TEdit.WMPaint(var Message: TWMPaint);
    var
     DC, TempDC, TempDC1: HDC;
     TempBmp, OldBmp, OldBmp1, TempBMP1: HBITMAP;
     PS: TPaintStruct;
     TempRect: TRect;
    begin
     if Message.DC <> 0 then
       inherited
     else begin
       TempRect := ClientRect;
       BeginPaint (Handle, PS);
       try
         DC := GetDC(Handle);
         TempDC := CreateCompatibleDC(DC);
         TempDC1 := CreateCompatibleDC(DC);
         TempBMP := CreateCompatibleBitmap(DC, TempRect.Right, TempRect.Bottom);
         TempBMP1 := CreateCompatibleBitmap(DC, TempRect.Right, TempRect.Bottom);
         try
           OldBmp := SelectObject(TempDC, TempBMP);
           OldBmp1 := SelectObject(TempDC1, TempBMP1);
           try
             Message.DC := TempDC;
             inherited;
             Message.DC := 0;
             FillRect(TempDC1, TempRect, GetStockObject(WHITE_BRUSH));
             if FBitmap <> nil then
               BitBlt(TempDC1, 0, 0, FBitmap.Width, FBitmap.Height, FBitmap.Canvas.Handle, 0, 0, SRCCOPY);
             TransparentBlt (TempDC1, 0, 0, TempRect.Right, TempRect.Bottom, TempDC, 0, 0, TempRect.Right, TempRect.Bottom, clWhite);
             BitBlt(DC, 0, 0, TempRect.Right, TempRect.Bottom, TempDC1, 0, 0, SRCCOPY);
           finally
             SelectObject (TempDC, OldBmp);
             SelectObject (TempDC1, OldBmp1)
           end;
         finally
           DeleteObject (TempBMP);
           DeleteObject (TempBMP1);
           ReleaseDC (Handle, TempDC);
           ReleaseDC (Handle, TempDC1);
           ReleaseDC (Handle, DC);
         end;
       finally
         EndPaint (Handle, PS)
       end;
     end
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
     Edit1.Color := clWhite;
     Edit1.Bitmap := TBitmap.Create;
     Edit1.Bitmap.Assign(image1.Picture.Graphic);
    end;

    end.


  • Игорь Шевченко © (30.04.08 22:49) [9]
    Microsoft рекомендует делать примерно так:

    unit main;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

    type
     TForm1 = class(TForm)
       EditPlace: TEdit;
     private
       procedure WmCtlColorEdit (var Message: TWMCtlColorEdit); message WM_CTLCOLOREDIT;
     end;

    var
     Form1: TForm1;

    implementation
    uses
     GraphUtil;

    {$R *.dfm}

    procedure TForm1.WmCtlColorEdit(var Message: TWMCtlColorEdit);
    var
     ACanvas: TCanvas;
    begin
     if Message.ChildWnd = EditPlace.Handle then
     begin
       ACanvas := TCanvas.Create;
       try
         ACanvas.Handle := Message.ChildDC;
         GradientFillCanvas (ACanvas, clRed, clGreen, EditPlace.ClientRect,
           gdHorizontal);
       finally
         ACanvas.Handle := 0;
         ACanvas.Free;
       end;
       SetBkMode(Message.ChildDC, TRANSPARENT);
       Message.Result := GetStockObject(NULL_BRUSH);
     end;
    end;

    end.

  • DVM © (30.04.08 22:58) [10]

    > Игорь Шевченко ©   (30.04.08 22:49) [9]

    тоже подглюкивает при вводе текста, буквы пропадают и шрифт странный стал.
  • Игорь Шевченко © (30.04.08 23:14) [11]
    DVM ©   (30.04.08 22:58) [10]

    Шрифт изменился, а пропажи букв не заметил. Пропал горизонтальный скорллинг. Но я к чему - к тому, что для полной функциональности надо самому заниматься отрисовкой.
  • R1ka © (30.04.08 23:32) [12]
    Спасибо, принцип понятен, только какой смысл в этом условии?

    if Message.DC <> 0 then
       inherited

  • DVM © (30.04.08 23:59) [13]

    > R1ka ©   (30.04.08 23:32) [12]
    > Спасибо, принцип понятен, только какой смысл в этом условии?
    >
    >
    > if Message.DC <> 0 then
    >    inherited


    чтобы управлять отрисовкой более гибко одним и тем же кодом, сначала подсовываем стандартной процедуре отрисовки свой DC, она рисует там текст, потом мы его забираем и рисуем его поверх своего рисунка.


    > try
    >          Message.DC := TempDC;
    >          inherited;
    >          Message.DC := 0;
  • R1ka © (01.05.08 04:38) [14]
    Так, а где отрисовывать если у меня отключены стили XP?
  • Игорь Шевченко © (01.05.08 10:32) [15]
    DVM ©   (30.04.08 22:58) [10]

    Кстати, проблема с шрифтом и скроллингом решилась добавлением одной строчки:

       SetBkMode(Message.ChildDC, TRANSPARENT);
       SelectObject(Message.ChildDC, EditPlace.Font.Handle);
       Message.Result := GetStockObject(NULL_BRUSH);
  • Игорь Шевченко © (01.05.08 11:13) [16]
    Ну и соответственно, в виде компонента это выходит примерно так:

    unit HsGradientEdit;

    interface
    uses
     Messages, Graphics, Controls, StdCtrls;

    type
     THsGradientEdit = class(TEdit)
     private
       FEndColor: TColor;
       FStartColor: TColor;
       procedure CnCtlColorEdit (var Message: TWMCtlColorEdit); message CN_CTLCOLOREDIT;
       procedure SetEndColor(const Value: TColor);
       procedure SetStartColor(const Value: TColor);
     published
       property StartColor: TColor read FStartColor write SetStartColor;
       property EndColor: TColor read FEndColor write SetEndColor;
     end;

    implementation
    uses
     Windows, HsGradient;

    { THsGradientEdit }

    procedure THsGradientEdit.CnCtlColorEdit(var Message: TWMCtlColorEdit);
    var
     ACanvas: TCanvas;
     GradientFill: THSGradientFill;
    begin
     GradientFill := THSGradientFill.Create;
     try
       GradientFill.StartColor := FStartColor;
       GradientFill.EndColor := FEndColor;
       GradientFill.Style := gsHorizontal;
       ACanvas := TCanvas.Create;
       try
         ACanvas.Handle := Message.ChildDC;
         GradientFill.FillRect(ACanvas, ClientRect);
       finally
         ACanvas.Handle := 0;
         ACanvas.Free;
       end;
     finally
       GradientFill.Free;
     end;
     SetBkMode(Message.ChildDC, TRANSPARENT);
     SelectObject(Message.ChildDC, Font.Handle);
     Message.Result := GetStockObject(NULL_BRUSH);
    end;

    procedure THsGradientEdit.SetEndColor(const Value: TColor);
    begin
     if FEndColor <> Value then
     begin
       FEndColor := Value;
       Invalidate;
     end;
    end;

    procedure THsGradientEdit.SetStartColor(const Value: TColor);
    begin
     if FStartColor <> Value then
     begin
       FStartColor := Value;
       Invalidate;
     end;
    end;

    end.



    Вместо HsGradientEdit и соответствующего класса можно вполне применить метод GradientFillCanvas из GraphUtil.pas, не мой вариант больше подходит, так как более переносим между версиями Delphi
  • R1ka © (01.05.08 13:40) [17]
    HsGradient - это что за юнит такой? Гугл молчит
  • {RASkov} © (01.05.08 13:56) [18]
    > [16] Игорь Шевченко ©   (01.05.08 11:13)

    Красиво, но при вводе текст перед курсором пропадает, от него остается только одна буква.
    TextInEdit - текст находится в эдите
      t|InEdit - при редактировании
    | - курсор.
    [D7, WinXP]
  • {RASkov} © (01.05.08 13:58) [19]
    > [17] R1ka ©   (01.05.08 13:40)

    В кладовке поищи... архив ownerdrawmenu.zip в нем есть два требующихся Игоревых модуля:)
  • {RASkov} © (01.05.08 13:59) [20]
  • Игорь Шевченко © (01.05.08 14:16) [21]

    > HsGradient - это что за юнит такой? Гугл молчит


    "Вместо HsGradientEdit и соответствующего класса можно вполне применить метод GradientFillCanvas из GraphUtil.pas, не мой вариант больше подходит, так как более переносим между версиями Delphi"

      ACanvas := TCanvas.Create;
      try
        ACanvas.Handle := Message.ChildDC;
        GradientFillCanvas (ACanvas, FStartColor, FEndColor, ClientRect,
          gdHorizontal);
      finally
        ACanvas.Handle := 0;
        ACanvas.Free;
      end;
  • R1ka © (01.05.08 14:18) [22]
    {RASkov},
    ага, нашел уже, спасибо!

    Игорь Шевченко,
    В моем GraphUtils нет такого метода
  • Игорь Шевченко © (01.05.08 14:18) [23]
    {RASkov} ©   (01.05.08 13:56) [18]


    > Красиво, но при вводе текст перед курсором пропадает, от
    > него остается только одна буква.
    > TextInEdit - текст находится в эдите
    >   t|InEdit - при редактировании
    > | - курсор.
    > [D7, WinXP]


    Не смог воспроизвести. D2006, WinXP, без тем

    Если не трудно, дай последовательность шагов для воспроизведения, а то я собираюсь кусок с градиентной заливкой в свой Edit вставлять и хотелось бы сразу наступить на возможные грабли.
  • Игорь Шевченко © (01.05.08 14:20) [24]

    > В моем GraphUtils нет такого метода


    Лови:

    unit HSGradient;

    interface
    uses
     Windows, Graphics;

    type
     THSGradientStyle = (gsNone, gsHorizontal, gsVertical);

     THSGradientFill = class
     private
       FStartColor: TColor;
       FEndColor: TColor;
       FStyle: THSGradientStyle;
     public
       procedure FillRect (ACanvas: TCanvas; ARect: TRect);
       property StartColor: TColor read FStartColor write FStartColor;
       property EndColor: TColor read FEndColor write FEndColor;
       property Style: THSGradientStyle read FStyle write FStyle;
     end;

    implementation
    uses
     HSMsImg;

    { THSGradientFill }

    procedure THSGradientFill.FillRect(ACanvas: TCanvas; ARect: TRect);
    const
     StdGradientRect: GRADIENT_RECT = (UpperLeft: 0; LowerRight: 1);
     GradientDirections: array[Boolean] of Integer = (GRADIENT_FILL_RECT_H,
       GRADIENT_FILL_RECT_V);
    var
     Vert: array[0..1] of THSTriVertex;
    begin
     Vert[0].Red := Word(GetRValue(FStartColor)) shl 8;
     Vert[0].Green := Word(GetGValue(FStartColor)) shl 8;
     Vert[0].Blue := Word(GetBValue(FStartColor)) shl 8;
     Vert[1].Red := Word(GetRValue(FEndColor)) shl 8;
     Vert[1].Green := Word(GetGValue(FEndColor)) shl 8;
     Vert[1].Blue := Word(GetBValue(FEndColor)) shl 8;
     Vert[0].x := ARect.Left;
     Vert[0].y := ARect.Top;
     Vert[1].y := ARect.Bottom;
     Vert[1].x := ARect.Right;
     HSGradientFill(ACanvas.Handle, PHSTriVertex(@Vert), 2, @StdGradientRect, 1,
       GradientDirections[FStyle = gsVertical]);
    end;

    end.



    {
      Модуль: HsMsImg

      Описание: Интерфейс к функциям MSIMG32

      Автор: Игорь Шевченко

      Дата создания: 18.10.2002

      История изменений:
    }

    unit HSMsImg;

    interface
    uses
     Windows;

    type
     THSTriVertex = packed record
       x: LongInt;
       y: LongInt;
       Red: Word;
       Green: Word;
       Blue: Word;
       Alpha: Word;
     end;
     PHSTriVertex = ^THSTriVertex;

    function HSGradientFill(DC: HDC; Vertex: PHSTriVertex; NumVertex: ULONG;
     Mesh: Pointer; NumMesh, Mode: ULONG): BOOL; stdcall;
    const
     { gradient drawing modes }
     GRADIENT_FILL_RECT_H = $00000000;
     GRADIENT_FILL_RECT_V = $00000001;
     GRADIENT_FILL_TRIANGLE = $00000002;
     GRADIENT_FILL_OP_FLAG = $000000ff;

    implementation

    type
     THSGradientFill = function (DC: HDC; Vertex: PHSTriVertex; NumVertex: ULONG;
       Mesh: Pointer; NumMesh, Mode: ULONG): BOOL; stdcall;
    var
     _HSGradientFill: THSGradientFill;
     DllHandle: THandle;

    const
     Dllname = 'msimg32.dll';

    function InitLib: Boolean;
    begin
     if DllHandle = 0 then begin
       DllHandle := LoadLibrary(Dllname);
       if DllHandle <> 0 then begin
         @_HSGradientFill := GetProcAddress(DllHandle, 'GradientFill');
       end;
     end;
     Result := DllHandle <> 0;
    end;

    function HSGradientFill(DC: HDC; Vertex: PHSTriVertex; NumVertex: ULONG;
     Mesh: Pointer; NumMesh, Mode: ULONG): BOOL; stdcall;
    begin
     if InitLib and Assigned(_HSGradientFill) then
       Result := _HSGradientFill(DC, Vertex, NumVertex, Mesh, NumMesh, Mode)
     else begin
       Result := false;
       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     end;
    end;

    initialization
    finalization
     if DllHandle <> 0 then
       FreeLibrary(DllHandle);
    end.

  • R1ka © (01.05.08 14:21) [25]
    Некоторые глюки вылазиют зависимо от того, включен-ли манифест в проект, а не от того, включены ли темы XP
  • R1ka © (01.05.08 14:26) [26]
    Игорь Шевченко,
    глюки такие:
    сразу как запускается форма и фокус попадает в окно эдита - курсор ставится в конец, но текста не видно. если кликнуть или выделить текст, то последний начинает отображаться

    если набирать текст, и он не влезает в окошко, то при сдвиге вправо, часть текста слева пропадает до следующей перерисовки едита
  • Игорь Шевченко © (01.05.08 14:29) [27]
    R1ka ©   (01.05.08 14:26) [26]

    у тебя edit или memo ?

    C memo такие явления наблюдаются, с edit не могу воспроизвести. Манифестов и тем у меня нету.
  • R1ka © (01.05.08 14:30) [28]
    Я ваш код взял => TEdit
  • {RASkov} © (01.05.08 14:37) [29]
    > [23] Игорь Шевченко ©   (01.05.08 14:18)
    > Если не трудно, дай последовательность шагов для воспроизведения

    Да соб-сно какие шаги.... вот:
    подключили uses HsGradientEdit;
    Создали:
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     with THsGradientEdit.Create(self) do begin
       Parent:=Self;
       Left:=50;
       Top:=100;
       StartColor:=clRed;
       EndColor:=clSkyBlue;
     end;
    end;

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

    Это самое и с манифестом и без него.... Тема стандартная XP
  • {RASkov} © (01.05.08 14:46) [30]
    > [23] Игорь Шевченко ©   (01.05.08 14:18)

    У нас одно только различие D7 vs D2006
  • Игорь Шевченко © (01.05.08 15:04) [31]
    Поставил стандартную тему XP - все вводится, ничего не пропадает, скроллинг нормальный.

    XPManifest в uses нету.
  • R1ka © (01.05.08 15:06) [32]
    А можно скомпиленый exe? Может не только в делфи дело?
  • {RASkov} © (01.05.08 15:08) [33]
    > [31] Игорь Шевченко ©   (01.05.08 15:04)
    > все вводится, ничего не пропадает, скроллинг нормальный.

    Значит везет не всем :)
  • Игорь Шевченко © (01.05.08 16:33) [34]

    > А можно скомпиленый exe?


    можно. на адрес в посте отправлен архив с ......@hotmail.com с темой
    "Edit with gradient fill"
  • R1ka © (01.05.08 16:52) [35]
    Получил, вот, скриншоты сделал с этими глюками:
    http://img329.imageshack.us/img329/4867/errwa4.png
  • Игорь Шевченко © (01.05.08 17:28) [36]
    Странно.
    У меня это выглядит вот так:

    http://cid-2fbfd926d50f54d0.spaces.live.com/photos/cns!2FBFD926D50F54D0!124/
  • guav © (01.05.08 19:17) [37]
    В Transparent Components вроде вполне успешно решена прорисовка произвольного бэкграунда (там рисуется не просто фон, а то что д.б. сзади)
    http://www.torry.net/quicksearchd.php?String=Transparent+Components&Title=Yes
  • Игорь Шевченко © (01.05.08 19:55) [38]
    guav ©   (01.05.08 19:17) [37]

    Интересно. Правда изображение мелькает со страшной силой, что неудивительно, у них по каждому поводу invalidate стоит.
    И некорректно отрабатывает Ctl3d := false;
  • {RASkov} © (01.05.08 20:48) [39]
    > Получил, вот, скриншоты сделал с этими глюками:
    > http://img329.imageshack.us/img329/4867/errwa4.png

    Вот именно так и у меня получилось.... :(
    Причем если двигать окно с эдитом за край экрана и возвращать, то можно по полбукве отрисовывать)...
    Т.е. текст не весь сразу рендерится, а только инвалидная облась...
  • DVM © (01.05.08 21:49) [40]
    у меня тоже такой же глюк с кодом Игоря. D7
  • Игорь Шевченко © (01.05.08 22:03) [41]
    {RASkov} ©   (01.05.08 20:48) [39]

    Ничего не могу предположить. У меня Windows XP русский, SP2 без обновлений. .Net Framework еще установлен, 3.5
    Стандартную тему XP специально включил, глюка нет, ни с темой ни без темы.
  • Игорь Шевченко © (01.05.08 22:05) [42]
    DVM ©   (01.05.08 21:49) [40]

    Если пошлю тот же архив, что и в посте [34], можно попросить EXEшник запустить ?
  • R1ka © (01.05.08 22:09) [43]
    у меня все обновления, которые мс через windows update толкает стоят. если скажете какая библиотека отвечает за прорисовку этого дела - могу посмотреть какие обновления ее затрагивали
  • guav © (01.05.08 22:09) [44]
    > [38] Игорь Шевченко ©   (01.05.08 19:55)


    > Правда изображение мелькает со страшной силой

    Да. Но в целом идея сделать субкласс EDIT со своми бэкграундом или даже прозрачный вполне реализуема.
    В стандартном редакторе Paint при вводе текста можно указать прозрачный фон, и при вводе он уже будет прозрачным. Инплейсный ввод текста там реализован через окно класса EDIT.
  • Игорь Шевченко © (01.05.08 22:22) [45]
    guav ©   (01.05.08 22:09) [44]

    А кто же спорит ? Если перекрыть WM_PAINT, то можно рисовать все, что угодно. Собственно, CTLCOLOREDIT оттуда же посылается.

    R1ka ©   (01.05.08 22:09) [43]

    С включенными темами - COMCTL32.DLL из WinSXS, без тем USER32.DLL
    А если тему отключить, эффект глюка будет проявляться ?
  • {RASkov} © (01.05.08 22:29) [46]
    > [42] Игорь Шевченко ©   (01.05.08 22:05)
    > Если пошлю тот же архив, что и в посте [34], можно попросить EXEшник запустить ?

    можно на cemvol2005(c)smtp.ru?
  • R1ka © (01.05.08 22:31) [47]
    Проявляется в любом случае.
    ComCtl32 у меня аж 10 штук, 4 из которых лежат в подпапках WinSxS
    и 7 USER32.dll (это исключая всякие темпы и бекапы апдейтов)
  • R1ka © (01.05.08 22:36) [48]
    C:\Windows\System32\COMCTL32.dll - 5.82.2900.2982
    остальные новее, и самая новая:
    C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9 - 6.0.2900.2180

    C:\Windows\System32\USER32.dll - 5.1.2600.3099 - она же самая новая
  • DVM © (01.05.08 22:52) [49]

    > Если пошлю тот же архив, что и в посте [34], можно попросить
    > EXEшник запустить ?

    можно
  • Игорь Шевченко © (01.05.08 22:56) [50]
    {RASkov} ©   (01.05.08 22:29) [46]
    DVM ©   (01.05.08 22:52) [49]

    Отослал, тема та же Edit with gradient fill

    guav ©   (01.05.08 22:09) [44]

    Вот у Paint как раз собственная обработка WM_PAINT в окне класса EDIT при вводе текста
  • DVM © (01.05.08 23:16) [51]

    > Игорь Шевченко ©   (01.05.08 22:56) [50]

    Запустил. Глюки есть.

    1) Сразу после запуска http://dvmuratov.narod.ru/1.png
    2) После потери и получения фокуса окном http://dvmuratov.narod.ru/2.png
    3) Ввод последовательности 12345678901234567890 http://dvmuratov.narod.ru/3.png
    4) После потери и получения фокуса окном http://dvmuratov.narod.ru/4.png
  • Игорь Шевченко © (01.05.08 23:21) [52]
    DVM ©   (01.05.08 23:16) [51]

    Спасибо. К сожалению, не могу воспроизвести у себя :(

    А хотелось бы, так как в этом случае глюк искать проще.
  • Игорь Шевченко © (01.05.08 23:23) [53]
    guav ©   (01.05.08 19:17) [37]

    Кстати, у этих компонентов еще и с кареткой глюк - она неверно позиционируется, относительно стандартного Edit
  • R1ka © (01.05.08 23:23) [54]
    Библиотки могу выслать, если, конечно, от них зависит
  • Игорь Шевченко © (01.05.08 23:33) [55]
    R1ka ©   (01.05.08 23:23) [54]

    Э...кто ж мне их даст переставить-то.

    Думать буду.
  • R1ka © (01.05.08 23:38) [56]
    мм.. тогда могу обновления, которые их ставят дать :)
  • Игорь Шевченко © (01.05.08 23:42) [57]
    R1ka ©   (01.05.08 23:38) [56]

    Э...я обновления как бы и сам могу :) Но не хочу, потому что не один раз натыкался на то, что после обновлений перестает работать то, что работало раньше. Например какое-то обновление вызывает конфликт Turbo Delphi 2006 и проводника.

    У меня вопрос ко всем проверящим (спасибо, в первую очередь) - если заниматься выделением текста во всех трех компонентах, и передавать/отнимать фокус у всего окна, вылезут какие-то эффекты ?

    Кстати, в присланном EXEшнике самим компонентом является второй сверху, у остальных градиентная заливка выполнена через обработку сообщения WM_CTLCOLOREDIT родительской формой.
  • {RASkov} © (01.05.08 23:45) [58]
    > [50] Игорь Шевченко ©   (01.05.08 22:56)
    > Отослал, тема та же Edit with gradient fill

    xex :)
    Что-то вообще интересный глюк... я даже и незнаю как его словами описать.... это видеть нужно... Попробую:
    Т.е. при старте в верхнем эдите текста не видно... при кликании по "панельке" на панели задач(т.е. сворачивание окна) на мгновение перед сворачиванием текст появляется, затем окно свернулось. После разворота - текста опять не видно.

    Фокус был в этом (верхнем) эдите.
    Если фокус сразу после запуска переместить на эдит ниже или на мемо, то в верхнем эдите текст появляется и уже не пропадает при сворачивании/разворачивании....

    Но самое интересное, что текст тоже пропадает как и при компиляции на моей машине, но немного по другому...
    У меня только 1 буква перед курсором видна, а в (хех) 12 букв перед курсором.... 13 и до начала стираются...
    Во втором сверху 15,5 букв до курсора видно, остальные до начала стираются. Это где курсивом.

    В Мемо при вводе вроде бы ничего не пропадает, но сильно моргает...
    В Мемо пропадают целиком строки. Т.е. если выделить пару символов на какой-нибудь строке, то эта строка одна и остается видна... остальные "стерлись"...
    Такая вот петрушка.
  • {RASkov} © (01.05.08 23:51) [59]
    Да, и в Д7 нет GradientFillCanvas.... навсяк)
  • DVM © (01.05.08 23:53) [60]

    > если заниматься выделением текста во всех трех компонентах,
    >  и передавать/отнимать фокус у всего окна, вылезут какие-
    > то эффекты ?

    У меня эффекты лезут самы разнообразные и закономерности я в них не вижу.

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

    При выделении в поле Memo пропадают все строки, кроме той, в которой происходит выделение, при потере фокуса остается только эта строка, при последующем получении тоже только она и выделение сохраняется. Причем больше двух строк выделить не получается.
  • Игорь Шевченко © (01.05.08 23:54) [61]
    {RASkov} ©   (01.05.08 23:45) [58]

    Спасибо.
    Про Memo я знаю - там даже в тексте самого Memo это написано.
    То, что сильно моргает, это при обработке KEYDOWN делается Invalidate, иначе текст будет пропадать при вводе с клавиатуры.
    Собственно, моргает и в компонентах по ссылке от guav. По той же самой причине.

    Так что пока единственно верным путем является все-таки собственная отрисовка текста и фона. Тогда можно и прозрачность сделать и заливку какую угодно.

    Но это долго писать.
  • Игорь Шевченко © (02.05.08 00:06) [62]
    Вот и я добился интересного эффекта - при включении XPMan в проект и включенных темах, при запуске все появляется, как и раньше, но при перемещении мыши над однострочным EDIT-ом, текст в окне пропадает. Целиком.
    Если XPMan убрать из проекта или отключить темы (задать тему "Классическую"), то все рисуется нормально (кроме выделения текста мышью в Memo, разумеется).

    Так что приходим к [61]
  • тиипа_того (03.05.08 16:28) [63]
    Удалено модератором
    Примечание: Не в пивной...
  • R1ka © (04.05.08 07:21) [64]
    тиипа_того,
    твое сообщение очень информативно и очень помогло. спасибо.
    и где в mail.ru агенте градиентное окошко ввода текста, там его нет - насколько вижу?
  • Игорь Шевченко © (04.05.08 10:31) [65]
    Эффект, получающийся у проверяющих, я воспроизвел. Сдается мне, что у меня на домашнем компьютере все хорошо и красиво, потому что установлена поддержка непростых языков, китайского, арабского и проч.
    В результате чего весь вывод текста выполняется в USP10.DLL (и все показывается, как надо).
    В системе, где поддержка таких языков не установлена, вывод текста в Edit выполняется в USER32.DLL (без тем) или в COMCTL32.DLL, причем, сначала выводится текст, а потом посылается сообщение WM_CTLCOLOREDIT (или WM_CTLCOLORSTATIC для Readonly или Disabled контрола), в котором весь текст вытирается градиентом.
    Порядок рисования примерно такой:
    Посылается WM_CTLCOLOREDIT
    Устанавливается цвет текста и цвет фона в DC, выводится текст,
    Посылается WM_CTLCOLOREDIT
    выводится текст (уже без установленных атрибутов)
 
Конференция "Компоненты" » Требуется компонент - подобие TEdit [D7, WinXP]
Есть новые Нет новых   [119357   +2][b:0.001][p:0.007]