Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
9-1100799849
Xerx
2004-11-18 20:44
2005.03.27
OpenGL, текстурирование и пересечения


3-1109661909
Чеширский_Кот
2005-03-01 10:25
2005.03.27
Data provider or other service returned an E_FAIL status


4-1108538439
Гость
2005-02-16 10:20
2005.03.27
Кэш


1-1110574689
Ji
2005-03-11 23:58
2005.03.27
Чтение двоичного файла.


8-1100903370
Maxim____
2004-11-20 01:29
2005.03.27
Алгоритм уровней.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский