Close button intermittently doesn't close
Posted: Fri Feb 23, 2024 9:24 am
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.
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
While WindowEvent(): Wend 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.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?
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.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?
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
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
Code: Select all
SetGadgetState(#imgVideo, ImageID(*Param\CaptureImage))
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
You should never update GUI from another thread, only from the main thread, otherwise it can lead to weird behavior, memory corruption and crashes.coco2 wrote: Fri Feb 23, 2024 10:07 pm I have narrowed it down to this line:
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.Code: Select all
SetGadgetState(#imgVideo, ImageID(*Param\CaptureImage))
EDIT: I moved the line to the main loop and it fixed the problem. For some reason updating an image causes problems in threads.