![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ListBox убрать рамку в выделенной строке [D7, WinXP]
Дмитрий_05 © (2005-12-01 13:44:00)Как в ListBox-е убрать рамку в выделенной строке? она рисуется вокруг строки как бы пунктиром... вот как от нее можно избавиться?
Antonn (2005-12-07 18:14:00) [1]Дмитрий_05 (07.12.05 17:21) [28]
глянь тут: http://an-files.narod.ru/_works/5016.html
Дмитрий_05 (2005-12-07 17:30:00) [2]Что за деньги то это точно...:)))
Игорь Шевченко (2005-12-07 17:29:00) [3]Дмитрий_05 (07.12.05 17:21) [28]
> а можно
За деньги можно все. Только их много надо, денег.
Дмитрий_05 (2005-12-07 17:21:00) [4]Работает ))) а можно чтобы курсор не изменялся(чтобы не рисовался квадратик снизу курсора), и чтобы перемещение строки происходило во время перемещения курсора, а не после того как отпустить клавишу... Ну, соответственно если нажать правую клавишу мышки, не отпуская левой, чтобы сбрасывалось это все, т.е. строка становилась туда, где она и была...
Игорь Шевченко (2005-12-07 14:07:00) [5]Дмитрий_05 (07.12.05 12:51) [26]
> А вот чтобы строки можно было перемещать мышкой, т.е. имеется
> ввиду если ее "взять и потацить"
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
procedure ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
ListBox1.BeginDrag({not (Button = mbLeft)}false);
end;
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if Source = ListBox1 then
with ListBox1,ListBox1.Items do
Move(ItemIndex, ItemAtPos(Point(X, Y), True));
end;
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept:=Source = ListBox1;
end;
end.
Дмитрий_05 (2005-12-07 12:51:00) [6]Игорь Шевченко, точно... что-то я не догадался, наверно из за того что не спал всю ночь, торможу уже :) Сейчас я на работе, тут нету Delphi, дома попробую :) А вот чтобы строки можно было перемещать мышкой, т.е. имеется ввиду если ее "взять и потацить", чтобы менялся ее индекс в зависимости от положения курсора, что посоветуете? :)
Игорь Шевченко (2005-12-07 12:31:00) [7]
> Если можно... подскажите пожалуйста, как сделать чтобы при
> потере фокуса строка в таком ListBox-е оставалась выделенной
в CNDrawItem убрать проверку на odFocused, а проверять на odSelected ?
Дмитрий_05 (2005-12-07 12:26:00) [8]я уже разобрался ))) может кому пригодится:
unit XListBox;
interface
uses
Windows, Messages, Classes, Controls, StdCtrls, Graphics, SysUtils;
type
TXListBox = class(TListBox)
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure RecreateBack; virtual;
private
procedure PictureChanged(Sender: TObject);
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
procedure WMEraseBkgnd(var Message: TWMERASEBKGND); Message WM_ERASEBKGND;
procedure WMHScroll(var Message: TWMHScroll); message WM_HScroll;
procedure WMVScroll(var Message: TWMVScroll); message WM_VScroll;
procedure WMMOUSEWHEEL(var Message: TWMMOUSEWHEEL); message WM_MOUSEWHEEL;
private
FBack: TBitmap;
FPicture: TPicture;
FSelectedTextColor: TColor;
procedure SetPicture(const Value: TPicture);
procedure SetSelectedTextColor(const Value: TColor);
published
property Picture: TPicture read FPicture write SetPicture;
property SelectedTextColor: TColor read FSelectedTextColor write SetSelectedTextColor default clHighlightText;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MyComp', [TXListBox]);
end;
constructor TXListBox.Create(AOwner: TComponent);
begin
inherited;
FBack := TBitmap.Create;
FPicture := TPicture.Create;
FPicture.OnChange := PictureChanged;
FSelectedTextColor := clRed;// clHighlightText;
end;
destructor TXListBox.Destroy;
begin
FPicture.Free;
FBack.Free;
inherited;
end;
procedure TXListBox.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do begin
if Style and (LBS_OWNERDRAWFIXED or LBS_OWNERDRAWVARIABLE) = 0 then
Style := Style or LBS_OWNERDRAWFIXED;
Style := Style or BS_OWNERDRAW{ or WS_CLIPCHILDREN};
end;
end;
procedure TXListBox.RecreateBack;
begin
if HandleAllocated then
with FBack, Canvas do begin
Width := ClientWidth;
Height := ClientHeight;
Brush.Color := Self.Color;
if FPicture.Graphic <> nil then
StretchDraw(ClipRect, FPicture.Graphic)
else
FillRect(ClipRect);
end;
end;
procedure TXListBox.PictureChanged(Sender: TObject);
begin
RecreateBack;
Invalidate;
end;
procedure TXListBox.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin
if (FBack.Width <> ClientWidth) or (FBack.Height <> ClientHeight) then
RecreateBack;
Canvas.Draw(0, 0, FBack);
InvalidateRect(Handle, nil, false);
Message.Result := 1;
end;
procedure TXListBox.WMPaint(var Message: TWMPaint);
begin
inherited;
if Items.Count = 0 then Canvas.Draw(0, 0, FBack);
end;
procedure TXListBox.CNDrawItem(var Message: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Message.DrawItemStruct^ do
begin
State := TOwnerDrawState(LongRec(itemState).Lo);
Canvas.Handle := hDC;
Canvas.Font := Font;
Canvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odFocused in State) then
Canvas.Font.Color := SelectedTextColor;
Canvas.Brush.Style := bsClear;
if Integer(itemID) >= TopIndex then
DrawItem(itemID, rcItem, State);
Canvas.Handle := 0;
end;
end;
procedure TXListBox.WMHScroll(var Message: TWMHScroll);
begin
if Message.ScrollBar = 0 then
begin
LockWindowUpdate(Handle);
inherited;
LockWindowUpdate(0);
InvalidateRect(Handle, nil, true);
end
else
inherited;
end;
procedure TXListBox.WMVScroll(var Message: TWMVScroll);
begin
if Message.ScrollBar = 0 then
begin
LockWindowUpdate(Handle);
inherited;
LockWindowUpdate(0);
InvalidateRect(Handle, nil, true);
end
else
inherited;
end;
procedure TXListBox.WMMOUSEWHEEL(var Message: TWMMOUSEWHEEL);
begin
if GetFocus = Handle then
begin
LockWindowUpdate(Handle);
inherited;
LockWindowUpdate(0);
InvalidateRect(Handle, nil, true);
end
else
inherited;
end;
procedure TXListBox.SetPicture(const Value: TPicture);
begin
FPicture.Assign(Value);
end;
procedure TXListBox.SetSelectedTextColor(const Value: TColor);
begin
if FSelectedTextColor = Value then exit;
FSelectedTextColor := Value;
Invalidate;
end;
end.
Если можно... подскажите пожалуйста, как сделать чтобы при потере фокуса строка в таком ListBox-е оставалась выделенной, т.е. оставалась SelectedTextColor цветом. И еще если можно, сделать так чтобы строки можно было перетаскивать мышкой...
Игорь Шевченко (2005-12-07 10:18:00) [9]
> Подскажите пожалуйста что не так?
А где код, в котором не так ?
Дмитрий_05 (2005-12-06 19:00:00) [10]Подскажите пожалуйста что не так? Может действительно сообщения не доходят о перерисовке строк?
Дмитрий_05 (2005-12-05 19:53:00) [11]Сори... Ошибся... посмотрел метод перерисовки строк, а не окна...)))))
Дмитрий_05 (2005-12-05 19:50:00) [12]Спасибо за ссылку... поразбирался... посмотрел метод перерисовки окна... в моем случае вроде все так... но блин... исчезают строки и все...((( Может само сообщение не доходит о перерисовки строк CN_DRAWITEM? просто если сделать так: вот выделить в ListBox-е по строчке, чтобы они все показались... а потом перенести форму за пределы монитора а потом назад, строки опять исчезают, а сам фон рисуется без проблем... вот в чем дело..(((
Игорь Шевченко (2005-12-05 12:18:00) [13]http://kladovka.net.ru/download.cgi?id=193
Дмитрий_05 (2005-12-05 00:39:00) [14]Переносил и уберал, еще до того как написать... Если совсем убрать, то в момент проектирования формы, при изменения свойства Picture, изображение не вставляется, само окно выбора изображения не закрывается никак, и Delphi как-бы виснет... Приходится выключать его через диспечер задачь... А если поставить в начало, то у меня строки не рисуются, только после того, если выделить их. Прорисовка строк, может там что-то не то я нахимичел:
type
TXListBox = class(TListBox)
private
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
protected
procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
.....
procedure TXListBox.CNDrawItem(var Message: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Message.DrawItemStruct^ do
begin
State := TOwnerDrawState(LongRec(itemState).Lo);
Canvas.Handle := hDC;
Canvas.Font := Font;
Canvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then
begin
Canvas.Font.Color := FSelectedTextColor;
end;
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State);
Canvas.Handle := 0;
end;
end;
procedure TXListBox.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
var
Flags: Longint;
Data: String;
begin
if Assigned(OnDrawItem) then
OnDrawItem(Self, Index, Rect, State)
else
begin
if Index < Count then
begin
Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
if not UseRightToLeftAlignment then
Inc(Rect.Left, 2)
else
Dec(Rect.Right, 2);
Data := '';
if (Style in [lbVirtual, lbVirtualOwnerDraw]) then
Data := DoGetData(Index)
else
Data := Items[Index];
SetBKMode(Canvas.Handle, TRANSPARENT);
DrawText(Canvas.Handle, PChar(Data), Length(Data), Rect, Flags);
end;
end;
end;
P.S. То что не используется FillRect, я решил выделять строки только цветом шрифта.
Джо (2005-12-04 23:23:00) [15]
> procedure TXListBox.WMPaint(var Message: TWMPAINT);
> var
> R: TRect;
> begin
> with Canvas do
> begin
> Brush.Style := bsClear;
> R := ClientRect;
> if FPicture.Graphic <> nil then
> StretchDraw(R, FPicture.Graphic);
> end;
> inherited;
> end;
Перенести inherited в начало кода или убрать.
Дмитрий_05 (2005-12-04 22:00:00) [16]Со строками разобрался, у меня небольшая проблема вот в чем. У меня этот компонент лежит на форме, которая создается диномически(по нажатию кнопки). Форма появляется, а мой ListBox не заполняется фоном, если эту форму перенести за пределы экрана а потом обратно, то фон рисуется. Прорисовка:
procedure TXListBox.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin // чтобы не мограл
Message.Result := 1;
end;
procedure TXListBox.WMPaint(var Message: TWMPAINT);
var
R: TRect;
begin
with Canvas do
begin
Brush.Style := bsClear;
R := ClientRect;
if FPicture.Graphic <> nil then
StretchDraw(R, FPicture.Graphic);
end;
inherited;
end;
Пробовал этот код и без WM_EraseBkgnd, тоже самое...
Пробовал и так:
procedure TXListBox.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin
if FPicture.Bitmap <> nil then
begin
BitBlt(Message.DC, 0, 0, ClientWidth, ClientHeight, FPicture.Bitmap.Canvas.Handle, 0, 0, srcCopy);
Message.Result := 1;
end
else
inherited;
end;
так вообще не рисуется... помогите, что не так...
Дмитрий_05 (2005-12-03 23:28:00) [17]Я нашел только вот что: http://delphimaster.ru/cgi-bin/forum.pl?id=1131899674&n=0
но там тема так и не расскрыта...
Джо (2005-12-03 22:40:00) [18]
> что делать?
Читать посты в этой ветке и думать над ними. А потом уже писать "свой вариант".
Дмитрий_05 (2005-12-03 22:36:00) [19]Мне тут посказали вот как сделать:
TXListBox = class(TListBox)
private
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
end;
..............
procedure TXListBox.CNDrawItem(var Message: TWMDrawItem);
begin
with Message.DrawItemStruct^ do
itemState:=itemState and not 16;
inherited;
end;
Решил всетаки свой компонент сделать... Решил туда еще добавить фон, картинку:
TXListBox = class(TListBox)
private
FPicture: TPicture;
procedure SetPicture(const Value: TPicture);
procedure PictureChanged(Sender: TObject);
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
procedure WMPaint(var Message: TWMPAINT); Message WM_PAINT;
procedure WMEraseBkgnd(var Message: TWMERASEBKGND); Message WM_ERASEBKGND;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Picture: TPicture read FPicture write SetPicture;
end;
...
constructor TXListBox.Create(AOwner: TComponent);
begin
inherited;
FPicture := TPicture.Create;
FPicture.OnChange := PictureChanged;
end;
destructor TXListBox.Destroy;
begin
FPicture.Free;
inherited;
end;
procedure TXListBox.CNDrawItem(var Message: TWMDrawItem);
begin
with Message.DrawItemStruct^ do
itemState := itemState and not 16;
inherited;
end;
procedure TXListBox.SetPicture(const Value: TPicture);
begin
FPicture.Assign(Value);
end;
procedure TXListBox.PictureChanged(Sender: TObject);
begin
Invalidate;
end;
procedure TXListBox.WMEraseBkgnd(var Message: TWMERASEBKGND);
begin
Message.Result := 1;
end;
procedure TXListBox.WMPaint(var Message: TWMPAINT);
var
R: TRect;
begin
inherited;
with Canvas do
begin
Brush.Style := bsClear;
R := ClientRect;
if FPicture.Graphic <> nil then
StretchDraw(R, FPicture.Graphic);
end;
end;
Но у меня теперь картинка то рисуется, а строки исчезли... При выделении строк, часть картинки исчезает, т.е. заместо той строки какая была выделена, просто белый фон... и строки опять стали с рамкой... что делать?
XCoder (2005-12-03 02:20:00) [20]Можно и так, я против ничего не имею, просто рассказал как сам делал.