Page 1 of 2

Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 9:24 am
by coco2
Does anyone know why the close button on my app randomly doesn't close the application? Sometimes it takes a few clicks to close it.

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 10:28 am
by Kiffi
My guess: The use of several WaitWindowEvents.

(But without code it is impossible to say exactly.)

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 1:09 pm
by Axolotl
Or look for WindowEvent() calls like this

Code: Select all

  While WindowEvent(): Wend 

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 5:04 pm
by Fred
If you use such clear events loop, you should use BindEvent() for all your event handling

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 5:55 pm
by skywalk
Hi Fred,
Do you have a link or help page that explains event priorities?
If I use BindEvent(), PostEvent() along with the standard Event Loop,
which Procedure "sees" an event first?
Does BindEvent return to the Event Loop and clear the event it acted on?

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 6:43 pm
by Demivec
skywalk wrote: Fri Feb 23, 2024 5:55 pm Hi Fred,
Do you have a link or help page that explains event priorities?
If I use BindEvent(), PostEvent() along with the standard Event Loop,
which Procedure "sees" an event first?
Does BindEvent return to the Event Loop and clear the event it acted on?
From my understanding BindEvent() does not remove the event from the queue. It handles it and it remains the current event in the queue and will remain such until the next WindowEvent() or WaitWindowEvent() call. This means if you use BindEvent() and handle the event elsewhere in your event loop it will be handled more than once.

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 6:56 pm
by RASHAD
Quiting rules
#1 : Only one main loop
#2 : WaitWindowEvent() must have some delay time (1 ms for exam.)
#3 : The main loop must have #PB_Event_CloseWindow
#4 : If you have Repeat-Until,While-Wend ....etc make sure that it's not running into endless loop
#5 : If you have WindowEvent() make sure it ends quit well
#6 : If have Thread make sure that it ends quit well
#7 : If you are calling a Procedure make sure it ends as it should be

That is as I remember right now

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 7:03 pm
by skywalk
Yes, I have the exit strategy ok, but it is the double event processing that I sometimes observe in my apps?
I would think the BindEvent() should clear the event before returning to the main event loop?

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 7:34 pm
by mk-soft
skywalk wrote: Fri Feb 23, 2024 7:03 pm Yes, I have the exit strategy ok, but it is the double event processing that I sometimes observe in my apps?
I would think the BindEvent() should clear the event before returning to the main event loop?
The bound event procedures are called before the WaitWindowEvent function is exited. Several functions can also be bound to one event. Thus also the MainScope after WaitWindowEvent.

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 9:43 pm
by coco2
There is something wrong with my event handling because it all my gadgets don't respond to clicks at times. The loop is really simple and I don't have any event clearing.

My main loop looks like this:

Code: Select all

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Timer
      ...
    Case #PB_Event_Menu
      Select EventMenu()   
        ... 
      EndSelect
    Case #PB_Event_Gadget
      Select EventGadget()
        ...
      EndSelect
  EndSelect
Until Event = #PB_Event_CloseWindow      

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 9:57 pm
by coco2
I think I have found the cause, I have a video capture thread and when I disable it the problem goes away. Does anyone know why it would interefere with the events?

Code: Select all

Procedure ThreadCapture(*Param.Parameters)
  Protected.i x, y, Pixel, RGB
  *Param\Capturing = 1
  Repeat
    doCapture(*Param\CaptureDevice)
    If StartDrawing(ImageOutput(*Param\CaptureImage))   
      For y = 0 To *Param\CapParams\mHeight - 1
        For x = 0 To *Param\CapParams\mWidth - 1
          Pixel = PeekL(*Param\CapParams\mTargetBuf + (y**Param\CapParams\mWidth + x) * 4)
          RGB = RGB((Pixel >> 16) & $FF, (Pixel >> 8) & $FF, Pixel & $FF)
          Plot(x, y, RGB)
        Next
      Next
      StopDrawing()
      SetGadgetState(#imgVideo, ImageID(*Param\CaptureImage))
    EndIf 
  Until Not *Param\Capturing
EndProcedure

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 10:07 pm
by coco2
I have narrowed it down to this line:

Code: Select all

SetGadgetState(#imgVideo, ImageID(*Param\CaptureImage))
I'm not sure why that line interferes with events. I think what it does is it refreshes the image? I'm not actually sure, I copied the code from someone.

EDIT: I moved the line to the main loop and it fixed the problem. For some reason updating an image causes problems in threads.

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 10:23 pm
by idle
It would be better to post an event and swap the image.

If your on windows you could also try CopymemoryToImage if you want it a little faster.

Code: Select all

Procedure CopyImageToMemory(ImageNumber, Memory)
 
  Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
  
   
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 32
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure

Procedure CopyMemoryToImage(Memory, ImageNumber)
 
  Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
 
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 32
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure

Re: Close button intermittently doesn't close

Posted: Fri Feb 23, 2024 11:03 pm
by coco2
Thanks it works good :)

Re: Close button intermittently doesn't close

Posted: Sat Feb 24, 2024 12:07 pm
by tored
coco2 wrote: Fri Feb 23, 2024 10:07 pm I have narrowed it down to this line:

Code: Select all

SetGadgetState(#imgVideo, ImageID(*Param\CaptureImage))
I'm not sure why that line interferes with events. I think what it does is it refreshes the image? I'm not actually sure, I copied the code from someone.

EDIT: I moved the line to the main loop and it fixed the problem. For some reason updating an image causes problems in threads.
You should never update GUI from another thread, only from the main thread, otherwise it can lead to weird behavior, memory corruption and crashes.

You should use PostEvent to notify main thread from the worker thread that the processing is done and let the main thread update the GUI. The image data (pointer) can either be sent with the event or be global that is guarded with a mutex lock.

https://www.purebasic.com/documentation ... event.html