Author |
Topic: Utilities (Read 3917 times) |
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #17 on: Apr 26th, 2009, 5:55pm » |
|
Quote:| Does anyone have any thoughts about where the best place to locate them is? |
|
I've created a UTILITIES subdirectory in the main BB4W installation folder (typically C:\Program Files\BBC BASIC for Windows). However that's just my personal preference, and of course Admin rights are required to put files there (that seems correct for an 'extension' to BB4W, but not everybody may agree).
Quote:| How can I tell if the IDE that I want to operate on is actively running a program |
|
That isn't straightforward, but it's very easy to discover whether the 'output window' is open (generally that's what you want to know, because if the interpreter is sitting at the command prompt it's the same as running a program for most practical purposes).
To find out whether the output window is open simply use the 'IsWindow' API on its handle (the third and last optional parameter that can be passed to a utility).
Richard.
|
|
Logged
|
|
|
|
MDCHutton
Guest
|
 |
Re: Utilities
« Reply #18 on: Apr 26th, 2009, 5:58pm » |
|
>How can I tell if the IDE that I want to operate on is > actively running a program.
From ' inside' the runing program, Yes. (I can't see your post in this page.) if your in a TimerProc (a callback procedure made with a timer) you can look at what the statement pointer is looking at and if it is 0, there is no statement there and hence you are in immediate mode! If your in an INPUT, GET or INKEY... it will give you the token for the relative one. You can also test for END and QUIT the same way (although in PROFILERvx.x I change all the QUITs to END before running the program because it leads to faster TimerProc..You could theoretically test for any keyword but I can only think the TimerProc would become to unwieldy...
but from 'outside', I don't know.
Michael
|
|
Logged
|
|
|
|
MDCHutton
Guest
|
 |
Re: Utilities
« Reply #19 on: Apr 26th, 2009, 6:03pm » |
|
Sorry, on the topic of where to put them - in their own folder under a \Utilities sub folder of \BBC Basic for Windows because of issues of removing them. RMDIR /s /q is an simpler option than relying on the user to 'register' every file they add.
|
|
Logged
|
|
|
|
MDCHutton
Guest
|
 |
Re: Utilities
« Reply #20 on: Apr 26th, 2009, 6:10pm » |
|
on Apr 26th, 2009, 5:55pm, Richard Russell wrote:and of course Admin rights are required to put files there (that seems correct for an 'extension' to BB4W, but not everybody may agree). |
|
I try to write a {GUID}.txt file to the directory the user has chosen and if they can't, they don't have access rights, and they have to choose again. I think it's a Vista drama? I would like custom filter the BrowseFor folder for access rights...but as to a default folder. under BB4W would be good.
Michael
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #21 on: Apr 26th, 2009, 9:25pm » |
|
Quote:| I think it's a Vista drama? |
|
No, that's a misapprehension. It applies equally to all versions of Windows NT, including Win2K and WinXP. The only reason Vista comes into it is that (thank goodness) it actually encourages running not as an administrator, so you're somewhat more likely to encounter 'permission' issues on that OS.
People running XP as a 'normal user' (which they always should, but most don't) will have similar issues with writing to Program Files. But of course that's exactly as it should be - an ordinary user ought not to be able to upset a 'shared' application.
Arguably, since the Registry entries controlling the add-in utilities, are 'per user' (i.e. in the HKEY_CURRENT_USER hive) the utilities themselves ought also to be stored in a 'per user' location. So maybe they should go in 'Documents and Settings\[user]\Application Data'.
Richard.
|
|
Logged
|
|
|
|
Malcolm
Guest
|
 |
Re: Utilities
« Reply #22 on: Apr 26th, 2009, 11:18pm » |
|
Thanks, Richard, The output window is not going to distinguish between running and having completed necessarily. No, I really was trying to find out if it had ended, if it ever was run, as I did not want any chance of writing to a program that was still running and thus crashing it, which seemed likely. I was hoping there would be a flag I could look at.
Quote:(the third and last optional parameter that can be passed to a utility). |
|
There seemed to be other data on the command line sometimes. Are they then "garbage"? I often see a '10' for a 4th parameter but am I just picking up random dross.
Malcolm.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #23 on: Apr 27th, 2009, 08:50am » |
|
Quote:| I did not want any chance of writing to a program that was still running and thus crashing it, which seemed likely. |
|
Just because the interpreter isn't actually 'running' a program doesn't mean you can't crash it! If you change the current program 'behind the interpreter's back' (i.e. change the contents of memory starting at PAGE) something as simple as an immediate-mode command entered at the prompt could crash it. That could happen, for example, if you increase the length of the program - since it will then overwrite the beginning of the heap (or the heap could overwrite the end of the program).
From the point of view of an add-in utility, the interpreter sitting at the command prompt is no different from the interpreter waiting for the user to respond to an INPUT statement. In neither case must you modify the program in memory.
So, whether the output window is open is exactly what you need to know to determine whether it's safe to modify the program. Indeed, that's why the IDE itself uses that information to enable or disable editing - if it's right for the IDE it must be right for a utility!
Quote:| There seemed to be other data on the command line sometimes. Are they then "garbage"? I often see a '10' for a 4th parameter but am I just picking up random dross. |
|
They're not "garbage" or "dross", they are command line parameters which you have provided (accidentally or deliberately). If you see something unexpected in the command line, check what you've stored in the Registry as the 'Parm' entry for that utility. I'm willing to bet you'll see the data there!
(Edit: alternatively, if you forget to store in the Registry the terminating NUL of your Parm string, you could be seeing uninitialised memory contents. Ensure you use code similar to that in 'checkquotes.bbc' to write strings to the registry).
You can use the same 'utility' executable to provide multiple entries in the Utilities menu, by adding your own command-line parameter(s) in the Parm data so that the executable knows which menu item was activated. That way you can package multiple utilities together in a single EXE if you wish.
Richard.
|
| « Last Edit: Apr 27th, 2009, 2:39pm by admin » |
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #24 on: Apr 28th, 2009, 08:23am » |
|
Quote:| if your in a TimerProc (a callback procedure made with a timer) you can look at what the statement pointer is looking at and if it is 0, there is no statement there and hence you are in immediate mode! |
|
I've no idea where you got that from, but it's not correct. To test for immediate mode you can check whether the statement pointer is < PAGE, but you can't tell (reliably) by looking at what it is pointing to. Even the '< PAGE' test could be fooled if PAGE has been raised by a program.
Also note that the 'statement pointer' isn't guaranteed to be pointing to the start of a statement. In some circumstances it can point part way through a statement. For this reason be careful how you use it.
Richard.
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: Utilities
« Reply #25 on: Apr 28th, 2009, 1:21pm » |
|
I should have been a bit more explicit. You look at the byte that the statement pointer is looking at and that seems to normally be the keyword token. So far in my limited tests when the program has run through to immediate mode the byte the statement pointer is addressing seems to be 0.
So in Profiler this seems to work:
Code:
.TimerProc
mov dword [^@%+392],!(^@%+392)
mov eax,[^@%+384]
cmp byte [eax],&E0 ;look for END
je close
cmp byte [eax],0 ;if nothing there ? immediate mode
jz close
....etc
So far I have got profiler to reliably exit when in immediate mode....
Michael
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #26 on: Apr 28th, 2009, 2:52pm » |
|
Quote:| when the program has run through to immediate mode the byte the statement pointer is addressing seems to be 0 |
|
I understood perfectly well what you meant! I have (again) looked at my code and I am certain that it is not a reliable test for being in immediate mode.
As far as I can see, if the interpreter enters immediate mode by 'falling off' the end of the program (i.e. by detecting a line-length byte of zero, being the first byte of the 00 FF FF terminating sequence) the 'statement pointer' ends up addressing the byte stored at TOP, i.e. the byte following the end of the program.
If that is the case, you are relying on the byte stored at that location (the first byte in the heap) being zero, which most definitely is not guaranteed, and is not even particularly likely. I reckon it's pure luck that you have found it to work.
Richard.
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: Utilities
« Reply #27 on: Apr 29th, 2009, 12:46am » |
|
Ah. I will test that one a bit more then, and see how many times I can be 'lucky'. I had only used 3 or four programs to test out the idea and I seem to have been lucky so far... I think I had assumed it was seeing the last 00 FF FF and ending there.
Thanks for the update and thoughts on that one.
Michael
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #28 on: May 7th, 2009, 9:34pm » |
|
In all normal situations it is not necessary to modify @lib$ in your programs; indeed all the 'system string variables' (@dir$, @lib$, @tmp$, @usr$) should be considered 'read only' values.
It is particularly important not to modify @lib$ because doing so in a 'compiled' BB4W program can - if you're unlucky - be highly destructive of disk contents. This is because of the way BB4W executables 'clean up after themselves' on termination.
Unfortunately the special requirements of 'add-in utilities' mean that modifying the value oif @lib$ can be necessary. I had, until today, believed that there was a 'safe' way to do so, but it turns out that I was wrong.
I have therefore created a special version of BBCWRUN.EXE which can be used when compiling such utilities. It still requires special measures to be taken when modifying @lib$ (you must not use a simple assignment statement) but when those precautions are taken the risk of accidentally deleting wanted files is eliminated.
If anybody is working on a program that needs to modify @lib$ please contact me privately so that I can supply you with a copy of the special version of BBCWRUN.EXE and explain how, using it, @lib$ can be safely modified.
Richard.
|
|
Logged
|
|
|
|
Malcolm
Guest
|
 |
Re: Utilities
« Reply #29 on: May 10th, 2009, 01:14am » |
|
With regard to the recent thread in Yahoo I can see the problem with insertion at the caret position. The question is if you did want to insert something at the caret (in a utility) how would you do that?
If you have a selection highlighted then that's pretty easy but otherwise?
EM_GETSEL seems to need some movement of the mouse to register a valid position even if no highlighted selection is apparent, and just gives the line when there is a selection. The Status line shows the info but how can we obtain that location?
I tried reading the status line but that did not seem to work although I located the status window ok.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Utilities
« Reply #30 on: May 10th, 2009, 10:06am » |
|
Quote:| if you did want to insert something at the caret (in a utility) how would you do that? |
|
To find the caret position you can send message 1034 (WM_USER+10). The value returned is (yCaret << 12) + xCaret
Richard.
|
|
Logged
|
|
|
|
Malcolm
Guest
|
 |
Re: Utilities
« Reply #31 on: May 10th, 2009, 11:55pm » |
|
Quote:| To find the caret position you can send message 1034 (WM_USER+10). |
|
Yes, that works nicely, Thanks again Richard.
Regards, Malcolm.
|
|
Logged
|
|
|
|
|