ShowMessage появляется за формой - Delphi - PullRequest
0 голосов
/ 11 июля 2020

Моя программа имеет MessageBox в коде. в первый раз, когда я запустил его, оказалось, что он не отображается, и программа зависла. Я часами читал форумы и все перепробовал. Я свернул форму прямо перед MessageBox, и, похоже, за формой появляется диалог. Я пробовал этот фрагмент кода, но ничего не помогло.

Application.NormalizeTopMosts; MessageBox(Handle,'Test','A message test',MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONHAND);

PS: У меня есть другая форма в программе, и она отлично работает с этой формой, и я убедился, что у них обоих одинаковые settings

Edit:

Я только что понял, что это была функция OnCellDraw моей StringGrid, которая заставила сообщение быть скрытым. Мне удалось заставить его работать, сделав StringGrid невидимым, а затем снова видимым. OnDrawCell имеет обманчивый код, который отображает зарезервированные дни года с использованием окрашенных ячеек. Я хотел бы знать, есть ли лучший способ заставить сообщение появляться, не делая невидимую сетку строк. Без запуска OnDrawCell MessageBox также работает

procedure TfrmClient.stgYearPlanDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  k, iMonth, iDay, iStart, iEnd, iSubtract : Integer;
begin
    case iYear of
      2020 :  begin
                iStart := 1;
                iEnd:= 12;
                iSubtract := 0;
              end;
      2021  : begin
                iStart := 13;
                iEnd:= 24;
                iSubtract := 12;
              end;
      2022  : begin
                iStart := 25;
                iEnd := 36;
                iSubtract := 24;
              end;
    end;
    for k := 1 to 31 do
      stgYearPlan.Cells[k,0] := IntToStr(k);

    for k := 1 to 12 do
      stgYearPlan.Cells[0,k] := ShortMonthNames[k];

    for iMonth := iStart to iEnd do
    begin
    for iDay := 1 to 31 do
     begin
          if ar2Booking[iDay,iMonth] = 'Y' then
          begin
            if (ACol = iDay) and (ARow = (iMonth-iSubtract)) then
            begin
              stgYearPlan.Canvas.Brush.Color := clBlack;
              stgYearPlan.Canvas.FillRect(Rect);
              stgYearPlan.Canvas.TextOut(Rect.Left,Rect.Top,stgYearPlan.Cells[ACol, ARow]);
            end;
          end;

          if ar2Booking[iDay,iMonth] = 'D' then
          begin
            if (ACol = iDay) and (ARow = (iMonth-iSubtract)) then
            begin
              stgYearPlan.Canvas.Brush.Color := clSilver;
              stgYearPlan.Canvas.FillRect(Rect);
              stgYearPlan.Canvas.TextOut(Rect.Left+2,Rect.Top+2,stgYearPlan.Cells[ACol, ARow]);
            end;
          end;
     end;
     end;
end;```


1 Ответ

3 голосов
/ 12 июля 2020

Проблема в том, что вы заполняете сетку строк данными в ее OnDrawCell обработчике.

В этом методе вы должны рисовать только на холсте; вы не должны трогать данные.

Когда сетка должна перерисоваться, вызывается ее обработчик OnDrawCell. Вы рисуете в сетке (это нормально), но вы также меняете данные. Из-за этого сетка понимает, что ей нужно снова перерисовать себя (потому что ее данные изменились!), Поэтому вызывается ее обработчик OnDrawCell. Вы рисуете в сетке (это нормально), но вы также меняете данные. Из-за этого сетка понимает, что ей нужно снова перерисовать себя (потому что ее данные изменились!), Поэтому вызывается ее обработчик OnDrawCell, ...

Ну, я остановлюсь на этом.

Очевидно, это вызывает бесконечную последовательность перерисовок, которая заставит ваше приложение перерисовывать сетку.

Вы можете довольно легко увидеть это явление в действии. Просто создайте новое приложение VCL, поместите TStringGrid в основную форму и добавьте

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  StringGrid1.Cells[3, 3] := Random(100).ToString;
end;

. Вы увидите постоянно обновляемое случайное число в ячейке (3, 3).

Занятие рисованием сетки будет иметь множество последствий. Например, помимо обнаруженной вами аномалии окна сообщения, вы, вероятно, увидите, что ваш процесс максимально использует один «поток» ЦП (если у вас четырехъядерный HT-процессор, скажем, вы будете использовать один поток полностью, или 1/8 = 12,5% ЦП).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...