Hi,
Yes, I know this behavior is documented in the help but I can't understand why Richard decided to put this in the WINLIB2B library or actually why he didn't just update WINLIB2.
As far as I can see from other applications (including BB4W IDE!) pressing escape or clicking the dialog box close button closes the dialog box.
Obviously the advantage to use WINLIB2B over WINLIB2 is that it forwards also WM_HELP and WM_NOTIFY messages. And yes, that is what I want as I need a WM_NOTIFY when an item in a ListView selected.
Still I fail to see why Richard didn't just update the WINLIB2 library because the programmer has control to allow/disallow this by *SYS1.
Bottom line is that I want/need to receive WM_NOTIFY but also to have close buttons behave in a common way, i.e. as in WINLIB2.
Do I need to modify WINLIB2B library assembly code (and how) or is there is simpler solution?
Thanks
Mike
WINLIB2B Close buttons don't work.
- hellomike
- Posts: 192
- Joined: Sat 09 Jun 2018, 09:47
- Location: Amsterdam
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: WINLIB2B Close buttons don't work.
The idea is to allow some processing to occur before the window closes so WINLIB2B enhances the options. It requires you to do a little more processing to detect the close button press but that is simple enough.
You will get an interrupt message of WM_COMMAND (@msg%=273) with a control ID of ID_CANCEL (@wparam%=2) so you will look for this in your interrupt handler and issue a QUIT or whatever else you wish to do with that input.
That is much simpler than messing with the library and customizing it.
Hope this helps.
Z
You will get an interrupt message of WM_COMMAND (@msg%=273) with a control ID of ID_CANCEL (@wparam%=2) so you will look for this in your interrupt handler and issue a QUIT or whatever else you wish to do with that input.
That is much simpler than messing with the library and customizing it.
Hope this helps.
Z
- hellomike
- Posts: 192
- Joined: Sat 09 Jun 2018, 09:47
- Location: Amsterdam
Re: WINLIB2B Close buttons don't work.
Hi Zaphod,
Thanks for the fast reply!
Actually I discovered today that at least WM_COMMAND with ID_CANCEL is send so I thought I was saved and that I could simply add this in my interrupt handler PROCedure, which is.....
As you can see all controls have their dedicated PROC, each handling all functionality for a specific Dialog box.
However when receiving ID_CANCEL (@wparam%=2), the program doesn't know which dedicated PROC to call, i.e. for dialog box to issue PROC_closedialog().
Hope the above makes sense.
Mike
Thanks for the fast reply!
Actually I discovered today that at least WM_COMMAND with ID_CANCEL is send so I thought I was saved and that I could simply add this in my interrupt handler PROCedure, which is.....
Code: Select all
DEF PROCappSys(msg%, wpa%, lpa%)
LOCAL nc%, id%
nc%=wpa%>>16 : id%=wpa% AND &FFFF
CASE msg% OF
WHEN WM_COMMAND
REM Dialog buttons...
CASE id% OF
WHEN 190, 199 PROCappAddCol(id%)
WHEN 290, 299 PROCappCDSet(id%)
WHEN 390, 399 PROCappOperations(id%)
......................
WHEN 9990 PROCdebug(id%, "")
ENDCASE
IF id%>469 IF id%<480 PROCappCDWidths(id%)
IF id%>=10000 PROCappCellDetails(20, id%)
IF id%=710 IF nc%=EN_CHANGE PROCappSearchAlbum(10)
IF id%=720 IF nc%=LBN_SELCHANGE PROCappSearchAlbum(30)
WHEN WM_NOTIFY
IF id%=400 IF nc%=LVN_ITEMCHANGED PROCappCDWidths(10)
ENDCASE
ENDPROC
However when receiving ID_CANCEL (@wparam%=2), the program doesn't know which dedicated PROC to call, i.e. for dialog box to issue PROC_closedialog().
Hope the above makes sense.
Mike
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: WINLIB2B Close buttons don't work.
Well if you keep a list of the dialog handles then you could presumably use SYS "GetActiveWindow" to find which one it was.
Z
Z
-
- Posts: 177
- Joined: Mon 02 Apr 2018, 21:51
Re: WINLIB2B Close buttons don't work.
You could always have asked him! The reason for the change in the behaviour of the Close button and the Escape key in WINLIB2B is simply because the way they behave in WINLIB2 is wrong! It is never sensible for a dialogue box unconditionally to close when Close or Escape is pressed: the programmer should always have the opportunity to suppress that action if it is not appropriate in the circumstances (like ON CLOSE in the main output window). Richard wasn't able to fix this in WINLIB2 because it would have introduced an incompatibility, but WINLIB2B gave him the opportunity to do it correctly.
The proper way for Close and Escape to work, and how they work in WINLIB2B, is for them to generate a WM_COMMAND message with an ID of 2 (Cancel); that can be intercepted in the normal way and, assuming you want the dialogue box to be closed as a result, you can call PROC_closedialog() to achieve that. Indeed if you look at the code of DLGDEMO.BBC you'll see that this is exactly what happens (even though WINLIB2 is normally used, you can change it to WINLIB2B and it will behave in exactly the same way).
The situation you describe there is extremely unusual, because it implies that there are two or more 'modeless' dialogue boxes open at the same time. In Windows dialogue boxes are almost always modal (in which case there is no ambiguity in respect of which is being closed); modeless dialogue boxes (such as the Find/Replace dialogue) are uncommon and having two or more open at the same time is a situation Richard has never encountered.
So if you really do have two modeless dialogue boxes Richard would be concerned that your user interface is exceptionally non-standard. If you can make the dialogue boxes modal, and hence more conventional, there cannot be any doubt about which is being closed. As a last resort, if you are convinced modeless dialogue boxes are appropriate, you can still distinguish which is being closed because the lParam value passed in the WM_COMMAND message will contain the handle of the Cancel button in the relevant box (even if Close or Escape was pressed).
- hellomike
- Posts: 192
- Joined: Sat 09 Jun 2018, 09:47
- Location: Amsterdam
Re: WINLIB2B Close buttons don't work.
Thanks for thinking along.
I agree that my handling of modal vs modeless boxes is an ongoing issue. Most of them can or rather should be modal.
Because of a menu-choice I call a PROC that opens the correct dialog box, like:
If some control is clicked on the open dialog box I know what to do because all controls have unique id's upon creation, like:
However if close button is clicked, ID_CANCEL isn't unique. Guess I could create a global variable OpenDlg% or something that I set after every call PROC_showdialog(dlg%) in the program and then do PROC_closedialog(OpenDlg%) when ID_CANCEL is received.
Kind of defies my approach of keeping all functionality from the same dialog box (each control on it) in a dedicated PROC.
Will give it more thought I guess.
Mike
I agree that my handling of modal vs modeless boxes is an ongoing issue. Most of them can or rather should be modal.
Because of a menu-choice I call a PROC that opens the correct dialog box, like:
Code: Select all
CASE msg% OF
WHEN WM_COMMAND
REM Menu handling...
CASE id% OF
.............
WHEN 25 PROCappSearchAlbum(0)
.............
Code: Select all
IF id%=710 IF nc%=EN_CHANGE PROCappSearchAlbum(10)
IF id%=720 IF nc%=LBN_SELCHANGE PROCappSearchAlbum(30)
Kind of defies my approach of keeping all functionality from the same dialog box (each control on it) in a dedicated PROC.
Will give it more thought I guess.
Mike
-
- Posts: 177
- Joined: Mon 02 Apr 2018, 21:51
Re: WINLIB2B Close buttons don't work.
Hello,
Richard says:
-----
-----
Richard says:
-----
Windows is designed in such a way that controls need not have unique IDs, for example the 'built in' dialogue boxes commonly reuse the same ID. So although that's something you can do when you have control of the IDs, it's not a general solution (and as you've noted the IDs for OK and Cancel/Close are mandated).
You could still do that, but the 'dispatch' mechanism that determines which PROC is called would have to take account of something which identifies the dialogue box. You could for example dispatch on the *handle* of the originating control rather than its *ID* (i.e. use lParam rather than wParam) which is guaranteed to be unique. As I said, if you press Escape or Close it will appear to have originated from the Cancel button according to the handle value.
-----
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: WINLIB2B Close buttons don't work.
So far as I can see, when you click on the close box of a dialog the @lparam% that is returned by ON SYS is "0", so that suggestion does not appear to work. Incidentally nor does my earlier suggestion of finding the active window. That also returns a "0". It looks like the calling thread is not the right one for those calls to work, but then again I may be missing something obvious.
Z
Code: Select all
REM This does not work.
INSTALL @lib$+"WINLIB2B"
:
dlg%=FN_newdialog("First",50,50,100,100,8,200)
PROC_showdialog(dlg%)
dlg1%=FN_newdialog("Second",250,50,100,100,8,200)
PROC_showdialog(dlg1%)
dlg2%=FN_newdialog("Third",450,50,100,100,8,200)
PROC_showdialog(dlg2%)
:
DIM Q%(2)
ON SYS Q%()=@msg%, @wparam% AND &FFFF, @lparam% : RETURN
REM ========================== MAIN LOOP =============================
REPEAT
IF Q%(1) = 2 THEN
CASE TRUE OF
WHEN Q%(2)=!dlg%: PROC_closedialog(dlg%)
WHEN Q%(2)=!dlg1%: PROC_closedialog(dlg1%)
WHEN Q%(2)=!dlg2%: PROC_closedialog(dlg2%)
ENDCASE
PRINT Q%(0), Q%(1), Q%(2)
ENDIF
Q%()=0
WAIT 10
UNTIL FALSE
END
- hellomike
- Posts: 192
- Joined: Sat 09 Jun 2018, 09:47
- Location: Amsterdam
Re: WINLIB2B Close buttons don't work.
p_m21987,
Please thank Richard for his reply. He always provides good information.
So I was thinking of getting the dialog handle when there is a ID_CANCEL and then give all dialog-PROCs a change to match the dlg and do their business.
Was about to test how to obtain the handle today but.... Zaphod beat me to it and saves me a lot of work.
Zaphod: Thanks. And you say also "GetActiveWindow" doesn't work, right?
Your elegant piece of code shows my problem exactly! Even IF it would work, I need a WHEN for every possible value of dlg%. It also implies that all handles should be in global variables. They aren't. All the dialog-PROCs have a PRIVATE dlg%.
Then again, giving each PROC a chance to match is far more elegant I would say. But....... handle can't be found!
Only 'solution' I can think of is add code to all PROCs to save dlg% in a global OpenDlg% to indicate which box is open and then upon receiving ID_CANCEL do a PROC_closedialog(OpenDlg%).
Regards,
Mike
Please thank Richard for his reply. He always provides good information.
So I was thinking of getting the dialog handle when there is a ID_CANCEL and then give all dialog-PROCs a change to match the dlg and do their business.
Was about to test how to obtain the handle today but.... Zaphod beat me to it and saves me a lot of work.
Zaphod: Thanks. And you say also "GetActiveWindow" doesn't work, right?
Your elegant piece of code shows my problem exactly! Even IF it would work, I need a WHEN for every possible value of dlg%. It also implies that all handles should be in global variables. They aren't. All the dialog-PROCs have a PRIVATE dlg%.
Then again, giving each PROC a chance to match is far more elegant I would say. But....... handle can't be found!
Only 'solution' I can think of is add code to all PROCs to save dlg% in a global OpenDlg% to indicate which box is open and then upon receiving ID_CANCEL do a PROC_closedialog(OpenDlg%).
Regards,
Mike
-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: WINLIB2B Close buttons don't work.
Actually I do have a modified version of WINLIB2B that does what you want from about 4 or 5 years ago, so it might not be the latest version. If you are interested then send me a private message and I will email it to you. It is not an 'approved' solution, obviously, so I won't post it here.
Z
Z