Delphi stringgrid TAdvsTringgrid函数用于禁用和重新启用鼠标单击

时间:2018-05-16 10:43:53

标签: delphi stringgrid

是否有Delphi函数来启用或禁用stringgrid的鼠标点击?

我使用了一个名为Tadvstringgrid的stringgrid派生,它允许根据竞争对单元格进行着色

我需要在使用来自各种线程的数据填充控件时阻止鼠标在stringgrid中单击。

仅禁用控件是不够的。如果我点击随机单元格,信息会被搞砸,这意味着某些字符串被放置在我点击的最后一个单元格中。

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}




type
  TThread_populate_stringgrid = class(TThread)

  strict private

f_stringgrid_to_populate:Tstringgrid;
f_name:string;




  protected

    procedure Execute; override;




  public

    constructor Create(a_name:string;a_stringgrid_to_populate:Tstringgrid);




  end;



constructor TThread_populate_stringgrid.Create(a_name:string;a_stringgrid_to_populate:Tstringgrid);
begin
  inherited Create(False);
  freeonterminate:=true;
  priority:=tpNormal ;

f_name:=a_name;
f_stringgrid_to_populate:=a_stringgrid_to_populate;
end;






procedure TThread_populate_stringgrid.Execute;
begin

Synchronize(
procedure
begin



f_stringgrid_to_populate.cells[0,0]:='DATE';
f_stringgrid_to_populate.cells[1,0]:='NAME';
f_stringgrid_to_populate.cells[2,0]:='ADRESS';
f_stringgrid_to_populate.cells[3,0]:='CITY';
f_stringgrid_to_populate.cells[4,0]:='COUNTRY';


f_stringgrid_to_populate.Cols[0].Add(FormatDatetime('dd-mm-yyyy hh:mm:ss', Now));
f_stringgrid_to_populate.Cols[1].Add(f_name);
f_stringgrid_to_populate.Cols[2].Add('58 RED ROAD');
f_stringgrid_to_populate.Cols[3].Add('ENGLAND');
f_stringgrid_to_populate.Cols[3].Add('UK');



end
)
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TThread_populate_stringgrid.Create('Andrei',form1.StringGrid1);
TThread_populate_stringgrid.Create('Matei',form1.StringGrid1);
TThread_populate_stringgrid.Create('Iulia',form1.StringGrid1);
TThread_populate_stringgrid.Create('Petru',form1.StringGrid1);
TThread_populate_stringgrid.Create('Gheorghe',form1.StringGrid1);
TThread_populate_stringgrid.Create('Tudor',form1.StringGrid1);
TThread_populate_stringgrid.Create('Cineva',form1.StringGrid1);
TThread_populate_stringgrid.Create('Altcine',form1.StringGrid1);
end;

end.

谢谢!

1 个答案:

答案 0 :(得分:0)

以下是适合我的解决方案:

- 在主窗体中放置一个“ApplicationEvents”组件。

- 转到ApplicationEvents的“事件”部分

- 双击“Onmessage”属性并添加以下过程

procedure TForm1.deactivate_mouse_in_advstringgrid(var Msg: tagMSG;
  var Handled: Boolean);

 var
  pnt: TPoint;
  ctrl: TWinControl;
 begin
  if (
  (Msg.message = SB_VERT) OR
  (Msg.message = SB_HORZ) OR
  (Msg.message = WS_HSCROLL) OR
  (Msg.message = WS_VSCROLL) OR
  (Msg.message = WM_VSCROLL) OR
  (Msg.message = WM_MOUSEWHEEL) OR
  (Msg.message = WM_LBUTTONDOWN)   OR
  (Msg.message = WM_LBUTTONUP)   OR
  (Msg.message = WM_LBUTTONDBLCLK)   OR
  (Msg.message = WM_MBUTTONDOWN)   OR
  (Msg.message = WM_MBUTTONUP) OR
  (Msg.message = WM_MBUTTONDBLCLK) OR
  (Msg.message = WM_RBUTTONDOWN) OR
  (Msg.message = WM_RBUTTONUP) OR
  (Msg.message = WM_RBUTTONDBLCLK) OR
  (Msg.message = WM_KEYUP) OR
  (Msg.message = WM_KEYDOWN)
  )

  then
  begin

    if not GetCursorPos(pnt) then Exit;
    ctrl := FindVCLWindow(pnt);
    if Assigned(CTRL) then
   begin
      if Ctrl is TAdvstringgrid then
         begin
        // Msg.hwnd:=ctrl.Handle;
      //Msg.hwnd := advsg1.Handle;
            if thread_activ>0 then
               begin
              Msg.hwnd := 0;
              Exit;
                end
            else
              begin
              Msg.hwnd:=ctrl.Handle;
             end;
  end;
  end;
  end;
