Board.KolibriOS.org
http://board.kolibrios.org/

Не перерисовывается фон, когда неактивное окно изменяет своё положение
http://board.kolibrios.org/viewtopic.php?f=36&t=3395
Page 1 of 2

Author:  0CodErr [ Tue Oct 04, 2016 4:58 pm ]
Post subject:  Не перерисовывается фон, когда неактивное окно изменяет своё положение

Есть исходник только на паскале
Spoiler: Show
Code:
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.
Скомпилированный бинарник
Attachment:
test.kex [793 Bytes]
Downloaded 100 times
Вот так это выглядит
Spoiler: Show
Image
Запускал в VirtualBox.

Author:  akron1 [ Tue Oct 04, 2016 9:27 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Баг подтверждаю. Аналогичная программа на Обероне дала точно такой же результат. Если деактивировать окно щелчком по рабочему столу, то фон рабочего стола не перерисовывается. Запускал в VMware.

Author:  Pathoswithin [ Mon Oct 10, 2016 2:33 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

revision #6585

Author:  0CodErr [ Thu Oct 13, 2016 11:12 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Вот я заметил, что иногда состояние процесса с этим окном становится "suspended"
Spoiler: Show
Image
Оно так и должно быть?

Author:  Pathoswithin [ Thu Oct 13, 2016 2:03 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть. Проверь, на каком этапе это происходит.

Author:  0CodErr [ Thu Oct 13, 2016 2:22 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

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

Author:  Serge [ Thu Oct 13, 2016 6:12 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Pathoswithin wrote:
Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть.
Не должно такого быть. Оконная система в состояние процессов не должна вмешиваться.

Author:  //DG [ Fri Oct 14, 2016 12:28 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Serge wrote:
Pathoswithin wrote:
Я тоже заметил, процесс приостанавливается когда его окно полностью располагается под активным окном. Может так и должно быть.
Не должно такого быть. Оконная система в состояние процессов не должна вмешиваться.

А если процессу больше нечего делать, кроме обработки сообщений от окна, которых не будет, поко оно позади?

Author:  Serge [ Fri Oct 14, 2016 12:49 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

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

Author:  //DG [ Fri Oct 14, 2016 1:08 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

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


А если мы ожидаем событий окна, а их нет, процесс не спит? Я имею в виду, ведь используется функция "получить сообщение", нет?

Author:  0CodErr [ Fri Oct 14, 2016 1:23 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Тут ещё вот какой момент: если во время движения этого окна кликнуть правой кнопкой мыши по рабочему столу, то появится наше меню, и оно будет очень часто моргать\перерисовываться. А с чего бы ему, находясь на самом верху и будучи активным, перерисовываться?

Author:  Serge [ Fri Oct 14, 2016 3:42 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

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

Author:  //DG [ Fri Oct 14, 2016 4:10 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

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

Ну так - окно полностью закрыто, перерисовывать его не надо; никаких событий мыши/клавиатуры оно получать не будет, т.к. неактивно. Значит, оно законно будет спать в WaitMessage'е или как там оно называется. Ф.10.

Author:  Serge [ Fri Oct 14, 2016 5:12 am ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Да будет спать. Но это процесс сам в такое состояние переходит. А вот почему вместо wait_state появляется suspended вопрос интересный.

Author:  //DG [ Fri Oct 14, 2016 1:44 pm ]
Post subject:  Re: Не перерисовывается фон, когда неактивное окно изменяет своё положение

Serge wrote:
Да будет спать. Но это процесс сам в такое состояние переходит.

Как, если он в системном вызове, в ядре? По идее, при пустой очереди его должны принудительно в спячку переводить, нет?

Page 1 of 2 All times are UTC+03:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/