Is there a way to stream in a smalltalk binary object emdedded in an exe
file instead of loading from a file? |
"umur" <[hidden email]> wrote in message
news:[hidden email]... > Is there a way to stream in a smalltalk binary object emdedded in an exe > file instead of loading from a file? Yes. You can either stream it from a ByteArray held in the image (which is effectively how view resources are normally saved and loaded), or you could add an RT_RCDATA (i.e. binary blob) resource to your executable stub, and then update this with the STB data you want to store there at deployment time in a custom image stripper. Loading STB from a byte array rather than a file is trivial, e.g. bytes := 'Hello' binaryStoreBytes. (Object fromBinaryStoreBytes: bytes) "Ctrl+D/DisplayIt" OR: (Object binaryReadFrom: bytes readStream) "Ctrl+D/DisplayIt" Various other levels of abstraction are possible, but essentially STB works off a binary stream so it makes sense to pass streams around, and then you can choose the source/destination for the streaming. If you use a byte array in the image, you need take no further action at deployment time, other than ensuring it is stored in a class or global that will not get stripped. In order to load STB from a real Win32 resource you will first need to get it into the .exe file as such. This can be done by overriding the ImageStripper>>updateStubResources: method. I've attached an example below. Regards Blair -------------------------------------------------------------------------------------------- | package | package := Package name: 'HelloWorldResource'. package paxVersion: 0; basicComment: 'Dolphin Smalltalk Hello World from STB Resource Copyright (c) Object Arts Ltd, 2004. This package is intended to demonstrate loading an STB resource stored in a deployed executable.'. package imageStripperBytes: (ByteArray fromBase64String: 'IVNUQiAxIEYPDwAEAAAATXlJbWFnZVN0cmlwcGVyAAAAAAAAAABSAAAAEgAAAEhlbGxvV29ybGRS ZXNvdXJjZVIAAAA6AAAAT2JqZWN0IEFydHNcU2FtcGxlc1xNVlBcSGVsbG8gV29ybGRcSGVsbG9X b3JsZFJlc291cmNlLmV4ZZoAAAAAAAAAUgAAABIAAABIZWxsb1dvcmxkUmVzb3VyY2VSAAAAGgAA AE15SGVsbG9Xb3JsZFNlc3Npb25NYW5hZ2Vy7/8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA='). package classNames add: #MyHelloWorld; add: #MyHelloWorldSessionManager; add: #MyImageStripper; yourself. package binaryGlobalNames: (Set new yourself). package globalAliases: (Set new yourself). package allResourceNames: (Set new yourself). package setPrerequisites: (IdentitySet new add: '..\..\..\Dolphin\Base\Dolphin'; add: 'Hello World'; add: '..\..\..\Dolphin\Lagoon\Lagoon Image Stripper'; yourself). package! "Class Definitions"! ImageStripper subclass: #MyImageStripper instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! HelloWorldSessionManager subclass: #MyHelloWorldSessionManager instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! HelloWorld subclass: #MyHelloWorld instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: ''! "Global Aliases"! "Loose Methods"! "End of package definition"! "Source Globals"! "Classes"! MyImageStripper guid: (GUID fromString: '{8BC9839E-6E29-4A00-A6FF-8C20BA3D5736}')! MyImageStripper comment: ''! !MyImageStripper categoriesForClass!MVP-Models! ! !MyImageStripper methodsFor! updateStubResources: anExternalHandle | data | super updateStubResources: anExternalHandle. data := 'Hello STB Resource World' binaryStoreBytes. (KernelLibrary default updateResource: anExternalHandle lpType: 10 "RT_RCDATA" lpName: 999 "Unique id for the resource" wLanguage: 0 lpData: data cbData: data size) ifFalse: [KernelLibrary default systemError] ! ! !MyImageStripper categoriesFor: #updateStubResources:!operations!private! ! MyHelloWorldSessionManager guid: (GUID fromString: '{6146C1BC-729B-45F3-8C06-09DF25D7297D}')! MyHelloWorldSessionManager comment: ''! !MyHelloWorldSessionManager categoriesForClass!Samples! ! !MyHelloWorldSessionManager class methodsFor! mainShellClass "Answer the class of the application's main window (a <Shell> presenter)." ^MyHelloWorld! ! !MyHelloWorldSessionManager class categoriesFor: #mainShellClass!constants!public! ! MyHelloWorld guid: (GUID fromString: '{FC889F02-1FEC-4353-9E2B-0A9D252D3DE1}')! MyHelloWorld comment: ''! !MyHelloWorld categoriesForClass!MVP-Views! ! !MyHelloWorld methodsFor! helloText ^(self loadSTBResource: 999 fromLibrary: SessionManager current defaultResourceLibrary) ifNil: ['Hello World']! loadRawDataResource: anIntegerOrString fromLibrary: anExternalResourceLibrary | address size bytes hFind kernel hRes hModule | kernel := KernelLibrary default. hModule := anExternalResourceLibrary asParameter. (hFind := kernel findResource: hModule lpName: anIntegerOrString lpType: 10 "RT_RCDATA") isNull ifTrue: [^nil]. (hRes := kernel loadResource: hModule hResInfo: hFind) isNull ifTrue: [^nil]. (address := (kernel lockResource: hRes) asExternalAddress) isNull ifTrue: [^nil]. size := kernel sizeOfResource: hModule hResInfo: hFind. bytes := address copyFrom: 1 to: size. ^bytes! loadSTBResource: anIntegerOrString fromLibrary: anExternalResourceLibrary ^(self loadRawDataResource: anIntegerOrString fromLibrary: anExternalResourceLibrary) ifNotNil: [:bytes | Object fromBinaryStoreBytes: bytes]! onPaintRequired: aPaintEvent | canvas rect | canvas := aPaintEvent canvas. rect := self clientRectangle. canvas text: self helloText at: rect center - (60 @ 10)! ! !MyHelloWorld categoriesFor: #helloText!public! ! !MyHelloWorld categoriesFor: #loadRawDataResource:fromLibrary:!private! ! !MyHelloWorld categoriesFor: #loadSTBResource:fromLibrary:!private! ! !MyHelloWorld categoriesFor: #onPaintRequired:!event handling!public! ! "Binary Globals"! "Resources"! |
Blair,
> In order to load STB from a real Win32 resource you will first need to get > it into the .exe file as such. This can be done by overriding the > ImageStripper>>updateStubResources: method. I've attached an example below. Is this something that should be obtained from the session manager subclass? It is rare to subclass ImageStripper; it is very common to subclass session managers. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
"Bill Schwab" <[hidden email]> wrote in message
news:cbq8gr$f3q$[hidden email]... > Blair, > >> In order to load STB from a real Win32 resource you will first need to >> get it into the .exe file as such. This can be done by overriding the >> ImageStripper>>updateStubResources: method. I've attached an example >> below. > > Is this something that should be obtained from the session manager > subclass? It is rare to subclass ImageStripper; it is very common to > subclass session managers. Well firstly this is a "rare" requirement - I think it is reasonable to classify it as rare since I don't recall seeing such a request before. I don't know the reason behind the request or which of the interpretations I placed on it in my posting was correct, and I don't know why one would choose to store STB as a Windows resource rather than a ByteArray in the deployed image. Its possible a lot of people have wanted to do this, but no one has asked before. If the request had arisen before, then its possible there might be an easier way to perform this task that did not involve code, but as it stands this can only be done in 5.1 by subclassing the ImageStripper, and so I provided a simple sample to demonstrate how this could be done. Secondly building the deployed executable is the task of the "ImageStripper" (a historical name that only partly describes the function of the object). The SessionManager's job is to manage the runtime environment, not really to define what is in it. The ImageStripper does the static stuff, the SessionManager the dynamic stuff, at least that's how I see it anyway. Regards Blair |
Free forum by Nabble | Edit this page |