end;

如果使用Tadvstringgrid组件,请将此代码更改为“如果Ctrl为TAdvstringgrid”。

如果使用Stringgrid,请将此更改为“如果Ctrl为TStringgrid”。

上述过程使用名为“thread_activ”的全局变量,该变量包含活动线程的数量。因此,如果存在使用Advstringgrid组件的活动线程,则鼠标单击,鼠标滚轮,滚动条和按键被压缩。

线程存储在具有以下代码的第二个单元中:

unit thread_stringgrid;

interface

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


type
  TThread_populate_stringgrid = class(TThread)

  strict private

f_stringgrid_to_populate:Tstringgrid;
f_name:string;


  protected

    procedure Execute; override;



  public
    CriticalSection: TRTLCriticalSection;
    constructor Create(a_name:string;a_stringgrid_to_populate:Tstringgrid);
  end;



implementation

{use the unit that holds the global vaiable "thread_activ"}
uses unit1;



constructor TThread_populate_stringgrid.Create(a_name:string;a_stringgrid_to_populate:Tstringgrid);
begin
  inherited Create(False);
  freeonterminate:=true;
  priority:=tpNormal ;

f_name:=a_name;
f_stringgrid_to_populate:=a_stringgrid_to_populate;
end;



procedure TThread_populate_stringgrid.Execute;
begin

//before the threads starts
InitializeCriticalSection(CriticalSection);

//in the thread
EnterCriticalSection(CriticalSection);
//From now on, you can safely make
//changes to the variables.

{increment variable from main unit1}
inc(unit1.thread_activ);

//End of safe block
LeaveCriticalSection(CriticalSection);

Synchronize(
procedure
begin

f_stringgrid_to_populate.cells[0,0]:='DATE';
f_stringgrid_to_populate.cells[1,0]:='NAME';
f_stringgrid_to_populate.cells[2,0]:='ADRESS';
f_stringgrid_to_populate.cells[3,0]:='CITY';
f_stringgrid_to_populate.cells[4,0]:='COUNTRY';


f_stringgrid_to_populate.Cols[0].Add(FormatDatetime('dd-mm-yyyy hh:mm:ss', Now));
f_stringgrid_to_populate.Cols[1].Add(f_name);
f_stringgrid_to_populate.Cols[2].Add('58 RED ROAD');
f_stringgrid_to_populate.Cols[3].Add('ENGLAND');
f_stringgrid_to_populate.Cols[3].Add('UK');



end
);

{eliminate thread counter from global variable "thread_activ"}
 EnterCriticalSection(CriticalSection);
  try
{decrement variable from main unit1}
dec(unit1.thread_activ);
finally
 LeaveCriticalSection(CriticalSection);
 end;

end;

