Page 1 of 2

Flickering when MDI child move [Resolved]

Posted: Tue Oct 31, 2017 3:45 pm
by Kwai chang caine
Hello at all :D

I try to move a child window always at the same distance from the bottom of the windows
But i have a flickering, the chlid windows appears two times, and i don't understand why :shock:

I can't use #PB_MDI_AutoSize when i create the MDI, it's the reason why i must resize the MDI in the callback :wink:

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

Global IdChild

Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
 
 If uMsg = #WM_SIZE And hWnd = WindowID(#FenetrePrincipale)
 
  ResizeGadget(#MdiGadget, 0, 0, WindowWidth(#FenetrePrincipale), WindowHeight(#FenetrePrincipale))
  ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - (WindowY(IdChild, #PB_Window_InnerCoordinate) + 19), #PB_Ignore, #PB_Ignore)

 EndIf 

 ProcedureReturn #PB_ProcessPureBasicEvents 

EndProcedure 


OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

ShowWindow_(WindowID(IdChild), #SW_SHOWMINIMIZED)
ResizeWindow(IdChild, 100, 100, #PB_Ignore, #PB_Ignore)

UseGadgetList(WindowID(#FenetrePrincipale))
SetWindowCallback(@WinCallback()) 

Repeat
 Event = WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
Have a good day

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 4:31 pm
by infratec
The problem is, that WindowY() returns toggling values. Looks like a bug.
I'll try something.

Bernd

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 4:37 pm
by Julian
I came to the same conclusion, here's a working version, I hope its what you wanted:

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

;MACROS from http://forums.purebasic.com/english/viewtopic.php?p=439919&sid=8e97d5aba0e4678f3e64140ee1846d83#p439919
Macro LOWORD(dwValue) : dwValue & $FFFF : EndMacro;
Macro HIWORD(dwValue) : dwValue >> 16 : EndMacro;

Macro MAKELPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;
Macro MAKEWPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;

Global IdChild

Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
 
 If uMsg = #WM_SIZE And hWnd = WindowID(#FenetrePrincipale)
   
   w = LOWORD(lparam)
   h = HIWORD(lparam)
   
   ResizeGadget(#MdiGadget, 0, 0, WindowWidth(#FenetrePrincipale), WindowHeight(#FenetrePrincipale))
   
   ;ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - (WindowY(IdChild, #PB_Window_InnerCoordinate) + 19), #PB_Ignore, #PB_Ignore)
   Debug "WindowY(IdChild, #PB_Window_InnerCoordinate)=" + WindowY(IdChild, #PB_Window_InnerCoordinate)
   ResizeWindow(IdChild, #PB_Ignore, h - WindowHeight(IdChild) - 19, #PB_Ignore, #PB_Ignore)
  
   ProcedureReturn 0
 EndIf 

 ProcedureReturn #PB_ProcessPureBasicEvents 

EndProcedure 


OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

ShowWindow_(WindowID(IdChild), #SW_SHOWMINIMIZED)
ResizeWindow(IdChild, 100, 100, #PB_Ignore, #PB_Ignore)

UseGadgetList(WindowID(#FenetrePrincipale))
SetWindowCallback(@WinCallback()) 

Repeat
 Event = WaitWindowEvent()
Until Event=#PB_Event_CloseWindow

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 4:53 pm
by Kwai chang caine
Thanks at you two for your quick answer 8)

@JULIAN
I have try your code and unfortunaltely, the child window, is not at the same distance of the bottom of the window when i resize #FenetrePrincipale, it sticked at the bottom :|
Me i search to have always the same distance between the bottom of the child window and the bottom of the GadgetMdi :wink:

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 5:11 pm
by infratec
My dirty dirty hack:

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

Global IdChild

Structure WindowHelpStructure
  x.i
  y.i
  bottom.i
EndStructure


Define ChildWindow.WindowHelpStructure

OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
Auto = 2
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

SetWindowState(IdChild, #PB_Window_Minimize)

ResizeWindow(IdChild, 100, 100, #PB_Ignore, #PB_Ignore)
ChildWindow\x = 100
ChildWindow\y = 100
ChildWindow\bottom = GadgetHeight(#MdiGadget) - 100 - 19

UseGadgetList(WindowID(#FenetrePrincipale))
;SetWindowCallback(@WinCallback())

Repeat
  Event = WaitWindowEvent()
  
  Select EventWindow()
    Case #FenetrePrincipale
      
      Select Event
        
        Case #PB_Event_SizeWindow
            ResizeGadget(#MdiGadget, 0, 0, WindowWidth(#FenetrePrincipale), WindowHeight(#FenetrePrincipale))
            Debug  "ResizeWindowMain"
            ;ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - ChildWindow\y, #PB_Ignore, #PB_Ignore)
            PostEvent(#PB_Event_SizeWindow, IdChild, 0)
            
      EndSelect
      
    Case IdChild
      
      Select Event
        Case #PB_Event_SizeWindow
          Debug "ChildResize " + Str(ChildWindow\y)
          Auto + 1
          ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - ChildWindow\bottom, #PB_Ignore, #PB_Ignore)
          
        Case #PB_Event_MoveWindow
          If Auto = 0
          Debug "ChildMove"
           ChildWindow\x = WindowX(IdChild, #PB_Window_InnerCoordinate)
           ChildWindow\y = WindowY(IdChild, #PB_Window_InnerCoordinate) - WindowY(#FenetrePrincipale, #PB_Window_InnerCoordinate)
           ChildWindow\bottom = GadgetHeight(#MdiGadget) - ChildWindow\y + 19
           Debug ChildWindow\y
           Debug ChildWindow\bottom
           
         Else
           Auto - 1
         EndIf

          
      EndSelect
      
  EndSelect
  
Until Event=#PB_Event_CloseWindow
Bernd

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 5:21 pm
by Kwai chang caine
Thanks a lot INFRATEC it's exactely this effect i search to have 8)
But here, the child window follow the MDI, only when i finish to resizing, not in the same time, is it normal ? :shock:

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 6:24 pm
by Julian
Sorry, I didnt understand what you wanted, here you go.

You can trim it down to size, there's a lot of debug/testing in there. The problem is that you need to remember the old position as you dont know how far to keep it away from the new size of the window.

The +6 is probably due to border size, you can find

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

;MACROS from http://forums.purebasic.com/english/viewtopic.php?p=439919&sid=8e97d5aba0e4678f3e64140ee1846d83#p439919
Macro LOWORD(dwValue) : dwValue & $FFFF : EndMacro;
Macro HIWORD(dwValue) : dwValue >> 16 : EndMacro;

Macro MAKELPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;
Macro MAKEWPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;

Global IdChild
Global Old_ParentWindowRect.RECT, Old_ParentClientRect.RECT
Global Old_ChildWindowRect.RECT, Old_ChildClientRect.RECT

Procedure CalcDiff(*new.RECT, *old.RECT, *out.RECT)
  *out\left = *new\left - *old\left
  *out\right = *new\right - *old\right
  *out\top = *new\top - *old\top
  *out\bottom = *new\bottom - *old\bottom
EndProcedure


Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  
  If uMsg = #WM_SIZING And hWnd = WindowID(#FenetrePrincipale)

   GetWindowRect_(WindowID(#FenetrePrincipale), Old_ParentWindowRect)
   GetClientRect_(WindowID(#FenetrePrincipale), Old_ParentClientRect)
   ;Debug "Old_ParentWindowRect l=" + Old_ParentWindowRect\left + " t=" + Old_ParentWindowRect\top + " r=" + Old_ParentWindowRect\right + " b=" + Old_ParentWindowRect\bottom
   ;Debug "Old_ParentClientRect l=" + Old_ParentClientRect\left + " t=" + Old_ParentClientRect\top + " h=" + Old_ParentClientRect\right + " h=" + Old_ParentClientRect\bottom
   
   GetWindowRect_(WindowID(IdChild), Old_ChildWindowRect)
   GetClientRect_(WindowID(IdChild), Old_ChildClientRect)
   ;Debug "ChildWindowRect l=" + Old_ChildWindowRect\left + " t=" + Old_ChildWindowRect\top + " r=" + Old_ChildWindowRect\right + " b=" + Old_ChildWindowRect\bottom
   ;Debug "ChildClientRect l=" + Old_ChildClientRect\left + " t=" + Old_ChildClientRect\top + " w=" + Old_ChildClientRect\right + " h=" + Old_ChildClientRect\bottom
  EndIf
  

 If uMsg = #WM_SIZE And hWnd = WindowID(#FenetrePrincipale)
   
   w = LOWORD(lparam)
   h = HIWORD(lparam)
   
   WindowRect.RECT
;     
;    GetWindowRect_(WindowID(IdChild), WindowRect)
;    Debug "l=" + WindowRect\left + " t=" + WindowRect\top + " r=" + WindowRect\right + " b=" + WindowRect\bottom
;    GetClientRect_(WindowID(IdChild), WindowRect)
;    Debug "l=" + WindowRect\left + " t=" + WindowRect\top + " w=" + WindowRect\right + " h=" + WindowRect\bottom
;    
   
   
   ParentWindowRect.RECT
   ParentClientRect.RECT
   GetWindowRect_(WindowID(#FenetrePrincipale), ParentWindowRect)
   GetClientRect_(WindowID(#FenetrePrincipale), ParentClientRect)
   Debug "AFTER ParentWindowRect l=" + ParentWindowRect\left + " t=" + ParentWindowRect\top + " r=" + ParentWindowRect\right + " b=" + ParentWindowRect\bottom
   Debug "AFTER ParentClientRect l=" + ParentClientRect\left + " t=" + ParentClientRect\top + " h=" + ParentClientRect\right + " h=" + ParentClientRect\bottom
   
   ChildWindowRect.RECT
   ChildClientRect.RECT
   GetWindowRect_(WindowID(IdChild), ChildWindowRect)
   GetClientRect_(WindowID(IdChild), ChildClientRect)
   Debug "ChildWindowRect l=" + ChildWindowRect\left + " t=" + ChildWindowRect\top + " r=" + ChildWindowRect\right + " b=" + ChildWindowRect\bottom
   Debug "ChildClientRect l=" + ChildClientRect\left + " t=" + ChildClientRect\top + " w=" + ChildClientRect\right + " h=" + ChildClientRect\bottom
   
   ParentWindowMovement.RECT
   ParentClientMovement.RECT
   CalcDiff(ParentWindowRect, Old_ParentWindowRect, ParentWindowMovement)
   CalcDiff(ParentClientRect, Old_ParentClientRect, ParentClientMovement)
   Debug "ParentWindowMovement l=" + ParentWindowMovement\left + " t=" + ParentWindowMovement\top + " r=" + ParentWindowMovement\right + " b=" + ParentWindowMovement\bottom
   
   ChildWindowMovement.RECT
   ChildClientMovement.RECT
   CalcDiff(ChildWindowRect, Old_ChildWindowRect, ChildWindowMovement)
   CalcDiff(ChildClientRect, Old_ChildClientRect, ChildClientMovement)
   Debug "ChildWindowMovement l=" + ChildWindowMovement\left + " t=" + ChildWindowMovement\top + " r=" + ChildWindowMovement\right + " b=" + ChildWindowMovement\bottom
      
   ResizeGadget(#MdiGadget, 0, 0, WindowWidth(#FenetrePrincipale), WindowHeight(#FenetrePrincipale))
   
   ChildNewTop = ((ChildWindowRect\top - ParentWindowRect\top) + ParentWindowMovement\bottom) - ((ChildWindowRect\bottom - ChildWindowRect\top) - ChildClientRect\bottom) + 6
   ;FromTop = ChildWindowRect\top - ParentWindowRect\top
   Debug "ChildNewTop=" + ChildNewTop
   ;Debug "FromTop=" + FromTop
   
   ;ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - (WindowY(IdChild, #PB_Window_InnerCoordinate) + 19), #PB_Ignore, #PB_Ignore)
   ;Debug "WindowY(IdChild, #PB_Window_InnerCoordinate)=" + WindowY(IdChild, #PB_Window_InnerCoordinate)
   ResizeWindow(IdChild, #PB_Ignore, ChildNewTop, #PB_Ignore, #PB_Ignore)
  
   ProcedureReturn 0
 EndIf 

 ProcedureReturn #PB_ProcessPureBasicEvents 

EndProcedure 


OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

ShowWindow_(WindowID(IdChild), #SW_SHOWMINIMIZED)
ResizeWindow(IdChild, 100, 100, #PB_Ignore, #PB_Ignore)

UseGadgetList(WindowID(#FenetrePrincipale))
SetWindowCallback(@WinCallback()) 

Repeat
 Event = WaitWindowEvent()
Until Event=#PB_Event_CloseWindow

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 6:53 pm
by Kwai chang caine
Thanks again, but this time the child window disapear when i resize the window :|
Sorry, I didnt understand what you wanted, here you go.
A little drawing is better than too much talk :lol:

I open the window, for exampler the value of the distance between the bottom of child window "classeur1" and bottom of MDI is 10

Image

Now i resize the window, and i want the value of the distance between the bottom of child window "classeur1" and bottom of MDI continue to be 10
You see in my photo, the distance have changed it's not good, i want always the value of the beginning before, during, and after resize the main window
No more, no less...always 10

Image

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 7:38 pm
by infratec
But something with the -19 is wrong

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

Global IdChild

Structure WindowHelpStructure
  x.i
  y.i
  bottom.i
EndStructure

Global ChildWindow.WindowHelpStructure
Global Auto.i


Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  
  If uMsg = #WM_SIZE 
    Select hWnd
      Case WindowID(#FenetrePrincipale)
        ResizeGadget(#MdiGadget, 0, 0, WindowWidth(#FenetrePrincipale), WindowHeight(#FenetrePrincipale))
        Auto + 1
        ResizeWindow(IdChild, #PB_Ignore, GadgetHeight(#MdiGadget) - ChildWindow\bottom, #PB_Ignore, #PB_Ignore)
    EndSelect
  EndIf
  
  If uMsg = #WM_MOVE
    If hWnd = WindowID(IdChild)
      If Auto = 0
        ChildWindow\x = lParam & $FFFF
        ChildWindow\y = lParam >> 16
        ChildWindow\bottom = GadgetHeight(#MdiGadget) - ChildWindow\y - 19
      Else
        Auto - 1
      EndIf
    EndIf
  EndIf

 ProcedureReturn #PB_ProcessPureBasicEvents

EndProcedure 




OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

SetWindowState(IdChild, #PB_Window_Minimize)

ChildWindow\x = 100
ChildWindow\y = 100
ChildWindow\bottom = GadgetHeight(#MdiGadget) - ChildWindow\y - 19
ResizeWindow(IdChild, 100, GadgetHeight(#MdiGadget) - ChildWindow\bottom, #PB_Ignore, #PB_Ignore)



UseGadgetList(WindowID(#FenetrePrincipale))
SetWindowCallback(@WinCallback())

Repeat
  Event = WaitWindowEvent() 
Until Event=#PB_Event_CloseWindow
Bernd

Re: Flickering when MDI child move

Posted: Tue Oct 31, 2017 7:44 pm
by Kwai chang caine
Yeeeeeaaaaaahhh !!!

That works very well, and it's exactely the effect i want
It's a very hard code for just do this simple effect :shock:
Never i can found that alone :oops:

One thousand of thanks INFRATEC 8)

I want also thanks JULIAN, for all the time he have spent for me :oops:

Have a very good day at you two 8)

Re: Flickering when MDI child move [Resolved]

Posted: Tue Oct 31, 2017 7:53 pm
by infratec
Corrected version:

Code: Select all

#FenetrePrincipale = 0
#FenetreFille = 1
#MdiGadget = 2

Global IdChild

Structure WindowHelpStructure
  x.i
  y.i
  bottom.i
EndStructure

Global ChildWindow.WindowHelpStructure
Global Auto.i


Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  
  If uMsg = #WM_SIZE 
    Select hWnd
      Case WindowID(#FenetrePrincipale)
        ResizeGadget(#MdiGadget, 0, 0, lParam & $FFFF, lParam >> 16)
        Auto + 1
        ResizeWindow(IdChild, #PB_Ignore, (lParam >> 16) - ChildWindow\bottom, #PB_Ignore, #PB_Ignore)
    EndSelect
  EndIf
  
  If uMsg = #WM_MOVE
    If hWnd = WindowID(IdChild)
      If Auto = 0
        ChildWindow\x = lParam & $FFFF
        ChildWindow\y = lParam >> 16
        ;Debug Str(GadgetHeight(#MdiGadget)) + " " + Str(ChildWindow\y)
        ChildWindow\bottom = GadgetY(#MdiGadget) + GadgetHeight(#MdiGadget) - ChildWindow\y
      Else
        Auto - 1
      EndIf
      
      ;Debug ChildWindow\y
    EndIf
  EndIf

 ProcedureReturn #PB_ProcessPureBasicEvents

EndProcedure 




OpenWindow(#FenetrePrincipale, 0, 0, 600, 400, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
   
MDIGadget(#MdiGadget, 0, 0, 600, 400, 0, 0, #PB_MDI_NoScrollBars)
IdChild = AddGadgetItem(#MdiGadget, #PB_Any, "Fenêtre fille")

SetWindowState(IdChild, #PB_Window_Minimize)

ChildWindow\x = 100
ChildWindow\y = 100
;ChildWindow\bottom = GadgetHeight(#MdiGadget) - ChildWindow\y - 31
ChildWindow\bottom = GadgetY(#MdiGadget) + GadgetHeight(#MdiGadget) - ChildWindow\y
ResizeWindow(IdChild, 100, GadgetHeight(#MdiGadget) - ChildWindow\bottom, #PB_Ignore, #PB_Ignore)



UseGadgetList(WindowID(#FenetrePrincipale))
SetWindowCallback(@WinCallback())

Repeat
  Event = WaitWindowEvent() 
Until Event=#PB_Event_CloseWindow
Bernd

Re: Flickering when MDI child move [Resolved]

Posted: Tue Oct 31, 2017 7:58 pm
by Kwai chang caine
The last version worked, but if you say it's better...i say this one is better :mrgreen:
Again thanks MASTER for all your precious help since all this years 8)

Re: Flickering when MDI child move [Resolved]

Posted: Wed Nov 01, 2017 4:00 pm
by Julian
FYI the above two pieces of code cause incorrect movement in the window on Windows 10. Its to do with the different sizes of windows borders etc between editions of the Windows. If you're just running this on your OS then no worries, but if you want it to work elsewhere you will need to calculate the offset (+6 in my code and -+19 in the other two codes).

I was writing this in my post but I cut it off for some reason.

"The +6 is probably due to border size, you can find"

You can find out the border sizes using GetSystemMetrics

Re: Flickering when MDI child move [Resolved]

Posted: Wed Nov 01, 2017 6:45 pm
by Kwai chang caine
Ok thanks for your advice 8)

Yesterday, i have W7 X86 and the INFRATEC code works very well
Today, i have W10 X64 and the INFRATEC code works also good than with W7

For the moment only good news :wink:

Re: Flickering when MDI child move [Resolved]

Posted: Wed Nov 01, 2017 6:54 pm
by Julian
This is what I see, there is a jump when the window is open.

https://www.dropbox.com/s/yuiayhmk1d08q ... 3.mp4?dl=0