Page 1 of 2

Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Tue Oct 04, 2016 4:58 pm
by 0CodErr
Есть исходник только на паскале
Spoiler:

Code: Select all

Unit test;

Interface

Type
  SIZE = Record height, width : Word End;

Const
 (* Window Style Constants *)
  WS_SKINNED_FIXED    =  $4000000;
  WS_SKINNED_SIZABLE  =  $3000000;
  WS_FIXED            =  $0000000;
  WS_SIZABLE          =  $2000000;
  WS_FILL_TRANSPARENT = $40000000;
  WS_FILL_GRADIENT    = $80000000;
  WS_COORD_CLIENT     = $20000000;
  WS_CAPTION          = $10000000;

 (* Event Constants *)
  REDRAW_EVENT = 1;
  KEY_EVENT    = 2;
  BUTTON_EVENT = 3;

 (* Color Constants *)
  COLOR_BLUE  = $000000FF;
  COLOR_RED   = $00FF0000;
  COLOR_GREEN = $0000FF00;
  COLOR_WHITE = $00FFFFFF;
  COLOR_BLACK = $00000000;

  sz_hello  = AnsiString('Test');

Var
  WindowLeft, WindowTop, WindowWidth, WindowHeight : Cardinal;
  Scr : SIZE;
  Motion : Cardinal;

Function  WaitEvent:        Cardinal; Forward;

Function  WaitEventByTime(time : Cardinal):
                            Cardinal;  StdCall; Forward;
                            
Function  GetKeyCode:       Cardinal; Forward;
Function  GetButtonNumber:  Cardinal; Forward;
Function  GetScreenSize:        SIZE; Forward;
Procedure RedrawStart;                Forward;
Procedure RedrawFinish;               Forward;
Procedure ThreadTerminate;            Forward;

Procedure SetWindowPos(left, top, right, bottom : INTEGER);
                                       StdCall; Forward;
                                      
Procedure DrawWindow(left, top, right, bottom : Cardinal; 
                     Caption :  PChar; BackColor, Style: Cardinal); 
                                       StdCall; Forward;

Procedure main;                  Forward;
Procedure On_Redraw;             Forward;
Procedure On_KeyPress;           Forward;
Procedure On_ButtonPress;        Forward;
Procedure CtlMove(N : Cardinal); Forward;

implementation
(* -------------------------------------------------------- *)
Procedure main; Begin
  Scr := GetScreenSize();

  WindowWidth  := Scr.width  Shr 2;
  WindowHeight := Scr.height Shr 2;
  WindowLeft   := (Scr.width  - WindowWidth)  Shr 1;
  WindowTop    := (Scr.height - WindowHeight) Shr 1;

  Motion := 1;
  
  On_Redraw;   
  While TRUE Do Begin
    CtlMove(10);
    Case WaitEventByTime(100) Of
    REDRAW_EVENT : On_Redraw;
    KEY_EVENT    : On_KeyPress;
    BUTTON_EVENT : On_ButtonPress;
    End;    
  End;
End;
(* -------------------------------------------------------- *)
Procedure CtlMove; Begin
    Case Motion Of
    1 : Begin               
          WindowLeft := WindowLeft - N; WindowTop := WindowTop - N;
          If      WindowLeft <= 0                         Then Motion := 2 
          Else If WindowTop  <= 0                         Then Motion := 4;      
        End;
    2 : Begin 
          WindowLeft := WindowLeft + N; WindowTop := WindowTop - N;
          If      WindowLeft >= Scr.Width - WindowWidth   Then Motion := 1
          Else If WindowTop  <= 0                         Then Motion := 3;        
        End;       
    3 : Begin 
          WindowLeft := WindowLeft + N; WindowTop := WindowTop + N;
          If      WindowLeft >= Scr.Width - WindowWidth   Then Motion := 4
          Else If WindowTop  >= Scr.Height - WindowHeight Then Motion := 2;
        End;
    4 : Begin 
          WindowLeft := WindowLeft - N; WindowTop := WindowTop + N;
          If      WindowLeft <= 0                         Then Motion := 3
          Else If WindowTop  >= Scr.Height - WindowHeight Then Motion := 1;
        End;
    End;
    SetWindowPos(WindowLeft, WindowTop, $FFFFFFFF, $FFFFFFFF);
End;
(* -------------------------------------------------------- *)
Procedure On_Redraw; Begin
 RedrawStart;
 DrawWindow(WindowLeft, WindowTop, WindowWidth, WindowHeight, 
            sz_hello, COLOR_WHITE, WS_SKINNED_FIXED + WS_COORD_CLIENT + WS_CAPTION);
 RedrawFinish;
End;
(* -------------------------------------------------------- *)
Procedure On_KeyPress; Begin
 GetKeyCode;
End;
(* -------------------------------------------------------- *)
Procedure On_ButtonPress; Begin
  Case  GetButtonNumber() Of
  1 : ThreadTerminate;
  End;
End;
(* -------------------------------------------------------- *)
Procedure RedrawStart; Asm
        push   ebx
        mov    eax, 12
        mov    ebx, 1
        int    64
        pop    ebx
End;
(* -------------------------------------------------------- *)
Procedure RedrawFinish; Asm
        push   ebx
        mov    eax, 12
        mov    ebx, 2
        int    64
        pop    ebx
End;
(* -------------------------------------------------------- *)
Procedure DrawWindow; Asm
        push   ebx
        push   edi
        xor    eax, eax
        mov    ebx, [WindowLeft]
        shl    ebx, 16
        add    ebx, [WindowWidth]
        mov    ecx, [WindowTop]
        shl    ecx, 16
        add    ecx, [WindowHeight]
        mov    edx, [Style]
        or     edx, [BackColor]
        mov    edi, [Caption]
        int    64
        pop    edi
        pop    ebx
