Close button intermittently doesn't close

Just starting out? Need help? Post your questions and find answers here.
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Close button intermittently doesn't close

Post 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.
User avatar
Kiffi
Addict
Addict
Posts: 1358
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: Close button intermittently doesn't close

Post by Kiffi »

My guess: The use of several WaitWindowEvents.

(But without code it is impossible to say exactly.)
Hygge
Axolotl
Enthusiast
Enthusiast
Posts: 449
Joined: Wed Dec 31, 2008 3:36 pm

Re: Close button intermittently doesn't close

Post by Axolotl »

Or look for WindowEvent() calls like this

Code: Select all

  While WindowEvent(): Wend 
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Fred
Administrator
Administrator
Posts: 16686
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Close button intermittently doesn't close

Post by Fred »

If you use such clear events loop, you should use BindEvent() for all your event handling
User avatar
skywalk
Addict
Addict
Posts: 3999
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Close button intermittently doesn't close

Post 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?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Demivec
Addict
Addict
Posts: 4091
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Close button intermittently doesn't close

Post 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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Close button intermittently doesn't close

Post 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
Egypt my love
User avatar
skywalk
Addict
Addict
Posts: 3999
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Close button intermittently doesn't close

Post 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?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
mk-soft
Always Here
Always Here
Posts: 5406
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Close button intermittently doesn't close

Post 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.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Close button intermittently doesn't close

Post 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      
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Close button intermittently doesn't close

Post 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
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Close button intermittently doesn't close

Post 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.
User avatar
idle
Always Here
Always Here
Posts: 5096
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Close button intermittently doesn't close

Post 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
coco2
Enthusiast
Enthusiast
Posts: 368
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Close button intermittently doesn't close

Post by coco2 »

Thanks it works good :)
tored
User
User
Posts: 61
Joined: Wed Feb 16, 2022 12:47 pm
Location: Sweden

Re: Close button intermittently doesn't close

Post 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
Post Reply