SaveFileDialog crashes in PaintEvent

A simple project:
the window1 has a property: SaveFlag as boolean
the window1 has a canvas with the following paint event code
Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint
If SaveFlag = True Then

Var dlg As New SaveFileDialog
Var saveFile As FolderItem
dlg.InitialFolder = SpecialFolder.Documents
dlg.PromptText = "Prompt Text"
dlg.SuggestedFileName = "Suggested Filename"
dlg.Title = "Title Property"
// dlg.Filter = FileTypeGroup1.Text // defined as a file type in FileTypeGroup1 file type set
saveFile = dlg.ShowModal
If saveFile <> Nil Then
  // saveFile is the FolderItem of the file to save
Else
  // user canceled
End If

SaveFlag = False 

End If
End Sub

the windwo1 has a button:
Sub Action() Handles Action
SaveFlag=true
Canvas1.Invalidate(false)
End Sub

Xojo crashes at saveFile = dlg.ShowModal
I wonder if it is not possible to cal dlg.ShowModal from inside Paint event?

using Mojave, X2020 r2.1

https://www.dropbox.com/preview/Public/dlgCrash.xojo_binary_project?role=personal

I am not surprised it is crashing; doing this basicaly blocks the view from updating, which can lead to all kinds of weirdness.

You are supposed to do as little as possible during a paint event, not even calculations.

Move your saving code to anotger event or function.

I don’t mean to be rude and aplogize if it came out that way.

2 Likes

There are full of examples where a complicated methods are called from the Paint event. I think this is an special case. Xojo should not crash.

Looks like a variation of a bug I found this week: feedback://showreport?report_id=63654 . Showing a sheet in a paint event makes a very strange sheet.

caling a file dialog in the paint event is the wrong place.
create a method with g As Graphics Parameter
call this method in the Paint event
if you need the canvas picture use this new Method to paint into a picture.graphics.

1 Like

Do you mean something like:

    Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint
  If SaveFlag = True Then
    
    SaveThePict()
    
    SaveFlag = False 
  End If
End Sub

But this is the same, Xojo crashes.

I tried your example but can’t run it shows:

Probably I need something additional

Can you tell us why you are trying to save during the paint event?

2 Likes

No, he means don’t do it in the paint event. At all.

1 Like

The app shouldn’t crash. Even if you do something that isn’t a good idea.

@Enric_Herrera: my bad, you only need to comment out the code. I’ve added an updated example to the Feedback case.

because ther is the only place where I may have acces to the graphics

Assemble an image somewhere else.
Display the image in the paint event.
Save it to disc from some other code

1 Like

This is one of my main purposes, how to create a picture from a graphics.

Passing g as graphics create a picture this is the target.

OK.

Here is my idea.

  1. Move the code from the paint event into a new method (for the purposes of this example I’ll call it DrawMe). This method should have a parameter g As Graphics.

  2. In your current paint event call DrawMe(g).

  3. In your save method create a new picture and then do DrawMe(mypicturevar.Graphics). At this point you can then do whatever to save the picture.

2 Likes

The Paint event can fire n times. So SaveFileDialog will be fired the same amount of times.

  1. Create a New Picture,
  2. Draw what you want there,
  3. In Canvas Paint, draw that Picture (if Not Nil)
  4. In a PushButton (located outside of the Canvas), put the SaveFileDialog Code…
1 Like

you could create the new picture object with
any size. this obj then have a graphics property.
any method with graphics argument can paint there.

as example from button event

Sub Action() Handles Action
  Var pic As New Picture(256,64)
  
  DrawMe(pic.Graphics)
  
  Self.Backdrop = pic 'just a test to view it
  
End Sub

Public Sub DrawMe(g As Graphics)
 g.DrawingColor = Color.Red
 g.FillRoundRectangle 0,0,g.Width,g.Height,32,32
End Sub

in the paint event of your canvas you can call the same method DrawMe. keving explained it.

paint event draw something
save dialog open a dialog, draw something, save the picture
this concurrence can use the same method.

Thanks all, but I want to create a picture like the graphics received, no draw things in a new graphics of a new created picture.

Imagine a canvas where the user may draw something. Passing this graphics from de Paint event, create a picture.

The user does not draw something.
YOU do, based on what they tell you.

There is no ready made picture sent to you in the Paint event.
g is an empty page
You must draw on it in paint
if you want the image saved to disc, either draw the image to G and also draw it to a picture (to save),
OR
draw to the picture (for saving) , and then throw the picture at G using drawpicture.

We are all telling you the same thing.

G does not contain your picture.
The Canvas is not a sheet of paper that remembers where someone drew on it.

1 Like

is that possible? what happens if you resize the window, or minimizes or maximized the window?

i guess you think Canvas1.Invalidate(false) will not clear the background,
what you see in this Canvas1 is unfortunately more temporary.