End;
(* -------------------------------------------------------- *)
Function WaitEvent; Asm
        mov    eax, 10
        int    64
End;
(* -------------------------------------------------------- *)
Function WaitEventByTime; Asm
        push   ebx
        mov    eax, 23
        mov    ebx, [time]	
        int    64
        pop    ebx
End;    
(* -------------------------------------------------------- *)
Function GetKeyCode; Asm
        mov    eax, 2
        int    64
End;
(* -------------------------------------------------------- *)
Function GetButtonNumber; Asm
        mov    eax, 17
        int    64
        shr    eax, 8
End;
(* -------------------------------------------------------- *)
Procedure ThreadTerminate; Asm
        or     eax, -1
        int    64
End;
(* -------------------------------------------------------- *)
Function GetScreenSize; Asm
        push   ebx
        mov    eax, 61
        mov    ebx, 1
        int    64
        pop    ebx
End;
(* -------------------------------------------------------- *)
Procedure  SetWindowPos; Asm
        push   ebx
        push   esi
        mov    eax, 67
        mov    ebx, [left]
        mov    ecx, [top]
        mov    edx, [right]	
        mov    esi, [bottom]
        int    64
        pop    esi
        pop    ebx
End;
(* -------------------------------------------------------- *)
End.
Скомпилированный бинарник
test.kex (793 Bytes)
Downloaded 342 times
Вот так это выглядит
Spoiler:Image
Запускал в VirtualBox.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Tue Oct 04, 2016 9:27 pm
by akron1
Баг подтверждаю. Аналогичная программа на Обероне дала точно такой же результат. Если деактивировать окно щелчком по рабочему столу, то фон рабочего стола не перерисовывается. Запускал в VMware.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Mon Oct 10, 2016 2:33 pm
by Pathoswithin
revision #6585

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Thu Oct 13, 2016 11:12 am
by 0CodErr
Вот я заметил, что иногда состояние процесса с этим окном становится "suspended"
Spoiler:Image
Оно так и должно быть?

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Thu Oct 13, 2016 2:03 pm
by Pathoswithin
Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть. Проверь, на каком этапе это происходит.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Thu Oct 13, 2016 2:22 pm
by 0CodErr
Не поймешь, на каком. Когда полностью под другим окном "wait event", а когда начинает вылазить из-под него "suspended". Попробовал запустить несколько таких процессов(4) — у меня от этого VirtualBox сломался :lol: "Во время работы виртуальной машины произошла критическая ошибка. Выполнение виртуальной машины приостановлено."

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Thu Oct 13, 2016 6:12 pm
by Serge
Pathoswithin wrote:Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть.
Не должно такого быть. Оконная система в состояние процессов не должна вмешиваться.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 12:28 am
by //DG
Serge wrote:
Pathoswithin wrote:Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть.
Не должно такого быть. Оконная система в состояние процессов не должна вмешиваться.
А если процессу больше нечего делать, кроме обработки сообщений от окна, которых не будет, поко оно позади?

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 12:49 am
by Serge
//DG wrote:А если процессу больше нечего делать, кроме обработки сообщений от окна, которых не будет, поко оно позади?
Это зависит от маски событий, которые процесс хочет получать, и от того, какую функцию для этого процесс использует. В общем случае процесс будет спать, пока для него нет событий. Но это он сам сделает, не оконная система.
TASKDATA.state=1 появляется если процесс под отладкой, при блокировке сетевого сокета или при ожидании блокировки мьютекса/фьютекса.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 1:08 am
by //DG
Serge wrote:
//DG wrote:А если процессу больше нечего делать, кроме обработки сообщений от окна, которых не будет, поко оно позади?
Это зависит от маски событий, которые процесс хочет получать, и от того, какую функцию для этого процесс использует. В общем случае процесс будет спать, пока для него нет событий. Но это он сам сделает, не оконная система.
TASKDATA.state=1 появляется если процесс под отладкой, при блокировке сетевого сокета или при ожидании блокировки мьютекса/фьютекса.
А если мы ожидаем событий окна, а их нет, процесс не спит? Я имею в виду, ведь используется функция "получить сообщение", нет?

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 1:23 am
by 0CodErr
Тут ещё вот какой момент: если во время движения этого окна кликнуть правой кнопкой мыши по рабочему столу, то появится наше меню, и оно будет очень часто моргать\перерисовываться. А с чего бы ему, находясь на самом верху и будучи активным, перерисовываться?

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 3:42 am
by Serge
//DG wrote:А если мы ожидаем событий окна, а их нет, процесс не спит? Я имею в виду, ведь используется функция "получить сообщение", нет?
Спит, если это ф.10 или ф.23

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 4:10 am
by //DG
Serge wrote:
//DG wrote:А если мы ожидаем событий окна, а их нет, процесс не спит? Я имею в виду, ведь используется функция "получить сообщение", нет?
Спит, если это ф.10 или ф.23
Ну так - окно полностью закрыто, перерисовывать его не надо; никаких событий мыши/клавиатуры оно получать не будет, т.к. неактивно. Значит, оно законно будет спать в WaitMessage'е или как там оно называется. Ф.10.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 5:12 am
by Serge
Да будет спать. Но это процесс сам в такое состояние переходит. А вот почему вместо wait_state появляется suspended вопрос интересный.

Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Posted: Fri Oct 14, 2016 1:44 pm
by //DG
Serge wrote:Да будет спать. Но это процесс сам в такое состояние переходит.
Как, если он в системном вызове, в ядре? По идее, при пустой очереди его должны принудительно в спячку переводить, нет?