Вот решение, которое работает для меня:
-В главной форме поместите компонент «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 is 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.
Я надеюсь, что это помогает другим.Хорошего дня!