Page 1 of 1

Posted: Sun Mar 10, 2002 10:26 pm
by BackupUser
Restored from previous forum. Originally posted by El_Choni.

Hi,

I'm trying to use OleLoadPicture_() to load Gif and Jpeg images in a Windows app. I've found an easy way to access IPicture methods from PureBasic, but OleLoadPicture_() will always crash. I don't even know if IPicture is an OLE or COM object, so I don't know if I should use CoInitialize_() or OleInitialize_(). To make things worse, OleLoadPicture_() is present in OLEPRO32.DLL and in OLEAUT32.DLL. Which one is called by PureBasic (being both defined in APIList.txt), and which should I use? Which libraries should I load with LoadLibrary_()?

If anyone here knows something about this issue, any help or comment would be appreciated. Bye,

El_Choni

Posted: Sun Mar 10, 2002 11:38 pm
by BackupUser
Restored from previous forum. Originally posted by Danilo.

Well... what you want is COM-programming (OOP),
but thats not supported in PB atm.
I have some commands for calling Methods in COM-Objects
for DirectX, maybe that will help a little bit.

You need also the right "IID_IPicture" GUID and the
right structure for this GUID.

I dont know what you have for now, so some source
would be cool (as always!).

cya,
...Danilo

(registered PureBasic user)

Posted: Mon Mar 11, 2002 12:50 am
by BackupUser
Restored from previous forum. Originally posted by El_Choni.

Hi,

Here's some code for you to bite. It does actually nothing but crash when the call is made inside the procedure (otherwise, it would't do much, either. It's just the conflictive part of a bigger app).

Code: Select all

Structure IPictureMethods; IPicture object methods
  QueryInterface.l        ; It's important to put them in the right order
  AddRef.l                ; because the procedure will call them. The methods after
  Release.l               ; Release aren't used in this example.
  Get_Handle.l
  Get_HPal.l
  Get_Type.l
  Get_Width.l
  Get_Height.l
  Render.l
  Set_HPal.l
  Get_CurDC.l
  SelectPicture.l
  get_KeepOriginalFormat.l
  put_KeepOriginalFormat.l
  PictureChanged.l
  SaveAsFile.l
  get_Attributes.l
EndStructure

Global *gpPicture.IPictureMethods

gpPicture = 0
pstm = 0

Global method ; <--- This is needed, since PB won't update its internal pointer to the procedure arguments
               ; when usin "push arg" inside it (translated To "push dword [esp+20]" in PureBasic.asm),
               ; and that will mess everything. So we Global the variable to get "push dword [v_method]"
               ; inside the proc. The problem really arises when using more than one arg.

Procedure IPicture_Release(IPicture) ; IPicture holds the pointer to the interface, whatever "interface" means
  *gpPicture = IPicture               ; now the IPictureMethods structure is "mapped" to the interface.
  method = *gpPicture\Release         ; We need the Release method.
  push *gpPicture                     ; Push the object (the pointer to the interface),
  call method                         ; and call the method
EndProcedure

;
; Open Gif file
;

OpenGif:

File.s = OpenFileRequester("Open Gif file","","GIF Image (*.gif)|*.gif", 0)
If ReadFile(0, File)
  LoadLibrary_("OLEPRO32.DLL")
  LoadLibrary_("ADVAPI32.DLL")
  LoadLibrary_("OLEAUT32.DLL")
  OleInitialize_(0)
  FileSize = FileSize(File)
  hGlobal = GlobalAlloc_(#GMEM_MOVEABLE, FileSize);
  pvData = GlobalLock_(hGlobal)
  ReadData(pvData, FileSize)
  CloseFile(0)
  GlobalUnlock_(hGlobal)
  CreateStreamOnHGlobal_(hGlobal, #TRUE, @pstm)
  OleLoadPicture_(pstm, FileSize, #FALSE, ?IID_IPicture, @gpPicture)
  IPicture_Release(gpPicture)
  GlobalFree_(hGlobal)
  OleUninitialize_()
EndIf

End

![section .data] ; this is the only way I've found to pass the IPicture GUID
IID_IPicture: ; because PB won't allow unsigned (we'be been reading about this lately)
!dd $07bf80980
!dw $0bf32, $0101a
!db $08b, $0bb, 0, $0aa, 0, $030, $0c, $0ab
Hope you can gime me any clues. Have a nice day,

El_Choni

Posted: Mon Mar 11, 2002 4:37 am
by BackupUser
Restored from previous forum. Originally posted by Danilo.

I could send you my Library, so you can use

Code: Select all

CallCOM(#IPicture_Release, gpPicture)
"CallCOM ( #Method, OBJECT )", where
#Method is the offset in the Interface.

0 = QueryInterface
4 = AddRef
8 = Release

are the first 3 Methods in every interface,
so the offsets are the same everytime for this
Methods.

cya,
...Danilo

(registered PureBasic user)

Posted: Tue Mar 12, 2002 12:15 am
by BackupUser
Restored from previous forum. Originally posted by Danilo.

Hi El_Choni !!

I sent you the Library for COM-Programming,
so look at your eMails.

But i think there are still some errors
in your code.

Your structure is not needed for this.

Code: Select all

; thats our OBJECT for COM-Programming:
gpPicture.l


; now we need the Method as a constant:
#IPicture_Release = 8


; your procedure isnt needed anymore
;
; here the rest of your code (unchanged):
pstm = 0


; Open Gif file
;
OpenGif:
File.s = OpenFileRequester("Open Gif file","","GIF Image (*.gif)|*.gif", 0)
If ReadFile(0, File)
   LoadLibrary_("OLEPRO32.DLL")
   LoadLibrary_("ADVAPI32.DLL")
   LoadLibrary_("OLEAUT32.DLL")
   OleInitialize_(0)
   FileSize = FileSize(File)
   hGlobal = GlobalAlloc_(#GMEM_MOVEABLE, FileSize);
   pvData = GlobalLock_(hGlobal)
   ReadData(pvData, FileSize)
   CloseFile(0)
   GlobalUnlock_(hGlobal)
   CreateStreamOnHGlobal_(hGlobal, #TRUE, @pstm)


; Now the COM-stuff:
   OleLoadPicture_(pstm, FileSize, #FALSE, ?IID_IPicture, @gpPicture)
   CallCOM0( #IPicture_Release, gpPicture )


   GlobalFree_(hGlobal)
   OleUninitialize_()
EndIf
End


![section .data] ; this is the only way I've found to pass the IPicture GUID
IID_IPicture: ; because PB won't allow unsigned (we'be been reading about this lately)
!dd $07bf80980
!dw $0bf32, $0101a
!db $08b, $0bb, 0, $0aa, 0, $030, $0c, $0ab
Thats only how it should look by using my
COM-Library, i didnt verify if the rest of
your code is OK.
You should also check if the functions fail
or return succesful, like:

Code: Select all

If OleLoadPicture_(pstm, FileSize, #FALSE, ?IID_IPicture, @gpPicture) = #S_OK
   CallCOM0( #IPicture_Release, gpPicture )
Else
   Beep_(1000,1000)
Endif
I check everything and add beep´s or a msg-box
in my code, when i want to try/learn new stuff,
so i can hear+see if something goes wrong...

cya,
...Danilo
(registered PureBasic user)

Edited by - Danilo on 12 March 2002 00:19:14