Kitet
Kitet

Reputation: 883

Self-destructing class containing a window

I've created a print preview class, PPREVIEW, containing a print preview window, which is supposed to popup over my app's main window, while disabling it. When user closes preview window, it is supposed to enable main window and destroy PPREVIEW object. I'd like to use it in the following way:

PPREVIEW *p=new PPREVIEW;
//next, preview window is created, user interaction begins
p->ShowPreview(<parameters>); //but this function returns
delete p;

Since ShowPreview does return, the above line would destroy object while window is still visible. If it was a modal dialog box, this would be possible, since DialogBox function doesn't return at that point. I thought i could put "delete this" somewhere upon destruction of the print preview window. Naturally WM_DESTROY comes to mind. But MSDN states at http://msdn.microsoft.com/en-us/library/windows/desktop/ms632620%28v=vs.85%29.aspx the following: "it can be assumed that during processing of WM_DESTROY child windows still exist", so there's still possibility some of them will refer to instance's variables (and they do, i was getting random access violation errors when i tried that, so i backed out).

Currently i've opted to:
- create some global variable,
- in WM_DESTROY of print preview window i put EnableWindow(MainWindow, TRUE) and set that global variable to FALSE.
- Then, upon main window's WM_ENABLE event i'm testing global variable for FALSE and deleting object.

But this is quite unelegant and requires that i program this behavior for every window that uses print preview, so i decided to pursue previous approach, which is: create, use, possibly self-delete. I need either:
- information when exactly could i use "delete this" in PPREVIEW window procedure, if this approach isn't unwise for some reason i am unaware of
- an idea how to make ShowPreview method to not return, mimicking DialogBox behavior.
- other suggestions that achieve my goal

Please assist.

Upvotes: 0

Views: 338

Answers (2)

bdonlan
bdonlan

Reputation: 231203

If you want ShowPreview to be modal, you'll need to run a sub-message-loop. You can find some examples here, including a reverse-engineered version of what DialogBox uses internally.

Alternately, you can simply have the WM_DESTROY of the preview window both re-enable the main window and delete your PPREVIEW * (in which case ShowPreview won't be modal, but it will be self-contained). You have to be careful here not to touch the PPREVIEW * (or, from within PPREVIEW's member functions, not to call any other members or access any member variables) after the DestroyWindow() call though - this in particular means you cannot access member variables in your message handler after the DefWindowProc() call

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 613013

  1. Your ShowPreview function should call ShowWindow() to show the preview window. It should also do whatever is needed to the main form, e.g. disabling it.
  2. When your preview window receives WM_CLOSE it should delete the C++ object that wraps it. Some part of this process also needs to call DestroyWindow() on the underlying window handle. The default handling of WM_CLOSE would do this, but perhaps you would want this in the C++ object's destructor.

Upvotes: 2

Related Questions