Hi all,
I was wondering if someone can help me with a few things that have me stumped:
• Is there an easy way to get the address of a literal that is not a string?
With strings I can do
*pointer=@"test"
but that does not seem to be the case for
*pointer=@1
so is there a way to do it without creating a variable first like:
tmp=1
*pointer=@tmp
?
Also, is there an easier way to pass structures than having to define them first like:
tmp.string\s="test"
*pointer.string=@tmp
?
• Is there a way to get the type of a variable by its address, i.e., if I sometimes have:
*pointer=@string_var
, but other times
*pointer=@int_var
. How can I find out whether *pointer contains the address of a string or int so that I can do either peekS or peekI, and avoid error when I try to access the wrong one?
• How do I check if a structure field is set?
structure var
s.s
i.i
endStructure
v.var
v\s="test"
How would I now find out which of them are set (maybe both?)
Checking for #null and #null$ is unreliable because #null would return true for 0, and #null$ would return true for "" (I sometimes wish pb had the equivalent of ===).
• What exactly do import "" and importC "" do?
I've used import and importC before to import functions from libraries, but what does importing from nothing do?
• How can I find out if my notify icon already exists (winapi)?
I display a help balloon in my program by using Shell_NotifyIcon_, and currently I have this:
procedure balloon()
Static update=0
If update
Shell_NotifyIcon_(#NIM_MODIFY, my_notifyicon)
Else
Shell_NotifyIcon_(#NIM_ADD, my_notifyicon)
update=1
EndIf
EndProcedure
, but that seems to cause the balloons not to appear sometimes until the program is restarted.
Is there a reliable way of detecting whether my icon already exists?
Am I even supposed to be modifying it instead of removing it and re-adding it?
My program displays the notifications only once in a while to alert the user about something, I don't need the icon for anything else...
• LSet function confuses me.
The documentation says: “If the string is longer than the specified length, it will be truncated starting from the left side of the string.” which is the opposite of the RSet function (which says: “If the string is longer than the specified length, it will be truncated starting from the right side of the string.”), yet the function actually truncates from the right side, just like RSet, and the example actually is the same truncating-wise for both functions.
Debug LSet("LongString", 4) ; will display "Long"
even though it should display “ring” for LSet.
Sounds to me like there's either a bug in the LSet, or the manual is misleading.
Any help would be greatly appreciated.
help with pointers, structures, and a possible bug with LSet
Re: help with pointers, structures, and a possible bug with
If you put the constant into a datasection and label it you can get the address.nsstudios wrote:Is there a way to do it without creating a variable first like:
What you are actually doing though is creating a variable by a different route, with a constant value, so the precise answer would be 'no'.
Code: Select all
Define *Int = ?D1
Debug *Int
DataSection
D1:
Data.I 1
EndDataSection
You can allocate a pointer and populate it directly. Personally I'd say it doesn't particularly meet the 'easier' criterion though.nsstudios wrote:Is there an easier way to pass structures than having to define them first
Code: Select all
Define *Pointer = AllocateMemory(SizeOf(Integer))
PokeI(*Pointer, 1234)
Debug PeekI(*Pointer)
No. If you want this information you would have to keep track of it yourself separately.nsstudios wrote:Is there a way to get the type of a variable by its address
The byte data of a string in memory is indistinguishable from a half dozen integers, say.
You won't get an error if you PeekS on an integer or vice versa, you just won't get back anything sensible.
Personally I'd say it would be better to use multiple pointers to ensure this type of ambiguity doesn't arise.
For the same reason as above you would need to have a separate flag to indicate the status of (a) particular member(s).nsstudios wrote:How do I check if a structure field is set?
Some functions exist in the standard library but aren't normally public.nsstudios wrote:What exactly do import "" and importC "" do?
For example PBs internal object creation functions get called when you add a gadget to a window but normally aren't visible to the programmer.
This allows them to be made public, if you need to use them.
Yep, something seems to have gone wrong there somewhere. I've posted a bug report.nsstudios wrote:LSet function confuses me. Sounds to me like there's either a bug in the LSet, or the manual is misleading.
Re: help with pointers, structures, and a possible bug with
Thanks a lot for the speedy reply and help.
Is there a way to see the functions that aren't publically exposed?
So far I've only seen people on forums use import/importC "", but how would I get the list of possible functions that I could import?
The reason I was asking for an easier way to get the address of an integer is because I've been trying to make an iif-like function that would work with both ints and strings, so having to first define a variable is really not what I want.
Here's what I tried:
;{
Procedure iif_(expression, *true, *false)
If expression
ProcedureReturn *true
EndIf
ProcedureReturn *false
EndProcedure
Macro iif(_expression_, _true_, _false_, _type_=s)
peek#_type_(iif_(Bool(_expression_), _true_, _false_))
EndMacro
a=1
;I can do string just fine
b.s="the state is: "+iif(a=1, @"on", @"off")
Debug b
;int does not work the way I'm trying to do it
;I guess I would need a function that would give me the address or something...
;c=iif(a=1, @256, @0, i)
;I can do this, but it defeats the whole purpose:
Define t=256, f=0
c=iif(a=1, @t, @f, i)
Debug c
;}
Silly example, but I hope it shows what I'm trying to do.
Is there a way to see the functions that aren't publically exposed?
So far I've only seen people on forums use import/importC "", but how would I get the list of possible functions that I could import?
The reason I was asking for an easier way to get the address of an integer is because I've been trying to make an iif-like function that would work with both ints and strings, so having to first define a variable is really not what I want.
Here's what I tried:
;{
Procedure iif_(expression, *true, *false)
If expression
ProcedureReturn *true
EndIf
ProcedureReturn *false
EndProcedure
Macro iif(_expression_, _true_, _false_, _type_=s)
peek#_type_(iif_(Bool(_expression_), _true_, _false_))
EndMacro
a=1
;I can do string just fine
b.s="the state is: "+iif(a=1, @"on", @"off")
Debug b
;int does not work the way I'm trying to do it
;I guess I would need a function that would give me the address or something...
;c=iif(a=1, @256, @0, i)
;I can do this, but it defeats the whole purpose:
Define t=256, f=0
c=iif(a=1, @t, @f, i)
Debug c
;}
Silly example, but I hope it shows what I'm trying to do.
Re: help with pointers, structures, and a possible bug with
For numbers, you could consider something like
Code: Select all
Macro IIF(expression, true, false)
((false) + ((true)-(false))*Bool(expression))
EndMacro
Debug IIF(3 > 4, 3, 5)
Debug IIF(4 > 3, 3.5, 5)
Debug 5 + IIF("a" > "b", 1, 0)
Debug 5 + IIF("b" > "a", 1, 0)
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: help with pointers, structures, and a possible bug with
Thanks for a great idea!
I guess I can then have a separate function that does that, and have it call either the string or numeric function based on the type.
I guess I can then have a separate function that does that, and have it call either the string or numeric function based on the type.