Page 1 of 2
How to get text from a resource into a string (PB4-Win XP)
Posted: Sun Nov 26, 2006 12:18 pm
by BigJack
Hi all,
Maybe some PB-expert can help me out here:
I am trying to get the text which is contained in the resource of the exe into a string variable by using the "LoadText_()" API function.
When trying this in order to display icons or bitmaps my code works just fine. But I can't get the text string to work...
Perhaps I am missing something in my code but don't know what I am doing wrong: Here is the source code:
Code: Select all
#ImageGadget_1 = 1
#ImageGadget_2 = 2
If OpenWindow(0,0,0,300,200,"ImageGadget",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ImageGadget(#ImageGadget_1, 4,4,100,100,0,#PB_Image_Border)
ImageGadget(#ImageGadget_2, 104,4,100,100,0,#PB_Image_Border)
hinstance=GetClassLong_(WindowID(0),#GCL_HMODULE)
IconhWnd=LoadIcon_(hinstance, @"#1") ;get Icon_Resource handle / No_1
BitmapWnd = LoadBitmap_(hinstance,@"#2") ;get Bitmap_Resource handle / No_1
TextWnd = LoadString_(hinstance,1,@"#1",10) ;get Text_Resource handle / No_1
; Display Icon_Resource
SetGadgetState(#ImageGadget_1,IconhWnd)
DestroyIcon_(IconhWnd)
; Display Bitmap Resource
SetGadgetState(#ImageGadget_2,BitmapWnd)
DestroyIcon_(BitmapWnd)
; Display Text Resource
Text$ = Str(TextWnd)
MessageRequester("Info",Text$,0)
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Posted: Sun Nov 26, 2006 1:00 pm
by srod
I would try GetLastError_() to see what is going on.
My guess is the fact that the 3rd parameter need to specifiy the address of a buffer which will receive the string.
Try something like:
Code: Select all
test$=space(10) ;Room for 10 characters
TextWnd = LoadString_(hinstance,1,@text$,10) ;get Text_Resource handle / No_1
Posted: Sun Nov 26, 2006 3:31 pm
by Fluid Byte
Srod, is right. You need to specify a valid buffer, not a string. You have set a buffersize of 10 bytes but you didn't asign a pointer one.
Posted: Sun Nov 26, 2006 4:35 pm
by BigJack
Thanks for the quick reply.
I changed the code to this (see below) BUT it still won't return the correct string value:
Code: Select all
*MemoryID = AllocateMemory(12)
TextWnd = LoadString_(hinstance,1,*MemoryID,12) ;get Text_Resource handle / No_1
Text$ = PeekS(*MemoryID,TextWnd)
FreeMemory(*MemoryID)
MessageRequester("Info",Text$,0)
PS: I checked the EXE and the resources are all in there.
I thought this one is going to be tough...

Posted: Sun Nov 26, 2006 5:16 pm
by Fluid Byte
Weird. This should work. I just tested to following example:
Code: Select all
*MemoryID = AllocateMemory(256)
HINSTANCE = OpenLibrary(0,"user32.dll")
TextWnd = LoadString_(HINSTANCE,14,*MemoryID,256)
CloseLibrary(0)
Debug PeekS(*MemoryID,TextWnd)
Works fine. So there just 2 things left to be checked:
1.) Is HINSTANCE a valid handle?
2.) Does the string resource you want to load really exists?
Posted: Sun Nov 26, 2006 7:10 pm
by BigJack
Well, then there is something wrong with my system.
The lines of code you posted, which work for you, don't work either when I compile them - strange, isn't it.
But thanks a lot anyway - atleast now I know a bit more...
Greetings Mike
Posted: Sun Nov 26, 2006 7:17 pm
by srod
I'd have a look inside your resource file at the identifier used for your string resource. Make sure you're at least using the correct identifier etc.
Other than this, like Fluid Byte, the code works for me (except I've never seen an instance handle obtained in that way - neat!

)
Posted: Sun Nov 26, 2006 11:55 pm
by Sparkie
Save the following as your .rc file
Code: Select all
STRINGTABLE
BEGIN
0 "Sparkie was here!"
1 "Sparkie was here too!\012Did you see him?"
END
Run this code after selecting the above .rc file in Complier Options (PB IDE) or under Project Options (jaPBe).
Code: Select all
If OpenWindow(0, 100, 100, 400, 200, "Testing Resources", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
TextGadget(0, 10, 10, 200, 25, "")
TextGadget(1, 10, 50, 200, 50, "")
For g = 0 To 1
buffer$ = Space(256)
LoadString_(GetModuleHandle_(0), g, @buffer$, 256)
SetGadgetText(g, buffer$)
Next g
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
End
If you don't see the 2 text strings in the window, then you have very well may have other issues to deal with.

Posted: Mon Nov 27, 2006 3:19 am
by netmaestro
For docs on how to create/use resource files in PB a good source is to download PellesC (it's free) and look through the help docs under Resources. Everything's covered and it all works with PureBasic just as described there. It doesn't need precompiled, just create the resource file in notepad and save it with an .rc extension. Then all you have to do is add the .rc file you made in compiler options - resources for your program.
Posted: Mon Nov 27, 2006 1:27 pm
by BigJack
Thanks guys for your help!
Sparkie: Your code worked!
NetMaestro: Thanks - I am going to have a close look at the help file.
My resource file which I wanted to include has just plain text:
Code: Select all
PLEASE READ:
THE PROGRAM IS PROVIDED ONLY ON AN 'As IS' BASIS, WITHOUT
WARRANTIES Or CONDITIONS OF ANY KIND, EITHER EXPRESSED Or
IMPLIED. UNDER NO CIRCUMSTANCES SHALL THE AUTHOR BE LIABLE
For ANY DAMAGES WHATSOEVER, INCLUDING ANY SPECIAL,
CONSEQUENTIAL, EXEMPLARY, INCIDENTAL Or INDIRECT
DAMAGES (INCLUDING, BUT Not LIMITED To, LOSS OF PROFITS,
REVENUES, Data And/Or USE Or OTHER FINANCIAL LOSS) ARISING
OUT OF Or IN CONNECTION HEREWITH Or THE USE OF; OR INABILITY
To USE THE PROGRAM And ITS DOCUMENTATION.
How do I include something like the above as a resource and how do I make use of it in the final exe?
Note: Without having to split each line that is (
Sparkie: I can get it done your way of course).
Greetings Mike
Posted: Tue Nov 28, 2006 8:17 am
by wayne-c
I use Sparkie's code (with success), but when I try to compile a rc-file that contains unicode characters (unicode or utf-8, does not matter) PB gives me an error. Does anybody know how to compile rc files that contains unicode characters (japanese, russian e.g.)?
Posted: Tue Nov 28, 2006 8:28 am
by netmaestro
Did you specify UTF-8 under "Source text encoding" on the resources page of the compiler options? If you did that it really should work. Also, PORC has a /C option to specify unicode strings.
Posted: Tue Nov 28, 2006 8:57 am
by wayne-c
netmaestro wrote:Did you specify UTF-8 under "Source text encoding" on the resources page of the compiler options? If you did that it really should work.
Yes, UTF-8 is selected.
I did the test with the following files:
ANSI rc file:
Code: Select all
STRINGTABLE
BEGIN
0 "Hello World"
1 "Hello ANSI Text"
2 "Hello Sun, Moon and Stars"
END
Unicode rc file (saved as utf-8 with notepad):
Code: Select all
STRINGTABLE
BEGIN
0 "Hello World"
1 "を多数擁する"
2 "Hello Sun, Moon and Stars"
END
PB File:
Code: Select all
Procedure.s ResString(Id.l)
Protected Buffer.s= Space(255)
LoadString_(GetModuleHandle_(0), Id, @Buffer, 255)
ProcedureReturn PeekS(@Buffer)
EndProcedure
Debug ResString(0)
Debug ResString(1)
Debug ResString(2)
It runs fine with the ANSI rc file, but as soon as I compile with the utf-8 / unicode stuff, it fails. Any ideas?
Posted: Tue Nov 28, 2006 11:41 am
by wayne-c
Googled MSDN and found this (I have not yet tried if it works!):
http://msdn2.microsoft.com/en-us/library/aa381050.aspx
Code: Select all
One or more strings, enclosed in quotation marks. The string must be no longer than 4097 characters and must occupy a single line in the source file. To add a carriage return to the string, use this character sequence: \012. For example, "Line one\012Line two" defines a string that is displayed as follows:
To embed quotes in the string, use the following sequence: "". For example, """Line three""" defines a string that is displayed as follows:
To encode Unicode characters, use an "L" followed by the Unicode characters enclosed by quotes. See the Examples section for an example.
Resource file with both ASCII and Unicode:
Code: Select all
STRINGTABLE
BEGIN
IDS_1 L"5\x00BC-Inch Floppy Disk"
IDS_1a "5\xBC-Inch Floppy Disk"
IDS_2 L"Don't confuse \x2229 (intersection) with \x222A (union)"
IDS_3 "Copyright \xA92001"
IDS_3a L"Copyright \x00a92001"
END
Posted: Wed Nov 29, 2006 5:14 pm
by BigJack
Hi all,
While browsing the German PB_Forum I received a code example provided by TS-Soft which is is able to handle binary resources in an excellent manner. Here is his code:
Code: Select all
Procedure LoadResource(ResNumber.l, Hmodule.l = 0)
Protected ResName.s
Protected hFind.l, hLoad.l, hLock.l, hSize.l, Mem.l
Protected ResType.s = "RC_DATA"
ResName = "#" + Str(ResNumber)
If Not Hmodule : Hmodule = GetModuleHandle_(#Null) : EndIf
hFind = FindResource_(Hmodule, ResName, @ResType)
If hFind
hLoad = LoadResource_(Hmodule, hFind)
hSize = SizeofResource_(Hmodule, hFind)
hLock = LockResource_(hLoad)
Mem = AllocateMemory(hSize)
If Mem
CopyMemory(hLock, Mem, hSize)
FreeResource_(hLock)
ProcedureReturn Mem
EndIf
EndIf
EndProcedure
*FilePointer = LoadResource(1); File wurde als RC_DATA mit der Nummer 1 im Resource Skript erzeugt
If *FilePointer
If CreateFile(0, "test.exe")
WriteData(0, *FilePointer, MemorySize(*FilePointer))
CloseFile(0)
FreeMemory(*FilePointer)
EndIf
EndIf
*TextPointer = LoadResource(2)
If *TextPointer
MyText.s = PeekS(*TextPointer)
FreeMemory(*TextPointer)
EndIf
Perhaps one must replace the value for "ResType.s" by something like "Text" or "RData". This atleast did it for me.
Thanks TS-Soft