Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
ВнизКолонка CheckBox ов в StringGrid e Найти похожие ветки
← →
ShimON © (2005-03-12 18:48) [0]Помогите, пожалуйста, реализовать сабж.
← →
begin...end © (2005-03-12 18:58) [1]> ShimON © (12.03.05 18:48)
Можно, конечно, делать настоящие, полноценные checkbox"ы, но, на мой взгляд, это будет требовать неоправданно много ресурсов. Поэтому я бы использовал API-функцию DrawFrameControl (см. её описание в справке) и вручную обрабатывал мышиные клики на полученных нарисованных checkbox"ах.
См. также статью на Королевстве Delphi: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=168
← →
ShimON © (2005-03-12 19:10) [2]
> и вручную обрабатывал мышиные клики на полученных нарисованных
> checkbox"ах.
Как это, не подскажешь??
← →
begin...end © (2005-03-12 19:18) [3]> ShimON © (12.03.05 19:10) [2]
Обрабатывайте TStringGrid.OnMouseDown, проверяйте, на какой колонке кликнули (TStringGrid.MouseToCell), и, если нужно, перерисовывайте checkbox (уже в другом состоянии) с помощью той же DrawFrameControl.
← →
ShimON © (2005-03-12 19:20) [4]Пишу так в обработчике
procedure TfmReport.StringGrid1DrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
if ACol = 3 then
DrawFrameControl(TStringGrid(Sender).Canvas.Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK);
end;
но эффекта ноль :( Что я делаю не так??
← →
begin...end © (2005-03-12 20:07) [5]> ShimON © (12.03.05 19:20) [4]
А у меня точно такой же код работает.
← →
Юрий Зотов © (2005-03-12 20:10) [6]> ShimON
DefaultDrawing проверьте
← →
ShimON © (2005-03-12 20:19) [7]Спасибо, разобрался, но вот следущая проблема...
procedure TfmReport.StringGrid1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ACol, ARow: integer;
i: byte;
ColInToolTip: byte;
Flag: boolean;
begin
StringGrid1.MouseToCell(X, Y, ACol, ARow);
if (ACol = 3) and (ARow <> 0) then
begin
if ReportItems[ARow].InToolTip then
Flag:= true
else
Flag:= false;
ColInToolTip:= 0;
if flag then
begin
for i:= 1 to 10 do
begin
if ReportItems[i].InToolTip then
Inc(ColInToolTip);
if ColInToolTip >= 2 then
begin
beep;
MessageDlg("Можно показать только две строки.", mtWarning, [mbOK], 0);
exit;
end;
end;
ReportItems[ARow].InToolTip:= true;
DrawFrameControl(TStringGrid(Sender).Canvas.Handle, StringGrid1.CellRect(ACol, ARow), DFC_BUTTON, DFCS_CHECKED)
end
else
begin
ReportItems[ARow].InToolTip:= false;
DrawFrameControl(TStringGrid(Sender).Canvas.Handle, StringGrid1.CellRect(ACol, ARow), DFC_BUTTON, DFCS_BUTTONCHECK)
end;
end;
end;
не меняется состояние и все тут, может я какое-то свойство поменял и клики не отлавливаются. Да, я еще по некой нужде покопался в настройках компилятора и линкера и у меня перестали появляться брикпоинты, то-есть появляются но он на них не останавливается (зажигает их зелеными крестиками), как мне это исправить??
← →
begin...end © (2005-03-12 20:35) [8]> ShimON © (12.03.05 20:19) [7]
Относительно настроек компилятора - возможно, Вы отключили включение отладочной информации. Проверьте состояние галочки Project -> Options -> Compiler -> Debugging -> Debug Information - если она не установлена, то установите её и перебилдите проект (Project -> Build ...).
Приведённый код несколько неоптимален, но в целом серьёзных ошибок не видно. Сообщите о результатах работы с отладчиком.
← →
ShimON © (2005-03-12 21:09) [9]Да, спасибо. именно это и сделал, но я пробывал все вернуть и так как не беребилдивал весь проект, то и результат был нулевой.
Насчет кода, а почему он некорректкн??
← →
Fenik (2005-03-12 21:15) [10]if ReportItems[ARow].InToolTip then
Flag:= true
else
Flag:= false;
Можно заменить на
Flag := ReportItems[ARow].InToolTip
Да и вообще, зачем этот Flag?
← →
begin...end © (2005-03-12 21:16) [11]> ShimON © (12.03.05 21:09) [9]
> Насчет кода, а почему он некорректкн??
Я не говорил, что он некорректен. Я сказал, что он неоптимален. Например, вот это:
> if ReportItems[ARow].InToolTip then
> Flag:= true
> else
> Flag:= false;
можно заменить на
Flag := ReportItems[ARow].InToolTip.
А строки
> ReportItems[ARow].InToolTip:= true
и
> ReportItems[ARow].InToolTip:= false
вообще не нужны.
Но всё это к обсуждаемому вопросу отношения не имеет. Что показывает отладчик - Вы выяснили причину проблемы? Или, может быть, лучше попробовать разобраться на новом (почти пустом) приложении, чтобы не запутываться?
← →
ShimON © (2005-03-12 21:19) [12]Все, я разобрался, суть флага в том, что если ячейка уже выбрана, то нужно просто убрать галочку, а если не выбрана, то надо проверить, что выделено не более двух ячеек и в этом случее только поставить галочку.
А ошибка в том, что надо было сделать наоборот:if ReportItems[ARow].InToolTip then
Flag:= false
else
Flag:= true;
← →
Fenik (2005-03-12 21:21) [13]>if ReportItems[ARow].InToolTip then
> Flag:= false
> else
> Flag:= true;
Flag := not ReportItems[ARow].InToolTip; :))
или вообще
if not ReportItems[ARow].InToolTip then
begin
for i:= 1 to 10 do
begin
if ReportItems[i].InToolTip then
Inc(ColInToolTip);
if ColInToolTip >= 2 then
begin
beep;
MessageDlg("Можно показать только две строки.", mtWarning, [mbOK], 0);
exit;
end;
end;
ReportItems[ARow].InToolTip:= true;
DrawFrameControl(TStringGrid(Sender).Canvas.Handle, StringGrid1.CellRect(ACol, ARow), DFC_BUTTON, DFCS_CHECKED)
end
else
begin
ReportItems[ARow].InToolTip:= false;
DrawFrameControl(TStringGrid(Sender).Canvas.Handle, StringGrid1.CellRect(ACol, ARow), DFC_BUTTON, DFCS_BUTTONCHECK)
end;
← →
ShimON © (2005-03-12 21:23) [14]Всем большое спасибо, проблема решена.
← →
begin...end © (2005-03-12 21:31) [15]> ShimON © (12.03.05 21:19) [12]
const
States: array [Boolean] of Cardinal = (DFCS_BUTTONCHECK, DFCS_CHECKED);
begin
with (Sender as TStringGrid) do
begin
MouseToCell(X, Y, ACol, ARow);
if (ACol = 3) and (ARow <> 0) then
begin
if not ReportItems[ARow].InToolTip then
begin
ColInToolTip := 0;
for i := 1 to 10 do
begin
...
end
end;
ReportItems[ARow].InToolTip := not ReportItems[ARow].InToolTip;
DrawFrameControl(Canvas.Handle, CellRect(ACol, ARow), DFC_BUTTON, States[ReportItems[ARow].InToolTip])
end;
end
end.
← →
ShimON © (2005-03-12 21:35) [16]Класс, мне нравиться! Буду учиться писать красиво и компактно!
← →
Юрий Зотов © (2005-03-12 22:11) [17]> ShimON
1. Нельзя определять колонку с чекбоксами только по ее номеру - ведь юзер может и перетащить ее на другое место. Этот признак должна иметь сама колонка, независимо от своего номера - и такие признаки удобно хранить в свойстве Objects нулевой строки (если она Fixed).
2. Не надо ничего рисовать в мышином обработчике. Там надо только проставить признак того, стоит ли птичка, или нет (причем для этого тоже удобно использовать свойство Objects), а потом запросить перерисовку. Windows сама разберется, что, когда и как ей надо перерисовывать.
3. Приличная программа должна позволять юзеру переключать птички не только мышью, а еще и клавишей "пробел".
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
with StringGrid1 do
for i := 0 to ColCount - 1 do
Objects[i, 0] := TObject(Odd(i))
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
const
Flags: array[Boolean] of DWORD = (0, DFCS_CHECKED);
begin
with StringGrid1, Canvas do
begin
if gdSelected in State then
Brush.Color := clHighlight
else
Brush.Color := clWindow;
FillRect(Rect);
if (ARow >= FixedRows) and Boolean(Objects[ACol, 0]) then
begin
InflateRect(Rect, -4, -4);
DrawFrameControl(Canvas.Handle, Rect, DFC_BUTTON,
DFCS_FLAT or DFCS_BUTTONCHECK or Flags[Boolean(Objects[ACol, ARow])])
end
end
end;
procedure TForm1.StringGrid1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ACol, ARow: integer;
begin
if Button = mbLeft then
with StringGrid1 do
begin
MouseToCell(X, Y, ACol, ARow);
if (ACol >= FixedCols) and (ARow >= FixedRows) then
SwitchCell
end
end;
procedure TForm1.StringGrid1KeyPress(Sender: TObject;
var Key: Char);
begin
if Key = " " then
SwitchCell
end;
procedure TForm1.SwitchCell;
begin
with StringGrid1 do
begin
Objects[Col, Row] := TObject(not Boolean(Objects[Col, Row]));
Invalidate
end
end;
← →
ShimON © (2005-03-12 22:17) [18]Сделал так, теперь буду знать, спасибо. Мне еще интересно, где этому научиться можно или это только с опытом приходит??
← →
Fenik (2005-03-12 22:32) [19]Книги читать надо.
← →
ShimON © (2005-03-12 22:34) [20]Так читаю, причем регулярно, но кода в них маловато... Может не то читаю...
← →
Юрий Зотов © (2005-03-12 22:49) [21]> ShimON
Попробуйте писать компоненты. Во-первых, получите ценнейший опыт. Во-вторых, придется полазить по коду VCL (вот уж где кода более, чем достаточно). В-третьих, получите знания, которые трудно получить, если писать только прикладные программы.
← →
ShimON © (2005-03-12 22:50) [22]Спасибо, я попробую
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.04 c