(*
procedure TForm1.Button1Click(Sender: TObject);
begin
TThread_populate_stringgrid.Create('Andrei',form1.StringGrid1);
TThread_populate_stringgrid.Create('Matei',form1.StringGrid1);
TThread_populate_stringgrid.Create('Iulia',form1.StringGrid1);
TThread_populate_stringgrid.Create('Petru',form1.StringGrid1);
TThread_populate_stringgrid.Create('Gheorghe',form1.StringGrid1);
TThread_populate_stringgrid.Create('Tudor',form1.StringGrid1);
TThread_populate_stringgrid.Create('Cineva',form1.StringGrid1);
TThread_populate_stringgrid.Create('Altcine',form1.StringGrid1);
end;

*)

(*
procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  S: string;
  RectForText: TRect;
begin
  // Check for your cell here (in this case the cell in column 4 and row 2 will be colored)
  //if (ACol = 1) and (ARow = 1) then
  if ((ACol = 1) and (ARow>0))  then
  begin
    S := form1.StringGrid1.Cells[ACol, ARow];
    if (s='Andrei') then
      begin
    // Fill rectangle with colour
    //form1.StringGrid1.Canvas.Brush.Color := clBlack;
    form1.StringGrid1.Canvas.FillRect(Rect);
    // Next, draw the text in the rectangle
    form1.StringGrid1.Canvas.Font.Color := clGreen;
    RectForText := Rect;
    // Make the rectangle where the text will be displayed a bit smaller than the cell
    // so the text is not "glued" to the grid lines
    InflateRect(RectForText, -2, -2);
    // Edit: using TextRect instead of TextOut to prevent overflowing of text
    form1.StringGrid1.Canvas.TextRect(RectForText, S);
      end;
  end;

   // if (ACol = 2) and (ARow = 1) then
     if ((ACol = 2)and (ARow>0)) then
  begin

    S := form1.StringGrid1.Cells[ACol, ARow];
    if (s='58 RED ROAD') then
    begin

    // Fill rectangle with colour
    //form1.StringGrid1.Canvas.Brush.Color := clwhite;
    form1.StringGrid1.Canvas.FillRect(Rect);
    // Next, draw the text in the rectangle
    form1.StringGrid1.Canvas.Font.Color := clRed;
    RectForText := Rect;
    // Make the rectangle where the text will be displayed a bit smaller than the cell
    // so the text is not "glued" to the grid lines
    InflateRect(RectForText, -2, -2);
    // Edit: using TextRect instead of TextOut to prevent overflowing of text
    form1.StringGrid1.Canvas.TextRect(RectForText, S);
    end
    else
    begin
     // Fill rectangle with colour
    //form1.StringGrid1.Canvas.Brush.Color := clwhite;
    form1.StringGrid1.Canvas.FillRect(Rect);
    // Next, draw the text in the rectangle
    form1.StringGrid1.Canvas.Font.Color := clBlue;
    RectForText := Rect;
    // Make the rectangle where the text will be displayed a bit smaller than the cell
    // so the text is not "glued" to the grid lines
    InflateRect(RectForText, -2, -2);
    // Edit: using TextRect instead of TextOut to prevent overflowing of text
    form1.StringGrid1.Canvas.TextRect(RectForText, S);
    end;
  end;


     //if (ACol = 3) and (ARow = 1) then
     if ((ACol = 3)and (ARow>0)) then
  begin
    S := form1.StringGrid1.Cells[ACol, ARow];
    if s='Altcine' then
    begin
    // Fill rectangle with colour
    //form1.StringGrid1.Canvas.Brush.Color := clwhite;
    form1.StringGrid1.Canvas.FillRect(Rect);
    // Next, draw the text in the rectangle
    form1.StringGrid1.Canvas.Font.Color := clYellow;
    RectForText := Rect;
    // Make the rectangle where the text will be displayed a bit smaller than the cell
    // so the text is not "glued" to the grid lines
    InflateRect(RectForText, -2, -2);
    // Edit: using TextRect instead of TextOut to prevent overflowing of text
    form1.StringGrid1.Canvas.TextRect(RectForText, S);
    end;
  end;

 *)



end.

我希望这有助于其他人。祝你有美好的一天!