Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

StandardShellWindow QueryClose behavior - 2.7a

25 views
Skip to first unread message

Jamal Assaf

unread,
Jul 23, 2004, 8:40:48 PM7/23/04
to
Could anyone tell me why the QueryClose( ) of DataWindows are called before
I the following StandardShellWindow QueryClose( ) is called, resulting in
the closing of the DataWindows when the X or Alt-F4 are used?

What I expected was that if the application X icon is clicked, the prompt to
quit will be displayed first, then if the user decides to quit, then the
QueryClose of every DataWindow is called, but in this it's the reverse.

METHOD QueryClose(oEvent) CLASS StandardShellWindow
LOCAL oTB AS textbox
LOCAL lAllowClose := FALSE AS LOGIC

// lAllowClose := SUPER:QueryClose(oEvent) // uncomming this line does
not make a difference.
oTB := TextBox{SELF, "My Application", "Do you really want to quit
program?"}
oTB:Type := BOXICONQUESTIONMARK + BUTTONYESNO
IF (oTB:Show() = BOXREPLYYES)
lAllowClose := TRUE // Quit application.

ELSE
lAllowClose := FALSE
ENDIF
RETURN lAllowClose

Am I missing something? How could I overcome the problem?

VO 2.7a, XP Pro
Jamal


Chris Pyrgas

unread,
Jul 26, 2004, 1:20:29 PM7/26/04
to

Hi Jamal,

> Could anyone tell me why the QueryClose( ) of DataWindows are called
before
> I the following StandardShellWindow QueryClose( ) is called, resulting in
> the closing of the DataWindows when the X or Alt-F4 are used?

are you sure that datawindows are closed even if you chose not to exit? not
happening here..

anyway indeed the datawindows' queryclose() are called before the shell's
i'm not sure but it seems by reading the sdk that it was done on purpose
a way to reverse it :

METHOD Dispatch(oEvent) CLASS MyShellWindow
DO CASE
CASE oEvent:Message==WM_CLOSE
IF SELF:QueryClose()
IF GetWindow(SELF:hWndClient,GW_CHILD) == 0
SELF:__Close(oEvent)
ELSE
IF EnumChildWindows(SELF:hWndClient, @__WCQueryCloseEnumFunc(),
0)
SELF:__Close(oEvent)
END IF
ENDIF
END IF
RETURN 0L
END CASE
RETURN SUPER:Dispatch(oEvent)

this is mainly copy&paste from the sdk, hope it doesn't break something else

hth,

Chris

Jamal Assaf

unread,
Jul 26, 2004, 2:55:48 PM7/26/04
to
Hi Chris,

May be it's the way I am trying to implement the closing of child
DataWindows that are logically owned by the parent via an extra parameter,
which is saved in an aChildWin array. The DataWindows are themselves truly
owned by the StandardShellWindow. Each DataWindow has its own QueryClose( )
method which will close child windows first and prompt user to save any
changes if made. Of course user may decide not to close the window!

I open the datawindow like this:

oCustWindow := CustWindow{AppObject():oAppWindow, NIL,
SELF:oDCbBrowser1:Server, NIL, SELF}
// AppObject:oAppWindow is StandardShellWindow initialized in Start( )
method. True owner.
// SELF is the logical owner

I usually check if any changes are made in the DataWindows and their
children, and close them if the user chooses to close them via their own X
icon. The problem is when the application main X icon is clicked, each
QueryClose( ) of the DataWindows is called before I am shown the prompt if I
want to quit the application (as mentioned in first post), causing those
windows to close prematurely. Sometimes user click the Application's X icon
by mistake and the data windows closed which should not happen because of
the cross interference if the application QueryClose(). What I expect is
that if the user chooses to quit the application and clicks "Yes", button,
the QueryClose( ) of the true child DataWindows will be called, but it's
happening before the prompt even appears.

The methods I implemented are needed so a parent window is not closed while
there are child windows still open that rely on same server, much like a
LIFO (Last In First Out) scenario. Hope this explains it.

My base DataWindow has:

METHOD QueryClose(oEvent) CLASS JAMALDATAWINDOW // inherits from
DataWindow
LOCAL lAllowClose := TRUE AS LOGIC
LOCAL dwLen AS DWORD
LOCAL i AS DWORD

// lAllowClose := SUPER:QueryClose(oEvent) // this does not work as it
returns true (all the time), that's why the code was commented.
// infobox{,"", "queryclose: " + AsString(lAllowClose)}:show()
// IF lAllowClose

SELF:DeleteAllChildWindows(oEvent)

dwLen := ALen(SELF:aChildWindows)

FOR I := 1 UPTO dwLen
IF SELF:aChildWindows[i] != NULL_OBJECT
lAllowClose := FALSE
ENDIF
NEXT
// ENDIF
RETURN lAllowClose


METHOD DeleteAllChildWindows(oEvent AS event) AS VOID PASCAL CLASS
JamalDataWindow
LOCAL dwLen AS DWORD
LOCAL i AS DWORD
dwLen := ALen(SELF:aChildWindows)
FOR i := dwLen DOWNTO 1
ApplicationExec(Execwhileevent)
IF SELF:aChildWindows[i] != NULL_OBJECT .AND.
SELF:aChildWindows[i]:EndWindow(TRUE) = 0 // TRUE required
SELF:aChildWindows[i] := NULL_OBJECT
ASize(SELF:aChildWindows, ALen(SELF:aChildWindows) - 1)
ENDIF
NEXT
RETURN

Is there anyway around this?

Jamal

"Chris Pyrgas" <c...@anadelta.com> wrote in message
news:x3bNc.12971$1V3.3...@twister2.libero.it...

Jamal Assaf

unread,
Jul 26, 2004, 3:20:53 PM7/26/04
to
Hi Chris,

I changed the RETURN 0L to RETURN 1L in the StandardShellWindow dispatch.
and now I am getting the behavior I want.

Jamal

"Chris Pyrgas" <c...@anadelta.com> wrote in message
news:x3bNc.12971$1V3.3...@twister2.libero.it...
>
>

Chris Pyrgas

unread,
Jul 27, 2004, 4:08:51 AM7/27/04
to

> I changed the RETURN 0L to RETURN 1L in the StandardShellWindow
dispatch.
> and now I am getting the behavior I want.

in the dispatch() i sent?
if yes then i suppose some of your child datawindows might get 2
querclose(), one from the shell and one from the parent datawindow
i think you should better implement the same technique you use for the
datawindows to the shell as well, in order to send messages only to the
"parent" datawindows
i would also send WM_QUERYENDSESSION to the child windows in the parent's
QueryClose() as the sdk does, instead of trying to close them at this time,
but of course this might be the behaviour you really want

regards,
Chris

Jamal Assaf

unread,
Jul 27, 2004, 1:13:01 PM7/27/04
to
Chris,

You know there is a Dispatch() method is generated by VO when an application
is created, I just had to add the Close DO CASE and modify the return and
all is fine now.

Jamal

"Chris Pyrgas" <c...@anadelta.com> wrote in message

news:n4oNc.13725$1V3.3...@twister2.libero.it...

Chris Pyrgas

unread,
Jul 27, 2004, 1:46:07 PM7/27/04
to

Jamal,

>
> You know there is a Dispatch() method is generated by VO when an
application

it is? well i don't see it here but anyway glad you solved your issue
cheers,
Chris

Jamal Assaf

unread,
Jul 27, 2004, 2:07:01 PM7/27/04
to
Chris,

Aha! The Dispatch( ) method only generated if you create a standard OLE
application under the Standard OLE module.

Jamal

"Chris Pyrgas" <c...@anadelta.com> wrote in message

news:zxwNc.15151$1V3.3...@twister2.libero.it...

Chris Pyrgas

unread,
Jul 27, 2004, 2:13:31 PM7/27/04
to

Jamal,

> Aha! The Dispatch( ) method only generated if you create a standard OLE
> application under the Standard OLE module.

Ah,yes! i had checked this too but only under Standard Shell module..it was
hiding elsewhere ;)

0 new messages