Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi stringgrid TAdvsTringgrid函数,用于禁用和重新启用鼠标单击_Delphi_Stringgrid - Fatal编程技术网

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

Delphi stringgrid TAdvsTringgrid函数,用于禁用和重新启用鼠标单击,delphi,stringgrid,Delphi,Stringgrid,是否有Delphi函数来启用或禁用stringgrid的鼠标单击 我使用了stringgrid的一个派生,名为Tadvstringgrid,它允许基于内容对单元格进行着色 我需要防止在stringgrid中单击鼠标,同时使用来自不同线程的数据填充控件 仅禁用控件是不够的。如果我在随机单元格中单击,则信息会出错,这意味着某些字符串会放置在我单击的最后一个单元格中 unit Unit1; interface uses Windows, Messages, SysUtils, Variants

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

我使用了stringgrid的一个派生,名为Tadvstringgrid,它允许基于内容对单元格进行着色

我需要防止在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.

谢谢大家!

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

-在主窗体中放置一个“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.

我希望这能帮助其他人。祝你今天愉快

为什么不在线程启动时将
StringGrid1.Enabled
设置为false,在线程全部完成后将其设置为True?为什么不参考帮助?(顺便说一句,用非常糟糕的方法填充来自多个线程的控件)这就是启用
的目的。您很可能想要禁用整个UI。也许最干净的方法是显示一个模式进度对话框。你是如何填充网格的?这听起来像是你的问题,但你没有给我们显示任何代码,所以我们只能猜测。谢谢你的更新,但是。。。您应该从一开始就明确表示您正在使用
TAdvStringGrid
。我没有,因此无法调查。