Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.27;
Скачать: CL | DM;

Вниз

Колонка 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.046 c
14-1110220844
SergSerSh
2005-03-07 21:40
2005.03.27
Клиент для форума


14-1110342902
КаПиБаРа
2005-03-09 07:35
2005.03.27
"Женская" и "мужская" музыка


3-1109413033
xman
2005-02-26 13:17
2005.03.27
копирование базы Oracle


9-1104822042
DonNikola
2005-01-04 10:00
2005.03.27
Юнит для логирования


1-1110895436
Mamed
2005-03-15 17:03
2005.03.27
UrlEncode