Christof and Sergey,
I repeat Bo, thanking you for the suggestions.
The real reason for this search for the best performance is that we can create some new controls that can bypass some of the original behaviors, eg. gradient commandbuttons, using system icons, etc...
For just one or 2 embedded images, I'm pretty sure that the suggestions that you both sent will do it really very fast.
But thinking in a form that contain more than 20 objects... some mliseconds on each control may represent an important difference, that's why I'd like to try to find out the fastest method.
>> what code would you recommend that would determine if the file is embedded vs. on disk?
Please check the full code from this msg at Codeplex:
http://www.codeplex.com/VFPX/WorkItem/View.aspx?WorkItemId=10185LOCAL lnStatus
lnStatus = xfcGdipLoadImageFromFile(STRCONV(m.tcFilename+0h00,5), @lhImage)
IF m.lnStatus = StatusOutOfMemory
ENDIF
So I think we have 3 options:
1 - Using FILETOSTR() and STRTOFILE(), with Temp files
2 - Using LOADPICTURE() function, that creates an OLE image object, and use an API call to send it to a stream, then use GdipLodImageFromStream to bring it to GDI+
3 - Create a Stream manually, with the size of the LENgth of the FILETOSTR, use SYS(2600) to send those binaries to memory stream, and finally use GdipLodImageFromStream to bring it to GDI+
I've already tried #2, but I'm facing a DLL exception when using the function OLESAVETOSTREAM.
Unfortunately, I've found really very few info about it on the web, NO SAMPLES AT ALL !!!
I'm not sure if I have to pass the OLE object or the OLE handle, but it does not work in anyway.
Maybe one of you can show me how to make it work ?
Here's the code that I'm using to load the picture embedded in the EXE, without disk access:
LOCAL loImg
m.loImg = LOADPICTURE(m.tcFilename)
IF VARTYPE(loImg) = "O"
LOCAL loStream as xfcMemoryStream
loStream = NEWOBJECT("xfcMemoryStream",XFCCLASS_SYSTEM)
DECLARE LONG OleSaveToStream IN OLE32.DLL OBJECT Obj, INTEGER Stream
OleSaveToStream(loImg, loStream.Handle)
This.SetStatus(xfcGdipLoadImageFromStream(m.loStream.Handle, @lhImage))
loStream.Dispose()
ENDIF
I'm getting an error in the "OleSaveToStream" call.
DO you have any ideas, or am I using the wrong function for that ?
Thnaks very much for your suggestions
TIA
Cesar
>Hi Bo,
>
>> what code would you recommend that would determine if the file is embedded vs. on disk?
>
>I've used ADIR() in the past, but SYS(2000) seems just as appropriate.
>
>>From what I can tell, these functions can see the embedded resource:
>
>There are three groups of commands and functions. Some cannot access embedded files at all, some only those stored in the project root and some those in sub folders, as well. Unfortunately I haven't done any systematic testing on these statements. It's more like little piece of knowledge like "Don't use COPY FILE" for embedded files", "use random file names for developer projects", "copy images to the temp directory when using ActiveX controls", and the like.
>
>>She is also using STRTOFILE(FILETOSTR()) as you are using here. Is there a point where size could be come an issue that FREAD/FWRITE ing blocks would be better?
>
>FILETOSTR() is about the best command. COPY FILE doesn't work on embedded files. FREAD() has problems with larger files and is slower. FILETOSTR() can even read files beyond the 16 MB limit, even though I wouldn't rely on it. Albeit this limit shouldn't be an issue with embedded files, as it's unlikely someone embeds a 20 MB picture file..