Page 1 of 1

bAction of IDCANCEL Button

PostPosted: Thu Nov 23, 2017 9:44 am
by AntoninoP
Hello,
using the new version I see that the bAction of cancel button never happens, I created a code this re-create the problem:
Code: Select all  Expand view
#include <Fivewin.ch>


FUNCTION MAIN()
    LOCAL oWnd
    DEFINE WINDOW oWnd
    ACTIVATE WINDOW oWnd;
             ON CLICK TEST()
RETURN NIL


STATIC FUNCTION TEST()
    LOCAL oDlg, nID, oBtn

    DEFINE DIALOG oDlg

    nID := TControl():nInitID
    TControl():nInitID := IDCANCEL-1
    @ 1, 20 BUTTON oBtn PROMPT "Cancel"
    TControl():nInitID := nID
    oBtn:bAction := {|| WQout("never happends") }
    oDlg:bValid := {|| WQout("never happends too"), .T. }

    ACTIVATE DIALOG oDlg CENTER NOMODAL
RETURN NIL


I need to intercept the closing of the dialog ...

We are using the version 9.04 (for XP version) and that works...

Re: bAction of IDCANCEL Button

PostPosted: Thu Nov 23, 2017 2:38 pm
by Enrico Maria Giordano
Try replacing WQOut() with MsgInfo().

EMG

Re: bAction of IDCANCEL Button

PostPosted: Fri Nov 24, 2017 11:15 am
by AntoninoP
You are right, the bValid block is called, the problem is that is called even when the program closes the dialog with End.

The problem using bValid is that is called even when I close the dialog from the code with :End .
So I need to intercept the click of CANCEL button...

Re: bAction of IDCANCEL Button

PostPosted: Fri Nov 24, 2017 11:34 am
by Enrico Maria Giordano
Try using the CANCEL clause of the @ BUTTON command.

EMG

Re: bAction of IDCANCEL Button

PostPosted: Wed Nov 29, 2017 1:57 pm
by AntoninoP
Hello,
I compared the version where bAction of IDCANCEL works and the version where don't.
I found this piece of code inside dialog.prg on method command:
Code: Select all  Expand view
     case nID == IDCANCEL .and. ! ::lModal
           if ::lValid()
              ::bValid = nil
              ::End()
              return .T.
           endif  
           return .F.

This piece of code does not send the FM_CLICK message, that is present in this case (just below):
Code: Select all  Expand view
     case nID != 0
           do case
              case nNotifyCode == BN_CLICKED
                   if hWndCtl != 0 .and. nID != IDCANCEL
                      oWnd := oWndFromhWnd( hWndCtl )
                      if ValType( ::nResult ) == "O" // latest control which had focus
                         // There is a pending Valid, it is not a clicked button
                         if oWnd != nil
                            if ! oWnd:lCancel
                               if ::nResult:nID != nID .and. ! ::nResult:lValid()
                                  return nil
                               endif
                            endif
                         else
                            if ::nResult:nID != nID .and. ! ::nResult:lValid()
                               return nil
                            endif
                         endif
                      endif

                      if AScan( ::aControls, { |o| o:nID == nID } ) > 0
                         SendMessage( hWndCtl, FM_CLICK, 0, 0 )
                      elseif nID == IDOK
                         ::End( IDOK )
                      endif
                   else
                      if nID == IDOK
                         ::GoNextCtrl( GetFocus() )
                         if ! ::lModal
                            return 0
                         endif
                      elseif hWndCtl != 0 .and. ; // There is a control for IDCANCEL
                             AScan( ::aControls, { |o| o:nID == nID } ) > 0
                             SendMessage( hWndCtl, FM_CLICK, 0, 0 )
                             return .F.
                      else
                         ::End( IDCANCEL )
                      endif
                   endif

As we can see if the ID is IDCANCEL it goes in the else part, where check if the id is IDOK, then if hWndCtl is not zero, in this case send the message...
so the case of IDCANCEL not modal should be something like (don't tested):
Code: Select all  Expand view
     case nID == IDCANCEL .and. ! ::lModal
         if hWndCtl != 0 .and. ; // There is a control for IDCANCEL
                  AScan( ::aControls, { |o| o:nID == nID } ) > 0
               SendMessage( hWndCtl, FM_CLICK, 0, 0 )
               return .F.
         else
            if ::lValid()
               ::bValid = nil
               ::End()
               return .T.
            endif  
            return .F.
         endif

I compared the versione 15.03 with the 17.07, Maybe someone more expert can review this piece of code...
Antonino