Page 1 of 1

Windows update messages

Posted: Wed Feb 06, 2013 11:12 am
by Michael Vogel
I have transfered a large project from 4.x to 5.1 now, which did not make real problems - thanks for this to Fred for his amazing work.

But today I saw, that a complex window with multiple bitmaps and list icon gadgets do not show all buttons on certain conditions. I tried to simulate the situation with a short code and here is the result:

Code: Select all

Enumeration
	#Window_0
	#Window_1
	#Button_0
	#Button_8
	#ListIcon_0
EndEnumeration

Procedure Redraw()
	
	SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#False,0)

	DisableWindow(#Window_0,1)
	HideWindow(#Window_1,0)
	SetActiveWindow(#Window_1)

	ClearGadgetItems(#ListIcon_0)

	For i=0 To 99
		AddGadgetItem(#ListIcon_0,-1,Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999)))
	Next i
	
	SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#True,#True)
	
	RedrawWindow_(WindowID(#Window_1),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE)

EndProcedure


OpenWindow(#Window_0, 0, 0, 380, 110, "", #PB_Window_SystemMenu)
ButtonGadget(#Button_0, 132, 34, 100, 25, "A")
AddKeyboardShortcut(Window_0,#PB_Shortcut_A,#Button_0)
AddKeyboardShortcut(Window_0,#PB_Shortcut_A|#PB_Shortcut_Shift,#Button_0)


Global Button_0, Button_0, Button_1, Button_2, Button_3, Button_4, Button_5, Button_6, Button_7, Button_8, ListIcon_0

OpenWindow(#Window_1, 0, 0, 600, 400, "", #PB_Window_SystemMenu|#PB_Window_Invisible)
Button_0 = ButtonGadget(#PB_Any, 132, 34, 100, 25, "")
Button_0 = ButtonGadget(#PB_Any, 30, 360, 50, 30, "")
Button_1 = ButtonGadget(#PB_Any, 80, 360, 40, 30, "")
Button_2 = ButtonGadget(#PB_Any, 120, 360, 40, 30, "")
Button_3 = ButtonGadget(#PB_Any, 160, 360, 40, 30, "")
Button_4 = ButtonGadget(#PB_Any, 200, 360, 40, 30, "")
ButtonImageGadget(#PB_Any, 240, 360, 40, 30,LoadIcon_(0,#IDI_EXCLAMATION))
ButtonImageGadget(#PB_Any, 290, 360, 40, 30,LoadIcon_(0,#IDI_WINLOGO))
ButtonImageGadget(#PB_Any,330, 360, 40, 30,LoadIcon_(0,#IDI_APPLICATION))
ButtonGadget(#Button_8, 380, 360, 40, 30, "X")
ListIconGadget(#ListIcon_0, 20, 20, 490, 344, "Column 1", 100)
AddGadgetColumn(#ListIcon_0, 1, "2", 100)
AddGadgetColumn(#ListIcon_0, 2, "3", 100)
AddGadgetColumn(#ListIcon_0, 3, "4", 100)
AddKeyboardShortcut(#Window_1,#PB_Shortcut_X,#Button_8)
AddKeyboardShortcut(#Window_1,#PB_Shortcut_X|#PB_Shortcut_Shift,#Button_8)
AddKeyboardShortcut(#Window_1,#PB_Shortcut_Escape,#Button_8)


Repeat
	event=WaitWindowEvent()
	Select event
	Case #PB_Event_CloseWindow
		End

	Case #PB_Event_Menu,#PB_Event_Gadget
		Select EventGadget()
		Case #Button_0
			Debug "ok"
			Redraw()
		Case #Button_8
			HideWindow(#Window_1,1)
			DisableWindow(#Window_0,0)
			SetActiveWindow(#Window_0)
		EndSelect
	EndSelect

ForEver
The code above is not an elegant one and the SendMessage and RedrawWindow calls seem to be useless (or even the reason for the issue), but in my project they do a fine job (most of the time) to get quicker screen updates.

So where's the problem? Not so easy to see, when you press 'A' to open the second window and press 'X' to close it, you won't see an issue, even if you do this multiple time. But when you press and hold the shift key while pressing 'A' you should get the second window without the imagebuttons. This effect may be seen already when opening the window the first time or after opening/closing the window multiple times (shift+A/shift+X).

Does anyone know, why the shift key influences the redraw mechanism of the window? Can I get rid of the problem without eliminating the RedrawWindows call?

Re: Windows update messages

Posted: Wed Feb 06, 2013 11:58 am
by Fangbeast
Don't know if it's the same problem or not but since running 5.1x 64 bit, windows randomly don't show buttonimagegadget images when opened.

At first I thought that it was my balloon tooltips that did it so I turned them off and it still happened.

The images return as you pass your mouse over them????

I tried my same program (RecipeMuncher) in the 32 bit version of PB 4.1 and I didn't have that problem. Have not tried the 32 bit version of 5.1 with it.

Re: Windows update messages

Posted: Wed Feb 06, 2013 12:09 pm
by Kurzer
Hmm, no problem here (Win XP 32 bit, SP3, PB 5.10b6).
I always see the 3 Imagebuttons.

But did you noticed, that yout Listview overlap the buttons at the bottom of the second window?
Maybe this cause the wired behaivour?

Image

Re: Windows update messages

Posted: Wed Feb 06, 2013 12:26 pm
by Michael Vogel
The window will be updated when:
- the debug window is open
- another window will be activated
- the mouse or any other window will force the redraw
- the shift key will not be used

The overlapping has been done by accident and doesn't influence the bahaviour. I have seen the effect on several PC's for now, XP and Windows 7, but it must not be seen each time the code is started. Sometimes I thought, I had solved the problem, because it worked for three or four times. One 'Compile and Run' later, the issue was back...

Re: Windows update messages

Posted: Wed Feb 06, 2013 8:15 pm
by idle
have tried to use a timeout in waitwindowevent ?
or set a windowcallback sounds like it's not processing all the events

Re: Windows update messages

Posted: Wed Feb 06, 2013 9:03 pm
by RASHAD
Hi Michael
Try the next

I think it is a matter of logic
1- Stop refreshing
2- Fill the ListIcon
3- Refresh The ListIcon again
Then show or hide as you like
Or vice versa

Code: Select all

Enumeration
   #Window_0
   #Window_1
   #Button_0
   #Button_8
   #ListIcon_0
EndEnumeration

Procedure Redraw()
   
   SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#False,0)
   ClearGadgetItems(#ListIcon_0)

   For i=0 To 99
      AddGadgetItem(#ListIcon_0,-1,Str(Random(999999999))+ #LF$+Str(Random(999999999))+#LF$+Str(Random(999999999)) +#LF$+Str(Random(999999999)))
   Next i
  SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#True,#True)

   DisableWindow(#Window_0,1)
   HideWindow(#Window_1,0)
   SetActiveWindow(#Window_1)
   ;RedrawWindow_(WindowID(#Window_1),#Null,#Null,#RDW_INVALIDATE| #RDW_ERASE)

EndProcedure


OpenWindow(#Window_0, 0, 0, 380, 110, "", #PB_Window_SystemMenu)
ButtonGadget(#Button_0, 132, 34, 100, 25, "A")
AddKeyboardShortcut(Window_0,#PB_Shortcut_A,#Button_0)
AddKeyboardShortcut(Window_0,#PB_Shortcut_A|#PB_Shortcut_Shift, #Button_0)


Global Button_0, Button_0, Button_1, Button_2, Button_3, Button_4, Button_5, Button_6, Button_7, Button_8, ListIcon_0

OpenWindow(#Window_1, 0, 0, 600, 400, "", #PB_Window_SystemMenu|#PB_Window_Invisible)
;Button_0 = ButtonGadget(#PB_Any, 132, 34, 100, 25, "")
Button_0 = ButtonGadget(#PB_Any, 30, 360, 50, 30, "")
Button_1 = ButtonGadget(#PB_Any, 80, 360, 40, 30, "")
Button_2 = ButtonGadget(#PB_Any, 120, 360, 40, 30, "")
Button_3 = ButtonGadget(#PB_Any, 160, 360, 40, 30, "")
Button_4 = ButtonGadget(#PB_Any, 200, 360, 40, 30, "")
ListIconGadget(#ListIcon_0, 20, 20, 490, 340, "Column 1", 100)
AddGadgetColumn(#ListIcon_0, 1, "2", 100)
AddGadgetColumn(#ListIcon_0, 2, "3", 100)
AddGadgetColumn(#ListIcon_0, 3, "4", 100)
ButtonImageGadget(#PB_Any, 240, 360, 40, 30,LoadIcon_(0,#IDI_EXCLAMATION))
ButtonImageGadget(#PB_Any, 290, 360, 40, 30,LoadIcon_(0,#IDI_WINLOGO))
ButtonImageGadget(#PB_Any,330, 360, 40, 30,LoadIcon_(0,#IDI_APPLICATION))
ButtonGadget(#Button_8, 380, 360, 40, 30, "X")
AddKeyboardShortcut(#Window_1,#PB_Shortcut_X,#Button_8)
AddKeyboardShortcut(#Window_1,#PB_Shortcut_X|#PB_Shortcut_Shift, #Button_8)
AddKeyboardShortcut(#Window_1,#PB_Shortcut_Escape,#Button_8)


Repeat
   event=WaitWindowEvent()
   Select event
   Case #PB_Event_CloseWindow
      End

   Case #PB_Event_Menu,#PB_Event_Gadget
      Select EventGadget()
      Case #Button_0
         Debug "ok"
         Redraw()
      Case #Button_8
         HideWindow(#Window_1,1)
         DisableWindow(#Window_0,0)
         SetActiveWindow(#Window_0)
      EndSelect
   EndSelect

ForEver

OR :

Code: Select all

Procedure Redraw()
   DisableWindow(#Window_0,1)
   HideWindow(#Window_1,0)
   ;SetActiveWindow(#Window_1)
   SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#False,0) 
   ClearGadgetItems(#ListIcon_0)
   For i=0 To 99
      AddGadgetItem(#ListIcon_0,-1,Str(Random(999999999))+ #LF$+Str(Random(999999999))+#LF$+Str(Random(999999999)) +#LF$+Str(Random(999999999)))
   Next i   
   SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#True,#True)
EndProcedure


Re: Windows update messages

Posted: Thu Feb 07, 2013 1:14 pm
by Michael Vogel
Thanks Idle and Rashad,

logic seems really to be a problem for me, otherwise I wouldn't have mixed some lines in my example – in the original source code, I have disabled redrawing for the complete window, because several tables and images must be refreshed, sometimes also some button states. Sorry for that, I was happy to simulate the problem and forgot to check all lines, now I have updated the procedure Redraw() to simulate the "original" behaviour.

But even with your tips I am not able to find a logical answer for one of these two questions:

Why the problem is only seen, when holding down the shift key?
Why disabling/enabling the redraw works for a single gadget (all=0), but not for the full window (all=1)?

Code: Select all

Procedure Redraw()

	#all=1

	If #all
		SendMessage_(WindowID(#Window_1),#WM_SETREDRAW,#False,0)
	Else
		SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#False,0)
	EndIf

	DisableWindow(#Window_0,1)
	HideWindow(#Window_1,0)
	SetActiveWindow(#Window_1)

	ClearGadgetItems(#ListIcon_0)

	For i=0 To 99
		AddGadgetItem(#ListIcon_0,-1,Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999)))
	Next i

	SetGadgetState(#ListIcon_0,Random(20))
	SetActiveGadget(#ListIcon_0)

	If #all
		SendMessage_(WindowID(#Window_1),#WM_SETREDRAW,#True,#True)
		RedrawWindow_(WindowID(#Window_1),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE|#RDW_ALLCHILDREN)
	Else
		SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#True,#True)
		RedrawWindow_(GadgetID(#ListIcon_0),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE)
	EndIf

EndProcedure

Re: Windows update messages

Posted: Thu Feb 07, 2013 4:16 pm
by RASHAD
Hi MV
Your problem is with using #RDW_ERASE with
RedrawWindow_(GadgetID(#ListIcon_0),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE)

It is a small price for using API with PB :)

Re: Windows update messages

Posted: Thu Feb 07, 2013 6:41 pm
by SFSxOI
Michael Vogel wrote:

Code: Select all

Procedure Redraw()

	#all=1

	If #all
		SendMessage_(WindowID(#Window_1),#WM_SETREDRAW,#False,0)
	Else
		SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#False,0)
	EndIf

	DisableWindow(#Window_0,1)
	HideWindow(#Window_1,0)
	SetActiveWindow(#Window_1)

	ClearGadgetItems(#ListIcon_0)

	For i=0 To 99
		AddGadgetItem(#ListIcon_0,-1,Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999))+#LF$+Str(Random(999999999)))
	Next i

	SetGadgetState(#ListIcon_0,Random(20))
	SetActiveGadget(#ListIcon_0)

	If #all
		SendMessage_(WindowID(#Window_1),#WM_SETREDRAW,#True,#True)
		RedrawWindow_(WindowID(#Window_1),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE|#RDW_ALLCHILDREN)
	Else
		SendMessage_(GadgetID(#ListIcon_0),#WM_SETREDRAW,#True,#True)
		RedrawWindow_(GadgetID(#ListIcon_0),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE)
	EndIf

EndProcedure

Code: Select all

SetGadgetState(#ListIcon_0,Random(20))
?

Don't mean to interject or go off topic for this, but I have a question.

According to the help, SetGadgetState(#Gadget, State) can only have for the State parameter the values of (depending on the gadget):
#PB_Checkbox_Checked
#PB_Checkbox_Unchecked
#PB_Checkbox_Inbetween
#PB_MDI_Cascade
#PB_MDI_TileVertically
#PB_MDI_TileHorizontally
#PB_MDI_Next
#PB_MDI_Previous
#PB_MDI_Arrange
So how does it work with 'SetGadgetState(#ListIcon_0,Random(20))' when Random(20) can produce a value outside that expected by the function doesn't it? (or am I not seeing the full picture here for its actual application?)

Re: Windows update messages

Posted: Fri Feb 08, 2013 12:19 pm
by Puffolino
SFSxOI wrote:

Code: Select all

SetGadgetState(#ListIcon_0,Random(20))
So how does it work...
For ListIcons, the parameter specifies the position of the selector, -1 means no selection will be seen.

Re: Windows update messages

Posted: Fri Feb 08, 2013 8:28 pm
by Michael Vogel
RASHAD wrote:Hi MV
Your problem is with using #RDW_ERASE with
RedrawWindow_(GadgetID(#ListIcon_0),#Null,#Null,#RDW_INVALIDATE|#RDW_ERASE)

It is a small price for using API with PB :)
You´re right, but the different results are confusing me completely :?
#RDW_INVALIDATE seems to be fine for the buttons (and all other gadgets), but there's no window background around it
INVAL... | #RDW_Frame: window background is not drawn
INVAL... | #RDW_NoFrame: window background is not drawn, sometimes
INVAL... | #RDW_Erase: everything looks fine, but ImageButtons are missing as soon, as shift has been pressed
I also tried to play around with the flags InternalPaint, UpdateNow, EraseNow etc.