Re: CatchImageEx (Windows API) Adresslesefehler [Gelöst]

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
dlldev
Beiträge: 23
Registriert: 28.07.2014 02:22

Re: CatchImageEx (Windows API) Adresslesefehler [Gelöst]

Beitrag von dlldev »

Seit Version 5.3 von PB erhalte ich in der Zeile mit "CopyMemory(Addr, *ptr, Size)" in der Prozedur "_CreateStreamFromMem" einen Adresslesefehler, bei Version 5.22 lief das ganze noch. Hat jemand eine Ahnung weshalb es bei der Version 5.3 zu genanntem Fehler kommt bez. dessen Ursache?

Code: Alles auswählen

Procedure _CreateStreamFromMem(Addr.l, Size.l)
  Protected.l mem = GlobalAlloc_(#GMEM_MOVEABLE, Size)
  Protected *ptr, Stream.IStream
  If mem
    *ptr = GlobalLock_(mem)
    If *ptr
      CopyMemory(Addr, *ptr, Size)
      CreateStreamOnHGlobal_(mem, #True, @Stream.IStream)
      GlobalUnlock_(mem)
    EndIf
    If Stream = 0
      GlobalFree_(mem)
    EndIf
  EndIf
  ProcedureReturn Stream
EndProcedure

Procedure CatchImageEx(Image, Addr, Size, Flags = 0)
  Protected dxsf.nIDXSurfaceFactory, dxtf.IDXTransformFactory, Stream.IStream, surf.IDXSurface, lock.IDXDCLock, re.rect
  Protected.l Success, DestDC, DC, result = CoInitialize_(0)
  If result = #S_FALSE Or result = #S_OK
    CoCreateInstance_(?CLSID_DXTransformFactory, 0, #CLSCTX_INPROC_SERVER, ?IID_IDXTransformFactory, @dxtf.IDXTransformFactory)
    If dxtf
      dxtf\QueryService(?IID_IDXSurfaceFactory, ?IID_IDXSurfaceFactory, @dxsf.nIDXSurfaceFactory)
      If dxsf
        Stream.IStream = _CreateStreamFromMem(Addr, Size)
        If Stream
          dxsf\LoadImageFromStream(Stream, 0, 0, 0, ?IID_IDXSurface, @surf.IDXSurface)
          If surf
            surf\LockSurfaceDC(0, #INFINITE, #DXLOCKF_READ, @lock.IDXDCLock)
            If lock
              DC = lock\GetDC()
              If DC
                GetClipBox_(DC, re.rect)
                If Image = #PB_Any
                  result = CreateImage(#PB_Any, re\right, re\bottom, Flags)
                  Image = result
                Else
                  result = CreateImage(Image, re\right, re\bottom, Flags)
                EndIf
                If result
                  DestDC = StartDrawing(ImageOutput(Image))
                  If DestDC
                    Success = BitBlt_(DestDC, 0, 0, re\right, re\bottom, DC, 0, 0, #SRCCOPY)
                    StopDrawing()
                  EndIf
                  If Success = #False : FreeImage(Image) : EndIf
                EndIf
              EndIf
              Lock\Release()
            EndIf
            surf\Release()
          EndIf
          dxsf\Release()
        EndIf
        Stream\Release()
      EndIf
      dxtf\Release()
    EndIf
    ;CoUninitialize_() ; dosn't work with this ?!?
  EndIf

  If Success:ProcedureReturn result:EndIf
  ProcedureReturn #False
  DataSection
  EndDataSection
EndProcedure

Zuletzt geändert von dlldev am 14.08.2014 13:31, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von NicTheQuick »

Ich kann's zwar nicht testen, aber 'Addr' ist sicherlich kein Long. Und 'mem' auch nicht.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von ts-soft »

Ist nicht vollständig, falsch, ...

Code: Alles auswählen

DataSection
  CLSID_DXTransformFactory:
  Data.l $D1FE6762
  Data.w $FC48,$11D0
  Data.b $88,$3A,$3C,$8B,$00,$C1,$00,$00

  IID_IDXTransformFactory:
  Data.l $6A950B2B
  Data.w $A971,$11D1
  Data.b $81,$C8,$00,$00,$F8,$75,$57,$DB

  IID_IDXSurfaceFactory:
  Data.l $144946F5
  Data.w $C4D4,$11D1
  Data.b $81,$D1,$00,$00,$F8,$75,$57,$DB

  IID_IDXSurface:
  Data.l $B39FD73F
  Data.w $E139,$11D1
  Data.b $90,$65,$00,$C0,$4F,$D9,$18,$9D
EndDataSection

CompilerIf Defined(nIDXSurfaceFactory, #PB_Interface) = #False
Interface nIDXSurfaceFactory
  QueryInterface(a.l, b.l)
  AddRef()
  Release()
  CreateSurface(a.l, b.l, c.l, d.l, e.l, f.l, g.l, h.l)
  CreateFromDDSurface(a.l, b.l, c.l, d.l, e.l, f.l)
  LoadImage(a.p-bstr, b.l, c.l, d.l, e.l, f.l)
  LoadImageFromStream(a.l, b.l, c.l, d.l, e.l, f.l)
  CopySurfaceToNewFormat(a.l, b.l, c.l, d.l, e.l)
  CreateD3DRMTexture(a.l, b.l, c.l, d.l, e.l)
  BitBlt(a.l, b.l, c.l, d.l, e.l)
EndInterface
CompilerEndIf

#DXLOCKF_READ = 0
#CLSCTX_INPROC_SERVER = 1

Procedure _CreateStreamFromMem(Addr.i, Size.l)
  Protected *mem = GlobalAlloc_(#GMEM_MOVEABLE, Size)
  Protected *ptr
  Protected Stream.IStream
  If *mem
    *ptr = GlobalLock_(*mem)
    If *ptr
      CopyMemory(Addr, *ptr, Size)
      CreateStreamOnHGlobal_(*mem, #True, @Stream)
      GlobalUnlock_(*mem)
    EndIf
    If Stream = 0: GlobalFree_(*mem) : EndIf
  EndIf
  ProcedureReturn Stream
EndProcedure

Procedure CatchImageEx(Image.i, Addr.i, Size.l, Flags = #PB_Image_DisplayFormat)
  Protected result = CoInitialize_(0)
  Protected dxtf.IDXTransformFactory
  Protected dxsf.nIDXSurfaceFactory
  Protected Stream.IStream
  Protected surf.IDXSurface
  Protected lock.IDXDCLock
  Protected DC.l, DestDC.l, Success.l
  Protected re.rect

  If result = #S_FALSE Or result = #S_OK
    CoCreateInstance_(?CLSID_DXTransformFactory, 0, #CLSCTX_INPROC_SERVER, ?IID_IDXTransformFactory, @dxtf)
    If dxtf
      dxtf\QueryService(?IID_IDXSurfaceFactory, ?IID_IDXSurfaceFactory, @dxsf)
      If dxsf
        Stream = _CreateStreamFromMem(Addr, Size)
        If Stream
          dxsf\LoadImageFromStream(Stream, 0, 0, 0, ?IID_IDXSurface,@surf)
          If surf
            surf\LockSurfaceDC(0, #INFINITE,#DXLOCKF_READ, @lock)
            If lock
              DC = lock\GetDC()
              If DC
                GetClipBox_(DC, re)
                result = CreateImage(Image, re\right, re\bottom, Flags)
                If Image = #PB_Any
                  Image = result
                EndIf
                If result
                  DestDC = StartDrawing(ImageOutput(Image))
                  If DestDC
                    Success = BitBlt_(DestDC, 0, 0, re\right, re\bottom, DC, 0, 0, #SRCCOPY)
                    StopDrawing()
                  EndIf
                  If Success = #False : FreeImage(Image) : EndIf
                EndIf
              EndIf
              Lock\Release()
            EndIf
            surf\Release()
          EndIf
          dxsf\Release()
        EndIf
        Stream\Release()
      EndIf
      dxtf\Release()
    EndIf
  EndIf

  If Success : ProcedureReturn result : EndIf
  ProcedureReturn #False
EndProcedure
Das sollte funktionieren.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
dlldev
Beiträge: 23
Registriert: 28.07.2014 02:22

Re: CatchImageEx (Windows API) Adresslesefehler [Gelöst]

Beitrag von dlldev »

ts-soft hat geschrieben:Ist nicht vollständig, falsch, ...

Das sollte funktionieren.
Oops, die DataSection hatte ich total vergessen. Mit dem von Dir geändertem Code sieht es bis jetzt gut aus, hatte jedenfalls keine Fehlermeldung mehr in meinen erneuten Tests. :allright: @NicTheQuick Auch ein Danke an Dich
Entwicklungsumgebung: Intel i7 Laptop mit 8GB RAM und Windows 8.1 drauf. PureBasic 5.24 LTS.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von edel »

NicTheQuick hat geschrieben:Ich kann's zwar nicht testen, aber 'Addr' ist sicherlich kein Long. Und 'mem' auch nicht.
Size, DC und DestDC auch nicht, sind alles Integer. Ach und a, b, c, d, e, f, g, h ebenfalls nicht.

:lurk:
Benutzeravatar
dlldev
Beiträge: 23
Registriert: 28.07.2014 02:22

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von dlldev »

edel hat geschrieben: Size, DC und DestDC auch nicht, sind alles Integer. Ach und a, b, c, d, e, f, g, h ebenfalls nicht.
:lurk:
Auch wenn es bei mir anscheinend schon jetzt tadellos läuft auch ein Danke an Dich, habe den Source noch angepasst.
Entwicklungsumgebung: Intel i7 Laptop mit 8GB RAM und Windows 8.1 drauf. PureBasic 5.24 LTS.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von edel »

Das war nicht wirklich ernst gemeint. Auf 32 Bit sollte das auch ohne Probleme laufen
Benutzeravatar
dlldev
Beiträge: 23
Registriert: 28.07.2014 02:22

Re: CatchImageEx (Windows API) Adresslesefehler

Beitrag von dlldev »

edel hat geschrieben:Das war nicht wirklich ernst gemeint. Auf 32 Bit sollte das auch ohne Probleme laufen
Wie auch immer, 64 Bit ist bei mir eh noch kein Thema. :wink:
Antworten