Bitmap von einer dll/Exe (Resource)

Für allgemeine Fragen zur Programmierung mit PureBasic.
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Bitmap von einer dll/Exe (Resource)

Beitrag von lite »

Hallo

Wie kann ich eine Bitmap mittels Resourcen ( kein RCData) von einer exe bzw dll in einer Gui anzeigen ?

Hab hier was gefunden, das funktioniert nicht 100%.
Die Anzeige ist verschoben, kann das jemand korrigieren ?
oder gibt es eine einfachere Lösung ?

Code: Alles auswählen


ProcedureDLL.l GetResourcePointer(Name.s, TypeRes = #RT_RCDATA, dll.s = "") 
    If dll And FileSize(dll) > 0 
       hModule = LoadLibrary_(dll) 
    Else 
       hModule = GetModuleHandle_(0) 
    EndIf 
    hResource= FindResource_(hModule,@Name,TypeRes) 
    If hResource 
       hGlobalMemBlock=LoadResource_(hModule,hResource) 
       SizeRes = SizeofResource_(hModule, hResource) 
       *MemoryID = AllocateMemory(SizeRes + 14) 
       For i=0 To 13 
         Read.b y.b 
         PokeB(*MemoryID+i, y) 
       Next 
       CopyMemory(hGlobalMemBlock, *MemoryID+14, SizeRes) 
       FreeResource_(hGlobalMemBlock) 
       FreeLibrary_(hModule) 
       ProcedureReturn *MemoryID 
    EndIf 
    FreeLibrary_(hModule) 
  EndProcedure 
  

  

 pRes = GetResourcePointer("#131", #RT_BITMAP, "C:\WINDOWS\system32\Shell32.dll") 
;Debug(Str(pRes))
   MemorySize(pRes) 
 CatchImage(0, pRes) 
 FreeMemory(pRes) 
;  MessageRequester("Debug","Pause",262144) 
 OpenWindow(0,0,0,440,440,"ImageGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
 
 ImageGadget (2, 0, 0, 200, 280, 0)
 SendMessage_( GadgetID(2), #STM_SETIMAGE, #IMAGE_BITMAP, ImageID(0))

 ImageGadget(0,20,120,200,200,ImageID(0)) 
 FreeImage(0) 
 Repeat : Event=WaitWindowEvent() : Until Event = #PB_Event_CloseWindow 
  
DataSection 
HEADER: 
Data.b   $42, $4D, $92, $13, $00, $00, $00, $00, $00, $00, $76, $00, $00, $00 
EndDataSection

End


Grüße

lite
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Bitmap von einer dll/Exe (Resource)

Beitrag von Danilo »

Bei mir findet er die Resource "#131" nicht, also crasht es weil 0 von der Funktion zurückgegeben wird.

Ich denke aber Du kannst .bmp direkt mit CatchImage() holen, ohne eigenen Header davor zu schreiben.
Die Verschiebung kommt bestimmt durch die 14 Bytes Deines Headers.

Probier mal ob das bei Dir geht:

Code: Alles auswählen

ProcedureDLL.l GetResourceBitmap(Name.s, dll.s = "")
    If dll And FileSize(dll) > 0
       hModule = LoadLibrary_(dll)
    Else
       hModule = GetModuleHandle_(0)
    EndIf
    hResource= FindResource_(hModule,@Name,#RT_BITMAP)
    If hResource
       hGlobalMemBlock=LoadResource_(hModule,hResource)
       SizeRes = SizeofResource_(hModule, hResource)
       Debug hGlobalMemBlock
       image = CatchImage(#PB_Any,hGlobalMemBlock,SizeRes)
       FreeResource_(hGlobalMemBlock)
       FreeLibrary_(hModule)
       ProcedureReturn image
    EndIf
    FreeLibrary_(hModule)
EndProcedure

img = GetResourceBitmap("#131", "C:\WINDOWS\system32\Shell32.dll")
If img
 OpenWindow(0,0,0,440,440,"ImageGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 
 ImageGadget (2, 0, 0, 200, 280, 0)
 SendMessage_( GadgetID(2), #STM_SETIMAGE, #IMAGE_BITMAP, ImageID(img))

 ImageGadget(0,20,120,200,200,ImageID(img))
 FreeImage(img)
 Repeat : Event=WaitWindowEvent() : Until Event = #PB_Event_CloseWindow
EndIf
Bei mir (Win7 64bit) gibt es diese Resource nicht, also wird nichts angezeigt.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Bitmap von einer dll/Exe (Resource)

Beitrag von lite »

Hallo

Danke für deine mühen, Such den ganzen Tag nach eine Lösung.
Bis jetzt nichts brauchbares gefunden.
Ja, auf win 7 64 gibt es diese Resource nicht. event. anpassen.

Dein Beispiel funktioniert leider nicht.
Das Fenster erscheint nicht :cry:

lite
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Bitmap von einer dll/Exe (Resource)

Beitrag von Danilo »

Direkt mit LoadBitmap_() sollte es aber gehen, wenn es die Resource gibt:

Code: Alles auswählen

hModule = LoadLibrary_("C:\WINDOWS\system32\Shell32.dll")
If hModule
    hBmp  = LoadBitmap_(hModule,131)
    hBmp2 = LoadBitmap_(hModule,@"#131")

    Debug hBmp
    Debug hBmp2
    
    icon = LoadIcon_(hModule,1)

    Debug icon    
EndIf
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
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: Bitmap von einer dll/Exe (Resource)

Beitrag von ts-soft »

Leider funktioniert Danilos Code auch nicht (mit existierender Resource), aber diese Version sollte es doch auch tun?

Code: Alles auswählen

EnableExplicit

ProcedureDLL GetResourceBitmap(Name.s, dll.s = "")
  Protected hModule, hBitmap
  If dll And FileSize(dll) > 0
    hModule = LoadLibrary_(dll)
  Else
    hModule = GetModuleHandle_(0)
  EndIf
  If hModule
    hBitmap = LoadImage_(hModule, Name, #IMAGE_BITMAP, 0, 0, #LR_DEFAULTSIZE | #LR_SHARED)
    FreeLibrary_(hModule)
  EndIf
  ProcedureReturn hBitmap
EndProcedure

Define img = GetResourceBitmap("#51209", "C:\WINDOWS\system32\Shell32.dll")
Define Event

If img
 OpenWindow(0, 0, 0, 440, 440, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
 
 ImageGadget (2, 0, 0, 200, 280, 0)
 SendMessage_( GadgetID(2), #STM_SETIMAGE, #IMAGE_BITMAP, img)

 ImageGadget(0, 20, 120, 200, 200, img)
 Repeat : Event = WaitWindowEvent() : Until Event = #PB_Event_CloseWindow
EndIf 
Gruß
Thomas

// edit
zu langsam, inzwischen 2 neue Beiträge :roll:
Zuletzt geändert von ts-soft am 14.10.2012 16:30, insgesamt 2-mal geändert.
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
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Bitmap von einer dll/Exe (Resource)

Beitrag von lite »

Hallo Danilo

Deine Lösung funktioniert. :bounce: super
was ist, wen es verschiedene Language-Einträge gibt ?
Kann man das auch wo einstellen ?

1031 / 2057...

lite
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Bitmap von einer dll/Exe (Resource)

Beitrag von Danilo »

lite hat geschrieben:Deine Lösung funktioniert. :bounce: super
Dein Original-Code funktioniert auch, wenn die Resource vorhanden ist.
Nur war das Bild verschoben, weil Deine DataSection nicht korrekt war:

Code: Alles auswählen

DataSection
HEADER:
Data.b   $42, $4D, $92, $13, $00, $00, $00, $00, $00, $00, $76, $00, $00, $00
EndDataSection
$76 ist 118, da muß aber 54 stehen, also $36. 54/$36 ist der Offset wo
die Bilddaten losgehen. Der Header ist die Structure "BITMAPFILEHEADER".
lite hat geschrieben:was ist, wen es verschiedene Language-Einträge gibt ?
Kann man das auch wo einstellen ?
Habe mal Deinen originalen Code genommen und etwas angepasst, mit optionalem Parameter für die Sprache der Resource:

Code: Alles auswählen

Macro MAKELANGID(p, s)
  (((s) << 10) | (p))
EndMacro

ProcedureDLL.l GetResourceBitmap(Name.s, dll.s = "", wLanguage = MAKELANGID(#LANG_NEUTRAL, #SUBLANG_NEUTRAL))
    If dll And FileSize(dll) > 0
       hModule = LoadLibrary_(dll)
    Else
       hModule = GetModuleHandle_(0)
    EndIf
    hResource= FindResourceEx_(hModule,#RT_BITMAP,@Name, wLanguage)
    If hResource
       hGlobalMemBlock=LoadResource_(hModule,hResource)
       If hGlobalMemBlock
           SizeRes = SizeofResource_(hModule, hResource)
           *MemoryID.BITMAPFILEHEADER = AllocateMemory(SizeOf(BITMAPFILEHEADER) + SizeRes)
           If *MemoryID
               *MemoryID\bfType = 19778 ; 'BM'
               *MemoryID\bfSize = SizeOf(BITMAPFILEHEADER) + SizeRes
               *MemoryID\bfOffBits = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER)
               locked = LockResource_(hGlobalMemBlock)
               If locked
                   CopyMemory(locked, *MemoryID+SizeOf(BITMAPFILEHEADER), SizeRes)
                   image = CatchImage(#PB_Any,*MemoryID,SizeOf(BITMAPFILEHEADER) + SizeRes)
               EndIf
               FreeMemory(*MemoryID)
           EndIf
           FreeResource_(hGlobalMemBlock)
       EndIf
    EndIf
    FreeLibrary_(hModule)
    ProcedureReturn image
EndProcedure

img = GetResourceBitmap("#51209", "C:\WINDOWS\system32\Shell32.dll")
If img
 OpenWindow(0,0,0,440,440,"ImageGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 
 ImageGadget (2, 0, 0, 200, 280, 0)
 SendMessage_( GadgetID(2), #STM_SETIMAGE, #IMAGE_BITMAP, ImageID(img))

 ImageGadget(0,20,120,200,200,ImageID(img))
 FreeImage(img)
 Repeat : Event=WaitWindowEvent() : Until Event = #PB_Event_CloseWindow
EndIf
Habe hier mal "#51209" von ts-soft genommen, das funktionierte hier.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten