BBC BASIC for Windows
Programming >> User Interface >> Retitling a dialogue box
http://bb4w.conforums.com/index.cgi?board=ui&action=display&num=1457518189

Retitling a dialogue box
Post by simong42 on Mar 9th, 2016, 09:09am

I've just started developing dialogue boxes in BBC Basic (excellent help text - thanks). I can change the text associated with items, e.g. static text, or buttons, but I can't see how to change the title of a dialogue box, post-creation. Is this possible?

aim : display a simple dialogue, with a title, some static text, and an OK button.
Re: Retitling a dialogue box
Post by sveinioslo on Mar 9th, 2016, 12:51pm

An example on how to do it.

Code:
      WM_SETTEXT = &C
      INSTALL @lib$+"winlib2"
      ON CLOSE PROC_closedialog(dlg%):QUIT

      dlg%=FN_newdialog("Clock box",10,10,150,50,8,100)
      PROC_showdialog(dlg%)
      WAIT 100
      REPEAT
        title$=TIME$
        SYS "SendMessage",!dlg%,WM_SETTEXT,0,title$
        WAIT 100
      UNTIL 0
 


Svein

Re: Retitling a dialogue box
Post by simong42 on Mar 9th, 2016, 6:34pm

Thanks very much, I'll check it out
Re: Retitling a dialogue box
Post by michael on Mar 9th, 2016, 9:27pm

Interesting. I would assume that the clock would keep itself updated seeing as how the windows library should access the built in function and update it automatically, but I may be overlooking something. Maybe it needs a different method. Or maybe I could just be wrong.
Re: Retitling a dialogue box
Post by DDRM on Mar 10th, 2016, 08:06am

Hi Michael,

The routine stores the current time in a string, and displays that: the dialogue box doesn't "know" it's a time - it isn't dynamically linked to the system clock, so you need to update it "manually".

If you needed to, you could use ON TIME, or if necessary, TIMERLIB, to generate periodic interrupts to update the clock, if you wanted to do that while your program was busy elsewhere. Note the cautions in the manual about the use of TIMERLIB (and indeed any interrupt-driven processes).

Best wishes,

D
Re: Retitling a dialogue box
Post by sveinioslo on Mar 10th, 2016, 09:08am

Sorry if my copy/paste/run example was more confusing than helpful.
The short and boring answer to the OP's question is:

SYS "SendMessage",!dlg%,WM_SETTEXT,0,"some text"

Note the exclamation mark before dlg%.


Svein


Re: Retitling a dialogue box
Post by DDRM on Mar 11th, 2016, 09:00am

Hi Svein,

I thought it was a really nice example, and even potentially useful - and it shows how easy it can be to implement a simple "app".

Two minor comments I'd add to your simplified example:


1) dlg% is the handle to the dialogue box - it needs to match the variable you assigned it to when you set up the dialogue box.

2) WM_SETTEXT is a Windows variable, which will need setting.

You can either use the "Add Windows Constants" utility (from the Utilities menu), which is easy, or add it yourself if you know the value. In your first example it is defined as

WM_SETTEXT = &C

For the newcomers, "&" means it is a hexadecimal number: in this case &C is 12 decimal, so you could also have written

WM_SETTEXT = 12

Hope that's useful, and not treating everyone as an idiot...

D
Re: Retitling a dialogue box
Post by Zaphod on Mar 11th, 2016, 1:00pm

No, Svein was right and the handle of the dialog is kept in the beginning of the dialog template in memory so it is accessed by !dlg%.

dlg% is the location of the template.

It is one of the idiosyncrasies of WINLIB2
Re: Retitling a dialogue box
Post by hellomike on Mar 11th, 2016, 1:59pm

This has little to do with WINLIB2.
dlg% contains the address of where the Template data begins and Microsoft dictates that the first 4 bytes of that data will contain the handle of the Dialog Box, hence the use of !dlg%.

So its rather one of the idiosyncrasies of Windows.
Re: Retitling a dialogue box
Post by Zaphod on Mar 11th, 2016, 4:35pm

Unless I am misunderstanding both MSDN and the WINLIB2 code
we have:
Code:
      push 0  ; lParamInit
      push D% ; lpDialogFunc
      push @hwnd%  ; hWndParemt
      push dlg%+16 ; lpTemplate
      push I% ; hInstance
      call "CreateDialogIndirectParam"
      mov [dlg%],eax
 


Which shows that the template structure starts at dlg%+16 and it is WINLIB2 that puts the returned handle into dlg%

But either way it is much better, in my opinion, to add a line hdlg%=!dlg% and use hdlg% whenever you need the handle which you do for all API calls.

For the original questioner it might be interesting to note that if you use WINLIB5 that does return the handle not a pointer to the handle so then you definitely don't use the "!" in calls to change the window header text.
Re: Retitling a dialogue box
Post by hellomike on Mar 12th, 2016, 2:16pm

Hi,

As soon as I posted, I started to have doubts and indeed the block at dlg% is a WINLIB2 structure, not a Windows one. I stand corrected.

Apparently the first 16 bytes are specific to WINLIB2 and as far as I understand these bytes are used for:

dlg%+0 Zero if Dialog Box is closed or the handle if its not
dlg%+4 Address of the machine code routine that will open the dialog box
dlg%+8 Address of the last byte in the dlg% structure
dlg%+12 Address where the data for the first new Dialog Item will be stored

Anyone care to comment on these findings?

Actually, I'm unsure about dlg%+8. Does it point to last byte in, or first byte áfter the structure?
If first byte, then would a test like '... > dlg%!8' not be incorrect?

Regards,

Mike
Re: Retitling a dialogue box
Post by Zaphod on Mar 12th, 2016, 3:37pm

Mike, we are in agreement.

dlg%!8 contains the position of the end of the reserved data block.
It is used to ensure that the controls definition don't overrun into memory that wasn't reserved for the dialog.

In WINLIB2 you see this:
Code:
 P% = dlg%!12
      WHILE (P% AND 3) P% += 1 : ENDWHILE
      IF (P%+2*LENtext$+26) > dlg%!8 ERROR 0, "No room for dialogue template" 


I hope this clears things up.





Re: Retitling a dialogue box
Post by hellomike on Mar 15th, 2016, 09:39am

Yeah, that makes sense.
Of course it would be rather unlikely that Richard made a mistake.

Clearly, working with Dialog Boxes in Windows is more complicated than it was in RISC OS.

What I understand is when a Dialog Box is showed on screen after creation, calling the 'CreateDialogIndirectParam' function is (must be) done within a thread.

I.e. the PROC_showdialog() code is not just doing a

SYS "CreateDialogIndirectParam",.....

as one, without enough knowledge like me, would expect.

Is there any online documentation that documents these concepts more clearly , apart from MSDN which just documents each function individually?

I guess this gets harder to find because accessing the API directly isn't really done anymore a lot. Instead Foundation Classes and .NET etc is used. I have no experience with any of these.
Re: Retitling a dialogue box
Post by Zaphod on Mar 17th, 2016, 01:38am

Quote:
Is there any online documentation that documents these concepts more clearly , apart from MSDN which just documents each function individually?


I am sure there is but I can't say I have found anything much. There is this:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644995%28v=vs.85%29.aspx#procedures That is the magic of RTRs assembly code that inserts the dialog message processing into the main windows message loop. There are brief periods of my life when I understood that bit, but I have not tinkered there for a couple of years so it is all misty again. Sorry I can't shed any more light. I think RTR tends to translate the C examples into assembly.